Merge MC->JM
authorBrian Hackett <bhackett1024@gmail.com>
Tue, 06 Sep 2011 14:53:24 -0700
changeset 76590 445b1e86590c42f2a5a66eacd15164fb6125cd46
parent 76589 a18eade1678f15b6dc44dd4dcad510994b46fb3c (current diff)
parent 76571 6a4e5dbe0d64d7646306b4c9fc50a69b29631551 (diff)
child 76591 e675a8b040a75140663c0fc06a7092de89400395
child 76662 02f42784ccb28b942b345d44d3465daf4ed78376
child 77049 c2726640029ff54f418ba361e6f330fc37bcc650
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone9.0a1
Merge MC->JM
--- a/accessible/public/nsIAccessible.idl
+++ b/accessible/public/nsIAccessible.idl
@@ -51,17 +51,17 @@ interface nsIAccessibleRelation;
  * accessibility APIs like MSAA and ATK. Contains the sum of what's needed
  * to support IAccessible as well as ATK's generic accessibility objects.
  * Can also be used by in-process accessibility clients to get information
  * about objects in the accessible tree. The accessible tree is a subset of 
  * nodes in the DOM tree -- such as documents, focusable elements and text.
  * Mozilla creates the implementations of nsIAccessible on demand.
  * See http://www.mozilla.org/projects/ui/accessibility for more information.
  */
-[scriptable, uuid(c7ac764a-b4c5-4479-9fb7-06e3c9f3db34)]
+[scriptable, uuid(3126544c-826c-4694-a2ed-67bfe56a1f37)]
 interface nsIAccessible : nsISupports
 {
   /**
    * Parent node in accessible tree.
    */
   readonly attribute nsIAccessible parent;
 
   /**
@@ -217,36 +217,16 @@ interface nsIAccessible : nsISupports
   nsIAccessible getDeepestChildAtPoint(in long x, in long y);
 
   /**
    * Nth accessible child using zero-based index or last child if index less than zero
    */
   nsIAccessible getChildAt(in long aChildIndex);
 
   /**
-   * Accessible node geometrically to the right of this one
-   */
-  nsIAccessible getAccessibleToRight();
-
-  /**
-   * Accessible node geometrically to the left of this one
-   */
-  nsIAccessible getAccessibleToLeft();
-
-  /**
-   * Accessible node geometrically above this one
-   */
-  nsIAccessible getAccessibleAbove();
-
-  /**
-   * Accessible node geometrically below this one
-   */
-  nsIAccessible getAccessibleBelow();
-
-  /**
    * Return accessible relation by the given relation type (see.
    * constants defined in nsIAccessibleRelation).
    */
   nsIAccessibleRelation getRelationByType(in unsigned long aRelationType);
 
   /**
    * Returns multiple accessible relations for this object.
    */
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1969,40 +1969,16 @@ nsAccessible::DoAction(PRUint8 aIndex)
 }
 
 /* DOMString getHelp (); */
 NS_IMETHODIMP nsAccessible::GetHelp(nsAString& _retval)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-/* nsIAccessible getAccessibleToRight(); */
