1 /*globals Editor fileId SplitView PanelContainerView EditorView FlashView messageCenter*/
2 Editor.Model = Editor.Object.extend({
8 Editor.ToolbarButtonsModel = Editor.Model.extend({
9 className: 'Editor.ToolbarButtonsModel',
10 serverURL: '/api/toolbar/buttons',
18 if (!this.get('buttons').length) {
22 success: this.loadSucceeded.bind(this)
27 loadSucceeded: function(data) {
28 this.set('buttons', data);
35 // -> error -> loading
37 // empty -> loading -> synced -> unsynced -> loading
39 // -> dirty -> updating -> updated -> synced
41 Editor.XMLModel = Editor.Model.extend({
42 _className: 'Editor.XMLModel',
47 init: function(serverURL, revision) {
49 this.set('state', 'empty');
50 this.set('revision', revision);
51 this.serverURL = serverURL;
52 this.toolbarButtonsModel = new Editor.ToolbarButtonsModel();
53 this.addObserver(this, 'data', this.dataChanged.bind(this));
56 load: function(force) {
57 if (force || this.get('state') == 'empty') {
58 this.set('state', 'loading');
62 data: {revision: this.get('revision')},
63 success: this.loadingSucceeded.bind(this),
64 error: this.loadingFailed.bind(this)
71 loadingSucceeded: function(data) {
72 if (this.get('state') != 'loading') {
73 alert('erroneous state:', this.get('state'));
75 this.set('data', data);
76 this.set('state', 'synced');
79 loadingFailed: function() {
80 if (this.get('state') != 'loading') {
81 alert('erroneous state:', this.get('state'));
83 this.set('error', 'Nie udało się załadować panelu');
84 this.set('state', 'error');
87 update: function(message) {
88 if (this.get('state') == 'dirty') {
89 this.set('state', 'updating');
92 contents: this.get('data'),
93 revision: this.get('revision')
96 payload.message = message;
104 success: this.updatingSucceeded.bind(this),
105 error: this.updatingFailed.bind(this)
112 updatingSucceeded: function(data) {
113 if (this.get('state') != 'updating') {
114 alert('erroneous state:', this.get('state'));
116 this.set('revision', data.revision);
117 this.set('state', 'updated');
120 updatingFailed: function() {
121 if (this.get('state') != 'updating') {
122 alert('erroneous state:', this.get('state'));
124 messageCenter.addMessage('error', 'Uaktualnienie nie powiodło się', 'Uaktualnienie nie powiodło się');
125 this.set('state', 'dirty');
129 set: function(property, value) {
130 if (property == 'state') {
131 console.log(this.description(), ':', property, '=', value);
133 return this._super(property, value);
136 dataChanged: function(property, value) {
137 if (this.get('state') == 'synced') {
138 this.set('state', 'dirty');
142 dispose: function() {
143 this.removeObserver(this);
149 Editor.HTMLModel = Editor.Model.extend({
150 _className: 'Editor.HTMLModel',
155 init: function(serverURL, revision) {
157 this.set('state', 'empty');
158 this.set('revision', revision);
159 this.serverURL = serverURL;
162 load: function(force) {
163 if (force || this.get('state') == 'empty') {
164 this.set('state', 'loading');
168 data: {revision: this.get('revision')},
169 success: this.loadingSucceeded.bind(this),
170 error: this.loadingFailed.bind(this)
175 loadingSucceeded: function(data) {
176 if (this.get('state') != 'loading') {
177 alert('erroneous state:', this.get('state'));
179 this.set('data', data);
180 this.set('state', 'synced');
183 loadingFailed: function() {
184 if (this.get('state') != 'loading') {
185 alert('erroneous state:', this.get('state'));
187 this.set('error', 'Nie udało się załadować panelu');
188 this.set('state', 'error');
192 set: function(property, value) {
193 if (property == 'state') {
194 console.log(this.description(), ':', property, '=', value);
196 return this._super(property, value);
201 Editor.ImageGalleryModel = Editor.Model.extend({
202 _className: 'Editor.ImageGalleryModel',
207 init: function(serverURL) {
209 this.set('state', 'empty');
210 this.serverURL = serverURL;
215 load: function(force) {
216 if (force || this.get('state') == 'empty') {
217 this.set('state', 'loading');
221 success: this.loadingSucceeded.bind(this)
226 loadingSucceeded: function(data) {
227 if (this.get('state') != 'loading') {
228 alert('erroneous state:', this.get('state'));
231 console.log('galleries:', data);
233 if (data.length === 0) {
234 this.set('data', []);
237 this.set('data', data[0].pages);
240 this.set('state', 'synced');
243 set: function(property, value) {
244 if (property == 'state') {
245 console.log(this.description(), ':', property, '=', value);
247 return this._super(property, value);
252 Editor.DocumentModel = Editor.Model.extend({
253 _className: 'Editor.DocumentModel',
254 data: null, // name, text_url, user_revision, latest_shared_rev, parts_url, dc_url, size, merge_url
260 this.set('state', 'empty');
265 if (this.get('state') == 'empty') {
266 this.set('state', 'loading');
269 url: documentsUrl + fileId,
271 success: this.successfulLoad.bind(this)
276 successfulLoad: function(data) {
277 this.set('data', data);
278 this.set('state', 'synced');
279 this.contentModels = {
280 'xml': new Editor.XMLModel(data.text_url, data.user_revision),
281 'html': new Editor.HTMLModel(data.html_url, data.user_revision),
282 'gallery': new Editor.ImageGalleryModel(data.gallery_url)
284 for (var key in this.contentModels) {
285 this.contentModels[key].addObserver(this, 'state', this.contentModelStateChanged.bind(this));
289 contentModelStateChanged: function(property, value, contentModel) {
290 if (value == 'dirty') {
291 this.set('state', 'dirty');
292 for (var key in this.contentModels) {
293 if (this.contentModels[key].guid() != contentModel.guid()) {
294 this.contentModels[key].set('state', 'unsynced');
297 } else if (value == 'updated') {
298 this.set('state', 'synced');
299 for (key in this.contentModels) {
300 if (this.contentModels[key].guid() == contentModel.guid()) {
301 this.contentModels[key].set('state', 'synced');
302 this.data.user_revision = this.contentModels[key].get('revision');
303 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.data.user_revision,
304 'Uaktualnienie dokumentu do wersji ' + this.data.user_revision);
307 for (key in this.contentModels) {
308 if (this.contentModels[key].guid() != contentModel.guid()) {
309 this.contentModels[key].set('revision', this.data.user_revision);
310 this.contentModels[key].set('state', 'empty');
316 saveDirtyContentModel: function(message) {
317 for (var key in this.contentModels) {
318 if (this.contentModels[key].get('state') == 'dirty') {
319 this.contentModels[key].update(message);
326 this.set('state', 'loading');
328 url: this.data.merge_url,
333 target_revision: this.data.user_revision
335 complete: this.updateCompleted.bind(this),
336 success: function(data) { this.set('updateData', data); }.bind(this)
340 updateCompleted: function(xhr, textStatus) {
341 console.log(xhr.status, textStatus);
342 if (xhr.status == 200) { // Sukces
343 this.data.user_revision = this.get('updateData').revision;
344 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision,
345 'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision);
346 for (var key in this.contentModels) {
347 this.contentModels[key].set('revision', this.data.user_revision);
348 this.contentModels[key].set('state', 'empty');
350 } else if (xhr.status == 202) { // Wygenerowano PullRequest (tutaj?)
351 } else if (xhr.status == 204) { // Nic nie zmieniono
352 } else if (xhr.status == 409) { // Konflikt podczas operacji
354 this.set('state', 'synced');
355 this.set('updateData', null);
358 merge: function(message) {
359 this.set('state', 'loading');
361 url: this.data.merge_url,
366 target_revision: this.data.user_revision,
369 complete: this.mergeCompleted.bind(this),
370 success: function(data) { this.set('mergeData', data); }.bind(this)
374 mergeCompleted: function(xhr, textStatus) {
375 console.log(xhr.status, textStatus);
376 if (xhr.status == 200) { // Sukces
377 this.data.user_revision = this.get('mergeData').revision;
378 for (var key in this.contentModels) {
379 this.contentModels[key].set('revision', this.data.user_revision);
380 this.contentModels[key].set('state', 'empty');
382 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.get('mergeData').revision,
383 'Uaktualnienie dokumentu do wersji ' + this.get('mergeData').revision);
384 } else if (xhr.status == 202) { // Wygenerowano PullRequest
385 } else if (xhr.status == 204) { // Nic nie zmieniono
386 } else if (xhr.status == 409) { // Konflikt podczas operacji
388 this.set('state', 'synced');
389 this.set('mergeData', null);
393 set: function(property, value) {
394 if (property == 'state') {
395 console.log(this.description(), ':', property, '=', value);
397 return this._super(property, value);
402 var leftPanelView, rightPanelContainer, doc;
406 documentsUrl = $('#api-base-url').text() + '/';
407 Editor.ToolbarButtonsModel.serverURL = $('#api-toolbar-url').text();
409 doc = new Editor.DocumentModel();
410 var editor = new EditorView('#body-wrap', doc);
412 var flashView = new FlashView('#flashview', messageCenter);
413 var splitView = new SplitView('#splitview', doc);
414 leftPanelView = new PanelContainerView('#left-panel-container', doc);
415 rightPanelContainer = new PanelContainerView('#right-panel-container', doc);