Bug 1128162 - Scale the select popup's text to match the page zoom r=mconley
authorGeorge Wright <george@mozilla.com>
Mon, 08 Jun 2015 14:41:17 -0400
changeset 279501 f49c57b57b438e9e669cd3be28a15959a477f1fe
parent 279500 660ab6f4e1be82f7d3cfbf3a211627a130a7ad54
child 279502 dc3050936510c89cb55c128c8de05dbd8386f385
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1128162
milestone41.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 1128162 - Scale the select popup's text to match the page zoom r=mconley
toolkit/content/widgets/remote-browser.xml
toolkit/modules/SelectContentHelper.jsm
toolkit/modules/SelectParentHelper.jsm
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -310,17 +310,17 @@
 
             case "Forms:ShowDropDown": {
               if (!this._selectParentHelper) {
                 this._selectParentHelper =
                   Cu.import("resource://gre/modules/SelectParentHelper.jsm", {}).SelectParentHelper;
               }
 
               let menulist = document.getElementById(this.getAttribute("selectmenulist"));
-              this._selectParentHelper.populate(menulist, data.options, data.selectedIndex);
+              this._selectParentHelper.populate(menulist, data.options, data.selectedIndex, this._fullZoom);
               this._selectParentHelper.open(this, menulist, data.rect);
               break;
             }
 
             case "FullZoomChange": {
               this._fullZoom = data.value;
               let event = document.createEvent("Events");
               event.initEvent("FullZoomChange", true, false);
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -40,17 +40,17 @@ this.SelectContentHelper.prototype = {
   },
 
   showDropDown: function() {
     let rect = this._getBoundingContentRect();
 
     this.global.sendAsyncMessage("Forms:ShowDropDown", {
       rect: rect,
       options: this._buildOptionList(),
-      selectedIndex: this.element.selectedIndex,
+      selectedIndex: this.element.selectedIndex
     });
   },
 
   _getBoundingContentRect: function() {
     return BrowserUtils.getElementBoundingScreenRect(this.element);
   },
 
   _buildOptionList: function() {
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -6,20 +6,20 @@
 
 this.EXPORTED_SYMBOLS = [
   "SelectParentHelper"
 ];
 
 let currentBrowser = null;
 
 this.SelectParentHelper = {
-  populate: function(menulist, items, selectedIndex) {
+  populate: function(menulist, items, selectedIndex, zoom) {
     // Clear the current contents of the popup
     menulist.menupopup.textContent = "";
-    populateChildren(menulist, items, selectedIndex);
+    populateChildren(menulist, items, selectedIndex, zoom);
   },
 
   open: function(browser, menulist, rect) {
     menulist.hidden = false;
     currentBrowser = browser;
     this._registerListeners(menulist.menupopup);
 
     menulist.menupopup.openPopupAtScreenRect("after_start", rect.left, rect.top, rect.width, rect.height, false, false);
@@ -60,38 +60,52 @@ this.SelectParentHelper = {
 
   _unregisterListeners: function(popup) {
     popup.removeEventListener("command", this);
     popup.removeEventListener("popuphidden", this);
   },
 
 };
 
-function populateChildren(menulist, options, selectedIndex, startIndex = 0,
-                          isInGroup = false, isGroupDisabled = false) {
+function populateChildren(menulist, options, selectedIndex, zoom, startIndex = 0,
+                          isInGroup = false, isGroupDisabled = false, adjustedTextSize = -1) {
   let index = startIndex;
   let element = menulist.menupopup;
 
+  // -1 just means we haven't calculated it yet. When we recurse through this function
+  // we will pass in adjustedTextSize to save on recalculations.
+  if (adjustedTextSize == -1) {
+    let win = element.ownerDocument.defaultView;
+
+    // Grab the computed text size and multiply it by the remote browser's fullZoom to ensure
+    // the popup's text size is matched with the content's. We can't just apply a CSS transform
+    // here as the popup's preferred size is calculated pre-transform.
+    let textSize = win.getComputedStyle(element).getPropertyValue("font-size");
+    adjustedTextSize = (zoom * parseFloat(textSize, 10)) + "px";
+  }
+
   for (let option of options) {
     let isOptGroup = (option.tagName == 'OPTGROUP');
     let item = element.ownerDocument.createElement(isOptGroup ? "menucaption" : "menuitem");
 
     item.setAttribute("label", option.textContent);
     item.style.direction = option.textDirection;
+    item.style.fontSize = adjustedTextSize;
 
     element.appendChild(item);
 
     // A disabled optgroup disables all of its child options.
     let isDisabled = isGroupDisabled || option.disabled;
     if (isDisabled) {
       item.setAttribute("disabled", "true");
     }
 
     if (isOptGroup) {
-      index = populateChildren(menulist, option.children, selectedIndex, index, true, isDisabled);
+      index = populateChildren(menulist, option.children, selectedIndex, zoom,
+                               index, true, isDisabled, adjustedTextSize);
     } else {
       if (index == selectedIndex) {
         // We expect the parent element of the popup to be a <xul:menulist> that
         // has the popuponly attribute set to "true". This is necessary in order
         // for a <xul:menupopup> to act like a proper <html:select> dropdown, as
         // the <xul:menulist> does things like remember state and set the
         // _moz-menuactive attribute on the selected <xul:menuitem>.
         menulist.selectedItem = item;