codemirror-rails 4.11 → 4.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a4bb46e0301a0f307a6f66351d88880b3491fda
4
- data.tar.gz: a0b67a693c500f1e6b6f111138b445b46316d22f
3
+ metadata.gz: 755dac8f6301821554cd558571336d2c8181b574
4
+ data.tar.gz: d4833e17c60976e47d8a2f88cf9e379e32c21939
5
5
  SHA512:
6
- metadata.gz: a6240ed9f991dff857cca43479ed33f3adabf85d443408f88228f9a5a9b7e31e63643d59b617bf6c3da1b5ad36f25beb99e8bf9190b1ec6b809fc39b11de74ee
7
- data.tar.gz: a2af425ce6c2042e65526137fdd577cd72a88975f779bf7ec7458d30dc1e2ea6ec244ec17fbfc773b096c4f4ee0861e9b6ddc5e76b8fbda9fcbc0496d7f24101
6
+ metadata.gz: d0ae3d0e459db75b2e02b13a8277f2717221f0677f6ccd25ad942480b6f39262a81d7a11f0c75982ce97a83ba6de79f9930755423b684f8c5340585698f77870
7
+ data.tar.gz: 266211c02fe70825f9df0643b7fae07692e9668b4d86885804a98e750001dd4ca2257febe6bae520421c0f162942c070f93a92dcd96423eb608bf6cf54040766
@@ -1,6 +1,6 @@
1
1
  module Codemirror
2
2
  module Rails
3
- VERSION = '4.11'
4
- CODEMIRROR_VERSION = '4.11'
3
+ VERSION = '4.12'
4
+ CODEMIRROR_VERSION = '4.12'
5
5
  end
6
6
  end
@@ -112,6 +112,11 @@
112
112
  maybeUpdateLineNumberWidth(this);
113
113
  for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
114
114
  endOperation(this);
115
+ // Suppress optimizelegibility in Webkit, since it breaks text
116
+ // measuring on line wrapping boundaries.
117
+ if (webkit && options.lineWrapping &&
118
+ getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
119
+ display.lineDiv.style.textRendering = "auto";
115
120
  }
116
121
 
117
122
  // DISPLAY CONSTRUCTOR
@@ -1847,7 +1852,8 @@
1847
1852
 
1848
1853
  // Converts a {top, bottom, left, right} box from line-local
1849
1854
  // coordinates into another coordinate system. Context may be one of
1850
- // "line", "div" (display.lineDiv), "local"/null (editor), or "page".
1855
+ // "line", "div" (display.lineDiv), "local"/null (editor), "window",
1856
+ // or "page".
1851
1857
  function intoCoordSystem(cm, lineObj, rect, context) {
1852
1858
  if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
1853
1859
  var size = widgetHeight(lineObj.widgets[i]);
@@ -2759,7 +2765,9 @@
2759
2765
  // Return true when the given mouse event happened in a widget
2760
2766
  function eventInWidget(display, e) {
2761
2767
  for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
2762
- if (!n || n.getAttribute("cm-ignore-events") == "true" || n.parentNode == display.sizer && n != display.mover) return true;
2768
+ if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
2769
+ (n.parentNode == display.sizer && n != display.mover))
2770
+ return true;
2763
2771
  }
2764
2772
  }
2765
2773
 
@@ -3788,7 +3796,9 @@
3788
3796
 
3789
3797
  var lendiff = change.text.length - (to.line - from.line) - 1;
3790
3798
  // Remember that these lines changed, for updating the display
3791
- if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
3799
+ if (change.full)
3800
+ regChange(cm);
3801
+ else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
3792
3802
  regLineChange(cm, from.line, "text");
3793
3803
  else
3794
3804
  regChange(cm, from.line, to.line + 1, lendiff);
@@ -5570,6 +5580,7 @@
5570
5580
  // spans partially within the change. Returns an array of span
5571
5581
  // arrays with one element for each line in (after) the change.
5572
5582
  function stretchSpansOverChange(doc, change) {
5583
+ if (change.full) return null;
5573
5584
  var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
5574
5585
  var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
5575
5586
  if (!oldFirst && !oldLast) return null;
@@ -5879,7 +5890,9 @@
5879
5890
  if (!contains(document.body, widget.node)) {
5880
5891
  var parentStyle = "position: relative;";
5881
5892
  if (widget.coverGutter)
5882
- parentStyle += "margin-left: -" + widget.cm.getGutterElement().offsetWidth + "px;";
5893
+ parentStyle += "margin-left: -" + widget.cm.display.gutters.offsetWidth + "px;";
5894
+ if (widget.noHScroll)
5895
+ parentStyle += "width: " + widget.cm.display.wrapper.clientWidth + "px;";
5883
5896
  removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, parentStyle));
