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.
Files changed (71) hide show
  1. package/CHANGELOG.md +6 -2
  2. package/blueprints/component-addon/index.js +2 -3
  3. package/blueprints/component-class-addon/index.js +2 -3
  4. package/blueprints/controller/files/__root__/__path__/__name__.js +2 -2
  5. package/blueprints/controller/index.js +2 -4
  6. package/blueprints/route/files/__root__/__path__/__name__.js +3 -3
  7. package/blueprints/route/index.js +2 -3
  8. package/blueprints/service/files/__root__/__path__/__name__.js +2 -2
  9. package/blueprints/service/index.js +2 -4
  10. package/build-metadata.json +3 -3
  11. package/dist/dependencies/router_js.js +66 -31
  12. package/dist/ember-template-compiler.js +1250 -861
  13. package/dist/ember-template-compiler.map +1 -1
  14. package/dist/ember-testing.js +88 -56
  15. package/dist/ember-testing.map +1 -1
  16. package/dist/ember.debug.js +3712 -3159
  17. package/dist/ember.debug.map +1 -1
  18. package/dist/header/license.js +1 -1
  19. package/dist/header/loader.js +0 -1
  20. package/dist/packages/@ember/-internals/bootstrap/index.js +0 -2
  21. package/dist/packages/@ember/-internals/container/index.js +16 -11
  22. package/dist/packages/@ember/-internals/extension-support/lib/container_debug_adapter.js +3 -3
  23. package/dist/packages/@ember/-internals/extension-support/lib/data_adapter.js +52 -52
  24. package/dist/packages/@ember/-internals/glimmer/index.js +161 -125
  25. package/dist/packages/@ember/-internals/meta/lib/meta.js +67 -11
  26. package/dist/packages/@ember/-internals/metal/index.js +95 -121
  27. package/dist/packages/@ember/-internals/routing/lib/ext/controller.js +24 -12
  28. package/dist/packages/@ember/-internals/routing/lib/location/api.js +1 -0
  29. package/dist/packages/@ember/-internals/routing/lib/location/auto_location.js +3 -1
  30. package/dist/packages/@ember/-internals/routing/lib/services/router.js +117 -197
  31. package/dist/packages/@ember/-internals/routing/lib/services/routing.js +3 -1
  32. package/dist/packages/@ember/-internals/routing/lib/system/route-info.js +2 -2
  33. package/dist/packages/@ember/-internals/routing/lib/system/route.js +147 -402
  34. package/dist/packages/@ember/-internals/routing/lib/system/router.js +82 -40
  35. package/dist/packages/@ember/-internals/routing/lib/utils.js +48 -25
  36. package/dist/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
  37. package/dist/packages/@ember/-internals/runtime/lib/mixins/array.js +1 -0
  38. package/dist/packages/@ember/-internals/runtime/lib/mixins/comparable.js +4 -4
  39. package/dist/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +29 -29
  40. package/dist/packages/@ember/-internals/runtime/lib/mixins/promise_proxy.js +16 -16
  41. package/dist/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +48 -48
  42. package/dist/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +8 -8
  43. package/dist/packages/@ember/-internals/runtime/lib/system/namespace.js +1 -2
  44. package/dist/packages/@ember/-internals/runtime/lib/type-of.js +1 -1
  45. package/dist/packages/@ember/-internals/utils/index.js +11 -9
  46. package/dist/packages/@ember/-internals/views/lib/mixins/view_support.js +2 -4
  47. package/dist/packages/@ember/-internals/views/lib/system/utils.js +2 -0
  48. package/dist/packages/@ember/application/lib/application.js +0 -2
  49. package/dist/packages/@ember/array/index.js +1 -1
  50. package/dist/packages/@ember/canary-features/index.js +2 -2
  51. package/dist/packages/@ember/controller/index.js +3 -54
  52. package/dist/packages/@ember/debug/index.js +1 -1
  53. package/dist/packages/@ember/debug/lib/deprecate.js +12 -10
  54. package/dist/packages/@ember/instrumentation/index.js +9 -13
  55. package/dist/packages/@ember/object/compat.js +16 -7
  56. package/dist/packages/@ember/polyfills/lib/assign.js +1 -0
  57. package/dist/packages/@ember/routing/router-service.js +1 -0
  58. package/dist/packages/@ember/runloop/index.js +9 -9
  59. package/dist/packages/@ember/service/index.js +6 -73
  60. package/dist/packages/@ember/string/index.js +1 -0
  61. package/dist/packages/ember/index.js +1 -2
  62. package/dist/packages/ember/version.js +1 -1
  63. package/docs/data.json +2588 -1839
  64. package/package.json +27 -27
  65. package/blueprints/component-addon/native-files/__root__/__path__/__name__.js +0 -1
  66. package/blueprints/component-class-addon/native-files/__root__/__path__/__name__.js +0 -1
  67. package/blueprints/controller/native-files/__root__/__path__/__name__.js +0 -4
  68. package/blueprints/edition-detector.js +0 -13
  69. package/blueprints/route/native-files/__root__/__path__/__name__.js +0 -11
  70. package/blueprints/route/native-files/__root__/__templatepath__/__templatename__.hbs +0 -2
  71. 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
