Web Inspector: Two lines in CSS rule are hidden until resize or click
authorjonowells@apple.com <jonowells@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jun 2014 22:35:07 +0000 (22:35 +0000)
committerjonowells@apple.com <jonowells@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jun 2014 22:35:07 +0000 (22:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133951

Reviewed by Joseph Pecoraro.

Update to CodeMirror 4.2 fixed the issue.

* Tools/PrettyPrinting/codemirror.js:
* Tools/PrettyPrinting/css.js:
* Tools/PrettyPrinting/javascript.js:
* UserInterface/External/CodeMirror/clojure.js:
* UserInterface/External/CodeMirror/closebrackets.js:
* UserInterface/External/CodeMirror/codemirror.js:
* UserInterface/External/CodeMirror/coffeescript.js:
* UserInterface/External/CodeMirror/comment.js:
* UserInterface/External/CodeMirror/css.js:
* UserInterface/External/CodeMirror/htmlmixed.js:
* UserInterface/External/CodeMirror/javascript.js:
* UserInterface/External/CodeMirror/livescript.js:
* UserInterface/External/CodeMirror/matchbrackets.js:
* UserInterface/External/CodeMirror/overlay.js:
* UserInterface/External/CodeMirror/placeholder.js:
* UserInterface/External/CodeMirror/runmode.js:
* UserInterface/External/CodeMirror/sass.js:
* UserInterface/External/CodeMirror/searchcursor.js:
* UserInterface/External/CodeMirror/sql.js:
* UserInterface/External/CodeMirror/xml.js:
Update CodeMirror 4.1 to CodeMirror 4.2.0.

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

21 files changed:
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Tools/PrettyPrinting/codemirror.js
Source/WebInspectorUI/Tools/PrettyPrinting/css.js
Source/WebInspectorUI/Tools/PrettyPrinting/javascript.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/clojure.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/closebrackets.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/codemirror.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/coffeescript.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/comment.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/css.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/htmlmixed.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/javascript.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/livescript.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/matchbrackets.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/overlay.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/placeholder.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/runmode.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/sass.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/searchcursor.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/sql.js
Source/WebInspectorUI/UserInterface/External/CodeMirror/xml.js

index 6dbc655..45e96cd 100644 (file)
@@ -1,5 +1,36 @@
 2014-06-17  Jono Wells  <jonowells@apple.com>
 
+        Web Inspector: Two lines in CSS rule are hidden until resize or click
+        https://bugs.webkit.org/show_bug.cgi?id=133951
+
+        Reviewed by Joseph Pecoraro.
+
+        Update to CodeMirror 4.2 fixed the issue.
+
+        * Tools/PrettyPrinting/codemirror.js:
+        * Tools/PrettyPrinting/css.js:
+        * Tools/PrettyPrinting/javascript.js:
+        * UserInterface/External/CodeMirror/clojure.js:
+        * UserInterface/External/CodeMirror/closebrackets.js:
+        * UserInterface/External/CodeMirror/codemirror.js:
+        * UserInterface/External/CodeMirror/coffeescript.js:
+        * UserInterface/External/CodeMirror/comment.js:
+        * UserInterface/External/CodeMirror/css.js:
+        * UserInterface/External/CodeMirror/htmlmixed.js:
+        * UserInterface/External/CodeMirror/javascript.js:
+        * UserInterface/External/CodeMirror/livescript.js:
+        * UserInterface/External/CodeMirror/matchbrackets.js:
+        * UserInterface/External/CodeMirror/overlay.js:
+        * UserInterface/External/CodeMirror/placeholder.js:
+        * UserInterface/External/CodeMirror/runmode.js:
+        * UserInterface/External/CodeMirror/sass.js:
+        * UserInterface/External/CodeMirror/searchcursor.js:
+        * UserInterface/External/CodeMirror/sql.js:
+        * UserInterface/External/CodeMirror/xml.js:
+        Update CodeMirror 4.1 to CodeMirror 4.2.0.
+
+2014-06-17  Jono Wells  <jonowells@apple.com>
+
         Web Inspector: style declaration editor: visual highlight doesn't match actual selected text
         https://bugs.webkit.org/show_bug.cgi?id=133965
 
index e351813..104ccd7 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 // This is CodeMirror (http://codemirror.net), a code editor
 // implemented in JavaScript on top of the browser's DOM.
 //
@@ -93,6 +96,7 @@
     if (ie_upto10) setTimeout(bind(resetInput, this, true), 20);
 
     registerEventHandlers(this);
+    ensureGlobalHandlers();
 
     var cm = this;
     runInOp(this, function() {
   // the the current scroll position). viewPort may contain top,
   // height, and ensure (see op.scrollToPos) properties.
   function visibleLines(display, doc, viewPort) {
-    var top = viewPort && viewPort.top != null ? viewPort.top : display.scroller.scrollTop;
+    var top = viewPort && viewPort.top != null ? Math.max(0, viewPort.top) : display.scroller.scrollTop;
     top = Math.floor(top - paddingTop(display));
     var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight;
 
         return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
                 to: ensureTo};
     }
-    return {from: from, to: to};
+    return {from: from, to: Math.max(to, from + 1)};
   }
 
   // LINE NUMBERS
     cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
   }
 
