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.
- package/CHANGELOG.md +5 -1
- package/blueprints/acceptance-test/mocha-files/tests/acceptance/__name__-test.js +4 -4
- package/blueprints/acceptance-test/mocha-rfc-232-files/tests/acceptance/__name__-test.js +3 -3
- package/blueprints/acceptance-test/qunit-files/tests/acceptance/__name__-test.js +2 -2
- package/blueprints/acceptance-test/qunit-rfc-232-files/tests/acceptance/__name__-test.js +3 -3
- package/blueprints/component/index.js +2 -2
- package/blueprints/component-class/index.js +2 -2
- package/blueprints/component-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +4 -4
- package/blueprints/component-test/mocha-files/__root__/__testType__/__path__/__test__.js +7 -5
- package/blueprints/component-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +6 -6
- package/blueprints/component-test/qunit-files/__root__/__testType__/__path__/__test__.js +4 -4
- package/blueprints/component-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +6 -6
- package/blueprints/controller/files/__root__/__path__/__name__.js +1 -2
- package/blueprints/controller-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
- package/blueprints/controller-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
- package/blueprints/controller-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
- package/blueprints/controller-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
- package/blueprints/controller-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
- package/blueprints/helper/files/__root__/__collection__/__name__.js +1 -1
- package/blueprints/helper/mu-files/__root__/__collection__/__name__.js +1 -1
- package/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js +3 -3
- package/blueprints/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js +6 -4
- package/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +3 -3
- package/blueprints/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js +2 -2
- package/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +3 -3
- package/blueprints/initializer/files/__root__/initializers/__name__.js +2 -3
- package/blueprints/initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +6 -7
- package/blueprints/initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +5 -5
- package/blueprints/initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +3 -4
- package/blueprints/instance-initializer/files/__root__/instance-initializers/__name__.js +2 -3
- package/blueprints/instance-initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +5 -5
- package/blueprints/instance-initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +5 -5
- package/blueprints/instance-initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +2 -2
- package/blueprints/mixin/files/__root__/mixins/__name__.js +1 -2
- package/blueprints/mixin-test/mocha-files/__root__/__testType__/__name__-test.js +2 -2
- package/blueprints/mixin-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +2 -2
- package/blueprints/mixin-test/qunit-files/__root__/__testType__/__name__-test.js +1 -1
- package/blueprints/mixin-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +1 -1
- package/blueprints/route/files/__root__/__path__/__name__.js +2 -2
- package/blueprints/route-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
- package/blueprints/route-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
- package/blueprints/route-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
- package/blueprints/route-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
- package/blueprints/route-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
- package/blueprints/service/files/__root__/__path__/__name__.js +1 -2
- package/blueprints/service-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
- package/blueprints/service-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
- package/blueprints/service-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
- package/blueprints/service-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
- package/blueprints/service-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +3 -3
- package/blueprints/util-test/mocha-files/__root__/__testType__/__name__-test.js +2 -2
- package/blueprints/util-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +2 -2
- package/blueprints/util-test/qunit-files/__root__/__testType__/__name__-test.js +1 -1
- package/blueprints/util-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +2 -3
- package/build-metadata.json +3 -3
- package/dist/dependencies/router_js.js +1 -1
- package/dist/ember-template-compiler.js +20 -143
- package/dist/ember-template-compiler.map +1 -1
- package/dist/ember-testing.js +5 -3
- package/dist/ember-testing.map +1 -1
- package/dist/ember.debug.js +1132 -1719
- package/dist/ember.debug.map +1 -1
- package/dist/header/license.js +1 -1
- package/dist/packages/@ember/-internals/container/index.js +3 -19
- package/dist/packages/@ember/-internals/extension-support/lib/container_debug_adapter.js +10 -19
- package/dist/packages/@ember/-internals/extension-support/lib/data_adapter.js +113 -112
- package/dist/packages/@ember/-internals/glimmer/index.js +163 -773
- package/dist/packages/@ember/-internals/metal/index.js +19 -32
- package/dist/packages/@ember/-internals/routing/lib/location/hash_location.js +1 -1
- package/dist/packages/@ember/-internals/routing/lib/services/router.js +67 -12
- package/dist/packages/@ember/-internals/routing/lib/services/routing.js +2 -0
- package/dist/packages/@ember/-internals/routing/lib/system/generate_controller.js +3 -1
- package/dist/packages/@ember/-internals/routing/lib/system/route.js +15 -7
- package/dist/packages/@ember/-internals/routing/lib/system/router.js +16 -21
- package/dist/packages/@ember/-internals/routing/lib/utils.js +2 -1
- package/dist/packages/@ember/-internals/runtime/lib/compare.js +19 -5
- package/dist/packages/@ember/-internals/runtime/lib/ext/rsvp.js +8 -4
- package/dist/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
- package/dist/packages/@ember/-internals/runtime/lib/mixins/array.js +1 -1
- 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 +51 -50
- package/dist/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +8 -8
- package/dist/packages/@ember/-internals/utils/index.js +1 -1
- package/dist/packages/@ember/-internals/views/lib/system/utils.js +4 -2
- package/dist/packages/@ember/-internals/views/lib/views/core_view.js +5 -22
- package/dist/packages/@ember/application/instance.js +3 -3
- package/dist/packages/@ember/canary-features/index.js +4 -12
- package/dist/packages/@ember/debug/index.js +1 -1
- package/dist/packages/@ember/debug/lib/capture-render-tree.js +2 -0
- package/dist/packages/@ember/debug/lib/handlers.js +1 -1
- package/dist/packages/@ember/renderer/index.js +21 -0
- package/dist/packages/@ember/runloop/index.js +31 -528
- package/dist/packages/@ember/runloop/type-tests.ts/begin-end.test.js +5 -0
- package/dist/packages/@ember/runloop/type-tests.ts/bind.test.js +59 -0
- package/dist/packages/@ember/runloop/type-tests.ts/cancel.test.js +5 -0
- package/dist/packages/@ember/runloop/type-tests.ts/debounce.test.js +77 -0
- package/dist/packages/@ember/runloop/type-tests.ts/join.test.js +38 -0
- package/dist/packages/@ember/runloop/type-tests.ts/later.test.js +38 -0
- package/dist/packages/@ember/runloop/type-tests.ts/next.test.js +38 -0
- package/dist/packages/@ember/runloop/type-tests.ts/once.test.js +38 -0
- package/dist/packages/@ember/runloop/type-tests.ts/run.test.js +38 -0
- package/dist/packages/@ember/runloop/type-tests.ts/schedule-once.test.js +39 -0
- package/dist/packages/@ember/runloop/type-tests.ts/schedule.test.js +39 -0
- package/dist/packages/@ember/runloop/type-tests.ts/throttle.test.js +77 -0
- package/dist/packages/ember/index.js +4 -14
- package/dist/packages/ember/version.js +1 -1
- package/docs/data.json +658 -383
- 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
|
-
@
|
|
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
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1782
|
+
if (obj == null) {
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1789
1786
|
let value;
|
|
1790
1787
|
|
|
1791
|
-
if (
|
|
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 &&
|
|
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(
|
|
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
|
-
|
|
1838
|
+
unknownProperty() {}
|
|
1842
1839
|
|
|
1843
1840
|
}, 'a');
|
|
1844
1841
|
|
|
1845
1842
|
_getProp({
|
|
1846
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
70
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
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(
|
|
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('
|
|
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('
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
703
|
-
assert('has
|
|
705
|
+
let instanceMap = instances[name];
|
|
706
|
+
assert('has instanceMap', instanceMap);
|
|
704
707
|
|
|
705
|
-
for (let id in
|
|
706
|
-
|
|
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,
|
|
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(
|
|
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,
|
|
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('
|
|
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
|
|
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('
|
|
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
|
-
|
|
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' &&
|
|
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' &&
|
|
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 (
|
|
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 (
|
|
30
|
-
return unwrapErrorThrown(
|
|
30
|
+
if (withErrorThrown.errorThrown) {
|
|
31
|
+
return unwrapErrorThrown(withErrorThrown);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|