1 /*globals Editor fileId SplitView PanelContainerView EditorView FlashView messageCenter*/
2 var documentsUrl = '/api/documents/';
5 Editor.Model = Editor.Object.extend({
11 Editor.ToolbarButtonsModel = Editor.Model.extend({
12 _className: 'Editor.ToolbarButtonsModel',
13 serverURL: '/api/toolbar/buttons',
21 if (!this.get('buttons').length) {
25 success: this.loadSucceeded.bind(this)
30 loadSucceeded: function(data) {
31 this.set('buttons', data);
38 // -> error -> loading
40 // empty -> loading -> synced -> unsynced -> loading
42 // -> dirty -> updating -> updated -> synced
44 Editor.XMLModel = Editor.Model.extend({
45 _className: 'Editor.XMLModel',
50 init: function(serverURL, revision) {
52 this.set('state', 'empty');
53 this.set('revision', revision);
54 this.serverURL = serverURL;
55 this.toolbarButtonsModel = new Editor.ToolbarButtonsModel();
56 this.addObserver(this, 'data', this.dataChanged.bind(this));
60 if (this.get('state') == 'empty') {
61 this.set('state', 'loading');
65 data: {revision: this.get('revision')},
66 success: this.loadingSucceeded.bind(this),
67 error: this.loadingFailed.bind(this)
74 loadingSucceeded: function(data) {
75 if (this.get('state') != 'loading') {
76 alert('erroneous state:', this.get('state'));
78 this.set('data', data);
79 this.set('state', 'synced');
82 loadingFailed: function() {
83 if (this.get('state') != 'loading') {
84 alert('erroneous state:', this.get('state'));
86 this.set('error', 'Nie udało się załadować panelu');
87 this.set('state', 'error');
90 update: function(message) {
91 if (this.get('state') == 'dirty') {
92 this.set('state', 'updating');
95 contents: this.get('data'),
96 revision: this.get('revision')
99 payload.message = message;
107 success: this.updatingSucceeded.bind(this),
108 error: this.updatingFailed.bind(this)
115 updatingSucceeded: function(data) {
116 if (this.get('state') != 'updating') {
117 alert('erroneous state:', this.get('state'));
119 this.set('revision', data.revision);
120 this.set('state', 'updated');
123 updatingFailed: function() {
124 if (this.get('state') != 'updating') {
125 alert('erroneous state:', this.get('state'));
127 messageCenter.addMessage('error', 'Uaktualnienie nie powiodło się', 'Uaktualnienie nie powiodło się');
128 this.set('state', 'dirty');
132 set: function(property, value) {
133 if (property == 'state') {
134 console.log(this.description(), ':', property, '=', value);
136 return this._super(property, value);
139 dataChanged: function(property, value) {
140 if (this.get('state') == 'synced') {
141 this.set('state', 'dirty');
145 dispose: function() {
146 this.removeObserver(this);
152 Editor.HTMLModel = Editor.Model.extend({
153 _className: 'Editor.HTMLModel',
158 init: function(serverURL, revision) {
160 this.set('state', 'empty');
161 this.set('revision', revision);
162 this.serverURL = serverURL;
166 if (this.get('state') == 'empty') {
167 this.set('state', 'loading');
171 data: {revision: this.get('revision')},
172 success: this.loadingSucceeded.bind(this),
173 error: this.loadingFailed.bind(this)
178 loadingSucceeded: function(data) {
179 if (this.get('state') != 'loading') {
180 alert('erroneous state:', this.get('state'));
182 this.set('data', data);
183 this.set('state', 'synced');
186 loadingFailed: function() {
187 if (this.get('state') != 'loading') {
188 alert('erroneous state:', this.get('state'));
190 this.set('error', 'Nie udało się załadować panelu');
191 this.set('state', 'error');
195 set: function(property, value) {
196 if (property == 'state') {
197 console.log(this.description(), ':', property, '=', value);
199 return this._super(property, value);
204 Editor.ImageGalleryModel = Editor.Model.extend({
205 _className: 'Editor.ImageGalleryModel',
210 init: function(serverURL) {
212 this.set('state', 'empty');
213 this.serverURL = serverURL;
219 if (this.get('state') == 'empty') {
220 this.set('state', 'loading');
224 success: this.loadingSucceeded.bind(this)
229 loadingSucceeded: function(data) {
230 if (this.get('state') != 'loading') {
231 alert('erroneous state:', this.get('state'));
234 console.log('galleries:', data);
236 if (data.length === 0) {
237 this.set('data', []);
240 this.set('data', data[0].pages);
243 this.set('state', 'synced');
246 set: function(property, value) {
247 if (property == 'state') {
248 console.log(this.description(), ':', property, '=', value);
250 return this._super(property, value);
255 Editor.DocumentModel = Editor.Model.extend({
256 _className: 'Editor.DocumentModel',
257 data: null, // name, text_url, user_revision, latest_shared_rev, parts_url, dc_url, size, merge_url
263 this.set('state', 'empty');
268 if (this.get('state') == 'empty') {
269 this.set('state', 'loading');
272 url: documentsUrl + fileId,
274 success: this.successfulLoad.bind(this)
279 successfulLoad: function(data) {
280 this.set('data', data);
281 this.set('state', 'synced');
282 this.contentModels = {
283 'xml': new Editor.XMLModel(data.text_url, data.user_revision),
284 'html': new Editor.HTMLModel(data.html_url, data.user_revision),
285 'gallery': new Editor.ImageGalleryModel(data.gallery_url)
287 for (var key in this.contentModels) {
288 this.contentModels[key].addObserver(this, 'state', this.contentModelStateChanged.bind(this));
292 contentModelStateChanged: function(property, value, contentModel) {
293 if (value == 'dirty') {
294 this.set('state', 'dirty');
295 for (var key in this.contentModels) {
296 if (this.contentModels[key].guid() != contentModel.guid()) {
297 this.contentModels[key].set('state', 'unsynced');
300 } else if (value == 'updated') {
301 this.set('state', 'synced');
302 for (key in this.contentModels) {
303 if (this.contentModels[key].guid() == contentModel.guid()) {
304 this.contentModels[key].set('state', 'synced');
305 this.data.user_revision = this.contentModels[key].get('revision');
306 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.data.user_revision,
307 'Uaktualnienie dokumentu do wersji ' + this.data.user_revision);
310 for (key in this.contentModels) {
311 if (this.contentModels[key].guid() != contentModel.guid()) {
312 this.contentModels[key].set('revision', this.data.user_revision);
313 this.contentModels[key].set('state', 'empty');
319 saveDirtyContentModel: function(message) {
320 for (var key in this.contentModels) {
321 if (this.contentModels[key].get('state') == 'dirty') {
322 this.contentModels[key].update(message);
329 this.set('state', 'loading');
331 url: this.data.merge_url,
336 target_revision: this.data.user_revision
338 complete: this.updateCompleted.bind(this),
339 success: function(data) { this.set('updateData', data); }.bind(this)
343 updateCompleted: function(xhr, textStatus) {
344 console.log(xhr.status, textStatus);
345 if (xhr.status == 200) { // Sukces
346 this.data.user_revision = this.get('updateData').revision;
347 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision,
348 'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision);
349 for (var key in this.contentModels) {
350 this.contentModels[key].set('revision', this.data.user_revision);
351 this.contentModels[key].set('state', 'empty');
353 } else if (xhr.status == 202) { // Wygenerowano PullRequest (tutaj?)
354 } else if (xhr.status == 204) { // Nic nie zmieniono
355 } else if (xhr.status == 409) { // Konflikt podczas operacji
357 this.set('state', 'synced');
358 this.set('updateData', null);
361 merge: function(message) {
362 this.set('state', 'loading');
364 url: this.data.merge_url,
369 target_revision: this.data.user_revision,
372 complete: this.mergeCompleted.bind(this),
373 success: function(data) { this.set('mergeData', data); }.bind(this)
377 mergeCompleted: function(xhr, textStatus) {
378 console.log(xhr.status, textStatus);
379 if (xhr.status == 200) { // Sukces
380 this.data.user_revision = this.get('mergeData').revision;
381 for (var key in this.contentModels) {
382 this.contentModels[key].set('revision', this.data.user_revision);
383 this.contentModels[key].set('state', 'empty');
385 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.get('mergeData').revision,
386 'Uaktualnienie dokumentu do wersji ' + this.get('mergeData').revision);
387 } else if (xhr.status == 202) { // Wygenerowano PullRequest
388 } else if (xhr.status == 204) { // Nic nie zmieniono
389 } else if (xhr.status == 409) { // Konflikt podczas operacji
391 this.set('state', 'synced');
392 this.set('mergeData', null);
396 set: function(property, value) {
397 if (property == 'state') {
398 console.log(this.description(), ':', property, '=', value);
400 return this._super(property, value);
405 var leftPanelView, rightPanelContainer, doc;
408 doc = new Editor.DocumentModel();
409 var editor = new EditorView('#body-wrap', doc);
411 var flashView = new FlashView('#flashview', messageCenter);
412 var splitView = new SplitView('#splitview', doc);
413 leftPanelView = new PanelContainerView('#left-panel-container', doc);
414 rightPanelContainer = new PanelContainerView('#right-panel-container', doc);