test.js 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: http://codemirror.net/LICENSE
  3. (function() {
  4. var config = {tabSize: 4, indentUnit: 2}
  5. var mode = CodeMirror.getMode(config, "markdown");
  6. function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
  7. var modeHighlightFormatting = CodeMirror.getMode(config, {name: "markdown", highlightFormatting: true});
  8. function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); }
  9. var modeMT_noXml = CodeMirror.getMode(config, {name: "markdown", xml: false});
  10. function MT_noXml(name) { test.mode(name, modeMT_noXml, Array.prototype.slice.call(arguments, 1)); }
  11. var modeMT_noFencedHighlight = CodeMirror.getMode(config, {name: "markdown", fencedCodeBlockHighlighting: false});
  12. function MT_noFencedHighlight(name) { test.mode(name, modeMT_noFencedHighlight, Array.prototype.slice.call(arguments, 1)); }
  13. var modeAtxNoSpace = CodeMirror.getMode(config, {name: "markdown", allowAtxHeaderWithoutSpace: true});
  14. function AtxNoSpaceTest(name) { test.mode(name, modeAtxNoSpace, Array.prototype.slice.call(arguments, 1)); }
  15. var modeOverrideClasses = CodeMirror.getMode(config, {
  16. name: "markdown",
  17. strikethrough: true,
  18. emoji: true,
  19. tokenTypeOverrides: {
  20. "header" : "override-header",
  21. "code" : "override-code",
  22. "quote" : "override-quote",
  23. "list1" : "override-list1",
  24. "list2" : "override-list2",
  25. "list3" : "override-list3",
  26. "hr" : "override-hr",
  27. "image" : "override-image",
  28. "imageAltText": "override-image-alt-text",
  29. "imageMarker": "override-image-marker",
  30. "linkInline" : "override-link-inline",
  31. "linkEmail" : "override-link-email",
  32. "linkText" : "override-link-text",
  33. "linkHref" : "override-link-href",
  34. "em" : "override-em",
  35. "strong" : "override-strong",
  36. "strikethrough" : "override-strikethrough",
  37. "emoji" : "override-emoji"
  38. }});
  39. function TokenTypeOverrideTest(name) { test.mode(name, modeOverrideClasses, Array.prototype.slice.call(arguments, 1)); }
  40. var modeFormattingOverride = CodeMirror.getMode(config, {
  41. name: "markdown",
  42. highlightFormatting: true,
  43. tokenTypeOverrides: {
  44. "formatting" : "override-formatting"
  45. }});
  46. function FormatTokenTypeOverrideTest(name) { test.mode(name, modeFormattingOverride, Array.prototype.slice.call(arguments, 1)); }
  47. FT("formatting_emAsterisk",
  48. "[em&formatting&formatting-em *][em foo][em&formatting&formatting-em *]");
  49. FT("formatting_emUnderscore",
  50. "[em&formatting&formatting-em _][em foo][em&formatting&formatting-em _]");
  51. FT("formatting_strongAsterisk",
  52. "[strong&formatting&formatting-strong **][strong foo][strong&formatting&formatting-strong **]");
  53. FT("formatting_strongUnderscore",
  54. "[strong&formatting&formatting-strong __][strong foo][strong&formatting&formatting-strong __]");
  55. FT("formatting_codeBackticks",
  56. "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]");
  57. FT("formatting_doubleBackticks",
  58. "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]");
  59. FT("formatting_atxHeader",
  60. "[header&header-1&formatting&formatting-header&formatting-header-1 # ][header&header-1 foo # bar ][header&header-1&formatting&formatting-header&formatting-header-1 #]");
  61. FT("formatting_setextHeader",
  62. "[header&header-1 foo]",
  63. "[header&header-1&formatting&formatting-header&formatting-header-1 =]");
  64. FT("formatting_blockquote",
  65. "[quote&quote-1&formatting&formatting-quote&formatting-quote-1 > ][quote&quote-1 foo]");
  66. FT("formatting_list",
  67. "[variable-2&formatting&formatting-list&formatting-list-ul - ][variable-2 foo]");
  68. FT("formatting_list",
  69. "[variable-2&formatting&formatting-list&formatting-list-ol 1. ][variable-2 foo]");
  70. FT("formatting_link",
  71. "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url (][string&url http://example.com/][string&formatting&formatting-link-string&url )]");
  72. FT("formatting_linkReference",
  73. "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url [][string&url bar][string&formatting&formatting-link-string&url ]]]",
  74. "[link&formatting&formatting-link [][link bar][link&formatting&formatting-link ]]:] [string&url http://example.com/]");
  75. FT("formatting_linkWeb",
  76. "[link&formatting&formatting-link <][link http://example.com/][link&formatting&formatting-link >]");
  77. FT("formatting_linkEmail",
  78. "[link&formatting&formatting-link <][link user@example.com][link&formatting&formatting-link >]");
  79. FT("formatting_escape",
  80. "[formatting-escape \\*]");
  81. FT("formatting_image",
  82. "[formatting&formatting-image&image&image-marker !][formatting&formatting-image&image&image-alt-text&link [[][image&image-alt-text&link alt text][formatting&formatting-image&image&image-alt-text&link ]]][formatting&formatting-link-string&string&url (][url&string http://link.to/image.jpg][formatting&formatting-link-string&string&url )]");
  83. FT("codeBlock",
  84. "[comment&formatting&formatting-code-block ```css]",
  85. "[tag foo]",
  86. "[comment&formatting&formatting-code-block ```]");
  87. MT("plainText",
  88. "foo");
  89. // Don't style single trailing space
  90. MT("trailingSpace1",
  91. "foo ");
  92. // Two or more trailing spaces should be styled with line break character
  93. MT("trailingSpace2",
  94. "foo[trailing-space-a ][trailing-space-new-line ]");
  95. MT("trailingSpace3",
  96. "foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]");
  97. MT("trailingSpace4",
  98. "foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]");
  99. // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
  100. MT("codeBlocksUsing4Spaces",
  101. " [comment foo]");
  102. // Code blocks using 4 spaces with internal indentation
  103. MT("codeBlocksUsing4SpacesIndentation",
  104. " [comment bar]",
  105. " [comment hello]",
  106. " [comment world]",
  107. " [comment foo]",
  108. "bar");
  109. // Code blocks should end even after extra indented lines
  110. MT("codeBlocksWithTrailingIndentedLine",
  111. " [comment foo]",
  112. " [comment bar]",
  113. " [comment baz]",
  114. " ",
  115. "hello");
  116. // Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value)
  117. MT("codeBlocksUsing1Tab",
  118. "\t[comment foo]");
  119. // No code blocks directly after paragraph
  120. // http://spec.commonmark.org/0.19/#example-65
  121. MT("noCodeBlocksAfterParagraph",
  122. "Foo",
  123. " Bar");
  124. MT("codeBlocksAfterATX",
  125. "[header&header-1 # foo]",
  126. " [comment code]");
  127. MT("codeBlocksAfterSetext",
  128. "[header&header-2 foo]",
  129. "[header&header-2 ---]",
  130. " [comment code]");
  131. MT("codeBlocksAfterFencedCode",
  132. "[comment ```]",
  133. "[comment foo]",
  134. "[comment ```]",
  135. " [comment code]");
  136. // Inline code using backticks
  137. MT("inlineCodeUsingBackticks",
  138. "foo [comment `bar`]");
  139. // Block code using single backtick (shouldn't work)
  140. MT("blockCodeSingleBacktick",
  141. "[comment `]",
  142. "[comment foo]",
  143. "[comment `]");
  144. // Unclosed backticks
  145. // Instead of simply marking as CODE, it would be nice to have an
  146. // incomplete flag for CODE, that is styled slightly different.
  147. MT("unclosedBackticks",
  148. "foo [comment `bar]");
  149. // Per documentation: "To include a literal backtick character within a
  150. // code span, you can use multiple backticks as the opening and closing
  151. // delimiters"
  152. MT("doubleBackticks",
  153. "[comment ``foo ` bar``]");
  154. // Tests based on Dingus
  155. // http://daringfireball.net/projects/markdown/dingus
  156. //
  157. // Multiple backticks within an inline code block
  158. MT("consecutiveBackticks",
  159. "[comment `foo```bar`]");
  160. // Multiple backticks within an inline code block with a second code block
  161. MT("consecutiveBackticks",
  162. "[comment `foo```bar`] hello [comment `world`]");
  163. // Unclosed with several different groups of backticks
  164. MT("unclosedBackticks",
  165. "[comment ``foo ``` bar` hello]");
  166. // Closed with several different groups of backticks
  167. MT("closedBackticks",
  168. "[comment ``foo ``` bar` hello``] world");
  169. // info string cannot contain backtick, thus should result in inline code
  170. MT("closingFencedMarksOnSameLine",
  171. "[comment ``` code ```] foo");
  172. // atx headers
  173. // http://daringfireball.net/projects/markdown/syntax#header
  174. MT("atxH1",
  175. "[header&header-1 # foo]");
  176. MT("atxH2",
  177. "[header&header-2 ## foo]");
  178. MT("atxH3",
  179. "[header&header-3 ### foo]");
  180. MT("atxH4",
  181. "[header&header-4 #### foo]");
  182. MT("atxH5",
  183. "[header&header-5 ##### foo]");
  184. MT("atxH6",
  185. "[header&header-6 ###### foo]");
  186. // http://spec.commonmark.org/0.19/#example-24
  187. MT("noAtxH7",
  188. "####### foo");
  189. // http://spec.commonmark.org/0.19/#example-25
  190. MT("noAtxH1WithoutSpace",
  191. "#5 bolt");
  192. // CommonMark requires a space after # but most parsers don't
  193. AtxNoSpaceTest("atxNoSpaceAllowed_H1NoSpace",
  194. "[header&header-1 #foo]");
  195. AtxNoSpaceTest("atxNoSpaceAllowed_H4NoSpace",
  196. "[header&header-4 ####foo]");
  197. AtxNoSpaceTest("atxNoSpaceAllowed_H1Space",
  198. "[header&header-1 # foo]");
  199. // Inline styles should be parsed inside headers
  200. MT("atxH1inline",
  201. "[header&header-1 # foo ][header&header-1&em *bar*]");
  202. MT("atxIndentedTooMuch",
  203. "[header&header-1 # foo]",
  204. " [comment # bar]");
  205. // disable atx inside blockquote until we implement proper blockquote inner mode
  206. // TODO: fix to be CommonMark-compliant
  207. MT("atxNestedInsideBlockquote",
  208. "[quote&quote-1 > # foo]");
  209. MT("atxAfterBlockquote",
  210. "[quote&quote-1 > foo]",
  211. "[header&header-1 # bar]");
  212. // Setext headers - H1, H2
  213. // Per documentation, "Any number of underlining =’s or -’s will work."
  214. // http://daringfireball.net/projects/markdown/syntax#header
  215. // Ideally, the text would be marked as `header` as well, but this is
  216. // not really feasible at the moment. So, instead, we're testing against
  217. // what works today, to avoid any regressions.
  218. //
  219. // Check if single underlining = works
  220. MT("setextH1",
  221. "[header&header-1 foo]",
  222. "[header&header-1 =]");
  223. // Check if 3+ ='s work
  224. MT("setextH1",
  225. "[header&header-1 foo]",
  226. "[header&header-1 ===]");
  227. // Check if single underlining - works
  228. MT("setextH2",
  229. "[header&header-2 foo]",
  230. "[header&header-2 -]");
  231. // Check if 3+ -'s work
  232. MT("setextH2",
  233. "[header&header-2 foo]",
  234. "[header&header-2 ---]");
  235. // http://spec.commonmark.org/0.19/#example-45
  236. MT("setextH2AllowSpaces",
  237. "[header&header-2 foo]",
  238. " [header&header-2 ---- ]");
  239. // http://spec.commonmark.org/0.19/#example-44
  240. MT("noSetextAfterIndentedCodeBlock",
  241. " [comment foo]",
  242. "[hr ---]");
  243. MT("setextAfterFencedCode",
  244. "[comment ```]",
  245. "[comment foo]",
  246. "[comment ```]",
  247. "[header&header-2 bar]",
  248. "[header&header-2 ---]");
  249. MT("setextAferATX",
  250. "[header&header-1 # foo]",
  251. "[header&header-2 bar]",
  252. "[header&header-2 ---]");
  253. // http://spec.commonmark.org/0.19/#example-51
  254. MT("noSetextAfterQuote",
  255. "[quote&quote-1 > foo]",
  256. "[hr ---]",
  257. "",
  258. "[quote&quote-1 > foo]",
  259. "[quote&quote-1 bar]",
  260. "[hr ---]");
  261. MT("noSetextAfterList",
  262. "[variable-2 - foo]",
  263. "[hr ---]");
  264. MT("noSetextAfterList_listContinuation",
  265. "[variable-2 - foo]",
  266. "bar",
  267. "[hr ---]");
  268. MT("setextAfterList_afterIndentedCode",
  269. "[variable-2 - foo]",
  270. "",
  271. " [comment bar]",
  272. "[header&header-2 baz]",
  273. "[header&header-2 ---]");
  274. MT("setextAfterList_afterFencedCodeBlocks",
  275. "[variable-2 - foo]",
  276. "",
  277. " [comment ```]",
  278. " [comment bar]",
  279. " [comment ```]",
  280. "[header&header-2 baz]",
  281. "[header&header-2 ---]");
  282. MT("setextAfterList_afterHeader",
  283. "[variable-2 - foo]",
  284. " [variable-2&header&header-1 # bar]",
  285. "[header&header-2 baz]",
  286. "[header&header-2 ---]");
  287. MT("setextAfterList_afterHr",
  288. "[variable-2 - foo]",
  289. "",
  290. " [hr ---]",
  291. "[header&header-2 bar]",
  292. "[header&header-2 ---]");
  293. MT("setext_nestedInlineMarkup",
  294. "[header&header-1 foo ][em&header&header-1 *bar*]",
  295. "[header&header-1 =]");
  296. MT("setext_linkDef",
  297. "[link [[aaa]]:] [string&url http://google.com 'title']",
  298. "[hr ---]");
  299. // currently, looks max one line ahead, thus won't catch valid CommonMark
  300. // markup
  301. MT("setext_oneLineLookahead",
  302. "foo",
  303. "[header&header-1 bar]",
  304. "[header&header-1 =]");
  305. // ensure we don't regard space after dash as a list
  306. MT("setext_emptyList",
  307. "[header&header-2 foo]",
  308. "[header&header-2 - ]",
  309. "foo");
  310. // Single-line blockquote with trailing space
  311. MT("blockquoteSpace",
  312. "[quote&quote-1 > foo]");
  313. // Single-line blockquote
  314. MT("blockquoteNoSpace",
  315. "[quote&quote-1 >foo]");
  316. // No blank line before blockquote
  317. MT("blockquoteNoBlankLine",
  318. "foo",
  319. "[quote&quote-1 > bar]");
  320. MT("blockquoteNested",
  321. "[quote&quote-1 > foo]",
  322. "[quote&quote-1 >][quote&quote-2 > foo]",
  323. "[quote&quote-1 >][quote&quote-2 >][quote&quote-3 > foo]");
  324. // ensure quote-level is inferred correctly even if indented
  325. MT("blockquoteNestedIndented",
  326. " [quote&quote-1 > foo]",
  327. " [quote&quote-1 >][quote&quote-2 > foo]",
  328. " [quote&quote-1 >][quote&quote-2 >][quote&quote-3 > foo]");
  329. // ensure quote-level is inferred correctly even if indented
  330. MT("blockquoteIndentedTooMuch",
  331. "foo",
  332. " > bar");
  333. // Single-line blockquote followed by normal paragraph
  334. MT("blockquoteThenParagraph",
  335. "[quote&quote-1 >foo]",
  336. "",
  337. "bar");
  338. // Multi-line blockquote (lazy mode)
  339. MT("multiBlockquoteLazy",
  340. "[quote&quote-1 >foo]",
  341. "[quote&quote-1 bar]");
  342. // Multi-line blockquote followed by normal paragraph (lazy mode)
  343. MT("multiBlockquoteLazyThenParagraph",
  344. "[quote&quote-1 >foo]",
  345. "[quote&quote-1 bar]",
  346. "",
  347. "hello");
  348. // Multi-line blockquote (non-lazy mode)
  349. MT("multiBlockquote",
  350. "[quote&quote-1 >foo]",
  351. "[quote&quote-1 >bar]");
  352. // Multi-line blockquote followed by normal paragraph (non-lazy mode)
  353. MT("multiBlockquoteThenParagraph",
  354. "[quote&quote-1 >foo]",
  355. "[quote&quote-1 >bar]",
  356. "",
  357. "hello");
  358. // disallow lists inside blockquote for now because it causes problems outside blockquote
  359. // TODO: fix to be CommonMark-compliant
  360. MT("listNestedInBlockquote",
  361. "[quote&quote-1 > - foo]");
  362. // disallow fenced blocks inside blockquote because it causes problems outside blockquote
  363. // TODO: fix to be CommonMark-compliant
  364. MT("fencedBlockNestedInBlockquote",
  365. "[quote&quote-1 > ```]",
  366. "[quote&quote-1 > code]",
  367. "[quote&quote-1 > ```]",
  368. // ensure we still allow inline code
  369. "[quote&quote-1 > ][quote&quote-1&comment `code`]");
  370. // Header with leading space after continued blockquote (#3287, negative indentation)
  371. MT("headerAfterContinuedBlockquote",
  372. "[quote&quote-1 > foo]",
  373. "[quote&quote-1 bar]",
  374. "",
  375. " [header&header-1 # hello]");
  376. // Check list types
  377. MT("listAsterisk",
  378. "foo",
  379. "bar",
  380. "",
  381. "[variable-2 * foo]",
  382. "[variable-2 * bar]");
  383. MT("listPlus",
  384. "foo",
  385. "bar",
  386. "",
  387. "[variable-2 + foo]",
  388. "[variable-2 + bar]");
  389. MT("listDash",
  390. "foo",
  391. "bar",
  392. "",
  393. "[variable-2 - foo]",
  394. "[variable-2 - bar]");
  395. MT("listNumber",
  396. "foo",
  397. "bar",
  398. "",
  399. "[variable-2 1. foo]",
  400. "[variable-2 2. bar]");
  401. MT("listFromParagraph",
  402. "foo",
  403. "[variable-2 1. bar]",
  404. "[variable-2 2. hello]");
  405. // List after hr
  406. MT("listAfterHr",
  407. "[hr ---]",
  408. "[variable-2 - bar]");
  409. // List after header
  410. MT("listAfterHeader",
  411. "[header&header-1 # foo]",
  412. "[variable-2 - bar]");
  413. // hr after list
  414. MT("hrAfterList",
  415. "[variable-2 - foo]",
  416. "[hr -----]");
  417. MT("hrAfterFencedCode",
  418. "[comment ```]",
  419. "[comment code]",
  420. "[comment ```]",
  421. "[hr ---]");
  422. // allow hr inside lists
  423. // (require prev line to be empty or hr, TODO: non-CommonMark-compliant)
  424. MT("hrInsideList",
  425. "[variable-2 - foo]",
  426. "",
  427. " [hr ---]",
  428. " [hr ---]",
  429. "",
  430. " [comment ---]");
  431. MT("consecutiveHr",
  432. "[hr ---]",
  433. "[hr ---]",
  434. "[hr ---]");
  435. // Formatting in lists (*)
  436. MT("listAsteriskFormatting",
  437. "[variable-2 * ][variable-2&em *foo*][variable-2 bar]",
  438. "[variable-2 * ][variable-2&strong **foo**][variable-2 bar]",
  439. "[variable-2 * ][variable-2&em&strong ***foo***][variable-2 bar]",
  440. "[variable-2 * ][variable-2&comment `foo`][variable-2 bar]");
  441. // Formatting in lists (+)
  442. MT("listPlusFormatting",
  443. "[variable-2 + ][variable-2&em *foo*][variable-2 bar]",
  444. "[variable-2 + ][variable-2&strong **foo**][variable-2 bar]",
  445. "[variable-2 + ][variable-2&em&strong ***foo***][variable-2 bar]",
  446. "[variable-2 + ][variable-2&comment `foo`][variable-2 bar]");
  447. // Formatting in lists (-)
  448. MT("listDashFormatting",
  449. "[variable-2 - ][variable-2&em *foo*][variable-2 bar]",
  450. "[variable-2 - ][variable-2&strong **foo**][variable-2 bar]",
  451. "[variable-2 - ][variable-2&em&strong ***foo***][variable-2 bar]",
  452. "[variable-2 - ][variable-2&comment `foo`][variable-2 bar]");
  453. // Formatting in lists (1.)
  454. MT("listNumberFormatting",
  455. "[variable-2 1. ][variable-2&em *foo*][variable-2 bar]",
  456. "[variable-2 2. ][variable-2&strong **foo**][variable-2 bar]",
  457. "[variable-2 3. ][variable-2&em&strong ***foo***][variable-2 bar]",
  458. "[variable-2 4. ][variable-2&comment `foo`][variable-2 bar]");
  459. // Paragraph lists
  460. MT("listParagraph",
  461. "[variable-2 * foo]",
  462. "",
  463. "[variable-2 * bar]");
  464. // Multi-paragraph lists
  465. //
  466. // 4 spaces
  467. MT("listMultiParagraph",
  468. "[variable-2 * foo]",
  469. "",
  470. "[variable-2 * bar]",
  471. "",
  472. " [variable-2 hello]");
  473. // 4 spaces, extra blank lines (should still be list, per Dingus)
  474. MT("listMultiParagraphExtra",
  475. "[variable-2 * foo]",
  476. "",
  477. "[variable-2 * bar]",
  478. "",
  479. "",
  480. " [variable-2 hello]");
  481. // 4 spaces, plus 1 space (should still be list, per Dingus)
  482. MT("listMultiParagraphExtraSpace",
  483. "[variable-2 * foo]",
  484. "",
  485. "[variable-2 * bar]",
  486. "",
  487. " [variable-2 hello]",
  488. "",
  489. " [variable-2 world]");
  490. // 1 tab
  491. MT("listTab",
  492. "[variable-2 * foo]",
  493. "",
  494. "[variable-2 * bar]",
  495. "",
  496. "\t[variable-2 hello]");
  497. // No indent
  498. MT("listNoIndent",
  499. "[variable-2 * foo]",
  500. "",
  501. "[variable-2 * bar]",
  502. "",
  503. "hello");
  504. MT("listCommonMarkIndentationCode",
  505. "[variable-2 * Code blocks also affect]",
  506. " [variable-3 * The next level starts where the contents start.]",
  507. " [variable-3 * Anything less than that will keep the item on the same level.]",
  508. " [variable-3 * Each list item can indent the first level further and further.]",
  509. " [variable-3 * For the most part, this makes sense while writing a list.]",
  510. " [keyword * This means two items with same indentation can be different levels.]",
  511. " [keyword * Each level has an indent requirement that can change between items.]",
  512. " [keyword * A list item that meets this will be part of the next level.]",
  513. " [variable-3 * Otherwise, it will be part of the level where it does meet this.]",
  514. " [variable-2 * World]");
  515. // should handle nested and un-nested lists
  516. MT("listCommonMark_MixedIndents",
  517. "[variable-2 * list1]",
  518. " [variable-2 list1]",
  519. " [variable-2&header&header-1 # heading still part of list1]",
  520. " [variable-2 text after heading still part of list1]",
  521. "",
  522. " [comment indented codeblock]",
  523. " [variable-2 list1 after code block]",
  524. " [variable-3 * list2]",
  525. // amount of spaces on empty lines between lists doesn't matter
  526. " ",
  527. // extra empty lines irrelevant
  528. "",
  529. "",
  530. " [variable-3 indented text part of list2]",
  531. " [keyword * list3]",
  532. "",
  533. " [variable-3 text at level of list2]",
  534. "",
  535. " [variable-2 de-indented text part of list1 again]",
  536. "",
  537. " [variable-2&comment ```]",
  538. " [comment code]",
  539. " [variable-2&comment ```]",
  540. "",
  541. " [variable-2 text after fenced code]");
  542. // should correctly parse numbered list content indentation
  543. MT("listCommonMark_NumeberedListIndent",
  544. "[variable-2 1000. list with base indent of 6]",
  545. "",
  546. " [variable-2 text must be indented 6 spaces at minimum]",
  547. "",
  548. " [variable-2 9-spaces indented text still part of list]",
  549. "",
  550. " [comment indented codeblock starts at 10 spaces]",
  551. "",
  552. " [comment text indented by 5 spaces no longer belong to list]");
  553. // should consider tab as 4 spaces
  554. MT("listCommonMark_TabIndented",
  555. "[variable-2 * list]",
  556. "\t[variable-3 * list2]",
  557. "",
  558. "\t\t[variable-3 part of list2]");
  559. MT("listAfterBlockquote",
  560. "[quote&quote-1 > foo]",
  561. "[variable-2 - bar]");
  562. // shouldn't create sublist if it's indented more than allowed
  563. MT("nestedListIndentedTooMuch",
  564. "[variable-2 - foo]",
  565. " [variable-2 - bar]");
  566. MT("listIndentedTooMuchAfterParagraph",
  567. "foo",
  568. " - bar");
  569. // Blockquote
  570. MT("blockquote",
  571. "[variable-2 * foo]",
  572. "",
  573. "[variable-2 * bar]",
  574. "",
  575. " [variable-2&quote&quote-1 > hello]");
  576. // Code block
  577. MT("blockquoteCode",
  578. "[variable-2 * foo]",
  579. "",
  580. "[variable-2 * bar]",
  581. "",
  582. " [comment > hello]",
  583. "",
  584. " [variable-2 world]");
  585. // Code block followed by text
  586. MT("blockquoteCodeText",
  587. "[variable-2 * foo]",
  588. "",
  589. " [variable-2 bar]",
  590. "",
  591. " [comment hello]",
  592. "",
  593. " [variable-2 world]");
  594. // Nested list
  595. MT("listAsteriskNested",
  596. "[variable-2 * foo]",
  597. "",
  598. " [variable-3 * bar]");
  599. MT("listPlusNested",
  600. "[variable-2 + foo]",
  601. "",
  602. " [variable-3 + bar]");
  603. MT("listDashNested",
  604. "[variable-2 - foo]",
  605. "",
  606. " [variable-3 - bar]");
  607. MT("listNumberNested",
  608. "[variable-2 1. foo]",
  609. "",
  610. " [variable-3 2. bar]");
  611. MT("listMixed",
  612. "[variable-2 * foo]",
  613. "",
  614. " [variable-3 + bar]",
  615. "",
  616. " [keyword - hello]",
  617. "",
  618. " [variable-2 1. world]");
  619. MT("listBlockquote",
  620. "[variable-2 * foo]",
  621. "",
  622. " [variable-3 + bar]",
  623. "",
  624. " [quote&quote-1&variable-3 > hello]");
  625. MT("listCode",
  626. "[variable-2 * foo]",
  627. "",
  628. " [variable-3 + bar]",
  629. "",
  630. " [comment hello]");
  631. // Code with internal indentation
  632. MT("listCodeIndentation",
  633. "[variable-2 * foo]",
  634. "",
  635. " [comment bar]",
  636. " [comment hello]",
  637. " [comment world]",
  638. " [comment foo]",
  639. " [variable-2 bar]");
  640. // List nesting edge cases
  641. MT("listNested",
  642. "[variable-2 * foo]",
  643. "",
  644. " [variable-3 * bar]",
  645. "",
  646. " [variable-3 hello]"
  647. );
  648. MT("listNested",
  649. "[variable-2 * foo]",
  650. "",
  651. " [variable-3 * bar]",
  652. "",
  653. " [keyword * foo]"
  654. );
  655. // Code followed by text
  656. MT("listCodeText",
  657. "[variable-2 * foo]",
  658. "",
  659. " [comment bar]",
  660. "",
  661. "hello");
  662. // Following tests directly from official Markdown documentation
  663. // http://daringfireball.net/projects/markdown/syntax#hr
  664. MT("hrSpace",
  665. "[hr * * *]");
  666. MT("hr",
  667. "[hr ***]");
  668. MT("hrLong",
  669. "[hr *****]");
  670. MT("hrSpaceDash",
  671. "[hr - - -]");
  672. MT("hrDashLong",
  673. "[hr ---------------------------------------]");
  674. //Images
  675. MT("Images",
  676. "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)]")
  677. //Images with highlight alt text
  678. MT("imageEm",
  679. "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&em&image&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
  680. MT("imageStrong",
  681. "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&strong&image&link **alt text**][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
  682. MT("imageEmStrong",
  683. "[image&image-marker !][image&image-alt-text&link [[][image&image-alt-text&em&strong&link ***alt text***][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
  684. // Inline link with title
  685. MT("linkTitle",
  686. "[link [[foo]]][string&url (http://example.com/ \"bar\")] hello");
  687. // Inline link without title
  688. MT("linkNoTitle",
  689. "[link [[foo]]][string&url (http://example.com/)] bar");
  690. // Inline link with image
  691. MT("linkImage",
  692. "[link [[][link&image&image-marker !][link&image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)][link ]]][string&url (http://example.com/)] bar");
  693. // Inline link with Em
  694. MT("linkEm",
  695. "[link [[][link&em *foo*][link ]]][string&url (http://example.com/)] bar");
  696. // Inline link with Strong
  697. MT("linkStrong",
  698. "[link [[][link&strong **foo**][link ]]][string&url (http://example.com/)] bar");
  699. // Inline link with EmStrong
  700. MT("linkEmStrong",
  701. "[link [[][link&em&strong ***foo***][link ]]][string&url (http://example.com/)] bar");
  702. MT("multilineLink",
  703. "[link [[foo]",
  704. "[link bar]]][string&url (https://foo#_a)]",
  705. "should not be italics")
  706. // Image with title
  707. MT("imageTitle",
  708. "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/ \"bar\")] hello");
  709. // Image without title
  710. MT("imageNoTitle",
  711. "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/)] bar");
  712. // Image with asterisks
  713. MT("imageAsterisks",
  714. "[image&image-marker !][image&image-alt-text&link [[ ][image&image-alt-text&em&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)] bar");
  715. // Not a link. Should be normal text due to square brackets being used
  716. // regularly in text, especially in quoted material, and no space is allowed
  717. // between square brackets and parentheses (per Dingus).
  718. MT("notALink",
  719. "[link [[foo]]] (bar)");
  720. // Reference-style links
  721. MT("linkReference",
  722. "[link [[foo]]][string&url [[bar]]] hello");
  723. // Reference-style links with Em
  724. MT("linkReferenceEm",
  725. "[link [[][link&em *foo*][link ]]][string&url [[bar]]] hello");
  726. // Reference-style links with Strong
  727. MT("linkReferenceStrong",
  728. "[link [[][link&strong **foo**][link ]]][string&url [[bar]]] hello");
  729. // Reference-style links with EmStrong
  730. MT("linkReferenceEmStrong",
  731. "[link [[][link&em&strong ***foo***][link ]]][string&url [[bar]]] hello");
  732. // Reference-style links with optional space separator (per documentation)
  733. // "You can optionally use a space to separate the sets of brackets"
  734. MT("linkReferenceSpace",
  735. "[link [[foo]]] [string&url [[bar]]] hello");
  736. // Should only allow a single space ("...use *a* space...")
  737. MT("linkReferenceDoubleSpace",
  738. "[link [[foo]]] [link [[bar]]] hello");
  739. // Reference-style links with implicit link name
  740. MT("linkImplicit",
  741. "[link [[foo]]][string&url [[]]] hello");
  742. // @todo It would be nice if, at some point, the document was actually
  743. // checked to see if the referenced link exists
  744. // Link label, for reference-style links (taken from documentation)
  745. MT("labelNoTitle",
  746. "[link [[foo]]:] [string&url http://example.com/]");
  747. MT("labelIndented",
  748. " [link [[foo]]:] [string&url http://example.com/]");
  749. MT("labelSpaceTitle",
  750. "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"]");
  751. MT("labelDoubleTitle",
  752. "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"] \"world\"");
  753. MT("labelTitleDoubleQuotes",
  754. "[link [[foo]]:] [string&url http://example.com/ \"bar\"]");
  755. MT("labelTitleSingleQuotes",
  756. "[link [[foo]]:] [string&url http://example.com/ 'bar']");
  757. MT("labelTitleParentheses",
  758. "[link [[foo]]:] [string&url http://example.com/ (bar)]");
  759. MT("labelTitleInvalid",
  760. "[link [[foo]]:] [string&url http://example.com/] bar");
  761. MT("labelLinkAngleBrackets",
  762. "[link [[foo]]:] [string&url <http://example.com/> \"bar\"]");
  763. MT("labelTitleNextDoubleQuotes",
  764. "[link [[foo]]:] [string&url http://example.com/]",
  765. "[string \"bar\"] hello");
  766. MT("labelTitleNextSingleQuotes",
  767. "[link [[foo]]:] [string&url http://example.com/]",
  768. "[string 'bar'] hello");
  769. MT("labelTitleNextParentheses",
  770. "[link [[foo]]:] [string&url http://example.com/]",
  771. "[string (bar)] hello");
  772. MT("labelTitleNextMixed",
  773. "[link [[foo]]:] [string&url http://example.com/]",
  774. "(bar\" hello");
  775. MT("labelEscape",
  776. "[link [[foo \\]] ]]:] [string&url http://example.com/]");
  777. MT("labelEscapeColon",
  778. "[link [[foo \\]]: bar]]:] [string&url http://example.com/]");
  779. MT("labelEscapeEnd",
  780. "\\[[foo\\]]: http://example.com/");
  781. MT("linkWeb",
  782. "[link <http://example.com/>] foo");
  783. MT("linkWebDouble",
  784. "[link <http://example.com/>] foo [link <http://example.com/>]");
  785. MT("linkEmail",
  786. "[link <user@example.com>] foo");
  787. MT("linkEmailDouble",
  788. "[link <user@example.com>] foo [link <user@example.com>]");
  789. MT("emAsterisk",
  790. "[em *foo*] bar");
  791. MT("emUnderscore",
  792. "[em _foo_] bar");
  793. MT("emInWordAsterisk",
  794. "foo[em *bar*]hello");
  795. MT("emInWordUnderscore",
  796. "foo_bar_hello");
  797. // Per documentation: "...surround an * or _ with spaces, it’ll be
  798. // treated as a literal asterisk or underscore."
  799. MT("emEscapedBySpaceIn",
  800. "foo [em _bar _ hello_] world");
  801. MT("emEscapedBySpaceOut",
  802. "foo _ bar [em _hello_] world");
  803. MT("emEscapedByNewline",
  804. "foo",
  805. "_ bar [em _hello_] world");
  806. // Unclosed emphasis characters
  807. // Instead of simply marking as EM / STRONG, it would be nice to have an
  808. // incomplete flag for EM and STRONG, that is styled slightly different.
  809. MT("emIncompleteAsterisk",
  810. "foo [em *bar]");
  811. MT("emIncompleteUnderscore",
  812. "foo [em _bar]");
  813. MT("strongAsterisk",
  814. "[strong **foo**] bar");
  815. MT("strongUnderscore",
  816. "[strong __foo__] bar");
  817. MT("emStrongAsterisk",
  818. "[em *foo][em&strong **bar*][strong hello**] world");
  819. MT("emStrongUnderscore",
  820. "[em _foo ][em&strong __bar_][strong hello__] world");
  821. // "...same character must be used to open and close an emphasis span.""
  822. MT("emStrongMixed",
  823. "[em _foo][em&strong **bar*hello__ world]");
  824. MT("emStrongMixed",
  825. "[em *foo ][em&strong __bar_hello** world]");
  826. MT("linkWithNestedParens",
  827. "[link [[foo]]][string&url (bar(baz))]")
  828. // These characters should be escaped:
  829. // \ backslash
  830. // ` backtick
  831. // * asterisk
  832. // _ underscore
  833. // {} curly braces
  834. // [] square brackets
  835. // () parentheses
  836. // # hash mark
  837. // + plus sign
  838. // - minus sign (hyphen)
  839. // . dot
  840. // ! exclamation mark
  841. MT("escapeBacktick",
  842. "foo \\`bar\\`");
  843. MT("doubleEscapeBacktick",
  844. "foo \\\\[comment `bar\\\\`]");
  845. MT("escapeAsterisk",
  846. "foo \\*bar\\*");
  847. MT("doubleEscapeAsterisk",
  848. "foo \\\\[em *bar\\\\*]");
  849. MT("escapeUnderscore",
  850. "foo \\_bar\\_");
  851. MT("doubleEscapeUnderscore",
  852. "foo \\\\[em _bar\\\\_]");
  853. MT("escapeHash",
  854. "\\# foo");
  855. MT("doubleEscapeHash",
  856. "\\\\# foo");
  857. MT("escapeNewline",
  858. "\\",
  859. "[em *foo*]");
  860. // Class override tests
  861. TokenTypeOverrideTest("overrideHeader1",
  862. "[override-header&override-header-1 # Foo]");
  863. TokenTypeOverrideTest("overrideHeader2",
  864. "[override-header&override-header-2 ## Foo]");
  865. TokenTypeOverrideTest("overrideHeader3",
  866. "[override-header&override-header-3 ### Foo]");
  867. TokenTypeOverrideTest("overrideHeader4",
  868. "[override-header&override-header-4 #### Foo]");
  869. TokenTypeOverrideTest("overrideHeader5",
  870. "[override-header&override-header-5 ##### Foo]");
  871. TokenTypeOverrideTest("overrideHeader6",
  872. "[override-header&override-header-6 ###### Foo]");
  873. TokenTypeOverrideTest("overrideCode",
  874. "[override-code `foo`]");
  875. TokenTypeOverrideTest("overrideCodeBlock",
  876. "[override-code ```]",
  877. "[override-code foo]",
  878. "[override-code ```]");
  879. TokenTypeOverrideTest("overrideQuote",
  880. "[override-quote&override-quote-1 > foo]",
  881. "[override-quote&override-quote-1 > bar]");
  882. TokenTypeOverrideTest("overrideQuoteNested",
  883. "[override-quote&override-quote-1 > foo]",
  884. "[override-quote&override-quote-1 >][override-quote&override-quote-2 > bar]",
  885. "[override-quote&override-quote-1 >][override-quote&override-quote-2 >][override-quote&override-quote-3 > baz]");
  886. TokenTypeOverrideTest("overrideLists",
  887. "[override-list1 - foo]",
  888. "",
  889. " [override-list2 + bar]",
  890. "",
  891. " [override-list3 * baz]",
  892. "",
  893. " [override-list1 1. qux]",
  894. "",
  895. " [override-list2 - quux]");
  896. TokenTypeOverrideTest("overrideHr",
  897. "[override-hr * * *]");
  898. TokenTypeOverrideTest("overrideImage",
  899. "[override-image&override-image-marker !][override-image&override-image-alt-text&link [[alt text]]][override-link-href&url (http://link.to/image.jpg)]");
  900. TokenTypeOverrideTest("overrideLinkText",
  901. "[override-link-text [[foo]]][override-link-href&url (http://example.com)]");
  902. TokenTypeOverrideTest("overrideLinkEmailAndInline",
  903. "[override-link-email <][override-link-inline foo@example.com>]");
  904. TokenTypeOverrideTest("overrideEm",
  905. "[override-em *foo*]");
  906. TokenTypeOverrideTest("overrideStrong",
  907. "[override-strong **foo**]");
  908. TokenTypeOverrideTest("overrideStrikethrough",
  909. "[override-strikethrough ~~foo~~]");
  910. TokenTypeOverrideTest("overrideEmoji",
  911. "[override-emoji :foo:]");
  912. FormatTokenTypeOverrideTest("overrideFormatting",
  913. "[override-formatting-escape \\*]");
  914. // Tests to make sure GFM-specific things aren't getting through
  915. MT("taskList",
  916. "[variable-2 * ][link&variable-2 [[ ]]][variable-2 bar]");
  917. MT("fencedCodeBlocks",
  918. "[comment ```]",
  919. "[comment foo]",
  920. "",
  921. "[comment bar]",
  922. "[comment ```]",
  923. "baz");
  924. MT("fencedCodeBlocks_invalidClosingFence_trailingText",
  925. "[comment ```]",
  926. "[comment foo]",
  927. "[comment ``` must not have trailing text]",
  928. "[comment baz]");
  929. MT("fencedCodeBlocks_invalidClosingFence_trailingTabs",
  930. "[comment ```]",
  931. "[comment foo]",
  932. "[comment ```\t]",
  933. "[comment baz]");
  934. MT("fencedCodeBlocks_validClosingFence",
  935. "[comment ```]",
  936. "[comment foo]",
  937. // may have trailing spaces
  938. "[comment ``` ]",
  939. "baz");
  940. MT("fencedCodeBlocksInList_closingFenceIndented",
  941. "[variable-2 - list]",
  942. " [variable-2&comment ```]",
  943. " [comment foo]",
  944. " [variable-2&comment ```]",
  945. " [variable-2 baz]");
  946. MT("fencedCodeBlocksInList_closingFenceIndentedTooMuch",
  947. "[variable-2 - list]",
  948. " [variable-2&comment ```]",
  949. " [comment foo]",
  950. " [comment ```]",
  951. " [comment baz]");
  952. MT("fencedCodeBlockModeSwitching",
  953. "[comment ```javascript]",
  954. "[variable foo]",
  955. "",
  956. "[comment ```]",
  957. "bar");
  958. MT_noFencedHighlight("fencedCodeBlock_noHighlight",
  959. "[comment ```javascript]",
  960. "[comment foo]",
  961. "[comment ```]");
  962. MT("fencedCodeBlockModeSwitchingObjc",
  963. "[comment ```objective-c]",
  964. "[keyword @property] [variable NSString] [operator *] [variable foo];",
  965. "[comment ```]",
  966. "bar");
  967. MT("fencedCodeBlocksMultipleChars",
  968. "[comment `````]",
  969. "[comment foo]",
  970. "[comment ```]",
  971. "[comment foo]",
  972. "[comment `````]",
  973. "bar");
  974. MT("fencedCodeBlocksTildes",
  975. "[comment ~~~]",
  976. "[comment foo]",
  977. "[comment ~~~]",
  978. "bar");
  979. MT("fencedCodeBlocksTildesMultipleChars",
  980. "[comment ~~~~~]",
  981. "[comment ~~~]",
  982. "[comment foo]",
  983. "[comment ~~~~~]",
  984. "bar");
  985. MT("fencedCodeBlocksMultipleChars",
  986. "[comment `````]",
  987. "[comment foo]",
  988. "[comment ```]",
  989. "[comment foo]",
  990. "[comment `````]",
  991. "bar");
  992. MT("fencedCodeBlocksMixed",
  993. "[comment ~~~]",
  994. "[comment ```]",
  995. "[comment foo]",
  996. "[comment ~~~]",
  997. "bar");
  998. MT("fencedCodeBlocksAfterBlockquote",
  999. "[quote&quote-1 > foo]",
  1000. "[comment ```]",
  1001. "[comment bar]",
  1002. "[comment ```]");
  1003. // fencedCode indented too much should act as simple indentedCode
  1004. // (hence has no highlight formatting)
  1005. FT("tooMuchIndentedFencedCode",
  1006. " [comment ```]",
  1007. " [comment code]",
  1008. " [comment ```]");
  1009. MT("autoTerminateFencedCodeWhenLeavingList",
  1010. "[variable-2 - list1]",
  1011. " [variable-3 - list2]",
  1012. " [variable-3&comment ```]",
  1013. " [comment code]",
  1014. " [variable-3 - list2]",
  1015. " [variable-2&comment ```]",
  1016. " [comment code]",
  1017. "[quote&quote-1 > foo]");
  1018. // Tests that require XML mode
  1019. MT("xmlMode",
  1020. "[tag&bracket <][tag div][tag&bracket >]",
  1021. " *foo*",
  1022. " [tag&bracket <][tag http://github.com][tag&bracket />]",
  1023. "[tag&bracket </][tag div][tag&bracket >]",
  1024. "[link <http://github.com/>]");
  1025. MT("xmlModeWithMarkdownInside",
  1026. "[tag&bracket <][tag div] [attribute markdown]=[string 1][tag&bracket >]",
  1027. "[em *foo*]",
  1028. "[link <http://github.com/>]",
  1029. "[tag </div>]",
  1030. "[link <http://github.com/>]",
  1031. "[tag&bracket <][tag div][tag&bracket >]",
  1032. "[tag&bracket </][tag div][tag&bracket >]");
  1033. MT_noXml("xmlHighlightDisabled",
  1034. "<div>foo</div>");
  1035. })();