From f4b30e13f370f50a926971df2d23ca423a0c88d8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Thu, 13 Mar 2014 10:39:36 +0100 Subject: [PATCH] smartxml: removing special implementation for changing tag name NodeElement.setTag stops being a magic method that tries to simulate tagName as being a mutable property. It's now just a shortcut for replaceWith combined with copying replaced element contents, attributes and custom data. This change: - allows for removal of a separate nodeTagChange event, - simplifies implementation, - makes api more in line with DOM specification, - invalidates references to the old node explicitly by returning reference to a newly created node. --- src/smartxml/core.js | 23 +++++++++-------------- src/smartxml/smartxml.test.js | 32 ++++---------------------------- 2 files changed, 13 insertions(+), 42 deletions(-) diff --git a/src/smartxml/core.js b/src/smartxml/core.js index a2d39a6..9630a77 100644 --- a/src/smartxml/core.js +++ b/src/smartxml/core.js @@ -115,26 +115,21 @@ var elementNodeTransformations = { }, setTag: function(tagName) { - var node = this.document.createDocumentNode({tagName: tagName}), - oldTagName = this.getTagName(), - myContents = this._$.contents(); + var node = this.document.createDocumentNode({tagName: tagName}); this.getAttrs().forEach(function(attribute) { - node.setAttr(attribute.name, attribute.value, true); + node.setAttr(attribute.name, attribute.value); }); - node.setData(this.getData()); - if(this.sameNode(this.document.root)) { - this.document._defineDocumentProperties(node._$); - } + this.contents().forEach(function(child) { + node.append(child); + }); - /* TODO: This invalidates old references to this node. Caching instances on nodes would fix this. */ - this._$.replaceWith(node._$); - this._setNativeNode(node._$[0]); - this._$.append(myContents); - this.triggerChangeEvent('nodeTagChange', {oldTagName: oldTagName, newTagName: this.getTagName()}); - }, + node.setData(this.getData()); + this.replaceWith(node); + return node; + }, setAttr: function(name, value, silent) { var oldVal = this.getAttr(name); diff --git a/src/smartxml/smartxml.test.js b/src/smartxml/smartxml.test.js index fb420db..e4e2724 100644 --- a/src/smartxml/smartxml.test.js +++ b/src/smartxml/smartxml.test.js @@ -169,40 +169,16 @@ describe('smartxml', function() { it('can change tag name', function() { var node = elementNodeFromXML('
'); - node.setTag('span'); + node = node.setTag('span'); expect(node.getTagName()).to.equal('span'); }); - it('emits nodeTagChange event', function() { - var node = elementNodeFromXML('
'), - spy = sinon.spy(); - - node.document.on('change', spy); - node.setTag('span'); - var event = spy.args[0][0]; - - expect(event.type).to.equal('nodeTagChange'); - expect(event.meta.node.sameNode(node)).to.be.true; - expect(event.meta.oldTagName).to.equal('div'); - }); - describe('Implementation specific expectations', function() { - // DOM specifies ElementNode tag as a read-only property, so - // changing it in a seamless way is a little bit tricky. For this reason - // the folowing expectations are required, despite the fact that they actually are - // motivated by implemetation details. - - it('keeps node in the document', function() { - var doc = getDocumentFromXML('
'), - header = doc.root.contents()[0]; - header.setTag('span'); - expect(header.parent().sameNode(doc.root)).to.be.true; - }); it('keeps custom data', function() { var node = elementNodeFromXML('
'); node.setData('key', 'value'); - node.setTag('header'); + node = node.setTag('header'); expect(node.getTagName()).to.equal('header'); expect(node.getData()).to.eql({key: 'value'}); @@ -214,9 +190,9 @@ describe('smartxml', function() { expect(doc.root.getTagName()).to.equal('span'); }); - it('keeps contents', function() { + it('keeps node contents', function() { var node = elementNodeFromXML('
'); - node.setTag('header'); + node = node.setTag('header'); expect(node.contents()).to.have.length(1); }); }); -- 2.20.1