Bug 1555497 - Remove menupopup binding, r=bgrins
authorAlexander Surkov <surkov.alexander@gmail.com>
Thu, 19 Sep 2019 02:13:43 +0000
changeset 494129 0257933d9e3104536d2352e559c64f6f42808ee0
parent 494128 c420af7f34af85867c4afdec0e32a64dbfbda056
child 494130 134ed13973c19948bc674fa21f0ac6d158ecb6b4
push id36596
push userapavel@mozilla.com
push dateFri, 20 Sep 2019 09:45:58 +0000
treeherdermozilla-central@52cb15e3f794 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1555497
milestone71.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 1555497 - Remove menupopup binding, r=bgrins Differential Revision: https://phabricator.services.mozilla.com/D33282
browser/base/content/browser.css
browser/components/places/content/places-menupopup.js
browser/components/places/content/places.css
layout/generic/crashtests/crashtests.list
toolkit/content/tests/chrome/popup_trigger.js
toolkit/content/tests/chrome/test_popupincontent.xul
toolkit/content/tests/chrome/window_largemenu.xul
toolkit/content/tests/widgets/popup_shared.js
toolkit/content/widgets/menupopup.js
toolkit/content/widgets/popup.xml
toolkit/content/xul.css
toolkit/themes/osx/global/popup.css
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -1007,17 +1007,16 @@ toolbarpaletteitem[place="palette"] > #d
 /* Indent options in optgroups */
 .contentSelectDropdown-ingroup .menu-iconic-text {
   padding-inline-start: 2em;
 }
 
 /* Give this menupopup an arrow panel styling */
 #BMB_bookmarksPopup {
   -moz-appearance: none;
-  -moz-binding: none;
   background: transparent;
   border: none;
   /* The popup inherits -moz-image-region from the button, must reset it */
   -moz-image-region: auto;
 }
 
 @supports -moz-bool-pref("xul.panel-animations.enabled") {
 %ifdef MOZ_WIDGET_COCOA
--- a/browser/components/places/content/places-menupopup.js
+++ b/browser/components/places/content/places-menupopup.js
@@ -25,33 +25,16 @@
         "drop",
         "dragover",
         "dragexit",
         "dragend",
       ];
       for (let event_name of event_names) {
         this.addEventListener(event_name, ev => this[`on_${event_name}`](ev));
       }
