File modules/editor/codemirror/addon/search/search.min.js

Last commit: Tue May 22 22:39:55 2018 +0200	Jan Dankert	Fix für PHP 7.2: 'Object' darf nun nicht mehr als Klassennamen verwendet werden. AUCH NICHT IN EINEM NAMESPACE! WTF, wozu habe ich das in einen verfickten Namespace gepackt? Wozu soll der sonst da sein??? Amateure. Daher nun notgedrungen unbenannt in 'BaseObject'.
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()) : 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 });
Download modules/editor/codemirror/addon/search/search.min.js
History Tue, 22 May 2018 22:39:55 +0200 Jan Dankert Fix für PHP 7.2: 'Object' darf nun nicht mehr als Klassennamen verwendet werden. AUCH NICHT IN EINEM NAMESPACE! WTF, wozu habe ich das in einen verfickten Namespace gepackt? Wozu soll der sonst da sein??? Amateure. Daher nun notgedrungen unbenannt in 'BaseObject'.