5884
5897
  }
5885
5898
  return widget.height = widget.node.offsetHeight;
@@ -6342,17 +6355,24 @@
6342
6355
  updateLine(line, text, spans, estimateHeight);
6343
6356
  signalLater(line, "change", line, change);
6344
6357
  }
6358
+ function linesFor(start, end) {
6359
+ for (var i = start, result = []; i < end; ++i)
6360
+ result.push(new Line(text[i], spansFor(i), estimateHeight));
6361
+ return result;
6362
+ }
6345
6363
 
6346
6364
  var from = change.from, to = change.to, text = change.text;
6347
6365
  var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
6348
6366
  var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
6349
6367
 
6350
6368
  // Adjust the line structure
6351
- if (isWholeLineUpdate(doc, change)) {
6369
+ if (change.full) {
6370
+ doc.insert(0, linesFor(0, text.length));
6371
+ doc.remove(text.length, doc.size - text.length);
6372
+ } else if (isWholeLineUpdate(doc, change)) {
6352
6373
  // This is a whole-line replace. Treated specially to make
6353
6374
  // sure line objects move the way they are supposed to.
6354
- for (var i = 0, added = []; i < text.length - 1; ++i)
6355
- added.push(new Line(text[i], spansFor(i), estimateHeight));
6375
+ var added = linesFor(0, text.length - 1);
6356
6376
  update(lastLine, lastLine.text, lastSpans);
6357
6377
  if (nlines) doc.remove(from.line, nlines);
6358
6378
  if (added.length) doc.insert(from.line, added);
@@ -6360,8 +6380,7 @@
6360
6380
  if (text.length == 1) {
6361
6381
  update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
6362
6382
  } else {
6363
- for (var added = [], i = 1; i < text.length - 1; ++i)
6364
- added.push(new Line(text[i], spansFor(i), estimateHeight));
6383
+ var added = linesFor(1, text.length - 1);
6365
6384
  added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
6366
6385
  update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6367
6386
  doc.insert(from.line + 1, added);
@@ -6372,8 +6391,7 @@
6372
6391
  } else {
6373
6392
  update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6374
6393
  update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
6375
- for (var i = 1, added = []; i < text.length - 1; ++i)
6376
- added.push(new Line(text[i], spansFor(i), estimateHeight));
6394
+ var added = linesFor(1, text.length - 1);
6377
6395
  if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
6378
6396
  doc.insert(from.line + 1, added);
6379
6397
  }
@@ -6584,7 +6602,7 @@
6584
6602
  setValue: docMethodOp(function(code) {
6585
6603
  var top = Pos(this.first, 0), last = this.first + this.size - 1;
6586
6604
  makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
6587
- text: splitLines(code), origin: "setValue"}, true);
6605
+ text: splitLines(code), origin: "setValue", full: true}, true);
6588
6606
  setSelection(this, simpleSelection(top));
6589
6607
  }),
6590
6608
  replaceRange: function(code, from, to, origin) {
@@ -7464,13 +7482,11 @@
7464
7482
  if (array[i] == elt) return i;
7465
7483
  return -1;
7466
7484
  }
7467
- if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); };
7468
7485
  function map(array, f) {
7469
7486
  var out = [];
7470
7487
  for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
7471
7488
  return out;
7472
7489
  }
7473
- if ([].map) map = function(array, f) { return array.map(f); };
7474
7490
 
7475
7491
  function createObj(base, props) {
7476
7492
  var inst;
@@ -8023,7 +8039,7 @@
8023
8039
 
8024
8040
  // THE END
8025
8041
 
8026
- CodeMirror.version = "4.11.0";
8042
+ CodeMirror.version = "4.12.0";
8027
8043
 
8028
8044
  return CodeMirror;
8029
8045
  });
@@ -94,15 +94,15 @@
94
94
  }
95
95
  }
96
96
 
