};
})();
+
(function() {
var slice = Array.prototype.slice;
}
})();
-
-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 = [];
--- /dev/null
+/*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);
+});
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();
}
});
-/*globals Class render_template*/
-var View = Class.extend({
+/*globals Editor render_template*/
+var View = Editor.Object.extend({
element: null,
model: null,
template: null,
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;
model: null,
template: 'xml-view-template',
editor: null,
+ buttonToolbar: null,
init: function(element, model, template) {
this._super(element, model, template);
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();
<script type="text/javascript" charset="utf-8">
var fileId = '{{ fileid }}';
</script>
- <link rel="stylesheet" href="{{STATIC_URL}}css/toolbar.css" type="text/css" />
- <link rel="stylesheet" href="{{STATIC_URL}}css/jquery.modal.css" type="text/css" />
- <script src="{{STATIC_URL}}js/lib/jquery.lazyload.js" type="text/javascript" charset="utf-8"></script>
<script src="{{STATIC_URL}}js/lib/codemirror/codemirror.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{STATIC_URL}}js/lib/jquery.wtooltip.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{STATIC_URL}}js/lib/jquery.json.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{STATIC_URL}}js/lib/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{STATIC_URL}}js/lib/jquery.modal.js" type="text/javascript" charset="utf-8"></script>
{# App and views #}
<script src="{{STATIC_URL}}js/app.js" type="text/javascript" charset="utf-8"></script>
<script src="{{STATIC_URL}}js/views/html.js" type="text/javascript" charset="utf-8"></script>
<script src="{{STATIC_URL}}js/views/panel_container.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{STATIC_URL}}js/editor.js" type="text/javascript" charset="utf-8"></script>
- <script src="{{STATIC_URL}}js/editor.ui.js" type="text/javascript" charset="utf-8"></script>
-
+ <script src="{{STATIC_URL}}js/models.js" type="text/javascript" charset="utf-8"></script>
+
{# JavaScript templates #}
<script type="text/html" charset="utf-8" id="panel-container-view-template">
<select>
</script>
<script type="text/html" charset="utf-8" id="html-view-template">
- <p>Hej! Jestem widokiem HTML!</p>
+ <div class="htmlview">
+ </div>
</script>
{% endblock extrahead %}
</div>
- <div id="commit-dialog" class="jqmWindow">
- <form action="{% url file_commit fileid %}" method="POST">
- <label for="message">Commit message:</label>
- <textarea cols="60" rows="10" name="message" id="commit-dialog-message"></textarea>
- <p id="commit-dialog-error-empty-message">Wiadomość nie może być pusta.</p>
- <fieldset id="commit-dialog-related-issues"
- ui:ajax-src="http://localhost:3000/publications/issues/{{fileid}}">
- <legend>Related issues</legend>
- <div class="loading-box" style="display: none;">
- <p>Loading related issues...</p>
- </div>
- <div class="container-box">No related issues.</div>
- </fieldset>
- <p>
- <input type="button" value="Save" id="commit-dialog-save-button" />
- <input type="reset" value="Cancel" id="commit-dialog-cancel-button" />
- </p>
- </form>
- </div>
-
- <div id="split-dialog" class="jqmWindow">
- <div class="container-box"> </div>
- <div class="loading-box" style="display: none;">
- <p>Loading dialog contents...</p>
- <!-- <p><button type="button" class="dialog-close-button">Close</button></p> -->
- </div>
- <div class="fatal-error-box" style="display: none;">
- <p>Server error, while loading dialog :(</p>
- <p><button type="button" class="dialog-close-button">Close</button></p>
- </div>
- </div>
+ {# <div id="commit-dialog" class="jqmWindow"> #}
+ {# <form action="{% url file_commit fileid %}" method="POST"> #}
+ {# <label for="message">Commit message:</label> #}
+ {# <textarea cols="60" rows="10" name="message" id="commit-dialog-message"></textarea> #}
+ {# <p id="commit-dialog-error-empty-message">Wiadomość nie może być pusta.</p> #}
+ {# <fieldset id="commit-dialog-related-issues" #}
+ {# ui:ajax-src="http://localhost:3000/publications/issues/{{fileid}}"> #}
+ {# <legend>Related issues</legend> #}
+ {# <div class="loading-box" style="display: none;"> #}
+ {# <p>Loading related issues...</p> #}
+ {# </div> #}
+ {# <div class="container-box">No related issues.</div> #}
+ {# </fieldset> #}
+ {# <p> #}
+ {# <input type="button" value="Save" id="commit-dialog-save-button" /> #}
+ {# <input type="reset" value="Cancel" id="commit-dialog-cancel-button" /> #}
+ {# </p> #}
+ {# </form> #}
+ {# </div> #}
+ {# #}
+ {# <div id="split-dialog" class="jqmWindow"> #}
+ {# <div class="container-box"> </div> #}
+ {# <div class="loading-box" style="display: none;"> #}
+ {# <p>Loading dialog contents...</p> #}
+ {# <!-- <p><button type="button" class="dialog-close-button">Close</button></p> --> #}
+ {# </div> #}
+ {# <div class="fatal-error-box" style="display: none;"> #}
+ {# <p>Server error, while loading dialog :(</p> #}
+ {# <p><button type="button" class="dialog-close-button">Close</button></p> #}
+ {# </div> #}
+ {# </div> #}
{% endblock maincontent %}