Commit 656beed0 authored by John Lee's avatar John Lee Committed by Commit Bot

WebUI Tab Strip: Hide elements when they get dragged out of tab strip

This CL hides tabs and tab groups when they are dragged out of tab
strip to indicate that the tab will leave the current window when
dropped. The elements must be hidden and not removed from the DOM
because once the elements are removed from the DOM, the drag events no
longer get bubbled to its parent.

Bug: 1081905
Change-Id: Ia4d52280362c320648e7cd105e333c62bfb723ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2285067
Commit-Queue: John Lee <johntlee@chromium.org>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#786036}
parent 84da473a
......@@ -226,6 +226,7 @@ class DragSession {
}
this.element_.setDragging(false);
this.element_.setDraggedOut(false);
}
/** @return {boolean} */
......@@ -277,6 +278,7 @@ class DragSession {
}
this.element_.setDragging(false);
this.element_.setDraggedOut(false);
}
/**
......@@ -336,7 +338,13 @@ class DragSession {
/** @param {!DragEvent} event */
update(event) {
if (event.type === 'dragleave') {
this.element_.setDraggedOut(true);
return;
}
event.dataTransfer.dropEffect = 'move';
this.element_.setDraggedOut(false);
if (isTabGroupElement(this.element_)) {
this.updateForTabGroupElement_(event);
} else if (isTabElement(this.element_)) {
......@@ -439,14 +447,18 @@ export class DragManager {
this.tabsProxy_ = TabsApiProxyImpl.getInstance();
}
/** @private */
onDragLeave_() {
if (this.dragSession_ && !this.dragSession_.isDraggingPlaceholder()) {
/**
* @param {!DragEvent} event
* @private
*/
onDragLeave_(event) {
if (this.dragSession_ && this.dragSession_.isDraggingPlaceholder()) {
this.dragSession_.cancel();
this.dragSession_ = null;
return;
}
this.dragSession_.cancel();
this.dragSession_ = null;
this.dragSession_.update(event);
}
/** @param {!DragEvent} event */
......@@ -488,6 +500,7 @@ export class DragManager {
/** @param {!DragEvent} event */
onDragEnter_(event) {
if (this.dragSession_) {
this.dragSession_.update(event);
return;
}
......@@ -512,8 +525,9 @@ export class DragManager {
this.delegate_.addEventListener(
'dragend', e => this.onDragEnd_(/** @type {!DragEvent} */ (e)));
this.delegate_.addEventListener(
'dragenter', (e) => this.onDragEnter_(/** @type {!DragEvent} */ (e)));
this.delegate_.addEventListener('dragleave', () => this.onDragLeave_());
'dragenter', e => this.onDragEnter_(/** @type {!DragEvent} */ (e)));
this.delegate_.addEventListener(
'dragleave', e => this.onDragLeave_(/** @type {!DragEvent} */ (e)));
this.delegate_.addEventListener(
'dragover', e => this.onDragOver_(/** @type {!DragEvent} */ (e)));
this.delegate_.addEventListener(
......
......@@ -14,6 +14,10 @@
transform-origin: top right;
}
:host([dragged-out_]) {
display: none;
}
#tab {
background: var(--tabstrip-tab-background-color);
border-radius: var(--tabstrip-tab-border-radius);
......
......@@ -276,6 +276,11 @@ export class TabElement extends CustomElement {
this.toggleAttribute('dragging_', isDragging);
}
/** @param {boolean} isDraggedOut */
setDraggedOut(isDraggedOut) {
this.toggleAttribute('dragged-out_', isDraggedOut);
}
/**
* @return {!Promise}
*/
......
......@@ -9,6 +9,10 @@
display: none;
}
:host([dragged-out_]) {
display: none;
}
#tabGroup {
border-radius: 8px;
box-shadow: 0 0 0 1px rgb(var(--tabstrip-tab-group-color-rgb));
......
......@@ -85,6 +85,11 @@ export class TabGroupElement extends CustomElement {
});
}
/** @param {boolean} isDraggedOut */
setDraggedOut(isDraggedOut) {
this.toggleAttribute('dragged-out_', isDraggedOut);
}
/**
* @param {!TabGroupVisualData} visualData
*/
......
......@@ -599,4 +599,29 @@ suite('DragManager', () => {
assertEquals(draggedTab, delegate.children[draggedIndex]);
assertEquals(dragOverTab, delegate.children[dragOverIndex]);
});
test('DragLeaveUpdatesElementsAsDraggedOut', () => {
let isDraggedOut = false;
// Mock a tab's setDraggedOut method to ensure it is called.
const draggedTab = delegate.children[0];
draggedTab.setDraggedOut = (isDraggedOutParam) => {
isDraggedOut = isDraggedOutParam;
};
const dataTransfer = new MockDataTransfer();
draggedTab.dispatchEvent(new DragEvent('dragstart', {
bubbles: true,
composed: true,
clientX: 100,
clientY: 150,
dataTransfer,
}));
delegate.dispatchEvent(new DragEvent('dragleave', {dataTransfer}));
assertTrue(isDraggedOut);
delegate.dispatchEvent(new DragEvent('dragenter', {dataTransfer}));
assertFalse(isDraggedOut);
});
});
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