-
   function checkForWebkitWidthBug(cm, measure) {
     // Work around Webkit bug where it sometimes reserves space for a
     // non-existing phantom scrollbar in the scroller (Issue #2420)
     if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
       sel = filterSelectionChange(doc, sel);
 
-    var bias = cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1;
+    var bias = options && options.bias ||
+      (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
     setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
 
     if (!(options && options.scroll === false) && doc.cm)
     if (!updated && op.selectionChanged) updateSelection(cm);
     if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm);
 
+    // Abort mouse wheel delta measurement, when scrolling explicitly
+    if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
+      display.wheelStartX = display.wheelStartY = null;
+
     // Propagate the scroll position to the actual DOM scroller
     if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) {
       var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
 
   function viewCuttingPoint(cm, oldN, newN, dir) {
     var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
-    if (!sawCollapsedSpans) return {index: index, lineN: newN};
+    if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
+      return {index: index, lineN: newN};
     for (var i = 0, n = cm.display.viewFrom; i < index; i++)
       n += view[i].size;
     if (n != oldN) {
         var pos = posFromMouse(cm, e);
         if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
         e_preventDefault(e);
-        var word = findWordAt(cm.doc, pos);
+        var word = findWordAt(cm, pos);
         extendSelection(cm.doc, word.anchor, word.head);
       }));
     else
     // Prevent wrapper from ever scrolling
     on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
 
-    // When the window resizes, we need to refresh active editors.
-    var resizeTimer;
-    function onResize() {
-      if (resizeTimer == null) resizeTimer = setTimeout(function() {
-        resizeTimer = null;
-        // Might be a text scaling operation, clear size caches.
-        d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null;
-        cm.setSize();
-      }, 100);
-    }
-    on(window, "resize", onResize);
-    // The above handler holds on to the editor and its data
-    // structures. Here we poll to unregister it when the editor is no
-    // longer in the document, so that it can be garbage-collected.
-    function unregister() {
-      if (contains(document.body, d.wrapper)) setTimeout(unregister, 5000);
-      else off(window, "resize", onResize);
-    }
-    setTimeout(unregister, 5000);
-
     on(d.input, "keyup", operation(cm, onKeyUp));
     on(d.input, "input", function() {
       if (ie && !ie_upto8 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
     });
   }
 
+  // Called when the window resizes
+  function onResize(cm) {
+    // Might be a text scaling operation, clear size caches.
+    var d = cm.display;
+    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+    cm.setSize();
+  }
+
   // MOUSE EVENTS
 
   // Return true when the given mouse event happened in a widget
       lastClick = {time: now, pos: start};
     }
 
-    var sel = cm.doc.sel, addNew = mac ? e.metaKey : e.ctrlKey;
-    if (cm.options.dragDrop && dragAndDrop && !addNew && !isReadOnly(cm) &&
+    var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey;
+    if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
         type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
-      leftButtonStartDrag(cm, e, start);
+      leftButtonStartDrag(cm, e, start, modifier);
     else
-      leftButtonSelect(cm, e, start, type, addNew);
+      leftButtonSelect(cm, e, start, type, modifier);
   }
 
   // Start a text drag. When it ends, see if any dragging actually
   // happen, and treat as a click if it didn't.
