summaryrefslogtreecommitdiff
path: root/chromium/ui/webui/resources/js/list_property_update_behavior.js
blob: 260f57c4b785b5733bbbd573e159d7ec00ee11bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview |ListPropertyUpdateBehavior| is used to update an existing
 * polymer list property given the list after all the edits were made while
 * maintaining the reference to the original list. This allows
 * dom-repeat/iron-list elements bound to this list property to not fully
 * re-rendered from scratch.
 *
 * The minimal splices needed to transform the original list to the edited list
 * are calculated using |Polymer.ArraySplice.calculateSplices|. All the edits
 * are then applied to the original list. Once completed, a single notification
 * containing information about all the edits is sent to the polyer object.
 */

/** @polymerBehavior */
const ListPropertyUpdateBehavior = {
  /**
   * @param {string} propertyName
   * @param {function(!Object): string} itemUidGetter
   * @param {!Array<!Object>} updatedList
   */
  updateList: function(propertyName, itemUidGetter, updatedList) {
    const list = this[propertyName];
    const splices = Polymer.ArraySplice.calculateSplices(
        updatedList.map(itemUidGetter), list.map(itemUidGetter));
    splices.forEach(splice => {
      const index = splice.index;
      const deleteCount = splice.removed.length;
      // Transform splices to the expected format of notifySplices().
      // Convert !Array<string> to !Array<!Object>.
      splice.removed = list.slice(index, index + deleteCount);
      splice.object = list;
      splice.type = 'splice';

      const added = updatedList.slice(index, index + splice.addedCount);
      const spliceParams = [index, deleteCount].concat(added);
      list.splice.apply(list, spliceParams);
    });
    if (splices.length > 0) {
      this.notifySplices(propertyName, splices);
    }
  },
};