dew/src/main/resources/org/apidesign/bck2brwsr/dew/js/app.js
branchdew
changeset 544 08ffdc3938e7
parent 542 7400dc9f48fb
child 545 29b8e1b87fad
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dew/src/main/resources/org/apidesign/bck2brwsr/dew/js/app.js	Wed Jan 23 13:18:46 2013 +0100
     1.3 @@ -0,0 +1,206 @@
     1.4 +// 'use strict';
     1.5 +
     1.6 +// Declare app level module which depends on filters, and services
     1.7 +angular.module('bck2brwsr', []).
     1.8 +  directive('uiCodemirror', ['$timeout', function($timeout) {
     1.9 +        'use strict';
    1.10 +
    1.11 +        var events = ["cursorActivity", "viewportChange", "gutterClick", "focus", "blur", "scroll", "update"];
    1.12 +        return {
    1.13 +            restrict: 'A',
    1.14 +            require: 'ngModel',
    1.15 +            link: function(scope, elm, attrs, ngModel) {
    1.16 +                var options, opts, onChange, deferCodeMirror, codeMirror, timeoutId, val;
    1.17 +
    1.18 +                if (elm[0].type !== 'textarea') {
    1.19 +                    throw new Error('uiCodemirror3 can only be applied to a textarea element');
    1.20 +                }
    1.21 +
    1.22 +                options = /* uiConfig.codemirror  || */ {};
    1.23 +                opts = angular.extend({}, options, scope.$eval(attrs.uiCodemirror));
    1.24 +
    1.25 +                onChange = function(instance, changeObj) {                    
    1.26 +                    val = instance.getValue();
    1.27 +                    $timeout.cancel(timeoutId);
    1.28 +                    timeoutId = $timeout(function() {
    1.29 +                        ngModel.$setViewValue(val);                        
    1.30 +                      }, 500);                    
    1.31 +                };
    1.32 +                
    1.33 +                deferCodeMirror = function() {
    1.34 +                    codeMirror = CodeMirror.fromTextArea(elm[0], opts);
    1.35 +                    elm[0].codeMirror = codeMirror;
    1.36 +                    // codeMirror.on("change", onChange(opts.onChange));
    1.37 +                    codeMirror.on("change", onChange);
    1.38 +
    1.39 +                    for (var i = 0, n = events.length, aEvent; i < n; ++i) {
    1.40 +                        aEvent = opts["on" + events[i].charAt(0).toUpperCase() + events[i].slice(1)];
    1.41 +                        if (aEvent === void 0)
    1.42 +                            continue;
    1.43 +                        if (typeof aEvent !== "function")
    1.44 +                            continue;
    1.45 +                                                
    1.46 +                        var bound = _.bind( aEvent, scope );
    1.47 +                        
    1.48 +                        codeMirror.on(events[i], bound);
    1.49 +                    }
    1.50 +
    1.51 +                    // CodeMirror expects a string, so make sure it gets one.
    1.52 +                    // This does not change the model.
    1.53 +                    ngModel.$formatters.push(function(value) {
    1.54 +                        if (angular.isUndefined(value) || value === null) {
    1.55 +                            return '';
    1.56 +                        }
    1.57 +                        else if (angular.isObject(value) || angular.isArray(value)) {
    1.58 +                            throw new Error('ui-codemirror cannot use an object or an array as a model');
    1.59 +                        }
    1.60 +                        return value;
    1.61 +                    });
    1.62 +
    1.63 +                    // Override the ngModelController $render method, which is what gets called when the model is updated.
    1.64 +                    // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
    1.65 +                    ngModel.$render = function() {
    1.66 +                        codeMirror.setValue(ngModel.$viewValue);
    1.67 +                    };
    1.68 +
    1.69 +                };
    1.70 +
    1.71 +                $timeout(deferCodeMirror);
    1.72 +
    1.73 +            }
    1.74 +        };
    1.75 +}]);
    1.76 +
    1.77 +function DevCtrl( $scope, $http ) {
    1.78 +    var templateHtml = "<html><body>\n"
    1.79 +        + " <button id='btn'>Hello!</button>\n"
    1.80 +        + " <hr/>\n"
    1.81 +        + "\n"
    1.82 +        + "\n"
    1.83 +        + "\n"
    1.84 +        + "\n"
    1.85 +        + "\n"
    1.86 +        + "\n"
    1.87 +        + "\n"
    1.88 +        + "\n"
    1.89 +        + "\n"
    1.90 +        + "\n"
    1.91 +        + "\n"
    1.92 +        + "\n"
    1.93 +        + "\n"
    1.94 +        + "\n"
    1.95 +        + "\n"
    1.96 +        + "\n"
    1.97 +        + "\n"
    1.98 +        + "\n"
    1.99 +        + "\n"
   1.100 +        + "\n"
   1.101 +        + " <script src=\"/bck2brwsr.js\"></script>\n"
   1.102 +        + " <script type=\"text/javascript\">\n"
   1.103 +        + "   function ldCls(res) {\n"
   1.104 +        + "     var request = new XMLHttpRequest();\n"
   1.105 +        + "     request.open('GET', '/classes/' + res, false);\n"
   1.106 +        + "     request.send();\n"
   1.107 +        + "     var arr = eval('(' + request.responseText + ')');\n"
   1.108 +        + "     return arr;\n"
   1.109 +        + "   }\n"
   1.110 +        + "   var vm = new bck2brwsr(ldCls);\n"
   1.111 +        + "   vm.loadClass('bck2brwsr.demo.Index');\n"
   1.112 +        + " </script>\n"
   1.113 +        + "</body></html>\n";
   1.114 +    var templateJava = "package bck2brwsr.demo;\n"
   1.115 +        + "import org.apidesign.bck2brwsr.htmlpage.api.*;\n"
   1.116 +        + "import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;\n"
   1.117 +        + "@Page(xhtml=\"index.html\", className=\"Index\")\n"
   1.118 +        + "class YourFirstHTML5PageInRealLanguage {\n"
   1.119 +        + "   @On(event=CLICK, id=\"btn\") static void clcs() {\n"
   1.120 +        + "     Element.alert(\"Hello World!\");\n"
   1.121 +        + "     Index.BTN.setDisabled(true);\n"
   1.122 +        + "   }\n"
   1.123 +        + "}\n";
   1.124 +
   1.125 +    
   1.126 +    $scope.makeMarker = function( editor, line ) {
   1.127 +        var marker = document.createElement("div");
   1.128 +        marker.innerHTML = " ";
   1.129 +        marker.className = "issue";
   1.130 +        
   1.131 +        var info = editor.lineInfo(line);
   1.132 +        editor.setGutterMarker(line, "issues", info.markers ? null : marker);
   1.133 +        
   1.134 +        return marker;
   1.135 +    };
   1.136 +    
   1.137 +    
   1.138 +    // Returns a function, that, as long as it continues to be invoked, will not
   1.139 +    // be triggered. The function will be called after it stops being called for
   1.140 +    // N milliseconds. If `immediate` is passed, trigger the function on the
   1.141 +    // leading edge, instead of the trailing.
   1.142 +    $scope.debounce = function(func, wait, immediate) {
   1.143 +      var timeout, result;
   1.144 +      return function() {
   1.145 +        var context = this, args = arguments;
   1.146 +        var later = function() {
   1.147 +          timeout = null;
   1.148 +          if (!immediate) result = func.apply(context, args);
   1.149 +        };
   1.150 +        var callNow = immediate && !timeout;
   1.151 +        clearTimeout(timeout);
   1.152 +        timeout = setTimeout(later, wait);
   1.153 +        if (callNow) result = func.apply(context, args);
   1.154 +        return result;
   1.155 +      };
   1.156 +    };
   1.157 +    
   1.158 +    $scope.reload = function() {
   1.159 +        $scope.errors = null;
   1.160 +        var frame = document.getElementById("result");        
   1.161 +        frame.src = "result.html";
   1.162 +        frame.contentDocument.location.reload(true);
   1.163 +        frame.contentWindow.location.reload();
   1.164 +        document.getElementById("editorJava").codeMirror.clearGutter("issues");   
   1.165 +    };
   1.166 +    
   1.167 +    $scope.fail = function( data ) {
   1.168 +        $scope.errors = eval( data );
   1.169 +        var editor = document.getElementById("editorJava").codeMirror;   
   1.170 +        editor.clearGutter( "issues" );
   1.171 +        
   1.172 +        for( var i = 0; i < $scope.errors.length; i ++ ) {
   1.173 +            $scope.makeMarker( editor, $scope.errors[i].line - 1 );
   1.174 +        }
   1.175 +        
   1.176 +    };
   1.177 +    
   1.178 +    $scope.post = function() {
   1.179 +        return $http({url: ".",
   1.180 +            method: "POST",
   1.181 +            //headers: this.headers,
   1.182 +            data: { html : $scope.html, java : $scope.java} 
   1.183 +        }).success( $scope.reload ).error( $scope.fail );
   1.184 +    };
   1.185 +    
   1.186 +    $scope.errorClass = function( kind ) {
   1.187 +        switch( kind ) {
   1.188 +            case "ERROR" :
   1.189 +                return "error";
   1.190 +            default :         
   1.191 +                return "warning";   
   1.192 +        }
   1.193 +    };
   1.194 +    
   1.195 +    $scope.gotoError = function( line, col ) {
   1.196 +        var editor = document.getElementById("editorJava").codeMirror;   
   1.197 +        editor.setCursor({ line: line - 1, ch : col - 1 });
   1.198 +        editor.focus();
   1.199 +    };
   1.200 +    
   1.201 +    $scope.tab = "html";
   1.202 +    $scope.html= templateHtml;  
   1.203 +    $scope.java = templateJava;  
   1.204 +    
   1.205 +    $scope.$watch( "html", $scope.debounce( $scope.post, 2000 ) );
   1.206 +    $scope.$watch( "java", $scope.debounce( $scope.post, 2000 ) );
   1.207 +    $scope.post();
   1.208 +    
   1.209 +}