- name = routeInfos[i].name;
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
- let owner = getOwner(this);
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
- let owner = getOwner(this);
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 i = 0; i < routeInfos.length; i++) {
471
- let route = routeInfos[i].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
- assert('expected infos to be set', infos);
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
- for (let id in instances[name]) {
675
- run(instances[name][id], 'destroy');
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 i = 0; i < routeInfoLength; ++i) {
998
- qpMeta = this._getQPMeta(routeInfos[i]);
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 i = 0; i < qpMeta.qps.length; i++) {
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 i = 0, len = routeInfos.length; i < len; ++i) {
1055
- qpMeta = this._getQPMeta(routeInfos[i]);
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
- let presentProp;
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 i = 0; i < routeInfos.length; ++i) {
1097
- qpMeta = this._getQPMeta(routeInfos[i]);
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
- let engineInstance = engineInstances[name][instanceId];
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
- engineInstances[name][instanceId] = engineInstance;
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 i = 0; i < routeInfos.length; ++i) {
1461
- let routeInfo = routeInfos[i]; // If the routeInfo is not resolved, we serialize the context into params
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 currentRouteName = infos[infos.length - 1].name;
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 appController = getOwner(router).lookup('controller:application');
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 possibleQueryParams = args[args.length - 1];
10
+ let possibleOptions = args[args.length - 1];
10
11
  let queryParams;
11
12
 
12
- if (possibleQueryParams && Object.prototype.hasOwnProperty.call(possibleQueryParams, 'queryParams')) {
13
- // SAFETY: this cast is safe because we have just checked whether
14
- // `possibleQueryParams` -- defined as the last item in args -- both exists
15
- // and has the property `queryParams`. If either of these invariants change,
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
- } // UNSAFE: these are simply assumed as the existing behavior of the system.
21
- // However, this could break if upstream refactors change it, and the types
22
- // here would not be able to tell us; we would lie to everything downstream.
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
- return routeInfos[routeInfos.length - 1].name;
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 targetRouteName = routeInfos[routeInfos.length - 1].name;
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 i = 0; i < parts.length; ++i) {
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 i = 0; i < queryParams.length; ++i) {
157
- accumulateQueryParamDescriptors(queryParams[i], qpMap);
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
- tmp = accum[key] || {
195
+ let val = accum[key] || {
189
196
  as: null,
190
197
  scope: 'model'
191
198
  };
192
- Object.assign(tmp, singleDesc);
193
- accum[key] = tmp;
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 = args[0];
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 routeName === 'string') {
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
  }
@@ -53,7 +53,7 @@ function customTagForProxy(proxy, key, addMandatorySetter) {
53
53
  export default Mixin.create({
54
54
  /**
55
55
  The object whose properties will be forwarded.
56
- @property content
56
+ @property content
57
57
  @type {unknown}
58
58
  @default null
59
59
  @public
@@ -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
- Override to return the result of the comparison of the two parameters. The
21
+ Override to return the result of the comparison of the two parameters. The
22
22
  compare method should return:
23
- - `-1` if `a < b`
23
+ - `-1` if `a < b`
24
24
  - `0` if `a == b`
25
25
  - `1` if `a > b`
26
- Default implementation raises an exception.
27
- @method compare
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
- @private
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
- Example:
27
- ```
26
+ Example:
27
+ ```
28
28
  import { getOwner } from '@ember/application';
29
- let owner = getOwner(this);
30
- User.create(
29
+ let owner = getOwner(this);
30
+ User.create(
31
31
  owner.ownerInjection(),
32
32
  { username: 'rwjblue' }
33
33
  )
34
34
  ```
35
- @public
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
- The default behavior is for lookup to return a singleton instance.
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
- ```javascript
49
+ ```javascript
50
50
  let registry = new Registry();
51
51
  let container = registry.container();
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
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
- twitter === twitter2; //=> true
58
+ twitter === twitter2; //=> true
59
59
  ```
60
- If singletons are not wanted an optional flag can be provided at lookup.
61
- ```javascript
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
- registry.register('api:twitter', Twitter);
65
- let twitter = container.lookup('api:twitter', { singleton: false });
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
- twitter === twitter2; //=> false
67
+ twitter === twitter2; //=> false
68
68
  ```
69
- @public
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
- This method returns a manager which can be used for introspection of the
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
- * `class` - The registered or resolved class.
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
- For example:
101
- ```javascript
100
+ For example:
101
+ ```javascript
102
102
  import { getOwner } from '@ember/application';
103
- let owner = getOwner(otherInstance);
103
+ let owner = getOwner(otherInstance);
104
104
  // the owner is commonly the `applicationInstance`, and can be accessed via
105
105
  // an instance initializer.
106
- let factory = owner.factoryFor('service:bespoke');
107
- factory.class;
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
- let instance = factory.create({
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
- Any instances created via the factory's `.create()` method *must* be destroyed
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
- @public
119
+ @public
120
120
  @method factoryFor
121
121
  @param {String} fullName
122
122
  @param {Object} options