Support syntax highlighting

Also maps the API preferences to proper codemirror properties... See
https://github.com/GerritCodeReview/gerrit/blob/6c1a52b8698d1ad392c590e7b515f2b5668e73f4/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java#L555

Change-Id: Icc222cde89eff7a0992fbcaaf8e7bac560347c18
diff --git a/gr-editor/gr-editor.html b/gr-editor/gr-editor.html
index 739fa5b..68b6d3f 100644
--- a/gr-editor/gr-editor.html
+++ b/gr-editor/gr-editor.html
@@ -14,7 +14,7 @@
 limitations under the License.
 -->
 
-<link rel="import" href="./gr-editor-styles.html">
+<link rel="import" href="gr-editor-styles.html">
 
 <dom-module id="gr-editor">
   <template>
@@ -30,21 +30,21 @@
     <div id="wrapper"></div>
   </template>
   <script src="../bower_components/codemirror-minified/lib/codemirror.js"></script>
-  <script src="../bower_components/codemirror-minified/mode/python/python.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/ruby/ruby.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/php/php.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/sql/sql.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/meta.js"></script>
   <script src="../bower_components/codemirror-minified/mode/clike/clike.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/xml/xml.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/javascript/javascript.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/css/css.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/htmlmixed/htmlmixed.js" ></script>
-  <script src="../bower_components/codemirror-minified/mode/markdown/markdown.js" ></script>
   <script src="../bower_components/codemirror-minified/mode/clojure/clojure.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/css/css.js" ></script>
   <script src="../bower_components/codemirror-minified/mode/dart/dart.js" ></script>
   <script src="../bower_components/codemirror-minified/mode/haskell/haskell.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/htmlmixed/htmlmixed.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/javascript/javascript.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/markdown/markdown.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/php/php.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/python/python.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/ruby/ruby.js" ></script>
   <script src="../bower_components/codemirror-minified/mode/sass/sass.js" ></script>
   <script src="../bower_components/codemirror-minified/mode/shell/shell.js" ></script>
+  <script src="../bower_components/codemirror-minified/mode/sql/sql.js" ></script>
   <script src="../bower_components/codemirror-minified/mode/xml/xml.js" ></script>
   <script src="../bower_components/codemirror-minified/mode/yaml/yaml.js" ></script>
   <script src="../bower_components/codemirror-minified/addon/fold/foldcode.js" ></script>
@@ -52,5 +52,5 @@
   <script src="../bower_components/codemirror-minified/addon/fold/brace-fold.js" ></script>
   <script src="../bower_components/codemirror-minified/addon/fold/xml-fold.js" ></script>
   <script src="../bower_components/codemirror-minified/addon/fold/markdown-fold.js" ></script>
-  <script src="./gr-editor.js"></script>
+  <script src="gr-editor.js"></script>
 </dom-module>
diff --git a/gr-editor/gr-editor.js b/gr-editor/gr-editor.js
index cf76865..58826c5 100644
--- a/gr-editor/gr-editor.js
+++ b/gr-editor/gr-editor.js
@@ -14,6 +14,12 @@
 (function() {
   'use strict';
 
+  // we need to be on codemirror 5.33.0+ to get the support for
+  // text/x-php in CodeMirror.findModeByMIME
+  const LANGUAGE_MAP = {
+    'text/x-php': 'php',
+  };
+
   Polymer({
     is: 'gr-editor',
     /**
@@ -24,15 +30,16 @@
 
     properties: {
       fileContent: String,
+      fileType: String,
       mirror: Object,
       prefs: Object,
     },
 
     attached() {
       this.scopeSubtree(this.$.wrapper, true);
-      this.mirror = CodeMirror(this.$.wrapper, Object.assign({} , {
-        value: this.fileContent,
-      }, this.prefs));
+      const params =
+          this.getCodeMirrorParams(this.fileType, this.fileContent, this.prefs);
+      this.mirror = CodeMirror(this.$.wrapper, params);
       this.async(() => { this.mirror.refresh(); }, 1);
       this.addEventListeners();
     },
@@ -43,5 +50,46 @@
             {detail: {value: e.getValue()}, bubbles: true}));
       });
     },
+
+    getCodeMirrorParams(type, value, prefs) {
+      const params = {value};
+
+      if (prefs) {
+        // TODO: Add gerrit's customizations from java codemirror to javascript
+        // gerrit-gwtui/src/main/java/net/codemirror/lib/Extras.java
+        params.autoCloseBrackets = prefs.auto_close_brackets;
+        params.cursorBlinkRate = prefs.cursor_blink_rate;
+        params.cursorHeight = 0.85;
+        params.hideTopMenu = prefs.hide_top_menu;
+        params.indentUnit = prefs.indent_unit;
+        params.indentWithTabs = prefs.indent_with_tabs;
+        params.keyMap = prefs.key_map_type.toLowerCase();
+        params.lineLength = prefs.line_length;
+        params.lineNumbers = prefs.hide_line_numbers;
+        params.lineWrapping = prefs.line_wrapping;
+        params.indentWithTabs = prefs.indent_with_tabs;
+        params.matchBrackets = prefs.match_brackets;
+        // TODO: Add support for a new commit msg MIME type
+        // Support for this is somewhere in gerrit's codebase
+        // needs backporting to javascript
+        params.mode = prefs.syntax_highlighting ? this._mapFileType(type) : '';
+        params.origLeft = value;
+        params.showTabs = prefs.show_tabs;
+        params.showTrailingSpace = prefs.show_whitespace_errors;
+        params.styleSelectedText = true;
+        params.tabSize = prefs.tab_size;
+        params.theme = prefs.theme.toLowerCase();
+
+        if (value && value.includes('\r\n')) {
+          params.lineSeparator = '\r\n';
+        }
+      }
+
+      return params;
+    },
+
+    _mapFileType(type) {
+      return LANGUAGE_MAP[type] || type || '';
+    },
   });
-})();
\ No newline at end of file
+})();