[ Index ] |
PHP Cross Reference of MyBB 1.8.38 |
[Summary view] [Print] [Text view]
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 var Pos = CodeMirror.Pos 14 15 function regexpFlags(regexp) { 16 var flags = regexp.flags 17 return flags != null ? flags : (regexp.ignoreCase ? "i" : "") 18 + (regexp.global ? "g" : "") 19 + (regexp.multiline ? "m" : "") 20 } 21 22 function ensureGlobal(regexp) { 23 return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g") 24 } 25 26 function maybeMultiline(regexp) { 27 return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source) 28 } 29 30 function searchRegexpForward(doc, regexp, start) { 31 regexp = ensureGlobal(regexp) 32 for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) { 33 regexp.lastIndex = ch 34 var string = doc.getLine(line), match = regexp.exec(string) 35 if (match) 36 return {from: Pos(line, match.index), 37 to: Pos(line, match.index + match[0].length), 38 match: match} 39 } 40 } 41 42 function searchRegexpForwardMultiline(doc, regexp, start) { 43 if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start) 44 45 regexp = ensureGlobal(regexp) 46 var string, chunk = 1 47 for (var line = start.line, last = doc.lastLine(); line <= last;) { 48 // This grows the search buffer in exponentially-sized chunks 49 // between matches, so that nearby matches are fast and don't 50 // require concatenating the whole document (in case we're 51 // searching for something that has tons of matches), but at the 52 // same time, the amount of retries is limited. 53 for (var i = 0; i < chunk; i++) { 54 var curLine = doc.getLine(line++) 55 string = string == null ? curLine : string + "\n" + curLine 56 } 57 chunk = chunk * 2 58 regexp.lastIndex = start.ch 59 var match = regexp.exec(string) 60 if (match) { 61 var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n") 62 var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length 63 return {from: Pos(startLine, startCh), 64 to: Pos(startLine + inside.length - 1, 65 inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), 66 match: match} 67 } 68 } 69 } 70 71 function lastMatchIn(string, regexp) { 72 var cutOff = 0, match 73 for (;;) { 74 regexp.lastIndex = cutOff 75 var newMatch = regexp.exec(string) 76 if (!newMatch) return match 77 match = newMatch 78 cutOff = match.index + (match[0].length || 1) 79 if (cutOff == string.length) return match 80 } 81 } 82 83 function searchRegexpBackward(doc, regexp, start) { 84 regexp = ensureGlobal(regexp) 85 for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) { 86 var string = doc.getLine(line) 87 if (ch > -1) string = string.slice(0, ch) 88 var match = lastMatchIn(string, regexp) 89 if (match) 90 return {from: Pos(line, match.index), 91 to: Pos(line, match.index + match[0].length), 92 match: match} 93 } 94 } 95 96 function searchRegexpBackwardMultiline(doc, regexp, start) { 97 regexp = ensureGlobal(regexp) 98 var string, chunk = 1 99 for (var line = start.line, first = doc.firstLine(); line >= first;) { 100 for (var i = 0; i < chunk; i++) { 101 var curLine = doc.getLine(line--) 102 string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string 103 } 104 chunk *= 2 105 106 var match = lastMatchIn(string, regexp) 107 if (match) { 108 var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n") 109 var startLine = line + before.length, startCh = before[before.length - 1].length 110 return {from: Pos(startLine, startCh), 111 to: Pos(startLine + inside.length - 1, 112 inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), 113 match: match} 114 } 115 } 116 } 117 118 var doFold, noFold 119 if (String.prototype.normalize) { 120 doFold = function(str) { return str.normalize("NFD").toLowerCase() } 121 noFold = function(str) { return str.normalize("NFD") } 122 } else { 123 doFold = function(str) { return str.toLowerCase() } 124 noFold = function(str) { return str } 125 } 126 127 // Maps a position in a case-folded line back to a position in the original line 128 // (compensating for codepoints increasing in number during folding) 129 function adjustPos(orig, folded, pos, foldFunc) { 130 if (orig.length == folded.length) return pos 131 for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) { 132 if (min == max) return min 133 var mid = (min + max) >> 1 134 var len = foldFunc(orig.slice(0, mid)).length 135 if (len == pos) return mid 136 else if (len > pos) max = mid 137 else min = mid + 1 138 } 139 } 140 141 function searchStringForward(doc, query, start, caseFold) { 142 // Empty string would match anything and never progress, so we 143 // define it to match nothing instead. 144 if (!query.length) return null 145 var fold = caseFold ? doFold : noFold 146 var lines = fold(query).split(/\r|\n\r?/) 147 148 search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) { 149 var orig = doc.getLine(line).slice(ch), string = fold(orig) 150 if (lines.length == 1) { 151 var found = string.indexOf(lines[0]) 152 if (found == -1) continue search 153 var start = adjustPos(orig, string, found, fold) + ch 154 return {from: Pos(line, adjustPos(orig, string, found, fold) + ch), 155 to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)} 156 } else { 157 var cutFrom = string.length - lines[0].length 158 if (string.slice(cutFrom) != lines[0]) continue search 159 for (var i = 1; i < lines.length - 1; i++) 160 if (fold(doc.getLine(line + i)) != lines[i]) continue search 161 var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1] 162 if (end.slice(0, lastLine.length) != lastLine) continue search 163 return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch), 164 to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))} 165 } 166 } 167 } 168 169 function searchStringBackward(doc, query, start, caseFold) { 170 if (!query.length) return null 171 var fold = caseFold ? doFold : noFold 172 var lines = fold(query).split(/\r|\n\r?/) 173 174 search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) { 175 var orig = doc.getLine(line) 176 if (ch > -1) orig = orig.slice(0, ch) 177 var string = fold(orig) 178 if (lines.length == 1) { 179 var found = string.lastIndexOf(lines[0]) 180 if (found == -1) continue search 181 return {from: Pos(line, adjustPos(orig, string, found, fold)), 182 to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))} 183 } else { 184 var lastLine = lines[lines.length - 1] 185 if (string.slice(0, lastLine.length) != lastLine) continue search 186 for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++) 187 if (fold(doc.getLine(start + i)) != lines[i]) continue search 188 var top = doc.getLine(line + 1 - lines.length), topString = fold(top) 189 if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search 190 return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)), 191 to: Pos(line, adjustPos(orig, string, lastLine.length, fold))} 192 } 193 } 194 } 195 196 function SearchCursor(doc, query, pos, options) { 197 this.atOccurrence = false 198 this.doc = doc 199 pos = pos ? doc.clipPos(pos) : Pos(0, 0) 200 this.pos = {from: pos, to: pos} 201 202 var caseFold 203 if (typeof options == "object") { 204 caseFold = options.caseFold 205 } else { // Backwards compat for when caseFold was the 4th argument 206 caseFold = options 207 options = null 208 } 209 210 if (typeof query == "string") { 211 if (caseFold == null) caseFold = false 212 this.matches = function(reverse, pos) { 213 return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold) 214 } 215 } else { 216 query = ensureGlobal(query) 217 if (!options || options.multiline !== false) 218 this.matches = function(reverse, pos) { 219 return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos) 220 } 221 else 222 this.matches = function(reverse, pos) { 223 return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos) 224 } 225 } 226 } 227 228 SearchCursor.prototype = { 229 findNext: function() {return this.find(false)}, 230 findPrevious: function() {return this.find(true)}, 231 232 find: function(reverse) { 233 var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to)) 234 235 // Implements weird auto-growing behavior on null-matches for 236 // backwards-compatiblity with the vim code (unfortunately) 237 while (result && CodeMirror.cmpPos(result.from, result.to) == 0) { 238 if (reverse) { 239 if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1) 240 else if (result.from.line == this.doc.firstLine()) result = null 241 else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1))) 242 } else { 243 if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1) 244 else if (result.to.line == this.doc.lastLine()) result = null 245 else result = this.matches(reverse, Pos(result.to.line + 1, 0)) 246 } 247 } 248 249 if (result) { 250 this.pos = result 251 this.atOccurrence = true 252 return this.pos.match || true 253 } else { 254 var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0) 255 this.pos = {from: end, to: end} 256 return this.atOccurrence = false 257 } 258 }, 259 260 from: function() {if (this.atOccurrence) return this.pos.from}, 261 to: function() {if (this.atOccurrence) return this.pos.to}, 262 263 replace: function(newText, origin) { 264 if (!this.atOccurrence) return 265 var lines = CodeMirror.splitLines(newText) 266 this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin) 267 this.pos.to = Pos(this.pos.from.line + lines.length - 1, 268 lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)) 269 } 270 } 271 272 CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { 273 return new SearchCursor(this.doc, query, pos, caseFold) 274 }) 275 CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { 276 return new SearchCursor(this, query, pos, caseFold) 277 }) 278 279 CodeMirror.defineExtension("selectMatches", function(query, caseFold) { 280 var ranges = [] 281 var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold) 282 while (cur.findNext()) { 283 if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break 284 ranges.push({anchor: cur.from(), head: cur.to()}) 285 } 286 if (ranges.length) 287 this.setSelections(ranges, 0) 288 }) 289 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup | Cross-referenced by PHPXref |