PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/svn/tracwysiwyg/tests/testcase.js

https://bitbucket.org/iwata0303/traclightning
JavaScript | 1781 lines | 1721 code | 60 blank | 0 comment | 20 complexity | 5ccf14e2f89dd232717cf41fc80e2514 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.1, CPL-1.0, MIT, GPL-2.0, LGPL-2.0, Apache-2.0, BSD-3-Clause, AGPL-3.0
  1. addEvent(window, "load", function() {
  2. TracWysiwyg.tracPaths = { base: ".", search: "./search", stylesheets: [] };
  3. var options = TracWysiwyg.getOptions();
  4. var instance = new TracWysiwyg(document.getElementById("textarea"), options);
  5. var contentDocument = instance.contentDocument;
  6. var d = document;
  7. var wysiwygHtml = d.getElementById("wysiwyg-html");
  8. var showWysiwygHtml = d.getElementById("show-wysiwyg-html");
  9. setTimeout(function() {
  10. if (showWysiwygHtml.checked) {
  11. var body = contentDocument.body;
  12. var browserIE = body.attachEvent ? true : false;
  13. var elements = body.getElementsByTagName("br");
  14. var count = 0;
  15. var html = body.innerHTML.replace(/<[Bb][Rr] *[^>\/]*/g, function(value) {
  16. var element = elements[count++];
  17. var attributes = element.attributes;
  18. var length = attributes.length;
  19. if (length == 0)
  20. return value;
  21. var texts = [ value ];
  22. for (var i = 0; i < length; i++) {
  23. var attr = attributes[i];
  24. if (!browserIE || !!element[attr.name]) {
  25. texts.push(' ', attr.name, '="', attr.value, '"');
  26. }
  27. }
  28. return texts.join("");
  29. });
  30. if (wysiwygHtml.value != html) {
  31. wysiwygHtml.value = html;
  32. }
  33. }
  34. setTimeout(arguments.callee, 500);
  35. }, 500);
  36. function generate(dom, wikitext, options, withoutDomToWikitext, withoutWikitextToFragment) {
  37. dom = dom.cloneNode(true);
  38. var anonymous = dom.ownerDocument.createElement("div");
  39. anonymous.appendChild(dom);
  40. if (!withoutWikitextToFragment) {
  41. var fragment = instance.wikitextToFragment(wikitext, contentDocument, options);
  42. var generated = contentDocument.createElement("div");
  43. generated.appendChild(fragment);
  44. var generatedHtml = generated.innerHTML;
  45. if (!generated.addEventListener || window.opera) {
  46. generatedHtml = generatedHtml.replace(/\n\r/g, "\uffff").replace(/\uffff\n?/g, "\n");
  47. }
  48. this.assertEqual(anonymous.innerHTML, generatedHtml, "wikitextToFragment");
  49. }
  50. if (!withoutDomToWikitext) {
  51. this.assertEqual(wikitext, instance.domToWikitext(anonymous, options), "domToWikitext");
  52. }
  53. }
  54. function generateFragment(dom, wikitext, options) {
  55. generate.call(this, dom, wikitext, options, true, false);
  56. }
  57. function generateWikitext(dom, wikitext, options) {
  58. generate.call(this, dom, wikitext, options, false, true);
  59. }
  60. function run() {
  61. var unit = new TracWysiwyg.TestUnit();
  62. var fragment = unit.fragment;
  63. var element = unit.element;
  64. var br = function() { return element("br") };
  65. var a = function(link, label) {
  66. var attrs = {
  67. href: "./search?q=" + encodeURIComponent(link),
  68. title: link, "tracwysiwyg-link": link, onclick: "return false;" };
  69. return element("a", attrs, label);
  70. };
  71. unit.add("treeWalk", function() {
  72. var list;
  73. function iterator(node) {
  74. var value;
  75. if (node) {
  76. switch (node.nodeType) {
  77. case 1: value = node.tagName.toLowerCase(); break;
  78. case 3: value = "#text"; break;
  79. }
  80. }
  81. else {
  82. value = "(null)";
  83. }
  84. list.push(value);
  85. }
  86. function doTreeWalk(expected, dom) {
  87. list = [];
  88. instance.treeWalk(dom, iterator);
  89. this.assertEqual(expected, list.join(" "));
  90. list = [];
  91. instance._treeWalkEmulation(dom, iterator);
  92. this.assertEqual(expected, list.join(" "));
  93. }
  94. doTreeWalk.call(this, "p #text (null)", element("div", element("p", "paragraph")));
  95. doTreeWalk.call(this, "#text (null)", element("div", element("p", "paragraph")).firstChild);
  96. doTreeWalk.call(this, "(null)", element("div", element("p")).firstChild);
  97. var dom = element("div");
  98. dom.innerHTML = [
  99. '<h2 id="Tables">Tables</h2>',
  100. '<p>',
  101. 'Simple tables can be created like this:',
  102. '</p>',
  103. '<pre class="wiki">||Cell 1||Cell 2||Cell 3||',
  104. '||Cell 4||Cell 5||Cell 6||',
  105. '</pre><p>',
  106. 'Display:',
  107. '</p>',
  108. '<table class="wiki">',
  109. '<tbody><tr><td>Cell 1</td><td>Cell 2</td><td>Cell 3',
  110. '</td></tr><tr><td>Cell 4</td><td>Cell 5</td><td>Cell 6',
  111. '</td></tr></tbody></table>',
  112. '<p>',
  113. 'Note that more complex tables can be created using',
  114. '<a class="wiki" href="/practice/wiki/WikiRestructuredText#BiggerReSTExample">reStructuredText</a>.',
  115. '</p>' ].join("");
  116. var expected = [
  117. 'h2', '#text', 'p', '#text', 'pre', '#text', 'p', '#text',
  118. 'table', 'tbody',
  119. 'tr', 'td', '#text', 'td', '#text', 'td', '#text',
  120. 'tr', 'td', '#text', 'td', '#text', 'td', '#text',
  121. 'p', '#text', 'a', '#text', '#text',
  122. '(null)'].join(" ");
  123. doTreeWalk.call(this, expected, dom);
  124. });
  125. unit.add("isLastChildInBlockNode", function() {
  126. var dom = fragment(
  127. element("p", element("br")),
  128. element("p", "foobar", element("br"), "foobar"),
  129. element("p", element("b", "foobar", element("br"))),
  130. element("p", element("b", "foobar"), element("br")),
  131. element("br"));
  132. var count = 0;
  133. function assert(expected, node) {
  134. this.assertEqual(expected, instance.isLastChildInBlockNode(node), "#" + (count++));
  135. }
  136. assert.call(this, true, dom.childNodes[0].childNodes[0]);
  137. assert.call(this, false, dom.childNodes[1].childNodes[0]);
  138. assert.call(this, false, dom.childNodes[1].childNodes[1]);
  139. assert.call(this, true, dom.childNodes[1].childNodes[2]);
  140. assert.call(this, false, dom.childNodes[2].childNodes[0].childNodes[0]);
  141. assert.call(this, true, dom.childNodes[2].childNodes[0].childNodes[1]);
  142. assert.call(this, false, dom.childNodes[3].childNodes[0].childNodes[0]);
  143. assert.call(this, true, dom.childNodes[3].childNodes[1]);
  144. assert.call(this, true, dom.childNodes[4]);
  145. });
  146. unit.add("code block", function() {
  147. var dom = fragment(
  148. element("p", element("tt", "abc")),
  149. element("pre", { "class": "wiki" }, "{{{code-block"));
  150. var wikitext = [
  151. "`abc`",
  152. "",
  153. "{{{",
  154. "{{{code-block",
  155. "}}}" ].join("\n");
  156. generate.call(this, dom, wikitext);
  157. });
  158. unit.add("code block nest", function() {
  159. var dom = fragment(
  160. element("pre", { "class": "wiki" }, "#!python\n= level 1\n{{{\n= level 2\n}}}\n= level 1"));
  161. var wikitext = [
  162. "{{{",
  163. "#!python",
  164. "= level 1",
  165. "{{{",
  166. "= level 2",
  167. "}}}",
  168. "= level 1",
  169. "}}}" ].join("\n");
  170. generate.call(this, dom, wikitext);
  171. });
  172. unit.add("paragraph", function() {
  173. var dom = fragment(
  174. element("p", "Paragraph continued..."),
  175. element("p", "Second paragraph continued..."));
  176. generateFragment.call(this, dom, [
  177. "Paragraph",
  178. "continued...",
  179. "",
  180. "Second paragraph",
  181. "continued...",
  182. "" ].join("\n"));
  183. generate.call(this, dom, [
  184. "Paragraph continued...",
  185. "",
  186. "Second paragraph continued..." ].join("\n"));
  187. });
  188. unit.add("hr", function() {
  189. var dom = fragment(
  190. element("p", "Paragraph"),
  191. element("hr"),
  192. element("ul",
  193. element("li", "item 1"),
  194. element("ol", element("li", "item 1.1"))),
  195. element("hr"));
  196. generateFragment.call(this, dom, [
  197. "Paragraph",
  198. "----",
  199. " * item 1",
  200. " 1. item 1.1",
  201. "----" ].join("\n"));
  202. generate.call(this, dom, [
  203. "Paragraph",
  204. "",
  205. "----",
  206. " * item 1",
  207. " 1. item 1.1",
  208. "",
  209. "----" ].join("\n"));
  210. });
  211. unit.add("bold italic", function() {
  212. var dom = element("p", element("b", element("i", "bold italic")));
  213. var wikitext = "'''''bold italic'''''";
  214. generate.call(this, dom, wikitext);
  215. });
  216. unit.add("bold", function() {
  217. var wikitext = [
  218. "The quick '''brown''' fox.",
  219. "",
  220. "The quick '''brown''' fox." ].join("\n");
  221. generateWikitext.call(this,
  222. fragment(
  223. element("p", "The quick ", element("b", "brown"), " fox."),
  224. element("p", "The quick ", element("strong", "brown"), " fox.")),
  225. wikitext);
  226. generateFragment.call(this,
  227. fragment(
  228. element("p", "The quick ", element("b", "brown"), " fox."),
  229. element("p", "The quick ", element("b", "brown"), " fox.")),
  230. wikitext);
  231. });
  232. unit.add("italic", function() {
  233. var wikitext = [
  234. "The quick ''brown'' fox.",
  235. "",
  236. "The quick ''brown'' fox." ].join("\n");
  237. generateWikitext.call(this,
  238. fragment(
  239. element("p", "The quick ", element("i", "brown"), " fox."),
  240. element("p", "The quick ", element("em", "brown"), " fox.")),
  241. wikitext);
  242. generateFragment.call(this,
  243. fragment(
  244. element("p", "The quick ", element("i", "brown"), " fox."),
  245. element("p", "The quick ", element("i", "brown"), " fox.")),
  246. wikitext);
  247. });
  248. unit.add("underline", function() {
  249. var dom = element("p", element("u", "underline"));
  250. var wikitext = "__underline__";
  251. generate.call(this, dom, wikitext);
  252. });
  253. unit.add("strike-through", function() {
  254. var dom = element("p", element("del", "strike-through"));
  255. var wikitext = "~~strike-through~~";
  256. generate.call(this, dom, wikitext);
  257. });
  258. unit.add("superscript", function() {
  259. var dom = element("p", element("sup", "superscript"));
  260. var wikitext = "^superscript^";
  261. generate.call(this, dom, wikitext);
  262. });
  263. unit.add("subscript", function() {
  264. var dom = element("p", element("sub", "subscript"));
  265. var wikitext = ",,subscript,,";
  266. generate.call(this, dom, wikitext);
  267. });
  268. unit.add("monospace", function() {
  269. var dom = element("p", element("tt", "monospace"),
  270. ", ", element("tt", "mono`s`pace"),
  271. ", ", element("tt", "mono{{{s}}}pace"));
  272. var wikitext = "`monospace`, {{{mono`s`pace}}}, `mono{{{s}}}pace`";
  273. generate.call(this, dom, wikitext);
  274. });
  275. unit.add("italic -> bold", function() {
  276. var dom = element("p",
  277. "normal",
  278. element("i", "italic"),
  279. element("b", "bold"),
  280. "normal");
  281. var wikitext = "normal''italic'''''bold'''normal";
  282. generate.call(this, dom, wikitext);
  283. });
  284. unit.add("bold -> italic", function() {
  285. var dom = element("p",
  286. "normal",
  287. element("b", "bold"),
  288. element("i", "italic"),
  289. "normal");
  290. var wikitext = "normal'''bold'''''italic''normal";
  291. generate.call(this, dom, wikitext);
  292. });
  293. unit.add("[ italic [ xyz ] bold ]", function() {
  294. var dom = element("p",
  295. "normal",
  296. element("i", "italic", element("b", "xyz")),
  297. element("b", "bold"),
  298. "normal");
  299. var wikitext = "normal''italic'''xyz''bold'''normal";
  300. generate.call(this, dom, wikitext);
  301. });
  302. unit.add("overlapped markups", function() {
  303. var dom = element("p",
  304. "normal",
  305. element("b", "bold",
  306. element("i", "italic",
  307. element("u", "underline",
  308. element("del", "strike-through",
  309. element("sup", "superscript",
  310. element("sub", "subscript"))))),
  311. element("u", element("del", element("sup", element("sub", "i")))),
  312. element("del", element("sup", element("sub", "u"))),
  313. element("sup", element("sub", "strike")),
  314. element("sub", "sup"),
  315. "sub"),
  316. ".");
  317. var wikitext = "normal'''bold''italic__underline~~strike-through^superscript,,subscript''i__u~~strike^sup,,sub'''.";
  318. generateFragment.call(this, dom, wikitext);
  319. });
  320. unit.add("! bold italic", function() {
  321. var dom = element("p", element("b", element("i", "bold''''' italic")), ".");
  322. var wikitext = "'''''bold!''''' italic'''''.";
  323. generate.call(this, dom, wikitext);
  324. });
  325. unit.add("! bold", function() {
  326. var dom = element("p", element("b", "bold''' bold"), ".");
  327. var wikitext = "'''bold!''' bold'''.";
  328. generate.call(this, dom, wikitext);
  329. });
  330. unit.add("! italic", function() {
  331. var dom = element("p", element("i", "italic'' italic"), ".");
  332. var wikitext = "''italic!'' italic''.";
  333. generate.call(this, dom, wikitext);
  334. });
  335. unit.add("! underline", function() {
  336. var dom = element("p", element("u", "underline__ underline"), ".");
  337. var wikitext = "__underline!__ underline__.";
  338. generate.call(this, dom, wikitext);
  339. });
  340. unit.add("! strike-through", function() {
  341. var dom = element("p", element("del", "strike~~through"), ".");
  342. var wikitext = "~~strike!~~through~~.";
  343. generate.call(this, dom, wikitext);
  344. });
  345. unit.add("! superscript", function() {
  346. var dom = element("p", element("sup", "superscript^ superscript"), ".");
  347. var wikitext = "^superscript!^ superscript^.";
  348. generate.call(this, dom, wikitext);
  349. });
  350. unit.add("! subscript", function() {
  351. var dom = element("p", element("sub", "subscript,, subscript"), ".");
  352. var wikitext = ",,subscript!,, subscript,,.";
  353. generate.call(this, dom, wikitext);
  354. });
  355. unit.add("! monospace", function() {
  356. var dom = element("p", "{{{monospace}}} or `monospace`");
  357. var wikitext = "!{{{monospace}}} or !`monospace`";
  358. generate.call(this, dom, wikitext);
  359. });
  360. unit.add("!||, !=||", function() {
  361. var dom = fragment(
  362. element("p", "Paragraph"),
  363. element("table", { "class": "wiki" },
  364. element("tbody",
  365. element("tr", element("td", "foo||bar!||||==||foobar")))),
  366. element("p", "||||cell=||= =||||=cell|| Paragraph"));
  367. generateFragment.call(this, dom, [
  368. "Paragraph",
  369. "||foo!||bar!!||||=!=||foobar",
  370. "!||||cell!=||=",
  371. "!=||||=cell!||",
  372. "Paragraph" ].join("\n"));
  373. generate.call(this, dom, [
  374. "Paragraph",
  375. "",
  376. "|| foo!||bar!!||||=!=||foobar ||",
  377. "",
  378. "!||||cell!=||= !=||||=cell!|| Paragraph" ].join("\n"));
  379. });
  380. unit.add("#ticket", function() {
  381. var dom = element("p",
  382. element("a", "#1234", {
  383. href: "./search?q=ticket%3A1234", title: "ticket:1234",
  384. "tracwysiwyg-link": "ticket:1234", onclick: "return false;" }),
  385. " #2345 &#3456");
  386. var wikitext = "#1234 !#2345 &#3456";
  387. generate.call(this, dom, wikitext);
  388. });
  389. unit.add("{report}", function() {
  390. var dom = element("p",
  391. "{987}",
  392. element("a", "{123}", {
  393. href: "./search?q=report%3A123", title: "report:123",
  394. "tracwysiwyg-link": "report:123", onclick: "return false;" }));
  395. var wikitext = "!{987}{123}";
  396. generate.call(this, dom, wikitext);
  397. });
  398. unit.add("[changeset]", function() {
  399. var dom = element("p",
  400. element("a", "[123]", {
  401. href: "./search?q=changeset%3A123", title: "changeset:123",
  402. "tracwysiwyg-link": "changeset:123", onclick: "return false;" }),
  403. ", ",
  404. element("a", "r234", {
  405. href: "./search?q=changeset%3A234", title: "changeset:234",
  406. "tracwysiwyg-link": "changeset:234", onclick: "return false;" }),
  407. ", ",
  408. element("a", "[345/trunk]", {
  409. href: "./search?q=changeset%3A345%2Ftrunk", title: "changeset:345/trunk",
  410. "tracwysiwyg-link": "changeset:345/trunk", onclick: "return false;" }),
  411. ", [123], r234, [345/trunk], ar123");
  412. generate.call(this, dom, "[123], r234, [345/trunk], ![123], !r234, ![345/trunk], ar123");
  413. });
  414. unit.add("[log]", function() {
  415. var dom = element("p",
  416. "log - ",
  417. element("a", "r1:3", {
  418. href: "./search?q=log%3A%401%3A3", title: "log:@1:3",
  419. "tracwysiwyg-link": "log:@1:3", onclick: "return false;" }),
  420. ", r1:3, ",
  421. element("a", "[1:3]", {
  422. href: "./search?q=log%3A%401%3A3", title: "log:@1:3",
  423. "tracwysiwyg-link": "log:@1:3", onclick: "return false;" }),
  424. ", [1:3], ",
  425. element("a", "log:@1:3", {
  426. href: "./search?q=log%3A%401%3A3", title: "log:@1:3",
  427. "tracwysiwyg-link": "log:@1:3", onclick: "return false;" }),
  428. ", log:@1:3, ",
  429. element("a", "log:trunk@1:3", {
  430. href: "./search?q=log%3Atrunk%401%3A3", title: "log:trunk@1:3",
  431. "tracwysiwyg-link": "log:trunk@1:3", onclick: "return false;" }),
  432. ", log:trunk@1:3");
  433. generate.call(this, dom, "log - r1:3, !r1:3, [1:3], ![1:3], log:@1:3, !log:@1:3, log:trunk@1:3, !log:trunk@1:3");
  434. });
  435. unit.add("wiki:TracLinks", function() {
  436. var dom = element("p",
  437. element("a", "link:WikiName", {
  438. href: "./search?q=link%3AWikiName", title: "link:WikiName",
  439. "tracwysiwyg-link": "link:WikiName", onclick: "return false;" }),
  440. " ",
  441. element("a", 'link:"Foo Bar"', {
  442. href: "./search?q=link%3A%22Foo%20Bar%22", title: 'link:"Foo Bar"',
  443. "tracwysiwyg-link": 'link:"Foo Bar"', onclick: "return false;" }),
  444. " ",
  445. element("a", 'link:"Foo Bar#baz"', {
  446. href: "./search?q=link%3A%22Foo%20Bar%23baz%22", title: 'link:"Foo Bar#baz"',
  447. "tracwysiwyg-link": 'link:"Foo Bar#baz"', onclick: "return false;" }),
  448. " ",
  449. element("a", "link:'Foo Bar'", {
  450. href: "./search?q=" + encodeURIComponent("link:'Foo Bar'"),
  451. title: "link:'Foo Bar'", "tracwysiwyg-link": "link:'Foo Bar'",
  452. onclick: "return false;" }),
  453. " ",
  454. element("a", "link:'Foo Bar#baz'", {
  455. href: "./search?q=" + encodeURIComponent("link:'Foo Bar#baz'"),
  456. title: "link:'Foo Bar#baz'", "tracwysiwyg-link": "link:'Foo Bar#baz'",
  457. onclick: "return false;" }),
  458. " ",
  459. element("a", "svn+ssh://example.com/trunk", {
  460. href: "./search?q=" + encodeURIComponent("svn+ssh://example.com/trunk"),
  461. title: "svn+ssh://example.com/trunk", "tracwysiwyg-link": "svn+ssh://example.com/trunk",
  462. onclick: "return false;" }),
  463. " ",
  464. element("a", "repository", {
  465. href: "./search?q=" + encodeURIComponent("svn+ssh://example.com/trunk"),
  466. title: "svn+ssh://example.com/trunk", "tracwysiwyg-link": "svn+ssh://example.com/trunk",
  467. onclick: "return false;" }),
  468. " ",
  469. element("a", "rfc-2396.compatible://link", {
  470. href: "./search?q=" + encodeURIComponent("rfc-2396.compatible://link"),
  471. title: "rfc-2396.compatible://link", "tracwysiwyg-link": "rfc-2396.compatible://link",
  472. onclick: "return false;" }),
  473. " ",
  474. element("a", "RFC 2396", {
  475. href: "./search?q=" + encodeURIComponent("rfc-2396.compatible://link"),
  476. title: "rfc-2396.compatible://link", "tracwysiwyg-link": "rfc-2396.compatible://link",
  477. onclick: "return false;" }),
  478. " ",
  479. "21:09,",
  480. element("u", "underline"),
  481. ",abc123 !21:09,",
  482. element("u", "underline"),
  483. ",abc123",
  484. " ",
  485. element("a", "foo:bar", {
  486. href: "./search?q=" + encodeURIComponent("foo:bar"),
  487. title: "foo:bar", "tracwysiwyg-link": "foo:bar",
  488. onclick: "return false;" }),
  489. " begin",
  490. element("a", "foo:bar", {
  491. href: "./search?q=" + encodeURIComponent("foo:bar"),
  492. title: "foo:bar", "tracwysiwyg-link": "foo:bar",
  493. onclick: "return false;" }),
  494. " ",
  495. element("a", "foo:bar", {
  496. href: "./search?q=" + encodeURIComponent("foo:bar"),
  497. title: "foo:bar", "tracwysiwyg-link": "foo:bar",
  498. onclick: "return false;" }),
  499. "end begin",
  500. element("a", "WikiStart", {
  501. href: "./search?q=" + encodeURIComponent("wiki:WikiStart"),
  502. title: "wiki:WikiStart", "tracwysiwyg-link": "wiki:WikiStart",
  503. onclick: "return false;" }),
  504. "end link:'Foo Bar#baz'");
  505. generateFragment.call(this, dom, [
  506. "link:WikiName",
  507. 'link:"Foo Bar" link:"Foo Bar#baz"',
  508. "link:'Foo Bar' link:'Foo Bar#baz'",
  509. "svn+ssh://example.com/trunk [svn+ssh://example.com/trunk repository]",
  510. "rfc-2396.compatible://link [rfc-2396.compatible://link RFC 2396]",
  511. "21:09,__underline__,abc123 !21:09,__underline__,abc123",
  512. "foo:bar begin[foo:bar foo:bar] [foo:bar foo:bar]end begin[wiki:WikiStart]end",
  513. "!link:'Foo Bar#baz'" ].join(" "));
  514. generate.call(this, dom, [
  515. "link:WikiName",
  516. 'link:"Foo Bar" link:"Foo Bar#baz"',
  517. "link:'Foo Bar' link:'Foo Bar#baz'",
  518. "svn+ssh://example.com/trunk [svn+ssh://example.com/trunk repository]",
  519. "rfc-2396.compatible://link [rfc-2396.compatible://link RFC 2396]",
  520. "21:09,__underline__,abc123 !21:09,__underline__,abc123",
  521. "foo:bar begin[foo:bar foo:bar] [foo:bar foo:bar]end begin[wiki:WikiStart]end",
  522. "!link:'Foo Bar#baz'" ].join(" "));
  523. });
  524. unit.add("[wiki:TracLinks label]", function() {
  525. var dom = element("p",
  526. element("a", "WikiName", {
  527. href: "./search?q=link%3AWikiName", title: "link:WikiName",
  528. "tracwysiwyg-link": "link:WikiName", onclick: "return false;" }),
  529. " ",
  530. element("a", "wiki name", {
  531. href: "./search?q=link%3AWikiName", title: "link:WikiName",
  532. "tracwysiwyg-link": "link:WikiName", onclick: "return false;" }),
  533. " ",
  534. element("a", "wiki]name", {
  535. href: "./search?q=wiki%3AWikiName", title: "wiki:WikiName",
  536. "tracwysiwyg-link": "wiki:WikiName", onclick: "return false;" }),
  537. " ",
  538. element("a", "wiki name", {
  539. href: "./search?q=wiki%3AWikiName", title: "wiki:WikiName",
  540. "tracwysiwyg-link": "wiki:WikiName", onclick: "return false;" }),
  541. " ",
  542. element("a", "Foo Bar", {
  543. href: "./search?q=link%3A%22Foo%20Bar%22", title: 'link:"Foo Bar"',
  544. "tracwysiwyg-link": 'link:"Foo Bar"', onclick: "return false;" }),
  545. " ",
  546. element("a", "Foo Bar#baz", {
  547. href: "./search?q=link%3A%22Foo%20Bar%23baz%22", title: 'link:"Foo Bar#baz"',
  548. "tracwysiwyg-link": 'link:"Foo Bar#baz"', onclick: "return false;" }),
  549. " ",
  550. element("a", "bar foo", {
  551. href: "./search?q=link%3A%22Foo%20Bar%22", title: 'link:"Foo Bar"',
  552. "tracwysiwyg-link": 'link:"Foo Bar"', onclick: "return false;" }),
  553. " ",
  554. element("a", 'foo "foobar" bar', {
  555. href: "./search?q=link%3A%22Foo%20Bar%23baz%22", title: 'link:"Foo Bar#baz"',
  556. "tracwysiwyg-link": 'link:"Foo Bar#baz"', onclick: "return false;" }),
  557. " ",
  558. element("a", "Foo Bar", {
  559. href: "./search?q=" + encodeURIComponent("link:'Foo Bar'"),
  560. title: "link:'Foo Bar'", "tracwysiwyg-link": "link:'Foo Bar'",
  561. onclick: "return false;" }),
  562. " ",
  563. element("a", "Foo Bar#baz", {
  564. href: "./search?q=" + encodeURIComponent("link:'Foo Bar#baz'"),
  565. title: "link:'Foo Bar#baz'", "tracwysiwyg-link": "link:'Foo Bar#baz'",
  566. onclick: "return false;" }),
  567. " ",
  568. element("a", "foo bar", {
  569. href: "./search?q=" + encodeURIComponent("link:'Foo Bar'"),
  570. title: "link:'Foo Bar'", "tracwysiwyg-link": "link:'Foo Bar'",
  571. onclick: "return false;" }),
  572. " ",
  573. element("a", "foo 'foobar' bar", {
  574. href: "./search?q=" + encodeURIComponent("link:'Foo Bar#baz'"),
  575. title: "link:'Foo Bar#baz'",
  576. "tracwysiwyg-link": "link:'Foo Bar#baz'",
  577. onclick: "return false;" }),
  578. " [link:'Foo Bar#baz'] [link:'Foo Bar#baz' label]");
  579. generateFragment.call(this, dom, [
  580. "[link:WikiName]",
  581. "[link:WikiName 'wiki name']",
  582. '[wiki:WikiName "wiki]name"]',
  583. "[WikiName 'wiki name']",
  584. '[link:"Foo Bar"] [link:"Foo Bar#baz"]',
  585. '[link:"Foo Bar" "bar foo"] [link:"Foo Bar#baz" foo "foobar" bar]',
  586. "[link:'Foo Bar'] [link:'Foo Bar#baz']",
  587. "[link:'Foo Bar' 'foo bar'] [link:'Foo Bar#baz' foo 'foobar' bar]",
  588. "![link:'Foo Bar#baz'] ![link:'Foo Bar#baz' label]" ].join(" "));
  589. generate.call(this, dom, [
  590. "[link:WikiName]",
  591. "[link:WikiName wiki name]",
  592. '[wiki:WikiName "wiki]name"]',
  593. "[wiki:WikiName wiki name]",
  594. '[link:"Foo Bar" Foo Bar] [link:"Foo Bar#baz" Foo Bar#baz]',
  595. '[link:"Foo Bar" bar foo] [link:"Foo Bar#baz" foo "foobar" bar]',
  596. "[link:'Foo Bar' Foo Bar] [link:'Foo Bar#baz' Foo Bar#baz]",
  597. "[link:'Foo Bar' foo bar] [link:'Foo Bar#baz' foo 'foobar' bar]",
  598. "![link:'Foo Bar#baz'] ![link:'Foo Bar#baz' label]" ].join(" "));
  599. });
  600. unit.add("[/relative label]", function() {
  601. var dom = element("p",
  602. element("a", "Trac", {
  603. href: "../trac", title: "../trac", "tracwysiwyg-link": "../trac",
  604. onclick: "return false;" }),
  605. " ",
  606. element("a", "here", {
  607. href: "/newticket?component=tracwysiwygplugin",
  608. title: "/newticket?component=tracwysiwygplugin",
  609. "tracwysiwyg-link": "/newticket?component=tracwysiwygplugin",
  610. onclick: "return false;" }),
  611. " ",
  612. element("a", "host", {
  613. href: "//hostname", title: "//hostname", "tracwysiwyg-link": "//hostname",
  614. onclick: "return false;" }),
  615. " ",
  616. element("a", "images", {
  617. href: "//hostname/images", title: "//hostname/images",
  618. "tracwysiwyg-link": "//hostname/images", onclick: "return false;" }),
  619. " ",
  620. element("a", "anchor", {
  621. href: "#anchor", title: "#anchor", "tracwysiwyg-link": "#anchor",
  622. onclick: "return false;" }));
  623. var wikitext = [
  624. "[../trac Trac]",
  625. "[/newticket?component=tracwysiwygplugin here]",
  626. "[//hostname host]",
  627. "[//hostname/images images]",
  628. "[#anchor anchor]" ].join(" ");
  629. generate.call(this, dom, wikitext);
  630. });
  631. unit.add("<wiki:bracket links>", function() {
  632. function a(link) {
  633. return element("a", link, {
  634. href: "./search?q=" + encodeURIComponent(link),
  635. title: link, "tracwysiwyg-link": link, onclick: "return false;" });
  636. }
  637. var dom = fragment(
  638. element("p", "<", a("link:1"), ">"),
  639. element("p", "Thing<", a("link:2 and (3)"), ">"),
  640. element("p", "<link:1>"),
  641. element("p", "Thing<link:2 and (3)>"));
  642. var wikitext = [
  643. "<link:1>",
  644. "",
  645. "Thing<link:2 and (3)>",
  646. "",
  647. "!<link:1>",
  648. "",
  649. "Thing!<link:2 and (3)>" ].join("\n");
  650. generate.call(this, dom, wikitext);
  651. });
  652. unit.add("[=#anchor]", function() {
  653. function a(link) {
  654. return element("a", link, {
  655. href: "./search?q=" + encodeURIComponent(link),
  656. title: link, "tracwysiwyg-link": link, onclick: "return false;" });
  657. }
  658. var dom = fragment(
  659. element("p",
  660. "This is the ",
  661. element("span", { "class": "wikianchor", id: "init" }),
  662. " initialization routine: ..."),
  663. element("p",
  664. "Look for ",
  665. element("span", { "class": "wikianchor", id : "extra" },
  666. element("i", "additional explanations")),
  667. " here."),
  668. element("p",
  669. "???",
  670. element("span", { "class": "wikianchor", id: "???" }),
  671. "???????: ..."),
  672. element("p",
  673. element("span", { "class": "wikianchor", id : "??" }, element("i", "????")),
  674. "???????????"));
  675. var wikitext = [
  676. "This is the [=#init] initialization routine: ...",
  677. "",
  678. "Look for [=#extra ''additional explanations''] here.",
  679. "",
  680. "???[=#???]???????: ...",
  681. "",
  682. "[=#?? ''????'']???????????" ].join("\n");
  683. generate.call(this, dom, wikitext);
  684. });
  685. unit.add("[[macro]]", function() {
  686. var dom = element("p",
  687. "Line break ", element("br"), " another line", element("br"),
  688. "last line [[bR]] ![[Br]] [[Macro]] ![[Macro]] [[Image?]] ![[Image?]] [[?]] ![[?]]");
  689. generateFragment.call(this, dom, "Line break [[BR]] another line[[br]]last line ![[bR]] !![[Br]] [[Macro]] ![[Macro]] [[Image?]] ![[Image?]] [[?]] ![[?]]");
  690. generate.call(this, dom, "Line break [[BR]] another line[[BR]]last line ![[bR]] !![[Br]] [[Macro]] ![[Macro]] [[Image?]] ![[Image?]] [[?]] ![[?]]");
  691. });
  692. unit.add("WikiPageName", function() {
  693. var dom = fragment(
  694. element("p",
  695. a("wiki:CamelCase", "CamelCase"),
  696. " CamelCase FooBarA FOo FoobarA OneÅngström Oneångström setTextColor"),
  697. element("p",
  698. a("wiki:WikiStart", "WikiStart"),
  699. " Wiki",
  700. a("wiki:Start", "Start"),
  701. " ",
  702. a("wiki:Wiki", "Wiki"),
  703. "Start Wiki",
  704. a("wiki:Start", "Start"),
  705. "Wiki"));
  706. generate.call(this, dom, [
  707. "CamelCase !CamelCase FooBarA FOo FoobarA OneÅngström Oneångström setTextColor",
  708. "",
  709. "WikiStart Wiki[wiki:Start] [wiki:Wiki]Start Wiki[wiki:Start]Wiki" ].join("\n"));
  710. });
  711. unit.add('["internal free link"]', function() {
  712. var dom = element("p",
  713. "link - ",
  714. element("a", "internal free link", {
  715. href: "./search?q=" + encodeURIComponent('wiki:"internal free link"'),
  716. title: 'wiki:"internal free link"', "tracwysiwyg-link": 'wiki:"internal free link"',
  717. onclick: "return false;" }),
  718. ' - ["free link"]');
  719. generate.call(this, dom, 'link - [wiki:"internal free link" internal free link] - !["free link"]');
  720. });
  721. unit.add("traclink + underline", function() {
  722. var dom = element("p",
  723. element("u", a("ticket:123", "#123")), " ",
  724. a("ticket:123", element("u", "#123")), " ",
  725. element("u", a("report:123", "{123}")), " ",
  726. a("report:123", element("u", "{123}")), " ",
  727. element("u", a("changeset:123", "[123]")), " ",
  728. a("changeset:123", element("u", "[123]")), " ",
  729. element("u", a("changeset:123", "r123")), " ",
  730. a("changeset:123", element("u", "r123")), " ",
  731. element("u", a("log:@123:234", "[123:234]")), " ",
  732. a("log:@123:234", element("u", "[123:234]")), " ",
  733. element("u", a("wiki:WikiStart", "wiki:WikiStart")), " ",
  734. a("wiki:WikiStart", element("u", "wiki:WikiStart")), " ",
  735. element("u", a("wiki:WikiStart", "WikiStart")), " ",
  736. a("wiki:WikiStart", element("u", "WikiStart")));
  737. generateWikitext.call(this, dom, [
  738. '__#123__',
  739. '__#123__',
  740. '__{123}__',
  741. '__{123}__',
  742. '__[123]__',
  743. '__[123]__',
  744. '__[changeset:123 r123]__',
  745. '__[changeset:123 r123]__',
  746. '__[123:234]__',
  747. '__[123:234]__',
  748. '__[wiki:WikiStart wiki:WikiStart]__',
  749. '__[wiki:WikiStart wiki:WikiStart]__',
  750. '__[wiki:WikiStart]__',
  751. '__[wiki:WikiStart]__' ].join(" "));
  752. });
  753. unit.add("token + br", function() {
  754. var dom = fragment(
  755. element("p", "head ", a("http://localhost/", "http://localhost/"), element("br"), "tail"),
  756. element("p", "head http://localhost/", element("br"), "tail"),
  757. element("p", "head ", element("tt", "teletype"), element("br"), "tail"),
  758. element("p", "head ", a("wiki:TracLinks", "TracLinks"), element("br"), "tail"),
  759. element("p",
  760. "head ", a("http://localhost/", "http://localhost/"), " ",
  761. a("wiki:TracLinks", "wiki:TracLinks"),
  762. element("br"),
  763. "tail"),
  764. element("p", "head http://localhost/ wiki:TracLinks", element("br"), "tail"));
  765. generateWikitext.call(this, dom, [
  766. "head http://localhost/ [[BR]]tail",
  767. "",
  768. "head !http://localhost/ [[BR]]tail",
  769. "",
  770. "head `teletype`[[BR]]tail",
  771. "",
  772. "head TracLinks[[BR]]tail",
  773. "",
  774. "head http://localhost/ wiki:TracLinks [[BR]]tail",
  775. "",
  776. "head !http://localhost/ !wiki:TracLinks [[BR]]tail" ].join("\n"));
  777. });
  778. if (window.getSelection) {
  779. unit.add("block + br", function() {
  780. function br() { return element("br"); }
  781. var wikitext = [
  782. "text, br",
  783. "",
  784. "text'', br[[BR]]''",
  785. "",
  786. "|| 1,1[[BR]] || || 1,3 ||",
  787. "|| || 2,2[[BR]][[BR]] ||",
  788. "",
  789. " * list, br[[BR]]",
  790. " * list, br",
  791. " * ",
  792. "",
  793. "text, br[[BR]]" ].join("\n")
  794. generateWikitext.call(this,
  795. fragment(
  796. element("p", "text, br", br()),
  797. element("p", "text", element("i", ", br", br()), br()),
  798. element("table", { "class": "wiki" },
  799. element("tbody",
  800. element("tr",
  801. element("td", "1,1", br(), br()),
  802. element("td", br()),
  803. element("td", "1,3", br())),
  804. element("tr",
  805. element("td", br()),
  806. element("td", "2,2", br(), br(), br())))),
  807. element("ul",
  808. element("li", "list, br", br(), br()),
  809. element("li", "list, br", br()),
  810. element("li")),
  811. element("p", "text, br", br(), br())),
  812. wikitext);
  813. generateFragment.call(this,
  814. fragment(
  815. element("p", "text, br"),
  816. element("p", "text", element("i", ", br", br()), br()),
  817. element("table", { "class": "wiki" },
  818. element("tbody",
  819. element("tr",
  820. element("td", "1,1", br(), br()),
  821. element("td", br()),
  822. element("td", "1,3")),
  823. element("tr",
  824. element("td", br()),
  825. element("td", "2,2", br(), br(), br())))),
  826. element("ul",
  827. element("li", "list, br", br(), br()),
  828. element("li", "list, br"),
  829. element("li", br())),
  830. element("p", "text, br", br(), br())),
  831. wikitext);
  832. });
  833. }
  834. else {
  835. unit.add("block + br", function() {
  836. function br() { return element("br"); }
  837. var wikitext = [
  838. "text, br",
  839. "",
  840. "text'', br[[BR]]''",
  841. "",
  842. "|| 1,1[[BR]] || || 1,3 ||",
  843. "|| || 2,2[[BR]][[BR]] ||",
  844. "",
  845. " * list, br[[BR]]",
  846. " * list, br",
  847. " * ",
  848. "",
  849. "text, br[[BR]]" ].join("\n")
  850. generate.call(this,
  851. fragment(
  852. element("p", "text, br"),
  853. element("p", "text", element("i", ", br", br())),
  854. element("table", { "class": "wiki" },
  855. element("tbody",
  856. element("tr",
  857. element("td", "1,1", br()),
  858. element("td"),
  859. element("td", "1,3")),
  860. element("tr",
  861. element("td"),
  862. element("td", "2,2", br(), br())))),
  863. element("ul",
  864. element("li", "list, br", br()),
  865. element("li", "list, br"),
  866. element("li")),
  867. element("p", "text, br", br())),
  868. wikitext);
  869. });
  870. }
  871. unit.add("citation", function() {
  872. var dom = fragment(
  873. element("blockquote", { "class": "citation" },
  874. element("p", "This is the quoted text continued"),
  875. element("blockquote", { "class": "citation" },
  876. element("p", "a nested quote"),
  877. element("blockquote", { "class": "citation" },
  878. element("p", "a nested-nested quote")))),
  879. element("p", "A comment on the above"),
  880. element("blockquote", { "class": "citation" },
  881. element("blockquote", { "class": "citation" },
  882. element("p", "start 2nd level")),
  883. element("p", "first level")));
  884. generateFragment.call(this, dom, [
  885. "> This is the quoted text",
  886. "> continued",
  887. "> > a nested quote",
  888. "> > > a nested-nested quote",
  889. "A comment on the above",
  890. "> > start 2nd level",
  891. ">first level" ].join("\n"));
  892. generate.call(this, dom, [
  893. "> This is the quoted text continued",
  894. "> > a nested quote",
  895. "> > > a nested-nested quote",
  896. "",
  897. "A comment on the above",
  898. "",
  899. "> > start 2nd level",
  900. "> first level" ].join("\n"));
  901. });
  902. unit.add("header", function() {
  903. var dom = fragment(
  904. element("h1", "Heading 1"),
  905. element("h2", { id: "anchor-2" }, "Heading 2"),
  906. element("h3", element("u", "Heading"), " ", element("i", "3")),
  907. element("h4", { id: "????-4" },
  908. "Heading 4 with ",
  909. element("a", "link", {
  910. href: "./search?q=" + encodeURIComponent('wiki:WikiStart'),
  911. title: 'wiki:WikiStart', "tracwysiwyg-link": 'wiki:WikiStart',
  912. onclick: "return false;" })),
  913. element("h5", "Heading 5"),
  914. element("h6", { id: "anchor-6" }, "Heading 6"));
  915. generate.call(this, dom, [
  916. "= Heading 1 =",
  917. "== Heading 2 == #anchor-2",
  918. "=== __Heading__ ''3'' ===",
  919. "==== Heading 4 with [wiki:WikiStart link] ==== #????-4",
  920. "===== Heading 5 =====",
  921. "====== Heading 6 ====== #anchor-6" ].join("\n"));
  922. });
  923. unit.add("header 2", function() {
  924. var dom = fragment(
  925. element("h1", "Heading 1"),
  926. element("h2", { id: "anchor-2" }, "Heading 2"),
  927. element("h3", element("u", "Heading"), " ", element("i", "3")),
  928. element("h4", { id: "????-4" },
  929. "Heading 4 with ",
  930. element("a", "link", {
  931. href: "./search?q=" + encodeURIComponent('wiki:WikiStart'),
  932. title: 'wiki:WikiStart', "tracwysiwyg-link": 'wiki:WikiStart',
  933. onclick: "return false;" })),
  934. element("h5", "Heading 5"),
  935. element("h6", { id: "anchor-6" }, "Heading 6"));
  936. generateFragment.call(this, dom, [
  937. "= Heading 1 ",
  938. "== Heading 2 #anchor-2",
  939. "=== __Heading__ ''3'' ",
  940. "==== Heading 4 with [wiki:WikiStart link] #????-4",
  941. "===== Heading 5 ",
  942. "====== Heading 6 #anchor-6" ].join("\n"));
  943. });
  944. unit.add("list", function() {
  945. var dom = fragment(
  946. element("p", "Paragraph"),
  947. element("ul",
  948. element("li", "foo bar boo baz"),
  949. element("ul", element("li", "Subitem Subitem line 2")),
  950. element("li", "item 2 item 2 line 2")),
  951. element("p", "Paragraph"));
  952. generateFragment.call(this, dom, [
  953. "Paragraph",
  954. " * foo bar",
  955. " boo baz",
  956. " * Subitem",
  957. " Subitem line 2",
  958. " * item 2",
  959. " item 2 line 2",
  960. "Paragraph" ].join("\n"));
  961. generate.call(this, dom, [
  962. "Paragraph",
  963. "",
  964. " * foo bar boo baz",
  965. " * Subitem Subitem line 2",
  966. " * item 2 item 2 line 2",
  967. "",
  968. "Paragraph" ].join("\n"));
  969. });
  970. unit.add("list 2", function() {
  971. var dom = fragment(
  972. element("ul",
  973. element("li", "foo bar boo baz"),
  974. element("ul",
  975. element("li", "Subitem 1"),
  976. element("ul",
  977. element("li", "nested item 1"),
  978. element("li", "nested item 2 nested item 2 continued")),
  979. element("li", "Subitem 2 subitem 2 continued"),
  980. element("li", "Subitem 3 subitem 3 continued")),
  981. element("li", "item 2 item 2 line 2")),
  982. element("p", "Paragraph"));
  983. generateFragment.call(this, dom, [
  984. " * foo bar",
  985. " boo baz",
  986. " * Subitem 1",
  987. " - nested item 1",
  988. " - nested item 2",
  989. " nested item 2 continued",
  990. " * Subitem 2",
  991. " subitem 2 continued",
  992. " * Subitem 3",
  993. " subitem 3 continued",
  994. " * item 2",
  995. " item 2 line 2",
  996. "Paragraph" ].join("\n"));
  997. generate.call(this, dom, [
  998. " * foo bar boo baz",
  999. " * Subitem 1",
  1000. " * nested item 1",
  1001. " * nested item 2 nested item 2 continued",
  1002. " * Subitem 2 subitem 2 continued",
  1003. " * Subitem 3 subitem 3 continued",
  1004. " * item 2 item 2 line 2",
  1005. "",
  1006. "Paragraph" ].join("\n"));
  1007. });
  1008. unit.add("ordered list", function() {
  1009. var dom = fragment(
  1010. element("p", "Paragraph"),
  1011. element("ol",
  1012. element("li", "item 1"),
  1013. element("ol", { "class": "arabiczero" },
  1014. element("li", "item 1.1"),
  1015. element("li", "item 1.2"),
  1016. element("ol", { "class": "loweralpha" },
  1017. element("li", "item 1.2.a"),
  1018. element("li", "item 1.2.b")),
  1019. element("li", "item 1.3"),
  1020. element("ol", { "class": "loweralpha" },
  1021. element("li", "item 1.3.a"),
  1022. element("li", "item 1.3.b")),
  1023. element("li", "item 1.4"),
  1024. element("ol", { "class": "upperalpha" },
  1025. element("li", "item 1.4.A"),
  1026. element("li", "item 1.4.B"),
  1027. element("li", "item 1.4.C")),
  1028. element("li", "item 1.5"),
  1029. element("ol", { "class": "upperalpha" },
  1030. element("li", "item 1.5.A")),
  1031. element("li", "item 1.6"),
  1032. element("ol", { "class": "lowerroman" },
  1033. element("li", "item 1.6.i"),
  1034. element("li", "item 1.6.ii")),
  1035. element("li", "item 1.7"),
  1036. element("ol", { "class": "upperroman" },
  1037. element("li", "item 1.7.I"),
  1038. element("li", "item 1.7.II")))),
  1039. element("p", "Paragraph"));
  1040. generateFragment.call(this, dom, [
  1041. "Paragraph",
  1042. " 1. item 1",
  1043. " 0. item 1.1",
  1044. " 2. item 1.2",
  1045. " a. item 1.2.a",
  1046. " z. item 1.2.b",
  1047. " a. item 1.3",
  1048. " b. item 1.3.a",
  1049. " y. item 1.3.b",
  1050. " Z. item 1.4",
  1051. " A. item 1.4.A",
  1052. " z. item 1.4.B",
  1053. " z. item 1.4.C",
  1054. " ii. item 1.5",
  1055. " C. item 1.5.A",
  1056. " XVI. item 1.6",
  1057. " i. item 1.6.i",
  1058. " x. item 1.6.ii",
  1059. " 0. item 1.7",
  1060. " I. item 1.7.I",
  1061. " III. item 1.7.II",
  1062. "Paragraph" ].join("\n"));
  1063. generate.call(this, dom, [
  1064. "Paragraph",
  1065. "",
  1066. " 1. item 1",
  1067. " 0. item 1.1",
  1068. " 0. item 1.2",
  1069. " a. item 1.2.a",
  1070. " a. item 1.2.b",
  1071. " 0. item 1.3",
  1072. " a. item 1.3.a",
  1073. " a. item 1.3.b",
  1074. " 0. item 1.4",
  1075. " A. item 1.4.A",
  1076. " A. item 1.4.B",
  1077. " A. item 1.4.C",
  1078. " 0. item 1.5",
  1079. " A. item 1.5.A",
  1080. " 0. item 1.6",
  1081. " i. item 1.6.i",
  1082. " i. item 1.6.ii",
  1083. " 0. item 1.7",
  1084. " I. item 1.7.I",
  1085. " I. item 1.7.II",
  1086. "",
  1087. "Paragraph" ].join("\n"));
  1088. });
  1089. unit.add("list + ordered list", function() {
  1090. var dom = fragment(
  1091. element("ul",
  1092. element("li", "Item 1"),
  1093. element("ul", element("li", "Item 1.1")),
  1094. element("li", "Item 2")),
  1095. element("ol",
  1096. element("li", "Item 1"),
  1097. element("ol", { "class": "loweralpha" },
  1098. element("li", "Item 1.a"),
  1099. element("li", "Item 1.b"),
  1100. element("ol", { "class": "lowerroman" },
  1101. element("li", "Item 1.b.i"),
  1102. element("li", "Item 1.b.ii"))),
  1103. element("li", "Item 2")),
  1104. element("p", "And numbered lists can also be given an explicit number:"),
  1105. element("ol", { start: 3 }, element("li", "Item 3")));
  1106. generateFragment.call(this, dom, [
  1107. " * Item 1",
  1108. " * Item 1.1",
  1109. " * Item 2",
  1110. " 1. Item 1",
  1111. " a. Item 1.a",
  1112. " a. Item 1.b",
  1113. " i. Item 1.b.i",
  1114. " i. Item 1.b.ii",
  1115. " 1. Item 2",
  1116. "And numbered lists can also be given an explicit number:",
  1117. " 3. Item 3" ].join("\n"));
  1118. generate.call(this, dom, [
  1119. " * Item 1",
  1120. " * Item 1.1",
  1121. " * Item 2",
  1122. "",
  1123. " 1. Item 1",
  1124. " a. Item 1.a",
  1125. " a. Item 1.b",
  1126. " i. Item 1.b.i",
  1127. " i. Item 1.b.ii",
  1128. " 1. Item 2",
  1129. "",
  1130. "And numbered lists can also be given an explicit number:",
  1131. "",
  1132. " 3. Item 3" ].join("\n"));
  1133. });
  1134. unit.add("list at beginning of line", function() {
  1135. var dom = fragment(
  1136. element("ul",
  1137. element("li", "item 1"),
  1138. element("li", "item 2"),
  1139. element("ul", element("li", "sub 2.1"), element("li", "sub 2.2"))),
  1140. element("ol", { "class": "loweralpha" },
  1141. element("li", "item A"), element("li", "item B")),
  1142. element("p", "Paragraph"));
  1143. generateFragment.call(this, dom, [
  1144. "- item 1",
  1145. "- item 2",
  1146. " - sub 2.1",
  1147. " - sub 2.2",
  1148. "a. item A",
  1149. "b. item B",
  1150. "Paragraph" ].join("\n"));
  1151. generate.call(this, dom, [
  1152. " * item 1",
  1153. " * item 2",
  1154. " * sub 2.1",
  1155. " * sub 2.2",
  1156. "",
  1157. " a. item A",
  1158. " a. item B",
  1159. "",
  1160. "Paragraph" ].join("\n"));
  1161. });
  1162. unit.add("list + code block", function() {
  1163. var dom = fragment(
  1164. element("p", "Paragraph"),
  1165. element("ul",
  1166. element("li",
  1167. "item 1",
  1168. element("pre", { "class": "wiki" }, "code")),
  1169. element("ul",
  1170. element("li",
  1171. "item 1.1",
  1172. element("pre", { "class": "wiki" }, "code"),
  1173. "cont.",
  1174. element("pre", { "class": "wiki" }, "code"))),
  1175. element("li",
  1176. "item 2",
  1177. element("pre", { "class": "wiki" }, "code"))),
  1178. element("ol", element("li", "item 1")));
  1179. generateFragment.call(this, dom, [
  1180. "Paragraph",
  1181. " * item 1",
  1182. "{{{",
  1183. "code",
  1184. "}}}",
  1185. " * item 1.1",
  1186. "{{{",
  1187. "code",
  1188. "}}}",
  1189. " cont.",
  1190. "{{{",
  1191. "code",
  1192. "}}}",
  1193. " * item 2",
  1194. "{{{",
  1195. "code",
  1196. "}}}",
  1197. " 1. item 1" ].join("\n"));
  1198. generate.call(this, dom, [
  1199. "Paragraph",
  1200. "",
  1201. " * item 1",
  1202. "{{{",
  1203. "code",
  1204. "}}}",
  1205. " * item 1.1",
  1206. "{{{",
  1207. "code",
  1208. "}}}",
  1209. " cont.",
  1210. "{{{",
  1211. "code",
  1212. "}}}",
  1213. " * item 2",
  1214. "{{{",
  1215. "code",
  1216. "}}}",
  1217. "",
  1218. " 1. item 1" ].join("\n"));
  1219. });
  1220. unit.add("list + citation", function() {
  1221. var dom = fragment(
  1222. element('ol', element('li', 'item 1')),
  1223. element('blockquote', { 'class': 'citation' }, element("p", "citation 1")),
  1224. element('ul',
  1225. element('li', 'item 2'),
  1226. element("ol",
  1227. element('li', 'item 2.1'),
  1228. element('li', 'item 2.2'))),
  1229. element('blockquote', { 'class': 'citation' }, element("p", "citation 2 citation 3")),
  1230. element('ol', element('li', 'item 3')));
  1231. generateFragment.call(this, dom, [
  1232. ' 1. item 1',
  1233. '> citation 1',
  1234. ' * item 2',
  1235. ' 1. item 2.1',
  1236. ' 1. item 2.2',
  1237. '> citation 2',
  1238. '> citation 3',
  1239. ' 1. item 3' ].join("\n"));
  1240. generateWikitext.call(this, dom, [
  1241. ' 1. item 1',
  1242. '',
  1243. '> citation 1',
  1244. '',
  1245. ' * item 2',
  1246. ' 1. item 2.1',
  1247. ' 1. item 2.2',
  1248. '',
  1249. '> citation 2 citation 3',
  1250. '',
  1251. ' 1. item 3' ].join("\n"));
  1252. });
  1253. unit.add("definition", function() {
  1254. var dom = element("dl",
  1255. element("dt", "python"),
  1256. element("dd", "www.python.org :: cont."),
  1257. element("dt", element("b", "trac")),
  1258. element("dd",
  1259. element("b", "trac"), ".edgewall.org cont.",
  1260. " ", element("tt", "trac-hacks::"), " trac-hacks.org"));
  1261. generateFragment.call(this, dom, [
  1262. " python:: www.python.org :: cont.",
  1263. " '''trac''':: '''trac'''.edgewall.org",
  1264. " cont.",
  1265. " `trac-hacks::` trac-hacks.org" ].join("\n"));
  1266. generate.call(this, dom, [
  1267. " python:: www.python.org :: cont.",
  1268. " '''trac''':: '''trac'''.edgewall.org cont. `trac-hacks::` trac-hacks.org" ].join("\n"));
  1269. });
  1270. unit.add("blockquote", function() {
  1271. var dom = fragment(
  1272. element("p", "Paragraph"),
  1273. element("blockquote",
  1274. element("p", "blockquote 1 cont. 1"),
  1275. element("blockquote",
  1276. element("p", "blockquote 1.1"),
  1277. element("blockquote", element("p", "blockquote 1.1.1 cont. 1.1.1")),
  1278. element("p", "blockquote 1.2")),
  1279. element("p", "blockquote 2")),
  1280. element("p", "Paragraph"));
  1281. generateFragment.call(this, dom, [
  1282. "Paragraph",
  1283. " blockquote 1",
  1284. " cont. 1",
  1285. " blockquote 1.1",
  1286. " blockquote 1.1.1",
  1287. " cont. 1.1.1",
  1288. " blockquote 1.2",
  1289. " blockquote 2",
  1290. "Paragraph" ].join("\n"));
  1291. generate.call(this, dom, [
  1292. "Paragraph",
  1293. "",
  1294. " blockquote 1 cont. 1",
  1295. " blockquote 1.1",
  1296. " blockquote 1.1.1 cont. 1.1.1",
  1297. " blockquote 1.2",
  1298. " blockquote 2",
  1299. "",
  1300. "Paragraph" ].join("\n"));
  1301. });
  1302. unit.add("table", function() {
  1303. var dom = fragment(
  1304. element("p", "Paragraph"),
  1305. element("table", { "class": "wiki" },
  1306. element("tbody",
  1307. element("tr", element("td", "1.1"), element("td", "1.2")),
  1308. element("tr", element("td", "2.1")),
  1309. element("tr",
  1310. element("td", "3.1"),
  1311. element("td", element("u", "3.2")),
  1312. element("td", element("tt", "3"), " ", element("tt", "-"))))),
  1313. element("p", "Paragraph"));
  1314. generateFragment.call(this, dom, [
  1315. "Paragraph",
  1316. "||1.1||1.2||",
  1317. "||2.1",
  1318. "||3.1||__3.2__||`3` `-`",
  1319. "Paragraph" ].join("\n"));
  1320. generate.call(this, dom, [
  1321. "Paragraph",
  1322. "",
  1323. "|| 1.1 || 1.2 ||",
  1324. "|| 2.1 ||",
  1325. "|| 3.1 || __3.2__ || `3` `-` ||",
  1326. "",
  1327. "Paragraph" ].join("\n"));
  1328. });
  1329. unit.add("colspan", function() {
  1330. var dom = fragment(
  1331. element("p", "Paragraph"),
  1332. element("table", { "class": "wiki" },
  1333. element("tbody",
  1334. element("tr", element("td", "1.1"), element("td", "1.2", { colSpan: 2 })),
  1335. element("tr", element("td", "2.1", { colSpan: 3 })),
  1336. element("tr",
  1337. element("td", "3.1"),
  1338. element("td", element("u", "3.2")),
  1339. element("td", element("tt", "3.3"))))),
  1340. element("p", "Paragraph"));
  1341. generateFragment.call(this, dom, [
  1342. "Paragraph",
  1343. "||1.1||||1.2",
  1344. "||||||2.1",
  1345. "||3.1||__3.2__||`3.3`",
  1346. "Paragraph" ].join("\n"));
  1347. generate.call(this, dom, [
  1348. "Paragraph",
  1349. "",
  1350. "|| 1.1 |||| 1.2 ||",
  1351. "|||||| 2.1 ||",
  1352. "|| 3.1 || __3.2__ || `3.3` ||",
  1353. "",
  1354. "Paragraph" ].join("\n"));
  1355. });
  1356. unit.add("table header", function() {
  1357. var dom = fragment(
  1358. element("p", "Paragraph"),
  1359. element("table", { "class": "wiki" },
  1360. element("tbody",
  1361. element("tr", element("th", "1.1"), element("td", "1.2", { colSpan: 2 })),
  1362. element("tr", element("th", "2.1", { colSpan: 3 })),
  1363. element("tr",
  1364. element("td", "3.1"),
  1365. element("th", element("u", "3.2")),
  1366. element("td", element("tt", "3.3"))))),
  1367. element("p", "Paragraph"));
  1368. generateFragment.call(this, dom, [
  1369. "Paragraph",
  1370. "||=1.1=||||1.2",
  1371. "||||||=2.1=||",
  1372. "||3.1||=__3.2__=||`3.3`",
  1373. "Paragraph" ].join("\n"));
  1374. generate.call(this, dom, [
  1375. "Paragraph",
  1376. "",
  1377. "||= 1.1 =|||| 1.2 ||",
  1378. "||||||= 2.1 =||",
  1379. "|| 3.1 ||= __3.2__ =|| `3.3` ||",
  1380. "",
  1381. "Paragraph" ].join("\n"));
  1382. });
  1383. unit.add("table with alignment", function() {
  1384. var dom = fragment(
  1385. element("p", "Paragraph"),
  1386. element("table", { "class": "wiki" },
  1387. element("tbody",
  1388. element("tr", element("th", "1.1"),
  1389. element("td", "1.2", { colSpan: 2, align: "right" })),
  1390. element("tr", element("th", "2.1", { colSpan: 3, align: "left" })),
  1391. element("tr",
  1392. element("td", "3||1", { align: "right" }),
  1393. element("th", element("u", "3.2")),
  1394. element("td", element("tt", "3.3"), { align: "left" })),
  1395. element("tr",
  1396. element("th", "4.1", { align: "center" }),
  1397. element("td", "4.2"),
  1398. element("td", "4.3", { align: "center" })))),
  1399. element("p", "Paragraph"));
  1400. generateFragment.call(this, dom, [
  1401. "Paragraph",
  1402. "||=1.1=|||| 1.2",
  1403. "||||||=2.1 =||",
  1404. "|| 3!||1||= __3.2__ =||`3.3` ||",
  1405. "||= 4.1 =|| 4.2 || 4.3 ||",
  1406. "Paragraph" ].join("\n"));
  1407. generate.call(this, dom, [
  1408. "Paragraph",
  1409. "",
  1410. "||= 1.1 =|||| 1.2||",
  1411. "||||||=2.1 =||",
  1412. "|| 3!||1||= __3.2__ =||`3.3` ||",
  1413. "||= 4.1 =|| 4.2 || 4.3 ||",
  1414. "",
  1415. "Paragraph" ].join("\n"));
  1416. });
  1417. unit.add("table with row continuation", function() {
  1418. var dom = fragment(
  1419. element("p", "Paragraph"),
  1420. element("table", { "class": "wiki" },
  1421. element("tbody",
  1422. element("tr", element("td", "1.1"), element("td", "1.2"), element("td", "1.3")),
  1423. element("tr", element("td", "2.1")),
  1424. element("tr",
  1425. element("td", "3.1"),
  1426. element("td", element("u", "3.2")),
  1427. element("td", element("tt", "3.3"))))),
  1428. element("p", "Paragraph"));
  1429. generateFragment.call(this, dom, [
  1430. "Paragraph",
  1431. "||1.1||1.2|| \\",
  1432. "||1.3",
  1433. "||2.1",
  1434. "||3.1||__3.2__||`3.3`||\\",
  1435. "Paragraph" ].join("\n"));
  1436. });
  1437. unit.add("table + rule", function() {
  1438. var dom = fragment(
  1439. element("table", { "class": "wiki" },
  1440. element("tbody", element("tr", element("td", "1st")))),
  1441. element("p", element("b", "bold")),
  1442. element("table", { "class": "wiki" },
  1443. element("tbody", element("tr", element("td", "2nd")))),
  1444. element("p", "'''normal"));
  1445. generateFragment.call(this, dom, [
  1446. "||1st||",
  1447. "'''bold'''",
  1448. "||2nd||",
  1449. "!'''normal" ].join("\n"));
  1450. generate.call(this, dom, [
  1451. "|| 1st ||",
  1452. "",
  1453. "'''bold'''",
  1454. "",
  1455. "|| 2nd ||",
  1456. "",
  1457. "!'''normal" ].join("\n"));
  1458. });
  1459. unit.add("blockquote + table", function() {
  1460. var dom = fragment(
  1461. element("p", "Paragraph"),
  1462. element("table", { "class": "wiki" },
  1463. element("tbody",
  1464. element("tr", element("td", "pre.1"), element("td", "pre.2")))),
  1465. element("blockquote",
  1466. element("table", { "class": "wiki" },
  1467. element("tbody",
  1468. element("tr", element("td", "1.1"), element("td", "1.2")),
  1469. element("tr", element("td", "2.1")))),
  1470. element("blockquote",
  1471. element("table", { "class": "wiki" },
  1472. element("tbody",
  1473. element("tr", element("td", "deep"))))),
  1474. element("table", { "class": "wiki" },
  1475. element("tbody",
  1476. element("tr",
  1477. element("td", "3.1"),
  1478. element("td", element("u", "3.2")),
  1479. element("td", element("tt", "3.3")))))),
  1480. element("table", { "class": "wiki" },
  1481. element("tbody",
  1482. element("tr", element("td", "post.1"), element("td", "post.2")))),
  1483. element("p", "Paragraph"));
  1484. generateFragment.call(this, dom, [
  1485. "Paragraph",
  1486. "||pre.1||pre.2||",
  1487. " ||1.1||1.2||",
  1488. " ||2.1",
  1489. " ||deep||",
  1490. " ||3.1||__3.2__||`3.3`",
  1491. "||post.1||post.2||",
  1492. "Paragraph" ].join("\n"));
  1493. generate.call(this, dom, [
  1494. "Paragraph",
  1495. "",
  1496. "|| pre.1 || pre.2 ||",
  1497. "",
  1498. " || 1.1 || 1.2 ||",
  1499. " || 2.1 ||",
  1500. " || deep ||",
  1501. " || 3.1 || __3.2__ || `3.3` ||",
  1502. "",
  1503. "|| post.1 || post.2 ||",
  1504. "",
  1505. "Paragraph" ].join("\n"));
  1506. });
  1507. unit.add("table [ paragraph, ul ]", function() {
  1508. var dom = fragment(
  1509. element("table", { "class": "wiki" },
  1510. element("tbody",
  1511. element("tr",
  1512. element("td", element("p", "1.1")),
  1513. element("td",
  1514. element("ul",
  1515. element("li", "item 1"),
  1516. element("li", "item 2")))),
  1517. element("tr",
  1518. element("td",
  1519. element("p", "2.1"),
  1520. element("ul",
  1521. element("li", "item 3"),
  1522. element("li", "item 4")))))));
  1523. generateWikitext.call(this, dom, [
  1524. "|| 1.1 || * item 1[[BR]] * item 2 ||",
  1525. "|| 2.1[[BR]][[BR]] * item 3[[BR]] * item 4 ||" ].join("\n"));
  1526. });
  1527. unit.add("table from word", function() {
  1528. var dom = element("div");
  1529. dom.innerHTML = [
  1530. '',
  1531. '<table class="MsoTableGrid" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">',
  1532. ' <tbody><tr style="">',
  1533. ' <td style="border: 1pt solid windowtext; padding: 0mm 5.4pt; width: 217.55pt;" valign="top" width="290">',
  1534. ' <p class="MsoNormal"><span lang="EN-US">a<o:p></o:p></span></p>',
  1535. ' <p class="MsoNormal"><span lang="EN-US">b<o:p></o:p></span></p>',
  1536. ' </td>',
  1537. ' <td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0mm 5.4pt; width: 217.55pt;" valign="top" width="290">',
  1538. '',
  1539. ' <p class="MsoNormal"><span lang="EN-US">b<o:p></o:p></span></p>',
  1540. ' </td>',
  1541. ' </tr>',
  1542. ' <tr style="">',
  1543. ' <td style="border-style: none solid solid; border-color: -moz-use-text-color windowtext windowtext; border-width: medium 1pt 1pt; padding: 0mm 5.4pt; width: 217.55pt;" valign="top" width="290">',
  1544. ' <p class="MsoNormal"><span lang="EN-US">c<o:p></o:p></span></p>',
  1545. ' </td>',
  1546. ' <td style="border-style: none solid solid none; border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0mm 5.4pt; width: 217.55pt;" valign="top" width="290">',
  1547. '',
  1548. ' <p class="MsoNormal"><span lang="EN-US">d<o:p></o:p></span></p>',
  1549. ' </td>',
  1550. ' </tr>',
  1551. '</tbody></table>',
  1552. '' ].join("\n");
  1553. generateWikitext.call(this, dom, [
  1554. "|| a[[BR]][[BR]]b || b ||",
  1555. "|| c || d ||" ].join("\n"));
  1556. });
  1557. unit.add("domToWikitext for code block", function() {
  1558. var br = function() { return element("br") };
  1559. var dom = fragment(
  1560. element("h1", "Heading", br(), "1"),
  1561. element("h2", "Heading", br(), "2"),
  1562. element("h3", "Heading", br(), "3"),
  1563. element("h4", "Heading", br(), "4"),
  1564. element("h5", "Heading", br(), "5"),
  1565. element("h6", "Heading", br(), "6"),
  1566. element("p",
  1567. "var TracWysiwyg = function(textarea) {", br(),
  1568. "...", br(),
  1569. "}"),
  1570. element("blockquote", { "class": "citation" }, element("p", "citation", br(), "continued")),
  1571. element("blockquote", element("p", "quote", br(), "continued")),
  1572. element("ul",
  1573. element("li", "item 1", br(), "continued"),
  1574. element("ol", element("li", "item", br(), "1.1"))),
  1575. element("dl",
  1576. element("dt", "def to_s(", br(), ")"),
  1577. element("dd", "dt", br(), "dd")),
  1578. element("table",
  1579. element("tbody",
  1580. element("tr",
  1581. element("td", "cell", br(), "1"),
  1582. element("th", "cell", br(), "2")))));
  1583. var wikitext = instance.domToWikitext(dom, { formatCodeBlock: true });
  1584. this.assertEqual([
  1585. "= Heading 1 =",
  1586. "== Heading 2 ==",
  1587. "=== Heading 3 ===",
  1588. "==== Heading 4 ====",
  1589. "===== Heading 5 =====",
  1590. "====== Heading 6 ======",
  1591. "var TracWysiwyg = function(textarea) {",
  1592. "...",
  1593. "}",
  1594. "",
  1595. "> citation",
  1596. "> continued",
  1597. "",
  1598. " quote",
  1599. " continued",
  1600. "",
  1601. " * item 1",
  1602. " continued",
  1603. " 1. item",
  1604. " 1.1",
  1605. "",
  1606. " def to_s( ):: dt",
  1607. " dd",
  1608. "",
  1609. "|| cell[[BR]]1 ||= cell[[BR]]2 =||" ].join("\n"), wikitext);
  1610. });
  1611. unit.add("escape newlines", function() {
  1612. var dom = fragment(
  1613. element("h1", "header"),
  1614. element("blockquote", { "class": "citation" },
  1615. element("p",
  1616. br(),
  1617. "preserve", br(),
  1618. "newlines", br(),
  1619. br(),
  1620. element("i", "(since 0.11)"), br(),
  1621. br(),
  1622. br())),
  1623. element("p",
  1624. "Whether Wiki formatter should respect the new lines present", br(),
  1625. "in the Wiki text. If set to ", element("b", "default"), ", this is equivalent to", br(),
  1626. element("i", "yes"), " for new environments but keeps the old behavior for", br(),
  1627. "upgraded environments (i.e. 'no')."),
  1628. element("p", "must_preserve_newlines"),
  1629. element("ul",
  1630. element("li", "first", br(), "word"),
  1631. element("li", "second", br(), "word")),
  1632. element("dl",
  1633. element("dt", "trac"),
  1634. element("dd", "trac.edgewall.org", br(), "trac-hacks.org")),
  1635. element("table", { "class": "wiki" },
  1636. element("tbody",
  1637. element("tr",
  1638. element("td", "cell", br(), "cell")))));
  1639. generate.call(this, dom, [
  1640. "= header =",
  1641. "> ",
  1642. "> preserve",
  1643. "> newlines",
  1644. "> ",
  1645. "> ''(since 0.11)''",
  1646. "> ",
  1647. "> ",
  1648. "",
  1649. "Whether Wiki formatter should respect the new lines present",
  1650. "in the Wiki text. If set to '''default''', this is equivalent to",
  1651. "''yes'' for new environments but keeps the old behavior for",
  1652. "upgraded environments (i.e. 'no').",
  1653. "",
  1654. "must_preserve_newlines",
  1655. "",
  1656. " * first[[BR]]word",
  1657. " * second[[BR]]word",
  1658. "",
  1659. " trac:: trac.edgewall.org[[BR]]trac-hacks.org",
  1660. "",
  1661. "|| cell[[BR]]cell ||" ].join("\n"), { escapeNewlines: true });
  1662. });
  1663. unit.add("selectRange", function() {
  1664. var d = instance.contentDocument;
  1665. function _element() {
  1666. var args = [ d ];
  1667. args.push.apply(args, arguments);
  1668. return element.apply(this, args);
  1669. }
  1670. function _text() {
  1671. var args = [ d ];
  1672. args.push.apply(args, arguments);
  1673. return text.apply(this, args);
  1674. }
  1675. function assertRangeText(expected, start, startOffset, end, endOffset) {
  1676. instance.selectRange(start, startOffset, end, endOffset);
  1677. if (expected instanceof RegExp) {
  1678. unit.assertMatch(expected, instance.getSelectionText());
  1679. }
  1680. else {
  1681. unit.assertEqual(expected, instance.getSelectionText());
  1682. }
  1683. }
  1684. var body = d.body;
  1685. while (body.childNodes.length > 0) {
  1686. body.removeChild(body.lastChild);
  1687. }
  1688. body.appendChild(fragment(d,
  1689. _element("p",
  1690. "The", " quick", " brown",
  1691. _element("b", " fox", " jumps", " over"),
  1692. " the", " lazy", " dog."),
  1693. _element("p", "Brick ", "quiz ", "whangs ", "jumpy ", "veldt ", "fox.")));
  1694. var paragraph1 = body.childNodes[0];
  1695. var paragraph2 = body.childNodes[1];
  1696. var bold = paragraph1.childNodes[3];
  1697. assertRangeText("The", paragraph1.childNodes[0], 0, paragraph1.childNodes[0], 3);
  1698. assertRangeText("he", paragraph1.childNodes[0], 1, paragraph1.childNodes[0], 3);
  1699. assertRangeText("e quick brow", paragraph1.childNodes[0], 2, paragraph1.childNodes[2], 5);
  1700. assertRangeText("ick brown", paragraph1.childNodes[1], 3, paragraph1.childNodes[2], 6);
  1701. assertRangeText("ick brown fox j", paragraph1.childNodes[1], 3, bold.childNodes[1], 2);
  1702. assertRangeText("ver the laz", bold.childNodes[2], 2, paragraph1.childNodes[5], 4);
  1703. assertRangeText(" the lazy", paragraph1.childNodes[4], 0, paragraph1.childNodes[5], 5);
  1704. assertRangeText("lazy dog.", paragraph1.childNodes[5], 1, paragraph1.childNodes[6], 5);
  1705. assertRangeText(/^fox jumps over the lazy dog\.[\r\n]*Brick quiz whangs$/,
  1706. bold.childNodes[0], 1, paragraph2.childNodes[2], 6);
  1707. assertRangeText(" fox jumps over", paragraph1, 3, paragraph1, 4);
  1708. assertRangeText(" dog.", paragraph1, 6, paragraph1, 7);
  1709. assertRangeText("", paragraph1, 7, paragraph1, 7);
  1710. assertRangeText("quick brown fox jumps over", paragraph1.childNodes[1], 1, paragraph1, 4);
  1711. assertRangeText(" fox jumps over t", paragraph1, 3, paragraph1.childNodes[4], 2);
  1712. });
  1713. unit.run();
  1714. }
  1715. var button = document.createElement("button");
  1716. button.innerHTML = "run &#187;";
  1717. button.style.textDecoration = "underline";
  1718. document.body.appendChild(button);
  1719. addEvent(button, "click", run);
  1720. button.focus();
  1721. });