Client-side XSLT renderer prototype.
[redakcja.git] / platforma / static / js / models.js
old mode 100644 (file)
new mode 100755 (executable)
index 6399c03..4052594
@@ -88,10 +88,12 @@ Editor.XMLModel = Editor.Model.extend({
         messageCenter.addMessage('success', 'xmlload', 'Wczytałem XML :-)');
     },
   
         messageCenter.addMessage('success', 'xmlload', 'Wczytałem XML :-)');
     },
   
-    loadingFailed: function() {
+    loadingFailed: function(response)
+    {
         if (this.get('state') != 'loading') {
             alert('erroneous state:', this.get('state'));
         }
         if (this.get('state') != 'loading') {
             alert('erroneous state:', this.get('state'));
         }
+        
         var message = parseXHRError(response);
         
         this.set('error', '<h2>Błąd przy ładowaniu XML</h2><p>'+message+'</p>');
         var message = parseXHRError(response);
         
         this.set('error', '<h2>Błąd przy ładowaniu XML</h2><p>'+message+'</p>');
@@ -218,15 +220,15 @@ Editor.HTMLModel = Editor.Model.extend({
             alert('erroneous state:', this.get('state'));
         }
         
             alert('erroneous state:', this.get('state'));
         }
         
-        var message = parseXHRError(response);
+        var err = parseXHRError(response);
         
         
-        this.set('error', '<p>Nie udało się wczytać widoku HTML: </p>' + message);
+        this.set('error', '<p>Nie udało się wczytać widoku HTML: </p>' + err.error_message);
         this.set('state', 'error');        
     },
 
     getXMLPart: function(elem, callback)
     {
         this.set('state', 'error');        
     },
 
     getXMLPart: function(elem, callback)
     {
-        var path = elem.attr('wl2o:path');
+        var path = elem.attr('x-pointer');
         if(!this.xmlParts[path])
             this.loadXMLPart(elem, callback);
         else
         if(!this.xmlParts[path])
             this.loadXMLPart(elem, callback);
         else
@@ -235,7 +237,7 @@ Editor.HTMLModel = Editor.Model.extend({
 
     loadXMLPart: function(elem, callback)
     {
 
     loadXMLPart: function(elem, callback)
     {
-        var path = elem.attr('wl2o:path');
+        var path = elem.attr('x-pointer');
         var self = this;
 
         $.ajax({
         var self = this;
 
         $.ajax({
@@ -244,10 +246,12 @@ Editor.HTMLModel = Editor.Model.extend({
             data: {
                 revision: this.get('revision'),
                 user: this.document.get('user'),
             data: {
                 revision: this.get('revision'),
                 user: this.document.get('user'),
-                part: path
+                chunk: path
+                // format: 'nl'
             },
             success: function(data) {
                 self.xmlParts[path] = data;
             },
             success: function(data) {
                 self.xmlParts[path] = data;
+                console.log(data);
                 callback(path, data);
             },
             // TODO: error handling
                 callback(path, data);
             },
             // TODO: error handling
@@ -258,13 +262,13 @@ Editor.HTMLModel = Editor.Model.extend({
         });
     },
 
         });
     },
 
-    putXMLPart: function(elem, data) {
+    putXMLPart: function(elem, data, callback) {
         var self = this;
       
         var self = this;
       
-        var path = elem.attr('wl2o:path');
+        var path = elem.attr('x-pointer');
         this.xmlParts[path] = data;
 
         this.xmlParts[path] = data;
 
-        this.set('state', 'unsynced');
+        this.set('state', 'dirty');
 
         /* re-render the changed fragment */
         $.ajax({
 
         /* re-render the changed fragment */
         $.ajax({
@@ -273,10 +277,11 @@ Editor.HTMLModel = Editor.Model.extend({
             dataType: 'text; charset=utf-8',
             data: {
                 fragment: data,
             dataType: 'text; charset=utf-8',
             data: {
                 fragment: data,
-                part: path
+                chunk: path
+                // format: 'nl'
             },
             success: function(htmldata) {
             },
             success: function(htmldata) {
-                elem.replaceWith(htmldata);
+                callback(elem, htmldata);
                 self.set('state', 'dirty');
             }
         });
                 self.set('state', 'dirty');
             }
         });
@@ -347,7 +352,7 @@ Editor.ImageGalleryModel = Editor.Model.extend({
     data: [],
     state: 'empty',
 
     data: [],
     state: 'empty',
 
-    init: function(serverURL) {
+    init: function(document, serverURL) {
         this._super();
         this.set('state', 'empty');
         this.serverURL = serverURL;
         this._super();
         this.set('state', 'empty');
         this.serverURL = serverURL;
@@ -357,16 +362,22 @@ Editor.ImageGalleryModel = Editor.Model.extend({
 
     load: function(force) {
         if (force || this.get('state') == 'empty') {
 
     load: function(force) {
         if (force || this.get('state') == 'empty') {
+            console.log("setting state");
             this.set('state', 'loading');
             this.set('state', 'loading');
+            console.log("going ajax");
             $.ajax({
                 url: this.serverURL,
                 dataType: 'json',
             $.ajax({
                 url: this.serverURL,
                 dataType: 'json',
-                success: this.loadingSucceeded.bind(this)
+                success: this.loadingSucceeded.bind(this),
+                error: this.loadingFailed.bind(this)
             });
         }
     },
 
             });
         }
     },
 
-    loadingSucceeded: function(data) {
+    loadingSucceeded: function(data) 
+    {
+        console.log("success");        
+        
         if (this.get('state') != 'loading') {
             alert('erroneous state:', this.get('state'));
         }
         if (this.get('state') != 'loading') {
             alert('erroneous state:', this.get('state'));
         }
@@ -382,6 +393,16 @@ Editor.ImageGalleryModel = Editor.Model.extend({
         this.set('state', 'synced');
     },
 
         this.set('state', 'synced');
     },
 
+    loadingFailed: function(data) {
+        console.log("failed");
+
+        if (this.get('state') != 'loading') {
+            alert('erroneous state:', this.get('state'));
+        }       
+
+        this.set('state', 'error');
+    },
+
     set: function(property, value) {
         if (property == 'state') {
             console.log(this.description(), ':', property, '=', value);
     set: function(property, value) {
         if (property == 'state') {
             console.log(this.description(), ':', property, '=', value);
@@ -393,7 +414,7 @@ Editor.ImageGalleryModel = Editor.Model.extend({
 
 Editor.DocumentModel = Editor.Model.extend({
     _className: 'Editor.DocumentModel',
 
 Editor.DocumentModel = Editor.Model.extend({
     _className: 'Editor.DocumentModel',
-    data: null, // name, text_url, user_revision, latest_shared_rev, parts_url, dc_url, size, merge_url
+    data: null, // name, text_url, revision, latest_shared_rev, parts_url, dc_url, size, merge_url
     contentModels: {},
     state: 'empty',
     errors: '',
     contentModels: {},
     state: 'empty',
     errors: '',
@@ -423,7 +444,7 @@ Editor.DocumentModel = Editor.Model.extend({
         this.set('data', data);
         this.set('state', 'synced');
 
         this.set('data', data);
         this.set('state', 'synced');
 
-        this.set('revision', data.user_revision);
+        this.set('revision', data.revision);
         this.set('user', data.user);
 
         this.contentModels = {
         this.set('user', data.user);
 
         this.contentModels = {
@@ -446,8 +467,8 @@ Editor.DocumentModel = Editor.Model.extend({
             alert('erroneous state:', this.get('state'));
         }
         
             alert('erroneous state:', this.get('state'));
         }
         
-        var message = parseXHRError(response);        
-        this.set('error', '<h2>Nie udało się wczytać dokumentu</h2><p>'+message+"</p>");
+        var err = parseXHRError(response);
+        this.set('error', '<h2>Nie udało się wczytać dokumentu</h2><p>'+err.error_message+"</p>");
         this.set('state', 'error');
     },
   
         this.set('state', 'error');
     },
   
@@ -464,12 +485,13 @@ Editor.DocumentModel = Editor.Model.extend({
             for (key in this.contentModels) {
                 if (this.contentModels[key].guid() == contentModel.guid()) {
                     this.contentModels[key].set('state', 'synced');
             for (key in this.contentModels) {
                 if (this.contentModels[key].guid() == contentModel.guid()) {
                     this.contentModels[key].set('state', 'synced');
-                    this.data.user_revision = this.contentModels[key].get('revision');
+                    this.revision = this.contentModels[key].get('revision');
+
                 }
             }
             for (key in this.contentModels) {
                 if (this.contentModels[key].guid() != contentModel.guid()) {
                 }
             }
             for (key in this.contentModels) {
                 if (this.contentModels[key].guid() != contentModel.guid()) {
-                    this.contentModels[key].set('revision', this.data.user_revision);
+                    this.contentModels[key].set('revision', this.revision);
                     this.contentModels[key].set('state', 'empty');
                 }
             }
                     this.contentModels[key].set('state', 'empty');
                 }
             }
@@ -487,60 +509,81 @@ Editor.DocumentModel = Editor.Model.extend({
   
     update: function() {
         this.set('state', 'loading');
   
     update: function() {
         this.set('state', 'loading');
-        messageCenter.addMessage('info', 'Uaktualniam dokument...');
+
+        messageCenter.addMessage('info', 'doc_update',
+            'Uaktualniam dokument...');
+            
         $.ajax({
             url: this.data.merge_url,
             dataType: 'json',
             type: 'post',
             data: {
                 type: 'update',
         $.ajax({
             url: this.data.merge_url,
             dataType: 'json',
             type: 'post',
             data: {
                 type: 'update',
-                revision: this.revision,
-                user: this.user
+                revision: this.get('revision'),
+                user: this.get('user')
             },
             },
-            complete: this.updateCompleted.bind(this),
-            success: function(data) {
-                this.set('updateData', data);
-            }.bind(this)
+            complete: this.updateCompleted.bind(this)           
         });
     },
   
         });
     },
   
-    updateCompleted: function(xhr, textStatus) {
-        console.log(xhr.status, textStatus);
-        if (xhr.status == 200) { // Sukces
-            this.data = this.get('updateData');
-            this.revision = this.data.user_revision;
-            this.user = this.data.user;
-            
-            messageCenter.addMessage('info', null, 'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision,
-                'Uaktualnienie dokumentu do wersji ' + this.get('updateData').revision);
+    updateCompleted: function(xhr, textStatus)
+    {
+        console.log(xhr.status, xhr.responseText);
+        var response = parseXHRResponse(xhr);
+        if(response.success)
+        {
+            if( (response.data.result == 'no-op')
+             || (response.data.timestamp == response.data.parent_timestamp))
+            {
+                if( (response.data.revision) && (response.data.revision != this.get('revision')) )
+                {
+                    // we're out of sync
+                    this.set('state', 'unsynced');
+                    return;
+                }
+                
+                messageCenter.addMessage('info', 'doc_update',
+                    'Już posiadasz najbardziej aktualną wersję.');
+                    this.set('state', 'synced');
+                return;
+            }
+
+            // result: success
+            this.set('revision', response.data.revision);
+            this.set('user', response.data.user);
+
+            messageCenter.addMessage('info', 'doc_update',
+                'Uaktualnienie dokumentu do wersji ' + response.data.revision);
+
             for (var key in this.contentModels) {
             for (var key in this.contentModels) {
-                this.contentModels[key].set('revision', this.data.user_revision);
+                this.contentModels[key].set('revision', this.get('revision') );
                 this.contentModels[key].set('state', 'empty');
             }
                 this.contentModels[key].set('state', 'empty');
             }
-            messageCenter.addMessage('success', null, 'Uaktualniłem dokument do najnowszej wersji :-)');
-        } else if (xhr.status == 202) { // Wygenerowano PullRequest (tutaj?)
-        } else if (xhr.status == 204) { // Nic nie zmieniono
-            messageCenter.addMessage('info', null, 'Nic się nie zmieniło od ostatniej aktualizacji. Po co mam uaktualniać?');
-        } else if (xhr.status == 409) { // Konflikt podczas operacji
-            messageCenter.addMessage('error', null, 'Wystąpił konflikt podczas aktualizacji. Pędź po programistów! :-(');
-        } else if (xhr.status == 500) {
-            messageCenter.addMessage('critical', null, 'Błąd serwera. Pędź po programistów! :-(');
+
+            this.set('state', 'synced');
+            return;
         }
         }
-        this.set('state', 'synced');
-        this.set('updateData', null);
+
+        // no success means trouble
+        messageCenter.addMessage(response.error_level, 'doc_update', 
+            response.error_message);       
+        
+        this.set('state', 'unsynced');
     },
   
     merge: function(message) {
         this.set('state', 'loading');
     },
   
     merge: function(message) {
         this.set('state', 'loading');
-        messageCenter.addMessage('info', null, 'Scalam dokument z głównym repozytorium...');
+        messageCenter.addMessage('info', 'doc_merge',
+            'Scalam dokument z głównym repozytorium...');
+            
         $.ajax({
             url: this.data.merge_url,
             type: 'post',
             dataType: 'json',
             data: {
                 type: 'share',
         $.ajax({
             url: this.data.merge_url,
             type: 'post',
             dataType: 'json',
             data: {
                 type: 'share',
-                revision: this.revision,
-                user: this.user,
+                revision: this.get('revision'),
+                user: this.get('user'),
                 message: message
             },
             complete: this.mergeCompleted.bind(this),
                 message: message
             },
             complete: this.mergeCompleted.bind(this),
@@ -551,29 +594,53 @@ Editor.DocumentModel = Editor.Model.extend({
     },
   
     mergeCompleted: function(xhr, textStatus) {
     },
   
     mergeCompleted: function(xhr, textStatus) {
-        console.log(xhr.status, textStatus);
-        if (xhr.status == 200) { // Sukces
-            this.data = this.get('updateData');
-            this.revision = this.data.user_revision;
-            this.user = this.data.user;
-            
-            for (var key in this.contentModels) {
-                this.contentModels[key].set('revision', this.revision);
-                this.contentModels[key].set('state', 'empty');
+        console.log(xhr.status, xhr.responseText);
+        var response = parseXHRResponse(xhr);
+        
+        if(response.success) {
+        
+            if( (response.data.result == 'no-op') ||             
+             ( response.data.shared_parent_timestamp
+               && response.data.shared_timestamp
+               && (response.data.shared_timestamp == response.data.shared_parent_timestamp)) )
+            {
+                if( (response.data.revision) && (response.data.revision != this.get('revision')) )
+                {
+                    // we're out of sync
+                    this.set('state', 'unsynced');
+                    return;
+                }
+
+                messageCenter.addMessage('info', 'doc_merge',
+                    'Twoja aktualna wersja nie różni się od ostatnio zatwierdzonej.');
+                this.set('state', 'synced');
+                return;
+            }
+
+            if( response.data.result == 'accepted')
+            {
+                messageCenter.addMessage('info', 'doc_merge',
+                    'Prośba o zatwierdzenie została przyjęta i oczekuję na przyjęcie.');
+                this.set('state', 'synced');
+                return;
             }
 
             }
 
-            messageCenter.addMessage('success', null, 'Scaliłem dokument z głównym repozytorium :-)');
-        } else if (xhr.status == 202) { // Wygenerowano PullRequest
-            messageCenter.addMessage('success', null, 'Wysłałem prośbę o scalenie dokumentu z głównym repozytorium.');
-        } else if (xhr.status == 204) { // Nic nie zmieniono
-            messageCenter.addMessage('info', null, 'Nic się nie zmieniło od ostatniego scalenia. Po co mam scalać?');
-        } else if (xhr.status == 409) { // Konflikt podczas operacji
-            messageCenter.addMessage('error', null, 'Wystąpił konflikt podczas scalania. Pędź po programistów! :-(');
-        } else if (xhr.status == 500) {
-            messageCenter.addMessage('critical', null, 'Błąd serwera. Pędź po programistów! :-(');
+            // result: success
+            this.set('revision', response.data.revision);
+            this.set('user', response.data.user);
+
+            messageCenter.addMessage('info', 'doc_merge',
+                'Twoja wersja dokumentu została zatwierdzona.');
+            
+            this.set('state', 'synced');
+            return;
         }
         }
-        this.set('state', 'synced');
-        this.set('mergeData', null);
+
+        // no success means trouble
+        messageCenter.addMessage(response.error_level, 'doc_merge',
+            response.error_message);
+
+        this.set('state', 'unsynced');
     },
   
     // For debbuging
     },
   
     // For debbuging