1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-09-15 15:32:28 +02:00

Upgrade CodeMirror library to 5.59.0 (from 5.46.0)

This commit is contained in:
Raymond Hill 2020-12-22 09:06:26 -05:00
parent 7e56a782e8
commit 5d617484e5
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
12 changed files with 618 additions and 467 deletions

View File

@ -2,7 +2,6 @@
[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror) [![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror) [![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
[![Join the chat at https://gitter.im/codemirror/CodeMirror](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/codemirror/CodeMirror)
CodeMirror is a versatile text editor implemented in JavaScript for CodeMirror is a versatile text editor implemented in JavaScript for
the browser. It is specialized for editing code, and comes with over the browser. It is specialized for editing code, and comes with over

View File

@ -13,7 +13,7 @@
var noOptions = {}; var noOptions = {};
var nonWS = /[^\s\u00a0]/; var nonWS = /[^\s\u00a0]/;
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos, cmp = CodeMirror.cmpPos;
function firstNonWS(str) { function firstNonWS(str) {
var found = str.search(nonWS); var found = str.search(nonWS);
@ -126,7 +126,9 @@
if (i != end || lastLineHasText) if (i != end || lastLineHasText)
self.replaceRange(lead + pad, Pos(i, 0)); self.replaceRange(lead + pad, Pos(i, 0));
} else { } else {
var atCursor = cmp(self.getCursor("to"), to) == 0, empty = !self.somethingSelected()
self.replaceRange(endString, to); self.replaceRange(endString, to);
if (atCursor) self.setSelection(empty ? to : self.getCursor("from"), to)
self.replaceRange(startString, from); self.replaceRange(startString, from);
} }
}); });

View File

@ -1,15 +1,15 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE // Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) { (function (mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror")); mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod); define(["../../lib/codemirror"], mod);
else // Plain browser env else // Plain browser env
mod(CodeMirror); mod(CodeMirror);
})(function(CodeMirror) { })(function (CodeMirror) {
CodeMirror.defineExtension("addPanel", function(node, options) { CodeMirror.defineExtension("addPanel", function (node, options) {
options = options || {}; options = options || {};
if (!this.state.panels) initPanels(this); if (!this.state.panels) initPanels(this);
@ -25,8 +25,7 @@
wrapper.insertBefore(node, options.before.node); wrapper.insertBefore(node, options.before.node);
} else if (replace) { } else if (replace) {
wrapper.insertBefore(node, options.replace.node); wrapper.insertBefore(node, options.replace.node);
info.panels++; options.replace.clear(true);
options.replace.clear();
} else if (options.position == "bottom") { } else if (options.position == "bottom") {
wrapper.appendChild(node); wrapper.appendChild(node);
} else if (options.position == "before-bottom") { } else if (options.position == "before-bottom") {
@ -38,14 +37,15 @@
} }
var height = (options && options.height) || node.offsetHeight; var height = (options && options.height) || node.offsetHeight;
this._setSize(null, info.heightLeft -= height);
if (!replace) {
info.panels++;
}
if (options.stable && isAtTop(this, node))
this.scrollTo(null, this.getScrollInfo().top + height)
return new Panel(this, node, options, height); var panel = new Panel(this, node, options, height);
info.panels.push(panel);
this.setSize();
if (options.stable && isAtTop(this, node))
this.scrollTo(null, this.getScrollInfo().top + height);
return panel;
}); });
function Panel(cm, node, options, height) { function Panel(cm, node, options, height) {
@ -56,22 +56,23 @@
this.cleared = false; this.cleared = false;
} }
Panel.prototype.clear = function() { /* when skipRemove is true, clear() was called from addPanel().
* Thus removePanels() should not be called (issue 5518) */
Panel.prototype.clear = function (skipRemove) {
if (this.cleared) return; if (this.cleared) return;
this.cleared = true; this.cleared = true;
var info = this.cm.state.panels; var info = this.cm.state.panels;
this.cm._setSize(null, info.heightLeft += this.height); info.panels.splice(info.panels.indexOf(this), 1);
this.cm.setSize();
if (this.options.stable && isAtTop(this.cm, this.node)) if (this.options.stable && isAtTop(this.cm, this.node))
this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height) this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height)
info.wrapper.removeChild(this.node); info.wrapper.removeChild(this.node);
if (--info.panels == 0) removePanels(this.cm); if (info.panels.length == 0 && !skipRemove) removePanels(this.cm);
}; };
Panel.prototype.changed = function(height) { Panel.prototype.changed = function () {
var newHeight = height == null ? this.node.offsetHeight : height; this.height = this.node.getBoundingClientRect().height;
var info = this.cm.state.panels; this.cm.setSize();
this.cm._setSize(null, info.heightLeft -= (newHeight - this.height));
this.height = newHeight;
}; };
function initPanels(cm) { function initPanels(cm) {
@ -80,8 +81,7 @@
var height = parseInt(style.height); var height = parseInt(style.height);
var info = cm.state.panels = { var info = cm.state.panels = {
setHeight: wrap.style.height, setHeight: wrap.style.height,
heightLeft: height, panels: [],
panels: 0,
wrapper: document.createElement("div") wrapper: document.createElement("div")
}; };
wrap.parentNode.insertBefore(info.wrapper, wrap); wrap.parentNode.insertBefore(info.wrapper, wrap);
@ -90,8 +90,8 @@
if (hasFocus) cm.focus(); if (hasFocus) cm.focus();
cm._setSize = cm.setSize; cm._setSize = cm.setSize;
if (height != null) cm.setSize = function(width, newHeight) { if (height != null) cm.setSize = function (width, newHeight) {
if (newHeight == null) return this._setSize(width, newHeight); if (!newHeight) newHeight = info.wrapper.offsetHeight;
info.setHeight = newHeight; info.setHeight = newHeight;
if (typeof newHeight != "number") { if (typeof newHeight != "number") {
var px = /^(\d+\.?\d*)px$/.exec(newHeight); var px = /^(\d+\.?\d*)px$/.exec(newHeight);
@ -100,10 +100,12 @@
} else { } else {
info.wrapper.style.height = newHeight; info.wrapper.style.height = newHeight;
newHeight = info.wrapper.offsetHeight; newHeight = info.wrapper.offsetHeight;
info.wrapper.style.height = "";
} }
} }
cm._setSize(width, info.heightLeft += (newHeight - height)); var editorheight = newHeight - info.panels
.map(function (p) { return p.node.getBoundingClientRect().height; })
.reduce(function (a, b) { return a + b; }, 0);
cm._setSize(width, editorheight);
height = newHeight; height = newHeight;
}; };
} }

