+ describe('Splitting text', function() {
+
+ it('splits TextNode\'s parent into two ElementNodes', function() {
+ var doc = getDocumentFromXML('<section><header>Some header</header></section>'),
+ section = doc.root,
+ text = section.contents()[0].contents()[0];
+
+ var returnedValue = text.split({offset: 5});
+ expect(section.contents().length).to.equal(2, 'section has two children');
+
+ var header1 = section.contents()[0];
+ var header2 = section.contents()[1];
+
+ expect(header1.getTagName()).to.equal('header', 'first section child ok');
+ expect(header1.contents().length).to.equal(1, 'first header has one child');
+ expect(header1.contents()[0].getText()).to.equal('Some ', 'first header has correct content');
+ expect(header2.getTagName()).to.equal('header', 'second section child ok');
+ expect(header2.contents().length).to.equal(1, 'second header has one child');
+ expect(header2.contents()[0].getText()).to.equal('header', 'second header has correct content');
+
+ expect(returnedValue.first.sameNode(header1)).to.equal(true, 'first node returned');
+ expect(returnedValue.second.sameNode(header2)).to.equal(true, 'second node returned');
+ });
+
+ it('leaves empty copy of ElementNode if splitting at the very beginning', function() {
+ var doc = getDocumentFromXML('<section><header>Some header</header></section>'),
+ section = doc.root,
+ text = section.contents()[0].contents()[0];
+
+ text.split({offset: 0});
+
+ var header1 = section.contents()[0];
+ var header2 = section.contents()[1];
+
+ expect(header1.contents().length).to.equal(0);
+ expect(header2.contents()[0].getText()).to.equal('Some header');
+ });
+
+ it('leaves empty copy of ElementNode if splitting at the very end', function() {
+ var doc = getDocumentFromXML('<section><header>Some header</header></section>'),
+ section = doc.root,
+ text = section.contents()[0].contents()[0];
+
+ text.split({offset: 11});
+
+ var header1 = section.contents()[0];
+ var header2 = section.contents()[1];
+
+ expect(header1.contents()[0].getText()).to.equal('Some header');
+ expect(header2.contents().length).to.equal(0);
+ });
+
+ it('keeps TextNodes\'s parent\'s children elements intact', function() {
+ var doc = getDocumentFromXML('<section><header>A <span>fancy</span> and <span>nice</span> header</header></section>'),
+ section = doc.root,
+ header = section.contents()[0],
+ textAnd = header.contents()[2];
+
+ textAnd.split({offset: 2});
+
+ var sectionContents = section.contents();
+ expect(sectionContents.length).to.equal(2, 'Section has two children');
+ expect(sectionContents[0].getTagName()).to.equal('header', 'First section node is a header');
+ expect(sectionContents[1].getTagName()).to.equal('header', 'Second section node is a header');
+
+ var firstHeaderContents = sectionContents[0].contents();
+ expect(firstHeaderContents.length).to.equal(3, 'First header has three children');
+ expect(firstHeaderContents[0].getText()).to.equal('A ', 'First header starts with a text');
+ expect(firstHeaderContents[1].getTagName()).to.equal('span', 'First header has span in the middle');
+ expect(firstHeaderContents[2].getText()).to.equal(' a', 'First header ends with text');
+
+ var secondHeaderContents = sectionContents[1].contents();
+ expect(secondHeaderContents.length).to.equal(3, 'Second header has three children');
+ expect(secondHeaderContents[0].getText()).to.equal('nd ', 'Second header starts with text');
+ expect(secondHeaderContents[1].getTagName()).to.equal('span', 'Second header has span in the middle');
+ expect(secondHeaderContents[2].getText()).to.equal(' header', 'Second header ends with text');
+ });
+ });
+
+ describe('Events', function() {
+ it('emits nodeDetached event on node detach', function() {
+ var node = elementNodeFromXML('<div><div></div></div>'),
+ innerNode = node.contents()[0],
+ spy = sinon.spy();
+ node.document.on('change', spy);
+
+ var detached = innerNode.detach(),
+ event = spy.args[0][0];
+
+ expect(event.type).to.equal('nodeDetached');
+ expect(event.meta.node.sameNode(detached, 'detached node in event meta'));
+ expect(event.meta.parent.sameNode(node), 'original parent node in event meta');
+ }),
+
+ it('emits nodeAdded event when appending new node', function() {
+ var node = elementNodeFromXML('<div></div>'),
+ spy = sinon.spy();
+ node.document.on('change', spy);
+
+ var appended = node.append({tagName:'div'}),
+ event = spy.args[0][0];
+ expect(event.type).to.equal('nodeAdded');
+ expect(event.meta.node.sameNode(appended)).to.be.true;
+ });
+
+ it('emits nodeMoved when appending aready existing node', function() {
+ var node = elementNodeFromXML('<div><a></a><b></b></div>'),
+ a = node.contents()[0],
+ b = node.contents()[1],
+ spy = sinon.spy();
+ node.document.on('change', spy);
+
+ var appended = a.append(b),
+ event = spy.args[0][0];
+
+ expect(spy.callCount).to.equal(1);
+ expect(event.type).to.equal('nodeMoved');
+ expect(event.meta.node.sameNode(appended)).to.be.true;
+ });
+
+ it('emits nodeAdded event when prepending new node', function() {
+ var node = elementNodeFromXML('<div></div>'),
+ spy = sinon.spy();
+ node.document.on('change', spy);
+
+ var prepended = node.prepend({tagName:'div'}),
+ event = spy.args[0][0];
+ expect(event.type).to.equal('nodeAdded');
+ expect(event.meta.node.sameNode(prepended)).to.be.true;
+ });
+
+ it('emits nodeMoved when prepending aready existing node', function() {
+ var node = elementNodeFromXML('<div><a></a><b></b></div>'),
+ a = node.contents()[0],
+ b = node.contents()[1],
+ spy = sinon.spy();
+ node.document.on('change', spy);
+
+ var prepended = a.prepend(b),
+ event = spy.args[0][0];
+ expect(spy.callCount).to.equal(1);
+ expect(event.type).to.equal('nodeMoved');
+ expect(event.meta.node.sameNode(prepended)).to.be.true;
+ });
+
+ it('emits nodeAdded event when inserting node after another', function() {
+ var node = elementNodeFromXML('<div><a></a></div>').contents()[0],
+ spy = sinon.spy();
+ node.document.on('change', spy);
+
+ var inserted = node.after({tagName:'div'}),
+ event = spy.args[0][0];
+ expect(event.type).to.equal('nodeAdded');
+ expect(event.meta.node.sameNode(inserted)).to.be.true;
+ });
+
+ it('emits nodeMoved when inserting aready existing node after another', function() {
+ var node = elementNodeFromXML('<div><a></a><b></b></div>'),
+ a = node.contents()[0],
+ b = node.contents()[1],
+ spy = sinon.spy();
+ node.document.on('change', spy);
+ var inserted = b.after(a),
+ event = spy.args[0][0];
+
+ expect(spy.callCount).to.equal(1);
+ expect(event.type).to.equal('nodeMoved');
+ expect(event.meta.node.sameNode(inserted)).to.be.true;
+ });
+
+ it('emits nodeAdded event when inserting node before another', function() {
+ var node = elementNodeFromXML('<div><a></a></div>').contents()[0],
+ spy = sinon.spy();
+ node.document.on('change', spy);
+
+ var inserted = node.before({tagName:'div'}),
+ event = spy.args[0][0];
+ expect(event.type).to.equal('nodeAdded');
+ expect(event.meta.node.sameNode(inserted)).to.be.true;
+ });
+
+ it('emits nodeAdded when inserting aready existing node before another', function() {
+ var node = elementNodeFromXML('<div><a></a><b></b></div>'),
+ a = node.contents()[0],
+ b = node.contents()[1],
+ spy = sinon.spy();
+ node.document.on('change', spy);
+ var inserted = a.before(b),
+ event = spy.args[0][0];
+
+ expect(spy.callCount).to.equal(1);
+ expect(event.type).to.equal('nodeMoved');
+ expect(event.meta.node.sameNode(inserted)).to.be.true;
+ });
+ });
+
+ describe('Traversing', function() {
+ describe('Basic', function() {
+ it('can access node parent', function() {
+ var doc = getDocumentFromXML('<a><b></b></a>'),
+ a = doc.root,
+ b = a.contents()[0];
+
+ expect(a.parent()).to.equal(null, 'parent of a root is null');
+ expect(b.parent().sameNode(a)).to.be.true;
+ });
+ it('can access node parents', function() {
+ var doc = getDocumentFromXML('<a><b><c></c></b></a>'),
+ a = doc.root,
+ b = a.contents()[0],
+ c = b.contents()[0];
+
+ var parents = c.parents();
+ expect(parents).to.eql([b,a]);
+ });
+ });
+
+ describe('finding sibling parents of two elements', function() {
+ it('returns elements themself if they have direct common parent', function() {
+ var doc = getDocumentFromXML('<section><div><div>A</div><div>B</div></div></section>'),
+ wrappingDiv = doc.root.contents()[0],
+ divA = wrappingDiv.contents()[0],
+ divB = wrappingDiv.contents()[1];
+
+ var siblingParents = doc.getSiblingParents({node1: divA, node2: divB});
+
+ expect(siblingParents.node1.sameNode(divA)).to.equal(true, 'divA');
+ expect(siblingParents.node2.sameNode(divB)).to.equal(true, 'divB');
+ });
+
+ it('returns sibling parents - example 1', function() {
+ var doc = getDocumentFromXML('<section>Alice <span>has a cat</span></section>'),
+ aliceText = doc.root.contents()[0],
+ span = doc.root.contents()[1],
+ spanText = span.contents()[0];
+
+ var siblingParents = doc.getSiblingParents({node1: aliceText, node2: spanText});
+
+ expect(siblingParents.node1.sameNode(aliceText)).to.equal(true, 'aliceText');
+ expect(siblingParents.node2.sameNode(span)).to.equal(true, 'span');
+ });
+ });
+ });
+