Merging mozilla-inbound into mozilla-central.
authorMounir Lamouri <mounir.lamouri@gmail.com>
Tue, 23 Aug 2011 10:19:26 +0200
changeset 75702 a41b781330a6bf4669c6ec32f4082374924c2137
parent 75660 7eb1a56eaaf1bdd55c3897a3d1d9c1445f5474b5 (current diff)
parent 75701 ecb597abc0bfb40a3c42235c6cfcfc86af78616d (diff)
child 75703 071d9c997f3d44c52e4dcf798ec466245b3b88c1
child 75704 4b8e0357f28c532ad49e4940fe5cacb849677633
child 75880 18288bc1b3a16a6a8e3c14a3033caf1c5a403d15
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone9.0a1
Merging mozilla-inbound into mozilla-central.
content/svg/content/test/test_animLengthRelativeUnits.xhtml
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -971,19 +971,21 @@ refRelationSetCB(AtkObject *aAtkObj)
       atk_relation_set_remove(relation_set, atkRelation);
 
     Relation rel(accWrap->RelationByType(relationTypes[i]));
     nsTArray<AtkObject*> targets;
     nsAccessible* tempAcc = nsnull;
     while ((tempAcc = rel.Next()))
       targets.AppendElement(nsAccessibleWrap::GetAtkObject(tempAcc));
 
-    atkRelation = atk_relation_new(targets.Elements(), targets.Length(), atkType);
-    atk_relation_set_add(relation_set, atkRelation);
-    g_object_unref(atkRelation);
+    if (targets.Length()) {
+      atkRelation = atk_relation_new(targets.Elements(), targets.Length(), atkType);
+      atk_relation_set_add(relation_set, atkRelation);
+      g_object_unref(atkRelation);
+    }
   }
 
   return relation_set;
 }
 
 // Check if aAtkObj is a valid MaiAtkObject, and return the nsAccessibleWrap
 // for it.
 nsAccessibleWrap *GetAccessibleWrap(AtkObject *aAtkObj)
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -151,20 +151,19 @@ Sanitizer.prototype = {
           }
         }
         else {
           // Remove everything
           cookieMgr.removeAll();
         }
 
         // Clear plugin data.
-        let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
         const phInterface = Ci.nsIPluginHost;
         const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
-        ph.QueryInterface(phInterface);
+        let ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface);
 
         // Determine age range in seconds. (-1 means clear all.) We don't know
         // that this.range[1] is actually now, so we compute age range based
         // on the lower bound. If this.range results in a negative age, do
         // nothing.
         let age = this.range ? (Date.now() / 1000 - this.range[0] / 1000000)
                              : -1;
         if (!this.range || age >= 0) {
@@ -190,23 +189,23 @@ Sanitizer.prototype = {
         var psvc = Components.classes["@mozilla.org/preferences-service;1"]
                              .getService(Components.interfaces.nsIPrefService);
         try {
             var branch = psvc.getBranch("geo.wifi.access_token.");
             branch.deleteBranch("");
         } catch (e) {}
 
       },
-      
+
       get canClear()
       {
         return true;
       }
     },
-    
+
     offlineApps: {
       clear: function ()
       {
         const Cc = Components.classes;
         const Ci = Components.interfaces;
         var cacheService = Cc["@mozilla.org/network/cache-service;1"].
                            getService(Ci.nsICacheService);
         try {
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -614,21 +614,19 @@ PrivateBrowsingService.prototype = {
       let enumerator = cm.getCookiesFromHost(aDomain);
       while (enumerator.hasMoreElements()) {
         let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
         cm.remove(cookie.host, cookie.name, cookie.path, false);
       }
     }
 
     // Plugin data
-    let (ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost)) {
-      const phInterface = Ci.nsIPluginHost;
-      const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
-      ph.QueryInterface(phInterface);
-
+    const phInterface = Ci.nsIPluginHost;
+    const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
+    let (ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface)) {
       let tags = ph.getPluginTags();
       for (let i = 0; i < tags.length; i++) {
         try {
           ph.clearSiteData(tags[i], aDomain, FLAG_CLEAR_ALL, -1);
         } catch (e) {
           // Ignore errors from the plugin
         }
       }
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -598,28 +598,47 @@ toolbar[mode="full"] .toolbarbutton-1 > 
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar");
 }
 #back-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar&state=disabled");
 }
 
 #forward-button {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar");
+  -moz-transition: 250ms ease-out;
 }
-#forward-button[disabled="true"] {
-  list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
-}
-
 #forward-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar");
 }
-#forward-button[disabled="true"]:-moz-locale-dir(rtl) {
+
+toolbar:not([mode=icons]) #forward-button[disabled="true"] {
+  list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
+}
+toolbar:not([mode=icons]) #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar&state=disabled");
 }
 
+toolbar[mode=icons] #forward-button[disabled="true"] {
+  -moz-transform: scale(0);
+  opacity: 0;
+  pointer-events: none;
+}
+toolbar[mode=icons] #forward-button[disabled="true"]:-moz-locale-dir(ltr) {
+  margin-left: -36px;
+}
+toolbar[mode=icons] #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
+  margin-right: -36px;
+}
+toolbar[mode=icons][iconsize=small] #forward-button[disabled="true"]:-moz-locale-dir(ltr) {
+  margin-left: -28px;
+}
+toolbar[mode=icons][iconsize=small] #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
+  margin-right: -28px;
+}
+
 #reload-button {
   list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar");
 }
 #reload-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar&state=disabled");
 }
 
 #stop-button {
@@ -781,27 +800,27 @@ toolbar[iconsize="small"] #back-button[d
 }
 
 toolbar[iconsize="small"] #forward-button {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu");
 }
 .unified-nav-forward[_moz-menuactive] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu") !important;
 }
-toolbar[iconsize="small"] #forward-button[disabled="true"] {
+toolbar[iconsize="small"]:not([mode=icons]) #forward-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu&state=disabled");
 }
 
 toolbar[iconsize="small"] #forward-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu");
 }
 .unified-nav-forward[_moz-menuactive]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu") !important;
 }
-toolbar[iconsize="small"] #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
+toolbar[iconsize="small"]:not([mode=icons]) #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
 }
 
 toolbar[iconsize="small"] #stop-button {
   list-style-image: url("moz-icon://stock/gtk-stop?size=menu");
 }
 toolbar[iconsize="small"] #stop-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-stop?size=menu&state=disabled");
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -38,17 +38,16 @@
 
 # A netscape style .mk file for autoconf builds
 
 INCLUDED_AUTOCONF_MK = 1
 USE_AUTOCONF 	= 1
 MOZILLA_CLIENT	= 1
 target          = @target@
 ac_configure_args = @ac_configure_args@
-BUILD_MODULES	= @BUILD_MODULES@
 MOZILLA_VERSION = @MOZILLA_VERSION@
 FIREFOX_VERSION	= @FIREFOX_VERSION@
 
 MOZ_BUILD_APP = @MOZ_BUILD_APP@
 MOZ_APP_NAME	= @MOZ_APP_NAME@
 MOZ_APP_DISPLAYNAME = @MOZ_APP_DISPLAYNAME@
 MOZ_APP_BASENAME = @MOZ_APP_BASENAME@
 MOZ_APP_VENDOR = @MOZ_APP_VENDOR@
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1148,18 +1148,19 @@ endif # OS/2
 	$(RM) $@
 	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
 	$(HOST_RANLIB) $@
 
 ifdef HAVE_DTRACE
 ifndef XP_MACOSX
 ifdef DTRACE_PROBE_OBJ
 ifndef DTRACE_LIB_DEPENDENT
-$(DTRACE_PROBE_OBJ):
-	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ)
+NON_DTRACE_OBJS := $(filter-out $(DTRACE_PROBE_OBJ),$(OBJS))
+$(DTRACE_PROBE_OBJ): $(NON_DTRACE_OBJS)
+	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(NON_DTRACE_OBJS)
 endif
 endif
 endif
 endif
 
 # On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
 # so instead of deleting .o files after repacking them into a dylib, we make
 # symlinks back to the originals. The symlinks are a no-op for stabs debugging,
@@ -1545,19 +1546,16 @@ ifeq ($(XPIDL_MODULE),) # we need $(XPID
 export:: FORCE
 	@echo
 	@echo "*** Error processing XPIDLSRCS:"
 	@echo "Please define MODULE or XPIDL_MODULE when defining XPIDLSRCS,"
 	@echo "so we have a module name to use when creating MODULE.xpt."
 	@echo; sleep 2; false
 endif
 
-$(IDL_DIR)::
-	$(NSINSTALL) -D $@
-
 # generate .h files from into $(XPIDL_GEN_DIR), then export to $(DIST)/include;
 # warn against overriding existing .h file. 
 $(XPIDL_GEN_DIR)/.done:
 	$(MKDIR) -p $(XPIDL_GEN_DIR)
 	@$(TOUCH) $@
 
 # don't depend on $(XPIDL_GEN_DIR), because the modification date changes
 # with any addition to the directory, regenerating all .h files -> everything.
@@ -1618,24 +1616,18 @@ export:: $(XPIDLSRCS) $(IDL_DIR)
 export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS)) $(DIST)/include
 	$(INSTALL) $(IFLAGS1) $^ 
 endif # NO_DIST_INSTALL
 
 endif # XPIDLSRCS
 
 
 
-#
 # General rules for exporting idl files.
-#
-# WORK-AROUND ONLY, for mozilla/tools/module-deps/bootstrap.pl build.
-# Bug to fix idl dependency problems w/o this extra build pass is
-#   http://bugzilla.mozilla.org/show_bug.cgi?id=145777
-#
-$(IDL_DIR)::
+$(IDL_DIR):
 	$(NSINSTALL) -D $@
 
 export-idl:: $(SUBMAKEFILES) $(MAKE_DIRS)
 
 ifneq ($(XPIDLSRCS),)
 ifndef NO_DIST_INSTALL
 export-idl:: $(XPIDLSRCS) $(IDL_DIR)
 	$(INSTALL) $(IFLAGS1) $^
@@ -2092,17 +2084,16 @@ showhost:
 	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
 	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
 	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
 	@echo "HOST_OBJS          = $(HOST_OBJS)"
 	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
 	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
 
 showbuildmods::
-	@echo "Build Modules	= $(BUILD_MODULES)"
 	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
 
 documentation:
 	@cd $(DEPTH)
 	$(DOXYGEN) $(DEPTH)/config/doxygen.cfg
 
 ifdef ENABLE_TESTS
 check:: $(SUBMAKEFILES) $(MAKE_DIRS)
--- a/content/media/test/test_replay_metadata.html
+++ b/content/media/test/test_replay_metadata.html
@@ -27,17 +27,16 @@ var manager = new MediaTestManager;
 function seekStarted(evt) {
   var v = evt.target;
   v._gotSeekStarted = true;
 }
 
 function seekEnded(evt) {
   var v = evt.target;
   v._gotSeekEnded = true;
-  v.play();
 }
 
 function loadedData(evt) {
   var v = evt.target;
   v._loadedDataCount++;
   ok(v._loadedDataCount <= 1, "No more than 1 onloadeddata event for " + v._name);
 }
 
--- a/content/smil/nsSMILCSSProperty.cpp
+++ b/content/smil/nsSMILCSSProperty.cpp
@@ -141,46 +141,47 @@ nsSMILCSSProperty::GetBaseValue() const
 
   // (3) Put cached override style back (if it's non-empty)
   if (overrideDecl && !cachedOverrideStyleVal.IsEmpty()) {
     overrideDecl->SetPropertyValue(mPropID, cachedOverrideStyleVal);
   }
 
   // (4) Populate our nsSMILValue from the computed style
   if (didGetComputedVal) {
+    // When we parse animation values we check if they are context-sensitive or
+    // not so that we don't cache animation values whose meaning may change.
+    // For base values however this is unnecessary since on each sample the
+    // compositor will fetch the (computed) base value and compare it against
+    // the cached (computed) value and detect changes for us.
     nsSMILCSSValueType::ValueFromString(mPropID, mElement,
-                                        computedStyleVal, baseValue);
+                                        computedStyleVal, baseValue,
+                                        nsnull);
   }
   return baseValue;
 }
 
 nsresult
 nsSMILCSSProperty::ValueFromString(const nsAString& aStr,
                                    const nsISMILAnimationElement* aSrcElement,
                                    nsSMILValue& aValue,
                                    PRBool& aPreventCachingOfSandwich) const
 {
   NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
 
-  nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue);
-  if (aValue.IsNull()) {
-    return NS_ERROR_FAILURE;
+  nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
+      &aPreventCachingOfSandwich);
+
+  // XXX Due to bug 536660 (or at least that seems to be the most likely
+  // culprit), when we have animation setting display:none on a <use> element,
+  // if we DON'T set the property every sample, chaos ensues.
+  if (!aPreventCachingOfSandwich && mPropID == eCSSProperty_display) {
+    aPreventCachingOfSandwich = PR_TRUE;
   }
 
