From: Aleksander Ɓukasz Date: Tue, 17 Jun 2014 07:55:37 +0000 (+0200) Subject: smartxml: Cache DocumentNode instances in the underlying DOM structure X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/5a57bc3cb22f2cb424186d8a7992d7dc7af68326 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. --- 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];