Bug 1356765 - Avoid flushing layout when showing menus with accel shortcuts. r?Gijs
MozReview-Commit-ID: KZYmbX7kwUm
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -265,30 +265,39 @@
<field name="scrollBox" readonly="true">
document.getAnonymousElementByAttribute(this, "class", "popup-internal-box");
</field>
</implementation>
<handlers>
<handler event="popupshowing" phase="target">
<![CDATA[
- var array = [];
- var width = 0;
- for (var menuitem = this.firstChild; menuitem; menuitem = menuitem.nextSibling) {
+ let array = [];
+ let maxWidth = 0;
+ let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ for (let menuitem = this.firstChild; menuitem; menuitem = menuitem.nextSibling) {
if (menuitem.localName == "menuitem" && menuitem.hasAttribute("acceltext")) {
- var accel = document.getAnonymousElementByAttribute(menuitem, "anonid", "accel");
+ let accel = document.getAnonymousElementByAttribute(menuitem, "anonid", "accel");
if (accel && accel.boxObject) {
array.push(accel);
- if (accel.boxObject.width > width)
- width = accel.boxObject.width;
+ // The popup is showing, which means it has already been laid
+ // out, so these bounds should still be accurate.
+ let itemWidth = dwu.getBoundsWithoutFlushing(accel);
+ if (itemWidth > maxWidth) {
+ maxWidth = itemWidth
+ }
}
}
}
- for (var i = 0; i < array.length; i++)
- array[i].width = width;
+ window.requestAnimationFrame(() => {
+ for (let i = 0; i < array.length; i++) {
+ array[i].width = width;
+ }
+ });
]]>
</handler>
</handlers>
</binding>
<binding id="panel"
extends="chrome://global/content/bindings/popup.xml#popup-base">
<implementation>