1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file. 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch/** 62385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * Model for the folder shortcuts. This object is cr.ui.ArrayDataModel-like 72385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * object with additional methods for the folder shortcut feature. 82385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * This uses chrome.storage as backend. Items are always sorted by file path. 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @constructor 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @extends {cr.EventTarget} 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochfunction FolderShortcutsDataModel() { 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.array_ = []; 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /** 17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * Eliminate unsupported folders from the list. 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @param {Array.<string>} array Folder array which may contain the 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * unsupported folders. 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @return {Array.<string>} Folder list without unsupported folder. 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) */ 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) var filter = function(array) { 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return array.filter(PathUtil.isEligibleForFolderShortcut); 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Loads the contents from the storage to initialize the array. 282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch chrome.storage.sync.get(FolderShortcutsDataModel.NAME, function(value) { 292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!(FolderShortcutsDataModel.NAME in value)) 30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Since the value comes from outer resource, we have to check it just in 33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // case. 342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var list = value[FolderShortcutsDataModel.NAME]; 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (list instanceof Array) { 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) list = filter(list); 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var permutation = this.calculatePermitation_(this.array_, list); 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.array_ = list; 402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.firePermutedEvent_(permutation); 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }.bind(this)); 43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Listening for changes in the storage. 45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch chrome.storage.onChanged.addListener(function(changes, namespace) { 462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!(FolderShortcutsDataModel.NAME in changes) || namespace != 'sync') 47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var list = changes[FolderShortcutsDataModel.NAME].newValue; 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Since the value comes from outer resource, we have to check it just in 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // case. 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (list instanceof Array) { 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) list = filter(list); 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // If the list is not changed, do nothing and just return. 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (this.array_.length == list.length) { 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch var changed = false; 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for (var i = 0; i < this.array_.length; i++) { 594311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Same item check: must be exact match. 60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (this.array_[i] != list[i]) { 61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch changed = true; 62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch break; 63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!changed) 66558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return; 67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var permutation = this.calculatePermitation_(this.array_, list); 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.array_ = list; 712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.firePermutedEvent_(permutation); 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }.bind(this)); 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch/** 772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * Key name in chrome.storage. The array are stored with this name. 782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * @type {string} 792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * @const 802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch */ 812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochFolderShortcutsDataModel.NAME = 'folder-shortcuts-list'; 822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochFolderShortcutsDataModel.prototype = { 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch __proto__: cr.EventTarget.prototype, 85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @return {number} Number of elements in the array. 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch get length() { 90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return this.array_.length; 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @param {number} index Index of the element to be retrieved. 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @return {string} The value of the |index|-th element. 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch item: function(index) { 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return this.array_[index]; 99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @param {string} value Value of the element to be retrieved. 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @return {number} Index of the element with the specified |value|. 104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch getIndex: function(value) { 106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (var i = 0; i < this.length; i++) { 1074311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Same item check: must be exact match. 1084311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (this.array_[i] == value) { 109ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return i; 110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 112ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return -1; 113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 114ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 115ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 1164311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch * Compares 2 strings and returns a number indicating one string comes before 1174311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch * or after or is the same as the other string in sort order. 1184311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch * 1194311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch * @param {string} a String1. 1204311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch * @param {string} b String2. 1214311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch * @return {boolean} Return -1, if String1 < String2. Return 0, if String1 == 1224311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch * String2. Otherwise, return 1. 1234311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch */ 1244311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch compare: function(a, b) { 1254311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch return a.localeCompare(b, 1264311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch undefined, // locale parameter, use default locale. 1274311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch {usage: 'sort', numeric: true}); 1284311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch }, 1294311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 1304311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch /** 1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * Adds the given item to the array. If there were already same item in the 1322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * list, return the index of the existing item without adding a duplicate 1332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * item. 1342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @param {string} value Value to be added into the array. 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @return {number} Index in the list which the element added to. 137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch add: function(value) { 1392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var oldArray = this.array_.slice(0); // Shallow copy. 1402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var addedIndex = -1; 1412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch for (var i = 0; i < this.length; i++) { 1424311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Same item check: must be exact match. 1434311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (this.array_[i] == value) 144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return i; 1454311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 1464311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Since the array is sorted, new item will be added just before the first 1474311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // larger item. 1484311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (this.compare(this.array_[i], value) >= 0) { 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.array_.splice(i, 0, value); 1502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch addedIndex = i; 151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // If value is not added yet, add it at the last. 1552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (addedIndex == -1) { 156ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.array_.push(value); 1572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch addedIndex = this.length; 1582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 1592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.firePermutedEvent_( 1612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.calculatePermitation_(oldArray, this.array_)); 162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.save_(); 1632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return addedIndex; 164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * Removes the given item from the array. 168ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @param {string} value Value to be removed from the array. 169ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @return {number} Index in the list which the element removed from. 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch remove: function(value) { 1722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var removedIndex = -1; 1732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var oldArray = this.array_.slice(0); // Shallow copy. 1742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch for (var i = 0; i < this.length; i++) { 1754311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Same item check: must be exact match. 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (this.array_[i] == value) { 177ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.array_.splice(i, 1); 1782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch removedIndex = i; 179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 180ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 1822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (removedIndex != -1) { 1842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.firePermutedEvent_( 1852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.calculatePermitation_(oldArray, this.array_)); 1862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.save_(); 1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return removedIndex; 1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 1892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // No item is removed. 1912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return -1; 1922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch }, 1932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch /** 1952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * @param {string} path Path to be checked. 1962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * @return {boolean} True if the given |path| exists in the array. False 1972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * otherwise. 1982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch */ 1992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch exists: function(path) { 2002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var index = this.getIndex(path); 2012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return (index >= 0); 202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * Saves the current array to chrome.storage. 206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @private 207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch save_: function() { 209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch var obj = {}; 2102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch obj[FolderShortcutsDataModel.NAME] = this.array_; 2112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch chrome.storage.sync.set(obj, function() {}); 212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 2152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * Creates a permutation array for 'permuted' event, which is compatible with 216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * a parmutation array used in cr/ui/array_data_model.js. 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * 218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @param {array} oldArray Previous array before changing. 219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @param {array} newArray New array after changing. 220ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @return {Array.<number>} Created permutation array. 221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * @private 222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 2232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch calculatePermitation_: function(oldArray, newArray) { 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch var oldIndex = 0; // Index of oldArray. 225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch var newIndex = 0; // Index of newArray. 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Note that both new and old arrays are sorted. 228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch var permutation = []; 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (; oldIndex < oldArray.length; oldIndex++) { 230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (newIndex >= newArray.length) { 231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // oldArray[oldIndex] is deleted, which is not in the new array. 232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch permutation[oldIndex] = -1; 233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch continue; 234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch while (newIndex < newArray.length) { 2374311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Unchanged item, which exists in both new and old array. But the 2384311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // index may be changed. 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (oldArray[oldIndex] == newArray[newIndex]) { 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch permutation[oldIndex] = newIndex; 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch newIndex++; 242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 2434311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch } 2444311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 2454311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // oldArray[oldIndex] is deleted, which is not in the new array. 2464311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (this.compare(oldArray[oldIndex], newArray[newIndex]) < 0) { 247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch permutation[oldIndex] = -1; 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 2504311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 2514311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // In the case of this.compare(oldArray[oldIndex]) > 0: 2524311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // newArray[newIndex] is added, which is not in the old array. 2534311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch newIndex++; 254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return permutation; 257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /** 2602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * Fires a 'permuted' event, which is compatible with cr.ui.ArrayDataModel. 2612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch * @param {Array.<number>} Permutation array. 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */ 2632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch firePermutedEvent_: function(permutation) { 264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch var permutedEvent = new Event('permuted'); 265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch permutedEvent.newLength = this.length; 266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch permutedEvent.permutation = permutation; 267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this.dispatchEvent(permutedEvent); 268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Note: This model only fires 'permuted' event, because: 270558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 1) 'change' event is not necessary to fire since it is covered by 271558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 'permuted' event. 2722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // 2) 'splice' and 'sorted' events are not implemented. These events are 2733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // not used in NavigationListModel. We have to implement them when 2743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // necessary. 275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}; 277