-  // XXXdholbert: For simplicity, just assume that all CSS values have to
-  // reparsed every sample. This prevents us from doing the "nothing's changed
-  // so don't recompose" optimization (bug 533291) for CSS properties & mapped
-  // attributes.  If it ends up being expensive to always recompose those, we
-  // can be a little smarter here.  We really only need to set
-  // aPreventCachingOfSandwich to true for "inherit" & "currentColor" (whose
-  // values could change at any time), for length-valued types (particularly
-  // those with em/ex/percent units, since their conversion ratios can change
-  // at any time), and for any value for 'font-family'.
-  aPreventCachingOfSandwich = PR_TRUE;
-  return NS_OK;
+  return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
 }
 
 nsresult
 nsSMILCSSProperty::SetAnimValue(const nsSMILValue& aValue)
 {
   NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
 
   // Convert nsSMILValue to string
--- a/content/smil/nsSMILCSSValueType.cpp
+++ b/content/smil/nsSMILCSSValueType.cpp
@@ -366,32 +366,34 @@ GetPresContextForElement(Element* aElem)
 }
 
 // Helper function to parse a string into a nsStyleAnimation::Value
 static PRBool
 ValueFromStringHelper(nsCSSProperty aPropID,
                       Element* aTargetElement,
                       nsPresContext* aPresContext,
                       const nsAString& aString,
-                      nsStyleAnimation::Value& aStyleAnimValue)
+                      nsStyleAnimation::Value& aStyleAnimValue,
+                      PRBool* aIsContextSensitive)
 {
   // If value is negative, we'll strip off the "-" so the CSS parser won't
   // barf, and then manually make the parsed value negative.
   // (This is a partial solution to let us accept some otherwise out-of-bounds
   // CSS values. Bug 501188 will provide a more complete fix.)
   PRBool isNegative = PR_FALSE;
   PRUint32 subStringBegin = 0;
   PRInt32 absValuePos = nsSMILParserUtils::CheckForNegativeNumber(aString);
   if (absValuePos > 0) {
     isNegative = PR_TRUE;
     subStringBegin = (PRUint32)absValuePos; // Start parsing after '-' sign
   }
   nsDependentSubstring subString(aString, subStringBegin);
   if (!nsStyleAnimation::ComputeValue(aPropID, aTargetElement, subString,
-                                      PR_TRUE, aStyleAnimValue)) {
+                                      PR_TRUE, aStyleAnimValue,
+                                      aIsContextSensitive)) {
     return PR_FALSE;
   }
   if (isNegative) {
     InvertSign(aStyleAnimValue);
   }
   
   if (aPropID == eCSSProperty_font_size) {
     // Divide out text-zoom, since SVG is supposed to ignore it
@@ -404,28 +406,29 @@ ValueFromStringHelper(nsCSSProperty aPro
   return PR_TRUE;
 }
 
 // static
 void
 nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID,
                                     Element* aTargetElement,
                                     const nsAString& aString,
-                                    nsSMILValue& aValue)
+                                    nsSMILValue& aValue,
+                                    PRBool* aIsContextSensitive)
 {
   NS_ABORT_IF_FALSE(aValue.IsNull(), "Outparam should be null-typed");
   nsPresContext* presContext = GetPresContextForElement(aTargetElement);
   if (!presContext) {
     NS_WARNING("Not parsing animation value; unable to get PresContext");
     return;
   }
 
   nsStyleAnimation::Value parsedValue;
   if (ValueFromStringHelper(aPropID, aTargetElement, presContext,
-                            aString, parsedValue)) {
+                            aString, parsedValue, aIsContextSensitive)) {
     sSingleton.Init(aValue);
     aValue.mU.mPtr = new ValueWrapper(aPropID, parsedValue, presContext);
   }
 }
 
 // static
 PRBool
 nsSMILCSSValueType::ValueToString(const nsSMILValue& aValue,
--- a/content/smil/nsSMILCSSValueType.h
+++ b/content/smil/nsSMILCSSValueType.h
@@ -95,23 +95,30 @@ public:
    * Otherwise, this method leaves aValue.mType == this class's singleton.
    *
    * @param       aPropID         The property for which we're parsing a value.
    * @param       aTargetElement  The target element to whom the property/value
    *                              setting applies.
    * @param       aString         The string to be parsed as a CSS value.
    * @param [out] aValue          The nsSMILValue to be populated. Should
    *                              initially be null-typed.
+   * @param [out] aIsContextSensitive Set to PR_TRUE if |aString| may produce
+   *                                  a different |aValue| depending on other
+   *                                  CSS properties on |aTargetElement|
+   *                                  or its ancestors (e.g. 'inherit).
+   *                                  PR_FALSE otherwise. May be nsnull.
+   *                                  Not set if the method fails.
    * @pre  aValue.IsNull()
    * @post aValue.IsNull() || aValue.mType == nsSMILCSSValueType::sSingleton
    */
   static void ValueFromString(nsCSSProperty aPropID,
                               Element* aTargetElement,
                               const nsAString& aString,
-                              nsSMILValue& aValue);
+                              nsSMILValue& aValue,
+                              PRBool* aIsContextSensitive);
 
   /**
    * Creates a string representation of the given nsSMILValue.
    *
    * Note: aValue is expected to be of this type (that is, it's expected to
    * have been initialized by nsSMILCSSValueType::sSingleton).  If aValue is a
    * freshly-initialized value, this method will succeed, though the resulting
    * string will be empty.
--- a/content/smil/nsSMILMappedAttribute.cpp
+++ b/content/smil/nsSMILMappedAttribute.cpp
@@ -62,38 +62,36 @@ ReleaseStringBufferPropertyValue(void*  
 nsresult
 nsSMILMappedAttribute::ValueFromString(const nsAString& aStr,
                                        const nsISMILAnimationElement* aSrcElement,
                                        nsSMILValue& aValue,
                                        PRBool& aPreventCachingOfSandwich) const
 {
   NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
 
-  nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue);
-  if (aValue.IsNull()) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // XXXdholbert: For simplicity, just assume that all CSS values have to
-  // reparsed every sample. See note in nsSMILCSSProperty::ValueFromString.
-  aPreventCachingOfSandwich = PR_TRUE;
-  return NS_OK;
+  nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
+                                      &aPreventCachingOfSandwich);
+  return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
 }
 
 nsSMILValue
 nsSMILMappedAttribute::GetBaseValue() const
 {
   nsAutoString baseStringValue;
   nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
   PRBool success = mElement->GetAttr(kNameSpaceID_None, attrName,
                                      baseStringValue);
   nsSMILValue baseValue;
   if (success) {
+    // For base values, we don't need to worry whether the value returned is
+    // context-sensitive or not since the compositor will take care of comparing
+    // the returned (computed) base value and its cached value and determining
+    // if an update is required or not.
     nsSMILCSSValueType::ValueFromString(mPropID, mElement,
-                                        baseStringValue, baseValue);
+                                        baseStringValue, baseValue, nsnull);
   } else {
     // Attribute is unset -- use computed value.
     // FIRST: Temporarily clear animated value, to make sure it doesn't pollute
     // the computed value. (We want base value, _without_ animations applied.)
     void* buf = mElement->UnsetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
                                         attrName, nsnull);
     FlushChangesToTargetAttr();
 
--- a/content/smil/test/test_smilChangeAfterFrozen.xhtml
+++ b/content/smil/test/test_smilChangeAfterFrozen.xhtml
@@ -3,118 +3,153 @@
   <title>Test for SMIL when things change after an animation is frozen</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="smilTestUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=533291">Mozilla Bug 533291</a>
 <p id="display"></p>
-<div id="content" style="display: none">
+<!-- Bug 628848: The following should be display: none but we currently don't
+     handle percentage lengths properly when the whole fragment is display: none
+     -->
+<div id="content" style="visibility: hidden">
 <svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
      onload="this.pauseAnimations()">
   <g id="circleParent">
     <circle cx="0" cy="20" r="15" fill="blue" id="circle"/>
   </g>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
-/** Test for SMIL fill modes **/
+/** Test for SMIL values that are context-sensitive **/
+
+/* See bugs 533291 and 562815.
+   
+   The format of each test is basically:
+   1) create some animated and frozen state
+   2) test the animated values
+   3) change the context
+   4) test that context-sensitive animation values have changed
+
+   Ideally, after changing the context (3), the animated state would instantly
+   update. However, this is not currently the case for many situations.
+
+     For CSS properties we have bug 545282 - In animations involving 'inherit'
+     / 'currentColor', changes to inherited value / 'color' don't show up in
+     animated value immediately
+
+     For SVG lengths we have bug 508206 - Relative units used in
+     animation don't update immediately
+
+     (There are a few of todo_is's in the following tests so that if those bugs
+     are ever resolved we'll know to update this test case accordingly.)
+
+   So in between (3) and (4) we force a sample. This is currently done by
+   calling SVGSVGElement.setCurrentTime with the same current time which has the
+   side effect of forcing a sample.
+
+   What we *are* testing is that we're not too zealous with caching animation
+   values whilst in the frozen state. Normally we'd say, "Hey, we're frozen,
+   let's just use the same animation result as last time" but for some
+   context-sensitive animation values that doesn't work.
+*/
 
 /* Global Variables */
 const SVGNS = "http://www.w3.org/2000/svg";
+
+// Animation parameters -- not used for <set> animation
 const ANIM_DUR = "4s";
 const TIME_ANIM_END = "4";
 const TIME_AFTER_ANIM_END = "5";
 
-// SETTIMEOUT_INTERVAL: This value just needs to be at least as large as
-// nsSMILAnimationController::kTimerInterval, so we can queue up a callback
-// for this far in the future and be assured that an animation sample will
-// have happened before the callback fires (because we presumably already
-// have an animation sample in the setTimeout queue, with a lower timeout
-// value than this).
-// NOTE: We only need to use timeouts here because of Bug 545282.
-const SETTIMEOUT_INTERVAL = 60;
-
-const gTestArray =
-  [ testBaseValueChange,
-    testCurrentColorChange,
-    testCurrentColorChangeUsingStyle,
-    testInheritChange,
-    testInheritChangeUsingStyle
-   ];
-
-// Index of current test in gTestArray
-var gNextTestIndex = 0;
-
 const gSvg = document.getElementById("svg");
 const gCircle = document.getElementById("circle");
 const gCircleParent = document.getElementById("circleParent");
 
-
 SimpleTest.waitForExplicitFinish();
 
 // MAIN FUNCTION
 // -------------
 
-function main() {
+function main()
+{
   ok(gSvg.animationsPaused(), "should be paused by <svg> load handler");
   is(gSvg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
-  if (gNextTestIndex != 0) {
-    ok(false, "expecting to start at first test in array.");
+  const tests =
+    [ testBaseValueChange,
+      testCurrentColorChange,
+      testCurrentColorChangeUsingStyle,
+      testCurrentColorChangeOnFallback,
+      testInheritChange,
+      testInheritChangeUsingStyle,
+      testEmUnitChangeOnProp,
+      testEmUnitChangeOnPropBase,
+      testEmUnitChangeOnLength,
+      testPercentUnitChangeOnProp,
+      testPercentUnitChangeOnLength,
+      testRelativeFontSize,
+      testRelativeFontWeight,
+      testRelativeFont,
+      testCalcFontSize,
+      testDashArray,
+      testClip
+     ];
+
+  while (tests.length) {
+    tests.shift()();
   }
-  // Kick off first test.  (It will kick off the one after it, and so on.)
-  runNextTest();
+  SimpleTest.finish();
 }
 
 // HELPER FUNCTIONS
 // ----------------
-function createAnimFromTo(attrName, fromVal, toVal) {
-  var anim = document.createElementNS(SVGNS,"animate");
+function createAnimSetTo(attrName, toVal)
+{
+  var anim = document.createElementNS(SVGNS,"set");
   anim.setAttribute("attributeName", attrName);
-  anim.setAttribute("dur", ANIM_DUR);
-  anim.setAttribute("begin", "0s");
-  anim.setAttribute("from", fromVal);
   anim.setAttribute("to", toVal);
-  anim.setAttribute("fill", "freeze");
   return gCircle.appendChild(anim);
 }
-function createAnimBy(attrName, byVal) {
+
+function createAnimBy(attrName, byVal)
+{
   var anim = document.createElementNS(SVGNS,"animate");
   anim.setAttribute("attributeName", attrName);
   anim.setAttribute("dur", ANIM_DUR);
   anim.setAttribute("begin","0s");
   anim.setAttribute("by", byVal);
   anim.setAttribute("fill", "freeze");
   return gCircle.appendChild(anim);
 }
 
+function createAnimFromTo(attrName, fromVal, toVal)
+{
+  var anim = document.createElementNS(SVGNS,"animate");
+  anim.setAttribute("attributeName", attrName);
+  anim.setAttribute("dur", ANIM_DUR);
+  anim.setAttribute("begin","0s");
+  anim.setAttribute("from", fromVal);
+  anim.setAttribute("to", toVal);
+  anim.setAttribute("fill", "freeze");
+  return gCircle.appendChild(anim);
+}
+
 // Common setup code for each test function: seek to 0, and make sure
 // the previous test cleaned up its animations.
 function setupTest() {
   gSvg.setCurrentTime(0);
   if (gCircle.firstChild) {
     ok(false, "Previous test didn't clean up after itself.");
   }
 }
 
-function runNextTest() {
-  if (gNextTestIndex == gTestArray.length) {
-    // No tests left! we're done.
-    SimpleTest.finish();
-    return;
-  }
-
-  // Call next test (and increment next-test index)
-  gTestArray[gNextTestIndex++]();
-}
-
 // THE TESTS
 // ---------
 
 function testBaseValueChange()
 {
   setupTest();
   var anim = createAnimBy("cx", "50");
   gSvg.setCurrentTime(TIME_ANIM_END);
@@ -125,116 +160,410 @@ function testBaseValueChange()
   is(gCircle.cx.animVal.value, 50,
      "Checking animated cx after anim ends");
 
   gCircle.setAttribute("cx", 20);
   is(gCircle.cx.animVal.value, 70,
      "Checking animated cx after anim ends & after changing base val");
 
   anim.parentNode.removeChild(anim); // clean up
-  runNextTest();
 }
 
 function testCurrentColorChange()
 {
   gCircle.setAttribute("color", "red"); // At first: currentColor=red
-  var anim = createAnimFromTo("fill", "yellow", "currentColor");
+  var anim = createAnimSetTo("fill", "currentColor");
 
-  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  gSvg.setCurrentTime(0); // trigger synchronous sample
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(255, 0, 0)",
-     "Checking animated fill=currentColor after anim ends");
+     "Checking animated fill=currentColor after animating");
 
   gCircle.setAttribute("color", "lime"); // Change: currentColor=lime
-  setTimeout(testCurrentColorChange_final, SETTIMEOUT_INTERVAL);
-}
-
-function testCurrentColorChange_final()
-{
+  // Bug 545282: We should really detect this change and update immediately but
+  // currently we don't until we get sampled again
+  todo_is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(0, 255, 0)",
+     "Checking animated fill=currentColor after updating context but before " +
+     "sampling");
+  gSvg.setCurrentTime(0);
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(0, 255, 0)",
-     "Checking animated fill=currentColor after anim ends and 'color' changes");
+     "Checking animated fill=currentColor after updating context");
 
   // Clean up
   gCircle.removeAttribute("color");
-  gCircle.firstChild.parentNode.removeChild(gCircle.firstChild);
-
-  // Kick off next test
-  runNextTest();
+  gCircle.removeChild(gCircle.firstChild);
 }
 
 function testCurrentColorChangeUsingStyle()
 {
   setupTest();
   gCircle.setAttribute("style", "color: red"); // At first: currentColor=red
-  var anim = createAnimFromTo("fill", "yellow", "currentColor");
+  var anim = createAnimSetTo("fill", "currentColor");
 
-  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  gSvg.setCurrentTime(0);
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(255, 0, 0)",
-     "Checking animated fill=currentColor after anim ends (using style attr)");
+     "Checking animated fill=currentColor after animating (using style attr)");
 
   gCircle.setAttribute("style", "color: lime"); // Change: currentColor=lime
-  setTimeout(testCurrentColorChangeUsingStyle_final, SETTIMEOUT_INTERVAL);
-}
-
-function testCurrentColorChangeUsingStyle_final()
-{
+  gSvg.setCurrentTime(0);
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(0, 255, 0)",
-     "Checking animated fill=currentColor after anim ends and 'color' changes "
+     "Checking animated fill=currentColor after updating context "
      + "(using style attr)");
 
   // Clean up
   gCircle.removeAttribute("style");
-  gCircle.firstChild.parentNode.removeChild(gCircle.firstChild);
-  runNextTest();
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function getFallbackColor(pServerStr)
+{
+  return pServerStr.substr(pServerStr.indexOf(" ")+1);
+}
+
+function testCurrentColorChangeOnFallback()
+{
+  setupTest();
+  gCircle.setAttribute("color", "red"); // At first: currentColor=red
+  var anim = createAnimSetTo("fill", "url(#missingGrad) currentColor");
+
+  gSvg.setCurrentTime(0);
+  var fallback =
+    getFallbackColor(SMILUtil.getComputedStyleSimple(gCircle, "fill"));
+  is(fallback, "rgb(255, 0, 0)",
+     "Checking animated fallback fill=currentColor after animating");
+
+  gCircle.setAttribute("color", "lime"); // Change: currentColor=lime
+  gSvg.setCurrentTime(0);
+  fallback = getFallbackColor(SMILUtil.getComputedStyleSimple(gCircle, "fill"));
+  is(fallback, "rgb(0, 255, 0)",
+     "Checking animated fallback fill=currentColor after updating context");
+
+  gCircle.removeAttribute("style");
+  gCircle.removeChild(gCircle.firstChild);
 }
 
 function testInheritChange()
 {
   setupTest();
   gCircleParent.setAttribute("fill", "red"); // At first: inherit=red
-  var anim = createAnimFromTo("fill", "yellow", "inherit");
+  var anim = createAnimSetTo("fill", "inherit");
 
-  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  gSvg.setCurrentTime(0);
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(255, 0, 0)",
-     "Checking animated fill=inherit after anim ends");
+     "Checking animated fill=inherit after animating");
 
   gCircleParent.setAttribute("fill", "lime"); // Change: inherit=lime
-  setTimeout(testInheritChange_final, SETTIMEOUT_INTERVAL);
-}
-
-function testInheritChange_final() {
+  gSvg.setCurrentTime(0);
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(0, 255, 0)",
-     "Checking animated fill=inherit after anim ends and parent val changes");
+     "Checking animated fill=inherit after updating context");
 
   gCircleParent.removeAttribute("fill");
-  gCircle.firstChild.parentNode.removeChild(gCircle.firstChild);
-  runNextTest();
+  gCircle.removeChild(gCircle.firstChild);
 }
 
 function testInheritChangeUsingStyle()
 {
   setupTest();
   gCircleParent.setAttribute("style", "fill: red"); // At first: inherit=red
-  var anim = createAnimFromTo("fill", "yellow", "inherit");
+  var anim = createAnimSetTo("fill", "inherit");
 
-  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  gSvg.setCurrentTime(0);
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(255, 0, 0)",
-     "Checking animated fill=inherit after anim ends (using style attr)");
+     "Checking animated fill=inherit after animating (using style attr)");
 
   gCircleParent.setAttribute("style", "fill: lime"); // Change: inherit=lime
