123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import { copyObj, createObj } from "./util/misc.js"
- // Known modes, by name and by MIME
- export let modes = {}, mimeModes = {}
- // Extra arguments are stored as the mode's dependencies, which is
- // used by (legacy) mechanisms like loadmode.js to automatically
- // load a mode. (Preferred mechanism is the require/define calls.)
- export function defineMode(name, mode) {
- if (arguments.length > 2)
- mode.dependencies = Array.prototype.slice.call(arguments, 2)
- modes[name] = mode
- }
- export function defineMIME(mime, spec) {
- mimeModes[mime] = spec
- }
- // Given a MIME type, a {name, ...options} config object, or a name
- // string, return a mode config object.
- export function resolveMode(spec) {
- if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
- spec = mimeModes[spec]
- } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
- let found = mimeModes[spec.name]
- if (typeof found == "string") found = {name: found}
- spec = createObj(found, spec)
- spec.name = found.name
- } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
- return resolveMode("application/xml")
- } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
- return resolveMode("application/json")
- }
- if (typeof spec == "string") return {name: spec}
- else return spec || {name: "null"}
- }
- // Given a mode spec (anything that resolveMode accepts), find and
- // initialize an actual mode object.
- export function getMode(options, spec) {
- spec = resolveMode(spec)
- let mfactory = modes[spec.name]
- if (!mfactory) return getMode(options, "text/plain")
- let modeObj = mfactory(options, spec)
- if (modeExtensions.hasOwnProperty(spec.name)) {
- let exts = modeExtensions[spec.name]
- for (let prop in exts) {
- if (!exts.hasOwnProperty(prop)) continue
- if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]
- modeObj[prop] = exts[prop]
- }
- }
- modeObj.name = spec.name
- if (spec.helperType) modeObj.helperType = spec.helperType
- if (spec.modeProps) for (let prop in spec.modeProps)
- modeObj[prop] = spec.modeProps[prop]
- return modeObj
- }
- // This can be used to attach properties to mode objects from
- // outside the actual mode definition.
- export let modeExtensions = {}
- export function extendMode(mode, properties) {
- let exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {})
- copyObj(properties, exts)
- }
- export function copyState(mode, state) {
- if (state === true) return state
- if (mode.copyState) return mode.copyState(state)
- let nstate = {}
- for (let n in state) {
- let val = state[n]
- if (val instanceof Array) val = val.concat([])
- nstate[n] = val
- }
- return nstate
- }
- // Given a mode and a state (for that mode), find the inner mode and
- // state at the position that the state refers to.
- export function innerMode(mode, state) {
- let info
- while (mode.innerMode) {
- info = mode.innerMode(state)
- if (!info || info.mode == mode) break
- state = info.state
- mode = info.mode
- }
- return info || {mode: mode, state: state}
- }
- export function startState(mode, a1, a2) {
- return mode.startState ? mode.startState(a1, a2) : true
- }
|