-NS_IMETHODIMP nsAccessible::GetAccessibleToRight(nsIAccessible **_retval)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-/* nsIAccessible getAccessibleToLeft(); */
-NS_IMETHODIMP nsAccessible::GetAccessibleToLeft(nsIAccessible **_retval)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-/* nsIAccessible getAccessibleAbove(); */
-NS_IMETHODIMP nsAccessible::GetAccessibleAbove(nsIAccessible **_retval)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-/* nsIAccessible getAccessibleBelow(); */
-NS_IMETHODIMP nsAccessible::GetAccessibleBelow(nsIAccessible **_retval)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 nsIContent*
 nsAccessible::GetAtomicRegion() const
 {
   nsIContent *loopContent = mContent;
   nsAutoString atomic;
   while (loopContent && !loopContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic))
     loopContent = loopContent->GetParent();
 
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -805,52 +805,45 @@ STDMETHODIMP nsAccessibleWrap::accNaviga
       /* [in] */ long navDir,
       /* [optional][in] */ VARIANT varStart,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
 {
 __try {
   if (!pvarEndUpAt)
     return E_INVALIDARG;
 
-  nsAccessible *xpAccessibleStart = GetXPAccessibleFor(varStart);
-  if (!xpAccessibleStart || IsDefunct())
+  nsAccessible* accessible = GetXPAccessibleFor(varStart);
+  if (!accessible || accessible->IsDefunct())
     return E_FAIL;
 
   VariantInit(pvarEndUpAt);
 
-  nsCOMPtr<nsIAccessible> xpAccessibleResult;
+  nsAccessible* navAccessible = nsnull;
   PRUint32 xpRelation = 0;
 
   switch(navDir) {
-    case NAVDIR_DOWN:
-      xpAccessibleStart->GetAccessibleBelow(getter_AddRefs(xpAccessibleResult));
-      break;
     case NAVDIR_FIRSTCHILD:
-      if (!nsAccUtils::MustPrune(xpAccessibleStart))
-        xpAccessibleStart->GetFirstChild(getter_AddRefs(xpAccessibleResult));
+      if (!nsAccUtils::MustPrune(accessible))
+        navAccessible = accessible->FirstChild();
       break;
     case NAVDIR_LASTCHILD:
-      if (!nsAccUtils::MustPrune(xpAccessibleStart))
-        xpAccessibleStart->GetLastChild(getter_AddRefs(xpAccessibleResult));
-      break;
-    case NAVDIR_LEFT:
-      xpAccessibleStart->GetAccessibleToLeft(getter_AddRefs(xpAccessibleResult));
+      if (!nsAccUtils::MustPrune(accessible))
+        navAccessible = accessible->LastChild();
       break;
     case NAVDIR_NEXT:
-      xpAccessibleStart->GetNextSibling(getter_AddRefs(xpAccessibleResult));
+      navAccessible = accessible->NextSibling();
       break;
     case NAVDIR_PREVIOUS:
-      xpAccessibleStart->GetPreviousSibling(getter_AddRefs(xpAccessibleResult));
+      navAccessible = accessible->PrevSibling();
       break;
+    case NAVDIR_DOWN:
+    case NAVDIR_LEFT:
     case NAVDIR_RIGHT:
-      xpAccessibleStart->GetAccessibleToRight(getter_AddRefs(xpAccessibleResult));
-      break;
     case NAVDIR_UP:
-      xpAccessibleStart->GetAccessibleAbove(getter_AddRefs(xpAccessibleResult));
-      break;
+      return E_NOTIMPL;
 
     // MSAA relationship extensions to accNavigate
     case NAVRELATION_CONTROLLED_BY:
       xpRelation = nsIAccessibleRelation::RELATION_CONTROLLED_BY;
       break;
     case NAVRELATION_CONTROLLER_FOR:
       xpRelation = nsIAccessibleRelation::RELATION_CONTROLLER_FOR;
       break;
@@ -891,27 +884,30 @@ STDMETHODIMP nsAccessibleWrap::accNaviga
       xpRelation = nsIAccessibleRelation::RELATION_DEFAULT_BUTTON;
       break;
     case NAVRELATION_DESCRIBED_BY:
       xpRelation = nsIAccessibleRelation::RELATION_DESCRIBED_BY;
       break;
     case NAVRELATION_DESCRIPTION_FOR:
       xpRelation = nsIAccessibleRelation::RELATION_DESCRIPTION_FOR;
       break;
+
+    default:
+      return E_INVALIDARG;
   }
 
   pvarEndUpAt->vt = VT_EMPTY;
 
   if (xpRelation) {
     Relation rel = RelationByType(xpRelation);
-    xpAccessibleResult = rel.Next();
+    navAccessible = rel.Next();
   }
 
-  if (xpAccessibleResult) {
-    pvarEndUpAt->pdispVal = NativeAccessible(xpAccessibleResult);
+  if (navAccessible) {
+    pvarEndUpAt->pdispVal = NativeAccessible(navAccessible);
     pvarEndUpAt->vt = VT_DISPATCH;
     return S_OK;
   }
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::accHitTest(
--- a/browser/devtools/styleinspector/StyleInspector.jsm
+++ b/browser/devtools/styleinspector/StyleInspector.jsm
@@ -50,17 +50,23 @@ var StyleInspector = {
    * Is the Style Inspector enabled?
    * @returns {Boolean} true or false
    */
   get isEnabled()
   {
     return Services.prefs.getBoolPref("devtools.styleinspector.enabled");
   },
 
-  createPanel: function SI_createPanel()
+  /**
+   * Factory method to create the actual style panel
+   * @param {Boolean} aPreserveOnHide Prevents destroy from being called
+   * onpopuphide. USE WITH CAUTION: When this value is set to true then you are
+   * responsible to manually call destroy from outside the style inspector.
+   */
+  createPanel: function SI_createPanel(aPreserveOnHide)
   {
     let win = Services.wm.getMostRecentWindow("navigator:browser");
     let popupSet = win.document.getElementById("mainPopupSet");
     let ns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     let panel = win.document.createElementNS(ns, "panel");
 
     panel.setAttribute("orient", "vertical");
     panel.setAttribute("ignorekeys", "true");
@@ -93,31 +99,45 @@ var StyleInspector = {
     spacer.setAttribute("flex", "1");
     hbox.appendChild(spacer);
 
     let resizer = win.document.createElement("resizer");
     resizer.setAttribute("dir", "bottomend");
     hbox.appendChild(resizer);
     popupSet.appendChild(panel);
 
-    panel.addEventListener("popupshown", function SI_popup_shown() {
+    /**
+     * Initialize the popup when it is first shown
+     */
+    function SI_popupShown() {
       if (!this.cssHtmlTree) {
         this.cssLogic = new CssLogic();
         this.cssHtmlTree = new CssHtmlTree(iframe, this.cssLogic, this);
       }
 
       this.cssLogic.highlight(this.selectedNode);
       this.cssHtmlTree.highlight(this.selectedNode);
       Services.obs.notifyObservers(null, "StyleInspector-opened", null);
-    }, false);
+    }
 
-    panel.addEventListener("popuphidden", function SI_popup_hidden() {
-      Services.obs.notifyObservers(null, "StyleInspector-closed", null);
-    }, false);
-    
+    /**
+     * Hide the popup and conditionally destroy it
+     */
+    function SI_popupHidden() {
+      if (panel.preserveOnHide) {
+        Services.obs.notifyObservers(null, "StyleInspector-closed", null);
+      } else {
+        panel.destroy();
+      }
+    }
+
+    panel.addEventListener("popupshown", SI_popupShown);
+    panel.addEventListener("popuphidden", SI_popupHidden);
+    panel.preserveOnHide = !!aPreserveOnHide;
+
     /**
      * Check if the style inspector is open
      */
     panel.isOpen = function SI_isOpen()
     {
       return this.state && this.state == "open";
     };
 
@@ -134,16 +154,29 @@ var StyleInspector = {
         this.cssHtmlTree.highlight(aNode);
       } else {
         let win = Services.wm.getMostRecentWindow("navigator:browser");
         this.openPopup(win.gBrowser.selectedBrowser, "end_before", 0, 0, false, false);
       }
     };
 
     /**
+     * Destroy the style panel, remove listeners etc.
+     */
+    panel.destroy = function SI_destroy()
+    {
+      this.cssLogic = null;
+      this.cssHtmlTree = null;
+      this.removeEventListener("popupshown", SI_popupShown);
+      this.removeEventListener("popuphidden", SI_popupHidden);
+      this.parentNode.removeChild(this);
+      Services.obs.notifyObservers(null, "StyleInspector-closed", null);
+    };
+
+    /**
      * Is the Style Inspector initialized?
      * @returns {Boolean} true or false
      */
     function isInitialized()
     {
       return panel.cssLogic && panel.cssHtmlTree;
     }
 
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -1781,17 +1781,16 @@ HUD_SERVICE.prototype =
     let popupset = hud.chromeDocument.getElementById("mainPopupSet");
     let panels = popupset.querySelectorAll("panel[hudId=" + aHUDId + "]");
     for (let i = 0; i < panels.length; i++) {
       panels[i].hidePopup();
     }
     panels = popupset.querySelectorAll("panel[hudToolId=" + aHUDId + "]");
     for (let i = 0; i < panels.length; i++) {
       panels[i].hidePopup();
-      popupset.removeChild(panels[i]);
     }
 
     let id = ConsoleUtils.supString(aHUDId);
     Services.obs.notifyObservers(id, "web-console-destroyed", null);
 
     if (Object.keys(this.hudReferences).length == 0) {
       let autocompletePopup = hud.chromeDocument.
                               getElementById("webConsole_autocompletePopup");
--- a/content/svg/content/test/Makefile.in
+++ b/content/svg/content/test/Makefile.in
@@ -55,16 +55,17 @@ include $(topsrcdir)/config/rules.mk
 		a_href_helper_01.svg \
 		a_href_helper_02_03.svg \
 		a_href_helper_04.svg \
 		test_animLengthObjectIdentity.xhtml \
 		test_animLengthReadonly.xhtml \
 		test_animLengthUnits.xhtml \
 		test_bbox.xhtml \
 		test_bbox-with-invalid-viewBox.xhtml \
+		test_bounds.html \
 		bbox-helper.svg \
 		bounds-helper.svg \
 		test_dataTypes.html \
 		dataTypes-helper.svg \
 		getCTM-helper.svg \
 		test_getCTM.html \
 		test_getSubStringLength.xhtml \
 		getSubStringLength-helper.svg \
--- a/content/svg/content/test/bounds-helper.svg
+++ b/content/svg/content/test/bounds-helper.svg
@@ -2,29 +2,28 @@
 <svg xmlns="http://www.w3.org/2000/svg" width="750"
      xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
   <style type="text/css">
 text { font: 20px monospace; }
   </style>
 
 <g id="g">
   <text id="text1" x="25" y="25">abc</text>
+  <text id="text1a" x="85" y="25" stroke="black" stroke-width="4">abc</text>
   <rect id="rect1" x="50" y="50" width="50" height="50" fill="green"/>
-  <rect id="rect1a" x="50" y="50" width="50" height="50" fill="none" stroke-width="2" stroke="yellow"/>
+  <rect id="rect1a" x="50" y="50" width="50" height="50" fill="none" stroke-width="4" stroke="yellow"/>
   <text id="text2" x="125" y="25">abc</text>
+  <text id="text2a" x="185" y="25" stroke="black" stroke-width="10">abc</text>
   <g transform="rotate(45 175 75)">
     <rect id="rect2" x="150" y="50" width="50" height="50" fill="yellow"/>
-    <rect id="rect2a" x="150" y="50" width="50" height="50" fill="none" stroke-width="2" stroke="blue"/>
+    <rect id="rect2a" x="150" y="50" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
     <text id="text3" x="150" y="50" text-anchor="middle">abc</text>
   </g>
   <g transform="scale(2)">
     <rect id="rect3" x="25" y="80" width="50" height="50" fill="green"/>
-    <rect id="rect3a" x="25" y="80" width="50" height="50" fill="none" stroke-width="2" stroke="blue"/>
+    <rect id="rect3a" x="25" y="80" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
   </g>
   <g transform="scale(2) rotate(45 175 75)">
     <rect id="rect4" x="150" y="50" width="50" height="50" fill="yellow"/>
-    <rect id="rect4a" x="150" y="50" width="50" height="50" fill="none" stroke-width="2" stroke="blue"/>
-    <text id="text4" x="125" y="125">abc</text>
+    <rect id="rect4a" x="150" y="50" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
   </g>
-  <text id="text1a" x="85" y="25" stroke="black" stroke-width="1">M</text>
-  <text id="text2a" x="185" y="25" stroke="black" stroke-width="10">M</text>
 </g>
 </svg>
--- a/content/svg/content/test/test_bounds.html
+++ b/content/svg/content/test/test_bounds.html
@@ -14,111 +14,130 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none"></div>
 
 <iframe id="svg" src="bounds-helper.svg"></iframe>
 
 <pre id="test">
 <script class="testbody" type="application/javascript">
 SimpleTest.waitForExplicitFinish();
 
+function Rect(left, top, width, height)
+{
+  this.left = left;
+  this.top = top;
+  this.width = width;
+  this.height = height;
+}
+
+Rect.prototype.roundOut = function()
+{
+  this.width = Math.ceil(this.left + this.width) - Math.floor(this.left);
+  this.height = Math.ceil(this.top + this.height) - Math.floor(this.top);
+  this.left = Math.floor(this.left);
+  this.top = Math.floor(this.top);
+}
+
+var delta = 1;
+
+function isApproximately(a, b, message)
+{
+  ok(delta >= Math.abs(a - b), message + " - got " + a + ", expected " + b + " ± " + delta);
+}
+
 function runTest()
 {
-  function isRounded(a, b, message) {
-    is (Math.round(a), Math.round(b), message);
-  }
+  var doc = $("svg").contentWindow.document;
 
-  var doc = $("svg").contentWindow.document;
-  
   var text1 = doc.getElementById("text1");
-  
-  var len = text1.getComputedTextLength();
-  
+
   var text1Bounds = text1.getBoundingClientRect();
   var text2Bounds = doc.getElementById("text2").getBoundingClientRect();
   var text3Bounds = doc.getElementById("text3").getBoundingClientRect();
-  var text4Bounds = doc.getElementById("text4").getBoundingClientRect();
 
   var sin45 = Math.sin(Math.PI / 4);
 
-  isRounded(text1Bounds.left, 25, "text1.getBoundingClientRect().left");
-  isRounded(text1Bounds.width, len, "text1.getBoundingClientRect().width");
+  isApproximately(text1Bounds.left, 24, "text1.getBoundingClientRect().left");
 
-  isRounded(text2Bounds.left, text1Bounds.left + 100, "text2.getBoundingClientRect().left");
-  isRounded(text2Bounds.top, text1Bounds.top, "text2.getBoundingClientRect().top");
-  isRounded(text2Bounds.width, text1Bounds.width, "text2.getBoundingClientRect().width");
-  isRounded(text2Bounds.height, text1Bounds.height, "text2.getBoundingClientRect().height");
+  is(text2Bounds.left, text1Bounds.left + 100, "text2.getBoundingClientRect().left");
+  is(text2Bounds.top, text1Bounds.top, "text2.getBoundingClientRect().top");
+  is(text2Bounds.width, text1Bounds.width, "text2.getBoundingClientRect().width");
+  is(text2Bounds.height, text1Bounds.height, "text2.getBoundingClientRect().height");
 
-  isRounded(text3Bounds.width, (text1Bounds.width + text1Bounds.height) * sin45 + .5, "text3.getBoundingClientRect().width");
-  isRounded(text3Bounds.height, (text1Bounds.height  + text1Bounds.width) * sin45 + .5, "text3.getBoundingClientRect().height");
-
-  isRounded(text4Bounds.width, 2 * (text1Bounds.width + text1Bounds.height) * sin45, "text4.getBoundingClientRect().width");
-  isRounded(text4Bounds.height, 2 * ((text1Bounds.height  + text1Bounds.width) * sin45 - .5), "text4.getBoundingClientRect().height");
+  var r = (text1Bounds.width + text1Bounds.height) * sin45;
+  isApproximately(text3Bounds.width, Math.ceil(r), "text3.getBoundingClientRect().width");
+  isApproximately(text3Bounds.height, Math.ceil(r), "text3.getBoundingClientRect().height");
 
   var rect1Bounds = doc.getElementById("rect1").getBoundingClientRect();
   var rect2Bounds = doc.getElementById("rect2").getBoundingClientRect();
   var rect3Bounds = doc.getElementById("rect3").getBoundingClientRect();
   var rect4Bounds = doc.getElementById("rect4").getBoundingClientRect();
-  
-  isRounded(rect1Bounds.left, 50, "rect1.getBoundingClientRect().left");
-  isRounded(rect1Bounds.top, 50, "rect1.getBoundingClientRect().top");
-  isRounded(rect1Bounds.width, 50, "rect1.getBoundingClientRect().width");
-  isRounded(rect1Bounds.height, 50, "rect1.getBoundingClientRect().height");
+
+  is(rect1Bounds.left, 50, "rect1.getBoundingClientRect().left");
+  is(rect1Bounds.top, 50, "rect1.getBoundingClientRect().top");
+  is(rect1Bounds.width, 50, "rect1.getBoundingClientRect().width");
+  is(rect1Bounds.height, 50, "rect1.getBoundingClientRect().height");
 
-  isRounded(rect2Bounds.left, 175 - 50 * sin45 - .5, "rect2.getBoundingClientRect().left");
-  isRounded(rect2Bounds.top, 75 - 50 * sin45 - .5, "rect2.getBoundingClientRect().top");
-  isRounded(rect2Bounds.width, (50 * sin45 + .5) * 2, "rect2.getBoundingClientRect().width");
-  isRounded(rect2Bounds.height, (50 * sin45 + .5) * 2, "rect2.getBoundingClientRect().height");
+  rect = new Rect(175 - 50 * sin45, 75 - 50 * sin45, 50 * sin45 * 2, 50 * sin45 * 2);
+  rect.roundOut();
+  is(rect2Bounds.left, rect.left, "rect2.getBoundingClientRect().left");
+  is(rect2Bounds.top, rect.top, "rect2.getBoundingClientRect().top");
+  is(rect2Bounds.width, rect.width, "rect2.getBoundingClientRect().width");
+  is(rect2Bounds.height, rect.height, "rect2.getBoundingClientRect().height");
 
-  isRounded(rect3Bounds.left, 50, "rect3.getBoundingClientRect().left");
-  isRounded(rect3Bounds.top, 160, "rect3.getBoundingClientRect().top");
-  isRounded(rect3Bounds.width, 100, "rect3.getBoundingClientRect().width");
-  isRounded(rect3Bounds.height, 100, "rect3.getBoundingClientRect().height");
+  is(rect3Bounds.left, 50, "rect3.getBoundingClientRect().left");
+  is(rect3Bounds.top, 160, "rect3.getBoundingClientRect().top");
+  is(rect3Bounds.width, 100, "rect3.getBoundingClientRect().width");
+  is(rect3Bounds.height, 100, "rect3.getBoundingClientRect().height");
 
-  isRounded(rect4Bounds.left, 350 - 100 * sin45 - .5, "rect4.getBoundingClientRect().left");
-  isRounded(rect4Bounds.top, 150 - 100 * sin45 - .5, "rect4.getBoundingClientRect().top");
-  isRounded(rect4Bounds.width, (100 * sin45 + .5) * 2, "rect4.getBoundingClientRect().width");
-  isRounded(rect4Bounds.height, (100 * sin45 + .5) * 2, "rect4.getBoundingClientRect().height");
+  rect = new Rect(350 - 100 * sin45, 150 - 100 * sin45, 100 * sin45 * 2, 100 * sin45 * 2);
+  rect.roundOut();
+  is(rect4Bounds.left, rect.left, "rect4.getBoundingClientRect().left");
+  is(rect4Bounds.top, rect.top, "rect4.getBoundingClientRect().top");
+  is(rect4Bounds.width, rect.width, "rect4.getBoundingClientRect().width");
+  is(rect4Bounds.height, rect.height, "rect4.getBoundingClientRect().height");
 
   var rect1aBounds = doc.getElementById("rect1a").getBoundingClientRect();
   var rect2aBounds = doc.getElementById("rect2a").getBoundingClientRect();
   var rect3aBounds = doc.getElementById("rect3a").getBoundingClientRect();
   var rect4aBounds = doc.getElementById("rect4a").getBoundingClientRect();
-  
-  isRounded(rect1aBounds.left, 49, "rect1a.getBoundingClientRect().left");
-  isRounded(rect1aBounds.top, 49, "rect1a.getBoundingClientRect().top");
-  isRounded(rect1aBounds.width, 52, "rect1a.getBoundingClientRect().width");
-  isRounded(rect1aBounds.height, 52, "rect1a.getBoundingClientRect().height");
+
+  is(rect1aBounds.left, 48, "rect1a.getBoundingClientRect().left");
+  is(rect1aBounds.top, 48, "rect1a.getBoundingClientRect().top");
+  is(rect1aBounds.width, 54, "rect1a.getBoundingClientRect().width");
+  is(rect1aBounds.height, 54, "rect1a.getBoundingClientRect().height");
 
-  isRounded(rect2aBounds.left, 175 - 52 * sin45 - .5, "rect2a.getBoundingClientRect().left");
-  isRounded(rect2aBounds.top, 75 - 52 * sin45 - .5, "rect2a.getBoundingClientRect().top");
-  isRounded(rect2aBounds.width, 52 * sin45 * 2, "rect2a.getBoundingClientRect().width");
-  isRounded(rect2aBounds.height, 52 * sin45 * 2, "rect2a.getBoundingClientRect().height");
+  rect = new Rect(175 - 54 * sin45, 75 - 54 * sin45, 54 * sin45 * 2, 54 * sin45 * 2);
+  rect.roundOut();
+  is(rect2aBounds.left, rect.left, "rect2a.getBoundingClientRect().left");
+  is(rect2aBounds.top, rect.top, "rect2a.getBoundingClientRect().top");
+  is(rect2aBounds.width, rect.width, "rect2a.getBoundingClientRect().width");
+  is(rect2aBounds.height, rect.height, "rect2a.getBoundingClientRect().height");
 
-  isRounded(rect3aBounds.left, 48, "rect3a.getBoundingClientRect().left");
-  isRounded(rect3aBounds.top, 158, "rect3a.getBoundingClientRect().top");
-  isRounded(rect3aBounds.width, 104, "rect3a.getBoundingClientRect().width");
-  isRounded(rect3aBounds.height, 104, "rect3a.getBoundingClientRect().height");
+  is(rect3aBounds.left, 46, "rect3a.getBoundingClientRect().left");
+  is(rect3aBounds.top, 156, "rect3a.getBoundingClientRect().top");
+  is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
+  is(rect3aBounds.height, 108, "rect3a.getBoundingClientRect().height");
 
-  isRounded(rect4aBounds.left, 350 - 104 * sin45 - .5, "rect4a.getBoundingClientRect().left");
-  isRounded(rect4aBounds.top, 150 - 104 * sin45 - .5, "rect4a.getBoundingClientRect().top");
-  isRounded(rect4aBounds.width, (104 * sin45 + .5) * 2, "rect4a.getBoundingClientRect().width");
-  isRounded(rect4aBounds.height, (104 * sin45 + .5) * 2, "rect4a.getBoundingClientRect().height");
+  rect = new Rect(350 - 108 * sin45, 150 - 108 * sin45, 108 * sin45 * 2, 108 * sin45 * 2);
+  rect.roundOut();
+  is(rect4aBounds.left, rect.left, "rect4a.getBoundingClientRect().left");
+  is(rect4aBounds.top, rect.top, "rect4a.getBoundingClientRect().top");
+  is(rect4aBounds.width, rect.width, "rect4a.getBoundingClientRect().width");
+  is(rect4aBounds.height, rect.height, "rect4a.getBoundingClientRect().height");
 
   var text1a = doc.getElementById("text1a");
-  
+
   var text1aBounds = text1a.getBoundingClientRect();
   var text2aBounds = doc.getElementById("text2a").getBoundingClientRect();
 
-  var len = text1a.getComputedTextLength();
+  isApproximately(text1aBounds.left, 82, "text1a.getBoundingClientRect().left");
+  is(text1aBounds.width, text1Bounds.width + 4, "text1a.getBoundingClientRect().width");
 
-  isRounded(text1aBounds.left, 85 - 1, "text1a.getBoundingClientRect().left");
-  isRounded(text1aBounds.width, len + 1, "text1a.getBoundingClientRect().width");
-  
-  isRounded(text2aBounds.left, text1aBounds.left + 100 - 4, "text2a.getBoundingClientRect().left");
-  isRounded(text2aBounds.width, text1aBounds.width + 9, "text2a.getBoundingClientRect().width");
+  is(text2aBounds.left, text1aBounds.left + 100 - 3, "text2a.getBoundingClientRect().left");
+  is(text2aBounds.width, text1aBounds.width + 6, "text2a.getBoundingClientRect().width");
 
   SimpleTest.finish();
 }
 
 window.addEventListener("load", runTest, false);
 </script>
 </pre>
 </body>
--- a/editor/composer/test/test_bug434998.xul
+++ b/editor/composer/test/test_bug434998.xul
@@ -60,16 +60,17 @@ https://bugzilla.mozilla.org/show_bug.cg
           // Should not throw
           var threw = false;
           try {
             this.mEditor.contentDocument.execCommand("bold", false, null);
           } catch (e) {
             threw = true;
           }
           ok(!threw, "The execCommand API should work on <xul:editor>");
+          progress.removeProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
           SimpleTest.finish();
         }
       }
     },
 
 
     onProgressChange : function(aWebProgress, aRequest,
                                 aCurSelfProgress, aMaxSelfProgress,
--- a/embedding/android/AndroidManifest.xml.in
+++ b/embedding/android/AndroidManifest.xml.in
@@ -5,17 +5,17 @@
       android:installLocation="auto"
       android:versionCode="@ANDROID_VERSION_CODE@"
       android:versionName="@MOZ_APP_VERSION@"
 #ifdef MOZ_ANDROID_SHARED_ID
       android:sharedUserId="@MOZ_ANDROID_SHARED_ID@"
 #endif
       >
     <uses-sdk android:minSdkVersion="5"
-              android:targetSdkVersion="11"/>
+              android:targetSdkVersion="5"/>
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
 
--- a/js/src/jscrashreport.h
+++ b/js/src/jscrashreport.h
@@ -51,32 +51,32 @@ void
 SnapshotGCStack();
 
 void
 SnapshotErrorStack();
 
 void
 SaveCrashData(uint64 tag, void *ptr, size_t size);
 
-template<size_t size, char marker>
+template<size_t size, unsigned char marker>
 class StackBuffer {
   private:
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-    volatile char buffer[size + 4];
+    volatile unsigned char buffer[size + 4];
 
   public:
     StackBuffer(void *data JS_GUARD_OBJECT_NOTIFIER_PARAM) {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
 
         buffer[0] = marker;
         buffer[1] = '[';
 
         for (size_t i = 0; i < size; i++) {
             if (data)
-                buffer[i + 2] = ((char *)data)[i];
+                buffer[i + 2] = ((unsigned char *)data)[i];
             else
                 buffer[i + 2] = 0;
         }
 
         buffer[size - 2] = ']';
         buffer[size - 1] = marker;
     }
 };
--- a/js/src/methodjit/FastBuiltins.cpp
+++ b/js/src/methodjit/FastBuiltins.cpp
@@ -503,17 +503,17 @@ mjit::Compiler::compileArrayWithArgs(uin
 
     JS_ASSERT(templateObject->getDenseArrayCapacity() >= argc);
 
     RegisterID result = frame.allocReg();
     Jump emptyFreeList = masm.getNewObject(cx, result, templateObject);
     stubcc.linkExit(emptyFreeList, Uses(0));
 
     for (unsigned i = 0; i < argc; i++) {
-        FrameEntry *arg = frame.peek(-argc + i);
+        FrameEntry *arg = frame.peek(-(int)argc + i);
         frame.storeTo(arg, Address(result, JSObject::getFixedSlotOffset(i)), /* popped = */ true);
     }
 
     masm.storePtr(ImmPtr((void *) argc), Address(result, offsetof(JSObject, initializedLength)));
 
     stubcc.leave();
 
     stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -64,32 +64,32 @@
 #include "nsSVGClipPathFrame.h"
 #include "nsSVGMaskFrame.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGTextContainerFrame.h"
 #include "nsSVGLength2.h"
 #include "nsGenericElement.h"
 #include "nsSVGGraphicElement.h"
 #include "nsAttrValue.h"
-#include "nsSVGGeometryFrame.h"
 #include "nsIScriptError.h"
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "gfxRect.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "nsSVGForeignObjectFrame.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGEffects.h"
 #include "nsMathUtils.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGGeometryFrame.h"
 #include "nsComputedDOMStyle.h"
 #include "nsSVGPathGeometryFrame.h"
+#include "nsSVGPathGeometryElement.h"
 #include "prdtoa.h"
 #include "mozilla/dom/Element.h"
 #include "gfxUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -1426,47 +1426,67 @@ nsSVGUtils::WritePPM(const char *fname, 
       fwrite(data + y * stride + 4 * x + GFX_ARGB32_OFFSET_G, 1, 1, f);
       fwrite(data + y * stride + 4 * x + GFX_ARGB32_OFFSET_B, 1, 1, f);
     }
   }
   fclose(f);
 }
 #endif
 
-/*static*/ gfxRect
-nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
-                                          nsSVGGeometryFrame* aFrame)
+// The logic here comes from _cairo_stroke_style_max_distance_from_path
+static gfxRect
+PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
+                              nsSVGGeometryFrame* aFrame,
+                              double styleExpansionFactor)
 {
-  // The logic here comes from _cairo_stroke_style_max_distance_from_path
-
-  double style_expansion = 0.5;
-
-  const nsStyleSVG* style = aFrame->GetStyleSVG();
-
-  if (style->mStrokeLinecap == NS_STYLE_STROKE_LINECAP_SQUARE) {
-    style_expansion = M_SQRT1_2;
-  }
-
-  if (style->mStrokeLinejoin == NS_STYLE_STROKE_LINEJOIN_MITER &&
-      style_expansion < style->mStrokeMiterlimit) {
-    style_expansion = style->mStrokeMiterlimit;
-  }
-
-  style_expansion *= aFrame->GetStrokeWidth();
+  double style_expansion =
+    styleExpansionFactor * aFrame->GetStrokeWidth();
 
   gfxMatrix ctm = aFrame->GetCanvasTM();
 
   double dx = style_expansion * (fabs(ctm.xx) + fabs(ctm.xy));
   double dy = style_expansion * (fabs(ctm.yy) + fabs(ctm.yx));
 
   gfxRect strokeExtents = aPathExtents;
   strokeExtents.Inflate(dx, dy);
   return strokeExtents;
 }
 
+/*static*/ gfxRect
+nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
+                                          nsSVGGeometryFrame* aFrame)
+{
+  return ::PathExtentsToMaxStrokeExtents(aPathExtents, aFrame, 0.5);
+}
+
+/*static*/ gfxRect
+nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
+                                          nsSVGPathGeometryFrame* aFrame)
+{
+  double styleExpansionFactor = 0.5;
+
+  if (static_cast<nsSVGPathGeometryElement*>(aFrame->GetContent())->IsMarkable()) {
+    const nsStyleSVG* style = aFrame->GetStyleSVG();
+
+    if (style->mStrokeLinecap == NS_STYLE_STROKE_LINECAP_SQUARE) {
+      styleExpansionFactor = M_SQRT1_2;
+    }
+
+    if (style->mStrokeLinejoin == NS_STYLE_STROKE_LINEJOIN_MITER &&
+        styleExpansionFactor < style->mStrokeMiterlimit &&
+        aFrame->GetContent()->Tag() != nsGkAtoms::line) {
+      styleExpansionFactor = style->mStrokeMiterlimit;
+    }
+  }
+
+  return ::PathExtentsToMaxStrokeExtents(aPathExtents,
+                                         aFrame,
+                                         styleExpansionFactor);
+}
+
 // ----------------------------------------------------------------------
 
 nsSVGRenderState::nsSVGRenderState(nsRenderingContext *aContext) :
   mRenderMode(NORMAL), mRenderingContext(aContext), mPaintingToWindow(PR_FALSE)
 {
   mGfxContext = aContext->ThebesContext();
 }
 
--- a/layout/svg/base/src/nsSVGUtils.h
+++ b/layout/svg/base/src/nsSVGUtils.h
@@ -71,16 +71,17 @@ class gfxContext;
 class gfxASurface;
 class gfxPattern;
 class gfxImageSurface;
 struct gfxSize;
 struct nsStyleFont;
 class nsSVGEnum;
 class nsISVGChildFrame;
 class nsSVGGeometryFrame;
+class nsSVGPathGeometryFrame;
 class nsSVGDisplayContainerFrame;
 
 namespace mozilla {
 class SVGAnimatedPreserveAspectRatio;
 class SVGPreserveAspectRatio;
 namespace dom {
 class Element;
 } // namespace dom
@@ -559,16 +560,18 @@ public:
    * without doing the calculations for the actual tight extents. We exploit
    * the fact that cairo does have an API for getting the tight device space
    * fill/path extents.
    *
    * This should die once bug 478152 is fixed.
    */
   static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
                                                nsSVGGeometryFrame* aFrame);
+  static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
+                                               nsSVGPathGeometryFrame* aFrame);
 
   /**
    * Convert a floating-point value to a 32-bit integer value, clamping to
    * the range of valid integers.
    */
   static PRInt32 ClampToInt(double aVal)
   {
     return NS_lround(NS_MAX(double(PR_INT32_MIN),
--- a/mobile/chrome/content/bindings.xml
+++ b/mobile/chrome/content/bindings.xml
@@ -1847,9 +1847,45 @@
             }
           }
 
           ContextHelper.showPopup({ target: aTextbox, json: json });
         ]]></body>
       </method>
     </implementation>
   </binding>
