1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * Watcher for entry lists.
7 * It watches entries and remove the item if the entry is removed from file
9 * @param {!cr.ui.ArrayDataModel} list
13 function EntryListWatcher(list) {
16 * @type {!cr.ui.ArrayDataModel}
24 * Key is watched entry URL. Value is always true.
25 * @type {!Object.<string, boolean>}
30 this.list_.addEventListener('splice', this.onSplice_.bind(this));
31 chrome.fileManagerPrivate.onDirectoryChanged.addListener(
32 this.onDirectoryChanged_.bind(this));
38 * Obtains entry from ArrayDataModel's item.
39 * @param {*} item Item in ArrayDataModel.
41 * @return {!FileEntry}
43 EntryListWatcher.prototype.getEntry = function(item) {
44 return /** @type {!FileEntry} */ (item);
48 * @param {Event} event
51 EntryListWatcher.prototype.onSplice_ = function(event) {
52 // Mark all existing watchers as candidates to be removed.
54 for (var url in this.watchers_) {
58 // Obtains the set of new watcher.
60 for (var i = 0; i < this.list_.length; i++) {
61 var entry = this.getEntry(this.list_.item(i));
62 var parentURL = entry.toURL().replace(/[^\/]+\/?$/, '');
63 this.watchers_[parentURL] = true;
66 // Mark new watchers to be added, and existing watchers to be kept.
67 for (var url in this.watchers_) {
68 diff[url] = (diff[url] || 0) + 1;
71 // Check the number in diff.
72 // -1: watcher exists in the old set, but does not exists in the new set.
73 // 0: watcher exists in both sets.
74 // 1: watcher does not exists in the old set, but exists in the new set.
75 var reportError = function() {
76 if (chrome.runtime.lastError)
77 console.error(chrome.runtime.lastError);
79 for (var url in diff) {
82 chrome.fileManagerPrivate.addFileWatch(url, reportError);
85 chrome.fileManagerPrivate.removeFileWatch(url, reportError);
97 * @param {!FileWatchEvent} event
100 EntryListWatcher.prototype.onDirectoryChanged_ = function(event) {
101 // Add '/' to the tail for checking if the each entry's URL is child URL of
102 // the URL or not by using entryURL.indexOf(thisUrl) === 0.
103 var url = event.entry.toURL().replace(/\/?$/, '/');
104 var promiseList = [];
105 var removedEntryURL = {};
106 for (var i = 0; i < this.list_.length; i++) {
107 var entry = this.getEntry(this.list_.item(i));
108 // Remove trailing '/' to prevent calling getMetadata in the case where the
109 // event.entry and the entry are same.
110 var entryURL = entry.toURL().replace(/\/$/, '');
111 if (entry.toURL().indexOf(url) !== 0)
113 // Look for non-existing files by using getMetadata.
114 // getMetadata returns NOT_FOUND error for non-existing files.
115 promiseList.push(new Promise(entry.getMetadata.bind(entry)).catch(
117 removedEntryURL[url] = true;
118 }.bind(null, entry.toURL())));
120 Promise.all(promiseList).then(function() {
122 while (i < this.list_.length) {
123 var url = this.getEntry(this.list_.item(i)).toURL();
124 if (removedEntryURL[url]) {
125 this.list_.splice(i, 1);