View File

@ -117,17 +117,25 @@
}); });
} }
function clearHighlighted(cm) {
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) { if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets); cm.off("cursorActivity", doMatchBrackets);
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) { cm.off("focus", doMatchBrackets)
cm.state.matchBrackets.currentlyHighlighted(); cm.off("blur", clearHighlighted)
cm.state.matchBrackets.currentlyHighlighted = null; clearHighlighted(cm);
}
} }
if (val) { if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {}; cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets); cm.on("cursorActivity", doMatchBrackets);
cm.on("focus", doMatchBrackets)
cm.on("blur", clearHighlighted)
} }
}); });

View File

@ -42,7 +42,7 @@
} }
if (!range || range.cleared || force === "unfold") return; if (!range || range.cleared || force === "unfold") return;
var myWidget = makeWidget(cm, options); var myWidget = makeWidget(cm, options, range);
CodeMirror.on(myWidget, "mousedown", function(e) { CodeMirror.on(myWidget, "mousedown", function(e) {
myRange.clear(); myRange.clear();
CodeMirror.e_preventDefault(e); CodeMirror.e_preventDefault(e);
@ -58,8 +58,13 @@
CodeMirror.signal(cm, "fold", cm, range.from, range.to); CodeMirror.signal(cm, "fold", cm, range.from, range.to);
} }
function makeWidget(cm, options) { function makeWidget(cm, options, range) {
var widget = getOption(cm, options, "widget"); var widget = getOption(cm, options, "widget");
if (typeof widget == "function") {
widget = widget(range.from, range.to);
}
if (typeof widget == "string") { if (typeof widget == "string") {
var text = document.createTextNode(widget); var text = document.createTextNode(widget);
widget = document.createElement("span"); widget = document.createElement("span");

View File

@ -16,7 +16,7 @@
cm.clearGutter(cm.state.foldGutter.options.gutter); cm.clearGutter(cm.state.foldGutter.options.gutter);
cm.state.foldGutter = null; cm.state.foldGutter = null;
cm.off("gutterClick", onGutterClick); cm.off("gutterClick", onGutterClick);
cm.off("change", onChange); cm.off("changes", onChange);
cm.off("viewportChange", onViewportChange); cm.off("viewportChange", onViewportChange);
cm.off("fold", onFold); cm.off("fold", onFold);
cm.off("unfold", onFold); cm.off("unfold", onFold);
@ -26,7 +26,7 @@
cm.state.foldGutter = new State(parseOptions(val)); cm.state.foldGutter = new State(parseOptions(val));
updateInViewport(cm); updateInViewport(cm);
cm.on("gutterClick", onGutterClick); cm.on("gutterClick", onGutterClick);
cm.on("change", onChange); cm.on("changes", onChange);
cm.on("viewportChange", onViewportChange); cm.on("viewportChange", onViewportChange);
cm.on("fold", onFold); cm.on("fold", onFold);
cm.on("unfold", onFold); cm.on("unfold", onFold);
@ -51,8 +51,13 @@
function isFolded(cm, line) { function isFolded(cm, line) {
var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0)); var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
for (var i = 0; i < marks.length; ++i) for (var i = 0; i < marks.length; ++i) {
if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i]; if (marks[i].__isFold) {
var fromPos = marks[i].find(-1);
if (fromPos && fromPos.line === line)
return marks[i];
}
}
} }
function marker(spec) { function marker(spec) {
@ -66,24 +71,36 @@
} }
function updateFoldInfo(cm, from, to) { function updateFoldInfo(cm, from, to) {
var opts = cm.state.foldGutter.options, cur = from; var opts = cm.state.foldGutter.options, cur = from - 1;
var minSize = cm.foldOption(opts, "minFoldSize"); var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder"); var func = cm.foldOption(opts, "rangeFinder");
// we can reuse the built-in indicator element if its className matches the new state
var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded);
var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen);
cm.eachLine(from, to, function(line) { cm.eachLine(from, to, function(line) {
++cur;
var mark = null; var mark = null;
var old = line.gutterMarkers;
if (old) old = old[opts.gutter];
if (isFolded(cm, cur)) { if (isFolded(cm, cur)) {
if (clsFolded && old && clsFolded.test(old.className)) return;
mark = marker(opts.indicatorFolded); mark = marker(opts.indicatorFolded);
} else { } else {
var pos = Pos(cur, 0); var pos = Pos(cur, 0);
var range = func && func(cm, pos); var range = func && func(cm, pos);
if (range && range.to.line - range.from.line >= minSize) if (range && range.to.line - range.from.line >= minSize) {
if (clsOpen && old && clsOpen.test(old.className)) return;
mark = marker(opts.indicatorOpen); mark = marker(opts.indicatorOpen);
}
} }
if (!mark && !old) return;
cm.setGutterMarker(line, opts.gutter, mark); cm.setGutterMarker(line, opts.gutter, mark);
++cur;
}); });
} }
// copied from CodeMirror/src/util/dom.js
function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
function updateInViewport(cm) { function updateInViewport(cm) {
var vp = cm.getViewport(), state = cm.state.foldGutter; var vp = cm.getViewport(), state = cm.state.foldGutter;
if (!state) return; if (!state) return;
@ -100,7 +117,7 @@
if (gutter != opts.gutter) return; if (gutter != opts.gutter) return;
var folded = isFolded(cm, line); var folded = isFolded(cm, line);
if (folded) folded.clear(); if (folded) folded.clear();
else cm.foldCode(Pos(line, 0), opts.rangeFinder); else cm.foldCode(Pos(line, 0), opts);
} }
function onChange(cm) { function onChange(cm) {

View File

@ -1,6 +1,8 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE // Distributed under an MIT license: https://codemirror.net/LICENSE
// declare global: DOMRect
(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror")); mod(require("../../lib/codemirror"));
@ -85,12 +87,19 @@
}, },
pick: function(data, i) { pick: function(data, i) {
var completion = data.list[i]; var completion = data.list[i], self = this;
if (completion.hint) completion.hint(this.cm, data, completion); this.cm.operation(function() {
else this.cm.replaceRange(getText(completion), completion.from || data.from, if (completion.hint)
completion.to || data.to, "complete"); completion.hint(self.cm, data, completion);
CodeMirror.signal(data, "pick", completion); else
this.close(); self.cm.replaceRange(getText(completion), completion.from || data.from,
completion.to || data.to, "complete");
CodeMirror.signal(data, "pick", completion);
self.cm.scrollIntoView();
});
if (this.options.closeOnPick) {
this.close();
}
}, },
cursorActivity: function() { cursorActivity: function() {
@ -99,11 +108,18 @@
this.debounce = 0; this.debounce = 0;
} }
var identStart = this.startPos;
if(this.data) {
identStart = this.data.from;
}
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
pos.ch < this.startPos.ch || this.cm.somethingSelected() || pos.ch < identStart.ch || this.cm.somethingSelected() ||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { (!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close(); if (this.options.closeOnCursorActivity) {
this.close();
}
} else { } else {
var self = this; var self = this;
this.debounce = requestAnimationFrame(function() {self.update();}); this.debounce = requestAnimationFrame(function() {self.update();});
@ -229,30 +245,47 @@
elt.hintId = i; elt.hintId = i;
} }
var container = completion.options.container || ownerDocument.body;
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true; var left = pos.left, top = pos.bottom, below = true;
hints.style.left = left + "px"; var offsetLeft = 0, offsetTop = 0;
hints.style.top = top + "px"; if (container !== ownerDocument.body) {
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1;
var offsetParent = isContainerPositioned ? container : container.offsetParent;
var offsetParentPosition = offsetParent.getBoundingClientRect();
var bodyPosition = ownerDocument.body.getBoundingClientRect();
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
}
hints.style.left = (left - offsetLeft) + "px";
hints.style.top = (top - offsetTop) + "px";
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth); var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight); var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
(completion.options.container || ownerDocument.body).appendChild(hints); container.appendChild(hints);
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
var scrolls = hints.scrollHeight > hints.clientHeight + 1
var startScroll = cm.getScrollInfo();
var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect();
var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false;
// Compute in the timeout to avoid reflow on init
var startScroll;
setTimeout(function() { startScroll = cm.getScrollInfo(); });
var overlapY = box.bottom - winH;
if (overlapY > 0) { if (overlapY > 0) {
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
if (curTop - height > 0) { // Fits above cursor if (curTop - height > 0) { // Fits above cursor
hints.style.top = (top = pos.top - height) + "px"; hints.style.top = (top = pos.top - height - offsetTop) + "px";
below = false; below = false;
} else if (height > winH) { } else if (height > winH) {
hints.style.height = (winH - 5) + "px"; hints.style.height = (winH - 5) + "px";
hints.style.top = (top = pos.bottom - box.top) + "px"; hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px";
var cursor = cm.getCursor(); var cursor = cm.getCursor();
if (data.from.ch != cursor.ch) { if (data.from.ch != cursor.ch) {
pos = cm.cursorCoords(cursor); pos = cm.cursorCoords(cursor);
hints.style.left = (left = pos.left) + "px"; hints.style.left = (left = pos.left - offsetLeft) + "px";
box = hints.getBoundingClientRect(); box = hints.getBoundingClientRect();
} }
} }
@ -263,7 +296,7 @@
hints.style.width = (winW - 5) + "px"; hints.style.width = (winW - 5) + "px";
overlapX -= (box.right - box.left) - winW; overlapX -= (box.right - box.left) - winW;
} }
hints.style.left = (left = pos.left - overlapX) + "px"; hints.style.left = (left = pos.left - overlapX - offsetLeft) + "px";
} }
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling) if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
node.style.paddingRight = cm.display.nativeBarWidth + "px" node.style.paddingRight = cm.display.nativeBarWidth + "px"
@ -311,6 +344,12 @@
setTimeout(function(){cm.focus();}, 20); setTimeout(function(){cm.focus();}, 20);
}); });
// The first hint doesn't need to be scrolled to on init
var selectedHintRange = this.getSelectedHintRange();
if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
this.scrollToActive();
}
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]); CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true; return true;
} }
@ -351,15 +390,31 @@
if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
node = this.hints.childNodes[this.selectedHint = i]; node = this.hints.childNodes[this.selectedHint = i];
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
if (node.offsetTop < this.hints.scrollTop) this.scrollToActive()
this.hints.scrollTop = node.offsetTop - 3;
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
}, },
scrollToActive: function() {
var selectedHintRange = this.getSelectedHintRange();
var node1 = this.hints.childNodes[selectedHintRange.from];
var node2 = this.hints.childNodes[selectedHintRange.to];
var firstNode = this.hints.firstChild;
if (node1.offsetTop < this.hints.scrollTop)
this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop;
else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
},
screenAmount: function() { screenAmount: function() {
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
},
getSelectedHintRange: function() {
var margin = this.completion.options.scrollMargin || 0;
return {
from: Math.max(0, this.selectedHint - margin),
to: Math.min(this.data.list.length - 1, this.selectedHint + margin),
};
} }
}; };
@ -437,11 +492,15 @@
completeSingle: true, completeSingle: true,
alignWithWord: true, alignWithWord: true,
closeCharacters: /[\s()\[\]{};:>,]/, closeCharacters: /[\s()\[\]{};:>,]/,
closeOnCursorActivity: true,
closeOnPick: true,
closeOnUnfocus: true, closeOnUnfocus: true,
completeOnSingleClick: true, completeOnSingleClick: true,
container: null, container: null,
customKeys: null, customKeys: null,
extraKeys: null extraKeys: null,
paddingForScrollbar: true,
moveOnOverlap: true,
}; };
CodeMirror.defineOption("hintOptions", null); CodeMirror.defineOption("hintOptions", null);