97
- function autoCloseSlash(cm) {
98
- if (cm.getOption("disableInput")) return CodeMirror.Pass;
97
+ function autoCloseCurrent(cm, typingSlash) {
99
98
  var ranges = cm.listSelections(), replacements = [];
99
+ var head = typingSlash ? "/" : "</";
100
100
  for (var i = 0; i < ranges.length; i++) {
101
101
  if (!ranges[i].empty()) return CodeMirror.Pass;
102
102
  var pos = ranges[i].head, tok = cm.getTokenAt(pos);
103
103
  var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
104
- if (tok.type == "string" || tok.string.charAt(0) != "<" ||
105
- tok.start != pos.ch - 1)
104
+ if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
105
+ tok.start != pos.ch - 1))
106
106
  return CodeMirror.Pass;
107
107
  // Kludge to get around the fact that we are not in XML mode
108
108
  // when completing in JS/CSS snippet in htmlmixed mode. Does not
@@ -110,16 +110,16 @@
110
110
  // way to go from a mixed mode to its current XML state).
111
111
  if (inner.mode.name != "xml") {
112
112
  if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
113
- replacements[i] = "/script>";
113
+ replacements[i] = head + "script>";
114
114
  else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
115
- replacements[i] = "/style>";
115
+ replacements[i] = head + "style>";
116
116
  else
117
117
  return CodeMirror.Pass;
118
118
  } else {
119
119
  if (!state.context || !state.context.tagName ||
120
120
  closingTagExists(cm, state.context.tagName, pos, state))
121
121
  return CodeMirror.Pass;
122
- replacements[i] = "/" + state.context.tagName + ">";
122
+ replacements[i] = head + state.context.tagName + ">";
123
123
  }
124
124
  }
125
125
  cm.replaceSelections(replacements);
@@ -129,6 +129,13 @@
129
129
  cm.indentLine(ranges[i].head.line);
130
130
  }
131
131
 
132
+ function autoCloseSlash(cm) {
133
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
134
+ autoCloseCurrent(cm, true);
135
+ }
136
+
137
+ CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
138
+
132
139
  function indexOf(collection, elt) {
133
140
  if (collection.indexOf) return collection.indexOf(elt);
134
141
  for (var i = 0, e = collection.length; i < e; ++i)
@@ -142,4 +142,8 @@
142
142
  return editorOptions[name];
143
143
  return defaultOptions[name];
144
144
  }
145
+
146
+ CodeMirror.defineExtension("foldOption", function(options, name) {
147
+ return getOption(this, options, name);
148
+ });
145
149
  });
@@ -67,14 +67,16 @@
67
67
 
