Commit 654a06a2 by Rocky Duan

updated backbone & single thread retrieval now working

parent aabb116a
...@@ -4,35 +4,37 @@ ...@@ -4,35 +4,37 @@
// Backbone may be freely distributed under the MIT license. // Backbone may be freely distributed under the MIT license.
// For all details and documentation: // For all details and documentation:
// http://backbonejs.org // http://backbonejs.org
(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks= (function(){var k=this,y=k.Backbone,z=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:k.Backbone={};g.VERSION="0.9.2";var f=k._;!f&&"undefined"!==typeof require&&(f=require("underscore"));g.$=k.jQuery||k.Zepto||k.ender;g.noConflict=function(){k.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,h=g.Events={on:function(a,b,c){var d,e;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks={});e=a.shift();)e=d[e]||(d[e]=[]),e.push(b,c);return this},
{});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,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g= off:function(a,b,c){var d,e,m;if(!(e=this._callbacks))return this;if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(!(m=e[d])||!b&&!c)delete e[d];else for(d=m.length-2;0<=d;d-=2)b&&m[d]!==b||c&&m[d+1]!==c||m.splice(d,2);return this},trigger:function(a){var b,c,d,e,f,g,j;if(!(c=this._callbacks))return this;j=[];a=a.split(p);e=1;for(f=arguments.length;e<f;e++)j[e-1]=arguments[e];for(;b=a.shift();){if(g=c.all)g=g.slice();if(d=c[b])d=d.slice();if(d){e=0;for(f=
z.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}};k.bind=k.on;k.unbind=k.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);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent= d.length;e<f;e+=2)d[e].apply(d[e+1]||this,j)}if(g){b=[b].concat(j);e=0;for(f=g.length;e<f;e+=2)g[e].apply(g[e+1]||this,b)}}return this}};h.bind=h.on;h.unbind=h.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.collection&&(this.collection=b.collection);b&&b.parse&&(a=this.parse(a));if(c=l(this,"defaults"))a=f.extend({},c,a);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent={};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent=
{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{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(null== {};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,h,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},sync:function(){return g.sync.apply(this,arguments)},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(null==b?"":""+b)},
b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent: has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},g=this.attributes,i=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 i[e],(c.silent?this._silent:b)[e]=!0;c.unset?
b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;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!1;c&&c(b,d)}; 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]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){b=f.extend({},b,{unset:!0});return this.set(a,null,b)},clear:function(a){a=f.extend({},a,{unset:!0});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!1;c&&c(b,d,a);b.trigger("sync",
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)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error, b,d,a)};a.error=g.wrapError(a.error,b,a);return this.sync("read",this,a)},save:function(a,b,c){var d,e,m;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c)||!d&&!this.isValid())return!1;var i=this,j=c.success;c.success=function(a,b,e){m=true;b=i.parse(a,e);c.wait&&(b=f.extend(d||{},b));if(!i.set(b,c))return false;j&&j(i,a,c);i.trigger("sync",i,a,c)};c.error=
h,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(),!1;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(); g.wrapError(c.error,i,c);b=this.sync(this.isNew()?"create":"update",this,c);!m&&c.wait&&(this.clear(a),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)};a.success=function(e){(a.wait||b.isNew())&&d();c&&c(b,e,a);b.isNew()||b.trigger("sync",b,e,a)};if(this.isNew())return a.success(),!1;a.error=g.wrapError(a.error,b,a);var e=this.sync("delete",this,a);a.wait||d();return e},url:function(){var a=l(this,"urlRoot")||
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 null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;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= l(this.collection,"url")||s();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 null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;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=!1;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):!1;var b,c=!1,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.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=!1;return this},hasChanged:function(a){return null==a?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,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 null==
!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!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator); a||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate||!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var q=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);void 0!==b.comparator&&
this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{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,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(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;i=e.id;j[g]||this._byCid[g]||null!=i&&(k[i]||this._byId[i])? (this.comparator=b.comparator);this._reset();this.initialize.apply(this,arguments);a&&(b.parse&&(a=this.parse(a)),this.reset(a,{silent:!0,parse:b.parse}))};f.extend(q.prototype,h,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},sync:function(){return g.sync.apply(this,arguments)},add:function(a,b){var c,d,e,g,i,j={},k={},h=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(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");
l.push(c):j[g]=k[i]=e}for(c=l.length;c--;)a.splice(l[c],1);c=0;for(d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=e.id&&(this._byId[e.id]=e);this.length+=d;A.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));this.comparator&&this.sort({silent:!0});if(b.silent)return this;c=0;for(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)? g=e.cid;i=e.id;j[g]||this._byCid[g]||null!=i&&(k[i]||this._byId[i])?h.push(c):j[g]=k[i]=e}for(c=h.length;c--;)h[c]=a.splice(h[c],1)[0];c=0;for(d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=e.id&&(this._byId[e.id]=e);this.length+=d;z.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));if(b.merge){c=0;for(d=h.length;c<d;c++)(e=this._byId[h[c].id])&&e.set(h[c],b)}this.comparator&&null==b.at&&this.sort({silent:!0});if(b.silent)return this;c=0;
a.slice():[a];c=0;for(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--,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}, for(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];c=0;for(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--,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,
shift:function(a){var b=this.at(0);this.remove(b,a);return b},get:function(a){return null==a?void 0:this._byId[null!=a.id?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!1;return!0})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1==this.comparator.length? 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},slice:function(a,b){return this.models.slice(a,b)},get:function(a){return null==a?void 0:this._byId[null!=a.id?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]!==
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:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d, b.get(c))return!1;return!0})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1===this.comparator.length?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,
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!1;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= f.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);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);b.trigger("sync",b,d,a)};a.error=g.wrapError(a.error,b,a);return this.sync("read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(a,b,f){f.wait&&c.add(a,
{};this._byCid={}},_prepareModel:function(a,b){b||(b={});a instanceof o?a.collection||(a.collection=this):(b.collection=this,a=new this.model(a,b),a._validate(a.attributes,b)||(a=!1));return a},_removeReference:function(a){this==a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"==a||"remove"==a)&&c!=this||("destroy"==a&&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, f);d&&d(a,b,f)};a.save(null,b);return a},parse:function(a){return a},clone:function(){return new this.constructor(this.models)},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){if(a instanceof o)return a.collection||(a.collection=this),a;b||(b={});b.collection=this;var c=new this.model(a,b);return!c._validate(c.attributes,b)?!1:c},_removeReference:function(a){this===a.collection&&delete a.collection;
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={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},B=/:\w+/g, a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"===a||"remove"===a)&&c!==this||("destroy"===a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],null!=b.id&&(this._byId[b.id]=b)),this.trigger.apply(this,arguments))}});f.each("forEach each map collect reduce foldl inject reduceRight foldr find detect filter select reject every all some any include contains invoke max min sortBy sortedIndex toArray size first head take initial rest tail last without indexOf shuffle lastIndexOf isEmpty groupBy".split(" "),
C=/\*\w+/g,D=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(u.prototype,k,{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, function(a){q.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});var t=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},A=/:\w+/g,B=/\*\w+/g,C=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(t.prototype,h,{initialize:function(){},route:function(a,b,c){g.history||(g.history=new n);f.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,f.bind(function(d){d=this._extractParameters(a,
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(D,"\\$&").replace(B,"([^/]+)").replace(C,"(.*?)");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=/^[#\/]/,E=/msie [\w.]+/;m.started=!1;f.extend(m.prototype,k,{interval:50,getHash:function(a){return(a=(a?a.location:window.location).href.match(/#(.*)$/))?a[1]: 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)}});
""},getFragment:function(a,b){if(null==a)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=!0;this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState= var n=g.History=function(a){this.handlers=[];f.bindAll(this,"checkUrl");this.location=a&&a.location||k.location;this.history=a&&a.history||k.history},r=/^[#\/]/,D=/msie [\w.]+/,u=/\/$/;n.started=!1;f.extend(n.prototype,h,{interval:50,getHash:function(a){return(a=(a||this).location.href.match(/#(.*)$/))?a[1]:""},getFragment:function(a,b){if(null==a)if(this._hasPushState||!this._wantsHashChange||b){var a=this.location.pathname,c=this.options.root.replace(u,"");a.indexOf(c)||(a=a.substr(c.length))}else a=
!(!this.options.pushState||!window.history||!window.history.pushState);var a=this.getFragment(),b=document.documentMode;if(b=E.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b))this.iframe=i('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a);this._hasPushState?i(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?i(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl, this.getHash();return decodeURIComponent(a.replace(r,""))},start:function(a){if(n.started)throw Error("Backbone.history has already been started");n.started=!0;this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||!this.history||!this.history.pushState);var a=this.getFragment(),b=document.documentMode,b=D.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b);u.test(this.options.root)||
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,!0),window.location.replace(this.options.root+"#"+this.fragment),!0;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()}, (this.options.root+="/");b&&this._wantsHashChange&&(this.iframe=g.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a));this._hasPushState?g.$(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?g.$(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval));this.fragment=a;a=this.location;b=a.pathname.replace(/[^/]$/,"$&/")===this.options.root&&
stop:function(){i(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);m.started=!1},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!1;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, !a.search;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),this.location.replace(this.options.root+this.location.search+"#"+this.fragment),!0;this._wantsPushState&&(this._hasPushState&&b&&a.hash)&&(this.fragment=this.getHash().replace(r,""),this.history.replaceState({},document.title,a.protocol+"//"+a.host+this.options.root+this.fragment));if(!this.options.silent)return this.loadUrl()},stop:function(){g.$(window).unbind("popstate",
function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!m.started)return!1;if(!b||!0===b)b={trigger:b};var c=(a||"").replace(s,"");this.fragment!=c&&(this._hasPushState?(0!=c.indexOf(this.options.root)&&(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.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);n.started=!1},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!1;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),
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()},F=/^(\S+)\s*(.*)$/,w="model,collection,el,id,attributes,className,tagName".split(","); !0})},navigate:function(a,b){if(!n.started)return!1;if(!b||!0===b)b={trigger:b};var c=(a||"").replace(r,"");if(this.fragment!==c){this.fragment=c;var d=(0!==c.indexOf(this.options.root)?this.options.root:"")+c;if(this._hasPushState)this.history[b.replace?"replaceState":"pushState"]({},document.title,d);else if(this._wantsHashChange)this._updateHash(this.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,
f.extend(v.prototype,k,{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&&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];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=n(this,"events"))){this.undelegateEvents(); c,b.replace));else return this.location.assign(d);b.trigger&&this.loadUrl(a)}},_updateHash:function(a,b,c){c?a.replace(a.href.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,h,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},
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(F),e=d[1],d=d[2],c=f.bind(c,this),e=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, render:function(){return this},dispose:function(){this.undelegateEvents();this.model&&this.model.off(null,null,this);this.collection&&this.collection.off(null,null,this);return this},remove:function(){this.dispose();this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);b&&g.$(a).attr(b);null!=c&&g.$(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof g.$?a:g.$(a);this.el=this.$el[0];this.$delegateElement=this.$el;!1!==b&&
!1);else{var a=n(this,"attributes")||{};this.id&&(a.id=this.id);this.className&&(a["class"]=this.className);this.setElement(this.make(this.tagName,a),!1)}}});o.extend=r.extend=u.extend=v.extend=function(a,b){var c=G(this,a,b);c.extend=this.extend;return c};var H={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=H[a];c||(c={});var e={type:d,dataType:"json"};c.url||(e.url=n(b,"url")||t());if(!c.data&&b&&("create"==a||"update"==a))e.contentType="application/json", this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=l(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=e+(".delegateEvents"+this.cid);""===d?this.$delegateElement.bind(e,c):this.$delegateElement.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=
e.data=JSON.stringify(b.toJSON());g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);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(){},G=function(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,!1);else{var a=f.extend({},l(this,"attributes"));this.id&&(a.id=l(this,"id"));this.className&&(a["class"]=l(this,"className"));this.setElement(this.make(l(this,"tagName"),a),!1)}}});o.extend=q.extend=t.extend=v.extend=function(a,b){var c=this,d;d=a&&a.hasOwnProperty("constructor")?a.constructor:function(){c.apply(this,arguments)};
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');}}).call(this); f.extend(d,c);x.prototype=c.prototype;d.prototype=new x;a&&f.extend(d.prototype,a);b&&f.extend(d,b);d.prototype.constructor=d;d.__super__=c.prototype;return d};var F={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=F[a];c||(c={});var e={type:d,dataType:"json"};c.url||(e.url=l(b,"url")||s());if(!c.data&&b&&("create"===a||"update"===a))e.contentType="application/json",e.data=JSON.stringify(b);g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=
e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);return g.ajax(f.extend(e,c))};g.ajax=function(){return g.$.ajax.apply(g.$,arguments)};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(){},l=function(a,b){return!a||!a[b]?null:f.isFunction(a[b])?
a[b]():a[b]},s=function(){throw Error('A "url" property or function must be specified');}}).call(this);
...@@ -10,6 +10,7 @@ from mitxmako.shortcuts import render_to_response, render_to_string ...@@ -10,6 +10,7 @@ from mitxmako.shortcuts import render_to_response, render_to_string
from courseware.courses import get_course_with_access from courseware.courses import get_course_with_access
from urllib import urlencode from urllib import urlencode
from operator import methodcaller
from django_comment_client.permissions import check_permissions_by_view from django_comment_client.permissions import check_permissions_by_view
from django_comment_client.utils import merge_dict, extract, strip_none from django_comment_client.utils import merge_dict, extract, strip_none
...@@ -188,6 +189,7 @@ def single_thread(request, course_id, discussion_id, thread_id): ...@@ -188,6 +189,7 @@ def single_thread(request, course_id, discussion_id, thread_id):
return utils.JsonResponse({ return utils.JsonResponse({
'html': html, 'html': html,
'content': thread.to_dict(),
'annotated_content_info': annotated_content_info, 'annotated_content_info': annotated_content_info,
}) })
......
...@@ -15,6 +15,7 @@ TEMPLATE_DEBUG = True ...@@ -15,6 +15,7 @@ TEMPLATE_DEBUG = True
MITX_FEATURES['DISABLE_START_DATES'] = True MITX_FEATURES['DISABLE_START_DATES'] = True
MITX_FEATURES['ENABLE_SQL_TRACKING_LOGS'] = True MITX_FEATURES['ENABLE_SQL_TRACKING_LOGS'] = True
MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = True
WIKI_ENABLED = True WIKI_ENABLED = True
......
...@@ -18,12 +18,61 @@ class @Content extends Backbone.Model ...@@ -18,12 +18,61 @@ class @Content extends Backbone.Model
can: (action) -> can: (action) ->
DiscussionUtil.getContentInfo @id, action DiscussionUtil.getContentInfo @id, action
initialize: ->
@set('comments', new Comments())
if @get('children')
@get('comments').reset @get('children'), {silent: false}
class @ContentView extends Backbone.View class @ContentView extends Backbone.View
$: (selector) -> $: (selector) ->
@$local.find(selector) @$local.find(selector)
showSingleThread: (event) -> showSingleThread: (event) ->
$threadTitle = @$(".thread-title")
$showComments = @$(".discussion-show-comments")
if not $showComments.hasClass("first-time") and (not $showComments.length or not $threadTitle.length)
return
rebindHideEvents = ->
$threadTitle.unbind('click').click @hideSingleThread
$showComments.unbind('click').click @hideSingleThread
$showComments.removeClass("discussion-show-comments")
.addClass("discussion-hide-comments")
prevHtml = $showComments.html()
$showComments.html prevHtml.replace "Show", "Hide"
if not $showComments.hasClass("first-time") and @$el.children(".comments").length
@$el.children(".comments").show()
rebindHideEvents()
else
discussion_id = @model.discussion.id
url = DiscussionUtil.urlFor('retrieve_single_thread', discussion_id, @model.id)
DiscussionUtil.safeAjax
$elem: $.merge($threadTitle, $showComments)
url: url
type: "GET"
dataType: 'json'
success: (response, textStatus) =>
DiscussionUtil.bulkExtendContentInfo response['annotated_content_info']
@$el.append(response['html'])
@model.get('comments').reset response.content.children, {silent: false}
@initCommentViews()
$showComments.removeClass("first-time")
rebindHideEvents()
initCommentViews: ->
@$el.children(".comments").children(".comment").each (index, elem) =>
model = @model.get('comments').find $(elem).attr("_id")
if not model.view
commentView = new CommentView el: elem, model: model
hideSingleThread: ->
reply: ->
cancelReply: ->
unvote: (event) -> unvote: (event) ->
url = DiscussionUtil.urlFor("undo_vote_for_#{@model.get('type')}", @model.id) url = DiscussionUtil.urlFor("undo_vote_for_#{@model.get('type')}", @model.id)
...@@ -55,12 +104,6 @@ class @ContentView extends Backbone.View ...@@ -55,12 +104,6 @@ class @ContentView extends Backbone.View
@$(".discussion-vote-#{value}").addClass("voted") @$(".discussion-vote-#{value}").addClass("voted")
@$(".discussion-votes-point").html response.votes.point @$(".discussion-votes-point").html response.votes.point
hideSingleThread: ->
reply: ->
cancelReply: ->
endorse: -> endorse: ->
close: -> close: ->
...@@ -85,6 +128,7 @@ class @ContentView extends Backbone.View ...@@ -85,6 +128,7 @@ class @ContentView extends Backbone.View
initLocal: -> initLocal: ->
@$local = @$el.children(".local") @$local = @$el.children(".local")
@$delegateElement = @$local
initFollowThread: -> initFollowThread: ->
$el.children(".discussion-content") $el.children(".discussion-content")
...@@ -117,6 +161,7 @@ class @ContentView extends Backbone.View ...@@ -117,6 +161,7 @@ class @ContentView extends Backbone.View
@initTimeago() @initTimeago()
@initBody() @initBody()
@initActions() @initActions()
@initCommentViews()
class @Thread extends @Content class @Thread extends @Content
...@@ -124,5 +169,16 @@ class @ThreadView extends @ContentView ...@@ -124,5 +169,16 @@ class @ThreadView extends @ContentView
class @Comment extends @Content class @Comment extends @Content
class @CommentView extends @ContentView
class @Comments extends Backbone.Collection class @Comments extends Backbone.Collection
model: Comment model: Comment
initialize: ->
@bind "add", (item) =>
item.collection = @
find: (id) ->
_.first @where(id: id)
class @Discussion extends Backbone.Collection class @Discussion extends Backbone.Collection
model: Thread model: Thread
initialize: -> initialize: ->
this.bind "add", (item) =>
item.collection = this @bind "add", (item) =>
console.log item
item.discussion = @
find: (id) -> find: (id) ->
_.first @where(id: id) _.first @where(id: id)
...@@ -16,9 +18,11 @@ class @DiscussionView extends Backbone.View ...@@ -16,9 +18,11 @@ class @DiscussionView extends Backbone.View
initLocal: -> initLocal: ->
@$local = @$el.children(".local") @$local = @$el.children(".local")
@$delegateElement = @$local
initialize: -> initialize: ->
@initLocal() @initLocal()
@model.id = @$el.attr("_id")
@model.view = @ @model.view = @
@$el.children(".threads").children(".thread").each (index, elem) => @$el.children(".threads").children(".thread").each (index, elem) =>
threadView = new ThreadView el: elem, model: @model.find $(elem).attr("_id") threadView = new ThreadView el: elem, model: @model.find $(elem).attr("_id")
......
...@@ -5,5 +5,6 @@ $ -> ...@@ -5,5 +5,6 @@ $ ->
$("section.discussion").each (index, elem) -> $("section.discussion").each (index, elem) ->
discussionData = DiscussionUtil.getDiscussionData(elem) discussionData = DiscussionUtil.getDiscussionData(elem)
discussion = new Discussion(discussionData) discussion = new Discussion()
discussion.reset(discussionData, {silent: false})
view = new DiscussionView(el: elem, model: discussion) view = new DiscussionView(el: elem, model: discussion)
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
</%def> </%def>
<%def name="render_content_with_comments(content)"> <%def name="render_content_with_comments(content)">
<div class="${content['type']}" _id="${content['id']}" _discussion_id="${content.get('commentable_id')}" _author_id="${helpers.show_if(content['user_id'], content.get('anonymous'))}"> <div class="${content['type']}${helpers.show_if(' endorsed', content.get('endorsed'))}" _id="${content['id']}" _discussion_id="${content.get('commentable_id', '')}" _author_id="${helpers.show_if(content['user_id'], not content.get('anonymous'))}">
<div class="local">${render_content(content)}</div> <div class="local">${render_content(content)}</div>
% if content.get('children') is not None: % if content.get('children') is not None:
${render_comments(content['children'])} ${render_comments(content['children'])}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment