Merge tips of mozilla-inbound and mozilla-central
authorEd Morley <bmo@edmorley.co.uk>
Sun, 28 Aug 2011 21:20:46 +0100
changeset 77326 ca5a3569462d7b03ba1da27ed161e1d506190912
parent 77313 0ac24f429e24d7f46731e9698d3f889bda63e2cb (current diff)
parent 77325 a12d726a586808a6de30983a9d38e4a69f0de795 (diff)
child 77327 ab1cbc8a9d51a6fe320b62819c2a5bbce95c5cee
child 77480 4c05b2f72ff17b225f8dcc6badc71b31e01b7a2a
child 77580 c37f23b36e54aed1afde621a23efb0dff82d2ff2
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone9.0a1
first release with
nightly linux32
ca5a3569462d / 9.0a1 / 20110829030811 / files
nightly linux64
ca5a3569462d / 9.0a1 / 20110829030811 / files
nightly mac
ca5a3569462d / 9.0a1 / 20110829030811 / files
nightly win32
ca5a3569462d / 9.0a1 / 20110829030811 / files
nightly win64
ca5a3569462d / 9.0a1 / 20110829030811 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge tips of mozilla-inbound and mozilla-central
--- a/accessible/public/nsIAccessible.idl
+++ b/accessible/public/nsIAccessible.idl
@@ -51,17 +51,17 @@ interface nsIAccessibleRelation;
  * accessibility APIs like MSAA and ATK. Contains the sum of what's needed
  * to support IAccessible as well as ATK's generic accessibility objects.
  * Can also be used by in-process accessibility clients to get information
  * about objects in the accessible tree. The accessible tree is a subset of 
  * nodes in the DOM tree -- such as documents, focusable elements and text.
  * Mozilla creates the implementations of nsIAccessible on demand.
  * See http://www.mozilla.org/projects/ui/accessibility for more information.
  */
-[scriptable, uuid(c81d8f8c-8585-4094-bc7c-71dd01494906)]
+[scriptable, uuid(c7ac764a-b4c5-4479-9fb7-06e3c9f3db34)]
 interface nsIAccessible : nsISupports
 {
   /**
    * Parent node in accessible tree.
    */
   readonly attribute nsIAccessible parent;
 
   /**
@@ -243,28 +243,16 @@ interface nsIAccessible : nsISupports
 
   /**
    * Return accessible relation by the given relation type (see.
    * constants defined in nsIAccessibleRelation).
    */
   nsIAccessibleRelation getRelationByType(in unsigned long aRelationType);
 
   /**
-   * Returns the number of accessible relations for this object.
-   */
-  readonly attribute unsigned long relationsCount;
-
-  /**
-   * Returns one accessible relation for this object.
-   *
-   * @param index - relation index (0-based)
-   */
-  nsIAccessibleRelation getRelation(in unsigned long index);
-
-  /**
    * Returns multiple accessible relations for this object.
    */
   nsIArray getRelations();
 
   /**
    * Return accessible's x and y coordinates relative to the screen and
    * accessible's width and height.
    */
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -2185,50 +2185,16 @@ nsAccessible::RelationByType(PRUint32 aT
     case nsIAccessibleRelation::RELATION_POPUP_FOR:
     case nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF:
     default:
     return Relation();
   }
 }
 
 NS_IMETHODIMP