68
68
  function updateFoldInfo(cm, from, to) {
69
69
  var opts = cm.state.foldGutter.options, cur = from;
70
+ var minSize = cm.foldOption(opts, "minFoldSize");
71
+ var func = cm.foldOption(opts, "rangeFinder");
70
72
  cm.eachLine(from, to, function(line) {
71
73
  var mark = null;
72
74
  if (isFolded(cm, cur)) {
73
75
  mark = marker(opts.indicatorFolded);
74
76
  } else {
75
- var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
77
+ var pos = Pos(cur, 0);
76
78
  var range = func && func(cm, pos);
77
- if (range && range.from.line + 1 < range.to.line)
79
+ if (range && range.to.line - range.from.line >= minSize)
78
80
  mark = marker(opts.indicatorOpen);
79
81
  }
80
82
  cm.setGutterMarker(line, opts.gutter, mark);
@@ -259,11 +259,13 @@
259
259
  function makeConnections(dv) {
260
260
  if (!dv.showDifferences) return;
261
261
 
262
- var align = dv.mv.options.connect == "align";
262
+ var align = dv.mv.options.connect == "align", oldScrollEdit, oldScrollOrig;
263
263
  if (align) {
264
264
  if (!dv.orig.curOp) return dv.orig.operation(function() {
265
265
  makeConnections(dv);
266
266
  });
267
+ oldScrollEdit = dv.edit.getScrollInfo().top;
268
+ oldScrollOrig = dv.orig.getScrollInfo().top;
267
269
  for (var i = 0; i < dv.aligners.length; i++)
268
270
  dv.aligners[i].clear();
269
271
  dv.aligners.length = 0;
@@ -293,6 +295,8 @@
293
295
  dv.aligners.push(padBelow(dv.edit, 0, extraSpaceAbove.edit));
294
296
  if (extraSpaceAbove.orig)
295
297
  dv.aligners.push(padBelow(dv.orig, 0, extraSpaceAbove.orig));
298
+ dv.edit.scrollTo(null, oldScrollEdit);
299
+ dv.orig.scrollTo(null, oldScrollOrig);
296
300
  }
297
301
  }
298
302
 
@@ -116,7 +116,7 @@
116
116
  var curState = states[state.state];
117
117
  for (var i = 0; i < curState.length; i++) {
118
118
  var rule = curState[i];
119
- var matches = stream.match(rule.regex);
119
+ var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
120
120
  if (matches) {
121
121
  if (rule.data.next) {
122
122
  state.state = rule.data.next;
@@ -27,14 +27,16 @@
27
27
  CodeMirror.e_preventDefault(e);
28
28
  var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
29
29
  var start = e[axis], startpos = self.pos;
30
+ function done() {
31
+ CodeMirror.off(document, "mousemove", move);
32
+ CodeMirror.off(document, "mouseup", done);
33
+ }
30
34
  function move(e) {
31
- if (e.which != 1) {
32
- CodeMirror.off(document, "mousemove", move);
33
- return;
34
- }
35
+ if (e.which != 1) return done();
35
36
  self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
36
37
  }
37
38
  CodeMirror.on(document, "mousemove", move);
39
+ CodeMirror.on(document, "mouseup", done);
38
40
  });
39
41
 
40
42
  CodeMirror.on(this.node, "click", function(e) {
@@ -0,0 +1,95 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineOption("selectionPointer", false, function(cm, val) {
15
+ var data = cm.state.selectionPointer;
16
+ if (data) {
17
+ CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove);
18
+ CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout);
19
+ cm.off("cursorActivity", reset);
20
+ cm.off("scroll", reset);
21
+ cm.state.selectionPointer = null;
22
+ cm.display.lineDiv.style.cursor = "";
23
+ }
24
+ if (val) {
25
+ data = cm.state.selectionPointer = {
26
+ value: typeof val == "string" ? val : "default",
27
+ mousemove: function(event) { mousemove(cm, event); },
28
+ mouseout: function(event) { mouseout(cm, event); },
29
+ rects: null,
30
+ mouseX: null, mouseY: null,
31
+ willUpdate: false
32
+ };
33
+ CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove);
34
+ CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout);
35
+ cm.on("cursorActivity", reset);
36
+ cm.on("scroll", reset);
37
+ }
38
+ });
39
+
40
+ function mousemove(cm, event) {
41
+ var data = cm.state.selectionPointer;
42
+ if (event.buttons == null ? event.which : event.buttons) {
43
+ data.mouseX = data.mouseY = null;
44
+ } else {
45
+ data.mouseX = event.clientX;
46
+ data.mouseY = event.clientY;
47
+ }
48
+ scheduleUpdate(cm);
49
+ }
50
+
51
+ function mouseout(cm, event) {
52
+ if (!cm.getWrapperElement().contains(event.relatedTarget)) {
53
+ var data = cm.state.selectionPointer;
54
+ data.mouseX = data.mouseY = null;
55
+ scheduleUpdate(cm);
56
+ }
57
+ }
58
+
59
+ function reset(cm) {
60
+ cm.state.selectionPointer.rects = null;
61
+ scheduleUpdate(cm);
62
+ }
63
+
64
+ function scheduleUpdate(cm) {
65
+ if (!cm.state.selectionPointer.willUpdate) {
66
+ cm.state.selectionPointer.willUpdate = true;
67
+ setTimeout(function() {
68
+ update(cm);
69
+ cm.state.selectionPointer.willUpdate = false;
70
+ }, 50);
71
+ }
72
+ }
73
+
74
+ function update(cm) {
75
+ var data = cm.state.selectionPointer;
76
+ if (!data) return;
77
+ if (data.rects == null && data.mouseX != null) {
78
+ data.rects = [];
79
+ if (cm.somethingSelected()) {
80
+ for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling)
81
+ data.rects.push(sel.getBoundingClientRect());
82
+ }
83
+ }
84
+ var inside = false;
85
+ if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) {
86
+ var rect = data.rects[i];
87
+ if (rect.left <= data.mouseX && rect.right >= data.mouseX &&
88
+ rect.top <= data.mouseY && rect.bottom >= data.mouseY)
89
+ inside = true;
90
+ }
91
+ var cursor = inside ? data.value : "";
92
+ if (cm.display.lineDiv.style.cursor != cursor)
93
+ cm.display.lineDiv.style.cursor = cursor;
94
+ }
95
+ });
@@ -395,6 +395,7 @@
395
395
  "Ctrl-X U": repeated("undo"),
396
396
  "Ctrl-X K": "close",
397
397
  "Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
398
+ "Ctrl-X H": "selectAll",
398
399
 
399
400
  "Ctrl-Q Tab": repeated("insertTab"),
400
401
  "Ctrl-U": addPrefixMap
@@ -3469,6 +3469,12 @@
3469
3469
  },
3470
3470
  setReversed: function(reversed) {
3471
3471
  vimGlobalState.isReversed = reversed;
3472
+ },
3473
+ getScrollbarAnnotate: function() {
3474
+ return this.annotate;
3475
+ },
3476
+ setScrollbarAnnotate: function(annotate) {
3477
+ this.annotate = annotate;
3472
3478
  }
3473
3479
  };
3474
3480
  function getSearchState(cm) {
@@ -3747,14 +3753,21 @@
3747
3753
  };