View File

@ -443,22 +443,26 @@
aligners[i].clear(); aligners[i].clear();
aligners.length = 0; aligners.length = 0;
var cm = [dv.edit, dv.orig], scroll = []; var cm = [dv.edit, dv.orig], scroll = [], offset = []
if (other) cm.push(other.orig); if (other) cm.push(other.orig);
for (var i = 0; i < cm.length; i++) for (var i = 0; i < cm.length; i++) {
scroll.push(cm[i].getScrollInfo().top); scroll.push(cm[i].getScrollInfo().top);
offset.push(-cm[i].getScrollerElement().getBoundingClientRect().top)
}
if (offset[0] != offset[1] || cm.length == 3 && offset[1] != offset[2])
alignLines(cm, offset, [0, 0, 0], aligners)
for (var ln = 0; ln < linesToAlign.length; ln++) for (var ln = 0; ln < linesToAlign.length; ln++)
alignLines(cm, linesToAlign[ln], aligners); alignLines(cm, offset, linesToAlign[ln], aligners);
for (var i = 0; i < cm.length; i++) for (var i = 0; i < cm.length; i++)
cm[i].scrollTo(null, scroll[i]); cm[i].scrollTo(null, scroll[i]);
} }
function alignLines(cm, lines, aligners) { function alignLines(cm, cmOffset, lines, aligners) {
var maxOffset = 0, offset = []; var maxOffset = -1e8, offset = [];
for (var i = 0; i < cm.length; i++) if (lines[i] != null) { for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
var off = cm[i].heightAtLine(lines[i], "local"); var off = cm[i].heightAtLine(lines[i], "local") - cmOffset[i];
offset[i] = off; offset[i] = off;
maxOffset = Math.max(maxOffset, off); maxOffset = Math.max(maxOffset, off);
} }
@ -918,7 +922,7 @@
hasMarker: function(n) { hasMarker: function(n) {
var handle = this.cm.getLineHandle(n) var handle = this.cm.getLineHandle(n)
if (handle.markedSpans) for (var i = 0; i < handle.markedSpans.length; i++) if (handle.markedSpans) for (var i = 0; i < handle.markedSpans.length; i++)
if (handle.markedSpans[i].mark.collapsed && handle.markedSpans[i].to != null) if (handle.markedSpans[i].marker.collapsed && handle.markedSpans[i].to != null)
return true return true
return false return false
}, },

View File

@ -43,7 +43,7 @@
cm.on("markerAdded", this.resizeHandler); cm.on("markerAdded", this.resizeHandler);
cm.on("markerCleared", this.resizeHandler); cm.on("markerCleared", this.resizeHandler);
if (options.listenForChanges !== false) if (options.listenForChanges !== false)
cm.on("change", this.changeHandler = function() { cm.on("changes", this.changeHandler = function() {
scheduleRedraw(250); scheduleRedraw(250);
}); });
} }
@ -72,10 +72,16 @@
var wrapping = cm.getOption("lineWrapping"); var wrapping = cm.getOption("lineWrapping");
var singleLineH = wrapping && cm.defaultTextHeight() * 1.5; var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
var curLine = null, curLineObj = null; var curLine = null, curLineObj = null;
function getY(pos, top) { function getY(pos, top) {
if (curLine != pos.line) { if (curLine != pos.line) {
curLine = pos.line; curLine = pos.line
curLineObj = cm.getLineHandle(curLine); curLineObj = cm.getLineHandle(pos.line)
var visual = cm.getLineHandleVisualStart(curLineObj)
if (visual != curLineObj) {
curLine = cm.getLineNumber(visual)
curLineObj = visual
}
} }
if ((curLineObj.widgets && curLineObj.widgets.length) || if ((curLineObj.widgets && curLineObj.widgets.length) ||
(wrapping && curLineObj.height > singleLineH)) (wrapping && curLineObj.height > singleLineH))
@ -116,7 +122,7 @@
this.cm.off("refresh", this.resizeHandler); this.cm.off("refresh", this.resizeHandler);
this.cm.off("markerAdded", this.resizeHandler); this.cm.off("markerAdded", this.resizeHandler);
this.cm.off("markerCleared", this.resizeHandler); this.cm.off("markerCleared", this.resizeHandler);
if (this.changeHandler) this.cm.off("change", this.changeHandler); if (this.changeHandler) this.cm.off("changes", this.changeHandler);
this.div.parentNode.removeChild(this.div); this.div.parentNode.removeChild(this.div);
}; };
}); });

