merge m-c to fx-team
authorTim Taubert <tim.taubert@gmx.de>
Sat, 04 Feb 2012 11:31:07 +0100
changeset 109308 661bf5efd10d10a6eb858013409523f2fb0e1ad4
parent 109307 a4fd961eb3c9912720b32551523878a71309caef (current diff)
parent 87685 7d139fa7ea139460d5b508b1b9070933927f7017 (diff)
child 109309 999a0f519542374effcee39b6fe6a9ebdd57980d
child 109340 a5a11d004b765e93bf17f8ff7f5a48a3b8231ad7
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.0a1
merge m-c to fx-team
browser/base/content/browser.js
browser/base/content/browser.xul
browser/components/tabview/groupitems.js
browser/components/tabview/test/browser_tabview_bug626455.js
browser/components/tabview/ui.js
content/html/content/src/nsHTMLCanvasElement.cpp
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/content/widgets/videocontrols.xml
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1761,16 +1761,33 @@ function delayedStartup(isLoadingBlank, 
   // If the user (or the locale) hasn't enabled the top-level "Character
   // Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
   // hide it.
   if ("true" != gPrefService.getComplexValue("browser.menu.showCharacterEncoding",
                                              Ci.nsIPrefLocalizedString).data)
     document.getElementById("appmenu_charsetMenu").hidden = true;
 #endif
 
+  let appMenuButton = document.getElementById("appmenu-button");
+  let appMenuPopup = document.getElementById("appmenu-popup");
+  if (appMenuButton && appMenuPopup) {
+    let appMenuOpening = null;
+    appMenuButton.addEventListener("mousedown", function(event) {
+      if (event.button == 0)
+        appMenuOpening = new Date();
+    }, false);
+    appMenuPopup.addEventListener("popupshown", function(event) {
+      if (event.target != appMenuPopup || !appMenuOpening)
+        return;
+      let duration = new Date() - appMenuOpening;
+      appMenuOpening = null;
+      Services.telemetry.getHistogramById("FX_APP_MENU_OPEN_MS").add(duration);
+    }, false);
+  }
+
   window.addEventListener("mousemove", MousePosTracker, false);
   window.addEventListener("dragover", MousePosTracker, false);
 
   Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
   TelemetryTimestamps.add("delayedStartupFinished");
 }
 
 function BrowserShutdown() {
@@ -8158,21 +8175,23 @@ var gIdentityHandler = {
     this._identityPopupContentSupp.textContent = supplemental;
     this._identityPopupContentVerif.textContent = verifier;
   },
 
   hideIdentityPopup : function() {
     this._identityPopup.hidePopup();
   },
 
+  _popupOpenTime : null,
+
   /**
    * Click handler for the identity-box element in primary chrome.
    */
   handleIdentityButtonEvent : function(event) {
-
+    this._popupOpenTime = new Date();
     event.stopPropagation();
 
     if ((event.type == "click" && event.button != 0) ||
         (event.type == "keypress" && event.charCode != KeyEvent.DOM_VK_SPACE &&
          event.keyCode != KeyEvent.DOM_VK_RETURN))
       return; // Left click, space or enter only
 
     // Revert the contents of the location bar, see bug 406779
@@ -8199,16 +8218,27 @@ var gIdentityHandler = {
       e.currentTarget.removeEventListener("popuphidden", arguments.callee, false);
       self._identityBox.removeAttribute("open");
     }, false);
 
     // Now open the popup, anchored off the primary chrome element
     this._identityPopup.openPopup(this._identityBox, "bottomcenter topleft");
   },
 
