X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/2a317c49f0b5110cc3717878a4f988aba8c63c5e..0a765eadd374d46fc8f4ebe88f9f97a4d8fae622:/src/smartxml/smartxml.js diff --git a/src/smartxml/smartxml.js b/src/smartxml/smartxml.js index 8110a97..ac59532 100644 --- a/src/smartxml/smartxml.js +++ b/src/smartxml/smartxml.js @@ -38,14 +38,8 @@ var DocumentNode = function(nativeNode, document) { $.extend(DocumentNode.prototype, { - transformations: new transformations.TransformationStorage(), - - transform: function(name, args) { - var Transformation = this.transformations.get(name), - transformation; - if(Transformation) { - transformation = new Transformation(this.document, this, args); - } + transform: function(Transformation, args) { + var transformation = new Transformation(this.document, this, args); return this.document.transform(transformation); }, @@ -382,63 +376,6 @@ $.extend(ElementNode.prototype, { } }); -// trans - -// todo - split+append - -ElementNode.prototype.transformations.register(transformations.createContextTransformation({ - name: 'smartxml.setAttr', - impl: function(args) { - this.setAttr(args.name, args.value); - }, - getChangeRoot: function() { - return this.context; - } -})); - -ElementNode.prototype.transformations.register(transformations.createContextTransformation({ - name: 'smartxml.setAttr2', - impl: function(args) { - this.prevAttr = this.getAttr(args.name); - this.setAttr(args.name, args.value); - }, - undo: function(args) { - this.setAttr(args.name, this.prevAttr); - } -})); - -DocumentNode.prototype.transformations.register(transformations.createContextTransformation({ - name: 'smartxml.wrapWith', - getChangeRoot: function() { - return this.context.parent(); - }, - impl: function(args) { - return this.wrapWith(args); - } -})); - -DocumentNode.prototype.transformations.register(transformations.createContextTransformation({ - name: 'smartxml.wrapText', - getChangeRoot: function() { - return this.context; - }, - impl: function(args) { - return this.wrapText(args); - } -})); - -DocumentNode.prototype.transformations.register(transformations.createContextTransformation({ - name: 'smartxml.detach', - getChangeRoot: function() { - return this.context.parent(); - }, - impl: function(args) { - return this.detach(); - } -})); - -/// - var TextNode = function(nativeNode, document) { DocumentNode.call(this, nativeNode, document); }; @@ -526,70 +463,44 @@ $.extend(TextNode.prototype, { }); -TextNode.prototype.transformations.register(transformations.createContextTransformation({ - name: 'rng.breakContent', - // impl: function(args) { - // var node = this.context, - // newNodes, emptyNode, emptyText; - // newNodes = node.transform('smartxml.split', {offset: args.offset}); - // [newNodes.first, newNodes.second].some(function(newNode) { - // if(!(newNode.contents().length)) { - // newNode.transform('smartxml.append', {text: ''}); - // return true; // break - // } - // }); - // return _.extend(newNodes, {emptyText: emptyText}); - // }, - impl: function(args) { - var node = this, - newNodes, emptyNode, emptyText; - newNodes = node.split({offset: args.offset}); - [newNodes.first, newNodes.second].some(function(newNode) { - if(!(newNode.contents().length)) { - newNode.append({text: ''}); - return true; // break - } - }); - return _.extend(newNodes, {emptyText: emptyText}); - }, - getChangeRoot: function() { - return this.context.parent().parent(); - }, - isAllowed: function(args) { - var parent = this.parent(); - return !!(parent && parent.parent()); - } -})); - +var parseXML = function(xml) { + return $($.trim(xml))[0]; +}; -ElementNode.prototype.transformations.register(transformations.createContextTransformation({ - name: 'smartxml.setText', - impl: function(args) { - this.setText(args.text); - }, - getChangeRoot: function() { - return this.context; +var registerTransformation = function(desc, name, target) { + var Transformation = transformations.createContextTransformation(desc, name); + target[name] = function(args) { + var instance = this; + return instance.transform(Transformation, args); } -})); - +}; -var parseXML = function(xml) { - return $($.trim(xml))[0]; +var registerMethod = function(methodName, method, target) { + if(target[methodName]) { + throw new Error('Cannot extend {target} with method name {methodName}. Name already exists.' + .replace('{target}', target) + .replace('{methodName}', methodName) + ); + } + target[methodName] = method; }; + var Document = function(xml) { this.loadXML(xml); this.undoStack = []; this.redoStack = []; this._transformationLevel = 0; - this.transformations = new transformations.TransformationStorage(); - + + this._nodeMethods = {}; + this._textNodeMethods = {}; + this._elementNodeMethods = {}; + this._nodeTransformations = {}; }; $.extend(Document.prototype, Backbone.Events, { ElementNodeFactory: ElementNode, TextNodeFactory: TextNode, - transformations: new transformations.TransformationStorage(), createDocumentNode: function(from) { if(!(from instanceof Node)) { @@ -606,13 +517,19 @@ $.extend(Document.prototype, Backbone.Events, { from = node[0]; } } - var Factory; + var Factory, typeMethods; if(from.nodeType === Node.TEXT_NODE) { Factory = this.TextNodeFactory; + typeMethods = this._textNodeMethods; } else if(from.nodeType === Node.ELEMENT_NODE) { Factory = this.ElementNodeFactory; + typeMethods = this._elementNodeMethods; } - return new Factory(from, this); + var toret = new Factory(from, this); + _.extend(toret, this._nodeMethods); + _.extend(toret, typeMethods); + _.extend(toret, this._nodeTransformations); + return toret; }, loadXML: function(xml, options) { @@ -761,15 +678,65 @@ $.extend(Document.prototype, Backbone.Events, { return insertion.ofNode; }, - transform: function(transformation, args) { - //console.log('transform'); - var Transformation, toret; - if(typeof transformation === 'string') { - Transformation = this.transformations.get(transformation); - if(Transformation) { - transformation = new Transformation(this, this, args); + registerMethod: function(methodName, method, dstName) { + var doc = this; + var destination = { + document: doc, + documentNode: doc._nodeMethods, + textNode: doc._textNodeMethods, + elementNode: doc._elementNodeMethods + }[dstName]; + registerMethod(methodName, method, destination); + }, + + registerDocumentTransformation: function(desc, name) { + registerTransformation(desc, name, this); + }, + + registerNodeTransformation: function(desc, name) { + registerTransformation(desc, name, this._nodeTransformations); + }, + + registerExtension: function(extension) { + //debugger; + var doc = this, + existingPropertyNames = _.values(this); + + ['document', 'documentNode', 'elementNode', 'textNode'].forEach(function(dstName) { + var dstExtension = extension[dstName]; + if(dstExtension) { + if(dstExtension.methods) { + _.pairs(dstExtension.methods).forEach(function(pair) { + var methodName = pair[0], + method = pair[1]; + + doc.registerMethod(methodName, method, dstName); + + }); + } + + if(dstExtension.transformations) { + _.pairs(dstExtension.transformations).forEach(function(pair) { + var name = pair[0], + desc = pair[1], + operation; + operation = {document: 'registerDocumentTransformation', documentNode: 'registerNodeTransformation'}[dstName]; + doc[operation](desc, name); + }); + } } - } + }); + }, + + transform: function(Transformation, args) { + //console.log('transform'); + var toret, transformation; + + if(typeof Transformation === 'function') { + transformation = new Transformation(this, this, args); + } else { + transformation = Transformation; + } if(transformation) { this._transformationLevel++; toret = transformation.run(); @@ -817,20 +784,6 @@ var defineDocumentProperties = function(doc, $document) { }, configurable: true}); }; -Document.prototype.transformations.register(transformations.createContextTransformation({ - name: 'smartxml.wrapNodes', - // init: function() { - - // }, - // getChangeRoot: function() { - // return this.context; - // }, - impl: function(args) { - this.wrapNodes(args); - }, - -})); - return { documentFromXML: function(xml) {