restore the original match-highlighter and monkeypatch it
This commit is contained in:
parent
c1c61ed590
commit
a30ef3ed14
|
@ -37,7 +37,7 @@
|
||||||
<link rel="stylesheet" href="vendor/codemirror/addon/search/matchesonscrollbar.css">
|
<link rel="stylesheet" href="vendor/codemirror/addon/search/matchesonscrollbar.css">
|
||||||
<script src="vendor/codemirror/addon/scroll/annotatescrollbar.js"></script>
|
<script src="vendor/codemirror/addon/scroll/annotatescrollbar.js"></script>
|
||||||
<script src="vendor/codemirror/addon/search/matchesonscrollbar.js"></script>
|
<script src="vendor/codemirror/addon/search/matchesonscrollbar.js"></script>
|
||||||
<script src="vendor-overwrites/codemirror/addon/search/match-highlighter.js"></script>
|
<script src="vendor/codemirror/addon/search/match-highlighter.js"></script>
|
||||||
<script src="vendor/codemirror/addon/dialog/dialog.js"></script>
|
<script src="vendor/codemirror/addon/dialog/dialog.js"></script>
|
||||||
<script src="vendor/codemirror/addon/search/searchcursor.js"></script>
|
<script src="vendor/codemirror/addon/search/searchcursor.js"></script>
|
||||||
<script src="vendor/codemirror/addon/search/search.js"></script>
|
<script src="vendor/codemirror/addon/search/search.js"></script>
|
||||||
|
@ -61,6 +61,7 @@
|
||||||
<script src="vendor/codemirror/keymap/emacs.js"></script>
|
<script src="vendor/codemirror/keymap/emacs.js"></script>
|
||||||
<script src="vendor/codemirror/keymap/vim.js"></script>
|
<script src="vendor/codemirror/keymap/vim.js"></script>
|
||||||
|
|
||||||
|
<script src="/edit/match-highlighter-helper.js"></script>
|
||||||
<script src="/edit/codemirror-default.js"></script>
|
<script src="/edit/codemirror-default.js"></script>
|
||||||
<link rel="stylesheet" href="/edit/codemirror-default.css">
|
<link rel="stylesheet" href="/edit/codemirror-default.css">
|
||||||
<link id="cm-theme" rel="stylesheet">
|
<link id="cm-theme" rel="stylesheet">
|
||||||
|
|
99
edit/match-highlighter-helper.js
Normal file
99
edit/match-highlighter-helper.js
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/* global CodeMirror */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
const HL_APPROVED = 'cm-matchhighlight-approved';
|
||||||
|
const originalAddOverlay = CodeMirror.prototype.addOverlay;
|
||||||
|
const originalRemoveOverlay = CodeMirror.prototype.removeOverlay;
|
||||||
|
CodeMirror.prototype.addOverlay = addOverlay;
|
||||||
|
CodeMirror.prototype.removeOverlay = removeOverlay;
|
||||||
|
return;
|
||||||
|
|
||||||
|
function shouldIntercept(overlay) {
|
||||||
|
const hlState = this.state.matchHighlighter || {};
|
||||||
|
return overlay === hlState.overlay && (hlState.options || {}).showToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addOverlay() {
|
||||||
|
return shouldIntercept.apply(this, arguments) &&
|
||||||
|
addOverlayForHighlighter.apply(this, arguments) ||
|
||||||
|
originalAddOverlay.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOverlay() {
|
||||||
|
return shouldIntercept.apply(this, arguments) &&
|
||||||
|
removeOverlayForHighlighter.apply(this, arguments) ||
|
||||||
|
originalRemoveOverlay.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addOverlayForHighlighter(overlay) {
|
||||||
|
const state = this.state.matchHighlighter || {};
|
||||||
|
const helper = state.stylusMHLHelper || {};
|
||||||
|
if (helper.matchesonscroll) {
|
||||||
|
// restore the original addon's unwanted removeOverlay effects
|
||||||
|
// (in case the token under cursor hasn't changed)
|
||||||
|
state.matchesonscroll = helper.matchesonscroll;
|
||||||
|
state.overlay = helper.overlay;
|
||||||
|
helper.matchesonscroll = null;
|
||||||
|
helper.overlay = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (overlay.token !== tokenHook) {
|
||||||
|
overlay.stylusMHLHelper = {
|
||||||
|
token: overlay.token,
|
||||||
|
occurrences: 0,
|
||||||
|
};
|
||||||
|
overlay.token = tokenHook;
|
||||||
|
}
|
||||||
|
clearTimeout(helper.hookTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tokenHook(stream) {
|
||||||
|
const style = this.stylusMHLHelper.token.call(this, stream);
|
||||||
|
if (style !== 'matchhighlight') {
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
const num = ++this.stylusMHLHelper.occurrences;
|
||||||
|
if (num === 1) {
|
||||||
|
stream.lineOracle.doc.cm.display.wrapper.classList.remove(HL_APPROVED);
|
||||||
|
} else if (num === 2) {
|
||||||
|
stream.lineOracle.doc.cm.display.wrapper.classList.add(HL_APPROVED);
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOverlayForHighlighter() {
|
||||||
|
const state = this.state.matchHighlighter || {};
|
||||||
|
const {query} = state.matchesonscroll || {};
|
||||||
|
if (!query) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const {line, ch} = this.getCursor();
|
||||||
|
const rx = query instanceof RegExp ? query : new RegExp(`\\b${query}\\b`);
|
||||||
|
const start = Math.max(0, ch - rx.source.length + 4 + 1);
|
||||||
|
const end = ch + rx.source.length - 4;
|
||||||
|
const area = this.getLine(line).substring(start, end);
|
||||||
|
const startInArea = (area.match(rx) || {}).index;
|
||||||
|
if (start + startInArea <= ch) {
|
||||||
|
// same token on cursor => prevent the highlighter from rerunning
|
||||||
|
state.stylusMHLHelper = {
|
||||||
|
overlay: state.overlay,
|
||||||
|
matchesonscroll: state.matchesonscroll,
|
||||||
|
hookTimer: setTimeout(removeOverlayIfExpired, 0, this, state),
|
||||||
|
};
|
||||||
|
state.matchesonscroll = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOverlayIfExpired(self, state) {
|
||||||
|
const {overlay, matchesonscroll} = state.stylusMHLHelper || {};
|
||||||
|
if (overlay) {
|
||||||
|
originalRemoveOverlay.call(self, overlay);
|
||||||
|
}
|
||||||
|
if (matchesonscroll) {
|
||||||
|
matchesonscroll.clear();
|
||||||
|
}
|
||||||
|
state.stylusMHLHelper = null;
|
||||||
|
}
|
||||||
|
})();
|
|
@ -23,6 +23,7 @@
|
||||||
<script src="/vendor/codemirror/keymap/emacs.js"></script>
|
<script src="/vendor/codemirror/keymap/emacs.js"></script>
|
||||||
<script src="/vendor/codemirror/keymap/vim.js"></script>
|
<script src="/vendor/codemirror/keymap/vim.js"></script>
|
||||||
|
|
||||||
|
<script src="/edit/match-highlighter-helper.js"></script>
|
||||||
<script src="/edit/codemirror-default.js"></script>
|
<script src="/edit/codemirror-default.js"></script>
|
||||||
<link rel="stylesheet" href="/edit/codemirror-default.css">
|
<link rel="stylesheet" href="/edit/codemirror-default.css">
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
<link rel="stylesheet" href="/vendor/codemirror/addon/search/matchesonscrollbar.css">
|
<link rel="stylesheet" href="/vendor/codemirror/addon/search/matchesonscrollbar.css">
|
||||||
<script src="/vendor/codemirror/addon/scroll/annotatescrollbar.js"></script>
|
<script src="/vendor/codemirror/addon/scroll/annotatescrollbar.js"></script>
|
||||||
<script src="/vendor/codemirror/addon/search/matchesonscrollbar.js"></script>
|
<script src="/vendor/codemirror/addon/search/matchesonscrollbar.js"></script>
|
||||||
<script src="/vendor-overwrites/codemirror/addon/search/match-highlighter.js"></script>
|
<script src="/vendor/codemirror/addon/search/match-highlighter.js"></script>
|
||||||
<script src="/vendor/codemirror/addon/dialog/dialog.js"></script>
|
<script src="/vendor/codemirror/addon/dialog/dialog.js"></script>
|
||||||
<script src="/vendor/codemirror/addon/search/searchcursor.js"></script>
|
<script src="/vendor/codemirror/addon/search/searchcursor.js"></script>
|
||||||
<script src="/vendor/codemirror/addon/search/search.js"></script>
|
<script src="/vendor/codemirror/addon/search/search.js"></script>
|
||||||
|
|
|
@ -19,12 +19,6 @@
|
||||||
// highlighting the matches. If annotateScrollbar is enabled, the occurences
|
// highlighting the matches. If annotateScrollbar is enabled, the occurences
|
||||||
// will be highlighted on the scrollbar via the matchesonscrollbar addon.
|
// will be highlighted on the scrollbar via the matchesonscrollbar addon.
|
||||||
|
|
||||||
/* STYLUS: hack start (part 1) */
|
|
||||||
/* eslint curly: 1, brace-style:1, strict: 0, quotes: 0, semi: 1, indent: 1 */
|
|
||||||
/* eslint no-var: 0, block-scoped-var: 0, no-redeclare: 0, no-unused-expressions: 1 */
|
|
||||||
/* global CodeMirror, require, define */
|
|
||||||
/* STYLUS: hack end (part 1) */
|
|
||||||
|
|
||||||
(function(mod) {
|
(function(mod) {
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||||
mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
|
mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
|
||||||
|
@ -94,9 +88,7 @@
|
||||||
|
|
||||||
function addOverlay(cm, query, hasBoundary, style) {
|
function addOverlay(cm, query, hasBoundary, style) {
|
||||||
var state = cm.state.matchHighlighter;
|
var state = cm.state.matchHighlighter;
|
||||||
/* STYLUS: hack start (part 2) */
|
cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
|
||||||
cm.addOverlay(state.overlay = makeOverlay(cm, query, hasBoundary, style));
|
|
||||||
/* STYLUS: hack end (part 2) */
|
|
||||||
if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
|
if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
|
||||||
var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query;
|
var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query;
|
||||||
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
|
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
|
||||||
|
@ -119,24 +111,16 @@
|
||||||
function highlightMatches(cm) {
|
function highlightMatches(cm) {
|
||||||
cm.operation(function() {
|
cm.operation(function() {
|
||||||
var state = cm.state.matchHighlighter;
|
var state = cm.state.matchHighlighter;
|
||||||
|
removeOverlay(cm);
|
||||||
if (!cm.somethingSelected() && state.options.showToken) {
|
if (!cm.somethingSelected() && state.options.showToken) {
|
||||||
var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
|
var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
|
||||||
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
|
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
|
||||||
while (start && re.test(line.charAt(start - 1))) --start;
|
while (start && re.test(line.charAt(start - 1))) --start;
|
||||||
while (end < line.length && re.test(line.charAt(end))) ++end;
|
while (end < line.length && re.test(line.charAt(end))) ++end;
|
||||||
/* STYLUS: hack start */
|
if (start < end)
|
||||||
const token = line.slice(start, end);
|
addOverlay(cm, line.slice(start, end), re, state.options.style);
|
||||||
if (token !== state.lastToken) {
|
|
||||||
state.lastToken = token;
|
|
||||||
removeOverlay(cm);
|
|
||||||
if (token) {
|
|
||||||
addOverlay(cm, token, re, state.options.style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
removeOverlay(cm);
|
|
||||||
/* STYLUS: hack end */
|
|
||||||
var from = cm.getCursor("from"), to = cm.getCursor("to");
|
var from = cm.getCursor("from"), to = cm.getCursor("to");
|
||||||
if (from.line != to.line) return;
|
if (from.line != to.line) return;
|
||||||
if (state.options.wordsOnly && !isWord(cm, from, to)) return;
|
if (state.options.wordsOnly && !isWord(cm, from, to)) return;
|
||||||
|
@ -169,28 +153,11 @@
|
||||||
(stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
|
(stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeOverlay(cm, query, hasBoundary, style) {
|
function makeOverlay(query, hasBoundary, style) {
|
||||||
/* STYLUS: hack start (part 3) */
|
|
||||||
const approvedClassName = `cm-${style}-approved`;
|
|
||||||
let timer;
|
|
||||||
let occurrences = 0;
|
|
||||||
return {token: function(stream) {
|
return {token: function(stream) {
|
||||||
clearTimeout(timer);
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
occurrences = 0;
|
|
||||||
timer = null;
|
|
||||||
});
|
|
||||||
if (stream.match(query) &&
|
if (stream.match(query) &&
|
||||||
(!hasBoundary || boundariesAround(stream, hasBoundary))) {
|
(!hasBoundary || boundariesAround(stream, hasBoundary)))
|
||||||
occurrences++;
|
|
||||||
if (occurrences == 1) {
|
|
||||||
cm.display.wrapper.classList.remove(approvedClassName);
|
|
||||||
} else if (occurrences == 2) {
|
|
||||||
cm.display.wrapper.classList.add(approvedClassName);
|
|
||||||
}
|
|
||||||
return style;
|
return style;
|
||||||
}
|
|
||||||
/* STYLUS: hack end (part 3) */
|
|
||||||
stream.next();
|
stream.next();
|
||||||
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
|
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
|
||||||
}};
|
}};
|
Loading…
Reference in New Issue
Block a user