-  function leftButtonStartDrag(cm, e, start) {
+  function leftButtonStartDrag(cm, e, start, modifier) {
     var display = cm.display;
     var dragEnd = operation(cm, function(e2) {
       if (webkit) display.scroller.draggable = false;
       off(display.scroller, "drop", dragEnd);
       if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
         e_preventDefault(e2);
-        extendSelection(cm.doc, start);
+        if (!modifier)
+          extendSelection(cm.doc, start);
         focusInput(cm);
         // Work around unexplainable focus problem in IE9 (#2127)
         if (ie_upto10 && !ie_upto8)
       start = posFromMouse(cm, e, true, true);
       ourIndex = -1;
     } else if (type == "double") {
-      var word = findWordAt(doc, start);
+      var word = findWordAt(cm, start);
       if (cm.display.shift || doc.extend)
         ourRange = extendRange(doc, ourRange, word.anchor, word.head);
       else
             ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
         }
         if (!ranges.length) ranges.push(new Range(start, start));
-        setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), sel_mouse);
+        setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
+                     {origin: "*mouse", scroll: false});
+        cm.scrollIntoView(pos);
       } else {
         var oldRange = ourRange;
         var anchor = oldRange.anchor, head = pos;
         if (type != "single") {
           if (type == "double")
-            var range = findWordAt(doc, pos);
+            var range = findWordAt(cm, pos);
           else
             var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
           if (cmp(range.anchor, anchor) > 0) {
       try {
         var text = e.dataTransfer.getData("Text");
         if (text) {
-          var selected = cm.state.draggingText && cm.listSelections();
+          if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))
+            var selected = cm.listSelections();
           setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
           if (selected) for (var i = 0; i < selected.length; ++i)
             replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
         var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
         display.prevInput = selected ? "" : "\u200b";
         display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
+        // Re-set this, in case some other handler touched the
+        // selection in the meantime.
+        display.selForContextMenu = cm.doc.sel;
       }
     }
     function rehide() {
     else if (unit == "column") moveOnce(true);
     else if (unit == "word" || unit == "group") {
       var sawType = null, group = unit == "group";
+      var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
       for (var first = true;; first = false) {
         if (dir < 0 && !moveOnce(!first)) break;
         var cur = lineObj.text.charAt(ch) || "\n";
-        var type = isWordChar(cur) ? "w"
+        var type = isWordChar(cur, helper) ? "w"
           : group && cur == "\n" ? "n"
           : !group || /\s/.test(cur) ? null
           : "p";
   }
 
   // Find the word at the given position (as returned by coordsChar).
-  function findWordAt(doc, pos) {
-    var line = getLine(doc, pos.line).text;
+  function findWordAt(cm, pos) {
+    var doc = cm.doc, line = getLine(doc, pos.line).text;
     var start = pos.ch, end = pos.ch;
     if (line) {
+      var helper = cm.getHelper(pos, "wordChars");
       if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
       var startChar = line.charAt(start);
-      var check = isWordChar(startChar) ? isWordChar
+      var check = isWordChar(startChar, helper)
+        ? function(ch) { return isWordChar(ch, helper); }
         : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
         : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
       while (start > 0 && check(line.charAt(start - 1))) --start;
     },
     transposeChars: function(cm) {
       runInOp(cm, function() {
-        var ranges = cm.listSelections();
+        var ranges = cm.listSelections(), newSel = [];
         for (var i = 0; i < ranges.length; i++) {
           var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
-          if (cur.ch > 0 && cur.ch < line.length - 1)
-            cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
-                            Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
+          if (line) {
+            if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
+            if (cur.ch > 0) {
+              cur = new Pos(cur.line, cur.ch + 1);
+              cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
+                              Pos(cur.line, cur.ch - 2), cur, "+transpose");
+            } else if (cur.line > cm.doc.first) {
+              var prev = getLine(cm.doc, cur.line - 1).text;
+              if (prev)
+                cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
+                                Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
+            }
+          }
+          newSel.push(new Range(cur, cur));
         }
+        cm.setSelections(newSel);
       });
     },
     newlineAndIndent: function(cm) {
   }
 
   function readToken(mode, stream, state) {
-    var style = mode.token(stream, state);
-    if (stream.pos <= stream.start)
-      throw new Error("Mode " + mode.name + " failed to advance stream.");
-    return style;
+    for (var i = 0; i < 10; i++) {
+      var style = mode.token(stream, state);
+      if (stream.pos > stream.start) return style;
+    }
+    throw new Error("Mode " + mode.name + " failed to advance stream.");
   }
 
   // Run the given mode's parser over a line, calling f for each token.
     }
 
     signal(cm, "renderLine", cm, lineView.line, builder.pre);
+    if (builder.pre.className)
+      builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
     return builder;
   }
 
   }
 
   var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
-  var isWordChar = CodeMirror.isWordChar = function(ch) {
+  var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
     return /\w/.test(ch) || ch > "\x80" &&
       (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
   };
+  function isWordChar(ch, helper) {
+    if (!helper) return isWordCharBasic(ch);
+    if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
+    return helper.test(ch);
+  }
 
   function isEmpty(obj) {
     for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
     return b;
   }
 
+  // WINDOW-WIDE EVENTS
+
+  // These must be handled carefully, because naively registering a
+  // handler for each editor will cause the editors to never be
+  // garbage collected.
+
+  function forEachCodeMirror(f) {
+    if (!document.body.getElementsByClassName) return;
+    var byClass = document.body.getElementsByClassName("CodeMirror");
+    for (var i = 0; i < byClass.length; i++) {
+      var cm = byClass[i].CodeMirror;
+      if (cm) f(cm);
+    }
+  }
+
+  var globalsRegistered = false;
+  function ensureGlobalHandlers() {
+    if (globalsRegistered) return;
+    registerGlobalHandlers();
+    globalsRegistered = true;
+  }
+  function registerGlobalHandlers() {
+    // When the window resizes, we need to refresh active editors.
+    var resizeTimer;
+    on(window, "resize", function() {
+      if (resizeTimer == null) resizeTimer = setTimeout(function() {
+        resizeTimer = null;
+        knownScrollbarWidth = null;
+        forEachCodeMirror(onResize);
+      }, 100);
+    });
+    // When the window loses focus, we want to show the editor as blurred
+    on(window, "blur", function() {
+      forEachCodeMirror(onBlur);
+    });
+  }
+
   // FEATURE DETECTION
 
   // Detect drag-and-drop
 
   // THE END
 
-  CodeMirror.version = "4.1.1";
+  CodeMirror.version = "4.2.0";
 
   return CodeMirror;
 });
