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.
Files changed (147) hide show
  1. package/build-metadata.json +3 -3
  2. package/dist/ember-template-compiler.js +48 -42
  3. package/dist/ember-testing.js +1 -1
  4. package/dist/ember.debug.js +23102 -23100
  5. package/dist/ember.prod.js +31562 -31563
  6. package/dist/packages/@ember/-internals/container/index.js +1 -1
  7. package/dist/packages/@ember/-internals/deprecations/index.js +2 -1
  8. package/dist/packages/@ember/-internals/glimmer/index.js +2 -1
  9. package/dist/packages/@ember/-internals/meta/lib/meta.js +4 -3
  10. package/dist/packages/@ember/-internals/metal/index.js +9 -8
  11. package/dist/packages/@ember/-internals/routing/index.js +6 -5
  12. package/dist/packages/@ember/-internals/runtime/lib/ext/rsvp.js +3 -2
  13. package/dist/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +6 -5
  14. package/dist/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +4 -3
  15. package/dist/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +1 -1
  16. package/dist/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +2 -1
  17. package/dist/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +4 -3
  18. package/dist/packages/@ember/-internals/string/index.js +1 -1
  19. package/dist/packages/@ember/-internals/utils/index.js +4 -4
  20. package/dist/packages/@ember/-internals/views/index.js +1 -1
  21. package/dist/packages/@ember/-internals/views/lib/compat/fallback-view-registry.js +1 -1
  22. package/dist/packages/@ember/-internals/views/lib/component_lookup.js +1 -1
  23. package/dist/packages/@ember/-internals/views/lib/mixins/action_support.js +5 -3
  24. package/dist/packages/@ember/-internals/views/lib/mixins/child_views_support.js +3 -3
  25. package/dist/packages/@ember/-internals/views/lib/mixins/class_names_support.js +4 -3
  26. package/dist/packages/@ember/-internals/views/lib/mixins/view_support.js +4 -3
  27. package/dist/packages/@ember/-internals/views/lib/system/event_dispatcher.js +6 -12
  28. package/dist/packages/@ember/-internals/views/lib/system/utils.js +3 -2
  29. package/dist/packages/@ember/-internals/views/lib/views/core_view.js +76 -8
  30. package/dist/packages/@ember/-internals/views/lib/views/states.js +4 -3
  31. package/dist/packages/@ember/application/index.js +16 -7
  32. package/dist/packages/@ember/application/instance.js +13 -9
  33. package/dist/packages/@ember/application/namespace.js +7 -6
  34. package/dist/packages/@ember/array/index.js +617 -11
  35. package/dist/packages/@ember/array/make.js +1 -0
  36. package/dist/packages/@ember/array/mutable.js +1 -1
  37. package/dist/packages/@ember/array/proxy.js +8 -5
  38. package/dist/packages/@ember/component/helper.js +4 -4
  39. package/dist/packages/@ember/component/index.js +4 -4
  40. package/dist/packages/@ember/controller/index.js +6 -6
  41. package/dist/packages/@ember/debug/container-debug-adapter.js +5 -4
  42. package/dist/packages/@ember/debug/data-adapter.js +7 -4
  43. package/dist/packages/@ember/debug/index.js +213 -4
  44. package/dist/packages/@ember/debug/lib/assert.js +47 -0
  45. package/dist/packages/@ember/debug/lib/deprecate.js +194 -4
  46. package/dist/packages/@ember/debug/lib/inspect.js +120 -2
  47. package/dist/packages/@ember/debug/lib/warn.js +94 -3
  48. package/dist/packages/@ember/engine/index.js +440 -17
  49. package/dist/packages/@ember/engine/instance.js +175 -11
  50. package/dist/packages/@ember/engine/parent.js +1 -0
  51. package/dist/packages/@ember/helper/index.js +4 -4
  52. package/dist/packages/@ember/instrumentation/index.js +2 -1
  53. package/dist/packages/@ember/modifier/index.js +13 -5
  54. package/dist/packages/@ember/modifier/on.js +15 -0
  55. package/dist/packages/@ember/object/-internals.js +6 -5
  56. package/dist/packages/@ember/object/compat.js +4 -3
  57. package/dist/packages/@ember/object/computed.js +4 -4
  58. package/dist/packages/@ember/object/core.js +861 -14
  59. package/dist/packages/@ember/object/evented.js +4 -4
  60. package/dist/packages/@ember/object/events.js +3 -3
  61. package/dist/packages/@ember/object/index.js +260 -9
  62. package/dist/packages/@ember/object/internals.js +1 -1
  63. package/dist/packages/@ember/object/lib/computed/computed_macros.js +8 -6
  64. package/dist/packages/@ember/object/lib/computed/reduce_computed_macros.js +8 -4
  65. package/dist/packages/@ember/object/mixin.js +6 -5
  66. package/dist/packages/@ember/object/observable.js +103 -9
  67. package/dist/packages/@ember/object/observers.js +3 -3
  68. package/dist/packages/@ember/object/promise-proxy-mixin.js +5 -5
  69. package/dist/packages/@ember/renderer/index.js +4 -4
  70. package/dist/packages/@ember/routing/-internals.js +3 -1
  71. package/dist/packages/@ember/routing/hash-location.js +2 -2
  72. package/dist/packages/@ember/routing/history-location.js +3 -2
  73. package/dist/packages/@ember/routing/index.js +4 -4
  74. package/dist/packages/@ember/routing/lib/dsl.js +2 -1
  75. package/dist/packages/@ember/routing/lib/generate_controller.js +4 -3
  76. package/dist/packages/@ember/routing/lib/router_state.js +26 -1
  77. package/dist/packages/@ember/routing/lib/routing-service.js +107 -9
  78. package/dist/packages/@ember/routing/lib/utils.js +238 -7
  79. package/dist/packages/@ember/routing/none-location.js +3 -2
  80. package/dist/packages/@ember/routing/route.js +1618 -22
  81. package/dist/packages/@ember/routing/router-service.js +638 -12
  82. package/dist/packages/@ember/routing/router.js +1449 -14
  83. package/dist/packages/@ember/runloop/index.js +760 -6
  84. package/dist/packages/@ember/service/index.js +3 -3
  85. package/dist/packages/@ember/template/index.js +4 -4
  86. package/dist/packages/@ember/utils/index.js +2 -1
  87. package/dist/packages/@ember/utils/lib/compare.js +159 -4
  88. package/dist/packages/@ember/utils/lib/is_empty.js +4 -4
  89. package/dist/packages/@ember/utils/lib/type-of.js +110 -1
  90. package/dist/packages/@glimmer/tracking/index.js +3 -3
  91. package/dist/packages/@glimmer/tracking/primitives/cache.js +3 -3
  92. package/dist/packages/ember/barrel.js +28 -13
  93. package/dist/packages/ember/version.js +1 -1
  94. package/dist/packages/ember-testing/lib/adapters/adapter.js +1 -1
  95. package/dist/packages/ember-testing/lib/adapters/qunit.js +2 -1
  96. package/dist/packages/ember-testing/lib/ext/application.js +2 -1
  97. package/dist/packages/ember-testing/lib/ext/rsvp.js +1 -1
  98. package/dist/packages/ember-testing/lib/helpers/and_then.js +2 -1
  99. package/dist/packages/ember-testing/lib/helpers/current_path.js +8 -6
  100. package/dist/packages/ember-testing/lib/helpers/current_route_name.js +8 -6
  101. package/dist/packages/ember-testing/lib/helpers/current_url.js +6 -5
  102. package/dist/packages/ember-testing/lib/helpers/pause_test.js +2 -1
  103. package/dist/packages/ember-testing/lib/helpers/visit.js +4 -3
  104. package/dist/packages/ember-testing/lib/helpers/wait.js +4 -3
  105. package/dist/packages/ember-testing/lib/initializers.js +15 -8
  106. package/dist/packages/ember-testing/lib/setup_for_testing.js +1 -1
  107. package/dist/packages/ember-testing/lib/test/run.js +1 -1
  108. package/dist/packages/router_js/index.js +2 -1
  109. package/dist/packages/shared-chunks/{alias-By_2yu5c.js → alias-Dri0koi2.js} +5 -3
  110. package/dist/packages/shared-chunks/array-3xbmc_4J.js +119 -0
  111. package/dist/packages/shared-chunks/{cache-gDE3bkXq.js → cache-BESCGvbE.js} +667 -1529
  112. package/dist/packages/shared-chunks/{core_view-Cxne2_wu.js → chunk-3SQBS3Y5-Cj4eryg1.js} +1 -88
  113. package/dist/packages/shared-chunks/{index-BXPoca1S.js → index-Llq6dmgX.js} +40 -4660
  114. package/dist/packages/shared-chunks/{is_proxy-Dmis-70B.js → is_proxy-DjvCKvd5.js} +1 -1
  115. package/dist/packages/shared-chunks/{mandatory-setter-1UQhiJOb.js → mandatory-setter-BiXq-dpN.js} +2 -1
  116. package/dist/packages/shared-chunks/{name-z9D9Yibn.js → name-Dx2bGFVv.js} +1 -1
  117. package/dist/packages/shared-chunks/{namespace_search-CBgHTkDh.js → namespace_search-btMaPM-_.js} +2 -2
  118. package/dist/packages/shared-chunks/{property_set-CW4q-uo4.js → property_set-BapAkp3X.js} +5 -4
  119. package/dist/packages/shared-chunks/{registry-DzfcDwii.js → registry-B8WARvkP.js} +3 -2
  120. package/dist/packages/shared-chunks/{router-B-Q1aYBn.js → router-DrLZsJeE.js} +2 -482
  121. package/dist/packages/shared-chunks/{set_properties-DvalyQdu.js → set_properties-BScfxzvI.js} +2 -2
  122. package/dist/packages/shared-chunks/setup-registry-du4pSGZi.js +48 -0
  123. package/dist/packages/shared-chunks/{to-string-D8i3mjEU.js → to-string-B1BmwUkt.js} +1 -1
  124. package/dist/packages/shared-chunks/unrecognized-url-error-zpz-JEoG.js +484 -0
  125. package/docs/data.json +152 -142
  126. package/package.json +4 -7
  127. package/types/stable/@ember/-internals/metal/lib/array.d.ts +1 -2
  128. package/types/stable/@ember/-internals/metal/lib/object-at.d.ts +4 -0
  129. package/types/stable/@ember/-internals/metal/lib/observer.d.ts +2 -1
  130. package/types/stable/@ember/array/index.d.ts +1 -1
  131. package/types/stable/@ember/array/make.d.ts +3 -0
  132. package/types/stable/@ember/debug/index.d.ts +3 -7
  133. package/types/stable/@ember/debug/lib/assert.d.ts +8 -0
  134. package/types/stable/@ember/engine/index.d.ts +1 -1
  135. package/types/stable/@ember/engine/instance.d.ts +2 -2
  136. package/types/stable/@ember/engine/parent.d.ts +3 -0
  137. package/types/stable/@ember/modifier/index.d.ts +1 -3
  138. package/types/stable/@ember/modifier/on.d.ts +5 -0
  139. package/types/stable/@ember/routing/lib/routing-service.d.ts +1 -1
  140. package/types/stable/@ember/routing/route.d.ts +2 -3
  141. package/types/stable/@ember/routing/router-service.d.ts +1 -1
  142. package/types/stable/@ember/routing/router.d.ts +4 -4
  143. package/types/stable/ember/barrel.d.ts +1 -1
  144. package/types/stable/ember/index.d.ts +1 -1
  145. package/types/stable/index.d.ts +5 -0
  146. package/dist/packages/shared-chunks/index-DTxy4Zgx.js +0 -641
  147. 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 };