empty text nodes after spans
[fnpeditor.git] / src / editor / modules / documentCanvas / canvas / genericElement.js
1 define(function(require) {
2     
3 'use strict';
4
5 var $ = require('libs/jquery'),
6     _ = require('libs/underscore'),
7     documentElement = require('./documentElement'),
8     CommentsView = require('./comments/comments');
9
10
11 var DocumentNodeElement = documentElement.DocumentNodeElement;
12
13 var generic = Object.create(DocumentNodeElement.prototype);
14
15 $.extend(generic, {
16     init: function() {
17         DocumentNodeElement.prototype.init.call(this);
18         this._container()
19             .attr('wlxml-tag', this.wlxmlNode.getTagName())
20             .attr('wlxml-class', this.wlxmlNode.getClass().replace(/\./g, '-'));
21
22         this.container = this.createContainer(this.wlxmlNode.contents(), {
23             manages: function(node) { return !node.isInside('comment'); },
24             dom: this._container()
25         });
26
27         this.commentsView = new CommentsView(this.wlxmlNode, this.canvas.metadata.user);
28         this.addToGutter(this.commentsView);
29         this.commentTip = $('<div class="comment-tip"><i class="icon-comment"></i></div>');
30         this.addWidget(this.commentTip);
31
32         if(!this.wlxmlNode.hasChild({klass: 'comment'})) {
33             this.commentTip.hide();
34         }
35
36         this.refresh();
37     },
38     
39     refresh: function() {
40         if(this.wlxmlNode.getTagName() === 'span' || this.wlxmlNode.getTagName() === 'aside') {
41             if(this.containsBlock()) {
42                 this.displayAsBlock();
43             } else {
44                 this.displayInline();
45             }
46         } else {
47             this.displayAsBlock();
48         }
49     },
50
51     getFirst: function(e1, e2) {
52         return this.container.getFirst(e1, e2);
53     },
54
55     containsBlock: function() {
56         return this.container.containsBlock();
57     },
58
59     children: function() {
60         return this.container.children();
61     },
62
63     getVerticallyFirstTextElement: function(params) {
64         return this.container.getVerticallyFirstTextElement(params);
65     },
66
67     onNodeAdded: function(event) {
68         if(event.meta.node.is('comment')) {
69             this.commentTip.show();
70             this.commentsView.render();
71         }
72     },
73
74     onNodeDetached: function(event) {
75         var isComment = event.meta.node.is('comment');
76         if(event.meta.node.sameNode(this)) {
77             // defacto jestesmy rootem?
78             this.detach();
79         } else {
80             if(isComment && !this.wlxmlNode.hasChild({klass: 'comment'})) {
81                 this.commentTip.hide();
82             }
83             this.commentsView.render();
84         }
85     },
86
87     onNodeTextChange: function(event) {
88         var node = event.meta.node;
89
90         /* TODO: This handling of changes to the comments should probably be implemented via separate,
91         non-rendering comments element */
92         if(node.parent() && node.parent().is('comment') && this.wlxmlNode.sameNode(node.parent().parent())) {
93             this.commentsView.render();
94         }
95     },
96
97     onStateChange: function(changes) {
98         var isSpan = this.wlxmlNode.getTagName() === 'span';
99         if(_.isBoolean(changes.exposed) && !isSpan) {
100             this._container().toggleClass('highlighted-element', changes.exposed);
101         }
102         if(_.isBoolean(changes.active) && !isSpan) {
103             this._container().toggleClass('current-node-element', changes.active);
104         }
105     },
106 });
107
108
109 return generic;
110
111
112
113 });