dew/src/main/resources/org/apidesign/bck2brwsr/dew/js/app.js
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 11 Feb 2013 19:55:00 +0100
branchemul
changeset 711 333326d65bf9
parent 579 942deef87200
permissions -rw-r--r--
Allows two isolated bck2brwsr VM in a single JavaScript page/context
phrebejk@460
     1
// 'use strict';
phrebejk@460
     2
phrebejk@460
     3
// Declare app level module which depends on filters, and services
phrebejk@460
     4
angular.module('bck2brwsr', []).
phrebejk@460
     5
  directive('uiCodemirror', ['$timeout', function($timeout) {
phrebejk@460
     6
        'use strict';
phrebejk@460
     7
phrebejk@460
     8
        var events = ["cursorActivity", "viewportChange", "gutterClick", "focus", "blur", "scroll", "update"];
phrebejk@460
     9
        return {
phrebejk@460
    10
            restrict: 'A',
phrebejk@460
    11
            require: 'ngModel',
phrebejk@460
    12
            link: function(scope, elm, attrs, ngModel) {
phrebejk@460
    13
                var options, opts, onChange, deferCodeMirror, codeMirror, timeoutId, val;
phrebejk@460
    14
phrebejk@460
    15
                if (elm[0].type !== 'textarea') {
phrebejk@460
    16
                    throw new Error('uiCodemirror3 can only be applied to a textarea element');
phrebejk@460
    17
                }
phrebejk@460
    18
phrebejk@460
    19
                options = /* uiConfig.codemirror  || */ {};
phrebejk@460
    20
                opts = angular.extend({}, options, scope.$eval(attrs.uiCodemirror));
phrebejk@460
    21
phrebejk@460
    22
                onChange = function(instance, changeObj) {                    
phrebejk@460
    23
                    val = instance.getValue();
phrebejk@460
    24
                    $timeout.cancel(timeoutId);
phrebejk@460
    25
                    timeoutId = $timeout(function() {
phrebejk@460
    26
                        ngModel.$setViewValue(val);                        
phrebejk@460
    27
                      }, 500);                    
phrebejk@460
    28
                };
phrebejk@460
    29
                
phrebejk@460
    30
                deferCodeMirror = function() {
phrebejk@460
    31
                    codeMirror = CodeMirror.fromTextArea(elm[0], opts);
phrebejk@541
    32
                    elm[0].codeMirror = codeMirror;
phrebejk@460
    33
                    // codeMirror.on("change", onChange(opts.onChange));
phrebejk@460
    34
                    codeMirror.on("change", onChange);
phrebejk@460
    35
phrebejk@460
    36
                    for (var i = 0, n = events.length, aEvent; i < n; ++i) {
phrebejk@460
    37
                        aEvent = opts["on" + events[i].charAt(0).toUpperCase() + events[i].slice(1)];
phrebejk@460
    38
                        if (aEvent === void 0)
phrebejk@460
    39
                            continue;
phrebejk@460
    40
                        if (typeof aEvent !== "function")
phrebejk@460
    41
                            continue;
phrebejk@460
    42
                                                
phrebejk@460
    43
                        var bound = _.bind( aEvent, scope );
phrebejk@460
    44
                        
phrebejk@460
    45
                        codeMirror.on(events[i], bound);
phrebejk@460
    46
                    }
phrebejk@460
    47
phrebejk@460
    48
                    // CodeMirror expects a string, so make sure it gets one.
phrebejk@460
    49
                    // This does not change the model.
phrebejk@460
    50
                    ngModel.$formatters.push(function(value) {
phrebejk@460
    51
                        if (angular.isUndefined(value) || value === null) {
phrebejk@460
    52
                            return '';
phrebejk@460
    53
                        }
phrebejk@460
    54
                        else if (angular.isObject(value) || angular.isArray(value)) {
phrebejk@460
    55
                            throw new Error('ui-codemirror cannot use an object or an array as a model');
phrebejk@460
    56
                        }
phrebejk@460
    57
                        return value;
phrebejk@460
    58
                    });
phrebejk@460
    59
phrebejk@460
    60
                    // Override the ngModelController $render method, which is what gets called when the model is updated.
phrebejk@460
    61
                    // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
phrebejk@460
    62
                    ngModel.$render = function() {
phrebejk@460
    63
                        codeMirror.setValue(ngModel.$viewValue);
phrebejk@460
    64
                    };
phrebejk@460
    65
phrebejk@460
    66
                };
phrebejk@460
    67
phrebejk@460
    68
                $timeout(deferCodeMirror);
phrebejk@460
    69
phrebejk@460
    70
            }
phrebejk@460
    71
        };
phrebejk@460
    72
}]);
phrebejk@460
    73
