dist/ember.prod.js in ember-source-2.8.0.beta.2 vs dist/ember.prod.js in ember-source-2.8.0
- old
+ new
@@ -4,11 +4,11 @@
* @copyright Copyright 2011-2016 Tilde Inc. and contributors
* Portions Copyright 2006-2011 Strobe Inc.
* Portions Copyright 2008-2011 Apple Inc. All rights reserved.
* @license Licensed under MIT license
* See https://raw.github.com/emberjs/ember.js/master/LICENSE
- * @version 2.8.0-beta.2
+ * @version 2.8.0
*/
var enifed, requireModule, require, Ember;
var mainContext = this;
@@ -4015,22 +4015,13 @@
*/
setupRegistry: function (registry) {
var options = arguments.length <= 1 || arguments[1] === undefined ? new BootOptions() : arguments[1];
registry.register('-environment:main', options.toEnvironment(), { instantiate: false });
- registry.injection('view', '_environment', '-environment:main');
- registry.injection('route', '_environment', '-environment:main');
-
registry.register('service:-document', options.document, { instantiate: false });
- if (options.isInteractive) {
- registry.injection('view', 'renderer', 'renderer:-dom');
- registry.injection('component', 'renderer', 'renderer:-dom');
- } else {
- registry.injection('view', 'renderer', 'renderer:-inert');
- registry.injection('component', 'renderer', 'renderer:-inert');
- }
+ this._super(registry, options);
}
});
/**
A list of boot-time configuration options for customizing the behavior of
@@ -4200,10 +4191,11 @@
BootOptions.prototype.toEnvironment = function () {
var env = _emberMetalAssign.default({}, _emberEnvironment.environment);
// For compatibility with existing code
env.hasDOM = this.isBrowser;
+ env.isInteractive = this.isInteractive;
env.options = this;
return env;
};
Object.defineProperty(ApplicationInstance.prototype, 'container', {
@@ -4227,11 +4219,11 @@
}
});
exports.default = ApplicationInstance;
});
-enifed('ember-application/system/application', ['exports', 'ember-environment', 'ember-metal/debug', 'ember-metal/libraries', 'ember-metal/testing', 'ember-metal/property_get', 'ember-runtime/system/namespace', 'ember-runtime/system/lazy_load', 'ember-metal/run_loop', 'ember-views/system/event_dispatcher', 'ember-views/system/jquery', 'ember-routing/system/route', 'ember-routing/system/router', 'ember-routing/location/hash_location', 'ember-routing/location/history_location', 'ember-routing/location/auto_location', 'ember-routing/location/none_location', 'ember-routing/system/cache', 'ember-application/system/application-instance', 'ember-runtime/mixins/registry_proxy', 'container/registry', 'ember-runtime/ext/rsvp', 'ember-application/system/engine', 'require'], function (exports, _emberEnvironment, _emberMetalDebug, _emberMetalLibraries, _emberMetalTesting, _emberMetalProperty_get, _emberRuntimeSystemNamespace, _emberRuntimeSystemLazy_load, _emberMetalRun_loop, _emberViewsSystemEvent_dispatcher, _emberViewsSystemJquery, _emberRoutingSystemRoute, _emberRoutingSystemRouter, _emberRoutingLocationHash_location, _emberRoutingLocationHistory_location, _emberRoutingLocationAuto_location, _emberRoutingLocationNone_location, _emberRoutingSystemCache, _emberApplicationSystemApplicationInstance, _emberRuntimeMixinsRegistry_proxy, _containerRegistry, _emberRuntimeExtRsvp, _emberApplicationSystemEngine, _require) {
+enifed('ember-application/system/application', ['exports', 'ember-environment', 'ember-metal/debug', 'ember-metal/dictionary', 'ember-metal/libraries', 'ember-metal/testing', 'ember-metal/property_get', 'ember-runtime/system/namespace', 'ember-runtime/system/lazy_load', 'ember-metal/run_loop', 'ember-views/system/event_dispatcher', 'ember-views/system/jquery', 'ember-routing/system/route', 'ember-routing/system/router', 'ember-routing/location/hash_location', 'ember-routing/location/history_location', 'ember-routing/location/auto_location', 'ember-routing/location/none_location', 'ember-routing/system/cache', 'ember-application/system/application-instance', 'ember-runtime/mixins/registry_proxy', 'container/registry', 'ember-runtime/ext/rsvp', 'ember-application/system/engine', 'require'], function (exports, _emberEnvironment, _emberMetalDebug, _emberMetalDictionary, _emberMetalLibraries, _emberMetalTesting, _emberMetalProperty_get, _emberRuntimeSystemNamespace, _emberRuntimeSystemLazy_load, _emberMetalRun_loop, _emberViewsSystemEvent_dispatcher, _emberViewsSystemJquery, _emberRoutingSystemRoute, _emberRoutingSystemRouter, _emberRoutingLocationHash_location, _emberRoutingLocationHistory_location, _emberRoutingLocationAuto_location, _emberRoutingLocationNone_location, _emberRoutingSystemCache, _emberApplicationSystemApplicationInstance, _emberRuntimeMixinsRegistry_proxy, _containerRegistry, _emberRuntimeExtRsvp, _emberApplicationSystemEngine, _require) {
/**
@module ember
@submodule ember-application
*/
'use strict';
@@ -5133,11 +5125,11 @@
}
});
function commonSetupRegistry(registry) {
registry.register('-view-registry:main', { create: function () {
- return {};
+ return _emberMetalDictionary.default(null);
} });
registry.register('route:basic', _emberRoutingSystemRoute.default);
registry.register('event_dispatcher:main', _emberViewsSystemEvent_dispatcher.default);
@@ -5244,15 +5236,13 @@
@private
@method boot
@param options {Object}
@return {Promise<Ember.EngineInstance,Error>}
*/
- boot: function () {
+ boot: function (options) {
var _this = this;
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
if (this._bootPromise) {
return this._bootPromise;
}
this._bootPromise = new _emberRuntimeExtRsvp.default.Promise(function (resolve) {
@@ -5281,17 +5271,25 @@
if (true) {
this.cloneParentDependencies();
}
+ this.setupRegistry(options);
+
this.base.runInstanceInitializers(this);
this._booted = true;
return this;
},
+ setupRegistry: function () {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? this.__container__.lookup('-environment:main') : arguments[0];
+
+ this.constructor.setupRegistry(this.__registry__, options);
+ },
+
/**
Unregister a factory.
Overrides `RegistryProxy#unregister` in order to clear any cached instances
of the unregistered factory.
@public
@@ -5310,10 +5308,36 @@
this._super.apply(this, arguments);
_emberMetalRun_loop.default(this.__container__, 'destroy');
}
});
+ EngineInstance.reopenClass({
+ /**
+ @private
+ @method setupRegistry
+ @param {Registry} registry
+ @param {BootOptions} options
+ */
+ setupRegistry: function (registry, options) {
+ // when no options/environment is present, do nothing
+ if (!options) {
+ return;
+ }
+
+ registry.injection('view', '_environment', '-environment:main');
+ registry.injection('route', '_environment', '-environment:main');
+
+ if (options.isInteractive) {
+ registry.injection('view', 'renderer', 'renderer:-dom');
+ registry.injection('component', 'renderer', 'renderer:-dom');
+ } else {
+ registry.injection('view', 'renderer', 'renderer:-inert');
+ registry.injection('component', 'renderer', 'renderer:-inert');
+ }
+ }
+ });
+
if (true) {
EngineInstance.reopen({
/**
Build a new `Ember.EngineInstance` that's a child of this instance.
Engines must be registered by name with their parent engine
@@ -5348,17 +5372,31 @@
cloneParentDependencies: function () {
var _this2 = this;
var parent = _emberApplicationSystemEngineParent.getEngineParent(this);
- ['route:basic', 'event_dispatcher:main', 'service:-routing'].forEach(function (key) {
+ var registrations = ['route:basic', 'event_dispatcher:main', 'service:-routing'];
+
+ if (false) {
+ registrations.push('service:-glimmer-environment');
+ }
+
+ registrations.forEach(function (key) {
return _this2.register(key, parent.resolveRegistration(key));
});
- ['router:main', _containerRegistry.privatize(_templateObject), '-view-registry:main'].forEach(function (key) {
+ var env = parent.lookup('-environment:main');
+ this.register('-environment:main', env, { instantiate: false });
+
+ var singletons = ['router:main', _containerRegistry.privatize(_templateObject), '-view-registry:main', 'renderer:-' + (env.isInteractive ? 'dom' : 'inert')];
+
+ singletons.forEach(function (key) {
return _this2.register(key, parent.lookup(key), { instantiate: false });
});
+
+ this.inject('view', '_environment', '-environment:main');
+ this.inject('route', '_environment', '-environment:main');
}
});
}
exports.default = EngineInstance;
@@ -8465,11 +8503,11 @@
var lastParam = params[params.length - 1];
if (lastParam && lastParam.isQueryParams) {
queryParams = params.pop();
} else {
- queryParams = {};
+ queryParams = { values: {} };
}
this.set('queryParams', queryParams);
// 4. Any remaining indices (excepting `targetRouteName` at 0) are `models`.
if (params.length > 1) {
@@ -9609,21 +9647,41 @@
}
return null;
}
});
-enifed("ember-htmlbars/hooks/cleanup-render-node", ["exports"], function (exports) {
+enifed('ember-htmlbars/hooks/cleanup-render-node', ['exports'], function (exports) {
/**
@module ember
@submodule ember-htmlbars
*/
- "use strict";
+ 'use strict';
exports.default = cleanupRenderNode;
function cleanupRenderNode(renderNode) {
+ var view = renderNode.emberView;
+ if (view) {
+ view.renderer.willDestroyElement(view);
+ view.ownerView._destroyingSubtreeForView.push(function (env) {
+ view._transitionTo('destroying'); // unregisters view
+ // prevents rerender and scheduling
+ view._renderNode = null;
+ renderNode.emberView = null;
+
+ view.renderer.didDestroyElement(view);
+
+ if (view.parentView && view.parentView === env.view) {
+ view.parentView.removeChild(view);
+ }
+ view.parentView = null;
+
+ view._transitionTo('preRender');
+ });
+ }
+
if (renderNode.cleanup) {
renderNode.cleanup();
}
}
});
@@ -9664,28 +9722,19 @@
}
// Determine if this is an initial render or a re-render.
if (state.manager) {
var sm = state.manager;
- var templateMeta = null;
- if (sm.block) {
- templateMeta = sm.block.template.meta;
- } else if (sm.scope && sm.scope._view && sm.scope._view.template) {
- templateMeta = sm.scope._view.template.meta;
- }
- env.meta.moduleName = templateMeta && templateMeta.moduleName || env.meta && env.meta.moduleName;
_emberHtmlbarsUtilsExtractPositionalParams.default(renderNode, sm.component.constructor, params, attrs, false);
state.manager.rerender(env, attrs, visitor);
return;
}
var parentView = env.view;
- var options = {};
+
var moduleName = env.meta && env.meta.moduleName;
- if (moduleName) {
- options.source = 'template:' + moduleName;
- }
+ var options = { source: moduleName && 'template:' + moduleName };
var _lookupComponent = _emberViewsUtilsLookupComponent.default(env.owner, tagName, options);
var component = _lookupComponent.component;
var layout = _lookupComponent.layout;
@@ -9949,29 +9998,35 @@
exports.default = destroyRenderNode;
function destroyRenderNode(renderNode) {
var view = renderNode.emberView;
if (view) {
- view.renderer.remove(view, true);
+ view.ownerView._destroyingSubtreeForView.push(function () {
+ view.destroy();
+ });
}
-
var streamUnsubscribers = renderNode.streamUnsubscribers;
if (streamUnsubscribers) {
for (var i = 0; i < streamUnsubscribers.length; i++) {
streamUnsubscribers[i]();
}
}
+ renderNode.streamUnsubscribers = null;
}
});
enifed("ember-htmlbars/hooks/did-cleanup-tree", ["exports"], function (exports) {
"use strict";
exports.default = didCleanupTree;
function didCleanupTree(env) {
// Once we have finsihed cleaning up the render node and sub-nodes, reset
// state tracking which view those render nodes belonged to.
+ var queue = env.view.ownerView._destroyingSubtreeForView;
+ for (var i = 0; i < queue.length; i++) {
+ queue[i](env);
+ }
env.view.ownerView._destroyingSubtreeForView = null;
}
});
enifed("ember-htmlbars/hooks/did-render-node", ["exports"], function (exports) {
"use strict";
@@ -10452,11 +10507,11 @@
// owner view, the root-most view in the graph (A in the example above). If
// we detect a view that is a direct child of that view, we remove it from
// the `childViews` array. Other parent/child view relationships are
// untouched. This view is then cleared once cleanup is complete in
// `didCleanupTree`.
- view.ownerView._destroyingSubtreeForView = view;
+ view.ownerView._destroyingSubtreeForView = [];
}
});
enifed('ember-htmlbars/index', ['exports', 'ember-metal/core', 'ember-htmlbars/helpers', 'ember-htmlbars/helpers/if_unless', 'ember-htmlbars/helpers/with', 'ember-htmlbars/helpers/loc', 'ember-htmlbars/helpers/log', 'ember-htmlbars/helpers/each', 'ember-htmlbars/helpers/each-in', 'ember-htmlbars/helpers/-normalize-class', 'ember-htmlbars/helpers/concat', 'ember-htmlbars/helpers/-join-classes', 'ember-htmlbars/helpers/-html-safe', 'ember-htmlbars/helpers/hash', 'ember-htmlbars/helpers/query-params', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/system/template'], function (exports, _emberMetalCore, _emberHtmlbarsHelpers, _emberHtmlbarsHelpersIf_unless, _emberHtmlbarsHelpersWith, _emberHtmlbarsHelpersLoc, _emberHtmlbarsHelpersLog, _emberHtmlbarsHelpersEach, _emberHtmlbarsHelpersEachIn, _emberHtmlbarsHelpersNormalizeClass, _emberHtmlbarsHelpersConcat, _emberHtmlbarsHelpersJoinClasses, _emberHtmlbarsHelpersHtmlSafe, _emberHtmlbarsHelpersHash, _emberHtmlbarsHelpersQueryParams, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsSystemTemplate) {
/**
Ember templates are executed by [HTMLBars](https://github.com/tildeio/htmlbars),
@@ -11520,15 +11575,11 @@
// Force the component hook to treat this as a first-time render,
// because normal components (`<foo-bar>`) cannot change at runtime,
// but the `{{component}}` helper can.
state.manager = null;
- for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- rest[_key - 1] = arguments[_key];
- }
-
- render.apply(undefined, [morph].concat(rest));
+ render.apply(undefined, arguments);
},
rerender: render
};
@@ -12408,16 +12459,16 @@
{{foo}}
{{partial "nav"}}
```
The above example template will render a template named
- "_nav", which has the same context as the parent template
- it's rendered into, so if the "_nav" template also referenced
+ "-nav", which has the same context as the parent template
+ it's rendered into, so if the "-nav" template also referenced
`{{foo}}`, it would print the same thing as the `{{foo}}`
in the above example.
- If a "_nav" template isn't found, the `partial` helper will
+ If a "-nav" template isn't found, the `partial` helper will
fall back to a template named "nav".
### Bound template names
The parameter supplied to `partial` can also be a path
@@ -13295,11 +13346,12 @@
ComponentNodeManager.prototype.rerender = function ComponentNodeManager_rerender(_env, attrs, visitor) {
var component = this.component;
return _emberHtmlbarsSystemInstrumentationSupport.instrument(component, function ComponentNodeManager_rerender_instrument() {
- var env = _env.childWithView(component);
+ var meta = this.block && this.block.template.meta;
+ var env = _env.childWithView(component, meta);
var snapshot = takeSnapshot(attrs);
if (component._renderNode.shouldReceiveAttrs) {
if (component._propagateAttrsToThis) {
@@ -13325,17 +13377,14 @@
return env;
}, this);
};
ComponentNodeManager.prototype.destroy = function ComponentNodeManager_destroy() {
- var component = this.component;
-
// Clear component's render node. Normally this gets cleared
// during view destruction, but in this case we're re-assigning the
// node to a different view and it will get cleaned up automatically.
- component._renderNode = null;
- component.destroy();
+ this.component.destroy();
};
function createComponent(_component, props, renderNode, env) {
var attrs = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];
@@ -13688,11 +13737,11 @@
}
};
Renderer.prototype.revalidateTopLevelView = function Renderer_revalidateTopLevelView(view) {
// This guard prevents revalidation on an already-destroyed view.
- if (view._renderNode.lastResult) {
+ if (view._renderNode && view._renderNode.lastResult) {
view._renderNode.lastResult.revalidate(view._env);
this.dispatchLifecycleHooks(view._env);
this.clearRenderedViews(view._env);
}
};
@@ -13860,37 +13909,17 @@
});
renderNode.ownerNode.emberView.scheduleRevalidate(renderNode, view.toString(), 'rerendering');
};
- Renderer.prototype.remove = function (view, shouldDestroy) {
- var renderNode = view._renderNode;
- view._renderNode = null;
- if (renderNode) {
- renderNode.emberView = null;
- this.willDestroyElement(view);
- view._transitionTo('destroying');
-
- view._renderNode = null;
- var _lastResult = renderNode.lastResult;
- if (_lastResult) {
- _htmlbarsRuntime.internal.clearMorph(renderNode, _lastResult.env, shouldDestroy !== false);
- }
- if (!shouldDestroy) {
- view._transitionTo('preRender');
- }
- this.didDestroyElement(view);
- }
-
- // toplevel view removed, remove insertion point
+ Renderer.prototype.remove = function (view) {
var lastResult = view.lastResult;
if (lastResult) {
+ // toplevel only.
view.lastResult = null;
lastResult.destroy();
- }
-
- if (shouldDestroy && !view.isDestroying) {
+ } else {
view.destroy();
}
};
Renderer.prototype.willDestroyElement = function (view) {
@@ -13934,16 +13963,20 @@
return new Renderer(dom, { destinedForDOM: true, _viewRegistry: _viewRegistry });
}
};
exports.InteractiveRenderer = InteractiveRenderer;
});
-enifed('ember-htmlbars/setup-registry', ['exports', 'ember-htmlbars/renderer', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/templates/top-level-view', 'ember-htmlbars/views/outlet', 'ember-views/views/view', 'ember-htmlbars/components/text_field', 'ember-htmlbars/components/text_area', 'ember-htmlbars/components/checkbox', 'ember-htmlbars/components/link-to', 'ember-views/mixins/template_support'], function (exports, _emberHtmlbarsRenderer, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsTemplatesTopLevelView, _emberHtmlbarsViewsOutlet, _emberViewsViewsView, _emberHtmlbarsComponentsText_field, _emberHtmlbarsComponentsText_area, _emberHtmlbarsComponentsCheckbox, _emberHtmlbarsComponentsLinkTo, _emberViewsMixinsTemplate_support) {
+enifed('ember-htmlbars/setup-registry', ['exports', 'container/registry', 'ember-htmlbars/renderer', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/templates/top-level-view', 'ember-htmlbars/views/outlet', 'ember-views/views/view', 'ember-htmlbars/component', 'ember-htmlbars/components/text_field', 'ember-htmlbars/components/text_area', 'ember-htmlbars/components/checkbox', 'ember-htmlbars/components/link-to', 'ember-views/mixins/template_support'], function (exports, _containerRegistry, _emberHtmlbarsRenderer, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsTemplatesTopLevelView, _emberHtmlbarsViewsOutlet, _emberViewsViewsView, _emberHtmlbarsComponent, _emberHtmlbarsComponentsText_field, _emberHtmlbarsComponentsText_area, _emberHtmlbarsComponentsCheckbox, _emberHtmlbarsComponentsLinkTo, _emberViewsMixinsTemplate_support) {
'use strict';
exports.setupApplicationRegistry = setupApplicationRegistry;
exports.setupEngineRegistry = setupEngineRegistry;
+ var _templateObject = _taggedTemplateLiteralLoose(['component:-default'], ['component:-default']);
+
+ function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
+
function setupApplicationRegistry(registry) {
registry.register('renderer:-dom', _emberHtmlbarsRenderer.InteractiveRenderer);
registry.register('renderer:-inert', _emberHtmlbarsRenderer.InertRenderer);
registry.register('service:-dom-helper', {
@@ -13963,10 +13996,12 @@
registry.register('component:-text-field', _emberHtmlbarsComponentsText_field.default);
registry.register('component:-text-area', _emberHtmlbarsComponentsText_area.default);
registry.register('component:-checkbox', _emberHtmlbarsComponentsCheckbox.default);
registry.register('component:link-to', _emberHtmlbarsComponentsLinkTo.default);
+
+ registry.register(_containerRegistry.privatize(_templateObject), _emberHtmlbarsComponent.default);
}
});
enifed('ember-htmlbars/streams/built-in-helper', ['exports', 'ember-htmlbars/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberHtmlbarsStreamsStream, _emberHtmlbarsStreamsUtils) {
'use strict';
@@ -15436,11 +15471,11 @@
normalized[attrName] = expression;
}
}
- normalized.role = _htmlbarsUtilTemplateUtils.buildStatement('get', 'ariaRole');
+ normalized.role = normalized.role || _htmlbarsUtilTemplateUtils.buildStatement('get', 'ariaRole');
if (attrs.tagName) {
component.tagName = attrs.tagName;
}
@@ -16303,11 +16338,18 @@
if (node.getState().manager) {
node.shouldReceiveAttrs = true;
}
- node.ownerNode.emberView.scheduleRevalidate(node, _emberHtmlbarsStreamsUtils.labelFor(stream));
+ // When the toplevelView (aka ownerView) is being torn
+ // down (generally in tests), `ownerNode.emberView` will be
+ // set to `null` (to prevent further work while tearing down)
+ // so we need to guard against that case here
+ var ownerView = node.ownerNode.emberView;
+ if (ownerView) {
+ ownerView.scheduleRevalidate(node, _emberHtmlbarsStreamsUtils.labelFor(stream));
+ }
}));
}
});
enifed('ember-htmlbars/utils/update-scope', ['exports', 'ember-htmlbars/streams/proxy-stream', 'ember-htmlbars/utils/subscribe'], function (exports, _emberHtmlbarsStreamsProxyStream, _emberHtmlbarsUtilsSubscribe) {
'use strict';
@@ -24961,13 +25003,13 @@
/**
@private
The user agent's global variable. In browsers, this will be `window`.
@since 1.11
@property global
- @default environment.global
+ @default window
*/
- global: _emberEnvironment.environment.global,
+ global: _emberEnvironment.environment.window,
/**
@private
The browser's `userAgent`. This is typically equivalent to
`navigator.userAgent`, but may be overridden for testing.
@@ -25971,11 +26013,11 @@
options = {};
}
if (this.enableLoadingSubstates) {
createRoute(this, name + '_loading', { resetNamespace: options.resetNamespace });
- createRoute(this, name + '_error', { path: dummyErrorRoute });
+ createRoute(this, name + '_error', { resetNamespace: options.resetNamespace, path: dummyErrorRoute });
}
if (callback) {
var fullName = getFullName(this, name, options.resetNamespace);
var dsl = new DSL(fullName, this.options);
@@ -26127,11 +26169,11 @@
}
if (this.enableLoadingSubstates) {
var dummyErrorRoute = '/_unused_dummy_error_path_route_' + name + '/:error';
createRoute(this, name + '_loading', { resetNamespace: options.resetNamespace });
- createRoute(this, name + '_error', { path: dummyErrorRoute });
+ createRoute(this, name + '_error', { resetNamespace: options.resetNamespace, path: dummyErrorRoute });
}
var localFullName = 'application';
var routeInfo = _emberMetalAssign.default({ localFullName: localFullName }, engineInfo);
@@ -26898,11 +26940,11 @@
/**
This action is called when one or more query params have changed. Bubbles.
@method queryParamsDidChange
@param changed {Object} Keys are names of query params that have changed.
- @param totalPresent {Number}
+ @param totalPresent {Object} Keys are names of query params that are currently set.
@param removed {Object} Keys are names of query params that have been removed.
@returns {boolean}
@private
*/
queryParamsDidChange: function (changed, totalPresent, removed) {
@@ -27906,11 +27948,12 @@
});
```
The string values provided for the template name, and controller
will eventually pass through to the resolver for lookup. See
Ember.Resolver for how these are mapped to JavaScript objects in your
- application.
+ application. The template to render into needs to be related to either the
+ current route or one of its ancestors.
Not all options need to be passed to `render`. Default values will be used
based on the name of the route specified in the router or the Route's
`controllerName` and `templateName` properties.
For example:
```javascript
@@ -28279,17 +28322,13 @@
/*
Returns an arguments array where the route name arg is prefixed based on the mount point
@private
*/
- function prefixRouteNameArg() {
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
+ function prefixRouteNameArg(route, args) {
var routeName = args[0];
- var owner = _containerOwner.getOwner(this);
+ var owner = _containerOwner.getOwner(route);
var prefix = owner.mountPoint;
// only alter the routeName if it's actually referencing a route.
if (owner.routable && typeof routeName === 'string') {
if (resemblesURL(routeName)) {
@@ -28313,23 +28352,23 @@
}
if (true) {
Route.reopen({
replaceWith: function () {
- for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- args[_key3] = arguments[_key3];
+ for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args[_key2] = arguments[_key2];
}
- return this._super.apply(this, prefixRouteNameArg.call.apply(prefixRouteNameArg, [this].concat(args)));
+ return this._super.apply(this, prefixRouteNameArg(this, args));
},
transitionTo: function () {
- for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
- args[_key4] = arguments[_key4];
+ for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
+ args[_key3] = arguments[_key3];
}
- return this._super.apply(this, prefixRouteNameArg.call.apply(prefixRouteNameArg, [this].concat(args)));
+ return this._super.apply(this, prefixRouteNameArg(this, args));
},
modelFor: function (_routeName) {
var routeName = undefined;
var owner = _containerOwner.getOwner(this);
@@ -28340,12 +28379,12 @@
routeName = getEngineRouteName(owner, _routeName);
} else {
routeName = _routeName;
}
- for (var _len5 = arguments.length, args = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
- args[_key5 - 1] = arguments[_key5];
+ for (var _len4 = arguments.length, args = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
+ args[_key4 - 1] = arguments[_key4];
}
return this._super.apply(this, [routeName].concat(args));
}
});
@@ -28477,10 +28516,14 @@
if (true) {
this._engineInstances = new _emberMetalEmpty_object.default();
this._engineInfoByRoute = new _emberMetalEmpty_object.default();
}
+
+ // avoid shaping issues with checks during `_setOutlets`
+ this.isDestroyed = false;
+ this.isDestroying = false;
},
/*
Resets all pending query paramter changes.
Called after transitioning to a new route
@@ -28600,10 +28643,17 @@
_emberConsole.default.log('Transitioned into \'' + EmberRouter._routePath(infos) + '\'');
}
},
_setOutlets: function () {
+ // This is triggered async during Ember.Route#willDestroy.
+ // If the router is also being destroyed we do not want to
+ // to create another this._toplevelView (and leak the renderer)
+ if (this.isDestroying || this.isDestroyed) {
+ return;
+ }
+
var handlerInfos = this.router.currentHandlerInfos;
var route = undefined;
var defaultParentState = undefined;
var liveRoutes = null;
@@ -28783,25 +28833,25 @@
this.router.reset();
}
},
willDestroy: function () {
- if (this._toplevelView) {
- this._toplevelView.destroy();
- this._toplevelView = null;
- }
- this._super.apply(this, arguments);
-
if (true) {
var instances = this._engineInstances;
for (var _name in instances) {
for (var id in instances[_name]) {
_emberMetalRun_loop.default(instances[_name][id], 'destroy');
}
}
}
+ if (this._toplevelView) {
+ this._toplevelView.destroy();
+ this._toplevelView = null;
+ }
+ this._super.apply(this, arguments);
+
this.reset();
},
_lookupActiveComponentNode: function (templateName) {
return this._activeViews[templateName];
@@ -29357,20 +29407,28 @@
if (originatingChildRouteName === 'application') {
originatingChildRouteName = _containerOwner.getOwner(originatingChildRoute).mountPoint;
}
}
- var targetChildRouteName = originatingChildRouteName.split('.').pop();
- var namespace = parentRoute.routeName === 'application' ? '' : parentRoute.routeName + '.';
-
- // First, try a named loading state, e.g. 'foo_loading'
- childName = namespace + targetChildRouteName + '_' + name;
+ // First, try a named loading state of the route, e.g. 'foo_loading'
+ childName = originatingChildRouteName + '_' + name;
if (routeHasBeenDefined(router, childName)) {
return childName;
}
- // Second, try general loading state, e.g. 'loading'
+ // Second, try general loading state of the parent, e.g. 'loading'
+ var originatingChildRouteParts = originatingChildRouteName.split('.').slice(0, -1);
+ var namespace = undefined;
+
+ // If there is a namespace on the route, then we use that, otherwise we use
+ // the parent route as the namespace.
+ if (originatingChildRouteParts.length) {
+ namespace = originatingChildRouteParts.join('.') + '.';
+ } else {
+ namespace = parentRoute.routeName === 'application' ? '' : parentRoute.routeName + '.';
+ }
+
childName = namespace + name;
if (routeHasBeenDefined(router, childName)) {
return childName;
}
}
@@ -29396,11 +29454,11 @@
for (var i = handlerInfos.length - 1; i >= 0; i--) {
handlerInfo = handlerInfos[i];
handler = handlerInfo.handler;
- if (handler.actions && handler.actions[name]) {
+ if (handler && handler.actions && handler.actions[name]) {
if (handler.actions[name].apply(handler, args) === true) {
eventWasHandled = true;
} else {
// Should only hit here if a non-bubbling error action is triggered on a route.
if (name === 'error') {
@@ -32921,21 +32979,21 @@
Returns `true` if the passed object can be found in the array.
This method is a Polyfill for ES 2016 Array.includes.
If no `startAt` argument is given, the starting location to
search is 0. If it's negative, searches from the index of
`this.length + startAt` by asc.
- ```javascript
+ ```javascript
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 2); // true
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, 3].includes(1, -1); // false
[1, 2, 3].includes(1, -4); // true
[1, 2, NaN].includes(NaN); // true
```
- @method includes
+ @method includes
@param {Object} obj The object to search for.
@param {Number} startAt optional starting location to search, default 0
@return {Boolean} `true` if object is found in the array.
@public
*/
@@ -33758,11 +33816,11 @@
*/
getEach: _emberMetalMixin.aliasMethod('mapBy'),
/**
Sets the value on the named property for each member. This is more
- efficient than using other methods defined on this helper. If the object
+ ergonomic than using other methods defined on this helper. If the object
implements Ember.Observable, the value will be changed to `set(),` otherwise
it will be set directly. `null` objects are skipped.
@method setEach
@param {String} key The key to set
@param {Object} value The object to set
@@ -34513,18 +34571,18 @@
if (true) {
Enumerable.reopen({
/**
Returns `true` if the passed object can be found in the enumerable.
- ```javascript
+ ```javascript
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, undefined].includes(undefined); // true
[1, 2, null].includes(null); // true
[1, 2, NaN].includes(NaN); // true
```
- @method includes
+ @method includes
@param {Object} obj The object to search for.
@return {Boolean} `true` if object is found in the enumerable.
@public
*/
includes: function (obj) {
@@ -36705,15 +36763,15 @@
var arr = this.toArray();
return arr.slice.apply(arr, arguments);
},
arrangedContentArrayWillChange: function (item, idx, removedCnt, addedCnt) {
- _emberRuntimeMixinsArray.arrayContentWillChange(this, idx, removedCnt, addedCnt);
+ this.arrayContentWillChange(idx, removedCnt, addedCnt);
},
arrangedContentArrayDidChange: function (item, idx, removedCnt, addedCnt) {
- _emberRuntimeMixinsArray.arrayContentDidChange(this, idx, removedCnt, addedCnt);
+ this.arrayContentDidChange(idx, removedCnt, addedCnt);
},
init: function () {
this._super.apply(this, arguments);
this._setupContent();
@@ -36850,23 +36908,11 @@
}
}
finishPartial(this, m);
- if (arguments.length === 0) {
- this.init();
- } else if (arguments.length === 1) {
- this.init(arguments[0]);
- } else {
- // v8 bug potentially incorrectly deopts this function: https://code.google.com/p/v8/issues/detail?id=3709
- // we may want to keep this around till this ages out on mobile
- var args = new Array(arguments.length);
- for (var x = 0; x < arguments.length; x++) {
- args[x] = arguments[x];
- }
- this.init.apply(this, args);
- }
+ this.init.apply(this, arguments);
this[POST_INIT]();
m.proto = proto;
_emberMetalChains.finishChains(this);
@@ -40249,11 +40295,11 @@
if (typeof this.didInitAttrs === 'function') {}
}
}, _Mixin$create[_emberRuntimeSystemCore_object.POST_INIT] = function () {
- this._super.apply(this, arguments);
+ this._super();
this.renderer.componentInitAttrs(this, this.attrs || {});
}, _Mixin$create.__defineNonEnumerable = function (property) {
this[property.name] = property.descriptor.value;
}, _Mixin$create.revalidate = function () {
@@ -40840,27 +40886,10 @@
}
return env.owner.lookup('template:' + underscored) || env.owner.lookup('template:' + name);
}
});
-enifed('ember-views/system/platform', ['exports', 'ember-environment'], function (exports, _emberEnvironment) {
- 'use strict';
-
- // IE 6/7 have bugs around setting names on inputs during creation.
- // From http://msdn.microsoft.com/en-us/library/ie/ms536389(v=vs.85).aspx:
- // "To include the NAME attribute at run time on objects created with the createElement method, use the eTag."
- var canSetNameOnInputs = _emberEnvironment.environment.hasDOM && (function () {
- var div = document.createElement('div');
- var el = document.createElement('input');
-
- el.setAttribute('name', 'foo');
- div.appendChild(el);
-
- return !!div.innerHTML.match('foo');
- })();
- exports.canSetNameOnInputs = canSetNameOnInputs;
-});
enifed('ember-views/system/utils', ['exports'], function (exports) {
/**
@module ember
@submodule ember-views
*/
@@ -40925,21 +40954,30 @@
function getViewBoundingClientRect(view) {
var range = getViewRange(view);
return range.getBoundingClientRect();
}
});
-enifed('ember-views/utils/lookup-component', ['exports'], function (exports) {
+enifed('ember-views/utils/lookup-component', ['exports', 'container/registry'], function (exports, _containerRegistry) {
'use strict';
exports.default = lookupComponent;
+
+ var _templateObject = _taggedTemplateLiteralLoose(['component:-default'], ['component:-default']);
+
+ function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
+
function lookupComponentPair(componentLookup, owner, name, options) {
var component = componentLookup.componentFor(name, owner, options);
var layout = componentLookup.layoutFor(name, owner, options);
- return {
- component: component,
- layout: layout
- };
+
+ var result = { layout: layout, component: component };
+
+ if (layout && !component) {
+ result.component = owner._lookupFactory(_containerRegistry.privatize(_templateObject));
+ }
+
+ return result;
}
function lookupComponent(owner, name, options) {
var componentLookup = owner.lookup('component-lookup:main');
@@ -41200,11 +41238,11 @@
view.renderer.ensureViewNotRendering(view);
view.renderer.rerender(view);
},
destroy: function (view) {
- view.renderer.remove(view, true);
+ view.renderer.remove(view);
},
// Handle events from `Ember.EventDispatcher`
handleEvent: function (view, eventName, event) {
if (view.has(eventName)) {
@@ -41517,11 +41555,11 @@
```html
<use xlink:href="#triangle"></use>
```
If the return value of an `attributeBindings` monitored property is a boolean
- the property's value will be set as a coerced string:
+ the attribute will be present or absent depending on the value:
```javascript
MyTextInput = Ember.View.extend({
tagName: 'input',
attributeBindings: ['disabled'],
@@ -41530,11 +41568,11 @@
```
Will result in a view instance with an HTML representation of:
```html
- <input id="ember1" class="ember-view" disabled="false" />
+ <input id="ember1" class="ember-view" />
```
`attributeBindings` can refer to computed properties:
```javascript
@@ -41839,11 +41877,11 @@
*/
});
enifed("ember/version", ["exports"], function (exports) {
"use strict";
- exports.default = "2.8.0-beta.2";
+ exports.default = "2.8.0";
});
enifed('htmlbars-runtime', ['exports', 'htmlbars-runtime/hooks', 'htmlbars-runtime/render', 'htmlbars-util/morph-utils', 'htmlbars-util/template-utils'], function (exports, _htmlbarsRuntimeHooks, _htmlbarsRuntimeRender, _htmlbarsUtilMorphUtils, _htmlbarsUtilTemplateUtils) {
'use strict';
var internal = {
@@ -45048,16 +45086,150 @@
}
node = nextNode;
} while (node);
}
});
-enifed('route-recognizer', ['exports', 'route-recognizer/dsl', 'route-recognizer/normalizer'], function (exports, _routeRecognizerDsl, _routeRecognizerNormalizer) {
- 'use strict';
+enifed("route-recognizer", ["exports"], function (exports) {
+ "use strict";
- var normalizePath = _routeRecognizerNormalizer.default.normalizePath;
- var normalizeSegment = _routeRecognizerNormalizer.default.normalizeSegment;
+ function Target(path, matcher, delegate) {
+ this.path = path;
+ this.matcher = matcher;
+ this.delegate = delegate;
+ }
+ Target.prototype = {
+ to: function (target, callback) {
+ var delegate = this.delegate;
+
+ if (delegate && delegate.willAddRoute) {
+ target = delegate.willAddRoute(this.matcher.target, target);
+ }
+
+ this.matcher.add(this.path, target);
+
+ if (callback) {
+ if (callback.length === 0) {
+ throw new Error("You must have an argument in the function passed to `to`");
+ }
+ this.matcher.addChild(this.path, target, callback, this.delegate);
+ }
+ return this;
+ }
+ };
+
+ function Matcher(target) {
+ this.routes = {};
+ this.children = {};
+ this.target = target;
+ }
+
+ Matcher.prototype = {
+ add: function (path, handler) {
+ this.routes[path] = handler;
+ },
+
+ addChild: function (path, target, callback, delegate) {
+ var matcher = new Matcher(target);
+ this.children[path] = matcher;
+
+ var match = generateMatch(path, matcher, delegate);
+
+ if (delegate && delegate.contextEntered) {
+ delegate.contextEntered(target, match);
+ }
+
+ callback(match);
+ }
+ };
+
+ function generateMatch(startingPath, matcher, delegate) {
+ return function (path, nestedCallback) {
+ var fullPath = startingPath + path;
+
+ if (nestedCallback) {
+ nestedCallback(generateMatch(fullPath, matcher, delegate));
+ } else {
+ return new Target(startingPath + path, matcher, delegate);
+ }
+ };
+ }
+
+ function addRoute(routeArray, path, handler) {
+ var len = 0;
+ for (var i = 0; i < routeArray.length; i++) {
+ len += routeArray[i].path.length;
+ }
+
+ path = path.substr(len);
+ var route = { path: path, handler: handler };
+ routeArray.push(route);
+ }
+
+ function eachRoute(baseRoute, matcher, callback, binding) {
+ var routes = matcher.routes;
+
+ for (var path in routes) {
+ if (routes.hasOwnProperty(path)) {
+ var routeArray = baseRoute.slice();
+ addRoute(routeArray, path, routes[path]);
+
+ if (matcher.children[path]) {
+ eachRoute(routeArray, matcher.children[path], callback, binding);
+ } else {
+ callback.call(binding, routeArray);
+ }
+ }
+ }
+ }
+
+ function map(callback, addRouteCallback) {
+ var matcher = new Matcher();
+
+ callback(generateMatch("", matcher, this.delegate));
+
+ eachRoute([], matcher, function (route) {
+ if (addRouteCallback) {
+ addRouteCallback(this, route);
+ } else {
+ this.add(route);
+ }
+ }, this);
+ }
+
+ // Normalizes percent-encoded values in `path` to upper-case and decodes percent-encoded
+ // values that are not reserved (i.e., unicode characters, emoji, etc). The reserved
+ // chars are "/" and "%".
+ // Safe to call multiple times on the same path.
+ function normalizePath(path) {
+ return path.split('/').map(normalizeSegment).join('/');
+ }
+
+ // We want to ensure the characters "%" and "/" remain in percent-encoded
+ // form when normalizing paths, so replace them with their encoded form after
+ // decoding the rest of the path
+ var SEGMENT_RESERVED_CHARS = /%|\//g;
+ function normalizeSegment(segment) {
+ return decodeURIComponent(segment).replace(SEGMENT_RESERVED_CHARS, encodeURIComponent);
+ }
+
+ // We do not want to encode these characters when generating dynamic path segments
+ // See https://tools.ietf.org/html/rfc3986#section-3.3
+ // sub-delims: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
+ // others allowed by RFC 3986: ":", "@"
+ //
+ // First encode the entire path segment, then decode any of the encoded special chars.
+ //
+ // The chars "!", "'", "(", ")", "*" do not get changed by `encodeURIComponent`,
+ // so the possible encoded chars are:
+ // ['%24', '%26', '%2B', '%2C', '%3B', '%3D', '%3A', '%40'].
+ var PATH_SEGMENT_ENCODINGS = /%(?:24|26|2B|2C|3B|3D|3A|40)/g;
+
+ function encodePathSegment(str) {
+ return encodeURIComponent(str).replace(PATH_SEGMENT_ENCODINGS, decodeURIComponent);
+ }
+
var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
var escapeRegex = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
function isArray(test) {
@@ -45118,11 +45290,11 @@
return "([^/]+)";
},
generate: function (params) {
if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS) {
- return encodeURIComponent(params[this.name]);
+ return encodePathSegment(params[this.name]);
} else {
return params[this.name];
}
}
};
@@ -45158,69 +45330,49 @@
};
// The `names` will be populated with the paramter name for each dynamic/star
// segment. `shouldDecodes` will be populated with a boolean for each dyanamic/star
// segment, indicating whether it should be decoded during recognition.
- function parse(route, names, specificity, shouldDecodes) {
+ function parse(route, names, types, shouldDecodes) {
// normalize route as not starting with a "/". Recognition will
// also normalize.
if (route.charAt(0) === "/") {
route = route.substr(1);
}
var segments = route.split("/");
var results = new Array(segments.length);
- // A routes has specificity determined by the order that its different segments
- // appear in. This system mirrors how the magnitude of numbers written as strings
- // works.
- // Consider a number written as: "abc". An example would be "200". Any other number written
- // "xyz" will be smaller than "abc" so long as `a > x`. For instance, "199" is smaller
- // then "200", even though "y" and "z" (which are both 9) are larger than "0" (the value
- // of (`b` and `c`). This is because the leading symbol, "2", is larger than the other
- // leading symbol, "1".
- // The rule is that symbols to the left carry more weight than symbols to the right
- // when a number is written out as a string. In the above strings, the leading digit
- // represents how many 100's are in the number, and it carries more weight than the middle
- // number which represents how many 10's are in the number.
- // This system of number magnitude works well for route specificity, too. A route written as
- // `a/b/c` will be more specific than `x/y/z` as long as `a` is more specific than
- // `x`, irrespective of the other parts.
- // Because of this similarity, we assign each type of segment a number value written as a
- // string. We can find the specificity of compound routes by concatenating these strings
- // together, from left to right. After we have looped through all of the segments,
- // we convert the string to a number.
- specificity.val = '';
-
for (var i = 0; i < segments.length; i++) {
var segment = segments[i],
match;
if (match = segment.match(/^:([^\/]+)$/)) {
results[i] = new DynamicSegment(match[1]);
names.push(match[1]);
shouldDecodes.push(true);
- specificity.val += '3';
+ types.dynamics++;
} else if (match = segment.match(/^\*([^\/]+)$/)) {
results[i] = new StarSegment(match[1]);
names.push(match[1]);
shouldDecodes.push(false);
- specificity.val += '1';
+ types.stars++;
} else if (segment === "") {
results[i] = new EpsilonSegment();
- specificity.val += '2';
} else {
results[i] = new StaticSegment(segment);
- specificity.val += '4';
+ types.statics++;
}
}
- specificity.val = +specificity.val;
-
return results;
}
+ function isEqualCharSpec(specA, specB) {
+ return specA.validChars === specB.validChars && specA.invalidChars === specB.invalidChars;
+ }
+
// A State has a character specification and (`charSpec`) and a list of possible
// subsequent states (`nextStates`).
//
// If a State is an accepting state, it will also have several additional
// properties:
@@ -45237,32 +45389,23 @@
// implementation would use a hash of keys pointing at one or more next states.
function State(charSpec) {
this.charSpec = charSpec;
this.nextStates = [];
- this.charSpecs = {};
this.regex = undefined;
this.handlers = undefined;
this.specificity = undefined;
}
State.prototype = {
get: function (charSpec) {
- if (this.charSpecs[charSpec.validChars]) {
- return this.charSpecs[charSpec.validChars];
- }
-
var nextStates = this.nextStates;
for (var i = 0; i < nextStates.length; i++) {
var child = nextStates[i];
- var isEqual = child.charSpec.validChars === charSpec.validChars;
- isEqual = isEqual && child.charSpec.invalidChars === charSpec.invalidChars;
-
- if (isEqual) {
- this.charSpecs[charSpec.validChars] = child;
+ if (isEqualCharSpec(child.charSpec, charSpec)) {
return child;
}
}
},
@@ -45319,14 +45462,43 @@
return returned;
}
};
- // Sort the routes by specificity
+ // This is a somewhat naive strategy, but should work in a lot of cases
+ // A better strategy would properly resolve /posts/:id/new and /posts/edit/:id.
+ //
+ // This strategy generally prefers more static and less dynamic matching.
+ // Specifically, it
+ //
+ // * prefers fewer stars to more, then
+ // * prefers using stars for less of the match to more, then
+ // * prefers fewer dynamic segments to more, then
+ // * prefers more static segments to more
function sortSolutions(states) {
return states.sort(function (a, b) {
- return b.specificity.val - a.specificity.val;
+ if (a.types.stars !== b.types.stars) {
+ return a.types.stars - b.types.stars;
+ }
+
+ if (a.types.stars) {
+ if (a.types.statics !== b.types.statics) {
+ return b.types.statics - a.types.statics;
+ }
+ if (a.types.dynamics !== b.types.dynamics) {
+ return b.types.dynamics - a.types.dynamics;
+ }
+ }
+
+ if (a.types.dynamics !== b.types.dynamics) {
+ return a.types.dynamics - b.types.dynamics;
+ }
+ if (a.types.statics !== b.types.statics) {
+ return b.types.statics - a.types.statics;
+ }
+
+ return 0;
});
}
function recognizeChar(states, ch) {
var nextStates = [];
@@ -45416,11 +45588,11 @@
RouteRecognizer.prototype = {
add: function (routes, options) {
var currentState = this.rootState,
regex = "^",
- specificity = {},
+ types = { statics: 0, dynamics: 0, stars: 0 },
handlers = new Array(routes.length),
allSegments = [],
name;
var isEmpty = true;
@@ -45428,11 +45600,11 @@
for (var i = 0; i < routes.length; i++) {
var route = routes[i],
names = [],
shouldDecodes = [];
- var segments = parse(route.path, names, specificity, shouldDecodes);
+ var segments = parse(route.path, names, types, shouldDecodes);
allSegments = allSegments.concat(segments);
for (var j = 0; j < segments.length; j++) {
var segment = segments[j];
@@ -45460,11 +45632,11 @@
regex += "/";
}
currentState.handlers = handlers;
currentState.regex = new RegExp(regex + "$");
- currentState.specificity = specificity;
+ currentState.types = types;
if (name = options && options.as) {
this.names[name] = {
segments: allSegments,
handlers: handlers
@@ -45521,11 +45693,11 @@
}
return output;
},
- generateQueryString: function (params, handlers) {
+ generateQueryString: function (params) {
var pairs = [];
var keys = [];
for (var key in params) {
if (params.hasOwnProperty(key)) {
keys.push(key);
@@ -45590,11 +45762,10 @@
recognize: function (path) {
var states = [this.rootState],
pathLen,
i,
- l,
queryStart,
queryParams = {},
hashStart,
isSlashDropped = false;
@@ -45656,250 +45827,89 @@
return findHandler(state, originalPath, queryParams);
}
}
};
- RouteRecognizer.prototype.map = _routeRecognizerDsl.default;
+ RouteRecognizer.prototype.map = map;
- RouteRecognizer.VERSION = '0.2.0';
+ RouteRecognizer.VERSION = '0.2.6';
// Set to false to opt-out of encoding and decoding path segments.
// See https://github.com/tildeio/route-recognizer/pull/55
RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS = true;
- RouteRecognizer.Normalizer = _routeRecognizerNormalizer.default;
-
- exports.default = RouteRecognizer;
-});
-enifed("route-recognizer/dsl", ["exports"], function (exports) {
- "use strict";
-
- function Target(path, matcher, delegate) {
- this.path = path;
- this.matcher = matcher;
- this.delegate = delegate;
- }
-
- Target.prototype = {
- to: function (target, callback) {
- var delegate = this.delegate;
-
- if (delegate && delegate.willAddRoute) {
- target = delegate.willAddRoute(this.matcher.target, target);
- }
-
- this.matcher.add(this.path, target);
-
- if (callback) {
- if (callback.length === 0) {
- throw new Error("You must have an argument in the function passed to `to`");
- }
- this.matcher.addChild(this.path, target, callback, this.delegate);
- }
- return this;
- }
- };
-
- function Matcher(target) {
- this.routes = {};
- this.children = {};
- this.target = target;
- }
-
- Matcher.prototype = {
- add: function (path, handler) {
- this.routes[path] = handler;
- },
-
- addChild: function (path, target, callback, delegate) {
- var matcher = new Matcher(target);
- this.children[path] = matcher;
-
- var match = generateMatch(path, matcher, delegate);
-
- if (delegate && delegate.contextEntered) {
- delegate.contextEntered(target, match);
- }
-
- callback(match);
- }
- };
-
- function generateMatch(startingPath, matcher, delegate) {
- return function (path, nestedCallback) {
- var fullPath = startingPath + path;
-
- if (nestedCallback) {
- nestedCallback(generateMatch(fullPath, matcher, delegate));
- } else {
- return new Target(startingPath + path, matcher, delegate);
- }
- };
- }
-
- function addRoute(routeArray, path, handler) {
- var len = 0;
- for (var i = 0; i < routeArray.length; i++) {
- len += routeArray[i].path.length;
- }
-
- path = path.substr(len);
- var route = { path: path, handler: handler };
- routeArray.push(route);
- }
-
- function eachRoute(baseRoute, matcher, callback, binding) {
- var routes = matcher.routes;
-
- for (var path in routes) {
- if (routes.hasOwnProperty(path)) {
- var routeArray = baseRoute.slice();
- addRoute(routeArray, path, routes[path]);
-
- if (matcher.children[path]) {
- eachRoute(routeArray, matcher.children[path], callback, binding);
- } else {
- callback.call(binding, routeArray);
- }
- }
- }
- }
-
- exports.default = function (callback, addRouteCallback) {
- var matcher = new Matcher();
-
- callback(generateMatch("", matcher, this.delegate));
-
- eachRoute([], matcher, function (route) {
- if (addRouteCallback) {
- addRouteCallback(this, route);
- } else {
- this.add(route);
- }
- }, this);
- };
-});
-enifed('route-recognizer/normalizer', ['exports'], function (exports) {
- // Match percent-encoded values (e.g. %3a, %3A, %25)
- 'use strict';
-
- var PERCENT_ENCODED_VALUES = /%[a-fA-F0-9]{2}/g;
-
- function toUpper(str) {
- return str.toUpperCase();
- }
-
- // Turn percent-encoded values to upper case ("%3a" -> "%3A")
- function percentEncodedValuesToUpper(string) {
- return string.replace(PERCENT_ENCODED_VALUES, toUpper);
- }
-
- // Normalizes percent-encoded values to upper-case and decodes percent-encoded
- // values that are not reserved (like unicode characters).
- // Safe to call multiple times on the same path.
- function normalizePath(path) {
- return path.split('/').map(normalizeSegment).join('/');
- }
-
- function percentEncode(char) {
- return '%' + charToHex(char);
- }
-
- function charToHex(char) {
- return char.charCodeAt(0).toString(16).toUpperCase();
- }
-
- // Decodes percent-encoded values in the string except those
- // characters in `reservedHex`, where `reservedHex` is an array of 2-character
- // percent-encodings
- function decodeURIComponentExcept(string, reservedHex) {
- if (string.indexOf('%') === -1) {
- // If there is no percent char, there is no decoding that needs to
- // be done and we exit early
- return string;
- }
- string = percentEncodedValuesToUpper(string);
-
- var result = '';
- var buffer = '';
- var idx = 0;
- while (idx < string.length) {
- var pIdx = string.indexOf('%', idx);
-
- if (pIdx === -1) {
- // no percent char
- buffer += string.slice(idx);
- break;
- } else {
- // found percent char
- buffer += string.slice(idx, pIdx);
- idx = pIdx + 3;
-
- var hex = string.slice(pIdx + 1, pIdx + 3);
- var encoded = '%' + hex;
-
- if (reservedHex.indexOf(hex) === -1) {
- // encoded is not in reserved set, add to buffer
- buffer += encoded;
- } else {
- result += decodeURIComponent(buffer);
- buffer = '';
- result += encoded;
- }
- }
- }
- result += decodeURIComponent(buffer);
- return result;
- }
-
- // Leave these characters in encoded state in segments
- var reservedSegmentChars = ['%', '/'];
- var reservedHex = reservedSegmentChars.map(charToHex);
-
- function normalizeSegment(segment) {
- return decodeURIComponentExcept(segment, reservedHex);
- }
-
- var Normalizer = {
+ RouteRecognizer.Normalizer = {
normalizeSegment: normalizeSegment,
- normalizePath: normalizePath
+ normalizePath: normalizePath,
+ encodePathSegment: encodePathSegment
};
- exports.default = Normalizer;
+ exports.default = RouteRecognizer;
});
enifed('router', ['exports', 'router/router'], function (exports, _routerRouter) {
'use strict';
exports.default = _routerRouter.default;
});
enifed('router/handler-info', ['exports', 'router/utils', 'rsvp/promise'], function (exports, _routerUtils, _rsvpPromise) {
'use strict';
+ var DEFAULT_HANDLER = Object.freeze({});
+
function HandlerInfo(_props) {
var props = _props || {};
- var name = props.name;
- // Setup a handlerPromise so that we can wait for asynchronously loaded handlers
- this.handlerPromise = _rsvpPromise.default.resolve(props.handler);
+ // Set a default handler to ensure consistent object shape
+ this._handler = DEFAULT_HANDLER;
- // Wait until the 'handler' property has been updated when chaining to a handler
- // that is a promise
- if (_routerUtils.isPromise(props.handler)) {
- this.handlerPromise = this.handlerPromise.then(_routerUtils.bind(this, this.updateHandler));
- props.handler = undefined;
- } else if (props.handler) {
- // Store the name of the handler on the handler for easy checks later
- props.handler._handlerName = name;
+ if (props.handler) {
+ var name = props.name;
+
+ // Setup a handlerPromise so that we can wait for asynchronously loaded handlers
+ this.handlerPromise = _rsvpPromise.default.resolve(props.handler);
+
+ // Wait until the 'handler' property has been updated when chaining to a handler
+ // that is a promise
+ if (_routerUtils.isPromise(props.handler)) {
+ this.handlerPromise = this.handlerPromise.then(_routerUtils.bind(this, this.updateHandler));
+ props.handler = undefined;
+ } else if (props.handler) {
+ // Store the name of the handler on the handler for easy checks later
+ props.handler._handlerName = name;
+ }
}
_routerUtils.merge(this, props);
this.initialize(props);
}
HandlerInfo.prototype = {
name: null,
- handler: null,
+
+ getHandler: function () {},
+
+ fetchHandler: function () {
+ var handler = this.getHandler(this.name);
+
+ // Setup a handlerPromise so that we can wait for asynchronously loaded handlers
+ this.handlerPromise = _rsvpPromise.default.resolve(handler);
+
+ // Wait until the 'handler' property has been updated when chaining to a handler
+ // that is a promise
+ if (_routerUtils.isPromise(handler)) {
+ this.handlerPromise = this.handlerPromise.then(_routerUtils.bind(this, this.updateHandler));
+ } else if (handler) {
+ // Store the name of the handler on the handler for easy checks later
+ handler._handlerName = this.name;
+ return this.handler = handler;
+ }
+
+ return this.handler = undefined;
+ },
+
+ _handlerPromise: undefined,
+
params: null,
context: null,
// Injected by the handler info factory.
factory: null,
@@ -46033,10 +46043,42 @@
var contextsMatch = other.context === this.context;
return other.name !== this.name || this.hasOwnProperty('context') && !contextsMatch || this.hasOwnProperty('params') && !paramsMatch(this.params, other.params);
}
};
+ Object.defineProperty(HandlerInfo.prototype, 'handler', {
+ get: function () {
+ // _handler could be set to either a handler object or undefined, so we
+ // compare against a default reference to know when it's been set
+ if (this._handler !== DEFAULT_HANDLER) {
+ return this._handler;
+ }
+
+ return this.fetchHandler();
+ },
+
+ set: function (handler) {
+ return this._handler = handler;
+ }
+ });
+
+ Object.defineProperty(HandlerInfo.prototype, 'handlerPromise', {
+ get: function () {
+ if (this._handlerPromise) {
+ return this._handlerPromise;
+ }
+
+ this.fetchHandler();
+
+ return this._handlerPromise;
+ },
+
+ set: function (handlerPromise) {
+ return this._handlerPromise = handlerPromise;
+ }
+ });
+
function paramsMatch(a, b) {
if (!a ^ !b) {
// Only one is null.
return false;
}
@@ -46124,12 +46166,11 @@
@param {Object} model the model to be serialized for this handler
*/
serialize: function (_model) {
var model = _model || this.context,
names = this.names,
- handler = this.handler,
- serializer = this.serializer || handler && handler.serialize;
+ serializer = this.serializer || this.handler && this.handler.serialize;
var object = {};
if (_routerUtils.isParam(model)) {
object[names[0]] = model;
return object;
@@ -46197,10 +46238,17 @@
this.didTransition = options.didTransition || this.didTransition;
this.willTransition = options.willTransition || this.willTransition;
this.delegate = options.delegate || this.delegate;
this.triggerEvent = options.triggerEvent || this.triggerEvent;
this.log = options.log || this.log;
+ this.dslCallBacks = []; // NOTE: set by Ember
+ this.state = undefined;
+ this.activeTransition = undefined;
+ this._changedQueryParams = undefined;
+ this.oldState = undefined;
+ this.currentHandlerInfos = undefined;
+ this.state = undefined;
this.recognizer = new _routeRecognizer.default();
this.reset();
}
@@ -46319,11 +46367,11 @@
},
// NOTE: this doesn't really belong here, but here
// it shall remain until our ES6 transpiler can
// handle cyclical deps.
- transitionByIntent: function (intent, isIntermediate) {
+ transitionByIntent: function (intent /*, isIntermediate*/) {
try {
return getTransitionByIntent.apply(this, arguments);
} catch (e) {
return new _routerTransition.Transition(this, intent, null, e);
}
@@ -46390,15 +46438,15 @@
Transition into the specified named route.
If necessary, trigger the exit callback on any handlers
that are no longer represented by the target route.
@param {String} name the name of the route
*/
- transitionTo: function (name) {
+ transitionTo: function () /*name*/{
return doTransition(this, arguments);
},
- intermediateTransitionTo: function (name) {
+ intermediateTransitionTo: function () /*name*/{
return doTransition(this, arguments, true);
},
refresh: function (pivotHandler) {
var state = this.activeTransition ? this.activeTransition.state : this.state;
@@ -46424,11 +46472,11 @@
Identical to `transitionTo` except that the current URL will be replaced
if possible.
This method is intended primarily for use with `replaceState`.
@param {String} name the name of the route
*/
- replaceWith: function (name) {
+ replaceWith: function () /*name*/{
return doTransition(this, arguments).method('replace');
},
/**
Take a named route and context objects and generate a
@@ -46471,16 +46519,11 @@
},
isActiveIntent: function (handlerName, contexts, queryParams, _state) {
var state = _state || this.state,
targetHandlerInfos = state.handlerInfos,
- found = false,
- names,
- object,
handlerInfo,
- handlerObj,
- i,
len;
if (!targetHandlerInfos.length) {
return false;
}
@@ -46534,11 +46577,11 @@
isActive: function (handlerName) {
var partitionedArgs = _routerUtils.extractQueryParams(_routerUtils.slice.call(arguments, 1));
return this.isActiveIntent(handlerName, partitionedArgs[0], partitionedArgs[1]);
},
- trigger: function (name) {
+ trigger: function () /*name*/{
var args = _routerUtils.slice.call(arguments);
_routerUtils.trigger(this, this.currentHandlerInfos, false, args);
},
/**
@@ -46732,11 +46775,12 @@
var handlers = {
updatedContext: [],
exited: [],
entered: [],
- unchanged: []
+ unchanged: [],
+ reset: undefined
};
var handlerChanged,
contextChanged = false,
i,
@@ -46771,11 +46815,11 @@
handlers.reset.reverse();
return handlers;
}
- function updateURL(transition, state, inputUrl) {
+ function updateURL(transition, state /*, inputUrl*/) {
var urlMethod = transition.urlMethod;
if (!urlMethod) {
return;
}
@@ -46815,12 +46859,11 @@
try {
_routerUtils.log(transition.router, transition.sequence, "Resolved all models on destination route; finalizing transition.");
var router = transition.router,
- handlerInfos = newState.handlerInfos,
- seq = transition.sequence;
+ handlerInfos = newState.handlerInfos;
// Run all the necessary enter/setup/exit hooks
setupContexts(router, newState, transition);
// Check if a redirect occurred in enter/setup
@@ -46999,12 +47042,12 @@
}
}
exports.default = Router;
});
-enifed('router/transition-intent', ['exports', 'router/utils'], function (exports, _routerUtils) {
- 'use strict';
+enifed("router/transition-intent", ["exports"], function (exports) {
+ "use strict";
function TransitionIntent(props) {
this.initialize(props);
// TODO: wat
@@ -47036,11 +47079,10 @@
applyToState: function (oldState, recognizer, getHandler, isIntermediate, getSerializer) {
var partitionedArgs = _routerUtils.extractQueryParams([this.name].concat(this.contexts)),
pureArgs = partitionedArgs[0],
- queryParams = partitionedArgs[1],
handlers = recognizer.handlersFor(pureArgs[0]);
var targetRouteName = handlers[handlers.length - 1].handler;
return this.applyToHandlers(oldState, handlers, getHandler, targetRouteName, isIntermediate, null, getSerializer);
@@ -47062,33 +47104,30 @@
break;
}
}
}
- var pivotHandlerFound = !this.pivotHandler;
-
for (i = handlers.length - 1; i >= 0; --i) {
var result = handlers[i];
var name = result.handler;
- var handler = getHandler(name);
var oldHandlerInfo = oldState.handlerInfos[i];
var newHandlerInfo = null;
if (result.names.length > 0) {
if (i >= invalidateIndex) {
- newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
+ newHandlerInfo = this.createParamHandlerInfo(name, getHandler, result.names, objects, oldHandlerInfo);
} else {
var serializer = getSerializer(name);
- newHandlerInfo = this.getHandlerInfoForDynamicSegment(name, handler, result.names, objects, oldHandlerInfo, targetRouteName, i, serializer);
+ newHandlerInfo = this.getHandlerInfoForDynamicSegment(name, getHandler, result.names, objects, oldHandlerInfo, targetRouteName, i, serializer);
}
} else {
// This route has no dynamic segment.
// Therefore treat as a param-based handlerInfo
// with empty params. This will cause the `model`
// hook to be called with empty params, which is desirable.
- newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
+ newHandlerInfo = this.createParamHandlerInfo(name, getHandler, result.names, objects, oldHandlerInfo);
}
if (checkingIfActive) {
// If we're performing an isActive check, we want to
// serialize URL params with the provided context, but
@@ -47131,24 +47170,22 @@
},
invalidateChildren: function (handlerInfos, invalidateIndex) {
for (var i = invalidateIndex, l = handlerInfos.length; i < l; ++i) {
var handlerInfo = handlerInfos[i];
- handlerInfos[i] = handlerInfos[i].getUnresolved();
+ handlerInfos[i] = handlerInfo.getUnresolved();
}
},
- getHandlerInfoForDynamicSegment: function (name, handler, names, objects, oldHandlerInfo, targetRouteName, i, serializer) {
-
- var numNames = names.length;
+ getHandlerInfoForDynamicSegment: function (name, getHandler, names, objects, oldHandlerInfo, targetRouteName, i, serializer) {
var objectToUse;
if (objects.length > 0) {
// Use the objects provided for this transition.
objectToUse = objects[objects.length - 1];
if (_routerUtils.isParam(objectToUse)) {
- return this.createParamHandlerInfo(name, handler, names, objects, oldHandlerInfo);
+ return this.createParamHandlerInfo(name, getHandler, names, objects, oldHandlerInfo);
} else {
objects.pop();
}
} else if (oldHandlerInfo && oldHandlerInfo.name === name) {
// Reuse the matching oldHandlerInfo
@@ -47169,18 +47206,18 @@
}
}
return _routerHandlerInfoFactory.default('object', {
name: name,
- handler: handler,
+ getHandler: getHandler,
serializer: serializer,
context: objectToUse,
names: names
});
},
- createParamHandlerInfo: function (name, handler, names, objects, oldHandlerInfo) {
+ createParamHandlerInfo: function (name, getHandler, names, objects, oldHandlerInfo) {
var params = {};
// Soak up all the provided string/numbers
var numNames = names.length;
while (numNames--) {
@@ -47204,11 +47241,11 @@
}
}
return _routerHandlerInfoFactory.default('param', {
name: name,
- handler: handler,
+ getHandler: getHandler,
params: params
});
}
});
});
@@ -47224,11 +47261,10 @@
applyToState: function (oldState, recognizer, getHandler) {
var newState = new _routerTransitionState.default();
var results = recognizer.recognize(this.url),
- queryParams = {},
i,
len;
if (!results) {
throw new _routerUnrecognizedUrlError.default(this.url);
@@ -47239,33 +47275,32 @@
// Checks if a handler is accessible by URL. If it is not, an error is thrown.
// For the case where the handler is loaded asynchronously, the error will be
// thrown once it is loaded.
function checkHandlerAccessibility(handler) {
- if (handler.inaccessibleByURL) {
+ if (handler && handler.inaccessibleByURL) {
throw new _routerUnrecognizedUrlError.default(url);
}
return handler;
}
for (i = 0, len = results.length; i < len; ++i) {
var result = results[i];
var name = result.handler;
- var handler = getHandler(name);
-
- checkHandlerAccessibility(handler);
-
var newHandlerInfo = _routerHandlerInfoFactory.default('param', {
name: name,
- handler: handler,
+ getHandler: getHandler,
params: result.params
});
+ var handler = newHandlerInfo.handler;
- // If the hanlder is being loaded asynchronously, check again if we can
- // access it after it has resolved
- if (_routerUtils.isPromise(handler)) {
+ if (handler) {
+ checkHandlerAccessibility(handler);
+ } else {
+ // If the hanlder is being loaded asynchronously, check if we can
+ // access it after it has resolved
newHandlerInfo.handlerPromise = newHandlerInfo.handlerPromise.then(checkHandlerAccessibility);
}
var oldHandlerInfo = oldState.handlerInfos[i];
if (statesDiffer || newHandlerInfo.shouldSupercede(oldHandlerInfo)) {
@@ -47280,24 +47315,20 @@
return newState;
}
});
});
-enifed('router/transition-state', ['exports', 'router/handler-info', 'router/utils', 'rsvp/promise'], function (exports, _routerHandlerInfo, _routerUtils, _rsvpPromise) {
+enifed('router/transition-state', ['exports', 'router/utils', 'rsvp/promise'], function (exports, _routerUtils, _rsvpPromise) {
'use strict';
- function TransitionState(other) {
+ function TransitionState() {
this.handlerInfos = [];
this.queryParams = {};
this.params = {};
}
TransitionState.prototype = {
- handlerInfos: null,
- queryParams: null,
- params: null,
-
promiseLabel: function (label) {
var targetName = '';
_routerUtils.forEach(this.handlerInfos, function (handlerInfo) {
if (targetName !== '') {
targetName += '.';
@@ -47306,11 +47337,10 @@
});
return _routerUtils.promiseLabel("'" + targetName + "': " + label);
},
resolve: function (shouldContinue, payload) {
- var self = this;
// First, calculate params for this state. This is useful
// information to provide to the various route hooks.
var params = this.params;
_routerUtils.forEach(this.handlerInfos, function (handlerInfo) {
params[handlerInfo.name] = handlerInfo.params || {};
@@ -47386,11 +47416,11 @@
}
};
exports.default = TransitionState;
});
-enifed('router/transition', ['exports', 'rsvp/promise', 'router/handler-info', 'router/utils'], function (exports, _rsvpPromise, _routerHandlerInfo, _routerUtils) {
+enifed('router/transition', ['exports', 'rsvp/promise', 'router/utils'], function (exports, _rsvpPromise, _routerUtils) {
'use strict';
/**
A Transition is a thennable (a promise-like object) that represents
an attempt to transition to another route. It can be aborted, either
@@ -47412,10 +47442,19 @@
this.intent = intent;
this.router = router;
this.data = this.intent && this.intent.data || {};
this.resolvedModels = {};
this.queryParams = {};
+ this.promise = undefined;
+ this.error = undefined;
+ this.params = undefined;
+ this.handlerInfos = undefined;
+ this.targetName = undefined;
+ this.pivotHandler = undefined;
+ this.sequence = undefined;
+ this.isAborted = undefined;
+ this.isActive = undefined;
if (error) {
this.promise = _rsvpPromise.default.reject(error);
this.error = error;
return;
@@ -47467,13 +47506,11 @@
Transition.prototype = {
targetName: null,
urlMethod: 'update',
intent: null,
- params: null,
pivotHandler: null,
resolveIndex: 0,
- handlerInfos: null,
resolvedModels: null,
isActive: true,
state: null,
queryParamsOnly: false,