ember-source 4.4.0-alpha.1 → 4.4.0-alpha.4

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 (110) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/blueprints/acceptance-test/mocha-files/tests/acceptance/__name__-test.js +4 -4
  3. package/blueprints/acceptance-test/mocha-rfc-232-files/tests/acceptance/__name__-test.js +3 -3
  4. package/blueprints/acceptance-test/qunit-files/tests/acceptance/__name__-test.js +2 -2
  5. package/blueprints/acceptance-test/qunit-rfc-232-files/tests/acceptance/__name__-test.js +3 -3
  6. package/blueprints/component/index.js +2 -2
  7. package/blueprints/component-class/index.js +2 -2
  8. package/blueprints/component-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +4 -4
  9. package/blueprints/component-test/mocha-files/__root__/__testType__/__path__/__test__.js +7 -5
  10. package/blueprints/component-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +6 -6
  11. package/blueprints/component-test/qunit-files/__root__/__testType__/__path__/__test__.js +4 -4
  12. package/blueprints/component-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +6 -6
  13. package/blueprints/controller/files/__root__/__path__/__name__.js +1 -2
  14. package/blueprints/controller-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
  15. package/blueprints/controller-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
  16. package/blueprints/controller-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
  17. package/blueprints/controller-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
  18. package/blueprints/controller-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
  19. package/blueprints/helper/files/__root__/__collection__/__name__.js +1 -1
  20. package/blueprints/helper/mu-files/__root__/__collection__/__name__.js +1 -1
  21. package/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js +3 -3
  22. package/blueprints/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js +6 -4
  23. package/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +3 -3
  24. package/blueprints/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js +2 -2
  25. package/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +3 -3
  26. package/blueprints/initializer/files/__root__/initializers/__name__.js +2 -3
  27. package/blueprints/initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +6 -7
  28. package/blueprints/initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +5 -5
  29. package/blueprints/initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +3 -4
  30. package/blueprints/instance-initializer/files/__root__/instance-initializers/__name__.js +2 -3
  31. package/blueprints/instance-initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +5 -5
  32. package/blueprints/instance-initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +5 -5
  33. package/blueprints/instance-initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +2 -2
  34. package/blueprints/mixin/files/__root__/mixins/__name__.js +1 -2
  35. package/blueprints/mixin-test/mocha-files/__root__/__testType__/__name__-test.js +2 -2
  36. package/blueprints/mixin-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +2 -2
  37. package/blueprints/mixin-test/qunit-files/__root__/__testType__/__name__-test.js +1 -1
  38. package/blueprints/mixin-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +1 -1
  39. package/blueprints/route/files/__root__/__path__/__name__.js +2 -2
  40. package/blueprints/route-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
  41. package/blueprints/route-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
  42. package/blueprints/route-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
  43. package/blueprints/route-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
  44. package/blueprints/route-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
  45. package/blueprints/service/files/__root__/__path__/__name__.js +1 -2
  46. package/blueprints/service-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
  47. package/blueprints/service-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
  48. package/blueprints/service-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
  49. package/blueprints/service-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
  50. package/blueprints/service-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
  51. package/blueprints/util-test/mocha-files/__root__/__testType__/__name__-test.js +2 -2
  52. package/blueprints/util-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +2 -2
  53. package/blueprints/util-test/qunit-files/__root__/__testType__/__name__-test.js +1 -1
  54. package/blueprints/util-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +2 -3
  55. package/build-metadata.json +3 -3
  56. package/dist/dependencies/router_js.js +1 -1
  57. package/dist/ember-template-compiler.js +20 -143
  58. package/dist/ember-template-compiler.map +1 -1
  59. package/dist/ember-testing.js +5 -3
  60. package/dist/ember-testing.map +1 -1
  61. package/dist/ember.debug.js +1132 -1719
  62. package/dist/ember.debug.map +1 -1
  63. package/dist/header/license.js +1 -1
  64. package/dist/packages/@ember/-internals/container/index.js +3 -19
  65. package/dist/packages/@ember/-internals/extension-support/lib/container_debug_adapter.js +10 -19
  66. package/dist/packages/@ember/-internals/extension-support/lib/data_adapter.js +113 -112
  67. package/dist/packages/@ember/-internals/glimmer/index.js +163 -773
  68. package/dist/packages/@ember/-internals/metal/index.js +19 -32
  69. package/dist/packages/@ember/-internals/routing/lib/location/hash_location.js +1 -1
  70. package/dist/packages/@ember/-internals/routing/lib/services/router.js +67 -12
  71. package/dist/packages/@ember/-internals/routing/lib/services/routing.js +2 -0
  72. package/dist/packages/@ember/-internals/routing/lib/system/generate_controller.js +3 -1
  73. package/dist/packages/@ember/-internals/routing/lib/system/route.js +15 -7
  74. package/dist/packages/@ember/-internals/routing/lib/system/router.js +16 -21
  75. package/dist/packages/@ember/-internals/routing/lib/utils.js +2 -1
  76. package/dist/packages/@ember/-internals/runtime/lib/compare.js +19 -5
  77. package/dist/packages/@ember/-internals/runtime/lib/ext/rsvp.js +8 -4
  78. package/dist/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
  79. package/dist/packages/@ember/-internals/runtime/lib/mixins/array.js +1 -1
  80. package/dist/packages/@ember/-internals/runtime/lib/mixins/comparable.js +4 -4
  81. package/dist/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +29 -29
  82. package/dist/packages/@ember/-internals/runtime/lib/mixins/promise_proxy.js +16 -16
  83. package/dist/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +51 -50
  84. package/dist/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +8 -8
  85. package/dist/packages/@ember/-internals/utils/index.js +1 -1
  86. package/dist/packages/@ember/-internals/views/lib/system/utils.js +4 -2
  87. package/dist/packages/@ember/-internals/views/lib/views/core_view.js +5 -22
  88. package/dist/packages/@ember/application/instance.js +3 -3
  89. package/dist/packages/@ember/canary-features/index.js +4 -12
  90. package/dist/packages/@ember/debug/index.js +1 -1
  91. package/dist/packages/@ember/debug/lib/capture-render-tree.js +2 -0
  92. package/dist/packages/@ember/debug/lib/handlers.js +1 -1
  93. package/dist/packages/@ember/renderer/index.js +21 -0
  94. package/dist/packages/@ember/runloop/index.js +31 -528
  95. package/dist/packages/@ember/runloop/type-tests.ts/begin-end.test.js +5 -0
  96. package/dist/packages/@ember/runloop/type-tests.ts/bind.test.js +59 -0
  97. package/dist/packages/@ember/runloop/type-tests.ts/cancel.test.js +5 -0
  98. package/dist/packages/@ember/runloop/type-tests.ts/debounce.test.js +77 -0
  99. package/dist/packages/@ember/runloop/type-tests.ts/join.test.js +38 -0
  100. package/dist/packages/@ember/runloop/type-tests.ts/later.test.js +38 -0
  101. package/dist/packages/@ember/runloop/type-tests.ts/next.test.js +38 -0
  102. package/dist/packages/@ember/runloop/type-tests.ts/once.test.js +38 -0
  103. package/dist/packages/@ember/runloop/type-tests.ts/run.test.js +38 -0
  104. package/dist/packages/@ember/runloop/type-tests.ts/schedule-once.test.js +39 -0
  105. package/dist/packages/@ember/runloop/type-tests.ts/schedule.test.js +39 -0
  106. package/dist/packages/@ember/runloop/type-tests.ts/throttle.test.js +77 -0
  107. package/dist/packages/ember/index.js +4 -14
  108. package/dist/packages/ember/version.js +1 -1
  109. package/docs/data.json +658 -383
  110. package/package.json +10 -10
