generator-white-label 3.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/README.md +140 -81
  2. package/app/404.hbs +20 -0
  3. package/app/README.md +19 -0
  4. package/app/assets/data/view/toolkit/colors.json +17 -0
  5. package/app/assets/data/view/toolkit/components.json +39 -0
  6. package/app/assets/data/view/toolkit/elements.json +119 -0
  7. package/app/assets/data/view/toolkit/grids.json +17 -0
  8. package/app/assets/data/view/toolkit/icons.json +17 -0
  9. package/app/assets/data/view/toolkit/index.json +17 -0
  10. package/app/assets/data/view/toolkit/type.json +17 -0
  11. package/app/assets/font/opensans/stylesheet.css +20 -60
  12. package/app/assets/image/demo/fallback.avif +0 -0
  13. package/app/assets/image/demo/fallback.jpg +0 -0
  14. package/app/assets/image/demo/fallback.webp +0 -0
  15. package/app/assets/image/demo/large.avif +0 -0
  16. package/app/assets/image/demo/large.webp +0 -0
  17. package/app/assets/image/demo/small.avif +0 -0
  18. package/app/assets/image/demo/small.webp +0 -0
  19. package/app/assets/markup/element/a.hbs +29 -0
  20. package/app/assets/markup/element/button.hbs +30 -0
  21. package/app/assets/markup/element/div.hbs +11 -0
  22. package/app/assets/markup/element/head.hbs +78 -0
  23. package/app/assets/markup/element/iframe.hbs +20 -0
  24. package/app/assets/markup/element/img.hbs +30 -0
  25. package/app/assets/markup/element/input.hbs +43 -0
  26. package/app/assets/markup/element/label.hbs +14 -0
  27. package/app/assets/markup/element/legend.hbs +5 -0
  28. package/app/assets/markup/element/meta.hbs +11 -0
  29. package/app/assets/markup/element/nav.hbs +13 -0
  30. package/app/assets/markup/element/p.hbs +8 -0
  31. package/app/assets/markup/element/picture.hbs +58 -0
  32. package/app/assets/markup/element/script.hbs +3 -0
  33. package/app/assets/markup/element/select.hbs +35 -0
  34. package/app/assets/markup/element/span.hbs +8 -0
  35. package/app/assets/markup/element/svg.hbs +11 -0
  36. package/app/assets/markup/element/table.hbs +50 -0
  37. package/app/assets/markup/element/textarea.hbs +24 -0
  38. package/app/assets/markup/element/ul.hbs +13 -0
  39. package/app/assets/markup/modal/modal-example-1.handlebars +8 -0
  40. package/app/assets/markup/toolkit/accessibility-skip-to-element-1.handlebars +1 -0
  41. package/app/assets/markup/toolkit/accessibility-speaker-1.handlebars +1 -0
  42. package/app/assets/markup/toolkit/anchor-1.handlebars +1 -0
  43. package/app/assets/markup/toolkit/button-1.handlebars +1 -0
  44. package/app/assets/markup/toolkit/footer-1.handlebars +3 -0
  45. package/app/assets/markup/toolkit/header-1.handlebars +1 -0
  46. package/app/assets/markup/toolkit/heading-1.handlebars +1 -0
  47. package/app/assets/markup/toolkit/heading-2.handlebars +1 -0
  48. package/app/assets/markup/toolkit/heading-3.handlebars +1 -0
  49. package/app/assets/markup/toolkit/heading-4.handlebars +1 -0
  50. package/app/assets/markup/toolkit/image-1.handlebars +1 -0
  51. package/app/assets/markup/toolkit/input-checkbox-1.handlebars +1 -0
  52. package/app/assets/markup/toolkit/input-error-1.handlebars +8 -0
  53. package/app/assets/markup/toolkit/input-radio-1.handlebars +1 -0
  54. package/app/assets/markup/toolkit/input-text-1.handlebars +1 -0
  55. package/app/assets/markup/toolkit/label-1.handlebars +1 -0
  56. package/app/assets/markup/toolkit/legend-1.handlebars +1 -0
  57. package/app/assets/markup/toolkit/list-1.handlebars +1 -0
  58. package/app/assets/markup/toolkit/modal-1.handlebars +4 -0
  59. package/app/assets/markup/toolkit/nav-1.handlebars +1 -0
  60. package/app/assets/markup/toolkit/picture-1.handlebars +1 -0
  61. package/app/assets/markup/toolkit/select-1.handlebars +1 -0
  62. package/app/assets/markup/toolkit/table-1.handlebars +1 -0
  63. package/app/assets/markup/toolkit/text-1.handlebars +1 -0
  64. package/app/assets/markup/toolkit/textarea-1.handlebars +1 -0
  65. package/app/assets/markup/toolkit/youtube-player-1.handlebars +1 -0
  66. package/app/assets/script/api/facebook.ts +41 -0
  67. package/app/assets/script/api/youtube.ts +22 -0
  68. package/app/assets/script/index.ts +2 -0
  69. package/app/assets/script/mediator/global.ts +4 -0
  70. package/app/assets/script/model/singletons/countries.ts +5 -0
  71. package/app/assets/script/model/singletons/global.ts +5 -0
  72. package/app/assets/script/model/singletons/states.ts +5 -0
  73. package/app/assets/script/model/user.ts +4 -0
  74. package/app/assets/script/toolkit.ts +11 -0
  75. package/app/assets/script/types.d.ts +16 -0
  76. package/app/assets/script/utility/ajax.ts +15 -0
  77. package/app/assets/script/utility/form.ts +119 -0
  78. package/app/assets/script/utility/{regex.js → regex.ts} +15 -6
  79. package/app/assets/script/utility/share.ts +77 -0
  80. package/app/assets/script/utility/string.ts +148 -0
  81. package/app/assets/script/view/default.tsx +14 -0
  82. package/app/assets/script/view/toolkit/youtube-player-1.ts +31 -0
  83. package/app/assets/style/base/_toolkit.scss +31 -15
  84. package/app/assets/style/base/components/_modal-1.scss +80 -0
  85. package/app/assets/style/base/components/_sticky-1.scss +19 -0
  86. package/app/assets/style/base/components/_tabpanel-1.scss +115 -0
  87. package/app/assets/style/base/components/_tabpanel-2.scss +64 -0
  88. package/app/assets/style/base/components/_tabpanel-base-1.scss +13 -0
  89. package/app/assets/style/base/components/_youtube-player-1.scss +16 -0
  90. package/app/assets/style/base/elements/_anchors.scss +12 -0
  91. package/app/assets/style/base/elements/_buttons.scss +15 -0
  92. package/app/assets/style/base/elements/_fieldsets.scss +9 -0
  93. package/app/assets/style/base/elements/_images.scss +6 -2
  94. package/app/assets/style/base/elements/_inputs.scss +70 -0
  95. package/app/assets/style/base/elements/_labels.scss +8 -0
  96. package/app/assets/style/base/elements/_landmarks.scss +3 -0
  97. package/app/assets/style/base/elements/_legends.scss +11 -0
  98. package/app/assets/style/base/elements/_lists.scss +8 -1
  99. package/app/assets/style/base/elements/_tables.scss +32 -1
  100. package/app/assets/style/base/layouts/_staggered-1.scss +29 -0
  101. package/app/assets/style/base/type/_fonts.scss +39 -1
  102. package/app/assets/style/base/type/_headings.scss +29 -0
  103. package/app/assets/style/base/type/_text.scss +2 -0
  104. package/app/assets/style/base/utilities/_accessibility.scss +5 -2
  105. package/app/assets/style/base/utilities/_functions.scss +62 -9
  106. package/app/assets/style/global.scss +108 -10
  107. package/app/assets/style/print.scss +2 -3
  108. package/app/assets/style/toolkit.scss +387 -0
  109. package/app/index.hbs +21 -0
  110. package/app/package.json +1 -0
  111. package/app/toolkit/colors.hbs +102 -0
  112. package/app/toolkit/components.hbs +261 -0
  113. package/app/toolkit/elements.hbs +497 -0
  114. package/app/toolkit/grids.hbs +413 -0
  115. package/app/toolkit/icons.hbs +87 -0
  116. package/app/toolkit/index.hbs +144 -0
  117. package/app/toolkit/type.hbs +120 -0
  118. package/dist/app/assets/data/coutries.json +992 -0
  119. package/dist/app/assets/data/states.json +204 -0
  120. package/dist/app/assets/script/api/facebook.d.ts +8 -0
  121. package/dist/app/assets/script/api/facebook.js +42 -0
  122. package/dist/app/assets/script/api/facebook.js.map +1 -0
  123. package/dist/app/assets/script/api/youtube.d.ts +8 -0
  124. package/dist/app/assets/script/api/youtube.js +22 -0
  125. package/dist/app/assets/script/api/youtube.js.map +1 -0
  126. package/dist/app/assets/script/index.d.ts +2 -0
  127. package/dist/app/assets/script/index.js +2 -0
  128. package/dist/app/assets/script/index.js.map +1 -0
  129. package/dist/app/assets/script/mediator/global.d.ts +4 -0
  130. package/dist/app/assets/script/mediator/global.js +4 -0
  131. package/dist/app/assets/script/mediator/global.js.map +1 -0
  132. package/dist/app/assets/script/model/singletons/countries.d.ts +20 -0
  133. package/dist/app/assets/script/model/singletons/countries.js +5 -0
  134. package/dist/app/assets/script/model/singletons/countries.js.map +1 -0
  135. package/dist/app/assets/script/model/singletons/global.d.ts +20 -0
  136. package/dist/app/assets/script/model/singletons/global.js +5 -0
  137. package/dist/app/assets/script/model/singletons/global.js.map +1 -0
  138. package/dist/app/assets/script/model/singletons/states.d.ts +20 -0
  139. package/dist/app/assets/script/model/singletons/states.js +5 -0
  140. package/dist/app/assets/script/model/singletons/states.js.map +1 -0
  141. package/dist/app/assets/script/model/user.d.ts +4 -0
  142. package/dist/app/assets/script/model/user.js +6 -0
  143. package/dist/app/assets/script/model/user.js.map +1 -0
  144. package/dist/app/assets/script/toolkit.d.ts +1 -0
  145. package/dist/app/assets/script/toolkit.js +7 -0
  146. package/dist/app/assets/script/toolkit.js.map +1 -0
  147. package/dist/app/assets/script/utility/ajax.d.ts +8 -0
  148. package/dist/app/assets/script/utility/ajax.js +17 -0
  149. package/dist/app/assets/script/utility/ajax.js.map +1 -0
  150. package/dist/app/assets/script/utility/form.d.ts +64 -0
  151. package/dist/app/assets/script/utility/form.js +111 -0
  152. package/dist/app/assets/script/utility/form.js.map +1 -0
  153. package/dist/app/assets/script/utility/regex.d.ts +14 -0
  154. package/dist/app/assets/script/utility/regex.js +27 -0
  155. package/dist/app/assets/script/utility/regex.js.map +1 -0
  156. package/dist/app/assets/script/utility/share.d.ts +68 -0
  157. package/dist/app/assets/script/utility/share.js +81 -0
  158. package/dist/app/assets/script/utility/share.js.map +1 -0
  159. package/dist/app/assets/script/utility/string.d.ts +64 -0
  160. package/dist/app/assets/script/utility/string.js +135 -0
  161. package/dist/app/assets/script/utility/string.js.map +1 -0
  162. package/dist/app/assets/script/view/default.d.ts +11 -0
  163. package/dist/app/assets/script/view/default.js +15 -0
  164. package/dist/app/assets/script/view/default.js.map +1 -0
  165. package/dist/app/assets/script/view/toolkit/youtube-player-1.d.ts +23 -0
  166. package/dist/app/assets/script/view/toolkit/youtube-player-1.js +32 -0
  167. package/dist/app/assets/script/view/toolkit/youtube-player-1.js.map +1 -0
  168. package/dist/generators/app/index.d.ts +18 -0
  169. package/dist/generators/app/index.js +59 -0
  170. package/dist/generators/app/index.js.map +1 -0
  171. package/dist/scripts/build.d.ts +22 -0
  172. package/dist/scripts/build.js +158 -0
  173. package/dist/scripts/build.js.map +1 -0
  174. package/generators/app/index.js +2 -43
  175. package/generators/app/index.ts +61 -0
  176. package/package.json +78 -109
  177. package/scripts/build.ts +175 -0
  178. package/tsconfig.site.json +26 -0
  179. package/.babelrc +0 -7
  180. package/.editorconfig +0 -13
  181. package/.eslintrc +0 -64
  182. package/.htmllintrc +0 -6
  183. package/.npmignore +0 -12
  184. package/.sass-lint.yml +0 -16
  185. package/.travis.yml +0 -18
  186. package/app/assets/font/opensans/generator_config.txt +0 -5
  187. package/app/assets/font/opensans/opensans-bold-webfont.eot +0 -0
  188. package/app/assets/font/opensans/opensans-bold-webfont.svg +0 -1824
  189. package/app/assets/font/opensans/opensans-bold-webfont.ttf +0 -0
  190. package/app/assets/font/opensans/opensans-bold-webfont.woff +0 -0
  191. package/app/assets/font/opensans/opensans-bolditalic-webfont.eot +0 -0
  192. package/app/assets/font/opensans/opensans-bolditalic-webfont.svg +0 -1824
  193. package/app/assets/font/opensans/opensans-bolditalic-webfont.ttf +0 -0
  194. package/app/assets/font/opensans/opensans-bolditalic-webfont.woff +0 -0
  195. package/app/assets/font/opensans/opensans-extrabold-webfont.eot +0 -0
  196. package/app/assets/font/opensans/opensans-extrabold-webfont.svg +0 -1824
  197. package/app/assets/font/opensans/opensans-extrabold-webfont.ttf +0 -0
  198. package/app/assets/font/opensans/opensans-extrabold-webfont.woff +0 -0
  199. package/app/assets/font/opensans/opensans-extrabolditalic-webfont.eot +0 -0
  200. package/app/assets/font/opensans/opensans-extrabolditalic-webfont.svg +0 -1824
  201. package/app/assets/font/opensans/opensans-extrabolditalic-webfont.ttf +0 -0
  202. package/app/assets/font/opensans/opensans-extrabolditalic-webfont.woff +0 -0
  203. package/app/assets/font/opensans/opensans-italic-webfont.eot +0 -0
  204. package/app/assets/font/opensans/opensans-italic-webfont.svg +0 -1824
  205. package/app/assets/font/opensans/opensans-italic-webfont.ttf +0 -0
  206. package/app/assets/font/opensans/opensans-italic-webfont.woff +0 -0
  207. package/app/assets/font/opensans/opensans-light-webfont.eot +0 -0
  208. package/app/assets/font/opensans/opensans-light-webfont.svg +0 -1824
  209. package/app/assets/font/opensans/opensans-light-webfont.ttf +0 -0
  210. package/app/assets/font/opensans/opensans-light-webfont.woff +0 -0
  211. package/app/assets/font/opensans/opensans-lightitalic-webfont.eot +0 -0
  212. package/app/assets/font/opensans/opensans-lightitalic-webfont.svg +0 -1824
  213. package/app/assets/font/opensans/opensans-lightitalic-webfont.ttf +0 -0
  214. package/app/assets/font/opensans/opensans-lightitalic-webfont.woff +0 -0
  215. package/app/assets/font/opensans/opensans-regular-webfont.eot +0 -0
  216. package/app/assets/font/opensans/opensans-regular-webfont.svg +0 -1824
  217. package/app/assets/font/opensans/opensans-regular-webfont.ttf +0 -0
  218. package/app/assets/font/opensans/opensans-regular-webfont.woff +0 -0
  219. package/app/assets/font/opensans/opensans-semibold-webfont.eot +0 -0
  220. package/app/assets/font/opensans/opensans-semibold-webfont.svg +0 -1824
  221. package/app/assets/font/opensans/opensans-semibold-webfont.ttf +0 -0
  222. package/app/assets/font/opensans/opensans-semibold-webfont.woff +0 -0
  223. package/app/assets/font/opensans/opensans-semibolditalic-webfont.eot +0 -0
  224. package/app/assets/font/opensans/opensans-semibolditalic-webfont.svg +0 -1824
  225. package/app/assets/font/opensans/opensans-semibolditalic-webfont.ttf +0 -0
  226. package/app/assets/font/opensans/opensans-semibolditalic-webfont.woff +0 -0
  227. package/app/assets/font/opensans/specimen_files/grid_12-825-55-15.css +0 -129
  228. package/app/assets/font/opensans/specimen_files/specimen_stylesheet.css +0 -396
  229. package/app/assets/script/index.js +0 -11
  230. package/app/assets/script/mediator/global.js +0 -5
  231. package/app/assets/script/model/singletons/countries.js +0 -6
  232. package/app/assets/script/model/singletons/global.js +0 -6
  233. package/app/assets/script/model/singletons/states.js +0 -6
  234. package/app/assets/script/model/user.js +0 -5
  235. package/app/assets/script/utility/form.js +0 -86
  236. package/app/assets/script/utility/share.js +0 -52
  237. package/app/assets/script/utility/string.js +0 -70
  238. package/app/assets/script/view/default.js +0 -11
  239. package/app/assets/style/base/vendor/_foundation.scss +0 -2
  240. package/app/assets/test/spec/shareSpec.js +0 -137
  241. package/app/index.html +0 -43
  242. package/app/report/istanbul/base.css +0 -213
  243. package/app/report/istanbul/index.html +0 -93
  244. package/app/report/istanbul/prettify.css +0 -1
  245. package/app/report/istanbul/prettify.js +0 -1
  246. package/app/report/istanbul/sort-arrow-sprite.png +0 -0
  247. package/app/report/istanbul/sorter.js +0 -158
  248. package/app/report/istanbul/utility/form.js.html +0 -524
  249. package/app/report/istanbul/utility/index.html +0 -132
  250. package/app/report/istanbul/utility/regex.js.html +0 -203
  251. package/app/report/istanbul/utility/share.js.html +0 -401
  252. package/app/report/istanbul/utility/string.js.html +0 -446
  253. package/app/report/jsdoc/DragEvent.html +0 -303
  254. package/app/report/jsdoc/Event.html +0 -773
  255. package/app/report/jsdoc/EventPropagators.html +0 -336
  256. package/app/report/jsdoc/FocusEvent.html +0 -303
  257. package/app/report/jsdoc/ForEachBookKeeping.html +0 -425
  258. package/app/report/jsdoc/KeyboardEvent.html +0 -303
  259. package/app/report/jsdoc/MapBookKeeping.html +0 -457
  260. package/app/report/jsdoc/MouseEvent.html +0 -303
  261. package/app/report/jsdoc/ReactClass.html +0 -330
  262. package/app/report/jsdoc/ReactClassInterface.html +0 -311
  263. package/app/report/jsdoc/ReactDOMComponent.html +0 -349
  264. package/app/report/jsdoc/ReactDOMTextComponent.html +0 -348
  265. package/app/report/jsdoc/ReactMountReady.html +0 -340
  266. package/app/report/jsdoc/ReactMultiChild.html +0 -330
  267. package/app/report/jsdoc/ReactOwner.html +0 -351
  268. package/app/report/jsdoc/ReactReconcileTransaction.html +0 -342
  269. package/app/report/jsdoc/ReactServerRenderingTransaction.html +0 -376
  270. package/app/report/jsdoc/ReactServerUpdateQueue.html +0 -382
  271. package/app/report/jsdoc/TouchEvent.html +0 -303
  272. package/app/report/jsdoc/Transaction.html +0 -459
  273. package/app/report/jsdoc/UIEvent.html +0 -303
  274. package/app/report/jsdoc/WheelEvent.html +0 -303
  275. package/app/report/jsdoc/classes.list.html +0 -339
  276. package/app/report/jsdoc/fonts/glyphicons-halflings-regular.eot +0 -0
  277. package/app/report/jsdoc/fonts/glyphicons-halflings-regular.svg +0 -288
  278. package/app/report/jsdoc/fonts/glyphicons-halflings-regular.ttf +0 -0
  279. package/app/report/jsdoc/fonts/glyphicons-halflings-regular.woff +0 -0
  280. package/app/report/jsdoc/fonts/glyphicons-halflings-regular.woff2 +0 -0
  281. package/app/report/jsdoc/global.html +0 -1653
  282. package/app/report/jsdoc/img/glyphicons-halflings-white.png +0 -0
  283. package/app/report/jsdoc/img/glyphicons-halflings.png +0 -0
  284. package/app/report/jsdoc/index.html +0 -236
  285. package/app/report/jsdoc/interfaces.list.html +0 -339
  286. package/app/report/jsdoc/quicksearch.html +0 -31
  287. package/app/report/jsdoc/scripts/docstrap.lib.js +0 -11
  288. package/app/report/jsdoc/scripts/fulltext-search-ui.js +0 -89
  289. package/app/report/jsdoc/scripts/fulltext-search.js +0 -36
  290. package/app/report/jsdoc/scripts/lunr.min.js +0 -6
  291. package/app/report/jsdoc/scripts/prettify/Apache-License-2.0.txt +0 -202
  292. package/app/report/jsdoc/scripts/prettify/jquery.min.js +0 -6
  293. package/app/report/jsdoc/scripts/prettify/lang-css.js +0 -21
  294. package/app/report/jsdoc/scripts/prettify/prettify.js +0 -496
  295. package/app/report/jsdoc/scripts/sunlight.js +0 -1157
  296. package/app/report/jsdoc/scripts/toc.js +0 -203
  297. package/app/report/jsdoc/styles/darkstrap.css +0 -960
  298. package/app/report/jsdoc/styles/prettify-tomorrow.css +0 -132
  299. package/app/report/jsdoc/styles/site.cerulean.css +0 -7008
  300. package/app/report/jsdoc/styles/site.cosmo.css +0 -7061
  301. package/app/report/jsdoc/styles/site.cyborg.css +0 -7048
  302. package/app/report/jsdoc/styles/site.darkly.css +0 -7171
  303. package/app/report/jsdoc/styles/site.darkstrap.css +0 -5638
  304. package/app/report/jsdoc/styles/site.dibs-bootstrap.css +0 -5899
  305. package/app/report/jsdoc/styles/site.flatly.css +0 -7147
  306. package/app/report/jsdoc/styles/site.journal.css +0 -6973
  307. package/app/report/jsdoc/styles/site.lumen.css +0 -7298
  308. package/app/report/jsdoc/styles/site.paper.css +0 -7623
  309. package/app/report/jsdoc/styles/site.readable.css +0 -6997
  310. package/app/report/jsdoc/styles/site.sandstone.css +0 -7035
  311. package/app/report/jsdoc/styles/site.simplex.css +0 -7023
  312. package/app/report/jsdoc/styles/site.slate.css +0 -7343
  313. package/app/report/jsdoc/styles/site.spacelab.css +0 -7055
  314. package/app/report/jsdoc/styles/site.superhero.css +0 -7131
  315. package/app/report/jsdoc/styles/site.united.css +0 -6895
  316. package/app/report/jsdoc/styles/site.yeti.css +0 -7195
  317. package/app/report/jsdoc/styles/sunlight.dark.css +0 -345
  318. package/app/report/jsdoc/styles/sunlight.default.css +0 -344
  319. package/gulp/config.js +0 -207
  320. package/gulp/tasks/accessibility.js +0 -34
  321. package/gulp/tasks/build.js +0 -18
  322. package/gulp/tasks/clean.js +0 -18
  323. package/gulp/tasks/data.js +0 -22
  324. package/gulp/tasks/default.js +0 -9
  325. package/gulp/tasks/deploy.js +0 -222
  326. package/gulp/tasks/documentation.js +0 -28
  327. package/gulp/tasks/markup.js +0 -26
  328. package/gulp/tasks/script.js +0 -92
  329. package/gulp/tasks/style.js +0 -42
  330. package/gulp/tasks/unit.js +0 -38
  331. package/gulp/tasks/watch.js +0 -77
  332. package/gulpfile.js +0 -8
  333. package/jsdoc.json +0 -23
  334. package/karma.conf.js +0 -58