+  
+  <binding id="setting-fulltoggle-bool" extends="chrome://mozapps/content/extensions/setting.xml#setting-bool">
+    <handlers>
+      <handler event="click" button="0" phase="capturing">
+        <![CDATA[
+        this.input.setChecked(!this.value);
+        this.inputChanged();
+        event.stopPropagation();
+        ]]>
+      </handler>
+    </handlers>
+  </binding>
+
+  <binding id="setting-fulltoggle-boolint" extends="chrome://mozapps/content/extensions/setting.xml#setting-boolint">
+    <handlers>
+      <handler event="click" button="0" phase="capturing">
+        <![CDATA[
+        this.input.setChecked(!this.value);
+        this.inputChanged();
+        event.stopPropagation();
+        ]]>
+      </handler>
+    </handlers>
+  </binding>
+
+  <binding id="setting-fulltoggle-localized-bool" extends="chrome://mozapps/content/extensions/setting.xml#setting-localized-bool">
+    <handlers>
+      <handler event="click" button="0" phase="capturing">
+        <![CDATA[
+        this.input.setChecked(!this.value);
+        this.inputChanged();
+        event.stopPropagation();
+        ]]>
+      </handler>
+    </handlers>
+  </binding>
 </bindings>
--- a/mobile/chrome/content/browser.css
+++ b/mobile/chrome/content/browser.css
@@ -22,25 +22,25 @@ documenttab {
   -moz-binding: url("chrome://browser/content/tabs.xml#documenttab");
 }
 
 settings {
   -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#settings");
 }
 
 setting[type="bool"] {
-  -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-bool");
+  -moz-binding: url("chrome://browser/content/bindings.xml#setting-fulltoggle-bool");
 }
 
 setting[type="bool"][localized="true"] {
-  -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-localized-bool");
+  -moz-binding: url("chrome://browser/content/bindings.xml#setting-fulltoggle-localized-bool");
 }
 
 setting[type="boolint"] {
-  -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-boolint");
+  -moz-binding: url("chrome://browser/content/bindings.xml#setting-fulltoggle-boolint");
 }
 
 setting[type="integer"] {
   -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-integer");
 }
 
 setting[type="control"] {
   -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-control");
--- a/mobile/chrome/tests/Makefile.in
+++ b/mobile/chrome/tests/Makefile.in
@@ -69,16 +69,17 @@ include $(topsrcdir)/config/rules.mk
   browser_focus.js \
   browser_forms.html \
   $(warning browser_forms.js disabled due to failures) \
   browser_formsZoom.html \
   $(warning browser_formsZoom.js disabled due to failures) \
   browser_history.js \
   browser_mainui.js \
   browser_preferences_text.js \
+  browser_preferences_fulltoggle.js \
   browser_rect.js \
   browser_rememberPassword.js \
   browser_scroll.js \
   browser_scroll.html \
   browser_scrollbar.js \
   browser_select.html \
   browser_select.js \
   browser_sessionstore.js \
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/browser_preferences_fulltoggle.js
@@ -0,0 +1,58 @@
+// browser-chrome test for fennec preferences to toggle values while clicking on the preference name
+
+var gTests = [];
+var gCurrentTest = null;
+
+function test() {
+  // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()"
+  // We call "finish()" when the tests are finished
+  waitForExplicitFinish();
+
+  // Start the tests
+  runNextTest();
+}
+//------------------------------------------------------------------------------
+// Iterating tests by shifting test out one by one as runNextTest is called.
+function runNextTest() {
+  // Run the next test until all tests completed
+  if (gTests.length > 0) {
+    gCurrentTest = gTests.shift();
+    info(gCurrentTest.desc);
+    gCurrentTest.run();
+  }
+  else {
+    // Cleanup. All tests are completed at this point
+    finish();
+  }
+}
+
+// -----------------------------------------------------------------------------------------
+// Verify preferences and text
+gTests.push({
+  desc: "Verify full toggle on Preferences",
+
+  run: function(){
+    // 1.Click preferences to view prefs
+    document.getElementById("tool-panel-open").click();
+    is(document.getElementById("panel-container").hidden, false, "Preferences should be visible");
+
+    var contentRegion = document.getElementById("prefs-content");
+
+    // Check for *Show images*
+    var imageRegion = document.getAnonymousElementByAttribute(contentRegion, "pref", "permissions.default.image");
+    var imageValue  = imageRegion.value;
+    var imageTitle  = document.getAnonymousElementByAttribute(imageRegion, "class", "preferences-title");
+    var imageButton = document.getAnonymousElementByAttribute(imageRegion, "anonid", "input");
+    imageButton.click();
+    is(imageRegion.value, !imageValue, "Tapping on input control should change the value");
+    imageTitle.click();
+    is(imageRegion.value, imageValue, "Tapping on the title should change the value"); 
+    imageRegion.click();
+    is(imageRegion.value, !imageValue, "Tapping on the setting should change the value"); 
+
+    BrowserUI.hidePanel();
+    is(document.getElementById("panel-container").hidden, true, "Preferences panel should be closed");
+    runNextTest();
+  }
+});
+
--- a/toolkit/mozapps/downloads/DownloadLastDir.jsm
+++ b/toolkit/mozapps/downloads/DownloadLastDir.jsm
@@ -78,24 +78,22 @@ let observer = {
   },
   observe: function (aSubject, aTopic, aData) {
     switch (aTopic) {
       case "private-browsing":
         if (aData == "enter")
           gDownloadLastDirFile = readLastDirPref();
         else if (aData == "exit") {
           gDownloadLastDirFile = null;
-          gDownloadLastDirStore = new Dict();
         }
         break;
       case "browser:purge-session-history":
         gDownloadLastDirFile = null;
         if (Services.prefs.prefHasUserValue(LAST_DIR_PREF))
           Services.prefs.clearUserPref(LAST_DIR_PREF);
-        gDownloadLastDirStore = new Dict();
         Services.contentPrefs.removePrefsByName(LAST_DIR_PREF);
         break;
     }
   }
 };
 
 let os = Components.classes["@mozilla.org/observer-service;1"]
                    .getService(Components.interfaces.nsIObserverService);
