Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Unified Diff: third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js

Issue 2771413006: Revert of [DevTools] Migrate SoftContextMenu to use GlassPane (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js b/third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js
index aa43be97ea93d6c8c5b6f32b69a9de822752b784..1f905c91545ae1cd73d2db88ea4479134a4ee13d 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js
@@ -40,28 +40,26 @@
/**
* @param {!Document} document
- * @param {!AnchorBox} anchorBox
+ * @param {number} x
+ * @param {number} y
*/
- show(document, anchorBox) {
+ show(document, x, y) {
if (!this._items.length)
return;
this._document = document;
-
- this._glassPane = new UI.GlassPane();
- this._glassPane.setBlockPointerEvents(!this._parentMenu);
- this._glassPane.setSetOutsideClickCallback(event => {
- this._discardMenu(true, event);
- event.consume();
- });
- this._glassPane.registerRequiredCSS('ui/softContextMenu.css');
- this._glassPane.setContentAnchorBox(anchorBox);
- this._glassPane.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
- this._glassPane.setMarginBehavior(UI.GlassPane.MarginBehavior.NoMargin);
- this._glassPane.setAnchorBehavior(
- this._parentMenu ? UI.GlassPane.AnchorBehavior.PreferRight : UI.GlassPane.AnchorBehavior.PreferBottom);
-
- this._contextMenuElement = this._glassPane.contentElement.createChild('div', 'soft-context-menu');
+ this._x = x;
+ this._y = y;
+ this._time = new Date().getTime();
+
+ // Create context menu.
+ this.element = createElementWithClass('div', 'soft-context-menu');
+ var root = UI.createShadowRootWithCoreStyles(this.element, 'ui/softContextMenu.css');
+ this._contextMenuElement = root.createChild('div');
+ this.element.style.top = y + 'px';
+ var subMenuOverlap = 3;
+ this.element.style.left = (this._parentMenu ? x - subMenuOverlap : x) + 'px';
+
this._contextMenuElement.tabIndex = 0;
this._contextMenuElement.addEventListener('mouseup', e => e.consume(), false);
this._contextMenuElement.addEventListener('keydown', this._menuKeyDown.bind(this), false);
@@ -69,12 +67,53 @@
for (var i = 0; i < this._items.length; ++i)
this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));
- this._glassPane.show(document);
+ // Install glass pane capturing events.
+ if (!this._parentMenu) {
+ this._glassPaneElement = createElementWithClass('div', 'soft-context-menu-glass-pane fill');
+ this._glassPaneElement.tabIndex = 0;
+ this._glassPaneElement.style.zIndex = '20000';
+ this._glassPaneElement.addEventListener('mouseup', this._glassPaneMouseUp.bind(this), false);
+ this._glassPaneElement.appendChild(this.element);
+ document.body.appendChild(this._glassPaneElement);
+ this._discardMenuOnResizeListener = this._discardMenu.bind(this, true);
+ document.defaultView.addEventListener('resize', this._discardMenuOnResizeListener, false);
+ } else {
+ this._parentMenu._parentGlassPaneElement().appendChild(this.element);
+ }
+
+ // Re-position menu in case it does not fit.
+ var containerElement = UI.GlassPane.container(document);
+ var hostLeft = containerElement.totalOffsetLeft();
+ var hostRight = hostLeft + containerElement.offsetWidth;
+ if (hostRight < this.element.offsetLeft + this.element.offsetWidth) {
+ var left = this._parentMenu ? this._parentMenu.element.offsetLeft - this.element.offsetWidth + subMenuOverlap :
+ hostRight - this.element.offsetWidth;
+ this.element.style.left = Math.max(hostLeft, left) + 'px';
+ }
+
+ // Move submenus upwards if it does not fit.
+ if (this._parentMenu && document.body.offsetHeight < this.element.offsetTop + this.element.offsetHeight) {
+ y = Math.max(containerElement.totalOffsetTop(), document.body.offsetHeight - this.element.offsetHeight);
+ this.element.style.top = y + 'px';
+ }
+
+ var maxHeight = containerElement.offsetHeight;
+ maxHeight -= y - containerElement.totalOffsetTop();
+ this.element.style.maxHeight = maxHeight + 'px';
+
this._focus();
}
discard() {
this._discardMenu(true);
+ }
+
+ _parentGlassPaneElement() {
+ if (this._glassPaneElement)
+ return this._glassPaneElement;
+ if (this._parentMenu)
+ return this._parentMenu._parentGlassPaneElement();
+ return null;
}
_createMenuItem(item) {
@@ -182,13 +221,10 @@
return;
this._subMenu = new UI.SoftContextMenu(menuItemElement._subItems, this._itemSelectedCallback, this);
- var anchorBox = menuItemElement.boxInWindow();
- // Adjust for padding.
- anchorBox.y -= 5;
- anchorBox.x += 3;
- anchorBox.width -= 6;
- anchorBox.height += 10;
- this._subMenu.show(this._document, anchorBox);
+ var topPadding = 4;
+ this._subMenu.show(
+ this._document, menuItemElement.totalOffsetLeft() + menuItemElement.offsetWidth,
+ menuItemElement.totalOffsetTop() - 1 - topPadding);
}
_hideSubMenu() {
@@ -209,7 +245,7 @@
}
var relatedTarget = event.relatedTarget;
- if (relatedTarget === this._contextMenuElement)
+ if (relatedTarget.classList.contains('soft-context-menu-glass-pane'))
this._highlightMenuItem(null, true);
}
@@ -303,6 +339,16 @@
event.consume(true);
}
+ _glassPaneMouseUp(event) {
+ // Return if this is simple 'click', since dispatched on glass pane, can't use 'click' event.
+ if (new Date().getTime() - this._time < 300)
+ return;
+ if (event.target === this.element)
+ return;
+ this._discardMenu(true, event);
+ event.consume();
+ }
+
/**
* @param {boolean} closeParentMenus
* @param {!Event=} event
@@ -310,27 +356,41 @@
_discardMenu(closeParentMenus, event) {
if (this._subMenu && !closeParentMenus)
return;
-
- this._discardSubMenus();
-
- if (this._parentMenu) {
+ if (this._glassPaneElement) {
+ var glassPane = this._glassPaneElement;
+ delete this._glassPaneElement;
+ // This can re-enter discardMenu due to blur.
+ this._document.body.removeChild(glassPane);
+ if (this._parentMenu) {
+ delete this._parentMenu._subMenu;
+ if (closeParentMenus)
+ this._parentMenu._discardMenu(closeParentMenus, event);
+ else
+ this._parentMenu._focus();
+ }
+
+ if (event)
+ event.consume(true);
+ } else if (this._parentMenu && this._contextMenuElement.parentElementOrShadowHost()) {
+ this._discardSubMenus();
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);
else
this._parentMenu._focus();
- }
-
- if (event)
- event.consume(true);
+ if (event)
+ event.consume(true);
+ }
+ if (this._discardMenuOnResizeListener) {
+ this._document.defaultView.removeEventListener('resize', this._discardMenuOnResizeListener, false);
+ delete this._discardMenuOnResizeListener;
+ }
}
_discardSubMenus() {
if (this._subMenu)
this._subMenu._discardSubMenus();
- if (this._glassPane) {
- this._glassPane.hide();
- delete this._glassPane;
- }
+ if (this.element)
+ this.element.remove();
if (this._parentMenu)
delete this._parentMenu._subMenu;
}

Powered by Google App Engine
This is Rietveld 408576698