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<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 // TODO(mtomasz, hirono): Remove operations on URLs as they won't work after
53 // switching to isolated entries.
55 // Mark all existing watchers as candidates to be removed.
57 for (var url in this.watchers_) {
61 // Obtains the set of new watcher.
63 for (var i = 0; i < this.list_.length; i++) {
64 var entry = this.getEntry(this.list_.item(i));
65 var parentURL = entry.toURL().replace(/[^\/]+\/?$/, '');
66 this.watchers_[parentURL] = true;
69 // Mark new watchers to be added, and existing watchers to be kept.
70 for (var url in this.watchers_) {
71 diff[url] = (diff[url] || 0) + 1;
74 // Check the number in diff.
75 // -1: watcher exists in the old set, but does not exists in the new set.
76 // 0: watcher exists in both sets.
77 // 1: watcher does not exists in the old set, but exists in the new set.
78 var reportError = function() {
79 if (chrome.runtime.lastError)
80 console.error(chrome.runtime.lastError.name);
82 for (var url in diff) {
85 window.webkitResolveLocalFileSystemURL(url, function(entry) {
87 chrome.fileManagerPrivate.addFileWatch(entry, reportError);
91 window.webkitResolveLocalFileSystemURL(url, function(entry) {
93 chrome.fileManagerPrivate.removeFileWatch(entry, reportError);
106 * @param {!FileWatchEvent} event
109 EntryListWatcher.prototype.onDirectoryChanged_ = function(event) {
110 // Add '/' to the tail for checking if the each entry's URL is child URL of
111 // the URL or not by using entryURL.indexOf(thisUrl) === 0.
112 var url = event.entry.toURL().replace(/\/?$/, '/');
113 var promiseList = [];
114 var removedEntryURL = {};
115 for (var i = 0; i < this.list_.length; i++) {
116 var entry = this.getEntry(this.list_.item(i));
117 // Remove trailing '/' to prevent calling getMetadata in the case where the
118 // event.entry and the entry are same.
119 var entryURL = entry.toURL().replace(/\/$/, '');
120 if (entry.toURL().indexOf(url) !== 0)
122 // Look for non-existing files by using getMetadata.
123 // getMetadata returns NOT_FOUND error for non-existing files.
124 promiseList.push(new Promise(entry.getMetadata.bind(entry)).catch(
126 removedEntryURL[url] = true;
127 }.bind(null, entry.toURL())));
129 Promise.all(promiseList).then(function() {
131 while (i < this.list_.length) {
132 var url = this.getEntry(this.list_.item(i)).toURL();
133 if (removedEntryURL[url]) {
134 this.list_.splice(i, 1);