@@ -1,1157 +0,0 @@
1
- /**
2
- * Sunlight
3
- * Intelligent syntax highlighting
4
- *
5
- * http://sunlightjs.com/
6
- *
7
- * by Tommy Montgomery <http://tmont.com>
8
- * Licensed under WTFPL <http://sam.zoy.org/wtfpl/>
9
- */
10
- (function(window, document, undefined){
11
-
12
- var
13
- //http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
14
- //we have to sniff this because IE requires \r
15
- isIe = !+"\v1",
16
- EOL = isIe ? "\r" : "\n",
17
- EMPTY = function() { return null; },
18
- HIGHLIGHTED_NODE_COUNT = 0,
19
- DEFAULT_LANGUAGE = "plaintext",
20
- DEFAULT_CLASS_PREFIX = "sunlight-",
21
-
22
- //global sunlight variables
23
- defaultAnalyzer,
24
- getComputedStyle,
25
- globalOptions = {
26
- tabWidth: 4,
27
- classPrefix: DEFAULT_CLASS_PREFIX,
28
- showWhitespace: false,
29
- maxHeight: false
30
- },
31
- languages = {},
32
- languageDefaults = {},
33
- events = {
34
- beforeHighlightNode: [],
35
- beforeHighlight: [],
36
- beforeTokenize: [],
37
- afterTokenize: [],
38
- beforeAnalyze: [],
39
- afterAnalyze: [],
40
- afterHighlight: [],
41
- afterHighlightNode: []
42
- };
43
-
44
- defaultAnalyzer = (function() {
45
- function defaultHandleToken(suffix) {
46
- return function(context) {
47
- var element = document.createElement("span");
48
- element.className = context.options.classPrefix + suffix;
49
- element.appendChild(context.createTextNode(context.tokens[context.index]));
50
- return context.addNode(element) || true;
51
- };
52
- }
53
-
54
- return {
55
- handleToken: function(context) {
56
- return defaultHandleToken(context.tokens[context.index].name)(context);
57
- },
58
-
59
- //just append default content as a text node
60
- handle_default: function(context) {
61
- return context.addNode(context.createTextNode(context.tokens[context.index]));
62
- },
63
-
64
- //this handles the named ident mayhem
65
- handle_ident: function(context) {
66
- var evaluate = function(rules, createRule) {
67
- var i;
68
- rules = rules || [];
69
- for (i = 0; i < rules.length; i++) {
70
- if (typeof(rules[i]) === "function") {
71
- if (rules[i](context)) {
72
- return defaultHandleToken("named-ident")(context);
73
- }
74
- } else if (createRule && createRule(rules[i])(context.tokens)) {
75
- return defaultHandleToken("named-ident")(context);
76
- }
77
- }
78
-
79
- return false;
80
- };
81
-
82
- return evaluate(context.language.namedIdentRules.custom)
83
- || evaluate(context.language.namedIdentRules.follows, function(ruleData) { return createProceduralRule(context.index - 1, -1, ruleData, context.language.caseInsensitive); })
84
- || evaluate(context.language.namedIdentRules.precedes, function(ruleData) { return createProceduralRule(context.index + 1, 1, ruleData, context.language.caseInsensitive); })
85
- || evaluate(context.language.namedIdentRules.between, function(ruleData) { return createBetweenRule(context.index, ruleData.opener, ruleData.closer, context.language.caseInsensitive); })
86
- || defaultHandleToken("ident")(context);
87
- }
88
- };
89
- }());
90
-
91
- languageDefaults = {
92
- analyzer: create(defaultAnalyzer),
93
- customTokens: [],
94
- namedIdentRules: {},
95
- punctuation: /[^\w\s]/,
96
- numberParser: defaultNumberParser,
97
- caseInsensitive: false,
98
- doNotParse: /\s/,
99
- contextItems: {},
100
- embeddedLanguages: {}
101
- };
102
-
103
- //adapted from http://blargh.tommymontgomery.com/2010/04/get-computed-style-in-javascript/
104
- getComputedStyle = (function() {
105
- var func = null;
106
- if (document.defaultView && document.defaultView.getComputedStyle) {
107
- func = document.defaultView.getComputedStyle;
108
- } else {
109
- func = function(element, anything) {
110
- return element["currentStyle"] || {};
111
- };
112
- }
113
-
114
- return function(element, style) {
115
- return func(element, null)[style];
116
- }
117
- }());
118
-
119
- //-----------
120
- //FUNCTIONS
121
- //-----------
122
-
123
- function createCodeReader(text) {
124
- var index = 0,
125
- line = 1,
126
- column = 1,
127
- length,
128
- EOF = undefined,
129
- currentChar,
130
- nextReadBeginsLine;
131
-
132
- text = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); //normalize line endings to unix
133
-
134
- length = text.length;
135
- currentChar = length > 0 ? text.charAt(0) : EOF;
136
-
137
- function getCharacters(count) {
138
- var value;
139
- if (count === 0) {
140
- return "";
141
- }
142
-
143
- count = count || 1;
144
-
145
- value = text.substring(index + 1, index + count + 1);
146
- return value === "" ? EOF : value;
147
- }
148
-
149
- return {
150
- toString: function() {
151
- return "length: " + length + ", index: " + index + ", line: " + line + ", column: " + column + ", current: [" + currentChar + "]";
152
- },
153
-
154
- peek: function(count) {
155
- return getCharacters(count);
156
- },
157
-
158
- substring: function() {
159
- return text.substring(index);
160
- },
161
-
162
- peekSubstring: function() {
163
- return text.substring(index + 1);
164
- },
165
-
166
- read: function(count) {
167
- var value = getCharacters(count),
168
- newlineCount,
169
- lastChar;
170
-
171
- if (value === "") {
172
- //this is a result of reading/peeking/doing nothing
173
- return value;
174
- }
175
-
176
- if (value !== EOF) {
177
- //advance index
178
- index += value.length;
179
- column += value.length;
180
-
181
- //update line count
182
- if (nextReadBeginsLine) {
183
- line++;
184
- column = 1;
185
- nextReadBeginsLine = false;
186
- }
187
-
188
- newlineCount = value.substring(0, value.length - 1).replace(/[^\n]/g, "").length;
189
- if (newlineCount > 0) {
190
- line += newlineCount;
191
- column = 1;
192
- }
193
-
194
- lastChar = last(value);
195
- if (lastChar === "\n") {
196
- nextReadBeginsLine = true;
197
- }
198
-
199
- currentChar = lastChar;
200
- } else {
201
- index = length;
202
- currentChar = EOF;
203
- }
204
-
205
- return value;
206
- },
207
-
208
- text: function() { return text; },
209
-
210
- getLine: function() { return line; },
211
- getColumn: function() { return column; },
212
- isEof: function() { return index >= length; },
213
- isSol: function() { return column === 1; },
214
- isSolWs: function() {
215
- var temp = index,
216
- c;
217
- if (column === 1) {
218
- return true;
219
- }
220
-
221
- //look backward until we find a newline or a non-whitespace character
222
- while ((c = text.charAt(--temp)) !== "") {
223
- if (c === "\n") {
224
- return true;
225
- }
226
- if (!/\s/.test(c)) {
227
- return false;
228
- }
229
- }
230
-
231
- return true;
232
- },
233
- isEol: function() { return nextReadBeginsLine; },
234
- EOF: EOF,
235
- current: function() { return currentChar; }
236
- };
237
- }
238
-
239
- //http://javascript.crockford.com/prototypal.html
240
- function create(o) {
241
- function F() {}
242
- F.prototype = o;
243
- return new F();
244
- }
245
-
246
- function appendAll(parent, children) {
247
- var i;
248
- for (i = 0; i < children.length; i++) {
249
- parent.appendChild(children[i]);
250
- }
251
- }
252
-
253
- //gets the last character in a string or the last element in an array
254
- function last(thing) {
255
- return thing.charAt ? thing.charAt(thing.length - 1) : thing[thing.length - 1];
256
- }
257
-
258
- //array.contains()
259
- function contains(arr, value, caseInsensitive) {
260
- var i;
261
- if (arr.indexOf && !caseInsensitive) {
262
- return arr.indexOf(value) >= 0;
263
- }
264
-
265
- for (i = 0; i < arr.length; i++) {
266
- if (arr[i] === value) {
267
- return true;
268
- }
269
-
270
- if (caseInsensitive && typeof(arr[i]) === "string" && typeof(value) === "string" && arr[i].toUpperCase() === value.toUpperCase()) {
271
- return true;
272
- }
273
- }
274
-
275
- return false;
276
- }
277
-
278
- //non-recursively merges one object into the other
279
- function merge(defaultObject, objectToMerge) {
280
- var key;
281
- if (!objectToMerge) {
282
- return defaultObject;
283
- }
284
-
285
- for (key in objectToMerge) {
286
- defaultObject[key] = objectToMerge[key];
287
- }
288
-
289
- return defaultObject;
290
- }
291
-
292
- function clone(object) {
293
- return merge({}, object);
294
- }
295
-
296
- //http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript/3561711#3561711
297
- function regexEscape(s) {
298
- return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
299
- }
300
-
301
- function createProceduralRule(startIndex, direction, tokenRequirements, caseInsensitive) {
302
- tokenRequirements = tokenRequirements.slice(0);
303
- return function(tokens) {
304
- var tokenIndexStart = startIndex,
305
- j,
306
- expected,
307
- actual;
308
-
309
- if (direction === 1) {
310
- tokenRequirements.reverse();
311
- }
312
-
313
- for (j = 0; j < tokenRequirements.length; j++) {
314
- actual = tokens[tokenIndexStart + (j * direction)];
315
- expected = tokenRequirements[tokenRequirements.length - 1 - j];
316
-
317
- if (actual === undefined) {
318
- if (expected["optional"] !== undefined && expected.optional) {
319
- tokenIndexStart -= direction;
320
- } else {
321
- return false;
322
- }
323
- } else if (actual.name === expected.token && (expected["values"] === undefined || contains(expected.values, actual.value, caseInsensitive))) {
324
- //derp
325
- continue;
326
- } else if (expected["optional"] !== undefined && expected.optional) {
327
- tokenIndexStart -= direction; //we need to reevaluate against this token again
328
- } else {
329
- return false;
330
- }
331
- }
332
-
333
- return true;
334
- };
335
- }
336
-
337
- function createBetweenRule(startIndex, opener, closer, caseInsensitive) {
338
- return function(tokens) {
339
- var index = startIndex,
340
- token,
341
- success = false;
342
-
343
- //check to the left: if we run into a closer or never run into an opener, fail
344
- while ((token = tokens[--index]) !== undefined) {
345
- if (token.name === closer.token && contains(closer.values, token.value)) {
346
- if (token.name === opener.token && contains(opener.values, token.value, caseInsensitive)) {
347
- //if the closer is the same as the opener that's okay
348
- success = true;
349
- break;
350
- }
351
-
352
- return false;
353
- }
354
-
355
- if (token.name === opener.token && contains(opener.values, token.value, caseInsensitive)) {
356
- success = true;
357
- break;
358
- }
359
- }
360
-
361
- if (!success) {
362
- return false;
363
- }
364
-
365
- //check to the right for the closer
366
- index = startIndex;
367
- while ((token = tokens[++index]) !== undefined) {
368
- if (token.name === opener.token && contains(opener.values, token.value, caseInsensitive)) {
369
- if (token.name === closer.token && contains(closer.values, token.value, caseInsensitive)) {
370
- //if the closer is the same as the opener that's okay
371
- success = true;
372
- break;
373
- }
374
-
375
- return false;
376
- }
377
-
378
- if (token.name === closer.token && contains(closer.values, token.value, caseInsensitive)) {
379
- success = true;
380
- break;
381
- }
382
- }
383
-
384
- return success;
385
- };
386
- }
387
-
388
- function matchWord(context, wordMap, tokenName, doNotRead) {
389
- var current = context.reader.current(),
390
- i,
391
- word,
392
- peek,
393
- line = context.reader.getLine(),
394
- column = context.reader.getColumn();
395
-
396
- wordMap = wordMap || [];
397
- if (context.language.caseInsensitive) {
398
- current = current.toUpperCase();
399
- }
400
-
401
- if (!wordMap[current]) {
402
- return null;
403
- }
404
-
405
- wordMap = wordMap[current];
406
- for (i = 0; i < wordMap.length; i++) {
407
- word = wordMap[i].value;
408
-
409
- peek = current + context.reader.peek(word.length);
410
- if (word === peek || wordMap[i].regex.test(peek)) {
411
- return context.createToken(
412
- tokenName,
413
- context.reader.current() + context.reader[doNotRead ? "peek" : "read"](word.length - 1),
414
- line,
415
- column
416
- );
417
- }
418
- }
419
-
420
- return null;
421
- }
422
-
423
- //gets the next token in the specified direction while matcher matches the current token
424
- function getNextWhile(tokens, index, direction, matcher) {
425
- var count = 1,
426
- token;
427
-
428
- direction = direction || 1;
429
- while (token = tokens[index + (direction * count++)]) {
430
- if (!matcher(token)) {
431
- return token;
432
- }
433
- }
434
-
435
- return undefined;
436
- }
437
-
438
- //this is crucial for performance
439
- function createHashMap(wordMap, boundary, caseInsensitive) {
440
- //creates a hash table where the hash is the first character of the word
441
- var newMap = { },
442
- i,
443
- word,
444
- firstChar;
445
-
446
- for (i = 0; i < wordMap.length; i++) {
447
- word = caseInsensitive ? wordMap[i].toUpperCase() : wordMap[i];
448
- firstChar = word.charAt(0);
449
- if (!newMap[firstChar]) {
450
- newMap[firstChar] = [];
451
- }
452
-
453
- newMap[firstChar].push({ value: word, regex: new RegExp("^" + regexEscape(word) + boundary, caseInsensitive ? "i" : "") });
454
- }
455
-
456
- return newMap;
457
- }
458
-
459
- function defaultNumberParser(context) {
460
- var current = context.reader.current(),
461
- number,
462
- line = context.reader.getLine(),
463
- column = context.reader.getColumn(),
464
- allowDecimal = true,
465
- peek;
466
-
467
- if (!/\d/.test(current)) {
468
- //is it a decimal followed by a number?
469
- if (current !== "." || !/\d/.test(context.reader.peek())) {
470
- return null;
471
- }
472
-
473
- //decimal without leading zero
474
- number = current + context.reader.read();
475
- allowDecimal = false;
476
- } else {
477
- number = current;
478
- if (current === "0" && context.reader.peek() !== ".") {
479
- //hex or octal
480
- allowDecimal = false;
481
- }
482
- }
483
-
484
- //easy way out: read until it's not a number or letter
485
- //this will work for hex (0xef), octal (012), decimal and scientific notation (1e3)
486
- //anything else and you're on your own
487
-
488
- while ((peek = context.reader.peek()) !== context.reader.EOF) {
489
- if (!/[A-Za-z0-9]/.test(peek)) {
490
- if (peek === "." && allowDecimal && /\d$/.test(context.reader.peek(2))) {
491
- number += context.reader.read();
492
- allowDecimal = false;
493
- continue;
494
- }
495
-
496
- break;
497
- }
498
-
499
- number += context.reader.read();
500
- }
501
-
502
- return context.createToken("number", number, line, column);
503
- }
504
-
505
- function fireEvent(eventName, highlighter, eventContext) {
506
- var delegates = events[eventName] || [],
507
- i;
508
-
509
- for (i = 0; i < delegates.length; i++) {
510
- delegates[i].call(highlighter, eventContext);
511
- }
512
- }
513
-
514
- function Highlighter(options) {
515
- this.options = merge(clone(globalOptions), options);
516
- }
517
-
518
- Highlighter.prototype = (function() {
519
- var parseNextToken = (function() {
520
- function isIdentMatch(context) {
521
- return context.language.identFirstLetter && context.language.identFirstLetter.test(context.reader.current());
522
- }
523
-
524
- //token parsing functions
525
- function parseKeyword(context) {
526
- return matchWord(context, context.language.keywords, "keyword");
527
- }
528
-
529
- function parseCustomTokens(context) {
530
- var tokenName,
531
- token;
532
- if (context.language.customTokens === undefined) {
533
- return null;
534
- }
535
-
536
- for (tokenName in context.language.customTokens) {
537
- token = matchWord(context, context.language.customTokens[tokenName], tokenName);
538
- if (token !== null) {
539
- return token;
540
- }
541
- }
542
-
543
- return null;
544
- }
545
-
546
- function parseOperator(context) {
547
- return matchWord(context, context.language.operators, "operator");
548
- }
549
-
550
- function parsePunctuation(context) {
551
- var current = context.reader.current();
552
- if (context.language.punctuation.test(regexEscape(current))) {
553
- return context.createToken("punctuation", current, context.reader.getLine(), context.reader.getColumn());
554
- }
555
-
556
- return null;
557
- }
558
-
559
- function parseIdent(context) {
560
- var ident,
561
- peek,
562
- line = context.reader.getLine(),
563
- column = context.reader.getColumn();
564
-
565
- if (!isIdentMatch(context)) {
566
- return null;
567
- }
568
-
569
- ident = context.reader.current();
570
- while ((peek = context.reader.peek()) !== context.reader.EOF) {
571
- if (!context.language.identAfterFirstLetter.test(peek)) {
572
- break;
573
- }
574
-
575
- ident += context.reader.read();
576
- }
577
-
578
- return context.createToken("ident", ident, line, column);
579
- }
580
-
581
- function parseDefault(context) {
582
- if (context.defaultData.text === "") {
583
- //new default token
584
- context.defaultData.line = context.reader.getLine();
585
- context.defaultData.column = context.reader.getColumn();
586
- }
587
-
588
- context.defaultData.text += context.reader.current();
589
- return null;
590
- }
591
-
592
- function parseScopes(context) {
593
- var current = context.reader.current(),
594
- tokenName,
595
- specificScopes,
596
- j,
597
- opener,
598
- line,
599
- column,
600
- continuation,
601
- value;
602
-
603
- for (tokenName in context.language.scopes) {
604
- specificScopes = context.language.scopes[tokenName];
605
- for (j = 0; j < specificScopes.length; j++) {
606
- opener = specificScopes[j][0];
607
-
608
- value = current + context.reader.peek(opener.length - 1);
609
-
610
- if (opener !== value && (!context.language.caseInsensitive || value.toUpperCase() !== opener.toUpperCase())) {
611
- continue;
612
- }
613
-
614
- line = context.reader.getLine(), column = context.reader.getColumn();
615
- context.reader.read(opener.length - 1);
616
- continuation = getScopeReaderFunction(specificScopes[j], tokenName);
617
- return continuation(context, continuation, value, line, column);
618
- }
619
- }
620
-
621
- return null;
622
- }
623
-
624
- function parseNumber(context) {
625
- return context.language.numberParser(context);
626
- }
627
-
628
- function parseCustomRules(context) {
629
- var customRules = context.language.customParseRules,
630
- i,
631
- token;
632
-
633
- if (customRules === undefined) {
634
- return null;
635
- }
636
-
637
- for (i = 0; i < customRules.length; i++) {
638
- token = customRules[i](context);
639
- if (token) {
640
- return token;
641
- }
642
- }
643
-
644
- return null;
645
- }
646
-
647
- return function(context) {
648
- if (context.language.doNotParse.test(context.reader.current())) {
649
- return parseDefault(context);
650
- }
651
-
652
- return parseCustomRules(context)
653
- || parseCustomTokens(context)
654
- || parseKeyword(context)
655
- || parseScopes(context)
656
- || parseIdent(context)
657
- || parseNumber(context)
658
- || parseOperator(context)
659
- || parsePunctuation(context)
660
- || parseDefault(context);
661
- }
662
- }());
663
-
664
- function getScopeReaderFunction(scope, tokenName) {
665
- var escapeSequences = scope[2] || [],
666
- closerLength = scope[1].length,
667
- closer = typeof(scope[1]) === "string" ? new RegExp(regexEscape(scope[1])) : scope[1].regex,
668
- zeroWidth = scope[3] || false;
669
-
670
- //processCurrent indicates that this is being called from a continuation
671
- //which means that we need to process the current char, rather than peeking at the next
672
- return function(context, continuation, buffer, line, column, processCurrent) {
673
- var foundCloser = false;
674
- buffer = buffer || "";
675
-
676
- processCurrent = processCurrent ? 1 : 0;
677
-
678
- function process(processCurrent) {
679
- //check for escape sequences
680
- var peekValue,
681
- current = context.reader.current(),
682
- i;
683
-
684
- for (i = 0; i < escapeSequences.length; i++) {
685
- peekValue = (processCurrent ? current : "") + context.reader.peek(escapeSequences[i].length - processCurrent);
686
- if (peekValue === escapeSequences[i]) {
687
- buffer += context.reader.read(peekValue.length - processCurrent);
688
- return true;
689
- }
690
- }
691
-
692
- peekValue = (processCurrent ? current : "") + context.reader.peek(closerLength - processCurrent);
693
- if (closer.test(peekValue)) {
694
- foundCloser = true;
695
- return false;
696
- }
697
-
698
- buffer += processCurrent ? current : context.reader.read();
699
- return true;
700
- };
701
-
702
- if (!processCurrent || process(true)) {
703
- while (context.reader.peek() !== context.reader.EOF && process(false)) { }
704
- }
705
-
706
- if (processCurrent) {
707
- buffer += context.reader.current();
708
- context.reader.read();
709
- } else {
710
- buffer += zeroWidth || context.reader.peek() === context.reader.EOF ? "" : context.reader.read(closerLength);
711
- }
712
-
713
- if (!foundCloser) {
714
- //we need to signal to the context that this scope was never properly closed
715
- //this has significance for partial parses (e.g. for nested languages)
716
- context.continuation = continuation;
717
- }
718
-
719
- return context.createToken(tokenName, buffer, line, column);
720
- };
721
- }
722
-
723
- //called before processing the current
724
- function switchToEmbeddedLanguageIfNecessary(context) {
725
- var i,
726
- embeddedLanguage;
727
-
728
- for (i = 0; i < context.language.embeddedLanguages.length; i++) {
729
- if (!languages[context.language.embeddedLanguages[i].language]) {
730
- //unregistered language
731
- continue;
732
- }
733
-
734
- embeddedLanguage = clone(context.language.embeddedLanguages[i]);
735
-
736
- if (embeddedLanguage.switchTo(context)) {
737
- embeddedLanguage.oldItems = clone(context.items);
738
- context.embeddedLanguageStack.push(embeddedLanguage);
739
- context.language = languages[embeddedLanguage.language];
740
- context.items = merge(context.items, clone(context.language.contextItems));
741
- break;
742
- }
743
- }
744
- }
745
-
746
- //called after processing the current
747
- function switchBackFromEmbeddedLanguageIfNecessary(context) {
748
- var current = last(context.embeddedLanguageStack),
749
- lang;
750
-
751
- if (current && current.switchBack(context)) {
752
- context.language = languages[current.parentLanguage];
753
- lang = context.embeddedLanguageStack.pop();
754
-
755
- //restore old items
756
- context.items = clone(lang.oldItems);
757
- lang.oldItems = {};
758
- }
759
- }
760
-
761
- function tokenize(unhighlightedCode, language, partialContext, options) {
762
- var tokens = [],
763
- context,
764
- continuation,
765
- token;
766
-
767
- fireEvent("beforeTokenize", this, { code: unhighlightedCode, language: language });
768
- context = {
769
- reader: createCodeReader(unhighlightedCode),
770
- language: language,
771
- items: clone(language.contextItems),
772
- token: function(index) { return tokens[index]; },
773
- getAllTokens: function() { return tokens.slice(0); },
774
- count: function() { return tokens.length; },
775
- options: options,
776
- embeddedLanguageStack: [],
777
-
778
- defaultData: {
779
- text: "",
780
- line: 1,
781
- column: 1
782
- },
783
- createToken: function(name, value, line, column) {
784
- return {
785
- name: name,
786
- line: line,
787
- value: isIe ? value.replace(/\n/g, "\r") : value,
788
- column: column,
789
- language: this.language.name
790
- };
791
- }
792
- };
793
-
794
- //if continuation is given, then we need to pick up where we left off from a previous parse
795
- //basically it indicates that a scope was never closed, so we need to continue that scope
796
- if (partialContext.continuation) {
797
- continuation = partialContext.continuation;
798
- partialContext.continuation = null;
799
- tokens.push(continuation(context, continuation, "", context.reader.getLine(), context.reader.getColumn(), true));
800
- }
801
-
802
- while (!context.reader.isEof()) {
803
- switchToEmbeddedLanguageIfNecessary(context);
804
- token = parseNextToken(context);
805
-
806
- //flush default data if needed (in pretty much all languages this is just whitespace)
807
- if (token !== null) {
808
- if (context.defaultData.text !== "") {
809
- tokens.push(context.createToken("default", context.defaultData.text, context.defaultData.line, context.defaultData.column));
810
- context.defaultData.text = "";
811
- }
812
-
813
- if (token[0] !== undefined) {
814
- //multiple tokens
815
- tokens = tokens.concat(token);
816
- } else {
817
- //single token
818
- tokens.push(token);
819
- }
820
- }
821
-
822
- switchBackFromEmbeddedLanguageIfNecessary(context);
823
- context.reader.read();
824
- }
825
-
826
- //append the last default token, if necessary
827
- if (context.defaultData.text !== "") {
828
- tokens.push(context.createToken("default", context.defaultData.text, context.defaultData.line, context.defaultData.column));
829
- }
830
-
831
- fireEvent("afterTokenize", this, { code: unhighlightedCode, parserContext: context });
832
- return context;
833
- }
834
-
835
- function createAnalyzerContext(parserContext, partialContext, options) {
836
- var nodes = [],
837
- prepareText = function() {
838
- var nbsp, tab;
839
- if (options.showWhitespace) {
840
- nbsp = String.fromCharCode(0xB7);
841
- tab = new Array(options.tabWidth).join(String.fromCharCode(0x2014)) + String.fromCharCode(0x2192);
842
- } else {
843
- nbsp = String.fromCharCode(0xA0);
844
- tab = new Array(options.tabWidth + 1).join(nbsp);
845
- }
846
-
847
- return function(token) {
848
- var value = token.value.split(" ").join(nbsp),
849
- tabIndex,
850
- lastNewlineColumn,
851
- actualColumn,
852
- tabLength;
853
-
854
- //tabstop madness: replace \t with the appropriate number of characters, depending on the tabWidth option and its relative position in the line
855
- while ((tabIndex = value.indexOf("\t")) >= 0) {
856
- lastNewlineColumn = value.lastIndexOf(EOL, tabIndex);
857
- actualColumn = lastNewlineColumn === -1 ? tabIndex : tabIndex - lastNewlineColumn - 1;
858
- tabLength = options.tabWidth - (actualColumn % options.tabWidth); //actual length of the TAB character
859
-
860
- value = value.substring(0, tabIndex) + tab.substring(options.tabWidth - tabLength) + value.substring(tabIndex + 1);
861
- }
862
-
863
- return value;
864
- };
865
- }();
866
-
867
- return {
868
- tokens: (partialContext.tokens || []).concat(parserContext.getAllTokens()),
869
- index: partialContext.index ? partialContext.index + 1 : 0,
870
- language: null,
871
- getAnalyzer: EMPTY,
872
- options: options,
873
- continuation: parserContext.continuation,
874
- addNode: function(node) { nodes.push(node); },
875
- createTextNode: function(token) { return document.createTextNode(prepareText(token)); },
876
- getNodes: function() { return nodes; },
877
- resetNodes: function() { nodes = []; },
878
- items: parserContext.items
879
- };
880
- }
881
-
882
- //partialContext allows us to perform a partial parse, and then pick up where we left off at a later time
883
- //this functionality enables nested highlights (language within a language, e.g. PHP within HTML followed by more PHP)
884
- function highlightText(unhighlightedCode, languageId, partialContext) {
885
- var language = languages[languageId],
886
- analyzerContext;
887
-
888
- partialContext = partialContext || { };
889
- if (language === undefined) {
890
- //use default language if one wasn't specified or hasn't been registered
891
- language = languages[DEFAULT_LANGUAGE];
892
- }
893
-
894
- fireEvent("beforeHighlight", this, { code: unhighlightedCode, language: language, previousContext: partialContext });
895
-
896
- analyzerContext = createAnalyzerContext(
897
- tokenize.call(this, unhighlightedCode, language, partialContext, this.options),
898
- partialContext,
899
- this.options
900
- );
901
-
902
- analyze.call(this, analyzerContext, partialContext.index ? partialContext.index + 1 : 0);
903
-
904
- fireEvent("afterHighlight", this, { analyzerContext: analyzerContext });
905
-
906
- return analyzerContext;
907
- }
908
-
909
- function createContainer(ctx) {
910
- var container = document.createElement("span");
911
- container.className = ctx.options.classPrefix + ctx.language.name;
912
- return container;
913
- }
914
-
915
- function analyze(analyzerContext, startIndex) {
916
- var nodes,
917
- lastIndex,
918
- container,
919
- i,
920
- tokenName,
921
- func,
922
- language,
923
- analyzer;
924
-
925
- fireEvent("beforeAnalyze", this, { analyzerContext: analyzerContext });
926
-
927
- if (analyzerContext.tokens.length > 0) {
928
- analyzerContext.language = languages[analyzerContext.tokens[0].language] || languages[DEFAULT_LANGUAGE];;
929
- nodes = [];
930
- lastIndex = 0;
931
- container = createContainer(analyzerContext);
932
-
933
- for (i = startIndex; i < analyzerContext.tokens.length; i++) {
934
- language = languages[analyzerContext.tokens[i].language] || languages[DEFAULT_LANGUAGE];
935
- if (language.name !== analyzerContext.language.name) {
936
- appendAll(container, analyzerContext.getNodes());
937
- analyzerContext.resetNodes();
938
-
939
- nodes.push(container);
940
- analyzerContext.language = language;
941
- container = createContainer(analyzerContext);
942
- }
943
-
944
- analyzerContext.index = i;
945
- tokenName = analyzerContext.tokens[i].name;
946
- func = "handle_" + tokenName;
947
-
948
- analyzer = analyzerContext.getAnalyzer.call(analyzerContext) || analyzerContext.language.analyzer;
949
- analyzer[func] ? analyzer[func](analyzerContext) : analyzer.handleToken(analyzerContext);
950
- }
951
-
952
- //append the last nodes, and add the final nodes to the context
953
- appendAll(container, analyzerContext.getNodes());
954
- nodes.push(container);
955
- analyzerContext.resetNodes();
956
- for (i = 0; i < nodes.length; i++) {
957
- analyzerContext.addNode(nodes[i]);
958
- }
959
- }
960
-
961
- fireEvent("afterAnalyze", this, { analyzerContext: analyzerContext });
962
- }
963
-
964
- return {
965
- //matches the language of the node to highlight
966
- matchSunlightNode: function() {
967
- var regex;
968
-
969
- return function(node) {
970
- if (!regex) {
971
- regex = new RegExp("(?:\\s|^)" + this.options.classPrefix + "highlight-(\\S+)(?:\\s|$)");
972
- }
973
-
974
- return regex.exec(node.className);
975
- };
976
- }(),
977
-
978
- //determines if the node has already been highlighted
979
- isAlreadyHighlighted: function() {
980
- var regex;
981
- return function(node) {
982
- if (!regex) {
983
- regex = new RegExp("(?:\\s|^)" + this.options.classPrefix + "highlighted(?:\\s|$)");
984
- }
985
-
986
- return regex.test(node.className);
987
- };
988
- }(),
989
-
990
- //highlights a block of text
991
- highlight: function(code, languageId) { return highlightText.call(this, code, languageId); },
992
-
993
- //recursively highlights a DOM node
994
- highlightNode: function highlightRecursive(node) {
995
- var match,
996
- languageId,
997
- currentNodeCount,
998
- j,
999
- nodes,
1000
- k,
1001
- partialContext,
1002
- container,
1003
- codeContainer;
1004
-
1005
- if (this.isAlreadyHighlighted(node) || (match = this.matchSunlightNode(node)) === null) {
1006
- return;
1007
- }
1008
-
1009
- languageId = match[1];
1010
- currentNodeCount = 0;
1011
- fireEvent("beforeHighlightNode", this, { node: node });
1012
- for (j = 0; j < node.childNodes.length; j++) {
1013
- if (node.childNodes[j].nodeType === 3) {
1014
- //text nodes
1015
- partialContext = highlightText.call(this, node.childNodes[j].nodeValue, languageId, partialContext);
1016
- HIGHLIGHTED_NODE_COUNT++;
1017
- currentNodeCount = currentNodeCount || HIGHLIGHTED_NODE_COUNT;
1018
- nodes = partialContext.getNodes();
1019
-
1020
- node.replaceChild(nodes[0], node.childNodes[j]);
1021
- for (k = 1; k < nodes.length; k++) {
1022
- node.insertBefore(nodes[k], nodes[k - 1].nextSibling);
1023
- }
1024
- } else if (node.childNodes[j].nodeType === 1) {
1025
- //element nodes
1026
- highlightRecursive.call(this, node.childNodes[j]);
1027
- }
1028
- }
1029
-
1030
- //indicate that this node has been highlighted
1031
- node.className += " " + this.options.classPrefix + "highlighted";
1032
-
1033
- //if the node is block level, we put it in a container, otherwise we just leave it alone
1034
- if (getComputedStyle(node, "display") === "block") {
1035
- container = document.createElement("div");
1036
- container.className = this.options.classPrefix + "container";
1037
-
1038
- codeContainer = document.createElement("div");
1039
- codeContainer.className = this.options.classPrefix + "code-container";
1040
-
1041
- //apply max height if specified in options
1042
- if (this.options.maxHeight !== false) {
1043
- codeContainer.style.overflowY = "auto";
1044
- codeContainer.style.maxHeight = this.options.maxHeight + (/^\d+$/.test(this.options.maxHeight) ? "px" : "");
1045
- }
1046
-
1047
- container.appendChild(codeContainer);
1048
-
1049
- node.parentNode.insertBefore(codeContainer, node);
1050
- node.parentNode.removeChild(node);
1051
- codeContainer.appendChild(node);
1052
-
1053
- codeContainer.parentNode.insertBefore(container, codeContainer);
1054
- codeContainer.parentNode.removeChild(codeContainer);
1055
- container.appendChild(codeContainer);
1056
- }
1057
-
1058
- fireEvent("afterHighlightNode", this, {
1059
- container: container,
1060
- codeContainer: codeContainer,
1061
- node: node,
1062
- count: currentNodeCount
1063
- });
1064
- }
1065
- };
1066
- }());
1067
-
1068
- //public facing object
1069
- window.Sunlight = {
1070
- version: "1.18",
1071
- Highlighter: Highlighter,
1072
- createAnalyzer: function() { return create(defaultAnalyzer); },
1073
- globalOptions: globalOptions,
1074
-
1075
- highlightAll: function(options) {
1076
- var highlighter = new Highlighter(options),
1077
- tags = document.getElementsByTagName("*"),
1078
- i;
1079
-
1080
- for (i = 0; i < tags.length; i++) {
1081
- highlighter.highlightNode(tags[i]);
1082
- }
1083
- },
1084
-
1085
- registerLanguage: function(languageId, languageData) {
1086
- var tokenName,
1087
- embeddedLanguages,
1088
- languageName;
1089
-
1090
- if (!languageId) {
1091
- throw "Languages must be registered with an identifier, e.g. \"php\" for PHP";
1092
- }
1093
-
1094
- languageData = merge(merge({}, languageDefaults), languageData);
1095
- languageData.name = languageId;
1096
-
1097
- //transform keywords, operators and custom tokens into a hash map
1098
- languageData.keywords = createHashMap(languageData.keywords || [], "\\b", languageData.caseInsensitive);
1099
- languageData.operators = createHashMap(languageData.operators || [], "", languageData.caseInsensitive);
1100
- for (tokenName in languageData.customTokens) {
1101
- languageData.customTokens[tokenName] = createHashMap(
1102
- languageData.customTokens[tokenName].values,
1103
- languageData.customTokens[tokenName].boundary,
1104
- languageData.caseInsensitive
1105
- );
1106
- }
1107
-
1108
- //convert the embedded language object to an easier-to-use array
1109
- embeddedLanguages = [];
1110
- for (languageName in languageData.embeddedLanguages) {
1111
- embeddedLanguages.push({
1112
- parentLanguage: languageData.name,
1113
- language: languageName,
1114
- switchTo: languageData.embeddedLanguages[languageName].switchTo,
1115
- switchBack: languageData.embeddedLanguages[languageName].switchBack
1116
- });
1117
- }
1118
-
1119
- languageData.embeddedLanguages = embeddedLanguages;
1120
-
1121
- languages[languageData.name] = languageData;
1122
- },
1123
-
1124
- isRegistered: function(languageId) { return languages[languageId] !== undefined; },
1125
-
1126
- bind: function(event, callback) {
1127
- if (!events[event]) {
1128
- throw "Unknown event \"" + event + "\"";
1129
- }
1130
-
1131
- events[event].push(callback);
1132
- },
1133
-
1134
- util: {
1135
- last: last,
1136
- regexEscape: regexEscape,
1137
- eol: EOL,
1138
- clone: clone,
1139
- escapeSequences: ["\\n", "\\t", "\\r", "\\\\", "\\v", "\\f"],
1140
- contains: contains,
1141
- matchWord: matchWord,
1142
- createHashMap: createHashMap,
1143
- createBetweenRule: createBetweenRule,
1144
- createProceduralRule: createProceduralRule,
1145
- getNextNonWsToken: function(tokens, index) { return getNextWhile(tokens, index, 1, function(token) { return token.name === "default"; }); },
1146
- getPreviousNonWsToken: function(tokens, index) { return getNextWhile(tokens, index, -1, function(token) { return token.name === "default"; }); },
1147
- getNextWhile: function(tokens, index, matcher) { return getNextWhile(tokens, index, 1, matcher); },
1148
- getPreviousWhile: function(tokens, index, matcher) { return getNextWhile(tokens, index, -1, matcher); },
1149
- whitespace: { token: "default", optional: true },
1150
- getComputedStyle: getComputedStyle
1151
- }
1152
- };
1153
-
1154
- //register the default language
1155
- window.Sunlight.registerLanguage(DEFAULT_LANGUAGE, { punctuation: /(?!x)x/, numberParser: EMPTY });
1156
-
1157
- }(this, document));