Bug 1644337, add an isAnchored property to popups, as popups can be anchored to a rectangle as well as a node. This prevented the arrow from appearing in panels, r=smaug
authorNeil Deakin <neil@mozilla.com>
Mon, 10 Aug 2020 09:47:38 +0000
changeset 544085 9fb094f206b36a257cea8ca267b636a5387c7b88
parent 544084 ca4a9ddeb5402132cbb5eddee2739dd55fe3fce2
child 544086 3bdd93319474f69d0bfe0825db83185c00d68a84
push id123808
push userneil@mozilla.com
push dateMon, 10 Aug 2020 10:31:26 +0000
treeherderautoland@3bdd93319474 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1644337
milestone81.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1644337, add an isAnchored property to popups, as popups can be anchored to a rectangle as well as a node. This prevented the arrow from appearing in panels, r=smaug Differential Revision: https://phabricator.services.mozilla.com/D86099
dom/webidl/XULPopupElement.webidl
dom/xul/XULPopupElement.cpp
dom/xul/XULPopupElement.h
toolkit/content/widgets/panel.js
--- a/dom/webidl/XULPopupElement.webidl
+++ b/dom/webidl/XULPopupElement.webidl
@@ -138,16 +138,22 @@ interface XULPopupElement : XULElement
 
   /**
    * The node that triggered the popup. If the popup is not open, will return
    * null.
    */
   readonly attribute Node? triggerNode;
 
   /**
+   * True if the popup is anchored to a point or rectangle. False if it
+   * appears at a fixed screen coordinate.
+   */
+  readonly attribute boolean isAnchored;
+
+  /**
    * Retrieve the anchor that was specified to openPopup or for menupopups in a
    * menu, the parent menu.
    */
   readonly attribute Element? anchorNode;
 
   /**
    * Retrieve the screen rectangle of the popup, including the area occupied by
    * any titlebar or borders present.
--- a/dom/xul/XULPopupElement.cpp
+++ b/dom/xul/XULPopupElement.cpp
@@ -183,16 +183,25 @@ void XULPopupElement::GetState(nsString&
   }
 }
 
 nsINode* XULPopupElement::GetTriggerNode() const {
   nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetPrimaryFrame());
   return nsMenuPopupFrame::GetTriggerContent(menuPopupFrame);
 }
 
+bool XULPopupElement::IsAnchored() const {
+  nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetPrimaryFrame());
+  if (!menuPopupFrame) {
+    return false;
+  }
+
+  return menuPopupFrame->IsAnchored();
+}
+
 // FIXME(emilio): should probably be renamed to GetAnchorElement?
 Element* XULPopupElement::GetAnchorNode() const {
   nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetPrimaryFrame());
   if (!menuPopupFrame) {
     return nullptr;
   }
 
   return Element::FromNodeOrNull(menuPopupFrame->GetAnchor());
--- a/dom/xul/XULPopupElement.h
+++ b/dom/xul/XULPopupElement.h
@@ -67,16 +67,18 @@ class XULPopupElement : public nsXULElem
                              Event* aTriggerEvent);
 
   void HidePopup(bool aCancel);
 
   void GetState(nsString& aState);
 
   nsINode* GetTriggerNode() const;
 
+  bool IsAnchored() const;
+
   Element* GetAnchorNode() const;
 
   already_AddRefed<DOMRect> GetOuterScreenRect();
 
   void MoveTo(int32_t aLeft, int32_t aTop);
 
   void MoveToAnchor(Element* aAnchorElement, const nsAString& aPosition,
                     int32_t aXPos, int32_t aYPos, bool aAttributesOverride);
--- a/toolkit/content/widgets/panel.js
+++ b/toolkit/content/widgets/panel.js
@@ -91,22 +91,17 @@
       super.removeAttribute(name);
     }
 
     get isArrowPanel() {
       return this.getAttribute("type") == "arrow";
     }
 
     adjustArrowPosition() {
-      if (!this.isArrowPanel) {
-        return;
-      }
-
-      var anchor = this.anchorNode;
-      if (!anchor) {
+      if (!this.isArrowPanel || !this.isAnchored) {
         return;
       }
 
       var container = this.shadowRoot.querySelector(".panel-arrowcontainer");
       var arrowbox = this.shadowRoot.querySelector(".panel-arrowbox");
 
       var position = this.alignmentPosition;
       var offset = this.alignmentOffset;
@@ -154,17 +149,17 @@
           this.setAttribute("side", "top");
         }
       }
     }
 
     on_popupshowing(event) {
       if (this.isArrowPanel && event.target == this) {
         var arrow = this.shadowRoot.querySelector(".panel-arrow");
-        arrow.hidden = this.anchorNode == null;
+        arrow.hidden = !this.isAnchored;
         this.shadowRoot
           .querySelector(".panel-arrowbox")
           .style.removeProperty("transform");
 
         if (this.getAttribute("animate") != "false") {
           this.setAttribute("animate", "open");
           // the animating attribute prevents user interaction during transition
           // it is removed when popupshown fires