+  onPopupShown : function(event) {
+    let openingDuration = new Date() - this._popupOpenTime;
+    this._popupOpenTime = null;
+    try {
+      Services.telemetry.getHistogramById("FX_IDENTITY_POPUP_OPEN_MS").add(openingDuration);
+    } catch (ex) {
+      Components.utils.reportError("Unable to report telemetry for FX_IDENTITY_POPUP_OPEN_MS.");
+    }
+    document.getElementById('identity-popup-more-info-button').focus();
+  },
+
   onDragStart: function (event) {
     if (gURLBar.getAttribute("pageproxystate") != "valid")
       return;
 
     var value = content.location.href;
     var urlString = value + "\n" + content.document.title;
     var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -299,17 +299,17 @@
            orient="vertical"
            role="alert"/>
 
     <!-- Popup for site identity information -->
     <panel id="identity-popup"
            type="arrow"
            hidden="true"
            noautofocus="true"
-           onpopupshown="document.getElementById('identity-popup-more-info-button').focus();"
+           onpopupshown="gIdentityHandler.onPopupShown(event);"
            level="top">
       <hbox id="identity-popup-container" align="top">
         <image id="identity-popup-icon"/>
         <vbox id="identity-popup-content-box">
           <label id="identity-popup-connectedToLabel"
                  class="identity-popup-label"
                  value="&identity.connectedTo;"/>
           <label id="identity-popup-connectedToLabel2"
--- a/browser/base/content/newtab/newTab.js
+++ b/browser/base/content/newtab/newTab.js
@@ -40,8 +40,11 @@ const THUMB_HEIGHT = 127;
 #include grid.js
 #include cells.js
 #include sites.js
 #include drag.js
 #include drop.js
 #include dropTargetShim.js
 #include dropPreview.js
 #include updater.js
+
+// Everything is loaded. Initialize the New Tab Page.
+gPage.init("#toolbar", "#grid");
--- a/browser/base/content/newtab/newTab.xul
+++ b/browser/base/content/newtab/newTab.xul
@@ -28,15 +28,13 @@
       </div>
 
       <ul id="grid">
         <li class="cell"/><li class="cell"/><li class="cell"/>
         <li class="cell"/><li class="cell"/><li class="cell"/>
         <li class="cell"/><li class="cell"/><li class="cell"/>
       </ul>
 
-      <xul:script type="text/javascript;version=1.8" src="chrome://browser/content/newtab/newTab.js"/>
-      <xul:script type="text/javascript;version=1.8">
-        gPage.init("#toolbar", "#grid");
-      </xul:script>
+      <xul:script type="text/javascript;version=1.8"
+                  src="chrome://browser/content/newtab/newTab.js"/>
     </body>
   </xul:vbox>
 </xul:window>
--- a/browser/components/tabview/groupitems.js
+++ b/browser/components/tabview/groupitems.js
@@ -1851,17 +1851,17 @@ GroupItem.prototype = Utils.extend(new I
   //    closedLastTab - boolean indicates the last tab has just been closed
   newTab: function GroupItem_newTab(url, options) {
     if (options && options.closedLastTab)
       UI.closedLastTabInTabView = true;
 
     UI.setActive(this, { dontSetActiveTabInGroup: true });
 
     let dontZoomIn = !!(options && options.dontZoomIn);
-    return gBrowser.loadOneTab(url || "about:blank", { inBackground: dontZoomIn });
+    return gBrowser.loadOneTab(url || gWindow.BROWSER_NEW_TAB_URL, { inBackground: dontZoomIn });
   },
 
   // ----------
   // Function: reorderTabItemsBasedOnTabOrder
   // Reorders the tabs in a groupItem based on the arrangment of the tabs
   // shown in the tab bar. It does it by sorting the children
   // of the groupItem by the positions of their respective tabs in the
   // tab bar.
--- a/browser/components/tabview/iq.js
+++ b/browser/components/tabview/iq.js
@@ -787,16 +787,17 @@ let events = [
   'keydown',
   'keypress',
   'mouseup',
   'mousedown',
   'mouseover',
   'mouseout',
   'mousemove',
   'click',
+  'dblclick',
   'resize',
   'change',
   'blur',
   'focus'
 ];
 
 events.forEach(function(event) {
   iQClass.prototype[event] = function(func) {
--- a/browser/components/tabview/test/browser_tabview_bug604098.js
+++ b/browser/components/tabview/test/browser_tabview_bug604098.js
@@ -25,21 +25,17 @@ function test1() {
   is(groupItems.length, 1, "there is one groupItem");
 
   whenTabViewIsHidden(function() {
     gBrowser.selectedTab = gBrowser.tabs[0];
     is(groupItems.length, 2, "there are two groupItems");
     closeGroupItem(groupItems[1], finish);
   });
 
-  // first click
-  mouseClick(contentElement, 0);
-  // second click
-  mouseClick(contentElement, 0);
+  // double click
+  doubleClick(contentElement, 0);
 }
 
-function mouseClick(targetElement, buttonCode) {
+function doubleClick(targetElement, buttonCode) {
   EventUtils.sendMouseEvent(
-    { type: "mousedown", button: buttonCode }, targetElement, contentWindow);
-  EventUtils.sendMouseEvent(
-    { type: "mouseup", button: buttonCode }, targetElement, contentWindow);
+    { type: "dblclick", button: buttonCode }, targetElement, contentWindow);
 }
 
--- a/browser/components/tabview/test/browser_tabview_bug626455.js
+++ b/browser/components/tabview/test/browser_tabview_bug626455.js
@@ -75,17 +75,17 @@ function testLeavePage() {
 
 function finishTest() {
   is(gBrowser.tabs.length, 1,
      "The total number of tab is 1 after leaving the page");
   is(contentWindow.TabItems.getItems().length, 1,
      "The total number of tab items is 1 after leaving the page");
 
   let location = gBrowser.browsers[0].currentURI.spec;
-  is(location, "about:blank", "The open tab is the expected one");
+  is(location, BROWSER_NEW_TAB_URL, "The open tab is the expected one");
 
   isnot(contentWindow.GroupItems.getActiveGroupItem(), activeGroup,
      "Active group is no longer the same");
 
   is(contentWindow.GroupItems.groupItems.length, 1,
      "Only one group is open");
 
   finish();
--- a/browser/components/tabview/test/browser_tabview_bug626791.js
+++ b/browser/components/tabview/test/browser_tabview_bug626791.js
@@ -74,18 +74,17 @@ function test() {
     prefix = 'create-orphan';
     assertNumberOfTabs(1);
     assertToolbarButtonNotExists();
 
     let width = cw.innerWidth;
     let height = cw.innerHeight;
 
     let body = cw.document.body;
-    EventUtils.synthesizeMouse(body, width - 10, height - 10, {}, cw);
-    EventUtils.synthesizeMouse(body, width - 10, height - 10, {}, cw);
+    EventUtils.synthesizeMouse(body, width - 10, height - 10, { clickCount: 2 }, cw);
 
     whenTabViewIsHidden(function () {
       assertNumberOfTabs(2);
       assertToolbarButtonExists();
 
       next();
     }, win);
   }
--- a/browser/components/tabview/test/browser_tabview_snapping.js
+++ b/browser/components/tabview/test/browser_tabview_snapping.js
@@ -29,24 +29,17 @@ function onTabViewWindowLoaded(win) {
   ok(secondGroup.getBounds().equals(secondBox), "This second group got its bounds");
   
   // A third group is created later, but multiple functions need access to it.
   let thirdGroup = null;
 
   is(secondGroup.getBounds().top - firstGroup.getBounds().bottom, 40,
     "There's currently 40 px between the first group and second group");
 
-  // set double click interval to negative so quick drag and drop doesn't 
-  // trigger the double click code.
-  let origDBlClickInterval = contentWindow.UI.DBLCLICK_INTERVAL;
-  contentWindow.UI.DBLCLICK_INTERVAL = -1;
-
   let endGame = function() {
-    contentWindow.UI.DBLCLICK_INTERVAL = origDBlClickInterval;
-
     firstGroup.container.parentNode.removeChild(firstGroup.container);
     firstGroup.close();
     thirdGroup.container.parentNode.removeChild(thirdGroup.container);
     thirdGroup.close();
 
     win.close();
     ok(win.closed, "new window is closed");
     finish();
--- a/browser/components/tabview/ui.js
+++ b/browser/components/tabview/ui.js
@@ -46,26 +46,16 @@
 // Title: ui.js
 
 let Keys = { meta: false };
 
 // ##########
 // Class: UI
 // Singleton top-level UI manager.
 let UI = {
-  // Constant: DBLCLICK_INTERVAL
-  // Defines the maximum time (in ms) between two clicks for it to count as
-  // a double click.
-  DBLCLICK_INTERVAL: 500,
-
-  // Constant: DBLCLICK_OFFSET
-  // Defines the maximum offset (in pixels) between two clicks for it to count as
-  // a double click.
-  DBLCLICK_OFFSET: 5,
-
   // Variable: _frameInitialized
   // True if the Tab View UI frame has been initialized.
   _frameInitialized: false,
 
   // Variable: _pageBounds
   // Stores the page bounds.
   _pageBounds: null,
 
@@ -95,21 +85,16 @@ let UI = {
   // TabView UI and re-orders the tabs when switcing back to main browser.
   _reorderTabsOnHide: [],
 
   // Variable: _currentTab
   // Keeps track of which xul:tab we are currently on.
   // Used to facilitate zooming down from a previous tab.
   _currentTab: null,
 
-  // Variable: _lastClick
-  // Keeps track of the time of last click event to detect double click.
-  // Used to create tabs on double-click since we cannot attach 'dblclick'
-  _lastClick: 0,
-
   // Variable: _eventListeners
   // Keeps track of event listeners added to the AllTabs object.
   _eventListeners: {},
 
   // Variable: _cleanupFunctions
   // An array of functions to be called at uninit time
   _cleanupFunctions: [],
   
@@ -207,48 +192,36 @@ let UI = {
       iQ(gTabViewFrame.contentDocument).mousedown(function(e) {
         if (iQ(":focus").length > 0) {
           iQ(":focus").each(function(element) {
             // don't fire blur event if the same input element is clicked.
             if (e.target != element && element.nodeName == "INPUT")
               element.blur();
           });
         }
-        if (e.originalTarget.id == "content") {
-          if (!Utils.isLeftClick(e)) {
-            self._lastClick = 0;
-            self._lastClickPositions = null;
-          } else {
-            // Create a group with one tab on double click
-            if (Date.now() - self._lastClick <= self.DBLCLICK_INTERVAL && 
-                (self._lastClickPositions.x - self.DBLCLICK_OFFSET) <= e.clientX &&
-                (self._lastClickPositions.x + self.DBLCLICK_OFFSET) >= e.clientX &&
-                (self._lastClickPositions.y - self.DBLCLICK_OFFSET) <= e.clientY &&
-                (self._lastClickPositions.y + self.DBLCLICK_OFFSET) >= e.clientY) {
+        if (e.originalTarget.id == "content" &&
+            Utils.isLeftClick(e) &&
+            e.detail == 1) {
+          self._createGroupItemOnDrag(e);
+        }
+      });
 
-              let box =
-                new Rect(e.clientX - Math.floor(TabItems.tabWidth/2),
-                         e.clientY - Math.floor(TabItems.tabHeight/2),
-                         TabItems.tabWidth, TabItems.tabHeight);
-              box.inset(-30, -30);
-
-              let opts = {immediately: true, bounds: box};
-              let groupItem = new GroupItem([], opts);
-              groupItem.newTab();
+      iQ(gTabViewFrame.contentDocument).dblclick(function(e) {
+        // Create a group with one tab on double click
+        let box =
+          new Rect(e.clientX - Math.floor(TabItems.tabWidth/2),
+                   e.clientY - Math.floor(TabItems.tabHeight/2),
+                   TabItems.tabWidth, TabItems.tabHeight);
+        box.inset(-30, -30);
 
-              self._lastClick = 0;
-              self._lastClickPositions = null;
-              gTabView.firstUseExperienced = true;
-            } else {
-              self._lastClick = Date.now();
-              self._lastClickPositions = new Point(e.clientX, e.clientY);
-              self._createGroupItemOnDrag(e);
-            }
-          }
-        }
+        let opts = {immediately: true, bounds: box};
+        let groupItem = new GroupItem([], opts);
+        groupItem.newTab();
+
+        gTabView.firstUseExperienced = true;
       });
 
       iQ(window).bind("unload", function() {
         self.uninit();
       });
 
       // ___ setup DOMWillOpenModalDialog message handler
       let mm = gWindow.messageManager;
--- a/browser/components/thumbnails/PageThumbs.jsm
+++ b/browser/components/thumbnails/PageThumbs.jsm
@@ -72,51 +72,62 @@ let PageThumbs = {
   },
 
   /**
    * Creates a canvas containing a thumbnail depicting the given window.
    * @param aWindow The DOM window to capture a thumbnail from.
    * @return The newly created canvas containing the image data.
    */
   capture: function PageThumbs_capture(aWindow) {
+    let telemetryCaptureTime = new Date();
     let [sw, sh, scale] = this._determineCropSize(aWindow);
 
     let canvas = this._createCanvas();
     let ctx = canvas.getContext("2d");
 
     // Scale the canvas accordingly.
     ctx.scale(scale, scale);
 
     try {
       // Draw the window contents to the canvas.
       ctx.drawWindow(aWindow, 0, 0, sw, sh, THUMBNAIL_BG_COLOR,
                      ctx.DRAWWINDOW_DO_NOT_FLUSH);
     } catch (e) {
       // We couldn't draw to the canvas for some reason.
     }
 
+    Services.telemetry.getHistogramById("FX_THUMBNAILS_CAPTURE_TIME_MS")
+      .add(new Date() - telemetryCaptureTime);
+
     return canvas;
   },
 
   /**
    * Stores the image data contained in the given canvas to the underlying
    * storage.
    * @param aKey The key to use for the storage.
    * @param aCanvas The canvas containing the thumbnail's image data.
    * @param aCallback The function to be called when the canvas data has been
    *                  stored (optional).
    */
   store: function PageThumbs_store(aKey, aCanvas, aCallback) {
-    let self = this;
+    let telemetryStoreTime = new Date();
 
     function finish(aSuccessful) {
+      if (aSuccessful) {
+        Services.telemetry.getHistogramById("FX_THUMBNAILS_STORE_TIME_MS")
+          .add(new Date() - telemetryStoreTime);
+      }
+
       if (aCallback)
         aCallback(aSuccessful);
     }
 
+    let self = this;
+
     // Get a writeable cache entry.
     PageThumbsCache.getWriteEntry(aKey, function (aEntry) {
       if (!aEntry) {
         finish(false);
         return;
       }
 
       // Extract image data from the canvas.
--- a/browser/components/thumbnails/PageThumbsProtocol.js
+++ b/browser/components/thumbnails/PageThumbsProtocol.js
@@ -124,22 +124,28 @@ Channel.prototype = {
     this._listener = aListener;
     this._context = aContext;
 
     this._isPending = true;
     this._wasOpened = true;
 
     // Try to read the data from the thumbnail cache.
     this._readCache(function (aData) {
+      let telemetryThumbnailFound = true;
+
       // Update response if there's no data.
       if (!aData) {
         this._responseStatus = 404;
         this._responseText = "Not Found";
+        telemetryThumbnailFound = false;
       }
 
+      Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
+        .add(telemetryThumbnailFound);
+
       this._startRequest();
 
       if (!this.canceled) {
         this._addToLoadGroup();
 
         if (aData)
           this._serveData(aData);
 
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -44,16 +44,17 @@
 #include "CheckedInt.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "nsContentUtils.h"
 #include "nsJSUtils.h"
 #include "nsMathUtils.h"
+#include "nsStreamUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 
 #include "nsFrameManager.h"
 #include "nsDisplayList.h"
 #include "ImageLayers.h"
 #include "BasicLayers.h"
 #include "imgIEncoder.h"
@@ -230,17 +231,25 @@ nsHTMLCanvasElement::MozFetchAsStream(ns
   nsCOMPtr<nsIInputStream> inputData;
 
   rv = ExtractData(aType, EmptyString(), getter_AddRefs(inputData), fellBackToPNG);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIAsyncInputStream> asyncData = do_QueryInterface(inputData, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return aCallback->OnInputStreamReady(asyncData);
+  nsCOMPtr<nsIThread> mainThread;
+  rv = NS_GetMainThread(getter_AddRefs(mainThread));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIInputStreamCallback> asyncCallback;
+  rv = NS_NewInputStreamReadyEvent(getter_AddRefs(asyncCallback), aCallback, mainThread);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return asyncCallback->OnInputStreamReady(asyncData);
 }
 
 nsresult
 nsHTMLCanvasElement::ExtractData(const nsAString& aType,
                                  const nsAString& aOptions,
                                  nsIInputStream** aStream,
                                  bool& aFellBackToPNG)
 {
--- a/toolkit/components/telemetry/TelemetryHistograms.h
+++ b/toolkit/components/telemetry/TelemetryHistograms.h
@@ -305,19 +305,28 @@ HISTOGRAM(THUNDERBIRD_CONVERSATIONS_TIME
 HISTOGRAM(THUNDERBIRD_INDEXING_RATE_MSG_PER_S, 1, 100, 20, LINEAR, "Gloda: indexing rate (message/s)")
 // #endif
 
 /**
  * Firefox-specific telemetry.
  */
 // Disable this application-specific #ifdef ftb. (See bug 710562)
 // #ifdef MOZ_PHOENIX
-HISTOGRAM(FX_TAB_ANIM_OPEN_MS, 1, 3000, 10, EXPONENTIAL, "Firefox: Time taken by the tab opening animation")
-HISTOGRAM(FX_TAB_ANIM_CLOSE_MS, 1, 3000, 10, EXPONENTIAL, "Firefox: Time taken by the tab closing animation")
+HISTOGRAM(FX_TAB_ANIM_OPEN_MS, 1, 3000, 10, EXPONENTIAL, "Firefox: Time taken by the tab opening animation in milliseconds")
+HISTOGRAM(FX_TAB_ANIM_CLOSE_MS, 1, 3000, 10, EXPONENTIAL, "Firefox: Time taken by the tab closing animation in milliseconds")
 HISTOGRAM_BOOLEAN(FX_CONTEXT_SEARCH_AND_TAB_SELECT, "Firefox: Background tab was selected within 5 seconds of searching from the context menu")
+HISTOGRAM(FX_IDENTITY_POPUP_OPEN_MS, 1, 1000, 10, EXPONENTIAL, "Firefox: Time taken by the identity popup to open in milliseconds")
+HISTOGRAM(FX_APP_MENU_OPEN_MS, 1, 1000, 10, EXPONENTIAL, "Firefox: Time taken by the app-menu opening in milliseconds")
+
+/**
+ * Thumbnail Service telemetry.
+ */
+HISTOGRAM(FX_THUMBNAILS_CAPTURE_TIME_MS, 1, 500, 15, EXPONENTIAL, "THUMBNAILS: Time (ms) it takes to capture a thumbnail")
+HISTOGRAM(FX_THUMBNAILS_STORE_TIME_MS, 1, 500, 15, EXPONENTIAL, "THUMBNAILS: Time (ms) it takes to store a thumbnail in the cache")
+HISTOGRAM(FX_THUMBNAILS_HIT_OR_MISS, 0, 1, 2, BOOLEAN, "THUMBNAILS: Thumbnail found")
 // #endif
 
 HISTOGRAM_BOOLEAN(INNERWINDOWS_WITH_MUTATION_LISTENERS, "Deleted or to-be-reused innerwindow which has had mutation event listeners.")
 HISTOGRAM(XUL_FOREGROUND_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "XUL reflows in foreground windows (ms)")
 HISTOGRAM(XUL_BACKGROUND_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "XUL reflows in background windows (ms)")
 HISTOGRAM(HTML_FOREGROUND_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "HTML reflows in foreground windows (ms)")
 HISTOGRAM(HTML_BACKGROUND_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "HTML reflows in background windows (ms)")
 HISTOGRAM(XUL_INITIAL_FRAME_CONSTRUCTION, 1, 3000, 10, EXPONENTIAL, "initial xul frame construction")
--- a/toolkit/content/tests/widgets/Makefile.in
+++ b/toolkit/content/tests/widgets/Makefile.in
@@ -53,16 +53,17 @@ include $(topsrcdir)/config/rules.mk
                 test_contextmenu_nested.xul \
 		test_tree_column_reorder.xul \
 		tree_shared.js \
 		test_mousecapture_area.html \
 		popup_shared.js \
                 test_videocontrols.html \
 		test_videocontrols_video_direction.html \
 		test_videocontrols_audio_direction.html \
+		test_audiocontrols_dimensions.html \
 		videocontrols_direction-1-ref.html \
 		videocontrols_direction-1a.html \
 		videocontrols_direction-1b.html \
 		videocontrols_direction-1c.html \
 		videocontrols_direction-1d.html \
 		videocontrols_direction-1e.html \
 		videocontrols_direction-2-ref.html \
 		videocontrols_direction-2a.html \
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/widgets/test_audiocontrols_dimensions.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Audio controls test</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>  
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+
+<div id="content">
+  <audio id="audio" src="audio.wav" controls preload="auto"></audio>
+</div>
+
+<pre id="test">
+<script type="text/javascript" src="use_large_cache.js"></script>
+<script class="testbody" type="text/javascript">
+  function loadedmetadata(event) {
+    is(event.type, "loadedmetadata", "checking event type");
+    is(audio.clientHeight, "28", "checking height of audio element");
+
+    SimpleTest.finish();
+  }
+
+  var audio = document.getElementById("audio"), video;
+
+  // Kick off test once audio has loaded.
+  audio.addEventListener("loadedmetadata", loadedmetadata, false);
+
+  SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
--- a/toolkit/content/widgets/videocontrols.xml
+++ b/toolkit/content/widgets/videocontrols.xml
@@ -1303,17 +1303,18 @@
                     //
                     // For videos with |autoplay| set, we'll leave the controls initially hidden,
                     // so that they don't get in the way of the playing video. Otherwise we'll
                     // go ahead and reveal the controls now, so they're an obvious user cue.
                     //
                     // (Note: the |controls| attribute is already handled via layout/style/html.css)
                     var shouldShow = (!(this.video.autoplay && this.video.mozAutoplayEnabled) || !this.dynamicControls);
                     // Hide the overlay if the video time is non-zero or if an error occurred to workaround bug 718107.
-                    this.startFade(this.clickToPlay, shouldShow && this.video.currentTime == 0 && !this.hasError(), true);
+                    this.startFade(this.clickToPlay, shouldShow && !this.isAudioOnly &&
+                                   this.video.currentTime == 0 && !this.hasError(), true);
                     this.startFade(this.controlBar, shouldShow, true);
 
                     // Use the handleEvent() callback for all media events.
                     // The "error" event listener must capture, so that it can trap error events
                     // from the <source> children, which don't bubble.
                     for each (let event in this.videoEvents)
                         this.video.addEventListener(event, this, (event == "error") ? true : false);
 
--- a/toolkit/themes/pinstripe/global/media/videoClickToPlayButton.svg
+++ b/toolkit/themes/pinstripe/global/media/videoClickToPlayButton.svg
@@ -65,35 +65,35 @@
         <feMergeNode
            in="offsetBlur" />
         <feMergeNode
            in="SourceGraphic" />
       </feMerge>
     </filter>
     <mask id="dropShadowMask">
       <path
-         d="M47.285,29.991L23.75,16.24c-0.357-0.208-0.692-0.278-0.969-0.221 C22.32,16.114,22,16.555,22,17.251v27.5c0,1.112,0.797,1.568,1.75,1.011l23.535-13.749C48.238,31.458,48.238,30.546,47.285,29.991z M0,0v64h64V0H0z M32,59C16.536,59,4,46.464,4,31S16.536,3,32,3s28,12.536,28,28S47.464,59,32,59z"
+         d="M47.285,30.991L23.75,17.24c-0.357-0.208-0.692-0.278-0.969-0.221 C22.32,17.115,22,17.555,22,18.252v27.499c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748C48.238,32.458,48.238,31.547,47.285,30.991 z M0,0v64h64V0H0z M32,60C16.536,60,4,47.464,4,32S16.536,4,32,4s28,12.536,28,28S47.464,60,32,60z"
          id="dropShadowMaskPath"
          style="fill:#ffffff;fill-opacity:1;stroke:none" />
     </mask>       
   </defs>
   <path 
-     d="M32,3C16.536,3,4,15.536,4,31s12.536,28,28,28s28-12.536,28-28S47.464,3,32,3z M47.285,32.013L23.75,45.762C22.797,46.319,22,45.863,22,44.751v-27.5c0-0.697,0.32-1.137,0.781-1.232 c0.277-0.058,0.612,0.012,0.969,0.221l23.535,13.751C48.238,30.546,48.238,31.458,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M47.285,33.014 L23.75,46.762C22.797,47.319,22,46.863,22,45.751v-27.5c0-0.697,0.32-1.137,0.781-1.232c0.277-0.058,0.612,0.012,0.969,0.221 l23.535,13.751C48.238,31.546,48.238,32.458,47.285,33.014z"
      mask="url(#dropShadowMask)"
      id="playButtonShadow"
      style="fill:black;fill-opacity:1;stroke:none;filter:url(#dropShadow)" />
   <path
-     d="M22.781,16.019C22.32,16.114,22,16.555,22,17.251v27.5c0,1.112,0.797,1.568,1.75,1.011 l23.535-13.749c0.953-0.556,0.953-1.467,0-2.022L23.75,16.24C23.393,16.031,23.058,15.961,22.781,16.019z"
+     d="M22.781,17.019C22.32,17.114,22,17.555,22,18.251v27.5c0,1.112,0.797,1.568,1.75,1.011 l23.535-13.748c0.953-0.556,0.953-1.467,0-2.023L23.75,17.24C23.393,17.031,23.058,16.961,22.781,17.019z"
      id="playButtonArrow"
      style="fill:url(#arrowGradient);fill-opacity:1;stroke:none" />
   <path 
-     d="M32,3C16.536,3,4,15.536,4,31s12.536,28,28,28s28-12.536,28-28S47.464,3,32,3z M47.285,32.013L23.75,45.762C22.797,46.319,22,45.863,22,44.751v-27.5c0-0.697,0.32-1.137,0.781-1.232 c0.277-0.058,0.612,0.012,0.969,0.221l23.535,13.751C48.238,30.546,48.238,31.458,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M47.285,33.014 L23.75,46.762C22.797,47.319,22,46.863,22,45.751v-27.5c0-0.697,0.32-1.137,0.781-1.232c0.277-0.058,0.612,0.012,0.969,0.221 l23.535,13.751C48.238,31.546,48.238,32.458,47.285,33.014z"
      id="playButton"
      style="fill:url(#whiteGradient);fill-opacity:1;stroke:none" />
   <path
-     d="M32,3C16.536,3,4,15.536,4,31s12.536,28,28,28s28-12.536,28-28S47.464,3,32,3 z M32,58C17.112,58,5,45.888,5,31S17.112,4,32,4s27,12.112,27,27S46.888,58,32,58z M47.789,29.127l-23.534-13.75 C23.826,15.126,23.396,15,22.976,15c-0.135,0-0.27,0.014-0.398,0.041C21.62,15.238,21,16.106,21,17.251v27.5 C21,46.075,21.812,47,22.977,47c0.423,0,0.854-0.126,1.279-0.375L47.79,32.876c0.769-0.448,1.21-1.131,1.21-1.875 S48.559,29.576,47.789,29.127z M47.285,32.013L23.75,45.762C23.474,45.924,23.211,46,22.977,46C22.402,46,22,45.541,22,44.751v-27.5 c0-0.697,0.32-1.137,0.781-1.232L22.976,16c0.233,0,0.498,0.079,0.775,0.24l23.535,13.751 C48.238,30.546,48.238,31.458,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M32,59C17.112,59,5,46.888,5,32S17.112,5,32,5s27,12.112,27,27S46.888,59,32,59z M47.789,30.127l-23.534-13.75 C23.826,16.126,23.396,16,22.976,16c-0.135,0-0.27,0.014-0.398,0.041C21.62,16.238,21,17.106,21,18.251v27.5 C21,47.075,21.812,48,22.977,48c0.423,0,0.854-0.126,1.279-0.375L47.79,33.877c0.769-0.449,1.21-1.132,1.21-1.875 S48.559,30.576,47.789,30.127z M47.285,33.014L23.75,46.762C23.474,46.924,23.211,47,22.977,47C22.402,47,22,46.541,22,45.751v-27.5 c0-0.697,0.32-1.137,0.781-1.232L22.976,17c0.233,0,0.498,0.079,0.775,0.24l23.535,13.751 C48.238,31.546,48.238,32.458,47.285,33.014z"
      id="playButtonEdgeHighlights"
      style="fill:white;fill-opacity:.3;stroke:none" />
   <path
-     d="M32,3C16.536,3,4,15.536,4,31c0,0.167,0.01,0.333,0.013,0.5C4.28,16.268,16.704,4,32,4 c15.296,0,27.72,12.268,27.987,27.5C59.99,31.333,60,31.167,60,31C60,15.536,47.464,3,32,3z M47.285,32.013L23.75,45.762 C22.797,46.319,22,45.863,22,44.751v1c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748c0.697-0.407,0.879-1.003,0.556-1.512 C47.723,31.688,47.541,31.864,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32c0,0.167,0.01,0.333,0.013,0.5 C4.28,17.268,16.704,5,32,5c15.296,0,27.72,12.268,27.987,27.5C59.99,32.333,60,32.167,60,32C60,16.536,47.464,4,32,4z M47.285,33.014L23.75,46.762C22.797,47.319,22,46.863,22,45.751v1c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748 c0.697-0.406,0.879-1.003,0.556-1.512C47.723,32.688,47.541,32.864,47.285,33.014z"
      id="playButtonTopEdgeHighlights"
      style="fill:white;fill-opacity:.8;stroke:none" />
 </svg>
--- a/toolkit/themes/winstripe/global/media/videoClickToPlayButton.svg
+++ b/toolkit/themes/winstripe/global/media/videoClickToPlayButton.svg
@@ -65,35 +65,35 @@
         <feMergeNode
            in="offsetBlur" />
         <feMergeNode
            in="SourceGraphic" />
       </feMerge>
     </filter>
     <mask id="dropShadowMask">
       <path
-         d="M47.285,29.991L23.75,16.24c-0.357-0.208-0.692-0.278-0.969-0.221 C22.32,16.114,22,16.555,22,17.251v27.5c0,1.112,0.797,1.568,1.75,1.011l23.535-13.749C48.238,31.458,48.238,30.546,47.285,29.991z M0,0v64h64V0H0z M32,59C16.536,59,4,46.464,4,31S16.536,3,32,3s28,12.536,28,28S47.464,59,32,59z"
+         d="M47.285,30.991L23.75,17.24c-0.357-0.208-0.692-0.278-0.969-0.221 C22.32,17.115,22,17.555,22,18.252v27.499c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748C48.238,32.458,48.238,31.547,47.285,30.991 z M0,0v64h64V0H0z M32,60C16.536,60,4,47.464,4,32S16.536,4,32,4s28,12.536,28,28S47.464,60,32,60z"
          id="dropShadowMaskPath"
          style="fill:#ffffff;fill-opacity:1;stroke:none" />
     </mask>       
   </defs>
   <path 
-     d="M32,3C16.536,3,4,15.536,4,31s12.536,28,28,28s28-12.536,28-28S47.464,3,32,3z M47.285,32.013L23.75,45.762C22.797,46.319,22,45.863,22,44.751v-27.5c0-0.697,0.32-1.137,0.781-1.232 c0.277-0.058,0.612,0.012,0.969,0.221l23.535,13.751C48.238,30.546,48.238,31.458,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M47.285,33.014 L23.75,46.762C22.797,47.319,22,46.863,22,45.751v-27.5c0-0.697,0.32-1.137,0.781-1.232c0.277-0.058,0.612,0.012,0.969,0.221 l23.535,13.751C48.238,31.546,48.238,32.458,47.285,33.014z"
      mask="url(#dropShadowMask)"
      id="playButtonShadow"
      style="fill:black;fill-opacity:1;stroke:none;filter:url(#dropShadow)" />
   <path
-     d="M22.781,16.019C22.32,16.114,22,16.555,22,17.251v27.5c0,1.112,0.797,1.568,1.75,1.011 l23.535-13.749c0.953-0.556,0.953-1.467,0-2.022L23.75,16.24C23.393,16.031,23.058,15.961,22.781,16.019z"
+     d="M22.781,17.019C22.32,17.114,22,17.555,22,18.251v27.5c0,1.112,0.797,1.568,1.75,1.011 l23.535-13.748c0.953-0.556,0.953-1.467,0-2.023L23.75,17.24C23.393,17.031,23.058,16.961,22.781,17.019z"
      id="playButtonArrow"
      style="fill:url(#arrowGradient);fill-opacity:1;stroke:none" />
   <path 
-     d="M32,3C16.536,3,4,15.536,4,31s12.536,28,28,28s28-12.536,28-28S47.464,3,32,3z M47.285,32.013L23.75,45.762C22.797,46.319,22,45.863,22,44.751v-27.5c0-0.697,0.32-1.137,0.781-1.232 c0.277-0.058,0.612,0.012,0.969,0.221l23.535,13.751C48.238,30.546,48.238,31.458,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M47.285,33.014 L23.75,46.762C22.797,47.319,22,46.863,22,45.751v-27.5c0-0.697,0.32-1.137,0.781-1.232c0.277-0.058,0.612,0.012,0.969,0.221 l23.535,13.751C48.238,31.546,48.238,32.458,47.285,33.014z"
      id="playButton"
      style="fill:url(#whiteGradient);fill-opacity:1;stroke:none" />
   <path
-     d="M32,3C16.536,3,4,15.536,4,31s12.536,28,28,28s28-12.536,28-28S47.464,3,32,3 z M32,58C17.112,58,5,45.888,5,31S17.112,4,32,4s27,12.112,27,27S46.888,58,32,58z M47.789,29.127l-23.534-13.75 C23.826,15.126,23.396,15,22.976,15c-0.135,0-0.27,0.014-0.398,0.041C21.62,15.238,21,16.106,21,17.251v27.5 C21,46.075,21.812,47,22.977,47c0.423,0,0.854-0.126,1.279-0.375L47.79,32.876c0.769-0.448,1.21-1.131,1.21-1.875 S48.559,29.576,47.789,29.127z M47.285,32.013L23.75,45.762C23.474,45.924,23.211,46,22.977,46C22.402,46,22,45.541,22,44.751v-27.5 c0-0.697,0.32-1.137,0.781-1.232L22.976,16c0.233,0,0.498,0.079,0.775,0.24l23.535,13.751 C48.238,30.546,48.238,31.458,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M32,59C17.112,59,5,46.888,5,32S17.112,5,32,5s27,12.112,27,27S46.888,59,32,59z M47.789,30.127l-23.534-13.75 C23.826,16.126,23.396,16,22.976,16c-0.135,0-0.27,0.014-0.398,0.041C21.62,16.238,21,17.106,21,18.251v27.5 C21,47.075,21.812,48,22.977,48c0.423,0,0.854-0.126,1.279-0.375L47.79,33.877c0.769-0.449,1.21-1.132,1.21-1.875 S48.559,30.576,47.789,30.127z M47.285,33.014L23.75,46.762C23.474,46.924,23.211,47,22.977,47C22.402,47,22,46.541,22,45.751v-27.5 c0-0.697,0.32-1.137,0.781-1.232L22.976,17c0.233,0,0.498,0.079,0.775,0.24l23.535,13.751 C48.238,31.546,48.238,32.458,47.285,33.014z"
      id="playButtonEdgeHighlights"
      style="fill:white;fill-opacity:.3;stroke:none" />
   <path
-     d="M32,3C16.536,3,4,15.536,4,31c0,0.167,0.01,0.333,0.013,0.5C4.28,16.268,16.704,4,32,4 c15.296,0,27.72,12.268,27.987,27.5C59.99,31.333,60,31.167,60,31C60,15.536,47.464,3,32,3z M47.285,32.013L23.75,45.762 C22.797,46.319,22,45.863,22,44.751v1c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748c0.697-0.407,0.879-1.003,0.556-1.512 C47.723,31.688,47.541,31.864,47.285,32.013z"
+     d="M32,4C16.536,4,4,16.536,4,32c0,0.167,0.01,0.333,0.013,0.5 C4.28,17.268,16.704,5,32,5c15.296,0,27.72,12.268,27.987,27.5C59.99,32.333,60,32.167,60,32C60,16.536,47.464,4,32,4z M47.285,33.014L23.75,46.762C22.797,47.319,22,46.863,22,45.751v1c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748 c0.697-0.406,0.879-1.003,0.556-1.512C47.723,32.688,47.541,32.864,47.285,33.014z"
      id="playButtonTopEdgeHighlights"
      style="fill:white;fill-opacity:.8;stroke:none" />
 </svg>