X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/6757e2f4fe80bfdc197d4963c464bf2b3a47f66b..8464a511c74dff643095ce419659df60b0580b7a:/src/smartxml/transformations.js diff --git a/src/smartxml/transformations.js b/src/smartxml/transformations.js new file mode 100644 index 0000000..53dc384 --- /dev/null +++ b/src/smartxml/transformations.js @@ -0,0 +1,142 @@ +define(function(require) { + +'use strict'; + +var _ = require('libs/underscore'), + toret = {}; + + +toret.createGenericTransformation = function(desc) { + + var GenericTransformation = function(document, args) { + this.args = args || {}; + + var transformation = this; + _.keys(this.args).forEach(function(key) { + if(transformation.args[key].nodeType) { //@@ change to instanceof check, fix circular dependency + var value = transformation.args[key], + path = value.getPath(); + Object.defineProperty(transformation.args, key, { + get: function() { + if(transformation.hasRun) { + console.log('returning via path'); + return transformation.document.getNodeByPath(path); + } else { + console.log('returning original arg'); + return value; + + } + } + }); + } + }); + this.document = document; + this.hasRun = false; + if(desc.init) { + desc.init.call(this); + } + }; + _.extend(GenericTransformation.prototype, { + name: desc.name, + run: function() { + var changeRoot; + if(!desc.undo) { + changeRoot = desc.getChangeRoot ? desc.getChangeRoot.call(this) : this.document.root; + this.snapshot = changeRoot.clone(); + this.changeRootPath = changeRoot.getPath(); + } + var toret = desc.impl.call(this.context, this.args); // a argumenty do metody? + this.hasRun = true; + return toret; + }, + undo: function() { + if(desc.undo) { + desc.undo.call(this.context); + } else { + this.document.getNodeByPath(this.changeRootPath).replaceWith(this.snapshot); + } + }, + }); + + return GenericTransformation; +}; +// var T = createGenericTransformation({impl: function() {}}); +// var t = T(doc, {a:1,b:2,c3:3}); + + +toret.createContextTransformation = function(desc) { + // mozna sie pozbyc przez przeniesienie object/context na koniec argumentow konstruktora generic transformation + var GenericTransformation = toret.createGenericTransformation(desc); + + var ContextTransformation = function(document, object, args) { + GenericTransformation.call(this, document, args); + + if(document === object) { + this.context = document; + } else { + var contextPath = object.getPath(); + Object.defineProperty(this, 'context', { + get: function() { + // todo: to jakos inaczej, bo np. this.context w undo transformacji before to juz nie ten sam obiekt + // moze transformacja powinna zwracac zmodyfikowana sciezke do obiektu po dzialaniu run? + + // tu tez trick z hasRun + return document.getNodeByPath(contextPath); + } + }); + } + } + ContextTransformation.prototype = Object.create(GenericTransformation.prototype); + return ContextTransformation; +} +// var T = createContextTransformation({impl: function() {}}); +// var t = T(doc, node, {a:1,b:2,c3:3}); +/// + + + +toret.TransformationStorage = function() {}; + +_.extend(toret.TransformationStorage.prototype, { + _transformations: {}, + + register: function(Transformation) { + var list = (this._transformations[Transformation.prototype.name] = this._transformations[Transformation.prototype.name] || []); + list.push(Transformation); + }, + + get: function(name) { + var transformations = this._transformations[name]; + if(!transformations) { + throw new Error('Transformation "' + name + '" not found!'); + } + // na razie zwraca pierwsza + return transformations[0]; + } +}); + + + +// var registerTransformationFromMethod = (object, methodName, desc) { +// if(!object[methodName]) { +// throw new Exeption('Cannot register transformation from unknown method ' + methodName + ' on ' + object); +// } +// desc.impl = object[name]; +// Transformation = createContextTransformation(desc); +// object.prototype.registerContextTransformation(name, createContextTransformation(method)); +// }; + + +// registerTransformationFromMethod(ElementNode, 'setAttr', { +// impl: function(args) { +// this.setAttr(args.name, args.value); +// }, +// getChangeRoot: function() { +// return this.context; +// } + +// }); + +return toret; + +}); \ No newline at end of file