source: tracwysiwygplugin/0.12/tests/testcase.js

Last change on this file was 17967, checked in by Jun Omae, 3 years ago

TracWysiwygPlugin: make able to test with arbitary Trac version

File size: 74.0 KB
Line 
1(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("!||, !=||", function() {
431            var dom = fragment(
432                element("p", "Paragraph"),
433                element("table", { "class": "wiki" },
434                    element("tbody",
435                        element("tr", element("td", "foo||bar!||||==||foobar")))),
436                element("p", "||||cell=||= =||||=cell|| Paragraph"));
437            generateFragment.call(this, dom, [
438                "Paragraph",
439                "||foo!||bar!!||||=!=||foobar",
440                "!||||cell!=||=",
441                "!=||||=cell!||",
442                "Paragraph" ].join("\n"));
443            generate.call(this, dom, [
444                "Paragraph",
445                "",
446                "|| foo!||bar!!||||=!=||foobar ||",
447                "",
448                "!||||cell!=||= !=||||=cell!|| Paragraph" ].join("\n"));
449        });
450
451        unit.add("#ticket", function() {
452            var dom = element("p",
453                a("ticket:1234", "#1234"),
454                " #2345 &#3456");
455            var wikitext = "#1234 !#2345 &#3456";
456            generate.call(this, dom, wikitext);
457        });
458
459        unit.add("{report}", function() {
460            var dom = element("p",
461                "{987}",
462                a("report:123", "{123}"));
463            var wikitext = "!{987}{123}";
464            generate.call(this, dom, wikitext);
465        });
466
467        unit.add("[changeset]", function() {
468            var dom = element("p",
469                a("changeset:123", "[123]"),
470                ", ",
471                a("changeset:234", "r234"),
472                ", ",
473                a("changeset:345/trunk", "[345/trunk]"),
474                ", [123], r234, [345/trunk], ar123");
475            generate.call(this, dom, "[123], r234, [345/trunk], ![123], !r234, ![345/trunk], ar123");
476        });
477
478        unit.add("[log]", function() {
479            var dom = element("p",
480                "log - ",
481                a("log:@1:3", "r1:3"),
482                ", r1:3, ",
483                a("log:@1:3", "[1:3]"),
484                ", [1:3], ",
485                a("log:@1:3", "log:@1:3"),
486                ", log:@1:3, ",
487                a("log:trunk@1:3", "log:trunk@1:3"),
488                ", log:trunk@1:3");
489            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");
490        });
491
492        unit.add("wiki:TracLinks", function() {
493            var dom = element("p",
494                a("link:WikiName", "link:WikiName"),
495                " ",
496                a('link:"Foo Bar"', 'link:"Foo Bar"'),
497                " ",
498                a('link:"Foo Bar#baz"', 'link:"Foo Bar#baz"'),
499                " ",
500                a("link:'Foo Bar'", "link:'Foo Bar'"),
501                " ",
502                a("link:'Foo Bar#baz'", "link:'Foo Bar#baz'"),
503                " ",
504                a("svn+ssh://example.com/trunk", "svn+ssh://example.com/trunk"),
505                " ",
506                a("svn+ssh://example.com/trunk", "repository"),
507                " ",
508                a("rfc-2396.compatible://link", "rfc-2396.compatible://link"),
509                " ",
510                a("rfc-2396.compatible://link", "RFC 2396"),
511                " ",
512                "21:09,",
513                element("u", "underline"),
514                ",abc123 !21:09,",
515                element("u", "underline"),
516                ",abc123",
517                " ",
518                a("foo:bar", "foo:bar"),
519                " begin",
520                a("foo:bar", "foo:bar"),
521                " ",
522                a("foo:bar", "foo:bar"),
523                "end begin",
524                a("wiki:WikiStart", "WikiStart"),
525                "end link:'Foo Bar#baz'");
526            generateFragment.call(this, dom, [
527                "link:WikiName",
528                'link:"Foo Bar" link:"Foo Bar#baz"',
529                "link:'Foo Bar' link:'Foo Bar#baz'",
530                "svn+ssh://example.com/trunk [svn+ssh://example.com/trunk repository]",
531                "rfc-2396.compatible://link [rfc-2396.compatible://link RFC 2396]",
532                "21:09,__underline__,abc123 !21:09,__underline__,abc123",
533                "foo:bar begin[foo:bar foo:bar] [foo:bar foo:bar]end begin[wiki:WikiStart]end",
534                "!link:'Foo Bar#baz'" ].join(" "));
535            generate.call(this, dom, [
536                "link:WikiName",
537                'link:"Foo Bar" link:"Foo Bar#baz"',
538                "link:'Foo Bar' link:'Foo Bar#baz'",
539                "svn+ssh://example.com/trunk [svn+ssh://example.com/trunk repository]",
540                "rfc-2396.compatible://link [rfc-2396.compatible://link RFC 2396]",
541                "21:09,__underline__,abc123 !21:09,__underline__,abc123",
542                "foo:bar begin[foo:bar foo:bar] [foo:bar foo:bar]end begin[wiki:WikiStart]end",
543                "!link:'Foo Bar#baz'" ].join(" "));
544        });
545
546        unit.add("[wiki:TracLinks label]", function() {
547            var dom = element("p",
548                a("link:WikiName", "WikiName"),
549                " ",
550                a("link:WikiName", "wiki name"),
551                " ",
552                a("wiki:WikiName", "wiki]name"),
553                " ",
554                a("wiki:WikiName", "wiki name"),
555                " ",
556                a('link:"Foo Bar"', "Foo Bar"),
557                " ",
558                a('link:"Foo Bar#baz"', "Foo Bar#baz"),
559                " ",
560                a('link:"Foo Bar"', "bar foo"),
561                " ",
562                a('link:"Foo Bar#baz"', 'foo "foobar" bar'),
563                " ",
564                a("link:'Foo Bar'", "Foo Bar"),
565                " ",
566                a("link:'Foo Bar#baz'", "Foo Bar#baz"),
567                " ",
568                a("link:'Foo Bar'", "foo bar"),
569                " ",
570                a("link:'Foo Bar#baz'", "foo 'foobar' bar"),
571                " [link:'Foo Bar#baz'] [link:'Foo Bar#baz' label]");
572            generateFragment.call(this, dom, [
573                "[link:WikiName]",
574                "[link:WikiName 'wiki name']",
575                '[wiki:WikiName "wiki]name"]',
576                "[WikiName 'wiki name']",
577                '[link:"Foo Bar"] [link:"Foo Bar#baz"]',
578                '[link:"Foo Bar" "bar foo"] [link:"Foo Bar#baz" foo "foobar" bar]',
579                "[link:'Foo Bar'] [link:'Foo Bar#baz']",
580                "[link:'Foo Bar' 'foo bar'] [link:'Foo Bar#baz' foo 'foobar' bar]",
581                "![link:'Foo Bar#baz'] ![link:'Foo Bar#baz' label]" ].join(" "));
582            generate.call(this, dom, [
583                "[link:WikiName]",
584                "[link:WikiName wiki name]",
585                '[wiki:WikiName "wiki]name"]',
586                "[wiki:WikiName wiki name]",
587                '[link:"Foo Bar" Foo Bar] [link:"Foo Bar#baz" Foo Bar#baz]',
588                '[link:"Foo Bar" bar foo] [link:"Foo Bar#baz" foo "foobar" bar]',
589                "[link:'Foo Bar' Foo Bar] [link:'Foo Bar#baz' Foo Bar#baz]",
590                "[link:'Foo Bar' foo bar] [link:'Foo Bar#baz' foo 'foobar' bar]",
591                "![link:'Foo Bar#baz'] ![link:'Foo Bar#baz' label]" ].join(" "));
592        });
593
594        unit.add("[/relative label]", function() {
595            var dom = element("p",
596                a("../trac", "Trac"),
597                " ",
598                a("/newticket?component=tracwysiwygplugin", "here"),
599                " ",
600                a("//hostname", "host"),
601                " ",
602                a("//hostname/images", "images"),
603                " ",
604                a("#anchor", "anchor"));
605            var wikitext = [
606                "[../trac Trac]",
607                "[/newticket?component=tracwysiwygplugin here]",
608                "[//hostname host]",
609                "[//hostname/images images]",
610                "[#anchor anchor]" ].join(" ");
611            generate.call(this, dom, wikitext);
612        });
613
614        unit.add("<wiki:bracket links>", function() {
615            var dom = fragment(
616                element("p", "<", a("link:1"), ">"),
617                element("p", "Thing<", a("link:2 and (3)"), ">"),
618                element("p", "<link:1>"),
619                element("p", "Thing<link:2 and (3)>"));
620            var wikitext = [
621                "<link:1>",
622                "",
623                "Thing<link:2 and (3)>",
624                "",
625                "!<link:1>",
626                "",
627                "Thing!<link:2 and (3)>" ].join("\n");
628            generate.call(this, dom, wikitext);
629        });
630
631        unit.add("[=#anchor]", function() {
632            var dom = fragment(
633                element("p",
634                    "This is the ",
635                    element("span", { "class": "wikianchor", id: "init" }),
636                    " initialization routine: ..."),
637                element("p",
638                    "Look for ",
639                    element("span", { "class": "wikianchor", id : "extra" },
640                        element("i", "additional explanations")),
641                    " here."),
642                element("p",
643                    "これは",
644                    element("span", { "class": "wikianchor", id: "初期化" }),
645                    "初期化ルーチン: ..."),
646                element("p",
647                    element("span", { "class": "wikianchor", id : "追加" }, element("i", "追加説明")),
648                    "はここを見てください。"));
649            var wikitext = [
650                "This is the [=#init] initialization routine: ...",
651                "",
652                "Look for [=#extra ''additional explanations''] here.",
653                "",
654                "これは[=#初期化]初期化ルーチン: ...",
655                "",
656                "[=#追加 ''追加説明'']はここを見てください。" ].join("\n");
657            generate.call(this, dom, wikitext);
658        });
659
660        unit.add("[[macro]]", function() {
661            var dom = element("p",
662                "Line break ", element("br"), " another line", element("br"),
663                "last line [[bR]] ![[Br]] [[Macro]] ![[Macro]] [[Image?]] ![[Image?]] [[?]] ![[?]]");
664            generateFragment.call(this, dom, "Line break [[BR]] another line[[br]]last line ![[bR]] !![[Br]] [[Macro]] ![[Macro]] [[Image?]] ![[Image?]] [[?]] ![[?]]");
665            generate.call(this, dom, "Line break [[BR]] another line[[BR]]last line ![[bR]] !![[Br]] [[Macro]] ![[Macro]] [[Image?]] ![[Image?]] [[?]] ![[?]]");
666        });
667
668        unit.add("WikiPageName", function() {
669            var dom = fragment(
670                element("p",
671                    a("wiki:CamelCase", "CamelCase"),
672                    " CamelCase FooBarA FOo FoobarA ",
673                    a("wiki:OneÅngström", "OneÅngström"),
674                    " ",
675                    "Oneångström setTextColor"),
676                element("p",
677                    a("wiki:FooBar", "FooBar"),
678                    " FooBar_ FooBar1"),
679                element("p",
680                    a("wiki:WikiStart", "WikiStart"),
681                    " Wiki",
682                    a("wiki:Start", "Start"),
683                    " ",
684                    a("wiki:Wiki", "Wiki"),
685                    "Start Wiki",
686                    a("wiki:Start", "Start"),
687                    "Wiki"));
688            generate.call(this, dom, [
689                "CamelCase !CamelCase FooBarA FOo FoobarA OneÅngström Oneångström setTextColor",
690                "",
691                "FooBar FooBar_ FooBar1",
692                "",
693                "WikiStart Wiki[wiki:Start] [wiki:Wiki]Start Wiki[wiki:Start]Wiki" ].join("\n"));
694        });
695
696        unit.add('["internal free link"]', function() {
697            var dom = element("p",
698                "link - ",
699                a('wiki:"internal free link"', "internal free link"),
700                ' - ["free link"]');
701            generate.call(this, dom, 'link - [wiki:"internal free link" internal free link] - !["free link"]');
702        });
703
704        unit.add("traclink + underline", function() {
705            var dom = element("p",
706                element("u", a("ticket:123", "#123")), " ",
707                a("ticket:123", element("u", "#123")), " ",
708                element("u", a("report:123", "{123}")), " ",
709                a("report:123", element("u", "{123}")), " ",
710                element("u", a("changeset:123", "[123]")), " ",
711                a("changeset:123", element("u", "[123]")), " ",
712                element("u", a("changeset:123", "r123")), " ",
713                a("changeset:123", element("u", "r123")), " ",
714                element("u", a("log:@123:234", "[123:234]")), " ",
715                a("log:@123:234", element("u", "[123:234]")), " ",
716                element("u", a("wiki:WikiStart", "wiki:WikiStart")), " ",
717                a("wiki:WikiStart", element("u", "wiki:WikiStart")), " ",
718                element("u", a("wiki:WikiStart", "WikiStart")), " ",
719                a("wiki:WikiStart", element("u", "WikiStart")));
720            generateWikitext.call(this, dom, [
721                '__#123__',
722                '__#123__',
723                '__{123}__',
724                '__{123}__',
725                '__[123]__',
726                '__[123]__',
727                '__[changeset:123 r123]__',
728                '__[changeset:123 r123]__',
729                '__[123:234]__',
730                '__[123:234]__',
731                '__[wiki:WikiStart wiki:WikiStart]__',
732                '__[wiki:WikiStart wiki:WikiStart]__',
733                '__[wiki:WikiStart]__',
734                '__[wiki:WikiStart]__' ].join(" "));
735        });
736
737        unit.add("token + br", function() {
738            var dom = fragment(
739                element("p", "head ", a("http://localhost/", "http://localhost/"), element("br"), "tail"),
740                element("p", "head http://localhost/", element("br"), "tail"),
741                element("p", "head ", element("tt", "teletype"), element("br"), "tail"),
742                element("p", "head ", a("wiki:TracLinks", "TracLinks"), element("br"), "tail"),
743                element("p",
744                    "head ", a("http://localhost/", "http://localhost/"), " ",
745                    a("wiki:TracLinks", "wiki:TracLinks"),
746                    element("br"),
747                    "tail"),
748                element("p", "head http://localhost/ wiki:TracLinks", element("br"), "tail"));
749            generateWikitext.call(this, dom, [
750                "head http://localhost/ [[BR]]tail",
751                "",
752                "head !http://localhost/ [[BR]]tail",
753                "",
754                "head `teletype`[[BR]]tail",
755                "",
756                "head TracLinks[[BR]]tail",
757                "",
758                "head http://localhost/ wiki:TracLinks [[BR]]tail",
759                "",
760                "head !http://localhost/ !wiki:TracLinks [[BR]]tail" ].join("\n"));
761        });
762
763        if (window.getSelection) {
764            unit.add("block + br", function() {
765                function br() { return element("br"); }
766                var wikitext = [
767                    "text, br",
768                    "",
769                    "text'', br[[BR]]''",
770                    "",
771                    "|| 1,1[[BR]] || || 1,3 ||",
772                    "|| || 2,2[[BR]][[BR]] ||",
773                    "",
774                    " * list, br[[BR]]",
775                    " * list, br",
776                    " * ",
777                    "",
778                    "text, br[[BR]]" ].join("\n")
779                generateWikitext.call(this,
780                    fragment(
781                        element("p", "text, br", br()),
782                        element("p", "text", element("i", ", br", br()), br()),
783                        element("table", { "class": "wiki" },
784                            element("tbody",
785                                element("tr",
786                                    element("td", "1,1", br(), br()),
787                                    element("td", br()),
788                                    element("td", "1,3", br())),
789                                element("tr",
790                                    element("td", br()),
791                                    element("td", "2,2", br(), br(), br())))),
792                        element("ul",
793                            element("li", "list, br", br(), br()),
794                            element("li", "list, br", br()),
795                            element("li")),
796                        element("p", "text, br", br(), br())),
797                    wikitext);
798                generateFragment.call(this,
799                    fragment(
800                        element("p", "text, br"),
801                        element("p", "text", element("i", ", br", br()), br()),
802                        element("table", { "class": "wiki" },
803                            element("tbody",
804                                element("tr",
805                                    element("td", "1,1", br(), br()),
806                                    element("td", br()),
807                                    element("td", "1,3")),
808                                element("tr",
809                                    element("td", br()),
810                                    element("td", "2,2", br(), br(), br())))),
811                        element("ul",
812                            element("li", "list, br", br(), br()),
813                            element("li", "list, br"),
814                            element("li", br())),
815                        element("p", "text, br", br(), br())),
816                    wikitext);
817            });
818        }
819        else {
820            unit.add("block + br", function() {
821                function br() { return element("br"); }
822                var wikitext = [
823                    "text, br",
824                    "",
825                    "text'', br[[BR]]''",
826                    "",
827                    "|| 1,1[[BR]] || || 1,3 ||",
828                    "|| || 2,2[[BR]][[BR]] ||",
829                    "",
830                    " * list, br[[BR]]",
831                    " * list, br",
832                    " * ",
833                    "",
834                    "text, br[[BR]]" ].join("\n")
835                generate.call(this,
836                    fragment(
837                        element("p", "text, br"),
838                        element("p", "text", element("i", ", br", br())),
839                        element("table", { "class": "wiki" },
840                            element("tbody",
841                                element("tr",
842                                    element("td", "1,1", br()),
843                                    element("td"),
844                                    element("td", "1,3")),
845                                element("tr",
846                                    element("td"),
847                                    element("td", "2,2", br(), br())))),
848                        element("ul",
849                            element("li", "list, br", br()),
850                            element("li", "list, br"),
851                            element("li")),
852                        element("p", "text, br", br())),
853                    wikitext);
854            });
855        }
856
857        unit.add("citation", function() {
858            var dom = fragment(
859                element("blockquote", { "class": "citation" },
860                    element("p", "This is the quoted text continued"),
861                    element("blockquote", { "class": "citation" },
862                        element("p", "a nested quote"),
863                        element("blockquote", { "class": "citation" },
864                            element("p", "a nested-nested quote")))),
865                element("p", "A comment on the above"),
866                element("blockquote", { "class": "citation" },
867                    element("blockquote", { "class": "citation" },
868                        element("p", "start 2nd level")),
869                    element("p", "first level")));
870            generateFragment.call(this, dom, [
871                "> This is the quoted text",
872                "> continued",
873                "> > a nested quote",
874                "> > > a nested-nested quote",
875                "A comment on the above",
876                "> > start 2nd level",
877                ">first level" ].join("\n"));
878            generate.call(this, dom, [
879                "> This is the quoted text continued",
880                "> > a nested quote",
881                "> > > a nested-nested quote",
882                "",
883                "A comment on the above",
884                "",
885                "> > start 2nd level",
886                "> first level" ].join("\n"));
887        });
888
889        unit.add("header", function() {
890            var dom = fragment(
891                element("h1", "Heading 1"),
892                element("h2", { id: "anchor-2" }, "Heading 2"),
893                element("h3", element("u", "Heading"), " ", element("i", "3")),
894                element("h4", { id: "アンカー-4" },
895                    "Heading 4 with ",
896                    a("wiki:WikiStart", "link")),
897                element("h5", "Heading 5"),
898                element("h6", { id: "anchor-6" }, "Heading 6"));
899            generate.call(this, dom, [
900                "= Heading 1 =",
901                "== Heading 2 == #anchor-2",
902                "=== __Heading__ ''3'' ===",
903                "==== Heading 4 with [wiki:WikiStart link] ==== #アンカー-4",
904                "===== Heading 5 =====",
905                "====== Heading 6 ====== #anchor-6" ].join("\n"));
906        });
907
908        unit.add("header 2", function() {
909            var dom = fragment(
910                element("h1", "Heading 1"),
911                element("h2", { id: "anchor-2" }, "Heading 2"),
912                element("h3", element("u", "Heading"), " ", element("i", "3")),
913                element("h4", { id: "アンカー-4" },
914                    "Heading 4 with ",
915                    a("wiki:WikiStart", "link")),
916                element("h5", "Heading 5"),
917                element("h6", { id: "anchor-6" }, "Heading 6"));
918            generateFragment.call(this, dom, [
919                "= Heading 1  ",
920                "== Heading 2    #anchor-2",
921                "=== __Heading__ ''3''    ",
922                "==== Heading 4 with [wiki:WikiStart link]      #アンカー-4",
923                "===== Heading 5      ",
924                "====== Heading 6        #anchor-6" ].join("\n"));
925        });
926
927        unit.add("list", function() {
928            var dom = fragment(
929                element("p", "Paragraph"),
930                element("ul",
931                    element("li", "foo bar boo baz"),
932                    element("ul", element("li", "Subitem Subitem line 2")),
933                    element("li", "item 2 item 2 line 2")),
934                element("p", "Paragraph"));
935            generateFragment.call(this, dom, [
936                "Paragraph",
937                " * foo bar",
938                "   boo baz",
939                "   * Subitem",
940                "     Subitem line 2",
941                " * item 2",
942                "   item 2 line 2",
943                "Paragraph" ].join("\n"));
944            generate.call(this, dom, [
945                "Paragraph",
946                "",
947                " * foo bar boo baz",
948                "   * Subitem Subitem line 2",
949                " * item 2 item 2 line 2",
950                "",
951                "Paragraph" ].join("\n"));
952        });
953
954        unit.add("list 2", function() {
955            var dom = fragment(
956                element("ul",
957                    element("li", "foo bar boo baz"),
958                    element("ul",
959                        element("li", "Subitem 1"),
960                        element("ul",
961                            element("li", "nested item 1"),
962                            element("li", "nested item 2 nested item 2 continued")),
963                        element("li", "Subitem 2 subitem 2 continued"),
964                        element("li", "Subitem 3 subitem 3 continued")),
965                    element("li", "item 2 item 2 line 2")),
966                element("p", "Paragraph"));
967            generateFragment.call(this, dom, [
968                "    * foo bar",
969                "      boo baz",
970                "           * Subitem 1",
971                "             - nested item 1",
972                "             - nested item 2",
973                "             nested item 2 continued",
974                "            * Subitem 2",
975                "             subitem 2 continued",
976                "            * Subitem 3",
977                "            subitem 3 continued",
978                "    * item 2",
979                "     item 2 line 2",
980                "Paragraph" ].join("\n"));
981            generate.call(this, dom, [
982                " * foo bar boo baz",
983                "   * Subitem 1",
984                "     * nested item 1",
985                "     * nested item 2 nested item 2 continued",
986                "   * Subitem 2 subitem 2 continued",
987                "   * Subitem 3 subitem 3 continued",
988                " * item 2 item 2 line 2",
989                "",
990                "Paragraph" ].join("\n"));
991        });
992
993        unit.add("ordered list", function() {
994            var dom = fragment(
995                element("p", "Paragraph"),
996                element("ol",
997                    element("li", "item 1"),
998                    element("ol", { "class": "arabiczero" },
999                        element("li", "item 1.1"),
1000                        element("li", "item 1.2"),
1001                        element("ol", { "class": "loweralpha" },
1002                            element("li", "item 1.2.a"),
1003                            element("li", "item 1.2.b")),
1004                        element("li", "item 1.3"),
1005                        element("ol", { "class": "loweralpha" },
1006                            element("li", "item 1.3.a"),
1007                            element("li", "item 1.3.b")),
1008                        element("li", "item 1.4"),
1009                        element("ol", { "class": "upperalpha" },
1010                            element("li", "item 1.4.A"),
1011                            element("li", "item 1.4.B"),
1012                            element("li", "item 1.4.C")),
1013                        element("li", "item 1.5"),
1014                        element("ol", { "class": "upperalpha" },
1015                            element("li", "item 1.5.A")),
1016                        element("li", "item 1.6"),
1017                        element("ol", { "class": "lowerroman" },
1018                            element("li", "item 1.6.i"),
1019                            element("li", "item 1.6.ii")),
1020                        element("li", "item 1.7"),
1021                        element("ol", { "class": "upperroman" },
1022                            element("li", "item 1.7.I"),
1023                            element("li", "item 1.7.II")))),
1024                element("p", "Paragraph"));
1025            generateFragment.call(this, dom, [
1026                "Paragraph",
1027                " 1. item 1",
1028                "   0. item 1.1",
1029                "   2. item 1.2",
1030                "     a. item 1.2.a",
1031                "     z. item 1.2.b",
1032                "   a. item 1.3",
1033                "     b. item 1.3.a",
1034                "     y. item 1.3.b",
1035                "   Z. item 1.4",
1036                "     A. item 1.4.A",
1037                "     z. item 1.4.B",
1038                "     z. item 1.4.C",
1039                "   ii. item 1.5",
1040                "     C. item 1.5.A",
1041                "   XVI. item 1.6",
1042                "     i. item 1.6.i",
1043                "     x. item 1.6.ii",
1044                "   0. item 1.7",
1045                "     I. item 1.7.I",
1046                "     III. item 1.7.II",
1047                "Paragraph" ].join("\n"));
1048            generate.call(this, dom, [
1049                "Paragraph",
1050                "",
1051                " 1. item 1",
1052                "   0. item 1.1",
1053                "   0. item 1.2",
1054                "     a. item 1.2.a",
1055                "     a. item 1.2.b",
1056                "   0. item 1.3",
1057                "     a. item 1.3.a",
1058                "     a. item 1.3.b",
1059                "   0. item 1.4",
1060                "     A. item 1.4.A",
1061                "     A. item 1.4.B",
1062                "     A. item 1.4.C",
1063                "   0. item 1.5",
1064                "     A. item 1.5.A",
1065                "   0. item 1.6",
1066                "     i. item 1.6.i",
1067                "     i. item 1.6.ii",
1068                "   0. item 1.7",
1069                "     I. item 1.7.I",
1070                "     I. item 1.7.II",
1071                "",
1072                "Paragraph" ].join("\n"));
1073        });
1074
1075        unit.add("list + ordered list", function() {
1076            var dom = fragment(
1077                element("ul",
1078                    element("li", "Item 1"),
1079                    element("ul", element("li", "Item 1.1")),
1080                    element("li", "Item 2")),
1081                element("ol",
1082                    element("li", "Item 1"),
1083                    element("ol", { "class": "loweralpha" },
1084                        element("li", "Item 1.a"),
1085                        element("li", "Item 1.b"),
1086                        element("ol", { "class": "lowerroman" },
1087                            element("li", "Item 1.b.i"),
1088                            element("li", "Item 1.b.ii"))),
1089                    element("li", "Item 2")),
1090                element("p", "And numbered lists can also be given an explicit number:"),
1091                element("ol", { start: 3 }, element("li", "Item 3")));
1092            generateFragment.call(this, dom, [
1093                " * Item 1",
1094                "   * Item 1.1",
1095                " * Item 2",
1096                " 1. Item 1",
1097                "   a. Item 1.a",
1098                "   a. Item 1.b",
1099                "      i. Item 1.b.i",
1100                "      i. Item 1.b.ii",
1101                " 1. Item 2",
1102                "And numbered lists can also be given an explicit number:",
1103                " 3. Item 3" ].join("\n"));
1104            generate.call(this, dom, [
1105                " * Item 1",
1106                "   * Item 1.1",
1107                " * Item 2",
1108                "",
1109                " 1. Item 1",
1110                "   a. Item 1.a",
1111                "   a. Item 1.b",
1112                "     i. Item 1.b.i",
1113                "     i. Item 1.b.ii",
1114                " 1. Item 2",
1115                "",
1116                "And numbered lists can also be given an explicit number:",
1117                "",
1118                " 3. Item 3" ].join("\n"));
1119        });
1120
1121        unit.add("list at beginning of line", function() {
1122            var dom = fragment(
1123                element("ul",
1124                    element("li", "item 1"),
1125                    element("li", "item 2"),
1126                    element("ul", element("li", "sub 2.1"), element("li", "sub 2.2"))),
1127                element("ol", { "class": "loweralpha" },
1128                    element("li", "item A"), element("li", "item B")),
1129                element("p", "Paragraph"));
1130            generateFragment.call(this, dom, [
1131                "- item 1",
1132                "- item 2",
1133                "  - sub 2.1",
1134                "  - sub 2.2",
1135                "a. item A",
1136                "b. item B",
1137                "Paragraph" ].join("\n"));
1138            generate.call(this, dom, [
1139                " * item 1",
1140                " * item 2",
1141                "   * sub 2.1",
1142                "   * sub 2.2",
1143                "",
1144                " a. item A",
1145                " a. item B",
1146                "",
1147                "Paragraph" ].join("\n"));
1148        });
1149
1150        unit.add("list + code block", function() {
1151            var dom = fragment(
1152                element("p", "Paragraph"),
1153                element("ul",
1154                    element("li",
1155                        "item 1",
1156                        element("pre", { "class": "wiki" }, "code")),
1157                    element("ul",
1158                        element("li",
1159                            "item 1.1",
1160                            element("pre", { "class": "wiki" }, "code"),
1161                            "cont.",
1162                            element("pre", { "class": "wiki" }, "code"))),
1163                    element("li",
1164                        "item 2",
1165                        element("pre", { "class": "wiki" }, "code"))),
1166                element("ol", element("li", "item 1")));
1167            generateFragment.call(this, dom, [
1168                "Paragraph",
1169                " * item 1",
1170                "{{{",
1171                "code",
1172                "}}}",
1173                "   * item 1.1",
1174                "{{{",
1175                "code",
1176                "}}}",
1177                "     cont.",
1178                "{{{",
1179                "code",
1180                "}}}",
1181                " * item 2",
1182                "{{{",
1183                "code",
1184                "}}}",
1185                " 1. item 1" ].join("\n"));
1186            generate.call(this, dom, [
1187                "Paragraph",
1188                "",
1189                " * item 1",
1190                "{{{",
1191                "code",
1192                "}}}",
1193                "   * item 1.1",
1194                "{{{",
1195                "code",
1196                "}}}",
1197                "     cont.",
1198                "{{{",
1199                "code",
1200                "}}}",
1201                " * item 2",
1202                "{{{",
1203                "code",
1204                "}}}",
1205                "",
1206                " 1. item 1" ].join("\n"));
1207        });
1208
1209        unit.add("list + citation", function() {
1210            var dom = fragment(
1211                element('ol', element('li', 'item 1')),
1212                element('blockquote', { 'class': 'citation' }, element("p", "citation 1")),
1213                element('ul',
1214                    element('li', 'item 2'),
1215                    element("ol",
1216                        element('li', 'item 2.1'),
1217                        element('li', 'item 2.2'))),
1218                element('blockquote', { 'class': 'citation' }, element("p", "citation 2 citation 3")),
1219                element('ol', element('li', 'item 3')));
1220            generateFragment.call(this, dom, [
1221                ' 1. item 1',
1222                '> citation 1',
1223                ' * item 2',
1224                '   1. item 2.1',
1225                '   1. item 2.2',
1226                '> citation 2',
1227                '> citation 3',
1228                ' 1. item 3' ].join("\n"));
1229            generateWikitext.call(this, dom, [
1230                ' 1. item 1',
1231                '',
1232                '> citation 1',
1233                '',
1234                ' * item 2',
1235                '   1. item 2.1',
1236                '   1. item 2.2',
1237                '',
1238                '> citation 2 citation 3',
1239                '',
1240                ' 1. item 3' ].join("\n"));
1241        });
1242
1243        unit.add("definition", function() {
1244            var dom = element("dl",
1245                element("dt", "python"),
1246                element("dd", "www.python.org :: cont."),
1247                element("dt", element("b", "trac")),
1248                element("dd",
1249                    element("b", "trac"), ".edgewall.org cont.",
1250                    " ", element("tt", "trac-hacks::"), " trac-hacks.org"));
1251            generateFragment.call(this, dom, [
1252                " python:: www.python.org :: cont.",
1253                " '''trac''':: '''trac'''.edgewall.org",
1254                "   cont.",
1255                " `trac-hacks::` trac-hacks.org" ].join("\n"));
1256            generate.call(this, dom, [
1257                " python:: www.python.org :: cont.",
1258                " '''trac''':: '''trac'''.edgewall.org cont. `trac-hacks::` trac-hacks.org" ].join("\n"));
1259        });
1260
1261        unit.add("blockquote", function() {
1262            var dom = fragment(
1263                element("p", "Paragraph"),
1264                element("blockquote",
1265                    element("p", "blockquote 1 cont. 1"),
1266                    element("blockquote",
1267                        element("p", "blockquote 1.1"),
1268                        element("blockquote", element("p", "blockquote 1.1.1 cont. 1.1.1")),
1269                        element("p", "blockquote 1.2")),
1270                    element("p", "blockquote 2")),
1271                element("p", "Paragraph"));
1272            generateFragment.call(this, dom, [
1273                "Paragraph",
1274                "  blockquote 1",
1275                "  cont. 1",
1276                "    blockquote 1.1",
1277                "      blockquote 1.1.1",
1278                "      cont. 1.1.1",
1279                "     blockquote 1.2",
1280                "    blockquote 2",
1281                "Paragraph" ].join("\n"));
1282            generate.call(this, dom, [
1283                "Paragraph",
1284                "",
1285                "  blockquote 1 cont. 1",
1286                "    blockquote 1.1",
1287                "      blockquote 1.1.1 cont. 1.1.1",
1288                "    blockquote 1.2",
1289                "  blockquote 2",
1290                "",
1291                "Paragraph" ].join("\n"));
1292        });
1293
1294        unit.add("table", function() {
1295            var dom = fragment(
1296                element("p", "Paragraph"),
1297                element("table", { "class": "wiki" },
1298                    element("tbody",
1299                        element("tr", element("td", "1.1"), element("td", "1.2")),
1300                        element("tr", element("td", "2.1")),
1301                        element("tr",
1302                            element("td", "3.1"),
1303                            element("td", element("u", "3.2")),
1304                            element("td", element("tt", "3"), " ", element("tt", "-"))))),
1305                element("p", "Paragraph"));
1306            generateFragment.call(this, dom, [
1307                "Paragraph",
1308                "||1.1||1.2||",
1309                "||2.1",
1310                "||3.1||__3.2__||`3` `-`",
1311                "Paragraph" ].join("\n"));
1312            generate.call(this, dom, [
1313                "Paragraph",
1314                "",
1315                "|| 1.1 || 1.2 ||",
1316                "|| 2.1 ||",
1317                "|| 3.1 || __3.2__ || `3` `-` ||",
1318                "",
1319                "Paragraph" ].join("\n"));
1320        });
1321
1322        unit.add("colspan", function() {
1323            var dom = fragment(
1324                element("p", "Paragraph"),
1325                element("table", { "class": "wiki" },
1326                    element("tbody",
1327                        element("tr", element("td", "1.1"), element("td", "1.2", { colSpan: 2 })),
1328                        element("tr", element("td", "2.1", { colSpan: 3 })),
1329                        element("tr",
1330                            element("td", "3.1"),
1331                            element("td", element("u", "3.2")),
1332                            element("td", element("tt", "3.3"))))),
1333                element("p", "Paragraph"));
1334            generateFragment.call(this, dom, [
1335                "Paragraph",
1336                "||1.1||||1.2",
1337                "||||||2.1",
1338                "||3.1||__3.2__||`3.3`",
1339                "Paragraph" ].join("\n"));
1340            generate.call(this, dom, [
1341                "Paragraph",
1342                "",
1343                "|| 1.1 |||| 1.2 ||",
1344                "|||||| 2.1 ||",
1345                "|| 3.1 || __3.2__ || `3.3` ||",
1346                "",
1347                "Paragraph" ].join("\n"));
1348        });
1349
1350        unit.add("table header", function() {
1351            var dom = fragment(
1352                element("p", "Paragraph"),
1353                element("table", { "class": "wiki" },
1354                    element("tbody",
1355                        element("tr", element("th", "1.1"), element("td", "1.2", { colSpan: 2 })),
1356                        element("tr", element("th", "2.1", { colSpan: 3 })),
1357                        element("tr",
1358                            element("td", "3.1"),
1359                            element("th", element("u", "3.2")),
1360                            element("td", element("tt", "3.3"))))),
1361                element("p", "Paragraph"));
1362            generateFragment.call(this, dom, [
1363                "Paragraph",
1364                "||=1.1=||||1.2",
1365                "||||||=2.1=||",
1366                "||3.1||=__3.2__=||`3.3`",
1367                "Paragraph" ].join("\n"));
1368            generate.call(this, dom, [
1369                "Paragraph",
1370                "",
1371                "||= 1.1 =|||| 1.2 ||",
1372                "||||||= 2.1 =||",
1373                "|| 3.1 ||= __3.2__ =|| `3.3` ||",
1374                "",
1375                "Paragraph" ].join("\n"));
1376        });
1377
1378        unit.add("table with alignment", function() {
1379            var dom = fragment(
1380                element("p", "Paragraph"),
1381                element("table", { "class": "wiki" },
1382                    element("tbody",
1383                        element("tr", element("th", "1.1"),
1384                        element("td", "1.2", { colSpan: 2, align: "right" })),
1385                        element("tr", element("th", "2.1", { colSpan: 3, align: "left" })),
1386                        element("tr",
1387                            element("td", "3||1", { align: "right" }),
1388                            element("th", element("u", "3.2")),
1389                            element("td", element("tt", "3.3"), { align: "left" })),
1390                        element("tr",
1391                            element("th", "4.1", { align: "center" }),
1392                            element("td", "4.2"),
1393                            element("td", "4.3", { align: "center" })))),
1394                element("p", "Paragraph"));
1395            generateFragment.call(this, dom, [
1396                "Paragraph",
1397                "||=1.1=|||| 1.2",
1398                "||||||=2.1 =||",
1399                "|| 3!||1||= __3.2__ =||`3.3` ||",
1400                "||=  4.1     =|| 4.2 ||    4.3    ||",
1401                "Paragraph" ].join("\n"));
1402            generate.call(this, dom, [
1403                "Paragraph",
1404                "",
1405                "||= 1.1 =|||| 1.2||",
1406                "||||||=2.1 =||",
1407                "|| 3!||1||= __3.2__ =||`3.3` ||",
1408                "||=  4.1  =|| 4.2 ||  4.3  ||",
1409                "",
1410                "Paragraph" ].join("\n"));
1411        });
1412
1413        unit.add("table with row continuation", function() {
1414            var dom = fragment(
1415                element("p", "Paragraph"),
1416                element("table", { "class": "wiki" },
1417                    element("tbody",
1418                        element("tr", element("td", "1.1"), element("td", "1.2"), element("td", "1.3")),
1419                        element("tr", element("td", "2.1")),
1420                        element("tr",
1421                            element("td", "3.1"),
1422                            element("td", element("u", "3.2")),
1423                            element("td", element("tt", "3.3"))))),
1424                element("p", "Paragraph"));
1425            generateFragment.call(this, dom, [
1426                "Paragraph",
1427                "||1.1||1.2||    \\",
1428                "||1.3",
1429                "||2.1",
1430                "||3.1||__3.2__||`3.3`||\\",
1431                "Paragraph" ].join("\n"));
1432        });
1433
1434        unit.add("table + rule", function() {
1435            var dom = fragment(
1436                element("table", { "class": "wiki" },
1437                    element("tbody", element("tr", element("td", "1st")))),
1438                element("p", element("b", "bold")),
1439                element("table", { "class": "wiki" },
1440                    element("tbody", element("tr", element("td", "2nd")))),
1441                element("p", "'''normal"));
1442            generateFragment.call(this, dom, [
1443                "||1st||",
1444                "'''bold'''",
1445                "||2nd||",
1446                "!'''normal" ].join("\n"));
1447            generate.call(this, dom, [
1448                "|| 1st ||",
1449                "",
1450                "'''bold'''",
1451                "",
1452                "|| 2nd ||",
1453                "",
1454                "!'''normal" ].join("\n"));
1455        });
1456
1457        unit.add("blockquote + table", function() {
1458            var dom = fragment(
1459                element("p", "Paragraph"),
1460                element("table", { "class": "wiki" },
1461                    element("tbody",
1462                        element("tr", element("td", "pre.1"), element("td", "pre.2")))),
1463                element("blockquote",
1464                    element("table", { "class": "wiki" },
1465                        element("tbody",
1466                            element("tr", element("td", "1.1"), element("td", "1.2")),
1467                            element("tr", element("td", "2.1")))),
1468                    element("blockquote",
1469                        element("table", { "class": "wiki" },
1470                            element("tbody",
1471                                element("tr", element("td", "deep"))))),
1472                    element("table", { "class": "wiki" },
1473                        element("tbody",
1474                            element("tr",
1475                                element("td", "3.1"),
1476                                element("td", element("u", "3.2")),
1477                                element("td", element("tt", "3.3")))))),
1478                element("table", { "class": "wiki" },
1479                    element("tbody",
1480                        element("tr", element("td", "post.1"), element("td", "post.2")))),
1481                element("p", "Paragraph"));
1482            generateFragment.call(this, dom, [
1483                "Paragraph",
1484                "||pre.1||pre.2||",
1485                " ||1.1||1.2||",
1486                " ||2.1",
1487                "  ||deep||",
1488                " ||3.1||__3.2__||`3.3`",
1489                "||post.1||post.2||",
1490                "Paragraph" ].join("\n"));
1491            generate.call(this, dom, [
1492                "Paragraph",
1493                "",
1494                "|| pre.1 || pre.2 ||",
1495                "",
1496                "  || 1.1 || 1.2 ||",
1497                "  || 2.1 ||",
1498                "    || deep ||",
1499                "  || 3.1 || __3.2__ || `3.3` ||",
1500                "",
1501                "|| post.1 || post.2 ||",
1502                "",
1503                "Paragraph" ].join("\n"));
1504        });
1505
1506        unit.add("table [ paragraph, ul ]", function() {
1507            var dom = fragment(
1508                element("table", { "class": "wiki" },
1509                    element("tbody",
1510                        element("tr",
1511                            element("td", element("p", "1.1")),
1512                            element("td",
1513                                element("ul",
1514                                    element("li", "item 1"),
1515                                    element("li", "item 2")))),
1516                        element("tr",
1517                            element("td",
1518                                element("p", "2.1"),
1519                                element("ul",
1520                                    element("li", "item 3"),
1521                                    element("li", "item 4")))))));
1522            generateWikitext.call(this, dom, [
1523                "|| 1.1 || * item 1[[BR]] * item 2 ||",
1524                "|| 2.1[[BR]][[BR]] * item 3[[BR]] * item 4 ||" ].join("\n"));
1525        });
1526
1527        unit.add("table with incomplete markups", function() {
1528            var dom = fragment(
1529                element("table", { "class": "wiki" },
1530                    element("tbody",
1531                        element("tr",
1532                            element("td", element("b", element("i", "'"))),
1533                            element("td", element("b", "bold")))
1534                    )
1535                )
1536            );
1537            generateFragment.call(this, dom, "|| '''''' || '''bold''' ||");
1538        });
1539
1540        unit.add("table from word", function() {
1541            var dom = element("div");
1542            dom.innerHTML = [
1543                '',
1544                '<table class="MsoTableGrid" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">',
1545                ' <tbody><tr style="">',
1546                '  <td style="border: 1pt solid windowtext; padding: 0mm 5.4pt; width: 217.55pt;" valign="top" width="290">',
1547                '  <p class="MsoNormal"><span lang="EN-US">a<o:p></o:p></span></p>',
1548                '  <p class="MsoNormal"><span lang="EN-US">b<o:p></o:p></span></p>',
1549                '  </td>',
1550                '  <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">',
1551                '',
1552                '  <p class="MsoNormal"><span lang="EN-US">b<o:p></o:p></span></p>',
1553                '  </td>',
1554                ' </tr>',
1555                ' <tr style="">',
1556                '  <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">',
1557                '  <p class="MsoNormal"><span lang="EN-US">c<o:p></o:p></span></p>',
1558                '  </td>',
1559                '  <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">',
1560                '',
1561                '  <p class="MsoNormal"><span lang="EN-US">d<o:p></o:p></span></p>',
1562                '  </td>',
1563                ' </tr>',
1564                '</tbody></table>',
1565                '' ].join("\n");
1566            generateWikitext.call(this, dom, [
1567                "|| a[[BR]][[BR]]b || b ||",
1568                "|| c || d ||" ].join("\n"));
1569        });
1570
1571        unit.add("domToWikitext for code block", function() {
1572            var br = function() { return element("br") };
1573            var dom = fragment(
1574                element("h1", "Heading", br(), "1"),
1575                element("h2", "Heading", br(), "2"),
1576                element("h3", "Heading", br(), "3"),
1577                element("h4", "Heading", br(), "4"),
1578                element("h5", "Heading", br(), "5"),
1579                element("h6", "Heading", br(), "6"),
1580                element("p",
1581                    "var TracWysiwyg = function(textarea) {", br(),
1582                    "...", br(),
1583                    "}"),
1584                element("blockquote", { "class": "citation" }, element("p", "citation", br(), "continued")),
1585                element("blockquote", element("p", "quote", br(), "continued")),
1586                element("ul",
1587                    element("li", "item 1", br(), "continued"),
1588                    element("ol", element("li", "item", br(), "1.1"))),
1589                element("dl",
1590                    element("dt", "def to_s(", br(), ")"),
1591                    element("dd", "dt", br(), "dd")),
1592                element("table",
1593                    element("tbody",
1594                        element("tr",
1595                            element("td", "cell", br(), "1"),
1596                            element("th", "cell", br(), "2")))));
1597            var wikitext = instance.domToWikitext(dom, { formatCodeBlock: true });
1598            this.assertEqual([
1599                "= Heading 1 =",
1600                "== Heading 2 ==",
1601                "=== Heading 3 ===",
1602                "==== Heading 4 ====",
1603                "===== Heading 5 =====",
1604                "====== Heading 6 ======",
1605                "var TracWysiwyg = function(textarea) {",
1606                "...",
1607                "}",
1608                "",
1609                "> citation",
1610                "> continued",
1611                "",
1612                "  quote",
1613                "  continued",
1614                "",
1615                " * item 1",
1616                "   continued",
1617                "   1. item",
1618                "     1.1",
1619                "",
1620                " def to_s( ):: dt",
1621                "    dd",
1622                "",
1623                "|| cell[[BR]]1 ||= cell[[BR]]2 =||" ].join("\n"), wikitext);
1624        });
1625
1626        unit.add("escape newlines", function() {
1627            var dom = fragment(
1628                element("h1", "header"),
1629                element("blockquote", { "class": "citation" },
1630                    element("p",
1631                        br(),
1632                        "preserve", br(),
1633                        "newlines", br(),
1634                        br(),
1635                        element("i", "(since 0.11)"), br(),
1636                        br(),
1637                        br())),
1638                element("p",
1639                    "Whether Wiki formatter should respect the new lines present", br(),
1640                    "in the Wiki text. If set to ", element("b", "default"), ", this is equivalent to", br(),
1641                    element("i", "yes"), " for new environments but keeps the old behavior for", br(),
1642                    "upgraded environments (i.e. 'no')."),
1643                element("p", "must_preserve_newlines"),
1644                element("ul",
1645                    element("li", "first", br(), "word"),
1646                    element("li", "second", br(), "word")),
1647                element("dl",
1648                    element("dt", "trac"),
1649                    element("dd", "trac.edgewall.org", br(), "trac-hacks.org")),
1650                element("table", { "class": "wiki" },
1651                    element("tbody",
1652                        element("tr",
1653                            element("td", "cell", br(), "cell")))));
1654            generate.call(this, dom, [
1655                "= header =",
1656                "> ",
1657                "> preserve",
1658                "> newlines",
1659                "> ",
1660                "> ''(since 0.11)''",
1661                "> ",
1662                "> ",
1663                "",
1664                "Whether Wiki formatter should respect the new lines present",
1665                "in the Wiki text. If set to '''default''', this is equivalent to",
1666                "''yes'' for new environments but keeps the old behavior for",
1667                "upgraded environments (i.e. 'no').",
1668                "",
1669                "must_preserve_newlines",
1670                "",
1671                " * first[[BR]]word",
1672                " * second[[BR]]word",
1673                "",
1674                " trac:: trac.edgewall.org[[BR]]trac-hacks.org",
1675                "",
1676                "|| cell[[BR]]cell ||" ].join("\n"), { escapeNewlines: true });
1677        });
1678
1679        unit.add("selectRange", function() {
1680            var d = instance.contentDocument;
1681            function _element() {
1682                var args = [ d ];
1683                args.push.apply(args, arguments);
1684                return element.apply(this, args);
1685            }
1686            function _text() {
1687                var args = [ d ];
1688                args.push.apply(args, arguments);
1689                return text.apply(this, args);
1690            }
1691            function assertRangeText(expected, start, startOffset, end, endOffset) {
1692                instance.selectRange(start, startOffset, end, endOffset);
1693                if (expected instanceof RegExp) {
1694                    unit.assertMatch(expected, instance.getSelectionText());
1695                }
1696                else {
1697                    unit.assertEqual(expected, instance.getSelectionText());
1698                }
1699            }
1700            var body = d.body;
1701            while (body.childNodes.length > 0) {
1702                body.removeChild(body.lastChild);
1703            }
1704            body.appendChild(fragment(d,
1705                _element("p",
1706                    "The", " quick", " brown",
1707                    _element("b", " fox", " jumps", " over"),
1708                    " the", " lazy", " dog."),
1709                _element("p", "Brick ", "quiz ", "whangs ", "jumpy ", "veldt ", "fox.")));
1710
1711            var paragraph1 = body.childNodes[0];
1712            var paragraph2 = body.childNodes[1];
1713            var bold = paragraph1.childNodes[3];
1714            assertRangeText("The", paragraph1.childNodes[0], 0, paragraph1.childNodes[0], 3);
1715            assertRangeText("he", paragraph1.childNodes[0], 1, paragraph1.childNodes[0], 3);
1716            assertRangeText("e quick brow", paragraph1.childNodes[0], 2, paragraph1.childNodes[2], 5);
1717            assertRangeText("ick brown", paragraph1.childNodes[1], 3, paragraph1.childNodes[2], 6);
1718            assertRangeText("ick brown fox j", paragraph1.childNodes[1], 3, bold.childNodes[1], 2);
1719            assertRangeText("ver the laz", bold.childNodes[2], 2, paragraph1.childNodes[5], 4);
1720            assertRangeText(" the lazy", paragraph1.childNodes[4], 0, paragraph1.childNodes[5], 5);
1721            assertRangeText("lazy dog.", paragraph1.childNodes[5], 1, paragraph1.childNodes[6], 5);
1722            assertRangeText(/^fox jumps over the lazy dog\.[\r\n]*Brick quiz whangs$/,
1723                bold.childNodes[0], 1, paragraph2.childNodes[2], 6);
1724            assertRangeText(" fox jumps over", paragraph1, 3, paragraph1, 4);
1725            assertRangeText(" dog.", paragraph1, 6, paragraph1, 7);
1726            assertRangeText("", paragraph1, 7, paragraph1, 7);
1727            assertRangeText("quick brown fox jumps over", paragraph1.childNodes[1], 1, paragraph1, 4);
1728            assertRangeText(" fox jumps over t", paragraph1, 3, paragraph1.childNodes[4], 2);
1729        });
1730
1731        unit.add("insertHTML", function() {
1732            var d = instance.contentDocument;
1733            var body = d.body;
1734            while (body.childNodes.length > 0) {
1735                body.removeChild(body.lastChild);
1736            }
1737            instance.insertHTML('<p>blah</p>');
1738            var paragraph1 = body.childNodes[0];
1739            unit.assertEqual('blah', paragraph1.innerHTML);
1740        });
1741
1742        unit.run();
1743    }
1744
1745    (function() {
1746        var body = $(document.body);
1747        var button = $(document.createElement("button"));
1748        button.text('run \u00bb');
1749        button.on('click', run);
1750        body.append(button, ' jQuery: ', jQuery.fn.jquery);
1751    })();
1752})(jQuery);
Note: See TracBrowser for help on using the repository browser.