wip: experiments with Canvas support for exercise.assign
[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             mirrors: this.mirror
26         });
27
28         this.commentsView = new CommentsView(this.wlxmlNode, this.canvas.metadata.user);
29         this.addToGutter(this.commentsView);
30         this.commentTip = $('<div class="comment-tip"><i class="icon-comment"></i></div>');
31         this.addWidget(this.commentTip);
32
33         if(!this.wlxmlNode.hasChild({klass: 'comment'})) {
34             this.commentTip.hide();
35         }
36
37         this.refresh();
38     },
39     
40     refresh: function() {
41         if(this.wlxmlNode.getTagName() === 'span' || this.wlxmlNode.getTagName() === 'aside') {
42             if(this.containsBlock()) {
43                 this.displayAsBlock();
44             } else {
45                 this.displayInline();
46             }
47         } else {
48             this.displayAsBlock();
49         }
50     },
51
52     getFirst: function(e1, e2) {
53         return this.container.getFirst(e1, e2);
54     },
55
56     containsBlock: function() {
57         return this.container.containsBlock();
58     },
59
60     children: function() {
61         return this.container.children();
62     },
63
64     getVerticallyFirstTextElement: function(params) {
65         return this.container.getVerticallyFirstTextElement(params);
66     },
67
68     onNodeAdded: function(event) {
69         if(event.meta.node.is('comment')) {
70             this.commentTip.show();
71             this.commentsView.render();
72         }
73     },
74
75     onNodeDetached: function(event) {
76         var isComment = event.meta.node.is('comment');
77         if(event.meta.node.sameNode(this)) {
78             // defacto jestesmy rootem?
79             this.detach();
80         } else {
81             if(isComment && !this.wlxmlNode.hasChild({klass: 'comment'})) {
82                 this.commentTip.hide();
83             }
84             this.commentsView.render();
85         }
86     },
87
88     onNodeTextChange: function(event) {
89         var node = event.meta.node;
90
91         /* TODO: This handling of changes to the comments should probably be implemented via separate,
92         non-rendering comments element */
93         if(node.parent() && node.parent().is('comment') && this.wlxmlNode.sameNode(node.parent().parent())) {
94             this.commentsView.render();
95         }
96     },
97
98     onStateChange: function(changes) {
99         var isSpan = this.wlxmlNode.getTagName() === 'span';
100         if(_.isBoolean(changes.exposed) && !isSpan) {
101             this._container().toggleClass('highlighted-element', changes.exposed);
102         }
103         if(_.isBoolean(changes.active) && !isSpan) {
104             this._container().toggleClass('current-node-element', changes.active);
105         }
106     },
107 });
108
109
110 return generic;
111
112
113
114 });