source: tracwysiwygplugin/0.11/tests/testcase.js

Last change on this file was 13294, checked in by Jun Omae, 10 years ago

tracwysiwygplugin: use pasteHTML instead of execCommand('inserthtml') on Internet Explorer 10 (fixed #11173)

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