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);