-nsAccessible::GetRelationsCount(PRUint32* aCount)
-{
-  NS_ENSURE_ARG_POINTER(aCount);
-  *aCount = 0;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIArray> relations;
-  nsresult rv = GetRelations(getter_AddRefs(relations));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return relations->GetLength(aCount);
-}
-
-NS_IMETHODIMP
-nsAccessible::GetRelation(PRUint32 aIndex, nsIAccessibleRelation** aRelation)
-{
-  NS_ENSURE_ARG_POINTER(aRelation);
-  *aRelation = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIArray> relations;
-  nsresult rv= GetRelations(getter_AddRefs(relations));
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIAccessibleRelation> relation = do_QueryElementAt(relations,
-                                                               aIndex, &rv);
-  NS_ADDREF(*aRelation = relation);
-  return rv;
-}
-
-NS_IMETHODIMP
 nsAccessible::GetRelations(nsIArray **aRelations)
 {
   NS_ENSURE_ARG_POINTER(aRelations);
   *aRelations = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -1022,33 +1022,9 @@ public:
   // accessibility.tabfocus_applies_to_xul pref - if it is set to true,
   // the tabfocus bit field applies to xul elements.
   static PRBool sTabFocusModelAppliesToXUL;
 
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
 
-// Some cycle-collecting helper macros for nsIContent subclasses
-
-#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER \
-  if (tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {           \
-    nsContentUtils::TraverseListenerManager(tmp, cb);     \
-  }
-
-#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA \
-  if (tmp->HasProperties()) {                      \
-    nsNodeUtils::TraverseUserData(tmp, cb);        \
-  }
-
-#define NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER \
-  if (tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {         \
-    nsContentUtils::RemoveListenerManager(tmp);         \
-    tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);          \
-  }
-
-#define NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA \
-  if (tmp->HasProperties()) {                    \
-    nsNodeUtils::UnlinkUserData(tmp);            \
-  }
-
-
 #endif /* nsIContent_h___ */
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -796,16 +796,19 @@ public:
         mWeakReference(nsnull)
     {
     }
 
     // If needed we could remove the vtable pointer this dtor causes by
     // putting a DestroySlots function on nsINode
     virtual ~nsSlots();
 
+    void Traverse(nsCycleCollectionTraversalCallback &cb);
+    void Unlink();
+
     /**
      * A list of mutation observers
      */
     nsTObserverArray<nsIMutationObserver*> mMutationObservers;
 
     /**
      * An object implementing nsIDOMNodeList for this content (childNodes)
      * @see nsIDOMNodeList
@@ -1337,16 +1340,20 @@ protected:
 #define EVENT(name_, id_, type_, struct_)                         \
   NS_IMETHOD GetOn##name_(JSContext *cx, jsval *vp);              \
   NS_IMETHOD SetOn##name_(JSContext *cx, const jsval &v);
 #define TOUCH_EVENT EVENT
 #include "nsEventNameList.h"
 #undef TOUCH_EVENT
 #undef EVENT  
 
+  static void Trace(nsINode *tmp, TraceCallback cb, void *closure);
+  static bool Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb);
+  static void Unlink(nsINode *tmp);
+
   nsCOMPtr<nsINodeInfo> mNodeInfo;
 
   nsINode* mParent;
 
   PRUint32 mFlags;
 
 private:
   // Boolean flags.
--- a/content/base/public/nsISelectionPrivate.idl
+++ b/content/base/public/nsISelectionPrivate.idl
@@ -148,24 +148,24 @@ interface nsISelectionPrivate : nsISelec
     readonly attribute short type;
 
     /**
      * Return array of ranges intersecting with the given DOM interval.
      */
     void GetRangesForInterval(
         in nsIDOMNode beginNode, in PRInt32 beginOffset,
         in nsIDOMNode endNode, in PRInt32 endOffset,
-        in PRBool allowAdjacent,
+        in boolean allowAdjacent,
         out PRUint32 resultCount,
         [retval, array, size_is(resultCount)] out nsIDOMRange results);
 
     [noscript] void GetRangesForIntervalCOMArray(
         in nsIDOMNode beginNode, in PRInt32 beginOffset,
         in nsIDOMNode endNode, in PRInt32 endOffset,
-        in PRBool allowAdjacent,
+        in boolean allowAdjacent,
         in RangeArray results);
 
     /**
      * Scrolls a region of the selection, so that it is visible in
      * the scrolled view.
      *
      * @param aRegion - the region inside the selection to scroll into view
      *                  (see selection region constants defined in
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -55,17 +55,16 @@
 #include "nsGkAtoms.h"
 #include "nsCOMArray.h"
 #include "nsNodeUtils.h"
 #include "nsEventListenerManager.h"
 #include "nsTextNode.h"
 #include "mozAutoDocUpdate.h"
 #include "nsMutationEvent.h"
 #include "nsPLDOMEvent.h"
-#include "nsContentUtils.h" // NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER
 
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 PRBool nsDOMAttribute::sInitialized;
 
 nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
                                already_AddRefed<nsINodeInfo> aNodeInfo,
@@ -100,35 +99,35 @@ nsDOMAttribute::~nsDOMAttribute()
     content->RemoveMutationObserver(this);
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttribute)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttribute)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
+
+  if (!nsINode::Traverse(tmp, cb)) {
+    return NS_SUCCESS_INTERRUPTED_TRAVERSE;
+  }
+
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mChild)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMAttribute)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+  nsINode::Trace(tmp, aCallback, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttribute)
+  nsINode::Unlink(tmp);
   if (tmp->mChild) {
     static_cast<nsTextNode*>(tmp->mChild)->UnbindFromAttribute();
     NS_RELEASE(tmp->mChild);
     tmp->mFirstChild = nsnull;
   }
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_NODE_DATA(Attr, nsDOMAttribute)
 
 // QueryInterface implementation for nsDOMAttribute
 NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_NODE_INTERFACE_TABLE5(nsDOMAttribute, nsIDOMAttr, nsIAttribute, nsIDOMNode,
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1820,34 +1820,30 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   else {
     NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsDocument, tmp->mRefCnt.get())
   }
 
   // Always need to traverse script objects, so do that before we check
   // if we're uncollectable.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 
-  if (nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration())) {
+  if (!nsINode::Traverse(tmp, cb)) {
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
 
   tmp->mIdentifierMap.EnumerateEntries(IdentifierMapEntryTraverse, &cb);
 
   tmp->mExternalResourceMap.Traverse(&cb);
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
-
   // Traverse the mChildren nsAttrAndChildArray.
   for (PRInt32 indx = PRInt32(tmp->mChildren.ChildCount()); indx > 0; --indx) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildren[i]");
     cb.NoteXPCOMChild(tmp->mChildren.ChildAt(indx - 1));
   }
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA
-
   // Traverse all nsIDocument pointer members.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCachedRootElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSecurityInfo)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDisplayDocument)
 
   // Traverse all nsDocument nsCOMPtrs.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParser)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptGlobalObject)
@@ -1896,28 +1892,30 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 
   if (tmp->mSubDocuments && tmp->mSubDocuments->ops) {
     PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDocument)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+  nsINode::Trace(tmp, aCallback, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
   tmp->mInUnlinkOrDeletion = PR_TRUE;
 
   // Clear out our external resources
   tmp->mExternalResourceMap.Shutdown();
 
   nsAutoScriptBlocker scriptBlocker;
 
+  nsINode::Unlink(tmp);
+
   // Unlink the mChildren nsAttrAndChildArray.
   for (PRInt32 indx = PRInt32(tmp->mChildren.ChildCount()) - 1; 
        indx >= 0; --indx) {
     tmp->mChildren.ChildAt(indx)->UnbindFromTree();
     tmp->mChildren.RemoveChildAt(indx);
   }
   tmp->mFirstChild = nsnull;
 
@@ -1925,19 +1923,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCachedRootElement)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDisplayDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstBaseNodeWithHref)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDOMImplementation)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mImageMaps)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOriginalDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCachedEncoder)
 
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
-
   tmp->mParentDocument = nsnull;
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPreloadingImages)
 
   
   if (tmp->mBoxObjectTable) {
    tmp->mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull);
    delete tmp->mBoxObjectTable;
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -88,46 +88,36 @@ nsGenericDOMDataNode::~nsGenericDOMDataN
   if (GetParent()) {
     NS_RELEASE(mParent);
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericDOMDataNode)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericDOMDataNode)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+  nsINode::Trace(tmp, aCallback, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericDOMDataNode)
   // Always need to traverse script objects, so do that before we check
   // if we're uncollectable.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 
-  nsIDocument* currentDoc = tmp->GetCurrentDoc();
-  if (currentDoc && nsCCUncollectableMarker::InGeneration(
-                      cb, currentDoc->GetMarkedCCGeneration())) {
+  if (!nsINode::Traverse(tmp, cb)) {
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
-
   nsIDocument* ownerDoc = tmp->GetOwnerDoc();
   if (ownerDoc) {
     ownerDoc->BindingManager()->Traverse(tmp, cb);
   }
-
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent())
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
+  nsINode::Unlink(tmp);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataNode)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericDOMDataNode)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -169,16 +169,32 @@ nsINode::nsSlots::~nsSlots()
     NS_RELEASE(mChildNodes);
   }
 
   if (mWeakReference) {
     mWeakReference->NoticeNodeDestruction();
   }
 }
 
+void
+nsINode::nsSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
+{
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildNodes");
+  cb.NoteXPCOMChild(mChildNodes);
+}
+
+void
+nsINode::nsSlots::Unlink()
+{
+  if (mChildNodes) {
+    mChildNodes->DropReference();
+    NS_RELEASE(mChildNodes);
+  }
+}
+
 //----------------------------------------------------------------------
 
 nsINode::~nsINode()
 {
   NS_ASSERTION(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
 }
 
 void*
@@ -1137,16 +1153,73 @@ nsINode::GetListenerManager(PRBool aCrea
 }
 
 nsIScriptContext*
 nsINode::GetContextForEventHandlers(nsresult* aRv)
 {
   return nsContentUtils::GetContextForEventHandlers(this, aRv);
 }
 
+/* static */
+void
+nsINode::Trace(nsINode *tmp, TraceCallback cb, void *closure)
+{
+  nsContentUtils::TraceWrapper(tmp, cb, closure);
+}
+
+/* static */
+bool
+nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
+{
+  nsIDocument *currentDoc = tmp->GetCurrentDoc();
+  if (currentDoc &&
+      nsCCUncollectableMarker::InGeneration(cb, currentDoc->GetMarkedCCGeneration())) {
+    return false;
+  }
+
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent())
+
+  nsSlots *slots = tmp->GetExistingSlots();
+  if (slots) {
+    slots->Traverse(cb);
+  }
+
+  if (tmp->HasProperties()) {
+    nsNodeUtils::TraverseUserData(tmp, cb);
+  }
+
+  if (tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {
+    nsContentUtils::TraverseListenerManager(tmp, cb);
+  }
+
+  return true;
+}
+
+/* static */
+void
+nsINode::Unlink(nsINode *tmp)
+{
+  nsContentUtils::ReleaseWrapper(tmp, tmp);
+
+  nsSlots *slots = tmp->GetExistingSlots();
+  if (slots) {
+    slots->Unlink();
+  }
+
+  if (tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {
+    nsContentUtils::RemoveListenerManager(tmp);
+    tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);
+  }
+
+  if (tmp->HasProperties()) {
+    nsNodeUtils::UnlinkUserData(tmp);
+  }
+}
+
 //----------------------------------------------------------------------
 
 nsEventStates
 Element::IntrinsicState() const
 {
   return IsEditable() ? NS_EVENT_STATE_MOZ_READWRITE :
                         NS_EVENT_STATE_MOZ_READONLY;
 }
@@ -2187,16 +2260,55 @@ nsGenericElement::nsDOMSlots::~nsDOMSlot
     mAttributeMap->DropReference();
   }
 
   if (mClassList) {
     mClassList->DropReference();
   }
 }
 
