5 'wlxml/extensions/list/list',
6 'fnpjs/logging/logging',
9 ], function($, Dialog, wlxml, listExtension, logging, datetime, Document) {
12 /* global gettext, alert, window */
14 var logger = logging.getLogger('editor.modules.data'),
15 stubDocument = '<section><div>' + gettext('This is an empty document.') + '</div></section>';
18 return function(sandbox) {
20 var document_id = sandbox.getBootstrappedData().document_id;
21 var history = sandbox.getBootstrappedData().history;
22 var documentDirty = false;
23 var draftDirty = false;
25 var documentProperties = {};
26 var data = sandbox.getBootstrappedData();
28 .filter(function(key) {
29 return key !== 'history' && key !== 'document';
31 .forEach(function(key) {
32 documentProperties[key] = data[key];
35 var wlxmlDocument, text;
37 var loadDocument = function(text, isDraft, draftTimestamp) {
38 logger.debug('loading document');
40 wlxmlDocument = wlxml.WLXMLDocumentFromXML(text, {editorConfig: sandbox.getConfig()}, Document);
43 alert(gettext('This document contains errors and can\'t be loaded. :(')); // TODO
44 wlxmlDocument = wlxml.WLXMLDocumentFromXML(stubDocument, {}, Document);
47 wlxmlDocument.registerExtension(listExtension);
48 sandbox.getPlugins().forEach(function(plugin) {
49 if(plugin.documentExtension) {
50 wlxmlDocument.registerExtension(plugin.documentExtension);
54 var modificationFlag = true;
55 var handleChange = function() {
58 modificationFlag = true;
60 wlxmlDocument.on('change', handleChange);
61 wlxmlDocument.on('contentSet', handleChange);
63 if(window.localStorage) {
64 window.setInterval(function() {
65 if(modificationFlag) {
66 modificationFlag = false;
69 if(wlxmlDocument && documentDirty && draftDirty) {
70 var timestamp = datetime.currentStrfmt();
71 logger.debug('Saving draft to local storage.');
72 sandbox.publish('savingStarted', 'local');
73 window.localStorage.setItem(getLocalStorageKey().content, wlxmlDocument.toXML());
74 window.localStorage.setItem(getLocalStorageKey().contentTimestamp, timestamp);
75 sandbox.publish('savingEnded', 'success', 'local', {timestamp: timestamp});
78 }, sandbox.getConfig().autoSaveInterval || 2500);
80 sandbox.publish('ready', isDraft, draftTimestamp);
83 function readCookie(name) {
84 /* global escape, unescape, document */
85 var nameEQ = escape(name) + '=';
86 var ca = document.cookie.split(';');
87 for (var i = 0; i < ca.length; i++) {
89 while (c.charAt(0) === ' ') {
90 c = c.substring(1, c.length);
92 if (c.indexOf(nameEQ) === 0) {
93 return unescape(c.substring(nameEQ.length, c.length));
101 beforeSend: function(xhr, settings) {
102 if (!(/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type))) {
103 xhr.setRequestHeader('X-CSRFToken', readCookie('csrftoken'));
108 var reloadHistory = function() {
111 url: sandbox.getConfig().documentHistoryUrl(document_id),
112 success: function(data) {
114 sandbox.publish('historyItemAdded', data.slice(-1)[0]);
119 var getLocalStorageKey = function() {
120 var base = 'draft-id:' + document_id + '-ver:' + documentProperties.version;
123 contentTimestamp: base + '-content-timestamp'
130 if(window.localStorage) {
131 text = window.localStorage.getItem(getLocalStorageKey().content);
133 var timestamp = window.localStorage.getItem(getLocalStorageKey().contentTimestamp),
136 logger.debug('Local draft exists');
137 var dialog = Dialog.create({
138 title: gettext('Local draft of a document exists'),
139 text: gettext('Unsaved local draft of this version of the document exists in your browser. Do you want to load it instead?'),
140 executeButtonText: gettext('Yes, restore local draft'),
141 cancelButtonText: gettext('No, use version loaded from the server')
143 dialog.on('cancel', function() {
144 logger.debug('Bootstrapped version chosen');
146 text = sandbox.getBootstrappedData().document;
149 dialog.on('execute', function(event) {
150 logger.debug('Local draft chosen');
155 dialog.on('close', function() {
156 loadDocument(text, usingDraft, timestamp);
159 loadDocument(sandbox.getBootstrappedData().document, false);
162 loadDocument(sandbox.getBootstrappedData().document, false);
165 getDocument: function() {
166 return wlxmlDocument;
168 saveDocument: function() {
169 var documentSaveForm = $.extend({
171 content_field_name: 'text',
172 version_field_name: 'version'
174 sandbox.getConfig().documentSaveForm
176 dialog = Dialog.create({
177 fields: documentSaveForm.fields,
178 title: gettext('Save Document'),
179 executeButtonText: gettext('Save'),
180 cancelButtonText: gettext('Cancel')
183 dialog.on('execute', function(event) {
184 sandbox.publish('savingStarted', 'remote');
186 var formData = event.formData;
187 formData[documentSaveForm.content_field_name] = wlxmlDocument.toXML();
188 formData[documentSaveForm.version_field_name] = documentProperties.version;
189 if(sandbox.getConfig().jsonifySentData) {
190 formData = JSON.stringify(formData);
193 dialog.toggleButtons(false);
196 url: sandbox.getConfig().documentSaveUrl(document_id),
198 success: function(data) {
200 sandbox.publish('savingEnded', 'success', 'remote', data);
203 .filter(function(key) {
204 return key !== 'text';
206 .forEach(function(key) {
207 documentProperties[key] = data[key];
212 error: function() {event.error(); sandbox.publish('savingEnded', 'error', 'remote');}
215 dialog.on('cancel', function() {
221 getHistory: function() {
224 fetchDiff: function(ver1, ver2) {
227 url: sandbox.getConfig().documentDiffUrl(document_id),
228 data: {from: ver1, to: ver2},
229 success: function(data) {
230 sandbox.publish('diffFetched', {table: data, ver1: ver1, ver2: ver2});
234 restoreVersion: function(version) {
235 var documentRestoreForm = $.extend({
237 version_field_name: 'version'
239 sandbox.getConfig().documentRestoreForm
241 dialog = Dialog.create({
242 fields: documentRestoreForm.fields,
243 title: gettext('Restore Version'),
244 executeButtonText: gettext('Restore'),
245 cancelButtonText: gettext('Cancel')
248 dialog.on('execute', function(event) {
249 var formData = event.formData;
250 formData[documentRestoreForm.version_field_name] = version;
251 sandbox.publish('restoringStarted', {version: version});
252 if(sandbox.getConfig().jsonifySentData) {
253 formData = JSON.stringify(formData);
258 url: sandbox.getConfig().documentRestoreUrl(document_id),
260 success: function(data) {
262 .filter(function(key) {
263 return key !== 'document';
265 .forEach(function(key) {
266 documentProperties[key] = data[key];
269 wlxmlDocument.loadXML(data.document);
270 documentDirty = false;
271 sandbox.publish('documentReverted', data.version);
278 dropDraft: function() {
279 logger.debug('Dropping a draft...');
280 wlxmlDocument.loadXML(sandbox.getBootstrappedData().document);
282 logger.debug('Draft dropped');
283 sandbox.publish('draftDropped');
285 getDocumentId: function() {
288 getDocumentProperties: function() {
289 return documentProperties;