Web Inspector: Update CodeMirror for gutter fix
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Sep 2013 23:27:59 +0000 (23:27 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Sep 2013 23:27:59 +0000 (23:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=121262

Update CodeMirror to 757944449 to fix gutter click issue:
<https://github.com/marijnh/CodeMirror/issues/1807>

Patch by Joseph Pecoraro <pecoraro@apple.com> on 2013-09-12
Reviewed by Timothy Hatcher.

* Tools/PrettyPrinting/CodeMirrorFormatters.js:
* Tools/PrettyPrinting/FormatterContentBuilder.js:
(FormatterContentBuilder.prototype._appendIndent):
* Tools/PrettyPrinting/codemirror.css:
* Tools/PrettyPrinting/codemirror.js:
* Tools/PrettyPrinting/css.js:
* UserInterface/CodeMirrorAdditions.js:
* UserInterface/CodeMirrorFormatters.js:
* UserInterface/DebuggerManager.js:
(WebInspector.DebuggerManager.prototype.didRemoveBreakpoint):
(WebInspector.DebuggerManager.prototype._removeBreakpoint):
* UserInterface/External/CodeMirror/codemirror.css:
* UserInterface/External/CodeMirror/codemirror.js:
* UserInterface/External/CodeMirror/coffeescript.js:
* UserInterface/External/CodeMirror/css.js:
* UserInterface/External/CodeMirror/less.js:
* UserInterface/External/CodeMirror/sql.js:
* UserInterface/TextEditor.js:
(WebInspector.TextEditor.prototype.hasFormatter):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@155659 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Tools/PrettyPrinting/CodeMirrorFormatters.js
Source/WebInspectorUI/Tools/PrettyPrinting/FormatterContentBuilder.js
Source/WebInspectorUI/Tools/PrettyPrinting/codemirror.css
Source/WebInspectorUI/Tools/PrettyPrinting/codemirror.js
Source/WebInspectorUI/Tools/PrettyPrinting/css.js
Source/WebInspectorUI/UserInterface/CodeMirrorAdditions.js
Source/WebInspectorUI/UserInterface/CodeMirrorFormatters.js
Source/WebInspectorUI/UserInterface/DebuggerManager.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/codemirror.css
Source/WebInspectorUI/UserInterface/External/CodeMirror/codemirror.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/coffeescript.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/css.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/less.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/sql.js
Source/WebInspectorUI/UserInterface/TextEditor.js

index d6852ba..cd62a82 100644 (file)
@@ -1,5 +1,35 @@
 2013-09-12  Joseph Pecoraro  <pecoraro@apple.com>
 
+        Web Inspector: Update CodeMirror for gutter fix
+        https://bugs.webkit.org/show_bug.cgi?id=121262
+
+        Update CodeMirror to 757944449 to fix gutter click issue:
+        <https://github.com/marijnh/CodeMirror/issues/1807>
+
+        Reviewed by Timothy Hatcher.
+
+        * Tools/PrettyPrinting/CodeMirrorFormatters.js:
+        * Tools/PrettyPrinting/FormatterContentBuilder.js:
+        (FormatterContentBuilder.prototype._appendIndent):
+        * Tools/PrettyPrinting/codemirror.css:
+        * Tools/PrettyPrinting/codemirror.js:
+        * Tools/PrettyPrinting/css.js:
+        * UserInterface/CodeMirrorAdditions.js:
+        * UserInterface/CodeMirrorFormatters.js:
+        * UserInterface/DebuggerManager.js:
+        (WebInspector.DebuggerManager.prototype.didRemoveBreakpoint):
+        (WebInspector.DebuggerManager.prototype._removeBreakpoint):
+        * UserInterface/External/CodeMirror/codemirror.css:
+        * UserInterface/External/CodeMirror/codemirror.js:
+        * UserInterface/External/CodeMirror/coffeescript.js:
+        * UserInterface/External/CodeMirror/css.js:
+        * UserInterface/External/CodeMirror/less.js:
+        * UserInterface/External/CodeMirror/sql.js:
+        * UserInterface/TextEditor.js:
+        (WebInspector.TextEditor.prototype.hasFormatter):
+
+2013-09-12  Joseph Pecoraro  <pecoraro@apple.com>
+
         Web Inspector: Update License copyrights in minified JavaScript
         https://bugs.webkit.org/show_bug.cgi?id=121264
 
index 81c8155..3d99cb6 100644 (file)
@@ -290,7 +290,7 @@ CodeMirror.extendMode("javascript", {
     }
 });
 
-CodeMirror.extendMode("css-base", {
+CodeMirror.extendMode("css", {
     shouldHaveSpaceBeforeToken: function(lastToken, lastContent, token, state, content, isComment)
     {
         if (!token) {
index 4596880..72d9a15 100644 (file)
@@ -202,7 +202,7 @@ FormatterContentBuilder.prototype = {
         var indent = this._indent;
         do {
             if (indent >= maxCacheIndent)
-                this._append(this._indentCache[maxCacheIndent])
+                this._append(this._indentCache[maxCacheIndent]);
             else
                 this._append(this._indentCache[indent]);
             indent -= maxCacheIndent;
index c95db64..4e300b2 100644 (file)
@@ -118,6 +118,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
   height: 100%;
   outline: none; /* Prevent dragging from highlighting the element */
   position: relative;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
 }
 .CodeMirror-sizer {
   position: relative;
@@ -156,6 +158,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
 .CodeMirror-gutter {
   white-space: normal;
   height: 100%;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
   padding-bottom: 30px;
   margin-bottom: -32px;
   display: inline-block;
@@ -215,8 +219,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
   overflow: auto;
 }
 
-.CodeMirror-widget {
-}
+.CodeMirror-widget {}
 
 .CodeMirror-wrap .CodeMirror-scroll {
   overflow-x: hidden;
@@ -224,7 +227,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
 
 .CodeMirror-measure {
   position: absolute;
-  width: 100%; height: 0px;
+  width: 100%;
+  height: 0;
   overflow: hidden;
   visibility: hidden;
 }
index bc238a2..81771e9 100644 (file)
@@ -304,15 +304,13 @@ window.CodeMirror = (function() {
   // Make sure the gutters options contains the element
   // "CodeMirror-linenumbers" when the lineNumbers option is true.
   function setGuttersForLineNumbers(options) {
-    var found = false;
-    for (var i = 0; i < options.gutters.length; ++i) {
-      if (options.gutters[i] == "CodeMirror-linenumbers") {
-        if (options.lineNumbers) found = true;
-        else options.gutters.splice(i--, 1);
-      }
+    var found = indexOf(options.gutters, "CodeMirror-linenumbers");
+    if (found == -1 && options.lineNumbers) {
+      options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
+    } else if (found > -1 && !options.lineNumbers) {
+      options.gutters = options.gutters.slice(0);
+      options.gutters.splice(i, 1);
     }
-    if (!found && options.lineNumbers)
-      options.gutters.push("CodeMirror-linenumbers");
   }
 
   // SCROLLBARS
@@ -412,11 +410,17 @@ window.CodeMirror = (function() {
     var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
     var visible = visibleLines(cm.display, cm.doc, viewPort);
     for (;;) {
+      var oldWidth = cm.display.scroller.clientWidth;
       if (!updateDisplayInner(cm, changes, visible, forced)) break;
-      forced = false;
       updated = true;
+      changes = [];
       updateSelection(cm);
       updateScrollbars(cm);
+      if (cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
+        forced = true;
+        continue;
+      }
+      forced = false;
 
       // Clip forced viewport to actual scrollable area
       if (viewPort)
@@ -425,7 +429,6 @@ window.CodeMirror = (function() {
       visible = visibleLines(cm.display, cm.doc, viewPort);
       if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
         break;
-      changes = [];
     }
 
     if (updated) {
@@ -663,10 +666,11 @@ window.CodeMirror = (function() {
   }
 
   function buildLineElement(cm, line, lineNo, dims, reuse) {
-    var lineElement = lineContent(cm, line);
+    var built = buildLineContent(cm, line), lineElement = built.pre;
     var markers = line.gutterMarkers, display = cm.display, wrap;
 
-    if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
+    var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass;
+    if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets)
       return lineElement;
 
     // Lines with gutter elements, widgets or a background class need
@@ -704,8 +708,8 @@ window.CodeMirror = (function() {
       wrap.appendChild(lineElement);
     }
     // Kludge to make sure the styled element lies behind the selection (by z-index)
-    if (line.bgClass)
-      wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
+    if (bgClass)
+      wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild);
     if (cm.options.lineNumbers || markers) {
       var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
                                              (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
@@ -972,6 +976,10 @@ window.CodeMirror = (function() {
   function measureChar(cm, line, ch, data, bias) {
     var dir = -1;
     data = data || measureLine(cm, line);
+    if (data.crude) {
+      var left = data.left + ch * data.width;
+      return {left: left, right: left + data.width, top: data.top, bottom: data.bottom};
+    }
 
     for (var pos = ch;; pos += dir) {
       var r = data[pos];
@@ -1020,8 +1028,11 @@ window.CodeMirror = (function() {
   }
 
   function measureLineInner(cm, line) {
+    if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom)
+      return crudelyMeasureLine(cm, line);
+
     var display = cm.display, measure = emptyArray(line.text.length);
-    var pre = lineContent(cm, line, measure, true);
+    var pre = buildLineContent(cm, line, measure, true).pre;
 
     // IE does not cache element positions of inline elements between
     // calls to getBoundingClientRect. This makes the loop below,
@@ -1106,6 +1117,15 @@ window.CodeMirror = (function() {
     return data;
   }
 
+  function crudelyMeasureLine(cm, line) {
+    var copy = new Line(line.text.slice(0, 100), null);
+    if (line.textClass) copy.textClass = line.textClass;
+    var measure = measureLineInner(cm, copy);
+    var left = measureChar(cm, copy, 0, measure, "left");
+    var right = measureChar(cm, copy, 99, measure, "right");
+    return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100};
+  }
+
   function measureLineWidth(cm, line) {
     var hasBadSpan = false;
     if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
@@ -1113,9 +1133,10 @@ window.CodeMirror = (function() {
       if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
     }
     var cached = !hasBadSpan && findCachedMeasurement(cm, line);
-    if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
+    if (cached || line.text.length >= cm.options.crudeMeasuringFrom)
+      return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right;
 
-    var pre = lineContent(cm, line, null, true);
+    var pre = buildLineContent(cm, line, null, true).pre;
     var end = pre.appendChild(zeroWidthElement(cm.display.measure));
     removeChildrenAndAdd(cm.display.measure, pre);
     return getRect(end).right - getRect(cm.display.lineDiv).left;
@@ -1892,6 +1913,7 @@ window.CodeMirror = (function() {
     // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
     if (e.dataTransfer.setDragImage && !safari) {
       var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
+      img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
       if (opera) {
         img.width = img.height = 1;
         cm.display.wrapper.appendChild(img);
@@ -2526,6 +2548,7 @@ window.CodeMirror = (function() {
 
     var sel = doc.sel;
     sel.goalColumn = null;
+    if (bias == null) bias = posLess(head, sel.head) ? -1 : 1;
     // Skip over atomic spans.
     if (checkAtomic || !posEq(anchor, sel.anchor))
       anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
@@ -3170,9 +3193,11 @@ window.CodeMirror = (function() {
     operation: function(f){return runInOp(this, f);},
 
     refresh: operation(null, function() {
+      var badHeight = this.display.cachedTextHeight == null;
       clearCaches(this);
       updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
       regChange(this);
+      if (badHeight) estimateLineHeights(this);
     }),
 
     swapDoc: operation(null, function(doc) {
@@ -3273,6 +3298,7 @@ window.CodeMirror = (function() {
   option("historyEventDelay", 500);
   option("viewportMargin", 10, function(cm){cm.refresh();}, true);
   option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
+  option("crudeMeasuringFrom", 10000);
   option("moveInputWithCursor", true, function(cm, val) {
     if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
   });
@@ -4215,8 +4241,7 @@ window.CodeMirror = (function() {
     while (!stream.eol()) {
       if (stream.pos > cm.options.maxHighlightLength) {
         flattenSpans = false;
-        // Webkit seems to refuse to render text nodes longer than 57444 characters
-        stream.pos = Math.min(text.length, stream.start + 50000);
+        stream.pos = text.length;
         style = null;
       } else {
         style = mode.token(stream, state);
@@ -4227,7 +4252,12 @@ window.CodeMirror = (function() {
       }
       stream.start = stream.pos;
     }
-    if (curStart < stream.pos) f(stream.pos, curStyle);
+    while (curStart < stream.pos) {
+      // Webkit seems to refuse to render text nodes longer than 57444 characters
+      var pos = Math.min(stream.pos, curStart + 50000);
+      f(pos, curStyle);
+      curStart = pos;
+    }
   }
 
   function highlightLine(cm, line, state) {
@@ -4285,13 +4315,23 @@ window.CodeMirror = (function() {
   }
 
   var styleToClassCache = {};
-  function styleToClass(style) {
+  function interpretTokenStyle(style, builder) {
     if (!style) return null;
+    for (;;) {
+      var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/);
+      if (!lineClass) break;
+      style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length);
+      var prop = lineClass[1] ? "bgClass" : "textClass";
+      if (builder[prop] == null)
+        builder[prop] = lineClass[2];
+      else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop]))
+        builder[prop] += " " + lineClass[2];
+    }
     return styleToClassCache[style] ||
       (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
   }
 
-  function lineContent(cm, realLine, measure, copyWidgets) {
+  function buildLineContent(cm, realLine, measure, copyWidgets) {
     var merged, line = realLine, empty = true;
     while (merged = collapsedSpanAtStart(line))
       line = getLine(cm.doc, merged.find().from.line);
@@ -4299,7 +4339,6 @@ window.CodeMirror = (function() {
     var builder = {pre: elt("pre"), col: 0, pos: 0,
                    measure: null, measuredSomething: false, cm: cm,
                    copyWidgets: copyWidgets};
-    if (line.textClass) builder.pre.className = line.textClass;
 
     do {
       if (line.text) empty = false;
@@ -4336,8 +4375,11 @@ window.CodeMirror = (function() {
       }
     }
 
+    var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass;
+    if (textClass) builder.pre.className = textClass;
+
     signal(cm, "renderLine", cm, realLine, builder.pre);
-    return builder.pre;
+    return builder;
   }
 
   var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
@@ -4448,7 +4490,7 @@ window.CodeMirror = (function() {
     var spans = line.markedSpans, allText = line.text, at = 0;
     if (!spans) {
       for (var i = 1; i < styles.length; i+=2)
-        builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
+        builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder));
       return;
     }
 
@@ -4498,7 +4540,7 @@ window.CodeMirror = (function() {
           spanStartStyle = "";
         }
         text = allText.slice(at, at = styles[i++]);
-        style = styleToClass(styles[i++]);
+        style = interpretTokenStyle(styles[i++], builder);
       }
     }
   }
@@ -5464,15 +5506,22 @@ window.CodeMirror = (function() {
     };
   else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
     spanAffectsWrapping = function(str, i) {
-      return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
+      var result = /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
+      return result;
+    };
+  else if (webkit && /Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
+    spanAffectsWrapping = function(str, i) {
+      var code = str.charCodeAt(i - 1);
+      return code >= 8208 && code <= 8212;
     };
-  else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
+  else if (webkit)
     spanAffectsWrapping = function(str, i) {
       if (i > 1 && str.charCodeAt(i - 1) == 45) {
         if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
         if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
       }
-      return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
+      var result = /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
+      return result;
     };
 
   var knownScrollbarWidth;
index 2eaa96a..085b119 100644 (file)
@@ -1,10 +1,8 @@
-CodeMirror.defineMode("css", function(config) {
-  return CodeMirror.getMode(config, "text/css");
-});
-
-CodeMirror.defineMode("css-base", function(config, parserConfig) {
+CodeMirror.defineMode("css", function(config, parserConfig) {
   "use strict";
 
+  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
+
   var indentUnit = config.indentUnit,
       hooks = parserConfig.hooks || {},
       atMediaTypes = parserConfig.atMediaTypes || {},
@@ -277,16 +275,14 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
           state.stack[state.stack.length-1] = "@mediaType";
           state.stack.push("@mediaType(");
         }
+        else state.stack.push("(");
       }
       else if (type == ")") {
-        if (context == "propertyValue" && state.stack[state.stack.length-2] == "@mediaType(") {
+        if (context == "propertyValue") {
           // In @mediaType( without closing ; after propertyValue
           state.stack.pop();
-          state.stack.pop();
-        }
-        else if (context == "@mediaType(") {
-          state.stack.pop();
         }
+        state.stack.pop();
       }
       else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
       else if (context == "propertyValue" && type == ";") state.stack.pop();
@@ -582,7 +578,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
         return false;
       }
     },
-    name: "css-base"
+    name: "css"
   });
 
   CodeMirror.defineMIME("text/x-scss", {
@@ -593,6 +589,12 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
     valueKeywords: valueKeywords,
     allowNested: true,
     hooks: {
+      ":": function(stream) {
+        if (stream.match(/\s*{/)) {
+          return [null, "{"];
+        }
+        return false;
+      },
       "$": function(stream) {
         stream.match(/^[\w-]+/);
         if (stream.peek() == ":") {
@@ -620,6 +622,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
         }
       }
     },
-    name: "css-base"
+    name: "css"
   });
 })();
index 473628a..832a37b 100644 (file)
         return state;
     }
 
-    CodeMirror.extendMode("css-base", {token: extendedCSSToken, alternateName: "css"});
+    CodeMirror.extendMode("css", {token: extendedCSSToken});
     CodeMirror.extendMode("xml", {token: extendedXMLToken});
     CodeMirror.extendMode("javascript", {token: extendedToken});
 
     CodeMirror.defineMode("css-rule", CodeMirror.modes.css);
-    CodeMirror.extendMode("css-rule", {startState: extendedCSSRuleStartState});
+    CodeMirror.extendMode("css-rule", {token: extendedCSSToken, startState: extendedCSSRuleStartState, alternateName: "css"});
 
     CodeMirror.defineExtension("hasLineClass", function(line, where, className) {
         // This matches the arguments to addLineClass and removeLineClass.
index 81c8155..3d99cb6 100644 (file)
@@ -290,7 +290,7 @@ CodeMirror.extendMode("javascript", {
     }
 });
 
-CodeMirror.extendMode("css-base", {
+CodeMirror.extendMode("css", {
     shouldHaveSpaceBeforeToken: function(lastToken, lastContent, token, state, content, isComment)
     {
         if (!token) {
index ed132d4..0bdcd54 100644 (file)
@@ -550,7 +550,7 @@ WebInspector.DebuggerManager.prototype = {
         function didRemoveBreakpoint(error)
         {
             if (error)
-                console.log(error);
+                console.error(error);
 
             delete this._breakpointIdMap[breakpoint.id];
 
index c95db64..4e300b2 100644 (file)
@@ -118,6 +118,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
   height: 100%;
   outline: none; /* Prevent dragging from highlighting the element */
   position: relative;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
 }
 .CodeMirror-sizer {
   position: relative;
@@ -156,6 +158,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
 .CodeMirror-gutter {
   white-space: normal;
   height: 100%;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
   padding-bottom: 30px;
   margin-bottom: -32px;
   display: inline-block;
@@ -215,8 +219,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
   overflow: auto;
 }
 
-.CodeMirror-widget {
-}
+.CodeMirror-widget {}
 
 .CodeMirror-wrap .CodeMirror-scroll {
   overflow-x: hidden;
@@ -224,7 +227,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
 
 .CodeMirror-measure {
   position: absolute;
-  width: 100%; height: 0px;
+  width: 100%;
+  height: 0;
   overflow: hidden;
   visibility: hidden;
 }
index 7a5a1e5..81771e9 100644 (file)
@@ -304,15 +304,13 @@ window.CodeMirror = (function() {
   // Make sure the gutters options contains the element
   // "CodeMirror-linenumbers" when the lineNumbers option is true.
   function setGuttersForLineNumbers(options) {
-    var found = false;
-    for (var i = 0; i < options.gutters.length; ++i) {
-      if (options.gutters[i] == "CodeMirror-linenumbers") {
-        if (options.lineNumbers) found = true;
-        else options.gutters.splice(i--, 1);
-      }
+    var found = indexOf(options.gutters, "CodeMirror-linenumbers");
+    if (found == -1 && options.lineNumbers) {
+      options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
+    } else if (found > -1 && !options.lineNumbers) {
+      options.gutters = options.gutters.slice(0);
+      options.gutters.splice(i, 1);
     }
-    if (!found && options.lineNumbers)
-      options.gutters.push("CodeMirror-linenumbers");
   }
 
   // SCROLLBARS
@@ -412,11 +410,17 @@ window.CodeMirror = (function() {
     var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
     var visible = visibleLines(cm.display, cm.doc, viewPort);
     for (;;) {
+      var oldWidth = cm.display.scroller.clientWidth;
       if (!updateDisplayInner(cm, changes, visible, forced)) break;
-      forced = false;
       updated = true;
+      changes = [];
       updateSelection(cm);
       updateScrollbars(cm);
+      if (cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
+        forced = true;
+        continue;
+      }
+      forced = false;
 
       // Clip forced viewport to actual scrollable area
       if (viewPort)
@@ -425,7 +429,6 @@ window.CodeMirror = (function() {
       visible = visibleLines(cm.display, cm.doc, viewPort);
       if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
         break;
-      changes = [];
     }
 
     if (updated) {
@@ -663,10 +666,11 @@ window.CodeMirror = (function() {
   }
 
   function buildLineElement(cm, line, lineNo, dims, reuse) {
-    var lineElement = lineContent(cm, line);
+    var built = buildLineContent(cm, line), lineElement = built.pre;
     var markers = line.gutterMarkers, display = cm.display, wrap;
 
-    if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
+    var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass;
+    if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets)
       return lineElement;
 
     // Lines with gutter elements, widgets or a background class need
@@ -704,8 +708,8 @@ window.CodeMirror = (function() {
       wrap.appendChild(lineElement);
     }
     // Kludge to make sure the styled element lies behind the selection (by z-index)
-    if (line.bgClass)
-      wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
+    if (bgClass)
+      wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild);
     if (cm.options.lineNumbers || markers) {
       var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
                                              (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
@@ -972,6 +976,10 @@ window.CodeMirror = (function() {
   function measureChar(cm, line, ch, data, bias) {
     var dir = -1;
     data = data || measureLine(cm, line);
+    if (data.crude) {
+      var left = data.left + ch * data.width;
+      return {left: left, right: left + data.width, top: data.top, bottom: data.bottom};
+    }
 
     for (var pos = ch;; pos += dir) {
       var r = data[pos];
@@ -1020,8 +1028,11 @@ window.CodeMirror = (function() {
   }
 
   function measureLineInner(cm, line) {
+    if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom)
+      return crudelyMeasureLine(cm, line);
+
     var display = cm.display, measure = emptyArray(line.text.length);
-    var pre = lineContent(cm, line, measure, true);
+    var pre = buildLineContent(cm, line, measure, true).pre;
 
     // IE does not cache element positions of inline elements between
     // calls to getBoundingClientRect. This makes the loop below,
@@ -1106,6 +1117,15 @@ window.CodeMirror = (function() {
     return data;
   }
 
+  function crudelyMeasureLine(cm, line) {
+    var copy = new Line(line.text.slice(0, 100), null);
+    if (line.textClass) copy.textClass = line.textClass;
+    var measure = measureLineInner(cm, copy);
+    var left = measureChar(cm, copy, 0, measure, "left");
+    var right = measureChar(cm, copy, 99, measure, "right");
+    return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100};
+  }
+
   function measureLineWidth(cm, line) {
     var hasBadSpan = false;
     if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
@@ -1113,9 +1133,10 @@ window.CodeMirror = (function() {
       if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
     }
     var cached = !hasBadSpan && findCachedMeasurement(cm, line);
-    if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
+    if (cached || line.text.length >= cm.options.crudeMeasuringFrom)
+      return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right;
 
-    var pre = lineContent(cm, line, null, true);
+    var pre = buildLineContent(cm, line, null, true).pre;
     var end = pre.appendChild(zeroWidthElement(cm.display.measure));
     removeChildrenAndAdd(cm.display.measure, pre);
     return getRect(end).right - getRect(cm.display.lineDiv).left;
@@ -1892,6 +1913,7 @@ window.CodeMirror = (function() {
     // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
     if (e.dataTransfer.setDragImage && !safari) {
       var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
+      img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
       if (opera) {
         img.width = img.height = 1;
         cm.display.wrapper.appendChild(img);
@@ -2526,6 +2548,7 @@ window.CodeMirror = (function() {
 
     var sel = doc.sel;
     sel.goalColumn = null;
+    if (bias == null) bias = posLess(head, sel.head) ? -1 : 1;
     // Skip over atomic spans.
     if (checkAtomic || !posEq(anchor, sel.anchor))
       anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
@@ -3170,9 +3193,11 @@ window.CodeMirror = (function() {
     operation: function(f){return runInOp(this, f);},
 
     refresh: operation(null, function() {
+      var badHeight = this.display.cachedTextHeight == null;
       clearCaches(this);
       updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
       regChange(this);
+      if (badHeight) estimateLineHeights(this);
     }),
 
     swapDoc: operation(null, function(doc) {
@@ -3273,6 +3298,7 @@ window.CodeMirror = (function() {
   option("historyEventDelay", 500);
   option("viewportMargin", 10, function(cm){cm.refresh();}, true);
   option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
+  option("crudeMeasuringFrom", 10000);
   option("moveInputWithCursor", true, function(cm, val) {
     if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
   });
@@ -4215,8 +4241,7 @@ window.CodeMirror = (function() {
     while (!stream.eol()) {
       if (stream.pos > cm.options.maxHighlightLength) {
         flattenSpans = false;
-        // Webkit seems to refuse to render text nodes longer than 57444 characters
-        stream.pos = Math.min(text.length, stream.start + 50000);
+        stream.pos = text.length;
         style = null;
       } else {
         style = mode.token(stream, state);
@@ -4227,7 +4252,12 @@ window.CodeMirror = (function() {
       }
       stream.start = stream.pos;
     }
-    if (curStart < stream.pos) f(stream.pos, curStyle);
+    while (curStart < stream.pos) {
+      // Webkit seems to refuse to render text nodes longer than 57444 characters
+      var pos = Math.min(stream.pos, curStart + 50000);
+      f(pos, curStyle);
+      curStart = pos;
+    }
   }
 
   function highlightLine(cm, line, state) {
@@ -4285,13 +4315,23 @@ window.CodeMirror = (function() {
   }
 
   var styleToClassCache = {};
-  function styleToClass(style) {
+  function interpretTokenStyle(style, builder) {
     if (!style) return null;
+    for (;;) {
+      var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/);
+      if (!lineClass) break;
+      style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length);
+      var prop = lineClass[1] ? "bgClass" : "textClass";
+      if (builder[prop] == null)
+        builder[prop] = lineClass[2];
+      else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop]))
+        builder[prop] += " " + lineClass[2];
+    }
     return styleToClassCache[style] ||
       (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
   }
 
-  function lineContent(cm, realLine, measure, copyWidgets) {
+  function buildLineContent(cm, realLine, measure, copyWidgets) {
     var merged, line = realLine, empty = true;
     while (merged = collapsedSpanAtStart(line))
       line = getLine(cm.doc, merged.find().from.line);
@@ -4299,7 +4339,6 @@ window.CodeMirror = (function() {
     var builder = {pre: elt("pre"), col: 0, pos: 0,
                    measure: null, measuredSomething: false, cm: cm,
                    copyWidgets: copyWidgets};
-    if (line.textClass) builder.pre.className = line.textClass;
 
     do {
       if (line.text) empty = false;
@@ -4336,8 +4375,11 @@ window.CodeMirror = (function() {
       }
     }
 
+    var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass;
+    if (textClass) builder.pre.className = textClass;
+
     signal(cm, "renderLine", cm, realLine, builder.pre);
-    return builder.pre;
+    return builder;
   }
 
   var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
@@ -4448,7 +4490,7 @@ window.CodeMirror = (function() {
     var spans = line.markedSpans, allText = line.text, at = 0;
     if (!spans) {
       for (var i = 1; i < styles.length; i+=2)
-        builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
+        builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder));
       return;
     }
 
@@ -4498,7 +4540,7 @@ window.CodeMirror = (function() {
           spanStartStyle = "";
         }
         text = allText.slice(at, at = styles[i++]);
-        style = styleToClass(styles[i++]);
+        style = interpretTokenStyle(styles[i++], builder);
       }
     }
   }
@@ -5467,7 +5509,12 @@ window.CodeMirror = (function() {
       var result = /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
       return result;
     };
-  else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
+  else if (webkit && /Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
+    spanAffectsWrapping = function(str, i) {
+      var code = str.charCodeAt(i - 1);
+      return code >= 8208 && code <= 8212;
+    };
+  else if (webkit)
     spanAffectsWrapping = function(str, i) {
       if (i > 1 && str.charCodeAt(i - 1) == 45) {
         if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
index 4f54b0c..b7203f1 100644 (file)
@@ -259,7 +259,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
         if (current === '.') {
             style = state.tokenize(stream, state);
             current = stream.current();
-            if (style === 'variable') {
+            if (/^\.[\w$]+$/.test(current)) {
                 return 'variable';
             } else {
                 return ERRORCLASS;
index 2eaa96a..085b119 100644 (file)
@@ -1,10 +1,8 @@
-CodeMirror.defineMode("css", function(config) {
-  return CodeMirror.getMode(config, "text/css");
-});
-
-CodeMirror.defineMode("css-base", function(config, parserConfig) {
+CodeMirror.defineMode("css", function(config, parserConfig) {
   "use strict";
 
+  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
+
   var indentUnit = config.indentUnit,
       hooks = parserConfig.hooks || {},
       atMediaTypes = parserConfig.atMediaTypes || {},
@@ -277,16 +275,14 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
           state.stack[state.stack.length-1] = "@mediaType";
           state.stack.push("@mediaType(");
         }
+        else state.stack.push("(");
       }
       else if (type == ")") {
-        if (context == "propertyValue" && state.stack[state.stack.length-2] == "@mediaType(") {
+        if (context == "propertyValue") {
           // In @mediaType( without closing ; after propertyValue
           state.stack.pop();
-          state.stack.pop();
-        }
-        else if (context == "@mediaType(") {
-          state.stack.pop();
         }
+        state.stack.pop();
       }
       else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
       else if (context == "propertyValue" && type == ";") state.stack.pop();
@@ -582,7 +578,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
         return false;
       }
     },
-    name: "css-base"
+    name: "css"
   });
 
   CodeMirror.defineMIME("text/x-scss", {
@@ -593,6 +589,12 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
     valueKeywords: valueKeywords,
     allowNested: true,
     hooks: {
+      ":": function(stream) {
+        if (stream.match(/\s*{/)) {
+          return [null, "{"];
+        }
+        return false;
+      },
       "$": function(stream) {
         stream.match(/^[\w-]+/);
         if (stream.peek() == ":") {
@@ -620,6 +622,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
         }
       }
     },
-    name: "css-base"
+    name: "css"
   });
 })();
index 09f510e..8384b3c 100644 (file)
@@ -1,7 +1,8 @@
 /*
   LESS mode - http://www.lesscss.org/
   Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
-  Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues  GitHub: @peterkroon
+  Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
+  GitHub: @peterkroon
 */
 
 CodeMirror.defineMode("less", function(config) {
@@ -17,68 +18,60 @@ CodeMirror.defineMode("less", function(config) {
     else if (ch == "/" && stream.eat("*")) {
       state.tokenize = tokenCComment;
       return tokenCComment(stream, state);
-    }
-    else if (ch == "<" && stream.eat("!")) {
+    } else if (ch == "<" && stream.eat("!")) {
       state.tokenize = tokenSGMLComment;
       return tokenSGMLComment(stream, state);
-    }
-    else if (ch == "=") ret(null, "compare");
+    } else if (ch == "=") ret(null, "compare");
     else if (ch == "|" && stream.eat("=")) return ret(null, "compare");
     else if (ch == "\"" || ch == "'") {
       state.tokenize = tokenString(ch);
       return state.tokenize(stream, state);
-    }
-    else if (ch == "/") { // e.g.: .png will not be parsed as a class
+    } else if (ch == "/") { // e.g.: .png will not be parsed as a class
       if(stream.eat("/")){
         state.tokenize = tokenSComment;
         return tokenSComment(stream, state);
-      }else{
-        if(type == "string" || type == "(")return ret("string", "string");
-        if(state.stack[state.stack.length-1] != undefined)return ret(null, ch);
+      } else {
+        if(type == "string" || type == "(") return ret("string", "string");
+        if(state.stack[state.stack.length-1] != undefined) return ret(null, ch);
         stream.eatWhile(/[\a-zA-Z0-9\-_.\s]/);
         if( /\/|\)|#/.test(stream.peek() || (stream.eatSpace() && stream.peek() == ")"))  || stream.eol() )return ret("string", "string"); // let url(/images/logo.png) without quotes return as string
       }
-    }
-    else if (ch == "!") {
+    } else if (ch == "!") {
       stream.match(/^\s*\w*/);
       return ret("keyword", "important");
-    }
-    else if (/\d/.test(ch)) {
+    } else if (/\d/.test(ch)) {
       stream.eatWhile(/[\w.%]/);
       return ret("number", "unit");
-    }
-    else if (/[,+<>*\/]/.test(ch)) {
+    } else if (/[,+<>*\/]/.test(ch)) {
       if(stream.peek() == "=" || type == "a")return ret("string", "string");
+      if(ch === ",")return ret(null, ch);
       return ret(null, "select-op");
-    }
-    else if (/[;{}:\[\]()~\|]/.test(ch)) {
+    } else if (/[;{}:\[\]()~\|]/.test(ch)) {
       if(ch == ":"){
         stream.eatWhile(/[a-z\\\-]/);
         if( selectors.test(stream.current()) ){
           return ret("tag", "tag");
-        }else if(stream.peek() == ":"){//::-webkit-search-decoration
+        } else if(stream.peek() == ":"){//::-webkit-search-decoration
           stream.next();
           stream.eatWhile(/[a-z\\\-]/);
           if(stream.current().match(/\:\:\-(o|ms|moz|webkit)\-/))return ret("string", "string");
           if( selectors.test(stream.current().substring(1)) )return ret("tag", "tag");
           return ret(null, ch);
-        }else{
+        } else {
           return ret(null, ch);
         }
-      }else if(ch == "~"){
+      } else if(ch == "~"){
         if(type == "r")return ret("string", "string");
-      }else{
+      } else {
         return ret(null, ch);
       }
-    }
-    else if (ch == ".") {
+    } else if (ch == ".") {
       if(type == "(" || type == "string")return ret("string", "string"); // allow url(../image.png)
       stream.eatWhile(/[\a-zA-Z0-9\-_]/);
       if(stream.peek() == " ")stream.eatSpace();
       if(stream.peek() == ")")return ret("number", "unit");//rgba(0,0,0,.25);
       return ret("tag", "tag");
-    }
-    else if (ch == "#") {
+    } else if (ch == "#") {
       //we don't eat white-space, we want the hex color and or id only
       stream.eatWhile(/[A-Za-z0-9]/);
       //check if there is a proper hex color length e.g. #eee || #eeeEEE
@@ -93,43 +86,41 @@ CodeMirror.defineMode("less", function(config) {
           //#time { color: #aaa }
           else if(stream.peek() == "}" )return ret("number", "unit");
           //we have a valid hex color value, parse as id whenever an element/class is defined after the hex(id) value e.g. #eee aaa || #eee .aaa
-          else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
+            else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
           //when a hex value is on the end of a line, parse as id
-          else if(stream.eol())return ret("atom", "tag");
+              else if(stream.eol())return ret("atom", "tag");
           //default
-          else return ret("number", "unit");
-        }else{//when not a valid hexvalue in the current stream e.g. #footer
+                else return ret("number", "unit");
+        } else {//when not a valid hexvalue in the current stream e.g. #footer
           stream.eatWhile(/[\w\\\-]/);
           return ret("atom", "tag");
         }
-      }else{//when not a valid hexvalue length
+      } else {//when not a valid hexvalue length
         stream.eatWhile(/[\w\\\-]/);
         return ret("atom", "tag");
       }
-    }
-    else if (ch == "&") {
+    } else if (ch == "&") {
       stream.eatWhile(/[\w\-]/);
       return ret(null, ch);
-    }
-    else {
+    } else {
       stream.eatWhile(/[\w\\\-_%.{]/);
       if(type == "string"){
         return ret("string", "string");
-      }else if(stream.current().match(/(^http$|^https$)/) != null){
+      } else if(stream.current().match(/(^http$|^https$)/) != null){
         stream.eatWhile(/[\w\\\-_%.{:\/]/);
         return ret("string", "string");
-      }else if(stream.peek() == "<" || stream.peek() == ">"){
+      } else if(stream.peek() == "<" || stream.peek() == ">" || stream.peek() == "+"){
         return ret("tag", "tag");
-      }else if( /\(/.test(stream.peek()) ){
+      } else if( /\(/.test(stream.peek()) ){
         return ret(null, ch);
-      }else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png)
+      } else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png)
         return ret("string", "string");
-      }else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign
+      } else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign
         //commment out these 2 comment if you want the minus sign to be parsed as null -500px
         //stream.backUp(stream.current().length-1);
-        //return ret(null, ch); //console.log( stream.current() );
+        //return ret(null, ch);
         return ret("number", "unit");
-      }else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){
+      } else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){
         if(stream.current().substring(stream.current().length-1,stream.current().length) == "{"){
           stream.backUp(1);
           return ret("tag", "tag");
@@ -137,14 +128,15 @@ CodeMirror.defineMode("less", function(config) {
         stream.eatSpace();
         if( /[{<>.a-zA-Z\/]/.test(stream.peek())  || stream.eol() )return ret("tag", "tag"); // e.g. button.icon-plus
         return ret("string", "string"); // let url(/images/logo.png) without quotes return as string
-      }else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){
+      } else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){
         if(stream.current().substring(stream.current().length-1,stream.current().length) == "{")stream.backUp(1);
         return ret("tag", "tag");
-      }else if(type == "compare" || type == "a" || type == "("){
+      } else if(type == "compare" || type == "a" || type == "("){
         return ret("string", "string");
-      }else if(type == "|" || stream.current() == "-" || type == "["){
+      } else if(type == "|" || stream.current() == "-" || type == "["){
+        if(type == "|" )return ret("tag", "tag");
         return ret(null, ch);
-      }else if(stream.peek() == ":") {
+      } else if(stream.peek() == ":") {
         stream.next();
         var t_v = stream.peek() == ":" ? true : false;
         if(!t_v){
@@ -156,11 +148,14 @@ CodeMirror.defineMode("less", function(config) {
             stream.backUp(new_pos-(old_pos-1));
             return ret("tag", "tag");
           } else stream.backUp(new_pos-(old_pos-1));
-        }else{
+        } else {
           stream.backUp(1);
         }
         if(t_v)return ret("tag", "tag"); else return ret("variable", "variable");
-      }else{
+      } else if(state.stack[state.stack.length-1]  === "font-family"){
+        return ret(null, null);
+      } else {
+        if(state.stack[state.stack.length-1] === "{" || type === "select-op"  || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag");
         return ret("variable", "variable");
       }
     }
@@ -238,12 +233,15 @@ CodeMirror.defineMode("less", function(config) {
       }
       else if (type == "}") state.stack.pop();
       else if (type == "@media") state.stack.push("@media");
-      else if (context == "{" && type != "comment") state.stack.push("rule");
+      else if (stream.current() === "font-family") state.stack[state.stack.length-1] = "font-family";
+      else if (context == "{" && type != "comment" && type !== "tag") state.stack.push("rule");
+      else if (stream.peek() === ":" && stream.current().match(/@|#/) === null) style = type;
       return style;
     },
 
     indent: function(state, textAfter) {
       var n = state.stack.length;
+
       if (/^\}/.test(textAfter))
         n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
       return state.baseIndent + n * indentUnit;
index 9016cc7..e9dcb7f 100644 (file)
@@ -180,7 +180,11 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
       if (!cx) return CodeMirror.Pass;
       if (cx.align) return cx.col + (textAfter.charAt(0) == cx.type ? 0 : 1);
       else return cx.indent + config.indentUnit;
-    }
+    },
+
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/",
+    lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : null
   };
 });
 
index 2b4ed41..ace04b0 100644 (file)
@@ -185,7 +185,7 @@ WebInspector.TextEditor.prototype = {
     {
         const supportedModes = {
             "javascript": true,
-            "css-base": true,
+            "css": true,
         };
 
         var mode = this._codeMirror.getMode();