////////////////////////////////////////////////////////////////////////// // // // This is a generated file. You can view the original // // source in your browser if your browser supports source maps. // // Source maps are supported by all recent versions of Chrome, Safari, // // and Firefox, and by Internet Explorer 11. // // // ////////////////////////////////////////////////////////////////////////// (function () { /* Imports */ var Meteor = Package.meteor.Meteor; var global = Package.meteor.global; var meteorEnv = Package.meteor.meteorEnv; var _ = Package.underscore._; var Tracker = Package.tracker.Tracker; var Deps = Package.tracker.Deps; var $ = Package.jquery.$; var jQuery = Package.jquery.jQuery; var Iron = Package['iron:core'].Iron; var Url = Package['clinical:router-url'].Url; /* Package-scope variables */ var urlToHashStyle, urlFromHashStyle, fixHashPath, State, Location; (function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/clinical_router-location/packages/clinical_router-location.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // (function () { ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/clinical:router-location/lib/utils.js // // // ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Url = Iron.Url; // 1 var HASH_PARAM_NAME='__hash__'; // 2 // 3 /** // 4 * Given: // 5 * http://host:port/some/pathname/?query=string#bar // 6 * // 7 * Return: // 8 * http://host:port#!some/pathname/?query=string&__hash__=bar // 9 */ // 10 urlToHashStyle = function (url) { // 11 var parts = Url.parse(url); // 12 var hash = parts.hash && parts.hash.replace('#', ''); // 13 var search = parts.search; // 14 var pathname = parts.pathname; // 15 var root = parts.rootUrl; // 16 // 17 // do we have another hash value that isn't a path? // 18 if (hash && hash.charAt(0) !== '!') { // 19 var hashQueryString = HASH_PARAM_NAME + '=' + hash; // 20 search = search ? (search + '&') : '?'; // 21 search += hashQueryString; // 22 hash = ''; // 23 } // 24 // 25 // if we don't already have a path on the hash create one // 26 if (! hash && pathname) { // 27 hash = '#!' + pathname.substring(1); // 28 } else if (hash) { // 29 hash = '#' + hash; // 30 } // 31 // 32 return [ // 33 root, // 34 hash, // 35 search // 36 ].join(''); // 37 }; // 38 // 39 /** // 40 * Given a url that uses the hash style (see above), return a new url that uses // 41 * the hash path as a normal pathname. // 42 * // 43 * Given: // 44 * http://host:port#!some/pathname/?query=string&__hash__=bar // 45 * // 46 * Return: // 47 * http://host:port/some/pathname/?query=string#bar // 48 */ // 49 urlFromHashStyle = function (url) { // 50 var parts = Url.parse(url); // 51 var pathname = parts.hash && parts.hash.replace('#!', '/'); // 52 var search = parts.search; // 53 var root = parts.rootUrl; // 54 var hash; // 55 // 56 // see if there's a __hash__=value in the query string in which case put it // 57 // back in the normal hash position and delete it from the search string. // 58 if (_.has(parts.queryObject, HASH_PARAM_NAME)) { // 59 hash = '#' + parts.queryObject[HASH_PARAM_NAME]; // 60 delete parts.queryObject[HASH_PARAM_NAME]; // 61 } else { // 62 hash = ''; // 63 } // 64 // 65 return [ // 66 root, // 67 pathname, // 68 Url.toQueryString(parts.queryObject), // 69 hash // 70 ].join(''); // 71 }; // 72 // 73 /** // 74 * Fix up a pathname intended for use with a hash path by moving any hash // 75 * fragments into the query string. // 76 */ // 77 fixHashPath = function (pathname) { // 78 var parts = Url.parse(pathname); // 79 var query = parts.queryObject; // 80 // 81 // if there's a hash in the path move that to the query string // 82 if (parts.hash) { // 83 query[HASH_PARAM_NAME] = parts.hash.replace('#', '') // 84 } // 85 // 86 return [ // 87 '!', // 88 parts.pathname.substring(1), // 89 Url.toQueryString(query) // 90 ].join(''); // 91 }; // 92 // 93 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); (function () { ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/clinical:router-location/lib/state.js // // // ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Url = Iron.Url; // 1 // 2 State = function (url, options) { // 3 _.extend(this, Url.parse(url), {options: options || {}}); // 4 }; // 5 // 6 // XXX: should this compare options (e.g. history.state?) // 7 State.prototype.equals = function (other) { // 8 if (!other) // 9 return false; // 10 // 11 if (!(other instanceof State)) // 12 return false; // 13 // 14 if (other.pathname == this.pathname && // 15 other.search == this.search && // 16 other.hash == this.hash && // 17 other.options.historyState === this.options.historyState) // 18 return true; // 19 // 20 return false; // 21 }; // 22 // 23 State.prototype.isCancelled = function () { // 24 return !!this._isCancelled; // 25 }; // 26 // 27 State.prototype.cancelUrlChange = function () { // 28 this._isCancelled = true; // 29 }; // 30 // 31 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); (function () { ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/clinical:router-location/lib/location.js // // // ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // /*****************************************************************************/ // 1 /* Imports */ // 2 /*****************************************************************************/ // 3 var Url = Iron.Url; // 4 // 5 /*****************************************************************************/ // 6 /* Private */ // 7 /*****************************************************************************/ // 8 var current = null; // 9 var dep = new Deps.Dependency; // 10 var handlers = {go: [], popState: []}; // 11 // 12 var isIE9 = function () { // 13 return /MSIE 9/.test(navigator.appVersion); // 14 }; // 15 // 16 var isIE8 = function () { // 17 return /MSIE 8/.test(navigator.appVersion); // 18 }; // 19 // 20 var usingAppcache = function () { // 21 return !! Package.appcache; // 22 }; // 23 // 24 var replaceStateUndefined = function() { // 25 return (typeof history === "undefined") || (typeof history.pushState !== "function"); // 26 }; // 27 // 28 var shouldUseHashPaths = function () { // 29 return Location.options.useHashPaths || isIE8() || isIE9() || usingAppcache() || replaceStateUndefined(); // 30 }; // 31 // 32 var isUsingHashPaths = function () { // 33 return !!Location.options.useHashPaths; // 34 }; // 35 // 36 var runHandlers = function (name, state) { // 37 _.each(handlers[name], function (cb) { // 38 cb.call(state); // 39 }); // 40 }; // 41 // 42 var set = function (state) { // 43 if (!(state instanceof State)) { // 44 throw new Error("Expected a State instance"); // 45 } // 46 // 47 if (!state.equals(current)) { // 48 current = state; // 49 dep.changed(); // 50 // 51 // return true to indicate state was set to a new value. // 52 return true; // 53 } // 54 // 55 // state not set // 56 return false; // 57 }; // 58 // 59 var setStateFromEventHandler = function () { // 60 var href = location.href; // 61 var state; // 62 // 63 if (isUsingHashPaths()) { // 64 state = new State(urlFromHashStyle(href)); // 65 } else { // 66 state = new State(href, {historyState: history.state}); // 67 } // 68 // 69 runHandlers('popState', state); // 70 set(state); // 71 }; // 72 // 73 var fireOnClick = function (e) { // 74 var handler = onClickHandler; // 75 handler && handler(e); // 76 }; // 77 // 78 /** // 79 * Go to a url. // 80 */ // 81 var go = function (url, options) { // 82 options = options || {}; // 83 // 84 var state = new State(url, options); // 85 // 86 runHandlers('go', state); // 87 // 88 if (set(state)) { // 89 Deps.afterFlush(function () { // 90 // if after we've flushed if nobody has cancelled the state then change // 91 // the url. // 92 if (!state.isCancelled()) { // 93 if (isUsingHashPaths()) { // 94 location.hash = fixHashPath(url); // 95 } else { // 96 if (options.replaceState === true) { // 97 history.replaceState(options.historyState, null, url); // 98 } else { // 99 history.pushState(options.historyState, null, url); // 100 } // 101 } // 102 } // 103 }); // 104 } // 105 }; // 106 // 107 var onClickHandler = function (e) { // 108 try { // 109 var el = e.currentTarget; // 110 var href = el.href; // 111 var path = el.pathname + el.search + el.hash; // 112 // 113 // ie9 omits the leading slash in pathname - so patch up if it's missing // 114 path = path.replace(/(^\/?)/, "/"); // 115 // 116 // haven't been cancelled already // 117 if (e.isDefaultPrevented()) { // 118 e.preventDefault(); // 119 return; // 120 } // 121 // 122 // with no meta key pressed // 123 if (e.metaKey || e.ctrlKey || e.shiftKey) { // 124 return; // 125 } // 126 // 127 // aren't targeting a new window // 128 if (el.target) { // 129 return; // 130 } // 131 // 132 // aren't external to the app // 133 if (!Url.isSameOrigin(href, location.href)) { // 134 return; // 135 } // 136 // 137 // note that we _do_ handle links which point to the current URL // 138 // and links which only change the hash. // 139 e.preventDefault(); // 140 // 141 // manage setting the new state and maybe pushing onto the pushState stack // 142 go(path); // 143 } catch (err) { // 144 // make sure we can see any errors that are thrown before going to the // 145 // server. // 146 e.preventDefault(); // 147 throw err; // 148 } // 149 }; // 150 // 151 /*****************************************************************************/ // 152 /* Location API */ // 153 /*****************************************************************************/ // 154 // 155 /** // 156 * Main Location object. Reactively respond to url changes. Normalized urls // 157 * between hash style (ie8/9) and normal style using pushState. // 158 */ // 159 Location = {}; // 160 // 161 /** // 162 * Default options. // 163 */ // 164 Location.options = { // 165 linkSelector: 'a[href]', // 166 useHashPaths: false // 167 }; // 168 // 169 /** // 170 * Set options on the Location object. // 171 */ // 172 Location.configure = function (options) { // 173 _.extend(this.options, options || {}); // 174 }; // 175 // 176 /** // 177 * Reactively get the current state. // 178 */ // 179 Location.get = function () { // 180 dep.depend(); // 181 return current; // 182 }; // 183 // 184 /** // 185 * Set the initial state and start listening for url events. // 186 */ // 187 Location.start = function () { // 188 if (this._isStarted) { // 189 return; // 190 } // 191 // 192 var parts = Url.parse(location.href); // 193 // 194 // if we're using the /#/items/5 style then start off at the root url but // 195 // store away the pathname, query and hash into the hash fragment so when the // 196 // client gets the response we can render the correct page. // 197 if (shouldUseHashPaths()) { // 198 // if we have any pathname like /items/5 take a trip to the server to get us // 199 // back a root url. // 200 if (parts.pathname.length > 1) { // 201 var url = urlToHashStyle(location.href); // 202 window.location = url; // 203 } // 204 // 205 // ok good to go // 206 this.configure({useHashPaths: true}); // 207 } // 208 // set initial state // 209 var href = location.href; // 210 // 211 if (isUsingHashPaths()) { // 212 var state = new State(urlFromHashStyle(href)); // 213 set(state); // 214 } else { // 215 // if we started at a URL in the /#!items/5 style then we have picked up a // 216 // URL from an non-HTML5 user. Let's redirect to /items/5 // 217 if (parts.hash.replace('#', '')[0] === '!') { // 218 var href = urlFromHashStyle(href); // 219 } // 220 // 221 // store the fact that this is the first route we hit. // 222 // this serves two purposes // 223 // 1. We can tell when we've reached an unhandled route and need to show a // 224 // 404 (rather than bailing out to let the server handle it) // 225 // 2. Users can look at the state to tell if the history.back() will stay // 226 // inside the app (this is important for mobile apps). // 227 var historyState = {initial: true}; // 228 history.replaceState(historyState, null, href); // 229 var state = new State(href, {historyState: historyState}); // 230 set(state); // 231 } // 232 // 233 // bind the event handlers // 234 $(window).on('popstate.iron-location', setStateFromEventHandler); // 235 $(window).on('hashchange.iron-location', setStateFromEventHandler); // 236 // 237 // make sure we have a document before binding the click handler // 238 Meteor.startup(function () { // 239 $(document).on('click.iron-location', Location.options.linkSelector, fireOnClick); // 240 }); // 241 // 242 this._isStarted = true; // 243 }; // 244 // 245 /** // 246 * Stop the Location from listening for url changes. // 247 */ // 248 Location.stop = function () { // 249 if (!this._isStarted) { // 250 return; // 251 } // 252 // 253 $(window).on('popstate.iron-location'); // 254 $(window).on('hashchange.iron-location'); // 255 $(document).off('click.iron-location'); // 256 // 257 this._isStarted = false; // 258 }; // 259 // 260 /** // 261 * Assign a different click handler. // 262 */ // 263 Location.onClick = function (fn) { // 264 onClickHandler = fn; // 265 }; // 266 // 267 /** // 268 * Go to a new url. // 269 */ // 270 Location.go = function (url, options) { // 271 return go(url, options); // 272 }; // 273 // 274 /** // 275 * Run the supplied callback whenever we "go" to a new location. // 276 * // 277 * Argument: cb - function, called with no arguments, // 278 * `this` is the state that's being set, _may_ be modified. // 279 */ // 280 Location.onGo = function (cb) { // 281 handlers.go.push(cb); // 282 }; // 283 // 284 /** // 285 * Run the supplied callback whenever we "popState" to an old location. // 286 * // 287 * Argument: cb - function, called with no arguments, // 288 * `this` is the state that's being set, _may_ be modified. // 289 */ // 290 Location.onPopState = function (cb) { // 291 handlers.popState.push(cb); // 292 }; // 293 // 294 /** // 295 * Automatically start Iron.Location // 296 */ // 297 Location.start(); // 298 // 299 /*****************************************************************************/ // 300 /* Namespacing */ // 301 /*****************************************************************************/ // 302 Iron.Location = Location; // 303 // 304 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); /* Exports */ Package._define("clinical:router-location", { urlToHashStyle: urlToHashStyle, urlFromHashStyle: urlFromHashStyle }); })();