-  setTimeout(testInheritChangeUsingStyle_final, SETTIMEOUT_INTERVAL);
-}
-
-function testInheritChangeUsingStyle_final() {
+  gSvg.setCurrentTime(0);
   is(SMILUtil.getComputedStyleSimple(gCircle, "fill"), "rgb(0, 255, 0)",
-     "Checking animated fill=inherit after anim ends and parent val changes "
+     "Checking animated fill=inherit after updating context "
      + "(using style attr)");
 
   gCircleParent.removeAttribute("style");
-  gCircle.firstChild.parentNode.removeChild(gCircle.firstChild);
-  runNextTest();
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testEmUnitChangeOnProp()
+{
+  setupTest();
+  gCircleParent.setAttribute("font-size", "10px"); // At first: font-size: 10px
+  var anim = createAnimSetTo("font-size", "2em");
+
+  gSvg.setCurrentTime(0);
+  is(SMILUtil.getComputedStyleSimple(gCircle, "font-size"), "20px",
+     "Checking animated font-size=2em after animating ends");
+
+  gCircleParent.setAttribute("font-size", "20px"); // Change: font-size: 20px
+  gSvg.setCurrentTime(0);
+  is(SMILUtil.getComputedStyleSimple(gCircle, "font-size"), "40px",
+     "Checking animated font-size=2em after updating context");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testEmUnitChangeOnPropBase()
+{
+  // Test the case where the base value for our animation sandwich is
+  // context-sensitive.
+  // Currently, this is taken care of by the compositor which keeps a cached
+  // base value and compares it with the current base value. This test then just
+  // serves as a regression test in case the compositor's behaviour changes.
+  setupTest();
+  gSvg.setAttribute("font-size", "10px"); // At first: font-size: 10px
+  gCircleParent.setAttribute("font-size", "1em"); // Base: 10px
+  var anim = createAnimBy("font-size", "10px");
+
+  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  is(SMILUtil.getComputedStyleSimple(gCircle, "font-size"), "20px",
+     "Checking animated font-size=20px after anim ends");
+
+  gSvg.setAttribute("font-size", "20px"); // Change: font-size: 20px
+  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  is(SMILUtil.getComputedStyleSimple(gCircle, "font-size"), "30px",
+     "Checking animated font-size=30px after updating context");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testEmUnitChangeOnLength()
+{
+  setupTest();
+  gCircleParent.setAttribute("font-size", "10px"); // At first: font-size: 10px
+  var anim = createAnimSetTo("cx", "2em");
+
+  gSvg.setCurrentTime(0);
+  is(gCircle.cx.animVal.value, 20,
+     "Checking animated length=2em after animating");
+
+  gCircleParent.setAttribute("font-size", "20px"); // Change: font-size: 20px
+  // Bug 508206: We should really detect this change and update immediately but
+  // currently we don't until we get sampled again
+  todo_is(gCircle.cx.animVal.value, 40,
+     "Checking animated length=2em after updating context but before sampling");
+
+  gSvg.setCurrentTime(0);
+  is(gCircle.cx.animVal.value, 40,
+     "Checking animated length=2em after updating context and after " +
+     "resampling");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testPercentUnitChangeOnProp()
+{
+  setupTest();
+  gCircleParent.setAttribute("font-size", "10px"); // At first: font-size: 10px
+  var anim = createAnimSetTo("font-size", "150%");
+
+  gSvg.setCurrentTime(0);
+  is(SMILUtil.getComputedStyleSimple(gCircle, "font-size"), "15px",
+     "Checking animated font-size=150% after animating");
+
+  gCircleParent.setAttribute("font-size", "20px"); // Change: font-size: 20px
+  gSvg.setCurrentTime(0);
+  is(SMILUtil.getComputedStyleSimple(gCircle, "font-size"), "30px",
+     "Checking animated font-size=150% after updating context");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testPercentUnitChangeOnLength()
+{
+  setupTest();
+  var oldHeight = gSvg.getAttribute("height");
+  gSvg.setAttribute("height", "100px"); // At first: viewport height: 100px
+  var anim = createAnimSetTo("cy", "100%");
+
+  gSvg.setCurrentTime(0); // Force synchronous sample so animation takes effect
+  // Due to bug 627594 (SVGLength.value for percent value lengths doesn't
+  // reflect updated viewport until reflow) the following will fail.
+  // Check that it does indeed fail so that when that bug is fixed this test
+  // can be updated.
+  todo_is(gCircle.cy.animVal.value, 100,
+     "Checking animated length=100% after animating but before reflow");
+  gSvg.forceRedraw();
+  // Even after doing a reflow though we'll still fail due to bug 508206
+  // (Relative units used in animation don't update immediately)
+  todo_is(gCircle.cy.animVal.value, 100,
+     "Checking animated length=100% after animating but before resampling");
+  gSvg.setCurrentTime(0);
+  // Now we should be up to date
+  is(gCircle.cy.animVal.value, 100,
+     "Checking animated length=100% after animating");
+
+  gSvg.setAttribute("height", "50px"); // Change: height: 50px
+  gSvg.forceRedraw(); // Bug 627594
+  gSvg.setCurrentTime(0); // Bug 508206
+  is(gCircle.cy.animVal.value, 50,
+     "Checking animated length=100% after updating context");
+
+  gSvg.setAttribute("height", oldHeight);
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testRelativeFontSize()
+{
+  setupTest();
+  gCircleParent.setAttribute("font-size", "10px"); // At first: font-size: 10px
+  var anim = createAnimSetTo("font-size", "larger");
+
+  gSvg.setCurrentTime(0);
+  var fsize = parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-size"));
+  // CSS 2 suggests a scaling factor of 1.2 so we should be looking at something
+  // around about 12 or so
+  ok(fsize > 10 && fsize < 20,
+    "Checking animated font-size > 10px after animating");
+
+  gCircleParent.setAttribute("font-size", "20px"); // Change: font-size: 20px
+  gSvg.setCurrentTime(0);
+  fsize = parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-size"));
+  ok(fsize > 20, "Checking animated font-size > 20px after updating context");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testRelativeFontWeight()
+{
+  setupTest();
+  gCircleParent.setAttribute("font-weight", "100"); // At first: font-weight 100
+  var anim = createAnimSetTo("font-weight", "bolder");
+  // CSS 2: 'bolder': Specifies the next weight that is assigned to a font
+  // that is darker than the inherited one. If there is no such weight, it
+  // simply results in the next darker numerical value (and the font remains
+  // unchanged), unless the inherited value was '900', in which case the
+  // resulting weight is also '900'.
+
+  gSvg.setCurrentTime(0);
+  var weight =
+    parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-weight"));
+  ok(weight > 100, "Checking animated font-weight > 100 after animating");
+
+  gCircleParent.setAttribute("font-weight", "800"); // Change: font-weight 800
+  gSvg.setCurrentTime(0);
+  weight = parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-weight"));
+  is(weight, 900,
+     "Checking animated font-weight = 900 after updating context");
+
+  gCircleParent.removeAttribute("font-weight");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testRelativeFont()
+{
+  // Test a relative font-size as part of a 'font' spec since the code path
+  // is different in this case
+  // It turns out that, due to the way we store shorthand font properties, we
+  // don't need to worry about marking such values as context-sensitive since we
+  // seem to store them in their relative form. If, however, we change the way
+  // we store shorthand font properties in the future, this will serve as
+  // a useful regression test.
+  setupTest();
+  gCircleParent.setAttribute("font-size", "10px"); // At first: font-size: 10px
+  // We must be sure to set every part of the shorthand property to some
+  // non-context sensitive value because we want to test that even if only the
+  // font-size is relative we will update it appropriately.
+  var anim =
+    createAnimSetTo("font", "normal normal bold larger/normal sans-serif");
+
+  gSvg.setCurrentTime(0);
+  var fsize = parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-size"));
+  ok(fsize > 10 && fsize < 20,
+    "Checking size of shorthand 'font' > 10px after animating");
+
+  gCircleParent.setAttribute("font-size", "20px"); // Change: font-size: 20px
+  gSvg.setCurrentTime(0);
+  fsize  = parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-size"));
+  ok(fsize > 20,
+     "Checking size of shorthand 'font' > 20px after updating context");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testCalcFontSize()
+{
+  setupTest();
+  gCircleParent.setAttribute("font-size", "10px"); // At first: font-size: 10px
+  var anim = createAnimSetTo("font-size", "-moz-calc(110% + 0.1em)");
+
+  gSvg.setCurrentTime(0);
+  var fsize = parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-size"));
+  // Font size should be 1.1 * 10px + 0.1 * 10px = 12
+  is(fsize, 12, "Checking animated calc font-size == 12px after animating");
+
+  gCircleParent.setAttribute("font-size", "20px"); // Change: font-size: 20px
+  gSvg.setCurrentTime(0);
+  fsize = parseInt(SMILUtil.getComputedStyleSimple(gCircle, "font-size"));
+  is(fsize, 24, "Checking animated calc font-size == 24px after updating " +
+                "context");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testDashArray()
+{
+  // stroke dasharrays don't currently convert units--but if someone ever fixes
+  // that, hopefully this test will fail and remind us not to cache percentage
+  // values in that case
+  setupTest();
+  var oldHeight = gSvg.getAttribute("height");
+  var oldWidth  = gSvg.getAttribute("width");
+  gSvg.setAttribute("height", "100px"); // At first: viewport: 100x100px
+  gSvg.setAttribute("width",  "100px");
+  var anim = createAnimFromTo("stroke-dasharray", "0 5", "0 50%");
+
+  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+
+  // Now we should be up to date
+  is(SMILUtil.getComputedStyleSimple(gCircle, "stroke-dasharray"), "0, 50%",
+     "Checking animated stroke-dasharray after animating");
+
+  gSvg.setAttribute("height", "50px"); // Change viewport: 50x50px
+  gSvg.setAttribute("width",  "50px");
+  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  is(SMILUtil.getComputedStyleSimple(gCircle, "stroke-dasharray"), "0, 50%",
+     "Checking animated stroke-dasharray after updating context");
+
+  gSvg.setAttribute("height", oldHeight);
+  gSvg.setAttribute("width",  oldWidth);
+  gCircle.removeChild(gCircle.firstChild);
+}
+
+function testClip()
+{
+  setupTest();
+  gCircleParent.setAttribute("font-size", "20px"); // At first: font-size: 20px
+
+  // The clip property only applies to elements that establish a new
+  // viewport so we need to create a nested svg and add animation to that
+  var nestedSVG = document.createElementNS(SVGNS, "svg");
+  nestedSVG.setAttribute("clip", "rect(0px 0px 0px 0px)");
+  gCircleParent.appendChild(nestedSVG);
+
+  var anim = createAnimSetTo("clip", "rect(1em 1em 1em 1em)");
+  // createAnimSetTo will make the animation a child of gCircle so we need to
+  // move it so it targets nestedSVG instead
+  nestedSVG.appendChild(anim);
+
+  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  is(SMILUtil.getComputedStyleSimple(nestedSVG, "clip"),
+     "rect(20px, 20px, 20px, 20px)",
+     "Checking animated clip rect after animating");
+
+  gCircleParent.setAttribute("font-size", "10px"); // Change: font-size: 10px
+  gSvg.setCurrentTime(TIME_AFTER_ANIM_END);
+  is(SMILUtil.getComputedStyleSimple(nestedSVG, "clip"),
+     "rect(10px, 10px, 10px, 10px)",
+     "Checking animated clip rect after updating context");
+
+  gCircleParent.removeAttribute("font-size");
+  gCircleParent.removeChild(nestedSVG);
 }
 
 window.addEventListener("load", main, false);
 ]]>
 </script>
 </pre>
 </body>
 </html>
--- a/content/svg/content/test/Makefile.in
+++ b/content/svg/content/test/Makefile.in
@@ -52,17 +52,16 @@ include $(topsrcdir)/config/rules.mk
 		test_a_href_01.xhtml \
 		test_a_href_02.xhtml \
 		a_href_destination.svg \
 		a_href_helper_01.svg \
 		a_href_helper_02_03.svg \
 		a_href_helper_04.svg \
 		test_animLengthObjectIdentity.xhtml \
 		test_animLengthReadonly.xhtml \
-		test_animLengthRelativeUnits.xhtml \
 		test_animLengthUnits.xhtml \
 		test_bbox.xhtml \
 		test_bbox-with-invalid-viewBox.xhtml \
 		bbox-helper.svg \
 		bounds-helper.svg \
 		test_dataTypes.html \
 		dataTypes-helper.svg \
 		getCTM-helper.svg \
deleted file mode 100644
--- a/content/svg/content/test/test_animLengthRelativeUnits.xhtml
+++ /dev/null
@@ -1,80 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=508206
--->
-<head>
-  <title>Test for liveness of relative units in animation</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=508206">Mozilla Bug 508206</a>
-<p id="display"></p>
-<!-- XXX The following should be display: none but that's broken by bug 413975
-     where we don't handle percentage lengths when the whole fragment is
-     display: none properly. -->
-<div id="content" style="visibility: hidden">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"
-     onload="this.pauseAnimations()">
-  <g font-size="10px">
-    <circle cx="0" cy="0" r="15" fill="blue" id="circle">
-      <animate attributeName="cx" from="0" to="10em" dur="10s" begin="0s"
-        fill="freeze" id="animate"/>
-      <animate attributeName="cy" from="0" to="100%" dur="10s" begin="0s"
-        fill="freeze"/>
-    </circle>
-  </g>
-</svg>
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-<![CDATA[
-/** Test liveness of relative units of animated lengths **/
-
-/* Global Variables */
-const svgns="http://www.w3.org/2000/svg";
-var svg = document.getElementById("svg");
-var circle = document.getElementById('circle');
-
-SimpleTest.waitForExplicitFinish();
-
-function main() {
-  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
-  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
-
-  // Sample mid-way through the animation
-  svg.setCurrentTime(5);
-
-  // (1) Check values mid-way
-  is(circle.cx.animVal.value, 50,
-    "(1) Unexpected animVal for cx before changing base length");
-  is(circle.cy.animVal.value, 50,
-    "(1) Unexpected animVal for cy before changing base length");
-
-  // (2) Change the frame of reference and check values are updated immediately
-
-  // Change font-size
-  circle.parentNode.setAttribute('font-size', '5px');
-  todo_is(circle.cx.animVal.value, 25,
-    "(2) Unexpected animVal for cx after changing parent font-size");
-
-  // Change the viewport size
-  svg.setAttribute('height', '50px');
-  todo_is(circle.cy.animVal.value, 25,
-    "(2) Unexpected animVal for cy after changing containing viewport size");
-
-  SimpleTest.finish();
-}
-
-var animate = document.getElementById('animate');
-if (animate && animate.targetElement) {
-  window.addEventListener("load", main, false);
-} else {
-  ok(true); // Skip tests but don't report 'todo' either
-  SimpleTest.finish();
-}
-]]>
-</script>
-</pre>
-</body>
-</html>
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -424,41 +424,41 @@ static PRBool IsChromeURI(nsIURI* aURI)
   PRBool isChrome = PR_FALSE;
   if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)))
       return isChrome;
   return PR_FALSE;
 }
 
 /* Implementation file */
 
-static PRIntn
+static PRBool
 TraverseProtos(nsHashKey *aKey, void *aData, void* aClosure)
 {
   nsCycleCollectionTraversalCallback *cb = 
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
   nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
   proto->Traverse(*cb);
   return kHashEnumerateNext;
 }
 
-static PRIntn
+static PRBool
 UnlinkProtoJSObjects(nsHashKey *aKey, void *aData, void* aClosure)
 {
   nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
   proto->UnlinkJSObjects();
   return kHashEnumerateNext;
 }
 
 struct ProtoTracer
 {
   TraceCallback mCallback;
   void *mClosure;
 };
 
-static PRIntn
+static PRBool
 TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
 {
   ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure);
   nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
   proto->Trace(closure->mCallback, closure->mClosure);
   return kHashEnumerateNext;
 }
 
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -323,17 +323,17 @@ PRBool nsXBLPrototypeBinding::CompareBin
   PRBool equal = PR_FALSE;
   mBindingURI->Equals(aURI, &equal);
   if (!equal && mAlternateBindingURI) {
     mAlternateBindingURI->Equals(aURI, &equal);
   }
   return equal;
 }
 
-static PRIntn
+static PRBool
 TraverseInsertionPoint(nsHashKey* aKey, void* aData, void* aClosure)
 {
   nsCycleCollectionTraversalCallback &cb = 
     *static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
   nsXBLInsertionPointEntry* entry =
     static_cast<nsXBLInsertionPointEntry*>(aData);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(entry,
                                                nsXBLInsertionPointEntry,
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -8447,23 +8447,23 @@ nsDocShell::InternalLoad(nsIURI * aURI,
             // Save the current URI; we need it if we fire a hashchange later.
             nsCOMPtr<nsIURI> oldURI = mCurrentURI;
 
             // Save the position of the scrollers.
             nscoord cx = 0, cy = 0;
             GetCurScrollPos(ScrollOrientation_X, &cx);
             GetCurScrollPos(ScrollOrientation_Y, &cy);
 
-            // We scroll whenever we're not doing a history load.  Note that
-            // sometimes we might scroll even if we don't fire a hashchange
-            // event!  See bug 653741.
-            if (!aSHEntry) {
-                rv = ScrollToAnchor(curHash, newHash, aLoadType);
-                NS_ENSURE_SUCCESS(rv, rv);
-            }
+            // ScrollToAnchor doesn't necessarily cause us to scroll the window;
+            // the function decides whether a scroll is appropriate based on the
+            // arguments it receives.  But even if we don't end up scrolling,
+            // ScrollToAnchor performs other important tasks, such as informing
+            // the presShell that we have a new hash.  See bug 680257.
+            rv = ScrollToAnchor(curHash, newHash, aLoadType);
+            NS_ENSURE_SUCCESS(rv, rv);
 
             mLoadType = aLoadType;
             mURIResultedInDocument = PR_TRUE;
 
             /* we need to assign mLSHE to aSHEntry right here, so that on History loads,
              * SetCurrentURI() called from OnNewURI() will send proper
              * onLocationChange() notifications to the browser to update
              * back/forward buttons.
--- a/docshell/test/Makefile.in
+++ b/docshell/test/Makefile.in
@@ -115,16 +115,18 @@ include $(topsrcdir)/config/rules.mk
 		bug570341_recordevents.html \
 		test_bug668513.html \
 		bug668513_redirect.html \
 		bug668513_redirect.html^headers^ \
 		test_bug669671.html \
 		file_bug669671.sjs \
 		test_bug675587.html \
 		test_bfcache_plus_hash.html \
+		test_bug680257.html \
+		file_bug680257.html \
 		$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 _TEST_FILES += \
 		test_bug511449.html \
 		file_bug511449.html \
 		$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/docshell/test/file_bug680257.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <style type='text/css'>
+    a        { color: black; }
+    a:target { color: red; }
+  </style>
+</head>
+
+<body onload='(opener || parent).popupLoaded()'>
+
+<a id='a' href='#a'>link</a>
+<a id='b' href='#b'>link2</a>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/test_bug680257.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=680257
+-->
+<head>
+  <title>Test for Bug 680257</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=680257">Mozilla Bug 680257</a>
+
+<script type="application/javascript;version=1.7">
+
+SimpleTest.waitForExplicitFinish();
+
+var popup = window.open('file_bug680257.html');
+
+// The popup will call into popupLoaded() once it loads.
+function popupLoaded() {
+  // runTests() needs to be called from outside popupLoaded's onload handler.
+  // Otherwise, the navigations we do in runTests won't create new SHEntries.
+  SimpleTest.executeSoon(runTests);
+}
+
+function runTests() {
+  checkPopupLinkStyle(false, 'Initial');
+
+  popup.location.hash = 'a';
+  checkPopupLinkStyle(true, 'After setting hash');
+
+  popup.history.back();
+  checkPopupLinkStyle(false, 'After going back');
+
+  popup.history.forward();
+  checkPopupLinkStyle(true, 'After going forward');
+
+  popup.close();
+  SimpleTest.finish();
+}
+
+function checkPopupLinkStyle(isTarget, desc) {
+  var link = popup.document.getElementById('a');
+  var style = popup.getComputedStyle(link);
+  var color = style.getPropertyValue('color');
+
+  // Color is red if isTarget, black otherwise.
+  if (isTarget) {
+    is(color, 'rgb(255, 0, 0)', desc);
+  }
+  else {
+    is(color, 'rgb(0, 0, 0)', desc);
+  }
+}
+
+</script>
+</body>
+</html>
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8215,29 +8215,31 @@ nsGlobalWindow::GetLocalStorage(nsIDOMSt
 //*****************************************************************************
 // nsGlobalWindow::nsIDOMStorageIndexedDB
 //*****************************************************************************
 
 NS_IMETHODIMP
 nsGlobalWindow::GetMozIndexedDB(nsIIDBFactory** _retval)
 {
   if (!mIndexedDB) {
-    nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
-      do_GetService(THIRDPARTYUTIL_CONTRACTID);
-    NS_ENSURE_TRUE(thirdPartyUtil, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-    PRBool isThirdParty;
-    nsresult rv = thirdPartyUtil->IsThirdPartyWindow(this, nsnull,
-                                                     &isThirdParty);
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-    if (isThirdParty) {
-      NS_WARNING("IndexedDB is not permitted in a third-party window.");
-      *_retval = nsnull;
-      return NS_OK;
+    if (!IsChromeWindow()) {
+      nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
+        do_GetService(THIRDPARTYUTIL_CONTRACTID);
+      NS_ENSURE_TRUE(thirdPartyUtil, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+
+      PRBool isThirdParty;
+      nsresult rv = thirdPartyUtil->IsThirdPartyWindow(this, nsnull,
+                                                       &isThirdParty);
+      NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+
+      if (isThirdParty) {
+        NS_WARNING("IndexedDB is not permitted in a third-party window.");
+        *_retval = nsnull;
+        return NS_OK;
+      }
     }
 
     mIndexedDB = indexedDB::IDBFactory::Create(this);
     NS_ENSURE_TRUE(mIndexedDB, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
   }
 
   nsCOMPtr<nsIIDBFactory> request(mIndexedDB);
   request.forget(_retval);
--- a/dom/interfaces/css/nsIDOMCSS2Properties.idl
+++ b/dom/interfaces/css/nsIDOMCSS2Properties.idl
@@ -46,17 +46,17 @@
  * The nsIDOMCSS2Properties interface is a datatype for additional
  * reflection of data already provided in nsIDOMCSSStyleDeclaration in
  * the Document Object Model.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-Style
  */
 
-[builtinclass, scriptable, uuid(10f43750-b379-11e0-aff2-0800200c9a66)]
+[builtinclass, scriptable, uuid(286466f1-4246-4574-afdb-2f8a03ad7cc8)]
 interface nsIDOMCSS2Properties : nsISupports
 {
            attribute DOMString        background;
                                         // raises(DOMException) on setting
 
            attribute DOMString        backgroundAttachment;
                                         // raises(DOMException) on setting
 
@@ -652,16 +652,19 @@ interface nsIDOMCSS2Properties : nsISupp
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozStackSizing;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozBorderImage;
                                         // raises(DOMException) on setting
 
+           attribute DOMString        MozColumns;
+                                        // raises(DOMException) on setting
+
            attribute DOMString        MozColumnRule;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozColumnRuleWidth;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozColumnRuleStyle;
                                         // raises(DOMException) on setting
--- a/dom/interfaces/events/nsIDOMMessageEvent.idl
+++ b/dom/interfaces/events/nsIDOMMessageEvent.idl
@@ -40,17 +40,17 @@
 
 /**
  * The nsIDOMMessageEvent interface is used for server-sent events and for
  * cross-domain messaging.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#messageevent
  */
-[scriptable, uuid(dc8ec5c6-ebf2-4f95-be99-cd13e3c0d0c6)]
+[scriptable, uuid(9ac4fa26-4d19-4f4e-807e-b30cd0dbe56a)]
 interface nsIDOMMessageEvent : nsIDOMEvent
 {
   /**
    * Custom string data associated with this event.
    */
   [implicit_jscontext]
   readonly attribute jsval data;
   
--- a/embedding/android/GeckoSurfaceView.java
+++ b/embedding/android/GeckoSurfaceView.java
@@ -164,18 +164,40 @@ class GeckoSurfaceView
             if (c == null)
                 return;
             c.drawBitmap(bitmap, 0, 0, null);
             holder.unlockCanvasAndPost(c);
         }
     }
 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+
+        // Force exactly one frame to render
+        // because the surface change is only seen after we
+        // have swapped the back buffer.
+        // The buffer size only changes after the next swap buffer.
+        // We need to make sure the Gecko's view resize when Android's 
+        // buffer resizes.
+        if (mDrawMode == DRAW_GLES_2) {
+            // When we get a surfaceChange event, we have 0 to n paint events 
+            // waiting in the Gecko event queue. We will make the first
+            // succeed and the abort the others.
+            mDrawSingleFrame = true;
+            if (!mInDrawing) { 
+                // Queue at least one paint event in case none are queued.
+                GeckoAppShell.scheduleRedraw();
+            }
+            GeckoAppShell.geckoEventSync();
+            mDrawSingleFrame = false;
+            mAbortDraw = false;
+        }
+
         if (mShowingSplashScreen)
             drawSplashScreen(holder, width, height);
+
         mSurfaceLock.lock();
 
         try {
             if (mInDrawing) {
                 Log.w(LOG_FILE_NAME, "surfaceChanged while mInDrawing is true!");
             }
 
             boolean invalidSize;
@@ -216,16 +238,22 @@ class GeckoSurfaceView
                 c.drawARGB(255, 255, 255, 255);
                 holder.unlockCanvasAndPost(c);
                 return;
             } else {
                 GeckoAppShell.scheduleRedraw();
             }
         } finally {
             mSurfaceLock.unlock();
+            if (mDrawMode == DRAW_GLES_2) {
+                // Force a frame to be drawn before the surfaceChange returns,
+                // otherwise we get artifacts.
+                GeckoAppShell.scheduleRedraw();
+                GeckoAppShell.geckoEventSync();
+            }
         }
 
         Object syncDrawObject = null;
         try {
             syncDrawObject = mSyncDraws.take();
         } catch (InterruptedException ie) {
             Log.e(LOG_FILE_NAME, "Threw exception while getting sync draw bitmap/buffer: ", ie);
         }
@@ -288,23 +316,33 @@ class GeckoSurfaceView
 
     /*
      * Called on Gecko thread
      */
 
     public static final int DRAW_ERROR = 0;
     public static final int DRAW_GLES_2 = 1;
     public static final int DRAW_2D = 2;
+    // Drawing is disable when the surface buffer
+    // has changed size but we haven't yet processed the
+    // resize event.
+    public static final int DRAW_DISABLED = 3;
 
     public int beginDrawing() {
         if (mInDrawing) {
             Log.e(LOG_FILE_NAME, "Recursive beginDrawing call!");
             return DRAW_ERROR;
         }
 
+        // Once we drawn our first frame after resize we can ignore
+        // the other draw events until we handle the resize events.
+        if (mAbortDraw) {
+            return DRAW_DISABLED;
+        }
+
         /* Grab the lock, which we'll hold while we're drawing.
          * It gets released in endDrawing(), and is also used in surfaceChanged
          * to make sure that we don't change our surface details while
          * we're in the middle of drawing (and especially in the middle of
          * executing beginDrawing/endDrawing).
          *
          * We might not need to hold this lock in between
          * beginDrawing/endDrawing, and might just be able to make
@@ -325,16 +363,19 @@ class GeckoSurfaceView
     }
 
     public void endDrawing() {
         if (!mInDrawing) {
             Log.e(LOG_FILE_NAME, "endDrawing without beginDrawing!");
             return;
         }
 
+       if (mDrawSingleFrame)
+            mAbortDraw = true;
+
         try {
             if (!mSurfaceValid) {
                 Log.e(LOG_FILE_NAME, "endDrawing with false mSurfaceValid");
                 return;
             }
         } finally {
             mInDrawing = false;
 
@@ -652,16 +693,20 @@ class GeckoSurfaceView
     }
 
     // Is this surface valid for drawing into?
     boolean mSurfaceValid;
 
     // Are we actively between beginDrawing/endDrawing?
     boolean mInDrawing;
 
+    // Used to finish the current buffer before changing the surface size
+    boolean mDrawSingleFrame = false;
+    boolean mAbortDraw = false;
+
     // Are we waiting for a buffer to draw in surfaceChanged?
     boolean mSyncDraw;
 
     // True if gecko requests a buffer
     int mDrawMode;
 
     static boolean mShowingSplashScreen = true;
     static String  mSplashStatusMsg = "";
--- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
+++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
@@ -280,17 +280,17 @@ NS_IMETHODIMP nsSystemPrefService::GetPr
 /* boolean getBoolPref (in string aPrefName); */
 NS_IMETHODIMP nsSystemPrefService::GetBoolPref(const char *aPrefName, PRBool *_retval)
 {
     return mInitialized ?
         mGConf->GetBoolPref(aPrefName, _retval) : NS_ERROR_FAILURE;
 }
 
 /* void setBoolPref (in string aPrefName, in long aValue); */
-NS_IMETHODIMP nsSystemPrefService::SetBoolPref(const char *aPrefName, PRInt32 aValue)
+NS_IMETHODIMP nsSystemPrefService::SetBoolPref(const char *aPrefName, PRBool aValue)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 /* string getCharPref (in string aPrefName); */
 NS_IMETHODIMP nsSystemPrefService::GetCharPref(const char *aPrefName, char **_retval)
 {
     return mInitialized ?
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -36,20 +36,16 @@
 
 #include "mozSpellChecker.h"
 #include "nsIServiceManager.h"
 #include "mozISpellI18NManager.h"
 #include "nsIStringEnumerator.h"
 #include "nsICategoryManager.h"
 #include "nsISupportsPrimitives.h"
 
-// The number 130 more or less comes out of thin air.
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=355178#c78 for a pseudo-rationale.
-#define UNREASONABLE_WORD_LENGTH 130
-
 #define DEFAULT_SPELL_CHECKER "@mozilla.org/spellchecker/engine;1"
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(mozSpellChecker)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(mozSpellChecker)
 
 NS_INTERFACE_MAP_BEGIN(mozSpellChecker)
   NS_INTERFACE_MAP_ENTRY(nsISpellChecker)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISpellChecker)
@@ -144,22 +140,16 @@ mozSpellChecker::NextMisspelledWord(nsAS
 NS_IMETHODIMP 
 mozSpellChecker::CheckWord(const nsAString &aWord, PRBool *aIsMisspelled, nsTArray<nsString> *aSuggestions)
 {
   nsresult result;
   PRBool correct;
   if(!mSpellCheckingEngine)
     return NS_ERROR_NULL_POINTER;
 
-  // don't bother to check crazy words
-  if (aWord.Length() > UNREASONABLE_WORD_LENGTH) {
-    *aIsMisspelled = PR_TRUE;
-    return NS_OK;
-  }
-
   *aIsMisspelled = PR_FALSE;
   result = mSpellCheckingEngine->Check(PromiseFlatString(aWord).get(), &correct);
   NS_ENSURE_SUCCESS(result, result);
   if(!correct){
     if(aSuggestions){
       PRUint32 count,i;
       PRUnichar **words;
       
--- a/js/src/config/autoconf.mk.in
+++ b/js/src/config/autoconf.mk.in
@@ -38,17 +38,16 @@
 
 # A netscape style .mk file for autoconf builds
 
 INCLUDED_AUTOCONF_MK = 1
 USE_AUTOCONF 	= 1
 MOZILLA_CLIENT	= 1
 target          = @target@
 ac_configure_args = @ac_configure_args@
-BUILD_MODULES	= @BUILD_MODULES@
 MOZILLA_VERSION = @MOZILLA_VERSION@
 
 MOZ_BUILD_APP = @MOZ_BUILD_APP@
 MOZ_APP_NAME	= @MOZ_APP_NAME@
 MOZ_APP_DISPLAYNAME = @MOZ_APP_DISPLAYNAME@
 MOZ_APP_VERSION = @MOZ_APP_VERSION@
 
 MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -1148,18 +1148,19 @@ endif # OS/2
 	$(RM) $@
 	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
 	$(HOST_RANLIB) $@
 
 ifdef HAVE_DTRACE
 ifndef XP_MACOSX
 ifdef DTRACE_PROBE_OBJ
 ifndef DTRACE_LIB_DEPENDENT
-$(DTRACE_PROBE_OBJ):
-	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ)
+NON_DTRACE_OBJS := $(filter-out $(DTRACE_PROBE_OBJ),$(OBJS))
+$(DTRACE_PROBE_OBJ): $(NON_DTRACE_OBJS)
+	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(NON_DTRACE_OBJS)
 endif
 endif
 endif
 endif
 
 # On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
 # so instead of deleting .o files after repacking them into a dylib, we make
 # symlinks back to the originals. The symlinks are a no-op for stabs debugging,
@@ -1545,19 +1546,16 @@ ifeq ($(XPIDL_MODULE),) # we need $(XPID
 export:: FORCE
 	@echo
 	@echo "*** Error processing XPIDLSRCS:"
 	@echo "Please define MODULE or XPIDL_MODULE when defining XPIDLSRCS,"
 	@echo "so we have a module name to use when creating MODULE.xpt."
 	@echo; sleep 2; false
 endif
 
-$(IDL_DIR)::
-	$(NSINSTALL) -D $@
-
 # generate .h files from into $(XPIDL_GEN_DIR), then export to $(DIST)/include;
 # warn against overriding existing .h file. 
 $(XPIDL_GEN_DIR)/.done:
 	$(MKDIR) -p $(XPIDL_GEN_DIR)
 	@$(TOUCH) $@
 
 # don't depend on $(XPIDL_GEN_DIR), because the modification date changes
 # with any addition to the directory, regenerating all .h files -> everything.
@@ -1618,24 +1616,18 @@ export:: $(XPIDLSRCS) $(IDL_DIR)
 export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS)) $(DIST)/include
 	$(INSTALL) $(IFLAGS1) $^ 
 endif # NO_DIST_INSTALL
 
 endif # XPIDLSRCS
 
 
 
-#
 # General rules for exporting idl files.
-#
-# WORK-AROUND ONLY, for mozilla/tools/module-deps/bootstrap.pl build.
-# Bug to fix idl dependency problems w/o this extra build pass is
-#   http://bugzilla.mozilla.org/show_bug.cgi?id=145777
-#
-$(IDL_DIR)::
+$(IDL_DIR):
 	$(NSINSTALL) -D $@
 
 export-idl:: $(SUBMAKEFILES) $(MAKE_DIRS)
 
 ifneq ($(XPIDLSRCS),)
 ifndef NO_DIST_INSTALL
 export-idl:: $(XPIDLSRCS) $(IDL_DIR)
 	$(INSTALL) $(IFLAGS1) $^
@@ -2092,17 +2084,16 @@ showhost:
 	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
 	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
 	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
 	@echo "HOST_OBJS          = $(HOST_OBJS)"
 	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
 	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
 
 showbuildmods::
-	@echo "Build Modules	= $(BUILD_MODULES)"
 	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
 
 documentation:
 	@cd $(DEPTH)
 	$(DOXYGEN) $(DEPTH)/config/doxygen.cfg
 
 ifdef ENABLE_TESTS
 check:: $(SUBMAKEFILES) $(MAKE_DIRS)
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2477,16 +2477,17 @@ js_CloneFunctionObject(JSContext *cx, JS
         clone->setPrivate(cfun);
         if (cfun->isInterpreted()) {
             JSScript *script = cfun->script();
             JS_ASSERT(script);
             JS_ASSERT(script->compartment == fun->compartment());
             JS_ASSERT(script->compartment != cx->compartment);
             JS_OPT_ASSERT(script->ownerObject == fun);
 
+            cfun->u.i.script = NULL;
             JSScript *cscript = js_CloneScript(cx, script);
             if (!cscript)
                 return NULL;
             cfun->u.i.script = cscript;
             cfun->script()->setOwnerObject(cfun);
 #ifdef CHECK_SCRIPT_OWNER
             cfun->script()->owner = NULL;
 #endif
--- a/js/src/xpconnect/src/Makefile.in
+++ b/js/src/xpconnect/src/Makefile.in
@@ -41,27 +41,18 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= xpconnect
 
-ifeq (xpconnect, $(findstring xpconnect, $(BUILD_MODULES)))
-LIBRARY_NAME	= xpconnect
-EXPORT_LIBRARY = 1
-SHORT_LIBNAME	= xpconect
-IS_COMPONENT	= 1
-MODULE_NAME	= xpconnect
-GRE_MODULE	= 1
-else
 LIBRARY_NAME    = xpconnect_s
 FORCE_STATIC_LIB = 1
-endif
 LIBXUL_LIBRARY = 1
 EXPORTS = xpcpublic.h
 
 CPPSRCS		= \
 		nsScriptError.cpp \
 		nsXPConnect.cpp \
 		xpccallcontext.cpp \
 		xpccomponents.cpp \
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -274,16 +274,38 @@ nsProgressFrame::ComputeAutoSize(nsRende
     autoSize.height *= 10; // 10em
   } else {
     autoSize.width *= 10; // 10em
   }
 
   return autoSize;
 }
 
+nscoord
+nsProgressFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
+{
+  nsRefPtr<nsFontMetrics> fontMet;
+  NS_ENSURE_SUCCESS(
+      nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)), 0);
+
+  nscoord minWidth = fontMet->Font().size; // 1em
+
+  if (GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
+    minWidth *= 10; // 10em
+  }
+
+  return minWidth;
+}
+
+nscoord
+nsProgressFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
+{
+  return GetMinWidth(aRenderingContext);
+}
+
 bool
 nsProgressFrame::ShouldUseNativeStyle() const
 {
   // Use the native style if these conditions are satisfied:
   // - both frames use the native appearance;
   // - neither frame has author specified rules setting the border or the
   //   background.
   return GetStyleDisplay()->mAppearance == NS_THEME_PROGRESSBAR &&
--- a/layout/forms/nsProgressFrame.h
+++ b/layout/forms/nsProgressFrame.h
@@ -79,16 +79,19 @@ public:
                               nsIAtom* aAttribute,
                               PRInt32  aModType);
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
                                  nsSize aPadding, PRBool aShrinkWrap);
 
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
     return nsHTMLContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   /**
    * Returns whether the frame and its child should use the native style.
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/progress/in-cells-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <style>
+    progress { width: 10em; height: 1em; }
+    progress.vertical { -moz-orient: vertical; width: 1em; height: 10em; }
+  </style>
+  <body>
+    <table>
+      <tr>
+        <td>foo</td>
+        <td><progress value='0.5'></td>
+        <td>bar</td>
+      </tr>
+      <tr>
+        <td>foo</td>
+        <td><progress class='vertical' value='0.5'></td>
+        <td>bar</td>
+      </tr>
+    </table>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/progress/in-cells.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <style>
+    progress.vertical { -moz-orient: vertical; }
+  </style>
+  <body>
+    <table>
+      <tr>
+        <td>foo</td>
+        <td><progress value='0.5'></td>
+        <td>bar</td>
+      </tr>
+      <tr>
+        <td>foo</td>
+        <td><progress class='vertical' value='0.5'></td>
+        <td>bar</td>
+      </tr>
+    </table>
+  </body>
+</html>
--- a/layout/reftests/forms/progress/reftest.list
+++ b/layout/reftests/forms/progress/reftest.list
@@ -17,8 +17,9 @@
 
 # The following test is disabled but kept in the repository because the
 # transformations will not behave exactly the same for <progress> and two divs.
 # However, it would be possible to manually check those.
 # == transformations.html transformations-ref.html
 
 # Tests for bugs:
 == block-invalidate.html block-invalidate-ref.html
+== in-cells.html in-cells-ref.html
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -764,16 +764,25 @@ Declaration::GetValue(nsCSSProperty aPro
       const nsCSSValue &midValue =
         *data->ValueFor(eCSSProperty_marker_mid);
       const nsCSSValue &startValue =
         *data->ValueFor(eCSSProperty_marker_start);
       if (endValue == midValue && midValue == startValue)
         AppendValueToString(eCSSProperty_marker_end, aValue);
       break;
     }
+    case eCSSProperty__moz_columns: {
+      // Two values, column-count and column-width, separated by a space.
+      const nsCSSProperty* subprops =
+        nsCSSProps::SubpropertyEntryFor(aProperty);
+      AppendValueToString(subprops[0], aValue);
+      aValue.Append(PRUnichar(' '));
+      AppendValueToString(subprops[1], aValue);
+      break;
+    }
     default:
       NS_ABORT_IF_FALSE(false, "no other shorthands");
       break;
   }
 }
 
 PRBool
 Declaration::GetValueIsImportant(const nsAString& aProperty) const
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -487,16 +487,17 @@ protected:
   PRBool ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
                                            PRInt32& aVariantMask,
                                            PRBool *aHadFinalWS);
   PRBool ParseCalcTerm(nsCSSValue& aValue, PRInt32& aVariantMask);
   PRBool RequireWhitespace();
 
   // for 'clip' and '-moz-image-region'
   PRBool ParseRect(nsCSSProperty aPropID);
+  PRBool ParseColumns();
   PRBool ParseContent();
   PRBool ParseCounterData(nsCSSProperty aPropID);
   PRBool ParseCursor();
   PRBool ParseFont();
   PRBool ParseFontWeight(nsCSSValue& aValue);
   PRBool ParseOneFamily(nsAString& aValue);
   PRBool ParseFamily(nsCSSValue& aValue);
   PRBool ParseFontSrc(nsCSSValue& aValue);
@@ -5487,16 +5488,18 @@ CSSParserImpl::ParsePropertyByFunction(n
     return ParseBoxCornerRadius(aPropID);
 
   case eCSSProperty_box_shadow:
   case eCSSProperty_text_shadow:
     return ParseShadowList(aPropID);
 
   case eCSSProperty_clip:
     return ParseRect(eCSSProperty_clip);
+  case eCSSProperty__moz_columns:
+    return ParseColumns();
   case eCSSProperty__moz_column_rule:
     return ParseBorderSide(kColumnRuleIDs, PR_FALSE);
   case eCSSProperty_content:
     return ParseContent();
   case eCSSProperty_counter_increment:
   case eCSSProperty_counter_reset:
     return ParseCounterData(aPropID);
   case eCSSProperty_cursor:
@@ -5582,16 +5585,20 @@ CSSParserImpl::ParsePropertyByFunction(n
 PRBool
 CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
                                         nsCSSProperty aPropID)
 {
   if (aPropID == eCSSPropertyExtra_x_none_value) {
     return ParseVariant(aValue, VARIANT_NONE | VARIANT_INHERIT, nsnull);
   }
 
+  if (aPropID == eCSSPropertyExtra_x_auto_value) {
+    return ParseVariant(aValue, VARIANT_AUTO | VARIANT_INHERIT, nsnull);
+  }
+
   if (aPropID < 0 || aPropID >= eCSSProperty_COUNT_no_shorthands) {
     NS_ABORT_IF_FALSE(PR_FALSE, "not a single value property");
     return PR_FALSE;
   }
 
   if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_VALUE_PARSER_FUNCTION)) {
     switch (aPropID) {
       case eCSSProperty_font_family:
@@ -6841,16 +6848,58 @@ CSSParserImpl::ParseRect(nsCSSProperty a
     UngetToken();
     return PR_FALSE;
   }
 
   AppendValue(aPropID, val);
   return PR_TRUE;
 }
 
+PRBool
+CSSParserImpl::ParseColumns()
+{
+  // We use a similar "fake value" hack to ParseListStyle, because
+  // "auto" is acceptable for both column-count and column-width.
+  // If the fake "auto" value is found, and one of the real values isn't,
+  // that means the fake auto value is meant for the real value we didn't
+  // find.
+  static const nsCSSProperty columnIDs[] = {
+    eCSSPropertyExtra_x_auto_value,
+    eCSSProperty__moz_column_count,
+    eCSSProperty__moz_column_width
+  };
+  const PRInt32 numProps = NS_ARRAY_LENGTH(columnIDs);
+
+  nsCSSValue values[numProps];
+  PRInt32 found = ParseChoice(values, columnIDs, numProps);
+  if (found < 1 || !ExpectEndProperty()) {
+    return PR_FALSE;
+  }
+  if ((found & (1|2|4)) == (1|2|4) &&
+      values[0].GetUnit() ==  eCSSUnit_Auto) {
+    // We filled all 3 values, which is invalid
+    return PR_FALSE;
+  }
+
+  if ((found & 2) == 0) {
+    // Provide auto column-count
+    values[1].SetAutoValue();
+  }
+  if ((found & 4) == 0) {
+    // Provide auto column-width
+    values[2].SetAutoValue();
+  }
+
+  // Start at index 1 to skip the fake auto value.
+  for (PRInt32 index = 1; index < numProps; index++) {
+    AppendValue(columnIDs[index], values[index]);
+  }
+  return PR_TRUE;
+}
+
 #define VARIANT_CONTENT (VARIANT_STRING | VARIANT_URL | VARIANT_COUNTER | VARIANT_ATTR | \
                          VARIANT_KEYWORD)
 PRBool
 CSSParserImpl::ParseContent()
 {
   // We need to divide the 'content' keywords into two classes for
   // ParseVariant's sake, so we can't just use nsCSSProps::kContentKTable.
   static const PRInt32 kContentListKWs[] = {
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1234,16 +1234,21 @@ CSS_PROP_COLOR(
     Color,
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
         CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
     VARIANT_HC,
     nsnull,
     offsetof(nsStyleColor, mColor),
     eStyleAnimType_Color)
+CSS_PROP_SHORTHAND(
+    -moz-columns,
+    _moz_columns,
+    CSS_PROP_DOMPROP_PREFIXED(Columns),
+    CSS_PROPERTY_PARSE_FUNCTION)
 CSS_PROP_COLUMN(
     -moz-column-count,
     _moz_column_count,
     CSS_PROP_DOMPROP_PREFIXED(ColumnCount),
     CSS_PROPERTY_PARSE_VALUE |
         // Need to reject 0 in addition to negatives.  If we accept 0, we
         // need to change NS_STYLE_COLUMN_COUNT_AUTO to something else.
         CSS_PROPERTY_VALUE_AT_LEAST_ONE,
--- a/layout/style/nsCSSProperty.h
+++ b/layout/style/nsCSSProperty.h
@@ -71,17 +71,18 @@ enum nsCSSProperty {
   // with eCSSProperty_COUNT if we had a need for them to do so.
 
   // Extra values for use in the values of the 'transition-property'
   // property.
   eCSSPropertyExtra_no_properties,
   eCSSPropertyExtra_all_properties,
 
   // Extra dummy values for nsCSSParser internal use.
-  eCSSPropertyExtra_x_none_value
+  eCSSPropertyExtra_x_none_value,
+  eCSSPropertyExtra_x_auto_value
 };
 
 // The "descriptors" that can appear in a @font-face rule.
 // They have the syntax of properties but different value rules.
 // Keep in sync with kCSSRawFontDescs in nsCSSProps.cpp and
 // nsCSSFontFaceStyleDecl::Fields in nsCSSRules.cpp.
 enum nsCSSFontDesc {
   eCSSFontDesc_UNKNOWN = -1,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1963,16 +1963,22 @@ static const nsCSSProperty gOutlineSubpr
   // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
   eCSSProperty_outline_width,
   eCSSProperty_outline_style,
   eCSSProperty_outline_color,
   eCSSProperty_UNKNOWN
 };
 
+static const nsCSSProperty gColumnsSubpropTable[] = {
+  eCSSProperty__moz_column_count,
+  eCSSProperty__moz_column_width,
+  eCSSProperty_UNKNOWN
+};
+
 static const nsCSSProperty gColumnRuleSubpropTable[] = {
   // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
   eCSSProperty__moz_column_rule_width,
   eCSSProperty__moz_column_rule_style,
   eCSSProperty__moz_column_rule_color,
   eCSSProperty_UNKNOWN
 };
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -739,11 +739,15 @@ public:
   // Return whether the rule tree for which this node is the root has
   // cached data such that we need to do dynamic change handling for
   // changes that change the results of media queries or require
   // rebuilding all style data.
   PRBool TreeHasCachedData() const {
     NS_ASSERTION(IsRoot(), "should only be called on root of rule tree");
     return HaveChildren() || mStyleData.mInheritedData || mStyleData.mResetData;
   }
+
+  PRBool NodeHasCachedData(const nsStyleStructID aSID) {
+    return !!mStyleData.GetStyleData(aSID);
+  }
 };
 
 #endif
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -1921,98 +1921,99 @@ LookupStyleContext(dom::Element* aElemen
   nsIDocument* doc = aElement->GetCurrentDoc();
   nsIPresShell* shell = doc->GetShell();
   if (!shell) {
     return nsnull;
   }
   return nsComputedDOMStyle::GetStyleContextForElement(aElement, nsnull, shell);
 }
 
-
-/**
- * Helper function: StyleWithDeclarationAdded
- * Creates a nsStyleRule with the specified property set to the specified
- * value, and returns a nsStyleContext for this rule, as a sibling of the
- * given element's nsStyleContext.
- *
- * If we fail to parse |aSpecifiedValue| for |aProperty|, this method will
- * return nsnull.
- *
- * @param aProperty       The property whose value we're customizing in the
- *                        custom style context.
- * @param aTargetElement  The element whose style context we'll use as a
- *                        sibling for our custom style context.
- * @param aSpecifiedValue The value for |aProperty| in our custom style
- *                        context.
- * @param aUseSVGMode     A flag to indicate whether we should parse
- *                        |aSpecifiedValue| in SVG mode.
- * @return The generated custom nsStyleContext, or nsnull on failure.
- */
-already_AddRefed<nsStyleContext>
-StyleWithDeclarationAdded(nsCSSProperty aProperty,
-                          dom::Element* aTargetElement,
-                          const nsAString& aSpecifiedValue,
-                          PRBool aUseSVGMode)
-{
-  NS_ABORT_IF_FALSE(aTargetElement, "null target element");
-  NS_ABORT_IF_FALSE(aTargetElement->GetCurrentDoc(),
-                    "element needs to be in a document "
-                    "if we're going to look up its style context");
-
-  // Look up style context for our target element
-  nsRefPtr<nsStyleContext> styleContext = LookupStyleContext(aTargetElement);
-  if (!styleContext) {
-    return nsnull;
-  }
-
-  // Parse specified value into a temporary StyleRule
-  nsRefPtr<css::StyleRule> styleRule =
-    BuildStyleRule(aProperty, aTargetElement, aSpecifiedValue, aUseSVGMode);
-  if (!styleRule) {
-    return nsnull;
-  }
-
-  styleRule->RuleMatched();
-
-  // Create a temporary nsStyleContext for the style rule
-  nsCOMArray<nsIStyleRule> ruleArray;
-  ruleArray.AppendObject(styleRule);
-  nsStyleSet* styleSet = styleContext->PresContext()->StyleSet();
-  return styleSet->ResolveStyleByAddingRules(styleContext, ruleArray);
-}
-
 PRBool
 nsStyleAnimation::ComputeValue(nsCSSProperty aProperty,
                                dom::Element* aTargetElement,
                                const nsAString& aSpecifiedValue,
                                PRBool aUseSVGMode,
-                               Value& aComputedValue)
+                               Value& aComputedValue,
+                               PRBool* aIsContextSensitive)
 {
   NS_ABORT_IF_FALSE(aTargetElement, "null target element");
   NS_ABORT_IF_FALSE(aTargetElement->GetCurrentDoc(),
                     "we should only be able to actively animate nodes that "
                     "are in a document");
 
   nsCSSProperty propToParse =
     nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_REPORT_OTHER_NAME)
       ? nsCSSProps::OtherNameFor(aProperty) : aProperty;
 
-  nsRefPtr<nsStyleContext> tmpStyleContext =
-    StyleWithDeclarationAdded(propToParse, aTargetElement,
-                              aSpecifiedValue, aUseSVGMode);
-  if (!tmpStyleContext) {
+  // Parse specified value into a temporary css::StyleRule
+  nsRefPtr<css::StyleRule> styleRule =
+    BuildStyleRule(propToParse, aTargetElement, aSpecifiedValue, aUseSVGMode);
+  if (!styleRule) {
     return PR_FALSE;
   }
 
- if (nsCSSProps::IsShorthand(aProperty) ||
-     nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
+  if (nsCSSProps::IsShorthand(aProperty) ||
+      nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
     // Just capture the specified value
     aComputedValue.SetUnparsedStringValue(nsString(aSpecifiedValue));
+    if (aIsContextSensitive) {
+      // Since we're just returning the string as-is, aComputedValue isn't going
+      // to change depending on the context
+      *aIsContextSensitive = PR_FALSE;
+    }
     return PR_TRUE;
   }
+
+  // Look up style context for our target element
+  nsRefPtr<nsStyleContext> styleContext = LookupStyleContext(aTargetElement);
+  if (!styleContext) {
+    return PR_FALSE;
+  }
+  nsStyleSet* styleSet = styleContext->PresContext()->StyleSet();
+
+  nsRefPtr<nsStyleContext> tmpStyleContext;
+  if (aIsContextSensitive) {
+    nsCOMArray<nsIStyleRule> ruleArray;
+    ruleArray.AppendObject(styleSet->InitialStyleRule());
+    ruleArray.AppendObject(styleRule);
+    styleRule->RuleMatched();
+    tmpStyleContext =
+      styleSet->ResolveStyleByAddingRules(styleContext, ruleArray);
+    if (!tmpStyleContext) {
+      return PR_FALSE;
+    }
+
+    // Force walk of rule tree
+    nsStyleStructID sid = nsCSSProps::kSIDTable[aProperty];
+    tmpStyleContext->GetStyleData(sid);
+
+    // If the rule node will have cached style data if the value is not
+    // context-sensitive. So if there's nothing cached, it's not context
+    // sensitive.
+    *aIsContextSensitive =
+      !tmpStyleContext->GetRuleNode()->NodeHasCachedData(sid);
+  }
+
+  // If we're not concerned whether the property is context sensitive then just
+  // add the rule to a new temporary style context alongside the target
+  // element's style context.
+  // Also, if we previously discovered that this property IS context-sensitive
+  // then we need to throw the temporary style context out since the property's
+  // value may have been biased by the 'initial' values supplied.
+  if (!aIsContextSensitive || *aIsContextSensitive) {
+    nsCOMArray<nsIStyleRule> ruleArray;
+    ruleArray.AppendObject(styleRule);
+    styleRule->RuleMatched();
+    tmpStyleContext =
+      styleSet->ResolveStyleByAddingRules(styleContext, ruleArray);
+    if (!tmpStyleContext) {
+      return PR_FALSE;
+    }
+  }
+
   // Extract computed value of our property from the temporary style rule
   return ExtractComputedValue(aProperty, tmpStyleContext, aComputedValue);
 }
 
 PRBool
 nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty,
                                  nsPresContext* aPresContext,
                                  const Value& aComputedValue,
--- a/layout/style/nsStyleAnimation.h
+++ b/layout/style/nsStyleAnimation.h
@@ -170,23 +170,32 @@ public:
    * @param aProperty       The property whose value we're computing.
    * @param aTargetElement  The content node to which our computed value is
    *                        applicable.
    * @param aSpecifiedValue The specified value, from which we'll build our
    *                        computed value.
    * @param aUseSVGMode     A flag to indicate whether we should parse
    *                        |aSpecifiedValue| in SVG mode.
    * @param [out] aComputedValue The resulting computed value.
+   * @param [out] aIsContextSensitive
+   *                        Set to PR_TRUE if |aSpecifiedValue| may produce
+   *                        a different |aComputedValue| depending on other CSS
+   *                        properties on |aTargetElement| or its ancestors.
+   *                        PR_FALSE otherwise.
+   *                        Note that the operation of this method is
+   *                        significantly faster when |aIsContextSensitive| is
+   *                        nsnull.
    * @return PR_TRUE on success, PR_FALSE on failure.
    */
   static PRBool ComputeValue(nsCSSProperty aProperty,
-                             mozilla::dom::Element* aElement,
+                             mozilla::dom::Element* aTargetElement,
                              const nsAString& aSpecifiedValue,
                              PRBool aUseSVGMode,
-                             Value& aComputedValue);
+                             Value& aComputedValue,
+                             PRBool* aIsContextSensitive = nsnull);
 
   /**
    * Creates a specified value for the given computed value.
    *
    * The first overload fills in an nsCSSValue object; the second
    * produces a string.  The nsCSSValue result may depend on objects
    * owned by the |aComputedValue| object, so users of that variant
    * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -52,16 +52,17 @@
 #include "nsStyleContext.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsContentUtils.h"
+#include "nsRuleData.h"
 #include "nsRuleProcessorData.h"
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 #include "nsEventStates.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla::dom;
 namespace css = mozilla::css;
@@ -75,16 +76,60 @@ nsEmptyStyleRule::MapRuleInfoInto(nsRule
 
 #ifdef DEBUG
 /* virtual */ void
 nsEmptyStyleRule::List(FILE* out, PRInt32 aIndent) const
 {
 }
 #endif
 
+NS_IMPL_ISUPPORTS1(nsInitialStyleRule, nsIStyleRule)
+
+/* virtual */ void
+nsInitialStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
+{
+  // Iterate over the property groups
+  for (nsStyleStructID sid = nsStyleStructID(0);
+       sid < nsStyleStructID_Length; sid = nsStyleStructID(sid + 1)) {
+    if (aRuleData->mSIDs & (1 << sid)) {
+      // Iterate over nsCSSValues within the property group
+      nsCSSValue * const value_start =
+        aRuleData->mValueStorage + aRuleData->mValueOffsets[sid];
+      for (nsCSSValue *value = value_start,
+           *value_end = value + nsCSSProps::PropertyCountInStruct(sid);
+           value != value_end; ++value) {
+        // If MathML is disabled take care not to set MathML properties (or we
+        // will trigger assertions in nsRuleNode)
+        if (sid == eStyleStruct_Font &&
+            !aRuleData->mPresContext->Document()->GetMathMLEnabled()) {
+          size_t index = value - value_start;
+          if (index == nsCSSProps::PropertyIndexInStruct(
+                          eCSSProperty_script_level) ||
+              index == nsCSSProps::PropertyIndexInStruct(
+                          eCSSProperty_script_size_multiplier) ||
+              index == nsCSSProps::PropertyIndexInStruct(
+                          eCSSProperty_script_min_size)) {
+            continue;
+          }
+        }
+        if (value->GetUnit() == eCSSUnit_Null) {
+          value->SetInitialValue();
+        }
+      }
+    }
+  }
+}
+
+#ifdef DEBUG
+/* virtual */ void
+nsInitialStyleRule::List(FILE* out, PRInt32 aIndent) const
+{
+}
+#endif
+
 static const nsStyleSet::sheetType gCSSSheetTypes[] = {
   nsStyleSet::eAgentSheet,
   nsStyleSet::eUserSheet,
   nsStyleSet::eDocSheet,
   nsStyleSet::eOverrideSheet
 };
 
 nsStyleSet::nsStyleSet()
@@ -1560,8 +1605,17 @@ nsStyleSet::EnsureUniqueInnerOnCSSSheets
 
     // Enqueue all the sheet's children.
     if (!sheet->AppendAllChildSheets(queue)) {
       return nsCSSStyleSheet::eUniqueInner_CloneFailed;
     }
   }
   return res;
 }
+
+nsIStyleRule*
+nsStyleSet::InitialStyleRule()
+{
+  if (!mInitialStyleRule) {
+    mInitialStyleRule = new nsInitialStyleRule;
+  }
+  return mInitialStyleRule;
+}
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -69,16 +69,25 @@ class nsEmptyStyleRule : public nsIStyle
 {
   NS_DECL_ISUPPORTS
   virtual void MapRuleInfoInto(nsRuleData* aRuleData);
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
 #endif
 };
 
+class nsInitialStyleRule : public nsIStyleRule
+{
+  NS_DECL_ISUPPORTS
+  virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+#ifdef DEBUG
+  virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
+#endif
+};
+
 // The style set object is created by the document viewer and ownership is
 // then handed off to the PresShell.  Only the PresShell should delete a
 // style set.
 
 class nsStyleSet
 {
  public:
   nsStyleSet();
@@ -304,16 +313,18 @@ class nsStyleSet
 
   // Notify the style set that a rulenode that wasn't in use now is
   void RuleNodeInUse() {
     --mUnusedRuleNodeCount;
   }
 
   nsCSSStyleSheet::EnsureUniqueInnerResult EnsureUniqueInnerOnCSSSheets();
 
+  nsIStyleRule* InitialStyleRule();
+
  private:
   // Not to be implemented
   nsStyleSet(const nsStyleSet& aCopy);
   nsStyleSet& operator=(const nsStyleSet& aCopy);
 
   // Returns false on out-of-memory.
   PRBool BuildDefaultStyleData(nsPresContext* aPresContext);
 
@@ -395,16 +406,20 @@ class nsStyleSet
 
   PRUint32 mUnusedRuleNodeCount; // used to batch rule node GC
   nsTArray<nsStyleContext*> mRoots; // style contexts with no parent
 
   // Empty style rules to force things that restrict which properties
   // apply into different branches of the rule tree.
   nsRefPtr<nsEmptyStyleRule> mFirstLineRule, mFirstLetterRule;
 
+  // Style rule which sets all properties to their initial values for
+  // determining when context-sensitive values are in use.
+  nsRefPtr<nsInitialStyleRule> mInitialStyleRule;
+
   PRUint16 mBatching;
 
   // Old rule trees, which should only be non-empty between
   // BeginReconstruct and EndReconstruct, but in case of bugs that cause
   // style contexts to exist too long, may last longer.
   nsTArray<nsRuleNode*> mOldRuleTrees;
 
   unsigned mInShutdown : 1;
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -467,16 +467,26 @@ var gCSSProperties = {
 	"-moz-box-sizing": {
 		domProp: "MozBoxSizing",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "content-box" ],
 		other_values: [ "border-box", "padding-box" ],
 		invalid_values: [ "margin-box", "content", "padding", "border", "margin" ]
 	},
+	"-moz-columns": {
+		domProp: "MozColumns",
+		inherited: false,
+		type: CSS_TYPE_TRUE_SHORTHAND,
+		subproperties: [ "-moz-column-count", "-moz-column-width" ],
+		initial_values: [ "auto", "auto auto" ],
+		other_values: [ "3", "20px", "2 10px", "10px 2", "2 auto", "auto 2", "auto 50px", "50px auto" ],
+		invalid_values: [ "5%", "-1px", "-1", "3 5", "10px 4px", "10 2px 5in", "30px -1",
+		                  "auto 3 5px", "5 auto 20px", "auto auto auto" ]
+	},
 	"-moz-column-count": {
 		domProp: "MozColumnCount",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "auto" ],
 		other_values: [ "1", "17" ],
 		// negative and zero invalid per editor's draft
 		invalid_values: [ "-1", "0", "3px" ]
--- a/mobile/chrome/content/common-ui.js
+++ b/mobile/chrome/content/common-ui.js
@@ -1485,17 +1485,26 @@ var BadgeHandlers = {
   ],
 
   register: function(aPopup) {
     let handlers = this._handlers;
     for (let i = 0; i < handlers.length; i++)
       aPopup.registerBadgeHandler(handlers[i].url, handlers[i]);
   },
 
+  get _pk11DB() {
+    delete this._pk11DB;
+    return this._pk11DB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(Ci.nsIPK11TokenDB);
+  },
+
   getLogin: function(aURL) {
+    let token = this._pk11DB.getInternalKeyToken();
+    if (!token.isLoggedIn())
+      return {username: "", password: ""};
+
     let lm = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
     let logins = lm.findLogins({}, aURL, aURL, null);
     let username = logins.length > 0 ? logins[0].username : "";
     let password = logins.length > 0 ? logins[0].password : "";
     return { username: username, password: password };
   },
 
   clampBadge: function(aValue) {
--- a/mobile/chrome/content/sync.js
+++ b/mobile/chrome/content/sync.js
@@ -377,35 +377,39 @@ let WeaveGlue = {
     });
 
     // Replace the getter with the collection of settings
     delete this._elements;
     return this._elements = elements;
   },
 
   observe: function observe(aSubject, aTopic, aData) {
-    let loggedIn = Weave.Service.isLoggedIn;
-
     // Make sure we're online when connecting/syncing
     Util.forceOnline();
 
     // Can't do anything before settings are loaded
     if (this._elements == null)
       return;
 
     // Make some aliases
     let connect = this._elements.connect;
     let connected = this._elements.connected;
     let autosync = this._elements.autosync;
     let details = this._elements.details;
     let device = this._elements.device;
     let disconnect = this._elements.disconnect;
     let sync = this._elements.sync;
 
-    let syncEnabled = this._elements.autosync.value;
+    let syncEnabled = autosync.value;
+    let loggedIn = Weave.Service.isLoggedIn;
+
+    // Sync may successfully log in after it was temporarily disabled by a
+    // canceled master password entry.  If so, then re-enable it.
+    if (loggedIn && !syncEnabled)
+      syncEnabled = autosync.value = true;
 
     // If Sync is not enabled, hide the connection row visibility
     if (syncEnabled) {
       connect.collapsed = loggedIn;
       connected.collapsed = !loggedIn;
     } else {
       connect.collapsed = true;
       connected.collapsed = true;
@@ -446,20 +450,28 @@ let WeaveGlue = {
     let lastSync = Weave.Svc.Prefs.get("lastSync");
     if (lastSync != null) {
       let syncDate = new Date(lastSync).toLocaleFormat("%a %R");
       let dateStr = this._bundle.formatStringFromName("lastSync2.label", [syncDate], 1);
       sync.setAttribute("title", dateStr);
     }
 
     // Show what went wrong with login if necessary
-    if (aTopic == "weave:service:login:error")
-      connect.setAttribute("desc", Weave.Utils.getErrorString(Weave.Status.login));
-    else
+    if (aTopic == "weave:service:login:error") {
+      if (Weave.Status.login == "service.master_password_locked") {
+        // Disable sync temporarily. Sync will try again after a set interval,
+        // or if the user presses the button to enable it again.
+        autosync.value = false;
+        this.toggleSyncEnabled();
+      } else {
+        connect.setAttribute("desc", Weave.Utils.getErrorString(Weave.Status.login));
+      }
+    } else {
       connect.removeAttribute("desc");
+    }
 
     // Init the setup data if we just logged in
     if (!this.setupData && aTopic == "weave:service:login:finish")
       this.loadSetupData();
 
     // Check for a storage format update, update the user and load the Sync update page
     if (aTopic =="weave:service:sync:error") {
       let clientOutdated = false, remoteOutdated = false;
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -580,29 +580,16 @@ nsJARURI::GetFilePath(nsACString& filePa
 
 NS_IMETHODIMP
 nsJARURI::SetFilePath(const nsACString& filePath)
 {
     return mJAREntry->SetFilePath(filePath);
 }
 
 NS_IMETHODIMP
-nsJARURI::GetParam(nsACString& param)
-{
-    param.Truncate();
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsJARURI::SetParam(const nsACString& param)
-{
-    return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
 nsJARURI::GetQuery(nsACString& query)
 {
     return mJAREntry->GetQuery(query);
 }
 
 NS_IMETHODIMP
 nsJARURI::SetQuery(const nsACString& query)
 {
--- a/modules/libpref/public/nsIPrefBranch.idl
+++ b/modules/libpref/public/nsIPrefBranch.idl
@@ -50,17 +50,17 @@
  * For example, if this object is created with the root "browser.startup.",
  * the preferences "browser.startup.page", "browser.startup.homepage",
  * and "browser.startup.homepage_override" can be accessed by simply passing
  * "page", "homepage", or "homepage_override" to the various Get/Set methods.
  *
  * @see nsIPrefService
  */
 
-[scriptable, uuid(e0b6e170-691b-11e0-ae3e-0800200c9a66)]
+[scriptable, uuid(e162bfa0-01bd-4e9f-9843-8fb2efcd6d1f)]
 interface nsIPrefBranch : nsISupports
 {
 
   /**
    * Values describing the basic preference types.
    *
    * @see getPrefType
    */
@@ -102,17 +102,17 @@ interface nsIPrefBranch : nsISupports
    * @param aPrefName The boolean preference to set the state of.
    * @param aValue    The boolean value to set the preference to.
    *
    * @return NS_OK The value was successfully set.
    * @return Other The value was not set or is the wrong type.
    *
    * @see getBoolPref
    */
-  void setBoolPref(in string aPrefName, in long aValue);
+  void setBoolPref(in string aPrefName, in boolean aValue);
 
   /**
    * Called to get the state of an individual string preference.
    *
    * @param aPrefName The string preference to retrieve.
    *
    * @return string   The value of the requested string preference.
    *
--- a/modules/libpref/public/nsIPrefBranch2.idl
+++ b/modules/libpref/public/nsIPrefBranch2.idl
@@ -42,17 +42,17 @@
 
 interface nsIObserver;
 
 /**
  * nsIPrefBranch2 allows clients to observe changes to pref values.
  *
  * @see nsIPrefBranch
  */
-[scriptable, uuid(784de8e2-e72f-441a-ae74-9d5fdfe13be3)]
+[scriptable, uuid(d9bb54df-daac-4ce6-a70c-95d87b770cd8)]
 interface nsIPrefBranch2 : nsIPrefBranch
 {
   /**
    * Add a preference change observer. On preference changes, the following
    * arguments will be passed to the nsIObserver.observe() method:
    *   aSubject - The nsIPrefBranch object (this)
    *   aTopic   - The string defined by NS_PREFBRANCH_PREFCHANGE_TOPIC_ID
    *   aData    - The name of the preference which has changed, relative to
--- a/modules/libpref/public/nsIPrefBranchInternal.idl
+++ b/modules/libpref/public/nsIPrefBranchInternal.idl
@@ -39,12 +39,12 @@
 
 /**
  * An empty interface to provide backwards compatibility for existing code that
  * bsmedberg didn't want to break all at once. Don't use me!
  *
  * @status NON-FROZEN interface WHICH WILL PROBABLY GO AWAY.
  */
 
-[scriptable, uuid(d1d412d9-15d6-4a6a-9533-b949dc175ff5)]
+[scriptable, uuid(355bd1e9-248a-438b-809d-e0db1b287882)]
 interface nsIPrefBranchInternal : nsIPrefBranch2
 {
 };
--- a/modules/libpref/src/nsPrefBranch.cpp
+++ b/modules/libpref/src/nsPrefBranch.cpp
@@ -159,17 +159,17 @@ NS_IMETHODIMP nsPrefBranch::GetPrefType(
 
 NS_IMETHODIMP nsPrefBranch::GetBoolPref(const char *aPrefName, PRBool *_retval)
 {
   NS_ENSURE_ARG(aPrefName);
   const char *pref = getPrefName(aPrefName);
   return PREF_GetBoolPref(pref, _retval, mIsDefault);
 }
 
-NS_IMETHODIMP nsPrefBranch::SetBoolPref(const char *aPrefName, PRInt32 aValue)
+NS_IMETHODIMP nsPrefBranch::SetBoolPref(const char *aPrefName, PRBool aValue)
 {
   if (GetContentChild()) {
     NS_ERROR("cannot set pref from content process");
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   NS_ENSURE_ARG(aPrefName);
   const char *pref = getPrefName(aPrefName);
--- a/modules/libpref/src/prefapi.cpp
+++ b/modules/libpref/src/prefapi.cpp
@@ -63,19 +63,16 @@
 #include "nsPrintfCString.h"
 #include "prlink.h"
 
 #ifdef XP_OS2
 #define INCL_DOS
 #include <os2.h>
 #endif
 
-#define BOGUS_DEFAULT_INT_PREF_VALUE (-5632)
-#define BOGUS_DEFAULT_BOOL_PREF_VALUE (-2)
-
 static void
 clearPrefEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
 {
     PrefHashEntry *pref = static_cast<PrefHashEntry *>(entry);
     if (pref->flags & PREF_STRING)
     {
         if (pref->defaultPref.stringVal)
             PL_strfree(pref->defaultPref.stringVal);
@@ -293,17 +290,17 @@ PREF_SetIntPref(const char *pref_name, P
 
     return pref_HashPref(pref_name, pref, PREF_INT, set_default);
 }
 
 nsresult
 PREF_SetBoolPref(const char *pref_name, PRBool value, PRBool set_default)
 {
     PrefValue pref;
-    pref.boolVal = value ? PR_TRUE : PR_FALSE;
+    pref.boolVal = value;
 
     return pref_HashPref(pref_name, pref, PREF_BOOL, set_default);
 }
 
 nsresult
 pref_SetPrefTuple(const PrefTuple &aPref, PRBool set_default)
 {
     switch (aPref.type) {
@@ -334,19 +331,20 @@ pref_savePref(PLDHashTable *table, PLDHa
     nsCAutoString prefValue;
     nsCAutoString prefPrefix;
     prefPrefix.Assign(NS_LITERAL_CSTRING("user_pref(\""));
 
     // where we're getting our pref from
     PrefValue* sourcePref;
 
     if (PREF_HAS_USER_VALUE(pref) &&
-        pref_ValueChanged(pref->defaultPref,
-                          pref->userPref,
-                          (PrefType) PREF_TYPE(pref))) {
+        (pref_ValueChanged(pref->defaultPref,
+                           pref->userPref,
+                           (PrefType) PREF_TYPE(pref)) ||
+         !(pref->flags & PREF_HAS_DEFAULT))) {
         sourcePref = &pref->userPref;
     } else {
         if (argData->saveTypes == SAVE_ALL_AND_DEFAULTS) {
             prefPrefix.Assign(NS_LITERAL_CSTRING("pref(\""));
             sourcePref = &pref->defaultPref;
         }
         else
             // do not save default prefs that haven't changed
@@ -518,17 +516,17 @@ nsresult PREF_GetIntPref(const char *pre
     nsresult rv = NS_ERROR_UNEXPECTED;
     PrefHashEntry* pref = pref_HashTableLookup(pref_name);
     if (pref && (pref->flags & PREF_INT))
     {
         if (get_default || PREF_IS_LOCKED(pref) || !PREF_HAS_USER_VALUE(pref))
         {
             PRInt32 tempInt = pref->defaultPref.intVal;
             /* check to see if we even had a default */
-            if (tempInt == ((PRInt32) BOGUS_DEFAULT_INT_PREF_VALUE))
+            if (!(pref->flags & PREF_HAS_DEFAULT))
                 return NS_ERROR_UNEXPECTED;
             *return_int = tempInt;
         }
         else
             *return_int = pref->userPref.intVal;
         rv = NS_OK;
     }
     return rv;
@@ -543,17 +541,17 @@ nsresult PREF_GetBoolPref(const char *pr
     PrefHashEntry* pref = pref_HashTableLookup(pref_name);
     //NS_ASSERTION(pref, pref_name);
     if (pref && (pref->flags & PREF_BOOL))
     {
         if (get_default || PREF_IS_LOCKED(pref) || !PREF_HAS_USER_VALUE(pref))
         {
             PRBool tempBool = pref->defaultPref.boolVal;
             /* check to see if we even had a default */
-            if (tempBool != ((PRBool) BOGUS_DEFAULT_BOOL_PREF_VALUE)) {
+            if (pref->flags & PREF_HAS_DEFAULT) {
                 *return_value = tempBool;
                 rv = NS_OK;
             }
         }
         else {
             *return_value = pref->userPref.boolVal;
             rv = NS_OK;
         }
@@ -609,21 +607,17 @@ PREF_ClearUserPref(const char *pref_name
     if (!gHashTable.ops)
         return NS_ERROR_NOT_INITIALIZED;
 
     PrefHashEntry* pref = pref_HashTableLookup(pref_name);
     if (pref && PREF_HAS_USER_VALUE(pref))
     {
         pref->flags &= ~PREF_USERSET;
 
-        if ((pref->flags & PREF_INT && 
-             pref->defaultPref.intVal == ((PRInt32) BOGUS_DEFAULT_INT_PREF_VALUE)) ||
-            (pref->flags & PREF_BOOL && 
-             pref->defaultPref.boolVal == ((PRBool) BOGUS_DEFAULT_BOOL_PREF_VALUE)) ||
-            (pref->flags & PREF_STRING && !pref->defaultPref.stringVal)) {
+        if (!(pref->flags & PREF_HAS_DEFAULT)) {
             PL_DHashTableOperate(&gHashTable, pref_name, PL_DHASH_REMOVE);
         }
 
         pref_DoCallback(pref_name);
         gDirty = PR_TRUE;
     }
     return NS_OK;
 }
@@ -635,21 +629,17 @@ pref_ClearUserPref(PLDHashTable *table, 
     PrefHashEntry *pref = static_cast<PrefHashEntry*>(he);
 
     PLDHashOperator nextOp = PL_DHASH_NEXT;
 
     if (PREF_HAS_USER_VALUE(pref))
     {
         pref->flags &= ~PREF_USERSET;
 
-        if ((pref->flags & PREF_INT && 
-             pref->defaultPref.intVal == ((PRInt32) BOGUS_DEFAULT_INT_PREF_VALUE)) ||
-            (pref->flags & PREF_BOOL && 
-             pref->defaultPref.boolVal == ((PRBool) BOGUS_DEFAULT_BOOL_PREF_VALUE)) ||
-            (pref->flags & PREF_STRING && !pref->defaultPref.stringVal)) {
+        if (!(pref->flags & PREF_HAS_DEFAULT)) {
             nextOp = PL_DHASH_REMOVE;
         }
 
         pref_DoCallback(pref->key);
     }
     return nextOp;
 }
 
@@ -752,51 +742,45 @@ nsresult pref_HashPref(const char *key, 
     // new entry, better intialize
     if (!pref->key) {
 
         // initialize the pref entry
         pref->flags = type;
         pref->key = ArenaStrDup(key, &gPrefNameArena);
         memset(&pref->defaultPref, 0, sizeof(pref->defaultPref));
         memset(&pref->userPref, 0, sizeof(pref->userPref));
-
-        /* ugly hack -- define it to a default that no pref will ever
-           default to this should really get fixed right by some out
-           of band data
-        */
-        if (pref->flags & PREF_BOOL)
-            pref->defaultPref.boolVal = (PRBool) BOGUS_DEFAULT_BOOL_PREF_VALUE;
-        if (pref->flags & PREF_INT)
-            pref->defaultPref.intVal = (PRInt32) BOGUS_DEFAULT_INT_PREF_VALUE;
     }
     else if ((((PrefType)(pref->flags)) & PREF_VALUETYPE_MASK) !=
                  (type & PREF_VALUETYPE_MASK))
     {
         NS_WARNING(nsPrintfCString(192, "Trying to set pref %s to with the wrong type!", key).get());
         return NS_ERROR_UNEXPECTED;
     }
 
     PRBool valueChanged = PR_FALSE;
     if (set_default)
     {
         if (!PREF_IS_LOCKED(pref))
         {       /* ?? change of semantics? */
-            if (pref_ValueChanged(pref->defaultPref, value, type))
+            if (pref_ValueChanged(pref->defaultPref, value, type) ||
+                !(pref->flags & PREF_HAS_DEFAULT))
             {
                 pref_SetValue(&pref->defaultPref, value, type);
+                pref->flags |= PREF_HAS_DEFAULT;
                 if (!PREF_HAS_USER_VALUE(pref))
                     valueChanged = PR_TRUE;
             }
         }
     }
     else
     {
         /* If new value is same as the default value, then un-set the user value.
            Otherwise, set the user value only if it has changed */
-        if ( !pref_ValueChanged(pref->defaultPref, value, type) )
+        if (!pref_ValueChanged(pref->defaultPref, value, type) &&
+            pref->flags & PREF_HAS_DEFAULT)
         {
             if (PREF_HAS_USER_VALUE(pref))
             {
                 pref->flags &= ~PREF_USERSET;
                 if (!PREF_IS_LOCKED(pref))
                     valueChanged = PR_TRUE;
             }
         }
--- a/modules/libpref/src/prefapi.h
+++ b/modules/libpref/src/prefapi.h
@@ -53,17 +53,17 @@ typedef union
     PRBool      boolVal;
 } PrefValue;
 
 struct PrefHashEntry : PLDHashEntryHdr
 {
     const char *key;
     PrefValue defaultPref;
     PrefValue userPref;
-    PRUint8   flags;
+    PRUint16  flags;
 };
 
 /*
 // <font color=blue>
 // The Init function initializes the preference context and creates
 // the preference hashtable.
 // </font>
 */
@@ -79,19 +79,20 @@ void        PREF_CleanupPrefs();
 /*
 // <font color=blue>
 // Preference flags, including the native type of the preference
 // </font>
 */
 
 typedef enum { PREF_INVALID = 0,
                PREF_LOCKED = 1, PREF_USERSET = 2, PREF_CONFIG = 4, PREF_REMOTE = 8,
-			   PREF_LILOCAL = 16, PREF_STRING = 32, PREF_INT = 64, PREF_BOOL = 128,
-			   PREF_VALUETYPE_MASK = (PREF_STRING | PREF_INT | PREF_BOOL)
-			  } PrefType;
+               PREF_LILOCAL = 16, PREF_STRING = 32, PREF_INT = 64, PREF_BOOL = 128,
+               PREF_HAS_DEFAULT = 256,
+               PREF_VALUETYPE_MASK = (PREF_STRING | PREF_INT | PREF_BOOL)
+             } PrefType;
 
 /*
 // <font color=blue>
 // Set the various types of preferences.  These functions take a dotted
 // notation of the preference name (e.g. "browser.startup.homepage").  
 // Note that this will cause the preference to be saved to the file if
 // it is different from the default.  In other words, these are used
 // to set the _user_ preferences.
--- a/netwerk/base/public/nsIURL.idl
+++ b/netwerk/base/public/nsIURL.idl
@@ -40,17 +40,16 @@
 #include "nsIURI.idl"
 
 /**
  * The nsIURL interface provides convenience methods that further
  * break down the path portion of nsIURI:
  *
  * http://host/directory/fileBaseName.fileExtension?query
  * http://host/directory/fileBaseName.fileExtension#ref
- * http://host/directory/fileBaseName.fileExtension;param
  *            \          \                       /
  *             \          -----------------------
  *              \                   |          /
  *               \               fileName     /
  *                ----------------------------
  *                            |
  *                        filePath
  */
@@ -66,23 +65,16 @@ interface nsIURL : nsIURI
      * URL.  For example, the filePath of "http://host/foo/bar.html#baz"
      * is "/foo/bar.html".
      *
      * Some characters may be escaped.
      */
     attribute AUTF8String filePath;
 
     /**
-     * Returns the parameters specified after the ; in the URL. 
-     *
-     * Some characters may be escaped.
-     */
-    attribute AUTF8String param;
-
-    /**
      * Returns the query portion (the part after the "?") of the URL.
      * If there isn't one, an empty string is returned.
      *
      * Some characters may be escaped.
      */
     attribute AUTF8String query;
 
 
--- a/netwerk/base/public/nsIURLParser.idl
+++ b/netwerk/base/public/nsIURLParser.idl
@@ -90,24 +90,23 @@ interface nsIURLParser : nsISupports
     /**
      * serverinfo = <hostname>:<port>
      */
     void parseServerInfo (in string serverinfo,            in long serverinfoLen,
                           out unsigned long hostnamePos,  out long hostnameLen,
                           out long port);
 
     /**
-     * ParsePath breaks the path string up into its 4 major components: a file path,
-     * a param string, a query string, and a reference string.
+     * ParsePath breaks the path string up into its 3 major components: a file path,
+     * a query string, and a reference string.
      *
-     * path = <filepath>;<param>?<query>#<ref>
+     * path = <filepath>?<query>#<ref>
      */
     void parsePath       (in string path,                  in long pathLen,
                           out unsigned long filepathPos,  out long filepathLen,
-                          out unsigned long paramPos,     out long paramLen,
                           out unsigned long queryPos,     out long queryLen,
                           out unsigned long refPos,       out long refLen);
 
     /**
      * ParseFilePath breaks the file path string up into: the directory portion,
      * file base name, and file extension.
      *
      * filepath = <directory><basename>.<extension>
--- a/netwerk/base/src/nsStandardURL.cpp
+++ b/netwerk/base/src/nsStandardURL.cpp
@@ -395,17 +395,16 @@ nsStandardURL::Clear()
     mHostEncoding = eEncoding_ASCII;
 
     mPath.Reset();
     mFilepath.Reset();
     mDirectory.Reset();
     mBasename.Reset();
 
     mExtension.Reset();
-    mParam.Reset();
     mQuery.Reset();
     mRef.Reset();
 
     InvalidateCache();
 }
 
 void
 nsStandardURL::InvalidateCache(PRBool invalidateCachedFile)
@@ -506,26 +505,26 @@ nsresult
 nsStandardURL::BuildNormalizedSpec(const char *spec)
 {
     // Assumptions: all member URLSegments must be relative the |spec| argument
     // passed to this function.
 
     // buffers for holding escaped url segments (these will remain empty unless
     // escaping is required).
     nsCAutoString encUsername, encPassword, encHost, encDirectory,
-      encBasename, encExtension, encParam, encQuery, encRef;
+      encBasename, encExtension, encQuery, encRef;
     PRBool useEncUsername, useEncPassword, useEncHost, useEncDirectory,
-      useEncBasename, useEncExtension, useEncParam, useEncQuery, useEncRef;
+      useEncBasename, useEncExtension, useEncQuery, useEncRef;
     nsCAutoString portbuf;
 
     //
     // escape each URL segment, if necessary, and calculate approximate normalized
     // spec length.
     //
-    // [scheme://][username[:password]@]host[:port]/path[;param][?query_string][#ref]
+    // [scheme://][username[:password]@]host[:port]/path[?query_string][#ref]
 
     PRUint32 approxLen = 0;
 
     // the scheme is already ASCII
     if (mScheme.mLen > 0)
         approxLen += mScheme.mLen + 3; // includes room for "://";
 
     // encode URL segments; convert UTF-8 to origin charset and possibly escape.
@@ -551,19 +550,16 @@ nsStandardURL::BuildNormalizedSpec(const
         approxLen += 1; // reserve space for possible leading '/' - may not be needed
         // Should just use mPath?  These are pessimistic, and thus waste space
         approxLen += encoder.EncodeSegmentCount(spec, mDirectory, esc_Directory,     encDirectory, useEncDirectory, 1);
         approxLen += encoder.EncodeSegmentCount(spec, mBasename,  esc_FileBaseName,  encBasename,  useEncBasename);
         approxLen += encoder.EncodeSegmentCount(spec, mExtension, esc_FileExtension, encExtension, useEncExtension, 1);
 
         // These next ones *always* add their leading character even if length is 0
         // Handles items like "http://#"
-        // ;param
-        if (mParam.mLen >= 0)
-            approxLen += 1 + encoder.EncodeSegmentCount(spec, mParam,     esc_Param,         encParam,     useEncParam);
         // ?query
         if (mQuery.mLen >= 0)
             approxLen += 1 + queryEncoder.EncodeSegmentCount(spec, mQuery, esc_Query,        encQuery,     useEncQuery);
         // #ref
         if (mRef.mLen >= 0)
             approxLen += 1 + encoder.EncodeSegmentCount(spec, mRef,       esc_Ref,           encRef,       useEncRef);
     }
 
@@ -673,20 +669,16 @@ nsStandardURL::BuildNormalizedSpec(const
 
         if (mExtension.mLen >= 0) {
             buf[i++] = '.';
             i = AppendSegmentToBuf(buf, i, spec, mExtension, &encExtension, useEncExtension);
         }
         // calculate corrected filepath length
         mFilepath.mLen = i - mFilepath.mPos;
 
-        if (mParam.mLen >= 0) {
-            buf[i++] = ';';
-            i = AppendSegmentToBuf(buf, i, spec, mParam, &encParam, useEncParam);
-        }
         if (mQuery.mLen >= 0) {
             buf[i++] = '?';
             i = AppendSegmentToBuf(buf, i, spec, mQuery, &encQuery, useEncQuery);
         }
         if (mRef.mLen >= 0) {
             buf[i++] = '#';
             i = AppendSegmentToBuf(buf, i, spec, mRef, &encRef, useEncRef);
         }
@@ -833,23 +825,21 @@ nsStandardURL::ParseURL(const char *spec
 
 nsresult
 nsStandardURL::ParsePath(const char *spec, PRUint32 pathPos, PRInt32 pathLen)
 {
     LOG(("ParsePath: %s pathpos %d len %d\n",spec,pathPos,pathLen));
 
     nsresult rv = mParser->ParsePath(spec + pathPos, pathLen,
                                      &mFilepath.mPos, &mFilepath.mLen,
-                                     &mParam.mPos, &mParam.mLen,
                                      &mQuery.mPos, &mQuery.mLen,
                                      &mRef.mPos, &mRef.mLen);
     if (NS_FAILED(rv)) return rv;
 
     mFilepath.mPos += pathPos;
-    mParam.mPos += pathPos;
     mQuery.mPos += pathPos;
     mRef.mPos += pathPos;
 
     if (mFilepath.mLen > 0) {
         rv = mParser->ParseFilePath(spec + mFilepath.mPos, mFilepath.mLen,
                                     &mDirectory.mPos, &mDirectory.mLen,
                                     &mBasename.mPos, &mBasename.mLen,
                                     &mExtension.mPos, &mExtension.mLen);
@@ -1203,17 +1193,16 @@ nsStandardURL::SetSpec(const nsACString 
         LOG((" username  = (%u,%d)\n", mUsername.mPos,  mUsername.mLen));
         LOG((" password  = (%u,%d)\n", mPassword.mPos,  mPassword.mLen));
         LOG((" hostname  = (%u,%d)\n", mHost.mPos,      mHost.mLen));
         LOG((" path      = (%u,%d)\n", mPath.mPos,      mPath.mLen));
         LOG((" filepath  = (%u,%d)\n", mFilepath.mPos,  mFilepath.mLen));
         LOG((" directory = (%u,%d)\n", mDirectory.mPos, mDirectory.mLen));
         LOG((" basename  = (%u,%d)\n", mBasename.mPos,  mBasename.mLen));
         LOG((" extension = (%u,%d)\n", mExtension.mPos, mExtension.mLen));
-        LOG((" param     = (%u,%d)\n", mParam.mPos,     mParam.mLen));
         LOG((" query     = (%u,%d)\n", mQuery.mPos,     mQuery.mLen));
         LOG((" ref       = (%u,%d)\n", mRef.mPos,       mRef.mLen));
     }
 #endif
     return rv;
 }
 
 NS_IMETHODIMP
@@ -1628,17 +1617,16 @@ nsStandardURL::SetPath(const nsACString 
         mSpec.Cut(mPath.mPos + 1, mPath.mLen - 1);
         // these contain only a '/'
         mPath.mLen = 1;
         mDirectory.mLen = 1;
         mFilepath.mLen = 1;
         // these are no longer defined
         mBasename.mLen = -1;
         mExtension.mLen = -1;
-        mParam.mLen = -1;
         mQuery.mLen = -1;
         mRef.mLen = -1;
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStandardURL::Equals(nsIURI *unknownOther, PRBool *result)
@@ -1679,18 +1667,17 @@ nsStandardURL::EqualsInternal(nsIURI *un
     // URIs different
     if (!SegmentIs(mScheme, other->mSpec.get(), other->mScheme) ||
         // Check for host manually, since conversion to file will
         // ignore the host!
         !SegmentIs(mHost, other->mSpec.get(), other->mHost) ||
         !SegmentIs(mQuery, other->mSpec.get(), other->mQuery) ||
         !SegmentIs(mUsername, other->mSpec.get(), other->mUsername) ||
         !SegmentIs(mPassword, other->mSpec.get(), other->mPassword) ||
-        Port() != other->Port() ||
-        !SegmentIs(mParam, other->mSpec.get(), other->mParam)) {
+        Port() != other->Port()) {
         // No need to compare files or other URI parts -- these are different
         // beasties
         *result = PR_FALSE;
         return NS_OK;
     }
 
     if (refHandlingMode == eHonorRef &&
         !SegmentIs(mRef, other->mSpec.get(), other->mRef)) {
@@ -1790,17 +1777,16 @@ nsStandardURL::CloneInternal(nsStandardU
     clone->mUsername = mUsername;
     clone->mPassword = mPassword;
     clone->mHost = mHost;
     clone->mPath = mPath;
     clone->mFilepath = mFilepath;
     clone->mDirectory = mDirectory;
     clone->mBasename = mBasename;
     clone->mExtension = mExtension;
-    clone->mParam = mParam;
     clone->mQuery = mQuery;
     clone->mRef = mRef;
     clone->mOriginCharset = mOriginCharset;
     clone->mURLType = mURLType;
     clone->mParser = mParser;
     clone->mFile = mFile;
     clone->mHostA = mHostA ? nsCRT::strdup(mHostA) : nsnull;
     clone->mMutable = PR_TRUE;
@@ -2015,17 +2001,17 @@ nsStandardURL::GetCommonBaseSpec(nsIURI 
     while ((*thisIndex == *thatIndex) && *thisIndex)
     {
         thisIndex++;
         thatIndex++;
     }
 
     // backup to just after previous slash so we grab an appropriate path
     // segment such as a directory (not partial segments)
-    // todo:  also check for file matches which include '?', '#', and ';'
+    // todo:  also check for file matches which include '?' and '#'
     while ((thisIndex != startCharPos) && (*(thisIndex-1) != '/'))
         thisIndex--;
 
     // grab spec from beginning to thisIndex
     aResult = Substring(mSpec, mScheme.mPos, thisIndex - mSpec.get());
 
     NS_RELEASE(stdurl2);
     return rv;
@@ -2096,17 +2082,17 @@ nsStandardURL::GetRelativeSpec(nsIURI *u
     while ((*thisIndex == *thatIndex) && *thisIndex)
     {
         thisIndex++;
         thatIndex++;
     }
 
     // backup to just after previous slash so we grab an appropriate path
     // segment such as a directory (not partial segments)
-    // todo:  also check for file matches with '#', '?' and ';'
+    // todo:  also check for file matches with '#' and '?'
     while ((*(thatIndex-1) != '/') && (thatIndex != startCharPos))
         thatIndex--;
 
     const char *limit = mSpec.get() + mFilepath.mPos + mFilepath.mLen;
 
     // need to account for slashes and add corresponding "../"
     for (; thisIndex <= limit && *thisIndex; ++thisIndex)
     {
@@ -2132,24 +2118,16 @@ NS_IMETHODIMP
 nsStandardURL::GetFilePath(nsACString &result)
 {
     result = Filepath();
     return NS_OK;
 }
 
 // result may contain unescaped UTF-8 characters
 NS_IMETHODIMP
-nsStandardURL::GetParam(nsACString &result)
-{
-    result = Param();
-    return NS_OK;
-}
-
-// result may contain unescaped UTF-8 characters
-NS_IMETHODIMP
 nsStandardURL::GetQuery(nsACString &result)
 {
     result = Query();
     return NS_OK;
 }
 
 // result may contain unescaped UTF-8 characters
 NS_IMETHODIMP
@@ -2258,37 +2236,30 @@ nsStandardURL::SetFilePath(const nsACStr
             if (mSpec.Length() > end)
                 spec.Append(mSpec.get() + end, mSpec.Length() - end);
         }
 
         return SetSpec(spec);
     }
     else if (mPath.mLen > 1) {
         mSpec.Cut(mPath.mPos + 1, mFilepath.mLen - 1);
-        // left shift param, query, and ref
-        ShiftFromParam(1 - mFilepath.mLen);
+        // left shift query, and ref
+        ShiftFromQuery(1 - mFilepath.mLen);
         // these contain only a '/'
         mPath.mLen = 1;
         mDirectory.mLen = 1;
         mFilepath.mLen = 1;
         // these are no longer defined
         mBasename.mLen = -1;
         mExtension.mLen = -1;
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsStandardURL::SetParam(const nsACString &input)
-{
-    NS_NOTYETIMPLEMENTED("");
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
 nsStandardURL::SetQuery(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *query = flat.get();
 
     LOG(("nsStandardURL::SetQuery [query=%s]\n", query));
@@ -2498,17 +2469,17 @@ nsStandardURL::SetFileName(const nsACStr
             
             mBasename.mLen = basename.mLen;
             mExtension.mLen = extension.mLen;
             if (mExtension.mLen >= 0)
                 mExtension.mPos = mBasename.mPos + mBasename.mLen + 1;
         }
     }
     if (shift) {
-        ShiftFromParam(shift);
+        ShiftFromQuery(shift);
         mFilepath.mLen += shift;
         mPath.mLen += shift;
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStandardURL::SetFileBaseName(const nsACString &input)
@@ -2795,19 +2766,16 @@ nsStandardURL::Read(nsIObjectInputStream
     if (NS_FAILED(rv)) return rv;
 
     rv = ReadSegment(stream, mBasename);
     if (NS_FAILED(rv)) return rv;
 
     rv = ReadSegment(stream, mExtension);
     if (NS_FAILED(rv)) return rv;
 
-    rv = ReadSegment(stream, mParam);
-    if (NS_FAILED(rv)) return rv;
-
     rv = ReadSegment(stream, mQuery);
     if (NS_FAILED(rv)) return rv;
 
     rv = ReadSegment(stream, mRef);
     if (NS_FAILED(rv)) return rv;
 
     rv = NS_ReadOptionalCString(stream, mOriginCharset);
     if (NS_FAILED(rv)) return rv;
@@ -2884,19 +2852,16 @@ nsStandardURL::Write(nsIObjectOutputStre
     if (NS_FAILED(rv)) return rv;
 
     rv = WriteSegment(stream, mBasename);
     if (NS_FAILED(rv)) return rv;
 
     rv = WriteSegment(stream, mExtension);
     if (NS_FAILED(rv)) return rv;
 
-    rv = WriteSegment(stream, mParam);
-    if (NS_FAILED(rv)) return rv;
-
     rv = WriteSegment(stream, mQuery);
     if (NS_FAILED(rv)) return rv;
 
     rv = WriteSegment(stream, mRef);
     if (NS_FAILED(rv)) return rv;
 
     rv = NS_WriteOptionalStringZ(stream, mOriginCharset.get());
     if (NS_FAILED(rv)) return rv;
@@ -2959,17 +2924,16 @@ nsStandardURL::Read(const IPC::Message *
         !ReadSegment(aMsg, aIter, mUsername) ||
         !ReadSegment(aMsg, aIter, mPassword) ||
         !ReadSegment(aMsg, aIter, mHost) ||
         !ReadSegment(aMsg, aIter, mPath) ||
         !ReadSegment(aMsg, aIter, mFilepath) ||
         !ReadSegment(aMsg, aIter, mDirectory) ||
         !ReadSegment(aMsg, aIter, mBasename) ||
         !ReadSegment(aMsg, aIter, mExtension) ||
-        !ReadSegment(aMsg, aIter, mParam) ||
         !ReadSegment(aMsg, aIter, mQuery) ||
         !ReadSegment(aMsg, aIter, mRef) ||
         !ReadParam(aMsg, aIter, &mOriginCharset) ||
         !ReadParam(aMsg, aIter, &isMutable) ||
         !ReadParam(aMsg, aIter, &supportsFileURL) ||
         !ReadParam(aMsg, aIter, &hostEncoding))
         return PR_FALSE;
 
@@ -3000,17 +2964,16 @@ nsStandardURL::Write(IPC::Message *aMsg)
     WriteSegment(aMsg, mUsername);
     WriteSegment(aMsg, mPassword);
     WriteSegment(aMsg, mHost);
     WriteSegment(aMsg, mPath);
     WriteSegment(aMsg, mFilepath);
     WriteSegment(aMsg, mDirectory);
     WriteSegment(aMsg, mBasename);
     WriteSegment(aMsg, mExtension);
-    WriteSegment(aMsg, mParam);
     WriteSegment(aMsg, mQuery);
     WriteSegment(aMsg, mRef);
     WriteParam(aMsg, mOriginCharset);
     WriteParam(aMsg, bool(mMutable));
     WriteParam(aMsg, bool(mSupportsFileURL));
     WriteParam(aMsg, mHostEncoding);
     // mSpecEncoding and mHostA are just caches that can be recovered as needed.
 }
--- a/netwerk/base/src/nsStandardURL.h
+++ b/netwerk/base/src/nsStandardURL.h
@@ -218,31 +218,29 @@ private:
     const nsDependentCSubstring Hostport(); // see below
     const nsDependentCSubstring Host();     // see below
     const nsDependentCSubstring Path()      { return Segment(mPath); }
     const nsDependentCSubstring Filepath()  { return Segment(mFilepath); }
     const nsDependentCSubstring Directory() { return Segment(mDirectory); }
     const nsDependentCSubstring Filename(); // see below
     const nsDependentCSubstring Basename()  { return Segment(mBasename); }
     const nsDependentCSubstring Extension() { return Segment(mExtension); }
-    const nsDependentCSubstring Param()     { return Segment(mParam); }
     const nsDependentCSubstring Query()     { return Segment(mQuery); }
     const nsDependentCSubstring Ref()       { return Segment(mRef); }
 
     // shift the URLSegments to the right by diff
     void ShiftFromAuthority(PRInt32 diff) { mAuthority.mPos += diff; ShiftFromUsername(diff); }
     void ShiftFromUsername(PRInt32 diff)  { mUsername.mPos += diff; ShiftFromPassword(diff); }
     void ShiftFromPassword(PRInt32 diff)  { mPassword.mPos += diff; ShiftFromHost(diff); }
     void ShiftFromHost(PRInt32 diff)      { mHost.mPos += diff; ShiftFromPath(diff); }
     void ShiftFromPath(PRInt32 diff)      { mPath.mPos += diff; ShiftFromFilepath(diff); }
     void ShiftFromFilepath(PRInt32 diff)  { mFilepath.mPos += diff; ShiftFromDirectory(diff); }
     void ShiftFromDirectory(PRInt32 diff) { mDirectory.mPos += diff; ShiftFromBasename(diff); }
     void ShiftFromBasename(PRInt32 diff)  { mBasename.mPos += diff; ShiftFromExtension(diff); }
-    void ShiftFromExtension(PRInt32 diff) { mExtension.mPos += diff; ShiftFromParam(diff); }
-    void ShiftFromParam(PRInt32 diff)     { mParam.mPos += diff; ShiftFromQuery(diff); }
+    void ShiftFromExtension(PRInt32 diff) { mExtension.mPos += diff; ShiftFromQuery(diff); }
     void ShiftFromQuery(PRInt32 diff)     { mQuery.mPos += diff; ShiftFromRef(diff); }
     void ShiftFromRef(PRInt32 diff)       { mRef.mPos += diff; }
 
     // fastload helper functions
     nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
     nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &);
 
     // ipc helper functions
@@ -262,17 +260,16 @@ private:
     URLSegment mUsername;
     URLSegment mPassword;
     URLSegment mHost;
     URLSegment mPath;
     URLSegment mFilepath;
     URLSegment mDirectory;
     URLSegment mBasename;
     URLSegment mExtension;
-    URLSegment mParam;
     URLSegment mQuery;
     URLSegment mRef;
 
     nsCString              mOriginCharset;
     nsCOMPtr<nsIURLParser> mParser;
 
     // mFile is protected so subclasses can access it directly
 protected:
--- a/netwerk/base/src/nsURLHelper.cpp
+++ b/netwerk/base/src/nsURLHelper.cpp
@@ -216,17 +216,16 @@ net_ParseFileURL(const nsACString &inURL
                           nsnull, nsnull, // don't care about scheme
                           nsnull, nsnull, // don't care about authority
                           &pathPos, &pathLen);
     if (NS_FAILED(rv)) return rv;
 
     // invoke the parser to extract filepath from the path
     rv = parser->ParsePath(url + pathPos, pathLen,
                            &filepathPos, &filepathLen,
-                           nsnull, nsnull,  // don't care about param
                            nsnull, nsnull,  // don't care about query
                            nsnull, nsnull); // don't care about ref
     if (NS_FAILED(rv)) return rv;
 
     filepathPos += pathPos;
 
     // invoke the parser to extract the directory and filename from filepath
     rv = parser->ParseFilePath(url + filepathPos, filepathLen,
@@ -446,17 +445,16 @@ net_ResolveRelativePath(const nsACString
     PRBool stop = PR_FALSE;
     char c;
     for (; !stop; ++beg) {
         c = (beg == end) ? '\0' : *beg;
         //printf("%c [name=%s] [path=%s]\n", c, name.get(), path.get());
         switch (c) {
           case '\0':
           case '#':
-          case ';':
           case '?':
             stop = PR_TRUE;
             // fall through...
           case '/':
             // delimiter found
             if (name.EqualsLiteral("..")) {
                 // pop path
                 // If we already have the delim at end, then
--- a/netwerk/base/src/nsURLParsers.cpp
+++ b/netwerk/base/src/nsURLParsers.cpp
@@ -112,17 +112,16 @@ nsBaseURLParser::ParseURL(const char *sp
         switch (*p) {
             case ':':
                 if (!colon)
                     colon = p;
                 break;
             case '/': // start of filepath
             case '?': // start of query
             case '#': // start of ref
-            case ';': // start of param
                 if (!slash)
                     slash = p;
                 break;
             case '@': // username@hostname
             case '[': // start of IPv6 address literal
                 if (!stop)
                     stop = p;
                 break;
@@ -235,26 +234,25 @@ nsBaseURLParser::ParseServerInfo(const c
     if (port)
        *port = -1;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBaseURLParser::ParsePath(const char *path, PRInt32 pathLen,
                            PRUint32 *filepathPos, PRInt32 *filepathLen,
-                           PRUint32 *paramPos, PRInt32 *paramLen,
                            PRUint32 *queryPos, PRInt32 *queryLen,
                            PRUint32 *refPos, PRInt32 *refLen)
 {
     NS_PRECONDITION(path, "null pointer");
 
     if (pathLen < 0)
         pathLen = strlen(path);
 
-    // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<ref>
+    // path = [/]<segment1>/<segment2>/<...>/<segmentN>?<query>#<ref>
 
     // XXX PL_strnpbrk would be nice, but it's buggy
 
     // search for first occurrence of either ? or #
     const char *query_beg = 0, *query_end = 0;
     const char *ref_beg = 0;
     const char *p = 0;
     for (p = path; p < path + pathLen; ++p) {
@@ -278,39 +276,23 @@ nsBaseURLParser::ParsePath(const char *p
     else
         SET_RESULT(query, 0, -1);
 
     if (ref_beg)
         SET_RESULT(ref, ref_beg - path, pathLen - (ref_beg - path));
     else
         SET_RESULT(ref, 0, -1);
 
-    // search backwards for param
-    const char *param_beg = 0;
     const char *end;
     if (query_beg)
         end = query_beg - 1;
     else if (ref_beg)
         end = ref_beg - 1;
     else
         end = path + pathLen;
-    for (p = end - 1; p >= path && *p != '/'; --p) {
-        if (*p == ';') {
-            // found param
-            param_beg = p + 1;
-        }
-    }
-
-    if (param_beg) {
-        // found <filepath>;<param>
-        SET_RESULT(param, param_beg - path, end - param_beg);
-        end = param_beg - 1;
-    }
-    else
-        SET_RESULT(param, 0, -1);
 
     // an empty file path is no file path
     if (end != path)
         SET_RESULT(filepath, 0, end - path);
     else
         SET_RESULT(filepath, 0, -1);
     return NS_OK;
 }
@@ -432,17 +414,17 @@ nsNoAuthURLParser::ParseAfterScheme(cons
                     nsCRT::IsAsciiAlpha(spec[2]) &&
                     ((specLen == 4) || (spec[4] == '/') || (spec[4] == '\\'))) {
                     pos = 1;
                     break;  
                 } 
 #endif
                 // Ignore apparent authority; path is everything after it
                 for (p = spec + 2; p < spec + specLen; ++p) {
-                    if (*p == '/' || *p == '?' || *p == '#' || *p == ';')
+                    if (*p == '/' || *p == '?' || *p == '#')
                         break;
                 }
             }
             SET_RESULT(auth, 0, -1);
             if (p && p != spec+specLen)
                 SET_RESULT(path, p - spec, specLen - (p - spec));
             else
                 SET_RESULT(path, 0, -1);
@@ -662,17 +644,17 @@ nsAuthURLParser::ParseAfterScheme(const 
     NS_PRECONDITION(specLen >= 0, "unexpected");
 
     PRUint32 nslash = CountConsecutiveSlashes(spec, specLen);
 
     // search for the end of the authority section
     const char *end = spec + specLen;
     const char *p;
     for (p = spec + nslash; p < end; ++p) {
-        if (*p == '/' || *p == '?' || *p == '#' || *p == ';')
+        if (*p == '/' || *p == '?' || *p == '#')
             break;
     }
     if (p < end) {
         // spec = [/]<auth><path>
         SET_RESULT(auth, nslash, p - (spec + nslash));
         SET_RESULT(path, p - spec, specLen - (p - spec));
     }
     else {
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -139,16 +139,58 @@ HttpChannelChild::AddIPDLReference()
 void
 HttpChannelChild::ReleaseIPDLReference()
 {
   NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
   mIPCOpen = false;
   Release();
 }
 
+class AssociateApplicationCacheEvent : public ChannelEvent
+{
+  public:
+    AssociateApplicationCacheEvent(HttpChannelChild* child,
+                                   const nsCString &groupID,
+                                   const nsCString &clientID)
+    : mChild(child)
+    , groupID(groupID)
+    , clientID(clientID) {}
+
+    void Run() { mChild->AssociateApplicationCache(groupID, clientID); }
+  private:
+    HttpChannelChild* mChild;
+    nsCString groupID;
+    nsCString clientID;
+};
+
+bool
+HttpChannelChild::RecvAssociateApplicationCache(const nsCString &groupID,
+                                                const nsCString &clientID)
+{
+  if (mEventQ.ShouldEnqueue()) {
+    mEventQ.Enqueue(new AssociateApplicationCacheEvent(this, groupID, clientID));
+  } else {
+    AssociateApplicationCache(groupID, clientID);
+  }
+  return true;
+}
+
+void
+HttpChannelChild::AssociateApplicationCache(const nsCString &groupID,
+                                            const nsCString &clientID)
+{
+  nsresult rv;
+  mApplicationCache = do_CreateInstance(NS_APPLICATIONCACHE_CONTRACTID, &rv);
+  if (NS_FAILED(rv))
+    return;
+
+  mLoadedFromApplicationCache = PR_TRUE;
+  mApplicationCache->InitAsHandle(groupID, clientID);
+}
+
 class StartRequestEvent : public ChannelEvent
 {
  public:
   StartRequestEvent(HttpChannelChild* child,
                     const nsHttpResponseHead& responseHead,
                     const PRBool& useResponseHead,
                     const RequestHeaderTuples& requestHeaders,
                     const PRBool& isFromCache,
@@ -187,31 +229,16 @@ class StartRequestEvent : public Channel
   PRPackedBool mCacheEntryAvailable;
   PRUint32 mCacheExpirationTime;
   nsCString mCachedCharset;
   nsCString mSecurityInfoSerialization;
   PRNetAddr mSelfAddr;
   PRNetAddr mPeerAddr;
 };
 
-bool
-HttpChannelChild::RecvAssociateApplicationCache(const nsCString &groupID,
-                                                const nsCString &clientID)
-{
-  nsresult rv;
-  mApplicationCache = do_CreateInstance(
-    NS_APPLICATIONCACHE_CONTRACTID, &rv);
-  if (NS_FAILED(rv))
-    return true;
-
-  mLoadedFromApplicationCache = PR_TRUE;
-  mApplicationCache->InitAsHandle(groupID, clientID);
-  return true;
-}
-
 bool 
 HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
                                      const PRBool& useResponseHead,
                                      const RequestHeaderTuples& requestHeaders,
                                      const PRBool& isFromCache,
                                      const PRBool& cacheEntryAvailable,
                                      const PRUint32& cacheExpirationTime,
                                      const nsCString& cachedCharset,
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -168,16 +168,18 @@ private:
 
   // If ResumeAt is called before AsyncOpen, we need to send extra data upstream
   bool mSendResumeAt;
 
   bool mIPCOpen;
   bool mKeptAlive;
   ChannelEventQueue mEventQ;
 
+  void AssociateApplicationCache(const nsCString &groupID,
+                                 const nsCString &clientID);
   void OnStartRequest(const nsHttpResponseHead& responseHead,
                       const PRBool& useResponseHead,
                       const RequestHeaderTuples& requestHeaders,
                       const PRBool& isFromCache,
                       const PRBool& cacheEntryAvailable,
                       const PRUint32& cacheExpirationTime,
                       const nsCString& cachedCharset,
                       const nsCString& securityInfoSerialization,
@@ -199,16 +201,17 @@ private:
                       const PRUint32& redirectFlags,
                       const nsHttpResponseHead& responseHead);
   void Redirect3Complete();
   void DeleteSelf();
 
   // Called asynchronously from Resume: continues any pending calls into client.
   void CompleteResume();
 
+  friend class AssociateApplicationCacheEvent;
   friend class StartRequestEvent;
   friend class StopRequestEvent;
   friend class TransportAndDataEvent;
   friend class ProgressEvent;
   friend class StatusEvent;
   friend class FailedAsyncOpenEvent;
   friend class Redirect1Event;
   friend class Redirect3Event;
--- a/netwerk/test/TestURLParser.cpp
+++ b/netwerk/test/TestURLParser.cpp
@@ -65,28 +65,26 @@ parse_file_path(nsIURLParser *urlParser,
     PRINT_SUBFIELD(filepath, ext);
 }
 
 static void
 parse_path(nsIURLParser *urlParser, char *path, PRInt32 pathLen)
 {
     PRINT_FIELD(path);
 
-    PRUint32 filePos, paramPos, queryPos, refPos;
-    PRInt32 fileLen, paramLen, queryLen, refLen;
+    PRUint32 filePos, queryPos, refPos;
+    PRInt32 fileLen, queryLen, refLen;
 
     urlParser->ParsePath(path, pathLen,
                          &filePos, &fileLen,
-                         &paramPos, &paramLen,
                          &queryPos, &queryLen,
                          &refPos, &refLen);
 
     if (fileLen != -1)
         parse_file_path(urlParser, path + filePos, fileLen);
-    PRINT_SUBFIELD(path, param);
     PRINT_SUBFIELD(path, query);
     PRINT_SUBFIELD(path, ref);
 }
 
 int
 main(int argc, char **argv)
 {
     if (test_common_init(&argc, &argv) != 0)
--- a/netwerk/test/unit/test_bug429347.js
+++ b/netwerk/test/unit/test_bug429347.js
@@ -9,28 +9,34 @@ function run_test() {
   var uri1 = ios.newURI("http://example.com#bar", null, null);
   var uri2 = ios.newURI("http://example.com/#bar", null, null);
   do_check_true(uri1.equals(uri2));
 
   uri1.spec = "http://example.com?bar";
   uri2.spec = "http://example.com/?bar";
   do_check_true(uri1.equals(uri2));
 
+  // see https://bugzilla.mozilla.org/show_bug.cgi?id=665706
+  // ";" is not parsed as special anymore and thus ends up
+  // in the authority component (see RFC 3986)
   uri1.spec = "http://example.com;bar";
   uri2.spec = "http://example.com/;bar";
-  do_check_true(uri1.equals(uri2));
+  do_check_false(uri1.equals(uri2));
 
   uri1.spec = "http://example.com#";
   uri2.spec = "http://example.com/#";
   do_check_true(uri1.equals(uri2));
 
   uri1.spec = "http://example.com?";
   uri2.spec = "http://example.com/?";
   do_check_true(uri1.equals(uri2));
 
+  // see https://bugzilla.mozilla.org/show_bug.cgi?id=665706
+  // ";" is not parsed as special anymore and thus ends up
+  // in the authority component (see RFC 3986)
   uri1.spec = "http://example.com;";
   uri2.spec = "http://example.com/;";
-  do_check_true(uri1.equals(uri2));
+  do_check_false(uri1.equals(uri2));
 
   uri1.spec = "http://example.com";
   uri2.spec = "http://example.com/";
   do_check_true(uri1.equals(uri2));
 }
--- a/netwerk/test/urltest.cpp
+++ b/netwerk/test/urltest.cpp
@@ -132,18 +132,19 @@ nsresult writeoutto(const char* i_pURL, 
         output += RESULT();
         output += ',';
         rv = tURL->GetFileBaseName(temp);
         output += RESULT();
         output += ',';
         rv = tURL->GetFileExtension(temp);
         output += RESULT();
         output += ',';
-        rv = tURL->GetParam(temp);
-        output += RESULT();
+        // removed with https://bugzilla.mozilla.org/show_bug.cgi?id=665706
+        // rv = tURL->GetParam(temp); 
+        // output += RESULT();
         output += ',';
         rv = tURL->GetQuery(temp);
         output += RESULT();
         output += ',';
         rv = tURL->GetRef(temp);
         output += RESULT();
         output += ',';
         rv = tURL->GetSpec(temp);
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -135,17 +135,17 @@ nsHtml5TreeOperation::~nsHtml5TreeOperat
       break;
     default: // keep the compiler happy
       break;
   }
 }
 
 nsresult
 nsHtml5TreeOperation::AppendTextToTextNode(const PRUnichar* aBuffer,
-                                           PRInt32 aLength,
+                                           PRUint32 aLength,
                                            nsIContent* aTextNode,
                                            nsHtml5TreeOpExecutor* aBuilder)
 {
   NS_PRECONDITION(aTextNode, "Got null text node.");
 
   if (aBuilder->HaveNotified(aTextNode)) {
     // This text node has already been notified on, so it's necessary to
     // notify on the append
@@ -167,17 +167,17 @@ nsHtml5TreeOperation::AppendTextToTextNo
   }
 
   return aTextNode->AppendText(aBuffer, aLength, PR_FALSE);
 }
 
 
 nsresult
 nsHtml5TreeOperation::AppendText(const PRUnichar* aBuffer,
-                                 PRInt32 aLength,
+                                 PRUint32 aLength,
                                  nsIContent* aParent,
                                  nsHtml5TreeOpExecutor* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIContent* lastChild = aParent->GetLastChild();
   if (lastChild && lastChild->IsNodeOfType(nsINode::eTEXT)) {
     nsHtml5OtherDocUpdate update(aParent->GetOwnerDoc(),
                                  aBuilder->GetDocument());
@@ -491,17 +491,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
           !node->HasAttr(kNameSpaceID_None, nsGkAtoms::form)) {
         formControl->SetForm(formElement);
       }
       return rv;
     }
     case eTreeOpAppendText: {
       nsIContent* parent = *mOne.node;
       PRUnichar* buffer = mTwo.unicharPtr;
-      PRInt32 length = mInt;
+      PRUint32 length = mInt;
       return AppendText(buffer, length, parent, aBuilder);
     }
     case eTreeOpAppendIsindexPrompt: {
       nsIContent* parent = *mOne.node;
       nsXPIDLString prompt;
       nsresult rv =
           nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
                                              "IsIndexPromptWithSpace", prompt);
@@ -513,17 +513,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
         // Don't bother appending a zero-length text node.
         return NS_OK;
       }
       return AppendText(prompt.BeginReading(), len, parent, aBuilder);
     }
     case eTreeOpFosterParentText: {
       nsIContent* stackParent = *mOne.node;
       PRUnichar* buffer = mTwo.unicharPtr;
-      PRInt32 length = mInt;
+      PRUint32 length = mInt;
       nsIContent* table = *mThree.node;
       
       nsIContent* foster = table->GetParent();
 
       if (foster && foster->IsElement()) {
         aBuilder->FlushPendingAppendNotifications();
 
         nsHtml5OtherDocUpdate update(foster->GetOwnerDoc(),
--- a/parser/html/nsHtml5TreeOperation.h
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -312,22 +312,22 @@ class nsHtml5TreeOperation {
       nsAutoString str;
       aAtom->ToString(str);
       return do_GetAtom(str);
     }
 
   private:
 
     nsresult AppendTextToTextNode(const PRUnichar* aBuffer,
-                                  PRInt32 aLength,
+                                  PRUint32 aLength,
                                   nsIContent* aTextNode,
                                   nsHtml5TreeOpExecutor* aBuilder);
 
     nsresult AppendText(const PRUnichar* aBuffer,
-                        PRInt32 aLength,
+                        PRUint32 aLength,
                         nsIContent* aParent,
                         nsHtml5TreeOpExecutor* aBuilder);
 
     nsresult Append(nsIContent* aNode,
                     nsIContent* aParent,
                     nsHtml5TreeOpExecutor* aBuilder);
 
     nsresult AppendToDocument(nsIContent* aNode,
--- a/services/sync/modules/engines/history.js
+++ b/services/sync/modules/engines/history.js
@@ -157,16 +157,17 @@ HistoryStore.prototype = {
 
     // Give the uri a GUID if it doesn't have one
     if (create)
       return this.setGUID(uri);
   },
 
   get _visitStm() {
     return this._getStmt(
+      "/* do not warn (bug 599936) */ " +
       "SELECT visit_type type, visit_date date " +
       "FROM moz_historyvisits " +
       "WHERE place_id = (SELECT id FROM moz_places WHERE url = :url) " +
       "ORDER BY date DESC LIMIT 10");
   },
   _visitCols: ["date", "type"],
 
   get _urlStm() {
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -254,17 +254,17 @@ WrapAndReturnHistogram(Histogram *h, JSC
     return NS_ERROR_FAILURE;
   *ret = OBJECT_TO_JSVAL(obj);
   return (JS_SetPrivate(cx, obj, h)
           && JS_DefineFunction (cx, obj, "add", JSHistogram_Add, 1, 0)
           && JS_DefineFunction (cx, obj, "snapshot", JSHistogram_Snapshot, 1, 0)) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 TelemetryImpl::TelemetryImpl():
-mCanRecord(true)
+mCanRecord(XRE_GetProcessType() == GeckoProcessType_Default)
 {
   mHistogramMap.Init(Telemetry::HistogramCount);
 }
 
 TelemetryImpl::~TelemetryImpl() {
   mHistogramMap.Clear();
 }
 
--- a/toolkit/components/telemetry/TelemetryHistograms.h
+++ b/toolkit/components/telemetry/TelemetryHistograms.h
@@ -37,16 +37,19 @@
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * This file lists Telemetry histograms collected by Firefox.  The format is
  *
  *    HISTOGRAM(id, minimum, maximum, bucket count, histogram kind,
  *              human-readable description for about:telemetry)
  *
+ * This file is the master list of telemetry histograms reported to Mozilla servers.
+ * The other data reported by telemetry is listed on https://wiki.mozilla.org/Privacy/Reviews/Telemetry/Measurements
+ *
  */
 
 /**
  * a11y telemetry
  */
 HISTOGRAM(A11Y_INSTANTIATED, 0, 1, 2, BOOLEAN, "has accessibility support been instantiated")
 
 HISTOGRAM(CYCLE_COLLECTOR, 1, 10000, 50, EXPONENTIAL, "Time spent on one cycle collection (ms)")
--- a/widget/src/android/AndroidJavaWrappers.h
+++ b/widget/src/android/AndroidJavaWrappers.h
@@ -158,17 +158,19 @@ public:
     AndroidGeckoSurfaceView(jobject jobj) {
         Init(jobj);
     }
 
     void Init(jobject jobj);
 
     enum {
         DRAW_ERROR = 0,
-        DRAW_GLES_2 = 1
+        DRAW_GLES_2 = 1,
+        DRAW_2D = 2,
+        DRAW_DISABLED = 3
     };
 
     int BeginDrawing();
     jobject GetSoftwareDrawBitmap();
     jobject GetSoftwareDrawBuffer();
     void EndDrawing();
     void Draw2D(jobject bitmap, int width, int height);
     void Draw2D(jobject buffer, int stride);
--- a/widget/src/android/nsFilePicker.cpp
+++ b/widget/src/android/nsFilePicker.cpp
@@ -40,17 +40,20 @@
 #include "nsNetUtil.h"
 #include "nsIURI.h"
 
 NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
 
 NS_IMETHODIMP nsFilePicker::Init(nsIDOMWindow *parent, const nsAString& title, 
                                  PRInt16 mode)
 {
-    return nsIFilePicker::modeOpen == mode ? NS_OK : NS_ERROR_NOT_IMPLEMENTED;
+    return (mode == nsIFilePicker::modeOpen ||
+            mode == nsIFilePicker::modeOpenMultiple)
+        ? NS_OK
+        : NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsFilePicker::AppendFilter(const nsAString& /*title*/,
                                          const nsAString& filter)
 {
     if (!mFilters.IsEmpty())
         mFilters.AppendLiteral(", ");
     mFilters.Append(filter);
--- a/widget/src/android/nsWindow.cpp
+++ b/widget/src/android/nsWindow.cpp
@@ -1045,16 +1045,20 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
                 DrawTo(targetSurface);
             }
 
             sview.Draw2D(bytebuf, mBounds.width * 2);
         }
     } else {
         int drawType = sview.BeginDrawing();
 
+        if (drawType == AndroidGeckoSurfaceView::DRAW_DISABLED) {
+            return;
+        }
+
         if (drawType == AndroidGeckoSurfaceView::DRAW_ERROR) {
             ALOG("##### BeginDrawing failed!");
             return;
         }
 
         if (!sValidSurface) {
             sGLContext->RenewSurface();
             sValidSurface = true;
--- a/xpcom/ds/nsHashtable.cpp
+++ b/xpcom/ds/nsHashtable.cpp
@@ -122,22 +122,18 @@ struct _HashEnumerateArgs {
 };
 
 static PLDHashOperator
 hashEnumerate(PLDHashTable* table, PLDHashEntryHdr* hdr, PRUint32 i, void *arg)
 {
     _HashEnumerateArgs* thunk = (_HashEnumerateArgs*)arg;
     HTEntry* entry = static_cast<HTEntry*>(hdr);
     
-    switch (thunk->fn(entry->key, entry->value, thunk->arg)) {
-      case kHashEnumerateNext:
+    if (thunk->fn(entry->key, entry->value, thunk->arg))
         return PL_DHASH_NEXT;
-      case kHashEnumerateRemove:
-        return PL_DHASH_REMOVE;
-    }
     return PL_DHASH_STOP;           
 }
 
 //
 // HashKey
 //
 
 nsHashKey::~nsHashKey(void)
--- a/xpcom/ds/nsHashtable.h
+++ b/xpcom/ds/nsHashtable.h
@@ -104,21 +104,20 @@ class nsHashKey {
 #endif
 };
 
 // Enumerator and Read/Write callback functions.
 
 // Return values for nsHashtableEnumFunc
 enum {
     kHashEnumerateStop      = PR_FALSE,
-    kHashEnumerateNext      = PR_TRUE,
-    kHashEnumerateRemove    = 2
+    kHashEnumerateNext      = PR_TRUE
 };
 
-typedef PRIntn
+typedef PRBool
 (* nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* aClosure);
 
 typedef nsresult
 (* nsHashtableReadEntryFunc)(nsIObjectInputStream *aStream, nsHashKey **aKey,
                              void **aData);
 
 // NB: may be called with null aKey or aData, to free just one of the two.
 typedef void
@@ -191,35 +190,33 @@ class nsObjectHashtable : public nsHasht
 // nsSupportsHashtable: an nsHashtable where the elements are nsISupports*
 
 class nsISupports;
 
 class nsSupportsHashtable
   : private nsHashtable
 {
   public:
-    typedef PRBool (* EnumFunc) (nsHashKey *aKey, void *aData, void* aClosure);
-
     nsSupportsHashtable(PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE)
       : nsHashtable(aSize, threadSafe) {}
     ~nsSupportsHashtable();
 
     PRInt32 Count(void) {
         return nsHashtable::Count();
     }
     PRBool Exists(nsHashKey *aKey) {
         return nsHashtable::Exists (aKey);
     }
     PRBool Put(nsHashKey *aKey,
                nsISupports *aData,
                nsISupports **value = nsnull);
     nsISupports* Get(nsHashKey *aKey);
     PRBool Remove(nsHashKey *aKey, nsISupports **value = nsnull);
     nsHashtable *Clone();
-    void Enumerate(EnumFunc aEnumFunc, void* aClosure = NULL) {
+    void Enumerate(nsHashtableEnumFunc aEnumFunc, void* aClosure = NULL) {
         nsHashtable::Enumerate(aEnumFunc, aClosure);
     }
     void Reset();
 
   private:
     static PRBool ReleaseElement(nsHashKey *, void *, void *);
     static PLDHashOperator EnumerateCopy(PLDHashTable*,
                                          PLDHashEntryHdr* hdr,
--- a/xpcom/io/nsEscape.cpp
+++ b/xpcom/io/nsEscape.cpp
@@ -348,17 +348,17 @@ nsEscapeHTML2(const PRUnichar *aSourceBu
 //----------------------------------------------------------------------------------------
 
 const int EscapeChars[256] =
 /*      0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F */
 {
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,       /* 0x */
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  	    /* 1x */
         0,1023,   0, 512,1023,   0,1023,   0,1023,1023,1023,1023,1023,1023, 953, 784,       /* 2x   !"#$%&'()*+,-./	 */
-     1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1008, 912,   0,1008,   0, 768,       /* 3x  0123456789:;<=>?	 */
+     1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1008,1008,   0,1008,   0, 768,       /* 3x  0123456789:;<=>?	 */
      1008,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,       /* 4x  @ABCDEFGHIJKLMNO  */
      1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, 896, 896, 896, 896,1023,       /* 5x  PQRSTUVWXYZ[\]^_	 */
         0,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,       /* 6x  `abcdefghijklmno	 */
      1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, 896,1012, 896,1023,   0,       /* 7x  pqrstuvwxyz{|}~	 */
         0    /* 8x  DEL               */
 };
 
 #define NO_NEED_ESC(C) (EscapeChars[((unsigned int) (C))] & (flags))