mirror of
https://github.com/Hopiu/postal.js.git
synced 2026-03-16 22:20:23 +00:00
710 lines
23 KiB
JavaScript
710 lines
23 KiB
JavaScript
// Backbone.js 0.9.2
|
|
|
|
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
|
// Backbone may be freely distributed under the MIT license.
|
|
// For all details and documentation:
|
|
// http://backbonejs.org
|
|
(function ( h, g ) {
|
|
typeof exports !== "undefined" ? g( h, exports, require( "underscore" ) ) : typeof define === "function" && define.amd ? define( ["underscore", "jquery", "exports"], function ( f, i, p ) {
|
|
h.Backbone = g( h, p, f, i )
|
|
} ) : h.Backbone = g( h, {}, h._, h.jQuery || h.Zepto || h.ender )
|
|
})( this, function ( h, g, f, i ) {
|
|
var p = h.Backbone, y = Array.prototype.slice, z = Array.prototype.splice;
|
|
g.VERSION = "0.9.2";
|
|
g.setDomLibrary = function ( a ) {
|
|
i = a
|
|
};
|
|
g.noConflict = function () {
|
|
h.Backbone = p;
|
|
return g
|
|
};
|
|
g.emulateHTTP = false;
|
|
g.emulateJSON = false;
|
|
var q = /\s+/, l = g.Events =
|
|
{on : function ( a, b, c ) {
|
|
var d, e, f, g, j;
|
|
if ( !b ) {
|
|
return this;
|
|
}
|
|
a = a.split( q );
|
|
for ( d = this._callbacks || (this._callbacks = {}); e = a.shift(); ) {
|
|
f = (j = d[e]) ? j.tail : {}, f.next = g = {}, f.context = c, f.callback = b, d[e] = {tail : g, next : j ? j.next : f};
|
|
}
|
|
return this
|
|
}, off : function ( a, b, c ) {
|
|
var d, e, k, g, j, h;
|
|
if ( e = this._callbacks ) {
|
|
if ( !a && !b && !c ) {
|
|
return delete this._callbacks, this;
|
|
}
|
|
for ( a = a ? a.split( q ) : f.keys( e ); d = a.shift(); ) {
|
|
if ( k = e[d], delete e[d], k && (b || c) ) {
|
|
for ( g = k.tail; (k = k.next) !== g; ) {
|
|
if ( j = k.callback, h = k.context, b && j !== b || c && h !== c ) {
|
|
this.on( d, j, h );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return this
|
|
}
|
|
},
|
|
trigger : function ( a ) {
|
|
var b, c, d, e, f, g;
|
|
if ( !(d = this._callbacks) ) {
|
|
return this;
|
|
}
|
|
f = d.all;
|
|
a = a.split( q );
|
|
for ( g = y.call( arguments, 1 ); b = a.shift(); ) {
|
|
if ( c = d[b] ) {
|
|
for ( e = c.tail; (c = c.next) !== e; ) {
|
|
c.callback.apply( c.context || this, g );
|
|
}
|
|
}
|
|
if ( c = f ) {
|
|
e = c.tail;
|
|
for ( b = [b].concat( g ); (c = c.next) !== e; ) {
|
|
c.callback.apply( c.context || this, b )
|
|
}
|
|
}
|
|
}
|
|
return this
|
|
}};
|
|
l.bind = l.on;
|
|
l.unbind = l.off;
|
|
var o = g.Model = function ( a, b ) {
|
|
var c;
|
|
a || (a = {});
|
|
b && b.parse && (a = this.parse( a ));
|
|
if ( c = n( this, "defaults" ) ) {
|
|
a = f.extend( {}, c, a );
|
|
}
|
|
if ( b && b.collection ) {
|
|
this.collection = b.collection;
|
|
}
|
|
this.attributes = {};
|
|
this._escapedAttributes = {};
|
|
this.cid = f.uniqueId( "c" );
|
|
this.changed = {};
|
|
this._silent = {};
|
|
this._pending = {};
|
|
this.set( a, {silent : true} );
|
|
this.changed = {};
|
|
this._silent = {};
|
|
this._pending = {};
|
|
this._previousAttributes = f.clone( this.attributes );
|
|
this.initialize.apply( this, arguments )
|
|
};
|
|
f.extend( o.prototype, l, {changed : null, _silent : null, _pending : null, idAttribute : "id", initialize : function () {
|
|
}, toJSON : function () {
|
|
return f.clone( this.attributes )
|
|
}, get : function ( a ) {
|
|
return this.attributes[a]
|
|
}, escape : function ( a ) {
|
|
var b;
|
|
if ( b = this._escapedAttributes[a] ) {
|
|
return b;
|
|
}
|
|
b = this.get( a );
|
|
return this._escapedAttributes[a] = f.escape( b == null ? "" : "" + b )
|
|
}, has : function ( a ) {
|
|
return this.get( a ) != null
|
|
}, set : function ( a, b, c ) {
|
|
var d, e;
|
|
f.isObject( a ) || a == null ? (d = a, c = b) : (d = {}, d[a] = b);
|
|
c || (c = {});
|
|
if ( !d ) {
|
|
return this;
|
|
}
|
|
if ( d instanceof o ) {
|
|
d = d.attributes;
|
|
}
|
|
if ( c.unset ) {
|
|
for ( e in d ) {
|
|
d[e] = void 0;
|
|
}
|
|
}
|
|
if ( !this._validate( d, c ) ) {
|
|
return false;
|
|
}
|
|
if ( this.idAttribute in d ) {
|
|
this.id = d[this.idAttribute];
|
|
}
|
|
var b = c.changes = {}, g = this.attributes, h = this._escapedAttributes, j = this._previousAttributes ||
|
|
{};
|
|
for ( e in d ) {
|
|
a = d[e];
|
|
if ( !f.isEqual( g[e], a ) || c.unset && f.has( g, e ) ) {
|
|
delete h[e], (c.silent ? this._silent : b)[e] = true;
|
|
}
|
|
c.unset ? delete g[e] : g[e] = a;
|
|
!f.isEqual( j[e], a ) || f.has( g, e ) != f.has( j, e ) ? (this.changed[e] = a, c.silent || (this._pending[e] = true)) : (delete this.changed[e], delete this._pending[e])
|
|
}
|
|
c.silent || this.change( c );
|
|
return this
|
|
}, unset : function ( a, b ) {
|
|
(b || (b = {})).unset = true;
|
|
return this.set( a, null, b )
|
|
}, clear : function ( a ) {
|
|
(a || (a = {})).unset = true;
|
|
return this.set( f.clone( this.attributes ), a )
|
|
}, fetch : function ( a ) {
|
|
var a =
|
|
a ? f.clone( a ) : {}, b = this, c = a.success;
|
|
a.success = function ( d, e, f ) {
|
|
if ( !b.set( b.parse( d, f ), a ) ) {
|
|
return false;
|
|
}
|
|
c && c( b, d )
|
|
};
|
|
a.error = g.wrapError( a.error, b, a );
|
|
return(this.sync || g.sync).call( this, "read", this, a )
|
|
}, save : function ( a, b, c ) {
|
|
var d, e;
|
|
f.isObject( a ) || a == null ? (d = a, c = b) : (d = {}, d[a] = b);
|
|
c = c ? f.clone( c ) : {};
|
|
if ( c.wait ) {
|
|
if ( !this._validate( d, c ) ) {
|
|
return false;
|
|
}
|
|
e = f.clone( this.attributes )
|
|
}
|
|
a = f.extend( {}, c, {silent : true} );
|
|
if ( d && !this.set( d, c.wait ? a : c ) ) {
|
|
return false;
|
|
}
|
|
var k = this, h = c.success;
|
|
c.success = function ( a, b, e ) {
|
|
b = k.parse( a, e );
|
|
c.wait && (delete c.wait, b = f.extend( d || {}, b ));
|
|
if ( !k.set( b, c ) ) {
|
|
return false;
|
|
}
|
|
h ? h( k, a ) : k.trigger( "sync", k, a, c )
|
|
};
|
|
c.error = g.wrapError( c.error, k, c );
|
|
b = this.isNew() ? "create" : "update";
|
|
b = (this.sync || g.sync).call( this, b, this, c );
|
|
c.wait && this.set( e, a );
|
|
return b
|
|
}, destroy : function ( a ) {
|
|
var a = a ? f.clone( a ) : {}, b = this, c = a.success, d = function () {
|
|
b.trigger( "destroy", b, b.collection, a )
|
|
};
|
|
if ( this.isNew() ) {
|
|
return d(), false;
|
|
}
|
|
a.success = function ( e ) {
|
|
a.wait && d();
|
|
c ? c( b, e ) : b.trigger( "sync", b, e, a )
|
|
};
|
|
a.error = g.wrapError( a.error, b, a );
|
|
var e = (this.sync ||
|
|
g.sync).call( this, "delete", this, a );
|
|
a.wait || d();
|
|
return e
|
|
}, url : function () {
|
|
var a = n( this, "urlRoot" ) || n( this.collection, "url" ) || t();
|
|
return this.isNew() ? a : a + (a.charAt( a.length - 1 ) == "/" ? "" : "/") + encodeURIComponent( this.id )
|
|
}, parse : function ( a ) {
|
|
return a
|
|
}, clone : function () {
|
|
return new this.constructor( this.attributes )
|
|
}, isNew : function () {
|
|
return this.id == null
|
|
}, change : function ( a ) {
|
|
a || (a = {});
|
|
var b = this._changing;
|
|
this._changing = true;
|
|
for ( var c in this._silent ) {
|
|
this._pending[c] = true;
|
|
}
|
|
var d = f.extend( {}, a.changes, this._silent );
|
|
this._silent = {};
|
|
for ( c in d ) {
|
|
this.trigger( "change:" + c, this, this.get( c ), a );
|
|
}
|
|
if ( b ) {
|
|
return this;
|
|
}
|
|
for ( ; !f.isEmpty( this._pending ); ) {
|
|
this._pending = {};
|
|
this.trigger( "change", this, a );
|
|
for ( c in this.changed ) {
|
|
!this._pending[c] && !this._silent[c] && delete this.changed[c];
|
|
}
|
|
this._previousAttributes = f.clone( this.attributes )
|
|
}
|
|
this._changing = false;
|
|
return this
|
|
}, hasChanged : function ( a ) {
|
|
return!arguments.length ? !f.isEmpty( this.changed ) : f.has( this.changed, a )
|
|
}, changedAttributes : function ( a ) {
|
|
if ( !a ) {
|
|
return this.hasChanged() ? f.clone( this.changed ) :
|
|
false;
|
|
}
|
|
var b, c = false, d = this._previousAttributes, e;
|
|
for ( e in a ) {
|
|
if ( !f.isEqual( d[e], b = a[e] ) ) {
|
|
(c || (c = {}))[e] = b;
|
|
}
|
|
}
|
|
return c
|
|
}, previous : function ( a ) {
|
|
return!arguments.length || !this._previousAttributes ? null : this._previousAttributes[a]
|
|
}, previousAttributes : function () {
|
|
return f.clone( this._previousAttributes )
|
|
}, isValid : function () {
|
|
return!this.validate( this.attributes )
|
|
}, _validate : function ( a, b ) {
|
|
if ( b.silent || !this.validate ) {
|
|
return true;
|
|
}
|
|
var a = f.extend( {}, this.attributes, a ), c = this.validate( a, b );
|
|
if ( !c ) {
|
|
return true;
|
|
}
|
|
b && b.error ?
|
|
b.error( this, c, b ) : this.trigger( "error", this, c, b );
|
|
return false
|
|
}} );
|
|
var r = g.Collection = function ( a, b ) {
|
|
b || (b = {});
|
|
if ( b.model ) {
|
|
this.model = b.model;
|
|
}
|
|
if ( b.comparator ) {
|
|
this.comparator = b.comparator;
|
|
}
|
|
this._reset();
|
|
this.initialize.apply( this, arguments );
|
|
a && this.reset( a, {silent : true, parse : b.parse} )
|
|
};
|
|
f.extend( r.prototype, l, {model : o, initialize : function () {
|
|
}, toJSON : function ( a ) {
|
|
return this.map( function ( b ) {
|
|
return b.toJSON( a )
|
|
} )
|
|
}, add : function ( a, b ) {
|
|
var c, d, e, g, h, j = {}, i = {}, l = [];
|
|
b || (b = {});
|
|
a = f.isArray( a ) ? a.slice() : [a];
|
|
for ( c = 0, d =
|
|
a.length; c < d; c++ ) {
|
|
if ( !(e = a[c] = this._prepareModel( a[c], b )) ) {
|
|
throw Error( "Can't add an invalid model to a collection" );
|
|
}
|
|
g = e.cid;
|
|
h = e.id;
|
|
j[g] || this._byCid[g] || h != null && (i[h] || this._byId[h]) ? l.push( c ) : j[g] = i[h] = e
|
|
}
|
|
for ( c = l.length; c--; ) {
|
|
a.splice( l[c], 1 );
|
|
}
|
|
for ( c = 0, d = a.length; c < d; c++ ) {
|
|
(e = a[c]).on( "all", this._onModelEvent, this ), this._byCid[e.cid] = e, e.id != null && (this._byId[e.id] = e);
|
|
}
|
|
this.length += d;
|
|
z.apply( this.models, [b.at != null ? b.at : this.models.length, 0].concat( a ) );
|
|
this.comparator && this.sort( {silent : true} );
|
|
if ( b.silent ) {
|
|
return this;
|
|
}
|
|
for ( c = 0, d = this.models.length; c < d; c++ ) {
|
|
if ( j[(e = this.models[c]).cid] ) {
|
|
b.index = c, e.trigger( "add", e, this, b );
|
|
}
|
|
}
|
|
return this
|
|
}, remove : function ( a, b ) {
|
|
var c, d, e, g;
|
|
b || (b = {});
|
|
a = f.isArray( a ) ? a.slice() : [a];
|
|
for ( c = 0, d = a.length; c < d; c++ ) {
|
|
if ( g = this.getByCid( a[c] ) || this.get( a[c] ) ) {
|
|
delete this._byId[g.id];
|
|
delete this._byCid[g.cid];
|
|
e = this.indexOf( g );
|
|
this.models.splice( e, 1 );
|
|
this.length--;
|
|
if ( !b.silent ) {
|
|
b.index = e, g.trigger( "remove", g, this, b );
|
|
}
|
|
this._removeReference( g )
|
|
}
|
|
}
|
|
return this
|
|
}, push : function ( a, b ) {
|
|
a = this._prepareModel( a, b );
|
|
this.add( a,
|
|
b );
|
|
return a
|
|
}, pop : function ( a ) {
|
|
var b = this.at( this.length - 1 );
|
|
this.remove( b, a );
|
|
return b
|
|
}, unshift : function ( a, b ) {
|
|
a = this._prepareModel( a, b );
|
|
this.add( a, f.extend( {at : 0}, b ) );
|
|
return a
|
|
}, shift : function ( a ) {
|
|
var b = this.at( 0 );
|
|
this.remove( b, a );
|
|
return b
|
|
}, get : function ( a ) {
|
|
return a == null ? void 0 : this._byId[a.id != null ? a.id : a]
|
|
}, getByCid : function ( a ) {
|
|
return a && this._byCid[a.cid || a]
|
|
}, at : function ( a ) {
|
|
return this.models[a]
|
|
}, where : function ( a ) {
|
|
return f.isEmpty( a ) ? [] : this.filter( function ( b ) {
|
|
for ( var c in a ) {
|
|
if ( a[c] !== b.get( c ) ) {
|
|
return false;
|
|
}
|
|
}
|
|
return true
|
|
} )
|
|
}, sort : function ( a ) {
|
|
a || (a = {});
|
|
if ( !this.comparator ) {
|
|
throw Error( "Cannot sort a set without a comparator" );
|
|
}
|
|
var b = f.bind( this.comparator, this );
|
|
this.comparator.length == 1 ? this.models = this.sortBy( b ) : this.models.sort( b );
|
|
a.silent || this.trigger( "reset", this, a );
|
|
return this
|
|
}, pluck : function ( a ) {
|
|
return f.map( this.models, function ( b ) {
|
|
return b.get( a )
|
|
} )
|
|
}, reset : function ( a, b ) {
|
|
a || (a = []);
|
|
b || (b = {});
|
|
for ( var c = 0, d = this.models.length; c < d; c++ ) {
|
|
this._removeReference( this.models[c] );
|
|
}
|
|
this._reset();
|
|
this.add( a, f.extend( {silent : true},
|
|
b ) );
|
|
b.silent || this.trigger( "reset", this, b );
|
|
return this
|
|
}, fetch : function ( a ) {
|
|
a = a ? f.clone( a ) : {};
|
|
if ( a.parse === void 0 ) {
|
|
a.parse = true;
|
|
}
|
|
var b = this, c = a.success;
|
|
a.success = function ( d, e, f ) {
|
|
b[a.add ? "add" : "reset"]( b.parse( d, f ), a );
|
|
c && c( b, d )
|
|
};
|
|
a.error = g.wrapError( a.error, b, a );
|
|
return(this.sync || g.sync).call( this, "read", this, a )
|
|
}, create : function ( a, b ) {
|
|
var c = this, b = b ? f.clone( b ) : {}, a = this._prepareModel( a, b );
|
|
if ( !a ) {
|
|
return false;
|
|
}
|
|
b.wait || c.add( a, b );
|
|
var d = b.success;
|
|
b.success = function ( e, f ) {
|
|
b.wait && c.add( e, b );
|
|
d ? d( e, f ) : e.trigger( "sync",
|
|
a, f, b )
|
|
};
|
|
a.save( null, b );
|
|
return a
|
|
}, parse : function ( a ) {
|
|
return a
|
|
}, chain : function () {
|
|
return f( this.models ).chain()
|
|
}, _reset : function () {
|
|
this.length = 0;
|
|
this.models = [];
|
|
this._byId = {};
|
|
this._byCid = {}
|
|
}, _prepareModel : function ( a, b ) {
|
|
b || (b = {});
|
|
if ( a instanceof o ) {
|
|
if ( !a.collection ) {
|
|
a.collection = this
|
|
}
|
|
} else {
|
|
var c;
|
|
b.collection = this;
|
|
a = new this.model( a, b );
|
|
a._validate( a.attributes, b ) || (a = false)
|
|
}
|
|
return a
|
|
}, _removeReference : function ( a ) {
|
|
this == a.collection && delete a.collection;
|
|
a.off( "all", this._onModelEvent, this )
|
|
}, _onModelEvent : function ( a, b, c, d ) {
|
|
(a == "add" || a == "remove") && c != this || (a == "destroy" && this.remove( b, d ), b && a === "change:" + b.idAttribute && (delete this._byId[b.previous( b.idAttribute )], this._byId[b.id] = b), this.trigger.apply( this, arguments ))
|
|
}} );
|
|
f.each( "forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split( "," ), function ( a ) {
|
|
r.prototype[a] = function () {
|
|
return f[a].apply( f,
|
|
[this.models].concat( f.toArray( arguments ) ) )
|
|
}
|
|
} );
|
|
var u = g.Router = function ( a ) {
|
|
a || (a = {});
|
|
if ( a.routes ) {
|
|
this.routes = a.routes;
|
|
}
|
|
this._bindRoutes();
|
|
this.initialize.apply( this, arguments )
|
|
}, A = /:\w+/g, B = /\*\w+/g, C = /[-[\]{}()+?.,\\^$|#\s]/g;
|
|
f.extend( u.prototype, l, {initialize : function () {
|
|
}, route : function ( a, b, c ) {
|
|
g.history || (g.history = new m);
|
|
f.isRegExp( a ) || (a = this._routeToRegExp( a ));
|
|
c || (c = this[b]);
|
|
g.history.route( a, f.bind( function ( d ) {
|
|
d = this._extractParameters( a, d );
|
|
c && c.apply( this, d );
|
|
this.trigger.apply( this, ["route:" +
|
|
b].concat( d ) );
|
|
g.history.trigger( "route", this, b, d )
|
|
}, this ) );
|
|
return this
|
|
}, navigate : function ( a, b ) {
|
|
g.history.navigate( a, b )
|
|
}, _bindRoutes : function () {
|
|
if ( this.routes ) {
|
|
var a = [], b;
|
|
for ( b in this.routes ) {
|
|
a.unshift( [b, this.routes[b]] );
|
|
}
|
|
b = 0;
|
|
for ( var c = a.length; b < c; b++ ) {
|
|
this.route( a[b][0], a[b][1], this[a[b][1]] )
|
|
}
|
|
}
|
|
}, _routeToRegExp : function ( a ) {
|
|
a = a.replace( C, "\\$&" ).replace( A, "([^/]+)" ).replace( B, "(.*?)" );
|
|
return RegExp( "^" + a + "$" )
|
|
}, _extractParameters : function ( a, b ) {
|
|
return a.exec( b ).slice( 1 )
|
|
}} );
|
|
var m = g.History = function () {
|
|
this.handlers =
|
|
[];
|
|
f.bindAll( this, "checkUrl" )
|
|
}, s = /^[#\/]/, D = /msie [\w.]+/;
|
|
m.started = false;
|
|
f.extend( m.prototype, l, {interval : 50, getHash : function ( a ) {
|
|
return(a = (a ? a.location : window.location).href.match( /#(.*)$/ )) ? a[1] : ""
|
|
}, getFragment : function ( a, b ) {
|
|
if ( a == null ) {
|
|
if ( this._hasPushState || b ) {
|
|
var a = window.location.pathname, c = window.location.search;
|
|
c && (a += c)
|
|
} else {
|
|
a = this.getHash();
|
|
}
|
|
}
|
|
a.indexOf( this.options.root ) || (a = a.substr( this.options.root.length ));
|
|
return a.replace( s, "" )
|
|
}, start : function ( a ) {
|
|
if ( m.started ) {
|
|
throw Error( "Backbone.history has already been started" );
|
|
}
|
|
m.started = true;
|
|
this.options = f.extend( {}, {root : "/"}, this.options, a );
|
|
this._wantsHashChange = this.options.hashChange !== false;
|
|
this._wantsPushState = !!this.options.pushState;
|
|
this._hasPushState = !(!this.options.pushState || !window.history || !window.history.pushState);
|
|
var a = this.getFragment(), b = document.documentMode;
|
|
if ( b = D.exec( navigator.userAgent.toLowerCase() ) && (!b || b <= 7) ) {
|
|
this.iframe = i( '<iframe src="javascript:0" tabindex="-1" />' ).hide().appendTo( "body" )[0].contentWindow, this.navigate( a );
|
|
}
|
|
if ( this._hasPushState ) {
|
|
i( window ).bind( "popstate",
|
|
this.checkUrl );
|
|
} else if ( this._wantsHashChange && "onhashchange"in window && !b ) {
|
|
i( window ).bind( "hashchange", this.checkUrl );
|
|
} else if ( this._wantsHashChange ) {
|
|
this._checkUrlInterval = setInterval( this.checkUrl, this.interval );
|
|
}
|
|
this.fragment = a;
|
|
a = window.location;
|
|
b = a.pathname == this.options.root;
|
|
if ( this._wantsHashChange && this._wantsPushState && !this._hasPushState && !b ) {
|
|
return this.fragment = this.getFragment( null, true ), window.location.replace( this.options.root + "#" + this.fragment ), true;
|
|
} else if ( this._wantsPushState && this._hasPushState &&
|
|
b && a.hash ) {
|
|
this.fragment = this.getHash().replace( s, "" ), window.history.replaceState( {}, document.title, a.protocol + "//" + a.host + this.options.root + this.fragment );
|
|
}
|
|
if ( !this.options.silent ) {
|
|
return this.loadUrl()
|
|
}
|
|
}, stop : function () {
|
|
i( window ).unbind( "popstate", this.checkUrl ).unbind( "hashchange", this.checkUrl );
|
|
clearInterval( this._checkUrlInterval );
|
|
m.started = false
|
|
}, route : function ( a, b ) {
|
|
this.handlers.unshift( {route : a, callback : b} )
|
|
}, checkUrl : function () {
|
|
var a = this.getFragment();
|
|
a == this.fragment && this.iframe && (a = this.getFragment( this.getHash( this.iframe ) ));
|
|
if ( a == this.fragment ) {
|
|
return false;
|
|
}
|
|
this.iframe && this.navigate( a );
|
|
this.loadUrl() || this.loadUrl( this.getHash() )
|
|
}, loadUrl : function ( a ) {
|
|
var b = this.fragment = this.getFragment( a );
|
|
return f.any( this.handlers, function ( a ) {
|
|
if ( a.route.test( b ) ) {
|
|
return a.callback( b ), true
|
|
}
|
|
} )
|
|
}, navigate : function ( a, b ) {
|
|
if ( !m.started ) {
|
|
return false;
|
|
}
|
|
if ( !b || b === true ) {
|
|
b = {trigger : b};
|
|
}
|
|
var c = (a || "").replace( s, "" );
|
|
if ( this.fragment != c ) {
|
|
this._hasPushState ? (c.indexOf( this.options.root ) != 0 && (c = this.options.root + c), this.fragment = c, window.history[b.replace ?
|
|
"replaceState" : "pushState"]( {}, document.title, c )) : this._wantsHashChange ? (this.fragment = c, this._updateHash( window.location, c, b.replace ), this.iframe && c != this.getFragment( this.getHash( this.iframe ) ) && (b.replace || this.iframe.document.open().close(), this._updateHash( this.iframe.location, c, b.replace ))) : window.location.assign( this.options.root + a ), b.trigger && this.loadUrl( a )
|
|
}
|
|
}, _updateHash : function ( a, b, c ) {
|
|
c ? a.replace( a.toString().replace( /(javascript:|#).*$/, "" ) + "#" + b ) : a.hash = b
|
|
}} );
|
|
var v = g.View = function ( a ) {
|
|
this.cid =
|
|
f.uniqueId( "view" );
|
|
this._configure( a || {} );
|
|
this._ensureElement();
|
|
this.initialize.apply( this, arguments );
|
|
this.delegateEvents()
|
|
}, E = /^(\S+)\s*(.*)$/, w = "model,collection,el,id,attributes,className,tagName".split( "," );
|
|
f.extend( v.prototype, l, {tagName : "div", $ : function ( a ) {
|
|
return this.$el.find( a )
|
|
}, initialize : function () {
|
|
}, render : function () {
|
|
return this
|
|
}, remove : function () {
|
|
this.$el.remove();
|
|
return this
|
|
}, make : function ( a, b, c ) {
|
|
a = document.createElement( a );
|
|
b && i( a ).attr( b );
|
|
c != null && i( a ).html( c );
|
|
return a
|
|
}, setElement : function ( a, b ) {
|
|
this.$el && this.undelegateEvents();
|
|
this.$el = a instanceof i ? a : i( a );
|
|
this.el = this.$el[0];
|
|
b !== false && this.delegateEvents();
|
|
return this
|
|
}, delegateEvents : function ( a ) {
|
|
if ( a || (a = n( this, "events" )) ) {
|
|
this.undelegateEvents();
|
|
for ( var b in a ) {
|
|
var c = a[b];
|
|
f.isFunction( c ) || (c = this[a[b]]);
|
|
if ( !c ) {
|
|
throw Error( 'Method "' + a[b] + '" does not exist' );
|
|
}
|
|
var d = b.match( E ), e = d[1], d = d[2], c = f.bind( c, this );
|
|
e += ".delegateEvents" + this.cid;
|
|
d === "" ? this.$el.bind( e, c ) : this.$el.delegate( d, e, c )
|
|
}
|
|
}
|
|
}, undelegateEvents : function () {
|
|
this.$el.unbind( ".delegateEvents" +
|
|
this.cid )
|
|
}, _configure : function ( a ) {
|
|
this.options && (a = f.extend( {}, this.options, a ));
|
|
for ( var b = 0, c = w.length; b < c; b++ ) {
|
|
var d = w[b];
|
|
a[d] && (this[d] = a[d])
|
|
}
|
|
this.options = a
|
|
}, _ensureElement : function () {
|
|
if ( this.el ) {
|
|
this.setElement( this.el, false );
|
|
} else {
|
|
var a = n( this, "attributes" ) || {};
|
|
if ( this.id ) {
|
|
a.id = this.id;
|
|
}
|
|
if ( this.className ) {
|
|
a["class"] = this.className;
|
|
}
|
|
this.setElement( this.make( this.tagName, a ), false )
|
|
}
|
|
}} );
|
|
o.extend = r.extend = u.extend = v.extend = function ( a, b ) {
|
|
var c = F( this, a, b );
|
|
c.extend = this.extend;
|
|
return c
|
|
};
|
|
var G = {create : "POST",
|
|
update : "PUT", "delete" : "DELETE", read : "GET"};
|
|
g.sync = function ( a, b, c ) {
|
|
var d = G[a];
|
|
c || (c = {});
|
|
var e = {type : d, dataType : "json"};
|
|
if ( !c.url ) {
|
|
e.url = n( b, "url" ) || t();
|
|
}
|
|
if ( !c.data && b && (a == "create" || a == "update") ) {
|
|
e.contentType = "application/json", e.data = JSON.stringify( b.toJSON() );
|
|
}
|
|
if ( g.emulateJSON ) {
|
|
e.contentType = "application/x-www-form-urlencoded", e.data = e.data ? {model : e.data} : {};
|
|
}
|
|
if ( g.emulateHTTP && (d === "PUT" || d === "DELETE") ) {
|
|
if ( g.emulateJSON ) {
|
|
e.data._method = d;
|
|
}
|
|
e.type = "POST";
|
|
e.beforeSend = function ( a ) {
|
|
a.setRequestHeader( "X-HTTP-Method-Override",
|
|
d )
|
|
}
|
|
}
|
|
if ( e.type !== "GET" && !g.emulateJSON ) {
|
|
e.processData = false;
|
|
}
|
|
return i.ajax( f.extend( e, c ) )
|
|
};
|
|
g.wrapError = function ( a, b, c ) {
|
|
return function ( d, e ) {
|
|
e = d === b ? e : d;
|
|
a ? a( b, e, c ) : b.trigger( "error", b, e, c )
|
|
}
|
|
};
|
|
var x = function () {
|
|
}, F = function ( a, b, c ) {
|
|
var d;
|
|
d = b && b.hasOwnProperty( "constructor" ) ? b.constructor : function () {
|
|
a.apply( this, arguments )
|
|
};
|
|
f.extend( d, a );
|
|
x.prototype = a.prototype;
|
|
d.prototype = new x;
|
|
b && f.extend( d.prototype, b );
|
|
c && f.extend( d, c );
|
|
d.prototype.constructor = d;
|
|
d.__super__ = a.prototype;
|
|
return d
|
|
}, n = function ( a, b ) {
|
|
return!a ||
|
|
!a[b] ? null : f.isFunction( a[b] ) ? a[b]() : a[b]
|
|
}, t = function () {
|
|
throw Error( 'A "url" property or function must be specified' );
|
|
};
|
|
return g
|
|
} );
|