Add ability for NetLogLogger to gather data from more than just NetLog
[chromium-blink-merge.git] / ui / file_manager / gallery / js / entry_list_watcher.js
blobe4e1149d87ea01f0b4e14bf5cfb5a72445dc2445
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.
5 /**
6 * Watcher for entry lists.
7 * It watches entries and remove the item if the entry is removed from file
8 * system.
9 * @param {!cr.ui.ArrayDataModel} list
10 * @constructor
11 * @struct
13 function EntryListWatcher(list) {
14 /**
15 * Watched list.
16 * @type {!cr.ui.ArrayDataModel}
17 * @const
18 * @private
20 this.list_ = list;
22 /**
23 * Set of watched URL.
24 * Key is watched entry URL. Value is always true.
25 * @type {!Object.<string, boolean>}
26 * @private
28 this.watchers_ = {};
30 this.list_.addEventListener('splice', this.onSplice_.bind(this));
31 chrome.fileManagerPrivate.onDirectoryChanged.addListener(
32 this.onDirectoryChanged_.bind(this));
34 this.onSplice_(null);
37 /**
38 * Obtains entry from ArrayDataModel's item.
39 * @param {*} item Item in ArrayDataModel.
40 * @protected
41 * @return {!FileEntry}
43 EntryListWatcher.prototype.getEntry = function(item) {
44 return /** @type {!FileEntry} */ (item);
47 /**
48 * @param {Event} event
49 * @private
51 EntryListWatcher.prototype.onSplice_ = function(event) {
52 // Mark all existing watchers as candidates to be removed.
53 var diff = {};
54 for (var url in this.watchers_) {
55 diff[url] = -1;
58 // Obtains the set of new watcher.
59 this.watchers_ = {};
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) {
80 switch (diff[url]) {
81 case 1:
82 chrome.fileManagerPrivate.addFileWatch(url, reportError);
83 break;
84 case -1:
85 chrome.fileManagerPrivate.removeFileWatch(url, reportError);
86 break;
87 case 0:
88 break;
89 default:
90 assertNotReached();
91 break;
96 /**
97 * @param {!FileWatchEvent} event
98 * @private
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)
112 continue;
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(
116 function(url) {
117 removedEntryURL[url] = true;
118 }.bind(null, entry.toURL())));
120 Promise.all(promiseList).then(function() {
121 var i = 0;
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);
126 } else {
127 i++;
130 }.bind(this));