3748
3754
  }
3749
3755
  function highlightSearchMatches(cm, query) {
3750
- var overlay = getSearchState(cm).getOverlay();
3756
+ var searchState = getSearchState(cm);
3757
+ var overlay = searchState.getOverlay();
3751
3758
  if (!overlay || query != overlay.query) {
3752
3759
  if (overlay) {
3753
3760
  cm.removeOverlay(overlay);
3754
3761
  }
3755
3762
  overlay = searchOverlay(query);
3756
3763
  cm.addOverlay(overlay);
3757
- getSearchState(cm).setOverlay(overlay);
3764
+ if (cm.showMatchesOnScrollbar) {
3765
+ if (searchState.getScrollbarAnnotate()) {
3766
+ searchState.getScrollbarAnnotate().clear();
3767
+ }
3768
+ searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));
3769
+ }
3770
+ searchState.setOverlay(overlay);
3758
3771
  }
3759
3772
  }
3760
3773
  function findNext(cm, prev, query, repeat) {
@@ -3779,8 +3792,13 @@
3779
3792
  });
3780
3793
  }
3781
3794
  function clearSearchHighlight(cm) {
3795
+ var state = getSearchState(cm);
3782
3796
  cm.removeOverlay(getSearchState(cm).getOverlay());
3783
- getSearchState(cm).setOverlay(null);
3797
+ state.setOverlay(null);
3798
+ if (state.getScrollbarAnnotate()) {
3799
+ state.getScrollbarAnnotate().clear();
3800
+ state.setScrollbarAnnotate(null);
3801
+ }
3784
3802
  }
3785
3803
  /**
3786
3804
  * Check if pos is in the specified range, INCLUSIVE.
@@ -4789,6 +4807,7 @@
4789
4807
  var macroModeState = vimGlobalState.macroModeState;
4790
4808
  var lastChange = macroModeState.lastInsertModeChanges;
4791
4809
  var keyName = CodeMirror.keyName(e);
4810
+ if (!keyName) { return; }
4792
4811
  function onKeyFound() {
4793
4812
  lastChange.changes.push(new InsertModeKey(keyName));
4794
4813
  return true;
@@ -408,7 +408,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
408
408
  "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
409
409
  "mat2 mat3 mat4 " +
410
410
  "sampler1D sampler2D sampler3D samplerCube " +
411
- "sampler1DShadow sampler2DShadow" +
411
+ "sampler1DShadow sampler2DShadow " +
412
412
  "const attribute uniform varying " +
413
413
  "break continue discard return " +
414
414
  "for while do if else struct " +
@@ -416,7 +416,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
416
416
  blockKeywords: words("for while do if else struct"),
417
417
  builtin: words("radians degrees sin cos tan asin acos atan " +
418
418
  "pow exp log exp2 sqrt inversesqrt " +
419
- "abs sign floor ceil fract mod min max clamp mix step smootstep " +
419
+ "abs sign floor ceil fract mod min max clamp mix step smoothstep " +
420
420
  "length distance dot cross normalize ftransform faceforward " +
421
421
  "reflect refract matrixCompMult " +
422
422
  "lessThan lessThanEqual greaterThan greaterThanEqual " +
@@ -433,12 +433,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
433
433
  "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
434
434
  "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
435
435
  "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
436
- "gl_FogCoord " +
436
+ "gl_FogCoord gl_PointCoord " +
437
437
  "gl_Position gl_PointSize gl_ClipVertex " +
438
438
  "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
439
439
  "gl_TexCoord gl_FogFragCoord " +
440
440
  "gl_FragCoord gl_FrontFacing " +
441
- "gl_FragColor gl_FragData gl_FragDepth " +
441
+ "gl_FragData gl_FragDepth " +
442
442
  "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
443
443
  "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
444
444
  "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
@@ -525,14 +525,14 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
525
525
  "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
526
526
  "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
527
527
  "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
528
- "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
528
+ "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "footnotes",
529
529
  "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
530
530
  "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
531
531
  "help", "hidden", "hide", "higher", "highlight", "highlighttext",
532
532
  "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
533
533
  "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
534
534
  "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
535
- "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
535
+ "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
536
536
  "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
537
537
  "landscape", "lao", "large", "larger", "left", "level", "lighter",
538
538
  "line-through", "linear", "lines", "list-item", "listbox", "listitem",
@@ -600,6 +600,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
600
600
  if (type == "if") return cont(expression, comprehension);
601
601
  }
602
602
 
603
+ function isContinuedStatement(state, textAfter) {
604
+ return state.lastType == "operator" || state.lastType == "," ||
605
+ isOperatorChar.test(textAfter.charAt(0)) ||
606
+ /[,.]/.test(textAfter.charAt(0));
607
+ }
608
+
603
609
  // Interface
604
610
 
605
611
  return {
@@ -651,7 +657,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
651
657
  else if (type == "form" && firstChar == "{") return lexical.indented;
652
658
  else if (type == "form") return lexical.indented + indentUnit;
653
659
  else if (type == "stat")
654
- return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
660
+ return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
655
661
  else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
656
662
  return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
657
663
  else if (lexical.align) return lexical.column + (closing ? 0 : 1);
@@ -780,16 +780,21 @@ CodeMirror.defineMode("perl",function(){
780
780
  return "meta";}
781
781
  return null;}
782
782
 
783
- return{
784
- startState:function(){
785
- return{
786
- tokenize:tokenPerl,
787
- chain:null,
788
- style:null,
789
- tail:null};},
790
- token:function(stream,state){
791
- return (state.tokenize||tokenPerl)(stream,state);}
792
- };});
783
+ return {
784
+ startState: function() {
785
+ return {
786
+ tokenize: tokenPerl,
787
+ chain: null,
788
+ style: null,
789
+ tail: null
790
+ };
791
+ },
792
+ token: function(stream, state) {
793
+ return (state.tokenize || tokenPerl)(stream, state);
794
+ },
795
+ lineComment: '#'
796
+ };
797
+ });
793
798
 
794
799
  CodeMirror.registerHelper("wordChars", "perl", /[\w$]/);
795
800
 
@@ -19,10 +19,11 @@ CodeMirror.defineMode("sass", function(config) {
19
19
  var keywords = ["true", "false", "null", "auto"];
20
20
  var keywordsRegexp = new RegExp("^" + keywords.join("|"));
21
21
 
22
- var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"];
22
+ var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-",
23
+ "\\!=", "/", "\\*", "%", "and", "or", "not", ";","\\{","\\}",":"];
23
24
  var opRegexp = tokenRegexp(operators);
24
25
 
25
- var pseudoElementsRegexp = /^::?[\w\-]+/;
26
+ var pseudoElementsRegexp = /^::?[a-zA-Z_][\w\-]*/;
26
27
 
