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