PluginProbe ʕ •ᴥ•ʔ
SiteOrigin CSS / 1.2.13
SiteOrigin CSS v1.2.13
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 / hint / show-hint.js
so-css / lib / codemirror / addon / hint Last commit date
anyword-hint.js 10 years ago anyword-hint.min.js 6 years ago css-hint.js 11 years ago css-hint.min.js 6 years ago html-hint.js 11 years ago html-hint.min.js 6 years ago javascript-hint.js 9 years ago javascript-hint.min.js 6 years ago show-hint.css 9 years ago show-hint.js 9 years ago show-hint.min.js 6 years ago sql-hint.js 9 years ago sql-hint.min.js 6 years ago xml-hint.js 11 years ago xml-hint.min.js 6 years ago
show-hint.js
439 lines
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 var HINT_ELEMENT_CLASS = "CodeMirror-hint";
15 var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
16
17 // This is the old interface, kept around for now to stay
18 // backwards-compatible.
19 CodeMirror.showHint = function(cm, getHints, options) {
20 if (!getHints) return cm.showHint(options);
21 if (options && options.async) getHints.async = true;
22 var newOpts = {hint: getHints};
23 if (options) for (var prop in options) newOpts[prop] = options[prop];
24 return cm.showHint(newOpts);
25 };
26
27 CodeMirror.defineExtension("showHint", function(options) {
28 options = parseOptions(this, this.getCursor("start"), options);
29 var selections = this.listSelections()
30 if (selections.length > 1) return;
31 // By default, don't allow completion when something is selected.
32 // A hint function can have a `supportsSelection` property to
33 // indicate that it can handle selections.
34 if (this.somethingSelected()) {
35 if (!options.hint.supportsSelection) return;
36 // Don't try with cross-line selections
37 for (var i = 0; i < selections.length; i++)
38 if (selections[i].head.line != selections[i].anchor.line) return;
39 }
40
41 if (this.state.completionActive) this.state.completionActive.close();
42 var completion = this.state.completionActive = new Completion(this, options);
43 if (!completion.options.hint) return;
44
45 CodeMirror.signal(this, "startCompletion", this);
46 completion.update(true);
47 });
48
49 function Completion(cm, options) {
50 this.cm = cm;
51 this.options = options;
52 this.widget = null;
53 this.debounce = 0;
54 this.tick = 0;
55 this.startPos = this.cm.getCursor("start");
56 this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
57
58 var self = this;
59 cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
60 }
61
62 var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
63 return setTimeout(fn, 1000/60);
64 };
65 var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
66
67 Completion.prototype = {
68 close: function() {
69 if (!this.active()) return;
70 this.cm.state.completionActive = null;
71 this.tick = null;
72 this.cm.off("cursorActivity", this.activityFunc);
73
74 if (this.widget && this.data) CodeMirror.signal(this.data, "close");
75 if (this.widget) this.widget.close();
76 CodeMirror.signal(this.cm, "endCompletion", this.cm);
77 },
78
79 active: function() {
80 return this.cm.state.completionActive == this;
81 },
82
83 pick: function(data, i) {
84 var completion = data.list[i];
85 if (completion.hint) completion.hint(this.cm, data, completion);
86 else this.cm.replaceRange(getText(completion), completion.from || data.from,
87 completion.to || data.to, "complete");
88 CodeMirror.signal(data, "pick", completion);
89 this.close();
90 },
91
92 cursorActivity: function() {
93 if (this.debounce) {
94 cancelAnimationFrame(this.debounce);
95 this.debounce = 0;
96 }
97
98 var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
99 if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
100 pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
101 (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
102 this.close();
103 } else {
104 var self = this;
105 this.debounce = requestAnimationFrame(function() {self.update();});
106 if (this.widget) this.widget.disable();
107 }
108 },
109
110 update: function(first) {
111 if (this.tick == null) return
112 var self = this, myTick = ++this.tick
113 fetchHints(this.options.hint, this.cm, this.options, function(data) {
114 if (self.tick == myTick) self.finishUpdate(data, first)
115 })
116 },
117
118 finishUpdate: function(data, first) {
119 if (this.data) CodeMirror.signal(this.data, "update");
120
121 var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
122 if (this.widget) this.widget.close();
123
124 if (data && this.data && isNewCompletion(this.data, data)) return;
125 this.data = data;
126
127 if (data && data.list.length) {
128 if (picked && data.list.length == 1) {
129 this.pick(data, 0);
130 } else {
131 this.widget = new Widget(this, data);
132 CodeMirror.signal(data, "shown");
133 }
134 }
135 }
136 };
137
138 function isNewCompletion(old, nw) {
139 var moved = CodeMirror.cmpPos(nw.from, old.from)
140 return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
141 }
142
143 function parseOptions(cm, pos, options) {
144 var editor = cm.options.hintOptions;
145 var out = {};
146 for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
147 if (editor) for (var prop in editor)
148 if (editor[prop] !== undefined) out[prop] = editor[prop];
149 if (options) for (var prop in options)
150 if (options[prop] !== undefined) out[prop] = options[prop];
151 if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
152 return out;
153 }
154
155 function getText(completion) {
156 if (typeof completion == "string") return completion;
157 else return completion.text;
158 }
159
160 function buildKeyMap(completion, handle) {
161 var baseMap = {
162 Up: function() {handle.moveFocus(-1);},
163 Down: function() {handle.moveFocus(1);},
164 PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
165 PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
166 Home: function() {handle.setFocus(0);},
167 End: function() {handle.setFocus(handle.length - 1);},
168 Enter: handle.pick,
169 Tab: handle.pick,
170 Esc: handle.close
171 };
172 var custom = completion.options.customKeys;
173 var ourMap = custom ? {} : baseMap;
174 function addBinding(key, val) {
175 var bound;
176 if (typeof val != "string")
177 bound = function(cm) { return val(cm, handle); };
178 // This mechanism is deprecated
179 else if (baseMap.hasOwnProperty(val))
180 bound = baseMap[val];
181 else
182 bound = val;
183 ourMap[key] = bound;
184 }
185 if (custom)
186 for (var key in custom) if (custom.hasOwnProperty(key))
187 addBinding(key, custom[key]);
188 var extra = completion.options.extraKeys;
189 if (extra)
190 for (var key in extra) if (extra.hasOwnProperty(key))
191 addBinding(key, extra[key]);
192 return ourMap;
193 }
194
195 function getHintElement(hintsElement, el) {
196 while (el && el != hintsElement) {
197 if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
198 el = el.parentNode;
199 }
200 }
201
202 function Widget(completion, data) {
203 this.completion = completion;
204 this.data = data;
205 this.picked = false;
206 var widget = this, cm = completion.cm;
207
208 var hints = this.hints = document.createElement("ul");
209 hints.className = "CodeMirror-hints";
210 this.selectedHint = data.selectedHint || 0;
211
212 var completions = data.list;
213 for (var i = 0; i < completions.length; ++i) {
214 var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
215 var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
216 if (cur.className != null) className = cur.className + " " + className;
217 elt.className = className;
218 if (cur.render) cur.render(elt, data, cur);
219 else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
220 elt.hintId = i;
221 }
222
223 var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
224 var left = pos.left, top = pos.bottom, below = true;
225 hints.style.left = left + "px";
226 hints.style.top = top + "px";
227 // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
228 var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
229 var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
230 (completion.options.container || document.body).appendChild(hints);
231 var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
232 var scrolls = hints.scrollHeight > hints.clientHeight + 1
233 var startScroll = cm.getScrollInfo();
234
235 if (overlapY > 0) {
236 var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
237 if (curTop - height > 0) { // Fits above cursor
238 hints.style.top = (top = pos.top - height) + "px";
239 below = false;
240 } else if (height > winH) {
241 hints.style.height = (winH - 5) + "px";
242 hints.style.top = (top = pos.bottom - box.top) + "px";
243 var cursor = cm.getCursor();
244 if (data.from.ch != cursor.ch) {
245 pos = cm.cursorCoords(cursor);
246 hints.style.left = (left = pos.left) + "px";
247 box = hints.getBoundingClientRect();
248 }
249 }
250 }
251 var overlapX = box.right - winW;
252 if (overlapX > 0) {
253 if (box.right - box.left > winW) {
254 hints.style.width = (winW - 5) + "px";
255 overlapX -= (box.right - box.left) - winW;
256 }
257 hints.style.left = (left = pos.left - overlapX) + "px";
258 }
259 if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
260 node.style.paddingRight = cm.display.nativeBarWidth + "px"
261
262 cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
263 moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
264 setFocus: function(n) { widget.changeActive(n); },
265 menuSize: function() { return widget.screenAmount(); },
266 length: completions.length,
267 close: function() { completion.close(); },
268 pick: function() { widget.pick(); },
269 data: data
270 }));
271
272 if (completion.options.closeOnUnfocus) {
273 var closingOnBlur;
274 cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
275 cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
276 }
277
278 cm.on("scroll", this.onScroll = function() {
279 var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
280 var newTop = top + startScroll.top - curScroll.top;
281 var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
282 if (!below) point += hints.offsetHeight;
283 if (point <= editor.top || point >= editor.bottom) return completion.close();
284 hints.style.top = newTop + "px";
285 hints.style.left = (left + startScroll.left - curScroll.left) + "px";
286 });
287
288 CodeMirror.on(hints, "dblclick", function(e) {
289 var t = getHintElement(hints, e.target || e.srcElement);
290 if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
291 });
292
293 CodeMirror.on(hints, "click", function(e) {
294 var t = getHintElement(hints, e.target || e.srcElement);
295 if (t && t.hintId != null) {
296 widget.changeActive(t.hintId);
297 if (completion.options.completeOnSingleClick) widget.pick();
298 }
299 });
300
301 CodeMirror.on(hints, "mousedown", function() {
302 setTimeout(function(){cm.focus();}, 20);
303 });
304
305 CodeMirror.signal(data, "select", completions[0], hints.firstChild);
306 return true;
307 }
308
309 Widget.prototype = {
310 close: function() {
311 if (this.completion.widget != this) return;
312 this.completion.widget = null;
313 this.hints.parentNode.removeChild(this.hints);
314 this.completion.cm.removeKeyMap(this.keyMap);
315
316 var cm = this.completion.cm;
317 if (this.completion.options.closeOnUnfocus) {
318 cm.off("blur", this.onBlur);
319 cm.off("focus", this.onFocus);
320 }
321 cm.off("scroll", this.onScroll);
322 },
323
324 disable: function() {
325 this.completion.cm.removeKeyMap(this.keyMap);
326 var widget = this;
327 this.keyMap = {Enter: function() { widget.picked = true; }};
328 this.completion.cm.addKeyMap(this.keyMap);
329 },
330
331 pick: function() {
332 this.completion.pick(this.data, this.selectedHint);
333 },
334
335 changeActive: function(i, avoidWrap) {
336 if (i >= this.data.list.length)
337 i = avoidWrap ? this.data.list.length - 1 : 0;
338 else if (i < 0)
339 i = avoidWrap ? 0 : this.data.list.length - 1;
340 if (this.selectedHint == i) return;
341 var node = this.hints.childNodes[this.selectedHint];
342 node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
343 node = this.hints.childNodes[this.selectedHint = i];
344 node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
345 if (node.offsetTop < this.hints.scrollTop)
346 this.hints.scrollTop = node.offsetTop - 3;
347 else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
348 this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
349 CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
350 },
351
352 screenAmount: function() {
353 return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
354 }
355 };
356
357 function applicableHelpers(cm, helpers) {
358 if (!cm.somethingSelected()) return helpers
359 var result = []
360 for (var i = 0; i < helpers.length; i++)
361 if (helpers[i].supportsSelection) result.push(helpers[i])
362 return result
363 }
364
365 function fetchHints(hint, cm, options, callback) {
366 if (hint.async) {
367 hint(cm, callback, options)
368 } else {
369 var result = hint(cm, options)
370 if (result && result.then) result.then(callback)
371 else callback(result)
372 }
373 }
374
375 function resolveAutoHints(cm, pos) {
376 var helpers = cm.getHelpers(pos, "hint"), words
377 if (helpers.length) {
378 var resolved = function(cm, callback, options) {
379 var app = applicableHelpers(cm, helpers);
380 function run(i) {
381 if (i == app.length) return callback(null)
382 fetchHints(app[i], cm, options, function(result) {
383 if (result && result.list.length > 0) callback(result)
384 else run(i + 1)
385 })
386 }
387 run(0)
388 }
389 resolved.async = true
390 resolved.supportsSelection = true
391 return resolved
392 } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
393 return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
394 } else if (CodeMirror.hint.anyword) {
395 return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
396 } else {
397 return function() {}
398 }
399 }
400
401 CodeMirror.registerHelper("hint", "auto", {
402 resolve: resolveAutoHints
403 });
404
405 CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
406 var cur = cm.getCursor(), token = cm.getTokenAt(cur);
407 var to = CodeMirror.Pos(cur.line, token.end);
408 if (token.string && /\w/.test(token.string[token.string.length - 1])) {
409 var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
410 } else {
411 var term = "", from = to;
412 }
413 var found = [];
414 for (var i = 0; i < options.words.length; i++) {
415 var word = options.words[i];
416 if (word.slice(0, term.length) == term)
417 found.push(word);
418 }
419
420 if (found.length) return {list: found, from: from, to: to};
421 });
422
423 CodeMirror.commands.autocomplete = CodeMirror.showHint;
424
425 var defaultOptions = {
426 hint: CodeMirror.hint.auto,
427 completeSingle: true,
428 alignWithWord: true,
429 closeCharacters: /[\s()\[\]{};:>,]/,
430 closeOnUnfocus: true,
431 completeOnSingleClick: true,
432 container: null,
433 customKeys: null,
434 extraKeys: null
435 };
436
437 CodeMirror.defineOption("hintOptions", null);
438 });
439