ember-source 4.3.0-alpha.1 → 4.3.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -2
- package/blueprints/component-addon/index.js +2 -3
- package/blueprints/component-class-addon/index.js +2 -3
- package/blueprints/controller/files/__root__/__path__/__name__.js +2 -2
- package/blueprints/controller/index.js +2 -4
- package/blueprints/route/files/__root__/__path__/__name__.js +3 -3
- package/blueprints/route/index.js +2 -3
- package/blueprints/service/files/__root__/__path__/__name__.js +2 -2
- package/blueprints/service/index.js +2 -4
- package/build-metadata.json +3 -3
- package/dist/dependencies/router_js.js +66 -31
- package/dist/ember-template-compiler.js +1250 -861
- package/dist/ember-template-compiler.map +1 -1
- package/dist/ember-testing.js +88 -56
- package/dist/ember-testing.map +1 -1
- package/dist/ember.debug.js +3712 -3159
- package/dist/ember.debug.map +1 -1
- package/dist/header/license.js +1 -1
- package/dist/header/loader.js +0 -1
- package/dist/packages/@ember/-internals/bootstrap/index.js +0 -2
- package/dist/packages/@ember/-internals/container/index.js +16 -11
- package/dist/packages/@ember/-internals/extension-support/lib/container_debug_adapter.js +3 -3
- package/dist/packages/@ember/-internals/extension-support/lib/data_adapter.js +52 -52
- package/dist/packages/@ember/-internals/glimmer/index.js +161 -125
- package/dist/packages/@ember/-internals/meta/lib/meta.js +67 -11
- package/dist/packages/@ember/-internals/metal/index.js +95 -121
- package/dist/packages/@ember/-internals/routing/lib/ext/controller.js +24 -12
- package/dist/packages/@ember/-internals/routing/lib/location/api.js +1 -0
- package/dist/packages/@ember/-internals/routing/lib/location/auto_location.js +3 -1
- package/dist/packages/@ember/-internals/routing/lib/services/router.js +117 -197
- package/dist/packages/@ember/-internals/routing/lib/services/routing.js +3 -1
- package/dist/packages/@ember/-internals/routing/lib/system/route-info.js +2 -2
- package/dist/packages/@ember/-internals/routing/lib/system/route.js +147 -402
- package/dist/packages/@ember/-internals/routing/lib/system/router.js +82 -40
- package/dist/packages/@ember/-internals/routing/lib/utils.js +48 -25
- package/dist/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
- package/dist/packages/@ember/-internals/runtime/lib/mixins/array.js +1 -0
- package/dist/packages/@ember/-internals/runtime/lib/mixins/comparable.js +4 -4
- package/dist/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +29 -29
- package/dist/packages/@ember/-internals/runtime/lib/mixins/promise_proxy.js +16 -16
- package/dist/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +48 -48
- package/dist/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +8 -8
- package/dist/packages/@ember/-internals/runtime/lib/system/namespace.js +1 -2
- package/dist/packages/@ember/-internals/runtime/lib/type-of.js +1 -1
- package/dist/packages/@ember/-internals/utils/index.js +11 -9
- package/dist/packages/@ember/-internals/views/lib/mixins/view_support.js +2 -4
- package/dist/packages/@ember/-internals/views/lib/system/utils.js +2 -0
- package/dist/packages/@ember/application/lib/application.js +0 -2
- package/dist/packages/@ember/array/index.js +1 -1
- package/dist/packages/@ember/canary-features/index.js +2 -2
- package/dist/packages/@ember/controller/index.js +3 -54
- package/dist/packages/@ember/debug/index.js +1 -1
- package/dist/packages/@ember/debug/lib/deprecate.js +12 -10
- package/dist/packages/@ember/instrumentation/index.js +9 -13
- package/dist/packages/@ember/object/compat.js +16 -7
- package/dist/packages/@ember/polyfills/lib/assign.js +1 -0
- package/dist/packages/@ember/routing/router-service.js +1 -0
- package/dist/packages/@ember/runloop/index.js +9 -9
- package/dist/packages/@ember/service/index.js +6 -73
- package/dist/packages/@ember/string/index.js +1 -0
- package/dist/packages/ember/index.js +1 -2
- package/dist/packages/ember/version.js +1 -1
- package/docs/data.json +2588 -1839
- package/package.json +27 -27
- package/blueprints/component-addon/native-files/__root__/__path__/__name__.js +0 -1
- package/blueprints/component-class-addon/native-files/__root__/__path__/__name__.js +0 -1
- package/blueprints/controller/native-files/__root__/__path__/__name__.js +0 -4
- package/blueprints/edition-detector.js +0 -13
- package/blueprints/route/native-files/__root__/__path__/__name__.js +0 -11
- package/blueprints/route/native-files/__root__/__templatepath__/__templatename__.hbs +0 -2
- package/blueprints/service/native-files/__root__/__path__/__name__.js +0 -4
|
@@ -11,6 +11,10 @@ import { calculateCacheKey, extractRouteArgs, getActiveTargetName, resemblesURL
|
|
|
11
11
|
import DSL from './dsl';
|
|
12
12
|
import { defaultSerialize, getFullQueryParams, hasDefaultSerialize, ROUTE_CONNECTIONS } from './route';
|
|
13
13
|
import RouterState from './router_state';
|
|
14
|
+
/**
|
|
15
|
+
@module @ember/routing
|
|
16
|
+
*/
|
|
17
|
+
|
|
14
18
|
import Router, { logAbort, STATE_SYMBOL } from 'router_js';
|
|
15
19
|
|
|
16
20
|
function defaultDidTransition(infos) {
|
|
@@ -80,7 +84,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
80
84
|
this.currentRouteName = null;
|
|
81
85
|
this.currentPath = null;
|
|
82
86
|
this.currentRoute = null;
|
|
83
|
-
this._qpCache = Object.create(null);
|
|
87
|
+
this._qpCache = Object.create(null); // Set of QueryParam['urlKey']
|
|
88
|
+
|
|
84
89
|
this._qpUpdates = new Set();
|
|
85
90
|
this._queuedQPChanges = {};
|
|
86
91
|
this._toplevelView = null;
|
|
@@ -165,7 +170,9 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
165
170
|
let name, nameParts, oldNameParts;
|
|
166
171
|
|
|
167
172
|
for (let i = 1; i < routeInfos.length; i++) {
|
|
168
|
-
|
|
173
|
+
let routeInfo = routeInfos[i];
|
|
174
|
+
assert('has routeInfo', routeInfo);
|
|
175
|
+
name = routeInfo.name;
|
|
169
176
|
nameParts = name.split('.');
|
|
170
177
|
oldNameParts = slice.call(path);
|
|
171
178
|
|
|
@@ -186,7 +193,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
186
193
|
_initRouterJs() {
|
|
187
194
|
let location = get(this, 'location');
|
|
188
195
|
let router = this;
|
|
189
|
-
|
|
196
|
+
const owner = getOwner(this);
|
|
197
|
+
assert('Router is unexpectedly missing an owner', owner);
|
|
190
198
|
let seen = Object.create(null);
|
|
191
199
|
|
|
192
200
|
class PrivateRouter extends Router {
|
|
@@ -203,6 +211,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
203
211
|
}
|
|
204
212
|
|
|
205
213
|
let fullRouteName = `route:${routeName}`;
|
|
214
|
+
assert('Route is unexpectedly missing an owner', routeOwner);
|
|
206
215
|
let route = routeOwner.lookup(fullRouteName);
|
|
207
216
|
|
|
208
217
|
if (seen[name]) {
|
|
@@ -367,7 +376,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
367
376
|
let enableLoadingSubstates = this._hasModuleBasedResolver();
|
|
368
377
|
|
|
369
378
|
let router = this;
|
|
370
|
-
|
|
379
|
+
const owner = getOwner(this);
|
|
380
|
+
assert('Router is unexpectedly missing an owner', owner);
|
|
371
381
|
let options = {
|
|
372
382
|
enableLoadingSubstates,
|
|
373
383
|
|
|
@@ -397,6 +407,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
397
407
|
|
|
398
408
|
_hasModuleBasedResolver() {
|
|
399
409
|
let owner = getOwner(this);
|
|
410
|
+
assert('Router is unexpectedly missing an owner', owner);
|
|
400
411
|
let resolver = get(owner, 'application.__registry__.resolver.moduleBasedResolver');
|
|
401
412
|
return Boolean(resolver);
|
|
402
413
|
}
|
|
@@ -467,8 +478,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
467
478
|
let defaultParentState;
|
|
468
479
|
let liveRoutes = null;
|
|
469
480
|
|
|
470
|
-
for (let
|
|
471
|
-
let route =
|
|
481
|
+
for (let routeInfo of routeInfos) {
|
|
482
|
+
let route = routeInfo.route;
|
|
472
483
|
let connections = ROUTE_CONNECTIONS.get(route);
|
|
473
484
|
let ownState;
|
|
474
485
|
|
|
@@ -503,6 +514,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
503
514
|
|
|
504
515
|
if (!this._toplevelView) {
|
|
505
516
|
let owner = getOwner(this);
|
|
517
|
+
assert('Router is unexpectedly missing an owner', owner);
|
|
506
518
|
let OutletView = owner.factoryFor('view:-outlet');
|
|
507
519
|
let application = owner.lookup('application:main');
|
|
508
520
|
let environment = owner.lookup('-environment:main');
|
|
@@ -543,9 +555,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
543
555
|
/**
|
|
544
556
|
Transition the application into another route. The route may
|
|
545
557
|
be either a single route or route path:
|
|
546
|
-
See [transitionTo](/ember/release/classes/Route/methods/transitionTo?anchor=transitionTo) for more info.
|
|
547
558
|
@method transitionTo
|
|
548
|
-
@param {String} name the name of the route or a URL
|
|
559
|
+
@param {String} [name] the name of the route or a URL
|
|
549
560
|
@param {...Object} models the model(s) or identifier(s) to be used while
|
|
550
561
|
transitioning to the route.
|
|
551
562
|
@param {Object} [options] optional hash with a queryParams property
|
|
@@ -580,12 +591,29 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
580
591
|
let infos = this._routerMicrolib.currentRouteInfos;
|
|
581
592
|
|
|
582
593
|
if (this.namespace.LOG_TRANSITIONS) {
|
|
583
|
-
// eslint-disable-next-line no-console
|
|
584
|
-
|
|
594
|
+
assert('expected infos to be set', infos); // eslint-disable-next-line no-console
|
|
595
|
+
|
|
585
596
|
console.log(`Intermediate-transitioned into '${EmberRouter._routePath(infos)}'`);
|
|
586
597
|
}
|
|
587
598
|
}
|
|
588
599
|
}
|
|
600
|
+
/**
|
|
601
|
+
Similar to `transitionTo`, but instead of adding the destination to the browser's URL history,
|
|
602
|
+
it replaces the entry for the current route.
|
|
603
|
+
When the user clicks the "back" button in the browser, there will be fewer steps.
|
|
604
|
+
This is most commonly used to manage redirects in a way that does not cause confusing additions
|
|
605
|
+
to the user's browsing history.
|
|
606
|
+
@method replaceWith
|
|
607
|
+
@param {String} [name] the name of the route or a URL
|
|
608
|
+
@param {...Object} models the model(s) or identifier(s) to be used while
|
|
609
|
+
transitioning to the route.
|
|
610
|
+
@param {Object} [options] optional hash with a queryParams property
|
|
611
|
+
containing a mapping of query parameters
|
|
612
|
+
@return {Transition} the transition object associated with this
|
|
613
|
+
attempted transition
|
|
614
|
+
@public
|
|
615
|
+
*/
|
|
616
|
+
|
|
589
617
|
|
|
590
618
|
replaceWith(...args) {
|
|
591
619
|
return this.transitionTo(...args).method('replace');
|
|
@@ -671,8 +699,11 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
671
699
|
let instances = this._engineInstances;
|
|
672
700
|
|
|
673
701
|
for (let name in instances) {
|
|
674
|
-
|
|
675
|
-
|
|
702
|
+
let instance = instances[name];
|
|
703
|
+
assert('has instance', instance);
|
|
704
|
+
|
|
705
|
+
for (let id in instance) {
|
|
706
|
+
run(instance[id], 'destroy');
|
|
676
707
|
}
|
|
677
708
|
}
|
|
678
709
|
}
|
|
@@ -686,7 +717,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
686
717
|
_activeQPChanged(queryParameterName, newValue) {
|
|
687
718
|
this._queuedQPChanges[queryParameterName] = newValue;
|
|
688
719
|
once(this, this._fireQueryParamTransition);
|
|
689
|
-
}
|
|
720
|
+
} // The queryParameterName is QueryParam['urlKey']
|
|
721
|
+
|
|
690
722
|
|
|
691
723
|
_updatingQPChanged(queryParameterName) {
|
|
692
724
|
this._qpUpdates.add(queryParameterName);
|
|
@@ -718,6 +750,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
718
750
|
let location = this.location;
|
|
719
751
|
let rootURL = this.rootURL;
|
|
720
752
|
let owner = getOwner(this);
|
|
753
|
+
assert('Router is unexpectedly missing an owner', owner);
|
|
721
754
|
|
|
722
755
|
if ('string' === typeof location) {
|
|
723
756
|
let resolvedLocation = owner.lookup(`location:${location}`);
|
|
@@ -729,6 +762,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
729
762
|
url: 'https://emberjs.com/deprecations/v4.x#toc_deprecate-auto-location',
|
|
730
763
|
for: 'ember-source',
|
|
731
764
|
since: {
|
|
765
|
+
available: '4.1.0',
|
|
732
766
|
enabled: '4.1.0'
|
|
733
767
|
}
|
|
734
768
|
});
|
|
@@ -761,6 +795,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
761
795
|
url: 'https://emberjs.com/deprecations/v4.x#toc_deprecate-auto-location',
|
|
762
796
|
for: 'ember-source',
|
|
763
797
|
since: {
|
|
798
|
+
available: '4.1.0',
|
|
764
799
|
enabled: '4.1.0'
|
|
765
800
|
}
|
|
766
801
|
});
|
|
@@ -990,12 +1025,11 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
990
1025
|
let qps = [];
|
|
991
1026
|
let qpsByUrlKey = DEBUG ? {} : null;
|
|
992
1027
|
let qpMeta;
|
|
993
|
-
let qp;
|
|
994
1028
|
let urlKey;
|
|
995
1029
|
let qpOther;
|
|
996
1030
|
|
|
997
|
-
for (let
|
|
998
|
-
qpMeta = this._getQPMeta(
|
|
1031
|
+
for (let routeInfo of routeInfos) {
|
|
1032
|
+
qpMeta = this._getQPMeta(routeInfo);
|
|
999
1033
|
|
|
1000
1034
|
if (!qpMeta) {
|
|
1001
1035
|
shouldCache = false;
|
|
@@ -1003,9 +1037,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1003
1037
|
} // Loop over each QP to make sure we don't have any collisions by urlKey
|
|
1004
1038
|
|
|
1005
1039
|
|
|
1006
|
-
for (let
|
|
1007
|
-
qp = qpMeta.qps[i];
|
|
1008
|
-
|
|
1040
|
+
for (let qp of qpMeta.qps) {
|
|
1009
1041
|
if (DEBUG) {
|
|
1010
1042
|
urlKey = qp.urlKey;
|
|
1011
1043
|
qpOther = qpsByUrlKey[urlKey];
|
|
@@ -1051,19 +1083,15 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1051
1083
|
let routeInfos = state.routeInfos;
|
|
1052
1084
|
let qpMeta;
|
|
1053
1085
|
|
|
1054
|
-
for (let
|
|
1055
|
-
qpMeta = this._getQPMeta(
|
|
1086
|
+
for (let routeInfo of routeInfos) {
|
|
1087
|
+
qpMeta = this._getQPMeta(routeInfo);
|
|
1056
1088
|
|
|
1057
1089
|
if (!qpMeta) {
|
|
1058
1090
|
continue;
|
|
1059
1091
|
}
|
|
1060
1092
|
|
|
1061
|
-
let qp
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
for (let j = 0, qpLen = qpMeta.qps.length; j < qpLen; ++j) {
|
|
1065
|
-
qp = qpMeta.qps[j];
|
|
1066
|
-
presentProp = qp.prop in queryParams && qp.prop || qp.scopedPropertyName in queryParams && qp.scopedPropertyName || qp.urlKey in queryParams && qp.urlKey;
|
|
1093
|
+
for (let qp of qpMeta.qps) {
|
|
1094
|
+
let presentProp = qp.prop in queryParams && qp.prop || qp.scopedPropertyName in queryParams && qp.scopedPropertyName || qp.urlKey in queryParams && qp.urlKey;
|
|
1067
1095
|
|
|
1068
1096
|
if (presentProp) {
|
|
1069
1097
|
if (presentProp !== qp.scopedPropertyName) {
|
|
@@ -1093,15 +1121,17 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1093
1121
|
let qp;
|
|
1094
1122
|
let presentProp;
|
|
1095
1123
|
|
|
1096
|
-
for (let
|
|
1097
|
-
qpMeta = this._getQPMeta(
|
|
1124
|
+
for (let routeInfo of routeInfos) {
|
|
1125
|
+
qpMeta = this._getQPMeta(routeInfo);
|
|
1098
1126
|
|
|
1099
1127
|
if (!qpMeta) {
|
|
1100
1128
|
continue;
|
|
1101
|
-
}
|
|
1129
|
+
} // Needs to stay for index loop to avoid throwIfClosureRequired
|
|
1130
|
+
|
|
1102
1131
|
|
|
1103
1132
|
for (let j = 0, qpLen = qpMeta.qps.length; j < qpLen; ++j) {
|
|
1104
1133
|
qp = qpMeta.qps[j];
|
|
1134
|
+
assert('expected qp', qp);
|
|
1105
1135
|
presentProp = qp.prop in queryParams && qp.prop || qp.scopedPropertyName in queryParams && qp.scopedPropertyName || qp.urlKey in queryParams && qp.urlKey;
|
|
1106
1136
|
assert(`You passed the \`${presentProp}\` query parameter during a transition into ${qp.route.routeName}, please update to ${qp.urlKey}`, function () {
|
|
1107
1137
|
if (qp.urlKey === presentProp || qp.scopedPropertyName === presentProp) {
|
|
@@ -1178,22 +1208,27 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1178
1208
|
mountPoint
|
|
1179
1209
|
}) {
|
|
1180
1210
|
let engineInstances = this._engineInstances;
|
|
1211
|
+
let namedInstances = engineInstances[name];
|
|
1212
|
+
|
|
1213
|
+
if (!namedInstances) {
|
|
1214
|
+
namedInstances = Object.create(null);
|
|
1215
|
+
engineInstances[name] = namedInstances;
|
|
1216
|
+
} // We just set these!
|
|
1181
1217
|
|
|
1182
|
-
if (!engineInstances[name]) {
|
|
1183
|
-
engineInstances[name] = Object.create(null);
|
|
1184
|
-
}
|
|
1185
1218
|
|
|
1186
|
-
|
|
1219
|
+
assert('has namedInstances', namedInstances);
|
|
1220
|
+
let engineInstance = namedInstances[instanceId];
|
|
1187
1221
|
|
|
1188
1222
|
if (!engineInstance) {
|
|
1189
1223
|
let owner = getOwner(this);
|
|
1224
|
+
assert('Router is unexpectedly missing an owner', owner);
|
|
1190
1225
|
assert(`You attempted to mount the engine '${name}' in your router map, but the engine can not be found.`, owner.hasRegistration(`engine:${name}`));
|
|
1191
1226
|
engineInstance = owner.buildChildEngineInstance(name, {
|
|
1192
1227
|
routable: true,
|
|
1193
1228
|
mountPoint
|
|
1194
1229
|
});
|
|
1195
1230
|
engineInstance.boot();
|
|
1196
|
-
|
|
1231
|
+
namedInstances[instanceId] = engineInstance;
|
|
1197
1232
|
}
|
|
1198
1233
|
|
|
1199
1234
|
return engineInstance;
|
|
@@ -1220,6 +1255,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1220
1255
|
function forEachRouteAbove(routeInfos, callback) {
|
|
1221
1256
|
for (let i = routeInfos.length - 1; i >= 0; --i) {
|
|
1222
1257
|
let routeInfo = routeInfos[i];
|
|
1258
|
+
assert('has routeInfo', routeInfo);
|
|
1223
1259
|
let route = routeInfo.route; // routeInfo.handler being `undefined` generally means either:
|
|
1224
1260
|
//
|
|
1225
1261
|
// 1. an error occurred during creation of the route in question
|
|
@@ -1354,6 +1390,7 @@ function logError(_error, initialMessage) {
|
|
|
1354
1390
|
|
|
1355
1391
|
function findRouteSubstateName(route, state) {
|
|
1356
1392
|
let owner = getOwner(route);
|
|
1393
|
+
assert('Route is unexpectedly missing an owner', owner);
|
|
1357
1394
|
let {
|
|
1358
1395
|
routeName,
|
|
1359
1396
|
fullRouteName,
|
|
@@ -1377,6 +1414,7 @@ function findRouteSubstateName(route, state) {
|
|
|
1377
1414
|
|
|
1378
1415
|
function findRouteStateName(route, state) {
|
|
1379
1416
|
let owner = getOwner(route);
|
|
1417
|
+
assert('Route is unexpectedly missing an owner', owner);
|
|
1380
1418
|
let {
|
|
1381
1419
|
routeName,
|
|
1382
1420
|
fullRouteName,
|
|
@@ -1420,6 +1458,7 @@ export function triggerEvent(routeInfos, ignoreFailure, name, args) {
|
|
|
1420
1458
|
|
|
1421
1459
|
for (let i = routeInfos.length - 1; i >= 0; i--) {
|
|
1422
1460
|
routeInfo = routeInfos[i];
|
|
1461
|
+
assert('has routeInfo', routeInfo);
|
|
1423
1462
|
handler = routeInfo.route;
|
|
1424
1463
|
actionHandler = handler && handler.actions && handler.actions[name];
|
|
1425
1464
|
|
|
@@ -1457,9 +1496,8 @@ function calculatePostTransitionState(emberRouter, leafRouteName, contexts) {
|
|
|
1457
1496
|
params
|
|
1458
1497
|
} = state;
|
|
1459
1498
|
|
|
1460
|
-
for (let
|
|
1461
|
-
|
|
1462
|
-
|
|
1499
|
+
for (let routeInfo of routeInfos) {
|
|
1500
|
+
// If the routeInfo is not resolved, we serialize the context into params
|
|
1463
1501
|
if (!routeInfo.isResolved) {
|
|
1464
1502
|
params[routeInfo.name] = routeInfo.serialize(routeInfo.context);
|
|
1465
1503
|
} else {
|
|
@@ -1479,14 +1517,18 @@ function updatePaths(router) {
|
|
|
1479
1517
|
|
|
1480
1518
|
let path = EmberRouter._routePath(infos);
|
|
1481
1519
|
|
|
1482
|
-
let
|
|
1520
|
+
let info = infos[infos.length - 1];
|
|
1521
|
+
assert('expected info', info);
|
|
1522
|
+
let currentRouteName = info.name;
|
|
1483
1523
|
let location = router.location;
|
|
1484
1524
|
assert('expected location to not be a string', typeof location !== 'string');
|
|
1485
1525
|
let currentURL = location.getURL();
|
|
1486
1526
|
set(router, 'currentPath', path);
|
|
1487
1527
|
set(router, 'currentRouteName', currentRouteName);
|
|
1488
1528
|
set(router, 'currentURL', currentURL);
|
|
1489
|
-
let
|
|
1529
|
+
let owner = getOwner(router);
|
|
1530
|
+
assert('Router is unexpectedly missing an owner', owner);
|
|
1531
|
+
let appController = owner.lookup('controller:application');
|
|
1490
1532
|
|
|
1491
1533
|
if (!appController) {
|
|
1492
1534
|
// appController might not exist when top-level loading/error
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import { get } from '@ember/-internals/metal';
|
|
2
2
|
import { getOwner } from '@ember/-internals/owner';
|
|
3
|
-
import { deprecate } from '@ember/debug';
|
|
3
|
+
import { assert, deprecate } from '@ember/debug';
|
|
4
4
|
import EmberError from '@ember/error';
|
|
5
5
|
import { STATE_SYMBOL } from 'router_js';
|
|
6
6
|
const ALL_PERIODS_REGEX = /\./g;
|
|
7
7
|
export function extractRouteArgs(args) {
|
|
8
|
+
// SAFETY: This should just be the same thing
|
|
8
9
|
args = args.slice();
|
|
9
|
-
let
|
|
10
|
+
let possibleOptions = args[args.length - 1];
|
|
10
11
|
let queryParams;
|
|
11
12
|
|
|
12
|
-
if (
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// ***this is unsafe and should be changed***.
|
|
17
|
-
queryParams = args.pop().queryParams;
|
|
13
|
+
if (isRouteOptions(possibleOptions)) {
|
|
14
|
+
args.pop(); // Remove options
|
|
15
|
+
|
|
16
|
+
queryParams = possibleOptions.queryParams;
|
|
18
17
|
} else {
|
|
19
18
|
queryParams = {};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let routeName;
|
|
22
|
+
|
|
23
|
+
if (typeof args[0] === 'string') {
|
|
24
|
+
routeName = args.shift(); // We just checked this!
|
|
25
|
+
|
|
26
|
+
assert('routeName is a string', typeof routeName === 'string');
|
|
27
|
+
} // SAFTEY: We removed the name and options if they existed, only models left.
|
|
23
28
|
|
|
24
29
|
|
|
25
|
-
let routeName = args.shift();
|
|
26
30
|
let models = args;
|
|
27
31
|
return {
|
|
28
32
|
routeName,
|
|
@@ -32,7 +36,9 @@ export function extractRouteArgs(args) {
|
|
|
32
36
|
}
|
|
33
37
|
export function getActiveTargetName(router) {
|
|
34
38
|
let routeInfos = router.activeTransition ? router.activeTransition[STATE_SYMBOL].routeInfos : router.state.routeInfos;
|
|
35
|
-
|
|
39
|
+
let lastRouteInfo = routeInfos[routeInfos.length - 1];
|
|
40
|
+
assert('has last route info', lastRouteInfo);
|
|
41
|
+
return lastRouteInfo.name;
|
|
36
42
|
}
|
|
37
43
|
export function stashParamNames(router, routeInfos) {
|
|
38
44
|
if (routeInfos['_namesStashed']) {
|
|
@@ -43,7 +49,9 @@ export function stashParamNames(router, routeInfos) {
|
|
|
43
49
|
// Hopefully we can remove this in the future.
|
|
44
50
|
|
|
45
51
|
|
|
46
|
-
let
|
|
52
|
+
let routeInfo = routeInfos[routeInfos.length - 1];
|
|
53
|
+
assert('has route info', routeInfo);
|
|
54
|
+
let targetRouteName = routeInfo.name;
|
|
47
55
|
|
|
48
56
|
let recogHandlers = router._routerMicrolib.recognizer.handlersFor(targetRouteName);
|
|
49
57
|
|
|
@@ -51,6 +59,7 @@ export function stashParamNames(router, routeInfos) {
|
|
|
51
59
|
|
|
52
60
|
for (let i = 0; i < routeInfos.length; ++i) {
|
|
53
61
|
let routeInfo = routeInfos[i];
|
|
62
|
+
assert('has route info', routeInfo);
|
|
54
63
|
let names = recogHandlers[i].names;
|
|
55
64
|
|
|
56
65
|
if (names.length) {
|
|
@@ -58,7 +67,7 @@ export function stashParamNames(router, routeInfos) {
|
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
routeInfo['_names'] = names;
|
|
61
|
-
let route = routeInfo.route;
|
|
70
|
+
let route = routeInfo.route; // SAFETY: This cast should be idential. I don't understand why it is needed.
|
|
62
71
|
|
|
63
72
|
route._stashNames(routeInfo, dynamicParent);
|
|
64
73
|
}
|
|
@@ -96,9 +105,7 @@ function _calculateCacheValuePrefix(prefix, part) {
|
|
|
96
105
|
export function calculateCacheKey(prefix, parts = [], values) {
|
|
97
106
|
let suffixes = '';
|
|
98
107
|
|
|
99
|
-
for (let
|
|
100
|
-
let part = parts[i];
|
|
101
|
-
|
|
108
|
+
for (let part of parts) {
|
|
102
109
|
let cacheValuePrefix = _calculateCacheValuePrefix(prefix, part);
|
|
103
110
|
|
|
104
111
|
let value;
|
|
@@ -153,8 +160,8 @@ export function calculateCacheKey(prefix, parts = [], values) {
|
|
|
153
160
|
export function normalizeControllerQueryParams(queryParams) {
|
|
154
161
|
let qpMap = {};
|
|
155
162
|
|
|
156
|
-
for (let
|
|
157
|
-
accumulateQueryParamDescriptors(
|
|
163
|
+
for (let queryParam of queryParams) {
|
|
164
|
+
accumulateQueryParamDescriptors(queryParam, qpMap);
|
|
158
165
|
}
|
|
159
166
|
|
|
160
167
|
return qpMap;
|
|
@@ -185,12 +192,12 @@ function accumulateQueryParamDescriptors(_desc, accum) {
|
|
|
185
192
|
};
|
|
186
193
|
}
|
|
187
194
|
|
|
188
|
-
|
|
195
|
+
let val = accum[key] || {
|
|
189
196
|
as: null,
|
|
190
197
|
scope: 'model'
|
|
191
198
|
};
|
|
192
|
-
Object.assign(
|
|
193
|
-
accum[key] =
|
|
199
|
+
Object.assign(val, singleDesc);
|
|
200
|
+
accum[key] = val;
|
|
194
201
|
}
|
|
195
202
|
}
|
|
196
203
|
/*
|
|
@@ -210,11 +217,14 @@ export function resemblesURL(str) {
|
|
|
210
217
|
*/
|
|
211
218
|
|
|
212
219
|
export function prefixRouteNameArg(route, args) {
|
|
213
|
-
let routeName
|
|
220
|
+
let routeName;
|
|
214
221
|
let owner = getOwner(route);
|
|
222
|
+
assert('Route is unexpectedly missing an owner', owner);
|
|
215
223
|
let prefix = owner.mountPoint; // only alter the routeName if it's actually referencing a route.
|
|
216
224
|
|
|
217
|
-
if (owner.routable && typeof
|
|
225
|
+
if (owner.routable && typeof args[0] === 'string') {
|
|
226
|
+
routeName = args[0];
|
|
227
|
+
|
|
218
228
|
if (resemblesURL(routeName)) {
|
|
219
229
|
throw new EmberError('Programmatic transitions by URL cannot be used within an Engine. Please use the route name instead.');
|
|
220
230
|
} else {
|
|
@@ -253,9 +263,22 @@ export function deprecateTransitionMethods(frameworkClass, methodName) {
|
|
|
253
263
|
id: 'routing.transition-methods',
|
|
254
264
|
for: 'ember-source',
|
|
255
265
|
since: {
|
|
266
|
+
available: '3.26.0',
|
|
256
267
|
enabled: '3.26.0'
|
|
257
268
|
},
|
|
258
269
|
until: '5.0.0',
|
|
259
270
|
url: 'https://deprecations.emberjs.com/v3.x/#toc_routing-transition-methods'
|
|
260
271
|
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function isRouteOptions(value) {
|
|
275
|
+
if (value && typeof value === 'object') {
|
|
276
|
+
let qps = value.queryParams;
|
|
277
|
+
|
|
278
|
+
if (qps && typeof qps === 'object') {
|
|
279
|
+
return Object.keys(qps).every(k => typeof k === 'string');
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return false;
|
|
261
284
|
}
|
|
@@ -952,6 +952,7 @@ const ArrayMixin = Mixin.create(Enumerable, {
|
|
|
952
952
|
@return {Object} The reduced value.
|
|
953
953
|
@public
|
|
954
954
|
*/
|
|
955
|
+
// FIXME: When called without initialValue, behavior does not match native behavior
|
|
955
956
|
reduce(callback, initialValue) {
|
|
956
957
|
assert('`reduce` expects a function as first argument.', typeof callback === 'function');
|
|
957
958
|
let ret = initialValue;
|
|
@@ -18,13 +18,13 @@ import { Mixin } from '@ember/-internals/metal';
|
|
|
18
18
|
export default Mixin.create({
|
|
19
19
|
/**
|
|
20
20
|
__Required.__ You must implement this method to apply this mixin.
|
|
21
|
-
|
|
21
|
+
Override to return the result of the comparison of the two parameters. The
|
|
22
22
|
compare method should return:
|
|
23
|
-
|
|
23
|
+
- `-1` if `a < b`
|
|
24
24
|
- `0` if `a == b`
|
|
25
25
|
- `1` if `a > b`
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
Default implementation raises an exception.
|
|
27
|
+
@method compare
|
|
28
28
|
@param a {Object} the first object to compare
|
|
29
29
|
@param b {Object} the second object to compare
|
|
30
30
|
@return {Number} the result of the comparison
|
|
@@ -15,7 +15,7 @@ import { Mixin } from '@ember/-internals/metal';
|
|
|
15
15
|
let containerProxyMixin = {
|
|
16
16
|
/**
|
|
17
17
|
The container stores state.
|
|
18
|
-
|
|
18
|
+
@private
|
|
19
19
|
@property {Ember.Container} __container__
|
|
20
20
|
*/
|
|
21
21
|
__container__: null,
|
|
@@ -23,16 +23,16 @@ let containerProxyMixin = {
|
|
|
23
23
|
/**
|
|
24
24
|
Returns an object that can be used to provide an owner to a
|
|
25
25
|
manually created instance.
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
Example:
|
|
27
|
+
```
|
|
28
28
|
import { getOwner } from '@ember/application';
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
let owner = getOwner(this);
|
|
30
|
+
User.create(
|
|
31
31
|
owner.ownerInjection(),
|
|
32
32
|
{ username: 'rwjblue' }
|
|
33
33
|
)
|
|
34
34
|
```
|
|
35
|
-
|
|
35
|
+
@public
|
|
36
36
|
@method ownerInjection
|
|
37
37
|
@since 2.3.0
|
|
38
38
|
@return {Object}
|
|
@@ -43,30 +43,30 @@ let containerProxyMixin = {
|
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
Given a fullName return a corresponding instance.
|
|
46
|
-
|
|
46
|
+
The default behavior is for lookup to return a singleton instance.
|
|
47
47
|
The singleton is scoped to the container, allowing multiple containers
|
|
48
48
|
to all have their own locally scoped singletons.
|
|
49
|
-
|
|
49
|
+
```javascript
|
|
50
50
|
let registry = new Registry();
|
|
51
51
|
let container = registry.container();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
registry.register('api:twitter', Twitter);
|
|
53
|
+
let twitter = container.lookup('api:twitter');
|
|
54
|
+
twitter instanceof Twitter; // => true
|
|
55
|
+
// by default the container will return singletons
|
|
56
56
|
let twitter2 = container.lookup('api:twitter');
|
|
57
57
|
twitter2 instanceof Twitter; // => true
|
|
58
|
-
|
|
58
|
+
twitter === twitter2; //=> true
|
|
59
59
|
```
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
If singletons are not wanted an optional flag can be provided at lookup.
|
|
61
|
+
```javascript
|
|
62
62
|
let registry = new Registry();
|
|
63
63
|
let container = registry.container();
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
registry.register('api:twitter', Twitter);
|
|
65
|
+
let twitter = container.lookup('api:twitter', { singleton: false });
|
|
66
66
|
let twitter2 = container.lookup('api:twitter', { singleton: false });
|
|
67
|
-
|
|
67
|
+
twitter === twitter2; //=> false
|
|
68
68
|
```
|
|
69
|
-
|
|
69
|
+
@public
|
|
70
70
|
@method lookup
|
|
71
71
|
@param {String} fullName
|
|
72
72
|
@param {Object} options
|
|
@@ -91,32 +91,32 @@ let containerProxyMixin = {
|
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
Given a fullName return a factory manager.
|
|
94
|
-
|
|
94
|
+
This method returns a manager which can be used for introspection of the
|
|
95
95
|
factory's class or for the creation of factory instances with initial
|
|
96
96
|
properties. The manager is an object with the following properties:
|
|
97
|
-
|
|
97
|
+
* `class` - The registered or resolved class.
|
|
98
98
|
* `create` - A function that will create an instance of the class with
|
|
99
99
|
any dependencies injected.
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
For example:
|
|
101
|
+
```javascript
|
|
102
102
|
import { getOwner } from '@ember/application';
|
|
103
|
-
|
|
103
|
+
let owner = getOwner(otherInstance);
|
|
104
104
|
// the owner is commonly the `applicationInstance`, and can be accessed via
|
|
105
105
|
// an instance initializer.
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
let factory = owner.factoryFor('service:bespoke');
|
|
107
|
+
factory.class;
|
|
108
108
|
// The registered or resolved class. For example when used with an Ember-CLI
|
|
109
109
|
// app, this would be the default export from `app/services/bespoke.js`.
|
|
110
|
-
|
|
110
|
+
let instance = factory.create({
|
|
111
111
|
someProperty: 'an initial property value'
|
|
112
112
|
});
|
|
113
113
|
// Create an instance with any injections and the passed options as
|
|
114
114
|
// initial properties.
|
|
115
115
|
```
|
|
116
|
-
|
|
116
|
+
Any instances created via the factory's `.create()` method *must* be destroyed
|
|
117
117
|
manually by the caller of `.create()`. Typically, this is done during the creating
|
|
118
118
|
objects own `destroy` or `willDestroy` methods.
|
|
119
|
-
|
|
119
|
+
@public
|
|
120
120
|
@method factoryFor
|
|
121
121
|
@param {String} fullName
|
|
122
122
|
@param {Object} options
|