ember-source 4.5.0-alpha.5 → 4.6.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -3
- package/blueprints-js/-addon-import.js +48 -0
- package/blueprints-js/acceptance-test/mocha-files/tests/acceptance/__name__-test.js +24 -0
- package/blueprints-js/acceptance-test/mocha-rfc-232-files/tests/acceptance/__name__-test.js +13 -0
- package/blueprints-js/acceptance-test/qunit-files/tests/acceptance/__name__-test.js +12 -0
- package/blueprints-js/acceptance-test/qunit-rfc-232-files/tests/acceptance/__name__-test.js +13 -0
- package/blueprints-js/component/files/__root__/__path__/__name__.js +3 -0
- package/blueprints-js/component/files/__root__/__templatepath__/__templatename__.hbs +1 -0
- package/blueprints-js/component-addon/files/__root__/__path__/__name__.js +1 -0
- package/blueprints-js/component-class/files/__root__/__path__/__name__.js +3 -0
- package/blueprints-js/component-class-addon/files/__root__/__path__/__name__.js +1 -0
- package/blueprints-js/component-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +34 -0
- package/blueprints-js/component-test/mocha-files/__root__/__testType__/__path__/__test__.js +36 -0
- package/blueprints-js/component-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +38 -0
- package/blueprints-js/component-test/qunit-files/__root__/__testType__/__path__/__test__.js +31 -0
- package/blueprints-js/component-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +36 -0
- package/blueprints-js/controller/files/__root__/__path__/__name__.js +3 -0
- package/blueprints-js/controller-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +16 -0
- package/blueprints-js/controller-test/mocha-files/__root__/__testType__/__path__/__test__.js +18 -0
- package/blueprints-js/controller-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +13 -0
- package/blueprints-js/controller-test/qunit-files/__root__/__testType__/__path__/__test__.js +12 -0
- package/blueprints-js/controller-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +12 -0
- package/blueprints-js/helper/files/__root__/__collection__/__name__.js +5 -0
- package/blueprints-js/helper/mu-files/__root__/__collection__/__name__.js +7 -0
- package/blueprints-js/helper-addon/files/__root__/__path__/__name__.js +1 -0
- package/blueprints-js/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js +26 -0
- package/blueprints-js/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js +28 -0
- package/blueprints-js/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +18 -0
- package/blueprints-js/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js +15 -0
- package/blueprints-js/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +17 -0
- package/blueprints-js/initializer/files/__root__/initializers/__name__.js +5 -0
- package/blueprints-js/initializer-addon/files/__root__/__path__/__name__.js +1 -0
- package/blueprints-js/initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +28 -0
- package/blueprints-js/initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +31 -0
- package/blueprints-js/initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +25 -0
- package/blueprints-js/initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +37 -0
- package/blueprints-js/instance-initializer/files/__root__/instance-initializers/__name__.js +5 -0
- package/blueprints-js/instance-initializer-addon/files/__root__/__path__/__name__.js +1 -0
- package/blueprints-js/instance-initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +30 -0
- package/blueprints-js/instance-initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +32 -0
- package/blueprints-js/instance-initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +26 -0
- package/blueprints-js/instance-initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +39 -0
- package/blueprints-js/mixin/files/__root__/mixins/__name__.js +3 -0
- package/blueprints-js/mixin-test/mocha-files/__root__/__testType__/__name__-test.js +13 -0
- package/blueprints-js/mixin-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +13 -0
- package/blueprints-js/mixin-test/qunit-files/__root__/__testType__/__name__-test.js +12 -0
- package/blueprints-js/mixin-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +12 -0
- package/blueprints-js/route/files/__root__/__path__/__name__.js +9 -0
- package/blueprints-js/route/files/__root__/__templatepath__/__templatename__.hbs +2 -0
- package/blueprints-js/route-addon/files/__root__/__path__/__name__.js +1 -0
- package/blueprints-js/route-addon/files/__root__/__templatepath__/__templatename__.js +1 -0
- package/blueprints-js/route-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +15 -0
- package/blueprints-js/route-test/mocha-files/__root__/__testType__/__path__/__test__.js +17 -0
- package/blueprints-js/route-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +12 -0
- package/blueprints-js/route-test/qunit-files/__root__/__testType__/__path__/__test__.js +11 -0
- package/blueprints-js/route-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +11 -0
- package/blueprints-js/service/files/__root__/__path__/__name__.js +3 -0
- package/blueprints-js/service-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +16 -0
- package/blueprints-js/service-test/mocha-files/__root__/__testType__/__path__/__test__.js +18 -0
- package/blueprints-js/service-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +13 -0
- package/blueprints-js/service-test/qunit-files/__root__/__testType__/__path__/__test__.js +12 -0
- package/blueprints-js/service-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +12 -0
- package/blueprints-js/template/files/__root__/__path__/__name__.hbs +0 -0
- package/blueprints-js/test-framework-detector.js +60 -0
- package/blueprints-js/util/files/__root__/utils/__name__.js +3 -0
- package/blueprints-js/util-test/mocha-files/__root__/__testType__/__name__-test.js +11 -0
- package/blueprints-js/util-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +11 -0
- package/blueprints-js/util-test/qunit-files/__root__/__testType__/__name__-test.js +10 -0
- package/blueprints-js/util-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +10 -0
- package/build-metadata.json +3 -3
- package/dist/ember-template-compiler.js +2 -2
- package/dist/ember-template-compiler.map +1 -1
- package/dist/ember-testing.js +3 -8
- package/dist/ember-testing.map +1 -1
- package/dist/ember.debug.js +119 -419
- package/dist/ember.debug.map +1 -1
- package/dist/header/license.js +1 -1
- package/dist/packages/@ember/-internals/glimmer/index.js +21 -11
- package/dist/packages/@ember/-internals/metal/index.js +0 -3
- package/dist/packages/@ember/-internals/routing/lib/system/router.js +0 -4
- package/dist/packages/@ember/controller/lib/controller_mixin.js +8 -18
- package/dist/packages/@ember/object/lib/computed/computed_macros.js +6 -4
- package/dist/packages/@ember/object/lib/computed/reduce_computed_macros.js +73 -364
- package/dist/packages/ember/version.js +1 -1
- package/dist/packages/ember-testing/lib/adapters/adapter.js +2 -7
- package/docs/data.json +534 -528
- package/package.json +5 -4
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
import { DEBUG } from '@glimmer/env';
|
|
5
5
|
import { assert } from '@ember/debug';
|
|
6
6
|
import { computed, autoComputed, get, isElementDescriptor } from '@ember/-internals/metal';
|
|
7
|
-
import { compare,
|
|
7
|
+
import { compare, A as emberA, uniqBy as uniqByArray } from '@ember/-internals/runtime';
|
|
8
|
+
import EmberArray from '@ember/-internals/runtime/lib/mixins/array';
|
|
9
|
+
|
|
10
|
+
function isNativeOrEmberArray(obj) {
|
|
11
|
+
return Array.isArray(obj) || EmberArray.detect(obj);
|
|
12
|
+
}
|
|
8
13
|
|
|
9
14
|
function reduceMacro(dependentKey, callback, initialValue, name) {
|
|
10
15
|
assert(`Dependent key passed to \`${name}\` computed macro shouldn't contain brace expanding pattern.`, !/[[\]{}]/g.test(dependentKey));
|
|
@@ -33,7 +38,7 @@ function arrayMacro(dependentKey, additionalDependentKeys, callback) {
|
|
|
33
38
|
return computed(dependentKey, ...additionalDependentKeys, function () {
|
|
34
39
|
let value = get(this, propertyName);
|
|
35
40
|
|
|
36
|
-
if (
|
|
41
|
+
if (isNativeOrEmberArray(value)) {
|
|
37
42
|
return emberA(callback.call(this, value));
|
|
38
43
|
} else {
|
|
39
44
|
return emberA();
|
|
@@ -203,94 +208,24 @@ export function min(dependentKey) {
|
|
|
203
208
|
assert('You attempted to use @min as a decorator directly, but it requires a `dependentKey` parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
|
|
204
209
|
return reduceMacro(dependentKey, (min, item) => Math.min(min, item), Infinity, 'min');
|
|
205
210
|
}
|
|
206
|
-
|
|
207
|
-
Returns an array mapped via the callback
|
|
208
|
-
|
|
209
|
-
The callback method you provide should have the following signature:
|
|
210
|
-
- `item` is the current item in the iteration.
|
|
211
|
-
- `index` is the integer index of the current item in the iteration.
|
|
212
|
-
|
|
213
|
-
```javascript
|
|
214
|
-
function mapCallback(item, index);
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
Example:
|
|
218
|
-
|
|
219
|
-
```javascript
|
|
220
|
-
import { set } from '@ember/object';
|
|
221
|
-
import { map } from '@ember/object/computed';
|
|
222
|
-
|
|
223
|
-
class Hamster {
|
|
224
|
-
constructor(chores) {
|
|
225
|
-
set(this, 'chores', chores);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
@map('chores', function(chore, index) {
|
|
229
|
-
return `${chore.toUpperCase()}!`;
|
|
230
|
-
})
|
|
231
|
-
excitingChores;
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
let hamster = new Hamster(['clean', 'write more unit tests']);
|
|
235
|
-
|
|
236
|
-
hamster.excitingChores; // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
You can optionally pass an array of additional dependent keys as the second
|
|
240
|
-
parameter to the macro, if your map function relies on any external values:
|
|
241
|
-
|
|
242
|
-
```javascript
|
|
243
|
-
import { set } from '@ember/object';
|
|
244
|
-
import { map } from '@ember/object/computed';
|
|
245
|
-
|
|
246
|
-
class Hamster {
|
|
247
|
-
shouldUpperCase = false;
|
|
248
|
-
|
|
249
|
-
constructor(chores) {
|
|
250
|
-
set(this, 'chores', chores);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
@map('chores', ['shouldUpperCase'], function(chore, index) {
|
|
254
|
-
if (this.shouldUpperCase) {
|
|
255
|
-
return `${chore.toUpperCase()}!`;
|
|
256
|
-
} else {
|
|
257
|
-
return `${chore}!`;
|
|
258
|
-
}
|
|
259
|
-
})
|
|
260
|
-
excitingChores;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
let hamster = new Hamster(['clean', 'write more unit tests']);
|
|
264
|
-
|
|
265
|
-
hamster.excitingChores; // ['clean!', 'write more unit tests!']
|
|
266
|
-
|
|
267
|
-
set(hamster, 'shouldUpperCase', true);
|
|
268
|
-
hamster.excitingChores; // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
@method map
|
|
272
|
-
@for @ember/object/computed
|
|
273
|
-
@static
|
|
274
|
-
@param {String} dependentKey
|
|
275
|
-
@param {Array} [additionalDependentKeys] optional array of additional
|
|
276
|
-
dependent keys
|
|
277
|
-
@param {Function} callback
|
|
278
|
-
@return {ComputedProperty} an array mapped via the callback
|
|
279
|
-
@public
|
|
280
|
-
*/
|
|
281
|
-
|
|
282
|
-
export function map(dependentKey, additionalDependentKeys, callback) {
|
|
211
|
+
export function map(dependentKey, additionalDependentKeysOrCallback, callback) {
|
|
283
212
|
assert('You attempted to use @map as a decorator directly, but it requires atleast `dependentKey` and `callback` parameters', !isElementDescriptor(Array.prototype.slice.call(arguments)));
|
|
213
|
+
assert('The final parameter provided to map must be a callback function', typeof callback === 'function' || callback === undefined && typeof additionalDependentKeysOrCallback === 'function');
|
|
214
|
+
assert('The second parameter provided to map must either be the callback or an array of additional dependent keys', Array.isArray(additionalDependentKeysOrCallback) || typeof additionalDependentKeysOrCallback === 'function');
|
|
215
|
+
let additionalDependentKeys;
|
|
284
216
|
|
|
285
|
-
if (
|
|
286
|
-
callback =
|
|
217
|
+
if (typeof additionalDependentKeysOrCallback === 'function') {
|
|
218
|
+
callback = additionalDependentKeysOrCallback;
|
|
287
219
|
additionalDependentKeys = [];
|
|
220
|
+
} else {
|
|
221
|
+
additionalDependentKeys = additionalDependentKeysOrCallback;
|
|
288
222
|
}
|
|
289
223
|
|
|
290
|
-
|
|
291
|
-
assert('
|
|
224
|
+
const cCallback = callback;
|
|
225
|
+
assert('[BUG] Missing callback', cCallback);
|
|
292
226
|
return arrayMacro(dependentKey, additionalDependentKeys, function (value) {
|
|
293
|
-
|
|
227
|
+
// This is so dumb...
|
|
228
|
+
return Array.isArray(value) ? value.map(cCallback, this) : value.map(cCallback, this);
|
|
294
229
|
});
|
|
295
230
|
}
|
|
296
231
|
/**
|
|
@@ -348,124 +283,23 @@ export function mapBy(dependentKey, propertyKey) {
|
|
|
348
283
|
assert(`Dependent key passed to \`mapBy\` computed macro shouldn't contain brace expanding pattern.`, !/[[\]{}]/g.test(dependentKey));
|
|
349
284
|
return map(`${dependentKey}.@each.${propertyKey}`, item => get(item, propertyKey));
|
|
350
285
|
}
|
|
351
|
-
|
|
352
|
-
Filters the array by the callback.
|
|
353
|
-
|
|
354
|
-
The callback method you provide should have the following signature:
|
|
355
|
-
- `item` is the current item in the iteration.
|
|
356
|
-
- `index` is the integer index of the current item in the iteration.
|
|
357
|
-
- `array` is the dependant array itself.
|
|
358
|
-
|
|
359
|
-
```javascript
|
|
360
|
-
function filterCallback(item, index, array);
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
Example:
|
|
364
|
-
|
|
365
|
-
```javascript
|
|
366
|
-
import { set } from '@ember/object';
|
|
367
|
-
import { filter } from '@ember/object/computed';
|
|
368
|
-
|
|
369
|
-
class Hamster {
|
|
370
|
-
constructor(chores) {
|
|
371
|
-
set(this, 'chores', chores);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
@filter('chores', function(chore, index, array) {
|
|
375
|
-
return !chore.done;
|
|
376
|
-
})
|
|
377
|
-
remainingChores;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
let hamster = Hamster.create([
|
|
381
|
-
{ name: 'cook', done: true },
|
|
382
|
-
{ name: 'clean', done: true },
|
|
383
|
-
{ name: 'write more unit tests', done: false }
|
|
384
|
-
]);
|
|
385
|
-
|
|
386
|
-
hamster.remainingChores; // [{name: 'write more unit tests', done: false}]
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
You can also use `@each.property` in your dependent key, the callback will
|
|
390
|
-
still use the underlying array:
|
|
391
|
-
|
|
392
|
-
```javascript
|
|
393
|
-
import { set } from '@ember/object';
|
|
394
|
-
import { filter } from '@ember/object/computed';
|
|
395
|
-
|
|
396
|
-
class Hamster {
|
|
397
|
-
constructor(chores) {
|
|
398
|
-
set(this, 'chores', chores);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
@filter('chores.@each.done', function(chore, index, array) {
|
|
402
|
-
return !chore.done;
|
|
403
|
-
})
|
|
404
|
-
remainingChores;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
let hamster = new Hamster([
|
|
408
|
-
{ name: 'cook', done: true },
|
|
409
|
-
{ name: 'clean', done: true },
|
|
410
|
-
{ name: 'write more unit tests', done: false }
|
|
411
|
-
]);
|
|
412
|
-
hamster.remainingChores; // [{name: 'write more unit tests', done: false}]
|
|
413
|
-
|
|
414
|
-
set(hamster.chores[2], 'done', true);
|
|
415
|
-
hamster.remainingChores; // []
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
Finally, you can optionally pass an array of additional dependent keys as the
|
|
419
|
-
second parameter to the macro, if your filter function relies on any external
|
|
420
|
-
values:
|
|
421
|
-
|
|
422
|
-
```javascript
|
|
423
|
-
import { filter } from '@ember/object/computed';
|
|
424
|
-
|
|
425
|
-
class Hamster {
|
|
426
|
-
constructor(chores) {
|
|
427
|
-
set(this, 'chores', chores);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
doneKey = 'finished';
|
|
431
|
-
|
|
432
|
-
@filter('chores', ['doneKey'], function(chore, index, array) {
|
|
433
|
-
return !chore[this.doneKey];
|
|
434
|
-
})
|
|
435
|
-
remainingChores;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
let hamster = new Hamster([
|
|
439
|
-
{ name: 'cook', finished: true },
|
|
440
|
-
{ name: 'clean', finished: true },
|
|
441
|
-
{ name: 'write more unit tests', finished: false }
|
|
442
|
-
]);
|
|
443
|
-
|
|
444
|
-
hamster.remainingChores; // [{name: 'write more unit tests', finished: false}]
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
@method filter
|
|
448
|
-
@for @ember/object/computed
|
|
449
|
-
@static
|
|
450
|
-
@param {String} dependentKey
|
|
451
|
-
@param {Array} [additionalDependentKeys] optional array of additional dependent keys
|
|
452
|
-
@param {Function} callback
|
|
453
|
-
@return {ComputedProperty} the filtered array
|
|
454
|
-
@public
|
|
455
|
-
*/
|
|
456
|
-
|
|
457
|
-
export function filter(dependentKey, additionalDependentKeys, callback) {
|
|
286
|
+
export function filter(dependentKey, additionalDependentKeysOrCallback, callback) {
|
|
458
287
|
assert('You attempted to use @filter as a decorator directly, but it requires atleast `dependentKey` and `callback` parameters', !isElementDescriptor(Array.prototype.slice.call(arguments)));
|
|
288
|
+
assert('The final parameter provided to filter must be a callback function', typeof callback === 'function' || callback === undefined && typeof additionalDependentKeysOrCallback === 'function');
|
|
289
|
+
assert('The second parameter provided to filter must either be the callback or an array of additional dependent keys', Array.isArray(additionalDependentKeysOrCallback) || typeof additionalDependentKeysOrCallback === 'function');
|
|
290
|
+
let additionalDependentKeys;
|
|
459
291
|
|
|
460
|
-
if (
|
|
461
|
-
callback =
|
|
292
|
+
if (typeof additionalDependentKeysOrCallback === 'function') {
|
|
293
|
+
callback = additionalDependentKeysOrCallback;
|
|
462
294
|
additionalDependentKeys = [];
|
|
295
|
+
} else {
|
|
296
|
+
additionalDependentKeys = additionalDependentKeysOrCallback;
|
|
463
297
|
}
|
|
464
298
|
|
|
465
|
-
|
|
466
|
-
assert('The second parameter provided to filter must either be the callback or an array of additional dependent keys', Array.isArray(additionalDependentKeys));
|
|
299
|
+
const cCallback = callback;
|
|
467
300
|
return arrayMacro(dependentKey, additionalDependentKeys, function (value) {
|
|
468
|
-
|
|
301
|
+
// This is a really silly way to keep TS happy
|
|
302
|
+
return Array.isArray(value) ? value.filter(cCallback, this) : value.filter(cCallback, this);
|
|
469
303
|
});
|
|
470
304
|
}
|
|
471
305
|
/**
|
|
@@ -554,15 +388,16 @@ export function filterBy(dependentKey, propertyKey, value) {
|
|
|
554
388
|
@public
|
|
555
389
|
*/
|
|
556
390
|
|
|
557
|
-
export function uniq(...
|
|
391
|
+
export function uniq(dependentKey, ...additionalDependentKeys) {
|
|
558
392
|
assert('You attempted to use @uniq/@union as a decorator directly, but it requires atleast one dependent key parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
|
|
393
|
+
let args = [dependentKey, ...additionalDependentKeys];
|
|
559
394
|
return multiArrayMacro(args, function (dependentKeys) {
|
|
560
395
|
let uniq = emberA();
|
|
561
396
|
let seen = new Set();
|
|
562
397
|
dependentKeys.forEach(dependentKey => {
|
|
563
398
|
let value = get(this, dependentKey);
|
|
564
399
|
|
|
565
|
-
if (
|
|
400
|
+
if (isNativeOrEmberArray(value)) {
|
|
566
401
|
value.forEach(item => {
|
|
567
402
|
if (!seen.has(item)) {
|
|
568
403
|
seen.add(item);
|
|
@@ -617,7 +452,7 @@ export function uniqBy(dependentKey, propertyKey) {
|
|
|
617
452
|
assert(`Dependent key passed to \`uniqBy\` computed macro shouldn't contain brace expanding pattern.`, !/[[\]{}]/g.test(dependentKey));
|
|
618
453
|
return computed(`${dependentKey}.[]`, function () {
|
|
619
454
|
let list = get(this, dependentKey);
|
|
620
|
-
return
|
|
455
|
+
return isNativeOrEmberArray(list) ? uniqByArray(list, propertyKey) : emberA();
|
|
621
456
|
}).readOnly();
|
|
622
457
|
}
|
|
623
458
|
/**
|
|
@@ -703,20 +538,22 @@ export let union = uniq;
|
|
|
703
538
|
@public
|
|
704
539
|
*/
|
|
705
540
|
|
|
706
|
-
export function intersect(...
|
|
541
|
+
export function intersect(dependentKey, ...additionalDependentKeys) {
|
|
707
542
|
assert('You attempted to use @intersect as a decorator directly, but it requires atleast one dependent key parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
|
|
543
|
+
let args = [dependentKey, ...additionalDependentKeys];
|
|
708
544
|
return multiArrayMacro(args, function (dependentKeys) {
|
|
709
545
|
let arrays = dependentKeys.map(dependentKey => {
|
|
710
546
|
let array = get(this, dependentKey);
|
|
711
|
-
return isArray(array) ? array : [];
|
|
547
|
+
return Array.isArray(array) ? array : [];
|
|
712
548
|
});
|
|
713
|
-
let
|
|
714
|
-
|
|
549
|
+
let firstArray = arrays.pop();
|
|
550
|
+
assert('Attempted to apply multiArrayMacro for intersect without any dependentKeys', firstArray);
|
|
551
|
+
let results = firstArray.filter(candidate => {
|
|
552
|
+
for (let array of arrays) {
|
|
715
553
|
let found = false;
|
|
716
|
-
let array = arrays[i];
|
|
717
554
|
|
|
718
|
-
for (let
|
|
719
|
-
if (
|
|
555
|
+
for (let item of array) {
|
|
556
|
+
if (item === candidate) {
|
|
720
557
|
found = true;
|
|
721
558
|
break;
|
|
722
559
|
}
|
|
@@ -784,11 +621,11 @@ export function setDiff(setAProperty, setBProperty) {
|
|
|
784
621
|
let setA = get(this, setAProperty);
|
|
785
622
|
let setB = get(this, setBProperty);
|
|
786
623
|
|
|
787
|
-
if (!
|
|
624
|
+
if (!isNativeOrEmberArray(setA)) {
|
|
788
625
|
return emberA();
|
|
789
626
|
}
|
|
790
627
|
|
|
791
|
-
if (!
|
|
628
|
+
if (!isNativeOrEmberArray(setB)) {
|
|
792
629
|
return emberA(setA);
|
|
793
630
|
}
|
|
794
631
|
|
|
@@ -827,8 +664,9 @@ export function setDiff(setAProperty, setBProperty) {
|
|
|
827
664
|
@public
|
|
828
665
|
*/
|
|
829
666
|
|
|
830
|
-
export function collect(...
|
|
667
|
+
export function collect(dependentKey, ...additionalDependentKeys) {
|
|
831
668
|
assert('You attempted to use @collect as a decorator directly, but it requires atleast one dependent key parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
|
|
669
|
+
let dependentKeys = [dependentKey, ...additionalDependentKeys];
|
|
832
670
|
return multiArrayMacro(dependentKeys, function () {
|
|
833
671
|
let res = dependentKeys.map(key => {
|
|
834
672
|
let val = get(this, key);
|
|
@@ -837,172 +675,38 @@ export function collect(...dependentKeys) {
|
|
|
837
675
|
return emberA(res);
|
|
838
676
|
}, 'collect');
|
|
839
677
|
}
|
|
840
|
-
|
|
841
|
-
A computed property which returns a new array with all the properties from the
|
|
842
|
-
first dependent array sorted based on a property or sort function. The sort
|
|
843
|
-
macro can be used in two different ways:
|
|
844
|
-
|
|
845
|
-
1. By providing a sort callback function
|
|
846
|
-
2. By providing an array of keys to sort the array
|
|
847
|
-
|
|
848
|
-
In the first form, the callback method you provide should have the following
|
|
849
|
-
signature:
|
|
850
|
-
|
|
851
|
-
```javascript
|
|
852
|
-
function sortCallback(itemA, itemB);
|
|
853
|
-
```
|
|
854
|
-
|
|
855
|
-
- `itemA` the first item to compare.
|
|
856
|
-
- `itemB` the second item to compare.
|
|
857
|
-
|
|
858
|
-
This function should return negative number (e.g. `-1`) when `itemA` should
|
|
859
|
-
come before `itemB`. It should return positive number (e.g. `1`) when `itemA`
|
|
860
|
-
should come after `itemB`. If the `itemA` and `itemB` are equal this function
|
|
861
|
-
should return `0`.
|
|
862
|
-
|
|
863
|
-
Therefore, if this function is comparing some numeric values, simple `itemA -
|
|
864
|
-
itemB` or `itemA.get( 'foo' ) - itemB.get( 'foo' )` can be used instead of
|
|
865
|
-
series of `if`.
|
|
866
|
-
|
|
867
|
-
Example:
|
|
868
|
-
|
|
869
|
-
```javascript
|
|
870
|
-
import { set } from '@ember/object';
|
|
871
|
-
import { sort } from '@ember/object/computed';
|
|
872
|
-
|
|
873
|
-
class ToDoList {
|
|
874
|
-
constructor(todos) {
|
|
875
|
-
set(this, 'todos', todos);
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
// using a custom sort function
|
|
879
|
-
@sort('todos', function(a, b){
|
|
880
|
-
if (a.priority > b.priority) {
|
|
881
|
-
return 1;
|
|
882
|
-
} else if (a.priority < b.priority) {
|
|
883
|
-
return -1;
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
return 0;
|
|
887
|
-
})
|
|
888
|
-
priorityTodos;
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
let todoList = new ToDoList([
|
|
892
|
-
{ name: 'Unit Test', priority: 2 },
|
|
893
|
-
{ name: 'Documentation', priority: 3 },
|
|
894
|
-
{ name: 'Release', priority: 1 }
|
|
895
|
-
]);
|
|
896
|
-
|
|
897
|
-
todoList.priorityTodos; // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
|
|
898
|
-
```
|
|
899
|
-
|
|
900
|
-
You can also optionally pass an array of additional dependent keys as the
|
|
901
|
-
second parameter, if your sort function is dependent on additional values that
|
|
902
|
-
could changes:
|
|
903
|
-
|
|
904
|
-
```js
|
|
905
|
-
import EmberObject, { set } from '@ember/object';
|
|
906
|
-
import { sort } from '@ember/object/computed';
|
|
907
|
-
|
|
908
|
-
class ToDoList {
|
|
909
|
-
sortKey = 'priority';
|
|
910
|
-
|
|
911
|
-
constructor(todos) {
|
|
912
|
-
set(this, 'todos', todos);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
// using a custom sort function
|
|
916
|
-
@sort('todos', ['sortKey'], function(a, b){
|
|
917
|
-
if (a[this.sortKey] > b[this.sortKey]) {
|
|
918
|
-
return 1;
|
|
919
|
-
} else if (a[this.sortKey] < b[this.sortKey]) {
|
|
920
|
-
return -1;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
return 0;
|
|
924
|
-
})
|
|
925
|
-
sortedTodos;
|
|
926
|
-
});
|
|
927
|
-
|
|
928
|
-
let todoList = new ToDoList([
|
|
929
|
-
{ name: 'Unit Test', priority: 2 },
|
|
930
|
-
{ name: 'Documentation', priority: 3 },
|
|
931
|
-
{ name: 'Release', priority: 1 }
|
|
932
|
-
]);
|
|
933
|
-
|
|
934
|
-
todoList.priorityTodos; // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
|
|
935
|
-
```
|
|
936
|
-
|
|
937
|
-
In the second form, you should provide the key of the array of sort values as
|
|
938
|
-
the second parameter:
|
|
939
|
-
|
|
940
|
-
```javascript
|
|
941
|
-
import { set } from '@ember/object';
|
|
942
|
-
import { sort } from '@ember/object/computed';
|
|
943
|
-
|
|
944
|
-
class ToDoList {
|
|
945
|
-
constructor(todos) {
|
|
946
|
-
set(this, 'todos', todos);
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
// using standard ascending sort
|
|
950
|
-
todosSorting = ['name'];
|
|
951
|
-
@sort('todos', 'todosSorting') sortedTodos;
|
|
952
|
-
|
|
953
|
-
// using descending sort
|
|
954
|
-
todosSortingDesc = ['name:desc'];
|
|
955
|
-
@sort('todos', 'todosSortingDesc') sortedTodosDesc;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
let todoList = new ToDoList([
|
|
959
|
-
{ name: 'Unit Test', priority: 2 },
|
|
960
|
-
{ name: 'Documentation', priority: 3 },
|
|
961
|
-
{ name: 'Release', priority: 1 }
|
|
962
|
-
]);
|
|
963
|
-
|
|
964
|
-
todoList.sortedTodos; // [{ name:'Documentation', priority:3 }, { name:'Release', priority:1 }, { name:'Unit Test', priority:2 }]
|
|
965
|
-
todoList.sortedTodosDesc; // [{ name:'Unit Test', priority:2 }, { name:'Release', priority:1 }, { name:'Documentation', priority:3 }]
|
|
966
|
-
```
|
|
967
|
-
|
|
968
|
-
@method sort
|
|
969
|
-
@for @ember/object/computed
|
|
970
|
-
@static
|
|
971
|
-
@param {String} itemsKey
|
|
972
|
-
@param {String|Function|Array} sortDefinitionOrDependentKeys The key of the sort definition (an array of sort properties),
|
|
973
|
-
the sort function, or an array of additional dependent keys
|
|
974
|
-
@param {Function?} sortDefinition the sort function (when used with additional dependent keys)
|
|
975
|
-
@return {ComputedProperty} computes a new sorted array based on the sort
|
|
976
|
-
property array or callback function
|
|
977
|
-
@public
|
|
978
|
-
*/
|
|
979
|
-
|
|
980
|
-
export function sort(itemsKey, additionalDependentKeys, sortDefinition) {
|
|
678
|
+
export function sort(itemsKey, additionalDependentKeysOrDefinition, sortDefinition) {
|
|
981
679
|
assert('You attempted to use @sort as a decorator directly, but it requires atleast an `itemsKey` parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
|
|
982
680
|
|
|
983
681
|
if (DEBUG) {
|
|
984
682
|
let argumentsValid = false;
|
|
985
683
|
|
|
986
684
|
if (arguments.length === 2) {
|
|
987
|
-
argumentsValid = typeof itemsKey === 'string' && (typeof
|
|
685
|
+
argumentsValid = typeof itemsKey === 'string' && (typeof additionalDependentKeysOrDefinition === 'string' || typeof additionalDependentKeysOrDefinition === 'function');
|
|
988
686
|
}
|
|
989
687
|
|
|
990
688
|
if (arguments.length === 3) {
|
|
991
|
-
argumentsValid = typeof itemsKey === 'string' && Array.isArray(
|
|
689
|
+
argumentsValid = typeof itemsKey === 'string' && Array.isArray(additionalDependentKeysOrDefinition) && typeof sortDefinition === 'function';
|
|
992
690
|
}
|
|
993
691
|
|
|
994
692
|
assert('The `sort` computed macro can either be used with an array of sort properties or with a sort function. If used with an array of sort properties, it must receive exactly two arguments: the key of the array to sort, and the key of the array of sort properties. If used with a sort function, it may receive up to three arguments: the key of the array to sort, an optional additional array of dependent keys for the computed property, and the sort function.', argumentsValid);
|
|
995
693
|
}
|
|
996
694
|
|
|
997
|
-
|
|
998
|
-
|
|
695
|
+
let additionalDependentKeys;
|
|
696
|
+
let sortDefinitionOrString;
|
|
697
|
+
|
|
698
|
+
if (Array.isArray(additionalDependentKeysOrDefinition)) {
|
|
699
|
+
additionalDependentKeys = additionalDependentKeysOrDefinition;
|
|
700
|
+
sortDefinitionOrString = sortDefinition;
|
|
701
|
+
} else {
|
|
999
702
|
additionalDependentKeys = [];
|
|
703
|
+
sortDefinitionOrString = additionalDependentKeysOrDefinition;
|
|
1000
704
|
}
|
|
1001
705
|
|
|
1002
|
-
if (typeof
|
|
1003
|
-
return customSort(itemsKey, additionalDependentKeys,
|
|
706
|
+
if (typeof sortDefinitionOrString === 'function') {
|
|
707
|
+
return customSort(itemsKey, additionalDependentKeys, sortDefinitionOrString);
|
|
1004
708
|
} else {
|
|
1005
|
-
return propertySort(itemsKey,
|
|
709
|
+
return propertySort(itemsKey, sortDefinitionOrString);
|
|
1006
710
|
}
|
|
1007
711
|
}
|
|
1008
712
|
|
|
@@ -1017,12 +721,14 @@ function customSort(itemsKey, additionalDependentKeys, comparator) {
|
|
|
1017
721
|
function propertySort(itemsKey, sortPropertiesKey) {
|
|
1018
722
|
let cp = autoComputed(function (key) {
|
|
1019
723
|
let sortProperties = get(this, sortPropertiesKey);
|
|
1020
|
-
assert(`The sort definition for '${key}' on ${this} must be a function or an array of strings`,
|
|
724
|
+
assert(`The sort definition for '${key}' on ${this} must be a function or an array of strings`, function (arr) {
|
|
725
|
+
return isNativeOrEmberArray(arr) && arr.every(s => typeof s === 'string');
|
|
726
|
+
}(sortProperties));
|
|
1021
727
|
let itemsKeyIsAtThis = itemsKey === '@this';
|
|
1022
728
|
let normalizedSortProperties = normalizeSortProperties(sortProperties);
|
|
1023
729
|
let items = itemsKeyIsAtThis ? this : get(this, itemsKey);
|
|
1024
730
|
|
|
1025
|
-
if (!
|
|
731
|
+
if (!isNativeOrEmberArray(items)) {
|
|
1026
732
|
return emberA();
|
|
1027
733
|
}
|
|
1028
734
|
|
|
@@ -1036,17 +742,20 @@ function propertySort(itemsKey, sortPropertiesKey) {
|
|
|
1036
742
|
}
|
|
1037
743
|
|
|
1038
744
|
function normalizeSortProperties(sortProperties) {
|
|
1039
|
-
|
|
745
|
+
let callback = p => {
|
|
1040
746
|
let [prop, direction] = p.split(':');
|
|
1041
|
-
direction = direction || 'asc';
|
|
747
|
+
direction = direction || 'asc'; // SAFETY: There will always be at least one value returned by split
|
|
748
|
+
|
|
1042
749
|
return [prop, direction];
|
|
1043
|
-
}
|
|
750
|
+
}; // This nonsense is necessary since technically the two map implementations diverge.
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
return Array.isArray(sortProperties) ? sortProperties.map(callback) : sortProperties.map(callback);
|
|
1044
754
|
}
|
|
1045
755
|
|
|
1046
756
|
function sortByNormalizedSortProperties(items, normalizedSortProperties) {
|
|
1047
757
|
return emberA(items.slice().sort((itemA, itemB) => {
|
|
1048
|
-
for (let
|
|
1049
|
-
let [prop, direction] = normalizedSortProperties[i];
|
|
758
|
+
for (let [prop, direction] of normalizedSortProperties) {
|
|
1050
759
|
let result = compare(get(itemA, prop), get(itemB, prop));
|
|
1051
760
|
|
|
1052
761
|
if (result !== 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default "4.
|
|
1
|
+
export default "4.6.0-alpha.2";
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { Object as EmberObject } from '@ember/-internals/runtime';
|
|
2
|
-
|
|
3
|
-
function K() {
|
|
4
|
-
return this;
|
|
5
|
-
}
|
|
6
2
|
/**
|
|
7
3
|
@module @ember/test
|
|
8
4
|
*/
|
|
@@ -15,7 +11,6 @@ function K() {
|
|
|
15
11
|
@public
|
|
16
12
|
*/
|
|
17
13
|
|
|
18
|
-
|
|
19
14
|
export default EmberObject.extend({
|
|
20
15
|
/**
|
|
21
16
|
This callback will be called whenever an async operation is about to start.
|
|
@@ -24,14 +19,14 @@ export default EmberObject.extend({
|
|
|
24
19
|
@public
|
|
25
20
|
@method asyncStart
|
|
26
21
|
*/
|
|
27
|
-
asyncStart
|
|
22
|
+
asyncStart() {},
|
|
28
23
|
|
|
29
24
|
/**
|
|
30
25
|
This callback will be called whenever an async operation has completed.
|
|
31
26
|
@public
|
|
32
27
|
@method asyncEnd
|
|
33
28
|
*/
|
|
34
|
-
asyncEnd
|
|
29
|
+
asyncEnd() {},
|
|
35
30
|
|
|
36
31
|
/**
|
|
37
32
|
Override this method with your testing framework's false assertion.
|