-
-      this.attachShadow({ mode: "open" });
-      this.shadowRoot.appendChild(this.fragment);
-
-      this._indicatorBar = this.shadowRoot.querySelector(
-        "[part=drop-indicator-bar]"
-      );
-      this._scrollBox = this.shadowRoot.querySelector(".popup-internal-box");
-    }
-
-    get fragment() {
-      if (!this.constructor.hasOwnProperty("_fragment")) {
-        this.constructor._fragment = MozXULElement.parseXULToFragment(
-          this.markup
-        );
-      }
-      return document.importNode(this.constructor._fragment, true);
     }
 
     get markup() {
       return `
       <html:link rel="stylesheet" href="chrome://global/skin/global.css" />
       <hbox flex="1" part="innerbox">
         <vbox part="drop-indicator-bar" hidden="true">
           <image part="drop-indicator" mousethrough="always"></image>
@@ -215,16 +198,25 @@
           if (this._folder.closeTimer) {
             this._folder.closeTimer.cancel();
             this._folder.closeTimer = null;
           }
         },
       };
     }
 
+    get _indicatorBar() {
+      if (!this.__indicatorBar) {
+        this.__indicatorBar = this.shadowRoot.querySelector(
+          "[part=drop-indicator-bar]"
+        );
+      }
+      return this.__indicatorBar;
+    }
+
     /**
      * This is the view that manages the popup.
      */
     get _rootView() {
       if (!this.__rootView) {
         this.__rootView = PlacesUIUtils.getViewForNode(this);
       }
       return this.__rootView;
@@ -490,47 +482,47 @@
       let anonid = event.originalTarget.getAttribute("anonid");
       let scrollDir = 0;
       if (anonid == "scrollbutton-up") {
         scrollDir = -1;
       } else if (anonid == "scrollbutton-down") {
         scrollDir = 1;
       }
       if (scrollDir != 0) {
-        this._scrollBox.scrollByIndex(scrollDir, true);
+        this.scrollBox.scrollByIndex(scrollDir, true);
       }
 
       // Check if we should hide the drop indicator for this target.
       if (dropPoint.folderElt || this._hideDropIndicator(event)) {
         this._indicatorBar.hidden = true;
         event.preventDefault();
         event.stopPropagation();
         return;
       }
 
       // We should display the drop indicator relative to the arrowscrollbox.
-      let scrollRect = this._scrollBox.getBoundingClientRect();
+      let scrollRect = this.scrollBox.getBoundingClientRect();
       let newMarginTop = 0;
       if (scrollDir == 0) {
         let elt = this.firstElementChild;
         while (
           elt &&
           event.screenY > elt.screenY + elt.getBoundingClientRect().height / 2
         ) {
           elt = elt.nextElementSibling;
         }
         newMarginTop = elt
-          ? elt.screenY - this._scrollBox.screenY
+          ? elt.screenY - this.scrollBox.screenY
           : scrollRect.height;
       } else if (scrollDir == 1) {
         newMarginTop = scrollRect.height;
       }
 
       // Set the new marginTop based on arrowscrollbox.
-      newMarginTop += scrollRect.y - this._scrollBox.getBoundingClientRect().y;
+      newMarginTop += scrollRect.y - this.scrollBox.getBoundingClientRect().y;
       this._indicatorBar.firstElementChild.style.marginTop =
         newMarginTop + "px";
       this._indicatorBar.hidden = false;
 
       event.preventDefault();
       event.stopPropagation();
     }
 
--- a/browser/components/places/content/places.css
+++ b/browser/components/places/content/places.css
@@ -14,20 +14,16 @@ tree[is="places-tree"] > treechildren::-
   unicode-bidi: plaintext;
 }
 
 .toolbar-drop-indicator {
   position: relative;
   z-index: 1;
 }
 
-menupopup[placespopup="true"] {
-  -moz-binding: none;
-}
-
 /* Apply crisp rendering for favicons at exactly 2dppx resolution */
 @media (resolution: 2dppx) {
   #bookmarksChildren,
   .sidebar-placesTreechildren,
   .placesTree > treechildren {
     image-rendering: -moz-crisp-edges;
   }
 }
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -32,17 +32,17 @@ load 323493-1.html
 load 323495-1.html
 load 324318-1.html
 load 328946-1.html
 load 331284-1.xhtml
 load 331292.html
 load 334105-1.xhtml
 load 334107-1.xhtml
 load 334147-1.xhtml
-asserts(1-18) load 334148-1.xhtml # XBL interacts poorly with CSS counters.
+load 334148-1.xhtml
 load 334602-1.html
 load 337412-1.html
 load 337883-1.html
 load 337883-2.html
 load 339769-1.html
 load 342322-1.html
 load 343206-1.xhtml
 load 344557-1.html
--- a/toolkit/content/tests/chrome/popup_trigger.js
+++ b/toolkit/content/tests/chrome/popup_trigger.js
@@ -55,17 +55,17 @@ var popupTests = [
     testname: "mouse click on trigger",
     events: ["popupshowing thepopup", "popupshown thepopup"],
     test() {
       // for menus, no trigger will be set. For non-menus using the popup
       // attribute, the trigger will be set to the node with the popup attribute
       gExpectedTriggerNode = gIsMenu ? "notset" : gTrigger;
       synthesizeMouse(gTrigger, 4, 4, {});
     },
-    result(testname) {
+    async result(testname) {
       gExpectedTriggerNode = null;
       // menus are the anchor but non-menus are opened at screen coordinates
       is(
         gMenuPopup.anchorNode,
         gIsMenu ? gTrigger : null,
         testname + " anchorNode"
       );
       // menus are opened internally, but non-menus have a mouse event which
@@ -85,16 +85,23 @@ var popupTests = [
       if (window.opener) {
         is(
           window.opener.document.popupNode,
           null,
           testname + " opener.document.popupNode"
         );
       }
 
+      // Popup may have wrong initial size in non e10s mode tests, because
+      // layout is not yet ready for popup content lazy population on
+      // popupshowing event.
+      await new Promise(r =>
+        requestAnimationFrame(() => requestAnimationFrame(r))
+      );
+
       // this will be used in some tests to ensure the size doesn't change
       var popuprect = gMenuPopup.getBoundingClientRect();
       gPopupWidth = Math.round(popuprect.width);
       gPopupHeight = Math.round(popuprect.height);
 
       checkActive(gMenuPopup, "", testname);
       checkOpen("trigger", testname);
       // if a menu, the popup should be opened underneath the menu in the
--- a/toolkit/content/tests/chrome/test_popupincontent.xul
+++ b/toolkit/content/tests/chrome/test_popupincontent.xul
@@ -78,18 +78,25 @@ function nextTest()
       synthesizeMouse(menu, 2, 2, { });
       break;
     case "shorter menu again":
       SimpleTest.finish();
       break;
   }
 }
 
-function popupShown()
+async function popupShown()
 {
+  // Popup may have wrong initial size in non e10s mode tests, because
+  // layout is not yet ready for popup content lazy population on
+  // popupshowing event.
+  await new Promise(r =>
+    requestAnimationFrame(() => requestAnimationFrame(r))
+  );
+
   var windowrect = document.documentElement.getBoundingClientRect();
   var popuprect = $("popup").getBoundingClientRect();
 
   // subtract one off the edge due to a rounding issue
   ok(popuprect.left >= windowrect.left, step + " left");
   ok(popuprect.right - 1 <= windowrect.right, step + " right");
 
   if (step == "left and top") {
--- a/toolkit/content/tests/chrome/window_largemenu.xul
+++ b/toolkit/content/tests/chrome/window_largemenu.xul
@@ -97,17 +97,17 @@ function popupShown()
   if (gTests[gTestIndex] == "menu movement")
     return testPopupMovement();
 
   if (gContextMenuTests)
     return contextMenuPopupShown();
 
   var popup = document.getElementById("popup");
   var rect = popup.getBoundingClientRect();
-  var scrollbox = document.getAnonymousNodes(popup)[0].scrollbox;
+  var scrollbox = popup.scrollBox.scrollbox;
   var expectedScrollPos = 0;
 
   if (gTestIndex == 0) {
     // the popup should be in the center of the screen
     // note that if the height is odd, the y-offset will have been rounded
     // down when we pass the fractional value to openPopupAtScreen above.
     is(Math.round(rect.top) + gScreenY, Math.floor(screen.height / 2),
                               gTests[gTestIndex] + " top");
--- a/toolkit/content/tests/widgets/popup_shared.js
+++ b/toolkit/content/tests/widgets/popup_shared.js
@@ -211,25 +211,25 @@ function eventOccurred(event) {
       gTestEventIndex++;
       if (events.length <= gTestEventIndex) {
         setTimeout(checkResult, 0);
       }
     }
   }
 }
 
-function checkResult() {
+async function checkResult() {
   var step = null;
   var test = gPopupTests[gTestIndex];
   if ("steps" in test) {
     step = test.steps[gTestStepIndex];
   }
 
   if ("result" in test) {
-    test.result(test.testname, step);
+    await test.result(test.testname, step);
   }
 
   if ("autohide" in test) {
     gAutoHide = true;
     document.getElementById(test.autohide).hidePopup();
     return;
   }
 
--- a/toolkit/content/widgets/menupopup.js
+++ b/toolkit/content/widgets/menupopup.js
@@ -2,32 +2,39 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 // This is loaded into all XUL windows. Wrap in a block to prevent
 // leaking to window scope.
 {
+  const { AppConstants } = ChromeUtils.import(
+    "resource://gre/modules/AppConstants.jsm"
+  );
+
   class MozMenuPopup extends MozElements.MozElementMixin(XULPopupElement) {
     constructor() {
       super();
 
       this.AUTOSCROLL_INTERVAL = 25;
       this.NOT_DRAGGING = 0;
       this.DRAG_OVER_BUTTON = -1;
       this.DRAG_OVER_POPUP = 1;
       this._draggingState = this.NOT_DRAGGING;
       this._scrollTimer = 0;
 
       this.addEventListener("popupshowing", event => {
         if (event.target != this) {
           return;
         }
 
+        // Make sure we generated shadow DOM to place menuitems into.
+        this.shadowRoot;
+
         let array = [];
         let width = 0;
         for (
           let menuitem = this.firstElementChild;
           menuitem;
           menuitem = menuitem.nextElementSibling
         ) {
           if (
@@ -40,60 +47,120 @@
               if (accel.boxObject.width > width) {
                 width = accel.boxObject.width;
               }
             }
           }
         }
         array.forEach(accel => (accel.width = width));
       });
+
+      this.attachShadow({ mode: "open" });
     }
 
     connectedCallback() {
       if (this.delayConnectedCallback() || this.hasConnected) {
         return;
       }
+
       this.hasConnected = true;
-      this.appendChild(
-        MozXULElement.parseXULToFragment(`
-        <arrowscrollbox class="popup-internal-box"
-                        flex="1"
-                        orient="vertical"
-                        smoothscroll="false"/>
-      `)
-      );
-      this.scrollBox = this.querySelector(".popup-internal-box");
-
       if (this.parentNode && this.parentNode.localName == "menulist") {
         this._setUpMenulistPopup();
       }
     }
 
-    /**
-     * When a custom element (CE) class extends this MozMenuPopup class,
-     * and child nodes are present inside that CE in the XUL files
-     * where it is used, then this method should be called in that CE's
-     * connectedCallback. It will slot those child nodes into place
-     * inside the CE's internal scroll box element.
-     *
-     * This "manual slotting" is done with this method, and not by default
-     * in the connectedCallback of this base class, to support cases where
-     * children are dynamically added, etc. (Which also requires "manual
-     * slotting".) See bug 1531870.
-     */
-    _setUpChildElements() {
-      while (this.childElementCount > 1) {
-        this.scrollBox.appendChild(this.firstElementChild);
+    get shadowRoot() {
+      // We generate shadow DOM lazily on popupshowing event to avoid extra load
+      // on the system during browser startup.
+      if (!super.shadowRoot.firstElementChild) {
+        super.shadowRoot.appendChild(this.fragment);
+
+        // Retarget events from shadow DOM scrolbox to the popup itself.
+        this.scrollBox.addEventListener("scroll", ev =>
+          this.dispatchEvent(new Event("scroll"))
+        );
+        this.scrollBox.addEventListener("overflow", ev =>
+          this.dispatchEvent(new Event("overflow"))
+        );
+        this.scrollBox.addEventListener("underflow", ev =>
+          this.dispatchEvent(new Event("underflow"))
+        );
+      }
+      return super.shadowRoot;
+    }
+
+    get fragment() {
+      if (!this.constructor.hasOwnProperty("_fragment")) {
+        this.constructor._fragment = MozXULElement.parseXULToFragment(
+          this.markup
+        );
       }
+      return document.importNode(this.constructor._fragment, true);
+    }
+
+    get markup() {
+      return `
+        <html:link rel="stylesheet" href="chrome://global/skin/global.css"/>
+        <html:style>${this.styles}</html:style>
+        <arrowscrollbox class="popup-internal-box"
+                        flex="1"
+                        orient="vertical"
+                        smoothscroll="false">
+          <html:slot></html:slot>
+        </arrowscrollbox>
+      `;
+    }
+
+    get styles() {
+      let s = `
+        :host(.in-menulist) .popup-internal-box > .scrollbutton-up,
+        :host(.in-menulist) .popup-internal-box > .arrowscrollbox-overflow-start-indicator,
+        :host(.in-menulist) .popup-internal-box > .arrowscrollbox-overflow-end-indicator,
+        :host(.in-menulist) .popup-internal-box > .scrollbutton-down {
+          display: none;
+        }
+        :host(.in-menulist) .popup-internal-box > .arrowscrollbox-scrollbox {
+          overflow: auto;
+        }
+      `;
+
+      switch (AppConstants.platform) {
+        case "macosx":
+          s += `
+            :host(.in-menulist) .popup-internal-box {
+              padding: 0;
+            }
+          `;
+          break;
+
+        default:
+          break;
+      }
+
+      return s;
+    }
+
+    get scrollBox() {
+      if (!this._scrollBox) {
+        this._scrollBox = this.shadowRoot.querySelector(".popup-internal-box");
+      }
+      return this._scrollBox;
     }
 
     /**
      * Adds event listeners for a MozMenuPopup inside a menulist element.
      */
     _setUpMenulistPopup() {
+      // Access shadow root to generate menupoup shadow DOMs. We do generate
+      // shadow DOM on popupshowing, but it doesn't work for HTML:selects,
+      // which are implemented via menulist elements living in the main process.
+      // So make them a special case then.
+      this.shadowRoot;
+      this.classList.add("in-menulist");
+
       this.addEventListener("popupshown", () => {
         // Enable drag scrolling even when the mouse wasn't used. The
         // mousemove handler will remove it if the mouse isn't down.
         this._enableDragScrolling(false);
       });
 
       this.addEventListener("popuphidden", () => {
         this._draggingState = this.NOT_DRAGGING;
@@ -192,12 +259,12 @@
     _clearScrollTimer() {
       if (this._scrollTimer) {
         this.ownerGlobal.clearInterval(this._scrollTimer);
         this._scrollTimer = 0;
       }
     }
   }
 
-  // Add this MozMenuPopup base class to MozElements, but don't define a custom
-  // element for it with `customElements.define` (for now, see bug 1531870).
+  customElements.define("menupopup", MozMenuPopup);
+
   MozElements.MozMenuPopup = MozMenuPopup;
 }
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -3,181 +3,16 @@
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <bindings id="popupBindings"
    xmlns="http://www.mozilla.org/xbl"
    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:xbl="http://www.mozilla.org/xbl">
 
-  <binding id="popup">
-    <content>
-      <xul:arrowscrollbox class="popup-internal-box" flex="1" orient="vertical"
-                          smoothscroll="false">
-        <children/>
-      </xul:arrowscrollbox>
-    </content>
-
-    <implementation>
-      <field name="scrollBox" readonly="true">
-        document.getAnonymousElementByAttribute(this, "class", "popup-internal-box");
-      </field>
-
-      <field name="AUTOSCROLL_INTERVAL">25</field>
-      <field name="NOT_DRAGGING">0</field>
-      <field name="DRAG_OVER_BUTTON">-1</field>
-      <field name="DRAG_OVER_POPUP">1</field>
-
-      <field name="_draggingState">this.NOT_DRAGGING</field>
-      <field name="_scrollTimer">0</field>
-
-      <method name="_enableDragScrolling">
-        <!-- when overItem is true, drag started over menuitem; when false, drag
-             started while the popup was opening.
-          -->
-        <parameter name="overItem"/>
-        <body>
-        <![CDATA[
-          if (!this._draggingState) {
-            this.setCaptureAlways();
-            this._draggingState = overItem ? this.DRAG_OVER_POPUP : this.DRAG_OVER_BUTTON;
-          }
-        ]]>
-        </body>
-      </method>
-
-      <method name="_clearScrollTimer">
-        <body>
-        <![CDATA[
-          if (this._scrollTimer) {
-            this.ownerGlobal.clearInterval(this._scrollTimer);
-            this._scrollTimer = 0;
-          }
-        ]]>
-        </body>
-      </method>
-
-      <constructor><![CDATA[
-        // Enable the drag-to-scroll events only in menulist popups.
-        if (!this.parentNode || this.parentNode.localName != "menulist") {
-          return;
-        }
-
-        // XBL bindings might be constructed more than once.
-        if (this.eventListenersAdded) {
-          return;
-        }
-        this.eventListenersAdded = true;
-
-        this.addEventListener("popupshown", () => {
-          // Enable drag scrolling even when the mouse wasn't used. The
-          // mousemove handler will remove it if the mouse isn't down.
-          this._enableDragScrolling(false);
-        });
-
-        this.addEventListener("popuphidden", () => {
-          this._draggingState = this.NOT_DRAGGING;
-          this._clearScrollTimer();
-          this.releaseCapture();
-        });
-
-        this.addEventListener("mousedown", event => {
-          if (event.button != 0) {
-            return;
-          }
-
-          if (this.state == "open" &&
-            (event.target.localName == "menuitem" ||
-              event.target.localName == "menu" ||
-              event.target.localName == "menucaption")) {
-            this._enableDragScrolling(true);
-          }
-        });
-
-        this.addEventListener("mouseup", event => {
-          if (event.button != 0) {
-            return;
-          }
-
-          this._draggingState = this.NOT_DRAGGING;
-          this._clearScrollTimer();
-        });
-
-        this.addEventListener("mousemove", event => {
-          if (!this._draggingState) {
-            return;
-          }
-
-          this._clearScrollTimer();
-
-          // If the user released the mouse before the popup opens, we will
-          // still be capturing, so check that the button is still pressed. If
-          // not, release the capture and do nothing else. This also handles if
-          // the dropdown was opened via the keyboard.
-          if (!(event.buttons & 1)) {
-            this._draggingState = this.NOT_DRAGGING;
-            this.releaseCapture();
-            return;
-          }
-
-          // If dragging outside the top or bottom edge of the popup, but within
-          // the popup area horizontally, scroll the list in that direction. The
-          // _draggingState flag is used to ensure that scrolling does not start
-          // until the mouse has moved over the popup first, preventing
-          // scrolling while over the dropdown button.
-          let popupRect = this.getOuterScreenRect();
-          if (event.screenX >= popupRect.left &&
-              event.screenX <= popupRect.right) {
-            if (this._draggingState == this.DRAG_OVER_BUTTON) {
-              if (event.screenY > popupRect.top &&
-                  event.screenY < popupRect.bottom) {
-                this._draggingState = this.DRAG_OVER_POPUP;
-              }
-            }
-
-            if (this._draggingState == this.DRAG_OVER_POPUP &&
-                (event.screenY <= popupRect.top ||
-                 event.screenY >= popupRect.bottom)) {
-              let scrollAmount = event.screenY <= popupRect.top ? -1 : 1;
-              this.scrollBox.scrollByIndex(scrollAmount, true);
-
-              let win = this.ownerGlobal;
-              this._scrollTimer = win.setInterval(() => {
-                this.scrollBox.scrollByIndex(scrollAmount, true);
-              }, this.AUTOSCROLL_INTERVAL);
-            }
-          }
-        });
-      ]]></constructor>
-    </implementation>
-
-    <handlers>
-      <handler event="popupshowing" phase="target">
-        <![CDATA[
-          var array = [];
-          var width = 0;
-          for (var menuitem = this.firstElementChild; menuitem; menuitem = menuitem.nextElementSibling) {
-            if (menuitem.localName == "menuitem" && menuitem.hasAttribute("acceltext")) {
-              var accel = menuitem.menuAccel;
-              if (accel) {
-                array.push(accel);
-                let accelWidth = accel.getBoundingClientRect().width;
-                if (accelWidth > width) {
-                  width = accelWidth;
-                }
-              }
-            }
-          }
-          for (var i = 0; i < array.length; i++)
-            array[i].width = width;
-        ]]>
-      </handler>
-    </handlers>
-  </binding>
-
   <binding id="panel">
     <implementation>
       <field name="_prevFocus">0</field>
     </implementation>
 
     <handlers>
       <handler event="popupshowing"><![CDATA[
         // Capture the previous focus before has a chance to get set inside the panel
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -224,17 +224,16 @@ menubar > menu:empty {
 
 .menu-text {
   -moz-box-flex: 1;
 }
 
 /********* menupopup, panel, & tooltip ***********/
 
 menupopup {
-  -moz-binding: url("chrome://global/content/bindings/popup.xml#popup");
   -moz-box-orient: vertical;
 }
 
 panel {
   -moz-binding: url("chrome://global/content/bindings/popup.xml#panel");
   -moz-box-orient: vertical;
 }
 
@@ -509,27 +508,16 @@ panel[type="autocomplete-richlistbox"] {
 menulist[popuponly="true"] {
   -moz-appearance: none !important;
   margin: 0 !important;
   height: 0 !important;
   min-height: 0 !important;
   border: 0 !important;
 }
 
-menulist > menupopup > .popup-internal-box > .scrollbutton-up,
-menulist > menupopup > .popup-internal-box > .arrowscrollbox-overflow-start-indicator,
-menulist > menupopup > .popup-internal-box > .arrowscrollbox-overflow-end-indicator,
-menulist > menupopup > .popup-internal-box > .scrollbutton-down {
-  display: none;
-}
-
-menulist > menupopup > .popup-internal-box > .arrowscrollbox-scrollbox {
-  overflow: auto;
-}
-
 /********** splitter **********/
 
 .tree-splitter {
   width: 0px;
   max-width: 0px;
   min-width: 0% ! important;
   min-height: 0% ! important;
   -moz-box-ordinal-group: 2147483646;
--- a/toolkit/themes/osx/global/popup.css
+++ b/toolkit/themes/osx/global/popup.css
@@ -101,17 +101,13 @@ menulist > menupopup {
   padding: 4px 0;
 }
 
 menulist > menupopup:not([position]) {
   margin-inline-start: -13px;
   margin-top: -2px;
 }
 
-menulist > menupopup > .popup-internal-box {
-  padding: 0;
-}
-
 menupopup[customoptionstyling="true"] {
   -moz-appearance: none;
   padding-top: 0;
   padding-bottom: 0;
 }