1950cc8db0
* restructured JavaScript using backbone.js * replaced highlight.js with CodeMirror for its editor * added CodeMirror Solarized (dark) theme based on Ethan Schoonover's solarized.vim * changed `POST /document` to accept real JSON * cleaned up template and stylesheet
172 lines
3.7 KiB
JavaScript
172 lines
3.7 KiB
JavaScript
window.Haste = {
|
|
Models: {},
|
|
Views: {},
|
|
Routers: {},
|
|
|
|
extensionMap: {
|
|
clj: 'clojure', coffee: 'coffeescript', css: 'css', diff: 'diff', go: 'go',
|
|
hs: 'haskell', html: 'htmlmixed', js: 'javascript', lua: 'lua',
|
|
md: 'markdown', markdown: 'markdown', sql: 'mysql', pl: 'perl', php: 'php',
|
|
py: 'python', r: 'r', rb: 'ruby', scm: 'scheme', xml: 'xml', yml: 'yaml'
|
|
},
|
|
|
|
init: function() {
|
|
new Haste.Routers.Document();
|
|
Backbone.history.start({ pushState: true });
|
|
}
|
|
};
|
|
|
|
Haste.Models.Document = Backbone.Model.extend({
|
|
idAttribute: 'key',
|
|
urlRoot: '/documents'
|
|
});
|
|
|
|
Haste.Routers.Document = Backbone.Router.extend({
|
|
routes: {
|
|
':id.:extension': 'show',
|
|
':id': 'show',
|
|
'': 'new'
|
|
},
|
|
|
|
initialize: function() {
|
|
this.editor = new Haste.Views.EditorView();
|
|
},
|
|
|
|
show: function(id, extension) {
|
|
this.editor.load(id, extension);
|
|
},
|
|
|
|
new: function() {
|
|
this.editor.new();
|
|
}
|
|
});
|
|
|
|
Haste.Views.ActionsView = Backbone.View.extend({
|
|
el: 'header',
|
|
|
|
events: {
|
|
'click .new': 'new',
|
|
'click .save': 'save',
|
|
'click .edit': 'edit',
|
|
'click .raw': 'raw',
|
|
'click .twitter': 'raw'
|
|
},
|
|
|
|
initialize: function() {
|
|
this.parent = this.options.parent;
|
|
},
|
|
|
|
toggleActions: function() {
|
|
var klass = 'disabled';
|
|
|
|
if (this.parent.model.isNew()) {
|
|
$('.save', this.el).removeClass(klass);
|
|
$('.edit, .raw, .twitter', this.el).addClass(klass);
|
|
} else {
|
|
$('.save', this.el).addClass(klass);
|
|
$('.edit, .raw, .twitter', this.el).removeClass(klass);
|
|
}
|
|
|
|
this.setLink('.raw', 'raw/' + this.parent.model.id);
|
|
this.setLink('.twitter', 'https://twitter.com/share?url=' + encodeURI(window.location.href));
|
|
},
|
|
|
|
setLink: function(el, href) {
|
|
if (this.parent.model.isNew()) {
|
|
href = '#';
|
|
}
|
|
|
|
$(el, this.el).attr('href', href);
|
|
},
|
|
|
|
new: function(event) {
|
|
event.preventDefault();
|
|
this.parent.new();
|
|
Backbone.history.navigate('');
|
|
},
|
|
|
|
save: function(event) {
|
|
event.preventDefault();
|
|
|
|
if (!this.parent.model.isNew()) { return; }
|
|
|
|
this.parent.save();
|
|
},
|
|
|
|
edit: function(event) {
|
|
event.preventDefault();
|
|
|
|
if (this.parent.model.isNew()) { return; }
|
|
|
|
this.parent.model.set('key', null);
|
|
Backbone.history.navigate('/');
|
|
},
|
|
|
|
raw: function(event) {
|
|
if (this.model.isNew()) {
|
|
event.preventDefault();
|
|
}
|
|
},
|
|
});
|
|
|
|
Haste.Views.EditorView = Backbone.View.extend({
|
|
el: 'textarea',
|
|
|
|
initialize: function() {
|
|
this.codeMirror = CodeMirror.fromTextArea(this.el, {
|
|
mode: 'null',
|
|
lineNumbers: true,
|
|
theme: 'solarized-dark'
|
|
});
|
|
|
|
this.actionsView = new Haste.Views.ActionsView({ parent: this });
|
|
},
|
|
|
|
render: function() {
|
|
this.codeMirror.setOption('mode', this.model.get('mode') || 'null');
|
|
this.codeMirror.setValue(this.model.get('data') || '');
|
|
|
|
return this;
|
|
},
|
|
|
|
new: function() {
|
|
this.model = new Haste.Models.Document();
|
|
|
|
this.model.on('change', this.render, this);
|
|
this.model.on('change', this.toggleLock, this);
|
|
this.model.on('change', this.actionsView.toggleActions, this.actionsView);
|
|
|
|
this.model.trigger('change');
|
|
},
|
|
|
|
load: function(key, extension) {
|
|
this.new();
|
|
|
|
var mode = Haste.extensionMap[extension];
|
|
this.model.set({ key: key, mode: mode }, { silent: true });
|
|
|
|
this.model.fetch();
|
|
},
|
|
|
|
save: function() {
|
|
var data = this.codeMirror.getValue();
|
|
|
|
if (!data) { return; }
|
|
|
|
this.model.save('data', data, {
|
|
success: function(model, response) {
|
|
Backbone.history.navigate(model.id);
|
|
}
|
|
});
|
|
},
|
|
|
|
toggleLock: function() {
|
|
this.codeMirror.setOption('readOnly', !this.model.isNew());
|
|
this.actionsView.toggleActions();
|
|
}
|
|
});
|
|
|
|
$(function() {
|
|
Haste.init();
|
|
});
|