ember-source 5.11.0-beta.2 → 5.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-metadata.json +3 -3
- package/dist/ember-template-compiler.js +48 -42
- package/dist/ember-testing.js +1 -1
- package/dist/ember.debug.js +23102 -23100
- package/dist/ember.prod.js +31562 -31563
- package/dist/packages/@ember/-internals/container/index.js +1 -1
- package/dist/packages/@ember/-internals/deprecations/index.js +2 -1
- package/dist/packages/@ember/-internals/glimmer/index.js +2 -1
- package/dist/packages/@ember/-internals/meta/lib/meta.js +4 -3
- package/dist/packages/@ember/-internals/metal/index.js +9 -8
- package/dist/packages/@ember/-internals/routing/index.js +6 -5
- package/dist/packages/@ember/-internals/runtime/lib/ext/rsvp.js +3 -2
- package/dist/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +6 -5
- package/dist/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +4 -3
- package/dist/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +1 -1
- package/dist/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +2 -1
- package/dist/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +4 -3
- package/dist/packages/@ember/-internals/string/index.js +1 -1
- package/dist/packages/@ember/-internals/utils/index.js +4 -4
- package/dist/packages/@ember/-internals/views/index.js +1 -1
- package/dist/packages/@ember/-internals/views/lib/compat/fallback-view-registry.js +1 -1
- package/dist/packages/@ember/-internals/views/lib/component_lookup.js +1 -1
- package/dist/packages/@ember/-internals/views/lib/mixins/action_support.js +5 -3
- package/dist/packages/@ember/-internals/views/lib/mixins/child_views_support.js +3 -3
- package/dist/packages/@ember/-internals/views/lib/mixins/class_names_support.js +4 -3
- package/dist/packages/@ember/-internals/views/lib/mixins/view_support.js +4 -3
- package/dist/packages/@ember/-internals/views/lib/system/event_dispatcher.js +6 -12
- package/dist/packages/@ember/-internals/views/lib/system/utils.js +3 -2
- package/dist/packages/@ember/-internals/views/lib/views/core_view.js +76 -8
- package/dist/packages/@ember/-internals/views/lib/views/states.js +4 -3
- package/dist/packages/@ember/application/index.js +16 -7
- package/dist/packages/@ember/application/instance.js +13 -9
- package/dist/packages/@ember/application/namespace.js +7 -6
- package/dist/packages/@ember/array/index.js +617 -11
- package/dist/packages/@ember/array/make.js +1 -0
- package/dist/packages/@ember/array/mutable.js +1 -1
- package/dist/packages/@ember/array/proxy.js +8 -5
- package/dist/packages/@ember/component/helper.js +4 -4
- package/dist/packages/@ember/component/index.js +4 -4
- package/dist/packages/@ember/controller/index.js +6 -6
- package/dist/packages/@ember/debug/container-debug-adapter.js +5 -4
- package/dist/packages/@ember/debug/data-adapter.js +7 -4
- package/dist/packages/@ember/debug/index.js +213 -4
- package/dist/packages/@ember/debug/lib/assert.js +47 -0
- package/dist/packages/@ember/debug/lib/deprecate.js +194 -4
- package/dist/packages/@ember/debug/lib/inspect.js +120 -2
- package/dist/packages/@ember/debug/lib/warn.js +94 -3
- package/dist/packages/@ember/engine/index.js +440 -17
- package/dist/packages/@ember/engine/instance.js +175 -11
- package/dist/packages/@ember/engine/parent.js +1 -0
- package/dist/packages/@ember/helper/index.js +4 -4
- package/dist/packages/@ember/instrumentation/index.js +2 -1
- package/dist/packages/@ember/modifier/index.js +13 -5
- package/dist/packages/@ember/modifier/on.js +15 -0
- package/dist/packages/@ember/object/-internals.js +6 -5
- package/dist/packages/@ember/object/compat.js +4 -3
- package/dist/packages/@ember/object/computed.js +4 -4
- package/dist/packages/@ember/object/core.js +861 -14
- package/dist/packages/@ember/object/evented.js +4 -4
- package/dist/packages/@ember/object/events.js +3 -3
- package/dist/packages/@ember/object/index.js +260 -9
- package/dist/packages/@ember/object/internals.js +1 -1
- package/dist/packages/@ember/object/lib/computed/computed_macros.js +8 -6
- package/dist/packages/@ember/object/lib/computed/reduce_computed_macros.js +8 -4
- package/dist/packages/@ember/object/mixin.js +6 -5
- package/dist/packages/@ember/object/observable.js +103 -9
- package/dist/packages/@ember/object/observers.js +3 -3
- package/dist/packages/@ember/object/promise-proxy-mixin.js +5 -5
- package/dist/packages/@ember/renderer/index.js +4 -4
- package/dist/packages/@ember/routing/-internals.js +3 -1
- package/dist/packages/@ember/routing/hash-location.js +2 -2
- package/dist/packages/@ember/routing/history-location.js +3 -2
- package/dist/packages/@ember/routing/index.js +4 -4
- package/dist/packages/@ember/routing/lib/dsl.js +2 -1
- package/dist/packages/@ember/routing/lib/generate_controller.js +4 -3
- package/dist/packages/@ember/routing/lib/router_state.js +26 -1
- package/dist/packages/@ember/routing/lib/routing-service.js +107 -9
- package/dist/packages/@ember/routing/lib/utils.js +238 -7
- package/dist/packages/@ember/routing/none-location.js +3 -2
- package/dist/packages/@ember/routing/route.js +1618 -22
- package/dist/packages/@ember/routing/router-service.js +638 -12
- package/dist/packages/@ember/routing/router.js +1449 -14
- package/dist/packages/@ember/runloop/index.js +760 -6
- package/dist/packages/@ember/service/index.js +3 -3
- package/dist/packages/@ember/template/index.js +4 -4
- package/dist/packages/@ember/utils/index.js +2 -1
- package/dist/packages/@ember/utils/lib/compare.js +159 -4
- package/dist/packages/@ember/utils/lib/is_empty.js +4 -4
- package/dist/packages/@ember/utils/lib/type-of.js +110 -1
- package/dist/packages/@glimmer/tracking/index.js +3 -3
- package/dist/packages/@glimmer/tracking/primitives/cache.js +3 -3
- package/dist/packages/ember/barrel.js +28 -13
- package/dist/packages/ember/version.js +1 -1
- package/dist/packages/ember-testing/lib/adapters/adapter.js +1 -1
- package/dist/packages/ember-testing/lib/adapters/qunit.js +2 -1
- package/dist/packages/ember-testing/lib/ext/application.js +2 -1
- package/dist/packages/ember-testing/lib/ext/rsvp.js +1 -1
- package/dist/packages/ember-testing/lib/helpers/and_then.js +2 -1
- package/dist/packages/ember-testing/lib/helpers/current_path.js +8 -6
- package/dist/packages/ember-testing/lib/helpers/current_route_name.js +8 -6
- package/dist/packages/ember-testing/lib/helpers/current_url.js +6 -5
- package/dist/packages/ember-testing/lib/helpers/pause_test.js +2 -1
- package/dist/packages/ember-testing/lib/helpers/visit.js +4 -3
- package/dist/packages/ember-testing/lib/helpers/wait.js +4 -3
- package/dist/packages/ember-testing/lib/initializers.js +15 -8
- package/dist/packages/ember-testing/lib/setup_for_testing.js +1 -1
- package/dist/packages/ember-testing/lib/test/run.js +1 -1
- package/dist/packages/router_js/index.js +2 -1
- package/dist/packages/shared-chunks/{alias-By_2yu5c.js → alias-Dri0koi2.js} +5 -3
- package/dist/packages/shared-chunks/array-3xbmc_4J.js +119 -0
- package/dist/packages/shared-chunks/{cache-gDE3bkXq.js → cache-BESCGvbE.js} +667 -1529
- package/dist/packages/shared-chunks/{core_view-Cxne2_wu.js → chunk-3SQBS3Y5-Cj4eryg1.js} +1 -88
- package/dist/packages/shared-chunks/{index-BXPoca1S.js → index-Llq6dmgX.js} +40 -4660
- package/dist/packages/shared-chunks/{is_proxy-Dmis-70B.js → is_proxy-DjvCKvd5.js} +1 -1
- package/dist/packages/shared-chunks/{mandatory-setter-1UQhiJOb.js → mandatory-setter-BiXq-dpN.js} +2 -1
- package/dist/packages/shared-chunks/{name-z9D9Yibn.js → name-Dx2bGFVv.js} +1 -1
- package/dist/packages/shared-chunks/{namespace_search-CBgHTkDh.js → namespace_search-btMaPM-_.js} +2 -2
- package/dist/packages/shared-chunks/{property_set-CW4q-uo4.js → property_set-BapAkp3X.js} +5 -4
- package/dist/packages/shared-chunks/{registry-DzfcDwii.js → registry-B8WARvkP.js} +3 -2
- package/dist/packages/shared-chunks/{router-B-Q1aYBn.js → router-DrLZsJeE.js} +2 -482
- package/dist/packages/shared-chunks/{set_properties-DvalyQdu.js → set_properties-BScfxzvI.js} +2 -2
- package/dist/packages/shared-chunks/setup-registry-du4pSGZi.js +48 -0
- package/dist/packages/shared-chunks/{to-string-D8i3mjEU.js → to-string-B1BmwUkt.js} +1 -1
- package/dist/packages/shared-chunks/unrecognized-url-error-zpz-JEoG.js +484 -0
- package/docs/data.json +152 -142
- package/package.json +4 -7
- package/types/stable/@ember/-internals/metal/lib/array.d.ts +1 -2
- package/types/stable/@ember/-internals/metal/lib/object-at.d.ts +4 -0
- package/types/stable/@ember/-internals/metal/lib/observer.d.ts +2 -1
- package/types/stable/@ember/array/index.d.ts +1 -1
- package/types/stable/@ember/array/make.d.ts +3 -0
- package/types/stable/@ember/debug/index.d.ts +3 -7
- package/types/stable/@ember/debug/lib/assert.d.ts +8 -0
- package/types/stable/@ember/engine/index.d.ts +1 -1
- package/types/stable/@ember/engine/instance.d.ts +2 -2
- package/types/stable/@ember/engine/parent.d.ts +3 -0
- package/types/stable/@ember/modifier/index.d.ts +1 -3
- package/types/stable/@ember/modifier/on.d.ts +5 -0
- package/types/stable/@ember/routing/lib/routing-service.d.ts +1 -1
- package/types/stable/@ember/routing/route.d.ts +2 -3
- package/types/stable/@ember/routing/router-service.d.ts +1 -1
- package/types/stable/@ember/routing/router.d.ts +4 -4
- package/types/stable/ember/barrel.d.ts +1 -1
- package/types/stable/ember/index.d.ts +1 -1
- package/types/stable/index.d.ts +5 -0
- package/dist/packages/shared-chunks/index-DTxy4Zgx.js +0 -641
- package/dist/packages/shared-chunks/index-PYiGj1jp.js +0 -2071
|
@@ -1,2071 +0,0 @@
|
|
|
1
|
-
import { a as assert } from './index-DTxy4Zgx.js';
|
|
2
|
-
import { E as ENV } from './env-BJLX2Arx.js';
|
|
3
|
-
import { g as get, a3 as endPropertyChanges, n as notifyPropertyChange, x as addObserver, y as removeObserver, J as hasListeners, a1 as beginPropertyChanges, R as objectAt, a7 as replaceInNativeArray, S as replace, a5 as PROXY_CONTENT, c as computed, H as hasUnknownProperty, B as descriptorForProperty, ad as DEBUG_INJECTION_FUNCTIONS, u as isClassicDecorator, d as defineProperty, ab as activateObserver, I as sendEvent, L as setClassicDecorator, i as isElementDescriptor, e as expandProperties } from './cache-gDE3bkXq.js';
|
|
4
|
-
import { peekMeta, meta } from '../@ember/-internals/meta/lib/meta.js';
|
|
5
|
-
import '../@glimmer/validator/index.js';
|
|
6
|
-
import { g as guidFor, s as setObservers } from './mandatory-setter-1UQhiJOb.js';
|
|
7
|
-
import { isDevelopingApp } from '@embroider/macros';
|
|
8
|
-
import { registerDestructor, isDestroyed, isDestroying, destroy } from '../@glimmer/destroyable/index.js';
|
|
9
|
-
import '../@glimmer/manager/index.js';
|
|
10
|
-
import { s as set } from './property_set-CW4q-uo4.js';
|
|
11
|
-
import { g as getProperties, s as setProperties } from './set_properties-DvalyQdu.js';
|
|
12
|
-
import { g as getFactoryFor, s as setFactoryFor } from './registry-DzfcDwii.js';
|
|
13
|
-
import { getOwner } from '../@ember/-internals/owner/index.js';
|
|
14
|
-
import { i as isInternalSymbol } from './to-string-D8i3mjEU.js';
|
|
15
|
-
import Mixin, { applyMixin } from '../@ember/object/mixin.js';
|
|
16
|
-
import '../@ember/-internals/runtime/lib/mixins/registry_proxy.js';
|
|
17
|
-
import '../@ember/-internals/runtime/lib/mixins/container_proxy.js';
|
|
18
|
-
import Comparable from '../@ember/-internals/runtime/lib/mixins/comparable.js';
|
|
19
|
-
import ActionHandler from '../@ember/-internals/runtime/lib/mixins/action_handler.js';
|
|
20
|
-
import '../@ember/-internals/runtime/lib/mixins/-proxy.js';
|
|
21
|
-
import MutableEnumerable from '../@ember/enumerable/mutable.js';
|
|
22
|
-
import '../@ember/-internals/runtime/lib/mixins/target_action_support.js';
|
|
23
|
-
import '../@ember/-internals/runtime/lib/ext/rsvp.js';
|
|
24
|
-
import Enumerable from '../@ember/enumerable/index.js';
|
|
25
|
-
import { setEmberArray, isEmberArray } from '../@ember/array/-internals.js';
|
|
26
|
-
import makeArray from '../@ember/array/lib/make-array.js';
|
|
27
|
-
import { OWNER } from '../@glimmer/owner/index.js';
|
|
28
|
-
|
|
29
|
-
// ........................................
|
|
30
|
-
// TYPING & ARRAY MESSAGING
|
|
31
|
-
//
|
|
32
|
-
const TYPE_MAP = {
|
|
33
|
-
'[object Boolean]': 'boolean',
|
|
34
|
-
'[object Number]': 'number',
|
|
35
|
-
'[object String]': 'string',
|
|
36
|
-
'[object Function]': 'function',
|
|
37
|
-
'[object AsyncFunction]': 'function',
|
|
38
|
-
'[object Array]': 'array',
|
|
39
|
-
'[object Date]': 'date',
|
|
40
|
-
'[object RegExp]': 'regexp',
|
|
41
|
-
'[object Object]': 'object',
|
|
42
|
-
'[object FileList]': 'filelist'
|
|
43
|
-
};
|
|
44
|
-
const {
|
|
45
|
-
toString
|
|
46
|
-
} = Object.prototype;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
@module @ember/utils
|
|
50
|
-
*/
|
|
51
|
-
/**
|
|
52
|
-
Returns a consistent type for the passed object.
|
|
53
|
-
|
|
54
|
-
Use this instead of the built-in `typeof` to get the type of an item.
|
|
55
|
-
It will return the same result across all browsers and includes a bit
|
|
56
|
-
more detail. Here is what will be returned:
|
|
57
|
-
|
|
58
|
-
| Return Value | Meaning |
|
|
59
|
-
|---------------|------------------------------------------------------|
|
|
60
|
-
| 'string' | String primitive or String object. |
|
|
61
|
-
| 'number' | Number primitive or Number object. |
|
|
62
|
-
| 'boolean' | Boolean primitive or Boolean object. |
|
|
63
|
-
| 'null' | Null value |
|
|
64
|
-
| 'undefined' | Undefined value |
|
|
65
|
-
| 'function' | A function |
|
|
66
|
-
| 'array' | An instance of Array |
|
|
67
|
-
| 'regexp' | An instance of RegExp |
|
|
68
|
-
| 'date' | An instance of Date |
|
|
69
|
-
| 'filelist' | An instance of FileList |
|
|
70
|
-
| 'class' | An Ember class (created using EmberObject.extend()) |
|
|
71
|
-
| 'instance' | An Ember object instance |
|
|
72
|
-
| 'error' | An instance of the Error object |
|
|
73
|
-
| 'object' | A JavaScript object not inheriting from EmberObject |
|
|
74
|
-
|
|
75
|
-
Examples:
|
|
76
|
-
|
|
77
|
-
```javascript
|
|
78
|
-
import { A } from '@ember/array';
|
|
79
|
-
import { typeOf } from '@ember/utils';
|
|
80
|
-
import EmberObject from '@ember/object';
|
|
81
|
-
|
|
82
|
-
typeOf(); // 'undefined'
|
|
83
|
-
typeOf(null); // 'null'
|
|
84
|
-
typeOf(undefined); // 'undefined'
|
|
85
|
-
typeOf('michael'); // 'string'
|
|
86
|
-
typeOf(new String('michael')); // 'string'
|
|
87
|
-
typeOf(101); // 'number'
|
|
88
|
-
typeOf(new Number(101)); // 'number'
|
|
89
|
-
typeOf(true); // 'boolean'
|
|
90
|
-
typeOf(new Boolean(true)); // 'boolean'
|
|
91
|
-
typeOf(A); // 'function'
|
|
92
|
-
typeOf(A()); // 'array'
|
|
93
|
-
typeOf([1, 2, 90]); // 'array'
|
|
94
|
-
typeOf(/abc/); // 'regexp'
|
|
95
|
-
typeOf(new Date()); // 'date'
|
|
96
|
-
typeOf(event.target.files); // 'filelist'
|
|
97
|
-
typeOf(EmberObject.extend()); // 'class'
|
|
98
|
-
typeOf(EmberObject.create()); // 'instance'
|
|
99
|
-
typeOf(new Error('teamocil')); // 'error'
|
|
100
|
-
|
|
101
|
-
// 'normal' JavaScript object
|
|
102
|
-
typeOf({ a: 'b' }); // 'object'
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
@method typeOf
|
|
106
|
-
@for @ember/utils
|
|
107
|
-
@param item the item to check
|
|
108
|
-
@return {String} the type
|
|
109
|
-
@public
|
|
110
|
-
@static
|
|
111
|
-
*/
|
|
112
|
-
function typeOf(item) {
|
|
113
|
-
if (item === null) {
|
|
114
|
-
return 'null';
|
|
115
|
-
}
|
|
116
|
-
if (item === undefined) {
|
|
117
|
-
return 'undefined';
|
|
118
|
-
}
|
|
119
|
-
let ret = TYPE_MAP[toString.call(item)] || 'object';
|
|
120
|
-
if (ret === 'function') {
|
|
121
|
-
if (EmberCoreObject.detect(item)) {
|
|
122
|
-
ret = 'class';
|
|
123
|
-
}
|
|
124
|
-
} else if (ret === 'object') {
|
|
125
|
-
if (item instanceof Error) {
|
|
126
|
-
ret = 'error';
|
|
127
|
-
} else if (item instanceof EmberCoreObject) {
|
|
128
|
-
ret = 'instance';
|
|
129
|
-
} else if (item instanceof Date) {
|
|
130
|
-
ret = 'date';
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return ret;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const TYPE_ORDER = {
|
|
137
|
-
undefined: 0,
|
|
138
|
-
null: 1,
|
|
139
|
-
boolean: 2,
|
|
140
|
-
number: 3,
|
|
141
|
-
string: 4,
|
|
142
|
-
array: 5,
|
|
143
|
-
object: 6,
|
|
144
|
-
instance: 7,
|
|
145
|
-
function: 8,
|
|
146
|
-
class: 9,
|
|
147
|
-
date: 10,
|
|
148
|
-
regexp: 11,
|
|
149
|
-
filelist: 12,
|
|
150
|
-
error: 13
|
|
151
|
-
};
|
|
152
|
-
//
|
|
153
|
-
// the spaceship operator
|
|
154
|
-
//
|
|
155
|
-
// `. ___
|
|
156
|
-
// __,' __`. _..----....____
|
|
157
|
-
// __...--.'``;. ,. ;``--..__ .' ,-._ _.-'
|
|
158
|
-
// _..-''-------' `' `' `' O ``-''._ (,;') _,'
|
|
159
|
-
// ,'________________ \`-._`-','
|
|
160
|
-
// `._ ```````````------...___ '-.._'-:
|
|
161
|
-
// ```--.._ ,. ````--...__\-.
|
|
162
|
-
// `.--. `-` "INFINITY IS LESS ____ | |`
|
|
163
|
-
// `. `. THAN BEYOND" ,'`````. ; ;`
|
|
164
|
-
// `._`. __________ `. \'__/`
|
|
165
|
-
// `-:._____/______/___/____`. \ `
|
|
166
|
-
// | `._ `. \
|
|
167
|
-
// `._________`-. `. `.___
|
|
168
|
-
// SSt `------'`
|
|
169
|
-
function spaceship(a, b) {
|
|
170
|
-
// SAFETY: `Math.sign` always returns `-1` for negative, `0` for zero, and `1`
|
|
171
|
-
// for positive numbers. (The extra precision is useful for the way we use
|
|
172
|
-
// this in the context of `compare`.)
|
|
173
|
-
return Math.sign(a - b);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
@module @ember/utils
|
|
178
|
-
*/
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
Compares two javascript values and returns:
|
|
182
|
-
|
|
183
|
-
- -1 if the first is smaller than the second,
|
|
184
|
-
- 0 if both are equal,
|
|
185
|
-
- 1 if the first is greater than the second.
|
|
186
|
-
|
|
187
|
-
```javascript
|
|
188
|
-
import { compare } from '@ember/utils';
|
|
189
|
-
|
|
190
|
-
compare('hello', 'hello'); // 0
|
|
191
|
-
compare('abc', 'dfg'); // -1
|
|
192
|
-
compare(2, 1); // 1
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
If the types of the two objects are different precedence occurs in the
|
|
196
|
-
following order, with types earlier in the list considered `<` types
|
|
197
|
-
later in the list:
|
|
198
|
-
|
|
199
|
-
- undefined
|
|
200
|
-
- null
|
|
201
|
-
- boolean
|
|
202
|
-
- number
|
|
203
|
-
- string
|
|
204
|
-
- array
|
|
205
|
-
- object
|
|
206
|
-
- instance
|
|
207
|
-
- function
|
|
208
|
-
- class
|
|
209
|
-
- date
|
|
210
|
-
|
|
211
|
-
```javascript
|
|
212
|
-
import { compare } from '@ember/utils';
|
|
213
|
-
|
|
214
|
-
compare('hello', 50); // 1
|
|
215
|
-
compare(50, 'hello'); // -1
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
@method compare
|
|
219
|
-
@for @ember/utils
|
|
220
|
-
@static
|
|
221
|
-
@param {Object} v First value to compare
|
|
222
|
-
@param {Object} w Second value to compare
|
|
223
|
-
@return {Number} -1 if v < w, 0 if v = w and 1 if v > w.
|
|
224
|
-
@public
|
|
225
|
-
*/
|
|
226
|
-
function compare(v, w) {
|
|
227
|
-
if (v === w) {
|
|
228
|
-
return 0;
|
|
229
|
-
}
|
|
230
|
-
let type1 = typeOf(v);
|
|
231
|
-
let type2 = typeOf(w);
|
|
232
|
-
if (type1 === 'instance' && isComparable(v) && v.constructor.compare) {
|
|
233
|
-
return v.constructor.compare(v, w);
|
|
234
|
-
}
|
|
235
|
-
if (type2 === 'instance' && isComparable(w) && w.constructor.compare) {
|
|
236
|
-
// SAFETY: Multiplying by a negative just changes the sign
|
|
237
|
-
return w.constructor.compare(w, v) * -1;
|
|
238
|
-
}
|
|
239
|
-
let res = spaceship(TYPE_ORDER[type1], TYPE_ORDER[type2]);
|
|
240
|
-
if (res !== 0) {
|
|
241
|
-
return res;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// types are equal - so we have to check values now
|
|
245
|
-
switch (type1) {
|
|
246
|
-
case 'boolean':
|
|
247
|
-
(isDevelopingApp() && !(typeof v === 'boolean' && typeof w === 'boolean') && assert('both are boolean', typeof v === 'boolean' && typeof w === 'boolean'));
|
|
248
|
-
return spaceship(Number(v), Number(w));
|
|
249
|
-
case 'number':
|
|
250
|
-
(isDevelopingApp() && !(typeof v === 'number' && typeof w === 'number') && assert('both are numbers', typeof v === 'number' && typeof w === 'number'));
|
|
251
|
-
return spaceship(v, w);
|
|
252
|
-
case 'string':
|
|
253
|
-
(isDevelopingApp() && !(typeof v === 'string' && typeof w === 'string') && assert('both are strings', typeof v === 'string' && typeof w === 'string'));
|
|
254
|
-
return spaceship(v.localeCompare(w), 0);
|
|
255
|
-
case 'array':
|
|
256
|
-
{
|
|
257
|
-
(isDevelopingApp() && !(Array.isArray(v) && Array.isArray(w)) && assert('both are arrays', Array.isArray(v) && Array.isArray(w)));
|
|
258
|
-
let vLen = v.length;
|
|
259
|
-
let wLen = w.length;
|
|
260
|
-
let len = Math.min(vLen, wLen);
|
|
261
|
-
for (let i = 0; i < len; i++) {
|
|
262
|
-
let r = compare(v[i], w[i]);
|
|
263
|
-
if (r !== 0) {
|
|
264
|
-
return r;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// all elements are equal now
|
|
269
|
-
// shorter array should be ordered first
|
|
270
|
-
return spaceship(vLen, wLen);
|
|
271
|
-
}
|
|
272
|
-
case 'instance':
|
|
273
|
-
if (isComparable(v) && v.compare) {
|
|
274
|
-
return v.compare(v, w);
|
|
275
|
-
}
|
|
276
|
-
return 0;
|
|
277
|
-
case 'date':
|
|
278
|
-
(isDevelopingApp() && !(v instanceof Date && w instanceof Date) && assert('both are dates', v instanceof Date && w instanceof Date));
|
|
279
|
-
return spaceship(v.getTime(), w.getTime());
|
|
280
|
-
default:
|
|
281
|
-
return 0;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
function isComparable(value) {
|
|
285
|
-
return Comparable.detect(value);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
@module @ember/object/observable
|
|
290
|
-
*/
|
|
291
|
-
|
|
292
|
-
const Observable = Mixin.create({
|
|
293
|
-
get(keyName) {
|
|
294
|
-
return get(this, keyName);
|
|
295
|
-
},
|
|
296
|
-
getProperties(...args) {
|
|
297
|
-
return getProperties(this, ...args);
|
|
298
|
-
},
|
|
299
|
-
set(keyName, value) {
|
|
300
|
-
return set(this, keyName, value);
|
|
301
|
-
},
|
|
302
|
-
setProperties(hash) {
|
|
303
|
-
return setProperties(this, hash);
|
|
304
|
-
},
|
|
305
|
-
/**
|
|
306
|
-
Begins a grouping of property changes.
|
|
307
|
-
You can use this method to group property changes so that notifications
|
|
308
|
-
will not be sent until the changes are finished. If you plan to make a
|
|
309
|
-
large number of changes to an object at one time, you should call this
|
|
310
|
-
method at the beginning of the changes to begin deferring change
|
|
311
|
-
notifications. When you are done making changes, call
|
|
312
|
-
`endPropertyChanges()` to deliver the deferred change notifications and end
|
|
313
|
-
deferring.
|
|
314
|
-
@method beginPropertyChanges
|
|
315
|
-
@return {Observable}
|
|
316
|
-
@private
|
|
317
|
-
*/
|
|
318
|
-
beginPropertyChanges() {
|
|
319
|
-
beginPropertyChanges();
|
|
320
|
-
return this;
|
|
321
|
-
},
|
|
322
|
-
/**
|
|
323
|
-
Ends a grouping of property changes.
|
|
324
|
-
You can use this method to group property changes so that notifications
|
|
325
|
-
will not be sent until the changes are finished. If you plan to make a
|
|
326
|
-
large number of changes to an object at one time, you should call
|
|
327
|
-
`beginPropertyChanges()` at the beginning of the changes to defer change
|
|
328
|
-
notifications. When you are done making changes, call this method to
|
|
329
|
-
deliver the deferred change notifications and end deferring.
|
|
330
|
-
@method endPropertyChanges
|
|
331
|
-
@return {Observable}
|
|
332
|
-
@private
|
|
333
|
-
*/
|
|
334
|
-
endPropertyChanges() {
|
|
335
|
-
endPropertyChanges();
|
|
336
|
-
return this;
|
|
337
|
-
},
|
|
338
|
-
notifyPropertyChange(keyName) {
|
|
339
|
-
notifyPropertyChange(this, keyName);
|
|
340
|
-
return this;
|
|
341
|
-
},
|
|
342
|
-
addObserver(key, target, method, sync) {
|
|
343
|
-
addObserver(this, key, target, method, sync);
|
|
344
|
-
return this;
|
|
345
|
-
},
|
|
346
|
-
removeObserver(key, target, method, sync) {
|
|
347
|
-
removeObserver(this, key, target, method, sync);
|
|
348
|
-
return this;
|
|
349
|
-
},
|
|
350
|
-
/**
|
|
351
|
-
Returns `true` if the object currently has observers registered for a
|
|
352
|
-
particular key. You can use this method to potentially defer performing
|
|
353
|
-
an expensive action until someone begins observing a particular property
|
|
354
|
-
on the object.
|
|
355
|
-
@method hasObserverFor
|
|
356
|
-
@param {String} key Key to check
|
|
357
|
-
@return {Boolean}
|
|
358
|
-
@private
|
|
359
|
-
*/
|
|
360
|
-
hasObserverFor(key) {
|
|
361
|
-
return hasListeners(this, `${key}:change`);
|
|
362
|
-
},
|
|
363
|
-
incrementProperty(keyName, increment = 1) {
|
|
364
|
-
(isDevelopingApp() && !(!isNaN(parseFloat(String(increment))) && isFinite(increment)) && assert('Must pass a numeric value to incrementProperty', !isNaN(parseFloat(String(increment))) && isFinite(increment)));
|
|
365
|
-
return set(this, keyName, (parseFloat(get(this, keyName)) || 0) + increment);
|
|
366
|
-
},
|
|
367
|
-
decrementProperty(keyName, decrement = 1) {
|
|
368
|
-
(isDevelopingApp() && !((typeof decrement === 'number' || !isNaN(parseFloat(decrement))) && isFinite(decrement)) && assert('Must pass a numeric value to decrementProperty', (typeof decrement === 'number' || !isNaN(parseFloat(decrement))) && isFinite(decrement)));
|
|
369
|
-
return set(this, keyName, (get(this, keyName) || 0) - decrement);
|
|
370
|
-
},
|
|
371
|
-
toggleProperty(keyName) {
|
|
372
|
-
return set(this, keyName, !get(this, keyName));
|
|
373
|
-
},
|
|
374
|
-
cacheFor(keyName) {
|
|
375
|
-
let meta = peekMeta(this);
|
|
376
|
-
return meta !== null ? meta.valueFor(keyName) : undefined;
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
@module @ember/array
|
|
382
|
-
*/
|
|
383
|
-
|
|
384
|
-
const EMPTY_ARRAY = Object.freeze([]);
|
|
385
|
-
const identityFunction = item => item;
|
|
386
|
-
function uniqBy(array, keyOrFunc = identityFunction) {
|
|
387
|
-
(isDevelopingApp() && !(isArray(array)) && assert(`first argument passed to \`uniqBy\` should be array`, isArray(array)));
|
|
388
|
-
let ret = A();
|
|
389
|
-
let seen = new Set();
|
|
390
|
-
let getter = typeof keyOrFunc === 'function' ? keyOrFunc : item => get(item, keyOrFunc);
|
|
391
|
-
array.forEach(item => {
|
|
392
|
-
let val = getter(item);
|
|
393
|
-
if (!seen.has(val)) {
|
|
394
|
-
seen.add(val);
|
|
395
|
-
ret.push(item);
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
return ret;
|
|
399
|
-
}
|
|
400
|
-
function iter(...args) {
|
|
401
|
-
let valueProvided = args.length === 2;
|
|
402
|
-
let [key, value] = args;
|
|
403
|
-
return valueProvided ? item => value === get(item, key) : item => Boolean(get(item, key));
|
|
404
|
-
}
|
|
405
|
-
function findIndex(array, predicate, startAt) {
|
|
406
|
-
let len = array.length;
|
|
407
|
-
for (let index = startAt; index < len; index++) {
|
|
408
|
-
// SAFETY: Because we're checking the index this value should always be set.
|
|
409
|
-
let item = objectAt(array, index);
|
|
410
|
-
if (predicate(item, index, array)) {
|
|
411
|
-
return index;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return -1;
|
|
415
|
-
}
|
|
416
|
-
function find(array, callback, target = null) {
|
|
417
|
-
let predicate = callback.bind(target);
|
|
418
|
-
let index = findIndex(array, predicate, 0);
|
|
419
|
-
return index === -1 ? undefined : objectAt(array, index);
|
|
420
|
-
}
|
|
421
|
-
function any(array, callback, target = null) {
|
|
422
|
-
let predicate = callback.bind(target);
|
|
423
|
-
return findIndex(array, predicate, 0) !== -1;
|
|
424
|
-
}
|
|
425
|
-
function every(array, callback, target = null) {
|
|
426
|
-
let cb = callback.bind(target);
|
|
427
|
-
let predicate = (item, index, array) => !cb(item, index, array);
|
|
428
|
-
return findIndex(array, predicate, 0) === -1;
|
|
429
|
-
}
|
|
430
|
-
function indexOf(array, val, startAt = 0, withNaNCheck) {
|
|
431
|
-
let len = array.length;
|
|
432
|
-
if (startAt < 0) {
|
|
433
|
-
startAt += len;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// SameValueZero comparison (NaN !== NaN)
|
|
437
|
-
let predicate = withNaNCheck && val !== val ? item => item !== item : item => item === val;
|
|
438
|
-
return findIndex(array, predicate, startAt);
|
|
439
|
-
}
|
|
440
|
-
function removeAt(array, index, len) {
|
|
441
|
-
(isDevelopingApp() && !(index > -1 && index < array.length) && assert(`\`removeAt\` index provided is out of range`, index > -1 && index < array.length));
|
|
442
|
-
replace(array, index, len ?? 1, EMPTY_ARRAY);
|
|
443
|
-
return array;
|
|
444
|
-
}
|
|
445
|
-
function insertAt(array, index, item) {
|
|
446
|
-
(isDevelopingApp() && !(index > -1 && index <= array.length) && assert(`\`insertAt\` index provided is out of range`, index > -1 && index <= array.length));
|
|
447
|
-
replace(array, index, 0, [item]);
|
|
448
|
-
return item;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
Returns true if the passed object is an array or Array-like.
|
|
453
|
-
|
|
454
|
-
Objects are considered Array-like if any of the following are true:
|
|
455
|
-
|
|
456
|
-
- the object is a native Array
|
|
457
|
-
- the object has an objectAt property
|
|
458
|
-
- the object is an Object, and has a length property
|
|
459
|
-
|
|
460
|
-
Unlike `typeOf` this method returns true even if the passed object is
|
|
461
|
-
not formally an array but appears to be array-like (i.e. implements `Array`)
|
|
462
|
-
|
|
463
|
-
```javascript
|
|
464
|
-
import { isArray } from '@ember/array';
|
|
465
|
-
import ArrayProxy from '@ember/array/proxy';
|
|
466
|
-
|
|
467
|
-
isArray(); // false
|
|
468
|
-
isArray([]); // true
|
|
469
|
-
isArray(ArrayProxy.create({ content: [] })); // true
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
@method isArray
|
|
473
|
-
@static
|
|
474
|
-
@for @ember/array
|
|
475
|
-
@param {Object} obj The object to test
|
|
476
|
-
@return {Boolean} true if the passed object is an array or Array-like
|
|
477
|
-
@public
|
|
478
|
-
*/
|
|
479
|
-
function isArray(obj) {
|
|
480
|
-
if (isDevelopingApp() && typeof obj === 'object' && obj !== null) {
|
|
481
|
-
// SAFETY: Property read checks are safe if it's an object
|
|
482
|
-
let possibleProxyContent = obj[PROXY_CONTENT];
|
|
483
|
-
if (possibleProxyContent !== undefined) {
|
|
484
|
-
obj = possibleProxyContent;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// SAFETY: Property read checks are safe if it's an object
|
|
489
|
-
if (!obj || obj.setInterval) {
|
|
490
|
-
return false;
|
|
491
|
-
}
|
|
492
|
-
if (Array.isArray(obj) || EmberArray.detect(obj)) {
|
|
493
|
-
return true;
|
|
494
|
-
}
|
|
495
|
-
let type = typeOf(obj);
|
|
496
|
-
if ('array' === type) {
|
|
497
|
-
return true;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// SAFETY: Property read checks are safe if it's an object
|
|
501
|
-
let length = obj.length;
|
|
502
|
-
if (typeof length === 'number' && length === length && 'object' === type) {
|
|
503
|
-
return true;
|
|
504
|
-
}
|
|
505
|
-
return false;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
/*
|
|
509
|
-
This allows us to define computed properties that are not enumerable.
|
|
510
|
-
The primary reason this is important is that when `NativeArray` is
|
|
511
|
-
applied to `Array.prototype` we need to ensure that we do not add _any_
|
|
512
|
-
new enumerable properties.
|
|
513
|
-
*/
|
|
514
|
-
function nonEnumerableComputed(callback) {
|
|
515
|
-
let property = computed(callback);
|
|
516
|
-
property.enumerable = false;
|
|
517
|
-
return property;
|
|
518
|
-
}
|
|
519
|
-
function mapBy(key) {
|
|
520
|
-
return this.map(next => get(next, key));
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// ..........................................................
|
|
524
|
-
// ARRAY
|
|
525
|
-
//
|
|
526
|
-
/**
|
|
527
|
-
This mixin implements Observer-friendly Array-like behavior. It is not a
|
|
528
|
-
concrete implementation, but it can be used up by other classes that want
|
|
529
|
-
to appear like arrays.
|
|
530
|
-
|
|
531
|
-
For example, ArrayProxy is a concrete class that can be instantiated to
|
|
532
|
-
implement array-like behavior. This class uses the Array Mixin by way of
|
|
533
|
-
the MutableArray mixin, which allows observable changes to be made to the
|
|
534
|
-
underlying array.
|
|
535
|
-
|
|
536
|
-
This mixin defines methods specifically for collections that provide
|
|
537
|
-
index-ordered access to their contents. When you are designing code that
|
|
538
|
-
needs to accept any kind of Array-like object, you should use these methods
|
|
539
|
-
instead of Array primitives because these will properly notify observers of
|
|
540
|
-
changes to the array.
|
|
541
|
-
|
|
542
|
-
Although these methods are efficient, they do add a layer of indirection to
|
|
543
|
-
your application so it is a good idea to use them only when you need the
|
|
544
|
-
flexibility of using both true JavaScript arrays and "virtual" arrays such
|
|
545
|
-
as controllers and collections.
|
|
546
|
-
|
|
547
|
-
You can use the methods defined in this module to access and modify array
|
|
548
|
-
contents in an observable-friendly way. You can also be notified whenever
|
|
549
|
-
the membership of an array changes by using `.observes('myArray.[]')`.
|
|
550
|
-
|
|
551
|
-
To support `EmberArray` in your own class, you must override two
|
|
552
|
-
primitives to use it: `length()` and `objectAt()`.
|
|
553
|
-
|
|
554
|
-
@class EmberArray
|
|
555
|
-
@uses Enumerable
|
|
556
|
-
@since Ember 0.9.0
|
|
557
|
-
@public
|
|
558
|
-
*/
|
|
559
|
-
|
|
560
|
-
const EmberArray = Mixin.create(Enumerable, {
|
|
561
|
-
init() {
|
|
562
|
-
this._super(...arguments);
|
|
563
|
-
setEmberArray(this);
|
|
564
|
-
},
|
|
565
|
-
objectsAt(indexes) {
|
|
566
|
-
return indexes.map(idx => objectAt(this, idx));
|
|
567
|
-
},
|
|
568
|
-
'[]': nonEnumerableComputed({
|
|
569
|
-
get() {
|
|
570
|
-
return this;
|
|
571
|
-
},
|
|
572
|
-
set(_key, value) {
|
|
573
|
-
this.replace(0, this.length, value);
|
|
574
|
-
return this;
|
|
575
|
-
}
|
|
576
|
-
}),
|
|
577
|
-
firstObject: nonEnumerableComputed(function () {
|
|
578
|
-
return objectAt(this, 0);
|
|
579
|
-
}).readOnly(),
|
|
580
|
-
lastObject: nonEnumerableComputed(function () {
|
|
581
|
-
return objectAt(this, this.length - 1);
|
|
582
|
-
}).readOnly(),
|
|
583
|
-
// Add any extra methods to EmberArray that are native to the built-in Array.
|
|
584
|
-
slice(beginIndex = 0, endIndex) {
|
|
585
|
-
let ret = A();
|
|
586
|
-
let length = this.length;
|
|
587
|
-
if (beginIndex < 0) {
|
|
588
|
-
beginIndex = length + beginIndex;
|
|
589
|
-
}
|
|
590
|
-
let validatedEndIndex;
|
|
591
|
-
if (endIndex === undefined || endIndex > length) {
|
|
592
|
-
validatedEndIndex = length;
|
|
593
|
-
} else if (endIndex < 0) {
|
|
594
|
-
validatedEndIndex = length + endIndex;
|
|
595
|
-
} else {
|
|
596
|
-
validatedEndIndex = endIndex;
|
|
597
|
-
}
|
|
598
|
-
while (beginIndex < validatedEndIndex) {
|
|
599
|
-
ret[ret.length] = objectAt(this, beginIndex++);
|
|
600
|
-
}
|
|
601
|
-
return ret;
|
|
602
|
-
},
|
|
603
|
-
indexOf(object, startAt) {
|
|
604
|
-
return indexOf(this, object, startAt, false);
|
|
605
|
-
},
|
|
606
|
-
lastIndexOf(object, startAt) {
|
|
607
|
-
let len = this.length;
|
|
608
|
-
if (startAt === undefined || startAt >= len) {
|
|
609
|
-
startAt = len - 1;
|
|
610
|
-
}
|
|
611
|
-
if (startAt < 0) {
|
|
612
|
-
startAt += len;
|
|
613
|
-
}
|
|
614
|
-
for (let idx = startAt; idx >= 0; idx--) {
|
|
615
|
-
if (objectAt(this, idx) === object) {
|
|
616
|
-
return idx;
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
return -1;
|
|
620
|
-
},
|
|
621
|
-
forEach(callback, target = null) {
|
|
622
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`forEach` expects a function as first argument.', typeof callback === 'function'));
|
|
623
|
-
let length = this.length;
|
|
624
|
-
for (let index = 0; index < length; index++) {
|
|
625
|
-
let item = this.objectAt(index);
|
|
626
|
-
callback.call(target, item, index, this);
|
|
627
|
-
}
|
|
628
|
-
return this;
|
|
629
|
-
},
|
|
630
|
-
getEach: mapBy,
|
|
631
|
-
setEach(key, value) {
|
|
632
|
-
return this.forEach(item => set(item, key, value));
|
|
633
|
-
},
|
|
634
|
-
map(callback, target = null) {
|
|
635
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`map` expects a function as first argument.', typeof callback === 'function'));
|
|
636
|
-
let ret = A();
|
|
637
|
-
this.forEach((x, idx, i) => ret[idx] = callback.call(target, x, idx, i));
|
|
638
|
-
return ret;
|
|
639
|
-
},
|
|
640
|
-
mapBy,
|
|
641
|
-
filter(callback, target = null) {
|
|
642
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`filter` expects a function as first argument.', typeof callback === 'function'));
|
|
643
|
-
let ret = A();
|
|
644
|
-
this.forEach((x, idx, i) => {
|
|
645
|
-
if (callback.call(target, x, idx, i)) {
|
|
646
|
-
ret.push(x);
|
|
647
|
-
}
|
|
648
|
-
});
|
|
649
|
-
return ret;
|
|
650
|
-
},
|
|
651
|
-
reject(callback, target = null) {
|
|
652
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`reject` expects a function as first argument.', typeof callback === 'function'));
|
|
653
|
-
return this.filter(function () {
|
|
654
|
-
// @ts-expect-error TS doesn't like us using arguments like this
|
|
655
|
-
return !callback.apply(target, arguments);
|
|
656
|
-
});
|
|
657
|
-
},
|
|
658
|
-
filterBy() {
|
|
659
|
-
// @ts-expect-error TS doesn't like the ...arguments spread here.
|
|
660
|
-
return this.filter(iter(...arguments));
|
|
661
|
-
},
|
|
662
|
-
rejectBy() {
|
|
663
|
-
// @ts-expect-error TS doesn't like the ...arguments spread here.
|
|
664
|
-
return this.reject(iter(...arguments));
|
|
665
|
-
},
|
|
666
|
-
find(callback, target = null) {
|
|
667
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`find` expects a function as first argument.', typeof callback === 'function'));
|
|
668
|
-
return find(this, callback, target);
|
|
669
|
-
},
|
|
670
|
-
findBy() {
|
|
671
|
-
// @ts-expect-error TS doesn't like the ...arguments spread here.
|
|
672
|
-
let callback = iter(...arguments);
|
|
673
|
-
return find(this, callback);
|
|
674
|
-
},
|
|
675
|
-
every(callback, target = null) {
|
|
676
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`every` expects a function as first argument.', typeof callback === 'function'));
|
|
677
|
-
return every(this, callback, target);
|
|
678
|
-
},
|
|
679
|
-
isEvery() {
|
|
680
|
-
// @ts-expect-error TS doesn't like the ...arguments spread here.
|
|
681
|
-
let callback = iter(...arguments);
|
|
682
|
-
return every(this, callback);
|
|
683
|
-
},
|
|
684
|
-
any(callback, target = null) {
|
|
685
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`any` expects a function as first argument.', typeof callback === 'function'));
|
|
686
|
-
return any(this, callback, target);
|
|
687
|
-
},
|
|
688
|
-
isAny() {
|
|
689
|
-
// @ts-expect-error TS doesn't like us using arguments like this
|
|
690
|
-
let callback = iter(...arguments);
|
|
691
|
-
return any(this, callback);
|
|
692
|
-
},
|
|
693
|
-
// FIXME: When called without initialValue, behavior does not match native behavior
|
|
694
|
-
reduce(callback, initialValue) {
|
|
695
|
-
(isDevelopingApp() && !(typeof callback === 'function') && assert('`reduce` expects a function as first argument.', typeof callback === 'function'));
|
|
696
|
-
let ret = initialValue;
|
|
697
|
-
this.forEach(function (item, i) {
|
|
698
|
-
ret = callback(ret, item, i, this);
|
|
699
|
-
}, this);
|
|
700
|
-
return ret;
|
|
701
|
-
},
|
|
702
|
-
invoke(methodName, ...args) {
|
|
703
|
-
let ret = A();
|
|
704
|
-
|
|
705
|
-
// SAFETY: This is not entirely safe and the code will not work with Ember proxies
|
|
706
|
-
this.forEach(item => ret.push(item[methodName]?.(...args)));
|
|
707
|
-
return ret;
|
|
708
|
-
},
|
|
709
|
-
toArray() {
|
|
710
|
-
return this.map(item => item);
|
|
711
|
-
},
|
|
712
|
-
compact() {
|
|
713
|
-
return this.filter(value => value != null);
|
|
714
|
-
},
|
|
715
|
-
includes(object, startAt) {
|
|
716
|
-
return indexOf(this, object, startAt, true) !== -1;
|
|
717
|
-
},
|
|
718
|
-
sortBy() {
|
|
719
|
-
let sortKeys = arguments;
|
|
720
|
-
return this.toArray().sort((a, b) => {
|
|
721
|
-
for (let i = 0; i < sortKeys.length; i++) {
|
|
722
|
-
let key = sortKeys[i];
|
|
723
|
-
let propA = get(a, key);
|
|
724
|
-
let propB = get(b, key);
|
|
725
|
-
// return 1 or -1 else continue to the next sortKey
|
|
726
|
-
let compareValue = compare(propA, propB);
|
|
727
|
-
if (compareValue) {
|
|
728
|
-
return compareValue;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
return 0;
|
|
732
|
-
});
|
|
733
|
-
},
|
|
734
|
-
uniq() {
|
|
735
|
-
return uniqBy(this);
|
|
736
|
-
},
|
|
737
|
-
uniqBy(key) {
|
|
738
|
-
return uniqBy(this, key);
|
|
739
|
-
},
|
|
740
|
-
without(value) {
|
|
741
|
-
if (!this.includes(value)) {
|
|
742
|
-
return this; // nothing to do
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
// SameValueZero comparison (NaN !== NaN)
|
|
746
|
-
let predicate = value === value ? item => item !== value : item => item === item;
|
|
747
|
-
return this.filter(predicate);
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
|
|
751
|
-
/**
|
|
752
|
-
This mixin defines the API for modifying array-like objects. These methods
|
|
753
|
-
can be applied only to a collection that keeps its items in an ordered set.
|
|
754
|
-
It builds upon the Array mixin and adds methods to modify the array.
|
|
755
|
-
One concrete implementations of this class include ArrayProxy.
|
|
756
|
-
|
|
757
|
-
It is important to use the methods in this class to modify arrays so that
|
|
758
|
-
changes are observable. This allows the binding system in Ember to function
|
|
759
|
-
correctly.
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
Note that an Array can change even if it does not implement this mixin.
|
|
763
|
-
For example, one might implement a SparseArray that cannot be directly
|
|
764
|
-
modified, but if its underlying enumerable changes, it will change also.
|
|
765
|
-
|
|
766
|
-
@class MutableArray
|
|
767
|
-
@uses EmberArray
|
|
768
|
-
@uses MutableEnumerable
|
|
769
|
-
@public
|
|
770
|
-
*/
|
|
771
|
-
|
|
772
|
-
const MutableArray = Mixin.create(EmberArray, MutableEnumerable, {
|
|
773
|
-
clear() {
|
|
774
|
-
let len = this.length;
|
|
775
|
-
if (len === 0) {
|
|
776
|
-
return this;
|
|
777
|
-
}
|
|
778
|
-
this.replace(0, len, EMPTY_ARRAY);
|
|
779
|
-
return this;
|
|
780
|
-
},
|
|
781
|
-
insertAt(idx, object) {
|
|
782
|
-
insertAt(this, idx, object);
|
|
783
|
-
return this;
|
|
784
|
-
},
|
|
785
|
-
removeAt(start, len) {
|
|
786
|
-
return removeAt(this, start, len);
|
|
787
|
-
},
|
|
788
|
-
pushObject(obj) {
|
|
789
|
-
return insertAt(this, this.length, obj);
|
|
790
|
-
},
|
|
791
|
-
pushObjects(objects) {
|
|
792
|
-
this.replace(this.length, 0, objects);
|
|
793
|
-
return this;
|
|
794
|
-
},
|
|
795
|
-
popObject() {
|
|
796
|
-
let len = this.length;
|
|
797
|
-
if (len === 0) {
|
|
798
|
-
return null;
|
|
799
|
-
}
|
|
800
|
-
let ret = objectAt(this, len - 1);
|
|
801
|
-
this.removeAt(len - 1, 1);
|
|
802
|
-
return ret;
|
|
803
|
-
},
|
|
804
|
-
shiftObject() {
|
|
805
|
-
if (this.length === 0) {
|
|
806
|
-
return null;
|
|
807
|
-
}
|
|
808
|
-
let ret = objectAt(this, 0);
|
|
809
|
-
this.removeAt(0);
|
|
810
|
-
return ret;
|
|
811
|
-
},
|
|
812
|
-
unshiftObject(obj) {
|
|
813
|
-
return insertAt(this, 0, obj);
|
|
814
|
-
},
|
|
815
|
-
unshiftObjects(objects) {
|
|
816
|
-
this.replace(0, 0, objects);
|
|
817
|
-
return this;
|
|
818
|
-
},
|
|
819
|
-
reverseObjects() {
|
|
820
|
-
let len = this.length;
|
|
821
|
-
if (len === 0) {
|
|
822
|
-
return this;
|
|
823
|
-
}
|
|
824
|
-
let objects = this.toArray().reverse();
|
|
825
|
-
this.replace(0, len, objects);
|
|
826
|
-
return this;
|
|
827
|
-
},
|
|
828
|
-
setObjects(objects) {
|
|
829
|
-
if (objects.length === 0) {
|
|
830
|
-
return this.clear();
|
|
831
|
-
}
|
|
832
|
-
let len = this.length;
|
|
833
|
-
this.replace(0, len, objects);
|
|
834
|
-
return this;
|
|
835
|
-
},
|
|
836
|
-
removeObject(obj) {
|
|
837
|
-
let loc = this.length || 0;
|
|
838
|
-
while (--loc >= 0) {
|
|
839
|
-
let curObject = objectAt(this, loc);
|
|
840
|
-
if (curObject === obj) {
|
|
841
|
-
this.removeAt(loc);
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
return this;
|
|
845
|
-
},
|
|
846
|
-
removeObjects(objects) {
|
|
847
|
-
beginPropertyChanges();
|
|
848
|
-
for (let i = objects.length - 1; i >= 0; i--) {
|
|
849
|
-
// SAFETY: Due to the loop structure we know this will always exist.
|
|
850
|
-
this.removeObject(objects[i]);
|
|
851
|
-
}
|
|
852
|
-
endPropertyChanges();
|
|
853
|
-
return this;
|
|
854
|
-
},
|
|
855
|
-
addObject(obj) {
|
|
856
|
-
let included = this.includes(obj);
|
|
857
|
-
if (!included) {
|
|
858
|
-
this.pushObject(obj);
|
|
859
|
-
}
|
|
860
|
-
return this;
|
|
861
|
-
},
|
|
862
|
-
addObjects(objects) {
|
|
863
|
-
beginPropertyChanges();
|
|
864
|
-
objects.forEach(obj => this.addObject(obj));
|
|
865
|
-
endPropertyChanges();
|
|
866
|
-
return this;
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
|
|
870
|
-
/**
|
|
871
|
-
Creates an `Ember.NativeArray` from an Array-like object.
|
|
872
|
-
Does not modify the original object's contents. `A()` is not needed if
|
|
873
|
-
`EmberENV.EXTEND_PROTOTYPES` is `true` (the default value). However,
|
|
874
|
-
it is recommended that you use `A()` when creating addons for
|
|
875
|
-
ember or when you can not guarantee that `EmberENV.EXTEND_PROTOTYPES`
|
|
876
|
-
will be `true`.
|
|
877
|
-
|
|
878
|
-
Example
|
|
879
|
-
|
|
880
|
-
```app/components/my-component.js
|
|
881
|
-
import Component from '@ember/component';
|
|
882
|
-
import { A } from '@ember/array';
|
|
883
|
-
|
|
884
|
-
export default Component.extend({
|
|
885
|
-
tagName: 'ul',
|
|
886
|
-
classNames: ['pagination'],
|
|
887
|
-
|
|
888
|
-
init() {
|
|
889
|
-
this._super(...arguments);
|
|
890
|
-
|
|
891
|
-
if (!this.get('content')) {
|
|
892
|
-
this.set('content', A());
|
|
893
|
-
this.set('otherContent', A([1,2,3]));
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
});
|
|
897
|
-
```
|
|
898
|
-
|
|
899
|
-
@method A
|
|
900
|
-
@static
|
|
901
|
-
@for @ember/array
|
|
902
|
-
@return {Ember.NativeArray}
|
|
903
|
-
@public
|
|
904
|
-
*/
|
|
905
|
-
|
|
906
|
-
// Add Ember.Array to Array.prototype. Remove methods with native
|
|
907
|
-
// implementations and supply some more optimized versions of generic methods
|
|
908
|
-
// because they are so common.
|
|
909
|
-
/**
|
|
910
|
-
@module ember
|
|
911
|
-
*/
|
|
912
|
-
|
|
913
|
-
/**
|
|
914
|
-
* The final definition of NativeArray removes all native methods. This is the list of removed methods
|
|
915
|
-
* when run in Chrome 106.
|
|
916
|
-
*/
|
|
917
|
-
|
|
918
|
-
/**
|
|
919
|
-
* These additional items must be redefined since `Omit` causes methods that return `this` to return the
|
|
920
|
-
* type at the time of the Omit.
|
|
921
|
-
*/
|
|
922
|
-
|
|
923
|
-
// This is the same as MutableArray, but removes the actual native methods that exist on Array.prototype.
|
|
924
|
-
|
|
925
|
-
/**
|
|
926
|
-
The NativeArray mixin contains the properties needed to make the native
|
|
927
|
-
Array support MutableArray and all of its dependent APIs. Unless you
|
|
928
|
-
have `EmberENV.EXTEND_PROTOTYPES` or `EmberENV.EXTEND_PROTOTYPES.Array` set to
|
|
929
|
-
false, this will be applied automatically. Otherwise you can apply the mixin
|
|
930
|
-
at anytime by calling `Ember.NativeArray.apply(Array.prototype)`.
|
|
931
|
-
|
|
932
|
-
@class Ember.NativeArray
|
|
933
|
-
@uses MutableArray
|
|
934
|
-
@uses Observable
|
|
935
|
-
@public
|
|
936
|
-
*/
|
|
937
|
-
|
|
938
|
-
let NativeArray = Mixin.create(MutableArray, Observable, {
|
|
939
|
-
objectAt(idx) {
|
|
940
|
-
return this[idx];
|
|
941
|
-
},
|
|
942
|
-
// primitive for array support.
|
|
943
|
-
replace(start, deleteCount, items = EMPTY_ARRAY) {
|
|
944
|
-
(isDevelopingApp() && !(Array.isArray(items)) && assert('The third argument to replace needs to be an array.', Array.isArray(items)));
|
|
945
|
-
replaceInNativeArray(this, start, deleteCount, items);
|
|
946
|
-
return this;
|
|
947
|
-
}
|
|
948
|
-
});
|
|
949
|
-
|
|
950
|
-
// Remove any methods implemented natively so we don't override them
|
|
951
|
-
const ignore = ['length'];
|
|
952
|
-
NativeArray.keys().forEach(methodName => {
|
|
953
|
-
// SAFETY: It's safe to read unknown properties from an object
|
|
954
|
-
if (Array.prototype[methodName]) {
|
|
955
|
-
ignore.push(methodName);
|
|
956
|
-
}
|
|
957
|
-
});
|
|
958
|
-
NativeArray = NativeArray.without(...ignore);
|
|
959
|
-
let A;
|
|
960
|
-
if (ENV.EXTEND_PROTOTYPES.Array) {
|
|
961
|
-
NativeArray.apply(Array.prototype, true);
|
|
962
|
-
A = function (arr) {
|
|
963
|
-
(isDevelopingApp() && !(!(this instanceof A)) && assert('You cannot create an Ember Array with `new A()`, please update to calling A as a function: `A()`', !(this instanceof A))); // SAFTEY: Since we are extending prototypes all true native arrays are Ember NativeArrays
|
|
964
|
-
return arr || [];
|
|
965
|
-
};
|
|
966
|
-
} else {
|
|
967
|
-
A = function (arr) {
|
|
968
|
-
(isDevelopingApp() && !(!(this instanceof A)) && assert('You cannot create an Ember Array with `new A()`, please update to calling A as a function: `A()`', !(this instanceof A)));
|
|
969
|
-
if (isEmberArray(arr)) {
|
|
970
|
-
// SAFETY: If it's a true native array and it is also an EmberArray then it should be an Ember NativeArray
|
|
971
|
-
return arr;
|
|
972
|
-
} else {
|
|
973
|
-
// SAFETY: This will return an NativeArray but TS can't infer that.
|
|
974
|
-
return NativeArray.apply(arr ?? []);
|
|
975
|
-
}
|
|
976
|
-
};
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
/**
|
|
980
|
-
@module @ember/object/core
|
|
981
|
-
*/
|
|
982
|
-
|
|
983
|
-
function hasSetUnknownProperty(val) {
|
|
984
|
-
return typeof val === 'object' && val !== null && typeof val.setUnknownProperty === 'function';
|
|
985
|
-
}
|
|
986
|
-
function hasToStringExtension(val) {
|
|
987
|
-
return typeof val === 'object' && val !== null && typeof val.toStringExtension === 'function';
|
|
988
|
-
}
|
|
989
|
-
const reopen = Mixin.prototype.reopen;
|
|
990
|
-
const wasApplied = new WeakSet();
|
|
991
|
-
const prototypeMixinMap = new WeakMap();
|
|
992
|
-
const initCalled = isDevelopingApp() ? new WeakSet() : undefined; // only used in debug builds to enable the proxy trap
|
|
993
|
-
|
|
994
|
-
const destroyCalled = new Set();
|
|
995
|
-
function ensureDestroyCalled(instance) {
|
|
996
|
-
if (!destroyCalled.has(instance)) {
|
|
997
|
-
instance.destroy();
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
function initialize(obj, properties) {
|
|
1001
|
-
let m = meta(obj);
|
|
1002
|
-
if (properties !== undefined) {
|
|
1003
|
-
(isDevelopingApp() && !(typeof properties === 'object' && properties !== null) && assert('EmberObject.create only accepts objects.', typeof properties === 'object' && properties !== null));
|
|
1004
|
-
(isDevelopingApp() && !(!(properties instanceof Mixin)) && assert('EmberObject.create no longer supports mixing in other ' + 'definitions, use .extend & .create separately instead.', !(properties instanceof Mixin)));
|
|
1005
|
-
let concatenatedProperties = obj.concatenatedProperties;
|
|
1006
|
-
let mergedProperties = obj.mergedProperties;
|
|
1007
|
-
let keyNames = Object.keys(properties);
|
|
1008
|
-
for (let keyName of keyNames) {
|
|
1009
|
-
// SAFETY: this cast as a Record is safe because all object types can be
|
|
1010
|
-
// indexed in JS, and we explicitly type it as returning `unknown`, so the
|
|
1011
|
-
// result *must* be checked below.
|
|
1012
|
-
let value = properties[keyName];
|
|
1013
|
-
(isDevelopingApp() && !(!isClassicDecorator(value)) && assert('EmberObject.create no longer supports defining computed ' + 'properties. Define computed properties using extend() or reopen() ' + 'before calling create().', !isClassicDecorator(value)));
|
|
1014
|
-
(isDevelopingApp() && !(!(typeof value === 'function' && value.toString().indexOf('._super') !== -1)) && assert('EmberObject.create no longer supports defining methods that call _super.', !(typeof value === 'function' && value.toString().indexOf('._super') !== -1)));
|
|
1015
|
-
(isDevelopingApp() && !(!(keyName === 'actions' && ActionHandler.detect(obj))) && assert('`actions` must be provided at extend time, not at create time, ' + 'when Ember.ActionHandler is used (i.e. views, controllers & routes).', !(keyName === 'actions' && ActionHandler.detect(obj))));
|
|
1016
|
-
let possibleDesc = descriptorForProperty(obj, keyName, m);
|
|
1017
|
-
let isDescriptor = possibleDesc !== undefined;
|
|
1018
|
-
if (!isDescriptor) {
|
|
1019
|
-
if (concatenatedProperties !== undefined && concatenatedProperties.length > 0 && concatenatedProperties.includes(keyName)) {
|
|
1020
|
-
let baseValue = obj[keyName];
|
|
1021
|
-
if (baseValue) {
|
|
1022
|
-
value = makeArray(baseValue).concat(value);
|
|
1023
|
-
} else {
|
|
1024
|
-
value = makeArray(value);
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
if (mergedProperties !== undefined && mergedProperties.length > 0 && mergedProperties.includes(keyName)) {
|
|
1028
|
-
let baseValue = obj[keyName];
|
|
1029
|
-
value = Object.assign({}, baseValue, value);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
if (isDescriptor) {
|
|
1033
|
-
possibleDesc.set(obj, keyName, value);
|
|
1034
|
-
} else if (hasSetUnknownProperty(obj) && !(keyName in obj)) {
|
|
1035
|
-
obj.setUnknownProperty(keyName, value);
|
|
1036
|
-
} else {
|
|
1037
|
-
if (isDevelopingApp()) {
|
|
1038
|
-
defineProperty(obj, keyName, null, value, m); // setup mandatory setter
|
|
1039
|
-
} else {
|
|
1040
|
-
obj[keyName] = value;
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
// using DEBUG here to avoid the extraneous variable when not needed
|
|
1047
|
-
if (isDevelopingApp()) {
|
|
1048
|
-
initCalled.add(obj);
|
|
1049
|
-
}
|
|
1050
|
-
obj.init(properties);
|
|
1051
|
-
m.unsetInitializing();
|
|
1052
|
-
let observerEvents = m.observerEvents();
|
|
1053
|
-
if (observerEvents !== undefined) {
|
|
1054
|
-
for (let i = 0; i < observerEvents.length; i++) {
|
|
1055
|
-
activateObserver(obj, observerEvents[i].event, observerEvents[i].sync);
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
sendEvent(obj, 'init', undefined, undefined, m);
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
/**
|
|
1062
|
-
`CoreObject` is the base class for all Ember constructs. It establishes a
|
|
1063
|
-
class system based on Ember's Mixin system, and provides the basis for the
|
|
1064
|
-
Ember Object Model. `CoreObject` should generally not be used directly,
|
|
1065
|
-
instead you should use `EmberObject`.
|
|
1066
|
-
|
|
1067
|
-
## Usage
|
|
1068
|
-
|
|
1069
|
-
You can define a class by extending from `CoreObject` using the `extend`
|
|
1070
|
-
method:
|
|
1071
|
-
|
|
1072
|
-
```js
|
|
1073
|
-
const Person = CoreObject.extend({
|
|
1074
|
-
name: 'Tomster',
|
|
1075
|
-
});
|
|
1076
|
-
```
|
|
1077
|
-
|
|
1078
|
-
For detailed usage, see the [Object Model](https://guides.emberjs.com/release/object-model/)
|
|
1079
|
-
section of the guides.
|
|
1080
|
-
|
|
1081
|
-
## Usage with Native Classes
|
|
1082
|
-
|
|
1083
|
-
Native JavaScript `class` syntax can be used to extend from any `CoreObject`
|
|
1084
|
-
based class:
|
|
1085
|
-
|
|
1086
|
-
```js
|
|
1087
|
-
class Person extends CoreObject {
|
|
1088
|
-
init() {
|
|
1089
|
-
super.init(...arguments);
|
|
1090
|
-
this.name = 'Tomster';
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
```
|
|
1094
|
-
|
|
1095
|
-
Some notes about `class` usage:
|
|
1096
|
-
|
|
1097
|
-
* `new` syntax is not currently supported with classes that extend from
|
|
1098
|
-
`EmberObject` or `CoreObject`. You must continue to use the `create` method
|
|
1099
|
-
when making new instances of classes, even if they are defined using native
|
|
1100
|
-
class syntax. If you want to use `new` syntax, consider creating classes
|
|
1101
|
-
which do _not_ extend from `EmberObject` or `CoreObject`. Ember features,
|
|
1102
|
-
such as computed properties and decorators, will still work with base-less
|
|
1103
|
-
classes.
|
|
1104
|
-
* Instead of using `this._super()`, you must use standard `super` syntax in
|
|
1105
|
-
native classes. See the [MDN docs on classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Super_class_calls_with_super)
|
|
1106
|
-
for more details.
|
|
1107
|
-
* Native classes support using [constructors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Constructor)
|
|
1108
|
-
to set up newly-created instances. Ember uses these to, among other things,
|
|
1109
|
-
support features that need to retrieve other entities by name, like Service
|
|
1110
|
-
injection and `getOwner`. To ensure your custom instance setup logic takes
|
|
1111
|
-
place after this important work is done, avoid using the `constructor` in
|
|
1112
|
-
favor of `init`.
|
|
1113
|
-
* Properties passed to `create` will be available on the instance by the time
|
|
1114
|
-
`init` runs, so any code that requires these values should work at that
|
|
1115
|
-
time.
|
|
1116
|
-
* Using native classes, and switching back to the old Ember Object model is
|
|
1117
|
-
fully supported.
|
|
1118
|
-
|
|
1119
|
-
@class CoreObject
|
|
1120
|
-
@public
|
|
1121
|
-
*/
|
|
1122
|
-
|
|
1123
|
-
class CoreObject {
|
|
1124
|
-
/** @internal */
|
|
1125
|
-
[OWNER];
|
|
1126
|
-
constructor(owner) {
|
|
1127
|
-
this[OWNER] = owner;
|
|
1128
|
-
|
|
1129
|
-
// prepare prototype...
|
|
1130
|
-
this.constructor.proto();
|
|
1131
|
-
let self;
|
|
1132
|
-
if (isDevelopingApp() && hasUnknownProperty(this)) {
|
|
1133
|
-
let messageFor = (obj, property) => {
|
|
1134
|
-
return `You attempted to access the \`${String(property)}\` property (of ${obj}).\n` + `Since Ember 3.1, this is usually fine as you no longer need to use \`.get()\`\n` + `to access computed properties. However, in this case, the object in question\n` + `is a special kind of Ember object (a proxy). Therefore, it is still necessary\n` + `to use \`.get('${String(property)}')\` in this case.\n\n` + `If you encountered this error because of third-party code that you don't control,\n` + `there is more information at https://github.com/emberjs/ember.js/issues/16148, and\n` + `you can help us improve this error message by telling us more about what happened in\n` + `this situation.`;
|
|
1135
|
-
};
|
|
1136
|
-
|
|
1137
|
-
/* globals Proxy Reflect */
|
|
1138
|
-
self = new Proxy(this, {
|
|
1139
|
-
get(target, property, receiver) {
|
|
1140
|
-
if (property === PROXY_CONTENT) {
|
|
1141
|
-
return target;
|
|
1142
|
-
} else if (
|
|
1143
|
-
// init called will be set on the proxy, not the target, so get with the receiver
|
|
1144
|
-
!initCalled.has(receiver) || typeof property === 'symbol' || isInternalSymbol(property) || property === 'toJSON' || property === 'toString' || property === 'toStringExtension' || property === 'didDefineProperty' || property === 'willWatchProperty' || property === 'didUnwatchProperty' || property === 'didAddListener' || property === 'didRemoveListener' || property === 'isDescriptor' || property === '_onLookup' || property in target) {
|
|
1145
|
-
return Reflect.get(target, property, receiver);
|
|
1146
|
-
}
|
|
1147
|
-
let value = target.unknownProperty.call(receiver, property);
|
|
1148
|
-
if (typeof value !== 'function') {
|
|
1149
|
-
(isDevelopingApp() && !(value === undefined || value === null) && assert(messageFor(receiver, property), value === undefined || value === null));
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
});
|
|
1153
|
-
} else {
|
|
1154
|
-
self = this;
|
|
1155
|
-
}
|
|
1156
|
-
const destroyable = self;
|
|
1157
|
-
registerDestructor(self, ensureDestroyCalled, true);
|
|
1158
|
-
registerDestructor(self, () => destroyable.willDestroy());
|
|
1159
|
-
|
|
1160
|
-
// disable chains
|
|
1161
|
-
let m = meta(self);
|
|
1162
|
-
m.setInitializing();
|
|
1163
|
-
|
|
1164
|
-
// only return when in debug builds and `self` is the proxy created above
|
|
1165
|
-
if (isDevelopingApp() && self !== this) {
|
|
1166
|
-
return self;
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
reopen(...args) {
|
|
1170
|
-
applyMixin(this, args);
|
|
1171
|
-
return this;
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
/**
|
|
1175
|
-
An overridable method called when objects are instantiated. By default,
|
|
1176
|
-
does nothing unless it is overridden during class definition.
|
|
1177
|
-
Example:
|
|
1178
|
-
```javascript
|
|
1179
|
-
import EmberObject from '@ember/object';
|
|
1180
|
-
const Person = EmberObject.extend({
|
|
1181
|
-
init() {
|
|
1182
|
-
alert(`Name is ${this.get('name')}`);
|
|
1183
|
-
}
|
|
1184
|
-
});
|
|
1185
|
-
let steve = Person.create({
|
|
1186
|
-
name: 'Steve'
|
|
1187
|
-
});
|
|
1188
|
-
// alerts 'Name is Steve'.
|
|
1189
|
-
```
|
|
1190
|
-
NOTE: If you do override `init` for a framework class like `Component`
|
|
1191
|
-
from `@ember/component`, be sure to call `this._super(...arguments)`
|
|
1192
|
-
in your `init` declaration!
|
|
1193
|
-
If you don't, Ember may not have an opportunity to
|
|
1194
|
-
do important setup work, and you'll see strange behavior in your
|
|
1195
|
-
application.
|
|
1196
|
-
@method init
|
|
1197
|
-
@public
|
|
1198
|
-
*/
|
|
1199
|
-
init(_properties) {}
|
|
1200
|
-
|
|
1201
|
-
/**
|
|
1202
|
-
Defines the properties that will be concatenated from the superclass
|
|
1203
|
-
(instead of overridden).
|
|
1204
|
-
By default, when you extend an Ember class a property defined in
|
|
1205
|
-
the subclass overrides a property with the same name that is defined
|
|
1206
|
-
in the superclass. However, there are some cases where it is preferable
|
|
1207
|
-
to build up a property's value by combining the superclass' property
|
|
1208
|
-
value with the subclass' value. An example of this in use within Ember
|
|
1209
|
-
is the `classNames` property of `Component` from `@ember/component`.
|
|
1210
|
-
Here is some sample code showing the difference between a concatenated
|
|
1211
|
-
property and a normal one:
|
|
1212
|
-
```javascript
|
|
1213
|
-
import EmberObject from '@ember/object';
|
|
1214
|
-
const Bar = EmberObject.extend({
|
|
1215
|
-
// Configure which properties to concatenate
|
|
1216
|
-
concatenatedProperties: ['concatenatedProperty'],
|
|
1217
|
-
someNonConcatenatedProperty: ['bar'],
|
|
1218
|
-
concatenatedProperty: ['bar']
|
|
1219
|
-
});
|
|
1220
|
-
const FooBar = Bar.extend({
|
|
1221
|
-
someNonConcatenatedProperty: ['foo'],
|
|
1222
|
-
concatenatedProperty: ['foo']
|
|
1223
|
-
});
|
|
1224
|
-
let fooBar = FooBar.create();
|
|
1225
|
-
fooBar.get('someNonConcatenatedProperty'); // ['foo']
|
|
1226
|
-
fooBar.get('concatenatedProperty'); // ['bar', 'foo']
|
|
1227
|
-
```
|
|
1228
|
-
This behavior extends to object creation as well. Continuing the
|
|
1229
|
-
above example:
|
|
1230
|
-
```javascript
|
|
1231
|
-
let fooBar = FooBar.create({
|
|
1232
|
-
someNonConcatenatedProperty: ['baz'],
|
|
1233
|
-
concatenatedProperty: ['baz']
|
|
1234
|
-
})
|
|
1235
|
-
fooBar.get('someNonConcatenatedProperty'); // ['baz']
|
|
1236
|
-
fooBar.get('concatenatedProperty'); // ['bar', 'foo', 'baz']
|
|
1237
|
-
```
|
|
1238
|
-
Adding a single property that is not an array will just add it in the array:
|
|
1239
|
-
```javascript
|
|
1240
|
-
let fooBar = FooBar.create({
|
|
1241
|
-
concatenatedProperty: 'baz'
|
|
1242
|
-
})
|
|
1243
|
-
view.get('concatenatedProperty'); // ['bar', 'foo', 'baz']
|
|
1244
|
-
```
|
|
1245
|
-
Using the `concatenatedProperties` property, we can tell Ember to mix the
|
|
1246
|
-
content of the properties.
|
|
1247
|
-
In `Component` the `classNames`, `classNameBindings` and
|
|
1248
|
-
`attributeBindings` properties are concatenated.
|
|
1249
|
-
This feature is available for you to use throughout the Ember object model,
|
|
1250
|
-
although typical app developers are likely to use it infrequently. Since
|
|
1251
|
-
it changes expectations about behavior of properties, you should properly
|
|
1252
|
-
document its usage in each individual concatenated property (to not
|
|
1253
|
-
mislead your users to think they can override the property in a subclass).
|
|
1254
|
-
@property concatenatedProperties
|
|
1255
|
-
@type Array
|
|
1256
|
-
@default null
|
|
1257
|
-
@public
|
|
1258
|
-
*/
|
|
1259
|
-
|
|
1260
|
-
/**
|
|
1261
|
-
Defines the properties that will be merged from the superclass
|
|
1262
|
-
(instead of overridden).
|
|
1263
|
-
By default, when you extend an Ember class a property defined in
|
|
1264
|
-
the subclass overrides a property with the same name that is defined
|
|
1265
|
-
in the superclass. However, there are some cases where it is preferable
|
|
1266
|
-
to build up a property's value by merging the superclass property value
|
|
1267
|
-
with the subclass property's value. An example of this in use within Ember
|
|
1268
|
-
is the `queryParams` property of routes.
|
|
1269
|
-
Here is some sample code showing the difference between a merged
|
|
1270
|
-
property and a normal one:
|
|
1271
|
-
```javascript
|
|
1272
|
-
import EmberObject from '@ember/object';
|
|
1273
|
-
const Bar = EmberObject.extend({
|
|
1274
|
-
// Configure which properties are to be merged
|
|
1275
|
-
mergedProperties: ['mergedProperty'],
|
|
1276
|
-
someNonMergedProperty: {
|
|
1277
|
-
nonMerged: 'superclass value of nonMerged'
|
|
1278
|
-
},
|
|
1279
|
-
mergedProperty: {
|
|
1280
|
-
page: { replace: false },
|
|
1281
|
-
limit: { replace: true }
|
|
1282
|
-
}
|
|
1283
|
-
});
|
|
1284
|
-
const FooBar = Bar.extend({
|
|
1285
|
-
someNonMergedProperty: {
|
|
1286
|
-
completelyNonMerged: 'subclass value of nonMerged'
|
|
1287
|
-
},
|
|
1288
|
-
mergedProperty: {
|
|
1289
|
-
limit: { replace: false }
|
|
1290
|
-
}
|
|
1291
|
-
});
|
|
1292
|
-
let fooBar = FooBar.create();
|
|
1293
|
-
fooBar.get('someNonMergedProperty');
|
|
1294
|
-
// => { completelyNonMerged: 'subclass value of nonMerged' }
|
|
1295
|
-
//
|
|
1296
|
-
// Note the entire object, including the nonMerged property of
|
|
1297
|
-
// the superclass object, has been replaced
|
|
1298
|
-
fooBar.get('mergedProperty');
|
|
1299
|
-
// => {
|
|
1300
|
-
// page: {replace: false},
|
|
1301
|
-
// limit: {replace: false}
|
|
1302
|
-
// }
|
|
1303
|
-
//
|
|
1304
|
-
// Note the page remains from the superclass, and the
|
|
1305
|
-
// `limit` property's value of `false` has been merged from
|
|
1306
|
-
// the subclass.
|
|
1307
|
-
```
|
|
1308
|
-
This behavior is not available during object `create` calls. It is only
|
|
1309
|
-
available at `extend` time.
|
|
1310
|
-
In `Route` the `queryParams` property is merged.
|
|
1311
|
-
This feature is available for you to use throughout the Ember object model,
|
|
1312
|
-
although typical app developers are likely to use it infrequently. Since
|
|
1313
|
-
it changes expectations about behavior of properties, you should properly
|
|
1314
|
-
document its usage in each individual merged property (to not
|
|
1315
|
-
mislead your users to think they can override the property in a subclass).
|
|
1316
|
-
@property mergedProperties
|
|
1317
|
-
@type Array
|
|
1318
|
-
@default null
|
|
1319
|
-
@public
|
|
1320
|
-
*/
|
|
1321
|
-
|
|
1322
|
-
/**
|
|
1323
|
-
Destroyed object property flag.
|
|
1324
|
-
if this property is `true` the observers and bindings were already
|
|
1325
|
-
removed by the effect of calling the `destroy()` method.
|
|
1326
|
-
@property isDestroyed
|
|
1327
|
-
@default false
|
|
1328
|
-
@public
|
|
1329
|
-
*/
|
|
1330
|
-
get isDestroyed() {
|
|
1331
|
-
return isDestroyed(this);
|
|
1332
|
-
}
|
|
1333
|
-
set isDestroyed(_value) {
|
|
1334
|
-
(isDevelopingApp() && !(false) && assert(`You cannot set \`${this}.isDestroyed\` directly, please use \`.destroy()\`.`, false));
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
|
-
/**
|
|
1338
|
-
Destruction scheduled flag. The `destroy()` method has been called.
|
|
1339
|
-
The object stays intact until the end of the run loop at which point
|
|
1340
|
-
the `isDestroyed` flag is set.
|
|
1341
|
-
@property isDestroying
|
|
1342
|
-
@default false
|
|
1343
|
-
@public
|
|
1344
|
-
*/
|
|
1345
|
-
get isDestroying() {
|
|
1346
|
-
return isDestroying(this);
|
|
1347
|
-
}
|
|
1348
|
-
set isDestroying(_value) {
|
|
1349
|
-
(isDevelopingApp() && !(false) && assert(`You cannot set \`${this}.isDestroying\` directly, please use \`.destroy()\`.`, false));
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
/**
|
|
1353
|
-
Destroys an object by setting the `isDestroyed` flag and removing its
|
|
1354
|
-
metadata, which effectively destroys observers and bindings.
|
|
1355
|
-
If you try to set a property on a destroyed object, an exception will be
|
|
1356
|
-
raised.
|
|
1357
|
-
Note that destruction is scheduled for the end of the run loop and does not
|
|
1358
|
-
happen immediately. It will set an isDestroying flag immediately.
|
|
1359
|
-
@method destroy
|
|
1360
|
-
@return {EmberObject} receiver
|
|
1361
|
-
@public
|
|
1362
|
-
*/
|
|
1363
|
-
destroy() {
|
|
1364
|
-
// Used to ensure that manually calling `.destroy()` does not immediately call destroy again
|
|
1365
|
-
destroyCalled.add(this);
|
|
1366
|
-
try {
|
|
1367
|
-
destroy(this);
|
|
1368
|
-
} finally {
|
|
1369
|
-
destroyCalled.delete(this);
|
|
1370
|
-
}
|
|
1371
|
-
return this;
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
/**
|
|
1375
|
-
Override to implement teardown.
|
|
1376
|
-
@method willDestroy
|
|
1377
|
-
@public
|
|
1378
|
-
*/
|
|
1379
|
-
willDestroy() {}
|
|
1380
|
-
|
|
1381
|
-
/**
|
|
1382
|
-
Returns a string representation which attempts to provide more information
|
|
1383
|
-
than Javascript's `toString` typically does, in a generic way for all Ember
|
|
1384
|
-
objects.
|
|
1385
|
-
```javascript
|
|
1386
|
-
import EmberObject from '@ember/object';
|
|
1387
|
-
const Person = EmberObject.extend();
|
|
1388
|
-
person = Person.create();
|
|
1389
|
-
person.toString(); //=> "<Person:ember1024>"
|
|
1390
|
-
```
|
|
1391
|
-
If the object's class is not defined on an Ember namespace, it will
|
|
1392
|
-
indicate it is a subclass of the registered superclass:
|
|
1393
|
-
```javascript
|
|
1394
|
-
const Student = Person.extend();
|
|
1395
|
-
let student = Student.create();
|
|
1396
|
-
student.toString(); //=> "<(subclass of Person):ember1025>"
|
|
1397
|
-
```
|
|
1398
|
-
If the method `toStringExtension` is defined, its return value will be
|
|
1399
|
-
included in the output.
|
|
1400
|
-
```javascript
|
|
1401
|
-
const Teacher = Person.extend({
|
|
1402
|
-
toStringExtension() {
|
|
1403
|
-
return this.get('fullName');
|
|
1404
|
-
}
|
|
1405
|
-
});
|
|
1406
|
-
teacher = Teacher.create();
|
|
1407
|
-
teacher.toString(); //=> "<Teacher:ember1026:Tom Dale>"
|
|
1408
|
-
```
|
|
1409
|
-
@method toString
|
|
1410
|
-
@return {String} string representation
|
|
1411
|
-
@public
|
|
1412
|
-
*/
|
|
1413
|
-
toString() {
|
|
1414
|
-
let extension = hasToStringExtension(this) ? `:${this.toStringExtension()}` : '';
|
|
1415
|
-
return `<${getFactoryFor(this) || '(unknown)'}:${guidFor(this)}${extension}>`;
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
/**
|
|
1419
|
-
Creates a new subclass.
|
|
1420
|
-
```javascript
|
|
1421
|
-
import EmberObject from '@ember/object';
|
|
1422
|
-
const Person = EmberObject.extend({
|
|
1423
|
-
say(thing) {
|
|
1424
|
-
alert(thing);
|
|
1425
|
-
}
|
|
1426
|
-
});
|
|
1427
|
-
```
|
|
1428
|
-
This defines a new subclass of EmberObject: `Person`. It contains one method: `say()`.
|
|
1429
|
-
You can also create a subclass from any existing class by calling its `extend()` method.
|
|
1430
|
-
For example, you might want to create a subclass of Ember's built-in `Component` class:
|
|
1431
|
-
```javascript
|
|
1432
|
-
import Component from '@ember/component';
|
|
1433
|
-
const PersonComponent = Component.extend({
|
|
1434
|
-
tagName: 'li',
|
|
1435
|
-
classNameBindings: ['isAdministrator']
|
|
1436
|
-
});
|
|
1437
|
-
```
|
|
1438
|
-
When defining a subclass, you can override methods but still access the
|
|
1439
|
-
implementation of your parent class by calling the special `_super()` method:
|
|
1440
|
-
```javascript
|
|
1441
|
-
import EmberObject from '@ember/object';
|
|
1442
|
-
const Person = EmberObject.extend({
|
|
1443
|
-
say(thing) {
|
|
1444
|
-
let name = this.get('name');
|
|
1445
|
-
alert(`${name} says: ${thing}`);
|
|
1446
|
-
}
|
|
1447
|
-
});
|
|
1448
|
-
const Soldier = Person.extend({
|
|
1449
|
-
say(thing) {
|
|
1450
|
-
this._super(`${thing}, sir!`);
|
|
1451
|
-
},
|
|
1452
|
-
march(numberOfHours) {
|
|
1453
|
-
alert(`${this.get('name')} marches for ${numberOfHours} hours.`);
|
|
1454
|
-
}
|
|
1455
|
-
});
|
|
1456
|
-
let yehuda = Soldier.create({
|
|
1457
|
-
name: 'Yehuda Katz'
|
|
1458
|
-
});
|
|
1459
|
-
yehuda.say('Yes'); // alerts "Yehuda Katz says: Yes, sir!"
|
|
1460
|
-
```
|
|
1461
|
-
The `create()` on line #17 creates an *instance* of the `Soldier` class.
|
|
1462
|
-
The `extend()` on line #8 creates a *subclass* of `Person`. Any instance
|
|
1463
|
-
of the `Person` class will *not* have the `march()` method.
|
|
1464
|
-
You can also pass `Mixin` classes to add additional properties to the subclass.
|
|
1465
|
-
```javascript
|
|
1466
|
-
import EmberObject from '@ember/object';
|
|
1467
|
-
import Mixin from '@ember/object/mixin';
|
|
1468
|
-
const Person = EmberObject.extend({
|
|
1469
|
-
say(thing) {
|
|
1470
|
-
alert(`${this.get('name')} says: ${thing}`);
|
|
1471
|
-
}
|
|
1472
|
-
});
|
|
1473
|
-
const SingingMixin = Mixin.create({
|
|
1474
|
-
sing(thing) {
|
|
1475
|
-
alert(`${this.get('name')} sings: la la la ${thing}`);
|
|
1476
|
-
}
|
|
1477
|
-
});
|
|
1478
|
-
const BroadwayStar = Person.extend(SingingMixin, {
|
|
1479
|
-
dance() {
|
|
1480
|
-
alert(`${this.get('name')} dances: tap tap tap tap `);
|
|
1481
|
-
}
|
|
1482
|
-
});
|
|
1483
|
-
```
|
|
1484
|
-
The `BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.
|
|
1485
|
-
@method extend
|
|
1486
|
-
@static
|
|
1487
|
-
@for @ember/object
|
|
1488
|
-
@param {Mixin} [mixins]* One or more Mixin classes
|
|
1489
|
-
@param {Object} [arguments]* Object containing values to use within the new class
|
|
1490
|
-
@public
|
|
1491
|
-
*/
|
|
1492
|
-
|
|
1493
|
-
static extend(...mixins) {
|
|
1494
|
-
let Class = class extends this {};
|
|
1495
|
-
reopen.apply(Class.PrototypeMixin, mixins);
|
|
1496
|
-
return Class;
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
/**
|
|
1500
|
-
Creates an instance of a class. Accepts either no arguments, or an object
|
|
1501
|
-
containing values to initialize the newly instantiated object with.
|
|
1502
|
-
```javascript
|
|
1503
|
-
import EmberObject from '@ember/object';
|
|
1504
|
-
const Person = EmberObject.extend({
|
|
1505
|
-
helloWorld() {
|
|
1506
|
-
alert(`Hi, my name is ${this.get('name')}`);
|
|
1507
|
-
}
|
|
1508
|
-
});
|
|
1509
|
-
let tom = Person.create({
|
|
1510
|
-
name: 'Tom Dale'
|
|
1511
|
-
});
|
|
1512
|
-
tom.helloWorld(); // alerts "Hi, my name is Tom Dale".
|
|
1513
|
-
```
|
|
1514
|
-
`create` will call the `init` function if defined during
|
|
1515
|
-
`AnyObject.extend`
|
|
1516
|
-
If no arguments are passed to `create`, it will not set values to the new
|
|
1517
|
-
instance during initialization:
|
|
1518
|
-
```javascript
|
|
1519
|
-
let noName = Person.create();
|
|
1520
|
-
noName.helloWorld(); // alerts undefined
|
|
1521
|
-
```
|
|
1522
|
-
NOTE: For performance reasons, you cannot declare methods or computed
|
|
1523
|
-
properties during `create`. You should instead declare methods and computed
|
|
1524
|
-
properties when using `extend`.
|
|
1525
|
-
@method create
|
|
1526
|
-
@for @ember/object
|
|
1527
|
-
@static
|
|
1528
|
-
@param [arguments]*
|
|
1529
|
-
@public
|
|
1530
|
-
*/
|
|
1531
|
-
|
|
1532
|
-
static create(...args) {
|
|
1533
|
-
let props = args[0];
|
|
1534
|
-
let instance;
|
|
1535
|
-
if (props !== undefined) {
|
|
1536
|
-
instance = new this(getOwner(props));
|
|
1537
|
-
// TODO(SAFETY): at present, we cannot actually rely on this being set,
|
|
1538
|
-
// because a number of acceptance tests are (incorrectly? Unclear!)
|
|
1539
|
-
// relying on the ability to run through this path with `factory` being
|
|
1540
|
-
// `undefined`. It's *possible* that actually means that the type for
|
|
1541
|
-
// `setFactoryFor()` should allow `undefined`, but we typed it the other
|
|
1542
|
-
// way for good reason! Accordingly, this *casts* `factory`, and the
|
|
1543
|
-
// commented-out `assert()` is here in the hope that we can enable it
|
|
1544
|
-
// after addressing tests *or* updating the call signature here.
|
|
1545
|
-
let factory = getFactoryFor(props);
|
|
1546
|
-
// assert(`missing factory when creating object ${instance}`, factory !== undefined);
|
|
1547
|
-
setFactoryFor(instance, factory);
|
|
1548
|
-
} else {
|
|
1549
|
-
instance = new this();
|
|
1550
|
-
}
|
|
1551
|
-
if (args.length <= 1) {
|
|
1552
|
-
initialize(instance, props);
|
|
1553
|
-
} else {
|
|
1554
|
-
initialize(instance, flattenProps.apply(this, args));
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
// SAFETY: The `initialize` call is responsible to merge the prototype chain
|
|
1558
|
-
// so that this holds.
|
|
1559
|
-
return instance;
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
/**
|
|
1563
|
-
Augments a constructor's prototype with additional
|
|
1564
|
-
properties and functions:
|
|
1565
|
-
```javascript
|
|
1566
|
-
import EmberObject from '@ember/object';
|
|
1567
|
-
const MyObject = EmberObject.extend({
|
|
1568
|
-
name: 'an object'
|
|
1569
|
-
});
|
|
1570
|
-
o = MyObject.create();
|
|
1571
|
-
o.get('name'); // 'an object'
|
|
1572
|
-
MyObject.reopen({
|
|
1573
|
-
say(msg) {
|
|
1574
|
-
console.log(msg);
|
|
1575
|
-
}
|
|
1576
|
-
});
|
|
1577
|
-
o2 = MyObject.create();
|
|
1578
|
-
o2.say('hello'); // logs "hello"
|
|
1579
|
-
o.say('goodbye'); // logs "goodbye"
|
|
1580
|
-
```
|
|
1581
|
-
To add functions and properties to the constructor itself,
|
|
1582
|
-
see `reopenClass`
|
|
1583
|
-
@method reopen
|
|
1584
|
-
@for @ember/object
|
|
1585
|
-
@static
|
|
1586
|
-
@public
|
|
1587
|
-
*/
|
|
1588
|
-
static reopen(...args) {
|
|
1589
|
-
this.willReopen();
|
|
1590
|
-
reopen.apply(this.PrototypeMixin, args);
|
|
1591
|
-
return this;
|
|
1592
|
-
}
|
|
1593
|
-
static willReopen() {
|
|
1594
|
-
let p = this.prototype;
|
|
1595
|
-
if (wasApplied.has(p)) {
|
|
1596
|
-
wasApplied.delete(p);
|
|
1597
|
-
|
|
1598
|
-
// If the base mixin already exists and was applied, create a new mixin to
|
|
1599
|
-
// make sure that it gets properly applied. Reusing the same mixin after
|
|
1600
|
-
// the first `proto` call will cause it to get skipped.
|
|
1601
|
-
if (prototypeMixinMap.has(this)) {
|
|
1602
|
-
prototypeMixinMap.set(this, Mixin.create(this.PrototypeMixin));
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
/**
|
|
1608
|
-
Augments a constructor's own properties and functions:
|
|
1609
|
-
```javascript
|
|
1610
|
-
import EmberObject from '@ember/object';
|
|
1611
|
-
const MyObject = EmberObject.extend({
|
|
1612
|
-
name: 'an object'
|
|
1613
|
-
});
|
|
1614
|
-
MyObject.reopenClass({
|
|
1615
|
-
canBuild: false
|
|
1616
|
-
});
|
|
1617
|
-
MyObject.canBuild; // false
|
|
1618
|
-
o = MyObject.create();
|
|
1619
|
-
```
|
|
1620
|
-
In other words, this creates static properties and functions for the class.
|
|
1621
|
-
These are only available on the class and not on any instance of that class.
|
|
1622
|
-
```javascript
|
|
1623
|
-
import EmberObject from '@ember/object';
|
|
1624
|
-
const Person = EmberObject.extend({
|
|
1625
|
-
name: '',
|
|
1626
|
-
sayHello() {
|
|
1627
|
-
alert(`Hello. My name is ${this.get('name')}`);
|
|
1628
|
-
}
|
|
1629
|
-
});
|
|
1630
|
-
Person.reopenClass({
|
|
1631
|
-
species: 'Homo sapiens',
|
|
1632
|
-
createPerson(name) {
|
|
1633
|
-
return Person.create({ name });
|
|
1634
|
-
}
|
|
1635
|
-
});
|
|
1636
|
-
let tom = Person.create({
|
|
1637
|
-
name: 'Tom Dale'
|
|
1638
|
-
});
|
|
1639
|
-
let yehuda = Person.createPerson('Yehuda Katz');
|
|
1640
|
-
tom.sayHello(); // "Hello. My name is Tom Dale"
|
|
1641
|
-
yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
|
|
1642
|
-
alert(Person.species); // "Homo sapiens"
|
|
1643
|
-
```
|
|
1644
|
-
Note that `species` and `createPerson` are *not* valid on the `tom` and `yehuda`
|
|
1645
|
-
variables. They are only valid on `Person`.
|
|
1646
|
-
To add functions and properties to instances of
|
|
1647
|
-
a constructor by extending the constructor's prototype
|
|
1648
|
-
see `reopen`
|
|
1649
|
-
@method reopenClass
|
|
1650
|
-
@for @ember/object
|
|
1651
|
-
@static
|
|
1652
|
-
@public
|
|
1653
|
-
*/
|
|
1654
|
-
static reopenClass(...mixins) {
|
|
1655
|
-
applyMixin(this, mixins);
|
|
1656
|
-
return this;
|
|
1657
|
-
}
|
|
1658
|
-
static detect(obj) {
|
|
1659
|
-
if ('function' !== typeof obj) {
|
|
1660
|
-
return false;
|
|
1661
|
-
}
|
|
1662
|
-
while (obj) {
|
|
1663
|
-
if (obj === this) {
|
|
1664
|
-
return true;
|
|
1665
|
-
}
|
|
1666
|
-
obj = obj.superclass;
|
|
1667
|
-
}
|
|
1668
|
-
return false;
|
|
1669
|
-
}
|
|
1670
|
-
static detectInstance(obj) {
|
|
1671
|
-
return obj instanceof this;
|
|
1672
|
-
}
|
|
1673
|
-
|
|
1674
|
-
/**
|
|
1675
|
-
In some cases, you may want to annotate computed properties with additional
|
|
1676
|
-
metadata about how they function or what values they operate on. For
|
|
1677
|
-
example, computed property functions may close over variables that are then
|
|
1678
|
-
no longer available for introspection.
|
|
1679
|
-
You can pass a hash of these values to a computed property like this:
|
|
1680
|
-
```javascript
|
|
1681
|
-
import { computed } from '@ember/object';
|
|
1682
|
-
person: computed(function() {
|
|
1683
|
-
let personId = this.get('personId');
|
|
1684
|
-
return Person.create({ id: personId });
|
|
1685
|
-
}).meta({ type: Person })
|
|
1686
|
-
```
|
|
1687
|
-
Once you've done this, you can retrieve the values saved to the computed
|
|
1688
|
-
property from your class like this:
|
|
1689
|
-
```javascript
|
|
1690
|
-
MyClass.metaForProperty('person');
|
|
1691
|
-
```
|
|
1692
|
-
This will return the original hash that was passed to `meta()`.
|
|
1693
|
-
@static
|
|
1694
|
-
@method metaForProperty
|
|
1695
|
-
@param key {String} property name
|
|
1696
|
-
@private
|
|
1697
|
-
*/
|
|
1698
|
-
static metaForProperty(key) {
|
|
1699
|
-
let proto = this.proto(); // ensure prototype is initialized
|
|
1700
|
-
let possibleDesc = descriptorForProperty(proto, key);
|
|
1701
|
-
(isDevelopingApp() && !(possibleDesc !== undefined) && assert(`metaForProperty() could not find a computed property with key '${key}'.`, possibleDesc !== undefined));
|
|
1702
|
-
return possibleDesc._meta || {};
|
|
1703
|
-
}
|
|
1704
|
-
|
|
1705
|
-
/**
|
|
1706
|
-
Iterate over each computed property for the class, passing its name
|
|
1707
|
-
and any associated metadata (see `metaForProperty`) to the callback.
|
|
1708
|
-
@static
|
|
1709
|
-
@method eachComputedProperty
|
|
1710
|
-
@param {Function} callback
|
|
1711
|
-
@param {Object} binding
|
|
1712
|
-
@private
|
|
1713
|
-
*/
|
|
1714
|
-
static eachComputedProperty(callback, binding = this) {
|
|
1715
|
-
this.proto(); // ensure prototype is initialized
|
|
1716
|
-
let empty = {};
|
|
1717
|
-
meta(this.prototype).forEachDescriptors((name, descriptor) => {
|
|
1718
|
-
if (descriptor.enumerable) {
|
|
1719
|
-
let meta = descriptor._meta || empty;
|
|
1720
|
-
callback.call(binding, name, meta);
|
|
1721
|
-
}
|
|
1722
|
-
});
|
|
1723
|
-
}
|
|
1724
|
-
static get PrototypeMixin() {
|
|
1725
|
-
let prototypeMixin = prototypeMixinMap.get(this);
|
|
1726
|
-
if (prototypeMixin === undefined) {
|
|
1727
|
-
prototypeMixin = Mixin.create();
|
|
1728
|
-
prototypeMixin.ownerConstructor = this;
|
|
1729
|
-
prototypeMixinMap.set(this, prototypeMixin);
|
|
1730
|
-
}
|
|
1731
|
-
return prototypeMixin;
|
|
1732
|
-
}
|
|
1733
|
-
static get superclass() {
|
|
1734
|
-
let c = Object.getPrototypeOf(this);
|
|
1735
|
-
return c !== Function.prototype ? c : undefined;
|
|
1736
|
-
}
|
|
1737
|
-
static proto() {
|
|
1738
|
-
let p = this.prototype;
|
|
1739
|
-
if (!wasApplied.has(p)) {
|
|
1740
|
-
wasApplied.add(p);
|
|
1741
|
-
let parent = this.superclass;
|
|
1742
|
-
if (parent) {
|
|
1743
|
-
parent.proto();
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
// If the prototype mixin exists, apply it. In the case of native classes,
|
|
1747
|
-
// it will not exist (unless the class has been reopened).
|
|
1748
|
-
if (prototypeMixinMap.has(this)) {
|
|
1749
|
-
this.PrototypeMixin.apply(p);
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
return p;
|
|
1753
|
-
}
|
|
1754
|
-
static toString() {
|
|
1755
|
-
return `<${getFactoryFor(this) || '(unknown)'}:constructor>`;
|
|
1756
|
-
}
|
|
1757
|
-
static isClass = true;
|
|
1758
|
-
static isMethod = false;
|
|
1759
|
-
static _onLookup;
|
|
1760
|
-
static _lazyInjections;
|
|
1761
|
-
}
|
|
1762
|
-
function flattenProps(...props) {
|
|
1763
|
-
let initProperties = {};
|
|
1764
|
-
for (let properties of props) {
|
|
1765
|
-
(isDevelopingApp() && !(!(properties instanceof Mixin)) && assert('EmberObject.create no longer supports mixing in other ' + 'definitions, use .extend & .create separately instead.', !(properties instanceof Mixin)));
|
|
1766
|
-
let keyNames = Object.keys(properties);
|
|
1767
|
-
for (let j = 0, k = keyNames.length; j < k; j++) {
|
|
1768
|
-
let keyName = keyNames[j];
|
|
1769
|
-
let value = properties[keyName];
|
|
1770
|
-
initProperties[keyName] = value;
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
return initProperties;
|
|
1774
|
-
}
|
|
1775
|
-
if (isDevelopingApp()) {
|
|
1776
|
-
/**
|
|
1777
|
-
Provides lookup-time type validation for injected properties.
|
|
1778
|
-
@private
|
|
1779
|
-
@method _onLookup
|
|
1780
|
-
*/
|
|
1781
|
-
CoreObject._onLookup = function injectedPropertyAssertion(debugContainerKey) {
|
|
1782
|
-
let [type] = debugContainerKey.split(':');
|
|
1783
|
-
let proto = this.proto();
|
|
1784
|
-
for (let key in proto) {
|
|
1785
|
-
let desc = descriptorForProperty(proto, key);
|
|
1786
|
-
if (desc && DEBUG_INJECTION_FUNCTIONS.has(desc._getter)) {
|
|
1787
|
-
(isDevelopingApp() && !(type === 'controller' || DEBUG_INJECTION_FUNCTIONS.get(desc._getter).type !== 'controller') && assert(`Defining \`${key}\` as an injected controller property on a non-controller (\`${debugContainerKey}\`) is not allowed.`, type === 'controller' || DEBUG_INJECTION_FUNCTIONS.get(desc._getter).type !== 'controller'));
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
};
|
|
1791
|
-
|
|
1792
|
-
/**
|
|
1793
|
-
Returns a hash of property names and container names that injected
|
|
1794
|
-
properties will lookup on the container lazily.
|
|
1795
|
-
@method _lazyInjections
|
|
1796
|
-
@return {Object} Hash of all lazy injected property keys to container names
|
|
1797
|
-
@private
|
|
1798
|
-
*/
|
|
1799
|
-
CoreObject._lazyInjections = function () {
|
|
1800
|
-
let injections = {};
|
|
1801
|
-
let proto = this.proto();
|
|
1802
|
-
let key;
|
|
1803
|
-
let desc;
|
|
1804
|
-
for (key in proto) {
|
|
1805
|
-
desc = descriptorForProperty(proto, key);
|
|
1806
|
-
if (desc && DEBUG_INJECTION_FUNCTIONS.has(desc._getter)) {
|
|
1807
|
-
let {
|
|
1808
|
-
namespace,
|
|
1809
|
-
source,
|
|
1810
|
-
type,
|
|
1811
|
-
name
|
|
1812
|
-
} = DEBUG_INJECTION_FUNCTIONS.get(desc._getter);
|
|
1813
|
-
injections[key] = {
|
|
1814
|
-
namespace,
|
|
1815
|
-
source,
|
|
1816
|
-
specifier: `${type}:${name || key}`
|
|
1817
|
-
};
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
return injections;
|
|
1821
|
-
};
|
|
1822
|
-
}
|
|
1823
|
-
const EmberCoreObject = CoreObject;
|
|
1824
|
-
|
|
1825
|
-
/**
|
|
1826
|
-
@module @ember/object
|
|
1827
|
-
*/
|
|
1828
|
-
|
|
1829
|
-
/**
|
|
1830
|
-
`EmberObject` is the main base class for all Ember objects. It is a subclass
|
|
1831
|
-
of `CoreObject` with the `Observable` mixin applied. For details,
|
|
1832
|
-
see the documentation for each of these.
|
|
1833
|
-
|
|
1834
|
-
@class EmberObject
|
|
1835
|
-
@extends CoreObject
|
|
1836
|
-
@uses Observable
|
|
1837
|
-
@public
|
|
1838
|
-
*/
|
|
1839
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
1840
|
-
|
|
1841
|
-
class EmberObject extends EmberCoreObject.extend(Observable) {
|
|
1842
|
-
get _debugContainerKey() {
|
|
1843
|
-
let factory = getFactoryFor(this);
|
|
1844
|
-
return factory !== undefined && factory.fullName;
|
|
1845
|
-
}
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
/**
|
|
1849
|
-
Decorator that turns the target function into an Action which can be accessed
|
|
1850
|
-
directly by reference.
|
|
1851
|
-
|
|
1852
|
-
```js
|
|
1853
|
-
import Component from '@ember/component';
|
|
1854
|
-
import { action, set } from '@ember/object';
|
|
1855
|
-
|
|
1856
|
-
export default class Tooltip extends Component {
|
|
1857
|
-
@action
|
|
1858
|
-
toggleShowing() {
|
|
1859
|
-
set(this, 'isShowing', !this.isShowing);
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
```
|
|
1863
|
-
```hbs
|
|
1864
|
-
<!-- template.hbs -->
|
|
1865
|
-
<button {{action this.toggleShowing}}>Show tooltip</button>
|
|
1866
|
-
|
|
1867
|
-
{{#if isShowing}}
|
|
1868
|
-
<div class="tooltip">
|
|
1869
|
-
I'm a tooltip!
|
|
1870
|
-
</div>
|
|
1871
|
-
{{/if}}
|
|
1872
|
-
```
|
|
1873
|
-
|
|
1874
|
-
Decorated actions also interop with the string style template actions:
|
|
1875
|
-
|
|
1876
|
-
```hbs
|
|
1877
|
-
<!-- template.hbs -->
|
|
1878
|
-
<button {{action "toggleShowing"}}>Show tooltip</button>
|
|
1879
|
-
|
|
1880
|
-
{{#if isShowing}}
|
|
1881
|
-
<div class="tooltip">
|
|
1882
|
-
I'm a tooltip!
|
|
1883
|
-
</div>
|
|
1884
|
-
{{/if}}
|
|
1885
|
-
```
|
|
1886
|
-
|
|
1887
|
-
It also binds the function directly to the instance, so it can be used in any
|
|
1888
|
-
context and will correctly refer to the class it came from:
|
|
1889
|
-
|
|
1890
|
-
```hbs
|
|
1891
|
-
<!-- template.hbs -->
|
|
1892
|
-
<button
|
|
1893
|
-
{{did-insert this.toggleShowing}}
|
|
1894
|
-
{{on "click" this.toggleShowing}}
|
|
1895
|
-
>
|
|
1896
|
-
Show tooltip
|
|
1897
|
-
</button>
|
|
1898
|
-
|
|
1899
|
-
{{#if isShowing}}
|
|
1900
|
-
<div class="tooltip">
|
|
1901
|
-
I'm a tooltip!
|
|
1902
|
-
</div>
|
|
1903
|
-
{{/if}}
|
|
1904
|
-
```
|
|
1905
|
-
|
|
1906
|
-
This can also be used in JavaScript code directly:
|
|
1907
|
-
|
|
1908
|
-
```js
|
|
1909
|
-
import Component from '@ember/component';
|
|
1910
|
-
import { action, set } from '@ember/object';
|
|
1911
|
-
|
|
1912
|
-
export default class Tooltip extends Component {
|
|
1913
|
-
constructor() {
|
|
1914
|
-
super(...arguments);
|
|
1915
|
-
|
|
1916
|
-
// this.toggleShowing is still bound correctly when added to
|
|
1917
|
-
// the event listener
|
|
1918
|
-
document.addEventListener('click', this.toggleShowing);
|
|
1919
|
-
}
|
|
1920
|
-
|
|
1921
|
-
@action
|
|
1922
|
-
toggleShowing() {
|
|
1923
|
-
set(this, 'isShowing', !this.isShowing);
|
|
1924
|
-
}
|
|
1925
|
-
}
|
|
1926
|
-
```
|
|
1927
|
-
|
|
1928
|
-
This is considered best practice, since it means that methods will be bound
|
|
1929
|
-
correctly no matter where they are used. By contrast, the `{{action}}` helper
|
|
1930
|
-
and modifier can also be used to bind context, but it will be required for
|
|
1931
|
-
every usage of the method:
|
|
1932
|
-
|
|
1933
|
-
```hbs
|
|
1934
|
-
<!-- template.hbs -->
|
|
1935
|
-
<button
|
|
1936
|
-
{{did-insert (action this.toggleShowing)}}
|
|
1937
|
-
{{on "click" (action this.toggleShowing)}}
|
|
1938
|
-
>
|
|
1939
|
-
Show tooltip
|
|
1940
|
-
</button>
|
|
1941
|
-
|
|
1942
|
-
{{#if isShowing}}
|
|
1943
|
-
<div class="tooltip">
|
|
1944
|
-
I'm a tooltip!
|
|
1945
|
-
</div>
|
|
1946
|
-
{{/if}}
|
|
1947
|
-
```
|
|
1948
|
-
|
|
1949
|
-
They also do not have equivalents in JavaScript directly, so they cannot be
|
|
1950
|
-
used for other situations where binding would be useful.
|
|
1951
|
-
|
|
1952
|
-
@public
|
|
1953
|
-
@method action
|
|
1954
|
-
@for @ember/object
|
|
1955
|
-
@static
|
|
1956
|
-
@param {Function|undefined} callback The function to turn into an action,
|
|
1957
|
-
when used in classic classes
|
|
1958
|
-
@return {PropertyDecorator} property decorator instance
|
|
1959
|
-
*/
|
|
1960
|
-
|
|
1961
|
-
const BINDINGS_MAP = new WeakMap();
|
|
1962
|
-
function hasProto(obj) {
|
|
1963
|
-
return obj != null && obj.constructor !== undefined && typeof obj.constructor.proto === 'function';
|
|
1964
|
-
}
|
|
1965
|
-
function setupAction(target, key, actionFn) {
|
|
1966
|
-
if (hasProto(target)) {
|
|
1967
|
-
target.constructor.proto();
|
|
1968
|
-
}
|
|
1969
|
-
if (!Object.prototype.hasOwnProperty.call(target, 'actions')) {
|
|
1970
|
-
let parentActions = target.actions;
|
|
1971
|
-
// we need to assign because of the way mixins copy actions down when inheriting
|
|
1972
|
-
target.actions = parentActions ? Object.assign({}, parentActions) : {};
|
|
1973
|
-
}
|
|
1974
|
-
(isDevelopingApp() && !(target.actions != null) && assert("[BUG] Somehow the target doesn't have actions!", target.actions != null));
|
|
1975
|
-
target.actions[key] = actionFn;
|
|
1976
|
-
return {
|
|
1977
|
-
get() {
|
|
1978
|
-
let bindings = BINDINGS_MAP.get(this);
|
|
1979
|
-
if (bindings === undefined) {
|
|
1980
|
-
bindings = new Map();
|
|
1981
|
-
BINDINGS_MAP.set(this, bindings);
|
|
1982
|
-
}
|
|
1983
|
-
let fn = bindings.get(actionFn);
|
|
1984
|
-
if (fn === undefined) {
|
|
1985
|
-
fn = actionFn.bind(this);
|
|
1986
|
-
bindings.set(actionFn, fn);
|
|
1987
|
-
}
|
|
1988
|
-
return fn;
|
|
1989
|
-
}
|
|
1990
|
-
};
|
|
1991
|
-
}
|
|
1992
|
-
function action(...args) {
|
|
1993
|
-
let actionFn;
|
|
1994
|
-
if (!isElementDescriptor(args)) {
|
|
1995
|
-
actionFn = args[0];
|
|
1996
|
-
let decorator = function (target, key, _desc, _meta, isClassicDecorator) {
|
|
1997
|
-
(isDevelopingApp() && !(isClassicDecorator) && assert('The @action decorator may only be passed a method when used in classic classes. You should decorate methods directly in native classes', isClassicDecorator));
|
|
1998
|
-
(isDevelopingApp() && !(typeof actionFn === 'function') && assert('The action() decorator must be passed a method when used in classic classes', typeof actionFn === 'function'));
|
|
1999
|
-
return setupAction(target, key, actionFn);
|
|
2000
|
-
};
|
|
2001
|
-
setClassicDecorator(decorator);
|
|
2002
|
-
return decorator;
|
|
2003
|
-
}
|
|
2004
|
-
let [target, key, desc] = args;
|
|
2005
|
-
actionFn = desc?.value;
|
|
2006
|
-
(isDevelopingApp() && !(typeof actionFn === 'function') && assert('The @action decorator must be applied to methods when used in native classes', typeof actionFn === 'function')); // SAFETY: TS types are weird with decorators. This should work.
|
|
2007
|
-
return setupAction(target, key, actionFn);
|
|
2008
|
-
}
|
|
2009
|
-
|
|
2010
|
-
// SAFETY: TS types are weird with decorators. This should work.
|
|
2011
|
-
setClassicDecorator(action);
|
|
2012
|
-
|
|
2013
|
-
// ..........................................................
|
|
2014
|
-
// OBSERVER HELPER
|
|
2015
|
-
//
|
|
2016
|
-
|
|
2017
|
-
/**
|
|
2018
|
-
Specify a method that observes property changes.
|
|
2019
|
-
|
|
2020
|
-
```javascript
|
|
2021
|
-
import EmberObject from '@ember/object';
|
|
2022
|
-
import { observer } from '@ember/object';
|
|
2023
|
-
|
|
2024
|
-
export default EmberObject.extend({
|
|
2025
|
-
valueObserver: observer('value', function() {
|
|
2026
|
-
// Executes whenever the "value" property changes
|
|
2027
|
-
})
|
|
2028
|
-
});
|
|
2029
|
-
```
|
|
2030
|
-
|
|
2031
|
-
Also available as `Function.prototype.observes` if prototype extensions are
|
|
2032
|
-
enabled.
|
|
2033
|
-
|
|
2034
|
-
@method observer
|
|
2035
|
-
@for @ember/object
|
|
2036
|
-
@param {String} propertyNames*
|
|
2037
|
-
@param {Function} func
|
|
2038
|
-
@return func
|
|
2039
|
-
@public
|
|
2040
|
-
@static
|
|
2041
|
-
*/
|
|
2042
|
-
function observer(...args) {
|
|
2043
|
-
let funcOrDef = args.pop();
|
|
2044
|
-
(isDevelopingApp() && !(typeof funcOrDef === 'function' || typeof funcOrDef === 'object' && funcOrDef !== null) && assert('observer must be provided a function or an observer definition', typeof funcOrDef === 'function' || typeof funcOrDef === 'object' && funcOrDef !== null));
|
|
2045
|
-
let func;
|
|
2046
|
-
let dependentKeys;
|
|
2047
|
-
let sync;
|
|
2048
|
-
if (typeof funcOrDef === 'function') {
|
|
2049
|
-
func = funcOrDef;
|
|
2050
|
-
dependentKeys = args;
|
|
2051
|
-
sync = !ENV._DEFAULT_ASYNC_OBSERVERS;
|
|
2052
|
-
} else {
|
|
2053
|
-
func = funcOrDef.fn;
|
|
2054
|
-
dependentKeys = funcOrDef.dependentKeys;
|
|
2055
|
-
sync = funcOrDef.sync;
|
|
2056
|
-
}
|
|
2057
|
-
(isDevelopingApp() && !(typeof func === 'function') && assert('observer called without a function', typeof func === 'function'));
|
|
2058
|
-
(isDevelopingApp() && !(Array.isArray(dependentKeys) && dependentKeys.length > 0 && dependentKeys.every(p => typeof p === 'string' && Boolean(p.length))) && assert('observer called without valid path', Array.isArray(dependentKeys) && dependentKeys.length > 0 && dependentKeys.every(p => typeof p === 'string' && Boolean(p.length))));
|
|
2059
|
-
(isDevelopingApp() && !(typeof sync === 'boolean') && assert('observer called without sync', typeof sync === 'boolean'));
|
|
2060
|
-
let paths = [];
|
|
2061
|
-
for (let dependentKey of dependentKeys) {
|
|
2062
|
-
expandProperties(dependentKey, path => paths.push(path));
|
|
2063
|
-
}
|
|
2064
|
-
setObservers(func, {
|
|
2065
|
-
paths,
|
|
2066
|
-
sync
|
|
2067
|
-
});
|
|
2068
|
-
return func;
|
|
2069
|
-
}
|
|
2070
|
-
|
|
2071
|
-
export { A, EmberObject as E, MutableArray as M, NativeArray as N, Observable as O, EmberArray as a, action as b, compare as c, EmberCoreObject as d, isArray as i, observer as o, removeAt as r, typeOf as t, uniqBy as u };
|