phrebejk@461
    74
function DevCtrl( $scope, $http ) {
jaroslav@545
    75
    var templateHtml = 
jaroslav@545
    76
"<html><body>\n" +
jaroslav@545
    77
"  <input data-bind=\"value: value, valueUpdate: 'afterkeydown'\" \n" +
jaroslav@545
    78
"     value=\"0\" type=\"number\">\n" +
jaroslav@545
    79
"  </input>\n" +
jaroslav@545
    80
"  * <span data-bind=\"text: value\">0</span> \n" +
jaroslav@545
    81
"  = <span data-bind=\"text: powerValue\">0</span>\n" +
jaroslav@545
    82
"  <br/>\n" +
jaroslav@545
    83
"  <button id='dupl'>Duplicate!</button>\n" +
jaroslav@545
    84
"  <button id=\"clear\">Clear!</button>" +
jaroslav@545
    85
" <hr/>\n" +
jaroslav@545
    86
"\n" +
jaroslav@545
    87
"\n" +
jaroslav@545
    88
"\n" +
jaroslav@545
    89
"\n" +
jaroslav@545
    90
"\n" +
jaroslav@545
    91
"\n" +
jaroslav@545
    92
"\n" +
jaroslav@545
    93
"\n" +
jaroslav@545
    94
"\n" +
jaroslav@545
    95
"\n" +
jaroslav@545
    96
"\n" +
jaroslav@545
    97
"\n" +
jaroslav@545
    98
"\n" +
jaroslav@545
    99
"\n" +
jaroslav@545
   100
"\n" +
jaroslav@545
   101
"\n" +
jaroslav@545
   102
"\n" +
jaroslav@545
   103
"\n" +
jaroslav@545
   104
"\n" +
jaroslav@545
   105
"\n" +
jaroslav@545
   106
" <script src=\"/bck2brwsr.js\"></script>\n" +
jaroslav@545
   107
" <script type=\"text/javascript\">\n" +
jaroslav@545
   108
"   function ldCls(res) {\n" +
jaroslav@545
   109
"     var request = new XMLHttpRequest();\n" +
jaroslav@545
   110
"     request.open('GET', '/classes/' + res, false);\n" +
jaroslav@545
   111
"     request.send();\n" +
jaroslav@545
   112
"     var arr = eval('(' + request.responseText + ')');\n" +
jaroslav@545
   113
"     return arr;\n" +
jaroslav@545
   114
"   }\n" +
jaroslav@711
   115
"   var vm = bck2brwsr(ldCls);\n" +
jaroslav@579
   116
"   vm.loadClass('${fqn}');\n" +
jaroslav@545
   117
" </script>\n" +
jaroslav@545
   118
"</body></html>";
jaroslav@545
   119
    var templateJava = 
jaroslav@545
   120
"package bck2brwsr.demo;\n" +
jaroslav@545
   121
"import org.apidesign.bck2brwsr.htmlpage.api.*;\n" +
jaroslav@545
   122
"import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;\n" +
jaroslav@545
   123
"\n" +
jaroslav@545
   124
"@Page(xhtml=\"index.html\", className=\"Index\", properties={\n" +
jaroslav@545
   125
"  @Property(name=\"value\", type=int.class)\n" +
jaroslav@545
   126
"})\n" +
jaroslav@545
   127
"class YourFirstHTML5PageInRealLanguage {\n" +
jaroslav@545
   128
"  static { new Index().applyBindings(); }\n" +
jaroslav@545
   129
"  @On(event=CLICK, id=\"dupl\") static void duplicateValue(Index m) {\n" +
jaroslav@545
   130
"    m.setValue(m.getValue() * 2);\n" +
jaroslav@545
   131
"  }\n" +
jaroslav@545
   132
"  @On(event=CLICK, id=\"clear\") static void zeroTheValue(Index m) {\n" +
jaroslav@545
   133
"     m.setValue(0);;\n" +
jaroslav@545
   134
"  }\n" +
jaroslav@545
   135
"  @ComputedProperty static int powerValue(int value) {\n" +
jaroslav@545
   136
"    return value * value;\n" +
jaroslav@545
   137
"  }\n" +
jaroslav@545
   138
"}";
jaroslav@466
   139
phrebejk@460
   140
    
phrebejk@542
   141
    $scope.makeMarker = function( editor, line ) {
phrebejk@542
   142
        var marker = document.createElement("div");
phrebejk@542
   143
        marker.innerHTML = " ";
phrebejk@542
   144
        marker.className = "issue";
phrebejk@542
   145
        
phrebejk@542
   146
        var info = editor.lineInfo(line);
phrebejk@542
   147
        editor.setGutterMarker(line, "issues", info.markers ? null : marker);
phrebejk@542
   148
        
phrebejk@542
   149
        return marker;
phrebejk@542
   150
    };
phrebejk@542
   151
    
phrebejk@542
   152
    
phrebejk@542
   153
    // Returns a function, that, as long as it continues to be invoked, will not
phrebejk@542
   154
    // be triggered. The function will be called after it stops being called for
phrebejk@542
   155
    // N milliseconds. If `immediate` is passed, trigger the function on the
phrebejk@542
   156
    // leading edge, instead of the trailing.
phrebejk@542
   157
    $scope.debounce = function(func, wait, immediate) {
phrebejk@542
   158
      var timeout, result;
phrebejk@542
   159
      return function() {
phrebejk@542
   160
        var context = this, args = arguments;
phrebejk@542
   161
        var later = function() {
phrebejk@542
   162
          timeout = null;
phrebejk@542
   163
          if (!immediate) result = func.apply(context, args);
phrebejk@542
   164
        };
phrebejk@542
   165
        var callNow = immediate && !timeout;
phrebejk@542
   166
        clearTimeout(timeout);
phrebejk@542
   167
        timeout = setTimeout(later, wait);
phrebejk@542
   168
        if (callNow) result = func.apply(context, args);
phrebejk@542
   169
        return result;
phrebejk@542
   170
      };
phrebejk@542
   171
    };
phrebejk@542
   172
    
phrebejk@541
   173
    $scope.reload = function() {
phrebejk@541
   174
        $scope.errors = null;
phrebejk@461
   175
        var frame = document.getElementById("result");        
phrebejk@461
   176
        frame.src = "result.html";
phrebejk@461
   177
        frame.contentDocument.location.reload(true);
phrebejk@461
   178
        frame.contentWindow.location.reload();
phrebejk@542
   179
        document.getElementById("editorJava").codeMirror.clearGutter("issues");   
phrebejk@461
   180
    };
phrebejk@461
   181
    
phrebejk@541
   182
    $scope.fail = function( data ) {
phrebejk@541
   183
        $scope.errors = eval( data );
phrebejk@542
   184
        var editor = document.getElementById("editorJava").codeMirror;   
phrebejk@542
   185
        editor.clearGutter( "issues" );
phrebejk@542
   186
        
phrebejk@542
   187
        for( var i = 0; i < $scope.errors.length; i ++ ) {
phrebejk@542
   188
            $scope.makeMarker( editor, $scope.errors[i].line - 1 );
phrebejk@542
   189
        }
phrebejk@542
   190
        
phrebejk@541
   191
    };
phrebejk@541
   192
    
phrebejk@542
   193
    $scope.post = function() {
phrebejk@461
   194
        return $http({url: ".",
phrebejk@461
   195
            method: "POST",
phrebejk@461
   196
            //headers: this.headers,
phrebejk@461
   197
            data: { html : $scope.html, java : $scope.java} 
phrebejk@541
   198
        }).success( $scope.reload ).error( $scope.fail );
phrebejk@541
   199
    };
phrebejk@541
   200
    
phrebejk@541
   201
    $scope.errorClass = function( kind ) {
phrebejk@541
   202
        switch( kind ) {
phrebejk@541
   203
            case "ERROR" :
phrebejk@541
   204
                return "error";
phrebejk@541
   205
            default :         
phrebejk@541
   206
                return "warning";   
phrebejk@541
   207
        }
phrebejk@541
   208
    };
phrebejk@541
   209
    
phrebejk@541
   210
    $scope.gotoError = function( line, col ) {
phrebejk@541
   211
        var editor = document.getElementById("editorJava").codeMirror;   
phrebejk@542
   212
        editor.setCursor({ line: line - 1, ch : col - 1 });
phrebejk@541
   213
        editor.focus();
phrebejk@460
   214
    };
phrebejk@460
   215
    
phrebejk@460
   216
    $scope.tab = "html";
jaroslav@466
   217
    $scope.html= templateHtml;  
jaroslav@466
   218
    $scope.java = templateJava;  
phrebejk@460
   219
    
phrebejk@542
   220
    $scope.$watch( "html", $scope.debounce( $scope.post, 2000 ) );
phrebejk@542
   221
    $scope.$watch( "java", $scope.debounce( $scope.post, 2000 ) );
jaroslav@466
   222
    $scope.post();
phrebejk@460
   223
    
phrebejk@460
   224
}