From: Aleksander Ɓukasz Date: Wed, 20 Nov 2013 13:26:59 +0000 (+0100) Subject: smartxml: splitting text X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/bc95fc1358ca35ecbd410d50b3c8c40e1afe0fa9 smartxml: splitting text --- diff --git a/src/smartxml/smartxml.js b/src/smartxml/smartxml.js index 0a1a354..6f4677b 100644 --- a/src/smartxml/smartxml.js +++ b/src/smartxml/smartxml.js @@ -351,6 +351,44 @@ $.extend(TextNode.prototype, { } }, + split: function(params) { + var parentElement = this.parent(), + passed = false, + succeedingChildren = [], + prefix = this.getText().substr(0, params.offset), + suffix = this.getText().substr(params.offset); + + parentElement.contents().forEach(function(child) { + if(passed) { + succeedingChildren.push(child); + } + if(child.sameNode(this)) { + passed = true; + } + }.bind(this)); + + if(prefix.length > 0) { + this.setText(prefix); + } + else { + this.detach(); + } + + var attrs = {}; + parentElement.getAttrs().forEach(function(attr) {attrs[attr.name] = attr.value; }); + var newElement = this.document.createDocumentNode({tagName: parentElement.getTagName(), attrs: attrs}); + parentElement.after(newElement); + + if(suffix.length > 0) { + newElement.append({text: suffix}); + } + succeedingChildren.forEach(function(child) { + newElement.append(child); + }); + + return {first: parentElement, second: newElement}; + }, + triggerTextChangeEvent: function() { var event = new events.ChangeEvent('nodeTextChange', {node: this}); this.document.trigger('change', event); @@ -359,7 +397,7 @@ $.extend(TextNode.prototype, { var parseXML = function(xml) { - return $(xml)[0]; + return $($.trim(xml))[0]; }; var Document = function(xml) { @@ -531,7 +569,7 @@ var defineDocumentProperties = function(doc, $document) { return { documentFromXML: function(xml) { - return new Document(parseXML(xml)); + return new Document(xml); }, elementNodeFromXML: function(xml) { diff --git a/src/smartxml/smartxml.test.js b/src/smartxml/smartxml.test.js index a0c1af4..822243d 100644 --- a/src/smartxml/smartxml.test.js +++ b/src/smartxml/smartxml.test.js @@ -388,11 +388,11 @@ describe('smartxml', function() { _with: {tagName: 'header'} }); - var sectionContents = section.contents(), - header = sectionContents[0], + var sectionContentss = section.contents(), + header = sectionContentss[0], headerContents = header.contents(); - expect(sectionContents).to.have.length(1); + expect(sectionContentss).to.have.length(1); expect(header.sameNode(returned)).to.equal(true, 'wrapper returned'); expect(header.parent().sameNode(section)).to.be.true; expect(headerContents).to.have.length(3); @@ -412,11 +412,11 @@ describe('smartxml', function() { _with: {tagName: 'header'} }); - var sectionContents = section.contents(), - header = sectionContents[1], + var sectionContentss = section.contents(), + header = sectionContentss[1], headerChildren = header.contents(); - expect(sectionContents).to.have.length(3); + expect(sectionContentss).to.have.length(3); expect(headerChildren).to.have.length(2); expect(headerChildren[0].sameNode(div2)).to.equal(true, 'first node wrapped'); expect(headerChildren[1].sameNode(div3)).to.equal(true, 'second node wrapped'); @@ -425,6 +425,85 @@ describe('smartxml', function() { }); + describe('Splitting text', function() { + + it('splits TextNode\'s parent into two ElementNodes', function() { + var doc = getDocumentFromXML('
Some header
'), + 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('
Some header
'), + 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('
Some header
'), + 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('
A fancy and nice header
'), + 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('
'),