View File

@ -72,24 +72,26 @@
} }
} }
function lastMatchIn(string, regexp) { function lastMatchIn(string, regexp, endMargin) {
var cutOff = 0, match var match, from = 0
for (;;) { while (from <= string.length) {
regexp.lastIndex = cutOff regexp.lastIndex = from
var newMatch = regexp.exec(string) var newMatch = regexp.exec(string)
if (!newMatch) return match if (!newMatch) break
match = newMatch var end = newMatch.index + newMatch[0].length
cutOff = match.index + (match[0].length || 1) if (end > string.length - endMargin) break
if (cutOff == string.length) return match if (!match || end > match.index + match[0].length)
match = newMatch
from = newMatch.index + 1
} }
return match
} }
function searchRegexpBackward(doc, regexp, start) { function searchRegexpBackward(doc, regexp, start) {
regexp = ensureFlags(regexp, "g") regexp = ensureFlags(regexp, "g")
for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) { for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
var string = doc.getLine(line) var string = doc.getLine(line)
if (ch > -1) string = string.slice(0, ch) var match = lastMatchIn(string, regexp, ch < 0 ? 0 : string.length - ch)
var match = lastMatchIn(string, regexp)
if (match) if (match)
return {from: Pos(line, match.index), return {from: Pos(line, match.index),
to: Pos(line, match.index + match[0].length), to: Pos(line, match.index + match[0].length),
@ -98,16 +100,17 @@
} }
function searchRegexpBackwardMultiline(doc, regexp, start) { function searchRegexpBackwardMultiline(doc, regexp, start) {
if (!maybeMultiline(regexp)) return searchRegexpBackward(doc, regexp, start)
regexp = ensureFlags(regexp, "gm") regexp = ensureFlags(regexp, "gm")
var string, chunk = 1 var string, chunkSize = 1, endMargin = doc.getLine(start.line).length - start.ch
for (var line = start.line, first = doc.firstLine(); line >= first;) { for (var line = start.line, first = doc.firstLine(); line >= first;) {
for (var i = 0; i < chunk; i++) { for (var i = 0; i < chunkSize && line >= first; i++) {
var curLine = doc.getLine(line--) var curLine = doc.getLine(line--)
string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string string = string == null ? curLine : curLine + "\n" + string
} }
chunk *= 2 chunkSize *= 2
var match = lastMatchIn(string, regexp) var match = lastMatchIn(string, regexp, endMargin)
if (match) { if (match) {
var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n") var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
var startLine = line + before.length, startCh = before[before.length - 1].length var startLine = line + before.length, startCh = before[before.length - 1].length
@ -237,7 +240,7 @@
var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to)) var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
// Implements weird auto-growing behavior on null-matches for // Implements weird auto-growing behavior on null-matches for
// backwards-compatiblity with the vim code (unfortunately) // backwards-compatibility with the vim code (unfortunately)
while (result && CodeMirror.cmpPos(result.from, result.to) == 0) { while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
if (reverse) { if (reverse) {
if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1) if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)

View File

@ -13,12 +13,13 @@
.CodeMirror-lines { .CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */ padding: 4px 0; /* Vertical padding around content */
} }
.CodeMirror pre { .CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px; /* Horizontal padding of content */ padding: 0 4px; /* Horizontal padding of content */
} }
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */ background-color: transparent; /* The little square between H and V scrollbars */
} }
/* GUTTER */ /* GUTTER */
@ -96,7 +97,7 @@
.CodeMirror-rulers { .CodeMirror-rulers {
position: absolute; position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px; left: 0; right: 0; top: -50px; bottom: 0;
overflow: hidden; overflow: hidden;
} }
.CodeMirror-ruler { .CodeMirror-ruler {
@ -163,17 +164,17 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-scroll { .CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */ overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */ /* 50px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */ /* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px; margin-bottom: -50px; margin-right: -50px;
padding-bottom: 30px; padding-bottom: 50px;
height: 100%; height: 100%;
outline: none; /* Prevent dragging from highlighting the element */ outline: none; /* Prevent dragging from highlighting the element */
position: relative; position: relative;
} }
.CodeMirror-sizer { .CodeMirror-sizer {
position: relative; position: relative;
border-right: 30px solid transparent; border-right: 50px solid transparent;
} }
/* The fake, visible scrollbars. Used to force redraw during scrolling /* The fake, visible scrollbars. Used to force redraw during scrolling
@ -183,6 +184,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
position: absolute; position: absolute;
z-index: 6; z-index: 6;
display: none; display: none;
outline: none;
} }
.CodeMirror-vscrollbar { .CodeMirror-vscrollbar {
right: 0; top: 0; right: 0; top: 0;
@ -211,7 +213,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
height: 100%; height: 100%;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
margin-bottom: -30px; margin-bottom: -50px;
} }
.CodeMirror-gutter-wrapper { .CodeMirror-gutter-wrapper {
position: absolute; position: absolute;
@ -236,7 +238,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
cursor: text; cursor: text;
min-height: 1px; /* prevents collapsing before first draw */ min-height: 1px; /* prevents collapsing before first draw */
} }
.CodeMirror pre { .CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */ /* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0; border-width: 0;
@ -255,7 +258,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
-webkit-font-variant-ligatures: contextual; -webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual; font-variant-ligatures: contextual;
} }
.CodeMirror-wrap pre { .CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word; word-wrap: break-word;
white-space: pre-wrap; white-space: pre-wrap;
word-break: normal; word-break: normal;

File diff suppressed because it is too large Load Diff