@@ -145,7 +145,7 @@ function sendEvent(obj, eventName, params, actions, _meta) {
145
145
  return true;
146
146
  }
147
147
  /**
148
- @private
148
+ @public
149
149
  @method hasListeners
150
150
  @static
151
151
  @for @ember/object/events
@@ -1755,9 +1755,6 @@ function isPath(path) {
1755
1755
  return typeof path === 'string' && firstDotIndexCache.get(path) !== -1;
1756
1756
  }
1757
1757
 
1758
- /**
1759
- @module @ember/object
1760
- */
1761
1758
  const PROXY_CONTENT = symbol('PROXY_CONTENT');
1762
1759
  let getPossibleMandatoryProxyValue;
1763
1760
 
@@ -1782,20 +1779,20 @@ function get(obj, keyName) {
1782
1779
  return isPath(keyName) ? _getPath(obj, keyName) : _getProp(obj, keyName);
1783
1780
  }
1784
1781
  function _getProp(obj, keyName) {
1785
- let type = typeof obj;
1786
- let isObject$$1 = type === 'object';
1787
- let isFunction = type === 'function';
1788
- let isObjectLike = isObject$$1 || isFunction;
1782
+ if (obj == null) {
1783
+ return;
1784
+ }
1785
+
1789
1786
  let value;
1790
1787
 
1791
- if (isObjectLike) {
1788
+ if (typeof obj === 'object' || typeof obj === 'function') {
1792
1789
  if (DEBUG) {
1793
1790
  value = getPossibleMandatoryProxyValue(obj, keyName);
1794
1791
  } else {
1795
1792
  value = obj[keyName];
1796
1793
  }
1797
1794
 
1798
- if (value === undefined && isObject$$1 && !(keyName in obj) && typeof obj.unknownProperty === 'function') {
1795
+ if (value === undefined && typeof obj === 'object' && !(keyName in obj) && typeof obj.unknownProperty === 'function') {
1799
1796
  value = obj.unknownProperty(keyName);
1800
1797
  }
1801
1798
 
@@ -1809,13 +1806,13 @@ function _getProp(obj, keyName) {
1809
1806
  }
1810
1807
  }
1811
1808
  } else {
1809
+ // SAFETY: It should be ok to access properties on any non-nullish value
1812
1810
  value = obj[keyName];
1813
1811
  }
1814
1812
 
1815
1813
  return value;
1816
1814
  }
1817
- function _getPath(root, path) {
1818
- let obj = root;
1815
+ function _getPath(obj, path) {
1819
1816
  let parts = typeof path === 'string' ? path.split('.') : path;
1820
1817
 
1821
1818
  for (let part of parts) {
@@ -1838,12 +1835,12 @@ _getProp({}, 'a');
1838
1835
  _getProp({}, 1);
1839
1836
 
1840
1837
  _getProp({
1841
- unkonwnProperty() {}
1838
+ unknownProperty() {}
1842
1839
 
1843
1840
  }, 'a');
1844
1841
 
1845
1842
  _getProp({
1846
- unkonwnProperty() {}
1843
+ unknownProperty() {}
1847
1844
 
1848
1845
  }, 1);
1849
1846
 
@@ -2125,7 +2122,6 @@ function eachProxyArrayDidChange(array, idx, removedCnt, addedCnt) {
2125
2122
  confusing.
2126
2123
 
2127
2124
  ```javascript
2128
- isNone(); // true
2129
2125
  isNone(null); // true
2130
2126
  isNone(undefined); // true
2131
2127
  isNone(''); // false
@@ -2159,7 +2155,6 @@ function isNone(obj) {
2159
2155
  to check emptiness.
2160
2156
 
2161
2157
  ```javascript
2162
- isEmpty(); // true
2163
2158
  isEmpty(null); // true
2164
2159
  isEmpty(undefined); // true
2165
2160
  isEmpty(''); // true
@@ -2183,31 +2178,21 @@ function isNone(obj) {
2183
2178
  */
2184
2179
 
2185
2180
  function isEmpty(obj) {
2186
- let none = obj === null || obj === undefined;
2187
-
2188
- if (none) {
2189
- return none;
2181
+ if (obj === null || obj === undefined) {
2182
+ return true;
2190
2183
  }
2191
2184
 
2192
2185
  if (typeof obj.unknownProperty !== 'function' && typeof obj.size === 'number') {
2193
2186
  return !obj.size;
2194
2187
  }
2195
2188
 
2196
- let objectType = typeof obj;
2197
-
2198
- if (objectType === 'object') {
2189
+ if (typeof obj === 'object') {
2199
2190
  let size = get(obj, 'size');
2200
2191
 
2201
2192
  if (typeof size === 'number') {
2202
2193
  return !size;
2203
2194
  }
2204
- }
2205
2195
 
2206
- if (typeof obj.length === 'number' && objectType !== 'function') {
2207
- return !obj.length;
2208
- }
2209
-
2210
- if (objectType === 'object') {
2211
2196
  let length = get(obj, 'length');
2212
2197
 
2213
2198
  if (typeof length === 'number') {
@@ -2215,6 +2200,10 @@ function isEmpty(obj) {
2215
2200
  }
2216
2201
  }
2217
2202
 
2203
+ if (typeof obj.length === 'number' && typeof obj !== 'function') {
2204
+ return !obj.length;
2205
+ }
2206
+
2218
2207
  return false;
2219
2208
  }
2220
2209
 
@@ -2228,7 +2217,6 @@ function isEmpty(obj) {
2228
2217
  ```javascript
2229
2218
  import { isBlank } from '@ember/utils';
2230
2219
 
2231
- isBlank(); // true
2232
2220
  isBlank(null); // true
2233
2221
  isBlank(undefined); // true
2234
2222
  isBlank(''); // true
@@ -2262,7 +2250,6 @@ function isBlank(obj) {
2262
2250
  A value is present if it not `isBlank`.
2263
2251
 
2264
2252
  ```javascript
2265
- isPresent(); // false
2266
2253
  isPresent(null); // false
2267
2254
  isPresent(undefined); // false
2268
2255
  isPresent(''); // false
@@ -2769,7 +2756,7 @@ function mergeMixins(mixins, meta$$1, descs, values, base, keys, keysWithSuper)
2769
2756
  } else if (mixins !== undefined) {
2770
2757
  mergeMixins(mixins, meta$$1, descs, values, base, keys, keysWithSuper);
2771
2758
 
2772
- if (currentMixin._without !== undefined) {
2759
+ if (currentMixin instanceof Mixin && currentMixin._without !== undefined) {
2773
2760
  currentMixin._without.forEach(keyName => {
2774
2761
  // deleting the key means we won't process the value
2775
2762
  let index = keys.indexOf(keyName);
@@ -124,7 +124,7 @@ export default class HashLocation extends EmberObject {
124
124
  onUpdateURL(callback) {
125
125
  this._removeEventListener();
126
126
 
127
- this._hashchangeHandler = bind(this, function () {
127
+ this._hashchangeHandler = bind(this, function (_event) {
128
128
  let path = this.getURL();
129
129
 
130
130
  if (this.lastSetURL === path) {
@@ -13,6 +13,7 @@ import { assert } from '@ember/debug';
13
13
  import { readOnly } from '@ember/object/computed';
14
14
  import Service from '@ember/service';
15
15
  import { consumeTag, tagFor } from '@glimmer/validator';
16
+ import EmberRouter from '../system/router';
16
17
  import { extractRouteArgs, resemblesURL, shallowEqual } from '../utils';
17
18
  const ROUTER = symbol('ROUTER');
18
19
 
@@ -27,6 +28,55 @@ function cleanURL(url, rootURL) {
27
28
  class RouterService extends Service.extend(Evented) {
28
29
  constructor() {
29
30
  super(...arguments);
31
+ /**
32
+ You can register a listener for events emitted by this service with `.on()`:
33
+ ```app/routes/contact-form.js
34
+ import Route from '@ember/routing';
35
+ import { service } from '@ember/service';
36
+ export default class extends Route {
37
+ @service router;
38
+ activate() {
39
+ this.router.on('routeWillChange', (transition) => {
40
+ if (!transition.to.find(route => route.name === this.routeName)) {
41
+ alert("Please save or cancel your changes.");
42
+ transition.abort();
43
+ }
44
+ })
45
+ }
46
+ }
47
+ ```
48
+ @method on
49
+ @param {String} eventName
50
+ @param {Function} callback
51
+ @public
52
+ */
53
+
54
+ /**
55
+ You can unregister a listener for events emitted by this service with `.off()`:
56
+ ```app/routes/contact-form.js
57
+ import Route from '@ember/routing';
58
+ import { service } from '@ember/service';
59
+ export default class extends Route {
60
+ @service router;
61
+ callback = (transition) => {
62
+ if (!transition.to.find(route => route.name === this.routeName)) {
63
+ alert("Please save or cancel your changes.");
64
+ transition.abort();
65
+ }
66
+ };
67
+ activate() {
68
+ this.router.on('routeWillChange', this.callback);
69
+ }
70
+ deactivate() {
71
+ this.router.off('routeWillChange', this.callback);
72
+ }
73
+ ```
74
+ @method off
75
+ @param {String} eventName
76
+ @param {Function} callback
77
+ @public
78
+ */
79
+
30
80
  /**
31
81
  The `routeWillChange` event is fired at the beginning of any
32
82
  attempted transition with a `Transition` object as the sole
@@ -39,9 +89,8 @@ class RouterService extends Service.extend(Evented) {
39
89
  import { service } from '@ember/service';
40
90
  export default class extends Route {
41
91
  @service router;
42
- constructor() {
43
- super(...arguments);
44
- this.router.on('routeWillChange', (transition) => {
92
+ activate() {
93
+ this.router.on('routeWillChange', (transition) => {
45
94
  if (!transition.to.find(route => route.name === this.routeName)) {
46
95
  alert("Please save or cancel your changes.");
47
96
  transition.abort();
@@ -66,9 +115,8 @@ class RouterService extends Service.extend(Evented) {
66
115
  import { service } from '@ember/service';
67
116
  export default class extends Route {
68
117
  @service router;
69
- constructor() {
70
- super(...arguments);
71
- this.router.on('routeDidChange', (transition) => {
118
+ activate() {
119
+ this.router.on('routeDidChange', (transition) => {
72
120
  ga.send('pageView', {
73
121
  current: transition.to.name,
74
122
  from: transition.from.name
@@ -133,6 +181,7 @@ class RouterService extends Service.extend(Evented) {
133
181
  let owner = getOwner(this);
134
182
  assert('RouterService is unexpectedly missing an owner', owner);
135
183
  router = owner.lookup('router:main');
184
+ assert('ROUTER SERVICE BUG: Expected router to be an instance of EmberRouter', router instanceof EmberRouter);
136
185
  return this[ROUTER] = router;
137
186
  }
138
187
 
@@ -195,7 +244,6 @@ class RouterService extends Service.extend(Evented) {
195
244
 
196
245
  let transition = this._router._doTransition(routeName, models, queryParams, true);
197
246
 
198
- transition['_keepDefaultQueryParamValues'] = true;
199
247
  return transition;
200
248
  }
201
249
  /**
@@ -366,19 +414,26 @@ class RouterService extends Service.extend(Evented) {
366
414
  let hasQueryParams = Object.keys(queryParams).length > 0;
367
415
 
368
416
  if (hasQueryParams) {
369
- queryParams = Object.assign({}, queryParams);
370
-
371
- this._router._prepareQueryParams( // UNSAFE: casting `routeName as string` here encodes the existing
417
+ // UNSAFE: casting `routeName as string` here encodes the existing
372
418
  // assumption but may be wrong: `extractRouteArgs` correctly returns it
373
419
  // as `string | undefined`. There may be bugs if `_prepareQueryParams`
374
420
  // does not correctly account for `undefined` values for `routeName`.
375
421
  // Spoilers: under the hood this currently uses router.js APIs which
376
422
  // *do not* account for this being `undefined`.
377
- routeName, models, queryParams, true
423
+ let targetRouteName = routeName;
424
+ queryParams = Object.assign({}, queryParams);
425
+
426
+ this._router._prepareQueryParams(targetRouteName, models, queryParams, true
427
+ /* fromRouterService */
428
+ );
429
+
430
+ let currentQueryParams = Object.assign({}, routerMicrolib.state.queryParams);
431
+
432
+ this._router._prepareQueryParams(targetRouteName, models, currentQueryParams, true
378
433
  /* fromRouterService */
379
434
  );
380
435
 
381
- return shallowEqual(queryParams, routerMicrolib.state.queryParams);
436
+ return shallowEqual(queryParams, currentQueryParams);
382
437
  }
383
438
 
384
439
  return true;
@@ -6,6 +6,7 @@ import { symbol } from '@ember/-internals/utils';
6
6
  import { assert } from '@ember/debug';
7
7
  import { readOnly } from '@ember/object/computed';
8
8
  import Service from '@ember/service';
9
+ import EmberRouter from '../system/router';
9
10
  const ROUTER = symbol('ROUTER');
10
11
  /**
11
12
  The Routing service is used by LinkTo, and provides facilities for
@@ -29,6 +30,7 @@ export default class RoutingService extends Service {
29
30
  let owner = getOwner(this);
30
31
  assert('RoutingService is unexpectedly missing an owner', owner);
31
32
  router = owner.lookup('router:main');
33
+ assert('ROUTING SERVICE BUG: Expected router to be an instance of EmberRouter', router instanceof EmberRouter);
32
34
  router.setupRouter();
33
35
  return this[ROUTER] = router;
34
36
  }
@@ -1,5 +1,6 @@
1
1
  import { get } from '@ember/-internals/metal';
2
- import { info } from '@ember/debug';
2
+ import Controller from '@ember/controller';
3
+ import { assert, info } from '@ember/debug';
3
4
  import { DEBUG } from '@glimmer/env';
4
5
  /**
5
6
  @module ember
@@ -39,6 +40,7 @@ export default function generateController(owner, controllerName) {
39
40
  generateControllerFactory(owner, controllerName);
40
41
  let fullName = `controller:${controllerName}`;
41
42
  let instance = owner.lookup(fullName);
43
+ assert('Expected an instance of controller', instance instanceof Controller);
42
44
 
43
45
  if (DEBUG) {
44
46
  if (get(instance, 'namespace.LOG_ACTIVE_GENERATION')) {
@@ -9,27 +9,31 @@ var __decorate = this && this.__decorate || function (decorators, target, key, d
9
9
  import { privatize as P } from '@ember/-internals/container';
10
10
  import { addObserver, computed, defineProperty, descriptorForProperty, flushAsyncObservers, get, getProperties, isEmpty, set, setProperties } from '@ember/-internals/metal';
11
11
  import { getOwner } from '@ember/-internals/owner';
12
+ import { BucketCache } from '@ember/-internals/routing';
12
13
  import { A as emberA, ActionHandler, Evented, Object as EmberObject, typeOf } from '@ember/-internals/runtime';
13
14
  import { isProxy, lookupDescriptor, symbol } from '@ember/-internals/utils';
15
+ import Controller from '@ember/controller';
14
16
  import { assert, info, isTesting } from '@ember/debug';
17
+ import EngineInstance from '@ember/engine/instance';
15
18
  import { dependentKeyCompat } from '@ember/object/compat';
16
19
  import { once } from '@ember/runloop';
17
20
  import { DEBUG } from '@glimmer/env';
18
21
  import { PARAMS_SYMBOL, STATE_SYMBOL } from 'router_js';
19
22
  import { calculateCacheKey, deprecateTransitionMethods, normalizeControllerQueryParams, prefixRouteNameArg, stashParamNames } from '../utils';
20
23
  import generateController from './generate_controller';
24
+ import EmberRouter from './router';
21
25
  export const ROUTE_CONNECTIONS = new WeakMap();
22
26
  const RENDER = symbol('render');
23
27
 
24
28
  class Route extends EmberObject.extend(ActionHandler, Evented) {
25
29
  constructor(owner) {
26
- super(...arguments);
30
+ super(owner);
27
31
  this.context = {};
28
32
 
29
33
  if (owner) {
30
34
  let router = owner.lookup('router:main');
31
35
  let bucketCache = owner.lookup(P`-bucket-cache:main`);
32
- assert('ROUTER BUG: Expected route injections to be defined on the route. This is an internal bug, please open an issue on Github if you see this message!', router && bucketCache);
36
+ assert('ROUTER BUG: Expected route injections to be defined on the route. This is an internal bug, please open an issue on Github if you see this message!', router instanceof EmberRouter && bucketCache instanceof BucketCache);
33
37
  this._router = router;
34
38
  this._bucketCache = bucketCache;
35
39
  this._topLevelViewTemplate = owner.lookup('template:-outlet');
@@ -110,7 +114,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
110
114
  _setRouteName(name) {
111
115
  this.routeName = name;
112
116
  let owner = getOwner(this);
113
- assert('Route is unexpectedly missing an owner', owner);
117
+ assert('Expected route to have EngineInstance as owner', owner instanceof EngineInstance);
114
118
  this.fullRouteName = getEngineRouteName(owner, name);
115
119
  }
116
120
  /**
@@ -943,6 +947,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
943
947
  // passed a model to skip the assertion.
944
948
 
945
949
  assert(`The controller named '${name}' could not be found. Make sure that this route exists and has already been entered at least once. If you are accessing a controller not associated with a route, make sure the controller class is explicitly defined.`, controller !== undefined || _skipAssert === true);
950
+ assert(`Expected controller:${name} to be an instance of Controller`, controller === undefined || controller instanceof Controller);
946
951
  return controller;
947
952
  }
948
953
  /**
@@ -1007,7 +1012,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1007
1012
  modelFor(_name) {
1008
1013
  let name;
1009
1014
  let owner = getOwner(this);
1010
- assert('Route is unexpectedly missing an owner', owner);
1015
+ assert('Expected router owner to be an EngineInstance', owner instanceof EngineInstance);
1011
1016
  let transition = this._router && this._router._routerMicrolib ? this._router._routerMicrolib.activeTransition : undefined; // Only change the route name when there is an active transition.
1012
1017
  // Otherwise, use the passed in route name.
1013
1018
 
@@ -1135,10 +1140,11 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1135
1140
  let hasRouterDefinedQueryParams = Object.keys(queryParameterConfiguraton).length > 0;
1136
1141
 
1137
1142
  if (controller) {
1138
- // the developer has authored a controller class in their application for
1143
+ assert('Expected an instance of controller', controller instanceof Controller); // the developer has authored a controller class in their application for
1139
1144
  // this route find its query params and normalize their object shape them
1140
1145
  // merge in the query params for the route. As a mergedProperty,
1141
1146
  // Route#queryParams is always at least `{}`
1147
+
1142
1148
  let controllerDefinedQueryParameterConfiguration = get(controller, 'queryParams') || [];
1143
1149
  let normalizedControllerQueryParameterConfiguration = normalizeControllerQueryParams(controllerDefinedQueryParameterConfiguration);
1144
1150
  combinedQueryParameterConfiguration = mergeEachQueryParams(normalizedControllerQueryParameterConfiguration, queryParameterConfiguraton);
@@ -1298,7 +1304,7 @@ function buildRenderOptions(route, nameOrOptions, options) {
1298
1304
  let owner = getOwner(route);
1299
1305
  assert('Route is unexpectedly missing an owner', owner);
1300
1306
  let name, templateName, into, outlet, model;
1301
- let controller = undefined;
1307
+ let controller;
1302
1308
 
1303
1309
  if (options) {
1304
1310
  into = options.into && options.into.replace(/\//g, '.');
@@ -1331,6 +1337,8 @@ function buildRenderOptions(route, nameOrOptions, options) {
1331
1337
  assert(`You passed \`controller: '${controllerName}'\` into the \`render\` method, but no such controller could be found.`, isDefaultRender || controller !== undefined);
1332
1338
  }
1333
1339
 
1340
+ assert('Expected an instance of controller', controller instanceof Controller);
1341
+
1334
1342
  if (model === undefined) {
1335
1343
  model = route.currentModel;
1336
1344
  } else {
@@ -1655,7 +1663,7 @@ Route.reopen({
1655
1663
  qp.serializedValue = svalue;
1656
1664
  let thisQueryParamHasDefaultValue = qp.serializedDefaultValue === svalue;
1657
1665
 
1658
- if (!thisQueryParamHasDefaultValue || transition._keepDefaultQueryParamValues) {
1666
+ if (!thisQueryParamHasDefaultValue) {
1659
1667
  finalParams.push({
1660
1668
  value: svalue,
1661
1669
  visible: true,
@@ -1,6 +1,7 @@
1
1
  import { privatize as P } from '@ember/-internals/container';
2
2
  import { computed, get, set } from '@ember/-internals/metal';
3
3
  import { getOwner } from '@ember/-internals/owner';
4
+ import { BucketCache } from '@ember/-internals/routing';
4
5
  import { A as emberA, Evented, Object as EmberObject, typeOf } from '@ember/-internals/runtime';
5
6
  import { assert, deprecate, info } from '@ember/debug';
6
7
  import EmberError from '@ember/error';
@@ -16,6 +17,7 @@ import RouterState from './router_state';
16
17
  */
17
18
 
18
19
  import Router, { logAbort, STATE_SYMBOL } from 'router_js';
20
+ import EngineInstance from '@ember/engine/instance';
19
21
 
20
22
  function defaultDidTransition(infos) {
21
23
  updatePaths(this);
@@ -77,7 +79,7 @@ const {
77
79
 
78
80
  class EmberRouter extends EmberObject.extend(Evented) {
79
81
  constructor(owner) {
80
- super(...arguments);
82
+ super(owner);
81
83
  this._didSetupRouter = false;
82
84
  this._initialTransitionStarted = false;
83
85
  this.currentURL = null;
@@ -92,6 +94,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
92
94
  this._handledErrors = new Set();
93
95
  this._engineInstances = Object.create(null);
94
96
  this._engineInfoByRoute = Object.create(null);
97
+ this._slowTransitionTimer = null;
95
98
  this.currentState = null;
96
99
  this.targetState = null;
97
100
 
@@ -99,7 +102,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
99
102
 
100
103
  this.namespace = owner.lookup('application:main');
101
104
  let bucketCache = owner.lookup(P`-bucket-cache:main`);
102
- assert('BUG: BucketCache should always be present', bucketCache !== undefined);
105
+ assert('BUG: BucketCache should always be present', bucketCache instanceof BucketCache);
103
106
  this._bucketCache = bucketCache;
104
107
  let routerService = owner.lookup('service:router');
105
108
  assert('BUG: RouterService should always be present', routerService !== undefined);
@@ -699,11 +702,13 @@ class EmberRouter extends EmberObject.extend(Evented) {
699
702
  let instances = this._engineInstances;
700
703
 
701
704
  for (let name in instances) {
702
- let instance = instances[name];
703
- assert('has instance', instance);
705
+ let instanceMap = instances[name];
706
+ assert('has instanceMap', instanceMap);
704
707
 
705
- for (let id in instance) {
706
- run(instance[id], 'destroy');
708
+ for (let id in instanceMap) {
709
+ let instance = instanceMap[id];
710
+ assert('has instance', instance);
711
+ run(instance, 'destroy');
707
712
  }
708
713
  }
709
714
  }
@@ -916,7 +921,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
916
921
  }
917
922
  }
918
923
 
919
- _doTransition(_targetRouteName, models, _queryParams, _keepDefaultQueryParamValues) {
924
+ _doTransition(_targetRouteName, models, _queryParams, _fromRouterService) {
920
925
  let targetRouteName = _targetRouteName || getActiveTargetName(this._routerMicrolib);
921
926
 
922
927
  assert(`The route ${targetRouteName} was not found`, Boolean(targetRouteName) && this._routerMicrolib.hasRoute(targetRouteName));
@@ -927,7 +932,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
927
932
 
928
933
  Object.assign(queryParams, _queryParams);
929
934
 
930
- this._prepareQueryParams(targetRouteName, models, queryParams, Boolean(_keepDefaultQueryParamValues));
935
+ this._prepareQueryParams(targetRouteName, models, queryParams, Boolean(_fromRouterService));
931
936
 
932
937
  let transition = this._routerMicrolib.transitionTo(targetRouteName, ...models, {
933
938
  queryParams
@@ -1165,7 +1170,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
1165
1170
  _scheduleLoadingEvent(transition, originRoute) {
1166
1171
  this._cancelSlowTransitionTimer();
1167
1172
 
1168
- this._slowTransitionTimer = scheduleOnce('routerTransitions', this, '_handleSlowTransition', transition, originRoute);
1173
+ this._slowTransitionTimer = scheduleOnce('routerTransitions', this, this._handleSlowTransition, transition, originRoute);
1169
1174
  }
1170
1175
 
1171
1176
  _handleSlowTransition(transition, originRoute) {
@@ -1221,7 +1226,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
1221
1226
 
1222
1227
  if (!engineInstance) {
1223
1228
  let owner = getOwner(this);
1224
- assert('Router is unexpectedly missing an owner', owner);
1229
+ assert('Expected router to have EngineInstance as owner', owner instanceof EngineInstance);
1225
1230
  assert(`You attempted to mount the engine '${name}' in your router map, but the engine can not be found.`, owner.hasRegistration(`engine:${name}`));
1226
1231
  engineInstance = owner.buildChildEngineInstance(name, {
1227
1232
  routable: true,
@@ -1526,16 +1531,6 @@ function updatePaths(router) {
1526
1531
  set(router, 'currentPath', path);
1527
1532
  set(router, 'currentRouteName', currentRouteName);
1528
1533
  set(router, 'currentURL', currentURL);
1529
- let owner = getOwner(router);
1530
- assert('Router is unexpectedly missing an owner', owner);
1531
- let appController = owner.lookup('controller:application');
1532
-
1533
- if (!appController) {
1534
- // appController might not exist when top-level loading/error
1535
- // substates have been entered since ApplicationRoute hasn't
1536
- // actually been entered at that point.
1537
- return;
1538
- }
1539
1534
  }
1540
1535
 
1541
1536
  function didBeginTransition(transition, router) {
@@ -1634,7 +1629,7 @@ function representEmptyRoute(liveRoutes, defaultParentState, {
1634
1629
  // Create an entry to represent our default template name,
1635
1630
  // just so other routes can target it and inherit its place
1636
1631
  // in the outlet hierarchy.
1637
- defaultParentState.outlets.main = {
1632
+ defaultParentState.outlets['main'] = {
1638
1633
  render: {
1639
1634
  name: routeName,
1640
1635
  outlet: 'main'
@@ -1,6 +1,7 @@
1
1
  import { get } from '@ember/-internals/metal';
2
2
  import { getOwner } from '@ember/-internals/owner';
3
3
  import { assert, deprecate } from '@ember/debug';
4
+ import EngineInstance from '@ember/engine/instance';
4
5
  import EmberError from '@ember/error';
5
6
  import { STATE_SYMBOL } from 'router_js';
6
7
  const ALL_PERIODS_REGEX = /\./g;
@@ -219,7 +220,7 @@ export function resemblesURL(str) {
219
220
  export function prefixRouteNameArg(route, args) {
220
221
  let routeName;
221
222
  let owner = getOwner(route);
222
- assert('Route is unexpectedly missing an owner', owner);
223
+ assert('Expected route to have EngineInstance as owner', owner instanceof EngineInstance);
223
224
  let prefix = owner.mountPoint; // only alter the routeName if it's actually referencing a route.
224
225
 
225
226
  if (owner.routable && typeof args[0] === 'string') {
@@ -1,5 +1,6 @@
1
1
  import { typeOf } from './type-of';
2
2
  import Comparable from './mixins/comparable';
3
+ import { assert } from '@ember/debug';
3
4
  const TYPE_ORDER = {
4
5
  undefined: 0,
5
6
  null: 1,
@@ -31,8 +32,9 @@ const TYPE_ORDER = {
31
32
  // SSt `------'`
32
33
 
33
34
  function spaceship(a, b) {
34
- let diff = a - b;
35
- return (diff > 0) - (diff < 0);
35
+ let diff = a - b; // SAFETY: Number casts true into 1 and false into 0. Therefore, this must end up as one of the Compare values.
36
+
37
+ return Number(diff > 0) - Number(diff < 0);
36
38
  }
37
39
  /**
38
40
  @module @ember/utils
@@ -94,11 +96,12 @@ export default function compare(v, w) {
94
96
  let type1 = typeOf(v);
95
97
  let type2 = typeOf(w);
96
98
 
97
- if (type1 === 'instance' && Comparable.detect(v) && v.constructor.compare) {
99
+ if (type1 === 'instance' && isComparable(v) && v.constructor.compare) {
98
100
  return v.constructor.compare(v, w);
99
101
  }
100
102
 
101
- if (type2 === 'instance' && Comparable.detect(w) && w.constructor.compare) {
103
+ if (type2 === 'instance' && isComparable(w) && w.constructor.compare) {
104
+ // SAFETY: Multiplying by a negative just changes the sign
102
105
  return w.constructor.compare(w, v) * -1;
103
106
  }
104
107
 
@@ -111,14 +114,20 @@ export default function compare(v, w) {
111
114
 
112
115
  switch (type1) {
113
116
  case 'boolean':
117
+ assert('both are boolean', typeof v === 'boolean' && typeof w === 'boolean');
118
+ return spaceship(Number(v), Number(w));
119
+
114
120
  case 'number':
121
+ assert('both are numbers', typeof v === 'number' && typeof w === 'number');
115
122
  return spaceship(v, w);
116
123
 
117
124
  case 'string':
125
+ assert('both are strings', typeof v === 'string' && typeof w === 'string');
118
126
  return spaceship(v.localeCompare(w), 0);
119
127
 
120
128
  case 'array':
121
129
  {
130
+ assert('both are arrays', Array.isArray(v) && Array.isArray(w));
122
131
  let vLen = v.length;
123
132
  let wLen = w.length;
124
133
  let len = Math.min(vLen, wLen);
@@ -137,16 +146,21 @@ export default function compare(v, w) {
137
146
  }
138
147
 
139
148
  case 'instance':
140
- if (Comparable.detect(v)) {
149
+ if (isComparable(v) && v.compare) {
141
150
  return v.compare(v, w);
142
151
  }
143
152
 
144
153
  return 0;
145
154
 
146
155
  case 'date':
156
+ assert('both are dates', v instanceof Date && w instanceof Date);
147
157
  return spaceship(v.getTime(), w.getTime());
148
158
 
149
159
  default:
150
160
  return 0;
151
161
  }
162
+ }
163
+
164
+ function isComparable(value) {
165
+ return Comparable.detect(value);
152
166
  }
@@ -25,13 +25,17 @@ export function onerrorDefault(reason) {
25
25
 
26
26
  function errorFor(reason) {
27
27
  if (!reason) return;
28
+ let withErrorThrown = reason;
28
29
 
29
- if (reason.errorThrown) {
30
- return unwrapErrorThrown(reason);
30
+ if (withErrorThrown.errorThrown) {
31
+ return unwrapErrorThrown(withErrorThrown);
31
32
  }
32
33
 
33
- if (reason.name === 'UnrecognizedURLError') {
34
- assert(`The URL '${reason.message}' did not match any routes in your application`, false);
34
+ let withName = reason;
35
+
36
+ if (withName.name === 'UnrecognizedURLError') {
37
+ assert(`The URL '${withName.message}' did not match any routes in your application`, false); // @ts-expect-error We'll hit this if the assert is stripped
38
+
35
39
  return;
36
40
  }
37
41