Mercurial
comparison .cms/lib/codemirror/src/modes.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 import { copyObj, createObj } from "./util/misc.js" | |
2 | |
3 // Known modes, by name and by MIME | |
4 export let modes = {}, mimeModes = {} | |
5 | |
6 // Extra arguments are stored as the mode's dependencies, which is | |
7 // used by (legacy) mechanisms like loadmode.js to automatically | |
8 // load a mode. (Preferred mechanism is the require/define calls.) | |
9 export function defineMode(name, mode) { | |
10 if (arguments.length > 2) | |
11 mode.dependencies = Array.prototype.slice.call(arguments, 2) | |
12 modes[name] = mode | |
13 } | |
14 | |
15 export function defineMIME(mime, spec) { | |
16 mimeModes[mime] = spec | |
17 } | |
18 | |
19 // Given a MIME type, a {name, ...options} config object, or a name | |
20 // string, return a mode config object. | |
21 export function resolveMode(spec) { | |
22 if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { | |
23 spec = mimeModes[spec] | |
24 } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { | |
25 let found = mimeModes[spec.name] | |
26 if (typeof found == "string") found = {name: found} | |
27 spec = createObj(found, spec) | |
28 spec.name = found.name | |
29 } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { | |
30 return resolveMode("application/xml") | |
31 } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { | |
32 return resolveMode("application/json") | |
33 } | |
34 if (typeof spec == "string") return {name: spec} | |
35 else return spec || {name: "null"} | |
36 } | |
37 | |
38 // Given a mode spec (anything that resolveMode accepts), find and | |
39 // initialize an actual mode object. | |
40 export function getMode(options, spec) { | |
41 spec = resolveMode(spec) | |
42 let mfactory = modes[spec.name] | |
43 if (!mfactory) return getMode(options, "text/plain") | |
44 let modeObj = mfactory(options, spec) | |
45 if (modeExtensions.hasOwnProperty(spec.name)) { | |
46 let exts = modeExtensions[spec.name] | |
47 for (let prop in exts) { | |
48 if (!exts.hasOwnProperty(prop)) continue | |
49 if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop] | |
50 modeObj[prop] = exts[prop] | |
51 } | |
52 } | |
53 modeObj.name = spec.name | |
54 if (spec.helperType) modeObj.helperType = spec.helperType | |
55 if (spec.modeProps) for (let prop in spec.modeProps) | |
56 modeObj[prop] = spec.modeProps[prop] | |
57 | |
58 return modeObj | |
59 } | |
60 | |
61 // This can be used to attach properties to mode objects from | |
62 // outside the actual mode definition. | |
63 export let modeExtensions = {} | |
64 export function extendMode(mode, properties) { | |
65 let exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}) | |
66 copyObj(properties, exts) | |
67 } | |
68 | |
69 export function copyState(mode, state) { | |
70 if (state === true) return state | |
71 if (mode.copyState) return mode.copyState(state) | |
72 let nstate = {} | |
73 for (let n in state) { | |
74 let val = state[n] | |
75 if (val instanceof Array) val = val.concat([]) | |
76 nstate[n] = val | |
77 } | |
78 return nstate | |
79 } | |
80 | |
81 // Given a mode and a state (for that mode), find the inner mode and | |
82 // state at the position that the state refers to. | |
83 export function innerMode(mode, state) { | |
84 let info | |
85 while (mode.innerMode) { | |
86 info = mode.innerMode(state) | |
87 if (!info || info.mode == mode) break | |
88 state = info.state | |
89 mode = info.mode | |
90 } | |
91 return info || {mode: mode, state: state} | |
92 } | |
93 | |
94 export function startState(mode, a1, a2) { | |
95 return mode.startState ? mode.startState(a1, a2) : true | |
96 } |