Finishing first take on node meta attributes editing
[fnpeditor.git] / modules / rng / rng.js
1 define([
2 'fnpjs/layout',
3 'fnpjs/vbox',
4 'views/tabs/tabs',
5 'libs/text!./mainLayout.html',
6 'libs/text!./editingLayout.html',
7 'libs/text!./diffLayout.html',
8 ], function(layout, vbox, tabs, mainLayoutTemplate, visualEditingLayoutTemplate, diffLayoutTemplate) {
9
10 'use strict';
11
12 return function(sandbox) {
13     
14     function addMainTab(title, slug, view) {
15         views.mainTabs.addTab(title, slug, view);
16     }
17     
18     var dirty = {
19         sourceEditor: false,
20         documentCanvas: false,
21         metadataEditor: false,
22     };
23     
24     var synchronizeTab = function(slug) {
25         function tabIsDirty(slug) {
26             if(slug === 'editor' && (dirty.documentCanvas || dirty.metadataEditor))
27                 return true;
28             if(slug === 'sourceEditor' && dirty.sourceEditor)
29                 return true;
30             return false;
31         }
32     
33         if(tabIsDirty(slug)) {
34             var reason, doc;
35             if(slug === 'sourceEditor') {
36                 doc = sandbox.getModule('sourceEditor').getDocument();
37                 reason = 'source_edit';
38                 dirty.sourceEditor = false;
39             }
40             if(slug === 'editor') {
41                 doc = dirty.documentCanvas ? sandbox.getModule('documentCanvas').getDocument() : sandbox.getModule('data').getDocument();
42                 if(dirty.metadataEditor) {
43                     doc = sandbox.getModule('metadataEditor').attachMetadata(doc);
44                 }
45                 reason = 'edit';
46                 dirty.documentCanvas = dirty.metadataEditor = false;
47             }
48             sandbox.getModule('data').commitDocument(doc, reason);
49         }
50     };
51     
52     var commands = {
53         highlightDocumentNode: function(canvasNode, origin) {
54             ['documentCanvas', 'nodeBreadCrumbs', 'nodeFamilyTree'].forEach(function(moduleName) {
55                 if(!origin || moduleName != origin)
56                     sandbox.getModule(moduleName).highlightNode(canvasNode);
57             });
58         },
59         dimDocumentNode: function(canvasNode, origin) {
60             ['documentCanvas', 'nodeBreadCrumbs', 'nodeFamilyTree'].forEach(function(moduleName) {
61                 if(!origin || moduleName != origin)
62                     sandbox.getModule(moduleName).dimNode(canvasNode);
63             });
64         },
65         selectNode: function(canvasNode, origin) {
66             sandbox.getModule('documentCanvas').selectNode(canvasNode);
67             this.updateNodesModules(canvasNode);           
68         },
69         updateNodesModules: function(canvasNode) {
70             sandbox.getModule('nodePane').setNode(canvasNode);
71             sandbox.getModule('nodeFamilyTree').setNode(canvasNode);
72             sandbox.getModule('nodeBreadCrumbs').setNode(canvasNode);
73         },
74         resetDocument: function(document, reason) {
75             var modules = [];
76             if(reason === 'source_edit')
77                 modules = ['documentCanvas', 'metadataEditor'];
78             else if (reason === 'edit')
79                 modules = ['sourceEditor'];
80             else if (reason === 'revert')
81                 modules = ['documentCanvas', 'metadataEditor', 'sourceEditor'];
82                 
83             modules.forEach(function(moduleName) {
84                 sandbox.getModule(moduleName).setDocument(document);
85             });
86         }
87     };
88     
89
90     var views = {
91         mainLayout: new layout.Layout(mainLayoutTemplate),
92         mainTabs: (new tabs.View()).render(),
93         visualEditing: new layout.Layout(visualEditingLayoutTemplate),
94         visualEditingSidebar: (new tabs.View({stacked: true})).render(),
95         currentNodePaneLayout: new vbox.VBox(),
96         diffLayout: new layout.Layout(diffLayoutTemplate)
97     };
98     
99     views.visualEditing.setView('rightColumn', views.visualEditingSidebar.getAsView());
100     addMainTab('Edytor', 'editor', views.visualEditing.getAsView());
101     addMainTab(gettext('Source'), 'sourceEditor',  '');
102     addMainTab('Historia', 'history', views.diffLayout.getAsView());
103     
104     sandbox.getDOM().append(views.mainLayout.getAsView());
105     
106     views.visualEditingSidebar.addTab({icon: 'pencil'}, 'edit', views.currentNodePaneLayout.getAsView());
107
108     views.mainTabs.on('tabSelected', function(event) {
109         if(event.prevSlug) {
110             synchronizeTab(event.prevSlug);
111         }
112     });
113     
114     /* Events handling */
115     
116     var eventHandlers = {};
117      
118     eventHandlers.sourceEditor = {
119         ready: function() {
120             addMainTab(gettext('Source'), 'sourceEditor',  sandbox.getModule('sourceEditor').getView());
121             sandbox.getModule('sourceEditor').setDocument(sandbox.getModule('data').getDocument());
122         },
123         xmlChanged: function() {
124             dirty.sourceEditor = true;
125         },
126         documentSet: function() {
127             dirty.sourceEditor = false;
128         }
129     };
130     
131     eventHandlers.data = {
132         ready: function() {
133             views.mainLayout.setView('mainView', views.mainTabs.getAsView());
134             
135             _.each(['sourceEditor', 'documentCanvas', 'documentToolbar', 'nodePane', 'metadataEditor', 'nodeFamilyTree', 'nodeBreadCrumbs', 'mainBar', 'indicator', 'documentHistory', 'diffViewer'], function(moduleName) {
136                 sandbox.getModule(moduleName).start();
137             });
138         },
139         documentChanged: function(document, reason) {
140             commands.resetDocument(document, reason);
141         },
142         savingStarted: function() {
143             sandbox.getModule('mainBar').setCommandEnabled('save', false);
144             sandbox.getModule('indicator').showMessage(gettext('Saving...'));
145         },
146         savingEnded: function(status) {
147             sandbox.getModule('mainBar').setCommandEnabled('save', true);
148             sandbox.getModule('indicator').clearMessage({message:'Dokument zapisany'});
149         },
150         restoringStarted: function(event) {
151             sandbox.getModule('mainBar').setCommandEnabled('save', false);
152             sandbox.getModule('indicator').showMessage(gettext('Restoring version ') + event.version + '...');
153         },
154         historyItemAdded: function(item) {
155             sandbox.getModule('documentHistory').addHistory([item], {animate: true});
156         },
157         diffFetched: function(diff) {
158             sandbox.getModule('diffViewer').setDiff(diff);
159         },
160         documentReverted: function(event) {
161             commands.resetDocument(event.document, 'revert');
162             sandbox.getModule('mainBar').setCommandEnabled('save', true);
163             sandbox.getModule('indicator').clearMessage({message:'Wersja ' + event.reverted_version + ' przywrócona'});
164             sandbox.getModule('mainBar').setVersion(event.current_version);
165         }
166     };
167     
168     eventHandlers.mainBar = {
169         ready: function() {
170             sandbox.getModule('mainBar').setVersion(sandbox.getModule('data').getDocumentVersion());
171             views.mainLayout.setView('topPanel', sandbox.getModule('mainBar').getView());
172         },
173         'cmd.save': function() {
174             synchronizeTab(views.mainTabs.getCurrentSlug());
175             sandbox.getModule('data').saveDocument();
176         }
177     };
178     
179     eventHandlers.indicator = {
180         ready: function() {
181             views.mainLayout.setView('messages', sandbox.getModule('indicator').getView());
182         }
183     };
184     
185
186     
187     eventHandlers.documentCanvas = {
188         ready: function() {
189             sandbox.getModule('documentCanvas').setDocument(sandbox.getModule('data').getDocument());
190             views.visualEditing.setView('leftColumn', sandbox.getModule('documentCanvas').getView());
191         },
192         documentSet: function() {
193             dirty.documentCanvas = false;
194         },
195         
196         nodeSelected: function(canvasNode) {
197             commands.selectNode(canvasNode);
198         },
199         
200         contentChanged: function() {
201             dirty.documentCanvas = true;
202         },
203         
204         currentNodeChanged: function(canvasNode) {
205             commands.updateNodesModules(canvasNode);
206         },
207
208         nodeHovered: function(canvasNode) {
209             commands.highlightDocumentNode(canvasNode);
210         },
211         
212         nodeBlured: function(canvasNode) {
213             commands.dimDocumentNode(canvasNode);
214         }
215     };
216
217     eventHandlers.nodePane = {
218         ready: function() {
219             views.currentNodePaneLayout.appendView(sandbox.getModule('nodePane').getView());
220         },
221         
222         nodeChanged: function(attr, value) {
223             sandbox.getModule('documentCanvas').modifyCurrentNode(attr, value);
224         }
225     };
226     
227     eventHandlers.metadataEditor = {
228         ready: function() {
229             sandbox.getModule('metadataEditor').setDocument(sandbox.getModule('data').getDocument());
230             views.visualEditingSidebar.addTab({icon: 'info-sign'}, 'metadataEditor', sandbox.getModule('metadataEditor').getView());
231         },
232         metadataChanged: function(metadata) {
233             dirty.metadataEditor = true;
234         },
235         metadataSet: function() {
236             dirty.metadataEditor = false;
237         },
238     };
239     
240     eventHandlers.nodeFamilyTree = {
241         ready: function() {
242             views.currentNodePaneLayout.appendView(sandbox.getModule('nodeFamilyTree').getView());
243         },
244         nodeEntered: function(canvasNode) {
245             commands.highlightDocumentNode(canvasNode, 'nodeFamilyTree');
246         },
247         nodeLeft: function(canvasNode) {
248             commands.dimDocumentNode(canvasNode, 'nodeFamilyTree');
249         },
250         nodeSelected: function(canvasNode) {
251             commands.selectNode(canvasNode);
252         }
253     };
254     
255     eventHandlers.documentToolbar = {
256         ready: function() {
257             views.visualEditing.setView('toolbar', sandbox.getModule('documentToolbar').getView());
258         },
259         toggleGrid: function(toggle) {
260             sandbox.getModule('documentCanvas').toggleGrid(toggle);
261         },
262         newNodeRequested: function(wlxmlTag, wlxmlClass) {
263                 sandbox.getModule('documentCanvas').insertNewNode(wlxmlTag, wlxmlClass);
264         },
265         command: function(cmd, meta) {
266             sandbox.getModule('documentCanvas').command(cmd, meta);
267         }
268     };
269     
270     eventHandlers.nodeBreadCrumbs = {
271         ready: function() {
272             views.visualEditing.setView('statusBar', sandbox.getModule('nodeBreadCrumbs').getView());
273         },
274         nodeHighlighted: function(canvasNode) {
275             commands.highlightDocumentNode(canvasNode, 'nodeBreadCrumbs');
276         },
277         nodeDimmed: function(canvasNode) {
278             commands.dimDocumentNode(canvasNode, 'nodeBreadCrumbs');
279         },
280         nodeSelected: function(canvasNode) {
281             commands.selectNode(canvasNode);
282         }        
283     };
284     
285     eventHandlers.documentHistory = {
286         ready: function() {
287             sandbox.getModule('documentHistory').addHistory(sandbox.getModule('data').getHistory());
288             views.diffLayout.setView('left', sandbox.getModule('documentHistory').getView());
289         },
290         compare: function(ver1, ver2) {
291             sandbox.getModule('data').fetchDiff(ver1, ver2);
292         },
293         restoreVersion: function(event) {
294             sandbox.getModule('data').restoreVersion(event);
295         },
296         displayVersion: function(event) {
297             window.open('/' + gettext('editor') + '/' + sandbox.getModule('data').getDocumentId() + '?version=' + event.version, _.uniqueId());
298         }
299     };
300     
301     eventHandlers.diffViewer = {
302         ready: function() {
303             views.diffLayout.setView('right', sandbox.getModule('diffViewer').getView());
304         }
305     };
306     
307     /* api */
308     
309     return {
310         start: function() {
311             sandbox.getModule('data').start();
312         },
313         handleEvent: function(moduleName, eventName, args) {
314             if('')
315                 wysiwigHandler.handleEvent(moduleName, eventName, args);
316             else if(eventHandlers[moduleName] && eventHandlers[moduleName][eventName]) {
317                 eventHandlers[moduleName][eventName].apply(eventHandlers, args);
318             }
319         }
320     };
321 };
322
323 });