index a2b80df..1fd46df 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
@@ -54,7 +57,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
       if (/[\d.]/.test(stream.peek())) {
         stream.eatWhile(/[\w.%]/);
         return ret("number", "unit");
-      } else if (stream.match(/^[^-]+-/)) {
+      } else if (stream.match(/^\w+-/)) {
         return ret("meta", "meta");
       }
     } else if (/[,+>*\/]/.test(ch)) {
@@ -164,7 +167,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     } else if (type == ":") {
       return "pseudo";
     } else if (allowNested && type == "(") {
-      return pushContext(state, stream, "params");
+      return pushContext(state, stream, "parens");
     }
     return state.context.type;
   };
@@ -225,6 +228,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
   states.parens = function(type, stream, state) {
     if (type == "{" || type == "}") return popAndPass(type, stream, state);
     if (type == ")") return popContext(state);
+    if (type == "(") return pushContext(state, stream, "parens");
+    if (type == "word") wordAsValue(stream);
     return "parens";
   };
 
@@ -300,13 +305,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     return "interpolation";
   };
 
-  states.params = function(type, stream, state) {
-    if (type == ")") return popContext(state);
-    if (type == "{" || type == "}") return popAndPass(type, stream, state);
-    if (type == "word") wordAsValue(stream);
-    return "params";
-  };
-
   return {
     startState: function(base) {
       return {tokenize: null,
@@ -329,10 +327,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     indent: function(state, textAfter) {
       var cx = state.context, ch = textAfter && textAfter.charAt(0);
       var indent = cx.indent;
-      if (cx.type == "prop" && ch == "}") cx = cx.prev;
+      if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
       if (cx.prev &&
           (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
-           ch == ")" && (cx.type == "parens" || cx.type == "params" || cx.type == "media_parens") ||
+           ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
            ch == "{" && (cx.type == "at" || cx.type == "media"))) {
         indent = cx.indent - indentUnit;
         cx = cx.prev;
@@ -422,7 +420,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     "marker-offset", "marks", "marquee-direction", "marquee-loop",
     "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
     "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
-    "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
+    "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
+    "opacity", "order", "orphans", "outline",
     "outline-color", "outline-offset", "outline-style", "outline-width",
     "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
     "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
@@ -433,8 +432,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     "region-break-before", "region-break-inside", "region-fragment",
     "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
     "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
-    "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
-    "speak", "speak-as", "speak-header",
+    "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
+    "shape-outside", "size", "speak", "speak-as", "speak-header",
     "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
     "tab-size", "table-layout", "target", "target-name", "target-new",
     "target-position", "text-align", "text-align-last", "text-decoration",
index daf138b..b522ec4 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 // TODO actually recognize syntax of TypeScript constructs
 
 (function(mod) {
@@ -645,6 +648,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
   };
 });
 
+CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/);
+
 CodeMirror.defineMIME("text/javascript", "javascript");
 CodeMirror.defineMIME("text/ecmascript", "javascript");
 CodeMirror.defineMIME("application/javascript", "javascript");
index 3b596ad..f81bd2c 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 /**
  * Author: Hans Engel
  * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
index 3cea887..83d4229 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index e351813..104ccd7 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 // This is CodeMirror (http://codemirror.net), a code editor
 // implemented in JavaScript on top of the browser's DOM.
 //
@@ -93,6 +96,7 @@
     if (ie_upto10) setTimeout(bind(resetInput, this, true), 20);
 
     registerEventHandlers(this);
+    ensureGlobalHandlers();
 
     var cm = this;
     runInOp(this, function() {
   // the the current scroll position). viewPort may contain top,
   // height, and ensure (see op.scrollToPos) properties.
   function visibleLines(display, doc, viewPort) {
-    var top = viewPort && viewPort.top != null ? viewPort.top : display.scroller.scrollTop;
+    var top = viewPort && viewPort.top != null ? Math.max(0, viewPort.top) : display.scroller.scrollTop;
     top = Math.floor(top - paddingTop(display));
     var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight;
 
         return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
                 to: ensureTo};
     }
-    return {from: from, to: to};
+    return {from: from, to: Math.max(to, from + 1)};
   }
 
   // LINE NUMBERS
     cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
   }
 
-
   function checkForWebkitWidthBug(cm, measure) {
     // Work around Webkit bug where it sometimes reserves space for a
     // non-existing phantom scrollbar in the scroller (Issue #2420)
     if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
       sel = filterSelectionChange(doc, sel);
 
-    var bias = cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1;
+    var bias = options && options.bias ||
+      (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
     setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
 
     if (!(options && options.scroll === false) && doc.cm)
     if (!updated && op.selectionChanged) updateSelection(cm);
     if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm);
 
+    // Abort mouse wheel delta measurement, when scrolling explicitly
+    if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
+      display.wheelStartX = display.wheelStartY = null;
+
     // Propagate the scroll position to the actual DOM scroller
     if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) {
       var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
 
   function viewCuttingPoint(cm, oldN, newN, dir) {
     var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
-    if (!sawCollapsedSpans) return {index: index, lineN: newN};
+    if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
+      return {index: index, lineN: newN};
     for (var i = 0, n = cm.display.viewFrom; i < index; i++)
       n += view[i].size;
     if (n != oldN) {
         var pos = posFromMouse(cm, e);
         if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
         e_preventDefault(e);
-        var word = findWordAt(cm.doc, pos);
+        var word = findWordAt(cm, pos);
         extendSelection(cm.doc, word.anchor, word.head);
       }));
     else
     // Prevent wrapper from ever scrolling
     on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
 
-    // When the window resizes, we need to refresh active editors.
-    var resizeTimer;
-    function onResize() {
-      if (resizeTimer == null) resizeTimer = setTimeout(function() {
-        resizeTimer = null;
-        // Might be a text scaling operation, clear size caches.
-        d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null;
-        cm.setSize();
-      }, 100);
-    }
-    on(window, "resize", onResize);
-    // The above handler holds on to the editor and its data
-    // structures. Here we poll to unregister it when the editor is no
-    // longer in the document, so that it can be garbage-collected.
-    function unregister() {
-      if (contains(document.body, d.wrapper)) setTimeout(unregister, 5000);
-      else off(window, "resize", onResize);
-    }
-    setTimeout(unregister, 5000);
-
     on(d.input, "keyup", operation(cm, onKeyUp));
     on(d.input, "input", function() {
       if (ie && !ie_upto8 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
     });
   }
 
+  // Called when the window resizes
+  function onResize(cm) {
+    // Might be a text scaling operation, clear size caches.
+    var d = cm.display;
+    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+    cm.setSize();
+  }
+
   // MOUSE EVENTS
 
   // Return true when the given mouse event happened in a widget
       lastClick = {time: now, pos: start};
     }
 
-    var sel = cm.doc.sel, addNew = mac ? e.metaKey : e.ctrlKey;
-    if (cm.options.dragDrop && dragAndDrop && !addNew && !isReadOnly(cm) &&
+    var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey;
+    if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
         type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
-      leftButtonStartDrag(cm, e, start);
+      leftButtonStartDrag(cm, e, start, modifier);
     else
-      leftButtonSelect(cm, e, start, type, addNew);
+      leftButtonSelect(cm, e, start, type, modifier);
   }
 
   // Start a text drag. When it ends, see if any dragging actually
   // happen, and treat as a click if it didn't.
-  function leftButtonStartDrag(cm, e, start) {
+  function leftButtonStartDrag(cm, e, start, modifier) {
     var display = cm.display;
     var dragEnd = operation(cm, function(e2) {
       if (webkit) display.scroller.draggable = false;
       off(display.scroller, "drop", dragEnd);
       if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
         e_preventDefault(e2);
-        extendSelection(cm.doc, start);
+        if (!modifier)
+          extendSelection(cm.doc, start);
         focusInput(cm);
         // Work around unexplainable focus problem in IE9 (#2127)
         if (ie_upto10 && !ie_upto8)
       start = posFromMouse(cm, e, true, true);
       ourIndex = -1;
     } else if (type == "double") {
-      var word = findWordAt(doc, start);
+      var word = findWordAt(cm, start);
       if (cm.display.shift || doc.extend)
         ourRange = extendRange(doc, ourRange, word.anchor, word.head);
       else
             ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
         }
         if (!ranges.length) ranges.push(new Range(start, start));
-        setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), sel_mouse);
+        setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
+                     {origin: "*mouse", scroll: false});
+        cm.scrollIntoView(pos);
       } else {
         var oldRange = ourRange;
         var anchor = oldRange.anchor, head = pos;
         if (type != "single") {
           if (type == "double")
-            var range = findWordAt(doc, pos);
+            var range = findWordAt(cm, pos);
           else
             var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
           if (cmp(range.anchor, anchor) > 0) {
       try {
         var text = e.dataTransfer.getData("Text");
         if (text) {
-          var selected = cm.state.draggingText && cm.listSelections();
+          if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))
+            var selected = cm.listSelections();
           setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
           if (selected) for (var i = 0; i < selected.length; ++i)
             replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
         var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
         display.prevInput = selected ? "" : "\u200b";
         display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
+        // Re-set this, in case some other handler touched the
+        // selection in the meantime.
+        display.selForContextMenu = cm.doc.sel;
       }
     }
     function rehide() {
     else if (unit == "column") moveOnce(true);
     else if (unit == "word" || unit == "group") {
       var sawType = null, group = unit == "group";
+      var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
       for (var first = true;; first = false) {
         if (dir < 0 && !moveOnce(!first)) break;
         var cur = lineObj.text.charAt(ch) || "\n";
-        var type = isWordChar(cur) ? "w"
+        var type = isWordChar(cur, helper) ? "w"
           : group && cur == "\n" ? "n"
           : !group || /\s/.test(cur) ? null
           : "p";
   }
 
   // Find the word at the given position (as returned by coordsChar).
-  function findWordAt(doc, pos) {
-    var line = getLine(doc, pos.line).text;
+  function findWordAt(cm, pos) {
+    var doc = cm.doc, line = getLine(doc, pos.line).text;
     var start = pos.ch, end = pos.ch;
     if (line) {
+      var helper = cm.getHelper(pos, "wordChars");
       if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
       var startChar = line.charAt(start);
-      var check = isWordChar(startChar) ? isWordChar
+      var check = isWordChar(startChar, helper)
+        ? function(ch) { return isWordChar(ch, helper); }
         : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
         : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
       while (start > 0 && check(line.charAt(start - 1))) --start;
     },
     transposeChars: function(cm) {
       runInOp(cm, function() {
-        var ranges = cm.listSelections();
+        var ranges = cm.listSelections(), newSel = [];
         for (var i = 0; i < ranges.length; i++) {
           var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
-          if (cur.ch > 0 && cur.ch < line.length - 1)
-            cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
-                            Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
+          if (line) {
+            if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
+            if (cur.ch > 0) {
+              cur = new Pos(cur.line, cur.ch + 1);
+              cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
+                              Pos(cur.line, cur.ch - 2), cur, "+transpose");
+            } else if (cur.line > cm.doc.first) {
+              var prev = getLine(cm.doc, cur.line - 1).text;
+              if (prev)
+                cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
+                                Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
+            }
+          }
+          newSel.push(new Range(cur, cur));
         }
+        cm.setSelections(newSel);
       });
     },
     newlineAndIndent: function(cm) {
   }
 
   function readToken(mode, stream, state) {
-    var style = mode.token(stream, state);
-    if (stream.pos <= stream.start)
-      throw new Error("Mode " + mode.name + " failed to advance stream.");
-    return style;
+    for (var i = 0; i < 10; i++) {
+      var style = mode.token(stream, state);
+      if (stream.pos > stream.start) return style;
+    }
+    throw new Error("Mode " + mode.name + " failed to advance stream.");
   }
 
   // Run the given mode's parser over a line, calling f for each token.
     }
 
     signal(cm, "renderLine", cm, lineView.line, builder.pre);
+    if (builder.pre.className)
+      builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
     return builder;
   }
 
   }
 
   var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
-  var isWordChar = CodeMirror.isWordChar = function(ch) {
+  var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
     return /\w/.test(ch) || ch > "\x80" &&
       (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
   };
+  function isWordChar(ch, helper) {
+    if (!helper) return isWordCharBasic(ch);
+    if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
+    return helper.test(ch);
+  }
 
   function isEmpty(obj) {
     for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
     return b;
   }
 
+  // WINDOW-WIDE EVENTS
+
+  // These must be handled carefully, because naively registering a
+  // handler for each editor will cause the editors to never be
+  // garbage collected.
+
+  function forEachCodeMirror(f) {
+    if (!document.body.getElementsByClassName) return;
+    var byClass = document.body.getElementsByClassName("CodeMirror");
+    for (var i = 0; i < byClass.length; i++) {
+      var cm = byClass[i].CodeMirror;
+      if (cm) f(cm);
+    }
+  }
+
+  var globalsRegistered = false;
+  function ensureGlobalHandlers() {
+    if (globalsRegistered) return;
+    registerGlobalHandlers();
+    globalsRegistered = true;
+  }
+  function registerGlobalHandlers() {
+    // When the window resizes, we need to refresh active editors.
+    var resizeTimer;
+    on(window, "resize", function() {
+      if (resizeTimer == null) resizeTimer = setTimeout(function() {
+        resizeTimer = null;
+        knownScrollbarWidth = null;
+        forEachCodeMirror(onResize);
+      }, 100);
+    });
+    // When the window loses focus, we want to show the editor as blurred
+    on(window, "blur", function() {
+      forEachCodeMirror(onBlur);
+    });
+  }
+
   // FEATURE DETECTION
 
   // Detect drag-and-drop
 
   // THE END
 
-  CodeMirror.version = "4.1.1";
+  CodeMirror.version = "4.2.0";
 
   return CodeMirror;
 });
index c6da8f2..1695650 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 /**
  * Link to the project's GitHub page:
  * https://github.com/pickhardt/coffeescript-codemirror-mode
index 1eb9a05..3ac4764 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index a2b80df..1fd46df 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
@@ -54,7 +57,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
       if (/[\d.]/.test(stream.peek())) {
         stream.eatWhile(/[\w.%]/);
         return ret("number", "unit");
-      } else if (stream.match(/^[^-]+-/)) {
+      } else if (stream.match(/^\w+-/)) {
         return ret("meta", "meta");
       }
     } else if (/[,+>*\/]/.test(ch)) {
@@ -164,7 +167,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     } else if (type == ":") {
       return "pseudo";
     } else if (allowNested && type == "(") {
-      return pushContext(state, stream, "params");
+      return pushContext(state, stream, "parens");
     }
     return state.context.type;
   };
@@ -225,6 +228,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
   states.parens = function(type, stream, state) {
     if (type == "{" || type == "}") return popAndPass(type, stream, state);
     if (type == ")") return popContext(state);
+    if (type == "(") return pushContext(state, stream, "parens");
+    if (type == "word") wordAsValue(stream);
     return "parens";
   };
 
@@ -300,13 +305,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     return "interpolation";
   };
 
-  states.params = function(type, stream, state) {
-    if (type == ")") return popContext(state);
-    if (type == "{" || type == "}") return popAndPass(type, stream, state);
-    if (type == "word") wordAsValue(stream);
-    return "params";
-  };
-
   return {
     startState: function(base) {
       return {tokenize: null,
@@ -329,10 +327,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     indent: function(state, textAfter) {
       var cx = state.context, ch = textAfter && textAfter.charAt(0);
       var indent = cx.indent;
-      if (cx.type == "prop" && ch == "}") cx = cx.prev;
+      if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
       if (cx.prev &&
           (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
-           ch == ")" && (cx.type == "parens" || cx.type == "params" || cx.type == "media_parens") ||
+           ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
            ch == "{" && (cx.type == "at" || cx.type == "media"))) {
         indent = cx.indent - indentUnit;
         cx = cx.prev;
@@ -422,7 +420,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     "marker-offset", "marks", "marquee-direction", "marquee-loop",
     "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
     "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
-    "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
+    "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
+    "opacity", "order", "orphans", "outline",
     "outline-color", "outline-offset", "outline-style", "outline-width",
     "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
     "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
@@ -433,8 +432,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
     "region-break-before", "region-break-inside", "region-fragment",
     "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
     "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
-    "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
-    "speak", "speak-as", "speak-header",
+    "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
+    "shape-outside", "size", "speak", "speak-as", "speak-header",
     "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
     "tab-size", "table-layout", "target", "target-name", "target-new",
     "target-position", "text-align", "text-align-last", "text-decoration",
index d80ef9c..dc48978 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
index daf138b..b522ec4 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 // TODO actually recognize syntax of TypeScript constructs
 
 (function(mod) {
@@ -645,6 +648,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
   };
 });
 
+CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/);
+
 CodeMirror.defineMIME("text/javascript", "javascript");
 CodeMirror.defineMIME("text/ecmascript", "javascript");
 CodeMirror.defineMIME("application/javascript", "javascript");
index 1efc3ec..55882ef 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 /**
  * Link to the project's GitHub page:
  * https://github.com/duralog/CodeMirror
index dcdde81..fa1ae03 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index c16b0c8..393054d 100644 (file)
@@ -1,10 +1,14 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 // Utility function that allows modes to be combined. The mode given
 // as the base argument takes care of most of the normal mode
 // functionality, but a second (typically simple) mode is used, which
 // can override the style of text. Both modes get to parse all of the
 // text, but when both assign a non-null style to a piece of code, the
-// overlay wins, unless the combine argument was true, in which case
-// the styles are combined.
+// overlay wins, unless the combine argument was true and not overridden,
+// or state.overlay.combineTokens was true, in which case the styles are
+// combined.
 
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -54,8 +58,13 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
       }
       stream.pos = Math.min(state.basePos, state.overlayPos);
 
+      // state.overlay.combineTokens always takes precedence over combine,
+      // unless set to null
       if (state.overlayCur == null) return state.baseCur;
-      if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
+      else if (state.baseCur != null &&
+               state.overlay.combineTokens ||
+               combine && state.overlay.combineTokens == null)
+        return state.baseCur + " " + state.overlayCur;
       else return state.overlayCur;
     },
 
index 0fdc9b0..bb0c393 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index 5592a99..07d2279 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index 74ae91d..2ff5003 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index 899f44c..2783308 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index 417db06..6c02f4e 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
index 3248c45..786507d 100644 (file)
@@ -1,3 +1,6 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
 (function(mod) {
   if (typeof exports == "object" && typeof module == "object") // CommonJS
     mod(require("../../lib/codemirror"));
@@ -121,7 +124,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
       state.state = baseState;
       state.tagName = state.tagStart = null;
       var next = state.tokenize(stream, state);
-      return next ? next + " error" : "error";
+      return next ? next + " tag error" : "tag error";
     } else if (/[\'\"]/.test(ch)) {
       state.tokenize = inAttribute(ch);
       state.stringStartCol = stream.column();