Visual editor: edit pane reacts to node selecting
[fnpeditor.git] / modules / visualEditor.js
1 rng.modules.visualEditor = function(sandbox) {\r
2     var transformations = rng.modules.visualEditor.transformations;\r
3 \r
4     var view = {\r
5         node: $(sandbox.getTemplate('main')()),\r
6         setup: function() {\r
7             var view = this;\r
8
9             this.node.find('#rng-visualEditor-content').on('keyup', function() {\r
10                 isDirty = true;\r
11             });\r
12             \r
13             this.node.find('#rng-visualEditor-meta').on('keyup', function() {\r
14                 isDirty = true;\r
15             });\r
16
17             this.node.on('mouseover', '[wlxml-tag]', function(e) { $(e.target).addClass('rng-hover')});\r
18             this.node.on('mouseout', '[wlxml-tag]', function(e) { $(e.target).removeClass('rng-hover')});\r
19             this.node.on('click', '[wlxml-tag]', function(e) {\r
20                 console.log('clicked node type: '+e.target.nodeType);\r
21                 view._markSelected($(e.target));\r
22             });\r
23 \r
24             this.node.on('keyup', '#rng-visualEditor-contentWrapper', function(e) {\r
25                 var anchor = $(window.getSelection().anchorNode);\r
26                 if(anchor[0].nodeType === Node.TEXT_NODE)\r
27                     anchor = anchor.parent();\r
28                 if(!anchor.is('[wlxml-tag]'))\r
29                     return;\r
30                 view._markSelected(anchor);\r
31             });\r
32             \r
33             \r
34             var metaTable = this.metaTable = this.node.find('#rng-visualEditor-meta table');\r
35             \r
36             this.node.find('.rng-visualEditor-metaAddBtn').click(function() {\r
37                 var newRow = view._addMetaRow('', '');\r
38                 $(newRow.find('td div')[0]).focus();\r
39                 isDirty = true;\r
40             });\r
41             \r
42             this.metaTable.on('click', '.rng-visualEditor-metaRemoveBtn', function(e) {\r
43                 $(e.target).closest('tr').remove();\r
44                 isDirty = true;\r
45             });\r
46             \r
47             this.metaTable.on('keydown', '[contenteditable]', function(e) {\r
48                 console.log(e.which);\r
49                 if(e.which === 13) { \r
50                     if($(document.activeElement).hasClass('rng-visualEditor-metaItemKey')) {\r
51                         metaTable.find('.rng-visualEditor-metaItemValue').focus();\r
52                     } else {\r
53                         var input = $('<input>');\r
54                         input.appendTo('body').focus()\r
55                         view.node.find('.rng-visualEditor-metaAddBtn').focus();\r
56                         input.remove();\r
57                     }\r
58                     e.preventDefault();\r
59                 }\r
60                 \r
61             });\r
62
63         },\r
64         getMetaData: function() {\r
65             var toret = {};\r
66             this.metaTable.find('tr').each(function() {\r
67                 var tr = $(this);\r
68                 var inputs = $(this).find('td [contenteditable]');\r
69                 var key = $(inputs[0]).text();\r
70                 var value = $(inputs[1]).text();\r
71                 toret[key] = value;\r
72             });\r
73             console.log(toret);\r
74             return toret;\r
75         },\r
76         setMetaData: function(metadata) {\r
77             var view = this;\r
78             this.metaTable.find('tr').remove();\r
79             _.each(_.keys(metadata), function(key) {    \r
80                 view._addMetaRow(key, metadata[key]);\r
81             });\r
82         },\r
83         setBody: function(HTMLTree) {\r
84             this.node.find('#rng-visualEditor-content').html(HTMLTree);\r
85         },\r
86         getBody: function() {\r
87             return this.node.find('#rng-visualEditor-content').html();\r
88         }, \r
89         _markSelected: function(node) {\r
90             this.node.find('.rng-current').removeClass('rng-current');\r
91             node.addClass('rng-current');\r
92             mediator.nodeSelected(node);\r
93         },\r
94         _addMetaRow: function(key, value) {\r
95             var newRow = $(sandbox.getTemplate('metaItem')({key: key || '', value: value || ''}));\r
96             newRow.appendTo(this.metaTable);\r
97             return newRow;\r
98         }\r
99     };\r
100     \r
101     \r
102     var sideBarView = {\r
103         node: view.node.find('#rng-visualEditor-sidebar'),\r
104         setup: function() {\r
105             var view = this;\r
106             this.node.find('#rng-visualEditor-sidebarButtons a').click(function(e) {\r
107                 e.preventDefault();\r
108                 var target = $(e.currentTarget);\r
109                 if(!target.attr('data-content-id'))\r
110                     return;\r
111                 view.selectTab(target.attr('data-content-id'));\r
112             });\r
113             view.selectTab('rng-visualEditor-edit');\r
114         },\r
115         selectTab: function(id) {\r
116            this.node.find('.rng-visualEditor-sidebarContentItem').hide();\r
117            this.node.find('#'+id).show();\r
118            this.node.find('#rng-visualEditor-sidebarButtons li').removeClass('active');\r
119            this.node.find('#rng-visualEditor-sidebarButtons li a[data-content-id=' + id + ']').parent().addClass('active');\r
120         \r
121         },\r
122         updateEditPane: function(node) {\r
123             var pane = this.node.find('#rng-visualEditor-edit');\r
124             pane.html( $(sandbox.getTemplate('editPane')({tag: node.attr('wlxml-tag'), klass: node.attr('wlxml-class')})));\r
125         }\r
126     }\r
127     \r
128     view.setup();\r
129     sideBarView.setup();\r
130     \r
131     var mediator = {\r
132         nodeSelected: function(node) {\r
133             sideBarView.updateEditPane(node);\r
134         }\r
135     }\r
136     \r
137     var isDirty = false;\r
138     \r
139     \r
140     \r
141     return {\r
142         start: function() {\r
143             sandbox.publish('ready');\r
144         },\r
145         getView: function() {\r
146             return view.node;\r
147         },\r
148         setDocument: function(xml) {\r
149             var transformed = transformations.fromXML.getDocumentDescription(xml);\r
150             view.setBody(transformed.HTMLTree);\r
151             view.setMetaData(transformed.metadata);\r
152             isDirty = false;\r
153         },\r
154         getDocument: function() {\r
155             return transformations.toXML.getXML({HTMLTree: view.getBody(), metadata: view.getMetaData()});\r
156         },\r
157         isDirty: function() {\r
158             return isDirty;\r
159         },\r
160         setDirty: function(dirty) {\r
161             isDirty = dirty;\r
162         }\r
163     \r
164     }\r
165 };