ember-source
Version:
A JavaScript framework for creating ambitious web applications
120 lines (113 loc) • 4.28 kB
JavaScript
import '../@ember/debug/index.js';
import { peekMeta } from '../@ember/-internals/meta/lib/meta.js';
import { k as sendEvent, n as notifyPropertyChange, E as addListener, F as removeListener } from './cache-fCezwMOy.js';
import { isDevelopingApp } from '@embroider/macros';
import { assert } from '../@ember/debug/lib/assert.js';
function arrayContentWillChange(array, startIdx, removeAmt, addAmt) {
// if no args are passed assume everything changes
if (startIdx === undefined) {
startIdx = 0;
removeAmt = addAmt = -1;
} else {
if (removeAmt === undefined) {
removeAmt = -1;
}
if (addAmt === undefined) {
addAmt = -1;
}
}
sendEvent(array, '@array:before', [array, startIdx, removeAmt, addAmt]);
return array;
}
function arrayContentDidChange(array, startIdx, removeAmt, addAmt, notify = true) {
// if no args are passed assume everything changes
if (startIdx === undefined) {
startIdx = 0;
removeAmt = addAmt = -1;
} else {
if (removeAmt === undefined) {
removeAmt = -1;
}
if (addAmt === undefined) {
addAmt = -1;
}
}
let meta = peekMeta(array);
if (notify) {
if (addAmt < 0 || removeAmt < 0 || addAmt - removeAmt !== 0) {
notifyPropertyChange(array, 'length', meta);
}
notifyPropertyChange(array, '[]', meta);
}
sendEvent(array, '@array:change', [array, startIdx, removeAmt, addAmt]);
if (meta !== null) {
let length = array.length;
let addedAmount = addAmt === -1 ? 0 : addAmt;
let removedAmount = removeAmt === -1 ? 0 : removeAmt;
let delta = addedAmount - removedAmount;
let previousLength = length - delta;
let normalStartIdx = startIdx < 0 ? previousLength + startIdx : startIdx;
if (meta.revisionFor('firstObject') !== undefined && normalStartIdx === 0) {
notifyPropertyChange(array, 'firstObject', meta);
}
if (meta.revisionFor('lastObject') !== undefined) {
let previousLastIndex = previousLength - 1;
let lastAffectedIndex = normalStartIdx + removedAmount;
if (previousLastIndex < lastAffectedIndex) {
notifyPropertyChange(array, 'lastObject', meta);
}
}
}
return array;
}
const EMPTY_ARRAY = Object.freeze([]);
// Ideally, we'd use MutableArray.detect but for unknown reasons this causes
// the node tests to fail strangely.
function isMutableArray(obj) {
return obj != null && typeof obj.replace === 'function';
}
function replace(array, start, deleteCount, items = EMPTY_ARRAY) {
if (isMutableArray(array)) {
array.replace(start, deleteCount, items);
} else {
(isDevelopingApp() && !(Array.isArray(array)) && assert('Can only replace content of a native array or MutableArray', Array.isArray(array)));
replaceInNativeArray(array, start, deleteCount, items);
}
}
const CHUNK_SIZE = 60000;
// To avoid overflowing the stack, we splice up to CHUNK_SIZE items at a time.
// See https://code.google.com/p/chromium/issues/detail?id=56588 for more details.
function replaceInNativeArray(array, start, deleteCount, items) {
arrayContentWillChange(array, start, deleteCount, items.length);
if (items.length <= CHUNK_SIZE) {
array.splice(start, deleteCount, ...items);
} else {
array.splice(start, deleteCount);
for (let i = 0; i < items.length; i += CHUNK_SIZE) {
let chunk = items.slice(i, i + CHUNK_SIZE);
array.splice(start + i, 0, ...chunk);
}
}
arrayContentDidChange(array, start, deleteCount, items.length);
}
function arrayObserversHelper(obj, target, opts, operation) {
let {
willChange,
didChange
} = opts;
operation(obj, '@array:before', target, willChange);
operation(obj, '@array:change', target, didChange);
/*
* Array proxies have a `_revalidate` method which must be called to set
* up their internal array observation systems.
*/
obj._revalidate?.();
return obj;
}
function addArrayObserver(array, target, opts) {
return arrayObserversHelper(array, target, opts, addListener);
}
function removeArrayObserver(array, target, opts) {
return arrayObserversHelper(array, target, opts, removeListener);
}
export { replace as a, arrayContentWillChange as b, arrayContentDidChange as c, addArrayObserver as d, removeArrayObserver as e, replaceInNativeArray as r };