PageSourceSearch

https://www.sports.sk/SiteJay2.0/Tools/codemirror/addon/search/search.js

js sports.sk collected 2026-10-09 01:47:21 UTC 10,306 bytes, 252 lines download raw bytes

1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: http://codemirror.net/LICENSE
3
4// Define search commands. Depends on dialog.js or another
5// implementation of the openDialog method.
6
7// Replace works a little oddly -- it will do the replace on the next
8// Ctrl-G (or whatever is bound to findNext) press. You prevent a
9// replace by making sure the match is no longer selected when hitting
10// Ctrl-G.
11
12(function(mod) {
13  if (typeof exports == "object" && typeof module == "object") // CommonJS
14    mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
15  else if (typeof define == "function" && define.amd) // AMD
16    define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
17  else // Plain browser env
18    mod(CodeMirror);
19})(function(CodeMirror) {
20  "use strict";
21
22  function searchOverlay(query, caseInsensitive) {
23    if (typeof query == "string")
24      query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
25    else if (!query.global)
26      query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
27
28    return {token: function(stream) {
29      query.lastIndex = stream.pos;
30      var match = query.exec(stream.string);
31      if (match && match.index == stream.pos) {
32        stream.pos += match[0].length || 1;
33        return "searching";
34      } else if (match) {
35        stream.pos = match.index;
36      } else {
37        stream.skipToEnd();
38      }
39    }};
40  }
41
42  function SearchState() {
43    this.posFrom = this.posTo = this.lastQuery = this.query = null;
44    this.overlay = null;
45  }
46
47  function getSearchState(cm) {
48    return cm.state.search || (cm.state.search = new SearchState());
49  }
50
51  function queryCaseInsensitive(query) {
52    return typeof query == "string" && query == query.toLowerCase();
53  }
54
55  function getSearchCursor(cm, query, pos) {
56    // Heuristic: if the query string is all lowercase, do a case insensitive search.
57    return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
58  }
59
60  function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
61    cm.openDialog(text, onEnter, {
62      value: deflt,
63      selectValueOnOpen: true,
64      closeOnEnter: false,
65      onClose: function() { clearSearch(cm); },
66      onKeyDown: onKeyDown
67    });
68  }
69
70  function dialog(cm, text, shortText, deflt, f) {
71    if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
72    else f(prompt(shortText, deflt));
73  }
74
75  function confirmDialog(cm, text, shortText, fs) {
76    if (cm.openConfirm) cm.openConfirm(text, fs);
77    else if (confirm(shortText)) fs[0]();
78  }
79
80  function parseString(string) {
81    return string.replace(/\\(.)/g, function(_, ch) {
82      if (ch == "n") return "\n"
83      if (ch == "r") return "\r"
84      return ch
85    })
86  }
87
88  function parseQuery(query) {
89    var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
90    if (isRE) {
91      try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
92      catch(e) {} // Not a regular expression after all, do a string search
93    } else {
94      query = parseString(query)
95    }
96    if (typeof query == "string" ? query == "" : query.test(""))
97      query = /x^/;
98    return query;
99  }
100
101  var queryDialog =
102    '<span class="CodeMirror-search-label">Search:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
103
104  function startSearch(cm, state, query) {
105    state.queryText = query;
106    state.query = parseQuery(query);
107    cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
108    state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
109    cm.addOverlay(state.overlay);
110    if (cm.showMatchesOnScrollbar) {
111      if (state.annotate) { state.annotate.clear(); state.annotate = null; }
112      state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
113    }
114  }
115
116  function doSearch(cm, rev, persistent, immediate) {
117    var state = getSearchState(cm);
118    if (state.query) return findNext(cm, rev);
119    var q = cm.getSelection() || state.lastQuery;
120    if (q instanceof RegExp && q.source == "x^") q = null
121    if (persistent && cm.openDialog) {
122      var hiding = null
123      var searchNext = function(query, event) {
124        CodeMirror.e_stop(event);
125        if (!query) return;
126        if (query != state.queryText) {
127          startSearch(cm, state, query);
128          state.posFrom = state.posTo = cm.getCursor();
129        }
130        if (hiding) hiding.style.opacity = 1
131        findNext(cm, event.shiftKey, function(_, to) {
132          var dialog
133          if (to.line < 3 && document.querySelector &&
134              (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
135              dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
136            (hiding = dialog).style.opacity = .4
137        })
138      };
139      persistentDialog(cm, queryDialog, q, searchNext, function(event, query) {
140        var keyName = CodeMirror.keyName(event)
141        var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
142        if (cmd == "findNext" || cmd == "findPrev" ||
143          cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
144          CodeMirror.e_stop(event);
145          startSearch(cm, getSearchState(cm), query);
146          cm.execCommand(cmd);
147        } else if (cmd == "find" || cmd == "findPersistent") {
148          CodeMirror.e_stop(event);
149          searchNext(query, event);
150        }
151      });
152      if (immediate && q) {
153        startSearch(cm, state, q);
154        findNext(cm, rev);
155      }
156    } else {
157      dialog(cm, queryDialog, "Search for:", q, function(query) {
158        if (query && !state.query) cm.operation(function() {
159          startSearch(cm, state, query);
160          state.posFrom = state.posTo = cm.getCursor();
161          findNext(cm, rev);
162        });
163      });
164    }
165  }
166
167  function findNext(cm, rev, callback) {cm.operation(function() {
168    var state = getSearchState(cm);
169    var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
170    if (!cursor.find(rev)) {
171      cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()
171) : CodeMirror.Pos(cm.firstLine(), 0));
172      if (!cursor.find(rev)) return;
173    }
174    cm.setSelection(cursor.from(), cursor.to());
175    cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
176    state.posFrom = cursor.from(); state.posTo = cursor.to();
177    if (callback) callback(cursor.from(), cursor.to())
178  });}
179
180  function clearSearch(cm) {cm.operation(function() {
181    var state = getSearchState(cm);
182    state.lastQuery = state.query;
183    if (!state.query) return;
184    state.query = state.queryText = null;
185    cm.removeOverlay(state.overlay);
186    if (state.annotate) { state.annotate.clear(); state.annotate = null; }
187  });}
188
189  var replaceQueryDialog =
190    ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
191  var replacementQueryDialog = '<span class="CodeMirror-search-label">With:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
192  var doReplaceConfirm = '<span class="CodeMirror-search-label">Replace?</span> <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>';
193
194  function replaceAll(cm, query, text) {
195    cm.operation(function() {
196      for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
197        if (typeof query != "string") {
198          var match = cm.getRange(cursor.from(), cursor.to()).match(query);
199          cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
200        } else cursor.replace(text);
201      }
202    });
203  }
204
205  function replace(cm, all) {
206    if (cm.getOption("readOnly")) return;
207    var query = cm.getSelection() || getSearchState(cm).lastQuery;
208    var dialogText = '<span class="CodeMirror-search-label">' + (all ? 'Replace all:' : 'Replace:') + '</span>';
209    dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
210      if (!query) return;
211      query = parseQuery(query);
212      dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
213        text = parseString(text)
214        if (all) {
215          replaceAll(cm, query, text)
216        } else {
217          clearSearch(cm);
218          var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
219          var advance = function() {
220            var start = cursor.from(), match;
221            if (!(match = cursor.findNext())) {
222              cursor = getSearchCursor(cm, query);
223              if (!(match = cursor.findNext()) ||
224                  (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
225            }
226            cm.setSelection(cursor.from(), cursor.to());
227            cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
228            confirmDialog(cm, doReplaceConfirm, "Replace?",
229                          [function() {doReplace(match);}, advance,
230                           function() {replaceAll(cm, query, text)}]);
231          };
232          var doReplace = function(match) {
233            cursor.replace(typeof query == "string" ? text :
234                           text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
235            advance();
236          };
237          advance();
238        }
239      });
240    });
241  }
242
243  CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
244  CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
245  CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
246  CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
247  CodeMirror.commands.findNext = doSearch;
248  CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
249  CodeMirror.commands.clearSearch = clearSearch;
250  CodeMirror.commands.replace = replace;
251  CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
252});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.