X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/0bea7025f60aa5cc2ed89eed72da0d616f3574ef..2a0f7de048f49f0087caae5962f124dbbb06d69e:/src/editor/modules/documentCanvas/canvas/genericElement.js diff --git a/src/editor/modules/documentCanvas/canvas/genericElement.js b/src/editor/modules/documentCanvas/canvas/genericElement.js index 7d5d986..4dfbe59 100644 --- a/src/editor/modules/documentCanvas/canvas/genericElement.js +++ b/src/editor/modules/documentCanvas/canvas/genericElement.js @@ -2,9 +2,12 @@ define(function(require) { 'use strict'; -var documentElement = require('./documentElement'), +var $ = require('libs/jquery'), + _ = require('libs/underscore'), + documentElement = require('./documentElement'), utils = require('./utils'), - wlxmlUtils = require('utils/wlxml'); + wlxmlUtils = require('utils/wlxml'), + CommentsView = require('./comments/comments'); var labelWidget = function(tag, klass) { return $('') @@ -13,8 +16,91 @@ var labelWidget = function(tag, klass) { }; void(labelWidget); // for linters; labelWidget is unused on purpose for now +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) { + var el = this.canvas.createElement(node); + if(el.dom) { + this._container().append(el.dom); + } + }.bind(this)); + + this.commentsView = new CommentsView(this.wlxmlNode, this.canvas.metadata.user); + this.addToGutter(this.commentsView); + this.commentTip = $('
'); + this.addWidget(this.commentTip); + + if(!this.wlxmlNode.hasChild({klass: 'comment'})) { + this.commentTip.hide(); + } + + 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(params) { + var toret; + + params = _.extend({ + considerChildren: true + }, params); + + this.children().some(function(child) { + if(child instanceof documentElement.DocumentTextElement) { + toret = child; + return true; // break + } else if(params.considerChildren) { + toret = child.getVerticallyFirstTextElement(); + if(toret) { + return true; // break + } + } + }); + return toret; + }, -var generic = { onNodeAttrChange: function(event) { if(event.meta.attr === 'class') { this.setWlxmlClass(event.meta.newVal); // @@ -26,24 +112,37 @@ var generic = { return; } - var nodeIndex = event.meta.node.getIndex(), + var ptr = event.meta.node.prev(), referenceElement, referenceAction, actionArg; + + while(ptr && !(referenceElement = utils.getElementForElementRootNode(ptr))) { + ptr = ptr.prev(); + } - if(nodeIndex === 0) { + if(referenceElement) { + referenceAction = 'after'; + } else { referenceElement = this; referenceAction = 'prepend'; - } else { - referenceElement = this.children()[nodeIndex-1]; - referenceAction = 'after'; + } + + if(event.meta.move) { + /* Let's check if this node had its own canvas element and it's accessible. */ + actionArg = utils.getElementForElementRootNode(event.meta.node); + } + if(!actionArg) { + 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); + + if(event.meta.node.is('comment')) { + this.commentTip.show(); + this.commentsView.render(); + } }, onNodeDetached: function(event) { + var isComment = event.meta.node.is('comment'); if(event.meta.node.sameNode(this)) { this.detach(); } else { @@ -53,12 +152,19 @@ var generic = { return true; } }); + if(isComment && !this.wlxmlNode.hasChild({klass: 'comment'})) { + this.commentTip.hide(); + } + this.commentsView.render(); } }, onNodeTextChange: function(event) { - var toSet = event.meta.node.getText(); - this.children().some(function(child) { - if(child.wlxmlNode.sameNode(event.meta.node)) { + var node = event.meta.node, + toSet = node.getText(), + handled; + + handled = this.children().some(function(child) { + if(child.wlxmlNode.sameNode(node)) { if(toSet === '') { toSet = utils.unicode.ZWS; } @@ -68,6 +174,39 @@ var generic = { return true; } }); + + if(!handled && node.parent() && node.parent().is('comment') && this.wlxmlNode.sameNode(node.parent().parent())) { + this.commentsView.render(); + } + }, + + onStateChange: function(changes) { + if(_.isBoolean(changes.exposed) && !this.isSpan()) { + this._container().toggleClass('highlighted-element', changes.exposed); + } + if(_.isBoolean(changes.active) && !this.isSpan()) { + this._container().toggleClass('current-node-element', changes.active); + } + }, + + /// + + isSpan: function() { + return this.wlxmlNode.getTagName() === 'span'; + }, + + 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) { @@ -77,32 +216,11 @@ var generic = { } else { element = this.canvas.createElement(param); } - this._container().prepend(element.dom()); - this.refreshPath(); - 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; + if(element.dom) { + this._container().prepend(element.dom); + this.refreshPath(); } - return idx1 <= idx2 ? e1: e2; + return element; }, childIndex: function(child) { @@ -135,44 +253,8 @@ var generic = { this._container().removeAttr('wlxml-class'); } this.refreshPath(); - }, - init: function() { - 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)); - }, - 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; - }, -}; + } +}); return generic;