+void
+nsGenericElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL)
+{
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
+  cb.NoteXPCOMChild(mStyle.get());
+
+#ifdef MOZ_SMIL
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mSMILOverrideStyle");
+  cb.NoteXPCOMChild(mSMILOverrideStyle.get());
+#endif // MOZ_SMIL
+
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
+  cb.NoteXPCOMChild(mAttributeMap.get());
+
+  if (aIsXUL) {
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mControllers");
+    cb.NoteXPCOMChild(mControllers);
+  }
+
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
+  cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
+}
+
+void
+nsGenericElement::nsDOMSlots::Unlink(bool aIsXUL)
+{
+  mStyle = nsnull;
+#ifdef MOZ_SMIL
+  mSMILOverrideStyle = nsnull;
+#endif // MOZ_SMIL
+  if (mAttributeMap) {
+    mAttributeMap->DropReference();
+    mAttributeMap = nsnull;
+  }
+  if (aIsXUL)
+    NS_IF_RELEASE(mControllers);
+  mChildrenList = nsnull;
+}
+
 nsGenericElement::nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : Element(aNodeInfo)
 {
   NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE ||
                     (mNodeInfo->NodeType() ==
                        nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
                      mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
                                        kNameSpaceID_None)),
@@ -4105,19 +4217,17 @@ nsINode::IsSameNode(nsIDOMNode* aOther, 
 
 //----------------------------------------------------------------------
 
 // nsISupports implementation
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericElement)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
+  nsINode::Unlink(tmp);
 
   if (tmp->HasProperties() && tmp->IsXUL()) {
     tmp->DeleteProperty(nsGkAtoms::contextmenulistener);
     tmp->DeleteProperty(nsGkAtoms::popuplistener);
   }
 
   // Unlink child content (and unbind our subtree).
   {
@@ -4135,40 +4245,30 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
       tmp->mFirstChild = nsnull;
     }
   }  
 
   // Unlink any DOM slots of interest.
   {
     nsDOMSlots *slots = tmp->GetExistingDOMSlots();
     if (slots) {
-      slots->mStyle = nsnull;
-#ifdef MOZ_SMIL
-      slots->mSMILOverrideStyle = nsnull;
-#endif // MOZ_SMIL
-      if (slots->mAttributeMap) {
-        slots->mAttributeMap->DropReference();
-        slots->mAttributeMap = nsnull;
-      }
-      if (tmp->IsXUL())
-        NS_IF_RELEASE(slots->mControllers);
-      slots->mChildrenList = nsnull;
+      slots->Unlink(tmp->IsXUL());
     }
   }
 
   {
     nsIDocument *doc;
     if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc())) {
       doc->BindingManager()->RemovedFromDocument(tmp, doc);
     }
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericElement)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+  nsINode::Trace(tmp, aCallback, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 static const char* kNSURIs[] = {
   " ([none])",
   " (xmlns)",
   " (xml)",
   " (xhtml)",
   " (XLink)",
@@ -4199,30 +4299,25 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   else {
     NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericElement, tmp->mRefCnt.get())
   }
 
   // Always need to traverse script objects, so do that before we check
   // if we're uncollectable.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 
-  nsIDocument* currentDoc = tmp->GetCurrentDoc();
-  if (currentDoc && nsCCUncollectableMarker::InGeneration(
-                      cb, currentDoc->GetMarkedCCGeneration())) {
+  if (!nsINode::Traverse(tmp, cb)) {
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
 
   nsIDocument* ownerDoc = tmp->GetOwnerDoc();
   if (ownerDoc) {
     ownerDoc->BindingManager()->Traverse(tmp, cb);
   }
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA
-
   if (tmp->HasProperties() && tmp->IsXUL()) {
     nsISupports* property =
       static_cast<nsISupports*>
                  (tmp->GetProperty(nsGkAtoms::contextmenulistener));
     cb.NoteXPCOMChild(property);
     property = static_cast<nsISupports*>
                           (tmp->GetProperty(nsGkAtoms::popuplistener));
     cb.NoteXPCOMChild(property);
@@ -4243,41 +4338,23 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 
     PRUint32 kids = tmp->mAttrsAndChildren.ChildCount();
     for (i = 0; i < kids; i++) {
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAttrsAndChildren[i]");
       cb.NoteXPCOMChild(tmp->mAttrsAndChildren.GetSafeChildAt(i));
     }
   }
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
-
   // Traverse any DOM slots of interest.
   {
     nsDOMSlots *slots = tmp->GetExistingDOMSlots();
     if (slots) {
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mStyle");
-      cb.NoteXPCOMChild(slots->mStyle.get());
-
-#ifdef MOZ_SMIL
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mSMILOverrideStyle");
-      cb.NoteXPCOMChild(slots->mSMILOverrideStyle.get());
-#endif // MOZ_SMIL
-
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mAttributeMap");
-      cb.NoteXPCOMChild(slots->mAttributeMap.get());
-
-      if (tmp->IsXUL())
-        cb.NoteXPCOMChild(slots->mControllers);
-      cb.NoteXPCOMChild(
-        static_cast<nsIDOMNodeList*>(slots->mChildrenList.get()));
+      slots->Traverse(cb, tmp->IsXUL());
     }
-    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent())
-  }
-  
+  }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 NS_INTERFACE_MAP_BEGIN(nsGenericElement)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericElement)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -821,16 +821,19 @@ public:
    * accessed through the DOM.
    */
   class nsDOMSlots : public nsINode::nsSlots
   {
   public:
     nsDOMSlots();
     virtual ~nsDOMSlots();
 
+    void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
+    void Unlink(bool aIsXUL);
+
     /**
      * The .style attribute (an interface that forwards to the actual
      * style rules)
      * @see nsGenericHTMLElement::GetStyle
      */
     nsCOMPtr<nsICSSDeclaration> mStyle;
 
     /**
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1520,20 +1520,23 @@ nsObjectLoadingContent::RemovedFromDocum
     mFrameLoader = nsnull;
 
     // Clear the current URI, so that LoadObject doesn't think that we
     // have already loaded the content.
     mURI = nsnull;
   }
 }
 
+/* static */
 void
-nsObjectLoadingContent::Traverse(nsCycleCollectionTraversalCallback &cb)
+nsObjectLoadingContent::Traverse(nsObjectLoadingContent *tmp,
+                                 nsCycleCollectionTraversalCallback &cb)
 {
-  cb.NoteXPCOMChild(static_cast<nsIFrameLoader*>(mFrameLoader));
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameLoader");
+  cb.NoteXPCOMChild(static_cast<nsIFrameLoader*>(tmp->mFrameLoader));
 }
 
 // <private>
 /* static */ PRBool
 nsObjectLoadingContent::IsSuccessfulRequest(nsIRequest* aRequest)
 {
   nsresult status;
   nsresult rv = aRequest->GetStatus(&status);
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -217,17 +217,18 @@ class nsObjectLoadingContent : public ns
     /**
      * Subclasses must call this function when they are removed from the
      * document.
      *
      * XXX This is a temporary workaround for docshell suckyness
      */
     void RemovedFromDocument();
 
-    void Traverse(nsCycleCollectionTraversalCallback &cb);
+    static void Traverse(nsObjectLoadingContent *tmp,
+                         nsCycleCollectionTraversalCallback &cb);
 
     void CreateStaticClone(nsObjectLoadingContent* aDest) const;
   private:
     /**
      * Check whether the given request represents a successful load.
      */
     static PRBool IsSuccessfulRequest(nsIRequest* aRequest);
 
new file mode 100644
--- /dev/null
+++ b/content/html/content/crashtests/682460.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+<script>
+
+function boom()
+{
+  var f = function() {
+    document.documentElement.offsetHeight;
+  };
+  window.addEventListener("DOMSubtreeModified", f, true);
+
+  document.getElementsByTagName("table")[0].setAttribute("cellpadding", "2");
+}
+
+</script>
+</head>
+
+<body onload="boom();">
+<table><tr><td></td></tr></table>
+</body>
+</html>
--- a/content/html/content/crashtests/crashtests.list
+++ b/content/html/content/crashtests/crashtests.list
@@ -24,8 +24,9 @@ load 604807.html
 load 605264.html
 load 606430-1.html
 load 602117.html
 load 613027.html
 load 614279.html
 load 614988-1.html
 load 620078-1.html
 load 620078-2.html
+load 682460.html
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -191,17 +191,17 @@ nsHTMLObjectElement::DoneAddingChildren(
     StartObjectLoad(aHaveNotified);
   }
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLObjectElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLObjectElement,
                                                   nsGenericHTMLFormElement)
-  tmp->Traverse(cb);
+  nsObjectLoadingContent::Traverse(tmp, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLObjectElement, nsGenericElement) 
 NS_IMPL_RELEASE_INHERITED(nsHTMLObjectElement, nsGenericElement) 
 
 DOMCI_NODE_DATA(HTMLObjectElement, nsHTMLObjectElement)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLObjectElement)
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -211,17 +211,17 @@ nsHTMLSharedObjectElement::DoneAddingChi
   }
 
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLSharedObjectElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLSharedObjectElement,
                                                   nsGenericHTMLElement)
