From 51ad9ffe405ad3f12201de1becaea70f6eee68bd Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 16 Jan 2014 20:06:50 +0100 Subject: [PATCH 001/100] Bump version number post-3.21 --- lib/codemirror.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 23ca5355b9..d82dc0d415 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -6041,7 +6041,7 @@ window.CodeMirror = (function() { // THE END - CodeMirror.version = "3.21.0"; + CodeMirror.version = "3.21.1"; return CodeMirror; })(); diff --git a/package.json b/package.json index 326b95890b..e8a7c18ac4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"3.21.0", + "version":"3.21.1", "main": "lib/codemirror.js", "description": "In-browser code editing made bearable", "licenses": [{"type": "MIT", From 286f38806cc6d0bc31abdb7f599906473e44c743 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 16 Jan 2014 20:08:35 +0100 Subject: [PATCH 002/100] [release notes] Fix date for 3.21 --- doc/releases.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases.html b/doc/releases.html index f9b2dcc814..4f5de8da25 100644 --- a/doc/releases.html +++ b/doc/releases.html @@ -28,7 +28,7 @@

Version 3.x

-

21-11-2013: Version 3.21:

+

16-01-2014: Version 3.21:

21-11-2013: Version 3.20:

From a53e500bba4df665f9cd12126cbe0da736423d28 Mon Sep 17 00:00:00 2001 From: sheopory Date: Thu, 16 Jan 2014 11:39:08 -0800 Subject: [PATCH 004/100] Fix bug in updateScrollbars. On IE8 only scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight evaluates to -ve in some cases. Guard that with returning 0 in that case. Seems a bug in IE8, so this can be treated as a workaround. --- lib/codemirror.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index d82dc0d415..dffa9ce9de 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -337,8 +337,9 @@ window.CodeMirror = (function() { if (needsV) { d.scrollbarV.style.display = "block"; d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0"; + // A bug in IE8 can cause this value to be negative, so guard it. d.scrollbarV.firstChild.style.height = - (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px"; + Math.max(0, scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px"; } else { d.scrollbarV.style.display = ""; d.scrollbarV.firstChild.style.height = "0"; From 804a30c8d1821856e8e6ff4885791f5a7efd0860 Mon Sep 17 00:00:00 2001 From: Beni Cherniavsky-Paskin Date: Thu, 16 Jan 2014 19:01:54 +0200 Subject: [PATCH 005/100] Don't generate nodes when token() returns only line-foo/line-background-foo styles. --- lib/codemirror.js | 1 + test/test.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index dffa9ce9de..0448274859 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -4485,6 +4485,7 @@ window.CodeMirror = (function() { else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop])) builder[prop] += " " + lineClass[2]; } + if (!style) return null; var cache = builder.cm.options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; return cache[style] || (cache[style] = "cm-" + style.replace(/ +/g, " cm-")); diff --git a/test/test.js b/test/test.js index 3ad8d35499..c6bfd8912b 100644 --- a/test/test.js +++ b/test/test.js @@ -1626,7 +1626,7 @@ testCM("lineStyleFromMode", function(cm) { CodeMirror.defineMode("test_mode", function() { return {token: function(stream) { if (stream.match(/^\[[^\]]*\]/)) return "line-brackets"; - if (stream.match(/^\([^\]]*\)/)) return "line-background-parens"; + if (stream.match(/^\([^\)]*\)/)) return "line-background-parens"; stream.match(/^\s+|^\S+/); }}; }); @@ -1635,10 +1635,13 @@ testCM("lineStyleFromMode", function(cm) { eq(bracketElts.length, 1); eq(bracketElts[0].nodeName, "PRE"); is(!/brackets.*brackets/.test(bracketElts[0].className)); + eq(bracketElts[0].getElementsByTagName("span").length, 0); var parenElts = byClassName(cm.getWrapperElement(), "parens"); eq(parenElts.length, 1); eq(parenElts[0].nodeName, "DIV"); is(!/parens.*parens/.test(parenElts[0].className)); + eq(parenElts[0].parentElement.nodeName, "DIV"); + eq(parenElts[0].parentElement.getElementsByTagName("span").length, 0); }, {value: "line1: [br] [br]\nline2: (par) (par)\nline3: nothing"}); CodeMirror.registerHelper("xxx", "a", "A"); From 6d2973189fba83816f5deb8d187211b10e98ee49 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 17 Jan 2014 11:59:27 +0100 Subject: [PATCH 006/100] Remove tests using getElementsByTagName The method isn't present on all supported platforms, and these tests tested someting very obscure, and already failed on the v4 branch which representes the editor content differently. Issue #2152 --- test/test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test.js b/test/test.js index c6bfd8912b..6eeca979c0 100644 --- a/test/test.js +++ b/test/test.js @@ -1635,13 +1635,11 @@ testCM("lineStyleFromMode", function(cm) { eq(bracketElts.length, 1); eq(bracketElts[0].nodeName, "PRE"); is(!/brackets.*brackets/.test(bracketElts[0].className)); - eq(bracketElts[0].getElementsByTagName("span").length, 0); var parenElts = byClassName(cm.getWrapperElement(), "parens"); eq(parenElts.length, 1); eq(parenElts[0].nodeName, "DIV"); is(!/parens.*parens/.test(parenElts[0].className)); eq(parenElts[0].parentElement.nodeName, "DIV"); - eq(parenElts[0].parentElement.getElementsByTagName("span").length, 0); }, {value: "line1: [br] [br]\nline2: (par) (par)\nline3: nothing"}); CodeMirror.registerHelper("xxx", "a", "A"); From 2b61ac92b58ac62ff3d63488d5508642f11d335b Mon Sep 17 00:00:00 2001 From: Beni Cherniavsky-Paskin Date: Fri, 17 Jan 2014 03:38:45 +0200 Subject: [PATCH 007/100] Handle spurious spaces from token(). --- lib/codemirror.js | 6 +++--- test/test.js | 13 ++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 0448274859..c5d02b6e08 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -4476,7 +4476,7 @@ window.CodeMirror = (function() { function interpretTokenStyle(style, builder) { if (!style) return null; for (;;) { - var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/); + 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"; @@ -4485,10 +4485,10 @@ window.CodeMirror = (function() { else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop])) builder[prop] += " " + lineClass[2]; } - if (!style) return null; + if (/^\s*$/.test(style)) return null; var cache = builder.cm.options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; return cache[style] || - (cache[style] = "cm-" + style.replace(/ +/g, " cm-")); + (cache[style] = style.replace(/\S+/g, "cm-$&")); } function buildLineContent(cm, realLine, measure, copyWidgets) { diff --git a/test/test.js b/test/test.js index 6eeca979c0..1d7f80e355 100644 --- a/test/test.js +++ b/test/test.js @@ -1625,8 +1625,9 @@ testCM("change_removedText", function(cm) { testCM("lineStyleFromMode", function(cm) { CodeMirror.defineMode("test_mode", function() { return {token: function(stream) { - if (stream.match(/^\[[^\]]*\]/)) return "line-brackets"; - if (stream.match(/^\([^\)]*\)/)) return "line-background-parens"; + if (stream.match(/^\[[^\]]*\]/)) return " line-brackets "; + if (stream.match(/^\([^\)]*\)/)) return " line-background-parens "; + if (stream.match(/^<[^>]*>/)) return " span line-line line-background-bg "; stream.match(/^\s+|^\S+/); }}; }); @@ -1640,7 +1641,13 @@ testCM("lineStyleFromMode", function(cm) { eq(parenElts[0].nodeName, "DIV"); is(!/parens.*parens/.test(parenElts[0].className)); eq(parenElts[0].parentElement.nodeName, "DIV"); -}, {value: "line1: [br] [br]\nline2: (par) (par)\nline3: nothing"}); + + eq(byClassName(cm.getWrapperElement(), "bg").length, 1); + eq(byClassName(cm.getWrapperElement(), "line").length, 1); + var spanElts = byClassName(cm.getWrapperElement(), "cm-span"); + eq(spanElts.length, 2); + is(/^\s*cm-span\s*$/.test(spanElts[0].className)); +}, {value: "line1: [br] [br]\nline2: (par) (par)\nline3: "}); CodeMirror.registerHelper("xxx", "a", "A"); CodeMirror.registerHelper("xxx", "b", "B"); From 087d37cb82dda413e210b00f55dd8b52ef7edbf7 Mon Sep 17 00:00:00 2001 From: Travis Heppe Date: Thu, 16 Jan 2014 17:54:21 -0800 Subject: [PATCH 008/100] [vim keymap] Fix to moveTillCharacter Return null from moveTillCharacter if nothing is found, so that if a deletion operation is active but no match was found, nothing gets deleted. Add a unit test for moveTillCharacter. --- keymap/vim.js | 2 +- test/vim_test.js | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/keymap/vim.js b/keymap/vim.js index 75b4e454d0..a08c5c2f7c 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -1457,7 +1457,7 @@ motionArgs.selectedCharacter); var increment = motionArgs.forward ? -1 : 1; recordLastCharacterSearch(increment, motionArgs); - if(!curEnd)return cm.getCursor(); + if (!curEnd) return null; curEnd.ch += increment; return curEnd; }, diff --git a/test/vim_test.js b/test/vim_test.js index 7184cb25ab..d39753c10c 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -2003,6 +2003,45 @@ testVim('zt==z', function(cm, vim, helpers){ eq(zVals[2], zVals[5]); }); +var moveTillCharacterSandbox = + 'The quick brown fox \n' + 'jumped over the lazy dog.' +testVim('moveTillCharacter', function(cm, vim, helpers){ + cm.setCursor(0, 0); + // Search for the 'q'. + cm.openDialog = helpers.fakeOpenDialog('q'); + helpers.doKeys('/'); + eq(4, cm.getCursor().ch); + // Jump to just before the first o in the list. + helpers.doKeys('t'); + helpers.doKeys('o'); + eq('The quick brown fox \n', cm.getValue()); + // Delete that one character. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('o'); + eq('The quick bown fox \n', cm.getValue()); + // Delete everything until the next 'o'. + helpers.doKeys('.'); + eq('The quick box \n', cm.getValue()); + // An unmatched character should have no effect. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('q'); + eq('The quick box \n', cm.getValue()); + // Matches should only be possible on single lines. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('z'); + eq('The quick box \n', cm.getValue()); + // After all that, the search for 'q' should still be active, so the 'N' command + // can run it again in reverse. Use that to delete everything back to the 'q'. + helpers.doKeys('d'); + helpers.doKeys('N'); + eq('The ox \n', cm.getValue()); + eq(4, cm.getCursor().ch); +}, { value: moveTillCharacterSandbox}); + var scrollMotionSandbox = '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n' '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n' From 537edc5c4a6344633823ce8935fd4b9017c8d888 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 20 Jan 2014 10:40:14 +0100 Subject: [PATCH 009/100] Make hasFocus use document.activeElement, rather than internal flag This way, it synchronously returns the current value, rather than only being updated when an async focus/blur event fires. Closes #2151 --- lib/codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index c5d02b6e08..10fcdbe7bc 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -3224,7 +3224,7 @@ window.CodeMirror = (function() { else this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", ""); }, - hasFocus: function() { return this.state.focused; }, + hasFocus: function() { return document.activeElement == this.display.input; }, scrollTo: operation(null, function(x, y) { updateScrollPos(this, x, y); From 982beb6e81ad404441fd1c6746747c4433941cde Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 17 Jan 2014 16:04:35 -0500 Subject: [PATCH 010/100] Fixed clojure indenting, now will try to use the user's setting --- mode/clojure/clojure.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mode/clojure/clojure.js b/mode/clojure/clojure.js index ee22a12fed..e3d87d23a6 100644 --- a/mode/clojure/clojure.js +++ b/mode/clojure/clojure.js @@ -2,10 +2,11 @@ * Author: Hans Engel * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun) */ -CodeMirror.defineMode("clojure", function () { +CodeMirror.defineMode("clojure", function (options) { var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2", ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword"; - var INDENT_WORD_SKIP = 2; + var INDENT_WORD_SKIP = options.indentUnit || 2; + var NORMAL_INDENT_UNIT = options.indentUnit || 2; function makeKeywords(str) { var obj = {}, words = str.split(" "); @@ -179,8 +180,8 @@ CodeMirror.defineMode("clojure", function () { stream.eatSpace(); if (stream.eol() || stream.peek() == ";") { // nothing significant after - // we restart indentation 1 space after - pushStack(state, indentTemp + 1, ch); + // we restart indentation the user defined spaces after + pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch); } else { pushStack(state, indentTemp + stream.current().length, ch); // else we match } From b2c87a4833e352b02cfca1e489fedb47245c8d36 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 20 Jan 2014 11:02:42 +0100 Subject: [PATCH 011/100] More aggressively clear line heights in refresh() Closes #2157 --- lib/codemirror.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 10fcdbe7bc..ac7e4ce6aa 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -3270,11 +3270,12 @@ window.CodeMirror = (function() { operation: function(f){return runInOp(this, f);}, refresh: operation(null, function() { - var badHeight = this.display.cachedTextHeight == null; + var oldHeight = this.display.cachedTextHeight; clearCaches(this); updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop); regChange(this); - if (badHeight) estimateLineHeights(this); + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + estimateLineHeights(this); }), swapDoc: operation(null, function(doc) { From 6dad920c6f04e656869e3f50e484dedb46a7ec8c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 20 Jan 2014 17:02:04 +0100 Subject: [PATCH 012/100] [css mode] When indenting, properly pop off prop context before closing brace Closes #2162 --- mode/css/css.js | 1 + 1 file changed, 1 insertion(+) diff --git a/mode/css/css.js b/mode/css/css.js index 8f6fe7df4d..c94f1daa54 100644 --- a/mode/css/css.js +++ b/mode/css/css.js @@ -308,6 +308,7 @@ 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.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") || From 9ad6218e4d9b2c510dbeeb462ae82aad66184f2a Mon Sep 17 00:00:00 2001 From: Narciso Jaramillo Date: Mon, 20 Jan 2014 11:18:05 -0800 Subject: [PATCH 013/100] [closetag addon] Allow typing '/' if there's no matching open tag --- addon/edit/closetag.js | 1 + 1 file changed, 1 insertion(+) diff --git a/addon/edit/closetag.js b/addon/edit/closetag.js index cad776a783..762a94ccbb 100644 --- a/addon/edit/closetag.js +++ b/addon/edit/closetag.js @@ -82,6 +82,7 @@ var tagName = state.context && state.context.tagName; if (tagName) cm.replaceSelection("/" + tagName + ">", "end"); + else return CodeMirror.Pass; } function indexOf(collection, elt) { From 2dcfbd67d3b2019e03fc6ea0bd93991f170fa8b3 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 22 Jan 2014 17:30:15 +0100 Subject: [PATCH 014/100] [scrollpastend plugin] Don't get confused when the editor changes size Closes #2160 --- addon/scroll/scrollpastend.js | 2 ++ lib/codemirror.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/addon/scroll/scrollpastend.js b/addon/scroll/scrollpastend.js index 14d7d5aeee..58720ad413 100644 --- a/addon/scroll/scrollpastend.js +++ b/addon/scroll/scrollpastend.js @@ -4,11 +4,13 @@ CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { if (old && old != CodeMirror.Init) { cm.off("change", onChange); + cm.off("refresh", updateBottomMargin); cm.display.lineSpace.parentNode.style.paddingBottom = ""; cm.state.scrollPastEndPadding = null; } if (val) { cm.on("change", onChange); + cm.on("refresh", updateBottomMargin); updateBottomMargin(cm); } }); diff --git a/lib/codemirror.js b/lib/codemirror.js index ac7e4ce6aa..67e5291f67 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -3265,6 +3265,7 @@ window.CodeMirror = (function() { if (this.options.lineWrapping) this.display.measureLineCache.length = this.display.measureLineCachePos = 0; this.curOp.forceUpdate = true; + signal(this, "refresh", this); }), operation: function(f){return runInOp(this, f);}, @@ -3276,6 +3277,7 @@ window.CodeMirror = (function() { regChange(this); if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) estimateLineHeights(this); + signal(this, "refresh", this); }), swapDoc: operation(null, function(doc) { From 0cbe02fde8394b62ea106774179519246e582cba Mon Sep 17 00:00:00 2001 From: Peter Kroon Date: Mon, 20 Jan 2014 23:40:26 +0100 Subject: [PATCH 015/100] [mdn-like theme] Add --- theme/mdn-like.css | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 theme/mdn-like.css diff --git a/theme/mdn-like.css b/theme/mdn-like.css new file mode 100644 index 0000000000..bcd4100439 --- /dev/null +++ b/theme/mdn-like.css @@ -0,0 +1,44 @@ +/* + MDN-LIKE Theme - Mozilla + Ported to CodeMirror by Peter Kroon + Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues + GitHub: @peterkroon + + The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation + +*/ +.cm-s-mdn-like.CodeMirror { color: #999; font-family: monospace; background-color: #fff; } /**/ +.cm-s-mdn-like .CodeMirror-selected { background: #cfc !important; } /**/ + +.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; } /**/ +.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; margin-left: 3px; } /**/ +.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222 !important; } /**/ + +.cm-s-mdn-like .cm-keyword { color: #6262FF; } /**/ +.cm-s-mdn-like .cm-atom { color: #F90; } /**/ +.cm-s-mdn-like .cm-number { color: #ca7841; } /**/ +.cm-s-mdn-like .cm-def { color: #8DA6CE; } /**/ +.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; } /**/ +.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def { color: #07a; } /**/ + +.cm-s-mdn-like .cm-variable { color: #07a; } /**/ +.cm-s-mdn-like .cm-property { color: #905; } /**/ +.cm-s-mdn-like .cm-qualifier { color: #690; } /**/ + +.cm-s-mdn-like .cm-operator { color: #cda869; } /**/ +.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; } /**/ +.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; } /**/ +.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/ +.cm-s-mdn-like .cm-meta { color: #000; } /*?*/ +.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/ +.cm-s-mdn-like .cm-tag { color: #997643; } /**/ +.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/ +.cm-s-mdn-like .cm-header { color: #FF6400; } /**/ +.cm-s-mdn-like .cm-hr { color: #AEAEAE; } /**/ +.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/ +.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; } /**/ + +.cm-s-mdn-like .CodeMirror-activeline-background {background: #efefff !important;} /**/ +.cm-s-mdn-like .CodeMirror-matchingbracket {outline:1px solid grey; color: inherit !important;} /**/ + +.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,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); } From 524e7705311df0dcd7d9218151967c36543b2ffd Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 22 Jan 2014 17:52:52 +0100 Subject: [PATCH 016/100] [mdn-like theme] Integrate --- demo/theme.html | 2 ++ theme/mdn-like.css | 60 +++++++++++++++++++++++++++--------------------------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/demo/theme.html b/demo/theme.html index e36e62eaa3..29b55df2e3 100644 --- a/demo/theme.html +++ b/demo/theme.html @@ -17,6 +17,7 @@ + @@ -83,6 +84,7 @@ + diff --git a/theme/mdn-like.css b/theme/mdn-like.css index bcd4100439..c12cb1f94f 100644 --- a/theme/mdn-like.css +++ b/theme/mdn-like.css @@ -3,42 +3,42 @@ Ported to CodeMirror by Peter Kroon Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues GitHub: @peterkroon - + The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation - + */ -.cm-s-mdn-like.CodeMirror { color: #999; font-family: monospace; background-color: #fff; } /**/ -.cm-s-mdn-like .CodeMirror-selected { background: #cfc !important; } /**/ - -.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; } /**/ -.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; margin-left: 3px; } /**/ -.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222 !important; } /**/ - -.cm-s-mdn-like .cm-keyword { color: #6262FF; } /**/ -.cm-s-mdn-like .cm-atom { color: #F90; } /**/ -.cm-s-mdn-like .cm-number { color: #ca7841; } /**/ -.cm-s-mdn-like .cm-def { color: #8DA6CE; } /**/ -.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; } /**/ -.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def { color: #07a; } /**/ - -.cm-s-mdn-like .cm-variable { color: #07a; } /**/ -.cm-s-mdn-like .cm-property { color: #905; } /**/ -.cm-s-mdn-like .cm-qualifier { color: #690; } /**/ - -.cm-s-mdn-like .cm-operator { color: #cda869; } /**/ -.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; } /**/ -.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; } /**/ +.cm-s-mdn-like.CodeMirror { color: #999; font-family: monospace; background-color: #fff; } +.cm-s-mdn-like .CodeMirror-selected { background: #cfc !important; } + +.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; } +.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; margin-left: 3px; } +div.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; } + +.cm-s-mdn-like .cm-keyword { color: #6262FF; } +.cm-s-mdn-like .cm-atom { color: #F90; } +.cm-s-mdn-like .cm-number { color: #ca7841; } +.cm-s-mdn-like .cm-def { color: #8DA6CE; } +.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; } +.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def { color: #07a; } + +.cm-s-mdn-like .cm-variable { color: #07a; } +.cm-s-mdn-like .cm-property { color: #905; } +.cm-s-mdn-like .cm-qualifier { color: #690; } + +.cm-s-mdn-like .cm-operator { color: #cda869; } +.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; } +.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; } .cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/ .cm-s-mdn-like .cm-meta { color: #000; } /*?*/ .cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/ -.cm-s-mdn-like .cm-tag { color: #997643; } /**/ +.cm-s-mdn-like .cm-tag { color: #997643; } .cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/ -.cm-s-mdn-like .cm-header { color: #FF6400; } /**/ -.cm-s-mdn-like .cm-hr { color: #AEAEAE; } /**/ -.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/ -.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; } /**/ +.cm-s-mdn-like .cm-header { color: #FF6400; } +.cm-s-mdn-like .cm-hr { color: #AEAEAE; } +.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } +.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; } -.cm-s-mdn-like .CodeMirror-activeline-background {background: #efefff !important;} /**/ -.cm-s-mdn-like .CodeMirror-matchingbracket {outline:1px solid grey; color: inherit !important;} /**/ +div.cm-s-mdn-like .CodeMirror-activeline-background {background: #efefff;} +div.cm-s-mdn-like span.CodeMirror-matchingbracket {outline:1px solid grey; color: inherit;} .cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,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); } From e2ccf3a8e5e4cfc8af2017df79a72176cb7f7ed2 Mon Sep 17 00:00:00 2001 From: Triangle717 Date: Tue, 21 Jan 2014 14:30:48 -0500 Subject: [PATCH 017/100] [css mode] Added missing animation-fill-mode property Also resorted the next few lines so one would not stick out farther than the others. https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode --- mode/css/css.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mode/css/css.js b/mode/css/css.js index c94f1daa54..2e61dcecc0 100644 --- a/mode/css/css.js +++ b/mode/css/css.js @@ -354,10 +354,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) { var propertyKeywords_ = [ "align-content", "align-items", "align-self", "alignment-adjust", "alignment-baseline", "anchor-point", "animation", "animation-delay", - "animation-direction", "animation-duration", "animation-iteration-count", - "animation-name", "animation-play-state", "animation-timing-function", - "appearance", "azimuth", "backface-visibility", "background", - "background-attachment", "background-clip", "background-color", + "animation-direction", "animation-duration", "animation-fill-mode", + "animation-iteration-count", "animation-name", "animation-play-state", + "animation-timing-function", "appearance", "azimuth", "backface-visibility", + "background", "background-attachment", "background-clip", "background-color", "background-image", "background-origin", "background-position", "background-repeat", "background-size", "baseline-shift", "binding", "bleed", "bookmark-label", "bookmark-level", "bookmark-state", From 327b688dc548bb336d6a547d34530ad47fa8553b Mon Sep 17 00:00:00 2001 From: Travis Heppe Date: Wed, 22 Jan 2014 00:14:57 -0800 Subject: [PATCH 018/100] [vim] Fix unescaping of escaped strings for search and replace Add unit tests. --- keymap/vim.js | 22 ++++++++++++++++++++-- test/vim_test.js | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index a08c5c2f7c..21c74c4cf4 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -2750,10 +2750,28 @@ if (!escapeNextChar && c == '/') { slashes.push(i); } - escapeNextChar = (c == '\\'); + escapeNextChar = !escapeNextChar && (c == '\\'); } return slashes; } + + function unescapeString(str) { + var escapeNextChar = false; + var out = []; + for (var i = 0; i < str.length; i++) { + var c = str.charAt(i); + var next = str.charAt(i+1); + var slashComesNext = (next == '\\') || (next == '/'); + if (c !== '\\' || escapeNextChar || !slashComesNext) { + out.push(c); + escapeNextChar = false; + } else { + escapeNextChar = true; + } + } + return out.join(''); + } + /** * Extract the regular expression from the query and return a Regexp object. * Returns null if the query is blank. @@ -3278,7 +3296,7 @@ var count; var confirm = false; // Whether to confirm each replace. if (slashes[1]) { - replacePart = argString.substring(slashes[1] + 1, slashes[2]); + replacePart = unescapeString(argString.substring(slashes[1] + 1, slashes[2])); } if (slashes[2]) { // After the 3rd slash, we can have flags followed by a space followed diff --git a/test/vim_test.js b/test/vim_test.js index d39753c10c..dd88bbf8c6 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -2264,6 +2264,8 @@ testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) { helpers.doEx('sort! d'); eq('a3\nb2\nc1\nz\ny', cm.getValue()); }, { value: 'a3\nz\nc1\ny\nb2'}); + + testVim('ex_substitute_same_line', function(cm, vim, helpers) { cm.setCursor(1, 0); helpers.doEx('s/one/two'); @@ -2299,6 +2301,25 @@ testVim('ex_substitute_empty_query', function(cm, vim, helpers) { helpers.doEx('s//b'); eq('abb ab2 ab3', cm.getValue()); }, { value: 'a11 a12 a13' }); +testVim('ex_substitute_slash_regex', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/\\//|'); + eq('one|two \n three|four', cm.getValue()); +}, { value: 'one/two \n three/four'}); +testVim('ex_substitute_backslashslash_regex', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/\\\\/,'); + eq('one,two \n three,four', cm.getValue()); +}, { value: 'one\\two \n three\\four'}); +testVim('ex_substitute_slash_replacement', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/,/\\/'); + eq('one/two \n three/four', cm.getValue()); +}, { value: 'one,two \n three,four'}); +testVim('ex_substitute_backslash_replacement', function(cm, vim, helpers) { + helpers.doEx('%s/,/\\\\/g'); + eq('one\\two \n three\\four', cm.getValue()); +}, { value: 'one,two \n three,four'}); testVim('ex_substitute_count', function(cm, vim, helpers) { cm.setCursor(1, 0); helpers.doEx('s/\\d/0/i 2'); From 38c84639c3606c209b4e1aad3a56ffb85ad65051 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 23 Jan 2014 15:12:48 +0100 Subject: [PATCH 019/100] [css mode] Add simple support for @keyframes Closes #2161 --- mode/css/css.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mode/css/css.js b/mode/css/css.js index 2e61dcecc0..06d73455da 100644 --- a/mode/css/css.js +++ b/mode/css/css.js @@ -140,6 +140,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) { return pushContext(state, stream, "media"); } else if (type == "@font-face") { return "font_face_before"; + } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { + return "keyframes"; } else if (type && type.charAt(0) == "@") { return pushContext(state, stream, "at"); } else if (type == "hash") { @@ -264,6 +266,12 @@ CodeMirror.defineMode("css", function(config, parserConfig) { return "font_face"; }; + states.keyframes = function(type, stream, state) { + if (type == "word") { override = "variable"; return "keyframes"; } + if (type == "{") return pushContext(state, stream, "top"); + return pass(type, stream, state); + }; + states.at = function(type, stream, state) { if (type == ";") return popContext(state); if (type == "{" || type == "}") return popAndPass(type, stream, state); From 31a264ab947e2a0992abe80f2bd4df57181ad2bb Mon Sep 17 00:00:00 2001 From: Peter Kroon Date: Thu, 23 Jan 2014 15:54:44 +0100 Subject: [PATCH 020/100] [less] don't confuse less mode.. ..with the newly added simple support for @keyframes --- mode/css/css.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mode/css/css.js b/mode/css/css.js index 06d73455da..b2c74a92ea 100644 --- a/mode/css/css.js +++ b/mode/css/css.js @@ -676,7 +676,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { } }, "@": function(stream) { - if (stream.match(/^(charset|document|font-face|import|keyframes|media|namespace|page|supports)\b/, false)) return false; + if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; stream.eatWhile(/[\w\\\-]/); if (stream.match(/^\s*:/, false)) return ["variable-2", "variable-definition"]; From a0522c12766735a033a9b7aeed21bce2922dcded Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Thu, 23 Jan 2014 18:25:34 +0400 Subject: [PATCH 021/100] Expose triggerOnKeyPress and triggerOnKeyUp for testing --- lib/codemirror.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 67e5291f67..c7a5c6dd1c 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -1629,10 +1629,7 @@ window.CodeMirror = (function() { } setTimeout(unregister, 5000); - on(d.input, "keyup", operation(cm, function(e) { - if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; - if (e.keyCode == 16) cm.doc.sel.shift = false; - })); + on(d.input, "keyup", operation(cm, onKeyUp)); on(d.input, "input", function() { if (ie && !ie_lt9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; fastPoll(cm); @@ -2142,6 +2139,12 @@ window.CodeMirror = (function() { return handled; } + function onKeyUp(e) { + var cm = this; + if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; + if (e.keyCode == 16) cm.doc.sel.shift = false; + } + var lastStoppedKey = null; function onKeyDown(e) { var cm = this; @@ -3157,6 +3160,8 @@ window.CodeMirror = (function() { }, triggerOnKeyDown: operation(null, onKeyDown), + triggerOnKeyPress: operation(null, onKeyPress), + triggerOnKeyUp: operation(null, onKeyUp), execCommand: function(cmd) { if (commands.hasOwnProperty(cmd)) From ccd334ce7180542c89939871875fbeb81ad1a4cc Mon Sep 17 00:00:00 2001 From: Yunchi Luo Date: Thu, 23 Jan 2014 23:37:13 -0500 Subject: [PATCH 022/100] [vim] Use key character instead of key identifier to map all character keys without modifiers --- keymap/vim.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index 21c74c4cf4..e837ee4994 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -3513,18 +3513,10 @@ * Shift + key modifier to the resulting letter, while preserving other * modifers. */ - // TODO: Figure out a way to catch capslock. function cmKeyToVimKey(key, modifier) { var vimKey = key; - if (isUpperCase(vimKey)) { - // Convert to lower case if shift is not the modifier since the key - // we get from CodeMirror is always upper case. - if (modifier == 'Shift') { - modifier = null; - } - else { + if (isUpperCase(vimKey) && modifier == 'Ctrl') { vimKey = vimKey.toLowerCase(); - } } if (modifier) { // Vim will parse modifier+key combination as a single key. @@ -3550,9 +3542,9 @@ function bindKeys(keys, modifier) { for (var i = 0; i < keys.length; i++) { var key = keys[i]; - if (!modifier && inArray(key, specialSymbols)) { - // Wrap special symbols with '' because that's how CodeMirror binds - // them. + if (!modifier && key.length == 1) { + // Wrap all keys without modifiers with '' to identify them by their + // key characters instead of key identifiers. key = "'" + key + "'"; } var vimKey = cmKeyToVimKey(keys[i], modifier); @@ -3561,7 +3553,7 @@ } } bindKeys(upperCaseAlphabet); - bindKeys(upperCaseAlphabet, 'Shift'); + bindKeys(lowerCaseAlphabet); bindKeys(upperCaseAlphabet, 'Ctrl'); bindKeys(specialSymbols); bindKeys(specialSymbols, 'Ctrl'); From c7e4ad741dbfc62ab2e4394c1945cd048f99a727 Mon Sep 17 00:00:00 2001 From: Grant Skinner Date: Sat, 25 Jan 2014 12:22:44 -0700 Subject: [PATCH 023/100] Added "historyAdded" doc event. Added a doc event "historyAdded" which is dispatched when a new entry is added to the document history. It is not dispatched when a history entry is amended. This allows CM's history to be integrated easily into application level undo/redo. Signed-off-by: Grant Skinner --- lib/codemirror.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/codemirror.js b/lib/codemirror.js index c7a5c6dd1c..c26d0126e7 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -5329,6 +5329,8 @@ window.CodeMirror = (function() { hist.lastTime = time; hist.lastOp = opId; hist.lastOrigin = change.origin; + + if (!last) { signal(doc, "historyAdded"); } } function removeClearedSpans(spans) { From 98a28993299e948c48a8402d5b57e4c8dd3e122c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sun, 26 Jan 2014 13:36:30 +0100 Subject: [PATCH 024/100] Fix trailing whitespace from c7e4ad741dbfc62ab2e4394c1945cd048f99a727 --- lib/codemirror.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index c26d0126e7..bb970cd1be 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -5329,8 +5329,8 @@ window.CodeMirror = (function() { hist.lastTime = time; hist.lastOp = opId; hist.lastOrigin = change.origin; - - if (!last) { signal(doc, "historyAdded"); } + + if (!last) signal(doc, "historyAdded"); } function removeClearedSpans(spans) { From 5523871d2004e323d3b0e5c2e0fcd7e23d6cf212 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sun, 26 Jan 2014 18:02:16 +0100 Subject: [PATCH 025/100] Fix bug in keymap table, properly bind Ctrl-Up --- lib/codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index bb970cd1be..15c7f9edf2 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -3636,7 +3636,7 @@ window.CodeMirror = (function() { // default. Unknown commands are simply ignored. keyMap.pcDefault = { "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd", + "Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd", "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", From f9aa052f92015cce3a79bd814866b0503778a4de Mon Sep 17 00:00:00 2001 From: Bernhard Sirlinger Date: Sun, 26 Jan 2014 23:02:22 +0100 Subject: [PATCH 026/100] Signal overwriteToggle event Issue #2180 --- lib/codemirror.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/codemirror.js b/lib/codemirror.js index 15c7f9edf2..dd94503084 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -3228,6 +3228,8 @@ window.CodeMirror = (function() { this.display.cursor.className += " CodeMirror-overwrite"; else this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", ""); + + signal(this, "overwriteToggle", this, this.state.overwrite); }, hasFocus: function() { return document.activeElement == this.display.input; }, From 55223f6003d372d84e631e3b257d1392187e58ef Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 28 Jan 2014 11:15:58 +0100 Subject: [PATCH 027/100] [foldcode addon] Add an isFolded method --- addon/fold/foldcode.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addon/fold/foldcode.js b/addon/fold/foldcode.js index 5c00d7093c..3c0817b8fe 100644 --- a/addon/fold/foldcode.js +++ b/addon/fold/foldcode.js @@ -62,6 +62,12 @@ doFold(this, pos, options, force); }); + CodeMirror.defineExtension("isFolded", function(pos) { + var marks = this.findMarksAt(pos); + for (var i = 0; i < marks.length; ++i) + if (marks[i].__isFold) return true; + }); + CodeMirror.commands.fold = function(cm) { cm.foldCode(cm.getCursor()); }; From 014157911ab5f55f91281fe5dca52bcea954ca86 Mon Sep 17 00:00:00 2001 From: Manuel Rego Casasnovas Date: Mon, 27 Jan 2014 21:48:11 +0100 Subject: [PATCH 028/100] [css mode] Update Grid Layout property names Some properties were outdated and some other were missing according to last version of the CSS Grid Layout spec: http://www.w3.org/TR/css3-grid-layout/#property-index --- mode/css/css.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mode/css/css.js b/mode/css/css.js index b2c74a92ea..6cc4b71b05 100644 --- a/mode/css/css.js +++ b/mode/css/css.js @@ -396,10 +396,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) { "font-stretch", "font-style", "font-synthesis", "font-variant", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", - "font-weight", "grid-cell", "grid-column", "grid-column-align", - "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow", - "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span", - "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens", + "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", + "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end", + "grid-column-start", "grid-row", "grid-row-end", "grid-row-start", + "grid-template", "grid-template-areas", "grid-template-columns", + "grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon", "image-orientation", "image-rendering", "image-resolution", "inline-box-align", "justify-content", "left", "letter-spacing", "line-break", "line-height", "line-stacking", "line-stacking-ruby", From b538a4ed74367cc66bc1d3067826ee60887e8d29 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 28 Jan 2014 11:25:36 +0100 Subject: [PATCH 029/100] Remove remaining uses of tabMode and enterMode in demos --- demo/changemode.html | 3 +- demo/fullscreen.html | 105 ++++++++++++------------------------------- demo/preview.html | 3 +- demo/search.html | 67 +++++++++++++-------------- mode/eiffel/index.html | 1 - mode/htmlembedded/index.html | 4 +- mode/htmlmixed/index.html | 2 +- mode/julia/index.html | 1 - mode/lua/index.html | 1 - mode/mirc/index.html | 5 +-- mode/octave/index.html | 1 - mode/php/index.html | 4 +- mode/python/index.html | 2 - mode/rpm/changes/index.html | 3 +- mode/ruby/index.html | 1 - mode/rust/index.html | 3 +- mode/sparql/index.html | 1 - mode/tcl/index.html | 15 +++---- mode/tiddlywiki/index.html | 1 - mode/turtle/index.html | 1 - mode/vb/index.html | 3 +- mode/velocity/index.html | 1 - test/test.js | 4 +- 23 files changed, 78 insertions(+), 154 deletions(-) diff --git a/demo/changemode.html b/demo/changemode.html index 9ea99b2d04..ad4c9d1b2c 100644 --- a/demo/changemode.html +++ b/demo/changemode.html @@ -41,8 +41,7 @@ diff --git a/mode/htmlmixed/index.html b/mode/htmlmixed/index.html index b46174351a..bd06bb504c 100644 --- a/mode/htmlmixed/index.html +++ b/mode/htmlmixed/index.html @@ -62,7 +62,7 @@ {matches: /(text|application)\/(x-)?vb(a|script)/i, mode: "vbscript"}] }; - var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: mixedMode, tabMode: "indent"}); + var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: mixedMode});

The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

diff --git a/mode/julia/index.html b/mode/julia/index.html index dd567a623b..945e1a91fc 100644 --- a/mode/julia/index.html +++ b/mode/julia/index.html @@ -178,7 +178,6 @@ }, lineNumbers: true, indentUnit: 4, - tabMode: "shift", matchBrackets: true }); diff --git a/mode/lua/index.html b/mode/lua/index.html index 69433e44ab..7f4eb2c84a 100644 --- a/mode/lua/index.html +++ b/mode/lua/index.html @@ -69,7 +69,6 @@ diff --git a/mode/php/index.html b/mode/php/index.html index aaf51c0f5a..1fb7435bb1 100644 --- a/mode/php/index.html +++ b/mode/php/index.html @@ -48,9 +48,7 @@ matchBrackets: true, mode: "application/x-httpd-php", indentUnit: 4, - indentWithTabs: true, - enterMode: "keep", - tabMode: "shift" + indentWithTabs: true }); diff --git a/mode/python/index.html b/mode/python/index.html index e8422fb77a..a1d6d2d838 100644 --- a/mode/python/index.html +++ b/mode/python/index.html @@ -150,7 +150,6 @@ singleLineStringErrors: false}, lineNumbers: true, indentUnit: 4, - tabMode: "shift", matchBrackets: true }); @@ -160,7 +159,6 @@ singleLineStringErrors: false}, lineNumbers: true, indentUnit: 4, - tabMode: "shift", matchBrackets: true }); diff --git a/mode/rpm/changes/index.html b/mode/rpm/changes/index.html index 18fe7ab7bf..0ade017966 100644 --- a/mode/rpm/changes/index.html +++ b/mode/rpm/changes/index.html @@ -58,8 +58,7 @@ var editor = CodeMirror.fromTextArea(document.getElementById("code"), { mode: {name: "changes"}, lineNumbers: true, - indentUnit: 4, - tabMode: "shift" + indentUnit: 4 }); diff --git a/mode/ruby/index.html b/mode/ruby/index.html index 2b3e1a3eb1..8f0ebca8e8 100644 --- a/mode/ruby/index.html +++ b/mode/ruby/index.html @@ -170,7 +170,6 @@ diff --git a/mode/sparql/index.html b/mode/sparql/index.html index 7c41e17b77..5f19d647bf 100644 --- a/mode/sparql/index.html +++ b/mode/sparql/index.html @@ -44,7 +44,6 @@ diff --git a/mode/tcl/index.html b/mode/tcl/index.html index 2c0d1a2dea..c48e253241 100644 --- a/mode/tcl/index.html +++ b/mode/tcl/index.html @@ -77,13 +77,13 @@ proc whois::311 {from key text} { if {[regexp -- {^[^\s]+\s(.+?)\s(.+?)\s(.+?)\s\*\s\:(.+)$} $text wholematch nick ident host realname]} { putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Host:${whois::textf} \ - $nick \(${ident}@${host}\) ${whois::tagf}Realname:${whois::textf} $realname" + $nick \(${ident}@${host}\) ${whois::tagf}Realname:${whois::textf} $realname" } } proc whois::multi {from key text} { if {[regexp {\:(.*)$} $text match $key]} { putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Note:${whois::textf} [subst $$key]" - return 1 + return 1 } } proc whois::312 {from key text} { @@ -98,7 +98,7 @@ proc whois::317 {from key text} { if {[regexp -- {.*\s(\d+)\s(\d+)\s\:} $text wholematch idle signon]} { putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Connected:${whois::textf} \ - [ctime $signon] ${whois::tagf}Idle:${whois::textf} [duration $idle]" + [ctime $signon] ${whois::tagf}Idle:${whois::textf} [duration $idle]" } } proc whois::301 {from key text} { @@ -108,7 +108,7 @@ } proc whois::318 {from key text} { namespace eval whois { - variable channel "" + variable channel "" } variable whois::channel "" } @@ -118,8 +118,8 @@ proc whois::list {nick host hand chan text} { if {[lsearch -exact [channel info $chan] "+${whois::command}"] != -1} { namespace eval whois { - variable channel "" - } + variable channel "" + } variable whois::channel $chan putserv "WHOIS $text" } @@ -129,8 +129,7 @@ diff --git a/mode/turtle/index.html b/mode/turtle/index.html index 74b5f896d9..27689c34ff 100644 --- a/mode/turtle/index.html +++ b/mode/turtle/index.html @@ -41,7 +41,6 @@ diff --git a/mode/vb/index.html b/mode/vb/index.html index 42c3e5261c..8b81a88b91 100644 --- a/mode/vb/index.html +++ b/mode/vb/index.html @@ -81,8 +81,7 @@ editor = CodeMirror.fromTextArea(document.getElementById("solution"), { lineNumbers: true, mode: "text/x-vb", - readOnly: false, - tabMode: "shift" + readOnly: false }); runTest(); } diff --git a/mode/velocity/index.html b/mode/velocity/index.html index 023542d1d7..bd38b886b2 100644 --- a/mode/velocity/index.html +++ b/mode/velocity/index.html @@ -106,7 +106,6 @@ +