couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject [14/14] git commit: updated refs/heads/master to 44c5d66
Date Mon, 04 Nov 2013 13:46:55 GMT
Fauxton: Replace CodeMirror with Ace Editor
Fixes #COUCHDB-1911


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/44c5d665
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/44c5d665
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/44c5d665

Branch: refs/heads/master
Commit: 44c5d6657e26330449a3b3b86b36aa05034cf45b
Parents: a36b3c6
Author: Garren Smith <garren.smith@gmail.com>
Authored: Tue Oct 29 17:27:51 2013 +0200
Committer: Garren Smith <garren.smith@gmail.com>
Committed: Mon Nov 4 15:44:00 2013 +0200

----------------------------------------------------------------------
 LICENSE                                         |    79 +-
 NOTICE                                          |    12 +-
 build-aux/compile                               |     1 +
 license.skip                                    |     1 +
 src/fauxton/app/config.js                       |    14 +-
 src/fauxton/app/modules/documents/views.js      |   236 +-
 src/fauxton/app/modules/fauxton/components.js   |    79 +-
 src/fauxton/app/templates/documents/doc.html    |     2 +-
 .../app/templates/documents/view_editor.html    |     8 +-
 src/fauxton/assets/css/codemirror.css           |   176 -
 src/fauxton/assets/js/libs/ace/ace.js           | 16541 +++++++++++++++++
 src/fauxton/assets/js/libs/ace/ext-chromevox.js |   537 +
 .../js/libs/ace/ext-elastic_tabstops_lite.js    |   301 +
 src/fauxton/assets/js/libs/ace/ext-emmet.js     |  1096 ++
 .../assets/js/libs/ace/ext-keybinding_menu.js   |   207 +
 .../assets/js/libs/ace/ext-language_tools.js    |  1615 ++
 src/fauxton/assets/js/libs/ace/ext-modelist.js  |   166 +
 src/fauxton/assets/js/libs/ace/ext-old_ie.js    |   499 +
 src/fauxton/assets/js/libs/ace/ext-options.js   |   252 +
 src/fauxton/assets/js/libs/ace/ext-searchbox.js |   420 +
 .../assets/js/libs/ace/ext-settings_menu.js     |   634 +
 .../assets/js/libs/ace/ext-spellcheck.js        |    68 +
 src/fauxton/assets/js/libs/ace/ext-split.js     |   271 +
 .../assets/js/libs/ace/ext-static_highlight.js  |   165 +
 src/fauxton/assets/js/libs/ace/ext-statusbar.js |    47 +
 src/fauxton/assets/js/libs/ace/ext-textarea.js  |   478 +
 src/fauxton/assets/js/libs/ace/ext-themelist.js |    90 +
 .../assets/js/libs/ace/ext-whitespace.js        |   206 +
 .../assets/js/libs/ace/mode-javascript.js       |   886 +
 src/fauxton/assets/js/libs/ace/mode-json.js     |   578 +
 src/fauxton/assets/js/libs/ace/mode-jsoniq.js   |  2714 +++
 .../assets/js/libs/ace/snippets/javascript.js   |   202 +
 src/fauxton/assets/js/libs/ace/snippets/json.js |     7 +
 .../assets/js/libs/ace/snippets/jsoniq.js       |     7 +
 .../assets/js/libs/ace/theme-crimson_editor.js  |   148 +
 .../assets/js/libs/ace/worker-javascript.js     | 10088 ++++++++++
 src/fauxton/assets/js/libs/ace/worker-json.js   |  2271 +++
 src/fauxton/assets/js/libs/codemirror.js        |  3193 ----
 .../assets/js/plugins/codemirror-javascript.js  |   361 -
 src/fauxton/assets/less/fauxton.less            |    17 +
 src/fauxton/tasks/couchserver.js                |     4 +-
 41 files changed, 40688 insertions(+), 3989 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index d4984bd..1a74c74 100644
--- a/LICENSE
+++ b/LICENSE
@@ -838,58 +838,6 @@ For src/fauxton/assets/js/plugins/prettify.js
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
 