-  tmp->Traverse(cb);
+  nsObjectLoadingContent::Traverse(tmp, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLSharedObjectElement, nsGenericElement) 
 NS_IMPL_RELEASE_INHERITED(nsHTMLSharedObjectElement, nsGenericElement) 
 
 DOMCI_DATA(HTMLAppletElement, nsHTMLSharedObjectElement)
 DOMCI_DATA(HTMLEmbedElement, nsHTMLSharedObjectElement)
 
--- a/content/html/content/src/nsHTMLTableCellElement.cpp
+++ b/content/html/content/src/nsHTMLTableCellElement.cpp
@@ -201,17 +201,17 @@ nsHTMLTableCellElement::GetCellIndex(PRI
 
 NS_IMETHODIMP
 nsHTMLTableCellElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
 {
   nsresult rv = nsGenericHTMLElement::WalkContentStyleRules(aRuleWalker);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIContent* node = GetTable();
-  if (node && node->IsHTML() && node->NodeInfo()->Equals(nsGkAtoms::table)) {
+  if (node && node->IsHTML(nsGkAtoms::table)) {
     nsHTMLTableElement* table = static_cast<nsHTMLTableElement*>(node);
     nsMappedAttributes* tableInheritedAttributes =
       table->GetAttributesMappedForCell();
     if (tableInheritedAttributes)
       aRuleWalker->Forward(tableInheritedAttributes);
   }
   return NS_OK;
 }
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -1271,37 +1271,30 @@ nsHTMLTableElement::BindToTree(nsIDocume
 void
 nsHTMLTableElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
 {
   ReleaseInheritedAttributes();
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 nsresult
-nsHTMLTableElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
-                            nsIAtom* aPrefix, const nsAString& aValue,
-                            PRBool aNotify)
+nsHTMLTableElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                                  const nsAString* aValue,
+                                  PRBool aNotify)
 {
-  PRBool isCellPadding = (aAttribute == nsGkAtoms::cellpadding);
-  if (isCellPadding) {
+  if (aName == nsGkAtoms::cellpadding && aNameSpaceID == kNameSpaceID_None) {
     ReleaseInheritedAttributes();
   }
-
-  nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aAttribute,
-                                              aPrefix, aValue, aNotify);
-
-  if (isCellPadding) {
-    BuildInheritedAttributes();
-  }
-  return rv;
+  return nsGenericHTMLElement::BeforeSetAttr(aNameSpaceID, aName, aValue,
+                                             aNotify);
 }
 
 nsresult
-nsHTMLTableElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
-                               PRBool aNotify)
+nsHTMLTableElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                                 const nsAString* aValue,
+                                 PRBool aNotify)
 {
-  PRBool isCellPadding = (aAttribute == nsGkAtoms::cellpadding);
-  if (isCellPadding) {
-    ReleaseInheritedAttributes();
+  if (aName == nsGkAtoms::cellpadding && aNameSpaceID == kNameSpaceID_None) {
+    BuildInheritedAttributes();
   }
-
-  return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
+  return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
+                                            aNotify);
 }
