From: Aleksander Ɓukasz Date: Fri, 25 Jul 2014 08:19:14 +0000 (+0200) Subject: editor: canvas containers X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/5d2695bd243591aa1697733184d07cdb3e67cf74?hp=45bebc5c454ced236db27631004cc2628260f3c9 editor: canvas containers --- diff --git a/src/editor/modules/documentCanvas/canvas/container.js b/src/editor/modules/documentCanvas/canvas/container.js new file mode 100644 index 0000000..6436526 --- /dev/null +++ b/src/editor/modules/documentCanvas/canvas/container.js @@ -0,0 +1,158 @@ +define(function(require) { + +'use strict'; + +var $ = require('libs/jquery'), + _ = require('libs/underscore'), + utils = require('./utils'); + + +var Container = function(nodes, params, element) { + _.extend(this, params); + this.dom = this.dom || $('
'); + this.dom.addClass('canvas-container'); + this.element = element; + + nodes.forEach(function(node) { + var el = this.element.canvas.createElement(node); + if(el.dom) { + this.dom.append(el.dom); + } + }.bind(this)); +}; + +_.extend(Container.prototype, { + remove: function() { + this.element.removeContainer(this); + }, + + onNodeAdded: function(event) { + if(event.meta.node.isRoot()) { + this.element.canvas.reloadRoot();// + return; + } + + var ptr = event.meta.node.prev(), + referenceElement, referenceAction, actionArg; + + while(ptr && !(referenceElement = utils.getElementForElementRootNode(ptr))) { + ptr = ptr.prev(); + } + + if(referenceElement) { + referenceAction = 'after'; + } else { + referenceElement = this; + referenceAction = '_prepend'; + } + + 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; + } + + referenceElement[referenceAction](actionArg); + }, + onNodeDetached: function(event) { + var container = this; + this.dom.contents().each(function() { + var childElement = container.element.canvas.getDocumentElement(this); + if(childElement && childElement.wlxmlNode.sameNode(event.meta.node)) { + childElement.detach(); + return false; + } + }); + }, + getVerticallyFirstTextElement: function(params) { + var documentElement = require('./documentElement'), + 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; + }, + 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; + }, + + _prepend: function(param) { + var documentElement = require('./documentElement'), + element; + if(param instanceof documentElement.DocumentElement) { + element = param; + } else { + element = this.element.canvas.createElement(param);// + } + if(element.dom) { + this.dom.prepend(element.dom); + } + return element; + }, + _childIndex: function(child) { + var children = this.children(), + toret = null; + children.forEach(function(c, idx) { + if(c.sameNode(child)) { + toret = idx; + return false; + } + }); + return toret; + }, + containsBlock: function() { + var documentElement = require('./documentElement'); + return this.children() + .filter(function(child) { + return child instanceof documentElement.DocumentNodeElement; + }) + .some(function(child) { + if(child.isBlock()) { + return true; + } else { + return child.containsBlock(); + } + }); + }, + children: function() { + var element = this.element.canvas, + toret = []; + this.dom.contents().each(function() { + var childElement = element.getDocumentElement(this); + if(childElement === undefined) { + return true; + } + + toret.push(childElement); + }); + return toret; + }, +}); + +return { + create: function(nodes, params, element) { + return new Container(nodes, params, element); + } +}; + +}); \ No newline at end of file diff --git a/src/editor/modules/documentCanvas/canvas/documentElement.js b/src/editor/modules/documentCanvas/canvas/documentElement.js index 7bbc5c1..859a80b 100644 --- a/src/editor/modules/documentCanvas/canvas/documentElement.js +++ b/src/editor/modules/documentCanvas/canvas/documentElement.js @@ -1,8 +1,9 @@ define([ 'libs/jquery', 'libs/underscore', -'modules/documentCanvas/canvas/utils' -], function($, _, utils) { +'modules/documentCanvas/canvas/utils', +'modules/documentCanvas/canvas/container' +], function($, _, utils, container) { 'use strict'; /* global Node:false */ @@ -93,6 +94,7 @@ $.extend(DocumentElement.prototype, { // DocumentNodeElement represents an element node from WLXML document rendered inside Canvas var DocumentNodeElement = function(wlxmlNode, canvas) { DocumentElement.call(this, wlxmlNode, canvas); + this.containers = []; this.init(this.dom); }; @@ -133,10 +135,35 @@ $.extend(DocumentNodeElement.prototype, { } this.gutterGroup.addView(view); }, + createContainer: function(nodes, params) { + var toret = container.create(nodes, params, this); + this.containers.push(toret); + return toret; + }, + removeContainer: function(container) { + var idx; + if((idx = this.containers.indexOf(container)) !== -1) { + this.containers.splice(idx, 1); + } + }, handle: function(event) { - var method = 'on' + event.type[0].toUpperCase() + event.type.substr(1); - if(this[method]) { - this[method](event); + var method = 'on' + event.type[0].toUpperCase() + event.type.substr(1), + target; + if(event.type === 'nodeAdded' || event.type === 'nodeDetached') { + this.containers.some(function(container) { + if(container.manages(event.meta.node, event.meta.parent)) { + target = container; + return true; + } + }); + } + + if(!target && this[method]) { + target = this; + } + + if(target) { + target[method](event); } }, createDOM: function() { diff --git a/src/editor/modules/documentCanvas/canvas/genericElement.js b/src/editor/modules/documentCanvas/canvas/genericElement.js index a769240..8ed08bf 100644 --- a/src/editor/modules/documentCanvas/canvas/genericElement.js +++ b/src/editor/modules/documentCanvas/canvas/genericElement.js @@ -5,7 +5,6 @@ define(function(require) { var $ = require('libs/jquery'), _ = require('libs/underscore'), documentElement = require('./documentElement'), - utils = require('./utils'), CommentsView = require('./comments/comments'); @@ -20,12 +19,10 @@ $.extend(generic, { .attr('wlxml-tag', this.wlxmlNode.getTagName()) .attr('wlxml-class', this.wlxmlNode.getClass().replace(/\./g, '-')); - this.wlxmlNode.contents().forEach(function(node) { - var el = this.canvas.createElement(node); - if(el.dom) { - this._container().append(el.dom); - } - }.bind(this)); + this.container = this.createContainer(this.wlxmlNode.contents(), { + manages: function(node) { return !node.isInside('comment'); }, + dom: this._container() + }); this.commentsView = new CommentsView(this.wlxmlNode, this.canvas.metadata.user); this.addToGutter(this.commentsView); @@ -52,101 +49,41 @@ $.extend(generic, { }, 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; + return this.container.getFirst(e1, e2); }, - children: function() { - var element = this, - toret = []; - this._container().contents().each(function() { - var childElement = element.canvas.getDocumentElement(this); - if(childElement === undefined) { - return true; - } + containsBlock: function() { + return this.container.containsBlock(); + }, - toret.push(childElement); - }); - return toret; + children: function() { + return this.container.children(); }, 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; + return this.container.getVerticallyFirstTextElement(params); }, onNodeAdded: function(event) { - if(event.meta.node.isRoot()) { - this.canvas.reloadRoot(); - return; - } - - var ptr = event.meta.node.prev(), - referenceElement, referenceAction, actionArg; - - while(ptr && !(referenceElement = utils.getElementForElementRootNode(ptr))) { - ptr = ptr.prev(); - } - - if(referenceElement) { - referenceAction = 'after'; - } else { - referenceElement = this; - referenceAction = 'prepend'; - } - - 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; - } - - referenceElement[referenceAction](actionArg); - 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)) { + // defacto jestesmy rootem? this.detach(); } else { - this.children().some(function(child) { - if(child.wlxmlNode.sameNode(event.meta.node)) { - child.detach(); - return true; - } - }); if(isComment && !this.wlxmlNode.hasChild({klass: 'comment'})) { this.commentTip.hide(); } this.commentsView.render(); } }, + onNodeTextChange: function(event) { var node = event.meta.node; @@ -158,59 +95,14 @@ $.extend(generic, { }, onStateChange: function(changes) { - if(_.isBoolean(changes.exposed) && !this.isSpan()) { + var isSpan = this.wlxmlNode.getTagName() === 'span'; + if(_.isBoolean(changes.exposed) && !isSpan) { this._container().toggleClass('highlighted-element', changes.exposed); } - if(_.isBoolean(changes.active) && !this.isSpan()) { + if(_.isBoolean(changes.active) && !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) { - var element; - if(param instanceof documentElement.DocumentElement) { - element = param; - } else { - element = this.canvas.createElement(param); - } - if(element.dom) { - this._container().prepend(element.dom); - this.refreshPath(); - } - return element; - }, - - childIndex: function(child) { - var children = this.children(), - toret = null; - children.forEach(function(c, idx) { - if(c.sameNode(child)) { - toret = idx; - return false; - } - }); - return toret; - } });