-For src/fauxton/assets/js/libs/codemirror.js
-
-	Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com>
-
-	Permission is hereby granted, free of charge, to any person obtaining a copy
-	of this software and associated documentation files (the "Software"), to deal
-	in the Software without restriction, including without limitation the rights
-	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-	copies of the Software, and to permit persons to whom the Software is
-	furnished to do so, subject to the following conditions:
-
-	The above copyright notice and this permission notice shall be included in
-	all copies or substantial portions of the Software.
-
-	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-	THE SOFTWARE.
-
-	Please note that some subdirectories of the CodeMirror distribution
-	include their own LICENSE files, and are released under different
-	licences.
-
-For src/fauxton/assets/js/plugins/codemirror-javascript.js
-
-	Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com>
-
-	Permission is hereby granted, free of charge, to any person obtaining a copy
-	of this software and associated documentation files (the "Software"), to deal
-	in the Software without restriction, including without limitation the rights
-	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-	copies of the Software, and to permit persons to whom the Software is
-	furnished to do so, subject to the following conditions:
-
-	The above copyright notice and this permission notice shall be included in
-	all copies or substantial portions of the Software.
-
-	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-	THE SOFTWARE.
-
-	Please note that some subdirectories of the CodeMirror distribution
-	include their own LICENSE files, and are released under different
-	licences.
-
 For the src/couch_dbupdates component
 
   2009-2012 (c) Benoît Chesneau <benoitc@e-engura.org>