--- a/content/html/content/src/nsHTMLTableElement.h
+++ b/content/html/content/src/nsHTMLTableElement.h
@@ -1,116 +1,120 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#include "nsIDOMHTMLTableElement.h"
-#include "nsGenericHTMLElement.h"
-#include "nsMappedAttributes.h"
-
-#define TABLE_ATTRS_DIRTY ((nsMappedAttributes*)0x1)
-
-
-class TableRowsCollection;
-
-class nsHTMLTableElement :  public nsGenericHTMLElement,
-                            public nsIDOMHTMLTableElement
-{
-public:
-  nsHTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsHTMLTableElement();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
-
-  // nsIDOMHTMLTableElement
-  NS_DECL_NSIDOMHTMLTABLEELEMENT
-
-  virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
-                                nsIAtom* aAttribute,
-                                const nsAString& aValue,
-                                nsAttrValue& aResult);
-  virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
-  NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              PRBool aCompileEventHandlers);
-  virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
-                              PRBool aNullParent = PR_TRUE);
-  virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
-                           nsIAtom *aPrefix, const nsAString &aValue,
-                           PRBool aNotify);
-  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
-                             PRBool aNotify);
-
-
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLTableElement,
-                                                     nsGenericHTMLElement)
-  nsMappedAttributes* GetAttributesMappedForCell();
-  already_AddRefed<nsIDOMHTMLTableSectionElement> GetTHead() {
-    return GetSection(nsGkAtoms::thead);
-  }
-  already_AddRefed<nsIDOMHTMLTableSectionElement> GetTFoot() {
-    return GetSection(nsGkAtoms::tfoot);
-  }
-  nsContentList* TBodies();
-protected:
-  already_AddRefed<nsIDOMHTMLTableSectionElement> GetSection(nsIAtom *aTag);
-
-  nsRefPtr<nsContentList> mTBodies;
-  nsRefPtr<TableRowsCollection> mRows;
-  // Sentinel value of TABLE_ATTRS_DIRTY indicates that this is dirty and needs
-  // to be recalculated.
-  nsMappedAttributes *mTableInheritedAttributes;
-  void BuildInheritedAttributes();
-  void ReleaseInheritedAttributes() {
-    if (mTableInheritedAttributes &&
-        mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
-      NS_RELEASE(mTableInheritedAttributes);
-      mTableInheritedAttributes = TABLE_ATTRS_DIRTY;
-  }
-};
-
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "nsIDOMHTMLTableElement.h"
+#include "nsGenericHTMLElement.h"
+#include "nsMappedAttributes.h"
+
+#define TABLE_ATTRS_DIRTY ((nsMappedAttributes*)0x1)
+
+
+class TableRowsCollection;
+
+class nsHTMLTableElement :  public nsGenericHTMLElement,
+                            public nsIDOMHTMLTableElement
+{
+public:
+  nsHTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~nsHTMLTableElement();
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+
+  // nsIDOMElement
+  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLElement
+  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLTableElement
+  NS_DECL_NSIDOMHTMLTABLEELEMENT
+
+  virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
+                                nsIAtom* aAttribute,
+                                const nsAString& aValue,
+                                nsAttrValue& aResult);
+  virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
+  NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+  virtual nsXPCClassInfo* GetClassInfo();
+  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                              nsIContent* aBindingParent,
+                              PRBool aCompileEventHandlers);
+  virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
+                              PRBool aNullParent = PR_TRUE);
+  /**
+   * Called when an attribute is about to be changed
+   */
+  virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                                 const nsAString* aValue, PRBool aNotify);
+  /**
+   * Called when an attribute has just been changed
+   */
+  virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                                const nsAString* aValue, PRBool aNotify);
+
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLTableElement,
+                                                     nsGenericHTMLElement)
+  nsMappedAttributes* GetAttributesMappedForCell();
+  already_AddRefed<nsIDOMHTMLTableSectionElement> GetTHead() {
+    return GetSection(nsGkAtoms::thead);
+  }
+  already_AddRefed<nsIDOMHTMLTableSectionElement> GetTFoot() {
+    return GetSection(nsGkAtoms::tfoot);
+  }
+  nsContentList* TBodies();
+protected:
+  already_AddRefed<nsIDOMHTMLTableSectionElement> GetSection(nsIAtom *aTag);
+
+  nsRefPtr<nsContentList> mTBodies;
+  nsRefPtr<TableRowsCollection> mRows;
+  // Sentinel value of TABLE_ATTRS_DIRTY indicates that this is dirty and needs
+  // to be recalculated.
+  nsMappedAttributes *mTableInheritedAttributes;
+  void BuildInheritedAttributes();
+  void ReleaseInheritedAttributes() {
+    if (mTableInheritedAttributes &&
+        mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
+      NS_RELEASE(mTableInheritedAttributes);
+      mTableInheritedAttributes = TABLE_ATTRS_DIRTY;
+  }
+};
+
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -248,16 +248,23 @@ nsXULElement::nsXULSlots::nsXULSlots()
 nsXULElement::nsXULSlots::~nsXULSlots()
 {
     NS_IF_RELEASE(mControllers); // Forces release
     if (mFrameLoader) {
         mFrameLoader->Destroy();
     }
 }
 
+void
+nsXULElement::nsXULSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
+{
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mFrameLoader");
+    cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIFrameLoader*, mFrameLoader));
+}
+
 nsINode::nsSlots*
 nsXULElement::CreateSlots()
 {
     return new nsXULSlots();
 }
 
 /* static */
 already_AddRefed<nsXULElement>
@@ -367,20 +374,17 @@ NS_TrustedNewXULElement(nsIContent** aRe
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULElement,
                                                   nsStyledElement)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mPrototype,
                                                     nsXULPrototypeElement)
     {
         nsXULSlots* slots = static_cast<nsXULSlots*>(tmp->GetExistingSlots());
         if (slots) {
-            NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameLoader");
-            nsISupports *frameLoader =
-                static_cast<nsIFrameLoader*>(slots->mFrameLoader);
-            cb.NoteXPCOMChild(frameLoader);
+            slots->Traverse(cb);
         }
     }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsXULElement, nsStyledElement)
 NS_IMPL_RELEASE_INHERITED(nsXULElement, nsStyledElement)
 
 DOMCI_NODE_DATA(XULElement, nsXULElement)
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -588,20 +588,22 @@ protected:
     // Helper routine that crawls a parent chain looking for a tree element.
     NS_IMETHOD GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement);
 
     nsresult AddPopupListener(nsIAtom* aName);
 
     class nsXULSlots : public nsGenericElement::nsDOMSlots
     {
     public:
-       nsXULSlots();
-       virtual ~nsXULSlots();
+        nsXULSlots();
+        virtual ~nsXULSlots();
 
-       nsRefPtr<nsFrameLoader> mFrameLoader;
+        void Traverse(nsCycleCollectionTraversalCallback &cb);
+
+        nsRefPtr<nsFrameLoader> mFrameLoader;
     };
 
     virtual nsINode::nsSlots* CreateSlots();
 
     nsresult LoadSrc();
 
     // Required fields
     nsRefPtr<nsXULPrototypeElement>     mPrototype;
--- a/js/src/ctypes/libffi/src/arm/sysv.S
+++ b/js/src/ctypes/libffi/src/arm/sysv.S
@@ -224,16 +224,20 @@ ARM_FUNC_START ffi_call_SYSV
 LSYM(Lepilogue):
 	RETLDM	"r0-r3,fp"
 
 .ffi_call_SYSV_end:
 	UNWIND .fnend
         .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
 
 
+/* Below are VFP hard-float ABI call and closure implementations.
+   Add VFP FPU directive here. */
+	.fpu	vfp
+
 	@ r0:   fn
 	@ r1:   &ecif
 	@ r2:   cif->bytes
 	@ r3:   fig->flags
 	@ sp+0: ecif.rvalue
 
 ARM_FUNC_START ffi_call_VFP
 	@ Save registers
