From: Aleksander Ɓukasz Date: Tue, 6 May 2014 09:42:42 +0000 (+0200) Subject: Cleaning documentElement/genericElement interfaces X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/436728b375888873e6e96079a73f12d8adbd7b96?ds=inline;hp=2e14f0181735b7acd0da023eb4c9524b75a45b56 Cleaning documentElement/genericElement interfaces --- diff --git a/src/editor/modules/documentCanvas/canvas/canvas.js b/src/editor/modules/documentCanvas/canvas/canvas.js index bcfc954..a467bee 100644 --- a/src/editor/modules/documentCanvas/canvas/canvas.js +++ b/src/editor/modules/documentCanvas/canvas/canvas.js @@ -247,7 +247,7 @@ $.extend(Canvas.prototype, Backbone.Events, { }, toggleElementHighlight: function(node, toggle) { - var element = utils.findCanvasElement(node); + var element = utils.getElementForNode(node); element.toggleHighlight(toggle); }, @@ -303,7 +303,7 @@ $.extend(Canvas.prototype, Backbone.Events, { } if(!(element instanceof documentElement.DocumentElement)) { - element = utils.findCanvasElement(element); + element = utils.getElementForNode(element); } if(!element || !this.contains(element)) { @@ -317,13 +317,7 @@ $.extend(Canvas.prototype, Backbone.Events, { if(byBrowser && byBrowser.parent().sameNode(nodeToLand)) { return byBrowser; } - var children = e.children(); - for(var i = 0; i < children.length; i++) { - if(children[i] instanceof documentElement.DocumentTextElement) { - return children[i]; - } - } - return null; + return e.getVerticallyFirstTextElement(); }.bind(this); var _markAsCurrent = function(element) { if(element instanceof documentElement.DocumentTextElement) { @@ -391,10 +385,6 @@ $.extend(Canvas.prototype, Backbone.Events, { } }, - findCanvasElement: function(node) { - return utils.findCanvasElement(node); - }, - toggleGrid: function() { this.wrapper.toggleClass('grid-on'); this.trigger('changed'); @@ -572,7 +562,7 @@ $.extend(Cursor.prototype, { if(selection.anchorNode === selection.focusNode) { anchorFirst = selection.anchorOffset <= selection.focusOffset; } else { - anchorFirst = parent.childIndex(anchorElement) < parent.childIndex(focusElement); + anchorFirst = (parent.getFirst(anchorElement, focusElement) === anchorElement); } placeData = getPlaceData(anchorFirst); } else { diff --git a/src/editor/modules/documentCanvas/canvas/canvas.test.js b/src/editor/modules/documentCanvas/canvas/canvas.test.js index 63ef243..9d6d94e 100644 --- a/src/editor/modules/documentCanvas/canvas/canvas.test.js +++ b/src/editor/modules/documentCanvas/canvas/canvas.test.js @@ -125,7 +125,7 @@ describe('Listening to document changes', function() { aTextElement; canvas.fromXMLDocument(doc); - aTextElement = utils.findCanvasElementInParent(aTextNode, aTextNode.parent()); // TODO: This really should be easier... + aTextElement = utils.getElementForTextNode(aTextNode); aTextElement.setText(''); diff --git a/src/editor/modules/documentCanvas/canvas/documentElement.js b/src/editor/modules/documentCanvas/canvas/documentElement.js index 99e97d0..a08788b 100644 --- a/src/editor/modules/documentCanvas/canvas/documentElement.js +++ b/src/editor/modules/documentCanvas/canvas/documentElement.js @@ -189,6 +189,15 @@ $.extend(DocumentTextElement.prototype, { this.canvas = null; return this; }, + handle: function(event) { + var toSet = event.meta.node.getText(); + if(toSet === '') { + toSet = utils.unicode.ZWS; + } + if(toSet !== this.getText()) { + this.setText(toSet); + } + }, setText: function(text) { this.dom.contents()[0].data = text; }, diff --git a/src/editor/modules/documentCanvas/canvas/genericElement.js b/src/editor/modules/documentCanvas/canvas/genericElement.js index d11cbd1..f115bd4 100644 --- a/src/editor/modules/documentCanvas/canvas/genericElement.js +++ b/src/editor/modules/documentCanvas/canvas/genericElement.js @@ -19,6 +19,68 @@ var DocumentNodeElement = documentElement.DocumentNodeElement; var generic = Object.create(DocumentNodeElement.prototype); $.extend(generic, { + init: function() { + DocumentNodeElement.prototype.init.call(this); + this._container() + .attr('wlxml-tag', this.wlxmlNode.getTagName()); + this.setWlxmlClass(this.wlxmlNode.getClass()); + this.wlxmlNode.contents().forEach(function(node) { + this._container().append(this.canvas.createElement(node).dom); + }.bind(this)); + this.refresh(); + }, + + refresh: function() { + if(this.wlxmlNode.getTagName() === 'span') { + if(this.containsBlock()) { + this.displayAsBlock(); + } else { + this.displayInline(); + } + } else { + this.displayAsBlock(); + } + }, + + getFirst: function(e1, e2) { + var idx1 = this.childIndex(e1), + idx2 = this.childIndex(e2); + if(e1 === null || e2 === null) { + return undefined; + } + return idx1 <= idx2 ? e1: e2; + }, + + children: function() { + var element = this, + toret = []; + this._container().contents().each(function() { + var childElement = element.canvas.getDocumentElement(this); + if(childElement === undefined) { + return true; + } + + toret.push(childElement); + }); + return toret; + }, + + getVerticallyFirstTextElement: function() { + var toret; + this.children().some(function(child) { + if(child instanceof documentElement.DocumentTextElement) { + toret = child; + return true; // break + } else { + toret = child.getVerticallyFirstTextElement(); + if(toret) { + return true; // break + } + } + }); + return toret; + }, + onNodeAttrChange: function(event) { if(event.meta.attr === 'class') { this.setWlxmlClass(event.meta.newVal); // @@ -40,12 +102,22 @@ $.extend(generic, { referenceElement = this.children()[nodeIndex-1]; referenceAction = 'after'; } + + if(event.type === 'nodeMoved') { + /* globals Node */ + if(event.meta.node.nodeType === Node.TEXT_NODE) { + actionArg = utils.getElementForTextNode(event.meta.node); + } else { + actionArg = utils.getElementForNode(event.meta.node); + } + } else { + actionArg = event.meta.node; + } - actionArg = (event.type === 'nodeMoved' && utils.findCanvasElement(event.meta.node, event.meta.parent)) || event.meta.node; referenceElement[referenceAction](actionArg); }, onNodeMoved: function(event) { - return this.onNodeAdded.call(this, event, true); + return this.onNodeAdded.call(this, event); }, onNodeDetached: function(event) { if(event.meta.node.sameNode(this)) { @@ -74,6 +146,23 @@ $.extend(generic, { }); }, + + /// + + containsBlock: function() { + return this.children() + .filter(function(child) { + return child instanceof documentElement.DocumentNodeElement; + }) + .some(function(child) { + if(child.isBlock()) { + return true; + } else { + return child.containsBlock(); + } + }); + }, + prepend: function(param) { var element; if(param instanceof documentElement.DocumentElement) { @@ -86,29 +175,6 @@ $.extend(generic, { return element; }, - children: function() { - var element = this, - toret = []; - this._container().contents().each(function() { - var childElement = element.canvas.getDocumentElement(this); - if(childElement === undefined) { - return true; - } - - toret.push(childElement); - }); - return toret; - }, - - getFirst: function(e1, e2) { - var idx1 = this.childIndex(e1), - idx2 = this.childIndex(e2); - if(e1 === null || e2 === null) { - return undefined; - } - return idx1 <= idx2 ? e1: e2; - }, - childIndex: function(child) { var children = this.children(), toret = null; @@ -139,57 +205,7 @@ $.extend(generic, { this._container().removeAttr('wlxml-class'); } this.refreshPath(); - }, - init: function() { - DocumentNodeElement.prototype.init.call(this); - this._container() - .attr('wlxml-tag', this.wlxmlNode.getTagName()); - this.setWlxmlClass(this.wlxmlNode.getClass()); - this.wlxmlNode.contents().forEach(function(node) { - this._container().append(this.canvas.createElement(node).dom); - }.bind(this)); - this.refresh(); - - }, - refresh: function() { - if(this.wlxmlNode.getTagName() === 'span') { - if(this.containsBlock()) { - this.displayAsBlock(); - } else { - this.displayInline(); - } - } else { - this.displayAsBlock(); - } - }, - containsBlock: function() { - return this.children() - .filter(function(child) { - return child instanceof documentElement.DocumentNodeElement; - }) - .some(function(child) { - if(child.isBlock()) { - return true; - } else { - return child.containsBlock(); - } - }); - }, - getVerticallyFirstTextElement: function() { - var toret; - this.children().some(function(child) { - if(child instanceof documentElement.DocumentTextElement) { - toret = child; - return true; // break - } else { - toret = child.getVerticallyFirstTextElement(); - if(toret) { - return true; // break - } - } - }); - return toret; - }, + } }); diff --git a/src/editor/modules/documentCanvas/canvas/keyboard.js b/src/editor/modules/documentCanvas/canvas/keyboard.js index 69dd060..18fcddb 100644 --- a/src/editor/modules/documentCanvas/canvas/keyboard.js +++ b/src/editor/modules/documentCanvas/canvas/keyboard.js @@ -61,7 +61,7 @@ handlers.push({key: KEYS.ENTER, description: gettext('Splitting text') }, success: function(ret) { - canvas.setCurrentElement(utils.findCanvasElement(ret), {caretTo: 'start'}); + canvas.setCurrentElement(utils.getElementForNode(ret), {caretTo: 'start'}); } }); @@ -86,7 +86,7 @@ handlers.push({key: KEYS.ENTER, description: gettext('Splitting text') }, success: function(ret) { - canvas.setCurrentElement(utils.findCanvasElement(ret), {caretTo: 'start'}); + canvas.setCurrentElement(utils.getElementForNode(ret), {caretTo: 'start'}); } }); @@ -133,7 +133,7 @@ handlers.push({key: KEYS.ENTER, gotoOptions = {caretTo: 'start'}; } - canvas.setCurrentElement(utils.findCanvasElement(goto), gotoOptions); + canvas.setCurrentElement(utils.getElementForNode(goto), gotoOptions); } } } diff --git a/src/editor/modules/documentCanvas/canvas/utils.js b/src/editor/modules/documentCanvas/canvas/utils.js index 89ed192..62845e3 100644 --- a/src/editor/modules/documentCanvas/canvas/utils.js +++ b/src/editor/modules/documentCanvas/canvas/utils.js @@ -20,38 +20,6 @@ var nearestInDocumentOrder = function(selector, direction, element) { return null; }; -var findCanvasElement = function(node, childOf) { - if(node.nodeType === Node.ELEMENT_NODE) { - return node.getData('canvasElement'); - } - if(node.nodeType === Node.TEXT_NODE) { - return findCanvasElementInParent(node, childOf || node.parent()); - } -}; - -/** - * We take child and its parent as arguments separatly to - * handle situation where child was removed from WLXMLDocument - * and it lost reference to its parent (but we may still have it on canvas). -*/ -var findCanvasElementInParent = function(wlxmlChildNode, wlxmlParentNode) { - var parentElement, toret; - - if(wlxmlParentNode === null) { - toret = wlxmlChildNode.getData('canvasElement'); - if(toret.parent()) { - throw new Error('This should never happen: root canvas element doesn\'t render root document node!'); - } - } else { - parentElement = findCanvasElement(wlxmlParentNode); - parentElement.children().forEach(function(child) { - if(child.wlxmlNode.sameNode(wlxmlChildNode)) { // czemu tu, przy drugim undo child nie mial data? - toret = child; - } - }); - } - return toret; -}; var getElementForNode = function(node) { @@ -73,15 +41,26 @@ var getElementForDetachedNode = function(node, originalParent) { return ptr.getData('canvasElement'); }; +var getElementForTextNode = function(textNode) { + var parentElement = getElementForNode(textNode.parent()), + toret; + parentElement.children().some(function(child) { + if(child.wlxmlNode.sameNode(textNode)) { + toret = child; + return true; + } + }); + return toret; +}; + return { nearestInDocumentOrder: nearestInDocumentOrder, - findCanvasElement: findCanvasElement, - findCanvasElementInParent: findCanvasElementInParent, unicode: { ZWS: '\u200B' }, getElementForNode: getElementForNode, - getElementForDetachedNode: getElementForDetachedNode + getElementForDetachedNode: getElementForDetachedNode, + getElementForTextNode: getElementForTextNode }; }); diff --git a/src/editor/modules/documentCanvas/canvas/wlxmlListener.js b/src/editor/modules/documentCanvas/canvas/wlxmlListener.js index 8667560..bb09ec7 100644 --- a/src/editor/modules/documentCanvas/canvas/wlxmlListener.js +++ b/src/editor/modules/documentCanvas/canvas/wlxmlListener.js @@ -70,7 +70,7 @@ var handlers = { containingElement.handle(event); }, nodeMoved: function(event) { - return handlers.nodeAdded.call(this, event, true); // + return handlers.nodeAdded.call(this, event); // // }, nodeDetached: function(event) { @@ -78,7 +78,7 @@ var handlers = { element.handle(event); }, nodeTextChange: function(event) { - var element = utils.getElementForNode(event.meta.node.parent()); + var element = utils.getElementForTextNode(event.meta.node); element.handle(event); },