4 'modules/documentCanvas/canvas/canvas',
5 'modules/documentCanvas/canvas/documentElement'
6 ], function(chai, sinon, canvas, documentElement) {
10 var expect = chai.expect;
13 describe('Canvas', function() {
15 describe('Internal HTML representation of a sample document', function() {
16 it('works', function() {
17 var c = canvas.fromXML('\
19 This is some text without its own wrapping tag.\
20 <div class="p.subclass">\
24 This is text in a div <span>with some inline text</span>.\
26 This is some text without its own wrapping tag.\
29 var expected = '<div wlxml-tag="section">'
30 + 'This is some text without its own wrapping tag.'
31 + '<div wlxml-tag="div" wlxml-class="p-subclass">This is a paragraph.</div>'
32 + '<div wlxml-tag="div">This is text in a div <div wlxml-tag="span">with some inline text</div>.</div>'
33 + 'This is some text without its own wrapping tag.'
35 expect(c.doc().dom()[0].isEqualNode($(expected)[0])).to.be.true;
39 describe('Internal HTML representation of a DocumentNodeElement', function() {
40 it('is always a div tag', function() {
41 ['section', 'header', 'span', 'aside', 'figure'].forEach(function(tagName) {
42 var dom = canvas.fromXML('<' + tagName + '></' + tagName + '>').doc().dom();
43 expect(dom.prop('tagName')).to.equal('DIV', tagName + ' is represented as div');
46 it('has wlxml tag put into wlxml-tag attribute', function() {
47 var dom = canvas.fromXML('<section></section>').doc().dom();
48 expect(dom.attr('wlxml-tag')).to.equal('section');
50 it('has wlxml class put into wlxml-class, dots replaced with dashes', function() {
51 var dom = canvas.fromXML('<section class="some.class"></section>').doc().dom();
52 expect(dom.attr('wlxml-class')).to.equal('some-class');
56 describe('Internal HTML representation of a DocumentTextElement', function() {
57 it('is just a TextNode', function() {
58 var dom = canvas.fromXML('<section>Alice</section>').doc().children()[0].dom();
59 expect(dom[0].nodeType === Node.TEXT_NODE);
63 describe('basic properties', function() {
64 it('renders empty document when canvas created from empty XML', function() {
65 var c = canvas.fromXML('');
66 expect(c.doc()).to.equal(null);
69 it('gives access to its document root node', function() {
70 var c = canvas.fromXML('<section></section>');
71 expect(c.doc().getWlxmlTag()).to.equal('section');
74 describe('DocumentTextElement', function() {
75 it('can have its content set', function() {
76 var c = canvas.fromXML('<section>Alice</section>'),
78 text = root.children()[0];
80 text.setText('a cat');
81 expect(root.children()[0].getText()).to.equal('a cat');
85 describe('DocumentNodeElement', function() {
86 it('knows index of its child', function() {
87 var c = canvas.fromXML('<section><div></div><header></header><span></span></section>'),
89 child = root.children()[1];
90 expect(root.childIndex(child)).to.equal(1);
93 it('knows WLXML tag it renders', function(){
94 var c = canvas.fromXML('<section></section>'),
96 expect(section.getWlxmlTag()).to.equal('section', 'initial tag is section');
97 section.setWlxmlTag('header');
98 expect(section.getWlxmlTag()).to.equal('header', 'tag is changed to header');
101 it('knows WLXML class of a WLXML tag it renders', function(){
102 var c = canvas.fromXML('<section class="some.class"></section>'),
104 expect(section.getWlxmlClass()).to.equal('some.class');
105 section.setWlxmlClass('some.other.class');
106 expect(section.getWlxmlClass()).to.equal('some.other.class');
107 section.setWlxmlClass(null);
108 expect(section.getWlxmlClass()).to.be.undefined;
112 it('returns DocumentNodeElement instance from HTMLElement', function() {
113 var c = canvas.fromXML('<section></section>'),
114 htmlElement = c.doc().dom().get(0),
115 element = c.getDocumentElement(htmlElement);
116 expect(element).to.be.instanceOf(documentElement.DocumentNodeElement);
117 expect(element.sameNode(c.doc()));
120 it('returns DocumentTextElement instance from Text Node', function() {
121 var c = canvas.fromXML('<section>Alice</section>'),
122 textNode = c.doc().children(0)[0].dom().get(0),
123 element = c.getDocumentElement(textNode);
124 expect(element).to.be.instanceOf(documentElement.DocumentTextElement);
125 expect(element.sameNode(c.doc().children()[0]));
131 describe('document representation api', function() {
132 describe('document root element', function() {
133 var c = canvas.fromXML('<section></section>');
134 it('exists', function() {
135 expect(c.doc()).to.be.instanceOf(documentElement.DocumentElement);
137 it('is of type DocumentNodeElement', function() {
138 expect(c.doc()).to.be.instanceOf(documentElement.DocumentNodeElement);
142 describe('DocumentElements comparison', function() {
143 it('reports dwo DocumentElements to be the same when they represent the same wlxml document element', function() {
144 var c = canvas.fromXML('<section><div></div><div></div></section>'),
145 first_div1 = c.doc().children()[0],
146 first_div2 = c.doc().children()[0],
147 second_div = c.doc().children()[1];
148 expect(first_div1.sameNode(first_div1)).to.be.true;
149 expect(first_div1.sameNode(first_div2)).to.be.true;
150 expect(first_div1.sameNode(second_div)).to.be.false;
154 describe('traversing', function() {
155 it('reports element nodes', function() {
156 var c = canvas.fromXML('<section><div></div></section>'),
157 children = c.doc().children();
158 expect(children.length).to.equal(1);
159 expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
161 c = canvas.fromXML('<section><div></div><div></div></section>'),
162 children = c.doc().children();
163 expect(children.length).to.equal(2);
164 expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
165 expect(children[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
168 it('reports text nodes', function() {
169 var c = canvas.fromXML('<section>Alice</section>'),
170 children = c.doc().children();
171 expect(children.length).to.equal(1);
172 expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
175 describe('accessing parents', function() {
176 it('returns DocumentNodeElement representing parent in wlxml document as DocumentNodeElement parent', function() {
177 var c = canvas.fromXML('<section><div></div></section>'),
178 div = c.doc().children()[0];
179 expect(div.parent().sameNode(c.doc())).to.be.true;
181 it('returns DocumentNodeElement representing parent in wlxml document as DocumentTextElement parent', function() {
182 var c = canvas.fromXML('<section>Alice</section>'),
183 text = c.doc().children()[0];
184 expect(text.parent().sameNode(c.doc())).to.be.true;
188 describe('free text handling', function() {
189 it('sees free text', function() {
190 var c = canvas.fromXML('<section>Alice <span>has</span> a cat</section>'),
191 children = c.doc().children();
192 expect(children.length).to.equal(3);
193 expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
194 expect(children[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
195 expect(children[2]).to.be.instanceOf(documentElement.DocumentTextElement);
199 describe('white characters handling', function() {
200 it('says empty element node has no children', function() {
201 var c = canvas.fromXML('<section></section>');
202 expect(c.doc().children().length).to.equal(0);
204 it('says element node with one space has one DocumentTextElement', function() {
205 var c = canvas.fromXML('<section> </section>');
206 expect(c.doc().children().length).to.equal(1);
207 expect(c.doc().children()[0]).to.be.instanceOf(documentElement.DocumentTextElement);
208 expect(c.doc().children()[0].getText()).to.equal(' ');
210 it('ignores white space surrounding block elements', function() {
211 var c = canvas.fromXML('<section> <div></div> </section>');
212 var children = c.doc().children();
213 expect(children.length).to.equal(1);
214 expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
216 it('ignores white space between block elements', function() {
217 var c = canvas.fromXML('<section><div></div> <div></div></section>');
218 var children = c.doc().children();
219 expect(children.length === 2);
220 [0,1].forEach(function(idx) {
221 expect(children[idx]).to.be.instanceOf(documentElement.DocumentNodeElement);
225 it('trims white space from the beginning and the end of the block elements', function() {
226 var c = canvas.fromXML('<section> Alice <span>has</span> a cat </section>');
227 expect(c.doc().children()[0].getText()).to.equal('Alice ');
228 expect(c.doc().children()[2].getText()).to.equal(' a cat');
231 it('normalizes string of white characters to one space at the inline element boundries', function() {
232 var c = canvas.fromXML('<span> Alice has a cat </span>');
233 expect(c.doc().children()[0].getText()).to.equal(' Alice has a cat ');
236 it('normalizes string of white characters to one space before inline element', function() {
237 var c = canvas.fromXML('<div>Alice has <span>a cat</span></div>');
238 expect(c.doc().children()[0].getText()).to.equal('Alice has ');
241 it('normalizes string of white characters to one space after inline element', function() {
242 var c = canvas.fromXML('<div>Alice has <span>a</span> cat</div>');
243 expect(c.doc().children()[2].getText()).to.equal(' cat');
248 describe('manipulation api', function() {
250 describe('Basic Element inserting', function() {
251 it('can put new NodeElement at the end', function() {
252 var c = canvas.fromXML('<section></section>'),
253 appended = c.doc().append({tag: 'header', klass: 'some.class'}),
254 children = c.doc().children();
256 expect(children.length).to.equal(1);
257 expect(children[0].sameNode(appended));
260 it('can put new TextElement at the end', function() {
261 var c = canvas.fromXML('<section></section>'),
262 appended = c.doc().append({text: 'Alice'}),
263 children = c.doc().children();
265 expect(children.length).to.equal(1);
266 expect(children[0].sameNode(appended));
267 expect(children[0].getText()).to.equal('Alice');
270 it('can put new NodeElement after another NodeElement', function() {
271 var c = canvas.fromXML('<section><div></div></section>'),
272 div = c.doc().children()[0],
273 added = div.after({tag: 'header', klass: 'some.class'}),
274 children = c.doc().children();
275 expect(children.length).to.equal(2);
276 expect(children[1].sameNode(added));
279 it('can put new Nodeelement before another element', function() {
280 var c = canvas.fromXML('<section><div></div></section>'),
281 div = c.doc().children()[0],
282 added = div.before({tag: 'header', klass: 'some.class'}),
283 children = c.doc().children();
284 expect(children.length).to.equal(2);
285 expect(children[0].sameNode(added));
288 it('can put new DocumentNodeElement after DocumentTextElement', function() {
289 var c = canvas.fromXML('<section>Alice</section>'),
290 text = c.doc().children()[0],
291 added = text.after({tag: 'p'}),
292 children = c.doc().children();
294 expect(children.length).to.equal(2);
295 expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
296 expect(children[0].getText()).to.equal('Alice');
297 expect(children[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
298 expect(children[1].sameNode(added)).to.be.true;
300 it('can put new DocumentNodeElement before DocumentTextElement', function() {
301 var c = canvas.fromXML('<section>Alice</section>'),
302 text = c.doc().children()[0],
303 added = text.before({tag: 'p'}),
304 children = c.doc().children();
306 expect(children.length).to.equal(2);
307 expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
308 expect(children[0].sameNode(added)).to.be.true;
309 expect(children[1]).to.be.instanceOf(documentElement.DocumentTextElement);
310 expect(children[1].getText()).to.equal('Alice');
314 describe('Splitting text', function() {
316 it('splits DocumentTextElement\'s parent into two DocumentNodeElements of the same type', function() {
317 var c = canvas.fromXML('<section><header>Some header</header></section>'),
319 text = section.children()[0].children()[0];
321 text.split({offset: 5});
322 expect(section.children().length).to.equal(2, 'section has two children');
324 var header1 = section.children()[0];
325 var header2 = section.children()[1];
327 expect(header1.getWlxmlTag()).to.equal('header', 'first section child represents wlxml header');
328 expect(header1.children().length).to.equal(1, 'first header has one text child');
329 expect(header1.children()[0].getText()).to.equal('Some ', 'first header has correct content');
330 expect(header2.getWlxmlTag()).to.equal('header', 'second section child represents wlxml header');
331 expect(header2.children().length).to.equal(1, 'second header has one text child');
332 expect(header2.children()[0].getText()).to.equal('header', 'second header has correct content');
335 it('leaves empty copy of DocumentNodeElement if splitting at the very beginning', function() {
336 var c = canvas.fromXML('<section><header>Some header</header></section>'),
338 text = section.children()[0].children()[0];
340 text.split({offset: 0});
342 var header1 = section.children()[0];
343 var header2 = section.children()[1];
345 expect(header1.children().length).to.equal(0);
346 expect(header2.children()[0].getText()).to.equal('Some header');
349 it('leaves empty copy of DocumentNodeElement if splitting at the very end', function() {
350 var c = canvas.fromXML('<section><header>Some header</header></section>'),
352 text = section.children()[0].children()[0];
354 text.split({offset: 11});
356 var header1 = section.children()[0];
357 var header2 = section.children()[1];
359 expect(header1.children()[0].getText()).to.equal('Some header');
360 expect(header2.children().length).to.equal(0);
363 it('keeps DocumentTextElement\'s parent\'s children elements intact', function() {
364 var c = canvas.fromXML('\
367 A <span>fancy</span> and <span>nice</span> header\
371 header = section.children()[0],
372 textAnd = header.children()[2];
374 textAnd.split({offset: 2});
376 var sectionChildren = section.children();
377 expect(sectionChildren.length).to.equal(2, 'Section has two children');
378 expect(sectionChildren[0].getWlxmlTag()).to.equal('header', 'First section element is a wlxml header');
379 expect(sectionChildren[1].getWlxmlTag()).to.equal('header', 'Second section element is a wlxml header');
381 var firstHeaderChildren = sectionChildren[0].children();
382 expect(firstHeaderChildren.length).to.equal(3, 'First header has three children');
383 expect(firstHeaderChildren[0].getText()).to.equal('A ', 'First header starts with a text');
384 expect(firstHeaderChildren[1].getWlxmlTag()).to.equal('span', 'First header has span in the middle');
385 expect(firstHeaderChildren[2].getText()).to.equal(' a', 'First header ends with text');
387 var secondHeaderChildren = sectionChildren[1].children();
388 expect(secondHeaderChildren.length).to.equal(3, 'Second header has three children');
389 expect(secondHeaderChildren[0].getText()).to.equal('nd ', 'Second header starts with text');
390 expect(secondHeaderChildren[1].getWlxmlTag()).to.equal('span', 'Second header has span in the middle');
391 expect(secondHeaderChildren[2].getText()).to.equal(' header', 'Second header ends with text');
395 describe('wrapping', function() {
396 it('wraps DocumentNodeElement', function() {
397 var c = canvas.fromXML('<section><div></div></section>'),
398 div = c.doc().children()[0];
400 var returned = div.wrapWithNodeElement({tag: 'header', klass: 'some.class'}),
401 parent = div.parent(),
402 parent2 = c.doc().children()[0];
404 expect(returned.sameNode(parent)).to.be.true;
405 expect(returned.sameNode(parent2)).to.be.true;
406 expect(returned.getWlxmlTag()).to.equal('header');
407 expect(returned.getWlxmlClass()).to.equal('some.class');
409 it('wraps DocumentTextElement', function() {
410 var c = canvas.fromXML('<section>Alice</section>'),
411 text = c.doc().children()[0];
413 var returned = text.wrapWithNodeElement({tag: 'header', klass: 'some.class'}),
414 parent = text.parent(),
415 parent2 = c.doc().children()[0];
417 expect(returned.sameNode(parent)).to.be.true;
418 expect(returned.sameNode(parent2)).to.be.true;
419 expect(returned.getWlxmlTag()).to.equal('header');
420 expect(returned.getWlxmlClass()).to.equal('some.class');
423 describe('wrapping part of DocumentTextElement', function() {
424 [{start: 5, end: 12}, {start: 12, end: 5}].forEach(function(offsets) {
425 it('wraps in the middle ' + offsets.start + '/' + offsets.end, function() {
426 var c = canvas.fromXML('<section>Alice has a cat</section>'),
427 text = c.doc().children()[0];
429 var returned = text.wrapWithNodeElement({tag: 'header', klass: 'some.class', start: offsets.start, end: offsets.end}),
430 children = c.doc().children();
432 expect(children.length).to.equal(3);
434 expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
435 expect(children[0].getText()).to.equal('Alice');
437 expect(children[1].sameNode(returned)).to.be.true;
438 expect(returned.getWlxmlTag()).to.equal('header');
439 expect(returned.getWlxmlClass()).to.equal('some.class');
440 expect(children[1].children().length).to.equal(1);
441 expect(children[1].children()[0].getText()).to.equal(' has a ');
443 expect(children[2]).to.be.instanceOf(documentElement.DocumentTextElement);
444 expect(children[2].getText()).to.equal('cat');
448 it('wraps whole text inside DocumentTextElement if offsets span entire content', function() {
449 var c = canvas.fromXML('<section>Alice has a cat</section>'),
450 text = c.doc().children()[0];
452 var returned = text.wrapWithNodeElement({tag: 'header', klass: 'some.class', start: 0, end: 15}),
453 children = c.doc().children();
455 expect(children.length).to.equal(1);
456 expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
457 expect(children[0].children()[0].getText()).to.equal('Alice has a cat');
461 it('wraps text spanning multiple sibling DocumentTextNodes', function() {
462 var c = canvas.fromXML('<section>Alice has a <span>small</span> cat</section>'),
464 wrapper = c.wrapText({
466 _with: {tag: 'span', klass: 'some.class'},
472 expect(section.children().length).to.equal(2);
473 expect(section.children()[0]).to.be.instanceOf(documentElement.DocumentTextElement);
474 expect(section.children()[0].getText()).to.equal('Alice ');
476 var wrapper2 = section.children()[1];
477 expect(wrapper2.sameNode(wrapper)).to.be.true;
479 var wrapperChildren = wrapper.children();
480 expect(wrapperChildren.length).to.equal(3);
481 expect(wrapperChildren[0].getText()).to.equal('has a ');
483 expect(wrapperChildren[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
484 expect(wrapperChildren[1].children().length).to.equal(1);
485 expect(wrapperChildren[1].children()[0].getText()).to.equal('small');
487 expect(wrapperChildren[2].getText()).to.equal(' cat');
491 describe('unwrapping', function() {
492 it('unwraps DocumentTextElement from its parent DocumentNodeElement if it\'s its only child', function() {
493 var c = canvas.fromXML('<section><div>Alice has a cat</div></section>'),
495 text = section.children()[0].children()[0];
499 expect(section.children().length).to.equal(1);
500 expect(section.children()[0].getText()).to.equal('Alice has a cat');
505 describe('Lists api', function() {
506 describe('creating lists', function() {
507 it('allows creation of a list from existing sibling DocumentElements', function() {
508 var c = canvas.fromXML('\
516 textHas = section.children()[1],
517 divA = section.children()[2]
519 c.list.create({element1: textHas, element2: divA});
521 expect(section.children().length).to.equal(3, 'section has three child elements');
523 var child1 = section.children()[0],
524 list = section.children()[1],
525 child3 = section.children()[2];
527 expect(child1.getText()).to.equal('Alice');
528 expect(list.is('list')).to.equal(true, 'second child is a list');
529 expect(list.children().length).to.equal(2, 'list contains two elements');
530 list.children().forEach(function(child) {
531 expect(child.getWlxmlClass()).to.equal('item', 'list childs have wlxml class of item');
533 expect(child3.children()[0].getText()).to.equal('cat');
536 it('allows creating nested list from existing sibling list items', function() {
537 var c = canvas.fromXML('\
539 <div class="list-items">\
540 <div class="item">A</div>\
541 <div class="item">B</div>\
542 <div class="item">C</div>\
543 <div class="item">D</div>\
546 outerList = c.doc().children()[0],
547 itemB = outerList.children()[1],
548 itemC = outerList.children()[2];
551 c.list.create({element1: itemB, element2: itemC});
553 var outerListItems = outerList.children(),
554 innerList = outerListItems[1].children()[0],
555 innerListItems = innerList.children();
557 expect(outerListItems.length).to.equal(3, 'outer list has three items');
558 expect(outerListItems[0].children()[0].getText()).to.equal('A', 'first outer item ok');
559 expect(outerListItems[1].getWlxmlClass()).to.equal('item', 'inner list is wrapped by item element');
561 expect(innerList.is('list')).to.equal(true, 'inner list created');
562 expect(innerListItems.length).to.equal(2, 'inner list has two items');
563 expect(innerListItems[0].children()[0].getText()).to.equal('B', 'first inner item ok');
564 expect(innerListItems[1].children()[0].getText()).to.equal('C', 'second inner item ok');
566 expect(outerListItems[2].children()[0].getText()).to.equal('D', 'last outer item ok');
572 describe('extracting list items', function() {
573 it('creates two lists with extracted items in the middle if extracting from the middle of the list', function() {
574 var c = canvas.fromXML('\
576 <div class="list.items">\
577 <div class="item">0</div>\
578 <div class="item">1</div>\
579 <div class="item">2</div>\
580 <div class="item">3</div>\
583 list = c.doc().children()[0],
584 item1 = list.children()[1],
585 item2 = list.children()[2];
587 c.list.extractItems({element1: item1, element2: item2});
589 var section = c.doc(),
590 list1 = section.children()[0],
591 oldItem1 = section.children()[1],
592 oldItem2 = section.children()[2],
593 list2 = section.children()[3];
595 expect(section.children().length).to.equal(4, 'section contains four children');
597 expect(list1.is('list')).to.equal(true, 'first section child is a list');
598 expect(list1.children().length).to.equal(1, 'first list has one child');
599 expect(list1.children()[0].children()[0].getText()).to.equal('0', 'first item of the first list is a first item of the original list');
601 expect(oldItem1.children()[0].getText()).to.equal('1', 'first item got extracted');
602 expect(oldItem1.getWlxmlClass() === undefined).to.equal(true, 'first extracted element has no wlxml class');
604 expect(oldItem2.children()[0].getText()).to.equal('2', 'second item got extracted');
605 expect(oldItem2.getWlxmlClass() === undefined).to.equal(true, 'second extracted element has no wlxml class');
607 expect(list2.is('list')).to.equal(true, 'last section child is a list');
608 expect(list2.children().length).to.equal(1, 'second list has one child');
609 expect(list2.children()[0].children()[0].getText()).to.equal('3', 'first item of the second list is a last item of the original list');
612 it('puts extracted items above the list if starting item is the first one', function() {
613 var c = canvas.fromXML('\
615 <div class="list.items">\
616 <div class="item">0</div>\
617 <div class="item">1</div>\
618 <div class="item">2</div>\
621 list = c.doc().children()[0],
622 item1 = list.children()[0],
623 item2 = list.children()[1],
624 item3 = list.children()[2];
626 c.list.extractItems({element1: item1, element2: item2});
628 var section = c.doc(),
629 oldItem1 = section.children()[0],
630 oldItem2 = section.children()[1],
631 newList = section.children()[2];
633 expect(section.children().length).to.equal(3, 'section has three children');
634 expect(oldItem1.children()[0].getText()).to.equal('0', 'first item extracted');
635 expect(oldItem2.children()[0].getText()).to.equal('1', 'second item extracted');
636 expect(newList.is('list')).to.equal(true, 'list lies below extracted item');
637 expect(newList.children().length).to.equal(1, 'list has now one child');
640 it('puts extracted items below the list if ending item is the last one', function() {
641 var c = canvas.fromXML('\
643 <div class="list.items">\
644 <div class="item">0</div>\
645 <div class="item">1</div>\
646 <div class="item">2</div>\
649 list = c.doc().children()[0],
650 item1 = list.children()[0],
651 item2 = list.children()[1],
652 item3 = list.children()[2];
654 c.list.extractItems({element1: item2, element2: item3});
656 var section = c.doc(),
657 oldItem1 = section.children()[1],
658 oldItem2 = section.children()[2],
659 newList = section.children()[0];
661 expect(section.children().length).to.equal(3, 'section has three children');
662 expect(oldItem1.children()[0].getText()).to.equal('1', 'first item extracted');
663 expect(oldItem2.children()[0].getText()).to.equal('2', 'second item extracted');
664 expect(newList.is('list')).to.equal(true, 'list lies above extracted item');
665 expect(newList.children().length).to.equal(1, 'list has now one child');
668 it('removes list if all its items are extracted', function() {
669 var c = canvas.fromXML('\
671 <div class="list.items">\
672 <div class="item">some item</div>\
673 <div class="item">some item 2</div>\
676 list = c.doc().children()[0],
677 item1 = list.children()[0],
678 item2 = list.children()[1];
680 c.list.extractItems({element1: item1, element2: item2});
682 var section = c.doc(),
683 list1 = section.children()[0],
684 oldItem1 = section.children()[0],
685 oldItem2 = section.children()[1];
687 expect(section.children().length).to.equal(2, 'section contains two children');
688 expect(oldItem1.children()[0].getText()).to.equal('some item');
689 expect(oldItem2.children()[0].getText()).to.equal('some item 2');
692 it('creates two lists with extracted items in the middle if extracting from the middle of the list - nested case' , function() {
693 var c = canvas.fromXML('\
695 <div class="list.items">\
696 <div class="item">0</div>\
698 <div class="list.items">\
699 <div class="item">1.1</div>\
700 <div class="item">1.2</div>\
701 <div class="item">1.3</div>\
704 <div class="item">2</div>\
707 list = c.doc().children()[0],
708 nestedList = list.children()[1].children()[0],
709 nestedListItem = nestedList.children()[1];
711 c.list.extractItems({element1: nestedListItem, element2: nestedListItem});
713 var section = c.doc(),
714 list = section.children()[0],
715 item1 = list.children()[0],
716 item2 = list.children()[1], //
717 item3 = list.children()[2],
718 item4 = list.children()[3], //
719 item5 = list.children()[4],
720 nestedList1 = item2.children()[0],
721 nestedList2 = item4.children()[0];
723 expect(list.children().length).to.equal(5, 'top list has five items');
725 expect(item1.children()[0].getText()).to.equal('0', 'first item ok');
727 expect(item2.getWlxmlClass()).to.equal('item', 'first nested list is still wrapped in item element');
728 expect(nestedList1.children().length).to.equal(1, 'first nested list is left with one child');
729 expect(nestedList1.children()[0].children()[0].getText()).to.equal('1.1', 'first nested list item left alone');
731 expect(item3.children()[0].getText()).to.equal('1.2', 'third item ok');
733 expect(item4.getWlxmlClass()).to.equal('item', 'second nested list is still wrapped in item element');
734 expect(nestedList2.children().length).to.equal(1, 'second nested list is left with one child');
735 expect(nestedList2.children()[0].children()[0].getText()).to.equal('1.3', 'second nested list item left alone');
737 expect(item5.children()[0].getText()).to.equal('2', 'last item ok');
740 it('puts extracted items below the list if ending item is the last one - nested case' , function() {
741 var c = canvas.fromXML('\
743 <div class="list.items">\
744 <div class="item">0</div>\
746 <div class="list.items">\
747 <div class="item">1.1</div>\
748 <div class="item">1.2</div>\
749 <div class="item">1.3</div>\
752 <div class="item">2</div>\
755 list = c.doc().children()[0],
756 nestedList = list.children()[1].children()[0],
757 nestedListItem1 = nestedList.children()[1],
758 nestedListItem2 = nestedList.children()[2];
760 c.list.extractItems({element1: nestedListItem1, element2: nestedListItem2});
762 var section = c.doc(),
763 list = section.children()[0],
764 item1 = list.children()[0],
765 item2 = list.children()[1],
766 item3 = list.children()[2],
767 item4 = list.children()[3],
768 item5 = list.children()[4];
769 nestedList = item2.children()[0];
771 expect(list.children().length).to.equal(5, 'top list has five items');
772 expect(item1.children()[0].getText()).to.equal('0', 'first item ok');
773 expect(item2.getWlxmlClass()).to.equal('item', 'nested list is still wrapped in item element');
774 expect(nestedList.children().length).to.equal(1, 'nested list is left with one child');
775 expect(nestedList.children()[0].children()[0].getText()).to.equal('1.1', 'nested list item left alone');
776 expect(item3.children()[0].getText()).to.equal('1.2', 'third item ok');
777 expect(item4.children()[0].getText()).to.equal('1.3', 'fourth item ok');
778 expect(item5.children()[0].getText()).to.equal('2', 'fifth item ok');
781 it('puts extracted items above the list if starting item is the first one - nested case' , function() {
782 var c = canvas.fromXML('\
784 <div class="list.items">\
785 <div class="item">0</div>\
787 <div class="list.items">\
788 <div class="item">1.1</div>\
789 <div class="item">1.2</div>\
790 <div class="item">1.3</div>\
793 <div class="item">2</div>\
796 list = c.doc().children()[0],
797 nestedList = list.children()[1].children()[0],
798 nestedListItem1 = nestedList.children()[0],
799 nestedListItem2 = nestedList.children()[1];
801 c.list.extractItems({element1: nestedListItem1, element2: nestedListItem2});
803 var section = c.doc(),
804 list = section.children()[0],
805 item1 = list.children()[0],
806 item2 = list.children()[1],
807 item3 = list.children()[2],
808 item4 = list.children()[3],
809 item5 = list.children()[4];
810 nestedList = item4.children()[0];
812 expect(list.children().length).to.equal(5, 'top list has five items');
813 expect(item1.children()[0].getText()).to.equal('0', 'first item ok');
814 expect(item2.children()[0].getText()).to.equal('1.1', 'second item ok');
815 expect(item3.children()[0].getText()).to.equal('1.2', 'third item ok');
817 expect(item4.getWlxmlClass()).to.equal('item', 'nested list is still wrapped in item element');
818 expect(nestedList.children().length).to.equal(1, 'nested list is left with one child');
819 expect(nestedList.children()[0].children()[0].getText()).to.equal('1.3', 'nested list item left alone');
820 expect(item5.children()[0].getText()).to.equal('2', 'fifth item ok');
823 it('removes list if all its items are extracted - nested case', function() {
824 var c = canvas.fromXML('\
826 <div class="list.items">\
827 <div class="item">0</div>\
829 <div class="list.items">\
830 <div class="item">1.1</div>\
831 <div class="item">1.2</div>\
834 <div class="item">2</div>\
837 list = c.doc().children()[0],
838 nestedList = list.children()[1].children()[0],
839 nestedListItem1 = nestedList.children()[0],
840 nestedListItem2 = nestedList.children()[1];
842 c.list.extractItems({element1: nestedListItem1, element2: nestedListItem2});
844 var section = c.doc(),
845 list = section.children()[0],
846 item1 = list.children()[0],
847 item2 = list.children()[1],
848 item3 = list.children()[2],
849 item4 = list.children()[3];
851 expect(list.children().length).to.equal(4, 'top list has four items');
852 expect(item1.children()[0].getText()).to.equal('0', 'first item ok');
853 expect(item2.children()[0].getText()).to.equal('1.1', 'second item ok');
854 expect(item3.children()[0].getText()).to.equal('1.2', 'third item ok');
855 expect(item4.children()[0].getText()).to.equal('2', 'fourth item ok');
858 it('extracts items out of outer most list when merge flag is set to false', function() {
859 var c = canvas.fromXML('\
861 <div class="list.items">\
862 <div class="item">0</div>\
864 <div class="list.items">\
865 <div class="item">1.1</div>\
866 <div class="item">1.2</div>\
869 <div class="item">2</div>\
873 list = section.children()[0],
874 nestedList = list.children()[1].children()[0],
875 nestedListItem = nestedList.children()[0];
877 var test = c.list.extractItems({element1: nestedListItem, element2: nestedListItem, merge: false});
879 expect(test).to.equal(true, 'extraction status ok');
881 var sectionChildren = section.children(),
882 extractedItem = sectionChildren[1];
884 expect(sectionChildren.length).to.equal(3, 'section has three children');
885 expect(sectionChildren[0].is('list')).to.equal(true, 'first child is a list');
887 expect(extractedItem.getWlxmlTag()).to.equal('div', 'extracted item is a wlxml div');
888 expect(extractedItem.getWlxmlClass()).to.equal(undefined, 'extracted item has no wlxml class');
889 expect(extractedItem.children()[0].getText()).to.equal('1.1', 'extracted item ok');
890 expect(sectionChildren[2].is('list')).to.equal(true, 'second child is a list');
897 describe('Cursor', function() {
901 beforeEach(function() {
902 getSelection = sinon.stub(window, 'getSelection');
905 afterEach(function() {
906 getSelection.restore();
909 it('returns position when browser selection collapsed', function() {
910 var c = canvas.fromXML('<section>Alice has a cat</section>'),
912 text = dom.contents(0);
914 expect(text.text()).to.equal('Alice has a cat');
916 getSelection.returns({
923 var cursor = c.getCursor(),
924 position = cursor.getPosition();
926 expect(cursor.isSelecting()).to.equal(false, 'cursor is not selecting anything');
927 expect(position.element.getText()).to.equal('Alice has a cat');
928 expect(position.offset).to.equal(5);
931 it('returns boundries of selection when browser selection not collapsed', function() {
932 var c = canvas.fromXML('<section>Alice <span>has</span> a <span>big</span> cat</section>'),
935 alice: dom.contents()[0],
936 has: $(dom.contents()[1]).contents()[0],
937 cat: dom.contents()[4]
939 cursor = c.getCursor(),
940 aliceElement = c.getDocumentElement(text.alice),
941 catElement = c.getDocumentElement(text.cat);
945 {focus: text.alice, focusOffset: 1, anchor: text.cat, anchorOffset: 2, selectionAnchor: catElement},
946 {focus: text.cat, focusOffset: 2, anchor: text.alice, anchorOffset: 1, selectionAnchor: aliceElement}
947 ].forEach(function(s, idx) {
948 getSelection.returns({isColapsed: false, anchorNode: s.anchor, anchorOffset: s.anchorOffset, focusNode: s.focus, focusOffset: s.focusOffset});
950 var selectionStart = cursor.getSelectionStart(),
951 selectionEnd = cursor.getSelectionEnd(),
952 selectionAnchor = cursor.getSelectionAnchor();
954 expect(cursor.isSelecting()).to.equal(true, 'cursor is selecting');
955 expect(selectionStart.element.sameNode(aliceElement)).to.equal(true, '"Alice" is the start of the selection ' + idx);
956 expect(selectionStart.offset).to.equal(1, '"Alice" offset ok' + idx);
957 expect(selectionEnd.element.sameNode(catElement)).to.equal(true, '"Cat" is the start of the selection ' + idx);
958 expect(selectionEnd.offset).to.equal(2, '"Cat" offset ok' + idx);
959 expect(selectionAnchor.element.sameNode(s.selectionAnchor)).to.equal(true, 'anchor ok');
960 expect(selectionAnchor.offset).to.equal(s.anchorOffset, 'anchor offset ok');
964 it('recognizes when browser selection boundries lies in sibling DocumentTextElements', function() {
965 var c = canvas.fromXML('<section>Alice <span>has</span> a <span>big</span> cat</section>'),
968 alice: dom.contents()[0],
969 has: $(dom.contents()[1]).contents()[0],
970 a: dom.contents()[2],
971 big: $(dom.contents()[3]).contents()[0],
972 cat: dom.contents()[4]
974 cursor = c.getCursor();
976 expect($(text.alice).text()).to.equal('Alice ');
977 expect($(text.has).text()).to.equal('has');
978 expect($(text.a).text()).to.equal(' a ');
979 expect($(text.big).text()).to.equal('big');
980 expect($(text.cat).text()).to.equal(' cat');
982 getSelection.returns({anchorNode: text.alice, focusNode: text.a});
983 expect(cursor.isSelectingSiblings()).to.equal(true, '"Alice" and "a" are children');
985 getSelection.returns({anchorNode: text.alice, focusNode: text.cat});
986 expect(cursor.isSelectingSiblings()).to.equal(true, '"Alice" and "cat" are children');
988 getSelection.returns({anchorNode: text.alice, focusNode: text.has});
989 expect(cursor.isSelectingSiblings()).to.equal(false, '"Alice" and "has" are not children');
991 getSelection.returns({anchorNode: text.has, focusNode: text.big});
992 expect(cursor.isSelectingSiblings()).to.equal(false, '"has" and "big" are not children');