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