diff --git a/bower.json b/bower.json index 0249b9b..c5745b2 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "Backbone.Manager", - "version": "2.0.3", + "version": "2.0.4", "homepage": "https://github.com/novu/Backbone.Manager", "author": "Johnathon Sanders", "description": "State-Based Routing/Control Manager for Backbone", diff --git a/package.json b/package.json index f197832..97c68cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Backbone.Manager", - "version": "2.0.3", + "version": "2.0.4", "description": "State-Based Routing/Control Manager for Backbone", "homepage": "https://github.com/novu/backbone.manager", "bugs": "https://github.com/novu/backbone.manager/issues", diff --git a/release/backbone.manager-min.js b/release/backbone.manager-min.js index 5c231b7..15e4a10 100644 --- a/release/backbone.manager-min.js +++ b/release/backbone.manager-min.js @@ -1,2 +1,2 @@ -!function(t,r,e,n){var a,i,s,o,l,u,h,c;h=[],u=r.extend({},t.Events),c=n.location.href,o=/[:*]([^(:?)\/]+)/g,s=/\(.*\)/g,l=null,a=function(){function e(e,n){h.push(this),this.router=e,r.extend(this,t.Events),this._parseStates(),this._parseEvents(),this.initialize(n)}return e.prototype.states={},e.prototype.events={},e.prototype.initialize=function(){},e.prototype._parseStates=function(){r.each(r.keys(this.states),function(t){return function(e){var n,a,i;if(a=t.states[e],!a.transitionMethod)throw new Error(e+" needs transitionMethod definitions");if(a.url){if(r.isRegExp(a.url))throw new Error(e+" is not allowed to have a RegExp url");a._urlParams=function(){var t;for(t=[];n=o.exec(a.url);)t.push(n[1]);return t}(),i=a.url.replace(s,""),a._urlAsTemplate=r.template(i,null,{interpolate:o}),a._urlAsRegex=t.router._routeToRegExp(a.url),t.router.route(a._urlAsRegex,e,function(){t._routeCallbackChooser(e,a,Array.apply(null,arguments))})}return t.listenTo(u,e,function(r,n){t._handleTransitionCallback(e,a,r,n)})}}(this))},e.prototype._routeCallbackChooser=function(t,r,e){var n;c&&this._getWindowHref()===c?this._handleLoadCallback(t,r,e):this._handleTransitionCallback(t,r,e,{},n=!0),c=null},e.prototype._handleLoadCallback=function(t,r,e){var n;if(l=this,r.loadMethod){this.trigger("loadStart"),this.trigger("loadStart:"+t,e);try{this[r.loadMethod].apply(this,e),this.trigger("loadSuccess"),this.trigger("loadSuccess:"+t,e)}catch(a){n=a,this.trigger("loadError",n),this.trigger("loadError:"+t,e,n)}}},e.prototype._handleTransitionCallback=function(t,e,n,a,i){var s,o,u,h,c,g;if(null==a&&(a={}),null==i&&(i=!1),null==a.navigate&&(a.navigate=!0),l&&l!==this&&l.trigger("exit"),l=this,this.trigger("transitionStart"),this.trigger("transitionStart:"+t),e.url){if(n instanceof Array)h=r.object(e._urlParams,n),c=r.last(n),g=e._urlAsTemplate(h),c&&(g+=g.indexOf("?")>-1?"&":"?",g+=c),!i&&a.navigate&&this.router.navigate(g),s=r.map(r.initial(n),String),s.push(c);else{if(!(n instanceof Object))throw new Error("Params are only supported as an object or array if state.url is defined");g=e._urlAsTemplate(n),!i&&a.navigate&&this.router.navigate(g),s=this.router._extractParameters(e._urlAsRegex,g)}u={url:g},s.push(u)}else s=n;try{this[e.transitionMethod].apply(this,s),this.trigger("transitionSuccess"),this.trigger("transitionSuccess:"+t)}catch(p){o=p,this.trigger("transitionError",o),this.trigger("transitionError:"+t,o)}},e.prototype._parseEvents=function(){r.each(r.keys(this.events),function(t){return function(r){t.on(r,t[t.events[r]])}}(this))},e.prototype._parseStateFromUrl=function(t){var e,n;return n=r.find(r.keys(this.states).reverse(),function(r){return function(e){var n;return null!=(n=r.states[e]._urlAsRegex)?n.test(t):void 0}}(this)),n?(e=this.router._extractParameters(this.states[n]._urlAsRegex,t),{state:n,params:e}):void 0},e.prototype._getWindowHref=function(){return null!=n?n.location.href:void 0},e.go=function(t,r,e){return r||(r=[]),r instanceof Array&&r.push(null),u.trigger(t,r,e)},e.goByUrl=function(t,e){var n,a,i,s,o;return o=document.createElement("a"),o.href=t,i=o.pathname.replace(/^\//,"")+o.search,a=null,r.find(h.slice().reverse(),function(t){return a=t._parseStateFromUrl(i)}),a?(s=a.state,n=a.params):(s="*",n=[i]),u.trigger(s,n,e)},e.extend=t.Model.extend,e.config={},e}(),t.Manager=a,i=function(t){var r,n,i,s,o,l;t.isDefaultPrevented()||(r=e(t.currentTarget),s=r.attr("data-bb-state"),l=r.attr("data-bb-options")||"{}",t.preventDefault(),""===s?a.goByUrl(t.currentTarget.href,JSON.parse(l)):(o=s.split("(",2),i=o[0],n=[],o.length>1&&o[1].length>2&&(n=JSON.parse(o[1].slice(0,o[1].indexOf(")")))),n instanceof Array&&n.push(null)),u.trigger(i,n,JSON.parse(l)))},e(n.document).on("click","a[data-bb-state]",function(t){return i(t)})}(Backbone,_,$,window); +!function(t,e,r,n){var a,i,o,s,l,u,h,c;h=[],u=e.extend({},t.Events),c=n.location.href,s=/[:*]([^(:?)\/]+)/g,o=/\(.*\)/g,l=null,a=function(){function r(r,n){h.push(this),this.router=r,e.extend(this,t.Events),this._parseStates(),this._parseEvents(),this.initialize(n)}return r.prototype.states={},r.prototype.events={},r.prototype.initialize=function(){},r.prototype._parseStates=function(){e.each(e.keys(this.states),function(t){return function(r){var n,a,i;if(a=t.states[r],!a.transitionMethod)throw new Error(r+" needs transitionMethod definitions");if(a.url){if(e.isRegExp(a.url))throw new Error(r+" is not allowed to have a RegExp url");a._urlParams=function(){var t;for(t=[];n=s.exec(a.url);)t.push(n[1]);return t}(),i=a.url.replace(o,""),a._urlAsTemplate=e.template(i,null,{interpolate:s}),a._urlAsRegex=t.router._routeToRegExp(a.url),t.router.route(a._urlAsRegex,r,function(){t._routeCallbackChooser(r,a,Array.apply(null,arguments))})}return t.listenTo(u,r,function(e,n){t._handleTransitionCallback(r,a,e,n)})}}(this))},r.prototype._routeCallbackChooser=function(t,e,r){var n;c&&this._getWindowHref()===c?this._handleLoadCallback(t,e,r):this._handleTransitionCallback(t,e,r,{},n=!0),c=null},r.prototype._handleLoadCallback=function(t,e,r){var n;if(l=this,e.loadMethod){this.trigger("loadStart"),this.trigger("loadStart:"+t,r);try{this[e.loadMethod].apply(this,r),this.trigger("loadSuccess"),this.trigger("loadSuccess:"+t,r)}catch(a){n=a,this.trigger("loadError",n),this.trigger("loadError:"+t,r,n)}}},r.prototype._handleTransitionCallback=function(t,r,n,a,i){var o,s,u,h,c,g;if(null==a&&(a={}),null==i&&(i=!1),null==a.navigate&&(a.navigate=!0),l&&l!==this&&l.trigger("exit"),l=this,this.trigger("transitionStart"),this.trigger("transitionStart:"+t),r.url){if(n instanceof Array)h=e.object(r._urlParams,n),c=e.last(n),g=r._urlAsTemplate(h),c&&(g+=g.indexOf("?")>-1?"&":"?",g+=c),!i&&a.navigate&&this._getWindowPath()!==g&&(this.router.navigate(g),this.trigger("navigate")),o=e.map(e.initial(n),String),o.push(c);else{if(!(n instanceof Object))throw new Error("Params are only supported as an object or array if state.url is defined");g=r._urlAsTemplate(n),!i&&a.navigate&&this._getWindowPath()!==g&&(this.router.navigate(g),this.trigger("navigate")),o=this.router._extractParameters(r._urlAsRegex,g)}u={url:g},o.push(u)}else o=n;try{this[r.transitionMethod].apply(this,o),this.trigger("transitionSuccess"),this.trigger("transitionSuccess:"+t)}catch(p){s=p,this.trigger("transitionError",s),this.trigger("transitionError:"+t,s)}},r.prototype._parseEvents=function(){e.each(e.keys(this.events),function(t){return function(e){t.on(e,t[t.events[e]])}}(this))},r.prototype._parseStateFromUrl=function(t){var r,n;return n=e.find(e.keys(this.states).reverse(),function(e){return function(r){var n;return null!=(n=e.states[r]._urlAsRegex)?n.test(t):void 0}}(this)),n?(r=this.router._extractParameters(this.states[n]._urlAsRegex,t),{state:n,params:r}):void 0},r.prototype._getWindowHref=function(){return null!=n?n.location.href:void 0},r.prototype._getWindowPath=function(){return(null!=n?n.location.pathname.replace(/^\//,""):void 0)+(null!=n?n.location.search:void 0)},r.go=function(t,e,r){return e||(e=[]),e instanceof Array&&e.push(null),u.trigger(t,e,r)},r.goByUrl=function(t,r){var n,a,i,o,s;return s=document.createElement("a"),s.href=t,i=s.pathname.replace(/^\//,"")+s.search,a=null,e.find(h.slice().reverse(),function(t){return a=t._parseStateFromUrl(i)}),a?(o=a.state,n=a.params):(o="*",n=[i]),u.trigger(o,n,r)},r.extend=t.Model.extend,r.config={},r}(),t.Manager=a,i=function(t){var e,n,i,o,s,l;t.isDefaultPrevented()||(e=r(t.currentTarget),o=e.attr("data-bb-state"),l=e.attr("data-bb-options")||"{}",t.preventDefault(),""===o?a.goByUrl(t.currentTarget.href,JSON.parse(l)):(s=o.split("(",2),i=s[0],n=[],s.length>1&&s[1].length>2&&(n=JSON.parse(s[1].slice(0,s[1].indexOf(")")))),n instanceof Array&&n.push(null)),u.trigger(i,n,JSON.parse(l)))},r(n.document).on("click","a[data-bb-state]",function(t){return i(t)})}(Backbone,_,$,window); //# sourceMappingURL=backbone.manager-min.js.map \ No newline at end of file diff --git a/release/backbone.manager-min.js.map b/release/backbone.manager-min.js.map index 8943e90..6d9065c 100644 --- a/release/backbone.manager-min.js.map +++ b/release/backbone.manager-min.js.map @@ -1 +1 @@ -{"version":3,"sources":["backbone.manager.js"],"names":["Backbone","_","$","window","Manager","_watchForStateChange","cachedOptionalMatcher","cachedParamMatcher","currentManager","managerQueue","managers","onloadUrl","extend","Events","location","href","router","options","push","this","_parseStates","_parseEvents","initialize","prototype","states","events","each","keys","_this","stateKey","matches","stateOptions","templateUrl","transitionMethod","Error","url","isRegExp","_urlParams","results","exec","replace","_urlAsTemplate","template","interpolate","_urlAsRegex","_routeToRegExp","route","_routeCallbackChooser","Array","apply","arguments","listenTo","params","transitionOptions","_handleTransitionCallback","historyHasUpdated","_getWindowHref","_handleLoadCallback","error","loadMethod","trigger","_error","data","paramsObject","queryParams","navigate","object","last","indexOf","map","initial","String","Object","_extractParameters","eventName","on","_parseStateFromUrl","find","reverse","ref","test","state","go","goByUrl","parsedUrl","path","urlParser","document","createElement","pathname","search","slice","manager","Model","config","event","$target","stateAttr","stateInfo","isDefaultPrevented","currentTarget","attr","preventDefault","JSON","parse","split","length"],"mappings":"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","file":"backbone.manager-min.js","sourcesContent":["/**\n * Backbone.Manager - State-Based Routing/Control Manager for Backbone\n * @version v2.0.3\n * @link https://github.com/novu/backbone.manager\n * @author Johnathon Sanders\n * @license MIT\n */\n(function(Backbone, _, $, window) {\n var Manager, _watchForStateChange, cachedOptionalMatcher, cachedParamMatcher, currentManager, managerQueue, managers, onloadUrl;\n managers = [];\n managerQueue = _.extend({}, Backbone.Events);\n onloadUrl = window.location.href;\n cachedParamMatcher = /[:*]([^(:?)\\/]+)/g;\n cachedOptionalMatcher = /\\(.*\\)/g;\n currentManager = null;\n Manager = (function() {\n Manager.prototype.states = {};\n\n Manager.prototype.events = {};\n\n function Manager(router, options) {\n managers.push(this);\n this.router = router;\n _.extend(this, Backbone.Events);\n this._parseStates();\n this._parseEvents();\n this.initialize(options);\n return;\n }\n\n Manager.prototype.initialize = function() {};\n\n Manager.prototype._parseStates = function() {\n _.each(_.keys(this.states), (function(_this) {\n return function(stateKey) {\n var matches, stateOptions, templateUrl;\n stateOptions = _this.states[stateKey];\n if (!stateOptions.transitionMethod) {\n throw new Error(stateKey + ' needs transitionMethod definitions');\n }\n if (stateOptions.url) {\n if (_.isRegExp(stateOptions.url)) {\n throw new Error(stateKey + ' is not allowed to have a RegExp url');\n }\n stateOptions._urlParams = (function() {\n var results;\n results = [];\n while (matches = cachedParamMatcher.exec(stateOptions.url)) {\n results.push(matches[1]);\n }\n return results;\n })();\n templateUrl = stateOptions.url.replace(cachedOptionalMatcher, '');\n stateOptions._urlAsTemplate = _.template(templateUrl, null, {\n interpolate: cachedParamMatcher\n });\n stateOptions._urlAsRegex = _this.router._routeToRegExp(stateOptions.url);\n _this.router.route(stateOptions._urlAsRegex, stateKey, function() {\n _this._routeCallbackChooser(stateKey, stateOptions, Array.apply(null, arguments));\n });\n }\n return _this.listenTo(managerQueue, stateKey, function(params, transitionOptions) {\n _this._handleTransitionCallback(stateKey, stateOptions, params, transitionOptions);\n });\n };\n })(this));\n };\n\n Manager.prototype._routeCallbackChooser = function(stateKey, stateOptions, params) {\n var historyHasUpdated;\n if (onloadUrl && this._getWindowHref() === onloadUrl) {\n this._handleLoadCallback(stateKey, stateOptions, params);\n } else {\n this._handleTransitionCallback(stateKey, stateOptions, params, {}, historyHasUpdated = true);\n }\n onloadUrl = null;\n };\n\n Manager.prototype._handleLoadCallback = function(stateKey, stateOptions, params) {\n var error;\n currentManager = this;\n if (stateOptions.loadMethod) {\n this.trigger('loadStart');\n this.trigger('loadStart:' + stateKey, params);\n try {\n this[stateOptions.loadMethod].apply(this, params);\n this.trigger('loadSuccess');\n this.trigger('loadSuccess:' + stateKey, params);\n } catch (_error) {\n error = _error;\n this.trigger('loadError', error);\n this.trigger('loadError:' + stateKey, params, error);\n }\n }\n };\n\n Manager.prototype._handleTransitionCallback = function(stateKey, stateOptions, params, transitionOptions, historyHasUpdated) {\n var data, error, options, paramsObject, queryParams, url;\n if (transitionOptions == null) {\n transitionOptions = {};\n }\n if (historyHasUpdated == null) {\n historyHasUpdated = false;\n }\n if (transitionOptions.navigate == null) {\n transitionOptions.navigate = true;\n }\n if (currentManager && currentManager !== this) {\n currentManager.trigger('exit');\n }\n currentManager = this;\n this.trigger('transitionStart');\n this.trigger('transitionStart:' + stateKey);\n if (stateOptions.url) {\n if (params instanceof Array) {\n paramsObject = _.object(stateOptions._urlParams, params);\n queryParams = _.last(params);\n url = stateOptions._urlAsTemplate(paramsObject);\n if (queryParams) {\n if (url.indexOf('?') > -1) {\n url += '&';\n } else {\n url += '?';\n }\n url += queryParams;\n }\n if (!historyHasUpdated && transitionOptions.navigate) {\n this.router.navigate(url);\n }\n data = _.map(_.initial(params), String);\n data.push(queryParams);\n } else if (params instanceof Object) {\n url = stateOptions._urlAsTemplate(params);\n if (!historyHasUpdated && transitionOptions.navigate) {\n this.router.navigate(url);\n }\n data = this.router._extractParameters(stateOptions._urlAsRegex, url);\n } else {\n throw new Error('Params are only supported as an object or array if state.url is defined');\n }\n options = {\n url: url\n };\n data.push(options);\n } else {\n data = params;\n }\n try {\n this[stateOptions.transitionMethod].apply(this, data);\n this.trigger('transitionSuccess');\n this.trigger('transitionSuccess:' + stateKey);\n } catch (_error) {\n error = _error;\n this.trigger('transitionError', error);\n this.trigger('transitionError:' + stateKey, error);\n }\n };\n\n Manager.prototype._parseEvents = function() {\n _.each(_.keys(this.events), (function(_this) {\n return function(eventName) {\n _this.on(eventName, _this[_this.events[eventName]]);\n };\n })(this));\n };\n\n Manager.prototype._parseStateFromUrl = function(url) {\n var data, stateKey;\n stateKey = _.find(_.keys(this.states).reverse(), (function(_this) {\n return function(stateKey) {\n var ref;\n return (ref = _this.states[stateKey]._urlAsRegex) != null ? ref.test(url) : void 0;\n };\n })(this));\n if (stateKey) {\n data = this.router._extractParameters(this.states[stateKey]._urlAsRegex, url);\n return {\n state: stateKey,\n params: data\n };\n }\n };\n\n Manager.prototype._getWindowHref = function() {\n return window != null ? window.location.href : void 0;\n };\n\n Manager.go = function(state, params, transitionOptions) {\n if (!params) {\n params = [];\n }\n if (params instanceof Array) {\n params.push(null);\n }\n return managerQueue.trigger(state, params, transitionOptions);\n };\n\n Manager.goByUrl = function(url, transitionOptions) {\n var params, parsedUrl, path, state, urlParser;\n urlParser = document.createElement('a');\n urlParser.href = url;\n path = urlParser.pathname.replace(/^\\//, '') + urlParser.search;\n parsedUrl = null;\n _.find(managers.slice().reverse(), function(manager) {\n return parsedUrl = manager._parseStateFromUrl(path);\n });\n if (parsedUrl) {\n state = parsedUrl.state;\n params = parsedUrl.params;\n } else {\n state = '*';\n params = [path];\n }\n return managerQueue.trigger(state, params, transitionOptions);\n };\n\n Manager.extend = Backbone.Model.extend;\n\n Manager.config = {};\n\n return Manager;\n\n })();\n Backbone.Manager = Manager;\n _watchForStateChange = function(event) {\n var $target, params, state, stateAttr, stateInfo, transitionOptions;\n if (!event.isDefaultPrevented()) {\n $target = $(event.currentTarget);\n stateAttr = $target.attr('data-bb-state');\n transitionOptions = $target.attr('data-bb-options') || '{}';\n event.preventDefault();\n if (stateAttr === '') {\n Manager.goByUrl(event.currentTarget.href, JSON.parse(transitionOptions));\n } else {\n stateInfo = stateAttr.split('(', 2);\n state = stateInfo[0];\n params = [];\n if (stateInfo.length > 1 && stateInfo[1].length > 2) {\n params = JSON.parse(stateInfo[1].slice(0, stateInfo[1].indexOf(')')));\n }\n if (params instanceof Array) {\n params.push(null);\n }\n }\n managerQueue.trigger(state, params, JSON.parse(transitionOptions));\n }\n };\n $(window.document).on('click', 'a[data-bb-state]', function(event) {\n return _watchForStateChange(event);\n });\n;\n})(Backbone, _, $, window);\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["backbone.manager.js"],"names":["Backbone","_","$","window","Manager","_watchForStateChange","cachedOptionalMatcher","cachedParamMatcher","currentManager","managerQueue","managers","onloadUrl","extend","Events","location","href","router","options","push","this","_parseStates","_parseEvents","initialize","prototype","states","events","each","keys","_this","stateKey","matches","stateOptions","templateUrl","transitionMethod","Error","url","isRegExp","_urlParams","results","exec","replace","_urlAsTemplate","template","interpolate","_urlAsRegex","_routeToRegExp","route","_routeCallbackChooser","Array","apply","arguments","listenTo","params","transitionOptions","_handleTransitionCallback","historyHasUpdated","_getWindowHref","_handleLoadCallback","error","loadMethod","trigger","_error","data","paramsObject","queryParams","navigate","object","last","indexOf","_getWindowPath","map","initial","String","Object","_extractParameters","eventName","on","_parseStateFromUrl","find","reverse","ref","test","state","pathname","search","go","goByUrl","parsedUrl","path","urlParser","document","createElement","slice","manager","Model","config","event","$target","stateAttr","stateInfo","isDefaultPrevented","currentTarget","attr","preventDefault","JSON","parse","split","length"],"mappings":"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","file":"backbone.manager-min.js","sourcesContent":["/**\n * Backbone.Manager - State-Based Routing/Control Manager for Backbone\n * @version v2.0.4\n * @link https://github.com/novu/backbone.manager\n * @author Johnathon Sanders\n * @license MIT\n */\n(function(Backbone, _, $, window) {\n var Manager, _watchForStateChange, cachedOptionalMatcher, cachedParamMatcher, currentManager, managerQueue, managers, onloadUrl;\n managers = [];\n managerQueue = _.extend({}, Backbone.Events);\n onloadUrl = window.location.href;\n cachedParamMatcher = /[:*]([^(:?)\\/]+)/g;\n cachedOptionalMatcher = /\\(.*\\)/g;\n currentManager = null;\n Manager = (function() {\n Manager.prototype.states = {};\n\n Manager.prototype.events = {};\n\n function Manager(router, options) {\n managers.push(this);\n this.router = router;\n _.extend(this, Backbone.Events);\n this._parseStates();\n this._parseEvents();\n this.initialize(options);\n return;\n }\n\n Manager.prototype.initialize = function() {};\n\n Manager.prototype._parseStates = function() {\n _.each(_.keys(this.states), (function(_this) {\n return function(stateKey) {\n var matches, stateOptions, templateUrl;\n stateOptions = _this.states[stateKey];\n if (!stateOptions.transitionMethod) {\n throw new Error(stateKey + ' needs transitionMethod definitions');\n }\n if (stateOptions.url) {\n if (_.isRegExp(stateOptions.url)) {\n throw new Error(stateKey + ' is not allowed to have a RegExp url');\n }\n stateOptions._urlParams = (function() {\n var results;\n results = [];\n while (matches = cachedParamMatcher.exec(stateOptions.url)) {\n results.push(matches[1]);\n }\n return results;\n })();\n templateUrl = stateOptions.url.replace(cachedOptionalMatcher, '');\n stateOptions._urlAsTemplate = _.template(templateUrl, null, {\n interpolate: cachedParamMatcher\n });\n stateOptions._urlAsRegex = _this.router._routeToRegExp(stateOptions.url);\n _this.router.route(stateOptions._urlAsRegex, stateKey, function() {\n _this._routeCallbackChooser(stateKey, stateOptions, Array.apply(null, arguments));\n });\n }\n return _this.listenTo(managerQueue, stateKey, function(params, transitionOptions) {\n _this._handleTransitionCallback(stateKey, stateOptions, params, transitionOptions);\n });\n };\n })(this));\n };\n\n Manager.prototype._routeCallbackChooser = function(stateKey, stateOptions, params) {\n var historyHasUpdated;\n if (onloadUrl && this._getWindowHref() === onloadUrl) {\n this._handleLoadCallback(stateKey, stateOptions, params);\n } else {\n this._handleTransitionCallback(stateKey, stateOptions, params, {}, historyHasUpdated = true);\n }\n onloadUrl = null;\n };\n\n Manager.prototype._handleLoadCallback = function(stateKey, stateOptions, params) {\n var error;\n currentManager = this;\n if (stateOptions.loadMethod) {\n this.trigger('loadStart');\n this.trigger('loadStart:' + stateKey, params);\n try {\n this[stateOptions.loadMethod].apply(this, params);\n this.trigger('loadSuccess');\n this.trigger('loadSuccess:' + stateKey, params);\n } catch (_error) {\n error = _error;\n this.trigger('loadError', error);\n this.trigger('loadError:' + stateKey, params, error);\n }\n }\n };\n\n Manager.prototype._handleTransitionCallback = function(stateKey, stateOptions, params, transitionOptions, historyHasUpdated) {\n var data, error, options, paramsObject, queryParams, url;\n if (transitionOptions == null) {\n transitionOptions = {};\n }\n if (historyHasUpdated == null) {\n historyHasUpdated = false;\n }\n if (transitionOptions.navigate == null) {\n transitionOptions.navigate = true;\n }\n if (currentManager && currentManager !== this) {\n currentManager.trigger('exit');\n }\n currentManager = this;\n this.trigger('transitionStart');\n this.trigger('transitionStart:' + stateKey);\n if (stateOptions.url) {\n if (params instanceof Array) {\n paramsObject = _.object(stateOptions._urlParams, params);\n queryParams = _.last(params);\n url = stateOptions._urlAsTemplate(paramsObject);\n if (queryParams) {\n if (url.indexOf('?') > -1) {\n url += '&';\n } else {\n url += '?';\n }\n url += queryParams;\n }\n if (!historyHasUpdated && transitionOptions.navigate) {\n if (this._getWindowPath() !== url) {\n this.router.navigate(url);\n this.trigger('navigate');\n }\n }\n data = _.map(_.initial(params), String);\n data.push(queryParams);\n } else if (params instanceof Object) {\n url = stateOptions._urlAsTemplate(params);\n if (!historyHasUpdated && transitionOptions.navigate) {\n if (this._getWindowPath() !== url) {\n this.router.navigate(url);\n this.trigger('navigate');\n }\n }\n data = this.router._extractParameters(stateOptions._urlAsRegex, url);\n } else {\n throw new Error('Params are only supported as an object or array if state.url is defined');\n }\n options = {\n url: url\n };\n data.push(options);\n } else {\n data = params;\n }\n try {\n this[stateOptions.transitionMethod].apply(this, data);\n this.trigger('transitionSuccess');\n this.trigger('transitionSuccess:' + stateKey);\n } catch (_error) {\n error = _error;\n this.trigger('transitionError', error);\n this.trigger('transitionError:' + stateKey, error);\n }\n };\n\n Manager.prototype._parseEvents = function() {\n _.each(_.keys(this.events), (function(_this) {\n return function(eventName) {\n _this.on(eventName, _this[_this.events[eventName]]);\n };\n })(this));\n };\n\n Manager.prototype._parseStateFromUrl = function(url) {\n var data, stateKey;\n stateKey = _.find(_.keys(this.states).reverse(), (function(_this) {\n return function(stateKey) {\n var ref;\n return (ref = _this.states[stateKey]._urlAsRegex) != null ? ref.test(url) : void 0;\n };\n })(this));\n if (stateKey) {\n data = this.router._extractParameters(this.states[stateKey]._urlAsRegex, url);\n return {\n state: stateKey,\n params: data\n };\n }\n };\n\n Manager.prototype._getWindowHref = function() {\n return window != null ? window.location.href : void 0;\n };\n\n Manager.prototype._getWindowPath = function() {\n return (window != null ? window.location.pathname.replace(/^\\//, '') : void 0) + (window != null ? window.location.search : void 0);\n };\n\n Manager.go = function(state, params, transitionOptions) {\n if (!params) {\n params = [];\n }\n if (params instanceof Array) {\n params.push(null);\n }\n return managerQueue.trigger(state, params, transitionOptions);\n };\n\n Manager.goByUrl = function(url, transitionOptions) {\n var params, parsedUrl, path, state, urlParser;\n urlParser = document.createElement('a');\n urlParser.href = url;\n path = urlParser.pathname.replace(/^\\//, '') + urlParser.search;\n parsedUrl = null;\n _.find(managers.slice().reverse(), function(manager) {\n return parsedUrl = manager._parseStateFromUrl(path);\n });\n if (parsedUrl) {\n state = parsedUrl.state;\n params = parsedUrl.params;\n } else {\n state = '*';\n params = [path];\n }\n return managerQueue.trigger(state, params, transitionOptions);\n };\n\n Manager.extend = Backbone.Model.extend;\n\n Manager.config = {};\n\n return Manager;\n\n })();\n Backbone.Manager = Manager;\n _watchForStateChange = function(event) {\n var $target, params, state, stateAttr, stateInfo, transitionOptions;\n if (!event.isDefaultPrevented()) {\n $target = $(event.currentTarget);\n stateAttr = $target.attr('data-bb-state');\n transitionOptions = $target.attr('data-bb-options') || '{}';\n event.preventDefault();\n if (stateAttr === '') {\n Manager.goByUrl(event.currentTarget.href, JSON.parse(transitionOptions));\n } else {\n stateInfo = stateAttr.split('(', 2);\n state = stateInfo[0];\n params = [];\n if (stateInfo.length > 1 && stateInfo[1].length > 2) {\n params = JSON.parse(stateInfo[1].slice(0, stateInfo[1].indexOf(')')));\n }\n if (params instanceof Array) {\n params.push(null);\n }\n }\n managerQueue.trigger(state, params, JSON.parse(transitionOptions));\n }\n };\n $(window.document).on('click', 'a[data-bb-state]', function(event) {\n return _watchForStateChange(event);\n });\n;\n})(Backbone, _, $, window);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/release/backbone.manager.js b/release/backbone.manager.js index 6eb165a..dd2388d 100644 --- a/release/backbone.manager.js +++ b/release/backbone.manager.js @@ -1,6 +1,6 @@ /** * Backbone.Manager - State-Based Routing/Control Manager for Backbone - * @version v2.0.3 + * @version v2.0.4 * @link https://github.com/novu/backbone.manager * @author Johnathon Sanders * @license MIT @@ -125,14 +125,20 @@ url += queryParams; } if (!historyHasUpdated && transitionOptions.navigate) { - this.router.navigate(url); + if (this._getWindowPath() !== url) { + this.router.navigate(url); + this.trigger('navigate'); + } } data = _.map(_.initial(params), String); data.push(queryParams); } else if (params instanceof Object) { url = stateOptions._urlAsTemplate(params); if (!historyHasUpdated && transitionOptions.navigate) { - this.router.navigate(url); + if (this._getWindowPath() !== url) { + this.router.navigate(url); + this.trigger('navigate'); + } } data = this.router._extractParameters(stateOptions._urlAsRegex, url); } else { @@ -185,6 +191,10 @@ return window != null ? window.location.href : void 0; }; + Manager.prototype._getWindowPath = function() { + return (window != null ? window.location.pathname.replace(/^\//, '') : void 0) + (window != null ? window.location.search : void 0); + }; + Manager.go = function(state, params, transitionOptions) { if (!params) { params = [];