1 define(function(require) {
5 /* globals describe, it, afterEach */
7 var $ = require('libs/jquery'),
8 _ = require('libs/underscore'),
9 chai = require('libs/chai'),
10 sinon = require('libs/sinon'),
11 wlxml = require('wlxml/wlxml'),
12 canvas = require('modules/documentCanvas/canvas/canvas'),
13 keyboard = require('modules/documentCanvas/canvas/keyboard'),
14 keyEvent = require('modules/documentCanvas/canvas/keyEvent'),
15 corePlugin = require('./core.js'),
18 var K = keyboard.KEYS;
20 var getDocumentFromXML = function(xml, options) {
21 var doc = wlxml.WLXMLDocumentFromXML(xml, options || {});
22 doc.registerExtension(corePlugin.documentExtension);
27 var getCanvasFromXML = function(xml, elements) {
28 var c = canvas.fromXMLDocument(getDocumentFromXML(xml), elements),
30 view.attr('canvas-test', true);
31 /* globals document */
32 $(document.body).append(view);
35 var removeCanvas = function() {
36 $('[canvas-test]').remove();
39 var getTextNodes = function(text, doc) {
42 var search = function(node) {
43 node.contents().forEach(function(node) {
44 if(node.nodeType === Node.TEXT_NODE) {
45 if(node.getText() === text) {
57 var getTextNode = function(text, doc) {
58 var nodes = getTextNodes(text, doc),
60 if(nodes.length === 0) {
61 error = 'Text not found';
62 } else if(nodes.length > 1) {
63 error = 'Text not unique';
64 } else if(nodes[0].getText() !== text) {
65 error = 'I was trying to cheat your test :(';
68 throw new Error(error);
73 var getTextElement = function(text, c) {
74 var node = getTextNode(text, c.wlxmlDocument),
75 element = node && node.getData('canvasElement');
76 if(!(element && element.getText() === text)) {
83 describe('Document extensions', function() {
84 describe('break content', function() {
85 it('break text into two nodes', function() {
86 var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
87 textNode = doc.root.contents()[0].contents()[0];
89 var result = textNode.breakContent({offset:3});
91 var section = doc.root;
92 expect(section.contents().length).to.equal(2);
93 expect(section.contents()[0].contents()[0].getText()).to.equal('Ali');
94 expect(section.contents()[1].contents()[0].getText()).to.equal('ce');
96 expect(result.first.sameNode(section.contents()[0])).to.equal(true);
97 expect(result.second.sameNode(section.contents()[1])).to.equal(true);
98 expect(result.emptyText).to.equal(undefined, 'no new text node created');
100 it('puts empty text node when breaking at the very beginning', function() {
101 var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
102 textNode = doc.root.contents()[0].contents()[0];
104 var result = textNode.breakContent({offset:0}),
105 firstNode = doc.root.contents()[0];
107 expect(result.emptyText.sameNode(firstNode.contents()[0]));
108 expect(result.emptyText.getText()).to.equal('');
110 it('puts empty text node when breaking at the very end', function() {
111 var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
112 textNode = doc.root.contents()[0].contents()[0];
114 var result = textNode.breakContent({offset:5}),
115 secondNode = doc.root.contents()[1];
117 expect(result.emptyText.sameNode(secondNode.contents()[0]));
118 expect(result.emptyText.getText()).to.equal('');
122 describe('mergin text with preceding content', function() {
123 it('does nothing if text node parent has no preceding element', function() {
124 var doc = getDocumentFromXML('<section><div><div>some text</div></div></section>'),
125 text = getTextNode('some text', doc),
128 doc.on('change', spy);
129 text.mergeContentUp();
130 expect(spy.callCount).to.equal(0);
132 it('does nothing if text node parent is precedeed by text node', function() {
133 var doc = getDocumentFromXML('<section><div></div>another text<div>some text</div></section>'),
134 text = getTextNode('some text', doc),
137 doc.on('change', spy);
138 text.mergeContentUp();
139 expect(spy.callCount).to.equal(0);
141 it('does nothing if text node is not first child of its parent', function() {
142 var doc = getDocumentFromXML('<section><div></div><div><a></a>some text</div></section>'),
143 text = getTextNode('some text', doc),
146 doc.on('change', spy);
147 text.mergeContentUp();
148 expect(spy.callCount).to.equal(0);
150 it('moves text node and its siblings to the block element preceding text node parent', function() {
151 var doc = getDocumentFromXML('<section><div></div><div>some text<span>is</span> here!</div></section>'),
152 text = getTextNode('some text', doc);
154 text.mergeContentUp();
156 var contents = doc.root.contents();
157 expect(contents.length).to.equal(1);
158 expect(contents[0].contents().length).to.equal(3);
159 expect(contents[0].contents()[0].getText()).to.equal('some text');
160 expect(contents[0].contents()[1].getTagName()).to.equal('span');
161 expect(contents[0].contents()[2].getText()).to.equal(' here!');
166 describe('Keyboard interactions', function() {
168 var Keyboard = function(canvas) {
169 this.canvas = canvas;
172 _.extend(Keyboard.prototype, {
173 press: function(key) {
174 this.canvas.triggerKeyEvent(keyEvent.fromParams({key:key}), this.selection);
175 this.selection = this.canvas.getSelection();
178 withCaret: function(where) {
179 var offset = where.indexOf('|'),
180 text = where.split('|').join(''),
181 el = getTextElement(text, this.canvas),
182 selection = this.canvas.createSelection({type: 'caret', element: el, offset: offset});
184 throw new Error('Invalid caret');
186 this.selection = selection;
189 withSelection: function(start, end) {
190 var startOffset = start.indexOf('|'),
191 endOffset = end.indexOf('|'),
192 startText= start.split('|').join(''),
193 endText = end.split('|').join(''),
194 startElement = getTextElement(startText, this.canvas),
195 endElement = getTextElement(endText, this.canvas),
196 selection = this.canvas.createSelection({
197 type: 'textSelection',
198 anchorElement: startElement,
199 anchorOffset: startOffset,
200 focusElement: endElement,
201 focusOffset: endOffset
203 if(startOffset === -1 || endOffset === -1) {
204 throw new Error('Invalid text selection');
206 this.selection = selection;
211 describe('deleting text with selection', function() {
212 afterEach(removeCanvas);
214 [K.BACKSPACE, K.DELETE].forEach(function(key) {
215 it('deletes text withing a single text element ' + key, function() {
216 var c = getCanvasFromXML('<section><div>Alice</div></section>'),
219 k.withSelection('A|lice', 'Alic|e').press(key);
220 expect(c.wlxmlDocument.root.contents()[0].contents()[0].getText()).to.equal('Ae');
223 var selection = c.getSelection();
224 expect(selection.type).to.equal('caret');
225 expect(selection.element.getText()).to.equal('Ae');
226 expect(selection.offset).to.equal(1);
228 it('deletes text across two paragraphs ' + key, function() {
229 var c = getCanvasFromXML('<section><div class="p">Alice</div><div class="p">cat</div></section>'),
232 k.withSelection('A|lice', 'c|at').press(key);
233 var rootContents = c.wlxmlDocument.root.contents();
235 expect(rootContents.length).to.equal(2);
236 expect(rootContents[0].contents()[0].getText()).to.equal('A');
237 expect(rootContents[1].contents()[0].getText()).to.equal('at');
239 var selection = c.getSelection();
240 expect(selection.type).to.equal('caret');
241 expect(selection.element.wlxmlNode.getText()).to.equal(key === K.BACKSPACE ? 'A' : 'at');
244 it('keeps an empty paragraph after deleting its whole text ' + key, function() {
245 var c = getCanvasFromXML('<section><div class="p">Alice</div></section>'),
248 k.withSelection('|Alice', 'Alice|').press(key);
249 var rootContents = c.wlxmlDocument.root.contents();
251 expect(rootContents.length).to.equal(1);
252 expect(rootContents[0].contents()[0].getText()).to.equal('');
254 var selection = c.getSelection();
255 expect(selection.type).to.equal('caret');
256 expect(selection.element.wlxmlNode.parent().sameNode(c.wlxmlDocument.root.contents()[0]));
263 describe('backspace at the beginning of a block', function() {
264 afterEach(removeCanvas);
266 it('merges two adjacent paragraphs', function() {
267 var c = getCanvasFromXML('<section><div class="p">A</div><div class="p">B</div></section>'),
270 k.withCaret('|B').press(K.BACKSPACE);
272 var rootContents = c.wlxmlDocument.root.contents();
273 expect(rootContents.length).to.equal(1);
274 expect(rootContents[0].getClass()).to.equal('p');
275 expect(rootContents[0].contents()[0].getText()).to.equal('AB');
277 var selection = c.getSelection();
278 expect(selection.type).to.equal('caret');
279 expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
280 expect(selection.offset).to.equal(1);
282 it('merges a paragraph with a header', function() {
283 var c = getCanvasFromXML('<section><header>A</header><div class="p">B</div></section>'),
286 k.withCaret('|B').press(K.BACKSPACE);
288 var rootContents = c.wlxmlDocument.root.contents();
289 expect(rootContents.length).to.equal(1);
290 expect(rootContents[0].getTagName()).to.equal('header');
291 expect(rootContents[0].contents()[0].getText()).to.equal('AB');
293 var selection = c.getSelection();
294 expect(selection.type).to.equal('caret');
295 expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
296 expect(selection.offset).to.equal(1);
298 it('merges two adjacent headers', function() {
299 var c = getCanvasFromXML('<section><header>A</header><header>B</header></section>'),
302 k.withCaret('|B').press(K.BACKSPACE);
303 var rootContents = c.wlxmlDocument.root.contents();
304 expect(rootContents.length).to.equal(1);
305 expect(rootContents[0].getTagName()).to.equal('header');
306 expect(rootContents[0].contents()[0].getText()).to.equal('AB');
308 var selection = c.getSelection();
309 expect(selection.type).to.equal('caret');
310 expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
311 expect(selection.offset).to.equal(1);
313 it('merges a header with a paragraph', function() {
314 var c = getCanvasFromXML('<section><div class="p">A</div><header>B</header></section>'),
317 k.withCaret('|B').press(K.BACKSPACE);
319 var rootContents = c.wlxmlDocument.root.contents();
320 expect(rootContents.length).to.equal(1);
321 expect(rootContents[0].is('p')).to.equal(true);
322 expect(rootContents[0].contents()[0].getText()).to.equal('AB');
324 var selection = c.getSelection();
325 expect(selection.type).to.equal('caret');
326 expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
327 expect(selection.offset).to.equal(1);
329 it('merges a paragraph into a last list item', function() {
330 var c = getCanvasFromXML('<section><div class="list"><div class="item">item</div></div><div class="p">paragraph</div></section>'),
331 list = c.wlxmlDocument.root.contents()[0],
334 k.withCaret('|paragraph').press(K.BACKSPACE);
336 var rootContents = c.wlxmlDocument.root.contents();
337 expect(rootContents.length).to.equal(1);
338 expect(rootContents[0].sameNode(list)).to.equal(true);
340 var items = list.contents();
341 expect(items.length).to.equal(1);
342 expect(items[0].contents()[0].getText()).to.equal('itemparagraph');
344 var selection = c.getSelection();
345 expect(selection.type).to.equal('caret');
346 expect(selection.element.sameNode(getTextElement('itemparagraph', c))).to.equal(true);
347 expect(selection.offset).to.equal(4);
349 it('merges a list item with a list item', function() {
350 var c = getCanvasFromXML('<section><div class="list"><div class="item">item1</div><div class="item">item2</div></div></section>'),
351 list = c.wlxmlDocument.root.contents()[0],
354 k.withCaret('|item2').press(K.BACKSPACE);
356 var rootContents = c.wlxmlDocument.root.contents();
357 expect(rootContents.length).to.equal(1);
359 expect(rootContents[0].sameNode(list)).to.equal(true);
361 var items = list.contents();
363 expect(items.length).to.equal(1);
364 expect(items[0].contents()[0].getText()).to.equal('item1item2');
366 var selection = c.getSelection();
367 expect(selection.type).to.equal('caret');
368 expect(selection.element.sameNode(getTextElement('item1item2', c))).to.equal(true);
369 expect(selection.offset).to.equal(5);
371 it('creates a new paragraph preceding the list from a first list item', function() {
372 var c = getCanvasFromXML('<section><div class="list"><div class="item">item1</div><div class="item">item2</div></div></section>'),
373 list = c.wlxmlDocument.root.contents()[0],
376 k.withCaret('|item1').press(K.BACKSPACE);
378 var rootContents = c.wlxmlDocument.root.contents();
379 expect(rootContents.length).to.equal(2);
381 expect(rootContents[0].getClass()).to.equal('p');
382 expect(rootContents[0].contents()[0].getText()).to.equal('item1');
384 expect(rootContents[1].sameNode(list)).to.equal(true);
386 var selection = c.getSelection();
387 expect(selection.type).to.equal('caret');
388 expect(selection.element.sameNode(getTextElement('item1', c))).to.equal(true);
389 expect(selection.offset).to.equal(0);
391 it('removes list after moving up its only item', function() {
392 var c = getCanvasFromXML('<section><div class="list"><div class="item">item</div></div></section>'),
395 k.withCaret('|item').press(K.BACKSPACE);
396 var rootContents = c.wlxmlDocument.root.contents();
397 expect(rootContents.length).to.equal(1);
399 expect(rootContents[0].getClass()).to.equal('p');
400 expect(rootContents[0].contents()[0].getText()).to.equal('item');
402 var selection = c.getSelection();
403 expect(selection.type).to.equal('caret');
404 expect(selection.element.sameNode(getTextElement('item', c))).to.equal(true);
405 expect(selection.offset).to.equal(0);
409 describe('backspace at the beginning of a span', function() {
410 afterEach(removeCanvas);
412 it('deletes span if it contains only one character', function() {
413 var c = getCanvasFromXML('<section>Alice<span class="emp">h</span>a cat</section>'),
416 k.withCaret('h|').press(K.BACKSPACE);
418 var rootContents = c.wlxmlDocument.root.contents();
419 expect(rootContents.length).to.equal(1);
420 expect(rootContents[0].getText()).to.equal('Alicea cat');
422 var selection = c.getSelection();
423 expect(selection.type).to.equal('caret');
424 expect(selection.element.sameNode(getTextElement('Alicea cat', c))).to.equal(true);
425 expect(selection.offset).to.equal(5);
428 it('deletes from the end of the preceding text element', function() {
429 var c = getCanvasFromXML('<section>Alice<span>has a cat</span></section>'),
432 k.withCaret('|has a cat').press(K.BACKSPACE);
434 var rootContents = c.wlxmlDocument.root.contents();
435 expect(rootContents.length).to.equal(2);
436 expect(rootContents[0].getText()).to.equal('Alic');
438 var selection = c.getSelection();
439 expect(selection.type).to.equal('caret');
440 expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
441 expect(selection.offset).to.equal(0);
444 it('deletes from the end of the preceding text element - multiple spans', function() {
445 var c = getCanvasFromXML('<section>Alice<span><span>has a cat</span></span></section>'),
448 k.withCaret('|has a cat').press(K.BACKSPACE);
450 var rootContents = c.wlxmlDocument.root.contents();
451 expect(rootContents.length).to.equal(2);
452 expect(rootContents[0].getText()).to.equal('Alic');
454 var selection = c.getSelection();
455 expect(selection.type).to.equal('caret');
456 expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
457 expect(selection.offset).to.equal(0);
460 it('deletes from the end of the preceding span element content', function() {
461 var c = getCanvasFromXML('<section><span>Alice</span><span>has a cat</span></section>'),
464 k.withCaret('|has a cat').press(K.BACKSPACE);
466 var rootContents = c.wlxmlDocument.root.contents();
467 expect(rootContents.length).to.equal(2);
468 expect(rootContents[0].is({tagName: 'span'})).to.equal(true);
469 expect(rootContents[0].contents()[0].getText()).to.equal('Alic');
471 expect(rootContents[1].contents()[0].getText()).to.equal('has a cat');
473 var selection = c.getSelection();
474 expect(selection.type).to.equal('caret');
475 expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
476 expect(selection.offset).to.equal(0);
479 it('deletes from the end of the preceding span element content - multiple spans', function() {
480 var c = getCanvasFromXML('<section><span>Alice</span><span><span>has a cat</span></span></section>'),
483 k.withCaret('|has a cat').press(K.BACKSPACE);
485 var rootContents = c.wlxmlDocument.root.contents();
486 expect(rootContents.length).to.equal(2);
487 expect(rootContents[0].is({tagName: 'span'})).to.equal(true);
488 expect(rootContents[0].contents()[0].getText()).to.equal('Alic');
490 var outerSpan = rootContents[1];
491 expect(outerSpan.is({tagName: 'span'})).to.equal(true);
493 var innerSpan = outerSpan.contents()[0];
494 expect(innerSpan.contents()[0].getText()).to.equal('has a cat');
496 var selection = c.getSelection();
497 expect(selection.type).to.equal('caret');
498 expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
499 expect(selection.offset).to.equal(0);
502 it('merges two paragrahps if span is a first content of the second paragraph', function() {
503 var c = getCanvasFromXML('<section><div class="p">para</div><div class="p"><span>Alice</span> has a cat</div></section>'),
506 k.withCaret('|Alice').press(K.BACKSPACE);
508 var rootContents = c.wlxmlDocument.root.contents();
510 expect(rootContents.length).to.equal(1, 'single paragraph left');
512 var p = rootContents[0],
513 pContents = p.contents();
515 expect(p.is('p')).to.equal(true);
517 expect(pContents.length).to.equal(3);
518 expect(pContents[0].getText()).to.equal('para');
519 expect(pContents[1].contents().length).to.equal(1);
520 expect(pContents[1].contents()[0].getText()).to.equal('Alice');
522 expect(pContents[2].getText()).to.equal(' has a cat');
524 var selection = c.getSelection();
525 expect(selection.type).to.equal('caret');
526 expect(selection.element.sameNode(getTextElement('Alice', c))).to.equal(true);
527 expect(selection.offset).to.equal(0);
531 describe('backspace before a span', function() {
532 it('deletes from the end of a span', function() {
533 var c = getCanvasFromXML('<section><span>Alice</span>has a cat</section>'),
536 k.withCaret('|has a cat').press(K.BACKSPACE);
538 var rootContents = c.wlxmlDocument.root.contents();
539 expect(rootContents.length).to.equal(2);
540 expect(rootContents[0].is({tagName: 'span'})).to.equal(true);
541 expect(rootContents[0].contents()[0].getText()).to.equal('Alic');
542 expect(rootContents[1].getText()).to.equal('has a cat');
544 var selection = c.getSelection();
545 expect(selection.type).to.equal('caret');
546 expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
547 expect(selection.offset).to.equal(0);
549 it('deletes span if it contains only one character (1)', function() {
550 var c = getCanvasFromXML('<section>Alice <span>h</span> a cat</section>'),
553 k.withCaret('| a cat').press(K.BACKSPACE);
555 var rootContents = c.wlxmlDocument.root.contents();
556 expect(rootContents.length).to.equal(1);
557 expect(rootContents[0].getText()).to.equal('Alice a cat');
559 var selection = c.getSelection();
560 expect(selection.type).to.equal('caret');
561 expect(selection.element.sameNode(getTextElement('Alice a cat', c))).to.equal(true);
562 expect(selection.offset).to.equal(6);
564 it('deletes span if it contains only one character (2)', function() {
565 var c = getCanvasFromXML('<section><span>a</span><span>b</span></section>'),
568 k.withCaret('|b').press(K.BACKSPACE);
570 var rootContents = c.wlxmlDocument.root.contents();
571 expect(rootContents.length).to.equal(1);
572 expect(rootContents[0].contents()[0].getText()).to.equal('b');
574 var selection = c.getSelection();
575 expect(selection.type).to.equal('caret');
576 expect(selection.element.sameNode(getTextElement('b', c))).to.equal(true);
577 expect(selection.offset).to.equal(0);
581 describe('splitting with enter', function() {
582 afterEach(removeCanvas);
584 it('splits paragraph into two in the middle', function() {
585 var c = getCanvasFromXML('<section><div class="p">paragraph</div></section>'),
588 k.withCaret('para|graph').press(K.ENTER);
590 var rootContents = c.wlxmlDocument.root.contents();
591 expect(rootContents.length).to.equal(2);
592 expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
593 expect(rootContents[0].contents()[0].getText()).to.equal('para');
594 expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
595 expect(rootContents[1].contents()[0].getText()).to.equal('graph');
597 var selection = c.getSelection();
598 expect(selection.type).to.equal('caret');
599 expect(selection.element.sameNode(getTextElement('graph', c))).to.equal(true);
600 expect(selection.offset).to.equal(0);
602 it('splits paragraph into two at the beginning', function() {
603 var c = getCanvasFromXML('<section><div class="p">paragraph</div></section>'),
606 k.withCaret('|paragraph').press(K.ENTER);
608 var rootContents = c.wlxmlDocument.root.contents();
609 expect(rootContents.length).to.equal(2);
610 expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
611 expect(rootContents[0].contents()[0].getText()).to.equal('');
612 expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
613 expect(rootContents[1].contents()[0].getText()).to.equal('paragraph');
615 var selection = c.getSelection();
616 expect(selection.type).to.equal('caret');
617 expect(selection.element.sameNode(getTextElement('', c))).to.equal(true);
618 expect(selection.offset).to.equal(0);
620 it('splits paragraph into two at the end', function() {
621 var c = getCanvasFromXML('<section><div class="p">paragraph</div></section>'),
624 k.withCaret('paragraph|').press(K.ENTER);
626 var rootContents = c.wlxmlDocument.root.contents();
627 expect(rootContents.length).to.equal(2);
628 expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
629 expect(rootContents[0].contents()[0].getText()).to.equal('paragraph');
630 expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
631 expect(rootContents[1].contents()[0].getText()).to.equal('');
633 var selection = c.getSelection();
634 expect(selection.type).to.equal('caret');
635 expect(selection.element.sameNode(getTextElement('', c))).to.equal(true);
636 expect(selection.offset).to.equal(0);
639 it('does nothing on an empty paragraph', function() {
640 var c = getCanvasFromXML('<section><div class="p">a</div></section>'),
644 k.withCaret('a|').press(K.BACKSPACE);
645 c.wlxmlDocument.on('change', spy);
647 expect(spy.callCount).to.equal(0);
650 it('splits its parent box if inside a span', function() {
651 var c = getCanvasFromXML('<section><div class="p">this <span>is</span> a paragraph</div></section>'),
654 k.withCaret('i|s').press(K.ENTER);
656 var rootContents = c.wlxmlDocument.root.contents();
658 expect(rootContents.length).to.equal(2);
660 var p1 = rootContents[0],
661 p2 = rootContents[1];
663 expect(p1.is({tagName: 'div', klass: 'p'})).to.equal(true);
664 expect(p2.is({tagName: 'div', klass: 'p'})).to.equal(true);
666 var p1Contents = p1.contents(),
667 p2Contents = p2.contents();
669 expect(p1Contents[0].getText()).to.equal('this ');
670 expect(p1Contents[1].is({tagName: 'span'})).to.equal(true);
671 expect(p1Contents[1].contents()[0].getText()).to.equal('i');
674 expect(p2Contents[0].is({tagName: 'span'})).to.equal(true);
675 expect(p2Contents[0].contents()[0].getText()).to.equal('s');
676 expect(p2Contents[1].getText()).to.equal(' a paragraph');
678 var selection = c.getSelection();
679 expect(selection.element.sameNode(getTextElement('s', c))).to.equal(true);
680 expect(selection.offset).to.equal(0);
683 it('splits its parent box if inside a double span', function() {
684 var c = getCanvasFromXML('<section><div class="p">this <span test="outer"><span test="inner">is</span></span> a paragraph</div></section>'),
687 k.withCaret('i|s').press(K.ENTER);
689 var rootContents = c.wlxmlDocument.root.contents();
691 expect(rootContents.length).to.equal(2);
693 var p1 = rootContents[0],
694 p2 = rootContents[1];
696 expect(p1.is({tagName: 'div', klass: 'p'})).to.equal(true);
697 expect(p2.is({tagName: 'div', klass: 'p'})).to.equal(true);
699 var p1Contents = p1.contents(),
700 p2Contents = p2.contents();
702 /* first paragraph */
703 expect(p1Contents[0].getText()).to.equal('this ');
705 var outer1 = p1Contents[1];
706 expect(outer1.getAttr('test')).to.equal('outer');
707 expect(outer1.contents().length).to.equal(1);
708 var inner1 = outer1.contents()[0];
709 expect(inner1.getAttr('test')).to.equal('inner');
710 expect(inner1.contents()[0].getText()).to.equal('i');
712 /* second paragraph */
713 var outer2 = p2Contents[0];
714 expect(outer2.getAttr('test')).to.equal('outer');
715 expect(outer2.contents().length).to.equal(1);
716 var inner2 = outer2.contents()[0];
717 expect(inner2.getAttr('test')).to.equal('inner');
718 expect(inner2.contents()[0].getText()).to.equal('s');
720 expect(p2Contents[1].getText()).to.equal(' a paragraph');
723 var selection = c.getSelection();
724 expect(selection.element.sameNode(getTextElement('s', c))).to.equal(true);
725 expect(selection.offset).to.equal(0);
729 describe('Enter on a list items', function() {
730 afterEach(removeCanvas);
732 it('creates a paragraph after a list if hitting enter on the last and empty list item', function() {
733 var c = getCanvasFromXML('<section><div class="list"><div class="item">item</div></div></section>'),
736 k.withCaret('item|').press(K.ENTER).press(K.ENTER);
738 var rootContents = c.wlxmlDocument.root.contents();
739 expect(rootContents.length).to.equal(2);
740 expect(rootContents[0].is('list')).to.equal(true);
741 expect(rootContents[1].is('p')).to.equal(true);
743 var list = rootContents[0];
744 expect(list.contents().length).to.equal(1);
746 var selection = c.getSelection();
747 expect(selection.element.wlxmlNode.sameNode(rootContents[1].contents()[0])).to.equal(true);
748 expect(selection.offset).to.equal(0);
752 describe('Deleting text from a node', function() {
753 it('deletes last character with backspace', function() {
754 var c = getCanvasFromXML('<section><div class="p">a</div><div class="p">b</div></section>'),
757 k.withCaret('b|').press(K.BACKSPACE);
759 var rootContents = c.wlxmlDocument.root.contents();
760 expect(rootContents.length).to.equal(2);
761 expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
762 expect(rootContents[0].contents()[0].getText()).to.equal('a');
763 expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
764 expect(rootContents[1].contents()[0].getText()).to.equal('');
766 var selection = c.getSelection();
767 expect(selection.type).to.equal('caret');
768 expect(selection.element.sameNode(getTextElement('', c))).to.equal(true);
769 expect(selection.offset).to.equal(0);