a00bf3cdd2891fb910b816fc8b9797cb385aa3af
[fnpeditor.git] / src / editor / modules / rng / rng.js
1 define([
2 './documentSummary',
3 'libs/underscore',
4 'fnpjs/layout',
5 'fnpjs/vbox',
6 'fnpjs/logging/logging',
7 'views/tabs/tabs',
8 'libs/text!./mainLayout.html',
9 'libs/text!./editingLayout.html',
10 'libs/text!./diffLayout.html',
11 ], function(documentSummary, _, layout, vbox, logging, tabs, mainLayoutTemplate, visualEditingLayoutTemplate, diffLayoutTemplate) {
12
13 'use strict';
14
15 return function(sandbox) {
16
17     /* globals gettext */
18
19     var logger = logging.getLogger('editor.modules.rng');
20     
21     function addMainTab(title, slug, view) {
22         views.mainTabs.addTab(title, slug, view);
23     }
24      
25     var commands = {
26         highlightDocumentElement: function(element, origin) {
27             ///'nodeBreadCrumbs', 'nodeFamilyTree'
28             ['documentCanvas', 'nodeFamilyTree'].forEach(function(moduleName) {
29                 if(!origin || moduleName !== origin) {
30                     sandbox.getModule(moduleName).highlightElement(element);
31                 }
32             });
33         },
34         dimDocumentElement: function(element, origin) {
35             //'nodeBreadCrumbs', 'nodeFamilyTree'
36             ['documentCanvas', 'nodeFamilyTree'].forEach(function(moduleName) {
37                 if(!origin || moduleName !== origin) {
38                     sandbox.getModule(moduleName).dimElement(element);
39                 }
40             });
41         },
42         jumpToDocumentElement: function(element) {
43             sandbox.getModule('documentCanvas').jumpToElement(element);
44         },
45         updateCurrentNodeElement: function(nodeElement) {
46             sandbox.getModule('nodePane').setNodeElement(nodeElement);
47             sandbox.getModule('nodeFamilyTree').setElement(nodeElement);
48             sandbox.getModule('nodeBreadCrumbs').setNodeElement(nodeElement);
49             sandbox.getModule('documentToolbar').setNodeElement(nodeElement);
50             sandbox.getModule('metadataEditor').setNodeElement(nodeElement);
51         },
52         updateCurrentTextElement: function(textElement) {
53             sandbox.getModule('nodeFamilyTree').setElement(textElement);
54         }
55     };
56     
57
58     var views = {
59         mainLayout: new layout.Layout(mainLayoutTemplate),
60         mainTabs: (new tabs.View()).render(),
61         visualEditing: new layout.Layout(visualEditingLayoutTemplate),
62         visualEditingSidebar: (new tabs.View({stacked: true})).render(),
63         currentNodePaneLayout: new vbox.VBox(),
64         diffLayout: new layout.Layout(diffLayoutTemplate)
65     };
66     
67     views.visualEditing.setView('rightColumn', views.visualEditingSidebar.getAsView());
68     addMainTab(gettext('Editor'), 'editor', views.visualEditing.getAsView());
69     addMainTab(gettext('Source'), 'sourceEditor',  '');
70     addMainTab(gettext('History'), 'history', views.diffLayout.getAsView());
71     
72     sandbox.getDOM().append(views.mainLayout.getAsView());
73     
74     views.visualEditingSidebar.addTab({icon: 'pencil'}, 'edit', views.currentNodePaneLayout.getAsView());
75
76     var wlxmlDocument, documentIsDirty;
77     
78     /* Events handling */
79     
80     var eventHandlers = {};
81      
82     eventHandlers.sourceEditor = {
83         ready: function() {
84             addMainTab(gettext('Source'), 'sourceEditor',  sandbox.getModule('sourceEditor').getView());
85             sandbox.getModule('sourceEditor').setDocument(sandbox.getModule('data').getDocument());
86         }
87     };
88     
89     eventHandlers.data = {
90         ready: function(usingDraft, draftTimestamp) {
91             views.mainLayout.setView('mainView', views.mainTabs.getAsView());
92             
93             documentSummary.init(sandbox.getConfig().documentSummaryView);
94             documentSummary.render(sandbox.getModule('data').getDocumentProperties());
95             documentSummary.setDraftField(usingDraft ? (draftTimestamp || '???') : '-');
96             views.currentNodePaneLayout.appendView(documentSummary.dom);
97
98             _.each(['sourceEditor', 'documentCanvas', 'documentToolbar', 'nodePane', 'metadataEditor', 'nodeFamilyTree', 'nodeBreadCrumbs', 'mainBar', 'indicator', 'documentHistory', 'diffViewer'], function(moduleName) {
99                 sandbox.getModule(moduleName).start();
100             });
101             
102             wlxmlDocument = sandbox.getModule('data').getDocument();
103             documentIsDirty = false;
104             wlxmlDocument.on('change', function() {
105                 documentIsDirty = true;
106             });
107             wlxmlDocument.on('contentSet', function() {
108                 documentIsDirty = true;
109             });
110         },
111         draftDropped: function() {
112             documentSummary.setDraftField('-');
113         },
114         savingStarted: function(what) {
115             var msg = {
116                 remote: gettext('Saving document'),
117                 local: gettext('Saving local copy')
118             };
119             sandbox.getModule('mainBar').setCommandEnabled('save', false);
120             sandbox.getModule('indicator').showMessage(msg[what] + '...');
121         },
122         savingEnded: function(status, what, data) {
123             void(status);
124             var msg = {
125                 remote: gettext('Document saved'),
126                 local: gettext('Local copy saved')
127             };
128             documentIsDirty = false;
129             sandbox.getModule('mainBar').setCommandEnabled('save', true);
130             sandbox.getModule('indicator').clearMessage({message: msg[what]});
131             if(status === 'success' && what === 'remote') {
132                 sandbox.getModule('mainBar').setVersion(data.version);
133                 documentSummary.render(data);
134                 documentSummary.setDraftField('-');
135             }
136             if(what === 'local') {
137                 documentSummary.setDraftField(data.timestamp);
138             }
139         },
140         restoringStarted: function(event) {
141             sandbox.getModule('mainBar').setCommandEnabled('save', false);
142             sandbox.getModule('indicator').showMessage(gettext('Restoring version ') + event.version + '...');
143         },
144         historyItemAdded: function(item) {
145             sandbox.getModule('documentHistory').addHistory([item], {animate: true});
146         },
147         diffFetched: function(diff) {
148             sandbox.getModule('diffViewer').setDiff(diff);
149         },
150         documentReverted: function(version) {
151             documentIsDirty = false;
152             sandbox.getModule('mainBar').setCommandEnabled('save', true);
153             sandbox.getModule('indicator').clearMessage({message:'Wersja ' + version + ' przywrócona'});
154             sandbox.getModule('mainBar').setVersion(version);
155         }
156     };
157     
158     eventHandlers.mainBar = {
159         ready: function() {
160             sandbox.getModule('mainBar').setVersion(sandbox.getModule('data').getDocumentProperties().version);
161             views.mainLayout.setView('topPanel', sandbox.getModule('mainBar').getView());
162         },
163         'cmd.save': function() {
164             var sourceEditor = sandbox.getModule('sourceEditor');
165             if(!sourceEditor.changesCommited()) {
166                 logger.debug('Source editor has uncommited changes, commiting...');
167                 sourceEditor.commitChanges();
168             }
169             sandbox.getModule('data').saveDocument();
170         },
171         'cmd.drop-draft': function() {
172             sandbox.getModule('data').dropDraft();
173         }
174     };
175     
176     eventHandlers.indicator = {
177         ready: function() {
178             views.mainLayout.setView('messages', sandbox.getModule('indicator').getView());
179         }
180     };
181     
182
183     
184     eventHandlers.documentCanvas = {
185         ready: function() {
186             sandbox.getModule('documentCanvas').setDocument(sandbox.getModule('data').getDocument());
187             views.visualEditing.setView('leftColumn', sandbox.getModule('documentCanvas').getView());
188         },
189         
190         currentTextElementSet: function(textElement) {
191             commands.updateCurrentTextElement(textElement);
192         },
193
194         currentNodeElementSet: function(nodeElement) {
195             commands.updateCurrentNodeElement(nodeElement);
196         },
197         
198         currentNodeElementChanged: function(nodeElement) {
199             commands.updateCurrentNodeElement(nodeElement);
200         },
201
202         nodeHovered: function(canvasNode) {
203             commands.highlightDocumentNode(canvasNode);
204         },
205         
206         nodeBlured: function(canvasNode) {
207             commands.dimDocumentNode(canvasNode);
208         }
209     };
210
211     eventHandlers.nodePane = {
212         ready: function() {
213             views.currentNodePaneLayout.appendView(sandbox.getModule('nodePane').getView());
214         },
215         
216         nodeElementChange: function(attr, value) {
217             sandbox.getModule('documentCanvas').modifyCurrentNodeElement(attr, value);
218         }
219     };
220     
221     eventHandlers.metadataEditor = {
222         ready: function() {
223             sandbox.getModule('metadataEditor').setDocument(sandbox.getModule('data').getDocument());
224             views.visualEditingSidebar.addTab({icon: 'info-sign'}, 'metadataEditor', sandbox.getModule('metadataEditor').getView());
225         }
226     };
227     
228     eventHandlers.nodeFamilyTree = {
229         ready: function() {
230             views.currentNodePaneLayout.appendView(sandbox.getModule('nodeFamilyTree').getView());
231         },
232         nodeEntered: function(node) {
233             commands.highlightDocumentElement(node, 'nodeFamilyTree');
234         },
235         nodeLeft: function(node) {
236             commands.dimDocumentElement(node, 'nodeFamilyTree');
237         },
238         nodeClicked: function(node) {
239             commands.jumpToDocumentElement(node);
240         }
241     };
242     
243     eventHandlers.documentToolbar = {
244         ready: function() {
245             views.visualEditing.setView('toolbar', sandbox.getModule('documentToolbar').getView());
246         },
247         command: function(cmd, params) {
248             sandbox.getModule('documentCanvas').command(cmd, params);
249         }
250     };
251     
252     eventHandlers.nodeBreadCrumbs = {
253         ready: function() {
254             views.visualEditing.setView('statusBar', sandbox.getModule('nodeBreadCrumbs').getView());
255         },
256         elementEntered: function(element) {
257             commands.highlightDocumentElement(element, 'nodeBreadCrumbs');
258         },
259         elementLeft: function(element) {
260             commands.dimDocumentElement(element, 'nodeBreadCrumbs');
261         },
262         elementClicked: function(element) {
263             commands.jumpToDocumentElement(element);
264         }
265     };
266     
267     eventHandlers.documentHistory = {
268         ready: function() {
269             sandbox.getModule('documentHistory').addHistory(sandbox.getModule('data').getHistory());
270             views.diffLayout.setView('left', sandbox.getModule('documentHistory').getView());
271         },
272         compare: function(ver1, ver2) {
273             sandbox.getModule('data').fetchDiff(ver1, ver2);
274         },
275         restoreVersion: function(version) {
276             sandbox.getModule('data').restoreVersion(version);
277         },
278         displayVersion: function(event) {
279             /* globals window */
280             window.open('/' + gettext('editor') + '/' + sandbox.getModule('data').getDocumentId() + '?version=' + event.version, _.uniqueId());
281         }
282     };
283     
284     eventHandlers.diffViewer = {
285         ready: function() {
286             views.diffLayout.setView('right', sandbox.getModule('diffViewer').getView());
287         }
288     };
289
290     window.addEventListener('beforeunload', function(event) {
291         var txt = gettext('Do you really want to exit?');
292         if(documentIsDirty) {
293             txt += ' ' + gettext('Document contains unsaved changes!');
294         }
295         event.returnValue = txt; // FF
296         return txt; // Chrome
297     });
298     
299     /* api */
300     
301     return {
302         start: function() {
303             sandbox.getModule('data').start();
304         },
305         handleEvent: function(moduleName, eventName, args) {
306             var eventRepr = moduleName + '.' + eventName;
307             if(eventHandlers[moduleName] && eventHandlers[moduleName][eventName]) {
308                 logger.debug('Handling event ' + eventRepr);
309                 eventHandlers[moduleName][eventName].apply(eventHandlers, args);
310             } else {
311                 logger.warning('No event handler for ' + eventRepr);
312             }
313
314         }
315     };
316 };
317
318 });