@angular/core
Version:
Angular - the core framework
1,068 lines • 88.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { looseIdentical } from '../../util/comparison';
import { stringify } from '../../util/stringify';
import { isListLikeIterable, iterateListLike } from '../change_detection_util';
export class DefaultIterableDifferFactory {
constructor() { }
/**
* @param {?} obj
* @return {?}
*/
supports(obj) { return isListLikeIterable(obj); }
/**
* @template V
* @param {?=} trackByFn
* @return {?}
*/
create(trackByFn) {
return new DefaultIterableDiffer(trackByFn);
}
}
/** @type {?} */
const trackByIdentity = (/**
* @param {?} index
* @param {?} item
* @return {?}
*/
(index, item) => item);
const ɵ0 = trackByIdentity;
/**
* @deprecated v4.0.0 - Should not be part of public API.
* \@publicApi
* @template V
*/
export class DefaultIterableDiffer {
/**
* @param {?=} trackByFn
*/
constructor(trackByFn) {
this.length = 0;
// Keeps track of the used records at any point in time (during & across `_check()` calls)
this._linkedRecords = null;
// Keeps track of the removed records at any point in time during `_check()` calls.
this._unlinkedRecords = null;
this._previousItHead = null;
this._itHead = null;
this._itTail = null;
this._additionsHead = null;
this._additionsTail = null;
this._movesHead = null;
this._movesTail = null;
this._removalsHead = null;
this._removalsTail = null;
// Keeps track of records where custom track by is the same, but item identity has changed
this._identityChangesHead = null;
this._identityChangesTail = null;
this._trackByFn = trackByFn || trackByIdentity;
}
/**
* @param {?} fn
* @return {?}
*/
forEachItem(fn) {
/** @type {?} */
let record;
for (record = this._itHead; record !== null; record = record._next) {
fn(record);
}
}
/**
* @param {?} fn
* @return {?}
*/
forEachOperation(fn) {
/** @type {?} */
let nextIt = this._itHead;
/** @type {?} */
let nextRemove = this._removalsHead;
/** @type {?} */
let addRemoveOffset = 0;
/** @type {?} */
let moveOffsets = null;
while (nextIt || nextRemove) {
// Figure out which is the next record to process
// Order: remove, add, move
/** @type {?} */
const record = !nextRemove ||
nextIt &&
(/** @type {?} */ (nextIt.currentIndex)) <
getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ?
(/** @type {?} */ (nextIt)) :
nextRemove;
/** @type {?} */
const adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
/** @type {?} */
const currentIndex = record.currentIndex;
// consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
if (record === nextRemove) {
addRemoveOffset--;
nextRemove = nextRemove._nextRemoved;
}
else {
nextIt = (/** @type {?} */ (nextIt))._next;
if (record.previousIndex == null) {
addRemoveOffset++;
}
else {
// INVARIANT: currentIndex < previousIndex
if (!moveOffsets)
moveOffsets = [];
/** @type {?} */
const localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
/** @type {?} */
const localCurrentIndex = (/** @type {?} */ (currentIndex)) - addRemoveOffset;
if (localMovePreviousIndex != localCurrentIndex) {
for (let i = 0; i < localMovePreviousIndex; i++) {
/** @type {?} */
const offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0);
/** @type {?} */
const index = offset + i;
if (localCurrentIndex <= index && index < localMovePreviousIndex) {
moveOffsets[i] = offset + 1;
}
}
/** @type {?} */
const previousIndex = record.previousIndex;
moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
}
}
}
if (adjPreviousIndex !== currentIndex) {
fn(record, adjPreviousIndex, currentIndex);
}
}
}
/**
* @param {?} fn
* @return {?}
*/
forEachPreviousItem(fn) {
/** @type {?} */
let record;
for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
fn(record);
}
}
/**
* @param {?} fn
* @return {?}
*/
forEachAddedItem(fn) {
/** @type {?} */
let record;
for (record = this._additionsHead; record !== null; record = record._nextAdded) {
fn(record);
}
}
/**
* @param {?} fn
* @return {?}
*/
forEachMovedItem(fn) {
/** @type {?} */
let record;
for (record = this._movesHead; record !== null; record = record._nextMoved) {
fn(record);
}
}
/**
* @param {?} fn
* @return {?}
*/
forEachRemovedItem(fn) {
/** @type {?} */
let record;
for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
fn(record);
}
}
/**
* @param {?} fn
* @return {?}
*/
forEachIdentityChange(fn) {
/** @type {?} */
let record;
for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
fn(record);
}
}
/**
* @param {?} collection
* @return {?}
*/
diff(collection) {
if (collection == null)
collection = [];
if (!isListLikeIterable(collection)) {
throw new Error(`Error trying to diff '${stringify(collection)}'. Only arrays and iterables are allowed`);
}
if (this.check(collection)) {
return this;
}
else {
return null;
}
}
/**
* @return {?}
*/
onDestroy() { }
/**
* @param {?} collection
* @return {?}
*/
check(collection) {
this._reset();
/** @type {?} */
let record = this._itHead;
/** @type {?} */
let mayBeDirty = false;
/** @type {?} */
let index;
/** @type {?} */
let item;
/** @type {?} */
let itemTrackBy;
if (Array.isArray(collection)) {
((/** @type {?} */ (this))).length = collection.length;
for (let index = 0; index < this.length; index++) {
item = collection[index];
itemTrackBy = this._trackByFn(index, item);
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
record = this._mismatch(record, item, itemTrackBy, index);
mayBeDirty = true;
}
else {
if (mayBeDirty) {
// TODO(misko): can we limit this to duplicates only?
record = this._verifyReinsertion(record, item, itemTrackBy, index);
}
if (!looseIdentical(record.item, item))
this._addIdentityChange(record, item);
}
record = record._next;
}
}
else {
index = 0;
iterateListLike(collection, (/**
* @param {?} item
* @return {?}
*/
(item) => {
itemTrackBy = this._trackByFn(index, item);
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
record = this._mismatch(record, item, itemTrackBy, index);
mayBeDirty = true;
}
else {
if (mayBeDirty) {
// TODO(misko): can we limit this to duplicates only?
record = this._verifyReinsertion(record, item, itemTrackBy, index);
}
if (!looseIdentical(record.item, item))
this._addIdentityChange(record, item);
}
record = record._next;
index++;
}));
((/** @type {?} */ (this))).length = index;
}
this._truncate(record);
((/** @type {?} */ (this))).collection = collection;
return this.isDirty;
}
/* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity
* changes.
*/
/**
* @return {?}
*/
get isDirty() {
return this._additionsHead !== null || this._movesHead !== null ||
this._removalsHead !== null || this._identityChangesHead !== null;
}
/**
* Reset the state of the change objects to show no changes. This means set previousKey to
* currentKey, and clear all of the queues (additions, moves, removals).
* Set the previousIndexes of moved and added items to their currentIndexes
* Reset the list of additions, moves and removals
*
* \@internal
* @return {?}
*/
_reset() {
if (this.isDirty) {
/** @type {?} */
let record;
/** @type {?} */
let nextRecord;
for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
record._nextPrevious = record._next;
}
for (record = this._additionsHead; record !== null; record = record._nextAdded) {
record.previousIndex = record.currentIndex;
}
this._additionsHead = this._additionsTail = null;
for (record = this._movesHead; record !== null; record = nextRecord) {
record.previousIndex = record.currentIndex;
nextRecord = record._nextMoved;
}
this._movesHead = this._movesTail = null;
this._removalsHead = this._removalsTail = null;
this._identityChangesHead = this._identityChangesTail = null;
// TODO(vicb): when assert gets supported
// assert(!this.isDirty);
}
}
/**
* This is the core function which handles differences between collections.
*
* - `record` is the record which we saw at this position last time. If null then it is a new
* item.
* - `item` is the current item in the collection
* - `index` is the position of the item in the collection
*
* \@internal
* @param {?} record
* @param {?} item
* @param {?} itemTrackBy
* @param {?} index
* @return {?}
*/
_mismatch(record, item, itemTrackBy, index) {
// The previous record after which we will append the current one.
/** @type {?} */
let previousRecord;
if (record === null) {
previousRecord = this._itTail;
}
else {
previousRecord = record._prev;
// Remove the record from the collection since we know it does not match the item.
this._remove(record);
}
// Attempt to see if we have seen the item before.
record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
if (record !== null) {
// We have seen this before, we need to move it forward in the collection.
// But first we need to check if identity changed, so we can update in view if necessary
if (!looseIdentical(record.item, item))
this._addIdentityChange(record, item);
this._moveAfter(record, previousRecord, index);
}
else {
// Never seen it, check evicted list.
record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
if (record !== null) {
// It is an item which we have evicted earlier: reinsert it back into the list.
// But first we need to check if identity changed, so we can update in view if necessary
if (!looseIdentical(record.item, item))
this._addIdentityChange(record, item);
this._reinsertAfter(record, previousRecord, index);
}
else {
// It is a new item: add it.
record =
this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
}
}
return record;
}
/**
* This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
*
* Use case: `[a, a]` => `[b, a, a]`
*
* If we did not have this check then the insertion of `b` would:
* 1) evict first `a`
* 2) insert `b` at `0` index.
* 3) leave `a` at index `1` as is. <-- this is wrong!
* 3) reinsert `a` at index 2. <-- this is wrong!
*
* The correct behavior is:
* 1) evict first `a`
* 2) insert `b` at `0` index.
* 3) reinsert `a` at index 1.
* 3) move `a` at from `1` to `2`.
*
*
* Double check that we have not evicted a duplicate item. We need to check if the item type may
* have already been removed:
* The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
* at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
* better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
* at the end.
*
* \@internal
* @param {?} record
* @param {?} item
* @param {?} itemTrackBy
* @param {?} index
* @return {?}
*/
_verifyReinsertion(record, item, itemTrackBy, index) {
/** @type {?} */
let reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
if (reinsertRecord !== null) {
record = this._reinsertAfter(reinsertRecord, (/** @type {?} */ (record._prev)), index);
}
else if (record.currentIndex != index) {
record.currentIndex = index;
this._addToMoves(record, index);
}
return record;
}
/**
* Get rid of any excess {\@link IterableChangeRecord_}s from the previous collection
*
* - `record` The first excess {\@link IterableChangeRecord_}.
*
* \@internal
* @param {?} record
* @return {?}
*/
_truncate(record) {
// Anything after that needs to be removed;
while (record !== null) {
/** @type {?} */
const nextRecord = record._next;
this._addToRemovals(this._unlink(record));
record = nextRecord;
}
if (this._unlinkedRecords !== null) {
this._unlinkedRecords.clear();
}
if (this._additionsTail !== null) {
this._additionsTail._nextAdded = null;
}
if (this._movesTail !== null) {
this._movesTail._nextMoved = null;
}
if (this._itTail !== null) {
this._itTail._next = null;
}
if (this._removalsTail !== null) {
this._removalsTail._nextRemoved = null;
}
if (this._identityChangesTail !== null) {
this._identityChangesTail._nextIdentityChange = null;
}
}
/**
* \@internal
* @param {?} record
* @param {?} prevRecord
* @param {?} index
* @return {?}
*/
_reinsertAfter(record, prevRecord, index) {
if (this._unlinkedRecords !== null) {
this._unlinkedRecords.remove(record);
}
/** @type {?} */
const prev = record._prevRemoved;
/** @type {?} */
const next = record._nextRemoved;
if (prev === null) {
this._removalsHead = next;
}
else {
prev._nextRemoved = next;
}
if (next === null) {
this._removalsTail = prev;
}
else {
next._prevRemoved = prev;
}
this._insertAfter(record, prevRecord, index);
this._addToMoves(record, index);
return record;
}
/**
* \@internal
* @param {?} record
* @param {?} prevRecord
* @param {?} index
* @return {?}
*/
_moveAfter(record, prevRecord, index) {
this._unlink(record);
this._insertAfter(record, prevRecord, index);
this._addToMoves(record, index);
return record;
}
/**
* \@internal
* @param {?} record
* @param {?} prevRecord
* @param {?} index
* @return {?}
*/
_addAfter(record, prevRecord, index) {
this._insertAfter(record, prevRecord, index);
if (this._additionsTail === null) {
// TODO(vicb):
// assert(this._additionsHead === null);
this._additionsTail = this._additionsHead = record;
}
else {
// TODO(vicb):
// assert(_additionsTail._nextAdded === null);
// assert(record._nextAdded === null);
this._additionsTail = this._additionsTail._nextAdded = record;
}
return record;
}
/**
* \@internal
* @param {?} record
* @param {?} prevRecord
* @param {?} index
* @return {?}
*/
_insertAfter(record, prevRecord, index) {
// TODO(vicb):
// assert(record != prevRecord);
// assert(record._next === null);
// assert(record._prev === null);
// TODO(vicb):
// assert(record != prevRecord);
// assert(record._next === null);
// assert(record._prev === null);
/** @type {?} */
const next = prevRecord === null ? this._itHead : prevRecord._next;
// TODO(vicb):
// assert(next != record);
// assert(prevRecord != record);
record._next = next;
record._prev = prevRecord;
if (next === null) {
this._itTail = record;
}
else {
next._prev = record;
}
if (prevRecord === null) {
this._itHead = record;
}
else {
prevRecord._next = record;
}
if (this._linkedRecords === null) {
this._linkedRecords = new _DuplicateMap();
}
this._linkedRecords.put(record);
record.currentIndex = index;
return record;
}
/**
* \@internal
* @param {?} record
* @return {?}
*/
_remove(record) {
return this._addToRemovals(this._unlink(record));
}
/**
* \@internal
* @param {?} record
* @return {?}
*/
_unlink(record) {
if (this._linkedRecords !== null) {
this._linkedRecords.remove(record);
}
/** @type {?} */
const prev = record._prev;
/** @type {?} */
const next = record._next;
// TODO(vicb):
// assert((record._prev = null) === null);
// assert((record._next = null) === null);
if (prev === null) {
this._itHead = next;
}
else {
prev._next = next;
}
if (next === null) {
this._itTail = prev;
}
else {
next._prev = prev;
}
return record;
}
/**
* \@internal
* @param {?} record
* @param {?} toIndex
* @return {?}
*/
_addToMoves(record, toIndex) {
// TODO(vicb):
// assert(record._nextMoved === null);
if (record.previousIndex === toIndex) {
return record;
}
if (this._movesTail === null) {
// TODO(vicb):
// assert(_movesHead === null);
this._movesTail = this._movesHead = record;
}
else {
// TODO(vicb):
// assert(_movesTail._nextMoved === null);
this._movesTail = this._movesTail._nextMoved = record;
}
return record;
}
/**
* @private
* @param {?} record
* @return {?}
*/
_addToRemovals(record) {
if (this._unlinkedRecords === null) {
this._unlinkedRecords = new _DuplicateMap();
}
this._unlinkedRecords.put(record);
record.currentIndex = null;
record._nextRemoved = null;
if (this._removalsTail === null) {
// TODO(vicb):
// assert(_removalsHead === null);
this._removalsTail = this._removalsHead = record;
record._prevRemoved = null;
}
else {
// TODO(vicb):
// assert(_removalsTail._nextRemoved === null);
// assert(record._nextRemoved === null);
record._prevRemoved = this._removalsTail;
this._removalsTail = this._removalsTail._nextRemoved = record;
}
return record;
}
/**
* \@internal
* @param {?} record
* @param {?} item
* @return {?}
*/
_addIdentityChange(record, item) {
record.item = item;
if (this._identityChangesTail === null) {
this._identityChangesTail = this._identityChangesHead = record;
}
else {
this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
}
return record;
}
}
if (false) {
/** @type {?} */
DefaultIterableDiffer.prototype.length;
/** @type {?} */
DefaultIterableDiffer.prototype.collection;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._linkedRecords;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._unlinkedRecords;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._previousItHead;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._itHead;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._itTail;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._additionsHead;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._additionsTail;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._movesHead;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._movesTail;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._removalsHead;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._removalsTail;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._identityChangesHead;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._identityChangesTail;
/**
* @type {?}
* @private
*/
DefaultIterableDiffer.prototype._trackByFn;
}
/**
* @template V
*/
export class IterableChangeRecord_ {
/**
* @param {?} item
* @param {?} trackById
*/
constructor(item, trackById) {
this.item = item;
this.trackById = trackById;
this.currentIndex = null;
this.previousIndex = null;
/**
* \@internal
*/
this._nextPrevious = null;
/**
* \@internal
*/
this._prev = null;
/**
* \@internal
*/
this._next = null;
/**
* \@internal
*/
this._prevDup = null;
/**
* \@internal
*/
this._nextDup = null;
/**
* \@internal
*/
this._prevRemoved = null;
/**
* \@internal
*/
this._nextRemoved = null;
/**
* \@internal
*/
this._nextAdded = null;
/**
* \@internal
*/
this._nextMoved = null;
/**
* \@internal
*/
this._nextIdentityChange = null;
}
}
if (false) {
/** @type {?} */
IterableChangeRecord_.prototype.currentIndex;
/** @type {?} */
IterableChangeRecord_.prototype.previousIndex;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._nextPrevious;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._prev;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._next;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._prevDup;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._nextDup;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._prevRemoved;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._nextRemoved;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._nextAdded;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._nextMoved;
/**
* \@internal
* @type {?}
*/
IterableChangeRecord_.prototype._nextIdentityChange;
/** @type {?} */
IterableChangeRecord_.prototype.item;
/** @type {?} */
IterableChangeRecord_.prototype.trackById;
}
// A linked list of CollectionChangeRecords with the same IterableChangeRecord_.item
/**
* @template V
*/
class _DuplicateItemRecordList {
constructor() {
/**
* \@internal
*/
this._head = null;
/**
* \@internal
*/
this._tail = null;
}
/**
* Append the record to the list of duplicates.
*
* Note: by design all records in the list of duplicates hold the same value in record.item.
* @param {?} record
* @return {?}
*/
add(record) {
if (this._head === null) {
this._head = this._tail = record;
record._nextDup = null;
record._prevDup = null;
}
else {
// TODO(vicb):
// assert(record.item == _head.item ||
// record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
(/** @type {?} */ (this._tail))._nextDup = record;
record._prevDup = this._tail;
record._nextDup = null;
this._tail = record;
}
}
// Returns a IterableChangeRecord_ having IterableChangeRecord_.trackById == trackById and
// IterableChangeRecord_.currentIndex >= atOrAfterIndex
/**
* @param {?} trackById
* @param {?} atOrAfterIndex
* @return {?}
*/
get(trackById, atOrAfterIndex) {
/** @type {?} */
let record;
for (record = this._head; record !== null; record = record._nextDup) {
if ((atOrAfterIndex === null || atOrAfterIndex <= (/** @type {?} */ (record.currentIndex))) &&
looseIdentical(record.trackById, trackById)) {
return record;
}
}
return null;
}
/**
* Remove one {\@link IterableChangeRecord_} from the list of duplicates.
*
* Returns whether the list of duplicates is empty.
* @param {?} record
* @return {?}
*/
remove(record) {
// TODO(vicb):
// assert(() {
// // verify that the record being removed is in the list.
// for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
// if (identical(cursor, record)) return true;
// }
// return false;
//});
// TODO(vicb):
// assert(() {
// // verify that the record being removed is in the list.
// for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
// if (identical(cursor, record)) return true;
// }
// return false;
//});
/** @type {?} */
const prev = record._prevDup;
/** @type {?} */
const next = record._nextDup;
if (prev === null) {
this._head = next;
}
else {
prev._nextDup = next;
}
if (next === null) {
this._tail = prev;
}
else {
next._prevDup = prev;
}
return this._head === null;
}
}
if (false) {
/**
* \@internal
* @type {?}
*/
_DuplicateItemRecordList.prototype._head;
/**
* \@internal
* @type {?}
*/
_DuplicateItemRecordList.prototype._tail;
}
/**
* @template V
*/
class _DuplicateMap {
constructor() {
this.map = new Map();
}
/**
* @param {?} record
* @return {?}
*/
put(record) {
/** @type {?} */
const key = record.trackById;
/** @type {?} */
let duplicates = this.map.get(key);
if (!duplicates) {
duplicates = new _DuplicateItemRecordList();
this.map.set(key, duplicates);
}
duplicates.add(record);
}
/**
* Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
* have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
*
* Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
* have any more `a`s needs to return the second `a`.
* @param {?} trackById
* @param {?} atOrAfterIndex
* @return {?}
*/
get(trackById, atOrAfterIndex) {
/** @type {?} */
const key = trackById;
/** @type {?} */
const recordList = this.map.get(key);
return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
}
/**
* Removes a {\@link IterableChangeRecord_} from the list of duplicates.
*
* The list of duplicates also is removed from the map if it gets empty.
* @param {?} record
* @return {?}
*/
remove(record) {
/** @type {?} */
const key = record.trackById;
/** @type {?} */
const recordList = (/** @type {?} */ (this.map.get(key)));
// Remove the list of duplicates when it gets empty
if (recordList.remove(record)) {
this.map.delete(key);
}
return record;
}
/**
* @return {?}
*/
get isEmpty() { return this.map.size === 0; }
/**
* @return {?}
*/
clear() { this.map.clear(); }
}
if (false) {
/** @type {?} */
_DuplicateMap.prototype.map;
}
/**
* @param {?} item
* @param {?} addRemoveOffset
* @param {?} moveOffsets
* @return {?}
*/
function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
/** @type {?} */
const previousIndex = item.previousIndex;
if (previousIndex === null)
return previousIndex;
/** @type {?} */
let moveOffset = 0;
if (moveOffsets && previousIndex < moveOffsets.length) {
moveOffset = moveOffsets[previousIndex];
}
return previousIndex + addRemoveOffset + moveOffset;
}
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdF9pdGVyYWJsZV9kaWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9jaGFuZ2VfZGV0ZWN0aW9uL2RpZmZlcnMvZGVmYXVsdF9pdGVyYWJsZV9kaWZmZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFRQSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxrQkFBa0IsRUFBRSxlQUFlLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUs3RSxNQUFNLE9BQU8sNEJBQTRCO0lBQ3ZDLGdCQUFlLENBQUM7Ozs7O0lBQ2hCLFFBQVEsQ0FBQyxHQUEwQixJQUFhLE9BQU8sa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOzs7Ozs7SUFFakYsTUFBTSxDQUFJLFNBQThCO1FBQ3RDLE9BQU8sSUFBSSxxQkFBcUIsQ0FBSSxTQUFTLENBQUMsQ0FBQztJQUNqRCxDQUFDO0NBQ0Y7O01BRUssZUFBZTs7Ozs7QUFBRyxDQUFDLEtBQWEsRUFBRSxJQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQTs7Ozs7OztBQU0xRCxNQUFNLE9BQU8scUJBQXFCOzs7O0lBc0JoQyxZQUFZLFNBQThCO1FBckIxQixXQUFNLEdBQVcsQ0FBQyxDQUFDOztRQUkzQixtQkFBYyxHQUEwQixJQUFJLENBQUM7O1FBRTdDLHFCQUFnQixHQUEwQixJQUFJLENBQUM7UUFDL0Msb0JBQWUsR0FBa0MsSUFBSSxDQUFDO1FBQ3RELFlBQU8sR0FBa0MsSUFBSSxDQUFDO1FBQzlDLFlBQU8sR0FBa0MsSUFBSSxDQUFDO1FBQzlDLG1CQUFjLEdBQWtDLElBQUksQ0FBQztRQUNyRCxtQkFBYyxHQUFrQyxJQUFJLENBQUM7UUFDckQsZUFBVSxHQUFr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