Visual editor - working sidebar
[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         },\r
93         _addMetaRow: function(key, value) {\r
94             var newRow = $(sandbox.getTemplate('metaItem')({key: key || '', value: value || ''}));\r
95             newRow.appendTo(this.metaTable);\r
96             return newRow;\r
97         }\r
98     };\r
99     \r
100     \r
101     var sideBarView = {\r
102         node: view.node.find('#rng-visualEditor-sidebar'),\r
103         setup: function() {\r
104             var view = this;\r
105             this.node.find('#rng-visualEditor-sidebarButtons a').click(function(e) {\r
106                 e.preventDefault();\r
107                 var target = $(e.currentTarget);\r
108                 if(!target.attr('data-content-id'))\r
109                     return;\r
110                 view.selectTab(target.attr('data-content-id'));\r
111             });\r
112             view.selectTab('rng-visualEditor-edit');\r
113         },\r
114         selectTab: function(id) {\r
115            this.node.find('.rng-visualEditor-sidebarContentItem').hide();\r
116            this.node.find('#'+id).show();\r
117            this.node.find('#rng-visualEditor-sidebarButtons li').removeClass('active');\r
118            this.node.find('#rng-visualEditor-sidebarButtons li a[data-content-id=' + id + ']').parent().addClass('active');\r
119         \r
120         }\r
121     \r
122     }\r
123     \r
124     view.setup();\r
125     sideBarView.setup();\r
126     \r
127     var isDirty = false;\r
128     \r
129     \r
130     return {\r
131         start: function() {\r
132             sandbox.publish('ready');\r
133         },\r
134         getView: function() {\r
135             return view.node;\r
136         },\r
137         setDocument: function(xml) {\r
138             var transformed = transformations.fromXML.getDocumentDescription(xml);\r
139             view.setBody(transformed.HTMLTree);\r
140             view.setMetaData(transformed.metadata);\r
141             isDirty = false;\r
142         },\r
143         getDocument: function() {\r
144             return transformations.toXML.getXML({HTMLTree: view.getBody(), metadata: view.getMetaData()});\r
145         },\r
146         isDirty: function() {\r
147             return isDirty;\r
148         },\r
149         setDirty: function(dirty) {\r
150             isDirty = dirty;\r
151         }\r
152     \r
153     }\r
154 };