PluginProbe ʕ •ᴥ•ʔ
SiteOrigin CSS / 1.5.2
SiteOrigin CSS v1.5.2
1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.10 1.5.11 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0
so-css / lib / codemirror / addon / search / match-highlighter.js
so-css / lib / codemirror / addon / search Last commit date
jump-to-line.js 6 years ago jump-to-line.min.js 6 years ago match-highlighter.js 6 years ago match-highlighter.min.js 6 years ago matchesonscrollbar.css 6 years ago matchesonscrollbar.js 6 years ago matchesonscrollbar.min.js 6 years ago search.js 6 years ago search.min.js 6 years ago searchcursor.js 6 years ago searchcursor.min.js 6 years ago
match-highlighter.js
166 lines
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // Highlighting text that matches the selection
5 //
6 // Defines an option highlightSelectionMatches, which, when enabled,
7 // will style strings that match the selection throughout the
8 // document.
9 //
10 // The option can be set to true to simply enable it, or to a
11 // {minChars, style, wordsOnly, showToken, delay} object to explicitly
12 // configure it. minChars is the minimum amount of characters that should be
13 // selected for the behavior to occur, and style is the token style to
14 // apply to the matches. This will be prefixed by "cm-" to create an
15 // actual CSS class name. If wordsOnly is enabled, the matches will be
16 // highlighted only if the selected text is a word. showToken, when enabled,
17 // will cause the current token to be highlighted when nothing is selected.
18 // delay is used to specify how much time to wait, in milliseconds, before
19 // highlighting the matches. If annotateScrollbar is enabled, the occurences
20 // will be highlighted on the scrollbar via the matchesonscrollbar addon.
21
22 (function(mod) {
23 if (typeof exports == "object" && typeof module == "object") // CommonJS
24 mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
25 else if (typeof define == "function" && define.amd) // AMD
26 define(["../../lib/codemirror", "./matchesonscrollbar"], mod);
27 else // Plain browser env
28 mod(CodeMirror);
29 })(function(CodeMirror) {
30 "use strict";
31
32 var defaults = {
33 style: "matchhighlight",
34 minChars: 2,
35 delay: 100,
36 wordsOnly: false,
37 annotateScrollbar: false,
38 showToken: false,
39 trim: true
40 }
41
42 function State(options) {
43 this.options = {}
44 for (var name in defaults)
45 this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name]
46 this.overlay = this.timeout = null;
47 this.matchesonscroll = null;
48 this.active = false;
49 }
50
51 CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
52 if (old && old != CodeMirror.Init) {
53 removeOverlay(cm);
54 clearTimeout(cm.state.matchHighlighter.timeout);
55 cm.state.matchHighlighter = null;
56 cm.off("cursorActivity", cursorActivity);
57 cm.off("focus", onFocus)
58 }
59 if (val) {
60 var state = cm.state.matchHighlighter = new State(val);
61 if (cm.hasFocus()) {
62 state.active = true
63 highlightMatches(cm)
64 } else {
65 cm.on("focus", onFocus)
66 }
67 cm.on("cursorActivity", cursorActivity);
68 }
69 });
70
71 function cursorActivity(cm) {
72 var state = cm.state.matchHighlighter;
73 if (state.active || cm.hasFocus()) scheduleHighlight(cm, state)
74 }
75
76 function onFocus(cm) {
77 var state = cm.state.matchHighlighter
78 if (!state.active) {
79 state.active = true
80 scheduleHighlight(cm, state)
81 }
82 }
83
84 function scheduleHighlight(cm, state) {
85 clearTimeout(state.timeout);
86 state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay);
87 }
88
89 function addOverlay(cm, query, hasBoundary, style) {
90 var state = cm.state.matchHighlighter;
91 cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
92 if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
93 var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query;
94 state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
95 {className: "CodeMirror-selection-highlight-scrollbar"});
96 }
97 }
98
99 function removeOverlay(cm) {
100 var state = cm.state.matchHighlighter;
101 if (state.overlay) {
102 cm.removeOverlay(state.overlay);
103 state.overlay = null;
104 if (state.matchesonscroll) {
105 state.matchesonscroll.clear();
106 state.matchesonscroll = null;
107 }
108 }
109 }
110
111 function highlightMatches(cm) {
112 cm.operation(function() {
113 var state = cm.state.matchHighlighter;
114 removeOverlay(cm);
115 if (!cm.somethingSelected() && state.options.showToken) {
116 var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
117 var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
118 while (start && re.test(line.charAt(start - 1))) --start;
119 while (end < line.length && re.test(line.charAt(end))) ++end;
120 if (start < end)
121 addOverlay(cm, line.slice(start, end), re, state.options.style);
122 return;
123 }
124 var from = cm.getCursor("from"), to = cm.getCursor("to");
125 if (from.line != to.line) return;
126 if (state.options.wordsOnly && !isWord(cm, from, to)) return;
127 var selection = cm.getRange(from, to)
128 if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "")
129 if (selection.length >= state.options.minChars)
130 addOverlay(cm, selection, false, state.options.style);
131 });
132 }
133
134 function isWord(cm, from, to) {
135 var str = cm.getRange(from, to);
136 if (str.match(/^\w+$/) !== null) {
137 if (from.ch > 0) {
138 var pos = {line: from.line, ch: from.ch - 1};
139 var chr = cm.getRange(pos, from);
140 if (chr.match(/\W/) === null) return false;
141 }
142 if (to.ch < cm.getLine(from.line).length) {
143 var pos = {line: to.line, ch: to.ch + 1};
144 var chr = cm.getRange(to, pos);
145 if (chr.match(/\W/) === null) return false;
146 }
147 return true;
148 } else return false;
149 }
150
151 function boundariesAround(stream, re) {
152 return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
153 (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
154 }
155
156 function makeOverlay(query, hasBoundary, style) {
157 return {token: function(stream) {
158 if (stream.match(query) &&
159 (!hasBoundary || boundariesAround(stream, hasBoundary)))
160 return style;
161 stream.next();
162 stream.skipTo(query.charAt(0)) || stream.skipToEnd();
163 }};
164 }
165 });
166