define([ 'dojo/_base/declare', 'dojo/_base/Deferred', 'dojo/_base/lang', 'dojo/hash', 'dojo/topic', 'dojo/io-query', './content', './util', ],function(declare,Deferred,lang,hash,topic,uriQuery,content,util){ return new (function() { var HRI = declare(null,{ constructor: function() { this._path = this._fixPath('/'); this._args = {}; if ( arguments.length == 1 ) { this.hash(arguments[0]); } else if ( arguments.length == 2 ) { this.path(arguments[0]); this.args(arguments[1]); } }, path: function(path) { if ( path ) this._path = this._fixPath(path); return this._path; }, args: function(args) { if ( args && lang.isObject(args) ) this._args = args; return this._args; }, hash: function(hash) { if ( hash && lang.isString(hash) ) { var parts = hash.split('!'); if ( parts[1] ) this._path = this._fixPath(parts[1]); if ( parts[2] ) this._args = uriQuery.queryToObject(parts[2]); } return '!'+this._path+'!'+uriQuery.objectToQuery(this._args); }, _fixPath: function(path) { if ( !lang.isString(path) || util.isEmptyString(path) ) { path = "/"; } if ( path[0] != '/' ) { path = '/'+path; } if ( path[path.length-1] == '/' ) { path = path + "index"; } return path; } }); var currentHri = null; var currentPage = null; function _goTo(hri,replace) { var dfd = new Deferred(); // if already there, return if ( currentHri && currentHri.hash() === hri.hash() ) { dfd.resolve(); return dfd.promise; } // check if we can leave current page if ( currentPage ) { if ( currentPage.onLeave() === false ) { // restore hash if changed by hand or back button hash(currentHri.hash()); dfd.reject(); return dfd.promise; } currentPage = null; } // update hash currentHri = hri; hash(hri.hash(),replace); content._loadPage(hri.path(),hri.args()) .then(function(page){ currentPage = page; dfd.resolve(); }); return dfd.promise; } content.initialImpl = function(path,args) { if ( currentHri ) { var dfd = new Deferred(); dfd.resolve(); return dfd.promise; } if ( hash() ) { var hri = new HRI(hash()); return _goTo(hri, true); } else { return _goTo(new HRI(path,args)); } }; content.goToImpl = function(path,args) { return _goTo(new HRI(path,args)); }; topic.subscribe('/dojo/hashchange', function(){ _goTo(new HRI(hash())); }); })(); });