handlebars.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. define('vs/basic-languages/handlebars/handlebars',["require", "exports", "../fillers/monaco-editor-core"], function (require, exports, monaco_editor_core_1) {
  6. "use strict";
  7. Object.defineProperty(exports, "__esModule", { value: true });
  8. exports.language = exports.conf = void 0;
  9. var EMPTY_ELEMENTS = [
  10. 'area',
  11. 'base',
  12. 'br',
  13. 'col',
  14. 'embed',
  15. 'hr',
  16. 'img',
  17. 'input',
  18. 'keygen',
  19. 'link',
  20. 'menuitem',
  21. 'meta',
  22. 'param',
  23. 'source',
  24. 'track',
  25. 'wbr'
  26. ];
  27. exports.conf = {
  28. wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g,
  29. comments: {
  30. blockComment: ['{{!--', '--}}']
  31. },
  32. brackets: [
  33. ['<!--', '-->'],
  34. ['<', '>'],
  35. ['{{', '}}'],
  36. ['{', '}'],
  37. ['(', ')']
  38. ],
  39. autoClosingPairs: [
  40. { open: '{', close: '}' },
  41. { open: '[', close: ']' },
  42. { open: '(', close: ')' },
  43. { open: '"', close: '"' },
  44. { open: "'", close: "'" }
  45. ],
  46. surroundingPairs: [
  47. { open: '<', close: '>' },
  48. { open: '"', close: '"' },
  49. { open: "'", close: "'" }
  50. ],
  51. onEnterRules: [
  52. {
  53. beforeText: new RegExp("<(?!(?:" + EMPTY_ELEMENTS.join('|') + "))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$", 'i'),
  54. afterText: /^<\/(\w[\w\d]*)\s*>$/i,
  55. action: {
  56. indentAction: monaco_editor_core_1.languages.IndentAction.IndentOutdent
  57. }
  58. },
  59. {
  60. beforeText: new RegExp("<(?!(?:" + EMPTY_ELEMENTS.join('|') + "))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$", 'i'),
  61. action: { indentAction: monaco_editor_core_1.languages.IndentAction.Indent }
  62. }
  63. ]
  64. };
  65. exports.language = {
  66. defaultToken: '',
  67. tokenPostfix: '',
  68. // ignoreCase: true,
  69. // The main tokenizer for our languages
  70. tokenizer: {
  71. root: [
  72. [/\{\{!--/, 'comment.block.start.handlebars', '@commentBlock'],
  73. [/\{\{!/, 'comment.start.handlebars', '@comment'],
  74. [/\{\{/, { token: '@rematch', switchTo: '@handlebarsInSimpleState.root' }],
  75. [/<!DOCTYPE/, 'metatag.html', '@doctype'],
  76. [/<!--/, 'comment.html', '@commentHtml'],
  77. [/(<)(\w+)(\/>)/, ['delimiter.html', 'tag.html', 'delimiter.html']],
  78. [/(<)(script)/, ['delimiter.html', { token: 'tag.html', next: '@script' }]],
  79. [/(<)(style)/, ['delimiter.html', { token: 'tag.html', next: '@style' }]],
  80. [/(<)([:\w]+)/, ['delimiter.html', { token: 'tag.html', next: '@otherTag' }]],
  81. [/(<\/)(\w+)/, ['delimiter.html', { token: 'tag.html', next: '@otherTag' }]],
  82. [/</, 'delimiter.html'],
  83. [/\{/, 'delimiter.html'],
  84. [/[^<{]+/] // text
  85. ],
  86. doctype: [
  87. [
  88. /\{\{/,
  89. {
  90. token: '@rematch',
  91. switchTo: '@handlebarsInSimpleState.comment'
  92. }
  93. ],
  94. [/[^>]+/, 'metatag.content.html'],
  95. [/>/, 'metatag.html', '@pop']
  96. ],
  97. comment: [
  98. [/\}\}/, 'comment.end.handlebars', '@pop'],
  99. [/./, 'comment.content.handlebars']
  100. ],
  101. commentBlock: [
  102. [/--\}\}/, 'comment.block.end.handlebars', '@pop'],
  103. [/./, 'comment.content.handlebars']
  104. ],
  105. commentHtml: [
  106. [
  107. /\{\{/,
  108. {
  109. token: '@rematch',
  110. switchTo: '@handlebarsInSimpleState.comment'
  111. }
  112. ],
  113. [/-->/, 'comment.html', '@pop'],
  114. [/[^-]+/, 'comment.content.html'],
  115. [/./, 'comment.content.html']
  116. ],
  117. otherTag: [
  118. [
  119. /\{\{/,
  120. {
  121. token: '@rematch',
  122. switchTo: '@handlebarsInSimpleState.otherTag'
  123. }
  124. ],
  125. [/\/?>/, 'delimiter.html', '@pop'],
  126. [/"([^"]*)"/, 'attribute.value'],
  127. [/'([^']*)'/, 'attribute.value'],
  128. [/[\w\-]+/, 'attribute.name'],
  129. [/=/, 'delimiter'],
  130. [/[ \t\r\n]+/] // whitespace
  131. ],
  132. // -- BEGIN <script> tags handling
  133. // After <script
  134. script: [
  135. [
  136. /\{\{/,
  137. {
  138. token: '@rematch',
  139. switchTo: '@handlebarsInSimpleState.script'
  140. }
  141. ],
  142. [/type/, 'attribute.name', '@scriptAfterType'],
  143. [/"([^"]*)"/, 'attribute.value'],
  144. [/'([^']*)'/, 'attribute.value'],
  145. [/[\w\-]+/, 'attribute.name'],
  146. [/=/, 'delimiter'],
  147. [
  148. />/,
  149. {
  150. token: 'delimiter.html',
  151. next: '@scriptEmbedded.text/javascript',
  152. nextEmbedded: 'text/javascript'
  153. }
  154. ],
  155. [/[ \t\r\n]+/],
  156. [
  157. /(<\/)(script\s*)(>)/,
  158. ['delimiter.html', 'tag.html', { token: 'delimiter.html', next: '@pop' }]
  159. ]
  160. ],
  161. // After <script ... type
  162. scriptAfterType: [
  163. [
  164. /\{\{/,
  165. {
  166. token: '@rematch',
  167. switchTo: '@handlebarsInSimpleState.scriptAfterType'
  168. }
  169. ],
  170. [/=/, 'delimiter', '@scriptAfterTypeEquals'],
  171. [
  172. />/,
  173. {
  174. token: 'delimiter.html',
  175. next: '@scriptEmbedded.text/javascript',
  176. nextEmbedded: 'text/javascript'
  177. }
  178. ],
  179. [/[ \t\r\n]+/],
  180. [/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
  181. ],
  182. // After <script ... type =
  183. scriptAfterTypeEquals: [
  184. [
  185. /\{\{/,
  186. {
  187. token: '@rematch',
  188. switchTo: '@handlebarsInSimpleState.scriptAfterTypeEquals'
  189. }
  190. ],
  191. [
  192. /"([^"]*)"/,
  193. {
  194. token: 'attribute.value',
  195. switchTo: '@scriptWithCustomType.$1'
  196. }
  197. ],
  198. [
  199. /'([^']*)'/,
  200. {
  201. token: 'attribute.value',
  202. switchTo: '@scriptWithCustomType.$1'
  203. }
  204. ],
  205. [
  206. />/,
  207. {
  208. token: 'delimiter.html',
  209. next: '@scriptEmbedded.text/javascript',
  210. nextEmbedded: 'text/javascript'
  211. }
  212. ],
  213. [/[ \t\r\n]+/],
  214. [/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
  215. ],
  216. // After <script ... type = $S2
  217. scriptWithCustomType: [
  218. [
  219. /\{\{/,
  220. {
  221. token: '@rematch',
  222. switchTo: '@handlebarsInSimpleState.scriptWithCustomType.$S2'
  223. }
  224. ],
  225. [
  226. />/,
  227. {
  228. token: 'delimiter.html',
  229. next: '@scriptEmbedded.$S2',
  230. nextEmbedded: '$S2'
  231. }
  232. ],
  233. [/"([^"]*)"/, 'attribute.value'],
  234. [/'([^']*)'/, 'attribute.value'],
  235. [/[\w\-]+/, 'attribute.name'],
  236. [/=/, 'delimiter'],
  237. [/[ \t\r\n]+/],
  238. [/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
  239. ],
  240. scriptEmbedded: [
  241. [
  242. /\{\{/,
  243. {
  244. token: '@rematch',
  245. switchTo: '@handlebarsInEmbeddedState.scriptEmbedded.$S2',
  246. nextEmbedded: '@pop'
  247. }
  248. ],
  249. [/<\/script/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }]
  250. ],
  251. // -- END <script> tags handling
  252. // -- BEGIN <style> tags handling
  253. // After <style
  254. style: [
  255. [
  256. /\{\{/,
  257. {
  258. token: '@rematch',
  259. switchTo: '@handlebarsInSimpleState.style'
  260. }
  261. ],
  262. [/type/, 'attribute.name', '@styleAfterType'],
  263. [/"([^"]*)"/, 'attribute.value'],
  264. [/'([^']*)'/, 'attribute.value'],
  265. [/[\w\-]+/, 'attribute.name'],
  266. [/=/, 'delimiter'],
  267. [
  268. />/,
  269. {
  270. token: 'delimiter.html',
  271. next: '@styleEmbedded.text/css',
  272. nextEmbedded: 'text/css'
  273. }
  274. ],
  275. [/[ \t\r\n]+/],
  276. [
  277. /(<\/)(style\s*)(>)/,
  278. ['delimiter.html', 'tag.html', { token: 'delimiter.html', next: '@pop' }]
  279. ]
  280. ],
  281. // After <style ... type
  282. styleAfterType: [
  283. [
  284. /\{\{/,
  285. {
  286. token: '@rematch',
  287. switchTo: '@handlebarsInSimpleState.styleAfterType'
  288. }
  289. ],
  290. [/=/, 'delimiter', '@styleAfterTypeEquals'],
  291. [
  292. />/,
  293. {
  294. token: 'delimiter.html',
  295. next: '@styleEmbedded.text/css',
  296. nextEmbedded: 'text/css'
  297. }
  298. ],
  299. [/[ \t\r\n]+/],
  300. [/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
  301. ],
  302. // After <style ... type =
  303. styleAfterTypeEquals: [
  304. [
  305. /\{\{/,
  306. {
  307. token: '@rematch',
  308. switchTo: '@handlebarsInSimpleState.styleAfterTypeEquals'
  309. }
  310. ],
  311. [
  312. /"([^"]*)"/,
  313. {
  314. token: 'attribute.value',
  315. switchTo: '@styleWithCustomType.$1'
  316. }
  317. ],
  318. [
  319. /'([^']*)'/,
  320. {
  321. token: 'attribute.value',
  322. switchTo: '@styleWithCustomType.$1'
  323. }
  324. ],
  325. [
  326. />/,
  327. {
  328. token: 'delimiter.html',
  329. next: '@styleEmbedded.text/css',
  330. nextEmbedded: 'text/css'
  331. }
  332. ],
  333. [/[ \t\r\n]+/],
  334. [/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
  335. ],
  336. // After <style ... type = $S2
  337. styleWithCustomType: [
  338. [
  339. /\{\{/,
  340. {
  341. token: '@rematch',
  342. switchTo: '@handlebarsInSimpleState.styleWithCustomType.$S2'
  343. }
  344. ],
  345. [
  346. />/,
  347. {
  348. token: 'delimiter.html',
  349. next: '@styleEmbedded.$S2',
  350. nextEmbedded: '$S2'
  351. }
  352. ],
  353. [/"([^"]*)"/, 'attribute.value'],
  354. [/'([^']*)'/, 'attribute.value'],
  355. [/[\w\-]+/, 'attribute.name'],
  356. [/=/, 'delimiter'],
  357. [/[ \t\r\n]+/],
  358. [/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
  359. ],
  360. styleEmbedded: [
  361. [
  362. /\{\{/,
  363. {
  364. token: '@rematch',
  365. switchTo: '@handlebarsInEmbeddedState.styleEmbedded.$S2',
  366. nextEmbedded: '@pop'
  367. }
  368. ],
  369. [/<\/style/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }]
  370. ],
  371. // -- END <style> tags handling
  372. handlebarsInSimpleState: [
  373. [/\{\{\{?/, 'delimiter.handlebars'],
  374. [/\}\}\}?/, { token: 'delimiter.handlebars', switchTo: '@$S2.$S3' }],
  375. { include: 'handlebarsRoot' }
  376. ],
  377. handlebarsInEmbeddedState: [
  378. [/\{\{\{?/, 'delimiter.handlebars'],
  379. [
  380. /\}\}\}?/,
  381. {
  382. token: 'delimiter.handlebars',
  383. switchTo: '@$S2.$S3',
  384. nextEmbedded: '$S3'
  385. }
  386. ],
  387. { include: 'handlebarsRoot' }
  388. ],
  389. handlebarsRoot: [
  390. [/"[^"]*"/, 'string.handlebars'],
  391. [/[#/][^\s}]+/, 'keyword.helper.handlebars'],
  392. [/else\b/, 'keyword.helper.handlebars'],
  393. [/[\s]+/],
  394. [/[^}]/, 'variable.parameter.handlebars']
  395. ]
  396. }
  397. };
  398. });