Poprawienienie implementacji obserwatorów.
authorzuber <marek@stepniowski.com>
Sat, 26 Sep 2009 11:27:56 +0000 (13:27 +0200)
committerzuber <marek@stepniowski.com>
Sat, 26 Sep 2009 11:27:56 +0000 (13:27 +0200)
project/static/js/app.js
project/static/js/views/html.js
project/static/js/views/panel_container.js
project/static/js/views/view.js
project/static/js/views/xml.js
project/templates/explorer/editor.html

index 7586f3f..6e6f0f8 100644 (file)
@@ -111,18 +111,18 @@ var Model = Class.extend({
   signal: function(event, data) {
     console.log('signal', this, event, data);
     if (this.observers[event]) {
-      for (observer in this.observers[event]) {
-        observer.handle(event, data);
+      for (key in this.observers[event]) {
+        this.observers[event][key](event, data);
       }
     };
     return this;
   },
   
-  addObserver: function(observer, event) {
+  addObserver: function(observer, event, callback) {
     if (!this.observers[event]) {
-      this.observers[event] = [];
+      this.observers[event] = {};
     }
-    this.observers[event][observer] = observer;
+    this.observers[event][observer.id] = callback;
     return this;
   },
   
@@ -132,7 +132,7 @@ var Model = Class.extend({
         this.removeObserver(observer, e);
       }
     } else {
-      delete this.observers[event][observer];
+      delete this.observers[event][observer.id];
     }
     return this;
   }
@@ -141,14 +141,27 @@ var Model = Class.extend({
 
 var XMLModel = Model.extend({
   parent: null,
-  data: 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,
@@ -161,65 +174,104 @@ var XMLModel = Model.extend({
     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();
+    }
+    return this.data;
+  },
+  
+  setData: function(data) {
+    console.log('setData');
+    if (this.data != 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('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() {},
+  init: function() {
+    this.getData();
+  },
   
-  getData: function(callback) {
-    console.log('get:', documentsUrl + fileId);
+  getData: function() {
+    console.log('DocumentModel#getData');
     $.ajax({
       cache: false,
       url: documentsUrl + fileId,
       dataType: 'json',
-      success: this.successfulGetData.bind(this, callback)
+      success: this.successfulGetData.bind(this)
     });
   },
   
-  successfulGetData: function(callback, data) {
+  successfulGetData: function(data) {
+    console.log('DocumentModel#successfulGetData:', data);
     this.data = data;
-    this.signal('changed');
-    if (callback) {
-      (callback.bind(this))(data);
-    }
-  },
-  
-  load: function(key) {
-    if (!this.data) {
-      this.getData(function() { this.load(key); }.bind(this));
-    } else {
-      console.log('load', key, this.data[key + 'url']);
-      $.ajax({
-        url: this.data[key + '_url'],
-        dataType: 'text',
-        success: this.loadSucceeded.bind(this, key)
-      });
-    }
-  },
-  
-  loadSucceeded: function(key, data) {
-    console.log('loadSucceeded', key, data);
-    this.set(key, data);
+    this.contentModels = {
+      'xml': new XMLModel(this, data.text_url)
+    };
   },
   
-  get: function(key) {
-    console.log(this[key]);
-    if (this[key]) {
-      return this[key]
-    } else {
-      this.load(key);
-      return '';
+  modelChanged: function(contentModelName) {
+    for (modelName in this.contentModels) {
+      if (!(modelName == contentModelName)) {
+        this.contentModels[modelName].needsReload();
+      }
     }
-  },
-  
-  set: function(key, value) {
-    this[key] = value;
-    this.signal(key + '-changed');
-    return this;
   }
 });
 
index cd32ced..87f2ab7 100644 (file)
@@ -5,10 +5,7 @@ var HTMLView = View.extend({
   template: 'html-view-template',
   
   init: function(element, model, template) {
-    this.element = $(element);
-    this.model = model;
-    this.template = template || this.template;
-    this.element.html(render_template(this.template, {}));
+    this._super(element, model, template);
   },
   
   dispose: function() {
@@ -17,4 +14,4 @@ var HTMLView = View.extend({
 });
 
 // Register view
-panels.push({name: 'html', klass: HTMLView});
\ No newline at end of file
+panels['html'] = HTMLView;
\ No newline at end of file
index c873574..e4950ba 100644 (file)
@@ -16,15 +16,14 @@ var PanelContainerView = View.extend({
   },
   
   selectChanged: function(event) {
-    var view = panels[$('select', this.element.get(0)).val()];
-    var klass = view.klass;
-    console.log(view, klass);
+    var value = $('select', this.element.get(0)).val();
+    var klass = panels[value];
     if (this.contentView) {
       this.contentView.dispose();
       this.contentView = null;
     }
-    this.contentView = new klass($('.content-view', this.element.get(0)), this.model);
-    console.log(this.contentView);
+    this.contentView = new klass($('.content-view', 
+      this.element.get(0)), this.model.contentModels[value]);
   },
   
   dispose: function() {
index 975eeb9..498341e 100644 (file)
@@ -5,7 +5,8 @@ var View = Class.extend({
   template: null,
   overlayClass: 'view-overlay',
   overlay: null,
-
+  id: null,
+  
   init: function(element, model, template) {
     this.element = $(element);
     this.model = model;
@@ -14,8 +15,16 @@ var View = Class.extend({
     if (this.template) {
       this.element.html(render_template(this.template, {}));
     }
+    
+    View.lastId = View.lastId + 1;
+    this.id = 'view-' + View.lastId;
   },
-
+  
+  // Identyczność
+  hash: function() {
+    
+  },
+  
   frozen: function() {
     return !!this.overlay;
   },
@@ -51,3 +60,6 @@ var View = Class.extend({
     this.element.contents().remove();
   }
 });
+
+
+View.lastId = 0;
index 333b1c2..54abf16 100644 (file)
@@ -6,14 +6,7 @@ var XMLView = View.extend({
   editor: null,
   
   init: function(element, model, template) {
-    this.element = $(element);
-    this.model = $(model).get(0);
-    this.template = template || this.template;
-    this.element.html(render_template(this.template, {}));
-    
-    this.model
-      .addObserver(this, 'xml-freeze')
-      .addObserver(this, 'xml-unfreeze');
+    this._super(element, model, template);
     
     this.freeze('Ładowanie edytora...');
        this.editor = new CodeMirror($('.xmlview', this.element).get(0), {
@@ -30,31 +23,31 @@ var XMLView = View.extend({
   },
   
   changed: function() {
-    this.model.set('text', this.editor.getCode());
+    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.get('text'));
-    this.model.addObserver(this, 'text-changed');
+    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));
+
     // editor.grabKeys(
     //   $.fbind(self, self.hotkeyPressed),
     //   $.fbind(self, self.isHotkey)
     // );
   },
   
-  handle: function(event, data) {
-    console.log('handle', this, event, data);
-    if (event == 'text-changed') {
-      this.freeze('Niezsynchronizowany');
-      // this.unfreeze();      
-    } else if (event == 'xml-freeze') {
-      this.freeze('Ładowanie XMLa...');
-    } else if (event == 'xml-unfreeze') {
-      this.editor.setCode(this.model.get('text'));
-      this.unfreeze();
+  textDidChange: function(event) {
+    console.log('textDidChange!');
+    if (this.editor.getCode() != this.model.getData()) {
+      this.editor.setCode(this.model.getData());
     }
   },
   
@@ -66,4 +59,4 @@ var XMLView = View.extend({
 });
 
 // Register view
-panels.push({name: 'xml', klass: XMLView});
+panels['xml'] = XMLView;
index c743308..d3c5196 100644 (file)
@@ -27,8 +27,8 @@
        {# JavaScript templates #}
        <script type="text/html" charset="utf-8" id="panel-container-view-template">
                <select>
-                       <% for (var i = 0; i < panels.length; i++) { %>
-                       <option value="<%= i %>"><%= panels[i].name %></option>
+                       <% for (panel in panels) { %>
+                       <option value="<%= panel %>"><%= panel %></option>
                        <% }; %>
                </select>
                <div class="content-view"></div>