--- a/layout/base/tests/bug613433-1.html
+++ b/layout/base/tests/bug613433-1.html
@@ -7,18 +7,18 @@
         overflow-x: auto;
       }
     </style>
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <script>
       function test() {
         document.querySelector("div").focus();
         // type a character, then press backspace to delete it
-        sendKey("X", window);
-        sendKey("BACK_SPACE", window);
+        sendKey("X", "div1");
+        sendKey("BACK_SPACE", "div1");
         document.documentElement.removeAttribute("class");
       }
     </script>
   </head>
   <body onload="test()">
-    <div contenteditable></div>
+    <div id="div1" contenteditable></div>
   </body>
 </html>
--- a/layout/base/tests/bug613433-2.html
+++ b/layout/base/tests/bug613433-2.html
@@ -7,18 +7,18 @@
         overflow-y: auto;
       }
     </style>
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <script>
       function test() {
         document.querySelector("div").focus();
         // type a character, then press backspace to delete it
-        sendKey("X", window);
-        sendKey("BACK_SPACE", window);
+        sendKey("X", "div1");
+        sendKey("BACK_SPACE", "div1");
         document.documentElement.removeAttribute("class");
       }
     </script>
   </head>
   <body onload="test()">
-    <div contenteditable></div>
+    <div id="div1" contenteditable></div>
   </body>
 </html>
--- a/layout/base/tests/bug613433-3.html
+++ b/layout/base/tests/bug613433-3.html
@@ -7,18 +7,18 @@
         overflow: auto;
       }
     </style>
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <script>
       function test() {
         document.querySelector("div").focus();
         // type a character, then press backspace to delete it
-        sendKey("X", window);
-        sendKey("BACK_SPACE", window);
+        sendKey("X", "div1");
+        sendKey("BACK_SPACE", "div1");
         document.documentElement.removeAttribute("class");
       }
     </script>
   </head>
   <body onload="test()">
-    <div contenteditable></div>
+    <div id="div1" contenteditable></div>
   </body>
 </html>
--- a/layout/base/tests/test_reftests_with_caret.html
+++ b/layout/base/tests/test_reftests_with_caret.html
@@ -89,56 +89,63 @@ function endTest() {
                         .getService(Components.interfaces.nsIPrefBranch);
   if (caretBlinkTime !== null) {
     prefs.setIntPref("ui.caretBlinkTime", caretBlinkTime);
   } else {
     prefs.clearUserPref("ui.caretBlinkTime");
   }
 }
 
+var isWindows = /WINNT/.test(SpecialPowers.OS);
+
 var tests = [
     [ 'bug106855-1.html' , 'bug106855-1-ref.html' ] ,
-    [ 'bug106855-2.html' , 'bug106855-1-ref.html' ] ,
-    [ 'bug240933-1.html' , 'bug240933-1-ref.html' ] ,
-    [ 'bug240933-2.html' , 'bug240933-1-ref.html' ] ,
     [ 'bug389321-1.html' , 'bug389321-1-ref.html' ] ,
     [ 'bug389321-2.html' , 'bug389321-2-ref.html' ] ,
     [ 'bug389321-3.html' , 'bug389321-3-ref.html' ] ,
     [ 'bug482484.html'   , 'bug482484-ref.html'   ] ,
-    [ 'bug512295-1.html' , 'bug512295-1-ref.html' ] ,
-    [ 'bug512295-2.html' , 'bug512295-2-ref.html' ] ,
     [ 'bug585922.html'   , 'bug585922-ref.html'   ] ,
-    [ 'bug597519-1.html' , 'bug597519-1-ref.html' ] ,
-    [ 'bug602141-1.html' , 'bug602141-1-ref.html' ] ,
     [ 'bug602141-2.html' , 'bug602141-2-ref.html' ] ,
     [ 'bug602141-3.html' , 'bug602141-3-ref.html' ] ,
-    [ 'bug602141-4.html' , 'bug602141-4-ref.html' ] ,
-    [ 'bug612271-1.html' , 'bug612271-ref.html' ] ,
-    [ 'bug612271-2.html' , 'bug612271-ref.html' ] ,
-    [ 'bug612271-3.html' , 'bug612271-ref.html' ] ,
-    [ 'bug613433-1.html' , 'bug613433-ref.html' ] ,
     [ 'bug613433-2.html' , 'bug613433-ref.html' ] ,
     [ 'bug613433-3.html' , 'bug613433-ref.html' ] ,
-//    [ 'bug613807-1.html' , 'bug613807-1-ref.html' ] ,  // see bug 680574
     [ 'bug632215-1.html' , 'bug632215-ref.html'   ] ,
     [ 'bug632215-2.html' , 'bug632215-ref.html'   ] ,
     [ 'bug633044-1.html' , 'bug633044-1-ref.html' ] ,
-    [ 'bug634406-1.html' , 'bug634406-1-ref.html' ] ,
     [ 'bug644428-1.html' , 'bug644428-1-ref.html' ] ,
-    function() {
-      SpecialPowers.setBoolPref("bidi.browser.ui", true);
-    },
-    [ 'bug646382-1.html' , 'bug646382-1-ref.html' ] ,
-//    [ 'bug646382-2.html' , 'bug646382-2-ref.html' ] ,  // see bug 680577
-    [ 'bug664087-1.html' , 'bug664087-1-ref.html' ] ,
-//    [ 'bug664087-2.html' , 'bug664087-2-ref.html' ] ,  // see bug 680578
-    function() {
-      SpecialPowers.clearUserPref("bidi.browser.ui");
-    },
 ];
