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',
17 if (!this.get('buttons').length) {
21 success: this.loadSucceeded.bind(this)
26 loadSucceeded: function(data) {
27 this.set('buttons', data);
34 // -> error -> loading
36 // empty -> loading -> synced -> unsynced -> loading
38 // -> dirty -> updating -> updated -> synced
40 Editor.XMLModel = Editor.Model.extend({
41 _className: 'Editor.XMLModel',
46 init: function(serverURL, revision) {
48 this.set('state', 'empty');
49 this.set('revision', revision);
50 this.serverURL = serverURL;
51 this.toolbarButtonsModel = new Editor.ToolbarButtonsModel();
52 this.addObserver(this, 'data', this.dataChanged.bind(this));
55 load: function(force) {
56 if (force || this.get('state') == 'empty') {
57 this.set('state', 'loading');
61 data: {revision: this.get('revision')},
62 success: this.loadingSucceeded.bind(this),
63 error: this.loadingFailed.bind(this)
70 loadingSucceeded: function(data) {
71 if (this.get('state') != 'loading') {
72 alert('erroneous state:', this.get('state'));
74 this.set('data', data);
75 this.set('state', 'synced');
78 loadingFailed: function() {
79 if (this.get('state') != 'loading') {
80 alert('erroneous state:', this.get('state'));
82 this.set('error', 'Nie udało się załadować panelu');
83 this.set('state', 'error');
86 update: function(message) {
87 if (this.get('state') == 'dirty') {
88 this.set('state', 'updating');
91 contents: this.get('data'),
92 revision: this.get('revision')
95 payload.message = message;
103 success: this.updatingSucceeded.bind(this),
104 error: this.updatingFailed.bind(this)
111 updatingSucceeded: function(data) {
112 if (this.get('state') != 'updating') {
113 alert('erroneous state:', this.get('state'));
115 this.set('revision', data.revision);
116 this.set('state', 'updated');
119 updatingFailed: function() {
120 if (this.get('state') != 'updating') {
121 alert('erroneous state:', this.get('state'));
123 messageCenter.addMessage('error', 'Uaktualnienie nie powiodło się', 'Uaktualnienie nie powiodło się');
124 this.set('state', 'dirty');
128 set: function(property, value) {
129 if (property == 'state') {
130 console.log(this.description(), ':', property, '=', value);
132 return this._super(property, value);
135 dataChanged: function(property, value) {
136 if (this.get('state') == 'synced') {
137 this.set('state', 'dirty');
141 dispose: function() {
142 this.removeObserver(this);
148 Editor.HTMLModel = Editor.Model.extend({
149 _className: 'Editor.HTMLModel',
154 init: function(serverURL, revision) {
156 this.set('state', 'empty');
157 this.set('revision', revision);
158 this.serverURL = serverURL;
161 load: function(force) {
162 if (force || this.get('state') == 'empty') {
163 this.set('state', 'loading');
167 data: {revision: this.get('revision')},
168 success: this.loadingSucceeded.bind(this),
169 error: this.loadingFailed.bind(this)
174 loadingSucceeded: function(data) {
175 if (this.get('state') != 'loading') {
176 alert('erroneous state:', this.get('state'));
178 this.set('data', data);
179 this.set('state', 'synced');
182 loadingFailed: function() {
183 if (this.get('state') != 'loading') {
184 alert('erroneous state:', this.get('state'));
186 this.set('error', 'Nie udało się załadować panelu');
187 this.set('state', 'error');
191 set: function(property, value) {
192 if (property == 'state') {
193 console.log(this.description(), ':', property, '=', value);
195 return this._super(property, value);
200 Editor.ImageGalleryModel = Editor.Model.extend({
201 _className: 'Editor.ImageGalleryModel',
206 init: function(serverURL) {
208 this.set('state', 'empty');
209 this.serverURL = serverURL;
214 load: function(force) {
215 if (force || this.get('state') == 'empty') {
216 this.set('state', 'loading');
220 success: this.loadingSucceeded.bind(this)
225 loadingSucceeded: function(data) {
226 if (this.get('state') != 'loading') {
227 alert('erroneous state:', this.get('state'));
230 console.log('galleries:', data);
232 if (data.length === 0) {
233 this.set('data', []);
236 this.set('data', data[0].pages);
239 this.set('state', 'synced');
242 set: function(property, value) {
243 if (property == 'state') {
244 console.log(this.description(), ':', property, '=', value);
246 return this._super(property, value);
251 Editor.DocumentModel = Editor.Model.extend({
252 _className: 'Editor.DocumentModel',
253 data: null, // name, text_url, user_revision, latest_shared_rev, parts_url, dc_url, size, merge_url
259 this.set('state', 'empty');
264 if (this.get('state') == 'empty') {
265 this.set('state', 'loading');
268 url: documentsUrl + fileId,
270 success: this.successfulLoad.bind(this)
275 successfulLoad: function(data) {
276 this.set('data', data);
277 this.set('state', 'synced');
278 this.contentModels = {
279 'xml': new Editor.XMLModel(data.text_url, data.user_revision),
280 'html': new Editor.HTMLModel(data.html_url, data.user_revision),
281 'gallery': new Editor.ImageGalleryModel(data.gallery_url)
283 for (var key in this.contentModels) {
284 this.contentModels[key].addObserver(this, 'state', this.contentModelStateChanged.bind(this));
288 contentModelStateChanged: function(property, value, contentModel) {
289 if (value == 'dirty') {
290 this.set('state', 'dirty');
291 for (var key in this.contentModels) {
292 if (this.contentModels[key].guid() != contentModel.guid()) {
293 this.contentModels[key].set('state', 'unsynced');
296 } else if (value == 'updated') {
297 this.set('state', 'synced');
298 for (key in this.contentModels) {
299 if (this.contentModels[key].guid() == contentModel.guid()) {
300 this.contentModels[key].set('state', 'synced');
301 this.data.user_revision = this.contentModels[key].get('revision');
302 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.data.user_revision,
303 'Uaktualnienie dokumentu do wersji ' + this.data.user_revision);
306 for (key in this.contentModels) {
307 if (this.contentModels[key].guid() != contentModel.guid()) {
308 this.contentModels[key].set('revision', this.data.user_revision);
309 this.contentModels[key].set('state', 'empty');
315 saveDirtyContentModel: function(message) {
316 for (var key in this.contentModels) {
317 if (this.contentModels[key].get('state') == 'dirty') {
318 this.contentModels[key].update(message);
325 this.set('state', 'loading');
327 url: this.data.merge_url,
332 target_revision: this.data.user_revision
334 complete: this.updateCompleted.bind(this),
335 success: function(data) { this.set('updateData', data); }.bind(this)
339 updateCompleted: function(xhr, textStatus) {
340 console.log(xhr.status, textStatus);
341 if (xhr.status == 200) { // Sukces
342 this.data.user_revision = this.get('updateData').revision;
343 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision,
344 'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision);
345 for (var key in this.contentModels) {
346 this.contentModels[key].set('revision', this.data.user_revision);
347 this.contentModels[key].set('state', 'empty');
349 } else if (xhr.status == 202) { // Wygenerowano PullRequest (tutaj?)
350 } else if (xhr.status == 204) { // Nic nie zmieniono
351 } else if (xhr.status == 409) { // Konflikt podczas operacji
353 this.set('state', 'synced');
354 this.set('updateData', null);
357 merge: function(message) {
358 this.set('state', 'loading');
360 url: this.data.merge_url,
365 target_revision: this.data.user_revision,
368 complete: this.mergeCompleted.bind(this),
369 success: function(data) { this.set('mergeData', data); }.bind(this)
373 mergeCompleted: function(xhr, textStatus) {
374 console.log(xhr.status, textStatus);
375 if (xhr.status == 200) { // Sukces
376 this.data.user_revision = this.get('mergeData').revision;
377 for (var key in this.contentModels) {
378 this.contentModels[key].set('revision', this.data.user_revision);
379 this.contentModels[key].set('state', 'empty');
381 messageCenter.addMessage('info', 'Uaktualnienie dokumentu do wersji ' + this.get('mergeData').revision,
382 'Uaktualnienie dokumentu do wersji ' + this.get('mergeData').revision);
383 } else if (xhr.status == 202) { // Wygenerowano PullRequest
384 } else if (xhr.status == 204) { // Nic nie zmieniono
385 } else if (xhr.status == 409) { // Konflikt podczas operacji
387 this.set('state', 'synced');
388 this.set('mergeData', null);
392 set: function(property, value) {
393 if (property == 'state') {
394 console.log(this.description(), ':', property, '=', value);
396 return this._super(property, value);
401 var leftPanelView, rightPanelContainer, doc;
405 documentsUrl = $('#api-base-url').text() + '/';
406 toolbarUrl = $('#api-toolbar-url').text();
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);