openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

modes.min.js (3241B)


      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 }