Merge fx-team and mozilla-central ready for MPL2 update
authorEd Morley <emorley@mozilla.com>
Mon, 21 May 2012 07:49:47 +0100
changeset 94474 1158503601be5ca5f0591732c96dde073b632cc4
parent 94473 c0065b9d90bfeb01fc75d8ffa5b97e997ec9f261 (current diff)
parent 94468 b5352f7337b15c7456cc1eafea7d2b5754360082 (diff)
child 94475 f4157e8c410708d76703f19e4dfb61859bfe32d8
push id22720
push useremorley@mozilla.com
push dateMon, 21 May 2012 07:27:23 +0000
treeherdermozilla-central@1158503601be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone15.0a1
first release with
nightly linux32
1158503601be / 15.0a1 / 20120521030525 / files
nightly linux64
1158503601be / 15.0a1 / 20120521030525 / files
nightly mac
1158503601be / 15.0a1 / 20120521030525 / files
nightly win32
1158503601be / 15.0a1 / 20120521030525 / files
nightly win64
1158503601be / 15.0a1 / 20120521030525 / 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 fx-team and mozilla-central ready for MPL2 update
build/mobile/robocop/robotium-solo-3.1.jar
content/xul/content/test/test_bug330705-2.xul
dom/imptests/failures.txt
dom/imptests/html.json
dom/imptests/testharnessreport.js.in
dom/imptests/webapps.json
dom/imptests/writeReporter.py
dom/plugins/base/nsIPluginStreamListener.idl
js/src/jit-test/tests/basic/testCrossGlobalInvokeSession.js
js/src/jit-test/tests/basic/testReconstructImacroPCStack.js
tools/profiler/thread_helper.h
--- a/.gitignore
+++ b/.gitignore
@@ -13,16 +13,17 @@ ID
 .*.sw[a-z]
 
 # User files that may appear at the root
 /.mozconfig*
 /mozconfig
 /configure
 /config.cache
 /config.log
+/.clang_complete
 
 # Empty marker file that's generated when we check out NSS
 security/manager/.nss.checkout
 
 # Build directories
 /obj*/
 
 # Build directories for js shell
--- a/.hgignore
+++ b/.hgignore
@@ -12,16 +12,17 @@
 .[^/]*\.sw.$
 
 # User files that may appear at the root
 ^\.mozconfig
 ^mozconfig*
 ^configure$
 ^config\.cache$
 ^config\.log$
+^\.clang_complete
 
 # Empty marker file that's generated when we check out NSS
 ^security/manager/\.nss\.checkout$
 
 # Build directories
 ^obj
 
 # Build directories for js shell
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -390,18 +390,17 @@ nsAccDocManager::CreateDocOrRootAccessib
 
   // We only create root accessibles for the true root, otherwise create a
   // doc accessible.
   nsRefPtr<nsDocAccessible> docAcc = isRootDoc ?
     new RootAccessibleWrap(aDocument, rootElm, presShell) :
     new nsDocAccessibleWrap(aDocument, rootElm, presShell);
 
   // Cache the document accessible into document cache.
-  if (!docAcc || !mDocAccessibleCache.Put(aDocument, docAcc))
-    return nsnull;
+  mDocAccessibleCache.Put(aDocument, docAcc);
 
   // Initialize the document accessible.
   if (!docAcc->Init()) {
     docAcc->Shutdown();
     return nsnull;
   }
   docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument));
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -741,23 +741,31 @@ nsAccessible::NativeState()
   if (frame && (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW))
     state |= states::FLOATING;
 
   // Check if a XUL element has the popup attribute (an attached popup menu).
   if (mContent->IsXUL())
     if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
       state |= states::HASPOPUP;
 
-  // Add 'linked' state for simple xlink.
-  if (nsCoreUtils::IsXLink(mContent))
-    state |= states::LINKED;
+  // Bypass the link states specialization for non links.
+  if (!mRoleMapEntry || mRoleMapEntry->roleRule == kUseNativeRole ||
+      mRoleMapEntry->role == roles::LINK)
+    state |= NativeLinkState();
 
   return state;
 }
 
+PRUint64
+nsAccessible::NativeLinkState() const
+{
+  // Expose linked state for simple xlink.
+  return nsCoreUtils::IsXLink(mContent) ? states::LINKED : 0;
+}
+
   /* readonly attribute boolean focusedChild; */
 NS_IMETHODIMP
 nsAccessible::GetFocusedChild(nsIAccessible** aChild)
 {
   NS_ENSURE_ARG_POINTER(aChild);
   *aChild = nsnull;
 
   if (IsDefunct())
@@ -1613,17 +1621,17 @@ nsAccessible::State()
       state |= states::HORIZONTAL;
     }
   }
 
   return state;
 }
 
 void
-nsAccessible::ApplyARIAState(PRUint64* aState)
+nsAccessible::ApplyARIAState(PRUint64* aState) const
 {
   if (!mContent->IsElement())
     return;
 
   dom::Element* element = mContent->AsElement();
 
   // Test for universal states first
   *aState |= nsARIAMap::UniversalStatesFor(element);
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -180,17 +180,17 @@ public:
 
   /**
    * Maps ARIA state attributes to state of accessible. Note the given state
    * argument should hold states for accessible before you pass it into this
    * method.
    *
    * @param  [in/out] where to fill the states into.
    */
-  virtual void ApplyARIAState(PRUint64* aState);
+  virtual void ApplyARIAState(PRUint64* aState) const;
 
   /**
    * Returns the accessible name provided by native markup. It doesn't take
    * into account ARIA markup used to specify the name.
    *
    * @param  aName             [out] the accessible name
    *
    * @return NS_OK_EMPTY_NAME  points empty name was specified by native markup
@@ -223,22 +223,37 @@ public:
   virtual mozilla::a11y::role NativeRole();
 
   /**
    * Return all states of accessible (including ARIA states).
    */
   virtual PRUint64 State();
 
   /**
+   * Return link states present on the accessible.
+   */
+  PRUint64 LinkState() const
+  {
+    PRUint64 state = NativeLinkState();
+    ApplyARIAState(&state);
+    return state;
+  }
+
+  /**
    * Return the states of accessible, not taking into account ARIA states.
    * Use State() to get complete set of states.
    */
   virtual PRUint64 NativeState();
 
   /**
+   * Return native link states present on the accessible.
+   */
+  virtual PRUint64 NativeLinkState() const;
+
+  /**
    * Return bit set of invisible and offscreen states.
    */
   PRUint64 VisibilityState();
 
   /**
    * Returns attributes for accessible without explicitly setted ARIA
    * attributes.
    */
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -108,26 +108,22 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableA
 
 NS_IMETHODIMP
 nsLinkableAccessible::TakeFocus()
 {
   return mActionAcc ? mActionAcc->TakeFocus() : nsAccessibleWrap::TakeFocus();
 }
 
 PRUint64
-nsLinkableAccessible::NativeState()
+nsLinkableAccessible::NativeLinkState() const
 {
-  PRUint64 states = nsAccessibleWrap::NativeState();
-  if (mIsLink) {
-    states |= states::LINKED;
-    if (mActionAcc->State() & states::TRAVERSED)
-      states |= states::TRAVERSED;
-  }
+  if (mIsLink)
+    return states::LINKED | (mActionAcc->LinkState() & states::TRAVERSED);
 
-  return states;
+  return 0;
 }
 
 void
 nsLinkableAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
 
   nsAccessible::Value(aValue);
@@ -230,21 +226,20 @@ nsLinkableAccessible::BindToParent(nsAcc
     return;
   }
 
   // XXX: The logic looks broken since the click listener may be registered
   // on non accessible node in parent chain but this node is skipped when tree
   // is traversed.
   nsAccessible* walkUpAcc = this;
   while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) {
-    if (walkUpAcc->Role() == roles::LINK &&
-        walkUpAcc->State() & states::LINKED) {
-        mIsLink = true;
-        mActionAcc = walkUpAcc;
-        return;
+    if (walkUpAcc->LinkState() & states::LINKED) {
+      mIsLink = true;
+      mActionAcc = walkUpAcc;
+      return;
     }
 
     if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
       mActionAcc = walkUpAcc;
       mIsOnclick = true;
       return;
     }
   }
--- a/accessible/src/base/nsBaseWidgetAccessible.h
+++ b/accessible/src/base/nsBaseWidgetAccessible.h
@@ -91,17 +91,17 @@ public:
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD TakeFocus();
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsAccessible
   virtual void Value(nsString& aValue);
-  virtual PRUint64 NativeState();
+  virtual PRUint64 NativeLinkState() const;
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
   virtual KeyBinding AccessKey() const;
 
   // HyperLinkAccessible
   virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);
 
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -336,17 +336,17 @@ nsDocAccessible::NativeState()
   nsCOMPtr<nsIEditor> editor = GetEditor();
   state |= editor ? states::EDITABLE : states::READONLY;
 
   return state;
 }
 
 // nsAccessible public method
 void
-nsDocAccessible::ApplyARIAState(PRUint64* aState)
+nsDocAccessible::ApplyARIAState(PRUint64* aState) const
 {
   // Combine with states from outer doc
   // 
   nsAccessible::ApplyARIAState(aState);
 
   // Allow iframe/frame etc. to have final state override via ARIA
   if (mParent)
     mParent->ApplyARIAState(aState);
@@ -1364,27 +1364,21 @@ nsDocAccessible::GetAccessibleOrContaine
 bool
 nsDocAccessible::BindToDocument(nsAccessible* aAccessible,
                                 nsRoleMapEntry* aRoleMapEntry)
 {
   if (!aAccessible)
     return false;
 
   // Put into DOM node cache.
-  if (aAccessible->IsPrimaryForNode() &&
-      !mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible))
-    return false;
+  if (aAccessible->IsPrimaryForNode())
+    mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible);
 
   // Put into unique ID cache.
-  if (!mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible)) {
-    if (aAccessible->IsPrimaryForNode())
-      mNodeToAccessibleMap.Remove(aAccessible->GetNode());
-
-    return false;
-  }
+  mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible);
 
   // Initialize the accessible.
   if (!aAccessible->Init()) {
     NS_ERROR("Failed to initialize an accessible!");
 
     UnbindFromDocument(aAccessible);
     return false;
   }
@@ -1616,20 +1610,17 @@ nsDocAccessible::AddDependentIDsFor(nsAc
       const nsDependentSubstring id = iter.NextID();
       if (id.IsEmpty())
         break;
 
       AttrRelProviderArray* providers = mDependentIDsHash.Get(id);
       if (!providers) {
         providers = new AttrRelProviderArray();
         if (providers) {
-          if (!mDependentIDsHash.Put(id, providers)) {
-            delete providers;
-            providers = nsnull;
-          }
+          mDependentIDsHash.Put(id, providers);
         }
       }
 
       if (providers) {
         AttrRelProvider* provider =
           new AttrRelProvider(relAttr, aRelProvider->GetContent());
         if (provider) {
           providers->AppendElement(provider);
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -110,17 +110,17 @@ public:
   virtual nsIDocument* GetDocumentNode() const { return mDocument; }
 
   // nsAccessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual void Description(nsString& aDescription);
   virtual nsAccessible* FocusedChild();
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
-  virtual void ApplyARIAState(PRUint64* aState);
+  virtual void ApplyARIAState(PRUint64* aState) const;
 
   virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
 
 #ifdef DEBUG_ACCDOCMGR
   virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
 #endif
 
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -1040,17 +1040,17 @@ ARIAGridCellAccessible::IsSelected(bool*
   *aIsSelected = true;
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible
 
 void
-ARIAGridCellAccessible::ApplyARIAState(PRUint64* aState)
+ARIAGridCellAccessible::ApplyARIAState(PRUint64* aState) const
 {
   nsHyperTextAccessibleWrap::ApplyARIAState(aState);
 
   // Return if the gridcell has aria-selected="true".
   if (*aState & states::SELECTED)
     return;
 
   // Check aria-selected="true" on the row.
--- a/accessible/src/generic/ARIAGridAccessible.h
+++ b/accessible/src/generic/ARIAGridAccessible.h
@@ -133,16 +133,16 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTableCell
   NS_DECL_NSIACCESSIBLETABLECELL
 
   // nsAccessible
-  virtual void ApplyARIAState(PRUint64* aState);
+  virtual void ApplyARIAState(PRUint64* aState) const;
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -328,17 +328,17 @@ ApplicationAccessible::IsPrimaryForNode(
 {
   return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible public methods
 
 void
-ApplicationAccessible::ApplyARIAState(PRUint64* aState)
+ApplicationAccessible::ApplyARIAState(PRUint64* aState) const
 {
 }
 
 role
 ApplicationAccessible::NativeRole()
 {
   return roles::APP_ROOT;
 }
--- a/accessible/src/generic/ApplicationAccessible.h
+++ b/accessible/src/generic/ApplicationAccessible.h
@@ -99,17 +99,17 @@ public:
 
   // nsAccessNode
   virtual bool Init();
   virtual void Shutdown();
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
-  virtual void ApplyARIAState(PRUint64* aState);
+  virtual void ApplyARIAState(PRUint64* aState) const;
   virtual void Description(nsString& aDescription);
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 State();
   virtual PRUint64 NativeState();
   virtual Relation RelationByType(PRUint32 aRelType);
 
   virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -432,17 +432,17 @@ HTMLTextFieldAccessible::Value(nsString&
   
   nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(mContent));
   if (inputElement) {
     inputElement->GetValue(aValue);
   }
 }
 
 void
-HTMLTextFieldAccessible::ApplyARIAState(PRUint64* aState)
+HTMLTextFieldAccessible::ApplyARIAState(PRUint64* aState) const
 {
   nsHyperTextAccessibleWrap::ApplyARIAState(aState);
 
   aria::MapToState(aria::eARIAAutoComplete, mContent->AsElement(), aState);
 }
 
 PRUint64
 HTMLTextFieldAccessible::State()
--- a/accessible/src/html/HTMLFormControlAccessible.h
+++ b/accessible/src/html/HTMLFormControlAccessible.h
@@ -140,17 +140,17 @@ public:
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 
   // nsHyperTextAccessible
   virtual already_AddRefed<nsIEditor> GetEditor() const;
 
   // nsAccessible
   virtual void Value(nsString& aValue);
-  virtual void ApplyARIAState(PRUint64* aState);
+  virtual void ApplyARIAState(PRUint64* aState) const;
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 State();
   virtual PRUint64 NativeState();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
--- a/accessible/src/html/nsHTMLImageMapAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageMapAccessible.cpp
@@ -226,29 +226,16 @@ nsHTMLAreaAccessible::IsPrimaryForNode()
   // Make HTML area DOM element not accessible. HTML image map accessible
   // manages its tree itself.
   return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLAreaAccessible: nsAccessible public
 
-PRUint64
-nsHTMLAreaAccessible::NativeState()
-{
-  // Bypass the link states specialization for non links.
-  if (mRoleMapEntry &&
-      mRoleMapEntry->role != roles::NOTHING &&
-      mRoleMapEntry->role != roles::LINK) {
-    return nsAccessible::NativeState();
-  }
-
-  return nsHTMLLinkAccessible::NativeState();
-}
-
 nsAccessible*
 nsHTMLAreaAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
                                    EWhichChildAtPoint aWhichChild)
 {
   // Don't walk into area accessibles.
   return this;
 }
 
--- a/accessible/src/html/nsHTMLImageMapAccessible.h
+++ b/accessible/src/html/nsHTMLImageMapAccessible.h
@@ -97,17 +97,16 @@ public:
   nsHTMLAreaAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
 
   // nsAccessNode
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
   virtual void Description(nsString& aDescription);
   virtual nsresult GetNameInternal(nsAString& aName);
-  virtual PRUint64 NativeState();
   virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
                                      EWhichChildAtPoint aWhichChild);
   virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
 
   // HyperLinkAccessible
   virtual PRUint32 StartOffset();
   virtual PRUint32 EndOffset();
 
--- a/accessible/src/html/nsHTMLLinkAccessible.cpp
+++ b/accessible/src/html/nsHTMLLinkAccessible.cpp
@@ -81,34 +81,33 @@ nsHTMLLinkAccessible::NativeState()
 
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name)) {
     // This is how we indicate it is a named anchor
     // In other words, this anchor can be selected as a location :)
     // There is no other better state to use to indicate this.
     states |= states::SELECTABLE;
   }
 
-  nsEventStates state = mContent->AsElement()->State();
-  if (state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED |
-                                  NS_EVENT_STATE_UNVISITED)) {
-    states |= states::LINKED;
+  return states;
+}
 
-    if (state.HasState(NS_EVENT_STATE_VISITED))
-      states |= states::TRAVERSED;
+PRUint64
+nsHTMLLinkAccessible::NativeLinkState() const
+{
+  nsEventStates eventState = mContent->AsElement()->State();
+  if (eventState.HasState(NS_EVENT_STATE_UNVISITED))
+    return states::LINKED;
 
-    return states;
-  }
+  if (eventState.HasState(NS_EVENT_STATE_VISITED))
+    return states::LINKED | states::TRAVERSED;
 
   // This is a either named anchor (a link with also a name attribute) or
   // it doesn't have any attributes. Check if 'click' event handler is
   // registered, otherwise bail out.
-  if (nsCoreUtils::HasClickListener(mContent))
-    states |= states::LINKED;
-
-  return states;
+  return nsCoreUtils::HasClickListener(mContent) ? states::LINKED : 0;
 }
 
 void
 nsHTMLLinkAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
 
   nsHyperTextAccessible::Value(aValue);
--- a/accessible/src/html/nsHTMLLinkAccessible.h
+++ b/accessible/src/html/nsHTMLLinkAccessible.h
@@ -52,16 +52,17 @@ public:
   // nsIAccessible
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsAccessible
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
+  virtual PRUint64 NativeLinkState() const;
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
   // HyperLinkAccessible
   virtual bool IsLink();
   virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);
 
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1493,17 +1493,17 @@ nsHyperTextAccessible::DeleteText(PRInt3
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIEditor> editor = GetEditor();
   NS_ENSURE_STATE(editor);
 
   nsresult rv = SetSelectionRange(aStartPos, aEndPos);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return editor->DeleteSelection(nsIEditor::eNone);
+  return editor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
 }
 
 NS_IMETHODIMP
 nsHyperTextAccessible::PasteText(PRInt32 aPosition)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -34,22 +34,22 @@ var AccessFu = {
       // XXX: only supports attaching to one window now.
       throw new Error('Only one window could be attached to AccessFu');
 
     dump('AccessFu attach!! ' + Services.appinfo.OS + '\n');
     this.chromeWin = aWindow;
     this.presenters = [];
 
     this.prefsBranch = Cc['@mozilla.org/preferences-service;1']
-      .getService(Ci.nsIPrefService).getBranch('accessibility.');
-    this.prefsBranch.addObserver('accessfu', this, false);
+      .getService(Ci.nsIPrefService).getBranch('accessibility.accessfu.');
+    this.prefsBranch.addObserver('activate', this, false);
 
     let accessPref = ACCESSFU_DISABLE;
     try {
-      accessPref = this.prefsBranch.getIntPref('accessfu');
+      accessPref = this.prefsBranch.getIntPref('activate');
     } catch (x) {
     }
 
     this._processPreferences(accessPref);
   },
 
   /**
    * Start AccessFu mode, this primarily means controlling the virtual cursor
@@ -171,18 +171,18 @@ var AccessFu = {
     switch (aTopic) {
       case 'Accessibility:Settings':
         if (JSON.parse(aData).enabled)
           this._enable();
         else
           this._disable();
         break;
       case 'nsPref:changed':
-        if (aData == 'accessfu')
-          this._processPreferences(this.prefsBranch.getIntPref('accessfu'));
+        if (aData == 'activate')
+          this._processPreferences(this.prefsBranch.getIntPref('activate'));
         break;
       case 'accessible-event':
         let event;
         try {
           event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
           this._handleAccEvent(event);
         } catch (ex) {
           dump(ex);
@@ -210,22 +210,20 @@ var AccessFu = {
             // focus.
             let sel = doc.getSelection();
             sel.collapse(position.DOMNode, 0);
             Cc["@mozilla.org/focus-manager;1"]
               .getService(Ci.nsIFocusManager).moveFocus(
                 doc.defaultView, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, 0);
           }
 
-          let newContext = this.getNewContext(event.oldAccessible,
-                                              pivot.position);
+          let presenterContext = new PresenterContext(pivot.position,
+                                                      event.oldAccessible);
           this.presenters.forEach(
-            function(p) {
-              p.pivotChanged(pivot.position, newContext);
-            });
+            function(p) { p.pivotChanged(presenterContext); });
           break;
         }
       case Ci.nsIAccessibleEvent.EVENT_STATE_CHANGE:
         {
           let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
           if (event.state == Ci.nsIAccessibleStates.STATE_CHECKED &&
               !(event.isExtraState())) {
             this.presenters.forEach(
@@ -308,18 +306,23 @@ var AccessFu = {
             }
           );
           break;
         }
       case Ci.nsIAccessibleEvent.EVENT_FOCUS:
         {
           if (this._isBrowserDoc(aEvent.accessible)) {
             // The document recieved focus, call tabSelected to present current tab.
+            let docContext = new PresenterContext(aEvent.accessible, null);
+            let cursorable = aEvent.accessible.
+              QueryInterface(Ci.nsIAccessibleCursorable);
+            let vcContext = new PresenterContext(
+              (cursorable) ? cursorable.virtualCursor.position : null, null);
             this.presenters.forEach(
-              function(p) { p.tabSelected(aEvent.accessible); });
+              function(p) { p.tabSelected(docContext, vcContext); });
           }
           break;
         }
       case Ci.nsIAccessibleEvent.EVENT_TEXT_INSERTED:
       case Ci.nsIAccessibleEvent.EVENT_TEXT_REMOVED:
       {
         if (aEvent.isFromUserInput) {
           // XXX support live regions as well.
@@ -378,51 +381,16 @@ var AccessFu = {
   _isNotChromeDoc: function _isNotChromeDoc(aDocument) {
     let location = aDocument.DOMNode.location;
     if (!location)
       return false;
 
     return location.protocol != "about:";
   },
 
-  getNewContext: function getNewContext(aOldObject, aNewObject) {
-    let newLineage = [];
-    let oldLineage = [];
-
-    let parent = aNewObject;
-    while ((parent = parent.parent))
-      newLineage.push(parent);
-
-    if (aOldObject) {
-      parent = aOldObject;
-      while ((parent = parent.parent))
-        oldLineage.push(parent);
-    }
-
-//    newLineage.reverse();
-//    oldLineage.reverse();
-
-    let i = 0;
-    let newContext = [];
-
-    while (true) {
-      let newAncestor = newLineage.pop();
-      let oldAncestor = oldLineage.pop();
-
-      if (newAncestor == undefined)
-        break;
-
-      if (newAncestor != oldAncestor)
-        newContext.push(newAncestor);
-      i++;
-    }
-
-    return newContext;
-  },
-
   // A hash of documents that don't yet have an accessible tree.
   _pendingDocuments: {},
 
   // So we don't enable/disable twice
   _enabled: false,
 
   // Observing accessibility settings
   _observingSystemSettings: false
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -9,17 +9,18 @@ const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import('resource://gre/modules/accessibility/UtteranceGenerator.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
 
 var EXPORTED_SYMBOLS = ['VisualPresenter',
                         'AndroidPresenter',
-                        'DummyAndroidPresenter'];
+                        'DummyAndroidPresenter',
+                        'PresenterContext'];
 
 /**
  * The interface for all presenter classes. A presenter could be, for example,
  * a speech output module, or a visual cursor indicator.
  */
 function Presenter() {}
 
 Presenter.prototype = {
@@ -31,21 +32,20 @@ Presenter.prototype = {
 
   /**
    * Detach function.
    */
   detach: function detach() {},
 
   /**
    * The virtual cursor's position changed.
-   * @param {nsIAccessible} aObject the new position.
-   * @param {nsIAccessible[]} aNewContext the ancestry of the new position that
-   *    is different from the old virtual cursor position.
+   * @param {PresenterContext} aContext the context object for the new pivot
+   *   position.
    */
-  pivotChanged: function pivotChanged(aObject, aNewContext) {},
+  pivotChanged: function pivotChanged(aContext) {},
 
   /**
    * An object's action has been invoked.
    * @param {nsIAccessible} aObject the object that has been invoked.
    * @param {string} aActionName the name of the action.
    */
   actionInvoked: function actionInvoked(aObject, aActionName) {},
 
@@ -73,21 +73,22 @@ Presenter.prototype = {
    *    state changed, or null if the tab has no associated document yet.
    * @param {string} aPageState the state name for the tab, valid states are:
    *    'newtab', 'loading', 'newdoc', 'loaded', 'stopped', and 'reload'.
    */
   tabStateChanged: function tabStateChanged(aDocObj, aPageState) {},
 
   /**
    * The current tab has changed.
-   * @param {nsIAccessible} aObject the document contained by the tab
-   *    accessible, or null if it is a new tab with no attached
-   *    document yet.
+   * @param {PresenterContext} aDocContext context object for tab's
+   *   document.
+   * @param {PresenterContext} aVCContext context object for tab's current
+   *   virtual cursor position.
    */
-  tabSelected: function tabSelected(aDocObj) {},
+  tabSelected: function tabSelected(aDocContext, aVCContext) {},
 
   /**
    * The viewport has changed, either a scroll, pan, zoom, or
    *    landscape/portrait toggle.
    */
   viewportChanged: function viewportChanged() {}
 };
 
@@ -134,44 +135,42 @@ VisualPresenter.prototype = {
     this.highlightBox = this.stylesheet = null;
   },
 
   viewportChanged: function VisualPresenter_viewportChanged() {
     if (this._currentObject)
       this._highlight(this._currentObject);
   },
 
-  pivotChanged: function VisualPresenter_pivotChanged(aObject, aNewContext) {
-    this._currentObject = aObject;
+  pivotChanged: function VisualPresenter_pivotChanged(aContext) {
+    this._currentObject = aContext.accessible;
 
-    if (!aObject) {
+    if (!aContext.accessible) {
       this._hide();
       return;
     }
 
     try {
-      aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
-      this._highlight(aObject);
+      aContext.accessible.scrollTo(
+        Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
+      this._highlight(aContext.accessible);
     } catch (e) {
       dump('Error getting bounds: ' + e);
       return;
     }
   },
 
-  tabSelected: function VisualPresenter_tabSelected(aDocObj) {
-    let vcPos = aDocObj ? aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).
-      virtualCursor.position : null;
-
-    this.pivotChanged(vcPos);
+  tabSelected: function VisualPresenter_tabSelected(aDocContext, aVCContext) {
+    this.pivotChanged(aVCContext);
   },
 
   tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
                                                             aPageState) {
     if (aPageState == 'newdoc')
-      this.pivotChanged(null);
+      this._hide();
   },
 
   // Internals
 
   _hide: function _hide() {
     this.highlightBox.style.display = 'none';
   },
 
@@ -229,24 +228,25 @@ AndroidPresenter.prototype = {
   // Android AccessibilityEvent type constants.
   ANDROID_VIEW_CLICKED: 0x01,
   ANDROID_VIEW_LONG_CLICKED: 0x02,
   ANDROID_VIEW_SELECTED: 0x04,
   ANDROID_VIEW_FOCUSED: 0x08,
   ANDROID_VIEW_TEXT_CHANGED: 0x10,
   ANDROID_WINDOW_STATE_CHANGED: 0x20,
 
-  pivotChanged: function AndroidPresenter_pivotChanged(aObject, aNewContext) {
+  pivotChanged: function AndroidPresenter_pivotChanged(aContext) {
     let output = [];
-    for (let i in aNewContext)
-      output.push.apply(output,
-                        UtteranceGenerator.genForObject(aNewContext[i]));
+    for (let i in aContext.newAncestry)
+      output.push.apply(
+        output, UtteranceGenerator.genForObject(aContext.newAncestry[i]));
 
     output.push.apply(output,
-                      UtteranceGenerator.genForObject(aObject, true));
+                      UtteranceGenerator.genForObject(aContext.accessible,
+                                                      true));
 
     this.sendMessageToJava({
       gecko: {
         type: 'Accessibility:Event',
         eventType: this.ANDROID_VIEW_FOCUSED,
         text: output
       }
     });
@@ -257,31 +257,19 @@ AndroidPresenter.prototype = {
       gecko: {
         type: 'Accessibility:Event',
         eventType: this.ANDROID_VIEW_CLICKED,
         text: UtteranceGenerator.genForAction(aObject, aActionName)
       }
     });
   },
 
-  tabSelected: function AndroidPresenter_tabSelected(aDocObj) {
+  tabSelected: function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
     // Send a pivot change message with the full context utterance for this doc.
-    let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
-    let context = [];
-
-    let parent = vcDoc.virtualCursor.position || aDocObj;
-    while ((parent = parent.parent)) {
-      context.push(parent);
-      if (parent == aDocObj)
-        break;
-    }
-
-    context.reverse();
-
-    this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
+    this.pivotChanged(aVCContext);
   },
 
   tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
                                                              aPageState) {
     let stateUtterance = UtteranceGenerator.
       genForTabStateChange(aDocObj, aPageState);
 
     if (!stateUtterance.length)
@@ -337,8 +325,67 @@ function DummyAndroidPresenter() {}
 
 DummyAndroidPresenter.prototype = {
   __proto__: AndroidPresenter.prototype,
 
   sendMessageToJava: function DummyAndroidPresenter_sendMessageToJava(aMsg) {
     dump(JSON.stringify(aMsg, null, 2) + '\n');
   }
 };
+
+/**
+ * PresenterContext: An object that generates and caches context information
+ * for a given accessible and its relationship with another accessible.
+ */
+function PresenterContext(aAccessible, aOldAccessible) {
+  this._accessible = aAccessible;
+  this._oldAccessible = aOldAccessible;
+}
+
+PresenterContext.prototype = {
+  get accessible() {
+    return this._accessible;
+  },
+
+  get oldAccessible() {
+    return this._oldAccessible;
+  },
+
+  /*
+   * This is a list of the accessible's ancestry up to the common ancestor
+   * of the accessible and the old accessible. It is useful for giving the
+   * user context as to where they are in the heirarchy.
+   */
+  get newAncestry() {
+    if (!this._newAncestry) {
+      let newLineage = [];
+      let oldLineage = [];
+
+      let parent = this._accessible;
+      while ((parent = parent.parent))
+        newLineage.push(parent);
+
+      if (this._oldAccessible) {
+        parent = this._oldAccessible;
+        while ((parent = parent.parent))
+          oldLineage.push(parent);
+      }
+
+      let i = 0;
+      this._newAncestry = [];
+
+      while (true) {
+        let newAncestor = newLineage.pop();
+        let oldAncestor = oldLineage.pop();
+
+        if (newAncestor == undefined)
+          break;
+
+        if (newAncestor != oldAncestor)
+          this._newAncestry.push(newAncestor);
+        i++;
+      }
+
+    }
+
+    return this._newAncestry;
+  }
+};
--- a/accessible/src/xul/XULFormControlAccessible.cpp
+++ b/accessible/src/xul/XULFormControlAccessible.cpp
@@ -749,22 +749,21 @@ XULTextFieldAccessible::Value(nsString& 
   }
 
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
   if (menuList)
     menuList->GetLabel(aValue);
 }
 
 void
-XULTextFieldAccessible::ApplyARIAState(PRUint64* aState)
+XULTextFieldAccessible::ApplyARIAState(PRUint64* aState) const
 {
   nsHyperTextAccessibleWrap::ApplyARIAState(aState);
 
   aria::MapToState(aria::eARIAAutoComplete, mContent->AsElement(), aState);
-
 }
 
 PRUint64
 XULTextFieldAccessible::NativeState()
 {
   PRUint64 state = nsHyperTextAccessibleWrap::NativeState();
 
   nsCOMPtr<nsIContent> inputField(GetInputField());
--- a/accessible/src/xul/XULFormControlAccessible.h
+++ b/accessible/src/xul/XULFormControlAccessible.h
@@ -260,17 +260,17 @@ public:
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 
   // nsHyperTextAccessible
   virtual already_AddRefed<nsIEditor> GetEditor() const;
 
   // nsAccessible
   virtual void Value(nsString& aValue);
-  virtual void ApplyARIAState(PRUint64* aState);
+  virtual void ApplyARIAState(PRUint64* aState) const;
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual bool CanHaveAnonChildren();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
 protected:
--- a/accessible/src/xul/nsXULTextAccessible.cpp
+++ b/accessible/src/xul/nsXULTextAccessible.cpp
@@ -173,19 +173,19 @@ nsXULLinkAccessible::GetNameInternal(nsA
 role
 nsXULLinkAccessible::NativeRole()
 {
   return roles::LINK;
 }
 
 
 PRUint64
-nsXULLinkAccessible::NativeState()
+nsXULLinkAccessible::NativeLinkState() const
 {
-  return nsHyperTextAccessible::NativeState() | states::LINKED;
+  return states::LINKED;
 }
 
 PRUint8
 nsXULLinkAccessible::ActionCount()
 {
   return 1;
 }
 
--- a/accessible/src/xul/nsXULTextAccessible.h
+++ b/accessible/src/xul/nsXULTextAccessible.h
@@ -83,17 +83,17 @@ public:
   // nsIAccessible
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsAccessible
   virtual void Value(nsString& aValue);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
-  virtual PRUint64 NativeState();
+  virtual PRUint64 NativeLinkState() const;
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
   // HyperLinkAccessible
   virtual bool IsLink();
   virtual PRUint32 StartOffset();
   virtual PRUint32 EndOffset();
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -569,22 +569,21 @@ nsXULTreeAccessible::GetTreeItemAccessib
 
   void *key = reinterpret_cast<void*>(aRow);
   nsAccessible* cachedTreeItem = mAccessibleCache.GetWeak(key);
   if (cachedTreeItem)
     return cachedTreeItem;
 
   nsRefPtr<nsAccessible> treeItem = CreateTreeItemAccessible(aRow);
   if (treeItem) {
-    if (mAccessibleCache.Put(key, treeItem)) {
-      if (Document()->BindToDocument(treeItem, nsnull))
-        return treeItem;
+    mAccessibleCache.Put(key, treeItem);
+    if (Document()->BindToDocument(treeItem, nsnull))
+      return treeItem;
 
-      mAccessibleCache.Remove(key);
-    }
+    mAccessibleCache.Remove(key);
   }
 
   return nsnull;
 }
 
 void
 nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
 {
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -727,22 +727,21 @@ nsXULTreeGridRowAccessible::GetCellAcces
   nsAccessible* cachedCell = mAccessibleCache.GetWeak(key);
   if (cachedCell)
     return cachedCell;
 
   nsRefPtr<nsAccessible> cell =
     new nsXULTreeGridCellAccessibleWrap(mContent, mDoc, this, mTree,
                                         mTreeView, mRow, aColumn);
   if (cell) {
-    if (mAccessibleCache.Put(key, cell)) {
-      if (Document()->BindToDocument(cell, nsnull))
-        return cell;
+    mAccessibleCache.Put(key, cell);
+    if (Document()->BindToDocument(cell, nsnull))
+      return cell;
 
-      mAccessibleCache.Remove(key);
-    }
+    mAccessibleCache.Remove(key);
   }
 
   return nsnull;
 }
 
 void
 nsXULTreeGridRowAccessible::RowInvalidated(PRInt32 aStartColIdx,
                                            PRInt32 aEndColIdx)
--- a/accessible/tests/mochitest/states/test_link.html
+++ b/accessible/tests/mochitest/states/test_link.html
@@ -3,54 +3,99 @@
 <head>
   <title>HTML link states testing</title>
 
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
   <script type="application/javascript"
           src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
 
   <script type="application/javascript">
     function doTest()
     {
-      testStates("link1", STATE_LINKED);
-      testStates("link2", STATE_LINKED);
-      testStates("link3", STATE_LINKED);
-      testStates("link4", STATE_LINKED);
-      testStates("link5", 0, 0, STATE_LINKED);
+      // a@href and its text node
+      testStates("link_href", STATE_LINKED);
+      testStates(getAccessible("link_href").firstChild, STATE_LINKED);
+
+      // a@onclick
+      testStates("link_click", STATE_LINKED);
+
+      // a@onmousedown
+      testStates("link_mousedown", STATE_LINKED);
+
+      // a@onmouseup
+      testStates("link_mouseup", STATE_LINKED);
+
+      // a@role="link"
+      testStates("link_arialink", STATE_LINKED);
+
+      // a@role="button"
+      testStates("link_ariabutton", 0, 0, STATE_LINKED);
 
-      SimpleTest.finish();
+      // a (no @href, no click event listener)
+      testStates("link_notlink", 0, 0, STATE_LINKED);
+
+      // a: traversal state
+      testStates("link_traversed", 0, 0, STATE_TRAVERSED);
+      registerA11yEventListener(EVENT_DOCUMENT_LOAD_COMPLETE,
+                                traversedLinkTester);
+
+      synthesizeMouse(getNode("link_traversed"), 1, 1, { shiftKey: true });
     }
 
+    var traversedLinkTester = {
+      handleEvent: function traversedLinkTester_handleEvent(aEvent) {
+        unregisterA11yEventListener(EVENT_DOCUMENT_LOAD_COMPLETE,
+                                    traversedLinkTester);
+        aEvent.accessible.rootDocument.window.close();
+
+        testStates("link_traversed", STATE_TRAVERSED);
+        SimpleTest.finish();
+      }
+    };
+
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
 
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=423409"
      title="Expose click action if mouseup and mousedown are registered">
     Mozilla Bug 423409
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=754830"
+     title="Calculate link states separately">
+    Mozilla Bug 754830
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
-  <a id="link1" href="http://mozilla.org">link</a>
-  <a id="link2" onclick="">link</a>
-  <a id="link3" onmousedown="">link</a>
-  <a id="link4" onmouseup="">link</a>
-  <a id="link5">not link</a>
+  <a id="link_href" href="http://mozilla.org">link</a>
+  <a id="link_click" onclick="">link</a>
+  <a id="link_mousedown" onmousedown="">link</a>
+  <a id="link_mouseup" onmouseup="">link</a>
+  <a id="link_arialink" role="link">aria link</a>
+  <a id="link_ariabutton" role="button">aria button</a>
+  <a id="link_notlink">not link</a>
+
+  <a id="link_traversed" href="http://www.example.com" target="_top">example.com</a>
 
 </body>
 </html>
--- a/accessible/tests/mochitest/test_nsIAccessibleDocument.html
+++ b/accessible/tests/mochitest/test_nsIAccessibleDocument.html
@@ -4,27 +4,24 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <head>
   <title>nsIAccessibleDocument chrome tests</title>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
   <script type="application/javascript"
-    src="common.js"></script>
+          src="common.js"></script>
   <script type="application/javascript"
-    src="role.js"></script>
+          src="role.js"></script>
   <script type="application/javascript"
-    src="states.js"></script>
+          src="states.js"></script>
 
-  <!-- chrome-harness.js breaks this test (bug 736886) -->
-  <!--
   <script type="application/javascript"
-          src="chrome://mochikit/content/chrome-harness.js"/>
-  -->
+          src="chrome://mochikit/content/chrome-harness.js"></script>
 
   <script type="application/javascript">
     function doTest()
     {
       var docAcc = getAccessible(document, [nsIAccessibleDocument]);
       if (docAcc) {
         // nsIAccessible
         is(docAcc.name, "nsIAccessibleDocument chrome tests",
@@ -38,29 +35,27 @@ https://bugzilla.mozilla.org/show_bug.cg
         // No actions wanted on doc
         is(docAcc.numActions, 0, "Wrong number of actions for document!");
 
         // attributes should contain tag:body
         attributes = docAcc.attributes;
         is(attributes.getStringProperty("tag"), "body",
            "Wrong attribute on document!");
 
-        // nsIAccessibleDocument
-        // getRootDirectory() depends on broken chrome-harness.js include (bug
-        // 736886)
-        /*
+        // Document URL.
         var rootDir = getRootDirectory(window.location.href);
-        is(docAcc.URL, rootDir.path + "test_nsIAccessibleDocument.html",
+        is(docAcc.URL, rootDir + "test_nsIAccessibleDocument.html",
            "Wrong URL for document!");
-        */
-        todo(false, "chrome-harness.js include is broken (bug 736886)");
-        is(docAcc.title, "nsIAccessibleDocument chrome tests",        
+
+        // Document title and mime type.
+        is(docAcc.title, "nsIAccessibleDocument chrome tests",
            "Wrong title for document!");
         is(docAcc.mimeType, "text/html",
            "Wrong mime type for document!");
+
         // nsDocAccessible::getDocType currently returns NS_ERROR_FAILURE.
         // See bug 442005. After fixing, please remove this comment and
         // uncomment the below two lines to enable the test.
 //        is(docAcc.docType, "HTML",
 //           "Wrong type of document!");
 
         // Test for correct nsIDOMDocument retrieval.
         var domDoc = null;
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -619,17 +619,17 @@ SettingsListener.observe('language.curre
   request.onerror = function onError() {
     if (!idleTimeout)
       return;
 
     Services.idle.addIdleObserver(idleHandler, idleTimeout);
     power.addWakeLockListener(wakeLockHandler);
   };
 
-  SettingsListener.observe('power.screen.timeout', 30, function(value) {
+  SettingsListener.observe('power.screen.timeout', idleTimeout, function(value) {
     if (!value)
       return;
 
     Services.idle.removeIdleObserver(idleHandler, idleTimeout);
     idleTimeout = value;
     Services.idle.addIdleObserver(idleHandler, idleTimeout);
   });
 
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1337190282000">
   <emItems>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
@@ -56,18 +56,22 @@
       <emItem  blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
                         <versionRange  minVersion="1.0" maxVersion="1.0">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i39" id="{c2d64ff7-0ab8-4263-89c9-ea3b0f8f050c}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
-                        <versionRange  minVersion="0.1" maxVersion="14.4.0" severity="1">
+      <emItem  blockID="i92" id="play5@vide04flash.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
+                        <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i61" id="youtube@youtube3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                                 <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
@@ -151,20 +155,28 @@
       <emItem  blockID="i68" id="flashupdate@adobe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i90" id="videoplugin@player.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i91" id="crossriderapp4926@crossrider.com">
+                        <versionRange  minVersion="0" maxVersion="0.81.43" severity="1">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i84" id="pink@rosaplugin.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
+                        <versionRange  minVersion="0.1" maxVersion="14.4.0" severity="1">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i67" id="youtube2@youtube2.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i60" id="youtb3@youtb3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
--- a/browser/base/content/browser-thumbnails.js
+++ b/browser/base/content/browser-thumbnails.js
@@ -117,18 +117,18 @@ let gBrowserThumbnails = {
     this._timeouts.set(aBrowser, timeout);
   },
 
   _shouldCapture: function Thumbnails_shouldCapture(aBrowser) {
     // Capture only if it's the currently selected tab.
     if (aBrowser != gBrowser.selectedBrowser)
       return false;
 
-    // Don't capture in private browsing mode.
-    if (gPrivateBrowsingUI.privateBrowsingEnabled)
+    // Don't capture in per-window private browsing mode.
+    if (gPrivateBrowsingUI.privateWindow)
       return false;
 
     let doc = aBrowser.contentDocument;
 
     // FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as
     //       that currently regresses Talos SVG tests.
     if (doc instanceof SVGDocument || doc instanceof XMLDocument)
       return false;
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -8863,27 +8863,29 @@ let gPrivateBrowsingUI = {
   },
 
   /**
    * These accessors are used to support per-window Private Browsing mode.
    * For now the getter returns nsIPrivateBrowsingService.privateBrowsingEnabled,
    * and the setter should only be used in tests.
    */
   get privateWindow() {
-    return window.getInterface(Ci.nsIWebNavigation)
+    return window.QueryInterface(Ci.nsIInterfaceRequestor)
+                 .getInterface(Ci.nsIWebNavigation)
                  .QueryInterface(Ci.nsIDocShellTreeItem)
                  .treeOwner
                  .QueryInterface(Ci.nsIInterfaceRequestor)
                  .getInterface(Ci.nsIXULWindow)
                  .docShell.QueryInterface(Ci.nsILoadContext)
                  .usePrivateBrowsing;
   },
 
   set privateWindow(val) {
-    return window.getInterface(Ci.nsIWebNavigation)
+    return window.QueryInterface(Ci.nsIInterfaceRequestor)
+                 .getInterface(Ci.nsIWebNavigation)
                  .QueryInterface(Ci.nsIDocShellTreeItem)
                  .treeOwner
                  .QueryInterface(Ci.nsIInterfaceRequestor)
                  .getInterface(Ci.nsIXULWindow)
                  .docShell.QueryInterface(Ci.nsILoadContext)
                  .usePrivateBrowsing = val;
   }
 };
--- a/browser/components/preferences/advanced.js
+++ b/browser/components/preferences/advanced.js
@@ -56,16 +56,19 @@ var gAdvancedPane = {
     if (extraArgs && extraArgs["advancedTab"]){
       advancedPrefs.selectedTab = document.getElementById(extraArgs["advancedTab"]);
     } else {
       var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
       if (preference.value !== null)
         advancedPrefs.selectedIndex = preference.value;
     }
 
+#ifdef HAVE_SHELL_SERVICE
+    this.updateSetDefaultBrowser();
+#endif
 #ifdef MOZ_UPDATER
     this.updateReadPrefs();
 #endif
     this.updateOfflineApps();
 #ifdef MOZ_CRASHREPORTER
     this.initSubmitCrashes();
 #endif
     this.updateActualCacheSize("disk");
@@ -699,42 +702,31 @@ var gAdvancedPane = {
    * Preferences:
    *
    * browser.shell.checkDefault
    * - true if a default-browser check (and prompt to make it so if necessary)
    *   occurs at startup, false otherwise
    */
 
   /**
-   * Checks whether the browser is currently registered with the operating
-   * system as the default browser.  If the browser is not currently the
-   * default browser, the user is given the option of making it the default;
-   * otherwise, the user is informed that this browser already is the browser.
+   * Show button for setting browser as default browser or information that
+   * browser is already the default browser.
    */
-  checkNow: function ()
+  updateSetDefaultBrowser: function()
   {
     var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
                              .getService(Components.interfaces.nsIShellService);
-    var brandBundle = document.getElementById("bundleBrand");
-    var shellBundle = document.getElementById("bundleShell");
-    var brandShortName = brandBundle.getString("brandShortName");
-    var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
-    var promptMessage;
-    const IPS = Components.interfaces.nsIPromptService;
-    var psvc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                         .getService(IPS);
-    if (!shellSvc.isDefaultBrowser(false)) {
-      promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage", 
-                                                     [brandShortName]);
-      var rv = psvc.confirmEx(window, promptTitle, promptMessage, 
-                              IPS.STD_YES_NO_BUTTONS,
-                              null, null, null, null, { });
-      if (rv == 0)
-        shellSvc.setDefaultBrowser(true, false);
-    }
-    else {
-      promptMessage = shellBundle.getFormattedString("alreadyDefaultBrowser",
-                                                     [brandShortName]);
-      psvc.alert(window, promptTitle, promptMessage);
-    }
+    let selectedIndex = shellSvc.isDefaultBrowser(false) ? 1 : 0;
+    document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
+  },
+
+  /**
+   * Set browser as the operating system default browser.
+   */
+  setDefaultBrowser: function()
+  {
+    var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
+                             .getService(Components.interfaces.nsIShellService);
+    shellSvc.setDefaultBrowser(true, false);
+    document.getElementById("setDefaultPane").selectedIndex = 1;
   }
 #endif
 };
--- a/browser/components/preferences/advanced.xul
+++ b/browser/components/preferences/advanced.xul
@@ -199,24 +199,27 @@
                       preference="layout.spellcheckDefault"/>
           </groupbox>
 
           <!-- System Defaults -->
           <groupbox id="systemDefaultsGroup" orient="vertical">
             <caption label="&systemDefaults.label;"/>
 
 #ifdef HAVE_SHELL_SERVICE
-            <hbox id="checkDefaultBox" align="center" flex="1">      
-              <checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
-                        label="&alwaysCheckDefault.label;" accesskey="&alwaysCheckDefault.accesskey;"
-                        flex="1"/>
-              <button id="checkDefaultButton"
-                      label="&checkNow.label;" accesskey="&checkNow.accesskey;"
-                      oncommand="gAdvancedPane.checkNow()"
-                      preference="pref.general.disable_button.default_browser"/>
+            <checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
+                      label="&alwaysCheckDefault.label;" accesskey="&alwaysCheckDefault.accesskey;"
+                      flex="1"/>
+            <hbox class="indent">
+              <deck id="setDefaultPane">
+                <button id="setDefaultButton"
+                        label="&setDefault.label;" accesskey="&setDefault.accesskey;"
+                        oncommand="gAdvancedPane.setDefaultBrowser();"
+                        preference="pref.general.disable_button.default_browser"/>
+                <description>&isDefault.label;</description>
+              </deck>
             </hbox>
 #ifdef MOZ_CRASHREPORTER
             <checkbox id="submitCrashesBox" flex="1"
                       oncommand="gAdvancedPane.updateSubmitCrashes();"
                       label="&submitCrashes.label;" accesskey="&submitCrashes.accesskey;"/>
 #endif
 #endif
             <checkbox id="submitTelemetryBox" flex="1"
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -15,16 +15,19 @@ var gAdvancedPane = {
   {
     this._inited = true;
     var advancedPrefs = document.getElementById("advancedPrefs");
 
     var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
     if (preference.value !== null)
         advancedPrefs.selectedIndex = preference.value;
 
+#ifdef HAVE_SHELL_SERVICE
+    this.updateSetDefaultBrowser();
+#endif
 #ifdef MOZ_UPDATER
     this.updateReadPrefs();
 #endif
     this.updateOfflineApps();
 #ifdef MOZ_CRASHREPORTER
     this.initSubmitCrashes();
 #endif
     this.updateActualCacheSize("disk");
@@ -662,42 +665,31 @@ var gAdvancedPane = {
    * Preferences:
    *
    * browser.shell.checkDefault
    * - true if a default-browser check (and prompt to make it so if necessary)
    *   occurs at startup, false otherwise
    */
 
   /**
-   * Checks whether the browser is currently registered with the operating
-   * system as the default browser.  If the browser is not currently the
-   * default browser, the user is given the option of making it the default;
-   * otherwise, the user is informed that this browser already is the browser.
+   * Show button for setting browser as default browser or information that
+   * browser is already the default browser.
    */
-  checkNow: function ()
+  updateSetDefaultBrowser: function()
   {
     var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
                              .getService(Components.interfaces.nsIShellService);
-    var brandBundle = document.getElementById("bundleBrand");
-    var shellBundle = document.getElementById("bundleShell");
-    var brandShortName = brandBundle.getString("brandShortName");
-    var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
-    var promptMessage;
-    const IPS = Components.interfaces.nsIPromptService;
-    var psvc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                         .getService(IPS);
-    if (!shellSvc.isDefaultBrowser(false)) {
-      promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
-                                                     [brandShortName]);
-      var rv = psvc.confirmEx(window, promptTitle, promptMessage,
-                              IPS.STD_YES_NO_BUTTONS,
-                              null, null, null, null, { });
-      if (rv == 0)
-        shellSvc.setDefaultBrowser(true, false);
-    }
-    else {
-      promptMessage = shellBundle.getFormattedString("alreadyDefaultBrowser",
-                                                     [brandShortName]);
-      psvc.alert(window, promptTitle, promptMessage);
-    }
+    let selectedIndex = shellSvc.isDefaultBrowser(false) ? 1 : 0;
+    document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
+  },
+
+  /**
+   * Set browser as the operating system default browser.
+   */
+  setDefaultBrowser: function()
+  {
+    var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
+                             .getService(Components.interfaces.nsIShellService);
+    shellSvc.setDefaultBrowser(true, false);
+    document.getElementById("setDefaultPane").selectedIndex = 1;
   }
 #endif
 };
--- a/browser/components/preferences/in-content/advanced.xul
+++ b/browser/components/preferences/in-content/advanced.xul
@@ -184,24 +184,27 @@
                   onsynctopreference="return gAdvancedPane.writeCheckSpelling();"
                   preference="layout.spellcheckDefault"/>
       </groupbox>
       <!-- System Defaults -->
       <groupbox id="systemDefaultsGroup" orient="vertical">
         <caption label="&systemDefaults.label;"/>
 
 #ifdef HAVE_SHELL_SERVICE
-        <hbox id="checkDefaultBox" align="center" flex="1">
-          <checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
-                    label="&alwaysCheckDefault.label;" accesskey="&alwaysCheckDefault.accesskey;"
-                    flex="1"/>
-          <button id="checkDefaultButton"
-                  label="&checkNow.label;" accesskey="&checkNow.accesskey;"
-                  oncommand="gAdvancedPane.checkNow()"
-                  preference="pref.general.disable_button.default_browser"/>
+        <checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
+                      label="&alwaysCheckDefault.label;" accesskey="&alwaysCheckDefault.accesskey;"
+                      flex="1"/>
+        <hbox class="indent">
+          <deck id="setDefaultPane">
+            <button id="setDefaultButton"
+                    label="&setDefault.label;" accesskey="&setDefault.accesskey;"
+                    oncommand="gAdvancedPane.setDefaultBrowser();"
+                    preference="pref.general.disable_button.default_browser"/>
+            <description>&isDefault.label;</description>
+          </deck>
         </hbox>
 #ifdef MOZ_CRASHREPORTER
         <checkbox id="submitCrashesBox" flex="1"
                   oncommand="gAdvancedPane.updateSubmitCrashes();"
                   label="&submitCrashes.label;" accesskey="&submitCrashes.accesskey;"/>
 #endif
 #endif
         <checkbox id="submitTelemetryBox" flex="1"
--- a/browser/components/preferences/in-content/sync.js
+++ b/browser/components/preferences/in-content/sync.js
@@ -60,17 +60,17 @@ let gSyncPane = {
     if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
         Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
       this.page = PAGE_NO_ACCOUNT;
     } else if (Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE ||
                Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
       this.needsUpdate();
     } else {
       this.page = PAGE_HAS_ACCOUNT;
-      document.getElementById("accountName").value = Weave.Service.account;
+      document.getElementById("accountName").value = Weave.Identity.account;
       document.getElementById("syncComputerName").value = Weave.Clients.localName;
       document.getElementById("tosPP").hidden = this._usingCustomServer;
     }
   },
 
   startOver: function (showDialog) {
     if (showDialog) {
       let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -90,16 +90,17 @@ const STATE_RESTORE_FINISHED = 3;
 function PrivateBrowsingService() {
   this._obs = Cc["@mozilla.org/observer-service;1"].
               getService(Ci.nsIObserverService);
   this._obs.addObserver(this, "profile-after-change", true);
   this._obs.addObserver(this, "quit-application-granted", true);
   this._obs.addObserver(this, "private-browsing", true);
   this._obs.addObserver(this, "command-line-startup", true);
   this._obs.addObserver(this, "sessionstore-browser-state-restored", true);
+  this._obs.addObserver(this, "domwindowopened", true);
 
   // List of nsIXULWindows we are going to be closing during the transition
   this._windowsToClose = [];
 }
 
 PrivateBrowsingService.prototype = {
   // Preferences Service
   get _prefs() {
@@ -147,16 +148,27 @@ PrivateBrowsingService.prototype = {
 
   _unload: function PBS__destroy() {
     // Force an exit from the private browsing mode on shutdown
     this._quitting = true;
     if (this._inPrivateBrowsing)
       this.privateBrowsingEnabled = false;
   },
 
+  _setPerWindowPBFlag: function PBS__setPerWindowPBFlag(aWindow, aFlag) {
+    aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+           .getInterface(Ci.nsIWebNavigation)
+           .QueryInterface(Ci.nsIDocShellTreeItem)
+           .treeOwner
+           .QueryInterface(Ci.nsIInterfaceRequestor)
+           .getInterface(Ci.nsIXULWindow)
+           .docShell.QueryInterface(Ci.nsILoadContext)
+           .usePrivateBrowsing = aFlag;
+  },
+
   _onBeforePrivateBrowsingModeChange: function PBS__onBeforePrivateBrowsingModeChange() {
     // nothing needs to be done here if we're enabling at startup
     if (!this._autoStarted) {
       let ss = Cc["@mozilla.org/browser/sessionstore;1"].
                getService(Ci.nsISessionStore);
       let blankState = JSON.stringify({
         "windows": [{
           "tabs": [{
@@ -217,33 +229,25 @@ PrivateBrowsingService.prototype = {
           browserWindow.getInterface(Ci.nsIWebNavigation)
                        .QueryInterface(Ci.nsIDocShellTreeItem)
                        .treeOwner
                        .QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIXULWindow)
                        .docShell.contentViewer.resetCloseWindow();
         }
       }
-
-      if (!this._quitting) {
-        var windowsEnum = Services.wm.getEnumerator("navigator:browser");
-        while (windowsEnum.hasMoreElements()) {
-          var window = windowsEnum.getNext();
-          window.getInterface(Ci.nsIWebNavigation)
-                .QueryInterface(Ci.nsIDocShellTreeItem)
-                .treeOwner
-                .QueryInterface(Ci.nsIInterfaceRequestor)
-                .getInterface(Ci.nsIXULWindow)
-                .docShell.QueryInterface(Ci.nsILoadContext)
-                .usePrivateBrowsing = this._inPrivateBrowsing;
-        }
-      }
     }
     else
       this._saveSession = false;
+
+    var windowsEnum = Services.wm.getEnumerator("navigator:browser");
+    while (windowsEnum.hasMoreElements()) {
+      var window = windowsEnum.getNext();
+      this._setPerWindowPBFlag(window, this._inPrivateBrowsing);
+    }
   },
 
   _onAfterPrivateBrowsingModeChange: function PBS__onAfterPrivateBrowsingModeChange() {
     // nothing to do here if we're enabling at startup or the current session is being
     // used
     if (!this._autoStarted && this._saveSession) {
       let ss = Cc["@mozilla.org/browser/sessionstore;1"].
                getService(Ci.nsISessionStore);
@@ -518,16 +522,28 @@ PrivateBrowsingService.prototype = {
         }
         break;
       case "sessionstore-browser-state-restored":
         if (this._currentStatus == STATE_WAITING_FOR_RESTORE) {
           this._currentStatus = STATE_RESTORE_FINISHED;
           this._notifyIfTransitionComplete();
         }
         break;
+      case "domwindowopened":
+        let aWindow = aSubject;
+        let self = this;
+        aWindow.addEventListener("load", function PBS__onWindowLoad(aEvent) {
+          aWindow.removeEventListener("load", arguments.callee);
+          if (aWindow.document
+                     .documentElement
+                     .getAttribute("windowtype") == "navigator:browser") {
+            self._setPerWindowPBFlag(aWindow, self._inPrivateBrowsing);
+          }
+        }, false);
+        break;
     }
   },
 
   // nsICommandLineHandler
 
   handle: function PBS_handle(aCmdLine) {
     if (aCmdLine.handleFlag("private", false))
       aCmdLine.preventDefault = true; // It has already been handled
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
@@ -35,71 +35,101 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // This test makes sure that the gPrivateBrowsingUI object, the Private Browsing
 // menu item and its XUL <command> element work correctly.
 
 function test() {
   // initialization
+  waitForExplicitFinish();
   gPrefService.setBoolPref("browser.privatebrowsing.keep_current_session", true);
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
   let observerData;
   function observer(aSubject, aTopic, aData) {
     if (aTopic == "private-browsing")
       observerData = aData;
   }
   Services.obs.addObserver(observer, "private-browsing", false);
   let pbMenuItem = document.getElementById("privateBrowsingItem");
   // add a new blank tab to ensure the title can be meaningfully compared later
   gBrowser.selectedTab = gBrowser.addTab();
   let originalTitle = document.title;
 
+  function testNewWindow(aCallback, expected) {
+    Services.obs.addObserver(function observer1(aSubject, aTopic, aData) {
+      aSubject.addEventListener("load", function() {
+        aSubject.removeEventListener("load", arguments.callee);
+        executeSoon(function() {
+          let ui = aSubject.gPrivateBrowsingUI;
+          is(ui.privateBrowsingEnabled, expected, "The privateBrowsingEnabled property on the new window is set correctly");
+          is(ui.privateWindow, expected, "The privateWindow property on the new window is set correctly");
+
+          Services.obs.addObserver(function observer2(aSubject, aTopic, aData) {
+            aCallback();
+            Services.obs.removeObserver(observer2, "domwindowclosed");
+          }, "domwindowclosed", false);
+          aSubject.close();
+        });
+        Services.obs.removeObserver(observer1, "domwindowopened");
+      }, false);
+    }, "domwindowopened", false);
+    OpenBrowserWindow();
+  }
+
   // test the gPrivateBrowsingUI object
   ok(gPrivateBrowsingUI, "The gPrivateBrowsingUI object exists");
   is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started initially");
   is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
   is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
   ok(pbMenuItem, "The Private Browsing menu item exists");
   is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
-  gPrivateBrowsingUI.toggleMode();
-  is(pb.privateBrowsingEnabled, true, "The private browsing mode should be started");
-  is(gPrivateBrowsingUI.privateBrowsingEnabled, true, "gPrivateBrowsingUI should expose the correct private browsing status");
-  is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
-  // check to see if the Private Browsing mode was activated successfully
-  is(observerData, "enter", "Private Browsing mode was activated using the gPrivateBrowsingUI object");
-  is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("stoplabel"), "The Private Browsing menu item should read \"Stop Private Browsing\"");
-  gPrivateBrowsingUI.toggleMode()
-  is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started");
-  is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
-  is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
-  // check to see if the Private Browsing mode was deactivated successfully
-  is(observerData, "exit", "Private Browsing mode was deactivated using the gPrivateBrowsingUI object");
-  is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
+  testNewWindow(function() {
+    gPrivateBrowsingUI.toggleMode();
+    is(pb.privateBrowsingEnabled, true, "The private browsing mode should be started");
+    is(gPrivateBrowsingUI.privateBrowsingEnabled, true, "gPrivateBrowsingUI should expose the correct private browsing status");
+    is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
+    // check to see if the Private Browsing mode was activated successfully
+    is(observerData, "enter", "Private Browsing mode was activated using the gPrivateBrowsingUI object");
+    is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("stoplabel"), "The Private Browsing menu item should read \"Stop Private Browsing\"");
+    testNewWindow(function() {
+      gPrivateBrowsingUI.toggleMode()
+      is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started");
+      is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
+      is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
+      // check to see if the Private Browsing mode was deactivated successfully
+      is(observerData, "exit", "Private Browsing mode was deactivated using the gPrivateBrowsingUI object");
+      is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
+
+      testNewWindow(function() {
+        // These are tests for the privateWindow setter.  Note that the setter should
+        // not be used anywhere else for now!
+        gPrivateBrowsingUI.privateWindow = true;
+        is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
+        gPrivateBrowsingUI.privateWindow = false;
+        is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
 
-  // These are tests for the privateWindow setter.  Note that the setter should
-  // not be used anywhere else for now!
-  gPrivateBrowsingUI.privateWindow = true;
-  is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
-  gPrivateBrowsingUI.privateWindow = false;
-  is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
+        // now, test using the <command> object
+        let cmd = document.getElementById("Tools:PrivateBrowsing");
+        isnot(cmd, null, "XUL command object for the private browsing service exists");
+        var func = new Function("", cmd.getAttribute("oncommand"));
+        func.call(cmd);
+        // check to see if the Private Browsing mode was activated successfully
+        is(observerData, "enter", "Private Browsing mode was activated using the command object");
+        // check to see that the window title has been changed correctly
+        isnot(document.title, originalTitle, "Private browsing mode has correctly changed the title");
+        func.call(cmd);
+        // check to see if the Private Browsing mode was deactivated successfully
+        is(observerData, "exit", "Private Browsing mode was deactivated using the command object");
+        // check to see that the window title has been restored correctly
+        is(document.title, originalTitle, "Private browsing mode has correctly restored the title");
 
-  // now, test using the <command> object
-  let cmd = document.getElementById("Tools:PrivateBrowsing");
-  isnot(cmd, null, "XUL command object for the private browsing service exists");
-  var func = new Function("", cmd.getAttribute("oncommand"));
-  func.call(cmd);
-  // check to see if the Private Browsing mode was activated successfully
-  is(observerData, "enter", "Private Browsing mode was activated using the command object");
-  // check to see that the window title has been changed correctly
-  isnot(document.title, originalTitle, "Private browsing mode has correctly changed the title");
-  func.call(cmd);
-  // check to see if the Private Browsing mode was deactivated successfully
-  is(observerData, "exit", "Private Browsing mode was deactivated using the command object");
-  // check to see that the window title has been restored correctly
-  is(document.title, originalTitle, "Private browsing mode has correctly restored the title");
+        // cleanup
+        gBrowser.removeCurrentTab();
+        Services.obs.removeObserver(observer, "private-browsing");
+        gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
 
-  // cleanup
-  gBrowser.removeCurrentTab();
-  Services.obs.removeObserver(observer, "private-browsing");
-  gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
+        finish();
+      }, false);
+    }, true);
+  }, false);
 }
--- a/browser/config/mozconfigs/win32/nightly
+++ b/browser/config/mozconfigs/win32/nightly
@@ -19,8 +19,14 @@ mk_add_options MOZ_MAKE_FLAGS=-j1
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+# For known full-clobber builds on Windows (like nightlies/try), 
+# this speeds things up. IS_NIGHTLY is set by the build automation.
+if test "$IS_NIGHTLY" != ""; then 
+  ac_add_options --disable-auto-deps
+fi
--- a/browser/config/mozconfigs/win64/nightly
+++ b/browser/config/mozconfigs/win64/nightly
@@ -17,9 +17,15 @@ export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
 mk_add_options MOZ_MAKE_FLAGS=-j1
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
+# For known full-clobber builds on Windows (like nightlies/try), 
+# this speeds things up. IS_NIGHTLY is set by the build automation.
+if test "$IS_NIGHTLY" != ""; then 
+  ac_add_options --disable-auto-deps
+fi
+
 . $topsrcdir/build/win64/mozconfig.vs2010
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
@@ -71,27 +71,28 @@ function testFrameParameters()
         "Should have the right property value for 'dArg'.");
 
       is(localNodes[5].querySelector(".info").textContent, "null",
         "Should have the right property value for 'eArg'.");
 
       is(localNodes[6].querySelector(".info").textContent, "undefined",
         "Should have the right property value for 'fArg'.");
 
-      is(localNodes[7].querySelector(".info").textContent, "1",
-        "Should have the right property value for 'a'.");
-
-      is(localNodes[8].querySelector(".info").textContent, "[object Object]",
-        "Should have the right property value for 'b'.");
+      // FIXME bug TODO: reenable
+      //is(localNodes[7].querySelector(".info").textContent, "1",
+      //  "Should have the right property value for 'a'.");
 
-      is(localNodes[9].querySelector(".info").textContent, "[object Object]",
-        "Should have the right property value for 'c'.");
+      //is(localNodes[8].querySelector(".info").textContent, "[object Object]",
+      //  "Should have the right property value for 'b'.");
 
-      is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
-        "Should have the right property value for 'arguments'.");
+      //is(localNodes[9].querySelector(".info").textContent, "[object Object]",
+      //  "Should have the right property value for 'c'.");
+
+      //is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
+      //  "Should have the right property value for 'arguments'.");
 
       resumeAndFinish();
     }}, 0);
   }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
     content.window);
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
@@ -91,27 +91,27 @@ function testFrameParameters()
         is(localNodes[9].querySelectorAll(".property > .title > .key")[1]
                         .textContent, "a",
           "Should have the right property name for 'a'.");
 
         is(localNodes[9].querySelectorAll(".property > .title > .value")[1]
                         .textContent, 1,
           "Should have the right value for 'c.a'.");
 
-        is(localNodes[10].querySelector(".info").textContent,
-          "[object Arguments]",
-          "Should have the right property value for 'arguments'.");
+        //is(localNodes[10].querySelector(".info").textContent,
+        //  "[object Arguments]",
+        //  "Should have the right property value for 'arguments'.");
 
-        is(localNodes[10].querySelector(".property > .title > .key")
-                        .textContent, "length",
-          "Should have the right property name for 'length'.");
+        //is(localNodes[10].querySelector(".property > .title > .key")
+        //                .textContent, "length",
+        //  "Should have the right property name for 'length'.");
 
-        is(localNodes[10].querySelector(".property > .title > .value")
-                        .textContent, 5,
-          "Should have the right argument length.");
+        //is(localNodes[10].querySelector(".property > .title > .value")
+        //                .textContent, 5,
+        //  "Should have the right argument length.");
 
         resumeAndFinish();
       }, 100);
     }}, 0);
   }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
--- a/browser/devtools/sourceeditor/orion/orion.js
+++ b/browser/devtools/sourceeditor/orion/orion.js
@@ -11270,17 +11270,17 @@ define("examples/textview/textStyler", [
 		 "overflow-y", "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before",
 		 "page-break-inside", "page-policy", "pause", "pause-after", "pause-before", "perspective", "perspective-origin", "phonemes", "pitch",
 		 "pitch-range", "play-during", "position", "presentation-level", "punctuation-trim", "quotes", "rendering-intent", "resize",
 		 "rest", "rest-after", "rest-before", "richness", "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", "ruby-position",
 		 "ruby-span", "size", "speak", "speak-header", "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", "table-layout",
 		 "target", "target-name", "target-new", "target-position", "text-align", "text-align-last", "text-decoration", "text-emphasis",
 		 "text-height", "text-indent", "text-justify", "text-outline", "text-shadow", "text-transform", "text-wrap", "top", "transform",
 		 "transform-origin", "transform-style", "transition", "transition-delay", "transition-duration", "transition-property",
-		 "transition-timing-function", "unicode-bidi", "vertical-align", "visibility", "voice-balance", "voice-duration", "voice-family",
+		 "transition-timing-function", "unicode-bidi", "vector-effect", "vertical-align", "visibility", "voice-balance", "voice-duration", "voice-family",
 		 "voice-pitch", "voice-pitch-range", "voice-rate", "voice-stress", "voice-volume", "volume", "white-space", "white-space-collapse",
 		 "widows", "width", "word-break", "word-spacing", "word-wrap", "z-index"
 		];
 
 	// Scanner constants
 	var UNKOWN = 1;
 	var KEYWORD = 2;
 	var STRING = 3;
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
@@ -20,18 +20,19 @@
 <!ENTITY allowHWAccel.label              "Use hardware acceleration when available">
 <!ENTITY allowHWAccel.accesskey          "r">
 <!ENTITY checkSpelling.label             "Check my spelling as I type">
 <!ENTITY checkSpelling.accesskey         "t">
 
 <!ENTITY systemDefaults.label            "System Defaults">
 <!ENTITY alwaysCheckDefault.label        "Always check to see if &brandShortName; is the default browser on startup"><!--XXX-->
 <!ENTITY alwaysCheckDefault.accesskey    "w">
-<!ENTITY checkNow.label                  "Check Now">
-<!ENTITY checkNow.accesskey              "N">
+<!ENTITY setDefault.label                "Make &brandShortName; the default browser">
+<!ENTITY setDefault.accesskey            "d">
+<!ENTITY isDefault.label                 "&brandShortName; is currently your default browser">
 <!ENTITY submitCrashes.label             "Submit crash reports">
 <!ENTITY submitCrashes.accesskey         "S">
 <!ENTITY submitTelemetry.label           "Submit performance data">
 <!ENTITY submitTelemetry.accesskey       "P">
 
 <!ENTITY networkTab.label                "Network">
 
 <!ENTITY connection.label                "Connection">
--- a/build/autoconf/test/makemakefile.tpm
+++ b/build/autoconf/test/makemakefile.tpm
@@ -115,17 +115,17 @@ sub check_getTopDir
     print "Running: check_getTopDir\n" if ($main::argv{debug});
 
     my $path = getTopDir();
 
     ## Unit test is special, cmd not invoked from the same directory
     ## as the makemakefile.pm module.
     ok($path ? 1 : 0, 1, "getTopDir failed");
     ok(-d $path ? 1 : 0, 1, "getTopDir: directory $path does not exist");
-    ok($FindBin::RealBin =~ m%$path/% ? 1 : 0, 1, 'Invalid topdir path');
+    ok($FindBin::RealBin =~ m%\Q$path/% ? 1 : 0, 1, 'Invalid topdir path');
     ok(-e "$path/client.mk" ? 1 : 0, 1, "client.mk not found in $path");
 } # check_getTopDir
 
 ###########################################################################
 ## Intent: Verify objdir lookup function
 ###########################################################################
 sub check_getObjDir
 {
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -454,17 +454,17 @@ def wrapCommand(cmd):
   return cmd
 
 class ShutdownLeakLogger(object):
   """
   Parses the mochitest run log when running a debug build, assigns all leaked
   DOM windows (that are still around after test suite shutdown, despite running
   the GC) to the tests that created them and prints leak statistics.
   """
-  MAX_LEAK_COUNT = 10
+  MAX_LEAK_COUNT = 7
 
   def __init__(self, logger):
     self.logger = logger
     self.tests = []
     self.leakedWindows = {}
     self.leakedDocShells = set()
     self.currentTest = None
     self.seenShutdown = False
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -40,17 +40,17 @@ topsrcdir   = @top_srcdir@
 srcdir      = @srcdir@
 VPATH       = @srcdir@
 TESTPATH    = $(topsrcdir)/mobile/android/base/tests
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = robocop
 
-ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.1.jar
+ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.2.1.jar
 
 JAVAFILES = \
   R.java \
 
 _JAVA_HARNESS = \
   Actions.java \
   Assert.java \
   Driver.java \
--- a/build/mobile/robocop/README
+++ b/build/mobile/robocop/README
@@ -1,9 +1,9 @@
 Robocop is a Mozilla project which uses Robotium to test Firefox on Android devices.
 
 Robotium is an open source tool licensed under the Apache 2.0 license and the original 
 source can be found here:
 http://code.google.com/p/robotium/
 
-We are including robotium-solo-3.1.jar as a binary and are not modifying it in anyway 
+We are including robotium-solo-3.2.1.jar as a binary and are not modifying it in anyway 
 from the original download found at: 
 http://code.google.com/p/robotium/
deleted file mode 100644
index 0ba05859b90a8c29ca519e228674db9aebe69d90..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f4107c7496ec18d7a5fc2fe56742036ef3861bb7
GIT binary patch
literal 52121
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
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -43,17 +43,18 @@ def run_in(path, args):
 
 def patch(patch, plevel, srcdir):
     patch = os.path.realpath(patch)
     check_run(['patch', '-d', srcdir, '-p%s' % plevel, '-i', patch, '--fuzz=0',
                '-s'])
 
 def build_package(package_source_dir, package_build_dir, configure_args,
                    make = old_make):
-    os.mkdir(package_build_dir)
+    if not os.path.exists(package_build_dir):
+        os.mkdir(package_build_dir)
     run_in(package_build_dir,
            ["%s/configure" % package_source_dir] + configure_args)
     run_in(package_build_dir, [make, "-j8"])
     run_in(package_build_dir, [make, "install"])
 
 def build_aux_tools(base_dir):
     make_build_dir = base_dir + '/make_build'
     build_package(make_source_dir, make_build_dir,
@@ -156,16 +157,22 @@ def build_one_stage_aux(stage_dir, is_st
 
     tool_inst_dir = stage_dir + '/inst'
     os.mkdir(tool_inst_dir)
     os.mkdir(tool_inst_dir + '/lib64')
     os.symlink('lib64', tool_inst_dir + '/lib')
 
     build_linux_headers(tool_inst_dir)
 
+    # zlib's configure only works if run from the source dir, copy the source
+    zlib_build_dir = stage_dir + '/zlib'
+    shutil.copytree(zlib_source_dir, zlib_build_dir)
+    build_package(zlib_build_dir, zlib_build_dir,
+                  ["--prefix=%s" % tool_inst_dir])
+
     binutils_build_dir = stage_dir + '/binutils'
     build_package(binutils_source_dir, binutils_build_dir,
                   ["--prefix=%s" % tool_inst_dir,
                    "--without-zlib"])
 
     # During stage one we have to build gcc first, this glibc doesn't even
     # build with gcc 4.6. During stage two, we have to build glibc first.
     # The problem is that libstdc++ is built with xgcc and if glibc has
@@ -192,16 +199,17 @@ def build_source_dir(prefix, version):
 binutils_version = "2.21.1"
 glibc_version = "2.5.1"
 linux_version = "2.6.18"
 tar_version = "1.26"
 gawk_version = "3.1.5"
 make_version = "3.81"
 gcc_version = "4.5.2"
 mpfr_version = "2.4.2"
+zlib_version = "1.2.3"
 gmp_version = "5.0.1"
 mpc_version = "0.8.1"
 unifdef_version = "2.6"
 
 binutils_source_uri = "http://ftp.gnu.org/gnu/binutils/binutils-%sa.tar.bz2" % \
     binutils_version
 glibc_source_uri = "http://ftp.gnu.org/gnu/glibc/glibc-%s.tar.bz2" % \
     glibc_version
@@ -214,41 +222,44 @@ gawk_source_uri = "http://ftp.gnu.org/gn
 make_source_uri = "http://ftp.gnu.org/gnu/make/make-%s.tar.bz2" % \
     make_version
 unifdef_source_uri = "http://dotat.at/prog/unifdef/unifdef-%s.tar.gz" % \
     unifdef_version
 gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \
     (gcc_version, gcc_version)
 mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \
     (mpfr_version, mpfr_version)
+zlib_source_uri = "http://iweb.dl.sourceforge.net/project/libpng/zlib/%s/zlib-%s.tar.bz2" % (zlib_version, zlib_version)
 gmp_source_uri = "http://ftp.gnu.org/gnu/gmp/gmp-%s.tar.bz2" % gmp_version
 mpc_source_uri = "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % \
     mpc_version
 
 binutils_source_tar = download_uri(binutils_source_uri)
 glibc_source_tar = download_uri(glibc_source_uri)
 linux_source_tar = download_uri(linux_source_uri)
 tar_source_tar = download_uri(tar_source_uri)
 gawk_source_tar = download_uri(gawk_source_uri)
 make_source_tar = download_uri(make_source_uri)
 unifdef_source_tar = download_uri(unifdef_source_uri)
 mpc_source_tar = download_uri(mpc_source_uri)
 mpfr_source_tar = download_uri(mpfr_source_uri)
+zlib_source_tar = download_uri(zlib_source_uri)
 gmp_source_tar = download_uri(gmp_source_uri)
 gcc_source_tar = download_uri(gcc_source_uri)
 
 binutils_source_dir  = build_source_dir('binutils-', binutils_version)
 glibc_source_dir  = build_source_dir('glibc-', glibc_version)
 linux_source_dir  = build_source_dir('linux-', linux_version)
 tar_source_dir  = build_source_dir('tar-', tar_version)
 gawk_source_dir  = build_source_dir('gawk-', gawk_version)
 make_source_dir  = build_source_dir('make-', make_version)
 unifdef_source_dir  = build_source_dir('unifdef-', unifdef_version)
 mpc_source_dir  = build_source_dir('mpc-', mpc_version)
 mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
+zlib_source_dir = build_source_dir('zlib-', zlib_version)
 gmp_source_dir  = build_source_dir('gmp-', gmp_version)
 gcc_source_dir  = build_source_dir('gcc-', gcc_version)
 
 if not os.path.exists(source_dir):
     os.makedirs(source_dir)
     extract(binutils_source_tar, source_dir)
     patch('binutils-deterministic.patch', 1, binutils_source_dir)
     extract(glibc_source_tar, source_dir)
@@ -256,16 +267,17 @@ if not os.path.exists(source_dir):
     patch('glibc-deterministic.patch', 1, glibc_source_dir)
     run_in(glibc_source_dir, ["autoconf"])
     extract(tar_source_tar, source_dir)
     extract(gawk_source_tar, source_dir)
     extract(make_source_tar, source_dir)
     extract(unifdef_source_tar, source_dir)
     extract(mpc_source_tar, source_dir)
     extract(mpfr_source_tar, source_dir)
+    extract(zlib_source_tar, source_dir)
     extract(gmp_source_tar, source_dir)
     extract(gcc_source_tar, source_dir)
     patch('plugin_finish_decl.diff', 0, gcc_source_dir)
     patch('libtool-74c8993c178a1386ea5e2363a01d919738402f30.patch', 1, gcc_source_dir)
     patch('pr49911.diff', 1, gcc_source_dir)
     patch('r159628-r163231-r171807.patch', 1, gcc_source_dir)
     patch('gcc-fixinc.patch', 1, gcc_source_dir)
     patch('gcc-include.patch', 1, gcc_source_dir)
@@ -279,26 +291,21 @@ build_aux_tools(build_dir)
 basic_path = aux_inst_dir + "/bin:/bin:/usr/bin"
 
 stage1_dir = build_dir + '/stage1'
 build_one_stage({"PATH"   : basic_path,
                  "CC"     : "gcc",
                  "CXX"    : "g++" },
                 stage1_dir, True)
 
-stage1_tool_inst_dir = stage1_dir + '/inst'
-stage2_dir = build_dir + '/stage2'
-build_one_stage({"PATH"   : stage1_tool_inst_dir + "/bin:" + basic_path,
-                 "CC"     : "gcc -fgnu89-inline",
-                 "CXX"    : "g++",
-                 "RANLIB" : "true" },
-                stage2_dir, False)
+for stage_num in range(2, 4):
+    prev_stage_dir = build_dir + '/stage' + str(stage_num - 1)
+    prev_stage_inst_dir = prev_stage_dir + '/inst'
+    cur_stage_dir = build_dir + '/stage' + str(stage_num)
+    build_one_stage({"PATH"   : prev_stage_inst_dir + "/bin:" + basic_path,
+                     "CC"     : "gcc -fgnu89-inline",
+                     "CXX"    : "g++",
+                     "RANLIB" : "true" },
+                    cur_stage_dir, False)
 
-stage2_tool_inst_dir = stage2_dir + '/inst'
 stage3_dir = build_dir + '/stage3'
-build_one_stage({"PATH"   : stage2_tool_inst_dir + "/bin:" + basic_path,
-                 "CC"     : "gcc -fgnu89-inline",
-                 "CXX"    : "g++",
-                 "RANLIB" : "true" },
-                stage3_dir, False)
-
 build_tar_package(aux_inst_dir + "/bin/tar",
                   "toolchain.tar", stage3_dir, "inst")
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -421,18 +421,18 @@ public:
 
 private:
 
     // GetScriptSecurityManager is the only call that can make one
     nsScriptSecurityManager();
     virtual ~nsScriptSecurityManager();
 
     static JSBool
-    CheckObjectAccess(JSContext *cx, JSObject *obj,
-                      jsid id, JSAccessMode mode,
+    CheckObjectAccess(JSContext *cx, JSHandleObject obj,
+                      JSHandleId id, JSAccessMode mode,
                       jsval *vp);
 
     static JSPrincipals *
     ObjectPrincipalFinder(JSObject *obj);
     
     // Decides, based on CSP, whether or not eval() and stuff can be executed.
     static JSBool
     ContentSecurityPolicyPermitsJSAction(JSContext *cx);
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -39,16 +39,17 @@
  * 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 "mozilla/Util.h"
 
 #include "xpcprivate.h"
+#include "XPCWrapper.h"
 #include "nsScriptSecurityManager.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsIURL.h"
 #include "nsINestedURI.h"
 #include "nspr.h"
 #include "nsJSPrincipals.h"
@@ -625,18 +626,18 @@ nsScriptSecurityManager::ContentSecurity
                                  lineNum);
     }
 
     return evalOK;
 }
 
 
 JSBool
-nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSObject *obj,
-                                           jsid id, JSAccessMode mode,
+nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSHandleObject obj,
+                                           JSHandleId id, JSAccessMode mode,
                                            jsval *vp)
 {
     // Get the security manager
     nsScriptSecurityManager *ssm =
         nsScriptSecurityManager::GetScriptSecurityManager();
 
     NS_ASSERTION(ssm, "Failed to get security manager service");
     if (!ssm)
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -170,18 +170,17 @@ nsChromeRegistry::GetService()
   }
   NS_ADDREF(gChromeRegistry);
   return gChromeRegistry;
 }
 
 nsresult
 nsChromeRegistry::Init()
 {
-  if (!mOverrideTable.Init())
-    return NS_ERROR_FAILURE;
+  mOverrideTable.Init();
 
   // This initialization process is fairly complicated and may cause reentrant
   // getservice calls to resolve chrome URIs (especially locale files). We
   // don't want that, so we inform the protocol handler about our existence
   // before we are actually fully initialized.
   gChromeRegistry = this;
 
   mInitialized = true;
--- a/chrome/src/nsChromeRegistryChrome.cpp
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -150,19 +150,18 @@ nsChromeRegistryChrome::~nsChromeRegistr
 
 nsresult
 nsChromeRegistryChrome::Init()
 {
   nsresult rv = nsChromeRegistry::Init();
   if (NS_FAILED(rv))
     return rv;
 
-  if (!mOverlayHash.Init() ||
-      !mStyleHash.Init())
-    return NS_ERROR_FAILURE;
+  mOverlayHash.Init();
+  mStyleHash.Init();
   
   mSelectedLocale = NS_LITERAL_CSTRING("en-US");
   mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
 
   if (!PL_DHashTableInit(&mPackagesHash, &kTableOps,
                          nsnull, sizeof(PackageEntry), 16))
     return NS_ERROR_FAILURE;
 
--- a/chrome/src/nsChromeRegistryChrome.h
+++ b/chrome/src/nsChromeRegistryChrome.h
@@ -166,17 +166,17 @@ class nsChromeRegistryChrome : public ns
   };
 
   class OverlayListHash
   {
    public:
     OverlayListHash() { }
     ~OverlayListHash() { }
 
-    bool Init() { return mTable.Init(); }
+    void Init() { mTable.Init(); }
     void Add(nsIURI* aBase, nsIURI* aOverlay);
     void Clear() { mTable.Clear(); }
     const nsCOMArray<nsIURI>* GetArray(nsIURI* aBase);
 
    private:
     nsTHashtable<OverlayListEntry> mTable;
   };
 
--- a/chrome/src/nsChromeRegistryContent.cpp
+++ b/chrome/src/nsChromeRegistryContent.cpp
@@ -112,19 +112,17 @@ nsChromeRegistryContent::RegisterPackage
   }
 
   PackageEntry* entry = new PackageEntry;
   entry->flags = aPackage.flags;
   entry->contentBaseURI = content;
   entry->localeBaseURI = locale;
   entry->skinBaseURI = skin;
 
-  nsresult rv = mPackagesHash.Put(aPackage.package, entry);
-  if (NS_FAILED(rv))
-    return;
+  mPackagesHash.Put(aPackage.package, entry);
 }
 
 void
 nsChromeRegistryContent::RegisterResource(const ResourceMapping& aResource)
 {
   nsCOMPtr<nsIIOService> io (do_GetIOService());
   if (!io)
     return;
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -120,17 +120,17 @@ class ExpandArgsMore(ExpandArgs):
     def makelist(self):
         '''Replaces object file names with a temporary list file, using a
         list format depending on the EXPAND_LIBS_LIST_STYLE variable
         '''
         objs = [o for o in self if isObject(o)]
         if not len(objs): return
         fd, tmp = tempfile.mkstemp(suffix=".list",dir=os.curdir)
         if conf.EXPAND_LIBS_LIST_STYLE == "linkerscript":
-            content = ["INPUT(%s)\n" % obj for obj in objs]
+            content = ['INPUT("%s")\n' % obj for obj in objs]
             ref = tmp
         elif conf.EXPAND_LIBS_LIST_STYLE == "list":
             content = ["%s\n" % obj for obj in objs]
             ref = "@" + tmp
         else:
             os.close(fd)
             os.remove(tmp)
             return
--- a/config/tests/unit-expandlibs.py
+++ b/config/tests/unit-expandlibs.py
@@ -232,17 +232,17 @@ class TestExpandArgsMore(TestExpandInit)
             self.assertRelEqual(args[:3], ['foo', '-bar'] + self.files[:1])
             self.assertRelEqual(args[4:], [self.files[3]] + self.files[5:] + [self.tmpfile('liby', Lib('z'))])
 
             # Check the list file content
             objs = [f for f in self.files + self.liby_files + self.libx_files if f.endswith(config.OBJ_SUFFIX)]
             if config.EXPAND_LIBS_LIST_STYLE == "linkerscript":
                 self.assertNotEqual(args[3][0], '@')
                 filename = args[3]
-                content = ["INPUT(%s)" % relativize(f) for f in objs]
+                content = ['INPUT("%s")' % relativize(f) for f in objs]
                 with open(filename, 'r') as f:
                     self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
             elif config.EXPAND_LIBS_LIST_STYLE == "list":
                 self.assertEqual(args[3][0], '@')
                 filename = args[3][1:]
                 content = objs
                 with open(filename, 'r') as f:
                     self.assertRelEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
--- a/content/base/public/nsISelection.idl
+++ b/content/base/public/nsISelection.idl
@@ -45,17 +45,17 @@ interface nsINode;
 
 /**
  * Interface for manipulating and querying the current selected range
  * of nodes within the document.
  *
  * @version 1.0
  */
 
-[scriptable, uuid(5ac0cd5d-3c08-4c4c-8e70-230c433f5d5c)]
+[scriptable, uuid(dd40d5b8-1fe1-487f-b66e-28f4b837024f)]
 interface nsISelection : nsISupports
 {
     /**
      * Returns the node in which the selection begins.
      */
     readonly attribute nsIDOMNode anchorNode;
 
     /**
@@ -72,16 +72,17 @@ interface nsISelection : nsISupports
      * The offset within the (text) node where the selection ends.
      */
     readonly attribute long focusOffset;
 
     /**
      * Indicates if the selection is collapsed or not.
      */
     readonly attribute boolean isCollapsed;
+    [noscript,notxpcom,nostdcall] boolean collapsed();
 
     /**
      * Returns the number of ranges in the selection.
      */
     readonly attribute long rangeCount;
 
     /**
      * Returns the range at the specified index.
@@ -101,16 +102,17 @@ interface nsISelection : nsISupports
     /**
      * Extends the selection by moving the selection end to the specified node and offset,
      * preserving the selection begin position. The new selection end result will always
      * be from the anchorNode to the new focusNode, regardless of direction.
      * @param parentNode      The node where the selection will be extended to
      * @param offset          Where in node to place the offset in the new selection end
      */
     void extend(in nsIDOMNode parentNode, in long offset);
+    [noscript] void extendNative(in nsINode parentNode, in long offset);
 
     /**
      * Collapses the whole selection to a single point at the start
      * of the current selection (irrespective of direction).  If content
      * is focused and editable, the caret will blink there.
      */
     void collapseToStart();
 
--- a/content/base/public/nsISelectionPrivate.idl
+++ b/content/base/public/nsISelectionPrivate.idl
@@ -61,17 +61,17 @@ struct ScrollAxis;
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native nsIPresShell(nsIPresShell);
 [ptr] native RangeArray(nsTArray<nsRange*>);
 [ref] native constTextRangeStyleRef(const nsTextRangeStyle);
 [ref] native nsPointRef(nsPoint);
 native nsDirection(nsDirection);
 native ScrollAxis(nsIPresShell::ScrollAxis);
 
-[scriptable, uuid(0ced91b9-3e77-4191-943f-95bcde5e2d14)]
+[scriptable, uuid(719a803f-aa1e-436c-8919-c42908f00599)]
 interface nsISelectionPrivate : nsISelection
  {
     const short ENDOFPRECEDINGLINE=0;
     const short STARTOFNEXTLINE=1;
     
     attribute boolean interlinePosition;
 
     /* startBatchChanges
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -543,40 +543,24 @@ nsContentUtils::InitializeEventTable() {
 #undef WINDOW_ONLY_EVENT
 #undef EVENT
     { nsnull }
   };
 
   sAtomEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping>;
   sStringEventTable = new nsDataHashtable<nsStringHashKey, EventNameMapping>;
   sUserDefinedEvents = new nsCOMArray<nsIAtom>(64);
-
-  if (!sAtomEventTable || !sStringEventTable || !sUserDefinedEvents ||
-      !sAtomEventTable->Init(int(ArrayLength(eventArray) / 0.75) + 1) ||
-      !sStringEventTable->Init(int(ArrayLength(eventArray) / 0.75) + 1)) {
-    delete sAtomEventTable;
-    sAtomEventTable = nsnull;
-    delete sStringEventTable;
-    sStringEventTable = nsnull;
-    delete sUserDefinedEvents;
-    sUserDefinedEvents = nsnull;
-    return false;
-  }
+  sAtomEventTable->Init(int(ArrayLength(eventArray) / 0.75) + 1);
+  sStringEventTable->Init(int(ArrayLength(eventArray) / 0.75) + 1);
 
   // Subtract one from the length because of the trailing null
   for (PRUint32 i = 0; i < ArrayLength(eventArray) - 1; ++i) {
-    if (!sAtomEventTable->Put(eventArray[i].mAtom, eventArray[i]) ||
-        !sStringEventTable->Put(Substring(nsDependentAtomString(eventArray[i].mAtom), 2),
-                                eventArray[i])) {
-      delete sAtomEventTable;
-      sAtomEventTable = nsnull;
-      delete sStringEventTable;
-      sStringEventTable = nsnull;
-      return false;
-    }
+    sAtomEventTable->Put(eventArray[i].mAtom, eventArray[i]);
+    sStringEventTable->Put(Substring(nsDependentAtomString(eventArray[i].mAtom), 2),
+                           eventArray[i]);
   }
 
   return true;
 }
 
 void
 nsContentUtils::InitializeTouchEventTable()
 {
@@ -589,25 +573,19 @@ nsContentUtils::InitializeTouchEventTabl
       { nsGkAtoms::on##name_, _id, _type, _struct },
 #include "nsEventNameList.h"
 #undef TOUCH_EVENT
 #undef EVENT
       { nsnull }
     };
     // Subtract one from the length because of the trailing null
     for (PRUint32 i = 0; i < ArrayLength(touchEventArray) - 1; ++i) {
-      if (!sAtomEventTable->Put(touchEventArray[i].mAtom, touchEventArray[i]) ||
-          !sStringEventTable->Put(Substring(nsDependentAtomString(touchEventArray[i].mAtom), 2),
-                                  touchEventArray[i])) {
-        delete sAtomEventTable;
-        sAtomEventTable = nsnull;
-        delete sStringEventTable;
-        sStringEventTable = nsnull;
-        return;
-      }
+      sAtomEventTable->Put(touchEventArray[i].mAtom, touchEventArray[i]);
+      sStringEventTable->Put(Substring(nsDependentAtomString(touchEventArray[i].mAtom), 2),
+                             touchEventArray[i]);
     }
   }
 }
 
 static bool
 Is8bit(const nsAString& aString)
 {
   static const PRUnichar EIGHT_BIT = PRUnichar(~0x00FF);
@@ -6410,16 +6388,31 @@ nsContentUtils::FindInternalContentViewe
         if (docFactory && aLoaderType) {
           *aLoaderType = TYPE_CONTENT;
         }
         return docFactory.forget();
       }
     }
   }
 #endif
+
+#ifdef MOZ_GSTREAMER
+  if (nsHTMLMediaElement::IsH264Enabled()) {
+    for (unsigned int i = 0; i < ArrayLength(nsHTMLMediaElement::gH264Types); ++i) {
+      const char* type = nsHTMLMediaElement::gH264Types[i];
+      if (!strcmp(aType, type)) {
+        docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1");
+        if (docFactory && aLoaderType) {
+          *aLoaderType = TYPE_CONTENT;
+        }
+        return docFactory.forget();
+      }
+    }
+  }
+#endif
 #endif // MOZ_MEDIA
 
   return NULL;
 }
 
 // static
 bool
 nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -108,17 +108,18 @@ public:
   ~nsPreflightCache()
   {
     Clear();
     MOZ_COUNT_DTOR(nsPreflightCache);
   }
 
   bool Initialize()
   {
-    return mTable.Init();
+    mTable.Init();
+    return true;
   }
 
   CacheEntry* GetEntry(nsIURI* aURI, nsIPrincipal* aPrincipal,
                        bool aWithCredentials, bool aCreate);
   void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal);
 
   void Clear();
 
@@ -255,24 +256,17 @@ nsPreflightCache::GetEntry(nsIURI* aURI,
       // This will delete 'lruEntry'.
       mTable.Remove(lruEntry->mKey);
 
       NS_ASSERTION(mTable.Count() == PREFLIGHT_CACHE_SIZE - 1,
                    "Somehow tried to remove an entry that was never added!");
     }
   }
   
-  if (!mTable.Put(key, entry)) {
-    // Failed, clean up the new entry.
-    delete entry;
-
-    NS_WARNING("Failed to add entry to the CORS preflight cache!");
-    return nsnull;
-  }
-
+  mTable.Put(key, entry);
   PR_INSERT_LINK(entry, &mList);
 
   return entry;
 }
 
 void
 nsPreflightCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal)
 {
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -60,17 +60,18 @@ nsDOMAttributeMap::nsDOMAttributeMap(Ele
 {
   // We don't add a reference to our content. If it goes away,
   // we'll be told to drop our reference
 }
 
 bool
 nsDOMAttributeMap::Init()
 {
-  return mAttributeCache.Init();
+  mAttributeCache.Init();
+  return true;
 }
 
 /**
  * Clear map pointer for attributes.
  */
 PLDHashOperator
 RemoveMapRef(nsAttrHashKey::KeyType aKey, nsRefPtr<nsDOMAttribute>& aData,
              void* aUserArg)
@@ -207,19 +208,18 @@ nsDOMAttributeMap::GetAttribute(nsINodeI
 
   nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom());
 
   nsDOMAttribute* node = mAttributeCache.GetWeak(attr);
   if (!node) {
     nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
     nsRefPtr<nsDOMAttribute> newAttr =
       new nsDOMAttribute(this, ni.forget(), EmptyString(), aNsAware);
-    if (newAttr && mAttributeCache.Put(attr, newAttr)) {
-      node = newAttr;
-    }
+    mAttributeCache.Put(attr, newAttr);
+    node = newAttr;
   }
 
   return node;
 }
 
 nsDOMAttribute*
 nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName, nsresult *aResult)
 {
@@ -347,18 +347,17 @@ nsDOMAttributeMap::SetNamedItemInternal(
     }
 
     nsAutoString value;
     attribute->GetValue(value);
 
     // Add the new attribute to the attribute map before updating
     // its value in the element. @see bug 364413.
     nsAttrKey attrkey(ni->NamespaceID(), ni->NameAtom());
-    rv = mAttributeCache.Put(attrkey, attribute);
-    NS_ENSURE_SUCCESS(rv, rv);
+    mAttributeCache.Put(attrkey, attribute);
     iAttribute->SetMap(this);
 
     rv = mContent->SetAttr(ni->NamespaceID(), ni->NameAtom(),
                            ni->GetPrefixAtom(), value, true);
     if (NS_FAILED(rv)) {
       DropAttribute(ni->NamespaceID(), ni->NameAtom());
     }
   }
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -206,66 +206,73 @@ nsDOMMultipartFile::InitInternal(JSConte
   if (aArgc > 1) {
     mozilla::dom::BlobPropertyBag d;
     nsresult rv = d.Init(aCx, &aArgv[1]);
     NS_ENSURE_SUCCESS(rv, rv);
     mContentType = d.type;
     if (d.endings.EqualsLiteral("native")) {
       nativeEOL = true;
     } else if (!d.endings.EqualsLiteral("transparent")) {
-      return NS_ERROR_DOM_INVALID_STATE_ERR;
+      return NS_ERROR_TYPE_ERR;
     }
   }
 
   if (aArgc > 0) {
     if (!aArgv[0].isObject()) {
-      return NS_ERROR_INVALID_ARG; // We're not interested
+      return NS_ERROR_TYPE_ERR; // We're not interested
     }
 
     JSObject& obj = aArgv[0].toObject();
-
     if (!JS_IsArrayObject(aCx, &obj)) {
-      return NS_ERROR_INVALID_ARG; // We're not interested
+      return NS_ERROR_TYPE_ERR; // We're not interested
     }
 
     BlobSet blobSet;
 
     uint32_t length;
     JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &length));
     for (uint32_t i = 0; i < length; ++i) {
       jsval element;
       if (!JS_GetElement(aCx, &obj, i, &element))
-        return NS_ERROR_INVALID_ARG;
+        return NS_ERROR_TYPE_ERR;
 
       if (element.isObject()) {
         JSObject& obj = element.toObject();
         nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, &obj);
         if (blob) {
           // Flatten so that multipart blobs will never nest
           nsDOMFileBase* file = static_cast<nsDOMFileBase*>(
               static_cast<nsIDOMBlob*>(blob));
           const nsTArray<nsCOMPtr<nsIDOMBlob> >*
               subBlobs = file->GetSubBlobs();
           if (subBlobs) {
             blobSet.AppendBlobs(*subBlobs);
           } else {
             blobSet.AppendBlob(blob);
           }
-        } else if (JS_IsArrayBufferObject(&obj, aCx)) {
+          continue;
+        }
+        if (JS_IsArrayBufferViewObject(&obj, aCx)) {
+          blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj, aCx),
+                                JS_GetArrayBufferViewByteLength(&obj, aCx));
+          continue;
+        }
+        if (JS_IsArrayBufferObject(&obj, aCx)) {
           blobSet.AppendArrayBuffer(&obj, aCx);
-        } else {
-          // neither arraybuffer nor blob
-          return NS_ERROR_DOM_INVALID_STATE_ERR;
+          continue;
         }
+        // neither Blob nor ArrayBuffer(View)
       } else if (element.isString()) {
         blobSet.AppendString(element.toString(), nativeEOL, aCx);
-      } else {
-        // neither object nor string
-        return NS_ERROR_DOM_INVALID_STATE_ERR;
+        continue;
       }
+      // coerce it to a string
+      JSString* str = JS_ValueToString(aCx, element);
+      NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR);
+      blobSet.AppendString(str, nativeEOL, aCx);
     }
 
     mBlobs = blobSet.GetBlobs();
   }
 
   return NS_OK;
 }
 
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -345,17 +345,17 @@ nsDOMFileReader::DoOnDataAvailable(nsIRe
                                    PRUint32 aCount)
 {
   if (mDataFormat == FILE_AS_BINARY) {
     //Continuously update our binary string as data comes in
     NS_ASSERTION(mResult.Length() == aOffset,
                  "unexpected mResult length");
     PRUint32 oldLen = mResult.Length();
     PRUnichar *buf = nsnull;
-    mResult.GetMutableData(&buf, oldLen + aCount);
+    mResult.GetMutableData(&buf, oldLen + aCount, fallible_t());
     NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
 
     PRUint32 bytesRead = 0;
     aInputStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
                                &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
   }
   else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
@@ -558,18 +558,18 @@ nsDOMFileReader::ConvertStream(const cha
   nsCOMPtr<nsIUnicodeDecoder> unicodeDecoder;
   rv = charsetConverter->GetUnicodeDecoder(aCharset, getter_AddRefs(unicodeDecoder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 destLength;
   rv = unicodeDecoder->GetMaxLength(aFileData, aDataLen, &destLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  aResult.SetLength(destLength);  //Make sure we have enough space for the conversion
-  destLength = aResult.Length();
+  if (!aResult.SetLength(destLength, fallible_t()))
+    return NS_ERROR_OUT_OF_MEMORY;
 
   PRInt32 srcLength = aDataLen;
   rv = unicodeDecoder->Convert(aFileData, &srcLength, aResult.BeginWriting(), &destLength);
   aResult.SetLength(destLength); //Trim down to the correct size
 
   return rv;
 }
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -721,19 +721,17 @@ nsExternalResourceMap::RequestResource(n
   mPendingLoads.Get(clone, getter_AddRefs(load));
   if (load) {
     load.forget(aPendingLoad);
     return nsnull;
   }
 
   load = new PendingLoad(aDisplayDocument);
 
-  if (!mPendingLoads.Put(clone, load)) {
-    return nsnull;
-  }
+  mPendingLoads.Put(clone, load);
 
   if (NS_FAILED(load->StartLoad(clone, aRequestingNode))) {
     // Make sure we don't thrash things by trying this load again, since
     // chances are it failed for good reasons (security check, etc).
     AddExternalResource(clone, nsnull, nsnull, aDisplayDocument);
   } else {
     load.forget(aPendingLoad);
   }
@@ -915,32 +913,24 @@ nsExternalResourceMap::AddExternalResour
     if (NS_FAILED(rv)) {
       doc = nsnull;
       aViewer = nsnull;
       aLoadGroup = nsnull;
     }
   }
 
   ExternalResource* newResource = new ExternalResource();
-  if (newResource && !mMap.Put(aURI, newResource)) {
-    delete newResource;
-    newResource = nsnull;
-    if (NS_SUCCEEDED(rv)) {
-      rv = NS_ERROR_OUT_OF_MEMORY;
-    }
-  }
-
-  if (newResource) {
-    newResource->mDocument = doc;
-    newResource->mViewer = aViewer;
-    newResource->mLoadGroup = aLoadGroup;
-    if (doc) {
-      TransferZoomLevels(aDisplayDocument, doc);
-      TransferShowingState(aDisplayDocument, doc);
-    }
+  mMap.Put(aURI, newResource);
+
+  newResource->mDocument = doc;
+  newResource->mViewer = aViewer;
+  newResource->mLoadGroup = aLoadGroup;
+  if (doc) {
+    TransferZoomLevels(aDisplayDocument, doc);
+    TransferShowingState(aDisplayDocument, doc);
   }
 
   const nsTArray< nsCOMPtr<nsIObserver> > & obs = load->Observers();
   for (PRUint32 i = 0; i < obs.Length(); ++i) {
     obs[i]->Observe(doc, "external-resource-document-created", nsnull);
   }
 
   return rv;
@@ -1995,17 +1985,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 nsresult
 nsDocument::Init()
 {
   if (mCSSLoader || mNodeInfoManager || mScriptLoader) {
     return NS_ERROR_ALREADY_INITIALIZED;
   }
 
   mIdentifierMap.Init();
-  (void)mStyledLinks.Init();
+  mStyledLinks.Init();
   mRadioGroups.Init();
 
   // Force initialization.
   nsINode::nsSlots* slots = GetSlots();
   NS_ENSURE_TRUE(slots,NS_ERROR_OUT_OF_MEMORY);
 
   // Prepend self as mutation-observer whether we need it or not (some
   // subclasses currently do, other don't). This is because the code in
@@ -2036,20 +2026,18 @@ nsDocument::Init()
   NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                     "Bad NodeType in aNodeInfo");
 
   NS_ASSERTION(OwnerDoc() == this, "Our nodeinfo is busted!");
 
   mScriptLoader = new nsScriptLoader(this);
   NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
 
-  if (!mImageTracker.Init() ||
-      !mPlugins.Init()) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  mImageTracker.Init();
+  mPlugins.Init();
 
   return NS_OK;
 }
 
 void 
 nsIDocument::DeleteAllProperties()
 {
   for (PRUint32 i = 0; i < GetPropertyTableCount(); ++i) {
@@ -5350,19 +5338,17 @@ nsDocument::GetBoxObjectFor(nsIDOMElemen
                                     nsContentUtils::eDOM_PROPERTIES,
                                     "UseOfGetBoxObjectForWarning");
   }
 
   *aResult = nsnull;
 
   if (!mBoxObjectTable) {
     mBoxObjectTable = new nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject>;
-    if (mBoxObjectTable && !mBoxObjectTable->Init(12)) {
-      mBoxObjectTable = nsnull;
-    }
+    mBoxObjectTable->Init(12);
   } else {
     // Want to use Get(content, aResult); but it's the wrong type
     *aResult = mBoxObjectTable->GetWeak(content);
     if (*aResult) {
       NS_ADDREF(*aResult);
       return NS_OK;
     }
   }
@@ -6497,17 +6483,17 @@ nsDocument::GetRadioGroup(const nsAStrin
   }
 
   nsRadioGroupStruct* radioGroup;
   if (mRadioGroups.Get(tmKey, &radioGroup)) {
     return radioGroup;
   }
 
   nsAutoPtr<nsRadioGroupStruct> newRadioGroup(new nsRadioGroupStruct());
-  NS_ENSURE_TRUE(mRadioGroups.Put(tmKey, newRadioGroup), nsnull);
+  mRadioGroups.Put(tmKey, newRadioGroup);
 
   return newRadioGroup.forget();
 }
 
 NS_IMETHODIMP
 nsDocument::SetCurrentRadioButton(const nsAString& aName,
                                   nsIDOMHTMLInputElement* aRadio)
 {
@@ -8280,19 +8266,17 @@ nsDocument::AddImage(imgIRequest* aImage
 {
   NS_ENSURE_ARG_POINTER(aImage);
 
   // See if the image is already in the hashtable. If it is, get the old count.
   PRUint32 oldCount = 0;
   mImageTracker.Get(aImage, &oldCount);
 
   // Put the image in the hashtable, with the proper count.
-  bool success = mImageTracker.Put(aImage, oldCount + 1);
-  if (!success)
-    return NS_ERROR_OUT_OF_MEMORY;
+  mImageTracker.Put(aImage, oldCount + 1);
 
   nsresult rv = NS_OK;
 
   // If this is the first insertion and we're locking images, lock this image
   // too.
   if (oldCount == 0 && mLockingImages) {
     rv = aImage->LockImage();
     if (NS_SUCCEEDED(rv))
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -48,16 +48,17 @@
 #include "nsNodeInfoManager.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMAttr.h"
 #include "nsDOMError.h"
 #include "nsGkAtoms.h"
 #include "nsDOMString.h"
 #include "nsIDOMUserDataHandler.h"
+#include "nsContentUtils.h"
 
 class nsDocumentFragment : public nsGenericElement,
                            public nsIDOMDocumentFragment
 {
 public:
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -156,19 +157,32 @@ nsIAtom*
 nsDocumentFragment::GetIDAttributeName() const
 {
   return nsnull;
 }
 
 DOMCI_NODE_DATA(DocumentFragment, nsDocumentFragment)
 
 // QueryInterface implementation for nsDocumentFragment
-NS_INTERFACE_TABLE_HEAD(nsDocumentFragment)
-  NS_NODE_INTERFACE_TABLE2(nsDocumentFragment, nsIDOMNode,
-                           nsIDOMDocumentFragment)
+NS_INTERFACE_MAP_BEGIN(nsDocumentFragment)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDocumentFragment)
+  NS_INTERFACE_MAP_ENTRY(nsIContent)
+  NS_INTERFACE_MAP_ENTRY(nsINode)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentFragment)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
+                                 new nsNodeSupportsWeakRefTearoff(this))
+  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNodeSelector,
+                                 new nsNodeSelectorTearoff(this))
+  // nsNodeSH::PreCreate() depends on the identity pointer being the
+  // same as nsINode (which nsIContent inherits), so if you change the
+  // below line, make sure nsNodeSH::PreCreate() still does the right
+  // thing!
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DocumentFragment)
-NS_INTERFACE_MAP_END_INHERITING(nsGenericElement)
-
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF_INHERITED(nsDocumentFragment, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsDocumentFragment, nsGenericElement)
 
 NS_IMPL_ELEMENT_CLONE(nsDocumentFragment)
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -148,17 +148,17 @@
 
 #include "nsCSSParser.h"
 #include "prprf.h"
 #include "nsDOMMutationObserver.h"
 #include "nsSVGFeatures.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsCycleCollector.h"
 #include "xpcpublic.h"
-#include "xpcprivate.h"
+#include "nsIScriptError.h"
 #include "nsLayoutStatics.h"
 #include "mozilla/Telemetry.h"
 
 #include "mozilla/CORSMode.h"
 
 #include "nsStyledElement.h"
 
 using namespace mozilla;
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1359,29 +1359,31 @@ GK_ATOM(text_rendering, "text-rendering"
 GK_ATOM(textPath, "textPath")
 GK_ATOM(tref, "tref")
 GK_ATOM(tspan, "tspan")
 GK_ATOM(turbulence, "turbulence")
 GK_ATOM(unicode_bidi, "unicode-bidi")
 GK_ATOM(userSpaceOnUse, "userSpaceOnUse")
 GK_ATOM(view, "view")
 GK_ATOM(viewBox, "viewBox")
+GK_ATOM(viewTarget, "viewTarget")
 GK_ATOM(vkern, "vkern")
 GK_ATOM(word_spacing, "word-spacing")
 GK_ATOM(x, "x")
 GK_ATOM(x1, "x1")
 GK_ATOM(x2, "x2")
 GK_ATOM(xChannelSelector, "xChannelSelector")
 GK_ATOM(xor_, "xor")
 GK_ATOM(y, "y")
 GK_ATOM(y1, "y1")
 GK_ATOM(y2, "y2")
 GK_ATOM(yChannelSelector, "yChannelSelector")
 GK_ATOM(z, "z")
 GK_ATOM(zoomAndPan, "zoomAndPan")
+GK_ATOM(vector_effect, "vector-effect")
 
 GK_ATOM(accumulate, "accumulate")
 GK_ATOM(additive, "additive")
 GK_ATOM(attributeName, "attributeName")
 GK_ATOM(attributeType, "attributeType")
 GK_ATOM(auto_reverse, "auto-reverse")
 GK_ATOM(begin, "begin")
 GK_ATOM(beginEvent, "beginEvent")
@@ -1711,16 +1713,17 @@ GK_ATOM(onMozPressTapGesture, "onMozPres
 GK_ATOM(onMozTouchDown, "onMozTouchDown")
 GK_ATOM(onMozTouchMove, "onMozTouchMove")
 GK_ATOM(onMozTouchUp, "onMozTouchUp")
 
 // orientation support
 GK_ATOM(ondevicemotion, "ondevicemotion")
 GK_ATOM(ondeviceorientation, "ondeviceorientation")
 GK_ATOM(ondeviceproximity, "ondeviceproximity")
+GK_ATOM(onuserproximity, "onuserproximity")
 
 // light sensor support
 GK_ATOM(ondevicelight, "ondevicelight")
 
 //---------------------------------------------------------------------------
 // Special atoms
 //---------------------------------------------------------------------------
 
--- a/content/base/src/nsNameSpaceManager.cpp
+++ b/content/base/src/nsNameSpaceManager.cpp
@@ -135,19 +135,19 @@ private:
 };
 
 static NameSpaceManagerImpl* sNameSpaceManager = nsnull;
 
 NS_IMPL_ISUPPORTS1(NameSpaceManagerImpl, nsINameSpaceManager)
 
 nsresult NameSpaceManagerImpl::Init()
 {
-  nsresult rv = mURIToIDTable.Init(32);
-  NS_ENSURE_SUCCESS(rv, rv);
+  mURIToIDTable.Init(32);
 
+  nsresult rv;
 #define REGISTER_NAMESPACE(uri, id) \
   rv = AddNameSpace(NS_LITERAL_STRING(uri), id); \
   NS_ENSURE_SUCCESS(rv, rv)
 
   // Need to be ordered according to ID.
   REGISTER_NAMESPACE(kXMLNSNameSpaceURI, kNameSpaceID_XMLNS);
   REGISTER_NAMESPACE(kXMLNameSpaceURI, kNameSpaceID_XML);
   REGISTER_NAMESPACE(kXHTMLNameSpaceURI, kNameSpaceID_XHTML);
@@ -283,21 +283,17 @@ nsresult NameSpaceManagerImpl::AddNameSp
                "BAD! AddNameSpace not called in right order!");
 
   nsString* uri = new nsString(aURI);
   if (!uri || !mURIArray.AppendElement(uri)) {
     delete uri;
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  if (!mURIToIDTable.Put(uri, aNameSpaceID)) {
-    mURIArray.RemoveElementAt(aNameSpaceID - 1);
-
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  mURIToIDTable.Put(uri, aNameSpaceID);
 
   return NS_OK;
 }
 
 nsresult
 NS_GetNameSpaceManager(nsINameSpaceManager** aInstancePtrResult)
 {
   NS_ENSURE_ARG_POINTER(aInstancePtrResult);
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -623,22 +623,23 @@ nsIAtom** const kAttributesSVG[] = {
   &nsGkAtoms::unicode_bidi, // unicode-bidi
   // unicode-range
   // units-per-em
   // v-alphabetic
   // v-hanging
   // v-ideographic
   // v-mathematical
   &nsGkAtoms::values, // values
+  &nsGkAtoms::vector_effect, // vector-effect
   // vert-adv-y
   // vert-origin-x
   // vert-origin-y
   &nsGkAtoms::viewBox, // viewBox
+  &nsGkAtoms::viewTarget, // viewTarget
   &nsGkAtoms::visibility, // visibility
-  // viewTarget
   &nsGkAtoms::width, // width
   // widths
   &nsGkAtoms::word_spacing, // word-spacing
   // writing-mode
   &nsGkAtoms::x, // x
   // x-height
   &nsGkAtoms::x1, // x1
   &nsGkAtoms::x2, // x2
--- a/content/base/src/nsWebSocket.cpp
+++ b/content/base/src/nsWebSocket.cpp
@@ -385,20 +385,24 @@ nsWebSocket::OnServerClose(nsISupports *
     return NS_ERROR_UNEXPECTED;
   }
 
   // store code/string for onclose DOM event
   mCloseEventCode = aCode;
   CopyUTF8toUTF16(aReason, mCloseEventReason);
 
   if (mReadyState == nsIWebSocket::OPEN) {
-    // Send reciprocal Close frame.
-    // 5.5.1: "When sending a Close frame in response, the endpoint typically
-    // echos the status code it received"
-    CloseConnection(aCode, aReason);
+    // RFC 6455, 5.5.1: "When sending a Close frame in response, the endpoint
+    // typically echos the status code it received".
+    // But never send certain codes, per section 7.4.1
+    if (aCode == 1005 || aCode == 1006 || aCode == 1015) {
+      CloseConnection(0, EmptyCString());
+    } else {
+      CloseConnection(aCode, aReason);
+    }
   } else {
     // Nothing else to do: OnStop does the rest of the work.
     NS_ASSERTION (mReadyState == nsIWebSocket::CLOSING, "unknown state");
     NS_ASSERTION(!mDisconnected, "should not be disconnected during CLOSING");
   }
 
   return NS_OK;
 }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -574,16 +574,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug650386_redirect_303.html \
 		test_bug650386_redirect_307.html \
 		file_bug650386_content.sjs \
 		file_bug650386_report.sjs \
 		test_bug719533.html \
 		test_bug737087.html \
 		test_bug433662.html \
 		test_bug749367.html \
+		test_bug753278.html \
 		$(NULL)
 
 _CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
--- a/content/base/test/file_websocket_wsh.py
+++ b/content/base/test/file_websocket_wsh.py
@@ -26,16 +26,29 @@ def web_socket_do_extra_handshake(reques
   elif request.ws_protocol == "test-22":
     # The timeout is 5 seconds
     time.sleep(13)
   elif request.ws_protocol == "test-41b":
     request.sts = "max-age=100"
   else:
     pass
 
+# Behave according to recommendation of RFC 6455, section # 5.5.1:
+#  "When sending a Close frame in response, the endpoint typically echos the
+#   status code it received."  
+# - Without this, pywebsocket replies with 1000 to any close code.
+#
+#  Note that this function is only called when the client initiates the close
+def web_socket_passive_closing_handshake(request):
+  if request.ws_close_code == 1005:
+    return None, None
+  else:
+    return request.ws_close_code, request.ws_close_reason
+
+
 def web_socket_transfer_data(request):
   if request.ws_protocol == "test-2.1" or request.ws_protocol == "test-2.2":
     msgutil.close_connection(request)
   elif request.ws_protocol == "test-6":
     resp = "wrong message"
     if msgutil.receive_message(request) == "1":
       resp = "2"
     msgutil.send_message(request, resp.decode('utf-8'))
@@ -52,17 +65,16 @@ def web_socket_transfer_data(request):
     msgutil.send_message(request, "test-7 data")
   elif request.ws_protocol == "test-10":
     msgutil.close_connection(request)
   elif request.ws_protocol == "test-11":
     resp = "wrong message"
     if msgutil.receive_message(request) == "client data":
       resp = "server data"
     msgutil.send_message(request, resp.decode('utf-8'))
-    msgutil.close_connection(request)
   elif request.ws_protocol == "test-12":
     msgutil.close_connection(request)
   elif request.ws_protocol == "test-13":
     # first one binary message containing the byte 0x61 ('a')
     request.connection.write('\xff\x01\x61')
     # after a bad utf8 message
     request.connection.write('\x01\x61\xff')
     msgutil.close_connection(request)
--- a/content/base/test/test_blobconstructor.html
+++ b/content/base/test/test_blobconstructor.html
@@ -132,16 +132,27 @@ let testData =
                              {start: 1, length: 2, contents:  "te"},
                              {start: 6, length: 4, contents:  "quig"}]],
     // Test an array buffer
     [[aB, blob1, "foo"], {},
                             [{start: 0, length: 8, contents:  "ABCDEFGH"},
                              {start: 8, length:10, contents:  "IJKLMNOPsq"},
                              {start: 17, length: 3, contents: "qui"},
                              {start: 4, length: 8, contents:  "EFGHIJKL"}]],
+    // Test an ArrayBufferView
+    [[int8View, blob1, "foo"], {},
+                            [{start: 0, length: 8, contents:  "ABCDEFGH"},
+                             {start: 8, length:10, contents:  "IJKLMNOPsq"},
+                             {start: 17, length: 3, contents: "qui"},
+                             {start: 4, length: 8, contents:  "EFGHIJKL"}]],
+    // Test a partial ArrayBufferView
+    [[new Uint8Array(aB, 3, 5), blob1, "foo"], {},
+                            [{start: 0, length: 8, contents:  "DEFGHsqu"},
+                             {start: 8, length:10, contents:  "igglefoo"},
+                             {start: 4, length: 8, contents:  "Hsquiggl"}]],
     // Test transparent line endings
     [["foo\r\n", "bar\r", "baz\n"], { endings: "transparent" },
                             [{start: 0, length: 5, contents:  "foo\r\n"},
                              {start: 5, length: 4, contents:  "bar\r"},
                              {start: 9, length: 4, contents: "baz\n"}]],
     // Test transparent line endings when the second argument is omitted
     [["foo\r\n", "bar\r", "baz\n"], undefined,
                             [{start: 0, length: 5, contents:  "foo\r\n"},
@@ -152,17 +163,21 @@ let testData =
                             navigator.platform.indexOf("Win") != -1 ?
                             [{start: 0, length: 5, contents:  "foo\r\n"},
                              {start: 5, length: 5, contents:  "bar\r\n"},
                              {start: 10, length: 5, contents: "baz\r\n"}] :
                             [{start: 0, length: 4, contents:  "foo\n"},
                              {start: 4, length: 4, contents:  "bar\n"},
                              {start: 8, length: 4, contents: "baz\n"}]],
     // Test type coercion of a number
-    [[3, aB, "foo"], {},    "InvalidStateError"]
+    [[3, int8View, "foo"], {},
+                            [{start: 0, length: 8, contents:  "3ABCDEFG"},
+                             {start: 8, length:10, contents:  "HIJKLMNOPf"},
+                             {start: 17, length: 4, contents: "foo"},
+                             {start: 4, length: 8, contents:  "DEFGHIJK"}]]
  ];
 
 let testCounter = 0;
 
 function doTest(data) {
   testCounter++;
 
   [blobs, options, tests] = data;
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug753278.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=753278
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 753278</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="runTest();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753278">Mozilla Bug 753278</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe></iframe>  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 753278 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var f = document.getElementsByTagName("iframe")[0];
+
+function runTest() {
+  f.contentDocument.open();
+  f.contentDocument.write('<script>window.location = "data:text/html;charset=utf-8,\\u003Cscript>parent.pass();\\u003C/script>"; document.close(); document.open(); document.write("\\u003Cscript>parent.fail();\\u003C/script>"); document.close();\u003c/script>');
+  f.contentDocument.close();
+}
+
+function pass() {
+  ok(true, "window.location took precedence");
+  SimpleTest.finish();
+}
+
+function fail() {
+  ok(false, "window.location should have taken precedence");
+  SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/base/test/test_websocket.html
+++ b/content/base/test/test_websocket.html
@@ -20,18 +20,18 @@
  * tests:
  *  1. client tries to connect to a http scheme location;
  *  2. assure serialization of the connections;
  *  3. client tries to connect to an non-existent ws server;
  *  4. client tries to connect using a relative url;
  *  5. client uses an invalid protocol value;
  *  6. counter and encoding check;
  *  7. onmessage event origin property check
- *  8. client calls close() and the server sends the close frame in
- *     acknowledgement;
+ *  8. client calls close() and the server sends the close frame (with no code
+ *     or reason) in acknowledgement;
  *  9. client closes the connection before the ws connection is established;
  * 10. client sends a message before the ws connection is established;
  * 11. a simple hello echo;
  * 12. client sends a message with bad bytes;
  * 13. server sends an invalid message;
  * 14. server sends the close frame, it doesn't close the tcp connection and
  *     it keeps sending normal ws messages;
  * 15. server closes the tcp connection, but it doesn't send the close frame;
@@ -50,17 +50,17 @@
  * 27. ctor with invalid sub-protocol array containing an empty element in list
  * 28. ctor using valid 1 element sub-protocol array
  * 29. ctor using all valid 5 element sub-protocol array
  * 30. ctor using valid 1 element sub-protocol array with element server will
  *     reject
  * 31. ctor using valid 2 element sub-protocol array with 1 element server
  *     will reject and one server will accept.
  * 32. ctor using invalid sub-protocol array that contains duplicate items
- * 33. default close code test
+ * 33. test for sending/receiving custom close code (but no close reason)
  * 34. test for receiving custom close code and reason
  * 35. test for sending custom close code and reason
  * 36. negative test for sending out of range close code
  * 37. negative test for too long of a close reason
  * 38. ensure extensions attribute is defined
  * 39. a basic wss:// connectivity test
  * 40. negative test for wss:// with no cert
  * 41. HSTS
@@ -382,16 +382,20 @@ function test8()
   ws.onopen = function()
   {
     ok(ws.protocol == "test-8", "test-8 subprotocol selection");
     ws.close();
   }
   ws.onclose = function(e)
   {
     shouldCloseCleanly(e);
+    // We called close() with no close code: so pywebsocket will also send no
+    // close code, which translates to code 1005 
+    ok(e.code == 1005, "test-8 close code has wrong value:" + e.code);
+    ok(e.reason == "", "test-8 close reason has wrong value:" + e.reason);
     doTest(9);
   };
 }
 
 var waitTest9 = false;
 
 function test9()
 {
@@ -456,26 +460,28 @@ function test11()
   ws.onopen = function()
   {
     ok(ws.readyState == 1, "open bad readyState in test-11!");
     ws.send("client data");
   }
   ws.onmessage = function(e)
   {
     ok(e.data == "server data", "bad received message in test-11!");
-    ws.close();
+    ws.close(1000, "Have a nice day");
 
 // this ok() is disabled due to a race condition - it state may have
 // advanced through 2 (closing) and into 3 (closed) before it is evald
 //    ok(ws.readyState == 2, "onmessage bad readyState in test-11!");
   }
   ws.onclose = function(e)
   {
     ok(ws.readyState == 3, "onclose bad readyState in test-11!");
     shouldCloseCleanly(e);
+    ok(e.code == 1000, "test 11 got wrong close code: " + e.code);
+    ok(e.reason == "Have a nice day", "test 11 got wrong close reason: " + e.reason);
     doTest(12);
   }
 }
 
 function test12()
 {
  ok(true,"test 12");
 
@@ -937,24 +943,25 @@ function test32()
 function test33()
 {
   var prots=["test33"];
 
   var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
   ws.onopen = function(e)
   {
     ok(true, "test 33 open");
-    ws.close();
+    ws.close(3131);   // pass code but not reason
   };
 
   ws.onclose = function(e)
   {
     ok(true, "test 33 close");
-    ok(e.wasClean, "test 33 closed cleanly");
-    ok(e.code == 1000, "test 33 had normal 1000 error code");
+    shouldCloseCleanly(e);
+    ok(e.code == 3131, "test 33 got wrong close code: " + e.code);
+    ok(e.reason === "", "test 33 got wrong close reason: " + e.reason);
     doTest(34);
   };
 }
 
 function test34()
 {
   var prots=["test-34"];
 
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -130,35 +130,35 @@ Canvas2D_GetStyleHelper(JSContext *cx, J
                                         &interfaces[k_nsIDOMCanvasGradient], vp);
     }
     default:
         return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(*vp), id);
     }
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, jsval *vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, jsval *vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, jsval *vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, jsval *vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
 }
 
 static bool
 CreateImageData(JSContext* cx, JSObject* obj, uint32_t w, uint32_t h, jsval* vp)
 {
     using mozilla::CheckedInt;
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -104,13 +104,12 @@ include $(topsrcdir)/ipc/chromium/chromi
 CXXFLAGS	+= $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
 INCLUDES	+= \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../html/content/src \
-		-I$(srcdir)/../../../js/xpconnect/src \
 		-I$(srcdir)/../../../dom/base \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/events/public/Makefile.in
+++ b/content/events/public/Makefile.in
@@ -49,16 +49,17 @@ EXPORTS		= \
 		nsMutationEvent.h \
 		nsIPrivateDOMEvent.h \
 		nsIPrivateTextEvent.h \
 		nsIPrivateTextRange.h \
 		nsAsyncDOMEvent.h \
 		nsEventDispatcher.h \
 		nsEventStates.h \
 		nsEventNameList.h \
+		nsVKList.h \
 		$(NULL)
 
 XPIDLSRCS	= \
 		nsIEventListenerService.idl \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/content/events/public/nsEventNameList.h
+++ b/content/events/public/nsEventNameList.h
@@ -454,16 +454,20 @@ WINDOW_ONLY_EVENT(devicemotion,
 WINDOW_ONLY_EVENT(deviceorientation,
                   NS_DEVICE_ORIENTATION,
                   EventNameType_None,
                   NS_EVENT)
 WINDOW_ONLY_EVENT(deviceproximity,
                   NS_DEVICE_PROXIMITY,
                   EventNameType_None,
                   NS_EVENT)
+WINDOW_ONLY_EVENT(userproximity,
+                  NS_USER_PROXIMITY,
+                  EventNameType_None,
+                  NS_EVENT)
 WINDOW_ONLY_EVENT(devicelight,
                   NS_DEVICE_LIGHT,
                   EventNameType_None,
                   NS_EVENT)
 
 TOUCH_EVENT(touchstart,
             NS_TOUCH_START,
             EventNameType_All,
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -89,16 +89,18 @@ nsresult
 NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsCompositionEvent *aEvent);
 nsresult
 NS_NewDOMMutationEvent(nsIDOMEvent** aResult NS_OUTPARAM, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
 nsresult
 NS_NewDOMPopupBlockedEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
 NS_NewDOMDeviceProximityEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
 nsresult
+NS_NewDOMUserProximityEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
+nsresult
 NS_NewDOMDeviceOrientationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
 NS_NewDOMDeviceLightEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
 NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
 NS_NewDOMTextEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsTextEvent* aEvent);
 nsresult
new file mode 100644
--- /dev/null
+++ b/content/events/public/nsVKList.h
@@ -0,0 +1,191 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * This header file defines all DOM keys which are defined in nsIDOMKeyEvent.
+ * You must define NS_DEFINE_VK macro before including this.
+ *
+ * It must have two arguments, (aDOMKeyName, aDOMKeyCode)
+ * aDOMKeyName is a key name in DOM.
+ * aDOMKeyCode is one of nsIDOMKeyEvent::DOM_VK_*.
+ */
+
+#define DEFINE_VK_INTERNAL(aKeyName) \
+  NS_DEFINE_VK(VK##aKeyName, nsIDOMKeyEvent::DOM_VK##aKeyName)
+
+// Some keycode may have different name in nsIDOMKeyEvent from its key name.
+#define DEFINE_VK_INTERNAL2(aKeyName, aKeyCodeName) \
+  NS_DEFINE_VK(VK##aKeyName, nsIDOMKeyEvent::DOM_VK##aKeyCodeName)
+
+DEFINE_VK_INTERNAL(_CANCEL),
+DEFINE_VK_INTERNAL(_HELP),
+DEFINE_VK_INTERNAL2(_BACK, _BACK_SPACE),
+DEFINE_VK_INTERNAL(_TAB),
+DEFINE_VK_INTERNAL(_CLEAR),
+DEFINE_VK_INTERNAL(_RETURN),
+DEFINE_VK_INTERNAL(_ENTER),
+DEFINE_VK_INTERNAL(_SHIFT),
+DEFINE_VK_INTERNAL(_CONTROL),
+DEFINE_VK_INTERNAL(_ALT),
+DEFINE_VK_INTERNAL(_PAUSE),
+DEFINE_VK_INTERNAL(_CAPS_LOCK),
+DEFINE_VK_INTERNAL(_KANA),
+DEFINE_VK_INTERNAL(_HANGUL),
+DEFINE_VK_INTERNAL(_EISU),
+DEFINE_VK_INTERNAL(_JUNJA),
+DEFINE_VK_INTERNAL(_FINAL),
+DEFINE_VK_INTERNAL(_HANJA),
+DEFINE_VK_INTERNAL(_KANJI),
+DEFINE_VK_INTERNAL(_ESCAPE),
+DEFINE_VK_INTERNAL(_CONVERT),
+DEFINE_VK_INTERNAL(_NONCONVERT),
+DEFINE_VK_INTERNAL(_ACCEPT),
+DEFINE_VK_INTERNAL(_MODECHANGE),
+DEFINE_VK_INTERNAL(_SPACE),
+DEFINE_VK_INTERNAL(_PAGE_UP),
+DEFINE_VK_INTERNAL(_PAGE_DOWN),
+DEFINE_VK_INTERNAL(_END),
+DEFINE_VK_INTERNAL(_HOME),
+DEFINE_VK_INTERNAL(_LEFT),
+DEFINE_VK_INTERNAL(_UP),
+DEFINE_VK_INTERNAL(_RIGHT),
+DEFINE_VK_INTERNAL(_DOWN),
+DEFINE_VK_INTERNAL(_SELECT),
+DEFINE_VK_INTERNAL(_PRINT),
+DEFINE_VK_INTERNAL(_EXECUTE),
+DEFINE_VK_INTERNAL(_PRINTSCREEN),
+DEFINE_VK_INTERNAL(_INSERT),
+DEFINE_VK_INTERNAL(_DELETE),
+
+DEFINE_VK_INTERNAL(_0),
+DEFINE_VK_INTERNAL(_1),
+DEFINE_VK_INTERNAL(_2),
+DEFINE_VK_INTERNAL(_3),
+DEFINE_VK_INTERNAL(_4),
+DEFINE_VK_INTERNAL(_5),
+DEFINE_VK_INTERNAL(_6),
+DEFINE_VK_INTERNAL(_7),
+DEFINE_VK_INTERNAL(_8),
+DEFINE_VK_INTERNAL(_9),
+
+DEFINE_VK_INTERNAL(_COLON),
+DEFINE_VK_INTERNAL(_SEMICOLON),
+DEFINE_VK_INTERNAL(_LESS_THAN),
+DEFINE_VK_INTERNAL(_EQUALS),
+DEFINE_VK_INTERNAL(_GREATER_THAN),
+DEFINE_VK_INTERNAL(_QUESTION_MARK),
+DEFINE_VK_INTERNAL(_AT),
+
+DEFINE_VK_INTERNAL(_A),
+DEFINE_VK_INTERNAL(_B),
+DEFINE_VK_INTERNAL(_C),
+DEFINE_VK_INTERNAL(_D),
+DEFINE_VK_INTERNAL(_E),
+DEFINE_VK_INTERNAL(_F),
+DEFINE_VK_INTERNAL(_G),
+DEFINE_VK_INTERNAL(_H),
+DEFINE_VK_INTERNAL(_I),
+DEFINE_VK_INTERNAL(_J),
+DEFINE_VK_INTERNAL(_K),
+DEFINE_VK_INTERNAL(_L),
+DEFINE_VK_INTERNAL(_M),
+DEFINE_VK_INTERNAL(_N),
+DEFINE_VK_INTERNAL(_O),
+DEFINE_VK_INTERNAL(_P),
+DEFINE_VK_INTERNAL(_Q),
+DEFINE_VK_INTERNAL(_R),
+DEFINE_VK_INTERNAL(_S),
+DEFINE_VK_INTERNAL(_T),
+DEFINE_VK_INTERNAL(_U),
+DEFINE_VK_INTERNAL(_V),
+DEFINE_VK_INTERNAL(_W),
+DEFINE_VK_INTERNAL(_X),
+DEFINE_VK_INTERNAL(_Y),
+DEFINE_VK_INTERNAL(_Z),
+
+DEFINE_VK_INTERNAL(_WIN),
+DEFINE_VK_INTERNAL(_CONTEXT_MENU),
+DEFINE_VK_INTERNAL(_SLEEP),
+
+DEFINE_VK_INTERNAL(_NUMPAD0),
+DEFINE_VK_INTERNAL(_NUMPAD1),
+DEFINE_VK_INTERNAL(_NUMPAD2),
+DEFINE_VK_INTERNAL(_NUMPAD3),
+DEFINE_VK_INTERNAL(_NUMPAD4),
+DEFINE_VK_INTERNAL(_NUMPAD5),
+DEFINE_VK_INTERNAL(_NUMPAD6),
+DEFINE_VK_INTERNAL(_NUMPAD7),
+DEFINE_VK_INTERNAL(_NUMPAD8),
+DEFINE_VK_INTERNAL(_NUMPAD9),
+DEFINE_VK_INTERNAL(_MULTIPLY),
+DEFINE_VK_INTERNAL(_ADD),
+DEFINE_VK_INTERNAL(_SEPARATOR),
+DEFINE_VK_INTERNAL(_SUBTRACT),
+DEFINE_VK_INTERNAL(_DECIMAL),
+DEFINE_VK_INTERNAL(_DIVIDE),
+
+DEFINE_VK_INTERNAL(_F1),
+DEFINE_VK_INTERNAL(_F2),
+DEFINE_VK_INTERNAL(_F3),
+DEFINE_VK_INTERNAL(_F4),
+DEFINE_VK_INTERNAL(_F5),
+DEFINE_VK_INTERNAL(_F6),
+DEFINE_VK_INTERNAL(_F7),
+DEFINE_VK_INTERNAL(_F8),
+DEFINE_VK_INTERNAL(_F9),
+DEFINE_VK_INTERNAL(_F10),
+DEFINE_VK_INTERNAL(_F11),
+DEFINE_VK_INTERNAL(_F12),
+DEFINE_VK_INTERNAL(_F13),
+DEFINE_VK_INTERNAL(_F14),
+DEFINE_VK_INTERNAL(_F15),
+DEFINE_VK_INTERNAL(_F16),
+DEFINE_VK_INTERNAL(_F17),
+DEFINE_VK_INTERNAL(_F18),
+DEFINE_VK_INTERNAL(_F19),
+DEFINE_VK_INTERNAL(_F20),
+DEFINE_VK_INTERNAL(_F21),
+DEFINE_VK_INTERNAL(_F22),
+DEFINE_VK_INTERNAL(_F23),
+DEFINE_VK_INTERNAL(_F24),
+
+DEFINE_VK_INTERNAL(_NUM_LOCK),
+DEFINE_VK_INTERNAL(_SCROLL_LOCK),
+
+DEFINE_VK_INTERNAL(_CIRCUMFLEX),
+DEFINE_VK_INTERNAL(_EXCLAMATION),
+DEFINE_VK_INTERNAL(_DOUBLE_QUOTE),
+DEFINE_VK_INTERNAL(_HASH),
+DEFINE_VK_INTERNAL(_DOLLAR),
+DEFINE_VK_INTERNAL(_PERCENT),
+DEFINE_VK_INTERNAL(_AMPERSAND),
+DEFINE_VK_INTERNAL(_UNDERSCORE),
+DEFINE_VK_INTERNAL(_OPEN_PAREN),
+DEFINE_VK_INTERNAL(_CLOSE_PAREN),
+DEFINE_VK_INTERNAL(_ASTERISK),
+DEFINE_VK_INTERNAL(_PLUS),
+DEFINE_VK_INTERNAL(_PIPE),
+DEFINE_VK_INTERNAL(_HYPHEN_MINUS),
+
+DEFINE_VK_INTERNAL(_OPEN_CURLY_BRACKET),
+DEFINE_VK_INTERNAL(_CLOSE_CURLY_BRACKET),
+
+DEFINE_VK_INTERNAL(_TILDE),
+
+DEFINE_VK_INTERNAL(_COMMA),
+DEFINE_VK_INTERNAL(_PERIOD),
+DEFINE_VK_INTERNAL(_SLASH),
+DEFINE_VK_INTERNAL(_BACK_QUOTE),
+DEFINE_VK_INTERNAL(_OPEN_BRACKET),
+DEFINE_VK_INTERNAL(_BACK_SLASH),
+DEFINE_VK_INTERNAL(_CLOSE_BRACKET),
+DEFINE_VK_INTERNAL(_QUOTE),
+
+DEFINE_VK_INTERNAL(_META),
+DEFINE_VK_INTERNAL(_ALTGR)
+
+#undef DEFINE_VK_INTERNAL
+#undef DEFINE_VK_INTERNAL2
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -61,16 +61,17 @@ CPPSRCS		= \
 		nsDOMKeyboardEvent.cpp \
 		nsDOMTextEvent.cpp \
 		nsDOMMouseEvent.cpp \
 		nsDOMMouseScrollEvent.cpp \
 		nsDOMDragEvent.cpp \
 		nsDOMMutationEvent.cpp \
 		nsDOMPopupBlockedEvent.cpp \
 		nsDOMDeviceProximityEvent.cpp \
+		nsDOMUserProximityEvent.cpp \
 		nsDOMDeviceLightEvent.cpp \
 		nsDOMDeviceOrientationEvent.cpp \
 		nsDOMDeviceMotionEvent.cpp \
 		nsDOMBeforeUnloadEvent.cpp \
 		nsDOMPageTransitionEvent.cpp \
 		nsDOMXULCommandEvent.cpp \
 		nsDOMCommandEvent.cpp \
 		nsDOMMessageEvent.cpp \
--- a/content/events/src/nsDOMDataContainerEvent.cpp
+++ b/content/events/src/nsDOMDataContainerEvent.cpp
@@ -84,17 +84,18 @@ nsDOMDataContainerEvent::GetData(const n
 NS_IMETHODIMP
 nsDOMDataContainerEvent::SetData(const nsAString& aKey, nsIVariant *aData)
 {
   NS_ENSURE_ARG(aData);
 
   // Make sure this event isn't already being dispatched.
   NS_ENSURE_STATE(!(NS_IS_EVENT_IN_DISPATCH(mEvent)));
   NS_ENSURE_STATE(mData.IsInitialized());
-  return mData.Put(aKey, aData) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+  mData.Put(aKey, aData);
+  return NS_OK;
 }
 
 nsresult
 NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult,
                    nsPresContext* aPresContext,
                    nsEvent* aEvent)
 {
   nsDOMDataContainerEvent* it =
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -123,16 +123,17 @@ static const char* const sEventNames[] =
   "MozScrolledAreaChanged",
   "transitionend",
   "animationstart",
   "animationend",
   "animationiteration",
   "devicemotion",
   "deviceorientation",
   "deviceproximity",
+  "userproximity",
   "devicelight"
 };
 
 static char *sPopupAllowedEvents;
 
 
 nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
 {
@@ -1552,16 +1553,18 @@ const char* nsDOMEvent::GetEventName(PRU
   case NS_ANIMATION_ITERATION:
     return sEventNames[eDOMEvents_animationiteration];
   case NS_DEVICE_MOTION:
     return sEventNames[eDOMEvents_devicemotion];
   case NS_DEVICE_ORIENTATION:
     return sEventNames[eDOMEvents_deviceorientation];
   case NS_DEVICE_PROXIMITY:
     return sEventNames[eDOMEvents_deviceproximity];
+  case NS_USER_PROXIMITY:
+    return sEventNames[eDOMEvents_userproximity];
   case NS_DEVICE_LIGHT:
     return sEventNames[eDOMEvents_devicelight];
   case NS_FULLSCREENCHANGE:
     return sEventNames[eDOMEvents_mozfullscreenchange];
   case NS_FULLSCREENERROR:
     return sEventNames[eDOMEvents_mozfullscreenerror];
   default:
     break;
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -206,16 +206,17 @@ public:
     eDOMEvents_MozScrolledAreaChanged,
     eDOMEvents_transitionend,
     eDOMEvents_animationstart,
     eDOMEvents_animationend,
     eDOMEvents_animationiteration,
     eDOMEvents_devicemotion,
     eDOMEvents_deviceorientation,
     eDOMEvents_deviceproximity,
+    eDOMEvents_userproximity,
     eDOMEvents_devicelight
   };
 
   nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);
   virtual ~nsDOMEvent();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMEvent, nsIDOMEvent)
new file mode 100644
--- /dev/null
+++ b/content/events/src/nsDOMUserProximityEvent.cpp
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsDOMUserProximityEvent.h"
+#include "nsContentUtils.h"
+#include "DictionaryHelpers.h"
+
+NS_IMPL_ADDREF_INHERITED(nsDOMUserProximityEvent, nsDOMEvent)
+NS_IMPL_RELEASE_INHERITED(nsDOMUserProximityEvent, nsDOMEvent)
+
+DOMCI_DATA(UserProximityEvent, nsDOMUserProximityEvent)
+
+NS_INTERFACE_MAP_BEGIN(nsDOMUserProximityEvent)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMUserProximityEvent)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(UserProximityEvent)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
+
+NS_IMETHODIMP
+nsDOMUserProximityEvent::InitUserProximityEvent(const nsAString & aEventTypeArg,
+                                                bool aCanBubbleArg,
+                                                bool aCancelableArg,
+                                                bool aNear)
+{
+  nsresult rv = nsDOMEvent::InitEvent(aEventTypeArg, aCanBubbleArg, aCancelableArg);
+  NS_ENSURE_SUCCESS(rv, rv);
+  mNear = aNear;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMUserProximityEvent::GetNear(bool *aNear)
+{
+  NS_ENSURE_ARG_POINTER(aNear);
+  *aNear = mNear;
+  return NS_OK;
+}
+
+nsresult
+nsDOMUserProximityEvent::InitFromCtor(const nsAString& aType,
+                                      JSContext* aCx, jsval* aVal)
+{
+  mozilla::dom::UserProximityEventInit d;
+  nsresult rv = d.Init(aCx, aVal);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return InitUserProximityEvent(aType, d.bubbles, d.cancelable, d.near);
+}
+
+nsresult
+NS_NewDOMUserProximityEvent(nsIDOMEvent** aInstancePtrResult,
+                            nsPresContext* aPresContext,
+                            nsEvent *aEvent) 
+{
+  NS_ENSURE_ARG_POINTER(aInstancePtrResult);
+  nsDOMUserProximityEvent* it = new nsDOMUserProximityEvent(aPresContext, aEvent);
+  return CallQueryInterface(it, aInstancePtrResult);
+}
new file mode 100644
--- /dev/null
+++ b/content/events/src/nsDOMUserProximityEvent.h
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsDOMUserProximityEvent_h__
+#define nsDOMUserProximityEvent_h__
+
+#include "nsIDOMUserProximityEvent.h"
+#include "nsDOMEvent.h"
+
+class nsDOMUserProximityEvent
+ : public nsDOMEvent
+ , public nsIDOMUserProximityEvent
+{
+public:
+
+  nsDOMUserProximityEvent(nsPresContext* aPresContext, nsEvent* aEvent)
+  : nsDOMEvent(aPresContext, aEvent),
+    mNear(false) {}
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // Forward to nsDOMEvent
+  NS_FORWARD_TO_NSDOMEVENT
+
+  // nsIDOMUserProximityEvent Interface
+  NS_DECL_NSIDOMUSERPROXIMITYEVENT
+
+  virtual nsresult InitFromCtor(const nsAString& aType,
+                                JSContext* aCx,
+                                jsval* aVal);
+protected:
+  bool mNear;
+};
+
+#endif
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -285,17 +285,17 @@ nsEventListenerManager::AddEventListener
       // If aType is NS_MUTATION_SUBTREEMODIFIED, we need to listen all
       // mutations. nsContentUtils::HasMutationListeners relies on this.
       window->SetMutationListeners((aType == NS_MUTATION_SUBTREEMODIFIED) ?
                                    kAllMutationBits :
                                    MutationBitForEventType(aType));
     }
   } else if (aTypeAtom == nsGkAtoms::ondeviceorientation) {
     EnableDevice(NS_DEVICE_ORIENTATION);
-  } else if (aTypeAtom == nsGkAtoms::ondeviceproximity) {
+  } else if (aTypeAtom == nsGkAtoms::ondeviceproximity || aTypeAtom == nsGkAtoms::onuserproximity) {
     EnableDevice(NS_DEVICE_PROXIMITY);
   } else if (aTypeAtom == nsGkAtoms::ondevicelight) {
     EnableDevice(NS_DEVICE_LIGHT);
   } else if (aTypeAtom == nsGkAtoms::ondevicemotion) {
     EnableDevice(NS_DEVICE_MOTION);
   } else if ((aType >= NS_MOZTOUCH_DOWN && aType <= NS_MOZTOUCH_UP) ||
              (aTypeAtom == nsGkAtoms::ontouchstart ||
               aTypeAtom == nsGkAtoms::ontouchend ||
@@ -346,16 +346,17 @@ nsEventListenerManager::EnableDevice(PRU
 
   NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window");
 
   switch (aType) {
     case NS_DEVICE_ORIENTATION:
       window->EnableDeviceSensor(SENSOR_ORIENTATION);
       break;
     case NS_DEVICE_PROXIMITY:
+    case NS_USER_PROXIMITY:
       window->EnableDeviceSensor(SENSOR_PROXIMITY);
       break;
     case NS_DEVICE_LIGHT:
       window->EnableDeviceSensor(SENSOR_LIGHT);
       break;
     case NS_DEVICE_MOTION:
       window->EnableDeviceSensor(SENSOR_ACCELERATION);
       window->EnableDeviceSensor(SENSOR_LINEAR_ACCELERATION);
@@ -382,16 +383,17 @@ nsEventListenerManager::DisableDevice(PR
       window->DisableDeviceSensor(SENSOR_ORIENTATION);
       break;
     case NS_DEVICE_MOTION:
       window->DisableDeviceSensor(SENSOR_ACCELERATION);
       window->DisableDeviceSensor(SENSOR_LINEAR_ACCELERATION);
       window->DisableDeviceSensor(SENSOR_GYROSCOPE);
       break;
     case NS_DEVICE_PROXIMITY:
+    case NS_USER_PROXIMITY:
       window->DisableDeviceSensor(SENSOR_PROXIMITY);
       break;
     case NS_DEVICE_LIGHT:
       window->DisableDeviceSensor(SENSOR_LIGHT);
       break;
     default:
       NS_WARNING("Disabling an unknown device sensor.");
       break;
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -2217,16 +2217,18 @@ nsEventStateManager::DetermineDragTarget
                                          nsDOMDataTransfer* aDataTransfer,
                                          nsISelection** aSelection,
                                          nsIContent** aTargetNode)
 {
   *aTargetNode = nsnull;
 
   nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
   nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
+  if (!window)
+    return;
 
   // GetDragData determines if a selection, link or image in the content
   // should be dragged, and places the data associated with the drag in the
   // data transfer.
   // mGestureDownContent is the node where the mousedown event for the drag
   // occurred, and aSelectionTarget is the node to use when a selection is used
   bool canDrag;
   nsCOMPtr<nsIContent> dragDataNode;
@@ -3533,16 +3535,23 @@ nsEventStateManager::IsTargetCrossProces
     return false;
   return TabParent::GetIMETabParent() != nsnull;
 }
 
 void
 nsEventStateManager::NotifyDestroyPresContext(nsPresContext* aPresContext)
 {
   nsIMEStateManager::OnDestroyPresContext(aPresContext);
+  if (mHoverContent) {
+    // Bug 70855: Presentation is going away, possibly for a reframe.
+    // Reset the hover state so that if we're recreating the presentation,
+    // we won't have the old hover state still set in the new presentation,
+    // as if the new presentation is resized, a new element may be hovered. 
+    SetContentState(nsnull, NS_EVENT_STATE_HOVER);
+  }
 }
 
 void
 nsEventStateManager::SetPresContext(nsPresContext* aPresContext)
 {
   mPresContext = aPresContext;
 }
 
--- a/content/events/test/test_eventctors.html
+++ b/content/events/test/test_eventctors.html
@@ -374,16 +374,24 @@ e = new DeviceProximityEvent("hello", {m
 ok(e.type, "hello", "Wrong event type!");
 ok(!e.isTrusted, "Event should not be trusted");
 is(e.value, 1, "value should be 1");
 is(e.min, 0, "min should be 0");
 is(e.max, 2, "max should be 2");
 document.dispatchEvent(e);
 is(receivedEvent, e, "Wrong event!");
 
+// UserProximityEvent
+e = new UserProximityEvent("hello", {near: true});
+ok(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.near, true, "near should be true");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
 // DeviceLightEvent
 e = new DeviceLightEvent("hello", {value: 1} );
 ok(e.type, "hello", "Wrong event type!");
 ok(!e.isTrusted, "Event should not be trusted");
 is(e.value, 1, "value should be 1");
 document.dispatchEvent(e);
 is(receivedEvent, e, "Wrong event!");
 
new file mode 100644
--- /dev/null
+++ b/content/html/content/crashtests/616401.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<script>
+var c = document.createElement("canvas");
+c.getContext("experimental-webgl", {
+  get a() { throw 7; },
+  get b() { throw 8; }
+});
+</script>
--- a/content/html/content/crashtests/crashtests.list
+++ b/content/html/content/crashtests/crashtests.list
@@ -22,16 +22,17 @@ load 596785-1.html
 load 596785-2.html
 load 604807.html
 load 605264.html
 load 606430-1.html
 load 602117.html
 load 613027.html
 load 614279.html
 load 614988-1.html
+load 616401.html
 load 620078-1.html
 load 620078-2.html
 load 680922-1.xul
 load 682058.xhtml
 load 682460.html
 load 673853.html
 load 738744.xhtml
 load 741250.xhtml
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -144,13 +144,12 @@ INCLUDES	+= \
 		-I$(srcdir)/../../../../layout/style \
 		-I$(srcdir)/../../../../layout/tables \
 		-I$(srcdir)/../../../../layout/xul/base/src \
 		-I$(srcdir)/../../../../layout/generic \
 		-I$(srcdir)/../../../../dom/base \
 		-I$(srcdir)/../../../../editor/libeditor/base \
 		-I$(srcdir)/../../../../editor/libeditor/text \
 		-I$(srcdir) \
-		-I$(topsrcdir)/js/xpconnect/src \
 		-I$(topsrcdir)/xpcom/ds \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -815,31 +815,31 @@ nsGenericHTMLElement::SetInnerHTML(const
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsGenericHTMLElement::SetOuterHTML(const nsAString& aOuterHTML)
 {
-  nsINode* parent = GetNodeParent();
+  nsCOMPtr<nsINode> parent = GetNodeParent();
   if (!parent) {
     return NS_OK;
   }
 
   if (parent->NodeType() == nsIDOMNode::DOCUMENT_NODE) {
     return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
   }
 
   if (OwnerDoc()->IsHTML()) {
     nsIAtom* localName;
     PRInt32 namespaceID;
     if (parent->IsElement()) {
-      localName = static_cast<nsIContent*>(parent)->Tag();
-      namespaceID = static_cast<nsIContent*>(parent)->GetNameSpaceID();
+      localName = static_cast<nsIContent*>(parent.get())->Tag();
+      namespaceID = static_cast<nsIContent*>(parent.get())->GetNameSpaceID();
     } else {
       NS_ASSERTION(parent->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
         "How come the parent isn't a document, a fragment or an element?");
       localName = nsGkAtoms::body;
       namespaceID = kNameSpaceID_XHTML;
     }
     nsCOMPtr<nsIDOMDocumentFragment> df;
     nsresult rv = NS_NewDocumentFragment(getter_AddRefs(df),
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -521,30 +521,29 @@ nsHTMLCanvasElement::GetContext(const ns
       return NS_ERROR_FAILURE;
     }
 
     // note: if any contexts end up supporting something other
     // than objects, e.g. plain strings, then we'll need to expand
     // this to know how to create nsISupportsStrings etc.
 
     nsCOMPtr<nsIWritablePropertyBag2> contextProps;
-    if (aContextOptions.isObject())
-    {
-      JSContext *cx = nsContentUtils::GetCurrentJSContext();
+    if (aContextOptions.isObject()) {
+      JSContext* cx = nsContentUtils::GetCurrentJSContext();
 
       contextProps = do_CreateInstance("@mozilla.org/hash-property-bag;1");
 
-      JSObject *opts = &aContextOptions.toObject();
-      JS::AutoIdArray props(cx, JS_Enumerate(cx, opts));
+      JSObject& opts = aContextOptions.toObject();
+      JS::AutoIdArray props(cx, JS_Enumerate(cx, &opts));
       for (size_t i = 0; !!props && i < props.length(); ++i) {
         jsid propid = props[i];
         jsval propname, propval;
         if (!JS_IdToValue(cx, propid, &propname) ||
-            !JS_GetPropertyById(cx, opts, propid, &propval)) {
-          continue;
+            !JS_GetPropertyById(cx, &opts, propid, &propval)) {
+          return NS_ERROR_FAILURE;
         }
 
         JSString *propnameString = JS_ValueToString(cx, propname);
         nsDependentJSString pstr;
         if (!propnameString || !pstr.init(cx, propnameString)) {
           mCurrentContext = nsnull;
           return NS_ERROR_FAILURE;
         }
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -284,22 +284,19 @@ nsHTMLFormElement::Init()
   nsresult rv = mControls->Init();
   
   if (NS_FAILED(rv))
   {
     mControls = nsnull;
     return rv;
   }
   
-  NS_ENSURE_TRUE(mSelectedRadioButtons.Init(4),
-                 NS_ERROR_OUT_OF_MEMORY);
-  NS_ENSURE_TRUE(mRequiredRadioButtonCounts.Init(4),
-                 NS_ERROR_OUT_OF_MEMORY);
-  NS_ENSURE_TRUE(mValueMissingRadioGroups.Init(4),
-                 NS_ERROR_OUT_OF_MEMORY);
+  mSelectedRadioButtons.Init(4);
+  mRequiredRadioButtonCounts.Init(4);
+  mValueMissingRadioGroups.Init(4);
 
   return NS_OK;
 }
 
 
 // nsISupports
 
 static PLDHashOperator
@@ -1889,18 +1886,17 @@ nsHTMLFormElement::IndexOfControl(nsIFor
   PRInt32 index = nsnull;
   return mControls->IndexOfControl(aControl, &index) == NS_OK ? index : nsnull;
 }
 
 NS_IMETHODIMP
 nsHTMLFormElement::SetCurrentRadioButton(const nsAString& aName,
                                          nsIDOMHTMLInputElement* aRadio)
 {
-  NS_ENSURE_TRUE(mSelectedRadioButtons.Put(aName, aRadio),
-                 NS_ERROR_OUT_OF_MEMORY);
+  mSelectedRadioButtons.Put(aName, aRadio);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLFormElement::GetCurrentRadioButton(const nsAString& aName,
                                          nsIDOMHTMLInputElement** aRadio)
 {
@@ -2139,20 +2135,17 @@ nsFormControlList::nsFormControlList(nsH
 nsFormControlList::~nsFormControlList()
 {
   mForm = nsnull;
   Clear();
 }
 
 nsresult nsFormControlList::Init()
 {
-  NS_ENSURE_TRUE(
-    mNameLookupTable.Init(NS_FORM_CONTROL_LIST_HASHTABLE_SIZE),
-    NS_ERROR_OUT_OF_MEMORY);
-
+  mNameLookupTable.Init(NS_FORM_CONTROL_LIST_HASHTABLE_SIZE);
   return NS_OK;
 }
 
 void
 nsFormControlList::DropFormReference()
 {
   mForm = nsnull;
   Clear();
@@ -2305,19 +2298,17 @@ nsFormControlList::AddElementToTable(nsG
     return NS_OK;
   }
 
   nsCOMPtr<nsISupports> supports;
   mNameLookupTable.Get(aName, getter_AddRefs(supports));
 
   if (!supports) {
     // No entry found, add the form control
-    NS_ENSURE_TRUE(mNameLookupTable.Put(aName,
-                                        NS_ISUPPORTS_CAST(nsIContent*, aChild)),
-                   NS_ERROR_FAILURE);
+    mNameLookupTable.Put(aName, NS_ISUPPORTS_CAST(nsIContent*, aChild));
   } else {
     // Found something in the hash, check its type
     nsCOMPtr<nsIContent> content = do_QueryInterface(supports);
 
     if (content) {
       // Check if the new content is the same as the one we found in the
       // hash, if it is then we leave it in the hash as it is, this will
       // happen if a form control has both a name and an id with the same
@@ -2340,18 +2331,17 @@ nsFormControlList::AddElementToTable(nsG
 
       list->AppendElement(newFirst ? aChild : content);
       list->AppendElement(newFirst ? content : aChild);
 
 
       nsCOMPtr<nsISupports> listSupports = do_QueryObject(list);
 
       // Replace the element with the list.
-      NS_ENSURE_TRUE(mNameLookupTable.Put(aName, listSupports),
-                     NS_ERROR_FAILURE);
+      mNameLookupTable.Put(aName, listSupports);
     } else {
       // There's already a list in the hash, add the child to the list
       nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
       NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
 
       // Upcast, uggly, but it works!
       nsSimpleContentList *list =
         static_cast<nsSimpleContentList*>(nodeList.get());
@@ -2450,17 +2440,17 @@ nsFormControlList::RemoveElementFromTabl
     // If the list is empty we remove if from our hash, this shouldn't
     // happen tho
     mNameLookupTable.Remove(aName);
   } else if (length == 1) {
     // Only one element left, replace the list in the hash with the
     // single element.
     nsIContent* node = list->GetNodeAt(0);
     if (node) {
-      NS_ENSURE_TRUE(mNameLookupTable.Put(aName, node),NS_ERROR_FAILURE);
+      mNameLookupTable.Put(aName, node);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 nsFormControlList::GetSortedControls(nsTArray<nsGenericHTMLFormElement*>& aControls) const
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -2189,16 +2189,20 @@ bool nsHTMLMediaElement::ShouldHandleMed
 #ifdef MOZ_OGG
   if (IsOggType(nsDependentCString(aMIMEType)))
     return true;
 #endif
 #ifdef MOZ_WEBM
   if (IsWebMType(nsDependentCString(aMIMEType)))
     return true;
 #endif
+#ifdef MOZ_GSTREAMER
+  if (IsH264Type(nsDependentCString(aMIMEType)))
+    return true;
+#endif
   // We should not return true for Wave types, since there are some
   // Wave codecs actually in use in the wild that we don't support, and
   // we should allow those to be handled by plugins or helper apps.
   // Furthermore people can play Wave files on most platforms by other
   // means.
   return false;
 }
 
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1858,17 +1858,17 @@ nsTextEditorState::SetValue(const nsAStr
         mTextListener->SettingValue(true);
 
         // Also don't enforce max-length here
         PRInt32 savedMaxLength;
         plaintextEditor->GetMaxTextLength(&savedMaxLength);
         plaintextEditor->SetMaxTextLength(-1);
 
         if (insertValue.IsEmpty()) {
-          mEditor->DeleteSelection(nsIEditor::eNone);
+          mEditor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
         } else {
           plaintextEditor->InsertText(insertValue);
         }
 
         mTextListener->SettingValue(false);
 
         if (!weakFrame.IsAlive()) {
           // If the frame was destroyed because of a flush somewhere inside
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1349,17 +1349,26 @@ nsHTMLDocument::Open(const nsAString& aC
     NS_ParseContentType(NS_ConvertUTF16toUTF8(type), actualType, dummy);
     if (!actualType.EqualsLiteral("text/html") &&
         !type.EqualsLiteral("replace")) {
       contentType.AssignLiteral("text/plain");
     }
   }
 
   // If we already have a parser we ignore the document.open call.
-  if (mParser) {
+  if (mParser || mParserAborted) {
+    // The WHATWG spec says: "If the document has an active parser that isn't
+    // a script-created parser, and the insertion point associated with that
+    // parser's input stream is not undefined (that is, it does point to
+    // somewhere in the input stream), then the method does nothing. Abort
+    // these steps and return the Document object on which the method was
+    // invoked."
+    // Note that aborting a parser leaves the parser "active" with its
+    // insertion point "not undefined". We track this using mParserAborted,
+    // because aborting a parser nulls out mParser.
     return NS_OK;
   }
 
   // No calling document.open() without a script global object
   if (!mScriptGlobalObject) {
     return NS_OK;
   }
 
@@ -3072,16 +3081,25 @@ nsHTMLDocument::ExecCommand(const nsAStr
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   //  for optional parameters see dom/src/base/nsHistory.cpp: HistoryImpl::Go()
   //  this might add some ugly JS dependencies?
 
   *_retval = false;
 
+  nsCAutoString cmdToDispatch, paramStr;
+  bool isBool, boolVal;
+  if (!ConvertToMidasInternalCommand(commandID, value,
+                                     cmdToDispatch, paramStr,
+                                     isBool, boolVal)) {
+    // Return false
+    return NS_OK;
+  }
+
   // if editing is not on, bail
   if (!IsEditingOnAfterFlush())
     return NS_ERROR_FAILURE;
 
   // if they are requesting UI from us, let's fail since we have no UI
   if (doShowUI)
     return NS_OK;
 
@@ -3105,22 +3123,16 @@ nsHTMLDocument::ExecCommand(const nsAStr
   GetMidasCommandManager(getter_AddRefs(cmdMgr));
   if (!cmdMgr)
     return NS_ERROR_FAILURE;
 
   nsIDOMWindow *window = GetWindow();
   if (!window)
     return NS_ERROR_FAILURE;
 
-  nsCAutoString cmdToDispatch, paramStr;
-  bool isBool, boolVal;
-  if (!ConvertToMidasInternalCommand(commandID, value,
-                                     cmdToDispatch, paramStr, isBool, boolVal))
-    return NS_OK;
-
   if ((cmdToDispatch.EqualsLiteral("cmd_paragraphState") ||
        cmdToDispatch.EqualsLiteral("cmd_fontSize")) && paramStr.IsEmpty()) {
     // Invalid value
     return NS_OK;
   }
 
   if (!isBool && paramStr.IsEmpty()) {
     rv = cmdMgr->DoCommand(cmdToDispatch.get(), nsnull, window);
@@ -3152,62 +3164,66 @@ nsHTMLDocument::ExecCommand(const nsAStr
 /* boolean queryCommandEnabled(in DOMString commandID); */
 NS_IMETHODIMP
 nsHTMLDocument::QueryCommandEnabled(const nsAString & commandID,
                                     bool *_retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
   *_retval = false;
 
-  // if editing is not on, bail
-  if (!IsEditingOnAfterFlush())
-    return NS_ERROR_FAILURE;
-
-  // get command manager and dispatch command to our window if it's acceptable
-  nsCOMPtr<nsICommandManager> cmdMgr;
-  GetMidasCommandManager(getter_AddRefs(cmdMgr));
-  if (!cmdMgr)
-    return NS_ERROR_FAILURE;
-
-  nsIDOMWindow *window = GetWindow();
-  if (!window)
-    return NS_ERROR_FAILURE;
-
   nsCAutoString cmdToDispatch;
-  if (!ConvertToMidasInternalCommand(commandID, cmdToDispatch))
-    return NS_OK; // queryCommandEnabled returns false on unsupported commands
-
-  return cmdMgr->IsCommandEnabled(cmdToDispatch.get(), window, _retval);
-}
-
-/* boolean queryCommandIndeterm (in DOMString commandID); */
-NS_IMETHODIMP
-nsHTMLDocument::QueryCommandIndeterm(const nsAString & commandID,
-                                     bool *_retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-  *_retval = false;
+  if (!ConvertToMidasInternalCommand(commandID, cmdToDispatch)) {
+    // Return false
+    return NS_OK;
+  }
 
   // if editing is not on, bail
   if (!IsEditingOnAfterFlush())
     return NS_ERROR_FAILURE;
 
   // get command manager and dispatch command to our window if it's acceptable
   nsCOMPtr<nsICommandManager> cmdMgr;
   GetMidasCommandManager(getter_AddRefs(cmdMgr));
   if (!cmdMgr)
     return NS_ERROR_FAILURE;
 
   nsIDOMWindow *window = GetWindow();
   if (!window)
     return NS_ERROR_FAILURE;
 
+  return cmdMgr->IsCommandEnabled(cmdToDispatch.get(), window, _retval);
+}
+
+/* boolean queryCommandIndeterm (in DOMString commandID); */
+NS_IMETHODIMP
+nsHTMLDocument::QueryCommandIndeterm(const nsAString & commandID,
+                                     bool *_retval)
+{
+  NS_ENSURE_ARG_POINTER(_retval);
+  *_retval = false;
+
   nsCAutoString cmdToDispatch;
-  if (!ConvertToMidasInternalCommand(commandID, cmdToDispatch))
-    return NS_ERROR_NOT_IMPLEMENTED;
+  if (!ConvertToMidasInternalCommand(commandID, cmdToDispatch)) {
+    // Return false
+    return NS_OK;
+  }
+
+  // if editing is not on, bail
+  if (!IsEditingOnAfterFlush())
+    return NS_ERROR_FAILURE;
+
+  // get command manager and dispatch command to our window if it's acceptable
+  nsCOMPtr<nsICommandManager> cmdMgr;
+  GetMidasCommandManager(getter_AddRefs(cmdMgr));
+  if (!cmdMgr)
+    return NS_ERROR_FAILURE;
+
+  nsIDOMWindow *window = GetWindow();
+  if (!window)
+    return NS_ERROR_FAILURE;
 
   nsresult rv;
   nsCOMPtr<nsICommandParams> cmdParams = do_CreateInstance(
                                            NS_COMMAND_PARAMS_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = cmdMgr->GetCommandState(cmdToDispatch.get(), window, cmdParams);
   if (NS_FAILED(rv))
@@ -3222,16 +3238,25 @@ nsHTMLDocument::QueryCommandIndeterm(con
 
 /* boolean queryCommandState(in DOMString commandID); */
 NS_IMETHODIMP
 nsHTMLDocument::QueryCommandState(const nsAString & commandID, bool *_retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
   *_retval = false;
 
+  nsCAutoString cmdToDispatch, paramToCheck;
+  bool dummy, dummy2;
+  if (!ConvertToMidasInternalCommand(commandID, commandID,
+                                     cmdToDispatch, paramToCheck,
+                                     dummy, dummy2)) {
+    // Return false
+    return NS_OK;
+  }
+
   // if editing is not on, bail
   if (!IsEditingOnAfterFlush())
     return NS_ERROR_FAILURE;
 
   // get command manager and dispatch command to our window if it's acceptable
   nsCOMPtr<nsICommandManager> cmdMgr;
   GetMidasCommandManager(getter_AddRefs(cmdMgr));
   if (!cmdMgr)
@@ -3243,22 +3268,16 @@ nsHTMLDocument::QueryCommandState(const 
 
   if (commandID.LowerCaseEqualsLiteral("usecss")) {
     // Per spec, state is supported for styleWithCSS but not useCSS, so we just
     // return false always.
     *_retval = false;
     return NS_OK;
   }
 
-  nsCAutoString cmdToDispatch, paramToCheck;
-  bool dummy, dummy2;
-  if (!ConvertToMidasInternalCommand(commandID, commandID,
-                                     cmdToDispatch, paramToCheck, dummy, dummy2))
-    return NS_ERROR_NOT_IMPLEMENTED;
-
   nsresult rv;
   nsCOMPtr<nsICommandParams> cmdParams = do_CreateInstance(
                                            NS_COMMAND_PARAMS_CONTRACTID, &rv);
   if (!cmdParams)
     return NS_ERROR_OUT_OF_MEMORY;
 
   rv = cmdMgr->GetCommandState(cmdToDispatch.get(), window, cmdParams);
   if (NS_FAILED(rv))
@@ -3289,61 +3308,51 @@ nsHTMLDocument::QueryCommandState(const 
 }
 
 /* boolean queryCommandSupported(in DOMString commandID); */
 NS_IMETHODIMP
 nsHTMLDocument::QueryCommandSupported(const nsAString & commandID,
                                       bool *_retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
-  *_retval = false;
-
-  // if editing is not on, bail
-  if (!IsEditingOnAfterFlush())
-    return NS_ERROR_FAILURE;
-
-  // get command manager
-  nsCOMPtr<nsICommandManager> cmdMgr;
-  GetMidasCommandManager(getter_AddRefs(cmdMgr));
-  if (!cmdMgr)
-    return NS_ERROR_FAILURE;
 
   // commandID is supported if it can be converted to a Midas command
   nsCAutoString cmdToDispatch;
-  if (ConvertToMidasInternalCommand(commandID, cmdToDispatch))
-    *_retval = true;
+  *_retval = ConvertToMidasInternalCommand(commandID, cmdToDispatch);
 
   return NS_OK;
 }
 
 /* DOMString queryCommandValue(in DOMString commandID); */
 NS_IMETHODIMP
 nsHTMLDocument::QueryCommandValue(const nsAString & commandID,
                                   nsAString &_retval)
 {
   _retval.SetLength(0);
 
+  nsCAutoString cmdToDispatch, paramStr;
+  if (!ConvertToMidasInternalCommand(commandID, cmdToDispatch)) {
+    // Return empty string
+    return NS_OK;
+  }
+
   // if editing is not on, bail
   if (!IsEditingOnAfterFlush())
     return NS_ERROR_FAILURE;
 
   // get command manager and dispatch command to our window if it's acceptable
   nsCOMPtr<nsICommandManager> cmdMgr;
   GetMidasCommandManager(getter_AddRefs(cmdMgr));
   if (!cmdMgr)
     return NS_ERROR_FAILURE;
 
   nsIDOMWindow *window = GetWindow();
   if (!window)
     return NS_ERROR_FAILURE;
 
-  nsCAutoString cmdToDispatch, paramStr;
-  if (!ConvertToMidasInternalCommand(commandID, cmdToDispatch))
-    return NS_ERROR_NOT_IMPLEMENTED;
-
   // create params
   nsresult rv;
   nsCOMPtr<nsICommandParams> cmdParams = do_CreateInstance(
                                            NS_COMMAND_PARAMS_CONTRACTID, &rv);
   if (!cmdParams)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // this is a special command since we are calling "DoCommand rather than
--- a/content/media/AudioSegment.h
+++ b/content/media/AudioSegment.h
@@ -118,16 +118,17 @@ public:
   }
   void ApplyVolume(float aVolume);
   /**
    * aOutput must have a matching number of channels, but we will automatically
    * convert sample formats.
    */
   void WriteTo(nsAudioStream* aOutput);
 
+  using MediaSegmentBase<AudioSegment, AudioChunk>::AppendFrom;
   void AppendFrom(AudioSegment* aSource)
   {
     NS_ASSERTION(aSource->mChannels == mChannels, "Non-matching channels");
     MediaSegmentBase<AudioSegment, AudioChunk>::AppendFrom(aSource);
   }
 
   // Segment-generic methods not in MediaSegmentBase
   void InitFrom(const AudioSegment& aOther)
--- a/content/media/gstreamer/nsGStreamerReader.h
+++ b/content/media/gstreamer/nsGStreamerReader.h
@@ -29,16 +29,20 @@ public:
                                 PRInt64 aTimeThreshold);
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime,
                         PRInt64 aStartTime,
                         PRInt64 aEndTime,
                         PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
+  virtual bool IsSeekableInBufferedRanges() {
+    return true;
+  }
+
   virtual bool HasAudio() {
     return mInfo.mHasAudio;
   }
 
   virtual bool HasVideo() {
     return mInfo.mHasVideo;
   }
 
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -980,17 +980,23 @@ nsresult nsBuiltinDecoder::GetSeekable(n
 
   if (IsSeekable()) {
     double end = IsInfinite() ? std::numeric_limits<double>::infinity()
                               : initialTime + GetDuration();
     aSeekable->Add(initialTime, end);
     return NS_OK;
   }
 
-  return GetBuffered(aSeekable);
+  if (mDecoderStateMachine->IsSeekableInBufferedRanges()) {
+    return GetBuffered(aSeekable);
+  } else {
+    // The stream is not seekable using only buffered ranges, and is not
+    // seekable. Don't allow seeking (return no ranges in |seekable|).
+    return NS_OK;
+  }
 }
 
 void nsBuiltinDecoder::SetEndTime(double aTime)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (mDecoderStateMachine) {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mDecoderStateMachine->SetFragmentEndTime(static_cast<PRInt64>(aTime * USECS_PER_S));
--- a/content/media/nsBuiltinDecoder.h
+++ b/content/media/nsBuiltinDecoder.h
@@ -326,16 +326,19 @@ public:
   // and an invalidate of the frame being dispatched asynchronously if
   // there is no such event currently queued.
   // Only called on the decoder thread. Must be called with
   // the decode monitor held.
   virtual void UpdatePlaybackPosition(PRInt64 aTime) = 0;
 
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered) = 0;
 
+  // Return true if the media is seekable using only buffered ranges.
+  virtual bool IsSeekableInBufferedRanges() = 0;
+
   virtual PRInt64 VideoQueueMemoryInUse() = 0;
   virtual PRInt64 AudioQueueMemoryInUse() = 0;
 
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset) = 0;
 
   // Causes the state machine to switch to buffering state, and to
   // immediately stop playback and buffer downloaded data. Must be called
   // with the decode monitor held. Called on the state machine thread and
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -475,16 +475,19 @@ public:
 
   // Populates aBuffered with the time ranges which are buffered. aStartTime
   // must be the presentation time of the first frame in the media, e.g.
   // the media time corresponding to playback time/position 0. This function
   // should only be called on the main thread.
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered,
                                PRInt64 aStartTime) = 0;
 
+  // True if we can seek using only buffered ranges. This is backend dependant.
+  virtual bool IsSeekableInBufferedRanges() = 0;
+
   class VideoQueueMemoryFunctor : public nsDequeFunctor {
   public:
     VideoQueueMemoryFunctor() : mResult(0) {}
 
     virtual void* operator()(void* anObject) {
       const VideoData* v = static_cast<const VideoData*>(anObject);
       if (!v->mImage) {
         return nsnull;
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -431,19 +431,19 @@ nsBuiltinDecoderStateMachine::nsBuiltinD
   mDecodeThreadIdle(false),
   mStopAudioThread(true),
   mQuickBuffering(false),
   mIsRunning(false),
   mRunAgain(false),
   mDispatchedRunEvent(false),
   mDecodeThreadWaiting(false),
   mRealTime(aRealTime),
-  mRequestedNewDecodeThread(false),
   mDidThrottleAudioDecoding(false),
   mDidThrottleVideoDecoding(false),
+  mRequestedNewDecodeThread(false),
   mEventManager(aDecoder)
 {
   MOZ_COUNT_CTOR(nsBuiltinDecoderStateMachine);
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   StateMachineTracker::Instance().EnsureGlobalStateMachine();
 
   // only enable realtime mode when "media.realtime_decoder.enabled" is true.
@@ -534,17 +534,17 @@ void nsBuiltinDecoderStateMachine::SendO
 
   if (aAudio->mTime <= aStream->mLastAudioPacketTime) {
     // ignore packet that we've already processed
     return;
   }
   aStream->mLastAudioPacketTime = aAudio->mTime;
   aStream->mLastAudioPacketEndTime = aAudio->GetEnd();
 
-  NS_ASSERTION(aOutput->GetChannels() == aAudio->mChannels,
+  NS_ASSERTION(aOutput->GetChannels() == PRInt32(aAudio->mChannels),
                "Wrong number of channels");
 
   // This logic has to mimic AudioLoop closely to make sure we write
   // the exact same silences
   CheckedInt64 audioWrittenOffset = UsecsToFrames(mInfo.mAudioRate,
       aStream->mAudioFramesWrittenBaseTime + mStartTime) + aStream->mAudioFramesWritten;
   CheckedInt64 frameOffset = UsecsToFrames(mInfo.mAudioRate, aAudio->mTime);
   if (!audioWrittenOffset.isValid() || !frameOffset.isValid())
@@ -630,17 +630,16 @@ void nsBuiltinDecoderStateMachine::SendO
     if (mInfo.mHasAudio) {
       nsAutoTArray<AudioData*,10> audio;
       // It's OK to hold references to the AudioData because while audio
       // is captured, only the decoder thread pops from the queue (see below).
       mReader->mAudioQueue.GetElementsAfter(stream->mLastAudioPacketTime, &audio);
       AudioSegment output;
       output.Init(mInfo.mAudioChannels);
       for (PRUint32 i = 0; i < audio.Length(); ++i) {
-        AudioData* a = audio[i];
         SendOutputStreamAudio(audio[i], stream, &output);
       }
       if (output.GetDuration() > 0) {
         mediaStream->AppendToTrack(TRACK_AUDIO, &output);
       }
       if (mReader->mAudioQueue.IsFinished() && !stream->mHaveSentFinishAudio) {
         mediaStream->EndTrack(TRACK_AUDIO);
         stream->mHaveSentFinishAudio = true;
@@ -1121,18 +1120,17 @@ void nsBuiltinDecoderStateMachine::Audio
     }
 
     PRInt64 framesWritten = 0;
     if (missingFrames.value() > 0) {
       // The next audio chunk begins some time after the end of the last chunk
       // we pushed to the audio hardware. We must push silence into the audio
       // hardware so that the next audio chunk begins playback at the correct
       // time.
-      missingFrames = NS_MIN(static_cast<PRInt64>(PR_UINT32_MAX),
-                             missingFrames.value());
+      missingFrames = NS_MIN<int64_t>(UINT32_MAX, missingFrames.value());
       LOG(PR_LOG_DEBUG, ("%p Decoder playing %d frames of silence",
                          mDecoder.get(), PRInt32(missingFrames.value())));
       framesWritten = PlaySilence(static_cast<PRUint32>(missingFrames.value()),
                                   channels, playedFrames.value());
     } else {
       framesWritten = PlayFromAudioQueue(sampleTime.value(), channels);
     }
     audioDuration += framesWritten;
--- a/content/media/nsBuiltinDecoderStateMachine.h
+++ b/content/media/nsBuiltinDecoderStateMachine.h
@@ -238,16 +238,23 @@ public:
     return mEndTime;
   }
 
   bool IsSeekable() {
     mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mSeekable;
   }
 
+  bool IsSeekableInBufferedRanges() {
+    if (mReader) {
+      return mReader->IsSeekableInBufferedRanges();
+    }
+    return false;
+  }
+
   // Sets the current frame buffer length for the MozAudioAvailable event.
   // Accessed on the main and state machine threads.
   virtual void SetFrameBufferLength(PRUint32 aLength);
 
   // Returns the shared state machine thread.
   static nsIThread* GetStateMachineThread();
 
   // Schedules the shared state machine thread to run the state machine.
--- a/content/media/ogg/nsOggCodecState.cpp
+++ b/content/media/ogg/nsOggCodecState.cpp
@@ -40,16 +40,19 @@
 #include "nsOggCodecState.h"
 #include "nsOggDecoder.h"
 #include <string.h>
 #include "nsTraceRefcnt.h"
 #include "VideoUtils.h"
 #include "nsBuiltinDecoderReader.h"
 
 #include "mozilla/StandardInteger.h"
+#include "mozilla/Util.h" // DebugOnly
+
+using namespace mozilla;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gBuiltinDecoderLog;
 #define LOG(type, msg) PR_LOG(gBuiltinDecoderLog, type, msg)
 #else
 #define LOG(type, msg)
 #endif
 
@@ -916,17 +919,17 @@ nsresult nsOpusState::PageIn(ogg_page* a
   }
   mUnstamped.Clear();
   return NS_OK;
 }
 
 void nsOpusState::ReconstructGranulepos(void)
 {
   NS_ASSERTION(mUnstamped.Length() > 0, "Must have unstamped packets");
-  ogg_packet* last = mUnstamped[mUnstamped.Length()-1];
+  DebugOnly<ogg_packet*> last = mUnstamped[mUnstamped.Length()-1];
   NS_ASSERTION(last->e_o_s || last->granulepos > 0,
       "Must know last granulepos!");
 
   // Loop through the packets backwards, subtracting the next
   // packet's duration from its granulepos to get the value
   // for the current packet.
   for (PRUint32 i = mUnstamped.Length() - 1; i > 0; i--) {
     ogg_packet* next = mUnstamped[i];
@@ -1255,22 +1258,17 @@ bool nsSkeletonState::DecodeHeader(ogg_p
     }
 
     // Extract the segment length.
     mLength = LEInt64(aPacket->packet + SKELETON_FILE_LENGTH_OFFSET);
 
     LOG(PR_LOG_DEBUG, ("Skeleton segment length: %lld", mLength));
 
     // Initialize the serianlno-to-index map.
-    bool init = mIndex.Init();
-    if (!init) {
-      NS_WARNING("Failed to initialize Ogg skeleton serialno-to-index map");
-      mActive = false;
-      return mDoneReadingHeaders = true;
-    }
+    mIndex.Init();
     mActive = true;
   } else if (IsSkeletonIndex(aPacket) && mVersion >= SKELETON_VERSION(4,0)) {
     if (!DecodeIndex(aPacket)) {
       // Failed to parse index, or invalid/hostile index. DecodeIndex() will
       // have deactivated the track.
       return mDoneReadingHeaders = true;
     }
 
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -121,21 +121,17 @@ nsOggReader::nsOggReader(nsBuiltinDecode
 
 nsOggReader::~nsOggReader()
 {
   ogg_sync_clear(&mOggState);
   MOZ_COUNT_DTOR(nsOggReader);
 }
 
 nsresult nsOggReader::Init(nsBuiltinDecoderReader* aCloneDonor) {
-  bool init = mCodecStates.Init();
-  NS_ASSERTION(init, "Failed to initialize mCodecStates");
-  if (!init) {
-    return NS_ERROR_FAILURE;
-  }
+  mCodecStates.Init();
   int ret = ogg_sync_init(&mOggState);
   NS_ENSURE_TRUE(ret == 0, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 nsresult nsOggReader::ResetDecode()
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
@@ -200,18 +196,17 @@ nsresult nsOggReader::ReadMetadata(nsVid
       // can follow in this Ogg segment, so there will be no other bitstreams
       // in the Ogg (unless it's invalid).
       readAllBOS = true;
     } else if (!mCodecStates.Get(serial, nsnull)) {
       // We've not encountered a stream with this serial number before. Create
       // an nsOggCodecState to demux it, and map that to the nsOggCodecState
       // in mCodecStates.
       codecState = nsOggCodecState::Create(&page);
-      DebugOnly<bool> r = mCodecStates.Put(serial, codecState);
-      NS_ASSERTION(r, "Failed to insert into mCodecStates");
+      mCodecStates.Put(serial, codecState);
       bitstreams.AppendElement(codecState);
       mKnownStreams.AppendElement(serial);
       if (codecState &&
           codecState->GetType() == nsOggCodecState::TYPE_VORBIS &&
           !mVorbisState)
       {
         // First Vorbis bitstream, we'll play this one. Subsequent Vorbis
         // bitstreams will be ignored.
@@ -446,17 +441,17 @@ nsresult nsOggReader::DecodeOpus(ogg_pac
   // Trim the initial samples.
   if (endTime < 0)
     return NS_OK;
   if (startTime < 0) {
     PRInt32 skip = mOpusState->mPreSkip;
     PRInt32 goodFrames = frames - skip;
     NS_ASSERTION(goodFrames > 0, "endTime calculation was wrong");
     nsAutoArrayPtr<AudioDataValue> goodBuffer(new AudioDataValue[goodFrames * channels]);
-    for (int i = 0; i < goodFrames*channels; i++)
+    for (PRInt32 i = 0; i < goodFrames * PRInt32(channels); i++)
       goodBuffer[i] = buffer[skip*channels + i];
 
     startTime = mOpusState->Time(endFrame - goodFrames);
     duration = endTime - startTime;
     frames = goodFrames;
     buffer = goodBuffer;
   }
 
--- a/content/media/ogg/nsOggReader.h
+++ b/content/media/ogg/nsOggReader.h
@@ -79,16 +79,21 @@ public:
   virtual bool HasVideo() {
     return mTheoraState != 0 && mTheoraState->mActive;
   }
 
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
+  // We use bisection to seek in buffered range.
+  virtual bool IsSeekableInBufferedRanges() {
+    return true;
+  }
+
 private:
 
   bool HasSkeleton() {
     return mSkeletonState != 0 && mSkeletonState->mActive;
   }
 
   // Seeks to the keyframe preceeding the target time using available
   // keyframe indexes.
--- a/content/media/raw/Makefile.in
+++ b/content/media/raw/Makefile.in
@@ -31,37 +31,37 @@
 # 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 *****
 
 
-DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
-LIBRARY_NAME	= gkconraw_s
-LIBXUL_LIBRARY  = 1
+MODULE = content
+LIBRARY_NAME = gkconraw_s
+LIBXUL_LIBRARY = 1
 
-EXPORTS		+= \
-		nsRawDecoder.h \
-                nsRawReader.h \
-		nsRawStructs.h \
-		$(NULL)
+EXPORTS += \
+  nsRawDecoder.h \
+  nsRawReader.h \
+  nsRawStructs.h \
+  $(NULL)
 
-CPPSRCS		+= \
-		nsRawDecoder.cpp \
-                nsRawReader.cpp \
-		$(NULL)
+CPPSRCS += \
+  nsRawDecoder.cpp \
+  nsRawReader.cpp \
+  $(NULL)
 
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES	+= \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../html/content/src \
--- a/content/media/raw/nsRawReader.h
+++ b/content/media/raw/nsRawReader.h
@@ -65,16 +65,21 @@ public:
   {
     return true;
   }
 
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
+  // By seeking in the media resource, it is possible to seek.
+  bool IsSeekableInBufferedRanges() {
+    return true;
+  }
+
 private:
   bool ReadFromResource(MediaResource *aResource, PRUint8 *aBuf, PRUint32 aLength);
 
   nsRawVideoHeader mMetadata;
   PRUint32 mCurrentFrame;
   double mFrameRate;
   PRUint32 mFrameSize;
   nsIntRect mPicture;
--- a/content/media/wave/nsWaveReader.h
+++ b/content/media/wave/nsWaveReader.h
@@ -63,16 +63,21 @@ public:
   {
     return false;
   }
 
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
+  // To seek in a buffered range, we just have to seek the stream.
+  virtual bool IsSeekableInBufferedRanges() {
+    return true;
+  }
+
 private:
   bool ReadAll(char* aBuf, PRInt64 aSize, PRInt64* aBytesRead = nsnull);
   bool LoadRIFFChunk();
   bool ScanForwardUntil(PRUint32 aWantedChunk, PRUint32* aChunkSize);
   bool LoadFormatChunk();
   bool FindDataOffset();
 
   // Returns the number of seconds that aBytes represents based on the
--- a/content/media/webm/nsWebMReader.h
+++ b/content/media/webm/nsWebMReader.h
@@ -151,16 +151,21 @@ public:
   }
 
   virtual bool HasVideo()
   {
     NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
     return mHasVideo;
   }
 
+  // Bug 575140, cannot seek in webm if no cue is present.
+  bool IsSeekableInBufferedRanges() {
+    return false;
+  }
+
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset);
 
 private:
   // Value passed to NextPacket to determine if we are reading a video or an
   // audio packet.
--- a/content/smil/nsSMILAnimationFunction.cpp
+++ b/content/smil/nsSMILAnimationFunction.cpp
@@ -210,26 +210,24 @@ nsSMILAnimationFunction::SampleLastValue
 }
 
 void
 nsSMILAnimationFunction::Activate(nsSMILTime aBeginTime)
 {
   mBeginTime = aBeginTime;
   mIsActive = true;
   mIsFrozen = false;
-  mFrozenValue = nsSMILValue();
   mHasChanged = true;
 }
 
 void
 nsSMILAnimationFunction::Inactivate(bool aIsFrozen)
 {
   mIsActive = false;
   mIsFrozen = aIsFrozen;
-  mFrozenValue = nsSMILValue();
   mHasChanged = true;
 }
 
 void
 nsSMILAnimationFunction::ComposeResult(const nsISMILAttr& aSMILAttr,
                                        nsSMILValue& aResult)
 {
   mHasChanged = false;
@@ -281,33 +279,24 @@ nsSMILAnimationFunction::ComposeResult(c
 
     // See comment in AccumulateResult: to-animation does not accumulate
     if (!IsToAnimation() && GetAccumulate() && mRepeatIteration) {
       // If the target attribute type doesn't support addition Add will
       // fail leaving result = last
       result.Add(last, mRepeatIteration);
     }
 
-  } else if (!mFrozenValue.IsNull() && !mHasChanged) {
-
-    // Frozen to animation
-    result = mFrozenValue;
-
   } else {
 
     // Interpolation
     if (NS_FAILED(InterpolateResult(values, result, aResult)))
       return;
 
     if (NS_FAILED(AccumulateResult(values, result)))
       return;
-
-    if (IsToAnimation() && mIsFrozen) {
-      mFrozenValue = result;
-    }
   }
 
   // If additive animation isn't required or isn't supported, set the value.
   if (!isAdditive || NS_FAILED(aResult.SandwichAdd(result))) {
     aResult.Swap(result);
     // Note: The old value of aResult is now in |result|, and it will get
     // cleaned up when |result| goes out of scope, when this function returns.
   }
@@ -354,32 +343,32 @@ nsSMILAnimationFunction::CompareTo(const
           ? -1 : 1;
 }
 
 bool
 nsSMILAnimationFunction::WillReplace() const
 {
   /*
    * In IsAdditive() we don't consider to-animation to be additive as it is
-   * a special case that is dealt with differently in the compositing method but
-   * here we return false for to animation as it builds on the underlying value
-   * unless its a frozen to animation.
+   * a special case that is dealt with differently in the compositing method.
+   * Here, however, we return FALSE for to-animation (i.e. it will NOT replace
+   * the underlying value) as it builds on the underlying value.
    */
-  return !mErrorFlags && (!(IsAdditive() || IsToAnimation()) ||
-                          (IsToAnimation() && mIsFrozen && !mHasChanged));
+  return !mErrorFlags && !(IsAdditive() || IsToAnimation());
 }
 
 bool
 nsSMILAnimationFunction::HasChanged() const
 {
   return mHasChanged || mValueNeedsReparsingEverySample;
 }
 
 bool
-nsSMILAnimationFunction::UpdateCachedTarget(const nsSMILTargetIdentifier& aNewTarget)
+nsSMILAnimationFunction::UpdateCachedTarget(
+  const nsSMILTargetIdentifier& aNewTarget)
 {
   if (!mLastTarget.Equals(aNewTarget)) {
     mLastTarget = aNewTarget;
     return true;
   }
   return false;
 }
 
@@ -509,18 +498,17 @@ nsSMILAnimationFunction::InterpolateResu
   }
   return rv;
 }
 
 nsresult
 nsSMILAnimationFunction::AccumulateResult(const nsSMILValueArray& aValues,
                                           nsSMILValue& aResult)
 {
-  if (!IsToAnimation() && GetAccumulate() && mRepeatIteration)
-  {
+  if (!IsToAnimation() && GetAccumulate() && mRepeatIteration) {
     const nsSMILValue& lastValue = aValues[aValues.Length() - 1];
 
     // If the target attribute type doesn't support addition, Add will
     // fail and we leave aResult untouched.
     aResult.Add(lastValue, mRepeatIteration);
   }
 
   return NS_OK;
@@ -814,17 +802,17 @@ nsSMILAnimationFunction::GetValues(const
     bool parseOk = true;
     nsSMILValue to, from, by;
     parseOk &= ParseAttr(nsGkAtoms::to,   aSMILAttr, to,
                          preventCachingOfSandwich);
     parseOk &= ParseAttr(nsGkAtoms::from, aSMILAttr, from,
                          preventCachingOfSandwich);
     parseOk &= ParseAttr(nsGkAtoms::by,   aSMILAttr, by,
                          preventCachingOfSandwich);
-    
+
     if (preventCachingOfSandwich) {
       mValueNeedsReparsingEverySample = true;
     }
 
     if (!parseOk)
       return NS_ERROR_FAILURE;
 
     result.SetCapacity(2);
--- a/content/smil/nsSMILAnimationFunction.h
+++ b/content/smil/nsSMILAnimationFunction.h
@@ -448,41 +448,16 @@ protected:
   // its owning animation element.
   nsISMILAnimationElement*      mAnimationElement;
 
   // Which attributes have been set but have had errors. This is not used for
   // all attributes but only those which have specified error behaviour
   // associated with them.
   PRUint16                      mErrorFlags;
 
-  // This is for the very specific case where we have a 'to' animation that is
-  // frozen part way through the simple duration and there are other active
-  // lower-priority animations targetting the same attribute. In this case
-  // SMILANIM 3.3.6 says:
-  //
-  //   The value for F(t) when a to-animation is frozen (at the end of the
-  //   simple duration) is just the to value. If a to-animation is frozen
-  //   anywhere within the simple duration (e.g., using a repeatCount of "2.5"),
-  //   the value for F(t) when the animation is frozen is the value computed for
-  //   the end of the active duration. Even if other, lower priority animations
-  //   are active while a to-animation is frozen, the value for F(t) does not
-  //   change.
-  //
-  // To implement this properly we'd need to force a resample of all the lower
-  // priority animations at the active end of this animation--something which
-  // would introduce unwanted coupling between the timing and animation model.
-  // Instead we just save the value calculated when this animation is frozen (in
-  // which case this animation will be sampled at the active end and the lower
-  // priority animations should be sampled at a time pretty close to this,
-  // provided we have a reasonable frame rate and we aren't seeking).
-  //
-  // @see
-  // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#FromToByAndAdditive
-  nsSMILValue                   mFrozenValue;
-
   // Allows us to check whether an animation function has changed target from
   // sample to sample (because if neither target nor animated value have
   // changed, we don't have to do anything).
   nsSMILWeakTargetIdentifier    mLastTarget;
 
   // Boolean flags
   bool mIsActive:1;
   bool mIsFrozen:1;
--- a/content/smil/nsSMILCSSProperty.cpp
+++ b/content/smil/nsSMILCSSProperty.cpp
@@ -276,16 +276,17 @@ nsSMILCSSProperty::IsPropertyAnimatable(
     case eCSSProperty_stroke_miterlimit:
     case eCSSProperty_stroke_opacity:
     case eCSSProperty_stroke_width:
     case eCSSProperty_text_anchor:
     case eCSSProperty_text_blink:
     case eCSSProperty_text_decoration:
     case eCSSProperty_text_decoration_line:
     case eCSSProperty_text_rendering:
+    case eCSSProperty_vector_effect:
     case eCSSProperty_visibility:
     case eCSSProperty_word_spacing:
       return true;
 
     // EXPLICITLY NON-ANIMATABLE PROPERTIES:
     // (Some of these aren't supported at all in Gecko -- I've commented those
     // ones out. If/when we add support for them, uncomment their line here)
     // ----------------------------------------------------------------------
--- a/content/smil/nsSMILTimedElement.cpp
+++ b/content/smil/nsSMILTimedElement.cpp
@@ -350,16 +350,33 @@ nsSMILTimeValue
 nsSMILTimedElement::GetStartTime() const
 {
   return mElementState == STATE_WAITING || mElementState == STATE_ACTIVE
          ? mCurrentInterval->Begin()->Time()
          : nsSMILTimeValue();
 }
 
 //----------------------------------------------------------------------
+// Hyperlinking support
+
+nsSMILTimeValue
+nsSMILTimedElement::GetHyperlinkTime() const
+{
+  nsSMILTimeValue hyperlinkTime; // Default ctor creates unresolved time
+
+  if (mElementState == STATE_ACTIVE) {
+    hyperlinkTime = mCurrentInterval->Begin()->Time();
+  } else if (!mBeginInstances.IsEmpty()) {
+    hyperlinkTime = mBeginInstances[0]->Time();
+  }
+
+  return hyperlinkTime;
+}
+
+//----------------------------------------------------------------------
 // nsSMILTimedElement
 
 void
 nsSMILTimedElement::AddInstanceTime(nsSMILInstanceTime* aInstanceTime,
                                     bool aIsBegin)
 {
   NS_ABORT_IF_FALSE(aInstanceTime, "Attempting to add null instance time");
 
@@ -1487,39 +1504,50 @@ nsSMILTimedElement::FilterHistory()
 }
 
 void
 nsSMILTimedElement::FilterIntervals()
 {
   // We can filter old intervals that:
   //
   // a) are not the previous interval; AND
-  // b) are not in the middle of a dependency chain
+  // b) are not in the middle of a dependency chain; AND
+  // c) are not the first interval
   //
   // Condition (a) is necessary since the previous interval is used for applying
   // fill effects and updating the current interval.
   //
   // Condition (b) is necessary since even if this interval itself is not
   // active, it may be part of a dependency chain that includes active
   // intervals. Such chains are used to establish priorities within the
   // animation sandwich.
   //
+  // Condition (c) is necessary to support hyperlinks that target animations
+  // since in some cases the defined behavior is to seek the document back to
+  // the first resolved begin time. Presumably the intention here is not
+  // actually to use the first resolved begin time, the
+  // _the_first_resolved_begin_time_that_produced_an_interval. That is,
+  // if we have begin="-5s; -3s; 1s; 3s" with a duration on 1s, we should seek
+  // to 1s. The spec doesn't say this but I'm pretty sure that is the intention.
+  // It seems negative times were simply not considered.
+  //
   // Although the above conditions allow us to safely filter intervals for most
   // scenarios they do not cover all cases and there will still be scenarios
   // that generate intervals indefinitely. In such a case we simply set
   // a maximum number of intervals and drop any intervals beyond that threshold.
 
   PRUint32 threshold = mOldIntervals.Length() > sMaxNumIntervals ?
                        mOldIntervals.Length() - sMaxNumIntervals :
                        0;
   IntervalList filteredList;
   for (PRUint32 i = 0; i < mOldIntervals.Length(); ++i)
   {
     nsSMILInterval* interval = mOldIntervals[i].get();
-    if (i + 1 < mOldIntervals.Length() /*skip previous interval*/ &&
+    if (i != 0 && /*skip first interval*/
+        i + 1 < mOldIntervals.Length() && /*skip previous interval*/
         (i < threshold || !interval->IsDependencyChainLink())) {
       interval->Unlink(true /*filtered, not deleted*/);
     } else {
       filteredList.AppendElement(mOldIntervals[i].forget());
     }
   }
   mOldIntervals.Clear();
   mOldIntervals.SwapElements(filteredList);
@@ -1579,24 +1607,28 @@ nsSMILTimedElement::FilterInstanceTimes(
   // they're unpredictable due to the possibility of seeking the document which
   // may prevent some events from being generated). Therefore we introduce
   // a hard cutoff at which point we just drop the oldest instance times.
   if (aList.Length() > sMaxNumInstanceTimes) {
     PRUint32 threshold = aList.Length() - sMaxNumInstanceTimes;
     // There are a few instance times we should keep though, notably:
     // - the current interval begin time,
     // - the previous interval end time (see note in RemoveInstanceTimes)
+    // - the first interval begin time (see note in FilterIntervals)
     nsTArray<const nsSMILInstanceTime *> timesToKeep;
     if (mCurrentInterval) {
       timesToKeep.AppendElement(mCurrentInterval->Begin());
     }
     const nsSMILInterval* prevInterval = GetPreviousInterval();
     if (prevInterval) {
       timesToKeep.AppendElement(prevInterval->End());
     }
+    if (!mOldIntervals.IsEmpty()) {
+      timesToKeep.AppendElement(mOldIntervals[0]->Begin());
+    }
     RemoveBelowThreshold removeBelowThreshold(threshold, timesToKeep);
     RemoveInstanceTimes(aList, removeBelowThreshold);
   }
 }
 
 //
 // This method is based on the pseudocode given in the SMILANIM spec.
 //
--- a/content/smil/nsSMILTimedElement.h
+++ b/content/smil/nsSMILTimedElement.h
@@ -135,20 +135,39 @@ public:
    * @return the simple duration in milliseconds or INDEFINITE.
    */
   nsSMILTimeValue GetSimpleDuration() const
   {
     return mSimpleDur;
   }
 
   /**
+   * Methods for supporting hyperlinking
+   */
+
+  /**
    * Internal SMIL methods
    */
 
   /**
+   * Returns the time to seek the document to when this element is targetted by
+   * a hyperlink.
+   *
+   * The behavior is defined here:
+   *   http://www.w3.org/TR/smil-animation/#HyperlinkSemantics
+   *
+   * It is very similar to GetStartTime() with the exception that when the
+   * element is not active, the begin time of the *first* interval is returned.
+   *
+   * @return the time to seek the documen to in milliseconds or an unresolved
+   * time if there is no resolved interval.
+   */
+  nsSMILTimeValue GetHyperlinkTime() const;
+
+  /**
    * Adds an instance time object this element's list of instance times.
    * These instance times are used when creating intervals.
    *
    * This method is typically called by an nsSMILTimeValueSpec.
    *
    * @param aInstanceTime   The time to add, expressed in container time.
    * @param aIsBegin        true if the time to be added represents a begin
    *                        time or false if it represents an end time.
--- a/content/smil/test/Makefile.in
+++ b/content/smil/test/Makefile.in
@@ -73,16 +73,17 @@ include $(topsrcdir)/config/rules.mk
 	  test_smilMappedAttrFromBy.xhtml \
 	  test_smilMappedAttrPaced.xhtml \
 	  test_smilReset.xhtml \
 	  test_smilRestart.xhtml \
 	  test_smilExtDoc.xhtml \
 	  test_smilFillMode.xhtml \
 	  test_smilGetStartTime.xhtml \
 	  test_smilGetSimpleDuration.xhtml \
+	  test_smilHyperlinking.xhtml \
 	  test_smilKeySplines.xhtml \
 	  test_smilKeyTimes.xhtml \
 	  test_smilKeyTimesPacedMode.xhtml \
 	  test_smilRepeatTiming.xhtml \
 	  test_smilSetCurrentTime.xhtml \
 	  test_smilSync.xhtml \
 	  test_smilSyncbaseTarget.xhtml \
 	  test_smilSyncTransform.xhtml \
--- a/content/smil/test/db_smilCSSFromTo.js
+++ b/content/smil/test/db_smilCSSFromTo.js
@@ -458,16 +458,19 @@ var gFromToBundles = [
                              toComp: "geometricprecision" }),
     new AnimTestcaseFromTo("geometricPrecision", "optimizeLegibility",
                            { fromComp: "geometricprecision",
                              toComp: "optimizelegibility" }),
   ]),
   new TestcaseBundle(gPropList.unicode_bidi, [
     new AnimTestcaseFromTo("embed", "bidi-override"),
   ]),
+  new TestcaseBundle(gPropList.vector_effect, [
+    new AnimTestcaseFromTo("none", "non-scaling-stroke"),
+  ]),
   new TestcaseBundle(gPropList.visibility, [
     new AnimTestcaseFromTo("visible", "hidden"),
     new AnimTestcaseFromTo("hidden", "collapse"),
   ]),
   new TestcaseBundle(gPropList.word_spacing,
                      [].concat(_fromToTestLists.lengthNoUnits,
                                _fromToTestLists.lengthPx,
                                _fromToTestLists.lengthPxPctSVG)),
--- a/content/smil/test/db_smilCSSPropertyList.js
+++ b/content/smil/test/db_smilCSSPropertyList.js
@@ -111,14 +111,15 @@ var gPropList =
   stroke_linejoin:   new NonAdditiveAttribute("stroke-linejoin", "CSS", "rect"),
   stroke_miterlimit: new AdditiveAttribute("stroke-miterlimit", "CSS", "rect"),
   stroke_opacity:    new AdditiveAttribute("stroke-opacity", "CSS", "rect"),
   stroke_width:      new AdditiveAttribute("stroke-width", "CSS", "rect"),
   text_anchor:       new NonAdditiveAttribute("text-anchor", "CSS", "text"),
   text_decoration:   new NonAdditiveAttribute("text-decoration", "CSS", "text"),
   text_rendering:    new NonAdditiveAttribute("text-rendering", "CSS", "text"),
   unicode_bidi:      new NonAnimatableAttribute("unicode-bidi", "CSS", "text"),
+  vector_effect:     new NonAdditiveAttribute("vector-effect", "CSS", "rect"),
   visibility:        new NonAdditiveAttribute("visibility", "CSS", "rect"),
   word_spacing:      new AdditiveAttribute("word-spacing", "CSS", "text"),
   writing_mode:
     // NOTE: Not supported by Mozilla, but explicitly non-animatable
     new NonAnimatableAttribute("writing-mode", "CSS", "text"),
 };
new file mode 100644
--- /dev/null
+++ b/content/smil/test/test_smilHyperlinking.xhtml
@@ -0,0 +1,233 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Test for hyperlinking</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display:none">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
+  <circle cx="-100" cy="20" r="15" fill="blue" id="circle"/>
+</svg>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+/** Test for SMIL keySplines **/
+
+/* Global Variables */
+const SVGNS="http://www.w3.org/2000/svg";
+var gSvg = document.getElementById("svg");
+var gAnim;
+
+var gTestStages =
+  [ testActive,
+    testSeekToFirst,
+    testKickStart,
+    testKickStartWithUnresolved,
+    testFiltering
+  ];
+
+SimpleTest.waitForExplicitFinish();
+
+function continueTest()
+{
+  if (gTestStages.length == 0) {
+    SimpleTest.finish();
+    return;
+  }
+
+  window.location.hash = "";
+  if (gAnim) {
+    gAnim.parentNode.removeChild(gAnim);
+  }
+  gAnim = createAnim();
+  gSvg.setCurrentTime(0);
+  gTestStages.shift()();
+}
+
+function createAnim() {
+  var anim = document.createElementNS(SVGNS,'animate');
+  anim.setAttribute('attributeName','cx');
+  anim.setAttribute('from','0');
+  anim.setAttribute('to','100');
+  anim.setAttribute('dur','1s');
+  anim.setAttribute('begin','indefinite');
+  anim.setAttribute('id','anim');
+  return document.getElementById('circle').appendChild(anim);
+}
+
+// Traversing a hyperlink, condition 1:
+// 
+// "If the target element is active, seek the document time back to the
+// (current) begin time of the element. If there are multiple begin times, use
+// the begin time that corresponds to the current "begin instance"."
+//
+function testActive() {
+  gAnim.setAttribute('begin','2s; 4s');
+  gSvg.setCurrentTime(2.5);
+  fireLink(rewindActiveInterval1);
+}
+
+function rewindActiveInterval1() {
+  is(gSvg.getCurrentTime(), 2,
+     "Unexpected time after activating link to animation in the middle of " +
+     "first active interval");
+
+  // Seek to second interval
+  gSvg.setCurrentTime(4.5);
+  fireLink(rewindActiveInterval2);
+}
+
+function rewindActiveInterval2() {
+  is(gSvg.getCurrentTime(), 4,
+     "Unexpected time after activating link to animation in the middle of " +
+     "second active interval");
+
+  // Try a negative time
+  gAnim.setAttribute("begin", "-0.5");
+  gSvg.setCurrentTime(0.2);
+  fireLink(rewindActiveIntervalAtZero);
+}
+
+function rewindActiveIntervalAtZero() {
+  is(gSvg.getCurrentTime(), 0,
+     "Unexpected time after activating link to animation in the middle of " +
+     "an active interval that overlaps zero");
+
+  continueTest();
+}
+
+// Traversing a hyperlink, condition 2:
+// 
+// "Else if the target element begin time is resolved (i.e., there is any
+// resolved time in the list of begin times, or if the begin time was forced by
+// an earlier hyperlink or a beginElement() method call), seek the document time
+// (forward or back, as needed) to the earliest resolved begin time of the
+// target element. Note that the begin time may be resolved as a result of an
+// earlier hyperlink, DOM or event activation. Once the begin time is resolved,
+// hyperlink traversal always seeks."
+//
+function testSeekToFirst() {
+  // Seek forwards
+  gAnim.setAttribute('begin','2s');
+  gSvg.setCurrentTime(0);
+  fireLink(forwardToInterval1);
+}
+
+function forwardToInterval1() {
+  is(gSvg.getCurrentTime(), 2,
+     "Unexpected time after activating link to animation scheduled to start " +
+     "the future");
+
+  // Seek backwards
+  gSvg.setCurrentTime(3.5);
+  fireLink(backwardToInterval1);
+}
+
+function backwardToInterval1() {
+  is(gSvg.getCurrentTime(), 2,
+     "Unexpected time after activating link to animation that ran in the past");
+
+  // What if the first begin instance is negative?
+  gAnim.setAttribute('begin','-0.5s');
+  gSvg.setCurrentTime(1);
+  fireLink(backwardToZero);
+}
+
+function backwardToZero() {
+  is(gSvg.getCurrentTime(), 0,
+     "Unexpected time after activating link to animation that ran in the " +
+     "past with a negative time");
+
+  continueTest();
+}
+
+// Traversing a hyperlink, condition 3:
+// 
+// "Else (animation begin time is unresolved) just resolve the target animation
+// begin time at current document time. Disregard the sync-base or event base of
+// the animation, and do not "back-propagate" any timing logic to resolve the
+// child, but rather treat it as though it were defined with begin="indefinite"
+// and just resolve begin time to the current document time."
+//
+function testKickStart() {
+  gSvg.setCurrentTime(1);
+  fireLink(startedAt1s);
+}
+
+function startedAt1s() {
+  is(gSvg.getCurrentTime(), 1,
+     "Unexpected time after kick-starting animation with indefinite start " +
+     "by hyperlink");
+  is(gAnim.getStartTime(), 1,
+     "Unexpected start time for kick-started animation");
+
+  continueTest();
+}
+
+function testKickStartWithUnresolved() {
+  gAnim.setAttribute("begin", "circle.click");
+  gSvg.setCurrentTime(3);
+  fireLink(startedAt3s);
+}
+
+function startedAt3s() {
+  is(gSvg.getCurrentTime(), 3,
+     "Unexpected time after kick-starting animation with unresolved start " +
+     "by hyperlink");
+  is(gAnim.getStartTime(), 3,
+     "Unexpected start time for kick-started animation with unresolved begin " +
+     "condition");
+
+  continueTest();
+}
+
+function testFiltering() {
+  gAnim.setAttribute('begin','-3s; 1s; 2s; 3s; 4s; 5s; 6s; 7s; 8s; 9s; 10s');
+  gSvg.setCurrentTime(12);
+  fireLink(rewindToFirst);
+}
+
+function rewindToFirst() {
+  is(gSvg.getCurrentTime(), 1,
+     "Unexpected time after triggering animation with a hyperlink after " +
+     "numerous intervals have passed");
+
+  continueTest();
+}
+
+function fireLink(callback) {
+  // First we need to reset the hash because otherwise the redundant hashchange
+  // events will be suppressed
+  if (window.location.hash === '') {
+    fireLinkPart2(callback);
+  } else {
+    window.location.hash = '';
+    window.addEventListener("hashchange",
+      function clearHash() {
+        window.removeEventListener("hashchange", clearHash, false);
+        window.setTimeout(fireLinkPart2, 0, callback);
+      },
+      false);
+  }
+}
+
+function fireLinkPart2(callback) {
+  window.addEventListener("hashchange",
+    function triggerCallback() {
+      window.removeEventListener("hashchange", triggerCallback, false);
+      window.setTimeout(callback, 0);
+    },
+    false);
+  window.location.hash = '#anim';
+}
+
+window.addEventListener("load", continueTest, false);
+]]>
+</script>
+</pre>
+</body>
+</html>
--- a/content/svg/content/src/DOMSVGStringList.cpp
+++ b/content/svg/content/src/DOMSVGStringList.cpp
@@ -213,14 +213,14 @@ DOMSVGStringList::AppendItem(const nsASt
   return InsertItemBefore(newItem, InternalList().Length(), _retval);
 }
 
 SVGStringList &
 DOMSVGStringList::InternalList()
 {
   if (mIsConditionalProcessingAttribute) {
     nsCOMPtr<DOMSVGTests> tests = do_QueryInterface(mElement);
-    return tests->mStringListAttributes[mAttrEnum];
+    return *tests->GetStringListAttribute(mAttrEnum);
   }
   return mElement->GetStringListInfo().mStringLists[mAttrEnum];
 }
 
 } // namespace mozilla
--- a/content/svg/content/src/DOMSVGTests.cpp
+++ b/content/svg/content/src/DOMSVGTests.cpp
@@ -32,16 +32,17 @@
  * 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 "DOMSVGTests.h"
 #include "DOMSVGStringList.h"
+#include "nsContentErrors.h" // For NS_PROPTABLE_PROP_OVERWRITTEN
 #include "nsSVGFeatures.h"
 #include "nsSVGSwitchElement.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsStyleUtil.h"
 #include "nsSVGUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
@@ -50,48 +51,43 @@ NS_IMPL_ISUPPORTS1(DOMSVGTests, nsIDOMSV
 
 nsIAtom** DOMSVGTests::sStringListNames[3] =
 {
   &nsGkAtoms::requiredFeatures,
   &nsGkAtoms::requiredExtensions,
   &nsGkAtoms::systemLanguage,
 };
 
-DOMSVGTests::DOMSVGTests()
-{
-  mStringListAttributes[LANGUAGE].SetIsCommaSeparated(true);
-}
-
 /* readonly attribute nsIDOMSVGStringList requiredFeatures; */
 NS_IMETHODIMP
 DOMSVGTests::GetRequiredFeatures(nsIDOMSVGStringList * *aRequiredFeatures)
 {
   nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
   *aRequiredFeatures = DOMSVGStringList::GetDOMWrapper(
-                         &mStringListAttributes[FEATURES], element, true, FEATURES).get();
+                         GetOrCreateStringListAttribute(FEATURES), element, true, FEATURES).get();
   return NS_OK;
 }
 
 /* readonly attribute nsIDOMSVGStringList requiredExtensions; */
 NS_IMETHODIMP
 DOMSVGTests::GetRequiredExtensions(nsIDOMSVGStringList * *aRequiredExtensions)
 {
   nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
   *aRequiredExtensions = DOMSVGStringList::GetDOMWrapper(
-                           &mStringListAttributes[EXTENSIONS], element, true, EXTENSIONS).get();
+                           GetOrCreateStringListAttribute(EXTENSIONS), element, true, EXTENSIONS).get();
   return NS_OK;
 }
 
 /* readonly attribute nsIDOMSVGStringList systemLanguage; */
 NS_IMETHODIMP
 DOMSVGTests::GetSystemLanguage(nsIDOMSVGStringList * *aSystemLanguage)
 {
   nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
   *aSystemLanguage = DOMSVGStringList::GetDOMWrapper(
-                       &mStringListAttributes[LANGUAGE], element, true, LANGUAGE).get();
+                       GetOrCreateStringListAttribute(LANGUAGE), element, true, LANGUAGE).get();
   return NS_OK;
 }
 
 /* boolean hasExtension (in DOMString extension); */
 NS_IMETHODIMP
 DOMSVGTests::HasExtension(const nsAString & extension, bool *_retval)
 {
   *_retval = nsSVGFeatures::HasExtension(extension);
@@ -111,25 +107,29 @@ DOMSVGTests::IsConditionalProcessingAttr
 
 PRInt32
 DOMSVGTests::GetBestLanguagePreferenceRank(const nsSubstring& aAcceptLangs) const
 {
   const nsDefaultStringComparator defaultComparator;
 
   PRInt32 lowestRank = -1;
 
-  for (PRUint32 i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
+  const SVGStringList *languageStringList = GetStringListAttribute(LANGUAGE);
+  if (!languageStringList) {
+    return lowestRank;
+  }
+  for (PRUint32 i = 0; i < languageStringList->Length(); i++) {
     nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',');
     PRInt32 index = 0;
     while (languageTokenizer.hasMoreTokens()) {
       const nsSubstring &languageToken = languageTokenizer.nextToken();
-      bool exactMatch = (languageToken == mStringListAttributes[LANGUAGE][i]);
+      bool exactMatch = (languageToken == (*languageStringList)[i]);
       bool prefixOnlyMatch =
         !exactMatch &&
-        nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
+        nsStyleUtil::DashMatchCompare((*languageStringList)[i],
                                       languageTokenizer.nextToken(),
                                       defaultComparator);
       if (index == 0 && exactMatch) {
         // best possible match
         return 0;
       }
       if ((exactMatch || prefixOnlyMatch) &&
           (lowestRank == -1 || 2 * index + prefixOnlyMatch < lowestRank)) {
@@ -142,79 +142,82 @@ DOMSVGTests::GetBestLanguagePreferenceRa
 }
 
 const nsString * const DOMSVGTests::kIgnoreSystemLanguage = (nsString *) 0x01;
 
 bool
 DOMSVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const
 {
   // Required Features
-  if (mStringListAttributes[FEATURES].IsExplicitlySet()) {
-    if (mStringListAttributes[FEATURES].IsEmpty()) {
+  const SVGStringList *featuresStringList = GetStringListAttribute(FEATURES);
+  if (featuresStringList && featuresStringList->IsExplicitlySet()) {
+    if (featuresStringList->IsEmpty()) {
       return false;
     }
     nsCOMPtr<nsIContent> content(
       do_QueryInterface(const_cast<DOMSVGTests*>(this)));
 
-    for (PRUint32 i = 0; i < mStringListAttributes[FEATURES].Length(); i++) {
-      if (!nsSVGFeatures::HasFeature(content, mStringListAttributes[FEATURES][i])) {
+    for (PRUint32 i = 0; i < featuresStringList->Length(); i++) {
+      if (!nsSVGFeatures::HasFeature(content, (*featuresStringList)[i])) {
         return false;
       }
     }
   }
 
   // Required Extensions
   //
   // The requiredExtensions  attribute defines a list of required language
   // extensions. Language extensions are capabilities within a user agent that
   // go beyond the feature set defined in the SVG specification.
   // Each extension is identified by a URI reference.
   // For now, claim that mozilla's SVG implementation supports XHTML and MathML.
-  if (mStringListAttributes[EXTENSIONS].IsExplicitlySet()) {
-    if (mStringListAttributes[EXTENSIONS].IsEmpty()) {
+  const SVGStringList *extensionsStringList = GetStringListAttribute(EXTENSIONS);
+  if (extensionsStringList && extensionsStringList->IsExplicitlySet()) {
+    if (extensionsStringList->IsEmpty()) {
       return false;
     }
-    for (PRUint32 i = 0; i < mStringListAttributes[EXTENSIONS].Length(); i++) {
-      if (!nsSVGFeatures::HasExtension(mStringListAttributes[EXTENSIONS][i])) {
+    for (PRUint32 i = 0; i < extensionsStringList->Length(); i++) {
+      if (!nsSVGFeatures::HasExtension((*extensionsStringList)[i])) {
         return false;
       }
     }
   }
 
   if (aAcceptLangs == kIgnoreSystemLanguage) {
     return true;
   }
 
   // systemLanguage
   //
   // Evaluates to "true" if one of the languages indicated by user preferences
   // exactly equals one of the languages given in the value of this parameter,
   // or if one of the languages indicated by user preferences exactly equals a
   // prefix of one of the languages given in the value of this parameter such
   // that the first tag character following the prefix is "-".
-  if (mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
-    if (mStringListAttributes[LANGUAGE].IsEmpty()) {
+  const SVGStringList *languageStringList = GetStringListAttribute(LANGUAGE);
+  if (languageStringList && languageStringList->IsExplicitlySet()) {
+    if (languageStringList->IsEmpty()) {
       return false;
     }
 
     // Get our language preferences
     const nsAutoString acceptLangs(aAcceptLangs ? *aAcceptLangs :
       Preferences::GetLocalizedString("intl.accept_languages"));
 
     if (acceptLangs.IsEmpty()) {
       NS_WARNING("no default language specified for systemLanguage conditional test");
       return false;
     }
 
     const nsDefaultStringComparator defaultComparator;
 
-    for (PRUint32 i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
+    for (PRUint32 i = 0; i < languageStringList->Length(); i++) {
       nsCharSeparatedTokenizer languageTokenizer(acceptLangs, ',');
       while (languageTokenizer.hasMoreTokens()) {
-        if (nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
+        if (nsStyleUtil::DashMatchCompare((*languageStringList)[i],
                                           languageTokenizer.nextToken(),
                                           defaultComparator)) {
           return true;
         }
       }
     }
     return false;
   }
@@ -224,51 +227,109 @@ DOMSVGTests::PassesConditionalProcessing
 
 bool
 DOMSVGTests::ParseConditionalProcessingAttribute(nsIAtom* aAttribute,
                                                  const nsAString& aValue,
                                                  nsAttrValue& aResult)
 {
   for (PRUint32 i = 0; i < ArrayLength(sStringListNames); i++) {
     if (aAttribute == *sStringListNames[i]) {
-      nsresult rv = mStringListAttributes[i].SetValue(aValue);
-      if (NS_FAILED(rv)) {
-        mStringListAttributes[i].Clear();
+      SVGStringList *stringList = GetOrCreateStringListAttribute(i);
+      if (stringList) {
+        nsresult rv = stringList->SetValue(aValue);
+        if (NS_FAILED(rv)) {
+          stringList->Clear();
+        }
       }
       MaybeInvalidate();
       return true;
     }
   }
   return false;
 }
 
 void
 DOMSVGTests::UnsetAttr(const nsIAtom* aAttribute)
 {
   for (PRUint32 i = 0; i < ArrayLength(sStringListNames); i++) {
     if (aAttribute == *sStringListNames[i]) {
-      mStringListAttributes[i].Clear();
-      MaybeInvalidate();
+      SVGStringList *stringList = GetStringListAttribute(i);
+      if (stringList) {
+        // don't destroy the property in case there are tear-offs
+        // referring to it
+        stringList->Clear();
+        MaybeInvalidate();
+      }
       return;
     }
   }
 }
 
+// Callback function, for freeing PRUint64 values stored in property table
+// when the element goes away
+static void
+ReleaseStringListPropertyValue(void*    aObject,       /* unused */
+                               nsIAtom* aPropertyName, /* unused */
+                               void*    aPropertyValue,
+                               void*    aData          /* unused */)
+{
+  SVGStringList* valPtr =
+    static_cast<SVGStringList*>(aPropertyValue);
+  delete valPtr;
+}
+
+SVGStringList*
+DOMSVGTests::GetStringListAttribute(PRUint8 aAttrEnum) const
+{
+  nsIAtom *attrName = GetAttrName(aAttrEnum);
+  const nsCOMPtr<nsSVGElement> element =
+    do_QueryInterface(const_cast<DOMSVGTests*>(this));
+
+  return static_cast<SVGStringList*>(element->GetProperty(attrName));
+}
+
+SVGStringList*
+DOMSVGTests::GetOrCreateStringListAttribute(PRUint8 aAttrEnum) const
+{
+  SVGStringList* stringListPtr = GetStringListAttribute(aAttrEnum);
+  if (stringListPtr) {
+    return stringListPtr;
+  }
+  nsIAtom *attrName = GetAttrName(aAttrEnum);
+  const nsCOMPtr<nsSVGElement> element =
+    do_QueryInterface(const_cast<DOMSVGTests*>(this));
+
+  stringListPtr = new SVGStringList();
+  stringListPtr->SetIsCommaSeparated(aAttrEnum == LANGUAGE);
+  nsresult rv = element->SetProperty(attrName,
+                                     stringListPtr,
+                                     ReleaseStringListPropertyValue);
+  NS_ABORT_IF_FALSE(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
+                    "Setting property value when it's already set...?"); 
+
+  if (NS_LIKELY(NS_SUCCEEDED(rv))) {
+    return stringListPtr;
+  }
+  // property-insertion failed (e.g. OOM in property-table code)
+  delete stringListPtr;
+  return nsnull;
+}
+
 nsIAtom*
 DOMSVGTests::GetAttrName(PRUint8 aAttrEnum) const
 {
   return *sStringListNames[aAttrEnum];
 }
 
 void
 DOMSVGTests::GetAttrValue(PRUint8 aAttrEnum, nsAttrValue& aValue) const
 {
   MOZ_ASSERT(aAttrEnum < ArrayLength(sStringListNames),
              "aAttrEnum out of range");
-  aValue.SetTo(mStringListAttributes[aAttrEnum], nsnull);
+  aValue.SetTo(*GetOrCreateStringListAttribute(aAttrEnum), nsnull);
 }
 
 void
 DOMSVGTests::MaybeInvalidate()
 {
   nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
 
   nsIContent* parent = element->GetFlattenedTreeParent();
--- a/content/svg/content/src/DOMSVGTests.h
+++ b/content/svg/content/src/DOMSVGTests.h
@@ -54,18 +54,16 @@ class DOMSVGTests : public nsIDOMSVGTest
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMSVGTESTS
 
   friend class mozilla::DOMSVGStringList;
   typedef mozilla::SVGStringList SVGStringList;
 
-  DOMSVGTests();
-
   /**
    * Compare the language name(s) in a systemLanguage attribute to the
    * user's language preferences, as defined in
    * http://www.w3.org/TR/SVG11/struct.html#SystemLanguageAttribute
    * We have a match if a language name in the users language preferences
    * exactly equals one of the language names or exactly equals a prefix of
    * one of the language names in the systemLanguage attribute.
    * @returns 2 * the lowest index in the aAcceptLangs that matches + 1
@@ -106,19 +104,20 @@ public:
          nsAttrValue& aResult);
 
   /**
    * Unsets a conditional processing attribute.
    */
   void UnsetAttr(const nsIAtom* aAttribute);
 
   nsIAtom* GetAttrName(PRUint8 aAttrEnum) const;
+  SVGStringList* GetStringListAttribute(PRUint8 aAttrEnum) const;
+  SVGStringList* GetOrCreateStringListAttribute(PRUint8 aAttrEnum) const;
   void GetAttrValue(PRUint8 aAttrEnum, nsAttrValue &aValue) const;
 
   void MaybeInvalidate();
 
 private:
   enum { FEATURES, EXTENSIONS, LANGUAGE };
-  SVGStringList mStringListAttributes[3];
   static nsIAtom** sStringListNames[3];
 };
 
 #endif // MOZILLA_DOMSVGTESTS_H__
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -119,22 +119,24 @@ CPPSRCS		= \
 		nsSVGTextContentElement.cpp \
 		nsSVGTextElement.cpp \
 		nsSVGTextPathElement.cpp \
 		nsSVGTextPositioningElement.cpp \
 		nsSVGTitleElement.cpp \
 		nsSVGUnknownElement.cpp \
 		nsSVGUseElement.cpp \
 		nsSVGViewBox.cpp \
+		nsSVGViewElement.cpp \
 		SVGAnimatedLengthList.cpp \
 		SVGAnimatedNumberList.cpp \
 		SVGAnimatedPathSegList.cpp \
 		SVGAnimatedPointList.cpp \
 		SVGAnimatedPreserveAspectRatio.cpp \
 		SVGAnimatedTransformList.cpp \
+		SVGFragmentIdentifier.cpp \
 		SVGLength.cpp \
 		SVGLengthList.cpp \
 		SVGNumberList.cpp \
 		SVGPathData.cpp \
 		SVGPathSegUtils.cpp \
 		SVGPointList.cpp \
 		SVGStringList.cpp \
 		SVGTransform.cpp \
--- a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
+++ b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
@@ -144,16 +144,24 @@ GetMeetOrSliceString(nsAString& aMeetOrS
     aMeetOrSlice <= nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE,
     "Unknown meetOrSlice");
 
   aMeetOrSliceString.AssignASCII(
     sMeetOrSliceStrings[aMeetOrSlice -
                         nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET]);
 }
 
+bool
+SVGPreserveAspectRatio::operator==(const SVGPreserveAspectRatio& aOther) const
+{
+  return mAlign == aOther.mAlign &&
+    mMeetOrSlice == aOther.mMeetOrSlice &&
+    mDefer == aOther.mDefer;
+}
+
 nsresult
 SVGAnimatedPreserveAspectRatio::ToDOMBaseVal(
   nsIDOMSVGPreserveAspectRatio **aResult,
   nsSVGElement *aSVGElement)
 {
   *aResult = new DOMBaseVal(this, aSVGElement);
   if (!*aResult)
     return NS_ERROR_OUT_OF_MEMORY;
@@ -268,58 +276,35 @@ SVGAnimatedPreserveAspectRatio::GetBaseV
       nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) {
 
     aValueAsString.AppendLiteral(" ");
     GetMeetOrSliceString(tmpString, mBaseVal.mMeetOrSlice);
     aValueAsString.Append(tmpString);
   }
 }
 
-nsresult
-SVGAnimatedPreserveAspectRatio::SetBaseAlign(PRUint16 aAlign,
+void
+SVGAnimatedPreserveAspectRatio::SetBaseValue(const SVGPreserveAspectRatio &aValue,
                                              nsSVGElement *aSVGElement)
 {
-  if (mIsBaseSet && mBaseVal.GetAlign() == aAlign) {
-    return NS_OK;
+  if (mIsBaseSet && mBaseVal == aValue) {
+    return;
   }
 
   nsAttrValue emptyOrOldValue = aSVGElement->WillChangePreserveAspectRatio();
-  nsresult rv = mBaseVal.SetAlign(aAlign);
-  NS_ENSURE_SUCCESS(rv, rv);
+  mBaseVal = aValue;
   mIsBaseSet = true;
 
-  mAnimVal.mAlign = mBaseVal.mAlign;
+  if (!mIsAnimated) {
+    mAnimVal = mBaseVal;
+  }
   aSVGElement->DidChangePreserveAspectRatio(emptyOrOldValue);
   if (mIsAnimated) {
     aSVGElement->AnimationNeedsResample();
   }
-  
-  return NS_OK;
-}
-
-nsresult
-SVGAnimatedPreserveAspectRatio::SetBaseMeetOrSlice(PRUint16 aMeetOrSlice,
-                                                   nsSVGElement *aSVGElement)
-{
-  if (mIsBaseSet && mBaseVal.GetMeetOrSlice() == aMeetOrSlice) {
-    return NS_OK;
-  }
-
-  nsAttrValue emptyOrOldValue = aSVGElement->WillChangePreserveAspectRatio();
-  nsresult rv = mBaseVal.SetMeetOrSlice(aMeetOrSlice);
-  NS_ENSURE_SUCCESS(rv, rv);
-  mIsBaseSet = true;
-
-  mAnimVal.mMeetOrSlice = mBaseVal.mMeetOrSlice;
-  aSVGElement->DidChangePreserveAspectRatio(emptyOrOldValue);
-  if (mIsAnimated) {
-    aSVGElement->AnimationNeedsResample();
-  }
-  
-  return NS_OK;
 }
 
 void
 SVGAnimatedPreserveAspectRatio::SetAnimValue(PRUint64 aPackedValue,
                                              nsSVGElement *aSVGElement)
 {
   mAnimVal.SetDefer(((aPackedValue & 0xff0000) >> 16) ? true : false);
   mAnimVal.SetAlign(PRUint16((aPackedValue & 0xff00) >> 8));
--- a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
+++ b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
@@ -55,22 +55,30 @@ namespace mozilla {
 
 class SVGAnimatedPreserveAspectRatio;
 
 class SVGPreserveAspectRatio
 {
   friend class SVGAnimatedPreserveAspectRatio;
 
 public:
+  SVGPreserveAspectRatio(PRUint16 aAlign, PRUint16 aMeetOrSlice, bool aDefer = false)
+    : mAlign(aAlign)
+    , mMeetOrSlice(aMeetOrSlice)
+    , mDefer(aDefer)
+  {};
+
   SVGPreserveAspectRatio()
     : mAlign(0)
     , mMeetOrSlice(0)
     , mDefer(false)
   {};
 
+  bool operator==(const SVGPreserveAspectRatio& aOther) const;
+
   nsresult SetAlign(PRUint16 aAlign) {
     if (aAlign < nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE ||
         aAlign > nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX)
       return NS_ERROR_FAILURE;
     mAlign = static_cast<PRUint8>(aAlign);
     return NS_OK;
   };
 
@@ -115,18 +123,38 @@ public:
     mIsAnimated = false;
     mIsBaseSet = false;
   }
 
   nsresult SetBaseValueString(const nsAString& aValue,
                               nsSVGElement *aSVGElement);
   void GetBaseValueString(nsAString& aValue) const;
 
-  nsresult SetBaseAlign(PRUint16 aAlign, nsSVGElement *aSVGElement);
-  nsresult SetBaseMeetOrSlice(PRUint16 aMeetOrSlice, nsSVGElement *aSVGElement);
+  void SetBaseValue(const SVGPreserveAspectRatio &aValue,
+                    nsSVGElement *aSVGElement);
+  nsresult SetBaseAlign(PRUint16 aAlign, nsSVGElement *aSVGElement) {
+    if (aAlign < nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE ||
+        aAlign > nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX) {
+      return NS_ERROR_FAILURE;
+    }
+    SetBaseValue(SVGPreserveAspectRatio(
+                   aAlign, mBaseVal.GetMeetOrSlice(), mBaseVal.GetDefer()),
+                 aSVGElement);
+    return NS_OK;
+  }
+  nsresult SetBaseMeetOrSlice(PRUint16 aMeetOrSlice, nsSVGElement *aSVGElement) {
+    if (aMeetOrSlice < nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET ||
+        aMeetOrSlice > nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE) {
+      return NS_ERROR_FAILURE;
+    }
+    SetBaseValue(SVGPreserveAspectRatio(
+                   mBaseVal.GetAlign(), aMeetOrSlice, mBaseVal.GetDefer()),
+                 aSVGElement);
+    return NS_OK;
+  }
   void SetAnimValue(PRUint64 aPackedValue, nsSVGElement *aSVGElement);
 
   const SVGPreserveAspectRatio &GetBaseValue() const
     { return mBaseVal; }
   const SVGPreserveAspectRatio &GetAnimValue() const
     { return mAnimVal; }
   bool IsAnimated() const
     { return mIsAnimated; }
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/SVGFragmentIdentifier.cpp
@@ -0,0 +1,262 @@
+/* -*- 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 the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * 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 "SVGFragmentIdentifier.h"
+#include "mozilla/CharTokenizer.h"
+#include "nsIDOMSVGDocument.h"
+#include "nsSVGSVGElement.h"
+#include "nsSVGViewElement.h"
+
+using namespace mozilla;
+
+static nsSVGEnumMapping sZoomAndPanMap[] = {
+  {&nsGkAtoms::disable, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE},
+  {&nsGkAtoms::magnify, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY},
+  {nsnull, 0}
+};
+
+static bool
+IsMatchingParameter(const nsAString &aString, const nsAString &aParameterName)
+{
+  // The first two tests ensure aString.Length() > aParameterName.Length()
+  // so it's then safe to do the third test
+  return StringBeginsWith(aString, aParameterName) &&
+         aString.Last() == ')' &&
+         aString.CharAt(aParameterName.Length()) == '(';
+}
+
+static nsSVGViewElement*
+GetViewElement(nsIDocument *aDocument, const nsAString &aId)
+{
+  dom::Element* element = aDocument->GetElementById(aId);
+  return (element && element->IsSVG(nsGkAtoms::view)) ?
+            static_cast<nsSVGViewElement*>(element) : nsnull;
+}
+
+void 
+SVGFragmentIdentifier::SaveOldPreserveAspectRatio(nsSVGSVGElement *root)
+{
+  const SVGPreserveAspectRatio *oldPARPtr = root->GetPreserveAspectRatioProperty();
+  if (!oldPARPtr) {
+    root->SetPreserveAspectRatioProperty(root->mPreserveAspectRatio.GetBaseValue());
+  }
+}
+
+void 
+SVGFragmentIdentifier::RestoreOldPreserveAspectRatio(nsSVGSVGElement *root)
+{
+  const SVGPreserveAspectRatio *oldPARPtr = root->GetPreserveAspectRatioProperty();
+  if (oldPARPtr) {
+    root->mPreserveAspectRatio.SetBaseValue(*oldPARPtr, root);
+    root->ClearPreserveAspectRatioProperty();
+  }
+}
+
+void 
+SVGFragmentIdentifier::SaveOldViewBox(nsSVGSVGElement *root)
+{
+  const nsSVGViewBoxRect *oldViewBoxPtr = root->GetViewBoxProperty();
+  if (!oldViewBoxPtr) {
+    root->SetViewBoxProperty(root->mViewBox.GetBaseValue());
+  }
+}
+
+void 
+SVGFragmentIdentifier::RestoreOldViewBox(nsSVGSVGElement *root)
+{
+  const nsSVGViewBoxRect *oldViewBoxPtr = root->GetViewBoxProperty();
+  if (oldViewBoxPtr) {
+    root->mViewBox.SetBaseValue(*oldViewBoxPtr, root);
+    root->ClearViewBoxProperty();
+  }
+}
+
+void 
+SVGFragmentIdentifier::SaveOldZoomAndPan(nsSVGSVGElement *root)
+{
+  const PRUint16 *oldZoomAndPanPtr = root->GetZoomAndPanProperty();
+  if (!oldZoomAndPanPtr) {
+    root->SetZoomAndPanProperty(root->mEnumAttributes[nsSVGSVGElement::ZOOMANDPAN].GetBaseValue());
+  }
+}
+
+void 
+SVGFragmentIdentifier::RestoreOldZoomAndPan(nsSVGSVGElement *root)
+{
+  const PRUint16 *oldZoomAndPanPtr = root->GetZoomAndPanProperty();
+  if (oldZoomAndPanPtr) {
+    root->mEnumAttributes[nsSVGSVGElement::ZOOMANDPAN].SetBaseValue(*oldZoomAndPanPtr, root);
+    root->ClearZoomAndPanProperty();
+  }
+}
+
+bool
+SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
+                                          nsSVGSVGElement *root)
+{
+  if (!IsMatchingParameter(aViewSpec, NS_LITERAL_STRING("svgView"))) {
+    return false;
+  }
+
+  // SVGViewAttribute may occur in any order, but each type may only occur at most one time
+  // in a correctly formed SVGViewSpec.
+  // If we encounter any element more than once or get any syntax errors we're going to
+  // return without updating the root element
+
+  const nsAString *viewBoxParams = nsnull;
+  const nsAString *preserveAspectRatioParams = nsnull;
+  const nsAString *zoomAndPanParams = nsnull;
+
+  // Each token is a SVGViewAttribute
+  PRInt32 bracketPos = aViewSpec.FindChar('(');
+  CharTokenizer<';'>tokenizer(
+    Substring(aViewSpec, bracketPos + 1, aViewSpec.Length() - bracketPos - 2));
+
+  while (tokenizer.hasMoreTokens()) {
+
+    nsAutoString token(tokenizer.nextToken());
+
+    bracketPos = token.FindChar('(');
+    if (bracketPos < 1 || token.Last() != ')') {
+      // invalid SVGViewAttribute syntax
+      return false;
+    }
+
+    const nsAString &params =
+      Substring(token, bracketPos + 1, token.Length() - bracketPos - 2);
+
+    if (IsMatchingParameter(token, NS_LITERAL_STRING("viewBox"))) {
+      if (viewBoxParams) {
+        return false;
+      }
+      viewBoxParams = &params;
+    } else if (IsMatchingParameter(token, NS_LITERAL_STRING("preserveAspectRatio"))) {
+      if (preserveAspectRatioParams) {
+        return false;
+      }
+      preserveAspectRatioParams = &params;
+    } else if (IsMatchingParameter(token, NS_LITERAL_STRING("zoomAndPan"))) {
+      if (zoomAndPanParams) {
+        return false;
+      }
+      zoomAndPanParams = &params;
+    } else {
+      // We don't support transform or viewTarget currently
+      return false;
+    }
+  }
+
+  const nsSVGViewBoxRect *oldViewBoxPtr = root->GetViewBoxProperty();
+  if (viewBoxParams) {
+    SaveOldViewBox(root);
+    root->mViewBox.SetBaseValueString(*viewBoxParams, root);
+  } else {
+    RestoreOldViewBox(root);
+  }
+
+  const SVGPreserveAspectRatio *oldPARPtr = root->GetPreserveAspectRatioProperty();
+  if (preserveAspectRatioParams) {
+    SaveOldPreserveAspectRatio(root);
+    root->mPreserveAspectRatio.SetBaseValueString(*preserveAspectRatioParams, root);
+  } else {
+    RestoreOldPreserveAspectRatio(root);
+  }
+
+  const PRUint16 *oldZoomAndPanPtr = root->GetZoomAndPanProperty();
+  if (zoomAndPanParams) {
+    SaveOldZoomAndPan(root);
+    nsCOMPtr<nsIAtom> valAtom = do_GetAtom(*zoomAndPanParams);
+    const nsSVGEnumMapping *mapping = root->sZoomAndPanMap;
+    while (mapping->mKey) {
+      if (valAtom == *(mapping->mKey)) {
+        root->mEnumAttributes[nsSVGSVGElement::ZOOMANDPAN].SetBaseValue(mapping->mVal, root);
+        break;
+      }
+      mapping++;
+    }
+  } else {
+    RestoreOldZoomAndPan(root);
+  }
+
+  return true;
+}
+
+bool
+SVGFragmentIdentifier::ProcessFragmentIdentifier(nsIDocument *aDocument,
+                                                 const nsAString &aAnchorName)
+{
+  NS_ABORT_IF_FALSE(aDocument->GetRootElement()->IsSVG(nsGkAtoms::svg),
+                    "expecting an SVG root element");
+
+  nsSVGSVGElement *rootElement =
+    static_cast<nsSVGSVGElement*>(aDocument->GetRootElement());
+
+  const nsSVGViewElement *viewElement = GetViewElement(aDocument, aAnchorName);
+
+  if (viewElement) {
+    if (viewElement->mViewBox.IsExplicitlySet()) {
+      SaveOldViewBox(rootElement);
+      rootElement->mViewBox.SetBaseValue(
+        viewElement->mViewBox.GetBaseValue(), rootElement);
+    } else {
+      RestoreOldViewBox(rootElement);
+    }
+    if (viewElement->mPreserveAspectRatio.IsExplicitlySet()) {
+      SaveOldPreserveAspectRatio(rootElement);
+      rootElement->mPreserveAspectRatio.SetBaseValue(
+        viewElement->mPreserveAspectRatio.GetBaseValue(), rootElement);
+    } else {
+      RestoreOldPreserveAspectRatio(rootElement);
+    }
+    if (viewElement->mEnumAttributes[nsSVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
+      SaveOldZoomAndPan(rootElement);
+      rootElement->mEnumAttributes[nsSVGSVGElement::ZOOMANDPAN].SetBaseValue(
+        viewElement->mEnumAttributes[nsSVGViewElement::ZOOMANDPAN].GetBaseValue(), rootElement);
+    } else {
+      RestoreOldZoomAndPan(rootElement);
+    }
+    return true;
+  }
+
+  if (ProcessSVGViewSpec(aAnchorName, rootElement)) {
+    return true;
+  }
+  RestoreOldViewBox(rootElement);
+  RestoreOldPreserveAspectRatio(rootElement);
+  RestoreOldZoomAndPan(rootElement);
+  return false;
+}
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/SVGFragmentIdentifier.h
@@ -0,0 +1,85 @@
+/* -*- 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 the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * 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 ***** */
+
+#ifndef MOZILLA_SVGFRAGMENTIDENTIFIER_H__
+#define MOZILLA_SVGFRAGMENTIDENTIFIER_H__
+
+#include "nsString.h"
+
+class nsIDocument;
+class nsSVGSVGElement;
+class nsSVGViewElement;
+
+namespace mozilla {
+
+/**
+ * Implements support for parsing SVG fragment identifiers
+ * http://www.w3.org/TR/SVG/linking.html#SVGFragmentIdentifiers
+ */
+class SVGFragmentIdentifier
+{
+  // To prevent the class being instantiated
+  SVGFragmentIdentifier() MOZ_DELETE;
+
+public:
+  /**
+   * Process the SVG fragment identifier, if there is one.
+   * @return true if we found something we recognised
+   */
+  static bool ProcessFragmentIdentifier(nsIDocument *aDocument,
+                                        const nsAString &aAnchorName);
+
+private:
+ /**
+  * Parse an SVG ViewSpec and set applicable attributes on the root element.
+  * @return true if there is a valid ViewSpec
+  */
+  static bool ProcessSVGViewSpec(const nsAString &aViewSpec, nsSVGSVGElement *root);
+
+  // Save and restore things we override in case we want to go back e.g. the
+  // user presses the back button
+  static void SaveOldPreserveAspectRatio(nsSVGSVGElement *root);
+  static void RestoreOldPreserveAspectRatio(nsSVGSVGElement *root);
+  static void SaveOldViewBox(nsSVGSVGElement *root);
+  static void RestoreOldViewBox(nsSVGSVGElement *root);
+  static void SaveOldZoomAndPan(nsSVGSVGElement *root);
+  static void RestoreOldZoomAndPan(nsSVGSVGElement *root);
+};
+
+} // namespace mozilla
+
+#endif // MOZILLA_SVGFRAGMENTIDENTIFIER_H__
--- a/content/svg/content/src/nsSVGAnimationElement.cpp
+++ b/content/svg/content/src/nsSVGAnimationElement.cpp
@@ -418,16 +418,44 @@ nsSVGAnimationElement::UnsetAttr(PRInt32
 
 bool
 nsSVGAnimationElement::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eANIMATION));
 }
 
 //----------------------------------------------------------------------
+// SVG utility methods
+
+void
+nsSVGAnimationElement::ActivateByHyperlink()
+{
+  FlushAnimations();
+
+  // The behavior for when the target is an animation element is defined in
+  // SMIL Animation:
+  //   http://www.w3.org/TR/smil-animation/#HyperlinkSemantics
+  nsSMILTimeValue seekTime = mTimedElement.GetHyperlinkTime();
+  if (seekTime.IsDefinite()) {
+    nsSMILTimeContainer* timeContainer = GetTimeContainer();
+    if (timeContainer) {
+      timeContainer->SetCurrentTime(seekTime.GetMillis());
+      AnimationNeedsResample();
+      // As with nsSVGSVGElement::SetCurrentTime, we need to trigger
+      // a synchronous sample now.
+      FlushAnimations();
+    }
+    // else, silently fail. We mustn't be part of an SVG document fragment that
+    // is attached to the document tree so there's nothing we can do here
+  } else {
+    BeginElement();
+  }
+}
+
+//----------------------------------------------------------------------
 // Implementation helpers
 
 nsSMILTimeContainer*
 nsSVGAnimationElement::GetTimeContainer()
 {
   nsSVGSVGElement *element = nsSVGUtils::GetOuterSVGElement(this);
 
   if (element) {
--- a/content/svg/content/src/nsSVGAnimationElement.h
+++ b/content/svg/content/src/nsSVGAnimationElement.h
@@ -95,16 +95,19 @@ public:
   virtual bool HasAnimAttr(nsIAtom* aAttName) const;
   virtual Element* GetTargetElementContent();
   virtual bool GetTargetAttributeName(PRInt32* aNamespaceID,
                                         nsIAtom** aLocalName) const;
   virtual nsSMILTargetAttrType GetTargetAttributeType() const;
   virtual nsSMILTimedElement& TimedElement();
   virtual nsSMILTimeContainer* GetTimeContainer();
 
+  // Utility methods for within SVG
+  void ActivateByHyperlink();
+
 protected:
   // nsSVGElement overrides
   bool IsEventName(nsIAtom* aName);
 
   void UpdateHrefTarget(nsIContent* aNodeForContext,
                         const nsAString& aHrefStr);
   void AnimationTargetChanged();
 
--- a/content/svg/content/src/nsSVGAttrTearoffTable.h
+++ b/content/svg/content/src/nsSVGAttrTearoffTable.h
@@ -99,21 +99,17 @@ nsSVGAttrTearoffTable<SimpleType, Tearof
 
   // We shouldn't be adding a tear-off if there already is one. If that happens,
   // something is wrong.
   if (mTable.Get(aSimple, nsnull)) {
     NS_ABORT_IF_FALSE(false, "There is already a tear-off for this object.");
     return;
   }
 
-#ifdef DEBUG
-  bool result =
-#endif
-    mTable.Put(aSimple, aTearoff);
-  NS_ABORT_IF_FALSE(result, "Out of memory.");
+  mTable.Put(aSimple, aTearoff);
 }
 
 template<class SimpleType, class TearoffType>
 void
 nsSVGAttrTearoffTable<SimpleType, TearoffType>::RemoveTearoff(
     SimpleType* aSimple)
 {
   if (!mTable.IsInitialized()) {
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -926,16 +926,17 @@ nsSVGElement::sFillStrokeMap[] = {
   { &nsGkAtoms::stroke },
   { &nsGkAtoms::stroke_dasharray },
   { &nsGkAtoms::stroke_dashoffset },
   { &nsGkAtoms::stroke_linecap },
   { &nsGkAtoms::stroke_linejoin },
   { &nsGkAtoms::stroke_miterlimit },
   { &nsGkAtoms::stroke_opacity },
   { &nsGkAtoms::stroke_width },
+  { &nsGkAtoms::vector_effect },
   { nsnull }
 };
 
 // PresentationAttributes-Graphics
 /* static */ const nsGenericElement::MappedAttributeEntry
 nsSVGElement::sGraphicsMap[] = {
   { &nsGkAtoms::clip_path },
   { &nsGkAtoms::clip_rule },
--- a/content/svg/content/src/nsSVGElementFactory.cpp
+++ b/content/svg/content/src/nsSVGElementFactory.cpp
@@ -217,16 +217,19 @@ nsresult
 NS_NewSVGFESpecularLightingElement(nsIContent **aResult,
                                    already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGFEImageElement(nsIContent **aResult,
                         already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGFEDisplacementMapElement(nsIContent **aResult,
                                   already_AddRefed<nsINodeInfo> aNodeInfo);
+nsresult
+NS_NewSVGViewElement(nsIContent **aResult,
+                     already_AddRefed<nsINodeInfo> aNodeInfo);
 
 nsresult
 NS_NewSVGAnimateElement(nsIContent **aResult,
                         already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGAnimateTransformElement(nsIContent **aResult,
                                  already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
@@ -365,16 +368,18 @@ NS_NewSVGElement(nsIContent** aResult, a
   if (name == nsGkAtoms::feDisplacementMap)
     return NS_NewSVGFEDisplacementMapElement(aResult, aNodeInfo);
   if (name == nsGkAtoms::pattern)
     return NS_NewSVGPatternElement(aResult, aNodeInfo);
   if (name == nsGkAtoms::mask)
     return NS_NewSVGMaskElement(aResult, aNodeInfo);
   if (name == nsGkAtoms::svgSwitch)
     return NS_NewSVGSwitchElement(aResult, aNodeInfo);
+  if (name == nsGkAtoms::view)
+    return NS_NewSVGViewElement(aResult, aNodeInfo);
   if (NS_SMILEnabled()) {
     if (name == nsGkAtoms::animate)
       return NS_NewSVGAnimateElement(aResult, aNodeInfo);
     if (name == nsGkAtoms::animateTransform)
       return NS_NewSVGAnimateTransformElement(aResult, aNodeInfo);
     if (name == nsGkAtoms::animateMotion)
       return NS_NewSVGAnimateMotionElement(aResult, aNodeInfo);
     if (name == nsGkAtoms::mpath)
--- a/content/svg/content/src/nsSVGGraphicElement.cpp
+++ b/content/svg/content/src/nsSVGGraphicElement.cpp
@@ -40,16 +40,17 @@
 #include "mozilla/Util.h"
 
 #include "nsSVGGraphicElement.h"
 #include "nsSVGSVGElement.h"
 #include "DOMSVGAnimatedTransformList.h"
 #include "DOMSVGMatrix.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMEventTarget.h"
+#include "nsIDOMMutationEvent.h"
 #include "nsIFrame.h"
 #include "nsISVGChildFrame.h"
 #include "nsIDOMSVGPoint.h"
 #include "nsSVGUtils.h"
 #include "nsDOMError.h"
 #include "nsSVGRect.h"
 #include "nsContentUtils.h"
 
@@ -174,16 +175,53 @@ nsSVGGraphicElement::IsAttributeMapped(c
     sFillStrokeMap,
     sGraphicsMap
   };
   
   return FindAttributeDependence(name, map) ||
     nsSVGGraphicElementBase::IsAttributeMapped(name);
 }
 
+nsChangeHint
+nsSVGGraphicElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                            PRInt32 aModType) const
+{
+  nsChangeHint retval =
+    nsSVGGraphicElementBase::GetAttributeChangeHint(aAttribute, aModType);
+  if (aAttribute == nsGkAtoms::transform) {
+    // We add nsChangeHint_UpdateOverflow so that nsFrame::UpdateOverflow()
+    // will be called on us and our ancestors.
+    nsIFrame* frame =
+      const_cast<nsSVGGraphicElement*>(this)->GetPrimaryFrame();
+    if (frame && frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) {
+      // No need to do anything.
+    } else if (aModType == nsIDOMMutationEvent::ADDITION ||
+               aModType == nsIDOMMutationEvent::REMOVAL) {
+      // In order to handle view creation/destruction and stacking context
+      // changes, the code in nsStyleDisplay::CalcDifference uses
+      // nsChangeHint_ReconstructFrame if the transform was added/removed.
+      // XXXSDL Currently we don't need to reconstruct SVG frames when their
+      // transform is set/unset since we don't currently create GFX layers for
+      // SVG transforms, but we will after bug 614732 is fixed. Also change the
+      // assertion in ApplyRenderingChangeToTree when we do that.
+      NS_UpdateHint(retval, nsChangeHint_UpdateOverflow);
+    } else {
+      NS_ABORT_IF_FALSE(aModType == nsIDOMMutationEvent::MODIFICATION,
+                        "Unknown modification type.");
+      // We just assume the old and new transforms are different.
+      // XXXSDL Once we use GFX layers for SVG transforms, we will need to pass
+      // the nsChangeHint_UpdateTransformLayer hint too. Note that the
+      // assertion in ApplyRenderingChangeToTree will fail if that hint is
+      // passed on nsIDOMMutationEvent::REMOVAL though.
+      NS_UpdateHint(retval, nsChangeHint_UpdateOverflow);
+    }
+  }
+  return retval;
+}
+
 //----------------------------------------------------------------------
 // nsSVGElement overrides
 
 bool
 nsSVGGraphicElement::IsEventName(nsIAtom* aName)
 {
   return nsContentUtils::IsEventAttributeName(aName, EventNameType_SVGGraphic);
 }
--- a/content/svg/content/src/nsSVGGraphicElement.h
+++ b/content/svg/content/src/nsSVGGraphicElement.h
@@ -57,16 +57,19 @@ public:
   // interfaces:  
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGLOCATABLE
   NS_DECL_NSIDOMSVGTRANSFORMABLE
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
+  nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                      PRInt32 aModType) const;
+
   virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const;
   virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix);
 
   virtual mozilla::SVGAnimatedTransformList* GetAnimatedTransformList();
   virtual nsIAtom* GetTransformListAttrName() const {
     return nsGkAtoms::transform;
   }
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -36,16 +36,17 @@
  * 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 "mozilla/Util.h"
 
 #include "nsGkAtoms.h"
+#include "nsLayoutUtils.h"
 #include "DOMSVGNumber.h"
 #include "DOMSVGLength.h"
 #include "nsSVGAngle.h"
 #include "nsCOMPtr.h"
 #include "nsIPresShell.h"
 #include "nsContentUtils.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
@@ -199,17 +200,18 @@ nsSVGSVGElement::nsSVGSVGElement(already
     mViewportWidth(0),
     mViewportHeight(0),
     mCurrentTranslate(0.0f, 0.0f),
     mCurrentScale(1.0f),
     mPreviousTranslate(0.0f, 0.0f),
     mPreviousScale(1.0f),
     mStartAnimationOnBindToTree(!aFromParser),
     mImageNeedsTransformInvalidation(false),
-    mIsPaintingSVGImageElement(false)
+    mIsPaintingSVGImageElement(false),
+    mHasChildrenOnlyTransform(false)
 {
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 // From NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGSVGElement)
 nsresult
@@ -949,81 +951,69 @@ ComputeSynthesizedViewBoxDimension(const
 }
 
 //----------------------------------------------------------------------
 // public helpers:
 
 gfxMatrix
 nsSVGSVGElement::GetViewBoxTransform() const
 {
-  // Do we have an override preserveAspectRatio value?
-  const SVGPreserveAspectRatio* overridePARPtr =
-    GetImageOverridePreserveAspectRatio();
-
-  // May assign this to overridePARPtr if we have no viewBox but are faking one:
-  SVGPreserveAspectRatio tmpPAR;
-
   float viewportWidth, viewportHeight;
   if (IsInner()) {
     nsSVGSVGElement *ctx = GetCtx();
     viewportWidth = mLengthAttributes[WIDTH].GetAnimValue(ctx);
     viewportHeight = mLengthAttributes[HEIGHT].GetAnimValue(ctx);
   } else {
     viewportWidth = mViewportWidth;
     viewportHeight = mViewportHeight;
   }
 
   if (viewportWidth <= 0.0f || viewportHeight <= 0.0f) {
     return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
   }
 
-  nsSVGViewBoxRect viewBox;
-  if (HasViewBox()) {
-    viewBox = mViewBox.GetAnimValue();
-  } else {
-    viewBox.x = viewBox.y = 0.0f;
-    if (ShouldSynthesizeViewBox()) {
-      // Special case -- fake a viewBox, using height & width attrs.
-      // (Use |this| as context, since if we get here, we're outermost <svg>.)
-      viewBox.width =
-        ComputeSynthesizedViewBoxDimension(mLengthAttributes[WIDTH],
-                                           mViewportWidth, this);
-      viewBox.height =
-        ComputeSynthesizedViewBoxDimension(mLengthAttributes[HEIGHT],
-                                           mViewportHeight, this);
-      NS_ABORT_IF_FALSE(!overridePARPtr,
-                        "shouldn't have overridePAR if we're "
-                        "synthesizing a viewBox");
-
-      // If we're synthesizing a viewBox, use preserveAspectRatio="none";
-      tmpPAR.SetAlign(nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE);
-
-      // (set the other pAR attributes too, just so they're initialized):
-      tmpPAR.SetDefer(false);
-      tmpPAR.SetMeetOrSlice(nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE);
-
-      overridePARPtr = &tmpPAR;
-    } else {
-      // No viewBox attribute, so we shouldn't auto-scale. This is equivalent
-      // to having a viewBox that exactly matches our viewport size.
-      viewBox.width  = viewportWidth;
-      viewBox.height = viewportHeight;
-    }
-  }
+  nsSVGViewBoxRect viewBox =
+    GetViewBoxWithSynthesis(viewportWidth, viewportHeight);
 
   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
     return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
   }
 
   return nsSVGUtils::GetViewBoxTransform(this,
                                          viewportWidth, viewportHeight,
                                          viewBox.x, viewBox.y,
                                          viewBox.width, viewBox.height,
-                                         overridePARPtr ? *overridePARPtr :
-                                         mPreserveAspectRatio.GetAnimValue());
+                                         GetPreserveAspectRatioWithOverride());
+}
+
+void
+nsSVGSVGElement::ChildrenOnlyTransformChanged()
+{
+  // Avoid wasteful calls:
+  NS_ABORT_IF_FALSE(!(GetPrimaryFrame()->GetStateBits() &
+                      NS_STATE_SVG_NONDISPLAY_CHILD),
+                    "Non-display SVG frames don't maintain overflow rects");
+
+  bool hasChildrenOnlyTransform = HasViewBoxOrSyntheticViewBox() ||
+    (IsRoot() && (mCurrentTranslate != nsSVGTranslatePoint(0.0f, 0.0f) ||
+                  mCurrentScale != 1.0f));
+
+  // XXXSDL Currently we don't destroy frames if
+  // hasChildrenOnlyTransform != mHasChildrenOnlyTransform
+  // but we should once we start using GFX layers for SVG transforms
+  // (see the comment in nsSVGGraphicElement::GetAttributeChangeHint).
+
+  nsChangeHint changeHint =
+    nsChangeHint(nsChangeHint_RepaintFrame |
+                 nsChangeHint_UpdateOverflow |
+                 nsChangeHint_ChildrenOnlyTransform);
+
+  nsLayoutUtils::PostRestyleEvent(this, nsRestyleHint(0), changeHint);
+
+  mHasChildrenOnlyTransform = hasChildrenOnlyTransform;
 }
 
 nsresult
 nsSVGSVGElement::BindToTree(nsIDocument* aDocument,
                             nsIContent* aParent,
                             nsIContent* aBindingParent,
                             bool aCompileEventHandlers)
 {
@@ -1115,16 +1105,60 @@ nsSVGSVGElement::InvalidateTransformNoti
 
 bool
 nsSVGSVGElement::HasPreserveAspectRatio()
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::preserveAspectRatio) ||
     mPreserveAspectRatio.IsAnimated();
 }
 
+nsSVGViewBoxRect
+nsSVGSVGElement::GetViewBoxWithSynthesis(
+  float aViewportWidth, float aViewportHeight) const
+{
+  if (HasViewBox()) {
+    return mViewBox.GetAnimValue();
+  }
+
+  if (ShouldSynthesizeViewBox()) {
+    // Special case -- fake a viewBox, using height & width attrs.
+    // (Use |this| as context, since if we get here, we're outermost <svg>.)
+    return nsSVGViewBoxRect(0, 0,
+              ComputeSynthesizedViewBoxDimension(mLengthAttributes[WIDTH],
+                                                 mViewportWidth, this),
+              ComputeSynthesizedViewBoxDimension(mLengthAttributes[HEIGHT],
+                                                 mViewportHeight, this));
+
+  }
+
+  // No viewBox attribute, so we shouldn't auto-scale. This is equivalent
+  // to having a viewBox that exactly matches our viewport size.
+  return nsSVGViewBoxRect(0, 0, aViewportWidth, aViewportHeight);
+}
+
+SVGPreserveAspectRatio
+nsSVGSVGElement::GetPreserveAspectRatioWithOverride() const
+{
+  if (GetCurrentDoc()->IsBeingUsedAsImage()) {
+    const SVGPreserveAspectRatio *pAROverridePtr = GetPreserveAspectRatioProperty();
+    if (pAROverridePtr) {
+      return *pAROverridePtr;
+    }
+  }
+
+  if (!HasViewBox() && ShouldSynthesizeViewBox()) {
+    // If we're synthesizing a viewBox, use preserveAspectRatio="none";
+    return SVGPreserveAspectRatio(
+         nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE,
+         nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE);
+  }
+
+  return mPreserveAspectRatio.GetAnimValue();
+}
+
 //----------------------------------------------------------------------
 // nsSVGSVGElement
 
 float
 nsSVGSVGElement::GetLength(PRUint8 aCtxType)
 {
   float h, w;
 
@@ -1267,16 +1301,53 @@ ReleasePreserveAspectRatioPropertyValue(
                                         void*    aPropertyValue,
                                         void*    aData          /* unused */)
 {
   SVGPreserveAspectRatio* valPtr =
     static_cast<SVGPreserveAspectRatio*>(aPropertyValue);
   delete valPtr;
 }
 
+bool
+nsSVGSVGElement::
+  SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR)
+{
+  SVGPreserveAspectRatio* pAROverridePtr = new SVGPreserveAspectRatio(aPAR);
+  nsresult rv = SetProperty(nsGkAtoms::overridePreserveAspectRatio,
+                            pAROverridePtr,
+                            ReleasePreserveAspectRatioPropertyValue);
+  NS_ABORT_IF_FALSE(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
+                    "Setting override value when it's already set...?"); 
+
+  if (NS_UNLIKELY(NS_FAILED(rv))) {
+    // property-insertion failed (e.g. OOM in property-table code)
+    delete pAROverridePtr;
+    return false;
+  }
+  return true;
+}
+
+const SVGPreserveAspectRatio*
+nsSVGSVGElement::GetPreserveAspectRatioProperty() const
+{
+  void* valPtr = GetProperty(nsGkAtoms::overridePreserveAspectRatio);
+  if (valPtr) {
+    return static_cast<SVGPreserveAspectRatio*>(valPtr);
+  }
+  return nsnull;
+}
+
+bool
+nsSVGSVGElement::ClearPreserveAspectRatioProperty()
+{
+  void* valPtr = UnsetProperty(nsGkAtoms::overridePreserveAspectRatio);
+  delete static_cast<SVGPreserveAspectRatio*>(valPtr);
+  return valPtr;
+}
+
 void
 nsSVGSVGElement::
   SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR)
 {
 #ifdef DEBUG
   NS_ABORT_IF_FALSE(GetCurrentDoc()->IsBeingUsedAsImage(),
                     "should only override preserveAspectRatio in images");
 #endif
@@ -1292,72 +1363,121 @@ nsSVGSVGElement::
   if (!HasViewBox()) {
     return; // preserveAspectRatio irrelevant (only matters if we have viewBox)
   }
 
   if (aPAR.GetDefer() && HasPreserveAspectRatio()) {
     return; // Referring element defers to my own preserveAspectRatio value.
   }
 
-  SVGPreserveAspectRatio* pAROverridePtr = new SVGPreserveAspectRatio(aPAR);
-  nsresult rv = SetProperty(nsGkAtoms::overridePreserveAspectRatio,
-                            pAROverridePtr,
-                            ReleasePreserveAspectRatioPropertyValue);
-  NS_ABORT_IF_FALSE(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
-                    "Setting override value when it's already set...?"); 
-
-  if (NS_LIKELY(NS_SUCCEEDED(rv))) {
+  if (SetPreserveAspectRatioProperty(aPAR)) {
     mImageNeedsTransformInvalidation = true;
-  } else {
-    // property-insertion failed (e.g. OOM in property-table code)
-    delete pAROverridePtr;
   }
 }
 
 void
 nsSVGSVGElement::ClearImageOverridePreserveAspectRatio()
 {
 #ifdef DEBUG
   NS_ABORT_IF_FALSE(GetCurrentDoc()->IsBeingUsedAsImage(),
-                    "should only override preserveAspectRatio in images");
+                    "should only override image preserveAspectRatio in images");
 #endif
 
   mIsPaintingSVGImageElement = false;
   if (!HasViewBox() && ShouldSynthesizeViewBox()) {
     // My non-<svg:image> clients will want to paint me with a synthesized
     // viewBox, but my <svg:image> client that just painted me did NOT
     // use that.  Need to tell ourselves to flush our transform.
     mImageNeedsTransformInvalidation = true;
   }
 
-  void* valPtr = UnsetProperty(nsGkAtoms::overridePreserveAspectRatio);
-  if (valPtr) {
+  if (ClearPreserveAspectRatioProperty()) {
     mImageNeedsTransformInvalidation = true;
-    delete static_cast<SVGPreserveAspectRatio*>(valPtr);
   }
 }
 
-const SVGPreserveAspectRatio*
-nsSVGSVGElement::GetImageOverridePreserveAspectRatio() const
-{
-  void* valPtr = GetProperty(nsGkAtoms::overridePreserveAspectRatio);
-#ifdef DEBUG
-  if (valPtr) {
-    NS_ABORT_IF_FALSE(GetCurrentDoc()->IsBeingUsedAsImage(),
-                      "should only override preserveAspectRatio in images");
-  }
-#endif
-
-  return static_cast<SVGPreserveAspectRatio*>(valPtr);
-}
-
 void
 nsSVGSVGElement::FlushImageTransformInvalidation()
 {
   NS_ABORT_IF_FALSE(!GetParent(), "Should only be called on root node");
   NS_ABORT_IF_FALSE(GetCurrentDoc()->IsBeingUsedAsImage(),
                     "Should only be called on image documents");
 
   if (mImageNeedsTransformInvalidation) {
     InvalidateTransformNotifyFrame();
     mImageNeedsTransformInvalidation = false;
   }
 }
+
+// Callback function, for freeing PRUint64 values stored in property table
+static void
+ReleaseViewBoxPropertyValue(void*    aObject,       /* unused */
+                            nsIAtom* aPropertyName, /* unused */
+                            void*    aPropertyValue,
+                            void*    aData          /* unused */)
+{
+  nsSVGViewBoxRect* valPtr =
+    static_cast<nsSVGViewBoxRect*>(aPropertyValue);
+  delete valPtr;
+}
+
+bool
+nsSVGSVGElement::SetViewBoxProperty(const nsSVGViewBoxRect& aViewBox)
+{
+  nsSVGViewBoxRect* pViewBoxOverridePtr = new nsSVGViewBoxRect(aViewBox);
+  nsresult rv = SetProperty(nsGkAtoms::viewBox,
+                            pViewBoxOverridePtr,
+                            ReleaseViewBoxPropertyValue);
+  NS_ABORT_IF_FALSE(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
+                    "Setting override value when it's already set...?"); 
+
+  if (NS_UNLIKELY(NS_FAILED(rv))) {
+    // property-insertion failed (e.g. OOM in property-table code)
+    delete pViewBoxOverridePtr;
+    return false;
+  }
+  return true;
+}
+
+const nsSVGViewBoxRect*
+nsSVGSVGElement::GetViewBoxProperty() const
+{
+  void* valPtr = GetProperty(nsGkAtoms::viewBox);
+  if (valPtr) {
+    return static_cast<nsSVGViewBoxRect*>(valPtr);
+  }
+  return nsnull;
+}
+
+bool
+nsSVGSVGElement::ClearViewBoxProperty()
+{
+  void* valPtr = UnsetProperty(nsGkAtoms::viewBox);
+  delete static_cast<nsSVGViewBoxRect*>(valPtr);
+  return valPtr;
+}
+
+bool
+nsSVGSVGElement::SetZoomAndPanProperty(PRUint16 aValue)
+{
+  nsresult rv = SetProperty(nsGkAtoms::zoomAndPan, reinterpret_cast<void*>(aValue));
+  NS_ABORT_IF_FALSE(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
+                    "Setting override value when it's already set...?"); 
+
+  return NS_SUCCEEDED(rv);
+}
+
+const PRUint16*
+nsSVGSVGElement::GetZoomAndPanProperty() const
+{
+  void* valPtr = GetProperty(nsGkAtoms::zoomAndPan);
+  if (valPtr) {
+    return reinterpret_cast<PRUint16*>(valPtr);
+  }
+  return nsnull;
+}
+
+bool
+nsSVGSVGElement::ClearZoomAndPanProperty()
+{
+  return UnsetProperty(nsGkAtoms::viewBox);
+}
+
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -50,37 +50,52 @@
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGStylableElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 
 class nsIDOMSVGMatrix;
 class nsSMILTimeContainer;
+class nsSVGViewElement;
+namespace mozilla {
+  class SVGFragmentIdentifier;
+}
 
 typedef nsSVGStylableElement nsSVGSVGElementBase;
 
 class nsSVGSVGElement;
 
 class nsSVGTranslatePoint {
 public:
-  nsSVGTranslatePoint(float aX, float aY) :
-    mX(aX), mY(aY) {}
+  nsSVGTranslatePoint()
+    : mX(0.0f)
+    , mY(0.0f)
+  {}
+
+  nsSVGTranslatePoint(float aX, float aY)
+    : mX(aX)
+    , mY(aY)
+  {}
 
   void SetX(float aX)
     { mX = aX; }
   void SetY(float aY)
     { mY = aY; }
   float GetX() const
     { return mX; }
   float GetY() const
     { return mY; }
 
   nsresult ToDOMVal(nsSVGSVGElement *aElement, nsIDOMSVGPoint **aResult);
 
+  bool operator!=(const nsSVGTranslatePoint &rhs) const {
+    return mX != rhs.mX || mY != rhs.mY;
+  }
+
 private:
 
   struct DOMVal : public nsIDOMSVGPoint {
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS(DOMVal)
 
     DOMVal(nsSVGTranslatePoint* aVal, nsSVGSVGElement *aElement)
       : mVal(aVal), mElement(aElement) {}
@@ -122,18 +137,18 @@ class nsSVGSVGElement : public nsSVGSVGE
                         public DOMSVGTests,
                         public nsIDOMSVGFitToViewBox,
                         public nsIDOMSVGLocatable,
                         public nsIDOMSVGZoomAndPan
 {
   friend class nsSVGOuterSVGFrame;
   friend class nsSVGInnerSVGFrame;
   friend class nsSVGImageFrame;
+  friend class mozilla::SVGFragmentIdentifier;
 
-protected:
   friend nsresult NS_NewSVGSVGElement(nsIContent **aResult,
                                       already_AddRefed<nsINodeInfo> aNodeInfo,
                                       mozilla::dom::FromParser aFromParser);
   nsSVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                   mozilla::dom::FromParser aFromParser);
   
 public:
   typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio;
@@ -215,18 +230,38 @@ public:
    * Returns true if we should synthesize a viewBox for ourselves (that is, if
    * we're the root element in an image document, and we're not currently being
    * painted for an <svg:image> element).
    *
    * Only call this method if HasViewBox() returns false.
    */
   bool ShouldSynthesizeViewBox() const;
 
+  bool HasViewBoxOrSyntheticViewBox() const {
+    return HasViewBox() || ShouldSynthesizeViewBox();
+  }
+
   gfxMatrix GetViewBoxTransform() const;
 
+  bool HasChildrenOnlyTransform() const {
+    return mHasChildrenOnlyTransform;
+  }
+
+  /**
+   * This method notifies the style system that the overflow rects of our
+   * immediate childrens' frames need to be updated. It is called by our own
+   * frame when changes (e.g. to currentScale) cause our children-only
+   * transform to change.
+   *
+   * The reason we have this method instead of overriding
+   * GetAttributeChangeHint is because we need to act on non-attribute (e.g.
+   * currentScale) changes in addition to attribute (e.g. viewBox) changes.
+   */
+  void ChildrenOnlyTransformChanged();
+
   // This services any pending notifications for the transform on on this root
   // <svg> node needing to be recalculated.  (Only applicable in
   // SVG-as-an-image documents.)
   virtual void FlushImageTransformInvalidation();
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   svgFloatSize GetViewportSize() const {
@@ -238,34 +273,43 @@ public:
     mViewportHeight = aSize.height;
   }
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
 private:
-  // Methods for <image> elements to override my "PreserveAspectRatio" value.
-  // These are private so that only our friends (nsSVGImageFrame in
-  // particular) have access.
-  void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
-  void ClearImageOverridePreserveAspectRatio();
-  const SVGPreserveAspectRatio* GetImageOverridePreserveAspectRatio() const;
-
-protected:
   // nsSVGElement overrides
   bool IsEventName(nsIAtom* aName);
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep, bool aNullParent);
 
   // implementation helpers:
 
+  // Methods for <image> elements to override my "PreserveAspectRatio" value.
+  // These are private so that only our friends (nsSVGImageFrame in
+  // particular) have access.
+  void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
+  void ClearImageOverridePreserveAspectRatio();
+
+  // Set/Clear properties to hold old or override versions of attributes
+  bool SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR);
+  const SVGPreserveAspectRatio* GetPreserveAspectRatioProperty() const;
+  bool ClearPreserveAspectRatioProperty();
+  bool SetViewBoxProperty(const nsSVGViewBoxRect& aViewBox);
+  const nsSVGViewBoxRect* GetViewBoxProperty() const;
+  bool ClearViewBoxProperty();
+  bool SetZoomAndPanProperty(PRUint16 aValue);
+  const PRUint16* GetZoomAndPanProperty() const;
+  bool ClearZoomAndPanProperty();
+
   bool IsRoot() const {
     NS_ASSERTION((IsInDoc() && !GetParent()) ==
                  (OwnerDoc() && (OwnerDoc()->GetRootElement() == this)),
                  "Can't determine if we're root");
     return IsInDoc() && !GetParent();
   }
 
   /**
@@ -283,26 +327,39 @@ protected:
    * <svg> element _before_ the children are bound (as they want to know what
    * timed document root to register with) and therefore _before_ our parent is
    * set (both actions are performed by nsGenericElement::BindToTree) so we
    * can't use GetOwnerSVGElement() as it relies on GetParent(). This code is
    * basically a simplified version of GetOwnerSVGElement that uses the parent
    * parameters passed in instead.
    */
   bool WillBeOutermostSVG(nsIContent* aParent,
-                            nsIContent* aBindingParent) const;
+                          nsIContent* aBindingParent) const;
 
   // invalidate viewbox -> viewport xform & inform frames
   void InvalidateTransformNotifyFrame();
 
   // Returns true if we have at least one of the following:
   // - a (valid or invalid) value for the preserveAspectRatio attribute
   // - a SMIL-animated value for the preserveAspectRatio attribute
   bool HasPreserveAspectRatio();
 
+ /**
+  * Returns the explicit viewBox rect, if specified, or else a synthesized
+  * viewBox, if appropriate, or else a viewBox matching the dimensions of the
+  * SVG viewport.
+  */
+  nsSVGViewBoxRect GetViewBoxWithSynthesis(
+      float aViewportWidth, float aViewportHeight) const;
+  /**
+   * Returns the explicit or default preserveAspectRatio, unless we're
+   * synthesizing a viewBox, in which case it returns the "none" value.
+   */
+  SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const;
+
   virtual LengthAttributesInfo GetLengthInfo();
 
   enum { X, Y, WIDTH, HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   virtual EnumAttributesInfo GetEnumInfo();
 
@@ -344,11 +401,12 @@ protected:
 
   // For outermost <svg> elements created from parsing, animation is started by
   // the onload event in accordance with the SVG spec, but for <svg> elements
   // created by script or promoted from inner <svg> to outermost <svg> we need
   // to manually kick off animation when they are bound to the tree.
   bool                              mStartAnimationOnBindToTree;
   bool                              mImageNeedsTransformInvalidation;
   bool                              mIsPaintingSVGImageElement;
+  bool                              mHasChildrenOnlyTransform;
 };
 
 #endif
--- a/content/svg/content/src/nsSVGViewBox.cpp
+++ b/content/svg/content/src/nsSVGViewBox.cpp
@@ -119,26 +119,26 @@ nsSVGViewBox::SetAnimValue(float aX, flo
     mAnimVal->y = aY;
     mAnimVal->width = aWidth;
     mAnimVal->height = aHeight;
   }
   aSVGElement->DidAnimateViewBox();
 }
 
 void
-nsSVGViewBox::SetBaseValue(float aX, float aY, float aWidth, float aHeight,
+nsSVGViewBox::SetBaseValue(const nsSVGViewBoxRect& aRect,
                            nsSVGElement *aSVGElement)
 {
-  if (mHasBaseVal && mBaseVal == nsSVGViewBoxRect(aX, aY, aWidth, aHeight)) {
+  if (mHasBaseVal && mBaseVal == aRect) {
     return;
   }
 
   nsAttrValue emptyOrOldValue = aSVGElement->WillChangeViewBox();
 
-  mBaseVal = nsSVGViewBoxRect(aX, aY, aWidth, aHeight);
+  mBaseVal = aRect;
   mHasBaseVal = true;
 
   aSVGElement->DidChangeViewBox(emptyOrOldValue);
   if (mAnimVal) {
     aSVGElement->AnimationNeedsResample();
   }
 }
 
--- a/content/svg/content/src/nsSVGViewBox.h
+++ b/content/svg/content/src/nsSVGViewBox.h
@@ -81,19 +81,21 @@ public:
    * positive, so callers must check whether the viewBox rect is valid where
    * necessary!
    */
   bool IsExplicitlySet() const
     { return (mHasBaseVal || mAnimVal); }
 
   const nsSVGViewBoxRect& GetBaseValue() const
     { return mBaseVal; }
-  void SetBaseValue(float aX, float aY, float aWidth, float aHeight,
+  void SetBaseValue(const nsSVGViewBoxRect& aRect,
                     nsSVGElement *aSVGElement);
-
+  void SetBaseValue(float aX, float aY, float aWidth, float aHeight,
+                    nsSVGElement *aSVGElement)
+    { SetBaseValue(nsSVGViewBoxRect(aX, aY, aWidth, aHeight), aSVGElement); }
   const nsSVGViewBoxRect& GetAnimValue() const
     { return mAnimVal ? *mAnimVal : mBaseVal; }
   void SetAnimValue(float aX, float aY, float aWidth, float aHeight,
                     nsSVGElement *aSVGElement);
 
   nsresult SetBaseValueString(const nsAString& aValue,
                               nsSVGElement *aSVGElement);
   void GetBaseValueString(nsAString& aValue) const;
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/nsSVGViewElement.cpp
@@ -0,0 +1,169 @@
+/* -*- 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 the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is Robert Longson.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * 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 "nsSVGViewElement.h"
+#include "DOMSVGStringList.h"
+
+using namespace mozilla;
+
+nsSVGElement::StringListInfo nsSVGViewElement::sStringListInfo[1] =
+{
+  { &nsGkAtoms::viewTarget }
+};
+
+nsSVGEnumMapping nsSVGViewElement::sZoomAndPanMap[] = {
+  {&nsGkAtoms::disable, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE},
+  {&nsGkAtoms::magnify, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY},
+  {nsnull, 0}
+};
+
+nsSVGElement::EnumInfo nsSVGViewElement::sEnumInfo[1] =
+{
+  { &nsGkAtoms::zoomAndPan,
+    sZoomAndPanMap,
+    nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY
+  }
+};
+
+NS_IMPL_NS_NEW_SVG_ELEMENT(View)
+
+//----------------------------------------------------------------------
+// nsISupports methods
+
+NS_IMPL_ADDREF_INHERITED(nsSVGViewElement,nsSVGViewElementBase)
+NS_IMPL_RELEASE_INHERITED(nsSVGViewElement,nsSVGViewElementBase)
+
+DOMCI_NODE_DATA(SVGViewElement, nsSVGViewElement)
+
+NS_INTERFACE_TABLE_HEAD(nsSVGViewElement)
+  NS_NODE_INTERFACE_TABLE6(nsSVGViewElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGViewElement,
+                           nsIDOMSVGFitToViewBox,
+                           nsIDOMSVGZoomAndPan)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGViewElement)
+NS_INTERFACE_MAP_END_INHERITING(nsSVGViewElementBase)
+
+//----------------------------------------------------------------------
+// Implementation
+
+nsSVGViewElement::nsSVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : nsSVGViewElementBase(aNodeInfo)
+{
+}
+
+//----------------------------------------------------------------------
+// nsIDOMNode methods
+
+NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGViewElement)
+
+//----------------------------------------------------------------------
+// nsIDOMSVGZoomAndPan methods
+
+/* attribute unsigned short zoomAndPan; */
+NS_IMETHODIMP
+nsSVGViewElement::GetZoomAndPan(PRUint16 *aZoomAndPan)
+{
+  *aZoomAndPan = mEnumAttributes[ZOOMANDPAN].GetAnimValue();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGViewElement::SetZoomAndPan(PRUint16 aZoomAndPan)
+{
+  if (aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE ||
+      aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY) {
+    mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
+    return NS_OK;
+  }
+
+  return NS_ERROR_DOM_SVG_INVALID_VALUE_ERR;
+}
+
+//----------------------------------------------------------------------
+// nsIDOMSVGFitToViewBox methods
+
+/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
+NS_IMETHODIMP
+nsSVGViewElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
+{
+  return mViewBox.ToDOMAnimatedRect(aViewBox, this);
+}
+
+/* readonly attribute nsIDOMSVGAnimatedPreserveAspectRatio preserveAspectRatio; */
+NS_IMETHODIMP
+nsSVGViewElement::GetPreserveAspectRatio(nsIDOMSVGAnimatedPreserveAspectRatio
+                                         **aPreserveAspectRatio)
+{
+  return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(aPreserveAspectRatio, this);
+}
+
+//----------------------------------------------------------------------
+// nsIDOMSVGViewElement methods
+
+/* readonly attribute nsIDOMSVGStringList viewTarget; */
+NS_IMETHODIMP nsSVGViewElement::GetViewTarget(nsIDOMSVGStringList * *aViewTarget)
+{
+  *aViewTarget = DOMSVGStringList::GetDOMWrapper(
+                   &mStringListAttributes[VIEW_TARGET], this, false, VIEW_TARGET).get();
+  return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// nsSVGElement methods
+
+nsSVGElement::EnumAttributesInfo
+nsSVGViewElement::GetEnumInfo()
+{
+  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
+                            ArrayLength(sEnumInfo));
+}
+
+nsSVGViewBox *
+nsSVGViewElement::GetViewBox()
+{
+  return &mViewBox;
+}
+
+SVGAnimatedPreserveAspectRatio *
+nsSVGViewElement::GetPreserveAspectRatio()
+{
+  return &mPreserveAspectRatio;
+}
+
+nsSVGElement::StringListAttributesInfo
+nsSVGViewElement::GetStringListInfo()
+{
+  return StringListAttributesInfo(mStringListAttributes, sStringListInfo,
+                                  ArrayLength(sStringListInfo));
+}
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/nsSVGViewElement.h
@@ -0,0 +1,106 @@
+/* -*- 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 the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is Robert Longson.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * 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 ***** */
+
+#ifndef __NS_SVGVIEWELEMENT_H__
+#define __NS_SVGVIEWELEMENT_H__
+
+#include "nsIDOMSVGViewElement.h"
+#include "nsIDOMSVGFitToViewBox.h"
+#include "nsIDOMSVGZoomAndPan.h"
+#include "nsSVGElement.h"
+#include "nsSVGEnum.h"
+#include "nsSVGViewBox.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
+#include "SVGStringList.h"
+
+namespace mozilla {
+  class SVGFragmentIdentifier;
+}
+
+typedef nsSVGElement nsSVGViewElementBase;
+
+class nsSVGViewElement : public nsSVGViewElementBase,
+                         public nsIDOMSVGViewElement,
+                         public nsIDOMSVGFitToViewBox,
+                         public nsIDOMSVGZoomAndPan
+{
+  friend class mozilla::SVGFragmentIdentifier;
+  friend nsresult NS_NewSVGViewElement(nsIContent **aResult,
+                                       already_AddRefed<nsINodeInfo> aNodeInfo);
+  nsSVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  
+public:
+  // interfaces:
+  
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIDOMSVGVIEWELEMENT
+  NS_DECL_NSIDOMSVGFITTOVIEWBOX
+  NS_DECL_NSIDOMSVGZOOMANDPAN
+
+  // xxx If xpcom allowed virtual inheritance we wouldn't need to
+  // forward here :-(
+  NS_FORWARD_NSIDOMNODE(nsSVGViewElementBase::)
+  NS_FORWARD_NSIDOMELEMENT(nsSVGViewElementBase::)
+  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGViewElementBase::)
+
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+  virtual nsXPCClassInfo* GetClassInfo();
+
+  virtual nsIDOMNode* AsDOMNode() { return this; }
+private:
+
+  // nsSVGElement overrides
+
+  virtual EnumAttributesInfo GetEnumInfo();
+
+  enum { ZOOMANDPAN };
+  nsSVGEnum mEnumAttributes[1];
+  static nsSVGEnumMapping sZoomAndPanMap[];
+  static EnumInfo sEnumInfo[1];
+
+  virtual nsSVGViewBox *GetViewBox();
+  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
+
+  nsSVGViewBox                   mViewBox;
+  SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
+
+  virtual StringListAttributesInfo GetStringListInfo();
+
+  enum { VIEW_TARGET };
+  SVGStringList mStringListAttributes[1];
+  static StringListInfo sStringListInfo[1];
+};
+
+#endif
--- a/content/svg/content/test/bounds-helper.svg
+++ b/content/svg/content/test/bounds-helper.svg
@@ -15,15 +15,16 @@ text { font: 20px monospace; }
   <g transform="rotate(45 175 75)">
     <rect id="rect2" x="150" y="50" width="50" height="50" fill="yellow"/>
     <rect id="rect2a" x="150" y="50" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
     <text id="text3" x="150" y="50" text-anchor="middle">abc</text>
   </g>
   <g transform="scale(2)">
     <rect id="rect3" x="25" y="80" width="50" height="50" fill="green"/>
     <rect id="rect3a" x="25" y="80" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
+    <rect id="rect3b" vector-effect="non-scaling-stroke" x="100" y="100" width="25" height="25" fill="orange" stroke-width="4" stroke="yellow"/>
   </g>
   <g transform="scale(2) rotate(45 175 75)">
     <rect id="rect4" x="150" y="50" width="50" height="50" fill="yellow"/>
     <rect id="rect4a" x="150" y="50" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
   </g>
 </g>
 </svg>
--- a/content/svg/content/test/test_bounds.html
+++ b/content/svg/content/test/test_bounds.html
@@ -88,16 +88,17 @@ function runTest()
   isWithAbsTolerance(rect4Bounds.left, rect.left, 0.1, "rect4.getBoundingClientRect().left");
   isWithAbsTolerance(rect4Bounds.top, rect.top, 0.1, "rect4.getBoundingClientRect().top");
   isWithAbsTolerance(rect4Bounds.width, rect.width, 0.1, "rect4.getBoundingClientRect().width");
   isWithAbsTolerance(rect4Bounds.height, rect.height, 0.1, "rect4.getBoundingClientRect().height");
 
   var rect1aBounds = doc.getElementById("rect1a").getBoundingClientRect();
   var rect2aBounds = doc.getElementById("rect2a").getBoundingClientRect();
   var rect3aBounds = doc.getElementById("rect3a").getBoundingClientRect();
+  var rect3bBounds = doc.getElementById("rect3b").getBoundingClientRect();
   var rect4aBounds = doc.getElementById("rect4a").getBoundingClientRect();
 
   is(rect1aBounds.left, 48, "rect1a.getBoundingClientRect().left");
   is(rect1aBounds.top, 48, "rect1a.getBoundingClientRect().top");
   is(rect1aBounds.width, 54, "rect1a.getBoundingClientRect().width");
   is(rect1aBounds.height, 54, "rect1a.getBoundingClientRect().height");
 
   rect = new Rect(175 - 54 * sin45, 75 - 54 * sin45, 54 * sin45 * 2, 54 * sin45 * 2);
@@ -106,16 +107,21 @@ function runTest()
   isWithAbsTolerance(rect2aBounds.width, rect.width, 0.1, "rect2a.getBoundingClientRect().width");
   isWithAbsTolerance(rect2aBounds.height, rect.height, 0.1, "rect2a.getBoundingClientRect().height");
 
   is(rect3aBounds.left, 46, "rect3a.getBoundingClientRect().left");
   is(rect3aBounds.top, 156, "rect3a.getBoundingClientRect().top");
   is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
   is(rect3aBounds.height, 108, "rect3a.getBoundingClientRect().height");
 
+  is(rect3bBounds.left, 198, "rect3b.getBoundingClientRect().left");
+  is(rect3bBounds.top, 198, "rect3b.getBoundingClientRect().top");
+  is(rect3bBounds.width, 54, "rect3b.getBoundingClientRect().width");
+  is(rect3bBounds.height, 54, "rect3b.getBoundingClientRect().height");
+
   rect = new Rect(350 - 108 * sin45, 150 - 108 * sin45, 108 * sin45 * 2, 108 * sin45 * 2);
   isWithAbsTolerance(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");
   isWithAbsTolerance(rect4aBounds.top, rect.top, 0.1, "rect4a.getBoundingClientRect().top");
   isWithAbsTolerance(rect4aBounds.width, rect.width, 0.1, "rect4a.getBoundingClientRect().width");
   isWithAbsTolerance(rect4aBounds.height, rect.height, 0.1, "rect4a.getBoundingClientRect().height");
 
   var text1a = doc.getElementById("text1a");
 
--- a/content/xbl/src/Makefile.in
+++ b/content/xbl/src/Makefile.in
@@ -84,12 +84,11 @@ LOCAL_INCLUDES	= \
 		-I$(srcdir)/../../html/document/src \
 		-I$(srcdir)/../../xml/document/src \
 		-I$(srcdir)/../../xul/content/src \
 		-I$(srcdir)/../../xul/document/src \
 		-I$(srcdir)/../../events/src \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../dom/base \
 		-I$(topsrcdir)/xpcom/ds \
-		-I$(topsrcdir)/js/xpconnect/src \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -549,18 +549,17 @@ nsBindingManager::GetBinding(nsIContent*
 
   return nsnull;
 }
 
 nsresult
 nsBindingManager::SetBinding(nsIContent* aContent, nsXBLBinding* aBinding)
 {
   if (!mBindingTable.IsInitialized()) {
-    if (!mBindingTable.Init())
-      return NS_ERROR_OUT_OF_MEMORY;
+    mBindingTable.Init();
   }
 
   // After this point, aBinding will be the most-derived binding for aContent.
   // If we already have a binding for aContent in our table, make sure to
   // remove it from the attached stack.  Otherwise we might end up firing its
   // constructor twice (if aBinding inherits from it) or firing its constructor
   // after aContent has been deleted (if aBinding is null and the content node
   // dies before we process mAttachedStack).
@@ -579,36 +578,34 @@ nsBindingManager::SetBinding(nsIContent*
     // Don't remove items here as that could mess up an executing
     // ProcessAttachedQueue
     PRUint32 index = mAttachedStack.IndexOf(oldBinding);
     if (index != mAttachedStack.NoIndex) {
       mAttachedStack[index] = nsnull;
     }
   }
   
-  bool result = true;
-
   if (aBinding) {
     aContent->SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
-    result = mBindingTable.Put(aContent, aBinding);
+    mBindingTable.Put(aContent, aBinding);
   } else {
     mBindingTable.Remove(aContent);
 
     // The death of the bindings means the death of the JS wrapper,
     // and the flushing of our explicit and anonymous insertion point
     // lists.
     SetWrappedJS(aContent, nsnull);
     SetContentListFor(aContent, nsnull);
     SetAnonymousNodesFor(aContent, nsnull);
     if (oldBinding) {
       oldBinding->SetBoundElement(nsnull);
     }
   }
 
-  return result ? NS_OK : NS_ERROR_FAILURE;
+  return NS_OK;
 }
 
 nsIContent*
 nsBindingManager::GetInsertionParent(nsIContent* aContent)
 { 
   if (mInsertionParentTable.ops) {
     return static_cast<nsIContent*>
                       (LookupObject(mInsertionParentTable, aContent));
@@ -1096,22 +1093,21 @@ nsBindingManager::ExecuteDetachedHandler
   }
 }
 
 nsresult
 nsBindingManager::PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo)
 {
   NS_PRECONDITION(aDocumentInfo, "Must have a non-null documentinfo!");
   
-  NS_ENSURE_TRUE(mDocumentTable.IsInitialized() || mDocumentTable.Init(16),
-                 NS_ERROR_OUT_OF_MEMORY);
+  if (!mDocumentTable.IsInitialized())
+    mDocumentTable.Init(16);
 
-  NS_ENSURE_TRUE(mDocumentTable.Put(aDocumentInfo->DocumentURI(),
-                                    aDocumentInfo),
-                 NS_ERROR_OUT_OF_MEMORY);
+  mDocumentTable.Put(aDocumentInfo->DocumentURI(),
+                     aDocumentInfo);
 
   return NS_OK;
 }
 
 void
 nsBindingManager::RemoveXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo)
 {
   if (mDocumentTable.IsInitialized()) {
@@ -1128,21 +1124,20 @@ nsBindingManager::GetXBLDocumentInfo(nsI
   return mDocumentTable.GetWeak(aURL);
 }
 
 nsresult
 nsBindingManager::PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener)
 {
   NS_PRECONDITION(aListener, "Must have a non-null listener!");
   
-  NS_ENSURE_TRUE(mLoadingDocTable.IsInitialized() || mLoadingDocTable.Init(16),
-                 NS_ERROR_OUT_OF_MEMORY);
+  if (!mLoadingDocTable.IsInitialized())
+    mLoadingDocTable.Init(16);
   
-  NS_ENSURE_TRUE(mLoadingDocTable.Put(aURL, aListener),
-                 NS_ERROR_OUT_OF_MEMORY);
+  mLoadingDocTable.Put(aURL, aListener);
 
   return NS_OK;
 }
 
 nsIStreamListener*
 nsBindingManager::GetLoadingDocListener(nsIURI* aURL)
 {
   if (!mLoadingDocTable.IsInitialized())
@@ -1350,18 +1345,19 @@ static PLDHashOperator
 EnumRuleProcessors(nsISupports *aKey, nsXBLBinding *aBinding, void* aClosure)
 {
   RuleProcessorSet *set = static_cast<RuleProcessorSet*>(aClosure);
   for (nsXBLBinding *binding = aBinding; binding;
        binding = binding->GetBaseBinding()) {
     nsIStyleRuleProcessor *ruleProc =
       binding->PrototypeBinding()->GetRuleProcessor();
     if (ruleProc) {
-      if (!set->IsInitialized() && !set->Init(16))
-        return PL_DHASH_STOP;
+      if (!set->IsInitialized()) {
+        set->Init(16);
+      }
       set->PutEntry(ruleProc);
     }
   }
   return PL_DHASH_NEXT;
 }
 
 struct WalkAllRulesData {
   nsIStyleRuleProcessor::EnumFunc mFunc;
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -108,17 +108,17 @@ XBLFinalize(JSFreeOp *fop, JSObject *obj
     static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(obj));
   NS_RELEASE(docInfo);
   
   nsXBLJSClass* c = static_cast<nsXBLJSClass*>(::JS_GetClass(obj));
   c->Drop();
 }
 
 static JSBool
-XBLResolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
+XBLResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
            JSObject **objp)
 {
   // Note: if we get here, that means that the implementation for some binding
   // was installed, which means that AllowScripts() tested true.  Hence no need
   // to do checks like that here.
   
   // Default to not resolving things.
   NS_ASSERTION(*objp, "Must have starting object");
@@ -1433,32 +1433,24 @@ nsXBLBinding::HasInsertionParent(nsICont
 
 nsresult
 nsXBLBinding::GetInsertionPointsFor(nsIContent* aParent,
                                     nsInsertionPointList** aResult)
 {
   if (!mInsertionPointTable) {
     mInsertionPointTable =
       new nsClassHashtable<nsISupportsHashKey, nsInsertionPointList>;
-    if (!mInsertionPointTable || !mInsertionPointTable->Init(4)) {
-      delete mInsertionPointTable;
-      mInsertionPointTable = nsnull;
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    mInsertionPointTable->Init(4);
   }
 
   mInsertionPointTable->Get(aParent, aResult);
 
   if (!*aResult) {
     *aResult = new nsInsertionPointList;
-    if (!*aResult || !mInsertionPointTable->Put(aParent, *aResult)) {
-      delete *aResult;
-      *aResult = nsnull;
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    mInsertionPointTable->Put(aParent, *aResult);
     if (aParent) {
       aParent->SetFlags(NODE_IS_INSERTION_PARENT);
     }
   }
 
   return NS_OK;
 }
 
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -138,33 +138,33 @@ nsXBLDocGlobalObject::doCheckAccess(JSCo
   }
 
   nsresult rv = ssm->CheckPropertyAccess(cx, obj, JS_GetClass(obj)->name,
                                          id, accessType);
   return NS_SUCCEEDED(rv);
 }
 
 static JSBool
-nsXBLDocGlobalObject_getProperty(JSContext *cx, JSObject *obj,
-                                 jsid id, jsval *vp)
+nsXBLDocGlobalObject_getProperty(JSContext *cx, JSHandleObject obj,
+                                 JSHandleId id, jsval *vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 }
 
 static JSBool
-nsXBLDocGlobalObject_setProperty(JSContext *cx, JSObject *obj,
-                                 jsid id, JSBool strict, jsval *vp)
+nsXBLDocGlobalObject_setProperty(JSContext *cx, JSHandleObject obj,
+                                 JSHandleId id, JSBool strict, jsval *vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
 }
 
 static JSBool
-nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
+nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSHandleObject obj, JSHandleId id,
                                  JSAccessMode mode, jsval *vp)
 {
   PRUint32 translated;
   if (mode & JSACC_WRITE) {
     translated = nsIXPCSecurityManager::ACCESS_SET_PROPERTY;
   } else {
     translated = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
   }
@@ -185,17 +185,17 @@ nsXBLDocGlobalObject_finalize(JSFreeOp *
 
   // The addref was part of JSObject construction
   NS_RELEASE(nativeThis);
 
   DestroyProtoOrIfaceCache(obj);
 }
 
 static JSBool
-nsXBLDocGlobalObject_resolve(JSContext *cx, JSObject *obj, jsid id)
+nsXBLDocGlobalObject_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id)
 {
   JSBool did_resolve = JS_FALSE;
   return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
 JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
     "nsXBLPrototypeScript compilation scope",
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -642,136 +642,20 @@ struct keyCodeData {
   PRUint32 keycode;
 };
 
 // All of these must be uppercase, since the function below does
 // case-insensitive comparison by converting to uppercase.
 // XXX: be sure to check this periodically for new symbol additions!
 static const keyCodeData gKeyCodes[] = {
 
-#define KEYCODE_ENTRY(str) {#str, sizeof(#str) - 1, nsIDOMKeyEvent::DOM_##str}
-#define KEYCODE_ENTRY2(str, code) {str, sizeof(str) - 1, code}
-
-  KEYCODE_ENTRY(VK_CANCEL),
-  KEYCODE_ENTRY2("VK_BACK", nsIDOMKeyEvent::DOM_VK_BACK_SPACE),
-  KEYCODE_ENTRY(VK_TAB),
-  KEYCODE_ENTRY(VK_CLEAR),
-  KEYCODE_ENTRY(VK_RETURN),
-  KEYCODE_ENTRY(VK_ENTER),
-  KEYCODE_ENTRY(VK_SHIFT),
-  KEYCODE_ENTRY(VK_CONTROL),
-  KEYCODE_ENTRY(VK_ALT),
-  KEYCODE_ENTRY(VK_PAUSE),
-  KEYCODE_ENTRY(VK_CAPS_LOCK),
-  KEYCODE_ENTRY(VK_ESCAPE),
-  KEYCODE_ENTRY(VK_SPACE),
-  KEYCODE_ENTRY(VK_PAGE_UP),
-  KEYCODE_ENTRY(VK_PAGE_DOWN),
-  KEYCODE_ENTRY(VK_END),
-  KEYCODE_ENTRY(VK_HOME),
-  KEYCODE_ENTRY(VK_LEFT),
-  KEYCODE_ENTRY(VK_UP),
-  KEYCODE_ENTRY(VK_RIGHT),
-  KEYCODE_ENTRY(VK_DOWN),
-  KEYCODE_ENTRY(VK_PRINTSCREEN),
-  KEYCODE_ENTRY(VK_INSERT),
-  KEYCODE_ENTRY(VK_HELP),
-  KEYCODE_ENTRY(VK_DELETE),
-  KEYCODE_ENTRY(VK_0),
-  KEYCODE_ENTRY(VK_1),
-  KEYCODE_ENTRY(VK_2),
-  KEYCODE_ENTRY(VK_3),
-  KEYCODE_ENTRY(VK_4),
-  KEYCODE_ENTRY(VK_5),
-  KEYCODE_ENTRY(VK_6),
-  KEYCODE_ENTRY(VK_7),
-  KEYCODE_ENTRY(VK_8),
-  KEYCODE_ENTRY(VK_9),
-  KEYCODE_ENTRY(VK_SEMICOLON),
-  KEYCODE_ENTRY(VK_EQUALS),
-  KEYCODE_ENTRY(VK_A),
-  KEYCODE_ENTRY(VK_B),
-  KEYCODE_ENTRY(VK_C),
-  KEYCODE_ENTRY(VK_D),
-  KEYCODE_ENTRY(VK_E),
-  KEYCODE_ENTRY(VK_F),
-  KEYCODE_ENTRY(VK_G),
-  KEYCODE_ENTRY(VK_H),
-  KEYCODE_ENTRY(VK_I),
-  KEYCODE_ENTRY(VK_J),
-  KEYCODE_ENTRY(VK_K),
-  KEYCODE_ENTRY(VK_L),
-  KEYCODE_ENTRY(VK_M),
-  KEYCODE_ENTRY(VK_N),
-  KEYCODE_ENTRY(VK_O),
-  KEYCODE_ENTRY(VK_P),
-  KEYCODE_ENTRY(VK_Q),
-  KEYCODE_ENTRY(VK_R),
-  KEYCODE_ENTRY(VK_S),
-  KEYCODE_ENTRY(VK_T),
-  KEYCODE_ENTRY(VK_U),
-  KEYCODE_ENTRY(VK_V),
-  KEYCODE_ENTRY(VK_W),
-  KEYCODE_ENTRY(VK_X),
-  KEYCODE_ENTRY(VK_Y),
-  KEYCODE_ENTRY(VK_Z),
-  KEYCODE_ENTRY(VK_NUMPAD0),
-  KEYCODE_ENTRY(VK_NUMPAD1),
-  KEYCODE_ENTRY(VK_NUMPAD2),
-  KEYCODE_ENTRY(VK_NUMPAD3),
-  KEYCODE_ENTRY(VK_NUMPAD4),
-  KEYCODE_ENTRY(VK_NUMPAD5),
-  KEYCODE_ENTRY(VK_NUMPAD6),
-  KEYCODE_ENTRY(VK_NUMPAD7),
-  KEYCODE_ENTRY(VK_NUMPAD8),
-  KEYCODE_ENTRY(VK_NUMPAD9),
-  KEYCODE_ENTRY(VK_MULTIPLY),
-  KEYCODE_ENTRY(VK_ADD),
-  KEYCODE_ENTRY(VK_SEPARATOR),
-  KEYCODE_ENTRY(VK_SUBTRACT),
-  KEYCODE_ENTRY(VK_DECIMAL),
-  KEYCODE_ENTRY(VK_DIVIDE),
-  KEYCODE_ENTRY(VK_F1),
-  KEYCODE_ENTRY(VK_F2),
-  KEYCODE_ENTRY(VK_F3),
-  KEYCODE_ENTRY(VK_F4),
-  KEYCODE_ENTRY(VK_F5),
-  KEYCODE_ENTRY(VK_F6),
-  KEYCODE_ENTRY(VK_F7),
-  KEYCODE_ENTRY(VK_F8),
-  KEYCODE_ENTRY(VK_F9),
-  KEYCODE_ENTRY(VK_F10),
-  KEYCODE_ENTRY(VK_F11),
-  KEYCODE_ENTRY(VK_F12),
-  KEYCODE_ENTRY(VK_F13),
-  KEYCODE_ENTRY(VK_F14),
-  KEYCODE_ENTRY(VK_F15),
-  KEYCODE_ENTRY(VK_F16),
-  KEYCODE_ENTRY(VK_F17),
-  KEYCODE_ENTRY(VK_F18),
-  KEYCODE_ENTRY(VK_F19),
-  KEYCODE_ENTRY(VK_F20),
-  KEYCODE_ENTRY(VK_F21),
-  KEYCODE_ENTRY(VK_F22),
-  KEYCODE_ENTRY(VK_F23),
-  KEYCODE_ENTRY(VK_F24),
-  KEYCODE_ENTRY(VK_NUM_LOCK),
-  KEYCODE_ENTRY(VK_SCROLL_LOCK),
-  KEYCODE_ENTRY(VK_COMMA),
-  KEYCODE_ENTRY(VK_PERIOD),
-  KEYCODE_ENTRY(VK_SLASH),
-  KEYCODE_ENTRY(VK_BACK_QUOTE),
-  KEYCODE_ENTRY(VK_OPEN_BRACKET),
-  KEYCODE_ENTRY(VK_BACK_SLASH),
-  KEYCODE_ENTRY(VK_CLOSE_BRACKET),
-  KEYCODE_ENTRY(VK_QUOTE)
-
-#undef KEYCODE_ENTRY
-#undef KEYCODE_ENTRY2
-
+#define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
+  { #aDOMKeyName, sizeof(#aDOMKeyName) - 1, aDOMKeyCode }
+#include "nsVKList.h"
+#undef NS_DEFINE_VK
 };
 
 PRInt32 nsXBLPrototypeHandler::GetMatchingKeyCode(const nsAString& aKeyName)
 {
   nsCAutoString keyName;
   keyName.AssignWithConversion(aKeyName);
   ToUpperCase(keyName); // We want case-insensitive comparison with data
                         // stored as uppercase.
--- a/content/xslt/src/xslt/txEXSLTFunctions.cpp
+++ b/content/xslt/src/xslt/txEXSLTFunctions.cpp
@@ -402,29 +402,25 @@ txEXSLTFunctionCall::evaluate(txIEvalCon
                                    getter_AddRefs(nodes));
             NS_ENSURE_SUCCESS(rv, rv);
 
             nsRefPtr<txNodeSet> resultSet;
             rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet));
             NS_ENSURE_SUCCESS(rv, rv);
 
             nsTHashtable<nsStringHashKey> hash;
-            if (!hash.Init()) {
-                return NS_ERROR_OUT_OF_MEMORY;
-            }
+            hash.Init();
 
             PRInt32 i, len = nodes->size();
             for (i = 0; i < len; ++i) {
                 nsAutoString str;
                 const txXPathNode& node = nodes->get(i);
                 txXPathNodeUtils::appendNodeValue(node, str);
                 if (!hash.GetEntry(str)) {
-                    if (!hash.PutEntry(str)) {
-                        return NS_ERROR_OUT_OF_MEMORY;
-                    }
+                    hash.PutEntry(str);
                     rv = resultSet->append(node);
                     NS_ENSURE_SUCCESS(rv, rv);
                 }
             }
 
             NS_ADDREF(*aResult = resultSet);
 
             return NS_OK;
--- a/content/xslt/src/xslt/txExecutionState.cpp
+++ b/content/xslt/src/xslt/txExecutionState.cpp
@@ -46,18 +46,17 @@
 #include "txLog.h"
 #include "txURIUtils.h"
 #include "txXMLParser.h"
 
 const PRInt32 txExecutionState::kMaxRecursionDepth = 20000;
 
 nsresult txLoadedDocumentsHash::init(txXPathNode* aSourceDocument)
 {
-    nsresult rv = Init(8);
-    NS_ENSURE_SUCCESS(rv, rv);
+    Init(8);
 
     mSourceDocument = aSourceDocument;
     
     nsAutoString baseURI;
     txXPathNodeUtils::getBaseURI(*mSourceDocument, baseURI);
 
     txLoadedDocumentEntry* entry = PutEntry(baseURI);
     if (!entry) {
--- a/content/xslt/src/xslt/txKeyFunctionCall.cpp
+++ b/content/xslt/src/xslt/txKeyFunctionCall.cpp
@@ -267,25 +267,20 @@ txKeyHash::getKeyNodes(const txExpandedN
     }
 
     return NS_OK;
 }
 
 nsresult
 txKeyHash::init()
 {
-    nsresult rv = mKeyValues.Init(8);
-    NS_ENSURE_SUCCESS(rv, rv);
+    mKeyValues.Init(8);
+    mIndexedKeys.Init(1);
+    mEmptyNodeSet = new txNodeSet(nsnull);
 
-    rv = mIndexedKeys.Init(1);
-    NS_ENSURE_SUCCESS(rv, rv);
-    
-    mEmptyNodeSet = new txNodeSet(nsnull);
-    NS_ENSURE_TRUE(mEmptyNodeSet, NS_ERROR_OUT_OF_MEMORY);
-    
     return NS_OK;
 }
 
 
 /**
  * Adds a match/use pair.
  * @param aMatch  match-pattern
  * @param aUse    use-expression
--- a/content/xul/content/test/Makefile.in
+++ b/content/xul/content/test/Makefile.in
@@ -45,17 +45,16 @@ include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = 	\
 		test_bug486990.xul \
 		test_bug749367.xul \
 		$(NULL)
 
 _CHROME_FILES = \
-		test_bug330705-2.xul \
 		test_bug233643.xul \
  		test_bug398289.html \
  		398289-resource.xul \
  		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
deleted file mode 100644
--- a/content/xul/content/test/test_bug330705-2.xul
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml"
-  title="Test for Bug 330705">
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=330705
--->
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>         
-  <body  xmlns="http://www.w3.org/1999/xhtml">
-    <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=330705">Mozilla Bug 330705</a>
-    <p id="display">
-      <box tabindex="1" style="-moz-user-focus:normal;" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
-      <box tabindex="1" style="-moz-user-focus:normal;" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
-    </p>
-    <div id="content" style="display: none">
-      <script class="testbody" type="text/javascript">
-      <![CDATA[
-        SimpleTest.waitForExplicitFinish();
-
-        var isFocused = false;
-
-        function doTest() {
-          document.getElementsByTagName('box')[1].blur();
-          setTimeout(function () {
-            ok(isFocused,
-               "The first box element is still focused after blur() has been called on the second box element");
-            SimpleTest.finish();
-          }, 0);
-        }
-
-        function onLoad() {
-          var box = document.getElementsByTagName('box')[0];
-          box.addEventListener('focus', function() {
-            isFocused = true;
-            setTimeout(doTest, 0);
-            box.removeEventListener('focus', arguments.callee, true);
-          }, true);
-          box.addEventListener('blur', function() { isFocused = false;}, true);
-          box.focus();
-        }
-
-        addLoadEvent(onLoad);
-      ]]>
-      </script>
-      <pre id="test">
-      </pre>
-    </div>
-  </body>
-</window>
--- a/content/xul/document/src/Makefile.in
+++ b/content/xul/document/src/Makefile.in
@@ -71,13 +71,12 @@ LOCAL_INCLUDES	= -I$(srcdir)/../../../ba
 		  -I$(srcdir)/../../../../layout/base \
 		  -I$(srcdir)/../../../../layout/generic \
 		  -I$(srcdir)/../../../../layout/style \
 		  -I$(srcdir)/../../../../layout/xul/base/src \
 		  -I$(srcdir)/../../../xml/document/src \
 		  -I$(srcdir)/../../../xbl/src \
 		  -I$(srcdir)/../../../events/src \
 		  -I$(topsrcdir)/xpcom/ds \
-		  -I$(topsrcdir)/js/xpconnect/src \
 		  -I$(topsrcdir)/dom/base \
 		  $(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -1868,20 +1868,17 @@ NS_IMETHODIMP
 nsXULDocument::SetTemplateBuilderFor(nsIContent* aContent,
                                      nsIXULTemplateBuilder* aBuilder)
 {
     if (! mTemplateBuilderTable) {
         if (!aBuilder) {
             return NS_OK;
         }
         mTemplateBuilderTable = new BuilderTable;
-        if (! mTemplateBuilderTable || !mTemplateBuilderTable->Init()) {
-            mTemplateBuilderTable = nsnull;
-            return NS_ERROR_OUT_OF_MEMORY;
-        }
+        mTemplateBuilderTable->Init();
     }
 
     if (aBuilder) {
         mTemplateBuilderTable->Put(aContent, aBuilder);
     }
     else {
         mTemplateBuilderTable->Remove(aContent);
     }
@@ -2644,19 +2641,19 @@ nsXULDocument::LoadOverlay(const nsAStri
     nsresult rv;
 
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), aURL, nsnull);
     if (NS_FAILED(rv)) return rv;
 
     if (aObserver) {
         nsIObserver* obs = nsnull;
-        NS_ENSURE_TRUE(mOverlayLoadObservers.IsInitialized() || mOverlayLoadObservers.Init(), 
-                       NS_ERROR_OUT_OF_MEMORY);
-        
+        if (!mOverlayLoadObservers.IsInitialized()) {
+            mOverlayLoadObservers.Init();
+        }
         obs = mOverlayLoadObservers.GetWeak(uri);
 
         if (obs) {
             // We don't support loading the same overlay twice into the same
             // document - that doesn't make sense anyway.
             return NS_ERROR_FAILURE;
         }
         mOverlayLoadObservers.Put(uri, aObserver);
@@ -3243,18 +3240,19 @@ nsXULDocument::DoneWalking()
                 // yet been attached. This can be a race condition because dynamic
                 // overlay loading can take varying amounts of time depending on
                 // whether or not the overlay prototype is in the XUL cache. The
                 // most likely effect of this bug is odd UI initialization due to
                 // methods and properties that do not work.
                 // XXXbz really, we shouldn't be firing binding constructors
                 // until after StartLayout returns!
 
-                NS_ENSURE_TRUE(mPendingOverlayLoadNotifications.IsInitialized() || mPendingOverlayLoadNotifications.Init(), 
-                               NS_ERROR_OUT_OF_MEMORY);
+                if (!mPendingOverlayLoadNotifications.IsInitialized()) {
+                    mPendingOverlayLoadNotifications.Init();
+                }
                 
                 mPendingOverlayLoadNotifications.Get(overlayURI, getter_AddRefs(obs));
                 if (!obs) {
                     mOverlayLoadObservers.Get(overlayURI, getter_AddRefs(obs));
                     NS_ASSERTION(obs, "null overlay load observer?");
                     mPendingOverlayLoadNotifications.Put(overlayURI, obs);
                 }
             }
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -204,28 +204,27 @@ nsXULPrototypeCache::GetPrototype(nsIURI
     return newProto;
 }
 
 nsresult
 nsXULPrototypeCache::PutPrototype(nsXULPrototypeDocument* aDocument)
 {
     nsCOMPtr<nsIURI> uri = aDocument->GetURI();
     // Put() releases any old value and addrefs the new one
-    NS_ENSURE_TRUE(mPrototypeTable.Put(uri, aDocument), NS_ERROR_OUT_OF_MEMORY);
+    mPrototypeTable.Put(uri, aDocument);
 
     return NS_OK;
 }
 
 nsresult
 nsXULPrototypeCache::PutStyleSheet(nsCSSStyleSheet* aStyleSheet)
 {
     nsIURI* uri = aStyleSheet->GetSheetURI();
 
-    NS_ENSURE_TRUE(mStyleSheetTable.Put(uri, aStyleSheet),
-                   NS_ERROR_OUT_OF_MEMORY);
+    mStyleSheetTable.Put(uri, aStyleSheet);
 
     return NS_OK;
 }
 
 
 JSScript*
 nsXULPrototypeCache::GetScript(nsIURI* aURI)
 {
@@ -261,17 +260,17 @@ nsXULPrototypeCache::PutScript(nsIURI* a
         NS_WARNING(message.get());
 #endif
         // Reuse the callback used for enumeration in FlushScripts
         ReleaseScriptObjectCallback(aURI, existingEntry, nsnull);
     }
 
     CacheScriptEntry entry = {aScriptObject};
 
-    NS_ENSURE_TRUE(mScriptTable.Put(aURI, entry), NS_ERROR_OUT_OF_MEMORY);
+    mScriptTable.Put(aURI, entry);
 
     // Lock the object from being gc'd until it is removed from the cache
     nsCOMPtr<nsIScriptRuntime> rt;
     nsresult rv = NS_GetJSRuntime(getter_AddRefs(rt));
     if (NS_SUCCEEDED(rv))
         rv = rt->HoldScriptObject(aScriptObject);
     NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to GC lock the object");
 
@@ -291,18 +290,17 @@ nsXULPrototypeCache::FlushScripts()
 nsresult
 nsXULPrototypeCache::PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo)
 {
     nsIURI* uri = aDocumentInfo->DocumentURI();
 
     nsRefPtr<nsXBLDocumentInfo> info;
     mXBLDocTable.Get(uri, getter_AddRefs(info));
     if (!info) {
-        NS_ENSURE_TRUE(mXBLDocTable.Put(uri, aDocumentInfo),
-                       NS_ERROR_OUT_OF_MEMORY);
+        mXBLDocTable.Put(uri, aDocumentInfo);
     }
     return NS_OK;
 }
 
 static PLDHashOperator
 FlushSkinXBL(nsIURI* aKey, nsRefPtr<nsXBLDocumentInfo>& aDocInfo, void* aClosure)
 {
   nsCAutoString str;
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -132,17 +132,17 @@ nsXULPDGlobalObject_finalize(JSFreeOp *f
     // The addref was part of JSObject construction
     NS_RELEASE(nativeThis);
 
     DestroyProtoOrIfaceCache(obj);
 }
 
 
 JSBool
-nsXULPDGlobalObject_resolve(JSContext *cx, JSObject *obj, jsid id)
+nsXULPDGlobalObject_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id)
 {
     JSBool did_resolve = JS_FALSE;
 
     return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
 JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1236,19 +1236,18 @@ nsXULContentBuilder::CreateContainerCont
         }
 
         if (mFlags & eLoggingEnabled)
             OutputMatchToLog(resultid, newmatch, true);
 
         if (prevmatch) {
             prevmatch->mNext = newmatch;
         }
-        else if (!mMatchMap.Put(resultid, newmatch)) {
-            nsTemplateMatch::Destroy(mPool, newmatch, true);
-            return NS_ERROR_OUT_OF_MEMORY;
+        else {
+            mMatchMap.Put(resultid, newmatch);
         }
 
         if (removematch) {
             newmatch->mNext = removematch->mNext;
             nsTemplateMatch::Destroy(mPool, removematch, true);
         }
         else {
             newmatch->mNext = existingmatch;
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -206,18 +206,18 @@ nsXULTemplateBuilder::InitGlobals()
             return rv;
     }
 
 #ifdef PR_LOGGING
     if (! gXULTemplateLog)
         gXULTemplateLog = PR_NewLogModule("nsXULTemplateBuilder");
 #endif
 
-    if (!mMatchMap.IsInitialized() && !mMatchMap.Init())
-        return NS_ERROR_OUT_OF_MEMORY;
+    if (!mMatchMap.IsInitialized())
+        mMatchMap.Init();
 
     const size_t bucketsizes[] = { sizeof(nsTemplateMatch) };
     return mPool.Init("nsXULTemplateBuilder", bucketsizes, 1, 256);
 }
 
 void
 nsXULTemplateBuilder::CleanUp(bool aIsFinal)
 {
@@ -786,18 +786,17 @@ nsXULTemplateBuilder::UpdateResultInCont
 
                         findmatch = findmatch->mNext;
                     }
                 }
 
                 if (oldmatch == firstmatch) {
                     // the match to remove is at the beginning
                     if (oldmatch->mNext) {
-                        if (!mMatchMap.Put(aOldId, oldmatch->mNext))
-                            return NS_ERROR_OUT_OF_MEMORY;
+                        mMatchMap.Put(aOldId, oldmatch->mNext);
                     }
                     else {
                         mMatchMap.Remove(aOldId);
                     }
                 }
 
                 if (prevmatch)
                     prevmatch->mNext = nextmatch;
@@ -960,23 +959,17 @@ nsXULTemplateBuilder::UpdateResultInCont
                         }
 
                         newmatch = newmatch->mNext;
                     }
                 }
 
                 // put the match in the map if there isn't a previous match
                 if (! prevmatch) {
-                    if (!mMatchMap.Put(aNewId, newmatch)) {
-                        // The match may have already matched a rule above, so
-                        // HasBeenRemoved should be called to indicate that it
-                        // is being removed again.
-                        nsTemplateMatch::Destroy(mPool, newmatch, true);
-                        return rv;
-                    }
+                    mMatchMap.Put(aNewId, newmatch);
                 }
             }
 
             // hook up the match last in case an error occurs
             if (prevmatch)
                 prevmatch->mNext = newmatch;
         }
         else {
@@ -995,20 +988,17 @@ nsXULTemplateBuilder::UpdateResultInCont
                 if (NS_FAILED(rv)) {
                     nsTemplateMatch::Destroy(mPool, newmatch, false);
                     return rv;
                 }
 
                 acceptedmatch = newmatch;
             }
 
-            if (!mMatchMap.Put(aNewId, newmatch)) {
-                nsTemplateMatch::Destroy(mPool, newmatch, true);
-                return NS_ERROR_OUT_OF_MEMORY;
-            }
+            mMatchMap.Put(aNewId, newmatch);
         }
     }
 
     // The ReplaceMatch method is builder specific and removes the generated
     // content for a match.
 
     // Remove the content for a match that was active and needs to be replaced.
     if (replacedmatch) {
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
@@ -337,25 +337,22 @@ nsXULTemplateQueryProcessorRDF::Initiali
                                                       nsIXULTemplateBuilder* aBuilder,
                                                       nsIDOMNode* aRootNode)
 {
     if (!mQueryProcessorRDFInited) {
         nsresult rv = InitGlobals();
         if (NS_FAILED(rv))
             return rv;
 
-        if (!mMemoryElementToResultMap.IsInitialized() &&
-            !mMemoryElementToResultMap.Init())
-            return NS_ERROR_OUT_OF_MEMORY;
-        if (!mBindingDependencies.IsInitialized() &&
-            !mBindingDependencies.Init())
-            return NS_ERROR_OUT_OF_MEMORY;
-        if (!mRuleToBindingsMap.IsInitialized() &&
-            !mRuleToBindingsMap.Init())
-            return NS_ERROR_OUT_OF_MEMORY;
+        if (!mMemoryElementToResultMap.IsInitialized())
+            mMemoryElementToResultMap.Init();
+        if (!mBindingDependencies.IsInitialized())
+            mBindingDependencies.Init();
+        if (!mRuleToBindingsMap.IsInitialized())
+            mRuleToBindingsMap.Init();
 
         mQueryProcessorRDFInited = true;
     }
 
     // don't do anything if generation has already been done
     if (mGenerationStarted)
         return NS_ERROR_UNEXPECTED;
 
@@ -615,18 +612,17 @@ nsXULTemplateQueryProcessorRDF::AddBindi
     nsCOMPtr<nsIRDFResource> property;
     nsresult rv = gRDFService->GetUnicodeResource(aExpr, getter_AddRefs(property));
     if (NS_FAILED(rv))
         return rv;
 
     nsRefPtr<RDFBindingSet> bindings = mRuleToBindingsMap.GetWeak(aRuleNode);
     if (!bindings) {
         bindings = new RDFBindingSet();
-        if (!bindings || !mRuleToBindingsMap.Put(aRuleNode, bindings))
-            return NS_ERROR_OUT_OF_MEMORY;
+        mRuleToBindingsMap.Put(aRuleNode, bindings);
     }
 
     return bindings->AddBinding(aVar, aRef, property);
 }
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorRDF::TranslateRef(nsISupports* aDatasource,
                                                            const nsAString& aRefString,
@@ -1761,20 +1757,17 @@ nsXULTemplateQueryProcessorRDF::AddBindi
                                                      nsIRDFResource* aResource)
 {
     nsCOMArray<nsXULTemplateResultRDF>* arr;
     if (!mBindingDependencies.Get(aResource, &arr)) {
         arr = new nsCOMArray<nsXULTemplateResultRDF>();
         if (!arr)
             return NS_ERROR_OUT_OF_MEMORY;
 
-        if (!mBindingDependencies.Put(aResource, arr)) {
-            delete arr;
-            return NS_ERROR_OUT_OF_MEMORY;
-        }
+        mBindingDependencies.Put(aResource, arr);
     }
 
     PRInt32 index = arr->IndexOf(aResult);
     if (index == -1)
         return arr->AppendObject(aResult);
 
     return NS_OK;
 }
@@ -1806,20 +1799,17 @@ nsXULTemplateQueryProcessorRDF::AddMemor
         PLHashNumber hash = (element.operator->())->Hash();
 
         nsCOMArray<nsXULTemplateResultRDF>* arr;
         if (!mMemoryElementToResultMap.Get(hash, &arr)) {
             arr = new nsCOMArray<nsXULTemplateResultRDF>();
             if (!arr)
                 return NS_ERROR_OUT_OF_MEMORY;
 
-            if (!mMemoryElementToResultMap.Put(hash, arr)) {
-                delete arr;
-                return NS_ERROR_OUT_OF_MEMORY;
-            }
+            mMemoryElementToResultMap.Put(hash, arr);
         }
 
         // results may be added more than once so they will all get deleted properly
         arr->AppendObject(aResult);
     }
 
     return NS_OK;
 }
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
@@ -250,19 +250,18 @@ nsXULTemplateQueryProcessorXML::Initiali
         doc->GetDocumentElement(getter_AddRefs(mRoot));
     else
       mRoot = do_QueryInterface(aDatasource);
     NS_ENSURE_STATE(mRoot);
 
     mEvaluator = do_CreateInstance("@mozilla.org/dom/xpath-evaluator;1");
     NS_ENSURE_TRUE(mEvaluator, NS_ERROR_OUT_OF_MEMORY);
 
-    if (!mRuleToBindingsMap.IsInitialized() &&
-        !mRuleToBindingsMap.Init())
-        return NS_ERROR_OUT_OF_MEMORY;
+    if (!mRuleToBindingsMap.IsInitialized())
+        mRuleToBindingsMap.Init();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorXML::Done()
 {
     mGenerationStarted = false;
@@ -395,18 +394,17 @@ nsXULTemplateQueryProcessorXML::AddBindi
                                            const nsAString& aExpr)
 {
     if (mGenerationStarted)
         return NS_ERROR_FAILURE;
 
     nsRefPtr<nsXMLBindingSet> bindings = mRuleToBindingsMap.GetWeak(aRuleNode);
     if (!bindings) {
         bindings = new nsXMLBindingSet();
-        if (!bindings || !mRuleToBindingsMap.Put(aRuleNode, bindings))
-            return NS_ERROR_OUT_OF_MEMORY;
+        mRuleToBindingsMap.Put(aRuleNode, bindings);
     }
 
     nsCOMPtr<nsIDOMXPathExpression> compiledexpr;
     nsresult rv =
         CreateExpression(aExpr, aRuleNode, getter_AddRefs(compiledexpr));
     if (NS_FAILED(rv)) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_BINDING_XPATH);
         return NS_OK;
--- a/content/xul/templates/src/nsXULTreeBuilder.cpp
+++ b/content/xul/templates/src/nsXULTreeBuilder.cpp
@@ -1738,19 +1738,18 @@ nsXULTreeBuilder::OpenSubtreeForQuerySet
             if (mFlags & eLoggingEnabled)
                 OutputMatchToLog(resultid, newmatch, true);
 
         }
 
         if (prevmatch) {
             prevmatch->mNext = newmatch;
         }
-        else if (!mMatchMap.Put(resultid, newmatch)) {
-            nsTemplateMatch::Destroy(mPool, newmatch, true);
-            return NS_ERROR_OUT_OF_MEMORY;
+        else {
+            mMatchMap.Put(resultid, newmatch);
         }
     }
 
     *aDelta = count;
     return rv;
 }
 
 nsresult
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -872,18 +872,17 @@ nsDocShell::Init()
     NS_ASSERTION(mLoadGroup, "Something went wrong!");
 
     mContentListener = new nsDSURIContentListener(this);
     NS_ENSURE_TRUE(mContentListener, NS_ERROR_OUT_OF_MEMORY);
 
     rv = mContentListener->Init();
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if (!mStorages.Init())
-        return NS_ERROR_OUT_OF_MEMORY;
+    mStorages.Init();
 
     // We want to hold a strong ref to the loadgroup, so it better hold a weak
     // ref to us...  use an InterfaceRequestorProxy to do this.
     nsCOMPtr<InterfaceRequestorProxy> proxy =
         new InterfaceRequestorProxy(static_cast<nsIInterfaceRequestor*>
                                                (this));
     NS_ENSURE_TRUE(proxy, NS_ERROR_OUT_OF_MEMORY);
     mLoadGroup->SetNotificationCallbacks(proxy);
@@ -2437,18 +2436,17 @@ nsDocShell::GetSessionStorageForPrincipa
         nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(newstorage);
         if (!pistorage)
             return NS_ERROR_FAILURE;
 
         rv = pistorage->InitAsSessionStorage(aPrincipal, aDocumentURI);
         if (NS_FAILED(rv))
             return rv;
 
-        if (!mStorages.Put(origin, newstorage))
-            return NS_ERROR_OUT_OF_MEMORY;
+        mStorages.Put(origin, newstorage);
 
         newstorage.swap(*aStorage);
 #if defined(PR_LOGGING) && defined(DEBUG)
         PR_LOG(gDocShellLog, PR_LOG_DEBUG,
                ("nsDocShell[%p]: created a new sessionStorage %p",
                 this, *aStorage));
 #endif
     }
@@ -2575,18 +2573,17 @@ nsDocShell::AddSessionStorage(nsIPrincip
             if (mStorages.GetWeak(origin))
                 return NS_ERROR_NOT_AVAILABLE;
 
 #if defined(PR_LOGGING) && defined(DEBUG)
             PR_LOG(gDocShellLog, PR_LOG_DEBUG,
                    ("nsDocShell[%p]: was added a sessionStorage %p",
                     this, aStorage));
 #endif
-            if (!mStorages.Put(origin, aStorage))
-                return NS_ERROR_OUT_OF_MEMORY;
+            mStorages.Put(origin, aStorage);
         }
         else {
             return topDocShell->AddSessionStorage(aPrincipal, aStorage);
         }
     }
 
     return NS_OK;
 }
--- a/dom/base/BrowserElementChild.js
+++ b/dom/base/BrowserElementChild.js
@@ -70,16 +70,19 @@ BrowserElementChild.prototype = {
                      this._titleChangedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
     addEventListener('DOMLinkAdded',
                      this._iconChangedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
+
+    addMessageListener("browser-element-api:get-screenshot",
+                       this._recvGetScreenshot.bind(this));
   },
 
   _titleChangedHandler: function(e) {
     debug("Got titlechanged: (" + e.target.title + ")");
     var win = e.target.defaultView;
 
     // Ignore titlechanges which don't come from the top-level
     // <iframe mozbrowser> window.
@@ -105,16 +108,32 @@ BrowserElementChild.prototype = {
         sendAsyncMsg('iconchange', e.target.href);
       }
       else {
         debug("Not top level!");
       }
     }
   },
 
+  _recvGetScreenshot: function(data) {
+    debug("Received getScreenshot message: (" + data.json.id + ")");
+    var canvas = content.document
+      .createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+    var ctx = canvas.getContext("2d");
+    canvas.mozOpaque = true;
+    canvas.height = content.innerHeight;
+    canvas.width = content.innerWidth;
+    ctx.drawWindow(content, 0, 0, content.innerWidth,
+                   content.innerHeight, "rgb(255,255,255)");
+    sendAsyncMsg('got-screenshot', {
+      id: data.json.id,
+      screenshot: canvas.toDataURL("image/png")
+    });
+  },
+
   // The docShell keeps a weak reference to the progress listener, so we need
   // to keep a strong ref to it ourselves.
   _progressListener: {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
                                            Ci.nsISupportsWeakReference,
                                            Ci.nsISupports]),
     _seenLoadStart: false,
 
--- a/dom/base/BrowserElementParent.js
+++ b/dom/base/BrowserElementParent.js
@@ -2,16 +2,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 let Cu = Components.utils;
 let Ci = Components.interfaces;
 let Cc = Components.classes;
+
+Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
 const BROWSER_FRAMES_ENABLED_PREF = "dom.mozBrowserFramesEnabled";
 
 function debug(msg) {
   //dump("BrowserElementParent - " + msg + "\n");
 }
@@ -47,16 +49,19 @@ BrowserElementParent.prototype = {
     if (!this._browserFramesPrefEnabled()) {
       var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
       prefs.addObserver(BROWSER_FRAMES_ENABLED_PREF, this, /* ownsWeak = */ true);
       return;
     }
 
     this._initialized = true;
 
+    this._screenshotListeners = {};
+    this._screenshotReqCounter = 0;
+
     var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
     os.addObserver(this, 'remote-browser-frame-shown', /* ownsWeak = */ true);
     os.addObserver(this, 'in-process-browser-frame-shown', /* ownsWeak = */ true);
   },
 
   _browserFramesPrefEnabled: function() {
     var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
     try {
@@ -96,16 +101,21 @@ BrowserElementParent.prototype = {
 
     addMessageListener("hello", this._recvHello);
     addMessageListener("locationchange", this._fireEventFromMsg);
     addMessageListener("loadstart", this._fireEventFromMsg);
     addMessageListener("loadend", this._fireEventFromMsg);
     addMessageListener("titlechange", this._fireEventFromMsg);
     addMessageListener("iconchange", this._fireEventFromMsg);
     addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
+    mm.addMessageListener('browser-element-api:got-screenshot',
+                          this._recvGotScreenshot.bind(this));
+
+    XPCNativeWrapper.unwrap(frameElement).getScreenshot =
+      this._getScreenshot.bind(this, mm, frameElement);
 
     mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
                        /* allowDelayedLoad = */ true);
   },
 
   _recvHello: function(frameElement, data) {
     debug("recvHello " + frameElement);
   },
@@ -134,16 +144,31 @@ BrowserElementParent.prototype = {
 
     frameElement.dispatchEvent(evt);
   },
 
   _sendMozAppManifestURL: function(frameElement, data) {
     return frameElement.getAttribute('mozapp');
   },
 
+  _recvGotScreenshot: function(data) {
+    var req = this._screenshotListeners[data.json.id];
+    delete this._screenshotListeners[data.json.id];
+    Services.DOMRequest.fireSuccess(req, data.json.screenshot);
+  },
+
+  _getScreenshot: function(mm, frameElement) {
+    let id = 'req_' + this._screenshotReqCounter++;
+    let req = Services.DOMRequest
+      .createRequest(frameElement.ownerDocument.defaultView);
+    this._screenshotListeners[id] = req;
+    mm.sendAsyncMessage('browser-element-api:get-screenshot', {id: id});
+    return req;
+  },
+
   observe: function(subject, topic, data) {
     switch(topic) {
     case 'app-startup':
       this._init();
       break;
     case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
       if (data == BROWSER_FRAMES_ENABLED_PREF) {
         this._init();
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -321,16 +321,17 @@
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
 #include "nsIDOMMozCSSKeyframesRule.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsDOMCSSValueList.h"
 #include "nsIDOMDeviceProximityEvent.h"
+#include "nsIDOMUserProximityEvent.h"
 #include "nsIDOMDeviceLightEvent.h"
 #include "nsIDOMDeviceOrientationEvent.h"
 #include "nsIDOMDeviceMotionEvent.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMNodeIterator.h"
 #include "nsIDOMTreeWalker.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMXULElement.h"
@@ -430,16 +431,17 @@
 #include "nsIDOMSVGTitleElement.h"
 #include "nsIDOMSVGTransform.h"
 #include "nsIDOMSVGTransformable.h"
 #include "nsIDOMSVGTransformList.h"
 #include "nsIDOMSVGTSpanElement.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsIDOMSVGUseElement.h"
+#include "nsIDOMSVGViewElement.h"
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsIDOMSVGZoomEvent.h"
 
 #include "nsIDOMCanvasRenderingContext2D.h"
 #include "nsIDOMWebGLRenderingContext.h"
 
 #include "nsIImageDocument.h"
 
@@ -816,16 +818,19 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(PopupBlockedEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   // Device Light
   NS_DEFINE_CLASSINFO_DATA(DeviceLightEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   // Device Proximity
   NS_DEFINE_CLASSINFO_DATA(DeviceProximityEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  // User Proximity
+  NS_DEFINE_CLASSINFO_DATA(UserProximityEvent, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   // Device Orientation
   NS_DEFINE_CLASSINFO_DATA(DeviceOrientationEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DeviceMotionEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DeviceAcceleration, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DeviceRotationRate, nsDOMGenericSH,
@@ -1206,16 +1211,18 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(SVGTitleElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGTSpanElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA_WITH_NAME(SVGUnknownElement, SVGElement, nsElementSH,
                                      ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGUseElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(SVGViewElement, nsElementSH,
+                           ELEMENT_SCRIPTABLE_FLAGS)
 
   // other SVG classes
   NS_DEFINE_CLASSINFO_DATA(SVGAngle, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGAnimatedAngle, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGAnimatedBoolean, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -1692,16 +1699,17 @@ NS_DEFINE_EVENT_CTOR(PopStateEvent)
 NS_DEFINE_EVENT_CTOR(HashChangeEvent)
 NS_DEFINE_EVENT_CTOR(PageTransitionEvent)
 NS_DEFINE_EVENT_CTOR(CloseEvent)
 NS_DEFINE_EVENT_CTOR(MozSettingsEvent)
 NS_DEFINE_EVENT_CTOR(UIEvent)
 NS_DEFINE_EVENT_CTOR(MouseEvent)
 NS_DEFINE_EVENT_CTOR(DeviceLightEvent)
 NS_DEFINE_EVENT_CTOR(DeviceProximityEvent)
+NS_DEFINE_EVENT_CTOR(UserProximityEvent)
 
 nsresult
 NS_DOMStorageEventCtor(nsISupports** aInstancePtrResult)
 {
   nsDOMStorageEvent* e = new nsDOMStorageEvent();
   return CallQueryInterface(e, aInstancePtrResult);
 }
 
@@ -1727,16 +1735,17 @@ static const nsConstructorFuncMapData kC
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(PopStateEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(HashChangeEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(PageTransitionEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(CloseEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozSettingsEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(DeviceProximityEvent)
+  NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UserProximityEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(DeviceLightEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(StorageEvent)
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozSmsFilter, sms::SmsFilter::NewSmsFilter)
 };
 
 nsIXPConnect *nsDOMClassInfo::sXPConnect = nsnull;
 nsIScriptSecurityManager *nsDOMClassInfo::sSecMan = nsnull;
 bool nsDOMClassInfo::sIsInitialized = false;
@@ -2616,16 +2625,21 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DeviceProximityEvent, nsIDOMDeviceProximityEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceProximityEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(UserProximityEvent, nsIDOMUserProximityEvent)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMUserProximityEvent)
+    DOM_CLASSINFO_EVENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(DeviceOrientationEvent, nsIDOMDeviceOrientationEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceOrientationEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DeviceMotionEvent, nsIDOMDeviceMotionEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceMotionEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
@@ -3661,16 +3675,22 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(SVGUseElement, nsIDOMSVGUseElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUseElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(SVGViewElement, nsIDOMSVGViewElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGZoomAndPan)
+    DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   // other SVG classes
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAngle, nsIDOMSVGAngle)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAngle)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedAngle, nsIDOMSVGAnimatedAngle)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedAngle)
@@ -5221,18 +5241,18 @@ static JSClass sGlobalScopePolluterClass
   (JSResolveOp)nsWindowSH::GlobalScopePolluterNewResolve,
   JS_ConvertStub,
   nsHTMLDocumentSH::ReleaseDocument
 };
 
 
 // static
 JSBool
-nsWindowSH::GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
-                                           jsid id, jsval *vp)
+nsWindowSH::GlobalScopePolluterGetProperty(JSContext *cx, JSHandleObject obj,
+                                           JSHandleId id, jsval *vp)
 {
   // Someone is accessing a element by referencing its name/id in the
   // global scope, do a security check to make sure that's ok.
 
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
                                  nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
@@ -5248,17 +5268,17 @@ nsWindowSH::GlobalScopePolluterGetProper
   // catch and fix these mistakes.
   PrintWarningOnConsole(cx, "GlobalScopeElementReference");
 
   return JS_TRUE;
 }
 
 // static
 JSBool
-nsWindowSH::SecurityCheckOnAddDelProp(JSContext *cx, JSObject *obj, jsid id,
+nsWindowSH::SecurityCheckOnAddDelProp(JSContext *cx, JSHandleObject obj, JSHandleId id,
                                       jsval *vp)
 {
   // Someone is accessing a element by referencing its name/id in the
   // global scope, do a security check to make sure that's ok.
 
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
@@ -5266,33 +5286,33 @@ nsWindowSH::SecurityCheckOnAddDelProp(JS
 
   // If !NS_SUCCEEDED(rv) the security check failed. The security
   // manager set a JS exception for us.
   return NS_SUCCEEDED(rv);
 }
 
 // static
 JSBool
-nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
+nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict,
                                    jsval *vp)
 {
   return SecurityCheckOnAddDelProp(cx, obj, id, vp);
 }
 
 static nsHTMLDocument*
 GetDocument(JSObject *obj)
 {
   return static_cast<nsHTMLDocument*>(
     static_cast<nsIHTMLDocument*>(::JS_GetPrivate(obj)));
 }
 
 // static
 JSBool
-nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
-                                          jsid id, unsigned flags,
+nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
+                                          JSHandleId id, unsigned flags,
                                           JSObject **objp)
 {
   if (flags & (JSRESOLVE_ASSIGNING | JSRESOLVE_DECLARING |
                JSRESOLVE_CLASSNAME | JSRESOLVE_QUALIFIED) ||
       !JSID_IS_STRING(id)) {
     // Nothing to do here if we're either assigning or declaring,
     // resolving a class name, doing a qualified resolve, or
     // resolving a number.
@@ -5771,17 +5791,17 @@ static const IDBConstant sIDBConstants[]
   { IDBConstant::IDBRequest,     "LOADING",           "pending" },
   { IDBConstant::IDBRequest,     "DONE",              "done" },
   { IDBConstant::IDBTransaction, "READ_ONLY",         "readonly" },
   { IDBConstant::IDBTransaction, "READ_WRITE",        "readwrite" },
   { IDBConstant::IDBTransaction, "VERSION_CHANGE",    "versionchange" },
 };
 
 static JSBool
-IDBConstantGetter(JSContext *cx, JSObject *obj, jsid id, jsval* vp)
+IDBConstantGetter(JSContext *cx, JSHandleObject obj, JSHandleId id, jsval* vp)
 {
   MOZ_ASSERT(JSID_IS_INT(id));
   
   int8_t index = JSID_TO_INT(id);
   
   MOZ_ASSERT((uint8_t)index < mozilla::ArrayLength(sIDBConstants));
 
   const IDBConstant& c = sIDBConstants[index];
@@ -6906,47 +6926,52 @@ LocationSetterGuts(JSContext *cx, JSObje
   nsDependentJSString depStr;
   NS_ENSURE_TRUE(depStr.init(cx, val), NS_ERROR_UNEXPECTED);
   
   return location->SetHref(depStr);
 }
 
 template<class Interface>
 static JSBool
-LocationSetter(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
+LocationSetter(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict,
                jsval *vp)
 {
   nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp);
   if (NS_FAILED(rv)) {
     if (!::JS_IsExceptionPending(cx)) {
       nsDOMClassInfo::ThrowJSException(cx, rv);
     }
     return JS_FALSE;
   }
 
   return JS_TRUE;
 }
 
 static JSBool
-LocationSetterUnwrapper(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
+LocationSetterUnwrapper(JSContext *cx, JSHandleObject obj_, JSHandleId id, JSBool strict,
                         jsval *vp)
 {
+  JS::RootedVarObject obj(cx, obj_);
+
   JSObject *wrapped = XPCWrapper::UnsafeUnwrapSecurityWrapper(obj);
   if (wrapped) {
     obj = wrapped;
   }
 
   return LocationSetter<nsIDOMWindow>(cx, obj, id, strict, vp);
 }
 
 NS_IMETHODIMP
 nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                       JSObject *obj, jsid id, PRUint32 flags,
+                       JSObject *obj_, jsid id_, PRUint32 flags,
                        JSObject **objp, bool *_retval)
 {
+  JS::RootedVarObject obj(cx, obj_);
+  JS::RootedVarId id(cx, id_);
+
   nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
 
   if (!JSID_IS_STRING(id)) {
     if (JSID_IS_INT(id) && JSID_TO_INT(id) >= 0 && !(flags & JSRESOLVE_ASSIGNING)) {
       // If we're resolving a numeric property, treat that as if
       // window.frames[n] is resolved (since window.frames ===
       // window), if window.frames[n] is a child frame, define a
       // property for this index.
@@ -7032,29 +7057,29 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
 
     return NS_OK;
   }
 
   if (!(flags & JSRESOLVE_ASSIGNING)) {
     // We want this code to be before the child frame lookup code
     // below so that a child frame named 'constructor' doesn't
     // shadow the window's constructor property.
-    if (id == sConstructor_id) {
+    if (sConstructor_id == id) {
       return ResolveConstructor(cx, obj, objp);
     }
   }
 </