From: Aleksander Ɓukasz Date: Thu, 5 Dec 2013 10:10:22 +0000 (+0100) Subject: wip: moving non wlxml specific extension support from wlxml.js to smartxml.js X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/0f5cbf957bc0bbdcff93bdb33c227f78041e332b wip: moving non wlxml specific extension support from wlxml.js to smartxml.js --- diff --git a/src/smartxml/smartxml.js b/src/smartxml/smartxml.js index 41e8e19..9215287 100644 --- a/src/smartxml/smartxml.js +++ b/src/smartxml/smartxml.js @@ -779,6 +779,69 @@ $.extend(Document.prototype, Backbone.Events, { this._nodeTransformations.register(Transformation); }, + registerExtension: function(extension) { + //debugger; + var doc = this, + existingPropertyNames = _.values(this); + + var getTrans = function(desc, methodName) { + if(typeof desc === 'function') { + desc = {impl: desc}; + } + if(!desc.impl) { + throw new Error('Got transformation description without implementation.') + } + desc.name = desc.name || methodName; + return desc; + }; + + [ + {source: extension.document, target: doc}, + {source: extension.documentNode, target: [doc.ElementNodeFactory.prototype, doc.TextNodeFactory.prototype]}, + + ].forEach(function(mapping) { + if(mapping.source) { + if(mapping.source.methods) { + existingPropertyNames = _.values(mapping.target) + _.pairs(mapping.source.methods).forEach(function(pair) { + var methodName = pair[0], + method = pair[1], + targets = _.isArray(mapping.target) ? mapping.target : [mapping.target]; + if(_.contains(existingPropertyNames, methodName)) { + throw new Error('Cannot extend {target} with method name {methodName}. Name already exists.' + .replace('{target}', mapping.target) + .replace('{methodName}', methodName) + ); + } + targets.forEach(function(target) { + if(target === doc) { + target.registerMethod(methodName, method); + } else { + doc.registerNodeMethod(methodName, method); + } + + }); + }); + } + + if(mapping.source.transformations) { + _.pairs(mapping.source.transformations).forEach(function(pair) { + var transformation = getTrans(pair[1], pair[0]), + targets = _.isArray(mapping.target) ? mapping.target : [mapping.target]; + targets.forEach(function(target) { + if(target === doc) { + target.registerTransformation(transformations.createContextTransformation(transformation)); + } else { + doc.registerNodeTransformation(transformations.createContextTransformation(transformation)); + } + + + }); + }); + } + } + }); + }, transform: function(transformation, args) { //console.log('transform'); diff --git a/src/smartxml/smartxml.test.js b/src/smartxml/smartxml.test.js index ca72e75..a15f833 100644 --- a/src/smartxml/smartxml.test.js +++ b/src/smartxml/smartxml.test.js @@ -827,6 +827,79 @@ describe('smartxml', function() { }); }); + describe('Extension API', function() { + var doc, extension, elementNode, textNode, testClassNode; + + beforeEach(function() { + doc = getDocumentFromXML('
Alice
'); + elementNode = doc.root; + textNode = doc.root.contents()[0]; + extension = {}; + + expect(function() { + elementNode.transform('testTransformation'); + }).to.throw(Error); + expect(function() { + textNode.transform('testTransformation'); + }).to.throw(Error); + expect(function() { + doc.transform('testTransformation'); + }).to.throw(Error); + expect(doc.testMethod).to.be.undefined; + expect(elementNode.testMethod).to.be.undefined; + expect(textNode.testMethod).to.be.undefined; + }); + + it('allows adding method to a document', function() { + extension = {document: {methods: { + testMethod: function() { return this; } + }}}; + + doc.registerExtension(extension); + expect(doc.testMethod()).to.equal(doc, 'context is set to a document instance'); + }); + + it('allows adding transformation to a document', function() { + extension = {document: {transformations: { + testTransformation: function() { return this; }, + testTransformation2: {impl: function() { return this;}} + }}}; + + doc.registerExtension(extension); + expect(doc.transform('testTransformation')).to.equal(doc, 'context is set to a document instance'); + expect(doc.transform('testTransformation2')).to.equal(doc, 'context is set to a document instance'); + }); + + it('allows adding method to a DocumentNode instance', function() { + extension = {documentNode: {methods: { + testMethod: function() { return this; } + }}}; + + doc.registerExtension(extension); + + /* refresh */ + elementNode = doc.root; + textNode = doc.root.contents()[0]; + + expect(elementNode.testMethod().sameNode(elementNode)).to.equal(true, 'context is set to a node instance'); + expect(textNode.testMethod().sameNode(textNode)).to.equal(true, 'context is set to a node instance'); + }); + + it('allows adding transformation to a DocumentNode', function() { + extension = {documentNode: {transformations: { + testTransformation: function() { return this; }, + testTransformation2: {impl: function() { return this;}} + }}}; + + doc.registerExtension(extension); + + expect(elementNode.transform('testTransformation').sameNode(elementNode)).to.equal(true, '1'); + expect(elementNode.transform('testTransformation2').sameNode(elementNode)).to.equal(true, '2'); + expect(textNode.transform('testTransformation').sameNode(textNode)).to.equal(true, '3'); + expect(textNode.transform('testTransformation2').sameNode(textNode)).to.equal(true, '4'); + }); + }); + // describe('Undo/redo', function() { // it('does work', function() { diff --git a/src/wlxml/wlxml.js b/src/wlxml/wlxml.js index 7c5207a..b560982 100644 --- a/src/wlxml/wlxml.js +++ b/src/wlxml/wlxml.js @@ -267,6 +267,7 @@ $.extend(WLXMLDocument.prototype, { registerExtension: function(extension) { //debugger; + smartxml.Document.prototype.registerExtension.call(this, extension); var doc = this, existingPropertyNames = _.values(this); @@ -281,53 +282,6 @@ $.extend(WLXMLDocument.prototype, { return desc; }; - [ - {source: extension.document, target: doc}, - {source: extension.documentNode, target: [doc.ElementNodeFactory.prototype, doc.TextNodeFactory.prototype]}, - - ].forEach(function(mapping) { - if(mapping.source) { - if(mapping.source.methods) { - existingPropertyNames = _.values(mapping.target) - _.pairs(mapping.source.methods).forEach(function(pair) { - var methodName = pair[0], - method = pair[1], - targets = _.isArray(mapping.target) ? mapping.target : [mapping.target]; - if(_.contains(existingPropertyNames, methodName)) { - throw new Error('Cannot extend {target} with method name {methodName}. Name already exists.' - .replace('{target}', mapping.target) - .replace('{methodName}', methodName) - ); - } - targets.forEach(function(target) { - if(target === doc) { - target.registerMethod(methodName, method); - } else { - doc.registerNodeMethod(methodName, method); - } - - }); - }); - } - - if(mapping.source.transformations) { - _.pairs(mapping.source.transformations).forEach(function(pair) { - var transformation = getTrans(pair[1], pair[0]), - targets = _.isArray(mapping.target) ? mapping.target : [mapping.target]; - targets.forEach(function(target) { - if(target === doc) { - target.registerTransformation(transformations.createContextTransformation(transformation)); - } else { - doc.registerNodeTransformation(transformations.createContextTransformation(transformation)); - } - - - }); - }); - } - } - }); - _.pairs(extension.wlxmlClass).forEach(function(pair) { var className = pair[0], classExtension = pair[1]; diff --git a/src/wlxml/wlxml.test.js b/src/wlxml/wlxml.test.js index 480ca1c..89f571c 100644 --- a/src/wlxml/wlxml.test.js +++ b/src/wlxml/wlxml.test.js @@ -260,21 +260,20 @@ describe('WLXMLDocument', function() { textNode = doc.root.contents()[0]; extension = {}; - console.log('A'); expect(function() { elementNode.transform('testTransformation'); }).to.throw(Error); - console.log('B'); expect(function() { textNode.transform('testTransformation'); }).to.throw(Error); - console.log('C'); expect(function() { doc.transform('testTransformation'); }).to.throw(Error); expect(doc.testMethod).to.be.undefined; expect(elementNode.testMethod).to.be.undefined; expect(textNode.testMethod).to.be.undefined; + + // spr+ a expect dotyczacy object api? }); it('allows adding method to a document', function() {