runmode.node.js 13 KB

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