Commit d71aaace authored by John Lee's avatar John Lee Committed by Commit Bot

WebUI Tab Strip: Don't animate slideOut when tab strip is closed

This CL also prevents a use case in which the slideOut animation
begins while the tab strip is open but will not end until the tab
strip is in a closed state.

Fixed: 1024620
Change-Id: Id9c7c8dac533bcdff530b1073a0a086a25efde28
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1914836Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Commit-Queue: John Lee <johntlee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715393}
parent 7f8fb9d6
...@@ -268,7 +268,18 @@ export class TabElement extends CustomElement { ...@@ -268,7 +268,18 @@ export class TabElement extends CustomElement {
* @return {!Promise} * @return {!Promise}
*/ */
slideOut() { slideOut() {
if (!this.embedderApi_.isVisible()) {
// There is no point in animating if the tab strip is hidden.
this.remove();
return Promise.resolve();
}
return new Promise(resolve => { return new Promise(resolve => {
const finishCallback = () => {
this.remove();
resolve();
};
const animation = this.animate( const animation = this.animate(
[ [
{maxWidth: 'var(--tabstrip-tab-width)', opacity: 1}, {maxWidth: 'var(--tabstrip-tab-width)', opacity: 1},
...@@ -278,9 +289,24 @@ export class TabElement extends CustomElement { ...@@ -278,9 +289,24 @@ export class TabElement extends CustomElement {
duration: DEFAULT_ANIMATION_DURATION, duration: DEFAULT_ANIMATION_DURATION,
fill: 'forwards', fill: 'forwards',
}); });
const visibilityChangeListener = () => {
if (!this.embedderApi_.isVisible()) {
// If a tab strip becomes hidden during the animation, the onfinish
// event will not get fired until the tab strip becomes visible again.
// Therefore, when the tab strip becomes hidden, immediately call the
// finish callback.
animation.cancel();
finishCallback();
}
};
document.addEventListener(
'visibilitychange', visibilityChangeListener, {once: true});
animation.onfinish = () => { animation.onfinish = () => {
this.remove(); document.removeEventListener(
resolve(); 'visibilitychange', visibilityChangeListener);
finishCallback();
}; };
}); });
} }
......
...@@ -53,23 +53,48 @@ suite('Tab', function() { ...@@ -53,23 +53,48 @@ suite('Tab', function() {
test('slideIn animates in the element', async () => { test('slideIn animates in the element', async () => {
const animationPromise = tabElement.slideIn(); const animationPromise = tabElement.slideIn();
// Before animation completes // Before animation completes.
assertEquals('0', window.getComputedStyle(tabElement).opacity); assertEquals('0', window.getComputedStyle(tabElement).opacity);
assertEquals('0px', window.getComputedStyle(tabElement).maxWidth); assertEquals('0px', window.getComputedStyle(tabElement).maxWidth);
await animationPromise; await animationPromise;
// After animation completes // After animation completes.
assertEquals('1', window.getComputedStyle(tabElement).opacity); assertEquals('1', window.getComputedStyle(tabElement).opacity);
assertEquals('none', window.getComputedStyle(tabElement).maxWidth); assertEquals('none', window.getComputedStyle(tabElement).maxWidth);
}); });
test('slideOut animates out the element', async () => { test('slideOut animates out the element', async () => {
testTabStripEmbedderProxy.setVisible(true);
const animationPromise = tabElement.slideOut(); const animationPromise = tabElement.slideOut();
// Before animation completes // Before animation completes.
assertEquals('1', window.getComputedStyle(tabElement).opacity); assertEquals('1', window.getComputedStyle(tabElement).opacity);
assertEquals('none', window.getComputedStyle(tabElement).maxWidth); assertEquals('none', window.getComputedStyle(tabElement).maxWidth);
assertTrue(tabElement.isConnected);
await animationPromise; await animationPromise;
// After animation completes // After animation completes.
assertFalse(document.body.contains(tabElement)); assertFalse(tabElement.isConnected);
});
test('slideOut does not animate when tab strip is hidden', () => {
testTabStripEmbedderProxy.setVisible(false);
assertTrue(tabElement.isConnected);
tabElement.slideOut();
// The tab should immediately be disconnected without waiting for the
// animation to finish.
assertFalse(tabElement.isConnected);
});
test('slideOut resolves immediately when tab strip becomes hidden', () => {
testTabStripEmbedderProxy.setVisible(true);
assertTrue(tabElement.isConnected);
const animationPromise = tabElement.slideOut();
testTabStripEmbedderProxy.setVisible(false);
document.dispatchEvent(new Event('visibilitychange'));
// The tab should immediately be disconnected without waiting for the
// animation to finish.
assertFalse(tabElement.isConnected);
}); });
test('toggles an [active] attribute when active', () => { test('toggles an [active] attribute when active', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment