launcher/src/main/resources/org/apidesign/bck2brwsr/dew/js/app.js
author phrebejk
Tue, 22 Jan 2013 19:48:10 +0100
branchdew
changeset 542 7400dc9f48fb
parent 541 927a5f9fa430
permissions -rw-r--r--
Error badges + auto reload.
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@466
    75
    var templateHtml = "<html><body>\n"
jaroslav@466
    76
        + " <button id='btn'>Hello!</button>\n"
jaroslav@466
    77
        + " <hr/>\n"
jaroslav@466
    78
        + "\n"
jaroslav@466
    79
        + "\n"
jaroslav@466
    80
        + "\n"
jaroslav@466
    81
        + "\n"
jaroslav@466
    82
        + "\n"
jaroslav@466
    83
        + "\n"
jaroslav@466
    84
        + "\n"
jaroslav@466
    85
        + "\n"
jaroslav@466
    86
        + "\n"
jaroslav@466
    87
        + "\n"
jaroslav@466
    88
        + "\n"
jaroslav@466
    89
        + "\n"
jaroslav@466
    90
        + "\n"
jaroslav@466
    91
        + "\n"
jaroslav@466
    92
        + "\n"
jaroslav@466
    93
        + "\n"
jaroslav@466
    94
        + "\n"
jaroslav@466
    95
        + "\n"
jaroslav@466
    96
        + "\n"
jaroslav@466
    97
        + "\n"
jaroslav@466
    98
        + " <script src=\"/bck2brwsr.js\"></script>\n"
jaroslav@466
    99
        + " <script type=\"text/javascript\">\n"
jaroslav@466
   100
        + "   function ldCls(res) {\n"
jaroslav@466
   101
        + "     var request = new XMLHttpRequest();\n"
jaroslav@470
   102
        + "     request.open('GET', '/classes/' + res, false);\n"
jaroslav@466
   103
        + "     request.send();\n"
jaroslav@466
   104
        + "     var arr = eval('(' + request.responseText + ')');\n"
jaroslav@466
   105
        + "     return arr;\n"
jaroslav@466
   106
        + "   }\n"
jaroslav@466
   107
        + "   var vm = new bck2brwsr(ldCls);\n"
jaroslav@466
   108
        + "   vm.loadClass('bck2brwsr.demo.Index');\n"
jaroslav@466
   109
        + " </script>\n"
jaroslav@466
   110
        + "</body></html>\n";
jaroslav@466
   111
    var templateJava = "package bck2brwsr.demo;\n"
jaroslav@466
   112
        + "import org.apidesign.bck2brwsr.htmlpage.api.*;\n"
jaroslav@469
   113
        + "import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;\n"
jaroslav@466
   114
        + "@Page(xhtml=\"index.html\", className=\"Index\")\n"
jaroslav@466
   115
        + "class YourFirstHTML5PageInRealLanguage {\n"
jaroslav@469
   116
        + "   @On(event=CLICK, id=\"btn\") static void clcs() {\n"
jaroslav@469
   117
        + "     Element.alert(\"Hello World!\");\n"
jaroslav@470
   118
        + "     Index.BTN.setDisabled(true);\n"
jaroslav@466
   119
        + "   }\n"
jaroslav@466
   120
        + "}\n";
jaroslav@466
   121
phrebejk@460
   122
    
phrebejk@542
   123
    $scope.makeMarker = function( editor, line ) {
phrebejk@542
   124
        var marker = document.createElement("div");
phrebejk@542
   125
        marker.innerHTML = " ";
phrebejk@542
   126
        marker.className = "issue";
phrebejk@542
   127
        
phrebejk@542
   128
        var info = editor.lineInfo(line);
phrebejk@542
   129
        editor.setGutterMarker(line, "issues", info.markers ? null : marker);
phrebejk@542
   130
        
phrebejk@542
   131
        return marker;
phrebejk@542
   132
    };
phrebejk@542
   133
    
phrebejk@542
   134
    
phrebejk@542
   135
    // Returns a function, that, as long as it continues to be invoked, will not
