Downloads WebUI: Re-format HTML and JS files after Polymer3 migration.
JS done automatically with
git cl format --js chrome/browser/resources/downloads/
HTML done manually by removing extra indentation.
Fixed: 1022215
Change-Id: If784d43a5035b0ec921a44d45b24b0fcc0500b96
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1918440
Reviewed-by: Rebekah Potter <rbpotter@chromium.org>
Commit-Queue: Demetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#717259}
diff --git a/chrome/browser/resources/downloads/browser_proxy.js b/chrome/browser/resources/downloads/browser_proxy.js
index 3a861bd1..d607f35f 100644
--- a/chrome/browser/resources/downloads/browser_proxy.js
+++ b/chrome/browser/resources/downloads/browser_proxy.js
@@ -2,23 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
import './downloads.mojom-lite.js';
- export class BrowserProxy {
- constructor() {
- /** @type {downloads.mojom.PageCallbackRouter} */
- this.callbackRouter = new downloads.mojom.PageCallbackRouter();
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
- /** @type {downloads.mojom.PageHandlerRemote} */
- this.handler = new downloads.mojom.PageHandlerRemote();
+export class BrowserProxy {
+ constructor() {
+ /** @type {downloads.mojom.PageCallbackRouter} */
+ this.callbackRouter = new downloads.mojom.PageCallbackRouter();
- const factory = downloads.mojom.PageHandlerFactory.getRemote();
- factory.createPageHandler(
- this.callbackRouter.$.bindNewPipeAndPassRemote(),
- this.handler.$.bindNewPipeAndPassReceiver());
- }
+ /** @type {downloads.mojom.PageHandlerRemote} */
+ this.handler = new downloads.mojom.PageHandlerRemote();
+
+ const factory = downloads.mojom.PageHandlerFactory.getRemote();
+ factory.createPageHandler(
+ this.callbackRouter.$.bindNewPipeAndPassRemote(),
+ this.handler.$.bindNewPipeAndPassReceiver());
}
+}
- addSingletonGetter(BrowserProxy);
+addSingletonGetter(BrowserProxy);
diff --git a/chrome/browser/resources/downloads/constants.js b/chrome/browser/resources/downloads/constants.js
index e6d3cc92..1a0401c1 100644
--- a/chrome/browser/resources/downloads/constants.js
+++ b/chrome/browser/resources/downloads/constants.js
@@ -2,36 +2,36 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
- /**
- * Explains why a download is in DANGEROUS state.
- * @enum {string}
- */
- export const DangerType = {
- NOT_DANGEROUS: 'NOT_DANGEROUS',
- DANGEROUS_FILE: 'DANGEROUS_FILE',
- DANGEROUS_URL: 'DANGEROUS_URL',
- DANGEROUS_CONTENT: 'DANGEROUS_CONTENT',
- UNCOMMON_CONTENT: 'UNCOMMON_CONTENT',
- DANGEROUS_HOST: 'DANGEROUS_HOST',
- POTENTIALLY_UNWANTED: 'POTENTIALLY_UNWANTED',
- DEEP_SCANNED_SAFE: 'DEEP_SCANNED_SAFE',
- DEEP_SCANNED_OPENED_DANGEROUS: 'DEEP_SCANNED_OPENED_DANGEROUS',
- SENSITIVE_CONTENT_WARNING: 'SENSITIVE_CONTENT_WARNING',
- SENSITIVE_CONTENT_BLOCK: 'SENSITIVE_CONTENT_BLOCK',
- BLOCKED_TOO_LARGE: 'BLOCKED_TOO_LARGE',
- BLOCKED_PASSWORD_PROTECTED: 'BLOCKED_PASSWORD_PROTECTED',
- };
+/**
+ * Explains why a download is in DANGEROUS state.
+ * @enum {string}
+ */
+export const DangerType = {
+ NOT_DANGEROUS: 'NOT_DANGEROUS',
+ DANGEROUS_FILE: 'DANGEROUS_FILE',
+ DANGEROUS_URL: 'DANGEROUS_URL',
+ DANGEROUS_CONTENT: 'DANGEROUS_CONTENT',
+ UNCOMMON_CONTENT: 'UNCOMMON_CONTENT',
+ DANGEROUS_HOST: 'DANGEROUS_HOST',
+ POTENTIALLY_UNWANTED: 'POTENTIALLY_UNWANTED',
+ DEEP_SCANNED_SAFE: 'DEEP_SCANNED_SAFE',
+ DEEP_SCANNED_OPENED_DANGEROUS: 'DEEP_SCANNED_OPENED_DANGEROUS',
+ SENSITIVE_CONTENT_WARNING: 'SENSITIVE_CONTENT_WARNING',
+ SENSITIVE_CONTENT_BLOCK: 'SENSITIVE_CONTENT_BLOCK',
+ BLOCKED_TOO_LARGE: 'BLOCKED_TOO_LARGE',
+ BLOCKED_PASSWORD_PROTECTED: 'BLOCKED_PASSWORD_PROTECTED',
+};
- /**
- * The states a download can be in. These correspond to states defined in
- * DownloadsDOMHandler::CreateDownloadItemValue
- * @enum {string}
- */
- export const States = {
- IN_PROGRESS: 'IN_PROGRESS',
- CANCELLED: 'CANCELLED',
- COMPLETE: 'COMPLETE',
- PAUSED: 'PAUSED',
- DANGEROUS: 'DANGEROUS',
- INTERRUPTED: 'INTERRUPTED',
- };
+/**
+ * The states a download can be in. These correspond to states defined in
+ * DownloadsDOMHandler::CreateDownloadItemValue
+ * @enum {string}
+ */
+export const States = {
+ IN_PROGRESS: 'IN_PROGRESS',
+ CANCELLED: 'CANCELLED',
+ COMPLETE: 'COMPLETE',
+ PAUSED: 'PAUSED',
+ DANGEROUS: 'DANGEROUS',
+ INTERRUPTED: 'INTERRUPTED',
+};
diff --git a/chrome/browser/resources/downloads/icon_loader.js b/chrome/browser/resources/downloads/icon_loader.js
index 38024d4..667c268 100644
--- a/chrome/browser/resources/downloads/icon_loader.js
+++ b/chrome/browser/resources/downloads/icon_loader.js
@@ -2,53 +2,53 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
import {assert} from 'chrome://resources/js/assert.m.js';
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
import {getFileIconUrl} from 'chrome://resources/js/icon.m.js';
import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
- export class IconLoader {
- constructor() {
- /** @private {!Object<!PromiseResolver<boolean>>} */
- this.iconResolvers_ = {};
+export class IconLoader {
+ constructor() {
+ /** @private {!Object<!PromiseResolver<boolean>>} */
+ this.iconResolvers_ = {};
- /** @private {!Set<!HTMLImageElement>} */
- this.listeningImages_ = new Set();
- }
-
- /**
- * @param {!HTMLImageElement} imageEl
- * @param {string} filePath
- * @return {!Promise<boolean>} Whether or not the icon loaded successfully.
- */
- loadIcon(imageEl, filePath) {
- const url = getFileIconUrl(filePath);
-
- if (!this.iconResolvers_[url]) {
- this.iconResolvers_[url] = new PromiseResolver();
- }
-
- if (!this.listeningImages_.has(imageEl)) {
- imageEl.addEventListener('load', this.finishedLoading_.bind(this));
- imageEl.addEventListener('error', this.finishedLoading_.bind(this));
- this.listeningImages_.add(imageEl);
- }
-
- imageEl.src = url;
-
- return assert(this.iconResolvers_[url]).promise;
- }
-
- /**
- * @param {!Event} e
- * @private
- */
- finishedLoading_(e) {
- const resolver = assert(this.iconResolvers_[e.currentTarget.src]);
- if (!resolver.isFulfilled) {
- resolver.resolve(e.type == 'load');
- }
- }
+ /** @private {!Set<!HTMLImageElement>} */
+ this.listeningImages_ = new Set();
}
- addSingletonGetter(IconLoader);
+ /**
+ * @param {!HTMLImageElement} imageEl
+ * @param {string} filePath
+ * @return {!Promise<boolean>} Whether or not the icon loaded successfully.
+ */
+ loadIcon(imageEl, filePath) {
+ const url = getFileIconUrl(filePath);
+
+ if (!this.iconResolvers_[url]) {
+ this.iconResolvers_[url] = new PromiseResolver();
+ }
+
+ if (!this.listeningImages_.has(imageEl)) {
+ imageEl.addEventListener('load', this.finishedLoading_.bind(this));
+ imageEl.addEventListener('error', this.finishedLoading_.bind(this));
+ this.listeningImages_.add(imageEl);
+ }
+
+ imageEl.src = url;
+
+ return assert(this.iconResolvers_[url]).promise;
+ }
+
+ /**
+ * @param {!Event} e
+ * @private
+ */
+ finishedLoading_(e) {
+ const resolver = assert(this.iconResolvers_[e.currentTarget.src]);
+ if (!resolver.isFulfilled) {
+ resolver.resolve(e.type == 'load');
+ }
+ }
+}
+
+addSingletonGetter(IconLoader);
diff --git a/chrome/browser/resources/downloads/item.html b/chrome/browser/resources/downloads/item.html
index b51c57b..79d71f09 100644
--- a/chrome/browser/resources/downloads/item.html
+++ b/chrome/browser/resources/downloads/item.html
@@ -1,374 +1,373 @@
- <style include="action-link cr-hidden-style cr-icons">
- :host {
- --controlled-by-active-color: #333;
- --controlled-by-active-link-color: var(--google-blue-600);
- --controlled-by-inactive-color: #5a5a5a;
- display: flex;
- flex-direction: column;
- outline: none;
- }
+<style include="action-link cr-hidden-style cr-icons">
+ :host {
+ --controlled-by-active-color: #333;
+ --controlled-by-active-link-color: var(--google-blue-600);
+ --controlled-by-inactive-color: #5a5a5a;
+ display: flex;
+ flex-direction: column;
+ outline: none;
+ }
- @media (prefers-color-scheme: dark) {
- :host {
- --controlled-by-active-color: inherit;
- --controlled-by-active-link-color: var(--cr-link-color);
- --controlled-by-inactive-color: inherit;
- }
- }
+ @media (prefers-color-scheme: dark) {
+ :host {
+ --controlled-by-active-color: inherit;
+ --controlled-by-active-link-color: var(--cr-link-color);
+ --controlled-by-inactive-color: inherit;
+ }
+ }
- cr-button {
- font-weight: 500;
- margin: 0;
- min-width: auto;
- }
+ cr-button {
+ font-weight: 500;
+ margin: 0;
+ min-width: auto;
+ }
- #date {
- font-size: 0.875rem;
- font-weight: 400;
- letter-spacing: .25px;
- margin: 21px auto 6px;
- padding-bottom: 4px;
- padding-top: 8px;
- width: var(--downloads-card-width);
- }
+ #date {
+ font-size: 0.875rem;
+ font-weight: 400;
+ letter-spacing: .25px;
+ margin: 21px auto 6px;
+ padding-bottom: 4px;
+ padding-top: 8px;
+ width: var(--downloads-card-width);
+ }
- #date:empty {
- display: none;
- }
+ #date:empty {
+ display: none;
+ }
- #content {
- border-radius: var(--cr-card-border-radius);
- display: flex;
- flex: none;
- margin: 6px auto;
- min-height: 103px;
- position: relative;
- width: var(--downloads-card-width);
- }
+ #content {
+ border-radius: var(--cr-card-border-radius);
+ display: flex;
+ flex: none;
+ margin: 6px auto;
+ min-height: 103px;
+ position: relative;
+ width: var(--downloads-card-width);
+ }
- #content.is-active {
- @apply --cr-card-elevation;
- }
+ #content.is-active {
+ @apply --cr-card-elevation;
+ }
- @media (prefers-color-scheme: light) {
- #content.is-active {
- background-color: var(--cr-card-background-color);
- }
- }
+ @media (prefers-color-scheme: light) {
+ #content.is-active {
+ background-color: var(--cr-card-background-color);
+ }
+ }
- #content:not(.is-active) {
- background: rgba(255, 255, 255, .6);
- border: 1px var(--google-grey-300) solid;
- }
+ #content:not(.is-active) {
+ background: rgba(255, 255, 255, .6);
+ border: 1px var(--google-grey-300) solid;
+ }
- @media (prefers-color-scheme: dark) {
- #content:not(.is-active) {
- background: none; /* override */
- border-color: var(--google-grey-800);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ #content:not(.is-active) {
+ background: none; /* override */
+ border-color: var(--google-grey-800);
+ }
+ }
- #details {
- border-inline-start: 1px #d8d8d8 solid;
- display: flex;
- flex: 1;
- flex-direction: column;
- min-width: 0; /* This allows #url to ellide correctly. */
- padding-bottom: 12px;
- padding-inline-end: 16px;
- padding-inline-start: var(--downloads-card-margin);
- padding-top: 16px;
- }
+ #details {
+ border-inline-start: 1px #d8d8d8 solid;
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ min-width: 0; /* This allows #url to ellide correctly. */
+ padding-bottom: 12px;
+ padding-inline-end: 16px;
+ padding-inline-start: var(--downloads-card-margin);
+ padding-top: 16px;
+ }
- @media (prefers-color-scheme: dark) {
- #details {
- border-color: rgba(var(--google-grey-800-rgb), .8);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ #details {
+ border-color: rgba(var(--google-grey-800-rgb), .8);
+ }
+ }
- #content:not(.is-active) #details {
- color: rgba(27, 27, 27, .6);
- }
+ #content:not(.is-active) #details {
+ color: rgba(27, 27, 27, .6);
+ }
- @media (prefers-color-scheme: dark) {
- #content:not(.is-active) #details {
- color: rgba(var(--google-grey-refresh-500-rgb), .6);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ #content:not(.is-active) #details {
+ color: rgba(var(--google-grey-refresh-500-rgb), .6);
+ }
+ }
- #content:not(.is-active) #name {
- text-decoration: line-through;
- }
+ #content:not(.is-active) #name {
+ text-decoration: line-through;
+ }
- @media (prefers-color-scheme: dark) {
- #content:not(.is-active) :-webkit-any(#name, #tag) {
- color: var(--google-grey-refresh-500);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ #content:not(.is-active) :-webkit-any(#name, #tag) {
+ color: var(--google-grey-refresh-500);
+ }
+ }
- .icon-wrapper {
- align-self: center;
- flex: none;
- justify-content: center;
- margin: 0 24px;
- }
+ .icon-wrapper {
+ align-self: center;
+ flex: none;
+ justify-content: center;
+ margin: 0 24px;
+ }
- .icon,
- #file-icon-wrapper {
- height: 32px;
- width: 32px;
- }
+ .icon,
+ #file-icon-wrapper {
+ height: 32px;
+ width: 32px;
+ }
- #file-icon-wrapper {
- overflow: hidden; /* Reduces file icon flicker on initial load. */
- }
+ #file-icon-wrapper {
+ overflow: hidden; /* Reduces file icon flicker on initial load. */
+ }
- #content:-webkit-any(.show-progress, .dangerous) #file-icon-wrapper {
- /* TODO(dbeam): animate from top-aligned to centered when items finish?
- */
- align-self: flex-start;
- padding-top: 16px;
- }
+ #content:-webkit-any(.show-progress, .dangerous) #file-icon-wrapper {
+ /* TODO(dbeam): animate from top-aligned to centered when items finish?
+ */
+ align-self: flex-start;
+ padding-top: 16px;
+ }
- #content:not(.is-active) .icon {
- -webkit-filter: grayscale(100%);
- opacity: .5;
- }
+ #content:not(.is-active) .icon {
+ -webkit-filter: grayscale(100%);
+ opacity: .5;
+ }
- #file-icon-wrapper iron-icon[icon='cr:insert-drive-file'] {
- color: var(--paper-grey-400);
- }
+ #file-icon-wrapper iron-icon[icon='cr:insert-drive-file'] {
+ color: var(--paper-grey-400);
+ }
- #file-icon-wrapper iron-icon[icon='cr:warning'],
- .dangerous #description {
- color: var(--google-red-700);
- }
+ #file-icon-wrapper iron-icon[icon='cr:warning'],
+ .dangerous #description {
+ color: var(--google-red-700);
+ }
- #file-icon-wrapper iron-icon[icon='cr:error'],
- .dangerous #description {
- color: var(--google-yellow-500);
- }
+ #file-icon-wrapper iron-icon[icon='cr:error'],
+ .dangerous #description {
+ color: var(--google-yellow-500);
+ }
- @media (prefers-color-scheme: dark) {
- #file-icon-wrapper iron-icon[icon='cr:warning'],
- .dangerous #description {
- color: var(--google-red-refresh-300);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ #file-icon-wrapper iron-icon[icon='cr:warning'],
+ .dangerous #description {
+ color: var(--google-red-refresh-300);
+ }
+ }
- #name,
- #file-link,
- #url {
- max-width: 100%;
- }
+ #name,
+ #file-link,
+ #url {
+ max-width: 100%;
+ }
- #name,
- #file-link {
- font-weight: 500;
- word-break: break-all;
- }
+ #name,
+ #file-link {
+ font-weight: 500;
+ word-break: break-all;
+ }
- @media (prefers-color-scheme: light) {
- .is-active :-webkit-any(#name, #file-link, #show) {
- color: var(--google-blue-600);
- }
- }
+ @media (prefers-color-scheme: light) {
+ .is-active :-webkit-any(#name, #file-link, #show) {
+ color: var(--google-blue-600);
+ }
+ }
- #name {
- margin-inline-end: 12px; /* Only really affects #tag. */
- }
+ #name {
+ margin-inline-end: 12px; /* Only really affects #tag. */
+ }
- #tag {
- color: #5a5a5a;
- font-weight: 500;
- }
+ #tag {
+ color: #5a5a5a;
+ font-weight: 500;
+ }
- #url {
- color: inherit;
- margin-top: 6px;
- min-height: 0;
- overflow: hidden;
- text-decoration: none;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
+ #url {
+ color: inherit;
+ margin-top: 6px;
+ min-height: 0;
+ overflow: hidden;
+ text-decoration: none;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
- .is-active #url {
- color: var(--cr-secondary-text-color);
- }
+ .is-active #url {
+ color: var(--cr-secondary-text-color);
+ }
- #progress,
- #description:not(:empty),
- .controls {
- margin-top: 16px;
- }
+ #progress,
+ #description:not(:empty),
+ .controls {
+ margin-top: 16px;
+ }
- @media (prefers-color-scheme: light) {
- .is-active #description {
- color: #616161;
- }
- }
+ @media (prefers-color-scheme: light) {
+ .is-active #description {
+ color: #616161;
+ }
+ }
- #progress {
- /* TODO(dbeam): border-radius on container and progress bar. */
- --paper-progress-active-color: var(--google-blue-600);
- --paper-progress-container-color: rgb(223, 222, 223);
- width: auto;
- }
+ #progress {
+ /* TODO(dbeam): border-radius on container and progress bar. */
+ --paper-progress-active-color: var(--google-blue-600);
+ --paper-progress-container-color: rgb(223, 222, 223);
+ width: auto;
+ }
- @media (prefers-color-scheme: dark) {
- #progress {
- --paper-progress-active-color: var(--google-blue-refresh-300);
- --paper-progress-container-color: var(--google-grey-800);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ #progress {
+ --paper-progress-active-color: var(--google-blue-refresh-300);
+ --paper-progress-container-color: var(--google-grey-800);
+ }
+ }
- #show {
- margin: .7em 0;
- }
+ #show {
+ margin: .7em 0;
+ }
- #controlled-by,
- #controlled-by a {
- color: var(--controlled-by-inactive-color);
- }
+ #controlled-by,
+ #controlled-by a {
+ color: var(--controlled-by-inactive-color);
+ }
- .is-active #controlled-by {
- color: var(--controlled-by-active-color);
- margin-inline-start: 8px;
- }
+ .is-active #controlled-by {
+ color: var(--controlled-by-active-color);
+ margin-inline-start: 8px;
+ }
- .is-active #controlled-by a {
- color: var(--controlled-by-active-link-color);
- }
+ .is-active #controlled-by a {
+ color: var(--controlled-by-active-link-color);
+ }
- cr-icon-button {
- --cr-icon-button-icon-size: 16px;
- --cr-icon-button-margin-end: 8px;
- margin-top: 8px;
- }
+ cr-icon-button {
+ --cr-icon-button-icon-size: 16px;
+ --cr-icon-button-margin-end: 8px;
+ margin-top: 8px;
+ }
- #incognito {
- -webkit-mask-image: url(images/incognito_marker.svg);
- background-color: var(--cr-secondary-text-color);
- bottom: 20px;
- height: 16px;
- position: absolute;
- right: 16px;
- width: 16px;
- }
+ #incognito {
+ -webkit-mask-image: url(images/incognito_marker.svg);
+ background-color: var(--cr-secondary-text-color);
+ bottom: 20px;
+ height: 16px;
+ position: absolute;
+ right: 16px;
+ width: 16px;
+ }
- :host-context([dir='rtl']) #incognito {
- left: 16px;
- right: initial;
- }
+ :host-context([dir='rtl']) #incognito {
+ left: 16px;
+ right: initial;
+ }
- #pauseOrResume,
- #dangerous .action-button {
- margin-inline-end: 8px;
- }
- </style>
+ #pauseOrResume,
+ #dangerous .action-button {
+ margin-inline-end: 8px;
+ }
+</style>
- <div id="date" role="heading" aria-level="2">[[computeDate_(data.hideDate,
- data.sinceString,
- data.dateString)]]</div>
+<div id="date" role="heading" aria-level="2">[[computeDate_(data.hideDate,
+ data.sinceString,
+ data.dateString)]]</div>
- <div id="content" on-dragstart="onDragStart_"
- class$="[[computeClass_(isActive_, isDangerous_, showProgress_)]]"
- focus-row-container>
- <div id="file-icon-wrapper" class="icon-wrapper">
- <img class="icon" id="file-icon" alt="" hidden="[[!useFileIcon_]]">
- <iron-icon class="icon" icon$="[[computeIcon_(
- isDangerous_, data.dangerType, useFileIcon_)]]"
- hidden="[[useFileIcon_]]"></iron-icon>
- </div>
+<div id="content" on-dragstart="onDragStart_"
+ class$="[[computeClass_(isActive_, isDangerous_, showProgress_)]]"
+ focus-row-container>
+ <div id="file-icon-wrapper" class="icon-wrapper">
+ <img class="icon" id="file-icon" alt="" hidden="[[!useFileIcon_]]">
+ <iron-icon class="icon" icon$="[[computeIcon_(
+ isDangerous_, data.dangerType, useFileIcon_)]]"
+ hidden="[[useFileIcon_]]"></iron-icon>
+ </div>
- <div id="details">
- <div id="title-area"><!--
- Can't have any line breaks.
- --><a is="action-link" id="file-link" href="[[data.url]]"
- on-click="onFileLinkTap_" focus-row-control
- focus-type="fileLink"
- hidden="[[!completelyOnDisk_]]">[[data.fileName]]</a><!--
- Before #name.
- --><span id="name"
- hidden="[[completelyOnDisk_]]">[[data.fileName]]</span>
- <span id="tag">[[computeTag_(data.state,
- data.lastReasonText,
- data.fileExternallyRemoved)]]</span>
- </div>
-
- <a id="url" target="_blank" on-click="onUrlTap_" focus-row-control
- focus-type="url">[[chopUrl_(data.url)]]</a>
-
- <div id="description">[[computeDescription_(
- data.state,
- data.dangerType,
- data.fileName,
- data.progressStatusText)]]</div>
-
- <template is="dom-if" if="[[showProgress_]]">
- <paper-progress id="progress"
- indeterminate="[[isIndeterminate_(data.percent)]]"
- value="[[data.percent]]"></paper-progress>
- </template>
-
- <div id="safe" class="controls" hidden="[[isDangerous_]]">
- <a is="action-link" id="show" on-click="onShowTap_"
- hidden="[[!completelyOnDisk_]]" focus-row-control
- focus-type="show">$i18n{controlShowInFolder}</a>
- <template is="dom-if" if="[[data.retry]]">
- <cr-button class="action-button" on-click="onRetryTap_"
- focus-row-control focus-type="retry">
- $i18n{controlRetry}
- </cr-button>
- </template>
- <template is="dom-if" if="[[pauseOrResumeText_]]">
- <cr-button on-click="onPauseOrResumeTap_" id="pauseOrResume"
- focus-row-control focus-type="pauseOrResume">
- [[pauseOrResumeText_]]
- </cr-button>
- </template>
- <template is="dom-if" if="[[showCancel_]]">
- <cr-button on-click="onCancelTap_" focus-row-control
- focus-type="cancel">
- $i18n{controlCancel}
- </cr-button>
- </template>
- <span id="controlled-by"><!-- Text populated dynamically. --></span>
- </div>
-
- <template is="dom-if" if="[[isDangerous_]]">
- <div id="dangerous" class="controls">
- <!-- Dangerous file types (e.g. .exe, .jar). -->
- <template is="dom-if" if="[[!isMalware_]]">
- <cr-button on-click="onDiscardDangerousTap_"
- class="action-button" focus-row-control
- focus-type="discard">$i18n{dangerDiscard}</cr-button>
- <cr-button on-click="onSaveDangerousTap_" focus-row-control
- focus-type="save">
- $i18n{dangerSave}</cr-button>
- </template>
-
- <!-- Things that safe browsing has determined to be dangerous. -->
- <template is="dom-if" if="[[isMalware_]]">
- <cr-button on-click="onDiscardDangerousTap_"
- class="action-button" focus-row-control focus-type="discard">
- $i18n{controlRemoveFromList}</cr-button>
- <cr-button on-click="onSaveDangerousTap_" focus-row-control
- focus-type="save">
- $i18n{dangerRestore}</cr-button>
- </template>
- </div>
- </template>
- </div>
- <cr-icon-button class="icon-clear"
- style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]"
- id="remove" title="$i18n{controlRemoveFromList}"
- aria-label$="[[controlRemoveFromListAriaLabel_]]"
- on-click="onRemoveTap_" focus-row-control focus-type="remove">
- </cr-icon-button>
- <div id="incognito" title="$i18n{inIncognito}" hidden="[[!data.otr]]">
- </div>
+ <div id="details">
+ <div id="title-area"><!--
+ Can't have any line breaks.
+ --><a is="action-link" id="file-link" href="[[data.url]]"
+ on-click="onFileLinkTap_" focus-row-control
+ focus-type="fileLink"
+ hidden="[[!completelyOnDisk_]]">[[data.fileName]]</a><!--
+ Before #name.
+ --><span id="name"
+ hidden="[[completelyOnDisk_]]">[[data.fileName]]</span>
+ <span id="tag">[[computeTag_(data.state,
+ data.lastReasonText,
+ data.fileExternallyRemoved)]]</span>
</div>
+ <a id="url" target="_blank" on-click="onUrlTap_" focus-row-control
+ focus-type="url">[[chopUrl_(data.url)]]</a>
+
+ <div id="description">[[computeDescription_(
+ data.state,
+ data.dangerType,
+ data.fileName,
+ data.progressStatusText)]]</div>
+
+ <template is="dom-if" if="[[showProgress_]]">
+ <paper-progress id="progress"
+ indeterminate="[[isIndeterminate_(data.percent)]]"
+ value="[[data.percent]]"></paper-progress>
+ </template>
+
+ <div id="safe" class="controls" hidden="[[isDangerous_]]">
+ <a is="action-link" id="show" on-click="onShowTap_"
+ hidden="[[!completelyOnDisk_]]" focus-row-control
+ focus-type="show">$i18n{controlShowInFolder}</a>
+ <template is="dom-if" if="[[data.retry]]">
+ <cr-button class="action-button" on-click="onRetryTap_"
+ focus-row-control focus-type="retry">
+ $i18n{controlRetry}
+ </cr-button>
+ </template>
+ <template is="dom-if" if="[[pauseOrResumeText_]]">
+ <cr-button on-click="onPauseOrResumeTap_" id="pauseOrResume"
+ focus-row-control focus-type="pauseOrResume">
+ [[pauseOrResumeText_]]
+ </cr-button>
+ </template>
+ <template is="dom-if" if="[[showCancel_]]">
+ <cr-button on-click="onCancelTap_" focus-row-control
+ focus-type="cancel">
+ $i18n{controlCancel}
+ </cr-button>
+ </template>
+ <span id="controlled-by"><!-- Text populated dynamically. --></span>
+ </div>
+
+ <template is="dom-if" if="[[isDangerous_]]">
+ <div id="dangerous" class="controls">
+ <!-- Dangerous file types (e.g. .exe, .jar). -->
+ <template is="dom-if" if="[[!isMalware_]]">
+ <cr-button on-click="onDiscardDangerousTap_"
+ class="action-button" focus-row-control
+ focus-type="discard">$i18n{dangerDiscard}</cr-button>
+ <cr-button on-click="onSaveDangerousTap_" focus-row-control
+ focus-type="save">
+ $i18n{dangerSave}</cr-button>
+ </template>
+
+ <!-- Things that safe browsing has determined to be dangerous. -->
+ <template is="dom-if" if="[[isMalware_]]">
+ <cr-button on-click="onDiscardDangerousTap_"
+ class="action-button" focus-row-control focus-type="discard">
+ $i18n{controlRemoveFromList}</cr-button>
+ <cr-button on-click="onSaveDangerousTap_" focus-row-control
+ focus-type="save">
+ $i18n{dangerRestore}</cr-button>
+ </template>
+ </div>
+ </template>
+ </div>
+ <cr-icon-button class="icon-clear"
+ style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]"
+ id="remove" title="$i18n{controlRemoveFromList}"
+ aria-label$="[[controlRemoveFromListAriaLabel_]]"
+ on-click="onRemoveTap_" focus-row-control focus-type="remove">
+ </cr-icon-button>
+ <div id="incognito" title="$i18n{inIncognito}" hidden="[[!data.otr]]">
+ </div>
+</div>
diff --git a/chrome/browser/resources/downloads/item.js b/chrome/browser/resources/downloads/item.js
index 324bff0..ae4b275 100644
--- a/chrome/browser/resources/downloads/item.js
+++ b/chrome/browser/resources/downloads/item.js
@@ -2,31 +2,33 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import {Polymer, html, beforeNextRender} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {BrowserProxy} from './browser_proxy.js';
-import {DangerType, States} from './constants.js';
-import {IconLoader} from './icon_loader.js';
import './icons.js';
import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
import 'chrome://resources/cr_elements/cr_icons_css.m.js';
-import {getInstance} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js';
import 'chrome://resources/cr_elements/hidden_style_css.m.js';
import 'chrome://resources/cr_elements/icons.m.js';
import 'chrome://resources/cr_elements/shared_vars_css.m.js';
import 'chrome://resources/js/action_link.js';
import 'chrome://resources/cr_elements/action_link_css.m.js';
-import {HTMLEscape} from 'chrome://resources/js/util.m.js';
-import {assert} from 'chrome://resources/js/assert.m.js';
import './strings.m.js';
-import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {FocusRowBehavior} from 'chrome://resources/js/cr/ui/focus_row_behavior.m.js';
-import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js';
import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
- Polymer({
+import {getInstance} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {FocusRowBehavior} from 'chrome://resources/js/cr/ui/focus_row_behavior.m.js';
+import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {HTMLEscape} from 'chrome://resources/js/util.m.js';
+import {beforeNextRender, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {BrowserProxy} from './browser_proxy.js';
+import {DangerType, States} from './constants.js';
+import {IconLoader} from './icon_loader.js';
+
+Polymer({
is: 'downloads-item',
_template: html`{__html_template__}`,
diff --git a/chrome/browser/resources/downloads/manager.html b/chrome/browser/resources/downloads/manager.html
index deccd25a..a05e64b 100644
--- a/chrome/browser/resources/downloads/manager.html
+++ b/chrome/browser/resources/downloads/manager.html
@@ -1,122 +1,122 @@
- <style include="cr-page-host-style cr-shared-style cr-hidden-style">
- :host {
- display: flex;
- flex: 1 0;
- flex-direction: column;
- height: 100%;
- overflow: hidden;
- z-index: 0;
- }
+<style include="cr-page-host-style cr-shared-style cr-hidden-style">
+ :host {
+ display: flex;
+ flex: 1 0;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+ z-index: 0;
+ }
- @media (prefers-color-scheme: dark) {
- :host {
- color: var(--cr-secondary-text-color);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ :host {
+ color: var(--cr-secondary-text-color);
+ }
+ }
- #toolbar {
- z-index: 1;
- }
+ #toolbar {
+ z-index: 1;
+ }
- :host([has-shadow_]) #drop-shadow {
- opacity: var(--cr-container-shadow-max-opacity);
- }
+ :host([has-shadow_]) #drop-shadow {
+ opacity: var(--cr-container-shadow-max-opacity);
+ }
- downloads-item,
- #downloadsList {
- --downloads-card-margin: 24px;
- --downloads-card-width: 680px;
- }
+ downloads-item,
+ #downloadsList {
+ --downloads-card-margin: 24px;
+ --downloads-card-width: 680px;
+ }
- #downloadsList {
- min-width: calc(
- var(--downloads-card-width) + 2 * var(--downloads-card-margin));
- }
+ #downloadsList {
+ min-width: calc(
+ var(--downloads-card-width) + 2 * var(--downloads-card-margin));
+ }
- #no-downloads,
- #downloadsList {
- flex: 1;
- }
+ #no-downloads,
+ #downloadsList {
+ flex: 1;
+ }
- :host([loading]) #no-downloads,
- :host([loading]) #downloadsList {
- display: none;
- }
+ :host([loading]) #no-downloads,
+ :host([loading]) #downloadsList {
+ display: none;
+ }
- #no-downloads {
- align-items: center;
- color: #6e6e6e;
- display: flex;
- font-size: 123.1%;
- font-weight: 500;
- justify-content: center;
- /* To avoid overlapping with the header, we need this min-height
- * until bug 596743 is fixed. */
- min-height: min-content;
- }
+ #no-downloads {
+ align-items: center;
+ color: #6e6e6e;
+ display: flex;
+ font-size: 123.1%;
+ font-weight: 500;
+ justify-content: center;
+ /* To avoid overlapping with the header, we need this min-height
+ * until bug 596743 is fixed. */
+ min-height: min-content;
+ }
- @media (prefers-color-scheme: dark) {
- #no-downloads {
- color: var(--cr-secondary-text-color);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ #no-downloads {
+ color: var(--cr-secondary-text-color);
+ }
+ }
- #no-downloads .illustration {
- background: url(images/no_downloads.svg) no-repeat
- center center;
- background-size: contain;
- height: 144px;
- margin-bottom: 32px;
- }
+ #no-downloads .illustration {
+ background: url(images/no_downloads.svg) no-repeat
+ center center;
+ background-size: contain;
+ height: 144px;
+ margin-bottom: 32px;
+ }
- #mainContainer {
- display: flex;
- flex: 1;
- flex-direction: column;
- height: 100%;
- overflow-y: overlay;
- }
+ #mainContainer {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ height: 100%;
+ overflow-y: overlay;
+ }
- managed-footnote {
- border-top: none;
- /* margin-bottom is needed to compensate for the next element's 21px
- * margin at the top and 8px padding at the top. This leaves a 12px
- * padding between this element's content and the top of the next
- * element's text. */
- margin-bottom: calc(-21px - 8px);
- min-width: calc(
- var(--downloads-card-width) + 2 * var(--downloads-card-margin));
- padding-bottom: 12px;
- padding-top: 12px;
- /* The next element spills over this element. This ensures the link
- * is clickable. */
- z-index: 1;
- }
- </style>
+ managed-footnote {
+ border-top: none;
+ /* margin-bottom is needed to compensate for the next element's 21px
+ * margin at the top and 8px padding at the top. This leaves a 12px
+ * padding between this element's content and the top of the next
+ * element's text. */
+ margin-bottom: calc(-21px - 8px);
+ min-width: calc(
+ var(--downloads-card-width) + 2 * var(--downloads-card-margin));
+ padding-bottom: 12px;
+ padding-top: 12px;
+ /* The next element spills over this element. This ensures the link
+ * is clickable. */
+ z-index: 1;
+ }
+</style>
- <downloads-toolbar id="toolbar" spinner-active="{{spinnerActive_}}"
- role="none" on-search-changed="onSearchChanged_">
- </downloads-toolbar>
- <div id="drop-shadow" class="cr-container-shadow"></div>
- <div id="mainContainer" on-scroll="onScroll_">
- <managed-footnote hidden="[[inSearchMode_]]"></managed-footnote>
- <iron-list id="downloadsList" items="[[items_]]"
- hidden="[[!hasDownloads_]]" scroll-target="mainContainer"
- preserve-focus>
- <template>
- <downloads-item data="[[item]]" tabindex$="[[tabIndex]]"
- iron-list-tab-index="[[tabIndex]]" last-focused="{{lastFocused_}}"
- list-blurred="{{listBlurred_}}" focus-row-index="[[index]]">
- </downloads-item>
- </template>
- </iron-list>
- <div id="no-downloads" hidden="[[hasDownloads_]]">
- <div>
- <div class="illustration"></div>
- <span>[[noDownloadsText_(inSearchMode_)]]</span>
- </div>
- </div>
+<downloads-toolbar id="toolbar" spinner-active="{{spinnerActive_}}"
+ role="none" on-search-changed="onSearchChanged_">
+</downloads-toolbar>
+<div id="drop-shadow" class="cr-container-shadow"></div>
+<div id="mainContainer" on-scroll="onScroll_">
+ <managed-footnote hidden="[[inSearchMode_]]"></managed-footnote>
+ <iron-list id="downloadsList" items="[[items_]]"
+ hidden="[[!hasDownloads_]]" scroll-target="mainContainer"
+ preserve-focus>
+ <template>
+ <downloads-item data="[[item]]" tabindex$="[[tabIndex]]"
+ iron-list-tab-index="[[tabIndex]]" last-focused="{{lastFocused_}}"
+ list-blurred="{{listBlurred_}}" focus-row-index="[[index]]">
+ </downloads-item>
+ </template>
+ </iron-list>
+ <div id="no-downloads" hidden="[[hasDownloads_]]">
+ <div>
+ <div class="illustration"></div>
+ <span>[[noDownloadsText_(inSearchMode_)]]</span>
</div>
- <cr-toast-manager on-undo-click="onUndoClick_" undo-label="$i18n{undo}"
- undo-description="$i18n{undoDescription}" duration="10000">
- </cr-toast-manager>
+ </div>
+</div>
+<cr-toast-manager on-undo-click="onUndoClick_" undo-label="$i18n{undo}"
+ undo-description="$i18n{undoDescription}" duration="10000">
+</cr-toast-manager>
diff --git a/chrome/browser/resources/downloads/manager.js b/chrome/browser/resources/downloads/manager.js
index bb997c6..66d77e2d 100644
--- a/chrome/browser/resources/downloads/manager.js
+++ b/chrome/browser/resources/downloads/manager.js
@@ -3,366 +3,364 @@
// found in the LICENSE file.
import './strings.m.js';
-import {Polymer, html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {BrowserProxy} from './browser_proxy.js';
-import {States} from './constants.js';
import './item.js';
-import {SearchService} from './search_service.js';
import './toolbar.js';
import 'chrome://resources/cr_components/managed_footnote/managed_footnote.m.js';
import 'chrome://resources/cr_elements/cr_page_host_style_css.m.js';
-import {getInstance as getToastManagerInstance} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js';
import 'chrome://resources/cr_elements/hidden_style_css.m.js';
import 'chrome://resources/cr_elements/shared_style_css.m.js';
import 'chrome://resources/cr_elements/shared_vars_css.m.js';
-import {FindShortcutBehavior} from 'chrome://resources/js/find_shortcut_behavior.m.js';
-import {queryRequiredElement} from 'chrome://resources/js/util.m.js';
-import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
+
+import {getInstance as getToastManagerInstance} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {FindShortcutBehavior} from 'chrome://resources/js/find_shortcut_behavior.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
-import {assert} from 'chrome://resources/js/assert.m.js';
+import {queryRequiredElement} from 'chrome://resources/js/util.m.js';
+import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
- Polymer({
- is: 'downloads-manager',
+import {BrowserProxy} from './browser_proxy.js';
+import {States} from './constants.js';
+import {SearchService} from './search_service.js';
- _template: html`{__html_template__}`,
+Polymer({
+ is: 'downloads-manager',
- behaviors: [
- FindShortcutBehavior,
- ],
+ _template: html`{__html_template__}`,
- properties: {
- /** @private */
- hasDownloads_: {
- observer: 'hasDownloadsChanged_',
- type: Boolean,
- },
+ behaviors: [
+ FindShortcutBehavior,
+ ],
- /** @private */
- hasShadow_: {
- type: Boolean,
- value: false,
- reflectToAttribute: true,
- },
-
- /** @private */
- inSearchMode_: {
- type: Boolean,
- value: false,
- },
-
- /** @private {!Array<!downloads.Data>} */
- items_: {
- type: Array,
- value: function() {
- return [];
- },
- },
-
- /** @private */
- spinnerActive_: {
- type: Boolean,
- notify: true,
- },
-
- /** @private {Element} */
- lastFocused_: Object,
-
- /** @private */
- listBlurred_: Boolean,
+ properties: {
+ /** @private */
+ hasDownloads_: {
+ observer: 'hasDownloadsChanged_',
+ type: Boolean,
},
- hostAttributes: {
- // TODO(dbeam): this should use a class instead.
- loading: true,
+ /** @private */
+ hasShadow_: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true,
},
- observers: [
- 'itemsChanged_(items_.*)',
- ],
-
- /** @private {downloads.mojom.PageCallbackRouter} */
- mojoEventTarget_: null,
-
- /** @private {downloads.mojom.PageHandlerInterface} */
- mojoHandler_: null,
-
- /** @private {?SearchService} */
- searchService_: null,
-
- /** @private {!PromiseResolver} */
- loaded_: new PromiseResolver,
-
- /** @private {Array<number>} */
- listenerIds_: null,
-
- /** @private {?Function} */
- boundOnKeyDown_: null,
-
- /** @override */
- created: function() {
- const browserProxy = BrowserProxy.getInstance();
- this.mojoEventTarget_ = browserProxy.callbackRouter;
- this.mojoHandler_ = browserProxy.handler;
- this.searchService_ = SearchService.getInstance();
-
- // Regular expression that captures the leading slash, the content and the
- // trailing slash in three different groups.
- const CANONICAL_PATH_REGEX = /(^\/)([\/-\w]+)(\/$)/;
- const path = location.pathname.replace(CANONICAL_PATH_REGEX, '$1$2');
- if (path !== '/') { // There are no subpages in chrome://downloads.
- window.history.replaceState(undefined /* stateObject */, '', '/');
- }
+ /** @private */
+ inSearchMode_: {
+ type: Boolean,
+ value: false,
},
- /** @override */
- attached: function() {
- document.documentElement.classList.remove('loading');
- this.listenerIds_ = [
- this.mojoEventTarget_.clearAll.addListener(this.clearAll_.bind(this)),
- this.mojoEventTarget_.insertItems.addListener(
- this.insertItems_.bind(this)),
- this.mojoEventTarget_.removeItem.addListener(
- this.removeItem_.bind(this)),
- this.mojoEventTarget_.updateItem.addListener(
- this.updateItem_.bind(this)),
- ];
+ /** @private {!Array<!downloads.Data>} */
+ items_: {
+ type: Array,
+ value: function() {
+ return [];
+ },
+ },
- this.boundOnKeyDown_ = e => this.onKeyDown_(e);
- document.addEventListener('keydown', this.boundOnKeyDown_);
+ /** @private */
+ spinnerActive_: {
+ type: Boolean,
+ notify: true,
+ },
- this.loaded_.promise.then(() => {
- requestIdleCallback(function() {
- chrome.send(
- 'metricsHandler:recordTime',
- ['Download.ResultsRenderedTime', window.performance.now()]);
- document.fonts.load('bold 12px Roboto');
- });
+ /** @private {Element} */
+ lastFocused_: Object,
+
+ /** @private */
+ listBlurred_: Boolean,
+ },
+
+ hostAttributes: {
+ // TODO(dbeam): this should use a class instead.
+ loading: true,
+ },
+
+ observers: [
+ 'itemsChanged_(items_.*)',
+ ],
+
+ /** @private {downloads.mojom.PageCallbackRouter} */
+ mojoEventTarget_: null,
+
+ /** @private {downloads.mojom.PageHandlerInterface} */
+ mojoHandler_: null,
+
+ /** @private {?SearchService} */
+ searchService_: null,
+
+ /** @private {!PromiseResolver} */
+ loaded_: new PromiseResolver,
+
+ /** @private {Array<number>} */
+ listenerIds_: null,
+
+ /** @private {?Function} */
+ boundOnKeyDown_: null,
+
+ /** @override */
+ created: function() {
+ const browserProxy = BrowserProxy.getInstance();
+ this.mojoEventTarget_ = browserProxy.callbackRouter;
+ this.mojoHandler_ = browserProxy.handler;
+ this.searchService_ = SearchService.getInstance();
+
+ // Regular expression that captures the leading slash, the content and the
+ // trailing slash in three different groups.
+ const CANONICAL_PATH_REGEX = /(^\/)([\/-\w]+)(\/$)/;
+ const path = location.pathname.replace(CANONICAL_PATH_REGEX, '$1$2');
+ if (path !== '/') { // There are no subpages in chrome://downloads.
+ window.history.replaceState(undefined /* stateObject */, '', '/');
+ }
+ },
+
+ /** @override */
+ attached: function() {
+ document.documentElement.classList.remove('loading');
+ this.listenerIds_ = [
+ this.mojoEventTarget_.clearAll.addListener(this.clearAll_.bind(this)),
+ this.mojoEventTarget_.insertItems.addListener(
+ this.insertItems_.bind(this)),
+ this.mojoEventTarget_.removeItem.addListener(this.removeItem_.bind(this)),
+ this.mojoEventTarget_.updateItem.addListener(this.updateItem_.bind(this)),
+ ];
+
+ this.boundOnKeyDown_ = e => this.onKeyDown_(e);
+ document.addEventListener('keydown', this.boundOnKeyDown_);
+
+ this.loaded_.promise.then(() => {
+ requestIdleCallback(function() {
+ chrome.send(
+ 'metricsHandler:recordTime',
+ ['Download.ResultsRenderedTime', window.performance.now()]);
+ document.fonts.load('bold 12px Roboto');
});
+ });
- this.searchService_.loadMore();
- },
+ this.searchService_.loadMore();
+ },
- /** @override */
- detached: function() {
- this.listenerIds_.forEach(
- id => assert(this.mojoEventTarget_.removeListener(id)));
+ /** @override */
+ detached: function() {
+ this.listenerIds_.forEach(
+ id => assert(this.mojoEventTarget_.removeListener(id)));
- document.removeEventListener('keydown', this.boundOnKeyDown_);
- this.boundOnKeyDown_ = null;
- },
+ document.removeEventListener('keydown', this.boundOnKeyDown_);
+ this.boundOnKeyDown_ = null;
+ },
- /** @private */
- clearAll_: function() {
- this.set('items_', []);
- },
+ /** @private */
+ clearAll_: function() {
+ this.set('items_', []);
+ },
- /** @private */
- hasDownloadsChanged_: function() {
- if (this.hasDownloads_) {
- this.$.downloadsList.fire('iron-resize');
- }
- },
+ /** @private */
+ hasDownloadsChanged_: function() {
+ if (this.hasDownloads_) {
+ this.$.downloadsList.fire('iron-resize');
+ }
+ },
- /**
- * @param {number} index
- * @param {!Array<downloads.Data>} items
- * @private
- */
- insertItems_: function(index, items) {
- // Insert |items| at the given |index| via Array#splice().
- if (items.length > 0) {
- this.items_.splice.apply(this.items_, [index, 0].concat(items));
- this.updateHideDates_(index, index + items.length);
- this.notifySplices('items_', [{
- index: index,
- addedCount: items.length,
- object: this.items_,
- type: 'splice',
- removed: [],
- }]);
- }
-
- if (this.hasAttribute('loading')) {
- this.removeAttribute('loading');
- this.loaded_.resolve();
- }
-
- this.spinnerActive_ = false;
- },
-
- /** @private */
- itemsChanged_: function() {
- this.hasDownloads_ = this.items_.length > 0;
- this.$.toolbar.hasClearableDownloads =
- loadTimeData.getBoolean('allowDeletingHistory') &&
- this.items_.some(
- ({state}) => state != States.DANGEROUS &&
- state != States.IN_PROGRESS &&
- state != States.PAUSED);
-
- if (this.inSearchMode_) {
- IronA11yAnnouncer.requestAvailability();
- this.fire('iron-announce', {
- text: this.items_.length == 0 ?
- this.noDownloadsText_() :
- (this.items_.length == 1 ?
- loadTimeData.getStringF(
- 'searchResultsSingular',
- this.$.toolbar.getSearchText()) :
- loadTimeData.getStringF(
- 'searchResultsPlural', this.items_.length,
- this.$.toolbar.getSearchText()))
- });
- }
- },
-
- /**
- * @return {string} The text to show when no download items are showing.
- * @private
- */
- noDownloadsText_: function() {
- return loadTimeData.getString(
- this.inSearchMode_ ? 'noSearchResults' : 'noDownloads');
- },
-
- /**
- * @param {!KeyboardEvent} e
- * @private
- */
- onKeyDown_: function(e) {
- let clearAllKey = 'c';
- // <if expr="is_macosx">
- // On Mac, pressing alt+c produces 'ç' as |event.key|.
- clearAllKey = 'ç';
- // </if>
- if (e.key === clearAllKey && e.altKey && !e.ctrlKey && !e.shiftKey &&
- !e.metaKey) {
- this.onClearAllCommand_();
- e.preventDefault();
- return;
- }
-
- if (e.key === 'z' && !e.altKey && !e.shiftKey) {
- let hasTriggerModifier = e.ctrlKey && !e.metaKey;
- // <if expr="is_macosx">
- hasTriggerModifier = !e.ctrlKey && e.metaKey;
- // </if>
- if (hasTriggerModifier) {
- this.onUndoCommand_();
- e.preventDefault();
- }
- }
- },
-
- /** @private */
- onClearAllCommand_() {
- if (!this.$.toolbar.canClearAll()) {
- return;
- }
-
- this.mojoHandler_.clearAll();
- getToastManagerInstance().show(
- loadTimeData.getString('toastClearedAll'), true);
- },
-
- /** @private */
- onUndoCommand_() {
- if (!this.$.toolbar.canUndo()) {
- return;
- }
-
- getToastManagerInstance().hide();
- this.mojoHandler_.undo();
- },
-
- /** @private */
- onScroll_: function() {
- const container = this.$.downloadsList.scrollTarget;
- const distanceToBottom =
- container.scrollHeight - container.scrollTop - container.offsetHeight;
- if (distanceToBottom <= 100) {
- // Approaching the end of the scrollback. Attempt to load more items.
- this.searchService_.loadMore();
- }
- this.hasShadow_ = container.scrollTop > 0;
- },
-
- /** @private */
- onSearchChanged_: function() {
- this.inSearchMode_ = this.searchService_.isSearching();
- },
-
- /**
- * @param {number} index
- * @private
- */
- removeItem_: function(index) {
- const removed = this.items_.splice(index, 1);
- this.updateHideDates_(index, index);
+ /**
+ * @param {number} index
+ * @param {!Array<downloads.Data>} items
+ * @private
+ */
+ insertItems_: function(index, items) {
+ // Insert |items| at the given |index| via Array#splice().
+ if (items.length > 0) {
+ this.items_.splice.apply(this.items_, [index, 0].concat(items));
+ this.updateHideDates_(index, index + items.length);
this.notifySplices('items_', [{
index: index,
- addedCount: 0,
+ addedCount: items.length,
object: this.items_,
type: 'splice',
- removed: removed,
+ removed: [],
}]);
- this.onScroll_();
- },
+ }
- /** @private */
- onUndoClick_: function() {
- getToastManagerInstance().hide();
- this.mojoHandler_.undo();
- },
+ if (this.hasAttribute('loading')) {
+ this.removeAttribute('loading');
+ this.loaded_.resolve();
+ }
- /**
- * Updates whether dates should show for |this.items_[start - end]|. Note:
- * this method does not trigger template bindings. Use notifySplices() or
- * after calling this method to ensure items are redrawn.
- * @param {number} start
- * @param {number} end
- * @private
- */
- updateHideDates_: function(start, end) {
- for (let i = start; i <= end; ++i) {
- const current = this.items_[i];
- if (!current) {
- continue;
- }
- const prev = this.items_[i - 1];
- current.hideDate = !!prev && prev.dateString == current.dateString;
- }
- },
+ this.spinnerActive_ = false;
+ },
- /**
- * @param {number} index
- * @param {!downloads.Data} data
- * @private
- */
- updateItem_: function(index, data) {
- this.items_[index] = data;
- this.updateHideDates_(index, index);
+ /** @private */
+ itemsChanged_: function() {
+ this.hasDownloads_ = this.items_.length > 0;
+ this.$.toolbar.hasClearableDownloads =
+ loadTimeData.getBoolean('allowDeletingHistory') &&
+ this.items_.some(
+ ({state}) => state != States.DANGEROUS &&
+ state != States.IN_PROGRESS && state != States.PAUSED);
- this.notifyPath(`items_.${index}`);
- this.async(() => {
- const list = /** @type {!IronListElement} */ (this.$.downloadsList);
- list.updateSizeForIndex(index);
+ if (this.inSearchMode_) {
+ IronA11yAnnouncer.requestAvailability();
+ this.fire('iron-announce', {
+ text: this.items_.length == 0 ?
+ this.noDownloadsText_() :
+ (this.items_.length == 1 ?
+ loadTimeData.getStringF(
+ 'searchResultsSingular', this.$.toolbar.getSearchText()) :
+ loadTimeData.getStringF(
+ 'searchResultsPlural', this.items_.length,
+ this.$.toolbar.getSearchText()))
});
- },
+ }
+ },
- // Override FindShortcutBehavior methods.
- handleFindShortcut: function(modalContextOpen) {
- if (modalContextOpen) {
- return false;
+ /**
+ * @return {string} The text to show when no download items are showing.
+ * @private
+ */
+ noDownloadsText_: function() {
+ return loadTimeData.getString(
+ this.inSearchMode_ ? 'noSearchResults' : 'noDownloads');
+ },
+
+ /**
+ * @param {!KeyboardEvent} e
+ * @private
+ */
+ onKeyDown_: function(e) {
+ let clearAllKey = 'c';
+ // <if expr="is_macosx">
+ // On Mac, pressing alt+c produces 'ç' as |event.key|.
+ clearAllKey = 'ç';
+ // </if>
+ if (e.key === clearAllKey && e.altKey && !e.ctrlKey && !e.shiftKey &&
+ !e.metaKey) {
+ this.onClearAllCommand_();
+ e.preventDefault();
+ return;
+ }
+
+ if (e.key === 'z' && !e.altKey && !e.shiftKey) {
+ let hasTriggerModifier = e.ctrlKey && !e.metaKey;
+ // <if expr="is_macosx">
+ hasTriggerModifier = !e.ctrlKey && e.metaKey;
+ // </if>
+ if (hasTriggerModifier) {
+ this.onUndoCommand_();
+ e.preventDefault();
}
- this.$.toolbar.focusOnSearchInput();
- return true;
- },
+ }
+ },
- // Override FindShortcutBehavior methods.
- searchInputHasFocus: function() {
- return this.$.toolbar.isSearchFocused();
- },
- });
+ /** @private */
+ onClearAllCommand_() {
+ if (!this.$.toolbar.canClearAll()) {
+ return;
+ }
+
+ this.mojoHandler_.clearAll();
+ getToastManagerInstance().show(
+ loadTimeData.getString('toastClearedAll'), true);
+ },
+
+ /** @private */
+ onUndoCommand_() {
+ if (!this.$.toolbar.canUndo()) {
+ return;
+ }
+
+ getToastManagerInstance().hide();
+ this.mojoHandler_.undo();
+ },
+
+ /** @private */
+ onScroll_: function() {
+ const container = this.$.downloadsList.scrollTarget;
+ const distanceToBottom =
+ container.scrollHeight - container.scrollTop - container.offsetHeight;
+ if (distanceToBottom <= 100) {
+ // Approaching the end of the scrollback. Attempt to load more items.
+ this.searchService_.loadMore();
+ }
+ this.hasShadow_ = container.scrollTop > 0;
+ },
+
+ /** @private */
+ onSearchChanged_: function() {
+ this.inSearchMode_ = this.searchService_.isSearching();
+ },
+
+ /**
+ * @param {number} index
+ * @private
+ */
+ removeItem_: function(index) {
+ const removed = this.items_.splice(index, 1);
+ this.updateHideDates_(index, index);
+ this.notifySplices('items_', [{
+ index: index,
+ addedCount: 0,
+ object: this.items_,
+ type: 'splice',
+ removed: removed,
+ }]);
+ this.onScroll_();
+ },
+
+ /** @private */
+ onUndoClick_: function() {
+ getToastManagerInstance().hide();
+ this.mojoHandler_.undo();
+ },
+
+ /**
+ * Updates whether dates should show for |this.items_[start - end]|. Note:
+ * this method does not trigger template bindings. Use notifySplices() or
+ * after calling this method to ensure items are redrawn.
+ * @param {number} start
+ * @param {number} end
+ * @private
+ */
+ updateHideDates_: function(start, end) {
+ for (let i = start; i <= end; ++i) {
+ const current = this.items_[i];
+ if (!current) {
+ continue;
+ }
+ const prev = this.items_[i - 1];
+ current.hideDate = !!prev && prev.dateString == current.dateString;
+ }
+ },
+
+ /**
+ * @param {number} index
+ * @param {!downloads.Data} data
+ * @private
+ */
+ updateItem_: function(index, data) {
+ this.items_[index] = data;
+ this.updateHideDates_(index, index);
+
+ this.notifyPath(`items_.${index}`);
+ this.async(() => {
+ const list = /** @type {!IronListElement} */ (this.$.downloadsList);
+ list.updateSizeForIndex(index);
+ });
+ },
+
+ // Override FindShortcutBehavior methods.
+ handleFindShortcut: function(modalContextOpen) {
+ if (modalContextOpen) {
+ return false;
+ }
+ this.$.toolbar.focusOnSearchInput();
+ return true;
+ },
+
+ // Override FindShortcutBehavior methods.
+ searchInputHasFocus: function() {
+ return this.$.toolbar.isSearchFocused();
+ },
+});
diff --git a/chrome/browser/resources/downloads/search_service.js b/chrome/browser/resources/downloads/search_service.js
index 012d2d71..f1af2cae 100644
--- a/chrome/browser/resources/downloads/search_service.js
+++ b/chrome/browser/resources/downloads/search_service.js
@@ -3,70 +3,71 @@
// found in the LICENSE file.
import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
-import {BrowserProxy} from './browser_proxy.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
- export class SearchService {
- constructor() {
- /** @private {!Array<string>} */
- this.searchTerms_ = [];
+import {BrowserProxy} from './browser_proxy.js';
- /** @private {downloads.mojom.PageHandlerInterface} */
- this.mojoHandler_ = BrowserProxy.getInstance().handler;
- }
+export class SearchService {
+ constructor() {
+ /** @private {!Array<string>} */
+ this.searchTerms_ = [];
- /**
- * @param {string} searchText Input typed by the user into a search box.
- * @return {Array<string>} A list of terms extracted from |searchText|.
- */
- static splitTerms(searchText) {
- // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
- return searchText.split(/"([^"]*)"/).map(s => s.trim()).filter(s => !!s);
- }
+ /** @private {downloads.mojom.PageHandlerInterface} */
+ this.mojoHandler_ = BrowserProxy.getInstance().handler;
+ }
- /** Instructs the browser to clear all finished downloads. */
- clearAll() {
- if (loadTimeData.getBoolean('allowDeletingHistory')) {
- this.mojoHandler_.clearAll();
- this.search('');
- }
- }
+ /**
+ * @param {string} searchText Input typed by the user into a search box.
+ * @return {Array<string>} A list of terms extracted from |searchText|.
+ */
+ static splitTerms(searchText) {
+ // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
+ return searchText.split(/"([^"]*)"/).map(s => s.trim()).filter(s => !!s);
+ }
- /** Loads more downloads with the current search terms. */
- loadMore() {
- this.mojoHandler_.getDownloads(this.searchTerms_);
- }
-
- /**
- * @return {boolean} Whether the user is currently searching for downloads
- * (i.e. has a non-empty search term).
- */
- isSearching() {
- return this.searchTerms_.length > 0;
- }
-
- /**
- * @param {string} searchText What to search for.
- * @return {boolean} Whether |searchText| resulted in new search terms.
- */
- search(searchText) {
- const searchTerms = SearchService.splitTerms(searchText);
- let sameTerms = searchTerms.length == this.searchTerms_.length;
-
- for (let i = 0; sameTerms && i < searchTerms.length; ++i) {
- if (searchTerms[i] != this.searchTerms_[i]) {
- sameTerms = false;
- }
- }
-
- if (sameTerms) {
- return false;
- }
-
- this.searchTerms_ = searchTerms;
- this.loadMore();
- return true;
+ /** Instructs the browser to clear all finished downloads. */
+ clearAll() {
+ if (loadTimeData.getBoolean('allowDeletingHistory')) {
+ this.mojoHandler_.clearAll();
+ this.search('');
}
}
- addSingletonGetter(SearchService);
+ /** Loads more downloads with the current search terms. */
+ loadMore() {
+ this.mojoHandler_.getDownloads(this.searchTerms_);
+ }
+
+ /**
+ * @return {boolean} Whether the user is currently searching for downloads
+ * (i.e. has a non-empty search term).
+ */
+ isSearching() {
+ return this.searchTerms_.length > 0;
+ }
+
+ /**
+ * @param {string} searchText What to search for.
+ * @return {boolean} Whether |searchText| resulted in new search terms.
+ */
+ search(searchText) {
+ const searchTerms = SearchService.splitTerms(searchText);
+ let sameTerms = searchTerms.length == this.searchTerms_.length;
+
+ for (let i = 0; sameTerms && i < searchTerms.length; ++i) {
+ if (searchTerms[i] != this.searchTerms_[i]) {
+ sameTerms = false;
+ }
+ }
+
+ if (sameTerms) {
+ return false;
+ }
+
+ this.searchTerms_ = searchTerms;
+ this.loadMore();
+ return true;
+ }
+}
+
+addSingletonGetter(SearchService);
diff --git a/chrome/browser/resources/downloads/toolbar.html b/chrome/browser/resources/downloads/toolbar.html
index a83d4da..4b2de7ef 100644
--- a/chrome/browser/resources/downloads/toolbar.html
+++ b/chrome/browser/resources/downloads/toolbar.html
@@ -1,39 +1,39 @@
- <style include="cr-hidden-style">
- :host {
- align-items: center;
- display: flex;
- min-height: 56px;
- }
+<style include="cr-hidden-style">
+ :host {
+ align-items: center;
+ display: flex;
+ min-height: 56px;
+ }
- #toolbar {
- flex: 1;
- }
+ #toolbar {
+ flex: 1;
+ }
- cr-icon-button {
- --cr-icon-button-fill-color-focus: var(--cr-toolbar-background-color);
- justify-content: flex-end;
- margin: 4px;
- }
+ cr-icon-button {
+ --cr-icon-button-fill-color-focus: var(--cr-toolbar-background-color);
+ justify-content: flex-end;
+ margin: 4px;
+ }
- @media (prefers-color-scheme: light) {
- cr-icon-button {
- --cr-icon-button-color: currentColor;
- }
- }
- </style>
- <cr-toolbar id="toolbar" page-name="$i18n{title}"
- search-prompt="$i18n{search}" clear-label="$i18n{clearSearch}"
- spinner-active="{{spinnerActive}}" on-search-changed="onSearchChanged_">
- <cr-icon-button id="moreActions" iron-icon="cr:more-vert"
- class="dropdown-trigger" title="$i18n{moreActions}"
- on-click="onMoreActionsTap_" aria-haspopup="menu"></cr-icon-button>
- </cr-toolbar>
- <cr-action-menu id="moreActionsMenu"
- role-description="$i18n{actionMenuDescription}">
- <button class="dropdown-item clear-all" on-click="onClearAllTap_">
- $i18n{clearAll}
- </button>
- <button class="dropdown-item" on-click="onOpenDownloadsFolderTap_">
- $i18n{openDownloadsFolder}
- </button>
- </cr-action-menu>
+ @media (prefers-color-scheme: light) {
+ cr-icon-button {
+ --cr-icon-button-color: currentColor;
+ }
+ }
+</style>
+<cr-toolbar id="toolbar" page-name="$i18n{title}"
+ search-prompt="$i18n{search}" clear-label="$i18n{clearSearch}"
+ spinner-active="{{spinnerActive}}" on-search-changed="onSearchChanged_">
+ <cr-icon-button id="moreActions" iron-icon="cr:more-vert"
+ class="dropdown-trigger" title="$i18n{moreActions}"
+ on-click="onMoreActionsTap_" aria-haspopup="menu"></cr-icon-button>
+</cr-toolbar>
+<cr-action-menu id="moreActionsMenu"
+ role-description="$i18n{actionMenuDescription}">
+ <button class="dropdown-item clear-all" on-click="onClearAllTap_">
+ $i18n{clearAll}
+ </button>
+ <button class="dropdown-item" on-click="onOpenDownloadsFolderTap_">
+ $i18n{openDownloadsFolder}
+ </button>
+</cr-action-menu>
diff --git a/chrome/browser/resources/downloads/toolbar.js b/chrome/browser/resources/downloads/toolbar.js
index cde85aa..483853b 100644
--- a/chrome/browser/resources/downloads/toolbar.js
+++ b/chrome/browser/resources/downloads/toolbar.js
@@ -2,107 +2,112 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import {Polymer, html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {SearchService} from './search_service.js';
-import {BrowserProxy} from './browser_proxy.js';
import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js';
import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
-import {getInstance} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js';
import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.m.js';
import 'chrome://resources/cr_elements/hidden_style_css.m.js';
import 'chrome://resources/cr_elements/icons.m.js';
import 'chrome://resources/cr_elements/shared_vars_css.m.js';
-import {assert} from 'chrome://resources/js/assert.m.js';
import 'chrome://resources/js/util.m.js';
import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
import './strings.m.js';
+
+import {getInstance} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
- Polymer({
- is: 'downloads-toolbar',
+import {BrowserProxy} from './browser_proxy.js';
+import {SearchService} from './search_service.js';
- _template: html`{__html_template__}`,
+Polymer({
+ is: 'downloads-toolbar',
- properties: {
- hasClearableDownloads: {
- type: Boolean,
- value: false,
- observer: 'updateClearAll_',
- },
+ _template: html`{__html_template__}`,
- spinnerActive: {
- type: Boolean,
- notify: true,
- },
+ properties: {
+ hasClearableDownloads: {
+ type: Boolean,
+ value: false,
+ observer: 'updateClearAll_',
},
- /** @private {?downloads.mojom.PageHandlerInterface} */
- mojoHandler_: null,
-
- /** @override */
- ready: function() {
- this.mojoHandler_ = BrowserProxy.getInstance().handler;
+ spinnerActive: {
+ type: Boolean,
+ notify: true,
},
+ },
- /** @return {boolean} Whether removal can be undone. */
- canUndo: function() {
- return !this.isSearchFocused();
- },
+ /** @private {?downloads.mojom.PageHandlerInterface} */
+ mojoHandler_: null,
- /** @return {boolean} Whether "Clear all" should be allowed. */
- canClearAll: function() {
- return this.getSearchText().length == 0 && this.hasClearableDownloads;
- },
+ /** @override */
+ ready: function() {
+ this.mojoHandler_ = BrowserProxy.getInstance().handler;
+ },
- /** @return {string} The full text being searched. */
- getSearchText: function() {
- return /** @type {!CrToolbarElement} */ (
- this.$.toolbar).getSearchField().getValue();
- },
+ /** @return {boolean} Whether removal can be undone. */
+ canUndo: function() {
+ return !this.isSearchFocused();
+ },
- focusOnSearchInput: function() {
- return /** @type {!CrToolbarElement} */ (
- this.$.toolbar).getSearchField().showAndFocus();
- },
+ /** @return {boolean} Whether "Clear all" should be allowed. */
+ canClearAll: function() {
+ return this.getSearchText().length == 0 && this.hasClearableDownloads;
+ },
- isSearchFocused: function() {
- return /** @type {!CrToolbarElement} */ (
- this.$.toolbar).getSearchField().isSearchFocused();
- },
+ /** @return {string} The full text being searched. */
+ getSearchText: function() {
+ return /** @type {!CrToolbarElement} */ (this.$.toolbar)
+ .getSearchField()
+ .getValue();
+ },
- /** @private */
- onClearAllTap_: function() {
- assert(this.canClearAll());
- this.mojoHandler_.clearAll();
- this.$.moreActionsMenu.close();
- getInstance().show(loadTimeData.getString('toastClearedAll'), true);
- },
+ focusOnSearchInput: function() {
+ return /** @type {!CrToolbarElement} */ (this.$.toolbar)
+ .getSearchField()
+ .showAndFocus();
+ },
- /** @private */
- onMoreActionsTap_: function() {
- this.$.moreActionsMenu.showAt(this.$.moreActions);
- },
+ isSearchFocused: function() {
+ return /** @type {!CrToolbarElement} */ (this.$.toolbar)
+ .getSearchField()
+ .isSearchFocused();
+ },
- /**
- * @param {!CustomEvent<string>} event
- * @private
- */
- onSearchChanged_: function(event) {
- const searchService = SearchService.getInstance();
- if (searchService.search(event.detail)) {
- this.spinnerActive = searchService.isSearching();
- }
- this.updateClearAll_();
- },
+ /** @private */
+ onClearAllTap_: function() {
+ assert(this.canClearAll());
+ this.mojoHandler_.clearAll();
+ this.$.moreActionsMenu.close();
+ getInstance().show(loadTimeData.getString('toastClearedAll'), true);
+ },
- /** @private */
- onOpenDownloadsFolderTap_: function() {
- this.mojoHandler_.openDownloadsFolderRequiringGesture();
- this.$.moreActionsMenu.close();
- },
+ /** @private */
+ onMoreActionsTap_: function() {
+ this.$.moreActionsMenu.showAt(this.$.moreActions);
+ },
- /** @private */
- updateClearAll_: function() {
- this.$$('.clear-all').hidden = !this.canClearAll();
- },
- });
+ /**
+ * @param {!CustomEvent<string>} event
+ * @private
+ */
+ onSearchChanged_: function(event) {
+ const searchService = SearchService.getInstance();
+ if (searchService.search(event.detail)) {
+ this.spinnerActive = searchService.isSearching();
+ }
+ this.updateClearAll_();
+ },
+
+ /** @private */
+ onOpenDownloadsFolderTap_: function() {
+ this.mojoHandler_.openDownloadsFolderRequiringGesture();
+ this.$.moreActionsMenu.close();
+ },
+
+ /** @private */
+ updateClearAll_: function() {
+ this.$$('.clear-all').hidden = !this.canClearAll();
+ },
+});