Skip to content
Browse files

update to latest spine

  • Loading branch information...
1 parent a8a66bf commit f8a1d0c257315d53b6125fbf89ade43901089988 @maccman committed Sep 25, 2011
Showing with 137 additions and 123 deletions.
  1. +8 −11 lib/application.js
  2. +63 −53 lib/spine.js
  3. +6 −10 src/application.coffee
  4. +60 −49 src/spine.coffee
View
19 lib/application.js
@@ -42,20 +42,20 @@
__extends(Tasks, Spine.Controller);
Tasks.prototype.events = {
"change input[type=checkbox]": "toggle",
- "click .destroy": "destroy",
+ "click .destroy": "remove",
"dblclick .view": "edit",
"keypress input[type=text]": "blurOnEnter",
"blur input[type=text]": "close"
};
Tasks.prototype.elements = {
- "input[type=text]": "input",
- ".item": "wrapper"
+ "input[type=text]": "input"
};
function Tasks() {
- this.remove = __bind(this.remove, this);
this.render = __bind(this.render, this); Tasks.__super__.constructor.apply(this, arguments);
this.item.bind("update", this.render);
- this.item.bind("destroy", this.remove);
+ this.item.bind("destroy", __bind(function() {
+ return this.trigger('destroy');
+ }, this));
}
Tasks.prototype.render = function() {
this.replace($("#taskTemplate").tmpl(this.item));
@@ -65,11 +65,11 @@
this.item.done = !this.item.done;
return this.item.save();
};
- Tasks.prototype.destroy = function() {
+ Tasks.prototype.remove = function() {
return this.item.destroy();
};
Tasks.prototype.edit = function() {
- this.wrapper.addClass("editing");
+ this.el.addClass("editing");
return this.input.focus();
};
Tasks.prototype.blurOnEnter = function(e) {
@@ -78,14 +78,11 @@
}
};
Tasks.prototype.close = function() {
- this.wrapper.removeClass("editing");
+ this.el.removeClass("editing");
return this.item.updateAttributes({
name: this.input.val()
});
};
- Tasks.prototype.remove = function() {
- return this.el.remove();
- };
return Tasks;
})();
TaskApp = (function() {
View
116 lib/spine.js
@@ -16,8 +16,8 @@
Events = {
bind: function(ev, callback) {
var calls, evs, name, _i, _len;
- evs = ev.split(" ");
- calls = this.hasOwnProperty("_callbacks") && this._callbacks || (this._callbacks = {});
+ evs = ev.split(' ');
+ calls = this.hasOwnProperty('_callbacks') && this._callbacks || (this._callbacks = {});
for (_i = 0, _len = evs.length; _i < _len; _i++) {
name = evs[_i];
calls[name] || (calls[name] = []);
@@ -29,7 +29,7 @@
var args, callback, ev, list, _i, _len, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
ev = args.shift();
- list = this.hasOwnProperty("_callbacks") && ((_ref = this._callbacks) != null ? _ref[ev] : void 0);
+ list = this.hasOwnProperty('_callbacks') && ((_ref = this._callbacks) != null ? _ref[ev] : void 0);
if (!list) {
return false;
}
@@ -69,14 +69,14 @@
};
Log = {
trace: true,
- logPrefix: "(App)",
+ logPrefix: '(App)',
log: function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (!this.trace) {
return;
}
- if (typeof console === "undefined") {
+ if (typeof console === 'undefined') {
return;
}
if (this.logPrefix) {
@@ -86,17 +86,12 @@
return this;
}
};
- moduleKeywords = ["included", "extended"];
+ moduleKeywords = ['included', 'extended'];
Module = (function() {
- function Module() {
- if (this.init) {
- this.init.apply(this, arguments);
- }
- }
Module.include = function(obj) {
var included, key, value;
if (!obj) {
- throw "include(obj) requires obj";
+ throw 'include(obj) requires obj';
}
for (key in obj) {
value = obj[key];
@@ -113,7 +108,7 @@
Module.extend = function(obj) {
var extended, key, value;
if (!obj) {
- throw "extend(obj) requires obj";
+ throw 'extend(obj) requires obj';
}
for (key in obj) {
value = obj[key];
@@ -137,6 +132,11 @@
return func.apply(this, arguments);
}, this);
};
+ function Module() {
+ if (typeof this.init === "function") {
+ this.init.apply(this, arguments);
+ }
+ }
return Module;
})();
Model = (function() {
@@ -164,7 +164,7 @@
var record;
record = this.records[id];
if (!record) {
- throw "Unknown record";
+ throw 'Unknown record';
}
return record.clone();
};
@@ -190,7 +190,7 @@
record.id || (record.id = guid());
this.records[record.id] = record;
}
- this.trigger("refresh");
+ this.trigger('refresh');
return this;
};
Model.select = function(callback) {
@@ -284,17 +284,17 @@
return this.find(id).destroy();
};
Model.change = function(callbackOrParams) {
- if (typeof callbackOrParams === "function") {
- return this.bind("change", callbackOrParams);
+ if (typeof callbackOrParams === 'function') {
+ return this.bind('change', callbackOrParams);
} else {
- return this.trigger("change", callbackOrParams);
+ return this.trigger('change', callbackOrParams);
}
};
Model.fetch = function(callbackOrParams) {
- if (typeof callbackOrParams === "function") {
- return this.bind("fetch", callbackOrParams);
+ if (typeof callbackOrParams === 'function') {
+ return this.bind('fetch', callbackOrParams);
} else {
- return this.trigger("fetch", callbackOrParams);
+ return this.trigger('fetch', callbackOrParams);
}
};
Model.toJSON = function() {
@@ -305,7 +305,7 @@
if (!objects) {
return;
}
- if (typeof objects === "string") {
+ if (typeof objects === 'string') {
objects = JSON.parse(objects);
}
if (isArray(objects)) {
@@ -381,16 +381,16 @@
var error;
error = this.validate();
if (error) {
- this.trigger("error", this, error);
+ this.trigger('error', this, error);
return false;
}
- this.trigger("beforeSave", this);
+ this.trigger('beforeSave', this);
if (this.newRecord) {
this.create();
} else {
this.update();
}
- this.trigger("save", this);
+ this.trigger('save', this);
return this;
};
Model.prototype.updateAttribute = function(name, value) {
@@ -411,11 +411,11 @@
return this.save();
};
Model.prototype.destroy = function() {
- this.trigger("beforeDestroy", this);
+ this.trigger('beforeDestroy', this);
delete this.constructor.records[this.id];
this.destroyed = true;
- this.trigger("destroy", this);
- this.trigger("change", this, "destroy");
+ this.trigger('destroy', this);
+ this.trigger('change', this, 'destroy');
this.unbind();
return this;
};
@@ -452,25 +452,25 @@
};
Model.prototype.update = function() {
var clone, records;
- this.trigger("beforeUpdate", this);
+ this.trigger('beforeUpdate', this);
records = this.constructor.records;
records[this.id].load(this.attributes());
clone = records[this.id].clone();
- this.trigger("update", clone);
- return this.trigger("change", clone, "update");
+ this.trigger('update', clone);
+ return this.trigger('change', clone, 'update');
};
Model.prototype.create = function() {
var clone, records;
- this.trigger("beforeCreate", this);
+ this.trigger('beforeCreate', this);
if (!this.id) {
this.id = guid();
}
this.newRecord = false;
records = this.constructor.records;
records[this.id] = this.dup(false);
clone = records[this.id].clone();
- this.trigger("create", clone);
- return this.trigger("change", clone, "create");
+ this.trigger('create', clone);
+ return this.trigger('change', clone, 'create');
};
Model.prototype.bind = function(events, callback) {
var binder, unbinder;
@@ -479,10 +479,10 @@
return callback.apply(this, arguments);
}
}, this));
- this.constructor.bind("unbind", unbinder = __bind(function(record) {
+ this.constructor.bind('unbind', unbinder = __bind(function(record) {
if (record && this.eql(record)) {
this.constructor.unbind(events, binder);
- return this.constructor.unbind("unbind", unbinder);
+ return this.constructor.unbind('unbind', unbinder);
}
}, this));
return binder;
@@ -492,7 +492,7 @@
return (_ref = this.constructor).trigger.apply(_ref, arguments);
};
Model.prototype.unbind = function() {
- return this.trigger("unbind", this);
+ return this.trigger('unbind', this);
};
return Model;
})();
@@ -501,8 +501,9 @@
Controller.include(Events);
Controller.include(Log);
Controller.prototype.eventSplitter = /^(\w+)\s*(.*)$/;
- Controller.prototype.tag = "div";
+ Controller.prototype.tag = 'div';
function Controller(options) {
+ this.destroy = __bind(this.destroy, this);
var key, value, _ref;
this.options = options;
_ref = this.options;
@@ -517,6 +518,9 @@
if (this.className) {
this.el.addClass(this.className);
}
+ this.destroy(function() {
+ return this.el.remove();
+ });
if (!this.events) {
this.events = this.constructor.events;
}
@@ -531,8 +535,12 @@
}
Controller.__super__.constructor.apply(this, arguments);
}
- Controller.prototype.destroy = function() {
- return this.trigger("destroy");
+ Controller.prototype.destroy = function(callback) {
+ if (typeof callback === 'function') {
+ return this.bind('destroy', callback);
+ } else {
+ return this.trigger('destroy');
+ }
};
Controller.prototype.$ = function(selector) {
return $(selector, this.el);
@@ -543,17 +551,13 @@
_results = [];
for (key in _ref) {
method = _ref[key];
- if (typeof method !== "function") {
+ if (typeof method !== 'function') {
method = this.proxy(this[method]);
}
match = key.match(this.eventSplitter);
eventName = match[1];
selector = match[2];
- _results.push(selector === '' ? (this.el.bind(eventName, method), this.bind("destroy", function() {
- return this.el.unbind(eventName, method);
- })) : (this.el.delegate(selector, eventName, method), this.bind("destroy", function() {
- return this.el.undelegate(selector, eventName, method);
- })));
+ _results.push(selector === '' ? this.el.bind(eventName, method) : this.el.delegate(selector, eventName, method));
}
return _results;
};
@@ -587,10 +591,14 @@
}
return _results;
})();
- return (_ref = this.el).append.apply(_ref, elements);
+ (_ref = this.el).append.apply(_ref, elements);
+ this.refreshElements();
+ return this.el;
};
Controller.prototype.appendTo = function(element) {
- return this.el.appendTo(element.el || element);
+ this.el.appendTo(element.el || element);
+ this.refreshElements();
+ return this.el;
};
Controller.prototype.prepend = function() {
var e, elements, _ref;
@@ -604,7 +612,9 @@
}
return _results;
})();
- return (_ref = this.el).prepend.apply(_ref, elements);
+ (_ref = this.el).prepend.apply(_ref, elements);
+ this.refreshElements();
+ return this.el;
};
Controller.prototype.replace = function(element) {
var previous, _ref;
@@ -619,7 +629,7 @@
$ = this.jQuery || this.Zepto || function(element) {
return element;
};
- if (typeof Object.create !== "function") {
+ if (typeof Object.create !== 'function') {
Object.create = function(o) {
var Func;
Func = function() {};
@@ -628,7 +638,7 @@
};
}
isArray = function(value) {
- return Object.prototype.toString.call(value) === "[object Array]";
+ return Object.prototype.toString.call(value) === '[object Array]';
};
makeArray = function(args) {
return Array.prototype.slice.call(args, 0);
@@ -645,14 +655,15 @@
if (typeof module !== "undefined" && module !== null) {
module.exports = Spine;
}
- Spine.version = "2.0.0";
+ Spine.version = '2.0.1';
Spine.isArray = isArray;
Spine.$ = $;
Spine.Events = Events;
Spine.Log = Log;
Spine.Module = Module;
Spine.Controller = Controller;
Spine.Model = Model;
+ Module.extend.call(Spine, Events);
Module.create = Module.sub = Controller.create = Controller.sub = Model.sub = function(instances, statics) {
var result;
result = (function() {
@@ -691,6 +702,5 @@
Module.init = Controller.init = Model.init = function(a1, a2, a3, a4, a5) {
return new this(a1, a2, a3, a4, a5);
};
- Spine.App = new Controller;
Spine.Class = Module;
}).call(this);
View
16 src/application.coffee
@@ -17,19 +17,18 @@ class Task extends Spine.Model
class Tasks extends Spine.Controller
events:
"change input[type=checkbox]": "toggle"
- "click .destroy": "destroy"
+ "click .destroy": "remove"
"dblclick .view": "edit"
"keypress input[type=text]": "blurOnEnter"
"blur input[type=text]": "close"
elements:
"input[type=text]": "input"
- ".item": "wrapper"
constructor: ->
super
@item.bind("update", @render)
- @item.bind("destroy", @remove)
+ @item.bind("destroy", @destroy)
render: =>
@replace($("#taskTemplate").tmpl(@item))
@@ -39,22 +38,19 @@ class Tasks extends Spine.Controller
@item.done = !@item.done
@item.save()
- destroy: ->
+ remove: ->
@item.destroy()
edit: ->
- @wrapper.addClass("editing")
+ @el.addClass("editing")
@input.focus()
blurOnEnter: (e) ->
- if e.keyCode == 13 then e.target.blur()
+ if e.keyCode is 13 then e.target.blur()
close: ->
- @wrapper.removeClass("editing")
+ @el.removeClass("editing")
@item.updateAttributes({name: @input.val()})
-
- remove: =>
- @el.remove()
class TaskApp extends Spine.Controller
events:
View
109 src/spine.coffee
@@ -1,7 +1,7 @@
Events =
bind: (ev, callback) ->
- evs = ev.split(" ")
- calls = @hasOwnProperty("_callbacks") and @_callbacks or= {}
+ evs = ev.split(' ')
+ calls = @hasOwnProperty('_callbacks') and @_callbacks or= {}
for name in evs
calls[name] or= []
@@ -11,7 +11,7 @@ Events =
trigger: (args...) ->
ev = args.shift()
- list = @hasOwnProperty("_callbacks") and @_callbacks?[ev]
+ list = @hasOwnProperty('_callbacks') and @_callbacks?[ev]
return false unless list
for callback in list
@@ -41,23 +41,20 @@ Events =
Log =
trace: true
- logPrefix: "(App)"
+ logPrefix: '(App)'
log: (args...) ->
return unless @trace
- return if typeof console is "undefined"
+ return if typeof console is 'undefined'
if @logPrefix then args.unshift(@logPrefix)
console.log(args...)
@
-moduleKeywords = ["included", "extended"]
+moduleKeywords = ['included', 'extended']
class Module
- constructor: ->
- @init(arguments...) if @init
-
@include: (obj) ->
- throw("include(obj) requires obj") unless obj
+ throw('include(obj) requires obj') unless obj
for key, value of obj when key not in moduleKeywords
@::[key] = value
@@ -66,7 +63,7 @@ class Module
@
@extend: (obj) ->
- throw("extend(obj) requires obj") unless obj
+ throw('extend(obj) requires obj') unless obj
for key, value of obj when key not in moduleKeywords
@[key] = value
@@ -80,6 +77,9 @@ class Module
proxy: (func) ->
=> func.apply(@, arguments)
+ constructor: ->
+ @init?(arguments...)
+
class Model extends Module
@extend Events
@@ -99,7 +99,7 @@ class Model extends Module
@find: (id) ->
record = @records[id]
- throw("Unknown record") unless record
+ throw('Unknown record') unless record
record.clone()
@exists: (id) ->
@@ -116,7 +116,7 @@ class Model extends Module
record.id or= guid()
@records[record.id] = record
- @trigger("refresh")
+ @trigger('refresh')
@
@select: (callback) ->
@@ -171,23 +171,23 @@ class Model extends Module
@find(id).destroy()
@change: (callbackOrParams) ->
- if typeof callbackOrParams is "function"
- @bind("change", callbackOrParams)
+ if typeof callbackOrParams is 'function'
+ @bind('change', callbackOrParams)
else
- @trigger("change", callbackOrParams)
+ @trigger('change', callbackOrParams)
@fetch: (callbackOrParams) ->
- if typeof callbackOrParams is "function"
- @bind("fetch", callbackOrParams)
+ if typeof callbackOrParams is 'function'
+ @bind('fetch', callbackOrParams)
else
- @trigger("fetch", callbackOrParams)
+ @trigger('fetch', callbackOrParams)
@toJSON: ->
@recordsValues()
@fromJSON: (objects) ->
return unless objects
- if typeof objects is "string"
+ if typeof objects is 'string'
objects = JSON.parse(objects)
if isArray(objects)
(new @(value) for value in objects)
@@ -239,12 +239,12 @@ class Model extends Module
save: ->
error = @validate()
if error
- @trigger("error", @, error)
+ @trigger('error', @, error)
return false
- @trigger("beforeSave", @)
+ @trigger('beforeSave', @)
if @newRecord then @create() else @update()
- @trigger("save", @)
+ @trigger('save', @)
@
updateAttribute: (name, value) ->
@@ -264,11 +264,11 @@ class Model extends Module
@save()
destroy: ->
- @trigger("beforeDestroy", @)
+ @trigger('beforeDestroy', @)
delete @constructor.records[@id]
@destroyed = true
- @trigger("destroy", @)
- @trigger("change", @, "destroy")
+ @trigger('destroy', @)
+ @trigger('change', @, 'destroy')
@unbind()
@
@@ -301,45 +301,45 @@ class Model extends Module
# Private
update: ->
- @trigger("beforeUpdate", @)
+ @trigger('beforeUpdate', @)
records = @constructor.records
records[@id].load @attributes()
clone = records[@id].clone()
- @trigger("update", clone)
- @trigger("change", clone, "update")
+ @trigger('update', clone)
+ @trigger('change', clone, 'update')
create: ->
- @trigger("beforeCreate", @)
+ @trigger('beforeCreate', @)
@id = guid() unless @id
@newRecord = false
records = @constructor.records
records[@id] = @dup(false)
clone = records[@id].clone()
- @trigger("create", clone)
- @trigger("change", clone, "create")
+ @trigger('create', clone)
+ @trigger('change', clone, 'create')
bind: (events, callback) ->
@constructor.bind events, binder = (record) =>
if record && @eql(record)
callback.apply(@, arguments)
- @constructor.bind "unbind", unbinder = (record) =>
+ @constructor.bind 'unbind', unbinder = (record) =>
if record && @eql(record)
@constructor.unbind(events, binder)
- @constructor.unbind("unbind", unbinder)
+ @constructor.unbind('unbind', unbinder)
binder
trigger: ->
@constructor.trigger(arguments...)
unbind: ->
- @trigger("unbind", @)
+ @trigger('unbind', @)
class Controller extends Module
@include Events
@include Log
eventSplitter: /^(\w+)\s*(.*)$/
- tag: "div"
+ tag: 'div'
constructor: (options) ->
@options = options
@@ -351,22 +351,28 @@ class Controller extends Module
@el = $(@el)
@el.addClass(@className) if @className
+
+ @destroy -> @el.remove()
@events = @constructor.events unless @events
@elements = @constructor.elements unless @elements
-
+
@delegateEvents() if @events
@refreshElements() if @elements
+
super
- destroy: ->
- @trigger "destroy"
+ destroy: (callback) =>
+ if typeof callback is 'function'
+ @bind 'destroy', callback
+ else
+ @trigger 'destroy'
$: (selector) -> $(selector, @el)
delegateEvents: ->
for key, method of @events
- unless typeof(method) is "function"
+ unless typeof(method) is 'function'
method = @proxy(@[method])
match = key.match(@eventSplitter)
@@ -375,12 +381,8 @@ class Controller extends Module
if selector is ''
@el.bind(eventName, method)
- @bind "destroy", ->
- @el.unbind(eventName, method)
else
@el.delegate(selector, eventName, method)
- @bind "destroy", ->
- @el.undelegate(selector, eventName, method)
refreshElements: ->
for key, value of @elements
@@ -397,13 +399,19 @@ class Controller extends Module
append: (elements...) ->
elements = (e.el or e for e in elements)
@el.append(elements...)
+ @refreshElements()
+ @el
appendTo: (element) ->
@el.appendTo(element.el or element)
+ @refreshElements()
+ @el
prepend: (elements...) ->
elements = (e.el or e for e in elements)
@el.prepend(elements...)
+ @refreshElements()
+ @el
replace: (element) ->
[previous, @el] = [@el, element.el or element]
@@ -416,14 +424,14 @@ class Controller extends Module
$ = @jQuery or @Zepto or (element) -> element
-unless typeof Object.create is "function"
+unless typeof Object.create is 'function'
Object.create = (o) ->
Func = ->
Func.prototype = o
new Func()
isArray = (value) ->
- Object::toString.call(value) is "[object Array]"
+ Object::toString.call(value) is '[object Array]'
makeArray = (args) ->
Array.prototype.slice.call(args, 0)
@@ -440,16 +448,20 @@ guid = ->
Spine = @Spine = {}
module?.exports = Spine
-Spine.version = "2.0.0"
+Spine.version = '2.0.1'
Spine.isArray = isArray
Spine.$ = $
Spine.Events = Events
Spine.Log = Log
Spine.Module = Module
Spine.Controller = Controller
Spine.Model = Model
+
+# Global events
+
+Module.extend.call(Spine, Events)
-# Backwards compatability
+# JavaScript compatability
Module.create = Module.sub =
Controller.create = Controller.sub =
@@ -468,5 +480,4 @@ Model.setup = (name, attributes = []) ->
Module.init = Controller.init = Model.init = (a1, a2, a3, a4, a5) ->
new this(a1, a2, a3, a4, a5)
-Spine.App = new Controller
Spine.Class = Module

0 comments on commit f8a1d0c

Please sign in to comment.
Something went wrong with that request. Please try again.