+
+if (!isWindows) {
+  tests.push([ 'bug106855-2.html' , 'bug106855-1-ref.html' ]); // bug 681138
+  tests.push([ 'bug240933-1.html' , 'bug240933-1-ref.html' ]); // bug 681144
+  tests.push([ 'bug240933-2.html' , 'bug240933-1-ref.html' ]); // bug 681162
+  tests.push([ 'bug512295-1.html' , 'bug512295-1-ref.html' ]); // bug 681152
+  tests.push([ 'bug512295-2.html' , 'bug512295-2-ref.html' ]); // bug 681331
+  tests.push([ 'bug597519-1.html' , 'bug597519-1-ref.html' ]); // bug 680579
+  tests.push([ 'bug602141-1.html' , 'bug602141-1-ref.html' ]); // bug 681334
+  tests.push([ 'bug602141-4.html' , 'bug602141-4-ref.html' ]); // bug 681167
+  tests.push([ 'bug612271-1.html' , 'bug612271-ref.html' ]);   // bug 681032
+  tests.push([ 'bug612271-2.html' , 'bug612271-ref.html' ]);   // bug 680581
+  tests.push([ 'bug612271-3.html' , 'bug612271-ref.html' ]);   // bug 681035
+  tests.push([ 'bug613433-1.html' , 'bug613433-ref.html' ]);   // bug 681332
+  tests.push([ 'bug613807-1.html' , 'bug613807-1-ref.html' ]); // bug 680574
+  tests.push([ 'bug634406-1.html' , 'bug634406-1-ref.html' ]); // bug 681146
+}
+
+tests.push(function() {SpecialPowers.setBoolPref("bidi.browser.ui", true);});
+
+if (!isWindows) {
+  tests.push([ 'bug646382-1.html' , 'bug646382-1-ref.html' ]);  // bug 681076
+  tests.push([ 'bug646382-2.html' , 'bug646382-2-ref.html' ]);  // bug 680577
+  tests.push([ 'bug664087-1.html' , 'bug664087-1-ref.html' ]);  // bug 681038
+  tests.push([ 'bug664087-2.html' , 'bug664087-2-ref.html' ]);  // bug 680578
+}
+
+tests.push(function() {SpecialPowers.clearUserPref("bidi.browser.ui");});
+
 var testIndex = 0;
 
 function nextTest() {
   if (testIndex < tests.length) {
     if (typeof(tests[testIndex]) == 'function') {
       tests[testIndex]();
       SimpleTest.executeSoon(nextTest);
     } else {
--- a/layout/svg/base/src/nsSVGFilterFrame.cpp
+++ b/layout/svg/base/src/nsSVGFilterFrame.cpp
@@ -138,16 +138,20 @@ nsAutoFilterInstance::nsAutoFilterInstan
 
   if (filterRegion.Width() <= 0 || filterRegion.Height() <= 0) {
     // 0 disables rendering, < 0 is error. dispatch error console warning
     // or error as appropriate.
     return;
   }
 
   gfxMatrix userToDeviceSpace = nsSVGUtils::GetCanvasTM(aTarget);
+  if (userToDeviceSpace.IsSingular()) {
+    // nothing to draw
+    return;
+  }
   
   // Calculate filterRes (the width and height of the pixel buffer of the
   // temporary offscreen surface that we'll paint into):
 
   gfxIntSize filterRes;
   const nsSVGIntegerPair& filterResAttrs =
     filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES];
   if (filterResAttrs.IsExplicitlySet()) {
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/682411-1.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<svg xmlns="http://www.w3.org/2000/svg" style="width: 0pt; padding: 100px;">
+  <filter id="s"/>
+  <g filter="url(#s)"><text>z</text></g>
+</svg>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -110,8 +110,9 @@ load 620034-1.html
 load 621598-1.svg
 load 648819-1.html
 load 655025-1.svg
 load 655025-2.svg
 load 655025-3.svg
 load 657077-1.svg
 load 669025-1.svg
 load 669025-2.svg
+load 682411-1.svg
--- a/layout/xul/base/src/tree/src/nsTreeColumns.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeColumns.cpp
@@ -50,36 +50,45 @@
 #include "nsINodeInfo.h"
 #include "nsContentUtils.h"
 #include "nsTreeBodyFrame.h"
 
 // Column class that caches all the info about our column.
 nsTreeColumn::nsTreeColumn(nsTreeColumns* aColumns, nsIContent* aContent)
   : mContent(aContent),
     mColumns(aColumns),
-    mNext(nsnull),
     mPrevious(nsnull)
 {
   NS_ASSERTION(aContent &&
                aContent->NodeInfo()->Equals(nsGkAtoms::treecol,
                                             kNameSpaceID_XUL),
                "nsTreeColumn's content must be a <xul:treecol>");
 
   Invalidate();
 }
 
 nsTreeColumn::~nsTreeColumn()
 {
   if (mNext) {
     mNext->SetPrevious(nsnull);
-    NS_RELEASE(mNext);
   }
 }
 
-NS_IMPL_CYCLE_COLLECTION_1(nsTreeColumn, mContent)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeColumn)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTreeColumn)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent)
+  if (tmp->mNext) {
+    tmp->mNext->SetPrevious(nsnull);
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNext)
+  }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTreeColumn)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContent)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNext)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeColumn)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeColumn)
 
 DOMCI_DATA(TreeColumn, nsTreeColumn)
 
 // QueryInterface implementation for nsTreeColumn
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumn)
--- a/layout/xul/base/src/tree/src/nsTreeColumns.h
+++ b/layout/xul/base/src/tree/src/nsTreeColumns.h
@@ -105,17 +105,17 @@ protected:
 
   PRInt8 GetCropStyle() { return mCropStyle; }
   PRInt32 GetTextAlignment() { return mTextAlignment; }
 
   nsTreeColumn* GetNext() { return mNext; }
   nsTreeColumn* GetPrevious() { return mPrevious; }
   void SetNext(nsTreeColumn* aNext) {
     NS_ASSERTION(!mNext, "already have a next sibling");
-    NS_IF_ADDREF(mNext = aNext);
+    mNext = aNext;
   }
   void SetPrevious(nsTreeColumn* aPrevious) { mPrevious = aPrevious; }
 
 private:
   /**
    * Non-null nsIContent for the associated <treecol> element.
    */
   nsCOMPtr<nsIContent> mContent;
@@ -133,17 +133,17 @@ private:
   PRPackedBool mIsSelectable;
   PRPackedBool mOverflow;
 
   PRInt16 mType;
 
   PRInt8 mCropStyle;
   PRInt8 mTextAlignment;
 
