Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / resources / md_downloads / item.js
blob706436de77ccc5b7b9d1a7eebe00000f6e7bacca
1 // Copyright 2015 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 cr.define('downloads', function() {
6   var Item = Polymer({
7     is: 'downloads-item',
9     /**
10      * @param {!downloads.ThrottledIconLoader} iconLoader
11      * @param {!downloads.ActionService} actionService
12      */
13     factoryImpl: function(iconLoader, actionService) {
14       /** @private {!downloads.ThrottledIconLoader} */
15       this.iconLoader_ = iconLoader;
17       /** @private {!downloads.ActionService} */
18       this.actionService_ = actionService;
19     },
21     properties: {
22       hideDate: {
23         reflectToAttribute: true,
24         type: Boolean,
25         value: true,
26       },
28       readyPromise: {
29         type: Object,
30         value: function() {
31           return new Promise(function(resolve, reject) {
32             this.resolveReadyPromise_ = resolve;
33           }.bind(this));
34         },
35       },
37       scrollbarWidth: {
38         observer: 'onScrollbarWidthChange_',
39         type: Number,
40         value: 0,
41       },
43       completelyOnDisk_: {
44         computed: 'computeCompletelyOnDisk_(' +
45             'data_.state, data_.file_externally_removed)',
46         type: Boolean,
47         value: true,
48       },
50       i18n_: {
51         readOnly: true,
52         type: Object,
53         value: function() {
54           return {
55             cancel: loadTimeData.getString('controlCancel'),
56             discard: loadTimeData.getString('dangerDiscard'),
57             pause: loadTimeData.getString('controlPause'),
58             remove: loadTimeData.getString('controlRemoveFromList'),
59             resume: loadTimeData.getString('controlResume'),
60             restore: loadTimeData.getString('dangerRestore'),
61             retry: loadTimeData.getString('controlRetry'),
62             save: loadTimeData.getString('dangerSave'),
63             show: loadTimeData.getString('controlShowInFolder'),
64           };
65         },
66       },
68       isDangerous_: {
69         computed: 'computeIsDangerous_(data_.state)',
70         type: Boolean,
71         value: false,
72       },
74       isInProgress_: {
75         computed: 'computeIsInProgress_(data_.state)',
76         type: Boolean,
77         value: false,
78       },
80       showCancel_: {
81         computed: 'computeShowCancel_(data_.state)',
82         type: Boolean,
83         value: false,
84       },
86       showProgress_: {
87         computed: 'computeShowProgress_(showCancel_, data_.percent)',
88         type: Boolean,
89         value: false,
90       },
92       isMalware_: {
93         computed: 'computeIsMalware_(isDangerous_, data_.danger_type)',
94         type: Boolean,
95         value: false,
96       },
98       // TODO(dbeam): move all properties to |data_|.
99       data_: {
100         type: Object,
101         value: function() { return {}; },
102       },
103     },
105     ready: function() {
106       this.content = this.$.content;
107       this.resolveReadyPromise_();
108     },
110     /** @param {!downloads.Data} data */
111     update: function(data) {
112       assert(!('id' in this.data_) || this.data_.id == data.id);
114       if (this.data_ &&
115           data.by_ext_id === this.data_.by_ext_id &&
116           data.by_ext_name === this.data_.by_ext_name &&
117           data.danger_type === this.data_.danger_type &&
118           data.date_string == this.data_.date_string &&
119           data.file_externally_removed == this.data_.file_externally_removed &&
120           data.file_name == this.data_.file_name &&
121           data.file_path == this.data_.file_path &&
122           data.file_url == this.data_.file_url &&
123           data.last_reason_text === this.data_.last_reason_text &&
124           data.otr == this.data_.otr &&
125           data.percent === this.data_.percent &&
126           data.progress_status_text === this.data_.progress_status_text &&
127           data.received === this.data_.received &&
128           data.resume == this.data_.resume &&
129           data.retry == this.data_.retry &&
130           data.since_string == this.data_.since_string &&
131           data.started == this.data_.started &&
132           data.state == this.data_.state &&
133           data.total == this.data_.total &&
134           data.url == this.data_.url) {
135         // TODO(dbeam): remove this once data binding is fully in place.
136         return;
137       }
139       for (var key in data) {
140         this.set('data_.' + key, data[key]);
141       }
143       /** @const */ var isActive =
144           data.state != downloads.States.CANCELLED &&
145           data.state != downloads.States.INTERRUPTED &&
146           !data.file_externally_removed;
147       this.$.content.classList.toggle('is-active', isActive);
148       this.$.content.elevation = isActive ? 1 : 0;
150       // Danger-dependent UI and controls.
151       this.$.content.classList.toggle('dangerous', this.isDangerous_);
153       var description = this.getDangerText_(data) || this.getStatusText_(data);
155       // Status goes in the "tag" (next to the file name) if there's no file.
156       this.ensureTextIs_(this.$.description, isActive ? description : '');
157       this.ensureTextIs_(this.$.tag, isActive ? '' : description);
159       this.$.content.classList.toggle('show-progress', this.showProgress_);
161       var hideRemove;
163       if (this.isDangerous_) {
164         hideRemove = true;
165       } else {
166         this.$['file-link'].href = data.url;
167         this.ensureTextIs_(this.$['file-link'], data.file_name);
169         this.$['file-link'].hidden = !this.completelyOnDisk_;
170         this.$.name.hidden = this.completelyOnDisk_;
172         hideRemove = this.showCancel_ ||
173             !loadTimeData.getBoolean('allowDeletingHistory');
175         /** @const */ var controlledByExtension = data.by_ext_id &&
176                                                   data.by_ext_name;
177         this.$['controlled-by'].hidden = !controlledByExtension;
178         if (controlledByExtension) {
179           var link = this.$['controlled-by'].querySelector('a');
180           link.href = 'chrome://extensions#' + data.by_ext_id;
181           link.textContent = data.by_ext_name;
182         }
184         var icon = 'chrome://fileicon/' + encodeURIComponent(data.file_path);
185         this.iconLoader_.loadScaledIcon(this.$['file-icon'], icon);
186       }
188       this.$.remove.style.visibility = hideRemove ? 'hidden' : '';
189     },
191     /** @private */
192     computeCompletelyOnDisk_: function() {
193       return this.data_.state == downloads.States.COMPLETE &&
194              !this.data_.file_externally_removed;
195     },
197     /** @private */
198     computeDate_: function() {
199       assert(!this.hideDate);
200       return assert(this.data_.since_string || this.data_.date_string);
201     },
203     /** @private */
204     computeIsInProgress_: function() {
205       return this.data_.state == downloads.States.IN_PROGRESS;
206     },
208     /** @private */
209     computeIsMalware_: function() {
210       return this.isDangerous_ &&
211           (this.data_.danger_type == downloads.DangerType.DANGEROUS_CONTENT ||
212            this.data_.danger_type == downloads.DangerType.DANGEROUS_HOST ||
213            this.data_.danger_type == downloads.DangerType.DANGEROUS_URL ||
214            this.data_.danger_type == downloads.DangerType.POTENTIALLY_UNWANTED);
215     },
217     /** @private */
218     computeIsDangerous_: function() {
219       return this.data_.state == downloads.States.DANGEROUS;
220     },
222     /** @private */
223     computeShowCancel_: function() {
224       return this.data_.state == downloads.States.IN_PROGRESS ||
225              this.data_.state == downloads.States.PAUSED;
226     },
228     /** @private */
229     computeShowProgress_: function() {
230       return this.showCancel_ && isFinite(this.data_.percent);
231     },
233     /**
234      * Overwrite |el|'s textContent if it differs from |text|. This is done
235      * generally so quickly updating text can be copied via text selection.
236      * @param {!Element} el
237      * @param {string} text
238      * @private
239      */
240     ensureTextIs_: function(el, text) {
241       if (el.textContent != text)
242         el.textContent = text;
243     },
245     /**
246      * @param {!downloads.Data} data
247      * @return {string} Text describing the danger of a download. Empty if not
248      *     dangerous.
249      */
250     getDangerText_: function(data) {
251       switch (data.danger_type) {
252         case downloads.DangerType.DANGEROUS_FILE:
253           return loadTimeData.getStringF('dangerFileDesc', data.file_name);
254         case downloads.DangerType.DANGEROUS_URL:
255           return loadTimeData.getString('dangerUrlDesc');
256         case downloads.DangerType.DANGEROUS_CONTENT:  // Fall through.
257         case downloads.DangerType.DANGEROUS_HOST:
258           return loadTimeData.getStringF('dangerContentDesc', data.file_name);
259         case downloads.DangerType.UNCOMMON_CONTENT:
260           return loadTimeData.getStringF('dangerUncommonDesc', data.file_name);
261         case downloads.DangerType.POTENTIALLY_UNWANTED:
262           return loadTimeData.getStringF('dangerSettingsDesc', data.file_name);
263         default:
264           return '';
265       }
266     },
268     /**
269      * @param {!downloads.Data} data
270      * @return {string} User-visible status update text.
271      * @private
272      */
273     getStatusText_: function(data) {
274       switch (data.state) {
275         case downloads.States.IN_PROGRESS:
276         case downloads.States.PAUSED:  // Fallthrough.
277           assert(typeof data.progress_status_text == 'string');
278           return data.progress_status_text;
279         case downloads.States.CANCELLED:
280           return loadTimeData.getString('statusCancelled');
281         case downloads.States.DANGEROUS:
282           break;  // Intentionally hit assertNotReached(); at bottom.
283         case downloads.States.INTERRUPTED:
284           assert(typeof data.last_reason_text == 'string');
285           return data.last_reason_text;
286         case downloads.States.COMPLETE:
287           return data.file_externally_removed ?
288               loadTimeData.getString('statusRemoved') : '';
289       }
290       assertNotReached();
291       return '';
292     },
294     /** @private */
295     isIndeterminate_: function() {
296       assert(this.showProgress_);
297       return this.data_.percent == -1;
298     },
300     /** @private */
301     onCancelClick_: function() {
302       this.actionService_.cancel(this.data_.id);
303     },
305     /**
306      * @private
307      * @param {Event} e
308      */
309     onDragStart_: function(e) {
310       e.preventDefault();
311       this.actionService_.drag(this.data_.id);
312     },
314     /**
315      * @param {Event} e
316      * @private
317      */
318     onFileLinkClick_: function(e) {
319       e.preventDefault();
320       this.actionService_.openFile(this.data_.id);
321     },
323     /** @private */
324     onPauseClick_: function() {
325       this.actionService_.pause(this.data_.id);
326     },
328     /** @private */
329     onRemoveClick_: function() {
330       assert(!this.$.remove.disabled);
331       this.actionService_.remove(this.data_.id);
332     },
334     /** @private */
335     onSaveDangerous_: function() {
336       this.actionService_.saveDangerous(this.data_.id);
337     },
339     /** @private */
340     onDiscardDangerous_: function() {
341       this.actionService_.discardDangerous(this.data_.id);
342     },
344     /** @private */
345     onResumeClick_: function() {
346       this.actionService_.resume(this.data_.id);
347     },
349     /** @private */
350     onRetryClick_: function() {
351       this.actionService_.download(this.$['file-link'].href);
352     },
354     /** @private */
355     onScrollbarWidthChange_: function() {
356       if (!this.$)
357         return;
359       var endCap = this.$['end-cap'];
360       endCap.style.flexBasis = '';
362       if (this.scrollbarWidth) {
363         var basis = parseInt(getComputedStyle(endCap).flexBasis, 10);
364         endCap.style.flexBasis = basis - this.scrollbarWidth + 'px';
365       }
366     },
368     /** @private */
369     onShowClick_: function() {
370       this.actionService_.show(this.data_.id);
371     },
372   });
374   return {Item: Item};