Web Inspector: Elements: context menu items in DOM tree should work when not clicking directly on the node representation
https://bugs.webkit.org/show_bug.cgi?id=197541
Reviewed by Timothy Hatcher.
* UserInterface/Views/DOMTreeElement.js:
(WI.DOMTreeElement.prototype.populateDOMNodeContextMenu): Added.
(WI.DOMTreeElement.prototype._populateTagContextMenu): Deleted.
(WI.DOMTreeElement.prototype._populateTextContextMenu): Deleted.
(WI.DOMTreeElement.prototype._populateNodeContextMenu): Deleted.
* UserInterface/Views/DOMTreeOutline.js:
(WI.DOMTreeOutline.prototype.populateContextMenu):
* UserInterface/Views/ContextMenuUtilities.js:
(WI.appendContextMenuItemsForDOMNode):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245495 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog
index 2fb9615..0f4e285 100644
--- a/Source/WebInspectorUI/ChangeLog
+++ b/Source/WebInspectorUI/ChangeLog
@@ -1,3 +1,20 @@
+2019-05-17 Devin Rousso <drousso@apple.com>
+
+ Web Inspector: Elements: context menu items in DOM tree should work when not clicking directly on the node representation
+ https://bugs.webkit.org/show_bug.cgi?id=197541
+
+ Reviewed by Timothy Hatcher.
+
+ * UserInterface/Views/DOMTreeElement.js:
+ (WI.DOMTreeElement.prototype.populateDOMNodeContextMenu): Added.
+ (WI.DOMTreeElement.prototype._populateTagContextMenu): Deleted.
+ (WI.DOMTreeElement.prototype._populateTextContextMenu): Deleted.
+ (WI.DOMTreeElement.prototype._populateNodeContextMenu): Deleted.
+ * UserInterface/Views/DOMTreeOutline.js:
+ (WI.DOMTreeOutline.prototype.populateContextMenu):
+ * UserInterface/Views/ContextMenuUtilities.js:
+ (WI.appendContextMenuItemsForDOMNode):
+
2019-05-17 Joonghun Park <pjh0718@gmail.com>
Implement CSS `display: flow-root` (modern clearfix)
diff --git a/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js b/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
index e1b126f..c435f7d4 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
@@ -207,6 +207,20 @@
contextMenu.appendSeparator();
}
+ if (WI.cssManager.canForcePseudoClasses() && domNode.attached) {
+ contextMenu.appendSeparator();
+
+ let pseudoSubMenu = contextMenu.appendSubMenuItem(WI.UIString("Forced Pseudo-Classes"));
+
+ let enabledPseudoClasses = domNode.enabledPseudoClasses;
+ WI.CSSManager.ForceablePseudoClasses.forEach((pseudoClass) => {
+ let enabled = enabledPseudoClasses.includes(pseudoClass);
+ pseudoSubMenu.appendCheckboxItem(pseudoClass.capitalize(), () => {
+ domNode.setPseudoClassEnabled(pseudoClass, !enabled);
+ }, enabled);
+ });
+ }
+
if (WI.domDebuggerManager.supported && isElement && !domNode.isPseudoElement() && attached) {
contextMenu.appendSeparator();
diff --git a/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js
index 0be9b08..c39534b 100644
--- a/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js
+++ b/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js
@@ -730,33 +730,10 @@
return false;
}
- _populateTagContextMenu(contextMenu, event, subMenus)
+ populateDOMNodeContextMenu(contextMenu, subMenus, event)
{
- let node = this.representedObject;
- let isNonShadowEditable = !node.isInUserAgentShadowTree() && this.editable;
- let attached = node.attached;
-
- if (event.target && event.target.tagName === "A")
- WI.appendContextMenuItemsForURL(contextMenu, event.target.href, {frame: node.frame});
-
- contextMenu.appendSeparator();
-
- this._populateNodeContextMenu(contextMenu, subMenus);
-
- if (this.selected && this.treeOutline && this.treeOutline.selectedTreeElements.length > 1) {
- let forceHidden = !this.treeOutline.selectedTreeElements.every((treeElement) => treeElement.isNodeHidden);
- let label = forceHidden ? WI.UIString("Hide Elements") : WI.UIString("Show Elements");
- contextMenu.appendItem(label, () => {
- if (this.treeOutline)
- this.treeOutline.toggleSelectedElementsVisibility(forceHidden);
- });
- } else
- contextMenu.appendItem(WI.UIString("Toggle Visibility"), this.toggleElementVisibility.bind(this));
-
- subMenus.add.appendItem(WI.UIString("Attribute"), this._addNewAttribute.bind(this), !isNonShadowEditable);
-
let attribute = event.target.closest(".html-attribute");
- subMenus.edit.appendItem(WI.UIString("Attribute"), this._startEditingAttribute.bind(this, attribute, event.target), !attribute || ! isNonShadowEditable);
+ let textNode = event.target.closest(".html-text-node");
let attributeName = null;
if (attribute) {
@@ -765,68 +742,109 @@
attributeName = attributeNameElement.textContent.trim();
}
- let attributeValue = node.getAttribute(attributeName);
- subMenus.copy.appendItem(WI.UIString("Attribute"), () => {
- let text = attributeName;
- if (attributeValue)
- text += "=\"" + attributeValue.replace(/"/g, "\\\"") + "\"";
- InspectorFrontendHost.copyText(text);
- }, !attribute || !isNonShadowEditable);
-
- subMenus.delete.appendItem(WI.UIString("Attribute"), () => {
- node.removeAttribute(attributeName);
- }, !attribute || !isNonShadowEditable);
-
- subMenus.edit.appendItem(WI.UIString("Tag"), () => {
- this._startEditingTagName();
- }, !isNonShadowEditable);
+ if (event.target && event.target.tagName === "A")
+ WI.appendContextMenuItemsForURL(contextMenu, event.target.href, {frame: this.representedObject.frame});
contextMenu.appendSeparator();
- if (WI.cssManager.canForcePseudoClasses() && attached) {
- let pseudoSubMenu = contextMenu.appendSubMenuItem(WI.UIString("Forced Pseudo-Classes"));
+ let isEditableNode = this.representedObject.nodeType() === Node.ELEMENT_NODE && this.editable;
+ let isNonShadowEditable = !this.representedObject.isInUserAgentShadowTree() && this.editable;
+ let forbiddenClosingTag = WI.DOMTreeElement.ForbiddenClosingTagElements.has(this.representedObject.nodeNameInCorrectCase());
- let enabledPseudoClasses = node.enabledPseudoClasses;
- WI.CSSManager.ForceablePseudoClasses.forEach((pseudoClass) => {
- let enabled = enabledPseudoClasses.includes(pseudoClass);
- pseudoSubMenu.appendCheckboxItem(pseudoClass.capitalize(), () => {
- node.setPseudoClassEnabled(pseudoClass, !enabled);
- }, enabled);
+ if (isEditableNode) {
+ if (!forbiddenClosingTag) {
+ subMenus.add.appendItem(WI.UIString("Child"), () => {
+ this._addHTML();
+ });
+ }
+
+ subMenus.add.appendItem(WI.UIString("Previous Sibling"), () => {
+ this._addPreviousSibling();
});
- contextMenu.appendSeparator();
+ subMenus.add.appendItem(WI.UIString("Next Sibling"), () => {
+ this._addNextSibling();
+ });
}
- }
- _populateTextContextMenu(contextMenu, textNode, subMenus)
- {
- this._populateNodeContextMenu(contextMenu, subMenus);
+ if (isNonShadowEditable) {
+ subMenus.add.appendItem(WI.UIString("Attribute"), () => {
+ this._addNewAttribute();
+ });
+ }
- subMenus.edit.appendItem(WI.UIString("Text"), this._startEditingTextNode.bind(this, textNode), !this.editable);
+ if (this.editable) {
+ subMenus.edit.appendItem(WI.UIString("HTML"), () => {
+ this._editAsHTML();
+ });
+ }
- subMenus.copy.appendItem(WI.UIString("Text"), () => {
- InspectorFrontendHost.copyText(textNode.textContent);
- }, !textNode.textContent.length);
- }
+ if (isNonShadowEditable) {
+ if (attributeName) {
+ subMenus.edit.appendItem(WI.UIString("Attribute"), () => {
+ this._startEditingAttribute(attribute, event.target);
+ });
+ }
- _populateNodeContextMenu(contextMenu, subMenus)
- {
- let node = this.representedObject;
+ subMenus.edit.appendItem(WI.UIString("Tag"), () => {
+ this._startEditingTagName();
+ });
+ }
- let isEditableNode = node.nodeType() === Node.ELEMENT_NODE && this.editable;
- let forbiddenClosingTag = WI.DOMTreeElement.ForbiddenClosingTagElements.has(node.nodeNameInCorrectCase());
- subMenus.add.appendItem(WI.UIString("Child"), this._addHTML.bind(this), forbiddenClosingTag || !isEditableNode);
- subMenus.add.appendItem(WI.UIString("Previous Sibling"), this._addPreviousSibling.bind(this), !isEditableNode);
- subMenus.add.appendItem(WI.UIString("Next Sibling"), this._addNextSibling.bind(this), !isEditableNode);
+ if (textNode && this.editable) {
+ subMenus.edit.appendItem(WI.UIString("Text"), () => {
+ this._startEditingTextNode(textNode);
+ });
+ }
- subMenus.edit.appendItem(WI.UIString("HTML"), this._editAsHTML.bind(this), !this.editable);
- subMenus.copy.appendItem(WI.UIString("HTML"), this._copyHTML.bind(this), node.isPseudoElement());
+ if (!this.representedObject.isPseudoElement()) {
+ subMenus.copy.appendItem(WI.UIString("HTML"), () => {
+ this._copyHTML();
+ });
+ }
- if (!this.selected || this.treeOutline.selectedTreeElements.length === 1)
- subMenus.delete.appendItem(WI.UIString("Node"), this.remove.bind(this), !this.editable);
+ if (attributeName && isNonShadowEditable) {
+ subMenus.copy.appendItem(WI.UIString("Attribute"), () => {
+ let text = attributeName;
+ let attributeValue = this.representedObject.getAttribute(attributeName);
+ if (attributeValue)
+ text += "=\"" + attributeValue.replace(/"/g, "\\\"") + "\"";
+ InspectorFrontendHost.copyText(text);
+ });
+ }
+
+ if (textNode && textNode.textContent.length) {
+ subMenus.copy.appendItem(WI.UIString("Text"), () => {
+ InspectorFrontendHost.copyText(textNode.textContent);
+ });
+ }
+
+ if (this.editable && (!this.selected || this.treeOutline.selectedTreeElements.length === 1)) {
+ subMenus.delete.appendItem(WI.UIString("Node"), () => {
+ this.remove();
+ });
+ }
+
+ if (attributeName && isNonShadowEditable) {
+ subMenus.delete.appendItem(WI.UIString("Attribute"), () => {
+ this.representedObject.removeAttribute(attributeName);
+ });
+ }
for (let subMenu of Object.values(subMenus))
contextMenu.pushItem(subMenu);
+
+ if (this.selected && this.treeOutline && this.treeOutline.selectedTreeElements.length > 1) {
+ let forceHidden = !this.treeOutline.selectedTreeElements.every((treeElement) => treeElement.isNodeHidden);
+ let label = forceHidden ? WI.UIString("Hide Elements") : WI.UIString("Show Elements");
+ contextMenu.appendItem(label, () => {
+ this.treeOutline.toggleSelectedElementsVisibility(forceHidden);
+ });
+ } else {
+ contextMenu.appendItem(WI.UIString("Toggle Visibility"), () => {
+ this.toggleElementVisibility();
+ });
+ }
}
_startEditing()
diff --git a/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js b/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js
index 668f8ea..1227a2b 100644
--- a/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js
+++ b/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js
@@ -272,11 +272,6 @@
populateContextMenu(contextMenu, event, treeElement)
{
- let tag = event.target.closest(".html-tag");
- let textNode = event.target.closest(".html-text-node");
- let commentNode = event.target.closest(".html-comment");
- let pseudoElement = event.target.closest(".html-pseudo-element");
-
let subMenus = {
add: new WI.ContextSubMenuItem(contextMenu, WI.UIString("Add")),
edit: new WI.ContextSubMenuItem(contextMenu, WI.UIString("Edit")),
@@ -287,12 +282,8 @@
if (treeElement.selected && this.selectedTreeElements.length > 1)
subMenus.delete.appendItem(WI.UIString("Nodes"), () => { this.ondelete(); }, !this._editable);
- if (tag && treeElement._populateTagContextMenu)
- treeElement._populateTagContextMenu(contextMenu, event, subMenus);
- else if (textNode && treeElement._populateTextContextMenu)
- treeElement._populateTextContextMenu(contextMenu, textNode, subMenus);
- else if ((commentNode || pseudoElement) && treeElement._populateNodeContextMenu)
- treeElement._populateNodeContextMenu(contextMenu, subMenus);
+ if (treeElement.populateDOMNodeContextMenu)
+ treeElement.populateDOMNodeContextMenu(contextMenu, subMenus, event, subMenus);
let options = {
excludeRevealElement: this._excludeRevealElementContextMenu,