522 lines
52 KiB
JavaScript
522 lines
52 KiB
JavaScript
//////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// 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
|
|
});
|
|
|
|
})();
|