WIP: Note editing, markdown to html
[oweals/karmaworld.git] / karmaworld / apps / wysihtml5 / static / wysihtml5 / wysihtml-0.4.17 / test / editor_commands_test.js
1 if (wysihtml5.browser.supported()) {
2   module("wysihtml5.Editor.commands", {
3     setup: function() {
4         
5       this.editableArea1        = document.createElement("div");
6       this.editableArea1.id     = "wysihtml5-test-editable1";
7       this.editableArea1.className = "wysihtml5-test-class1";
8       this.editableArea1.title  = "Please enter your foo";
9       this.editableArea1.innerHTML  = "hey tiff, what's up?";
10       
11       document.body.appendChild(this.editableArea1);
12       
13     },
14
15     setCaretInsideNode: function(editor, el) {
16         var r1 = editor.composer.selection.createRange(),
17             e1 = el.childNodes[0];
18         r1.setEnd(e1, 1);
19         r1.setStart(e1, 1);
20         editor.composer.selection.setSelection(r1);
21     },
22
23     teardown: function() {
24       var leftover;
25       this.editableArea1.parentNode.removeChild(this.editableArea1);
26       while (leftover = document.querySelector("div.wysihtml5-test-class1, iframe.wysihtml5-sandbox, div.wysihtml5-sandbox")) {
27         leftover.parentNode.removeChild(leftover);
28       }
29       document.body.className = this.originalBodyClassName;
30     },
31
32     equal: function(actual, expected, message) {
33       return QUnit.assert.htmlEqual(actual, expected, message);
34     },
35   });
36   
37   
38 // bold, italic, underline
39   asyncTest("Basic formating tests", function() {
40      expect(18);
41     var that = this,
42         text = "once upon a time there was an unformated text.",
43         parserRules = {
44           tags: {
45             b: true,
46             i: true,
47             u: true
48           }
49         },
50         editor = new wysihtml5.Editor(this.editableArea1, {
51           parserRules: parserRules
52         });
53         
54     editor.on("load", function() {
55       var editableElement   = that.editableArea1;
56       // basic bold
57       editor.setValue(text, true);
58       editor.composer.selection.selectNode(editor.editableElement);
59       editor.composer.commands.exec('bold');
60       equal(editableElement.innerHTML.toLowerCase(), "<b>" + text + "</b>", "Command bold sets text as bold correctly");
61
62       editor.composer.selection.getSelection().collapseToEnd();
63
64       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret is collapsed");
65
66       editor.composer.commands.exec('bold');
67       editor.composer.selection.getSelection().collapseToEnd();
68       editor.composer.commands.exec('insertHtml', 'test');
69       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret did remain collapsed");
70       equal(editableElement.innerHTML.toLowerCase().replace(/\uFEFF/g, ''), "<b>" + text + "</b>test", "With caret at last position bold is not removed but set to notbold at caret");
71       
72
73       that.setCaretInsideNode(editor, editableElement.querySelector('b'));
74       editor.composer.commands.exec('bold');
75
76       equal(editableElement.innerHTML.toLowerCase().replace(/\uFEFF/g, ''), text + "test", "Bold is correctly removed when text caret is inside bold");
77       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret did remain collapsed");
78
79       // basic italic
80       editor.setValue(text, true);
81       editor.composer.selection.selectNode(editor.editableElement);
82       editor.composer.commands.exec('italic');
83       equal(editableElement.innerHTML.toLowerCase(), "<i>" + text + "</i>", "Command italic sets text as italic correctly");
84       
85       editor.composer.selection.getSelection().collapseToEnd();
86       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret is collapsed");
87
88       editor.composer.commands.exec('italic');
89       editor.composer.selection.getSelection().collapseToEnd();
90       editor.composer.commands.exec('insertHtml', 'test');
91
92       equal(editableElement.innerHTML.toLowerCase().replace(/\uFEFF/g, ''), "<i>" + text + "</i>test", "With caret at last position italic is not removed but set to notitalic at caret");
93       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret did remain collapsed");
94
95       that.setCaretInsideNode(editor, editableElement.querySelector('i'));
96       editor.composer.commands.exec('italic');
97
98       equal(editableElement.innerHTML.toLowerCase().replace(/\uFEFF/g, ''), text + "test", "Italic is correctly removed when text caret is inside italic");
99       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret did remain collapsed");
100
101       // basic underline
102       editor.setValue(text, true);
103       editor.composer.selection.selectNode(editor.editableElement);
104       editor.composer.commands.exec('underline');
105       equal(editableElement.innerHTML.toLowerCase().replace(/\uFEFF/g, ''), "<u>" + text + "</u>", "Command underline sets text as underline correctly");
106
107       editor.composer.selection.getSelection().collapseToEnd();
108       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret is collapsed");
109
110       editor.composer.commands.exec('underline');
111       editor.composer.selection.getSelection().collapseToEnd();
112       editor.composer.commands.exec('insertHtml', 'test');
113
114       equal(editableElement.innerHTML.toLowerCase().replace(/\uFEFF/g, ''), "<u>" + text + "</u>test", "With caret at last position underline is not removed but set to notunderline at caret");
115       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret did remain collapsed");
116
117       that.setCaretInsideNode(editor, editableElement.querySelector('u'));
118       editor.composer.commands.exec('underline');
119
120       equal(editableElement.innerHTML.toLowerCase().replace(/\uFEFF/g, ''), text + "test", "Underline is correctly removed when text caret is inside underline");
121       ok(editor.composer.selection.getSelection().isCollapsed, "Text caret did remain collapsed");
122
123       start();
124     });
125   });
126   
127 // formatblock (alignment, headings, paragraph, pre, blockquote)
128     asyncTest("Format block", function() {
129        expect(12);
130       var that = this,
131           editor = new wysihtml5.Editor(this.editableArea1),
132           text = "once upon a time<br>there was an unformated text<br>spanning many lines.";
133         
134       editor.on("load", function() {
135         var editableElement   = that.editableArea1;
136         editor.setValue(text, true);
137         editor.composer.selection.selectNode(editor.editableElement);
138         editor.composer.commands.exec('justifyRight');
139         equal(editableElement.innerHTML.toLowerCase(), '<div class="wysiwyg-text-align-right">' + text + '</div>', "Text corectly wrapped in one aligning div");
140     
141         editor.composer.commands.exec('justifyRight');
142         equal(editableElement.innerHTML.toLowerCase(), text, "Aligning div correctly removed");
143         
144         editor.composer.selection.selectNode(editor.editableElement);
145         editor.composer.selection.getSelection().collapseToStart();
146
147         editor.composer.commands.exec('justifyRight');
148         editor.composer.selection.getSelection().collapseToStart();
149         equal(editableElement.innerHTML.toLowerCase(), '<div class="wysiwyg-text-align-right">once upon a time</div>there was an unformated text<br>spanning many lines.', "Only first line correctly wrapped in aligning div");
150         
151         var node = editor.editableElement.querySelectorAll('.wysiwyg-text-align-right');
152         editor.composer.selection.selectNode(node[0].childNodes[0]);
153         editor.composer.commands.exec('justifyLeft');
154         equal(editableElement.innerHTML.toLowerCase(), '<div class="wysiwyg-text-align-left">once upon a time</div>there was an unformated text<br>spanning many lines.', "First line wrapper class changed correctly");
155         
156         editor.composer.commands.exec('formatBlock', "h1");
157         equal(editableElement.innerHTML.toLowerCase(), '<h1 class="wysiwyg-text-align-left">once upon a time</h1>there was an unformated text<br>spanning many lines.', "Alignment div changed to heading ok");
158         
159         editor.composer.commands.exec('formatBlock', "h1");
160         equal(editableElement.innerHTML.toLowerCase(), '<div class="wysiwyg-text-align-left">once upon a time</div>there was an unformated text<br>spanning many lines.', "heading back to div ok");
161         
162         editor.composer.commands.exec('justifyRight');
163         editor.composer.commands.exec('formatBlock', "h1");
164         editor.composer.commands.exec('justifyRight');
165         equal(editableElement.innerHTML.toLowerCase(), '<h1>once upon a time</h1>there was an unformated text<br>spanning many lines.', "heading alignment removed sucessfully");
166         
167         editor.composer.commands.exec('justifyRight');
168         editor.composer.commands.exec('formatBlock', "p");
169         editor.composer.commands.exec('justifyRight');
170         equal(editableElement.innerHTML.toLowerCase(), '<p>once upon a time</p>there was an unformated text<br>spanning many lines.', "heading alignment removed sucessfully");
171
172         editor.setValue(text, true);
173         editor.composer.selection.selectNode(editor.editableElement);
174         editor.composer.commands.exec('alignRightStyle');
175         equal(editableElement.innerHTML.toLowerCase(), '<div style="text-align: right;">' + text + '</div>', "Text corectly wrapped in one aligning div with style");
176
177         editor.composer.commands.exec('alignCenterStyle');
178         equal(editableElement.innerHTML.toLowerCase(), '<div style="text-align: center;">' + text + '</div>', "Alignment (style) changed correctly to center");
179
180         editor.composer.commands.exec('alignLeftStyle');
181         equal(editableElement.innerHTML.toLowerCase(), '<div style="text-align: left;">' + text + '</div>', "Alignment (style) changed correctly to left");
182
183         editor.composer.commands.exec('alignLeftStyle');
184         equal(editableElement.innerHTML.toLowerCase(), text, "Alignment (style) correctly removed");
185
186         start();
187       });
188     });
189
190 // Format code
191   asyncTest("Format code", function() {
192        expect(2);
193       var that = this,
194           editor = new wysihtml5.Editor(this.editableArea1),
195           text = "once upon a time there was an unformated text.";
196         
197       editor.on("load", function() {
198         var editableElement   = that.editableArea1;
199         editor.setValue(text, true);
200
201         editor.composer.selection.selectNode(editor.editableElement);
202         editor.composer.commands.exec('formatCode', 'language-html');
203         equal(editableElement.innerHTML.toLowerCase(), '<pre><code class="language-html">' + text + '</code></pre>', "Text corectly wrapped in pre and code and classname addded");
204     
205         editor.composer.commands.exec('formatCode', 'language-html');
206         equal(editableElement.innerHTML.toLowerCase(), text, "Code block correctly removed");
207
208         start();
209       });
210     });
211     
212 // createLink/removeLink
213         asyncTest("Create/remove link", function() {
214            expect(4);
215            
216           var that = this,
217               editor = new wysihtml5.Editor(this.editableArea1),
218               text = "text";
219         
220           editor.on("load", function() {
221             var editableElement   = that.editableArea1;
222             editor.setValue(text, true);
223             editor.composer.selection.selectNode(editor.editableElement);
224             
225             // Create
226             editor.composer.commands.exec('createLink', {
227               "href": "http://test.com", "title": "test"
228             });
229             that.equal(editableElement.innerHTML.toLowerCase(), '<a href="http://test.com" title="test">' + text + '</a>', "Link added correctly");
230             
231             // Change
232             editor.composer.selection.selectNode(editor.editableElement);
233             editor.composer.commands.exec('createLink', {
234               "href": "http://changed.com"
235             });
236             that.equal(editableElement.innerHTML.toLowerCase(), '<a href="http://changed.com">' + text + '</a>', "Link attributes changed correctly when createLink is executed on existing link");
237             
238             //Remove
239             editor.composer.selection.selectNode(editor.editableElement);
240             editor.composer.commands.exec('removeLink');
241             that.equal(editableElement.innerHTML, text, "Link remove correctly");
242             
243             // Create with caret
244             editor.composer.selection.selectNode(editor.editableElement);
245             editor.composer.selection.getSelection().collapseToStart();
246             editor.composer.commands.exec('createLink', {
247               "href": "http://test.com", "title": "test"
248             });
249             that.equal(editableElement.innerHTML.toLowerCase(), '<a href="http://test.com" title="test">http://test.com/</a> ' + text + '', "Link with caret added correctly");
250             
251             start();
252           });
253         });
254
255   // create table
256     asyncTest("Create table", function() {
257        expect(1);
258       var that = this,
259           editor = new wysihtml5.Editor(this.editableArea1),
260           text = "test";
261         
262       editor.on("load", function() {
263         var editableElement   = that.editableArea1,
264             expectText = '<table style="width: 100%;">' +
265                            '<tbody>' +
266                               '<tr>' +
267                                 '<td>&nbsp;</td>' +
268                                 '<td>&nbsp;</td>' +
269                               '</tr>' +
270                               '<tr>' +
271                                 '<td>&nbsp;</td>' +
272                                 '<td>&nbsp;</td>' +
273                               '</tr>' +
274                             '</tbody>' +
275                           '</table>';
276         editor.setValue(text, true);
277         editor.composer.selection.selectNode(editor.editableElement);
278         editor.composer.commands.exec('createTable', {
279           cols: 2,
280           rows: 2,
281           tableStyle: "width: 100%;"
282         });
283         equal(editableElement.innerHTML.toLowerCase(), expectText, "Text corectly wrapped in one aligning div");
284         start();
285       });
286     });
287
288   // create table
289     asyncTest("Create lists", function() {
290       expect(7);
291       var that = this,
292           editor = new wysihtml5.Editor(this.editableArea1),
293           text = "";
294         
295       editor.on("load", function() {
296         var editableElement   = that.editableArea1,
297             expectText = '<ul><li></li></ul>',
298             expectTextBr = '<ul><li><br></li></ul>',
299             expectTextWithContents = '<ul><li>text</li></ul>',
300             expectTextWithContentsBr = '<ul><li>text<br></li></ul>',
301             expectOrdText = '<ol><li></li></ol>',
302             expectOrdTextBr = '<ol><li><br></li></ol>',
303             expectOrdTextWithContents = '<ol><li>text</li></ol>',
304             expectOrdTextWithContentsBr = '<ol><li>text<br></li></ol>';
305
306         editor.setValue(text, true);
307         editor.composer.selection.selectNode(editor.editableElement);
308         editor.composer.commands.exec('insertUnorderedList');
309         ok(editableElement.innerHTML.toLowerCase() == expectText || editableElement.innerHTML.toLowerCase() == expectTextBr, "Unordered list created");
310
311         editor.composer.commands.exec('insertHTML', 'text');
312         ok(editableElement.innerHTML.toLowerCase() == expectTextWithContents || editableElement.innerHTML.toLowerCase() == expectTextWithContentsBr , "In unordered list placed caret correctly");
313
314         editor.setValue(text, true);
315         editor.composer.selection.selectNode(editor.editableElement);
316         editor.composer.commands.exec('insertOrderedList');
317         ok(editableElement.innerHTML.toLowerCase() == expectOrdText || editableElement.innerHTML.toLowerCase() == expectOrdTextBr, "Ordered list created");
318
319         editor.composer.commands.exec('insertHTML', 'text');
320         ok(editableElement.innerHTML.toLowerCase() == expectOrdTextWithContents || editableElement.innerHTML.toLowerCase() == expectOrdTextWithContentsBr, "In ordered list placed caret correctly");
321
322         editableElement.innerHTML = '<ul><li>test</li><li class="second">test</li><li>test</li></ul>';
323         editor.composer.selection.selectNode(editor.editableElement.querySelector('.second'));
324         editor.composer.commands.exec('indentList');
325         equal(editableElement.innerHTML.toLowerCase(), '<ul><li>test<ul><li class="second">test</li></ul></li><li>test</li></ul>', "List indent increases level correctly");
326
327         editor.composer.commands.exec('outdentList');
328         equal(editableElement.innerHTML.toLowerCase(), '<ul><li>test</li><li class="second">test</li><li>test</li></ul>', "List outdent decreases level correctly");
329
330         editor.composer.commands.exec('outdentList');
331         equal(editableElement.innerHTML.toLowerCase(), '<ul><li>test</li></ul><br>test<ul><li>test</li></ul>', "List outdent escapes current list item correctly out of list");
332
333
334         start();
335       });
336     });
337
338
339   // create blockQuote
340     asyncTest("Create blockquote", function() {
341       expect(4);
342       var that = this,
343         editor = new wysihtml5.Editor(this.editableArea1, {
344           parserRules: {
345             tags: {
346               h1: true,
347               p: true,
348               blockquote: true
349             }
350           }
351         }),
352         text = "<h1>heading</h1><p>text</p>",
353         text2 = "test<h1>heading</h1>test";
354
355       editor.on("load", function() {
356         var editableElement   = that.editableArea1;
357
358         editor.setValue(text, true);
359
360         editor.composer.selection.selectNode(editor.editableElement);
361         editor.composer.commands.exec('insertBlockQuote');
362         equal(editableElement.innerHTML.toLowerCase(), "<blockquote>" + text + "</blockquote>" , "Blockquote created with headings and paragraphs preserved.");
363
364         editor.composer.commands.exec('insertBlockQuote');
365         equal(editableElement.innerHTML.toLowerCase(), text, "Blockquote removed with headings and paragraphs preserved.");
366
367
368         editor.setValue(text2, true);
369         editor.composer.selection.selectNode(editor.editableElement.querySelector('h1'));
370         editor.composer.commands.exec('insertBlockQuote');
371         equal(editableElement.innerHTML.toLowerCase(), "test<blockquote><h1>heading</h1></blockquote>test" , "Blockquote created.");
372
373         editor.composer.commands.exec('insertBlockQuote');
374         equal(editableElement.innerHTML.toLowerCase(), "test<br><h1>heading</h1><br>test" , "Blockquote removed and line breaks added.");
375
376         start();
377       });
378     });
379
380
381   
382 }