-  nsTreeColumn* mNext;
+  nsRefPtr<nsTreeColumn> mNext;
   nsTreeColumn* mPrevious;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsTreeColumn, NS_TREECOLUMN_IMPL_CID)
 
 class nsTreeColumns : public nsITreeColumns {
 public:
   nsTreeColumns(nsITreeBoxObject* aTree);
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -773,16 +773,20 @@ pref("network.http.prompt-temp-redirect"
 // Section 4.8 "High-Throughput Data Service Class"
 pref("network.http.qos", 0);
 
 // The number of milliseconds after sending a SYN for an HTTP connection,
 // to wait before trying a different connection. 0 means do not use a second
 // connection.
 pref("network.http.connection-retry-timeout", 250);
 
+// Disable IPv6 for backup connections to workaround problems about broken
+// IPv6 connectivity.
+pref("network.http.fast-fallback-to-IPv4", false);
+
 // default values for FTP
 // in a DSCP environment this should be 40 (0x28, or AF11), per RFC-4594,
 // Section 4.8 "High-Throughput Data Service Class", and 80 (0x50, or AF22)
 // per Section 4.7 "Low-Latency Data Service Class".
 pref("network.ftp.data.qos", 0);
 pref("network.ftp.control.qos", 0);
 
 // </http>
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -1363,17 +1363,17 @@ nsHalfOpenSocket::SetupStreams(nsISocket
     if (mTransaction->Caps() & NS_HTTP_LOAD_ANONYMOUS)
         tmpFlags |= nsISocketTransport::ANONYMOUS_CONNECT;
 
     // For backup connections, we disable IPv6. That's because some users have
     // broken IPv6 connectivity (leading to very long timeouts), and disabling
     // IPv6 on the backup connection gives them a much better user experience
     // with dual-stack hosts, though they still pay the 250ms delay for each new
     // connection. This strategy is also known as "happy eyeballs".
-    if (isBackup)
+    if (isBackup && gHttpHandler->FastFallbackToIPv4())
         tmpFlags |= nsISocketTransport::DISABLE_IPV6;
 
     socketTransport->SetConnectionFlags(tmpFlags);
 
     socketTransport->SetQoSBits(gHttpHandler->GetQoSBits());
 
     rv = socketTransport->SetEventSink(this, nsnull);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -165,16 +165,17 @@ nsHttpHandler *gHttpHandler = nsnull;
 
 nsHttpHandler::nsHttpHandler()
     : mConnMgr(nsnull)
     , mHttpVersion(NS_HTTP_VERSION_1_1)
     , mProxyHttpVersion(NS_HTTP_VERSION_1_1)
     , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     , mProxyCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     , mReferrerLevel(0xff) // by default we always send a referrer
+    , mFastFallbackToIPv4(PR_FALSE)
     , mIdleTimeout(10)
     , mMaxRequestAttempts(10)
     , mMaxRequestDelay(10)
     , mIdleSynTimeout(250)
     , mMaxConnections(24)
     , mMaxConnectionsPerServer(8)
     , mMaxPersistentConnectionsPerServer(2)
     , mMaxPersistentConnectionsPerProxy(4)
@@ -893,16 +894,22 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
     }
 
     if (PREF_CHANGED(HTTP_PREF("connection-retry-timeout"))) {
         rv = prefs->GetIntPref(HTTP_PREF("connection-retry-timeout"), &val);
         if (NS_SUCCEEDED(rv))
             mIdleSynTimeout = (PRUint16) NS_CLAMP(val, 0, 3000);
     }
 
+    if (PREF_CHANGED(HTTP_PREF("fast-fallback-to-IPv4"))) {
+        rv = prefs->GetBoolPref(HTTP_PREF("fast-fallback-to-IPv4"), &cVar);
+        if (NS_SUCCEEDED(rv))
+            mFastFallbackToIPv4 = cVar;
+    }
+
     if (PREF_CHANGED(HTTP_PREF("version"))) {
         nsXPIDLCString httpVersion;
         prefs->GetCharPref(HTTP_PREF("version"), getter_Copies(httpVersion));
         if (httpVersion) {
             if (!PL_strcmp(httpVersion, "1.1"))
                 mHttpVersion = NS_HTTP_VERSION_1_1;
             else if (!PL_strcmp(httpVersion, "0.9"))
                 mHttpVersion = NS_HTTP_VERSION_0_9;
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -102,17 +102,18 @@ public:
     PRUint8        RedirectionLimit()        { return mRedirectionLimit; }
     PRUint16       IdleTimeout()             { return mIdleTimeout; }
     PRUint16       MaxRequestAttempts()      { return mMaxRequestAttempts; }
     const char    *DefaultSocketType()       { return mDefaultSocketType.get(); /* ok to return null */ }
     nsIIDNService *IDNConverter()            { return mIDNConverter; }
     PRUint32       PhishyUserPassLength()    { return mPhishyUserPassLength; }
     PRUint8        GetQoSBits()              { return mQoSBits; }
     PRUint16       GetIdleSynTimeout()       { return mIdleSynTimeout; }
-    
+    PRBool         FastFallbackToIPv4()      { return mFastFallbackToIPv4; }
+
     PRBool         IsPersistentHttpsCachingEnabled() { return mEnablePersistentHttpsCaching; }
 
     PRBool         PromptTempRedirect()      { return mPromptTempRedirect; }
 
     nsHttpAuthCache     *AuthCache() { return &mAuthCache; }
     nsHttpConnectionMgr *ConnMgr()   { return mConnMgr; }
 
     // cache support
@@ -254,16 +255,18 @@ private:
     //
 
     PRUint8  mHttpVersion;
     PRUint8  mProxyHttpVersion;
     PRUint8  mCapabilities;
     PRUint8  mProxyCapabilities;
     PRUint8  mReferrerLevel;
 
+    PRPackedBool mFastFallbackToIPv4;
+
     PRUint16 mIdleTimeout;
     PRUint16 mMaxRequestAttempts;
     PRUint16 mMaxRequestDelay;
     PRUint16 mIdleSynTimeout;
 
     PRUint16 mMaxConnections;
     PRUint8  mMaxConnectionsPerServer;
     PRUint8  mMaxPersistentConnectionsPerServer;
--- a/testing/mochitest/specialpowers/content/specialpowers.js
+++ b/testing/mochitest/specialpowers/content/specialpowers.js
@@ -289,16 +289,30 @@ SpecialPowers.prototype = {
     var xulRuntime = Cc["@mozilla.org/xre/app-info;1"]
                         .getService(Components.interfaces.nsIXULAppInfo)
                         .QueryInterface(Components.interfaces.nsIXULRuntime);
 
     this._xpcomabi = xulRuntime.XPCOMABI;
     return this._xpcomabi;
   },
 
+  _os: null,
+
+  get OS() {
+    if (this._os != null)
+      return this._os;
+
+    var xulRuntime = Cc["@mozilla.org/xre/app-info;1"]
+                        .getService(Components.interfaces.nsIXULAppInfo)
+                        .QueryInterface(Components.interfaces.nsIXULRuntime);
+
+    this._os = xulRuntime.OS;
+    return this._os;
+  },
+
   registerProcessCrashObservers: function() {
     addMessageListener("SPProcessCrashService", this._messageListener);
     sendSyncMessage("SPProcessCrashService", { op: "register-observer" });
   },
 
   _messageReceived: function(aMessage) {
     switch (aMessage.name) {
       case "SPProcessCrashService":
--- a/widget/src/qt/nsWindow.cpp
+++ b/widget/src/qt/nsWindow.cpp
@@ -2690,16 +2690,25 @@ nsWindow::createQWidget(MozQWidget *pare
             // Disable double buffer and system background rendering
 #ifdef MOZ_X11
             newView->viewport()->setAttribute(Qt::WA_PaintOnScreen, true);
 #endif
             newView->viewport()->setAttribute(Qt::WA_NoSystemBackground, true);
         }
         // Enable gestures:
 #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
+#if defined MOZ_ENABLE_MEEGOTOUCH
+        // Disable default Gesture filters (speedup filtering)
+        newView->viewport()->ungrabGesture(Qt::PanGesture);
+        newView->viewport()->ungrabGesture(Qt::TapGesture);
+        newView->viewport()->ungrabGesture(Qt::TapAndHoldGesture);
+        newView->viewport()->ungrabGesture(Qt::SwipeGesture);
+#endif
+
+        // Enable required filters
         newView->viewport()->grabGesture(Qt::PinchGesture);
         newView->viewport()->grabGesture(gSwipeGestureId);
 #endif
         newView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
         newView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
 #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
         // Top level widget is just container, and should not be painted
@@ -2720,16 +2729,23 @@ nsWindow::createQWidget(MozQWidget *pare
         // XXX is this needed for Qt?
         // gdk does not automatically set the cursor for "temporary"
         // windows, which are what gtk uses for popups.
         SetCursor(eCursor_standard);
     } else if (mIsTopLevel) {
         SetDefaultIcon();
     }
 #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
+#if defined MOZ_ENABLE_MEEGOTOUCH
+    // Disable default Gesture filters (speedup filtering)
+    widget->ungrabGesture(Qt::PanGesture);
+    widget->ungrabGesture(Qt::TapGesture);
+    widget->ungrabGesture(Qt::TapAndHoldGesture);
+    widget->ungrabGesture(Qt::SwipeGesture);
+#endif
     widget->grabGesture(Qt::PinchGesture);
     widget->grabGesture(gSwipeGestureId);
 #endif
 
     return widget;
 }
 
 // return the gfxASurface for rendering to this widget