phrebejk@542
   136
    // be triggered. The function will be called after it stops being called for
phrebejk@542
   137
    // N milliseconds. If `immediate` is passed, trigger the function on the
phrebejk@542
   138
    // leading edge, instead of the trailing.
phrebejk@542
   139
    $scope.debounce = function(func, wait, immediate) {
phrebejk@542
   140
      var timeout, result;
phrebejk@542
   141
      return function() {
phrebejk@542
   142
        var context = this, args = arguments;
phrebejk@542
   143
        var later = function() {
phrebejk@542
   144
          timeout = null;
phrebejk@542
   145
          if (!immediate) result = func.apply(context, args);
phrebejk@542
   146
        };
phrebejk@542
   147
        var callNow = immediate && !timeout;
phrebejk@542
   148
        clearTimeout(timeout);
phrebejk@542
   149
        timeout = setTimeout(later, wait);
phrebejk@542
   150
        if (callNow) result = func.apply(context, args);
phrebejk@542
   151
        return result;
phrebejk@542
   152
      };
phrebejk@542
   153
    };
phrebejk@542
   154
    
phrebejk@541
   155
    $scope.reload = function() {
phrebejk@541
   156
        $scope.errors = null;
phrebejk@461
   157
        var frame = document.getElementById("result");        
phrebejk@461
   158
        frame.src = "result.html";
phrebejk@461
   159
        frame.contentDocument.location.reload(true);
phrebejk@461
   160
        frame.contentWindow.location.reload();
phrebejk@542
   161
        document.getElementById("editorJava").codeMirror.clearGutter("issues");   
phrebejk@461
   162
    };
phrebejk@461
   163
    
phrebejk@541
   164
    $scope.fail = function( data ) {
phrebejk@541
   165
        $scope.errors = eval( data );
phrebejk@542
   166
        var editor = document.getElementById("editorJava").codeMirror;   
phrebejk@542
   167
        editor.clearGutter( "issues" );
phrebejk@542
   168
        
phrebejk@542
   169
        for( var i = 0; i < $scope.errors.length; i ++ ) {
phrebejk@542
   170
            $scope.makeMarker( editor, $scope.errors[i].line - 1 );
phrebejk@542
   171
        }
phrebejk@542
   172
        
phrebejk@541
   173
    };
phrebejk@541
   174
    
phrebejk@542
   175
    $scope.post = function() {
phrebejk@461
   176
        return $http({url: ".",
phrebejk@461
   177
            method: "POST",
phrebejk@461
   178
            //headers: this.headers,
phrebejk@461
   179
            data: { html : $scope.html, java : $scope.java} 
phrebejk@541
   180
        }).success( $scope.reload ).error( $scope.fail );
phrebejk@541
   181
    };
phrebejk@541
   182
    
phrebejk@541
   183
    $scope.errorClass = function( kind ) {
phrebejk@541
   184
        switch( kind ) {
phrebejk@541
   185
            case "ERROR" :
phrebejk@541
   186
                return "error";
phrebejk@541
   187
            default :         
phrebejk@541
   188
                return "warning";   
phrebejk@541
   189
        }
phrebejk@541
   190
    };
phrebejk@541
   191
    
phrebejk@541
   192
    $scope.gotoError = function( line, col ) {
phrebejk@541
   193
        var editor = document.getElementById("editorJava").codeMirror;   
phrebejk@542
   194
        editor.setCursor({ line: line - 1, ch : col - 1 });
phrebejk@541
   195
        editor.focus();
phrebejk@460
   196
    };
phrebejk@460
   197
    
phrebejk@460
   198
    $scope.tab = "html";
jaroslav@466
   199
    $scope.html= templateHtml;  
jaroslav@466
   200
    $scope.java = templateJava;  
phrebejk@460
   201
    
phrebejk@542
   202
    $scope.$watch( "html", $scope.debounce( $scope.post, 2000 ) );
phrebejk@542
   203
    $scope.$watch( "java", $scope.debounce( $scope.post, 2000 ) );
jaroslav@466
   204
    $scope.post();
phrebejk@460
   205
    
phrebejk@460
   206
}