@@ -107,31 +105,23 @@ function readLastDirPref() {
     return Services.prefs.getComplexValue(LAST_DIR_PREF, nsILocalFile);
   }
   catch (e) {
     return null;
   }
 }
 
 let gDownloadLastDirFile = readLastDirPref();
-let gDownloadLastDirStore = new Dict();
 let gDownloadLastDir = {
   // compat shims
   get file() { return this.getFile(); },
   set file(val) { this.setFile(null, val); },
   getFile: function (aURI) {
     if (aURI) {
-      let lastDir;
-      if (pbSvc && pbSvc.privateBrowsingEnabled) {
-        let group = Services.contentPrefs.grouper.group(aURI);
-        lastDir = gDownloadLastDirStore.get(group, null);
-      }
-      if (!lastDir) {
-        lastDir = Services.contentPrefs.getPref(aURI, LAST_DIR_PREF);
-      }
+      let lastDir = Services.contentPrefs.getPref(aURI, LAST_DIR_PREF);
       if (lastDir) {
         var lastDirFile = Components.classes["@mozilla.org/file/local;1"]
                                     .createInstance(Components.interfaces.nsILocalFile);
         lastDirFile.initWithPath(lastDir);
         return lastDirFile;
       }
     }
     if (gDownloadLastDirFile && !gDownloadLastDirFile.exists())
@@ -139,22 +129,17 @@ let gDownloadLastDir = {
 
     if (pbSvc && pbSvc.privateBrowsingEnabled)
       return gDownloadLastDirFile;
     else
       return readLastDirPref();
   },
   setFile: function (aURI, aFile) {
     if (aURI) {
-      if (pbSvc && pbSvc.privateBrowsingEnabled) {
-        let group = Services.contentPrefs.grouper.group(aURI);
-        gDownloadLastDirStore.set(group, aFile.path);
-      } else {
-        Services.contentPrefs.setPref(aURI, LAST_DIR_PREF, aFile.path);
-      }
+      Services.contentPrefs.setPref(aURI, LAST_DIR_PREF, aFile.path);
     }
     if (pbSvc && pbSvc.privateBrowsingEnabled) {
       if (aFile instanceof Components.interfaces.nsIFile)
         gDownloadLastDirFile = aFile.clone();
       else
         gDownloadLastDirFile = null;
     } else {
       if (aFile instanceof Components.interfaces.nsIFile)