@@ -1126,3 +1074,30 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+for src/fauxton/assets/js/lib/ace/*
+
+Copyright (c) 2010, Ajax.org B.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Ajax.org B.V. nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 5c95dd2..62611d7 100644
--- a/NOTICE
+++ b/NOTICE
@@ -130,14 +130,6 @@ This product also includes the following third-party components:
 
    Copyright (c) 2010-2011, The Dojo Foundation
 
- * codemirror.js (https://github.com/marijnh/CodeMirror)
-
-   Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com>
-
- * codemirror-javascript.js (https://github.com/marijnh/CodeMirror)
-
-   Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com>
-
  * jquery.form.js (https://github.com/malsup/form/)
 
    Copyright 2006-2013 (c) M. Alsup
@@ -193,3 +185,7 @@ This product also includes the following third-party components:
  * sandbox.js https://github.com/KlausTrainer/sandbox.js
 
    (c) 2013 Klaus Trainer
+
+ * ace editor https://github.com/ajaxorg/ace
+
+   Copyright (c) 2010, Ajax.org B.V.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/build-aux/compile
----------------------------------------------------------------------
diff --git a/build-aux/compile b/build-aux/compile
new file mode 120000
index 0000000..e0ab062
--- /dev/null
+++ b/build-aux/compile
@@ -0,0 +1 @@
+/usr/local/Cellar/automake/1.14/share/automake-1.14/compile
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/license.skip
----------------------------------------------------------------------
diff --git a/license.skip b/license.skip
index a20ab00..beb94e6 100644
--- a/license.skip
+++ b/license.skip
@@ -143,6 +143,7 @@
 ^src/fauxton/test/mocha/sinon.js
 ^src/fauxton/test/mocha/sinon-chai.js
 ^src/fauxton/tasks/addon/rename.json
+^src/fauxton/assets/lib/ace/.*
 ^src/ibrowse/.*
 ^src/mochiweb/.*
 ^src/my-first-couchdb-plugin/priv/*/*

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index 4edeba0..45e279d 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -27,18 +27,19 @@ require.config({
     backbone: "../assets/js/libs/backbone",
     "backbone.layoutmanger": "../assets/js/plugins/backbone.layoutmanager",
     bootstrap: "../assets/js/libs/bootstrap",
-    codemirror: "../assets/js/libs/codemirror",
     jshint: "../assets/js/libs/jshint",
     spin: "../assets/js/libs/spin.min",
     d3: "../assets/js/libs/d3",
-    "nv.d3": "../assets/js/libs/nv.d3"
+    "nv.d3": "../assets/js/libs/nv.d3",
+    "ace":"../assets/js/libs/ace"
   },
 
   baseUrl: '/',
 
   map: {
     "*": {
-      'underscore': 'lodash'
+      'underscore': 'lodash',
+      //'./lib/dom':'ace/lib/dom'
     }
 
   },
@@ -55,18 +56,11 @@ require.config({
       exports: "Bootstrap"
     },
 
-    codemirror: {
-      deps: ["jquery"],
-      exports: "CodeMirror"
-    },
-
     jshint: {
       deps: ["jquery"],
       exports: "JSHINT"
     },
 
-    "plugins/codemirror-javascript": ["codemirror"],
-
     "plugins/prettify": [],
 
     "plugins/jquery.form": ["jquery"]

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index f822544..5c22504 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -20,17 +20,14 @@ define([
        "modules/pouchdb/base",
 
        // Libs
-       "codemirror",
-       "jshint",
        "resizeColumns",
 
        // Plugins
-       "plugins/codemirror-javascript",
        "plugins/prettify"
 
 ],
 
-function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, resizeColumns)
{
+function(app, FauxtonAPI, Components, Documents, pouchdb, resizeColumns) {
   var Views = {};
 
   Views.Tabs = FauxtonAPI.View.extend({
@@ -708,6 +705,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
     disableLoader: true,
     initialize: function (options) {
       this.database = options.database;
+      _.bindAll(this);
     },
     goback: function(){
       window.history.back();
@@ -849,6 +847,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
       }
 
       json = JSON.parse(this.editor.getValue());
+
       this.model.set(json, {validate: true});
       if (this.model.validationError) {
         return false;
@@ -858,32 +857,8 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
     },
 
     hasValidCode: function() {
-      return JSHINT(this.editor.getValue()) !== false;
-    },
-
-    runJSHint: function() {
-      var json = this.editor.getValue();
-      var output = JSHint(json);
-
-      // Clear existing markers
-      for (var i = 0, l = this.editor.lineCount(); i < l; i++) {
-        this.editor.clearMarker(i);
-      }
-
-      if (output === false) {
-        _.map(JSHint.errors, function(error) {
-          var line = error.line - 1;
-          var className = "view-code-error-line-" + line;
-          this.editor.setMarker(line, "●", "view-code-error "+className);
-
-          setTimeout(function() {
-            $(".CodeMirror ."+className).tooltip({
-              title: "ERROR: " + error.reason,
-              container: 'body'
-            });
-          }, 0);
-        }, this);
-      }
+      var errors = this.editor.getAnnotations();
+      return errors.length === 0;
     },
 
     serialize: function() {
@@ -909,30 +884,21 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
     },
 
     afterRender: function() {
-      this.model.on("sync", this.updateValues, this);
-      var that = this;
-      if ($('.CodeMirror').length > 0){
-        $('.CodeMirror').remove();
-      }
-      this.editor = Codemirror.fromTextArea(this.$el.find("textarea.doc-code").get()[0],
{
-        mode: "application/json",
-        json: false,
-        lineNumbers: true,
-        matchBrackets: true,
-        lineWrapping: true,
-        onChange: function() {
-          try {
-            that.runJSHint();
-          } catch (e) {
-            console.log('ERROR for jshint',e);
-          }
-        },
-        extraKeys: {
-          "Ctrl-S": function(instance) { that.saveDoc(); },
-          "Ctrl-/": "undo"
-        }
+      var saveDoc = this.saveDoc;
+
+      this.editor = new Components.Editor({
+        editorId: "editor-container",
+        commands: [{
+          name: 'save',
+          bindKey: {win: 'Ctrl-S',  mac: 'Ctrl-S'},
+          exec: function(editor) {
+            saveDoc();
+          },
+          readOnly: true // false if this command should not apply in readOnly mode
+        }]
       });
-      setTimeout(function(){that.editor.setSize(null,$('#dashboard').outerHeight()-295);},200);
+      this.editor.render();
+      this.model.on("sync", this.updateValues, this);
     }
   });
 
@@ -1244,6 +1210,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
       var $ele = $("#reduce-function-selector");
       var $reduceContainer = $(".control-group.reduce-function");
       if ($ele.val() == "CUSTOM") {
+        this.createReduceEditor();
         $reduceContainer.show();
       } else {
         $reduceContainer.hide();
@@ -1334,42 +1301,6 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
       }
     },
 
-    updateView: function(event, paramInfo) {
-      event.preventDefault();
-
-      if (this.newView) { return alert('Please save this new view before querying it.');
}
-
-      var errorParams = paramInfo.errorParams,
-          params = paramInfo.params;
-
-      if (_.any(errorParams)) {
-        _.map(errorParams, function(param) {
-
-          // TODO: Where to add this error?
-          // bootstrap wants the error on a control-group div, but we're not using that
-          //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error');
-          return FauxtonAPI.addNotification({
-            msg: "JSON Parse Error on field: "+param.name,
-            type: "error",
-            selector: ".advanced-options .errors-container"
-          });
-        });
-        FauxtonAPI.addNotification({
-          msg: "Make sure that strings are properly quoted and any other values are valid
JSON structures",
-          type: "warning",
-          selector: ".advanced-options .errors-container"
-        });
-
-        return false;
-      }
-
-      var fragment = window.location.hash.replace(/\?.*$/, '');
-      fragment = fragment + '?' + $.param(params);
-      FauxtonAPI.navigate(fragment, {trigger: false});
-
-      FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
-    },
-
     previewView: function(event, paramsInfo) {
       var that = this,
       mapVal = this.mapEditor.getValue(),
@@ -1433,46 +1364,13 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
     hasValidCode: function() {
       return _.every(["mapEditor", "reduceEditor"], function(editorName) {
         var editor = this[editorName];
-        if (editorName == "reduceEditor" && ! this.isCustomReduceEnabled()) {
-          return true;
-        } else if (JSHINT(editor.getValue()) !== false) {
+        if (editorName === "reduceEditor" && ! this.isCustomReduceEnabled()) {
           return true;
-        } else {
-          // By default CouchDB view functions don't pass lint
-          return _.every(JSHINT.errors, function(error) {
-            return FauxtonAPI.isIgnorableError(error.raw);
-          });
-        }
+        } 
+        return editor.hadValidCode();
       }, this);
     },
 
-    runJSHint: function(editorName) {
-      var editor = this[editorName];
-      var json = editor.getValue();
-      var output = JSHint(json);
-
-      // Clear existing markers
-      for (var i = 0, l = editor.lineCount(); i < l; i++) {
-        editor.clearMarker(i);
-      }
-
-      if (output === false) {
-        _.map(JSHint.errors, function(error) {
-          // By default CouchDB view functions don't pass lint
-          if (FauxtonAPI.isIgnorableError(error.reason)) return true;
-
-          var line = error.line - 1;
-          var className = "view-code-error-line-" + line;
-          editor.setMarker(line, "●", "view-code-error "+className);
-
-          setTimeout(function() {
-            $(".CodeMirror ."+className).tooltip({
-              title: "ERROR: " + error.reason
-            });
-          }, 0);
-        }, this);
-      }
-    },
     toggleIndexNav: function (event) {
       var $index = this.$('#index'),
           $targetId = this.$(event.target).attr('id');
@@ -1480,6 +1378,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
       if ($targetId === 'index-nav') {
         if (this.newView) { return; }
         $index.toggle('slow');
+        this.showEditors();
       } else {
         $index.removeAttr('style');
       }
@@ -1503,6 +1402,19 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
       return this.reduceFunStr && ! _.contains(this.builtinReduces, this.reduceFunStr);
     },
 
+    createReduceEditor: function () {
+      if (this.reduceEditor) {
+        this.reduceEditor.remove();
+      }
+
+      this.reduceEditor = new Components.Editor({
+        editorId: "reduce-function",
+        mode: "javascript",
+        couchJSHINT: true
+      });
+      this.reduceEditor.render();
+    },
+
     beforeRender: function () {
 
       if (this.newView) {
@@ -1535,71 +1447,37 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror,
JSHint, re
     },
 
     afterRender: function() {
-      var that = this, 
-          mapFun = this.$("#map-function"),
-          reduceFun = this.$("#reduce-function");
+      if (this.params) {
+        this.advancedOptions.updateFromParams(this.params);
+      }
 
+      this.designDocSelector.updateDesignDoc();
       if (this.newView) {
-        mapFun.val(this.langTemplates[this.defaultLang].map);
-        reduceFun.val(this.langTemplates[this.defaultLang].reduce);
+        this.showEditors();
       } else {
-        setTimeout(function(){this.$('#index').hide();}, 300);
+        this.$('#index').hide();
         this.$('#index-nav').parent().removeClass('active');
       }
+    },
 
-      this.designDocSelector.updateDesignDoc();
-      // This is a hack around a bug in backbone.layoutmanager with grunt dev
-      // When in grunt dev mode we load templates asynchronously
-      // and this can cause a double render which then gives us two 
-      // mapeditors
-      if (this.mapViewSet) { return;}
-      this.mapViewSet = true;
-
-      this.mapEditor = Codemirror.fromTextArea(mapFun.get()[0], {
+    showEditors: function () {
+      this.mapEditor = new Components.Editor({
+        editorId: "map-function",
         mode: "javascript",
-        lineNumbers: true,
-        matchBrackets: true,
-        lineWrapping: true,
-        onChange: function() {
-          try {
-            that.runJSHint("mapEditor");
-          } catch (e) {
-            console.log('ERROR for jshint',e);
-          }
-        },
-        extraKeys: {
-          "Ctrl-S": function(instance) { that.saveView(); },
-          "Ctrl-/": "undo"
-        }
+        couchJSHINT: true
       });
-      this.reduceEditor = Codemirror.fromTextArea(reduceFun.get()[0], {
-        mode: "javascript",
-        lineNumbers: true,
-        matchBrackets: true,
-        lineWrapping: true,
-        onChange: function() {
-          try {
-            that.runJSHint("reduceEditor");
-          } catch (e) {
-            console.log('ERROR for jshint',e);
-          }
-        },
-        extraKeys: {
-          "Ctrl-S": function(instance) { that.saveView(); },
-          "Ctrl-/": "undo"
-        }
-      });
-      // HACK: this should be in the html
-      // but CodeMirror's head explodes and it won't set the hight properly.
-      // So render it first, set the editor, then hide.
-      if ( ! this.hasCustomReduce()) {
-        $(".control-group.reduce-function").hide();
-      }
+      this.mapEditor.render();
 
-      if (this.params) {
-        this.advancedOptions.updateFromParams(this.params);
+      if (this.hasCustomReduce()) {
+        this.createReduceEditor();
+      } else {
+        $(".control-group.reduce-function").hide();
       }
 
+      if (this.newView) {
+        this.mapEditor.setValue(this.langTemplates[this.defaultLang].map);
+        this.reduceEditor.setValue(this.langTemplates[this.defaultLang].reduce);
+      } 
     }
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/src/fauxton/app/modules/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/components.js b/src/fauxton/app/modules/fauxton/components.js
index 30a57d8..c79439e 100644
--- a/src/fauxton/app/modules/fauxton/components.js
+++ b/src/fauxton/app/modules/fauxton/components.js
@@ -11,12 +11,13 @@
 // the License.
 
 define([
-       "app",
-       // Libs
-       "api"
+  "app",
+  // Libs
+  "api",
+  "ace/ace"
 ],
 
-function(app, FauxtonAPI) {
+function(app, FauxtonAPI, ace) {
   var Components = app.module();
 
   Components.Pagination = FauxtonAPI.View.extend({
@@ -175,6 +176,76 @@ function(app, FauxtonAPI) {
     }
   });
 
+  Components.Editor = FauxtonAPI.View.extend({
+    initialize: function (options) {
+      this.editorId = options.editorId;
+      this.mode = options.mode || "json";
+      this.commands = options.commands;
+      this.theme = options.theme || 'crimson_editor';
+      this.couchJSHINT = options.couchJSHINT;
+    },
+
+    afterRender: function () {
+      this.editor = ace.edit(this.editorId);
+      this.editor.setTheme("ace/theme/" + this.theme);
+      this.editor.getSession().setMode("ace/mode/" + this.mode);
+      this.editor.setShowPrintMargin(false);
+      this.editor.gotoLine(2);
+      this.addCommands();
+
+      if (this.couchJSHINT) {
+        this.removeIncorrectAnnotations();
+      }
+    },
+
+    addCommands: function () {
+      _.each(this.commands, function (command) {
+        this.editor.commands.addCommand(command);
+      }, this);
+    },
+
+    removeIncorrectAnnotations: function () {
+      var editor = this.editor;
+
+      this.editor.getSession().on("changeAnnotation", function(){
+        var annotations = editor.getSession().getAnnotations();
+
+        var newAnnotations = _.reduce(annotations, function (annotations, error) {
+          if (!FauxtonAPI.isIgnorableError(error.raw)) {
+            annotations.push(error);
+          }
+          return annotations;
+        }, []);
+
+        if (annotations.length !== newAnnotations.length) {
+          editor.getSession().setAnnotations(newAnnotations);
+        }
+      });
+    },
+
+    setValue: function (data, lineNumber) {
+      lineNumber = lineNumber ? lineNumber : -1;
+      this.editor.setValue(data, lineNumber);
+    },
+
+    getValue: function () {
+      return this.editor.getValue();
+    },
+
+    getAnnotations: function () {
+      return this.editor.getSession().getAnnotations();
+    },
+
+    hadValidCode: function () {
+     var errors = this.getAnnotations();
+     // By default CouchDB view functions don't pass lint
+     return _.every(errors, function(error) {
+      return FauxtonAPI.isIgnorableError(error.raw);
+      },this);
+    }
+
+  });
+
   return Components;
 });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/src/fauxton/app/templates/documents/doc.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/doc.html b/src/fauxton/app/templates/documents/doc.html
index 8c8fc7b..f83a1a9 100644
--- a/src/fauxton/app/templates/documents/doc.html
+++ b/src/fauxton/app/templates/documents/doc.html
@@ -41,7 +41,7 @@ the License.
 <div id="duplicate-modal"> </div> 
 </div>
 
-  <textarea class="doc-code"><%- JSON.stringify(doc.attributes, null, "  ") %></textarea>
+  <div id="editor-container" class="doc-code"><%- JSON.stringify(doc.attributes,
null, "  ") %></div>
   <br />
   <p>
        <button class="save-doc button green btn-success btn-large save fonticon-circle-check"
type="button">Save</button>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/src/fauxton/app/templates/documents/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/view_editor.html b/src/fauxton/app/templates/documents/view_editor.html
index 76265e0..8fcd07a 100644
--- a/src/fauxton/app/templates/documents/view_editor.html
+++ b/src/fauxton/app/templates/documents/view_editor.html
@@ -36,9 +36,9 @@ the License.
           <div class="control-group">
             <label for="map-function">Map function <a href="<%=getDocUrl('map_functions')%>"
target="_blank"><i class="icon-question-sign"></i></a></label>
             <% if (newView) { %>
-            <textarea class="js-editor" id="map-function"><%= langTemplates.map
%></textarea>
+            <div class="js-editor" id="map-function"><%= langTemplates.map %></div>
             <% } else { %>
-            <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewName].map
%></textarea>
+            <div class="js-editor" id="map-function"><%= ddoc.get('views')[viewName].map
%></div>
             <% } %>
           </div>
 
@@ -60,9 +60,9 @@ the License.
           <div class="control-group reduce-function">
             <label for="reduce-function">Custom Reduce</label>
             <% if (newView) { %>
-            <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce
%></textarea>
+            <div class="js-editor" id="reduce-function"><%= langTemplates.reduce
%></div>
             <% } else { %>
-            <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewName].reduce
%></textarea>
+            <div class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewName].reduce
%></div>
             <% } %>
           </div>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/44c5d665/src/fauxton/assets/css/codemirror.css
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/css/codemirror.css b/src/fauxton/assets/css/codemirror.css
deleted file mode 100644
index 3fcbc44..0000000
--- a/src/fauxton/assets/css/codemirror.css
+++ /dev/null
@@ -1,176 +0,0 @@
-.CodeMirror {
-  line-height: 1em;
-  font-family: monospace;
-
-  /* Necessary so the scrollbar can be absolutely positioned within the wrapper on Lion.
*/
-  position: relative;
-  /* This prevents unwanted scrollbars from showing up on the body and wrapper in IE. */
-  overflow: hidden;
-}
-
-.CodeMirror-scroll {
-  overflow: auto;
-  height: 300px;
-  /* This is needed to prevent an IE[67] bug where the scrolled content
-     is visible outside of the scrolling box. */
-  position: relative;
-  outline: none;
-}
-
-/* Vertical scrollbar */
-.CodeMirror-scrollbar {
-  position: absolute;
-  right: 0; top: 0;
-  overflow-x: hidden;
-  overflow-y: scroll;
-  z-index: 5;
-}
-.CodeMirror-scrollbar-inner {
-  /* This needs to have a nonzero width in order for the scrollbar to appear
-     in Firefox and IE9. */
-  width: 1px;
-}
-.CodeMirror-scrollbar.cm-sb-overlap {
-  /* Ensure that the scrollbar appears in Lion, and that it overlaps the content
-     rather than sitting to the right of it. */
-  position: absolute;
-  z-index: 1;
-  float: none;
-  right: 0;
-  min-width: 12px;
-}
-.CodeMirror-scrollbar.cm-sb-nonoverlap {
-  min-width: 12px;
-}
-.CodeMirror-scrollbar.cm-sb-ie7 {
-  min-width: 18px;
-}
-
-.CodeMirror-gutter {
-  position: absolute; left: 0; top: 0;
-  z-index: 10;
-  background-color: #f7f7f7;
-  border-right: 1px solid #eee;
-  min-width: 2em;
-  height: 100%;
-}
-.CodeMirror-gutter-text {
-  color: #aaa;
-  text-align: right;
-  padding: .4em .2em .4em .4em;
-  white-space: pre !important;
-  cursor: default;
-}
-.CodeMirror-lines {
-  padding: .4em;
-  white-space: pre;
-  cursor: text;
-}
-
-.CodeMirror pre {
-  -moz-border-radius: 0;
-  -webkit-border-radius: 0;
-  -o-border-radius: 0;
-  border-radius: 0;
-  border-width: 0; margin: 0; padding: 0; background: transparent;
-  font-family: inherit;
-  font-size: inherit;
-  padding: 0; margin: 0;
-  white-space: pre;
-  word-wrap: normal;
-  line-height: inherit;
-  color: inherit;
-  overflow: visible;
-}
-
-.CodeMirror-wrap pre {
-  word-wrap: break-word;
-  white-space: pre-wrap;
-  word-break: normal;
-}
-.CodeMirror-wrap .CodeMirror-scroll {
-  overflow-x: hidden;
-}
-
-.CodeMirror textarea {
-  outline: none !important;
-}
-
-.CodeMirror pre.CodeMirror-cursor {
-  z-index: 10;
-  position: absolute;
-  visibility: hidden;
-  border-left: 1px solid black;
-  border-right: none;
-  width: 0;
-}
-.cm-keymap-fat-cursor pre.CodeMirror-cursor {
-  width: auto;
-  border: 0;
-  background: transparent;
-  background: rgba(0, 200, 0, .4);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
-}
-/* Kludge to turn off filter in ie9+, which also accepts rgba */
-.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
-.CodeMirror-focused pre.CodeMirror-cursor {
-  visibility: visible;
-}
-
-div.CodeMirror-selected { background: #d9d9d9; }
-.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
-
-.CodeMirror-searching {
-  background: #ffa;
-  background: rgba(255, 255, 0, .4);
-}
-
-/* Default theme */
-
-.cm-s-default span.cm-keyword {color: #708;}
-.cm-s-default span.cm-atom {color: #219;}
-.cm-s-default span.cm-number {color: #164;}
-.cm-s-default span.cm-def {color: #00f;}
-.cm-s-default span.cm-variable {color: black;}
-.cm-s-default span.cm-variable-2 {color: #05a;}
-.cm-s-default span.cm-variable-3 {color: #085;}
-.cm-s-default span.cm-property {color: black;}
-.cm-s-default span.cm-operator {color: black;}
-.cm-s-default span.cm-comment {color: #a50;}
-.cm-s-default span.cm-string {color: #a11;}
-.cm-s-default span.cm-string-2 {color: #f50;}
-.cm-s-default span.cm-meta {color: #555;}
-.cm-s-default span.cm-error {color: #f00;}
-.cm-s-default span.cm-qualifier {color: #555;}
-.cm-s-default span.cm-builtin {color: #30a;}
-.cm-s-default span.cm-bracket {color: #997;}
-.cm-s-default span.cm-tag {color: #170;}
-.cm-s-default span.cm-attribute {color: #00c;}
-.cm-s-default span.cm-header {color: blue;}
-.cm-s-default span.cm-quote {color: #090;}
-.cm-s-default span.cm-hr {color: #999;}
-.cm-s-default span.cm-link {color: #00c;}
-span.cm-negative {color: #d44;}
-span.cm-positive {color: #292;}
-
-span.cm-header, span.cm-strong {font-weight: bold;}
-span.cm-em {font-style: italic;}
-span.cm-emstrong {font-style: italic; font-weight: bold;}
-span.cm-link {text-decoration: underline;}
-
-span.cm-invalidchar {color: #f00;}
-
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
-
-@media print {
-
-  /* Hide the cursor when printing */
-  .CodeMirror pre.CodeMirror-cursor {
-    visibility: hidden;
-  }
-}
-


Mime
View raw message