27
28
  function urlTokens(stream, state) {
28
29
  var ch = stream.peek();
@@ -56,7 +57,7 @@ CodeMirror.defineMode("sass", function(config) {
56
57
  stream.next();
57
58
  state.tokenizer = tokenBase;
58
59
  } else {
59
- stream.next();
60
+ stream.skipToEnd();
60
61
  }
61
62
 
62
63
  return "comment";
@@ -64,7 +65,7 @@ CodeMirror.defineMode("sass", function(config) {
64
65
  }
65
66
 
66
67
  function buildStringTokenizer(quote, greedy) {
67
- if(greedy == null) { greedy = true; }
68
+ if (greedy == null) { greedy = true; }
68
69
 
69
70
  function stringTokenizer(stream, state) {
70
71
  var nextChar = stream.next();
@@ -135,128 +136,213 @@ CodeMirror.defineMode("sass", function(config) {
135
136
  return "operator";
136
137
  }
137
138
 
138
- if (ch === ".") {
139
+ // Strings
140
+ if (ch === '"' || ch === "'") {
139
141
  stream.next();
142
+ state.tokenizer = buildStringTokenizer(ch);
143
+ return "string";
144
+ }
140
145
 
141
- // Match class selectors
142
- if (stream.match(/^[\w-]+/)) {
143
- indent(state);
144
- return "atom";
145
- } else if (stream.peek() === "#") {
146
- indent(state);
147
- return "atom";
148
- } else {
149
- return "operator";
146
+ if(!state.cursorHalf){// state.cursorHalf === 0
147
+ // first half i.e. before : for key-value pairs
148
+ // including selectors
149
+
150
+ if (ch === ".") {
151
+ stream.next();
152
+ if (stream.match(/^[\w-]+/)) {
153
+ indent(state);
154
+ return "atom";
155
+ } else if (stream.peek() === "#") {
156
+ indent(state);
157
+ return "atom";
158
+ }
150
159
  }
151
- }
152
160
 
153
- if (ch === "#") {
154
- stream.next();
161
+ if (ch === "#") {
162
+ stream.next();
163
+ // ID selectors
164
+ if (stream.match(/^[\w-]+/)) {
165
+ indent(state);
166
+ return "atom";
167
+ }
168
+ if (stream.peek() === "#") {
169
+ indent(state);
170
+ return "atom";
171
+ }
172
+ }
173
+
174
+ // Variables
175
+ if (ch === "$") {
176
+ stream.next();
177
+ stream.eatWhile(/[\w-]/);
178
+ return "variable-2";
179
+ }
155
180
 
156
- // Hex numbers
157
- if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/))
181
+ // Numbers
182
+ if (stream.match(/^-?[0-9\.]+/))
158
183
  return "number";
159
184
 
160
- // ID selectors
161
- if (stream.match(/^[\w-]+/)) {
162
- indent(state);
185
+ // Units
186
+ if (stream.match(/^(px|em|in)\b/))
187
+ return "unit";
188
+
189
+ if (stream.match(keywordsRegexp))
190
+ return "keyword";
191
+
192
+ if (stream.match(/^url/) && stream.peek() === "(") {
193
+ state.tokenizer = urlTokens;
163
194
  return "atom";
164
195
  }
165
196
 
166
- if (stream.peek() === "#") {
167
- indent(state);
168
- return "atom";
197
+ if (ch === "=") {
198
+ // Match shortcut mixin definition
199
+ if (stream.match(/^=[\w-]+/)) {
200
+ indent(state);
201
+ return "meta";
202
+ }
169
203
  }
170
- }
171
204
 
172
- // Numbers
173
- if (stream.match(/^-?[0-9\.]+/))
174
- return "number";
205
+ if (ch === "+") {
206
+ // Match shortcut mixin definition
207
+ if (stream.match(/^\+[\w-]+/)){
208
+ return "variable-3";
209
+ }
210
+ }
175
211
 
176
- // Units
177
- if (stream.match(/^(px|em|in)\b/))
178
- return "unit";
212
+ if(ch === "@"){
213
+ if(stream.match(/@extend/)){
214
+ if(!stream.match(/\s*[\w]/))
215
+ dedent(state);
216
+ }
217
+ }
179
218
 
180
- if (stream.match(keywordsRegexp))
181
- return "keyword";
182
219
 
183
- if (stream.match(/^url/) && stream.peek() === "(") {
184
- state.tokenizer = urlTokens;
185
- return "atom";
186
- }
220
+ // Indent Directives
221
+ if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
222
+ indent(state);
223
+ return "meta";
224
+ }
187
225
 
188
- // Variables
189
- if (ch === "$") {
190
- stream.next();
191
- stream.eatWhile(/[\w-]/);
226
+ // Other Directives
227
+ if (ch === "@") {
228
+ stream.next();
229
+ stream.eatWhile(/[\w-]/);
230
+ return "meta";
231
+ }
192
232
 
193
- if (stream.peek() === ":") {
233
+ if (stream.eatWhile(/[\w-]/)){
234
+ if(stream.match(/ *: *[\w-\+\$#!\("']/,false)){
235
+ return "propery";
236
+ }
237
+ else if(stream.match(/ *:/,false)){
238
+ indent(state);
239
+ state.cursorHalf = 1;
240
+ return "atom";
241
+ }
242
+ else if(stream.match(/ *,/,false)){
243
+ return "atom";
244
+ }
245
+ else{
246
+ indent(state);
247
+ return "atom";
248
+ }
249
+ }
250
+
251
+ if(ch === ":"){
252
+ if (stream.match(pseudoElementsRegexp)){ // could be a pseudo-element
253
+ return "keyword";
254
+ }
194
255
  stream.next();
195
- return "variable-2";
196
- } else {
197
- return "variable-3";
256
+ state.cursorHalf=1;
257
+ return "operator";
198
258
  }
199
- }
200
259
 
201
- if (ch === "!") {
202
- stream.next();
203
- return stream.match(/^[\w]+/) ? "keyword": "operator";
204
- }
260
+ } // cursorHalf===0 ends here
261
+ else{
205
262
 
206
- if (ch === "=") {
207
- stream.next();
263
+ if (ch === "#") {
264
+ stream.next();
265
+ // Hex numbers
266
+ if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){
267
+ if(!stream.peek()){
268
+ state.cursorHalf = 0;
269
+ }
270
+ return "number";
271
+ }
272
+ }
208
273
 
209
- // Match shortcut mixin definition
210
- if (stream.match(/^[\w-]+/)) {
211
- indent(state);
212
- return "meta";
213
- } else {
214
- return "operator";
274
+ // Numbers
275
+ if (stream.match(/^-?[0-9\.]+/)){
276
+ if(!stream.peek()){
277
+ state.cursorHalf = 0;
278
+ }
279
+ return "number";
215
280
  }
216
- }
217
281
 
218
- if (ch === "+") {
219
- stream.next();
282
+ // Units
283
+ if (stream.match(/^(px|em|in)\b/)){
284
+ if(!stream.peek()){
285
+ state.cursorHalf = 0;
286
+ }
287
+ return "unit";
288
+ }
220
289
 
221
- // Match shortcut mixin definition
222
- if (stream.match(/^[\w-]+/))
290
+ if (stream.match(keywordsRegexp)){
291
+ if(!stream.peek()){
292
+ state.cursorHalf = 0;
293
+ }
294
+ return "keyword";
295
+ }
296
+
297
+ if (stream.match(/^url/) && stream.peek() === "(") {
298
+ state.tokenizer = urlTokens;
299
+ if(!stream.peek()){
300
+ state.cursorHalf = 0;
301
+ }
302
+ return "atom";
303
+ }
304
+
305
+ // Variables
306
+ if (ch === "$") {
307
+ stream.next();
308
+ stream.eatWhile(/[\w-]/);
309
+ if(!stream.peek()){
310
+ state.cursorHalf = 0;
311
+ }
223
312
  return "variable-3";
224
- else
225
- return "operator";
226
- }
313
+ }
227
314
 
228
- // Indent Directives
229
- if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
230
- indent(state);
231
- return "meta";
232
- }
315
+ // bang character for !important, !default, etc.
316
+ if (ch === "!") {
317
+ stream.next();
318
+ if(!stream.peek()){
319
+ state.cursorHalf = 0;
320
+ }
321
+ return stream.match(/^[\w]+/) ? "keyword": "operator";
322
+ }
233
323
 
234
- // Other Directives
235
- if (ch === "@") {
236
- stream.next();
237
- stream.eatWhile(/[\w-]/);
238
- return "meta";
239
- }
324
+ if (stream.match(opRegexp)){
325
+ if(!stream.peek()){
326
+ state.cursorHalf = 0;
327
+ }
328
+ return "operator";
329
+ }
240
330
 
241
- // Strings
242
- if (ch === '"' || ch === "'") {
243
- stream.next();
244
- state.tokenizer = buildStringTokenizer(ch);
245
- return "string";
246
- }
331
+ // attributes
332
+ if (stream.eatWhile(/[\w-]/)) {
333
+ if(!stream.peek()){
334
+ state.cursorHalf = 0;
335
+ }
336
+ return "attribute";
337
+ }
247
338
 
248
- // Pseudo element selectors
249
- if (ch == ":" && stream.match(pseudoElementsRegexp))
250
- return "keyword";
339
+ //stream.eatSpace();
340
+ if(!stream.peek()){
341
+ state.cursorHalf = 0;
342
+ return null;
343
+ }
251
344
 
252
- // atoms
253
- if (stream.eatWhile(/[\w-&]/)) {
254
- // matches a property definition
255
- if (stream.peek() === ":" && !stream.match(pseudoElementsRegexp, false))
256
- return "property";
257
- else
258
- return "atom";
259
- }
345
+ } // else ends here
260
346
 
261
347
  if (stream.match(opRegexp))
262
348
  return "operator";
@@ -272,14 +358,13 @@ CodeMirror.defineMode("sass", function(config) {
272
358
  var style = state.tokenizer(stream, state);
273
359
  var current = stream.current();
274
360
 
275
- if (current === "@return")
361
+ if (current === "@return" || current === "}"){
276
362
  dedent(state);
277
-
278
- if (style === "atom")
279
- indent(state);
363
+ }
280
364
 
281
365
  if (style !== null) {
282
366
  var startOfToken = stream.pos - current.length;
367
+
283
368
  var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount);
284
369
 
285
370
  var newScopes = [];
@@ -304,6 +389,8 @@ CodeMirror.defineMode("sass", function(config) {
304
389
  tokenizer: tokenBase,
305
390
  scopes: [{offset: 0, type: "sass"}],
306
391
  indentCount: 0,
392
+ cursorHalf: 0, // cursor half tells us if cursor lies after (1)
393
+ // or before (0) colon (well... more or less)
307
394
  definedVars: [],
308
395
  definedMixins: []
309
396
  };
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codemirror-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: '4.11'
4
+ version: '4.12'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Fixler
@@ -260,6 +260,7 @@ files:
260
260
  - vendor/assets/javascripts/codemirror/addons/search/searchcursor.js
261
261
  - vendor/assets/javascripts/codemirror/addons/selection/active-line.js
262
262
  - vendor/assets/javascripts/codemirror/addons/selection/mark-selection.js
263
+ - vendor/assets/javascripts/codemirror/addons/selection/selection-pointer.js
263
264
  - vendor/assets/javascripts/codemirror/addons/tern/tern.js
264
265
  - vendor/assets/javascripts/codemirror/addons/tern/worker.js
265
266
  - vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js