From 5a57bc3cb22f2cb424186d8a7992d7dc7af68326 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Tue, 17 Jun 2014 09:55:37 +0200 Subject: [PATCH] smartxml: Cache DocumentNode instances in the underlying DOM structure This allows for data persistence in the DocumentNode.object api. And, at last, puts an end to the creation of unnecessary instances. The side effect is that extensions needs to be registered before acquiring references to nodes as they won't be updated with extension behavior after they are created. This probably should be better reflected in the api, maybe by setting extension via document constructor. --- src/smartxml/smartxml.js | 18 +++++++++++++++--- src/smartxml/smartxml.test.js | 31 +++++++++---------------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/smartxml/smartxml.js b/src/smartxml/smartxml.js index a5a1abc..9cff5ec 100644 --- a/src/smartxml/smartxml.js +++ b/src/smartxml/smartxml.js @@ -12,6 +12,8 @@ define([ /* globals Node */ +var privateKey = '_smartxml'; + var DocumentNode = function(nativeNode, document) { if(!document) { throw new Error('undefined document for a node'); @@ -48,7 +50,7 @@ $.extend(DocumentNode.prototype, { clone.find('*').addBack().each(function() { var el = this, clonedData = $(this).data(); - + $(el).removeData(privateKey); _.pairs(clonedData).forEach(function(pair) { var key = pair[0], value = pair[1]; @@ -180,6 +182,7 @@ $.extend(DocumentNode.prototype, { var ElementNode = function(nativeNode, document) { DocumentNode.call(this, nativeNode, document); + $(nativeNode).data(privateKey, {node: this}); }; ElementNode.prototype = Object.create(DocumentNode.prototype); @@ -203,7 +206,9 @@ $.extend(ElementNode.prototype, { if(key) { return this._$.data(key); } - return this._$.data(); + var toret = _.clone(this._$.data()); + delete toret[privateKey]; + return toret; }, getTagName: function() { @@ -352,7 +357,14 @@ $.extend(Document.prototype, Backbone.Events, fragments, { TextNodeFactory: TextNode, createDocumentNode: function(from) { - if(!(from instanceof Node)) { + var cached; + + if(from instanceof Node) { + cached = ($(from).data(privateKey) || {}).node; + if(cached instanceof DocumentNode) { + return cached; + } + } else { if(typeof from === 'string') { from = parseXML(from); this.normalizeXML(from); diff --git a/src/smartxml/smartxml.test.js b/src/smartxml/smartxml.test.js index 524c976..93c401b 100644 --- a/src/smartxml/smartxml.test.js +++ b/src/smartxml/smartxml.test.js @@ -620,9 +620,7 @@ describe('smartxml', function() { }); it('removes parent-describing sibling nodes of unwrapped node', function() { - var doc = getDocumentFromXML('
'), - div = doc.root.contents()[0], - x = div.contents()[1]; + var doc = getDocumentFromXML('
'); doc.registerExtension({documentNode: {methods: { object: { @@ -632,6 +630,9 @@ describe('smartxml', function() { } }}}); + var div = doc.root.contents()[0], + x = div.contents()[1]; + div.unwrapContent(); expect(doc.root.contents().length).to.equal(2); expect(x.isInDocument()).to.be.false; @@ -691,10 +692,7 @@ describe('smartxml', function() { }); it('keeps parent-describing nodes in place', function() { - var doc = getDocumentFromXML('Alice probably has a cat'), - root = doc.root, - x = root.contents()[1], - y = root.contents()[3]; + var doc = getDocumentFromXML('Alice probably has a cat'); doc.registerExtension({documentNode: {methods: { object: { @@ -705,6 +703,10 @@ describe('smartxml', function() { } }}}); + var root = doc.root, + x = root.contents()[1], + y = root.contents()[3]; + root.wrapText({ _with: {tagName: 'span', attrs: {'attr1': 'value1'}}, offsetStart: 1, @@ -1348,19 +1350,6 @@ describe('smartxml', function() { beforeEach(function() { doc = getDocumentFromXML('
Alice
'); - elementNode = doc.root; - textNode = doc.root.contents()[0]; - extension = {}; - - expect(elementNode.testTransformation).to.be.undefined; - expect(textNode.testTransformation).to.be.undefined; - expect(doc.testTransformation).to.be.undefined; - - expect(doc.testMethod).to.be.undefined; - expect(elementNode.testMethod).to.be.undefined; - expect(textNode.testMethod).to.be.undefined; - expect(elementNode.elementTestMethod).to.be.undefined; - expect(textNode.textTestMethod).to.be.undefined; }); it('allows adding method to a document', function() { @@ -1404,7 +1393,6 @@ describe('smartxml', function() { doc.registerExtension(extension); - /* refresh */ elementNode = doc.root; textNode = doc.root.contents()[0]; @@ -1440,7 +1428,6 @@ describe('smartxml', function() { doc.registerExtension(extension); - /* refresh */ elementNode = doc.root; textNode = doc.root.contents()[0]; -- 2.20.1