summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources/tab_strip/alert_indicator.js
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-11 11:32:04 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-18 13:40:17 +0000
commit31ccca0778db85c159634478b4ec7997f6704860 (patch)
tree3d33fc3afd9d5ec95541e1bbe074a9cf8da12a0e /chromium/chrome/browser/resources/tab_strip/alert_indicator.js
parent248b70b82a40964d5594eb04feca0fa36716185d (diff)
BASELINE: Update Chromium to 80.0.3987.136
Change-Id: I98e1649aafae85ba3a83e67af00bb27ef301db7b Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources/tab_strip/alert_indicator.js')
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicator.js178
1 files changed, 174 insertions, 4 deletions
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicator.js b/chromium/chrome/browser/resources/tab_strip/alert_indicator.js
index 2d41eab42f6..f2120ba7ec1 100644
--- a/chromium/chrome/browser/resources/tab_strip/alert_indicator.js
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicator.js
@@ -2,17 +2,187 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import './strings.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+
import {CustomElement} from './custom_element.js';
+import {TabAlertState} from './tabs_api_proxy.js';
+
+/** @const {string} */
+const MAX_WIDTH = '16px';
+
+/**
+ * @param {!TabAlertState} alertState
+ * @return {string}
+ */
+function getAriaLabel(alertState) {
+ // The existing labels for alert states currently expects to format itself
+ // using the title of the tab (eg. "Website - Audio is playing"). The WebUI
+ // tab strip will provide the title of the tab elsewhere outside of this
+ // element, so just provide an empty string as the title here. This also
+ // allows for multiple labels for the same title (eg. "Website - Audio is
+ // playing - VR is presenting").
+ switch (alertState) {
+ case TabAlertState.MEDIA_RECORDING:
+ return loadTimeData.getStringF('mediaRecording', '');
+ case TabAlertState.TAB_CAPTURING:
+ return loadTimeData.getStringF('tabCapturing', '');
+ case TabAlertState.AUDIO_PLAYING:
+ return loadTimeData.getStringF('audioPlaying', '');
+ case TabAlertState.AUDIO_MUTING:
+ return loadTimeData.getStringF('audioMuting', '');
+ case TabAlertState.BLUETOOTH_CONNECTED:
+ return loadTimeData.getStringF('bluetoothConnected', '');
+ case TabAlertState.USB_CONNECTED:
+ return loadTimeData.getStringF('usbConnected', '');
+ case TabAlertState.SERIAL_CONNECTED:
+ return loadTimeData.getStringF('serialConnected', '');
+ case TabAlertState.PIP_PLAYING:
+ return loadTimeData.getStringF('pipPlaying', '');
+ case TabAlertState.DESKTOP_CAPTURING:
+ return loadTimeData.getStringF('desktopCapturing', '');
+ case TabAlertState.VR_PRESENTING_IN_HEADSET:
+ return loadTimeData.getStringF('vrPresenting', '');
+ default:
+ return '';
+ }
+}
export class AlertIndicatorElement extends CustomElement {
static get template() {
return `{__html_template__}`;
}
- /** @override */
- remove() {
- this.toggleAttribute('fade-out', true);
- this.addEventListener('animationend', () => super.remove(), {once: true});
+ constructor() {
+ super();
+
+ /** @private {!TabAlertState} */
+ this.alertState_;
+
+ /** @private {number} */
+ this.fadeDurationMs_ = 125;
+
+ /**
+ * An animation that is currently in-flight to fade the element in.
+ * @private {?Animation}
+ */
+ this.fadeInAnimation_ = null;
+
+ /**
+ * An animation that is currently in-flight to fade the element out.
+ * @private {?Animation}
+ */
+ this.fadeOutAnimation_ = null;
+
+ /**
+ * A promise that resolves when the fade out animation finishes or rejects
+ * if a fade out animation is canceled.
+ * @private {?Promise}
+ */
+ this.fadeOutAnimationPromise_ = null;
+ }
+
+ /** @return {!TabAlertState} */
+ get alertState() {
+ return this.alertState_;
+ }
+
+ /** @param {!TabAlertState} alertState */
+ set alertState(alertState) {
+ this.setAttribute('alert-state_', alertState);
+ this.setAttribute('aria-label', getAriaLabel(alertState));
+ this.alertState_ = alertState;
+ }
+
+ /** @param {number} duration */
+ overrideFadeDurationForTesting(duration) {
+ this.fadeDurationMs_ = duration;
+ }
+
+ show() {
+ if (this.fadeOutAnimation_) {
+ // Cancel any fade out animations to prevent the element from fading out
+ // and being removed. At this point, the tab's alertStates have changed
+ // to a state in which this indicator should be visible.
+ this.fadeOutAnimation_.cancel();
+ this.fadeOutAnimation_ = null;
+ this.fadeOutAnimationPromise_ = null;
+ }
+
+ if (this.fadeInAnimation_) {
+ // If the element was already faded in, don't fade it in again
+ return;
+ }
+
+
+ if (this.alertState_ === TabAlertState.MEDIA_RECORDING ||
+ this.alertState_ === TabAlertState.TAB_CAPTURING ||
+ this.alertState_ === TabAlertState.DESKTOP_CAPTURING) {
+ // Fade in and out 2 times and then fade in
+ const totalDuration = 2600;
+ this.fadeInAnimation_ = this.animate(
+ [
+ {opacity: 0, maxWidth: 0, offset: 0},
+ {opacity: 1, maxWidth: MAX_WIDTH, offset: 200 / totalDuration},
+ {opacity: 0, maxWidth: MAX_WIDTH, offset: 1200 / totalDuration},
+ {opacity: 1, maxWidth: MAX_WIDTH, offset: 1400 / totalDuration},
+ {opacity: 0, maxWidth: MAX_WIDTH, offset: 2400 / totalDuration},
+ {opacity: 1, maxWidth: MAX_WIDTH, offset: 1},
+ ],
+ {
+ duration: totalDuration,
+ easing: 'linear',
+ fill: 'forwards',
+ });
+ } else {
+ this.fadeInAnimation_ = this.animate(
+ [
+ {opacity: 0, maxWidth: 0},
+ {opacity: 1, maxWidth: MAX_WIDTH},
+ ],
+ {
+ duration: this.fadeDurationMs_,
+ fill: 'forwards',
+ });
+ }
+ }
+
+ /** @return {!Promise} */
+ hide() {
+ if (this.fadeInAnimation_) {
+ // Cancel any fade in animations to prevent the element from fading in. At
+ // this point, the tab's alertStates have changed to a state in which this
+ // indicator should not be visible.
+ this.fadeInAnimation_.cancel();
+ this.fadeInAnimation_ = null;
+ }
+
+ if (this.fadeOutAnimationPromise_) {
+ return this.fadeOutAnimationPromise_;
+ }
+
+ this.fadeOutAnimationPromise_ = new Promise((resolve, reject) => {
+ this.fadeOutAnimation_ = this.animate(
+ [
+ {opacity: 1, maxWidth: MAX_WIDTH},
+ {opacity: 0, maxWidth: 0},
+ ],
+ {
+ duration: this.fadeDurationMs_,
+ fill: 'forwards',
+ });
+ this.fadeOutAnimation_.addEventListener('cancel', () => {
+ reject();
+ });
+ this.fadeOutAnimation_.addEventListener('finish', () => {
+ this.remove();
+ this.fadeOutAnimation_ = null;
+ this.fadeOutAnimationPromise_ = null;
+ resolve();
+ });
+ });
+
+ return this.fadeOutAnimationPromise_;
}
}