Mercurial
comparison .cms/lib/codemirror/addon/runmode/runmode-standalone.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 (function () { | |
2 'use strict'; | |
3 | |
4 function copyObj(obj, target, overwrite) { | |
5 if (!target) { target = {}; } | |
6 for (var prop in obj) | |
7 { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) | |
8 { target[prop] = obj[prop]; } } | |
9 return target | |
10 } | |
11 | |
12 // Counts the column offset in a string, taking tabs into account. | |
13 // Used mostly to find indentation. | |
14 function countColumn(string, end, tabSize, startIndex, startValue) { | |
15 if (end == null) { | |
16 end = string.search(/[^\s\u00a0]/); | |
17 if (end == -1) { end = string.length; } | |
18 } | |
19 for (var i = startIndex || 0, n = startValue || 0;;) { | |
20 var nextTab = string.indexOf("\t", i); | |
21 if (nextTab < 0 || nextTab >= end) | |
22 { return n + (end - i) } | |
23 n += nextTab - i; | |
24 n += tabSize - (n % tabSize); | |
25 i = nextTab + 1; | |
26 } | |
27 } | |
28 | |
29 function nothing() {} | |
30 | |
31 function createObj(base, props) { | |
32 var inst; | |
33 if (Object.create) { | |
34 inst = Object.create(base); | |
35 } else { | |
36 nothing.prototype = base; | |
37 inst = new nothing(); | |
38 } | |
39 if (props) { copyObj(props, inst); } | |
40 return inst | |
41 } | |
42 | |
43 // STRING STREAM | |
44 | |
45 // Fed to the mode parsers, provides helper functions to make | |
46 // parsers more succinct. | |
47 | |
48 var StringStream = function(string, tabSize, lineOracle) { | |
49 this.pos = this.start = 0; | |
50 this.string = string; | |
51 this.tabSize = tabSize || 8; | |
52 this.lastColumnPos = this.lastColumnValue = 0; | |
53 this.lineStart = 0; | |
54 this.lineOracle = lineOracle; | |
55 }; | |
56 | |
57 StringStream.prototype.eol = function () {return this.pos >= this.string.length}; | |
58 StringStream.prototype.sol = function () {return this.pos == this.lineStart}; | |
59 StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined}; | |
60 StringStream.prototype.next = function () { | |
61 if (this.pos < this.string.length) | |
62 { return this.string.charAt(this.pos++) } | |
63 }; | |
64 StringStream.prototype.eat = function (match) { | |
65 var ch = this.string.charAt(this.pos); | |
66 var ok; | |
67 if (typeof match == "string") { ok = ch == match; } | |
68 else { ok = ch && (match.test ? match.test(ch) : match(ch)); } | |
69 if (ok) {++this.pos; return ch} | |
70 }; | |
71 StringStream.prototype.eatWhile = function (match) { | |
72 var start = this.pos; | |
73 while (this.eat(match)){} | |
74 return this.pos > start | |
75 }; | |
76 StringStream.prototype.eatSpace = function () { | |
77 var start = this.pos; | |
78 while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; } | |
79 return this.pos > start | |
80 }; | |
81 StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;}; | |
82 StringStream.prototype.skipTo = function (ch) { | |
83 var found = this.string.indexOf(ch, this.pos); | |
84 if (found > -1) {this.pos = found; return true} | |
85 }; | |
86 StringStream.prototype.backUp = function (n) {this.pos -= n;}; | |
87 StringStream.prototype.column = function () { | |
88 if (this.lastColumnPos < this.start) { | |
89 this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); | |
90 this.lastColumnPos = this.start; | |
91 } | |
92 return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) | |
93 }; | |
94 StringStream.prototype.indentation = function () { | |
95 return countColumn(this.string, null, this.tabSize) - | |
96 (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) | |
97 }; | |
98 StringStream.prototype.match = function (pattern, consume, caseInsensitive) { | |
99 if (typeof pattern == "string") { | |
100 var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; | |
101 var substr = this.string.substr(this.pos, pattern.length); | |
102 if (cased(substr) == cased(pattern)) { | |
103 if (consume !== false) { this.pos += pattern.length; } | |
104 return true | |
105 } | |
106 } else { | |
107 var match = this.string.slice(this.pos).match(pattern); | |
108 if (match && match.index > 0) { return null } | |
109 if (match && consume !== false) { this.pos += match[0].length; } | |
110 return match | |
111 } | |
112 }; | |
113 StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)}; | |
114 StringStream.prototype.hideFirstChars = function (n, inner) { | |
115 this.lineStart += n; | |
116 try { return inner() } | |
117 finally { this.lineStart -= n; } | |
118 }; | |
119 StringStream.prototype.lookAhead = function (n) { | |
120 var oracle = this.lineOracle; | |
121 return oracle && oracle.lookAhead(n) | |
122 }; | |
123 StringStream.prototype.baseToken = function () { | |
124 var oracle = this.lineOracle; | |
125 return oracle && oracle.baseToken(this.pos) | |
126 }; | |
127 | |
128 // Known modes, by name and by MIME | |
129 var modes = {}, mimeModes = {}; | |
130 | |
131 // Extra arguments are stored as the mode's dependencies, which is | |
132 // used by (legacy) mechanisms like loadmode.js to automatically | |
133 // load a mode. (Preferred mechanism is the require/define calls.) | |
134 function defineMode(name, mode) { | |
135 if (arguments.length > 2) | |
136 { mode.dependencies = Array.prototype.slice.call(arguments, 2); } | |
137 modes[name] = mode; | |
138 } | |
139 | |
140 function defineMIME(mime, spec) { | |
141 mimeModes[mime] = spec; | |
142 } | |
143 | |
144 // Given a MIME type, a {name, ...options} config object, or a name | |
145 // string, return a mode config object. | |
146 function resolveMode(spec) { | |
147 if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { | |
148 spec = mimeModes[spec]; | |
149 } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { | |
150 var found = mimeModes[spec.name]; | |
151 if (typeof found == "string") { found = {name: found}; } | |
152 spec = createObj(found, spec); | |
153 spec.name = found.name; | |
154 } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { | |
155 return resolveMode("application/xml") | |
156 } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { | |
157 return resolveMode("application/json") | |
158 } | |
159 if (typeof spec == "string") { return {name: spec} } | |
160 else { return spec || {name: "null"} } | |
161 } | |
162 | |
163 // Given a mode spec (anything that resolveMode accepts), find and | |
164 // initialize an actual mode object. | |
165 function getMode(options, spec) { | |
166 spec = resolveMode(spec); | |
167 var mfactory = modes[spec.name]; | |
168 if (!mfactory) { return getMode(options, "text/plain") } | |
169 var modeObj = mfactory(options, spec); | |
170 if (modeExtensions.hasOwnProperty(spec.name)) { | |
171 var exts = modeExtensions[spec.name]; | |
172 for (var prop in exts) { | |
173 if (!exts.hasOwnProperty(prop)) { continue } | |
174 if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; } | |
175 modeObj[prop] = exts[prop]; | |
176 } | |
177 } | |
178 modeObj.name = spec.name; | |
179 if (spec.helperType) { modeObj.helperType = spec.helperType; } | |
180 if (spec.modeProps) { for (var prop$1 in spec.modeProps) | |
181 { modeObj[prop$1] = spec.modeProps[prop$1]; } } | |
182 | |
183 return modeObj | |
184 } | |
185 | |
186 // This can be used to attach properties to mode objects from | |
187 // outside the actual mode definition. | |
188 var modeExtensions = {}; | |
189 function extendMode(mode, properties) { | |
190 var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); | |
191 copyObj(properties, exts); | |
192 } | |
193 | |
194 function copyState(mode, state) { | |
195 if (state === true) { return state } | |
196 if (mode.copyState) { return mode.copyState(state) } | |
197 var nstate = {}; | |
198 for (var n in state) { | |
199 var val = state[n]; | |
200 if (val instanceof Array) { val = val.concat([]); } | |
201 nstate[n] = val; | |
202 } | |
203 return nstate | |
204 } | |
205 | |
206 // Given a mode and a state (for that mode), find the inner mode and | |
207 // state at the position that the state refers to. | |
208 function innerMode(mode, state) { | |
209 var info; | |
210 while (mode.innerMode) { | |
211 info = mode.innerMode(state); | |
212 if (!info || info.mode == mode) { break } | |
213 state = info.state; | |
214 mode = info.mode; | |
215 } | |
216 return info || {mode: mode, state: state} | |
217 } | |
218 | |
219 function startState(mode, a1, a2) { | |
220 return mode.startState ? mode.startState(a1, a2) : true | |
221 } | |
222 | |
223 var modeMethods = { | |
224 __proto__: null, | |
225 modes: modes, | |
226 mimeModes: mimeModes, | |
227 defineMode: defineMode, | |
228 defineMIME: defineMIME, | |
229 resolveMode: resolveMode, | |
230 getMode: getMode, | |
231 modeExtensions: modeExtensions, | |
232 extendMode: extendMode, | |
233 copyState: copyState, | |
234 innerMode: innerMode, | |
235 startState: startState | |
236 }; | |
237 | |
238 // declare global: globalThis, CodeMirror | |
239 | |
240 // Create a minimal CodeMirror needed to use runMode, and assign to root. | |
241 var root = typeof globalThis !== 'undefined' ? globalThis : window; | |
242 root.CodeMirror = {}; | |
243 | |
244 // Copy StringStream and mode methods into CodeMirror object. | |
245 CodeMirror.StringStream = StringStream; | |
246 for (var exported in modeMethods) { CodeMirror[exported] = modeMethods[exported]; } | |
247 | |
248 // Minimal default mode. | |
249 CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); }); | |
250 CodeMirror.defineMIME("text/plain", "null"); | |
251 | |
252 CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min; | |
253 CodeMirror.splitLines = function(string) { return string.split(/\r?\n|\r/) }; | |
254 CodeMirror.countColumn = countColumn; | |
255 | |
256 CodeMirror.defaults = { indentUnit: 2 }; | |
257 | |
258 // CodeMirror, copyright (c) by Marijn Haverbeke and others | |
259 // Distributed under an MIT license: https://codemirror.net/5/LICENSE | |
260 | |
261 (function(mod) { | |
262 if (typeof exports == "object" && typeof module == "object") // CommonJS | |
263 { mod(require("../../lib/codemirror")); } | |
264 else if (typeof define == "function" && define.amd) // AMD | |
265 { define(["../../lib/codemirror"], mod); } | |
266 else // Plain browser env | |
267 { mod(CodeMirror); } | |
268 })(function(CodeMirror) { | |
269 | |
270 CodeMirror.runMode = function(string, modespec, callback, options) { | |
271 var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); | |
272 var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; | |
273 | |
274 // Create a tokenizing callback function if passed-in callback is a DOM element. | |
275 if (callback.appendChild) { | |
276 var ie = /MSIE \d/.test(navigator.userAgent); | |
277 var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); | |
278 var node = callback, col = 0; | |
279 node.textContent = ""; | |
280 callback = function(text, style) { | |
281 if (text == "\n") { | |
282 // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. | |
283 // Emitting a carriage return makes everything ok. | |
284 node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); | |
285 col = 0; | |
286 return; | |
287 } | |
288 var content = ""; | |
289 // replace tabs | |
290 for (var pos = 0;;) { | |
291 var idx = text.indexOf("\t", pos); | |
292 if (idx == -1) { | |
293 content += text.slice(pos); | |
294 col += text.length - pos; | |
295 break; | |
296 } else { | |
297 col += idx - pos; | |
298 content += text.slice(pos, idx); | |
299 var size = tabSize - col % tabSize; | |
300 col += size; | |
301 for (var i = 0; i < size; ++i) { content += " "; } | |
302 pos = idx + 1; | |
303 } | |
304 } | |
305 // Create a node with token style and append it to the callback DOM element. | |
306 if (style) { | |
307 var sp = node.appendChild(document.createElement("span")); | |
308 sp.className = "cm-" + style.replace(/ +/g, " cm-"); | |
309 sp.appendChild(document.createTextNode(content)); | |
310 } else { | |
311 node.appendChild(document.createTextNode(content)); | |
312 } | |
313 }; | |
314 } | |
315 | |
316 var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); | |
317 for (var i = 0, e = lines.length; i < e; ++i) { | |
318 if (i) { callback("\n"); } | |
319 var stream = new CodeMirror.StringStream(lines[i], null, { | |
320 lookAhead: function(n) { return lines[i + n] }, | |
321 baseToken: function() {} | |
322 }); | |
323 if (!stream.string && mode.blankLine) { mode.blankLine(state); } | |
324 while (!stream.eol()) { | |
325 var style = mode.token(stream, state); | |
326 callback(stream.current(), style, i, stream.start, state, mode); | |
327 stream.start = stream.pos; | |
328 } | |
329 } | |
330 }; | |
331 | |
332 }); | |
333 | |
334 }()); |