From: zuber Date: Sat, 26 Sep 2009 21:50:55 +0000 (+0200) Subject: Dodanie KVC/KVO. Przeniesienie modeli do models.js. X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/0ac983162763199b07270a9a675e22672d4462ce Dodanie KVC/KVO. Przeniesienie modeli do models.js. --- diff --git a/project/static/js/app.js b/project/static/js/app.js index 6e6f0f80..7bf026b4 100644 --- a/project/static/js/app.js +++ b/project/static/js/app.js @@ -70,6 +70,7 @@ var panel_hooks; }; })(); + (function() { var slice = Array.prototype.slice; @@ -97,189 +98,66 @@ var panel_hooks; } })(); - -var panels = []; -var documentsUrl = '/api/documents/'; +var Editor = Editor || {}; -var Model = Class.extend({ - observers: {}, - - init: function() {}, - - signal: function(event, data) { - console.log('signal', this, event, data); - if (this.observers[event]) { - for (key in this.observers[event]) { - this.observers[event][key](event, data); - } - }; - return this; - }, +// Obiekt implementujący wzorzec KVC/KVO +Editor.Object = Class.extend({ + _observers: {}, - addObserver: function(observer, event, callback) { - if (!this.observers[event]) { - this.observers[event] = {}; + addObserver: function(observer, property, callback) { + if (!this._observers[property]) { + this._observers[property] = {} } - this.observers[event][observer.id] = callback; + this._observers[property][this.guid()] = callback; return this; }, - removeObserver: function(observer, event) { - if (!event) { - for (e in this.observers) { - this.removeObserver(observer, e); + removeObserver: function(observer, property) { + if (!property) { + for (var property in this._observers) { + this.removeObserver(observer, property) } } else { - delete this.observers[event][observer.id]; + delete this._observers[property][observer.guid()]; } return this; - } -}); - - -var XMLModel = Model.extend({ - parent: null, - data: '', - serverURL: null, - needsReload: false, - - init: function(parent, serverURL) { - this.parent = parent; - this.serverURL = serverURL; - }, - - getData: function() { - if (!this.data) { - this.reload(); - } - return this.data; - }, - - setData: function(data) { - this.data = data; - this.dataChanged(); - }, - - reload: function() { - $.ajax({ - url: this.serverURL, - dataType: 'text', - success: this.reloadSucceeded.bind(this) - }); - }, - - reloadSucceeded: function(data) { - this.data = data; - this.signal('reloaded'); - }, - - dataChanged: function() { - this.parent.modelChanged('xml'); - this.signal('dataChanged'); - }, - - needsReload: function() { - this.needsReload = true; - this.signal('needsReload'); - } -}) - - - -var HTMLModel = Model.extend({ - parent: null, - data: '', - serverURL: null, - needsReload: false, - - init: function(parent, serverURL) { - this.parent = parent; - this.serverURL = serverURL; }, - getData: function() { - if (!this.data) { - this.reload(); + notifyObservers: function(property) { + var currentValue = this[property]; + for (var guid in this._observers[property]) { + this._observers[property][guid](property, currentValue); } - return this.data; + return this; }, - setData: function(data) { - console.log('setData'); - if (this.data != data) { - this.data = data; - this.dataChanged(); + guid: function() { + if (!this._guid) { + this._guid = ('editor-' + Editor.Object._lastGuid++); } + return this._guid; }, - reload: function() { - $.ajax({ - url: this.serverURL, - dataType: 'text', - success: this.reloadSucceeded.bind(this) - }); + get: function(property) { + return this[property]; }, - reloadSucceeded: function(data) { - this.data = data; - this.signal('reloaded'); - }, - - dataChanged: function() { - this.parent.modelChanged('html'); - }, - - needsReload: function() { - this.needsReload = true; - this.signal('needsReload'); - } -}) - - -var DocumentModel = Model.extend({ - data: null, // name, text_url, latest_rev, latest_shared_rev, parts_url, dc_url, size - xml: null, - html: null, - contentModels: {}, - - init: function() { - this.getData(); - }, - - getData: function() { - console.log('DocumentModel#getData'); - $.ajax({ - cache: false, - url: documentsUrl + fileId, - dataType: 'json', - success: this.successfulGetData.bind(this) - }); - }, - - successfulGetData: function(data) { - console.log('DocumentModel#successfulGetData:', data); - this.data = data; - this.contentModels = { - 'xml': new XMLModel(this, data.text_url) - }; + set: function(property, value) { + if (this[property] != value) { + this[property] = value; + this.notifyObservers(property); + } + return this; }, - modelChanged: function(contentModelName) { - for (modelName in this.contentModels) { - if (!(modelName == contentModelName)) { - this.contentModels[modelName].needsReload(); - } - } + dispose: function() { + delete this._observers; } }); -var leftPanelView, rightPanelContainer, doc; +Editor.Object._lastGuid = 0; -$(function() { - doc = new DocumentModel(); - var splitView = new SplitView('#splitview', doc); - leftPanelView = new PanelContainerView('#left-panel-container', doc); - rightPanelContainer = new PanelContainerView('#right-panel-container', doc); -}); + +var panels = []; diff --git a/project/static/js/models.js b/project/static/js/models.js new file mode 100644 index 00000000..9ccefcaa --- /dev/null +++ b/project/static/js/models.js @@ -0,0 +1,107 @@ +/*globals Editor fileId SplitView PanelContainerView*/ +var documentsUrl = '/api/documents/'; + + +Editor.Model = Editor.Object.extend({ + synced: false, + data: null +}); + + +Editor.XMLModel = Editor.Model.extend({ + serverURL: null, + + init: function(serverURL) { + this.serverURL = serverURL; + }, + + getData: function() { + if (!this.data) { + this.reload(); + } + return this.data; + }, + + setData: function(data) { + this.data = data; + this.dataChanged(); + }, + + load: function() { + if (!this.get('synced')) { + $.ajax({ + url: this.serverURL, + dataType: 'text', + success: this.reloadSucceeded.bind(this) + }); + } + }, + + reloadSucceeded: function(data) { + this.set('data', data); + this.set('synced', true); + } +}); + + +Editor.HTMLModel = Editor.Model.extend({ + serverURL: null, + + init: function(serverURL) { + this.serverURL = serverURL; + }, + + load: function() { + if (!this.get('synced')) { + $.ajax({ + url: this.serverURL, + dataType: 'text', + success: this.reloadSucceeded.bind(this) + }); + } + }, + + reloadSucceeded: function(data) { + this.set('data', data); + this.set('synced', true); + } +}); + + +Editor.DocumentModel = Editor.Model.extend({ + data: null, // name, text_url, latest_rev, latest_shared_rev, parts_url, dc_url, size + contentModels: {}, + + init: function() { + this.load(); + }, + + load: function() { + console.log('DocumentModel#load'); + $.ajax({ + cache: false, + url: documentsUrl + fileId, + dataType: 'json', + success: this.successfulLoad.bind(this) + }); + }, + + successfulLoad: function(data) { + console.log('DocumentModel#successfulLoad:', data); + this.set('data', data); + this.contentModels = { + 'xml': new Editor.XMLModel(data.text_url), + 'html': new Editor.HTMLModel(data.html_url) + }; + } +}); + + +var leftPanelView, rightPanelContainer, doc; + +$(function() { + doc = new Editor.DocumentModel(); + var splitView = new SplitView('#splitview', doc); + leftPanelView = new PanelContainerView('#left-panel-container', doc); + rightPanelContainer = new PanelContainerView('#right-panel-container', doc); +}); diff --git a/project/static/js/views/html.js b/project/static/js/views/html.js index 87f2ab7b..59579af7 100644 --- a/project/static/js/views/html.js +++ b/project/static/js/views/html.js @@ -6,9 +6,33 @@ var HTMLView = View.extend({ init: function(element, model, template) { this._super(element, model, template); + + this.model + .addObserver(this, 'data', this.modelDataChanged.bind(this)) + .addObserver(this, 'synced', this.modelSyncChanged.bind(this)); + + if (!this.model.get('synced')) { + this.freeze('Niezsynchronizowany...'); + this.model.load(); + } else { + $('.htmlview', this.element).html(this.model.get('data')); + } + }, + + modelDataChanged: function(property, value) { + $('.htmlview', this.element).html(value); + }, + + modelSyncChanged: function(property, value) { + if (value) { + this.unfreeze(); + } else { + this.freeze('Niezsynchronizowany...'); + } }, dispose: function() { + this.model.removeObserver(this); this._super(); } }); diff --git a/project/static/js/views/view.js b/project/static/js/views/view.js index 498341e7..59b339f7 100644 --- a/project/static/js/views/view.js +++ b/project/static/js/views/view.js @@ -1,5 +1,5 @@ -/*globals Class render_template*/ -var View = Class.extend({ +/*globals Editor render_template*/ +var View = Editor.Object.extend({ element: null, model: null, template: null, @@ -13,7 +13,7 @@ var View = Class.extend({ this.template = template || this.template; if (this.template) { - this.element.html(render_template(this.template, {})); + this.element.html(render_template(this.template, this)); } View.lastId = View.lastId + 1; diff --git a/project/static/js/views/xml.js b/project/static/js/views/xml.js index 54abf164..9df8954d 100644 --- a/project/static/js/views/xml.js +++ b/project/static/js/views/xml.js @@ -4,6 +4,7 @@ var XMLView = View.extend({ model: null, template: 'xml-view-template', editor: null, + buttonToolbar: null, init: function(element, model, template) { this._super(element, model, template); @@ -17,40 +18,50 @@ var XMLView = View.extend({ textWrapping: false, tabMode: 'spaces', indentUnit: 0, - onChange: this.changed.bind(this), + onChange: this.editorDataChanged.bind(this), initCallback: this.editorDidLoad.bind(this) }); }, - changed: function() { - this.model.setData(this.editor.getCode()); - }, - editorDidLoad: function(editor) { - editor.setCode('Ładowanie edytora...'); $(editor.frame).css({width: '100%', height: '100%'}); - this.editor.setCode(this.model.getData()); - this.unfreeze(); + this.model - .addObserver(this, 'reloaded', function() { - this.editor.setCode(this.model.getData()); this.unfreeze(); }.bind(this)) - .addObserver(this, 'needsReload', function() { - this.freeze('Niezsynchronizowany'); }.bind(this)) - .addObserver(this, 'dataChanged', this.textDidChange.bind(this)); - + .addObserver(this, 'data', this.modelDataChanged.bind(this)) + .addObserver(this, 'synced', this.modelSyncChanged.bind(this)); + + if (!this.model.get('synced')) { + this.freeze('Niezsynchronizowany...'); + this.model.load(); + } else { + this.editor.setCode(this.model.get('data')); + } + this.unfreeze(); + // editor.grabKeys( // $.fbind(self, self.hotkeyPressed), // $.fbind(self, self.isHotkey) // ); }, - textDidChange: function(event) { - console.log('textDidChange!'); - if (this.editor.getCode() != this.model.getData()) { - this.editor.setCode(this.model.getData()); + editorDataChanged: function() { + this.model.set('data', this.editor.getCode()); + }, + + modelDataChanged: function(property, value) { + if (this.editor.getCode() != value) { + this.editor.setCode(value); } }, + modelSyncChanged: function(property, value) { + if (value) { + this.unfreeze(); + } else { + this.freeze('Niezsynchronizowany...'); + } + }, + dispose: function() { this.model.removeObserver(this); $(this.editor.frame).remove(); diff --git a/project/templates/explorer/editor.html b/project/templates/explorer/editor.html index f7e827fe..27f7e592 100644 --- a/project/templates/explorer/editor.html +++ b/project/templates/explorer/editor.html @@ -4,14 +4,7 @@ - - - - - - - {# App and views #} @@ -21,9 +14,8 @@ - - - + + {# JavaScript templates #} {% endblock extrahead %} @@ -67,35 +60,35 @@ -
-
- - -

Wiadomość nie może być pusta.

- -

- - -

-
-
- -
-
- - -
+ {#
#} + {#
#} + {# #} + {# #} + {#

Wiadomość nie może być pusta.

#} + {# #} + {#

#} + {# #} + {# #} + {#

#} + {#
#} + {#
#} + {# #} + {#
#} + {#
#} + {# #} + {# #} + {#
#} {% endblock maincontent %}