merge m-c to fx-team
authorTim Taubert <tim.taubert@gmx.de>
Sat, 30 Jul 2011 22:31:04 +0200
changeset 74322 499ac3d7582b7ddca5fed1ea3148fad6ae293c21
parent 74321 e2e7b2275adedd033a0e2dd677002e402529994f (current diff)
parent 74316 040446311029ece2ace17f12210364f400ee55a7 (diff)
child 74323 da7801acfbdb5babfbcde6c5ef967ff5731f2d45
child 74437 30e5fe8a62c2a9f31c334ccdf3faed7db19f636f
push id235
push userbzbarsky@mozilla.com
push dateTue, 27 Sep 2011 17:13:04 +0000
treeherdermozilla-beta@2d1e082d176a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge m-c to fx-team
content/base/test/file_bug391728.html
content/base/test/file_bug391728_2.html
content/base/test/test_bug391728.html
testing/sisyphus/bin/appinfo.js
testing/sisyphus/bin/build.sh
testing/sisyphus/bin/builder.sh
testing/sisyphus/bin/buildinfo.html
testing/sisyphus/bin/check-spider.sh
testing/sisyphus/bin/checkout.sh
testing/sisyphus/bin/clean.sh
testing/sisyphus/bin/clobber.sh
testing/sisyphus/bin/combo.sh
testing/sisyphus/bin/create-directory.sh
testing/sisyphus/bin/create-profile.sh
testing/sisyphus/bin/dateparse.pl
testing/sisyphus/bin/download.sh
testing/sisyphus/bin/each-to-html.pl
testing/sisyphus/bin/edit-talkback.pl
testing/sisyphus/bin/edit-talkback.sh
testing/sisyphus/bin/firefox.diff
testing/sisyphus/bin/get-build-info.html
testing/sisyphus/bin/get-extension-uuid.pl
testing/sisyphus/bin/include.mk
testing/sisyphus/bin/install-build.sh
testing/sisyphus/bin/install-extensions-1.html
testing/sisyphus/bin/install-extensions.sh
testing/sisyphus/bin/install-plugins.sh
testing/sisyphus/bin/library.sh
testing/sisyphus/bin/master.sed
testing/sisyphus/bin/memory.pl
testing/sisyphus/bin/mips.pl
testing/sisyphus/bin/quit.js
testing/sisyphus/bin/run-mozilla.diff
testing/sisyphus/bin/sayvars.sh
testing/sisyphus/bin/set-build-env.sh
testing/sisyphus/bin/start-spider.html
testing/sisyphus/bin/test-setup.sh
testing/sisyphus/bin/tester.sh
testing/sisyphus/bin/timed_run.py
testing/sisyphus/bin/uninstall-build.sh
testing/sisyphus/bin/userhook-checkspider.js
testing/sisyphus/data/firefox,1.8.0,debug.data
testing/sisyphus/data/firefox,1.8.0,opt.data
testing/sisyphus/data/firefox,1.8.0-test,debug.data
testing/sisyphus/data/firefox,1.8.0-test,opt.data
testing/sisyphus/data/firefox,1.8.0-too-much-gc,debug.data
testing/sisyphus/data/firefox,1.8.1,debug.data
testing/sisyphus/data/firefox,1.8.1,opt.data
testing/sisyphus/data/firefox,1.8.1-test,debug.data
testing/sisyphus/data/firefox,1.8.1-test,opt.data
testing/sisyphus/data/firefox,1.8.1-too-much-gc,debug.data
testing/sisyphus/data/firefox,1.9.0,debug.data
testing/sisyphus/data/firefox,1.9.0,nightly-darwin.data
testing/sisyphus/data/firefox,1.9.0,nightly-linux.data
testing/sisyphus/data/firefox,1.9.0,nightly-nt.data
testing/sisyphus/data/firefox,1.9.0,opt.data
testing/sisyphus/data/firefox,1.9.0-gcov,debug.data
testing/sisyphus/data/firefox,1.9.0-gcov,opt.data
testing/sisyphus/data/firefox,1.9.0-jprof,debug.data
testing/sisyphus/data/firefox,1.9.0-jprof,opt.data
testing/sisyphus/data/firefox,1.9.0-test,debug.data
testing/sisyphus/data/firefox,1.9.0-test,opt.data
testing/sisyphus/data/firefox,1.9.0-too-much-gc,debug.data
testing/sisyphus/data/firefox,1.9.1,debug.data
testing/sisyphus/data/firefox,1.9.1,nightly-darwin.data
testing/sisyphus/data/firefox,1.9.1,nightly-linux.data
testing/sisyphus/data/firefox,1.9.1,nightly-nt.data
testing/sisyphus/data/firefox,1.9.1,opt.data
testing/sisyphus/data/firefox,1.9.1-jprof,debug.data
testing/sisyphus/data/firefox,1.9.1-jprof,opt.data
testing/sisyphus/data/firefox,1.9.1-test,debug.data
testing/sisyphus/data/firefox,1.9.1-test,opt.data
testing/sisyphus/data/firefox,1.9.1-too-much-gc,debug.data
testing/sisyphus/data/firefox,1.9.2,debug.data
testing/sisyphus/data/firefox,1.9.2,nightly-darwin.data
testing/sisyphus/data/firefox,1.9.2,nightly-linux.data
testing/sisyphus/data/firefox,1.9.2,nightly-nt.data
testing/sisyphus/data/firefox,1.9.2,opt.data
testing/sisyphus/data/firefox,1.9.2-test,debug.data
testing/sisyphus/data/firefox,1.9.2-test,opt.data
testing/sisyphus/data/firefox,1.9.3,nightly-darwin.data
testing/sisyphus/data/firefox,1.9.3,nightly-linux.data
testing/sisyphus/data/firefox,1.9.3,nightly-nt.data
testing/sisyphus/data/firefox,1.9.3-tracemonkey,debug.data
testing/sisyphus/data/firefox,1.9.3-tracemonkey,opt.data
testing/sisyphus/data/firefox,1.9.3-tracemonkey-test,debug.data
testing/sisyphus/data/firefox,1.9.3-tracemonkey-test,opt.data
testing/sisyphus/data/js,1.8.0,debug.data
testing/sisyphus/data/js,1.8.0,opt.data
testing/sisyphus/data/js,1.8.0-test,debug.data
testing/sisyphus/data/js,1.8.0-test,opt.data
testing/sisyphus/data/js,1.8.1,debug.data
testing/sisyphus/data/js,1.8.1,opt.data
testing/sisyphus/data/js,1.8.1-test,debug.data
testing/sisyphus/data/js,1.8.1-test,opt.data
testing/sisyphus/data/js,1.8.1-too-much-gc,debug.data
testing/sisyphus/data/js,1.9.0,debug.data
testing/sisyphus/data/js,1.9.0,opt.data
testing/sisyphus/data/js,1.9.0-gcov,debug.data
testing/sisyphus/data/js,1.9.0-gcov,opt.data
testing/sisyphus/data/js,1.9.0-test,debug.data
testing/sisyphus/data/js,1.9.0-test,opt.data
testing/sisyphus/data/js,1.9.0-too-much-gc,debug.data
testing/sisyphus/data/js,1.9.1,debug.data
testing/sisyphus/data/js,1.9.1,opt.data
testing/sisyphus/data/js,1.9.1-test,debug.data
testing/sisyphus/data/js,1.9.1-test,opt.data
testing/sisyphus/data/js,1.9.1-too-much-gc,debug.data
testing/sisyphus/data/js,1.9.2,debug.data
testing/sisyphus/data/js,1.9.2,opt.data
testing/sisyphus/data/js,1.9.2-narcissus,debug.data
testing/sisyphus/data/js,1.9.2-narcissus,opt.data
testing/sisyphus/data/js,1.9.2-test,debug.data
testing/sisyphus/data/js,1.9.2-test,opt.data
testing/sisyphus/data/js,1.9.3,debug.data
testing/sisyphus/data/js,1.9.3,opt.data
testing/sisyphus/data/js,1.9.3-narcissus,debug.data
testing/sisyphus/data/js,1.9.3-narcissus,opt.data
testing/sisyphus/data/js,1.9.3-test,debug.data
testing/sisyphus/data/js,1.9.3-test,opt.data
testing/sisyphus/data/js,1.9.3-tracemonkey,debug.data
testing/sisyphus/data/js,1.9.3-tracemonkey,opt.data
testing/sisyphus/data/js,1.9.3-tracemonkey-test,debug.data
testing/sisyphus/data/js,1.9.3-tracemonkey-test,opt.data
testing/sisyphus/prefs/mail-user.js
testing/sisyphus/prefs/public-user.js
testing/sisyphus/prefs/test-user.js
testing/sisyphus/talkback/linux/Talkback.ini
testing/sisyphus/talkback/mac/Talkback.ini
testing/sisyphus/talkback/win32/Talkback.ini
testing/sisyphus/tests/mozilla.org/download-page/collect-urls-userhook.js
testing/sisyphus/tests/mozilla.org/download-page/test.sh
testing/sisyphus/tests/mozilla.org/download-page/userhook-ftp.js
testing/sisyphus/tests/mozilla.org/download-page/userhook.js
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -821,31 +821,30 @@ getAttributesCB(AtkObject *aAtkObj)
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
 
     return accWrap ? GetAttributeSet(accWrap) : nsnull;
 }
 
 AtkObject *
 getParentCB(AtkObject *aAtkObj)
 {
-    if (!aAtkObj->accessible_parent) {
-        nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
-        if (!accWrap) {
-            return nsnull;
-        }
+  if (!aAtkObj->accessible_parent) {
+    nsAccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
+    if (!accWrap)
+      return nsnull;
 
-        nsAccessible* accParent = accWrap->GetParent();
-        if (!accParent)
-            return nsnull;
+    nsAccessible* accParent = accWrap->Parent();
+    if (!accParent)
+      return nsnull;
 
-        AtkObject *parent = nsAccessibleWrap::GetAtkObject(accParent);
-        if (parent)
-            atk_object_set_parent(aAtkObj, parent);
-    }
-    return aAtkObj->accessible_parent;
+    AtkObject* parent = nsAccessibleWrap::GetAtkObject(accParent);
+    if (parent)
+      atk_object_set_parent(aAtkObj, parent);
+  }
+  return aAtkObj->accessible_parent;
 }
 
 gint
 getChildCountCB(AtkObject *aAtkObj)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
     if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
         return 0;
@@ -888,20 +887,19 @@ getIndexInParentCB(AtkObject *aAtkObj)
 {
     // We don't use nsIAccessible::GetIndexInParent() because
     // for ATK we don't want to include text leaf nodes as children
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
     if (!accWrap) {
         return -1;
     }
 
-    nsAccessible *parent = accWrap->GetParent();
-    if (!parent) {
+    nsAccessible* parent = accWrap->Parent();
+    if (!parent)
         return -1; // No parent
-    }
 
     return parent->GetIndexOfEmbeddedChild(accWrap);
 }
 
 static void
 TranslateStates(PRUint64 aState, AtkStateSet* aStateSet)
 {
 
--- a/accessible/src/atk/nsMaiInterfaceAction.cpp
+++ b/accessible/src/atk/nsMaiInterfaceAction.cpp
@@ -118,17 +118,17 @@ getKeyBindingCB(AtkAction *aAction, gint
   // Return all key bindings including access key and keyboard shortcut.
   nsAutoString keyBindingsStr;
 
   // Get access key.
   KeyBinding keyBinding = acc->AccessKey();
   if (!keyBinding.IsEmpty()) {
     keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
 
-    nsAccessible* parent = acc->GetParent();
+    nsAccessible* parent = acc->Parent();
     PRUint32 role = parent ? parent->Role() : 0;
     if (role == nsIAccessibleRole::ROLE_PARENT_MENUITEM ||
         role == nsIAccessibleRole::ROLE_MENUITEM ||
         role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM ||
         role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM) {
       // It is submenu, expose keyboard shortcuts from menu hierarchy like
       // "s;<Alt>f:s"
       nsAutoString keysInHierarchyStr = keyBindingsStr;
@@ -136,17 +136,17 @@ getKeyBindingCB(AtkAction *aAction, gint
         KeyBinding parentKeyBinding = parent->AccessKey();
         if (!parentKeyBinding.IsEmpty()) {
           nsAutoString str;
           parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
           str.Append(':');
 
           keysInHierarchyStr.Insert(str, 0);
         }
-      } while ((parent = parent->GetParent()) &&
+      } while ((parent = parent->Parent()) &&
                parent->Role() != nsIAccessibleRole::ROLE_MENUBAR);
 
       keyBindingsStr.Append(';');
       keyBindingsStr.Append(keysInHierarchyStr);
     }
   } else {
     // No access key, add ';' to point this.
     keyBindingsStr.Append(';');
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -307,17 +307,17 @@ AccMutationEvent::
 ////////////////////////////////////////////////////////////////////////////////
 // AccHideEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 AccHideEvent::
   AccHideEvent(nsAccessible* aTarget, nsINode* aTargetNode) :
   AccMutationEvent(::nsIAccessibleEvent::EVENT_HIDE, aTarget, aTargetNode)
 {
-  mParent = mAccessible->GetParent();
+  mParent = mAccessible->Parent();
   mNextSibling = mAccessible->NextSibling();
   mPrevSibling = mAccessible->PrevSibling();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccShowEvent
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/base/AccGroupInfo.cpp
+++ b/accessible/src/base/AccGroupInfo.cpp
@@ -38,17 +38,17 @@
 #include "AccGroupInfo.h"
 
 #include "States.h"
 
 AccGroupInfo::AccGroupInfo(nsAccessible* aItem, PRUint32 aRole) :
   mPosInSet(0), mSetSize(0), mParent(nsnull)
 {
   MOZ_COUNT_CTOR(AccGroupInfo);
-  nsAccessible* parent = aItem->GetParent();
+  nsAccessible* parent = aItem->Parent();
   if (!parent)
     return;
 
   PRInt32 indexInParent = aItem->IndexInParent();
   PRInt32 level = nsAccUtils::GetARIAOrDefaultLevel(aItem);
 
   // Compute position in set.
   mPosInSet = 1;
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -369,18 +369,18 @@ NotificationController::CoalesceEvents()
 
             // Coalesce text change events for hide events.
             if (tailEvent->mEventRule != AccEvent::eDoNotEmit)
               CoalesceTextChangeEventsFor(tailHideEvent, thisHideEvent);
 
             return;
           }
         } else if (tailEvent->mEventType == nsIAccessibleEvent::EVENT_SHOW) {
-          if (thisEvent->mAccessible->GetParent() ==
-              tailEvent->mAccessible->GetParent()) {
+          if (thisEvent->mAccessible->Parent() ==
+              tailEvent->mAccessible->Parent()) {
             tailEvent->mEventRule = thisEvent->mEventRule;
 
             // Coalesce text change events for show events.
             if (tailEvent->mEventRule != AccEvent::eDoNotEmit) {
               AccShowEvent* tailShowEvent = downcast_accEvent(tailEvent);
               AccShowEvent* thisShowEvent = downcast_accEvent(thisEvent);
               CoalesceTextChangeEventsFor(tailShowEvent, thisShowEvent);
             }
--- a/accessible/src/base/TextUpdater.cpp
+++ b/accessible/src/base/TextUpdater.cpp
@@ -64,21 +64,19 @@ TextUpdater::Run(nsDocAccessible* aDocum
     updater.DoUpdate(aNewText, oldText, skipStart);
   }
 }
 
 void
 TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
                       PRUint32 aSkipStart)
 {
-  nsAccessible* parent = mTextLeaf->GetParent();
-  if (!parent) {
-    NS_ERROR("No parent for text leaf!");
+  nsAccessible* parent = mTextLeaf->Parent();
+  if (!parent)
     return;
-  }
 
   mHyperText = parent->AsHyperText();
   if (!mHyperText) {
     NS_ERROR("Text leaf parent is not hypertext!");
     return;
   }
 
   // Get the text leaf accessible offset and invalidate cached offsets after it.
--- a/accessible/src/base/nsARIAGridAccessible.cpp
+++ b/accessible/src/base/nsARIAGridAccessible.cpp
@@ -825,17 +825,17 @@ nsARIAGridAccessible::SetARIASelected(ns
   }
 
   // If the given accessible is cell that was unselected and its row is selected
   // then remove aria-selected from row and put aria-selected on
   // siblings cells.
   if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
       role == nsIAccessibleRole::ROLE_ROWHEADER ||
       role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
-    nsAccessible *row = aAccessible->GetParent();
+    nsAccessible* row = aAccessible->Parent();
 
     if (row && row->Role() == nsIAccessibleRole::ROLE_ROW &&
         nsAccUtils::IsARIASelected(row)) {
       rv = SetARIASelected(row, PR_FALSE, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
 
       AccIterator cellIter(row, filters::GetCell);
       nsAccessible *cell = nsnull;
@@ -944,21 +944,21 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsARIAGridC
 // nsIAccessibleTableCell
 
 NS_IMETHODIMP
 nsARIAGridCellAccessible::GetTable(nsIAccessibleTable **aTable)
 {
   NS_ENSURE_ARG_POINTER(aTable);
   *aTable = nsnull;
 
-  nsAccessible* thisRow = GetParent();
+  nsAccessible* thisRow = Parent();
   if (!thisRow || thisRow->Role() != nsIAccessibleRole::ROLE_ROW)
     return NS_OK;
 
-  nsAccessible* table = thisRow->GetParent();
+  nsAccessible* table = thisRow->Parent();
   if (!table)
     return NS_OK;
 
   PRUint32 tableRole = table->Role();
   if (tableRole != nsIAccessibleRole::ROLE_TABLE &&
       tableRole != nsIAccessibleRole::ROLE_TREE_TABLE)
     return NS_OK;
 
@@ -970,17 +970,17 @@ NS_IMETHODIMP
 nsARIAGridCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccessible* row = GetParent();
+  nsAccessible* row = Parent();
   if (!row)
     return NS_OK;
 
   *aColumnIndex = 0;
 
   PRInt32 indexInRow = IndexInParent();
   for (PRInt32 idx = 0; idx < indexInRow; idx++) {
     nsAccessible* cell = row->GetChildAt(idx);
@@ -998,21 +998,21 @@ NS_IMETHODIMP
 nsARIAGridCellAccessible::GetRowIndex(PRInt32 *aRowIndex)
 {
   NS_ENSURE_ARG_POINTER(aRowIndex);
   *aRowIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccessible* row = GetParent();
+  nsAccessible* row = Parent();
   if (!row)
     return NS_OK;
 
-  nsAccessible* table = row->GetParent();
+  nsAccessible* table = row->Parent();
   if (!table)
     return NS_OK;
 
   *aRowIndex = 0;
 
   PRInt32 indexInTable = row->IndexInParent();
   for (PRInt32 idx = 0; idx < indexInTable; idx++) {
     row = table->GetChildAt(idx);
@@ -1091,17 +1091,17 @@ NS_IMETHODIMP
 nsARIAGridCellAccessible::IsSelected(PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccessible *row = GetParent();
+  nsAccessible* row = Parent();
   if (!row || row->Role() != nsIAccessibleRole::ROLE_ROW)
     return NS_OK;
 
   if (!nsAccUtils::IsARIASelected(row) && !nsAccUtils::IsARIASelected(this))
     return NS_OK;
 
   *aIsSelected = PR_TRUE;
   return NS_OK;
@@ -1115,17 +1115,17 @@ nsARIAGridCellAccessible::ApplyARIAState
 {
   nsHyperTextAccessibleWrap::ApplyARIAState(aState);
 
   // Return if the gridcell has aria-selected="true".
   if (*aState & states::SELECTED)
     return;
 
   // Check aria-selected="true" on the row.
-  nsAccessible* row = GetParent();
+  nsAccessible* row = Parent();
   if (!row || row->Role() != nsIAccessibleRole::ROLE_ROW)
     return;
 
   nsIContent *rowContent = row->GetContent();
   if (nsAccUtils::HasDefinedARIAToken(rowContent,
                                       nsAccessibilityAtoms::aria_selected) &&
       !rowContent->AttrValueIs(kNameSpaceID_None,
                                nsAccessibilityAtoms::aria_selected,
@@ -1139,17 +1139,17 @@ nsARIAGridCellAccessible::GetAttributesI
   if (IsDefunct())
     return NS_ERROR_FAILURE;
   
   nsresult rv = nsHyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Expose "table-cell-index" attribute.
 
-  nsAccessible* thisRow = GetParent();
+  nsAccessible* thisRow = Parent();
   if (!thisRow || thisRow->Role() != nsIAccessibleRole::ROLE_ROW)
     return NS_OK;
 
   PRInt32 colIdx = 0, colCount = 0;
   PRInt32 childCount = thisRow->GetChildCount();
   for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
     nsAccessible *child = thisRow->GetChildAt(childIdx);
     if (child == this)
@@ -1157,17 +1157,17 @@ nsARIAGridCellAccessible::GetAttributesI
 
     PRUint32 role = child->Role();
     if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
         role == nsIAccessibleRole::ROLE_ROWHEADER ||
         role == nsIAccessibleRole::ROLE_COLUMNHEADER)
       colCount++;
   }
 
-  nsAccessible* table = thisRow->GetParent();
+  nsAccessible* table = thisRow->Parent();
   if (!table)
     return NS_OK;
 
   PRUint32 tableRole = table->Role();
   if (tableRole != nsIAccessibleRole::ROLE_TABLE &&
       tableRole != nsIAccessibleRole::ROLE_TREE_TABLE)
     return NS_OK;
 
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -103,17 +103,17 @@ PRInt32
 nsAccUtils::GetDefaultLevel(nsAccessible *aAccessible)
 {
   PRUint32 role = aAccessible->Role();
 
   if (role == nsIAccessibleRole::ROLE_OUTLINEITEM)
     return 1;
 
   if (role == nsIAccessibleRole::ROLE_ROW) {
-    nsAccessible *parent = aAccessible->GetParent();
+    nsAccessible* parent = aAccessible->Parent();
     if (parent && parent->Role() == nsIAccessibleRole::ROLE_TREE_TABLE) {
       // It is a row inside flatten treegrid. Group level is always 1 until it
       // is overriden by aria-level attribute.
       return 1;
     }
   }
 
   return 0;
@@ -333,17 +333,17 @@ nsAccUtils::HasDefinedARIAToken(nsIConte
   return PR_TRUE;
 }
 
 nsAccessible *
 nsAccUtils::GetAncestorWithRole(nsAccessible *aDescendant, PRUint32 aRole)
 {
   nsAccessible *document = aDescendant->GetDocAccessible();
   nsAccessible *parent = aDescendant;
-  while ((parent = parent->GetParent())) {
+  while ((parent = parent->Parent())) {
     PRUint32 testRole = parent->Role();
     if (testRole == aRole)
       return parent;
 
     if (parent == document)
       break;
   }
   return nsnull;
@@ -354,17 +354,17 @@ nsAccUtils::GetSelectableContainer(nsAcc
 {
   if (!aAccessible)
     return nsnull;
 
   if (!(aState & states::SELECTABLE))
     return nsnull;
 
   nsAccessible* parent = aAccessible;
-  while ((parent = parent->GetParent()) && !parent->IsSelect()) {
+  while ((parent = parent->Parent()) && !parent->IsSelect()) {
     if (Role(parent) == nsIAccessibleRole::ROLE_PANE)
       return nsnull;
   }
   return parent;
 }
 
 nsAccessible*
 nsAccUtils::GetMultiSelectableContainer(nsINode* aNode)
@@ -415,17 +415,17 @@ nsAccUtils::GetTextAccessibleFromSelecti
     return nsnull;
   }
 
   do {
     nsHyperTextAccessible* textAcc = accessible->AsHyperText();
     if (textAcc)
       return textAcc;
 
-  } while (accessible = accessible->GetParent());
+  } while (accessible = accessible->Parent());
 
   NS_NOTREACHED("We must reach document accessible implementing nsIAccessibleText!");
   return nsnull;
 }
 
 nsresult
 nsAccUtils::ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
                                   PRUint32 aCoordinateType,
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -416,18 +416,20 @@ nsAccessible::KeyboardShortcut() const
 {
   return KeyBinding();
 }
 
 NS_IMETHODIMP
 nsAccessible::GetParent(nsIAccessible **aParent)
 {
   NS_ENSURE_ARG_POINTER(aParent);
-
-  NS_IF_ADDREF(*aParent = GetParent());
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  NS_IF_ADDREF(*aParent = Parent());
   return *aParent ? NS_OK : NS_ERROR_FAILURE;
 }
 
   /* readonly attribute nsIAccessible nextSibling; */
 NS_IMETHODIMP
 nsAccessible::GetNextSibling(nsIAccessible **aNextSibling) 
 {
   NS_ENSURE_ARG_POINTER(aNextSibling);
@@ -724,17 +726,17 @@ NS_IMETHODIMP
 nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) 
 { 
   nsAccessible *focusedChild = nsnull;
   if (gLastFocusedNode == mContent) {
     focusedChild = this;
   }
   else if (gLastFocusedNode) {
     focusedChild = GetAccService()->GetAccessible(gLastFocusedNode);
-    if (focusedChild && focusedChild->GetParent() != this)
+    if (focusedChild && focusedChild->Parent() != this)
       focusedChild = nsnull;
   }
 
   NS_IF_ADDREF(*aFocusedChild = focusedChild);
   return NS_OK;
 }
 
 // nsAccessible::ChildAtPoint()
@@ -814,17 +816,17 @@ nsAccessible::ChildAtPoint(PRInt32 aX, P
     // return |this| as the answer.
     return accessible;
   }
 
   // Since DOM node of obtained accessible may be out of flow then we should
   // ensure obtained accessible is a child of this accessible.
   nsAccessible* child = accessible;
   while (true) {
-    nsAccessible* parent = child->GetParent();
+    nsAccessible* parent = child->Parent();
     if (!parent) {
       // Reached the top of the hierarchy. These bounds were inside an
       // accessible that is not a descendant of this one.
       return fallbackAnswer;
     }
 
     if (parent == this)
       return aWhichChild == eDeepestChild ? accessible : child;
@@ -2135,19 +2137,18 @@ nsAccessible::GetRelationByType(PRUint32
       // ROLE_WINDOW accessible which will prevent us from going up further
       // (because it is system generated and has no idea about the hierarchy
       // above it).
       nsIFrame *frame = GetFrame();
       if (frame) {
         nsIView *view = frame->GetViewExternal();
         if (view) {
           nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
-          if (scrollFrame || view->GetWidget() || !frame->GetParent()) {
-            return nsRelUtils::AddTarget(aRelationType, aRelation, GetParent());
-          }
+          if (scrollFrame || view->GetWidget() || !frame->GetParent())
+            return nsRelUtils::AddTarget(aRelationType, aRelation, Parent());
         }
       }
 
       return rv;
     }
 
   case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
     {
@@ -2610,17 +2611,17 @@ nsAccessible::AppendTextTo(nsAString& aT
     return;
 
   nsIFrame *frame = GetFrame();
   if (!frame)
     return;
 
   if (frame->GetType() == nsAccessibilityAtoms::brFrame) {
     aText += kForcedNewLineChar;
-  } else if (nsAccUtils::MustPrune(GetParent())) {
+  } else if (nsAccUtils::MustPrune(Parent())) {
     // Expose the embedded object accessible as imaginary embedded object
     // character if its parent hypertext accessible doesn't expose children to
     // AT.
     aText += kImaginaryEmbeddedObjectChar;
   } else {
     aText += kEmbeddedObjectChar;
   }
 }
@@ -3252,70 +3253,68 @@ nsAccessible::GetPositionAndSizeInternal
   }
 }
 
 PRInt32
 nsAccessible::GetLevelInternal()
 {
   PRInt32 level = nsAccUtils::GetDefaultLevel(this);
 
+  if (!IsBoundToParent())
+    return level;
+
   PRUint32 role = Role();
-  nsAccessible* parent = GetParent();
-
   if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
     // Always expose 'level' attribute for 'outlineitem' accessible. The number
     // of nested 'grouping' accessibles containing 'outlineitem' accessible is
     // its level.
     level = 1;
 
-    while (parent) {
+    nsAccessible* parent = this;
+    while ((parent = parent->Parent())) {
       PRUint32 parentRole = parent->Role();
 
       if (parentRole == nsIAccessibleRole::ROLE_OUTLINE)
         break;
       if (parentRole == nsIAccessibleRole::ROLE_GROUPING)
         ++ level;
 
-      parent = parent->GetParent();
     }
 
   } else if (role == nsIAccessibleRole::ROLE_LISTITEM) {
     // Expose 'level' attribute on nested lists. We assume nested list is a last
     // child of listitem of parent list. We don't handle the case when nested
     // lists have more complex structure, for example when there are accessibles
     // between parent listitem and nested list.
 
     // Calculate 'level' attribute based on number of parent listitems.
     level = 0;
-
-    while (parent) {
+    nsAccessible* parent = this;
+    while ((parent = parent->Parent())) {
       PRUint32 parentRole = parent->Role();
 
       if (parentRole == nsIAccessibleRole::ROLE_LISTITEM)
         ++ level;
       else if (parentRole != nsIAccessibleRole::ROLE_LIST)
         break;
 
-      parent = parent->GetParent();
     }
 
     if (level == 0) {
       // If this listitem is on top of nested lists then expose 'level'
       // attribute.
-      nsAccessible* parent(GetParent());
+      parent = Parent();
       PRInt32 siblingCount = parent->GetChildCount();
       for (PRInt32 siblingIdx = 0; siblingIdx < siblingCount; siblingIdx++) {
         nsAccessible* sibling = parent->GetChildAt(siblingIdx);
 
-        nsCOMPtr<nsIAccessible> siblingChild;
-        sibling->GetLastChild(getter_AddRefs(siblingChild));
-        if (nsAccUtils::Role(siblingChild) == nsIAccessibleRole::ROLE_LIST) {
-          level = 1;
-          break;
-        }
+        nsAccessible* siblingChild = sibling->LastChild();
+        if (siblingChild &&
+            siblingChild->Role() == nsIAccessibleRole::ROLE_LIST)
+          return 1;
       }
     } else {
       ++ level; // level is 1-index based
     }
   }
 
   return level;
 }
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -274,17 +274,17 @@ public:
   virtual PRBool RemoveChild(nsAccessible* aChild);
 
   //////////////////////////////////////////////////////////////////////////////
   // Accessible tree traverse methods
 
   /**
    * Return parent accessible.
    */
-  nsAccessible* GetParent() const { return mParent; }
+  nsAccessible* Parent() const { return mParent; }
 
   /**
    * Return child accessible at the given index.
    */
   virtual nsAccessible* GetChildAt(PRUint32 aIndex);
 
   /**
    * Return child accessible count.
@@ -302,22 +302,30 @@ public:
   virtual PRInt32 IndexInParent() const;
 
   /**
    * Return true if accessible has children;
    */
   PRBool HasChildren() { return !!GetChildAt(0); }
 
   /**
-   * Return next/previous sibling of the accessible.
+   * Return first/last/next/previous sibling of the accessible.
    */
   inline nsAccessible* NextSibling() const
     {  return GetSiblingAtOffset(1); }
   inline nsAccessible* PrevSibling() const
     { return GetSiblingAtOffset(-1); }
+  inline nsAccessible* FirstChild()
+    { return GetChildCount() != 0 ? GetChildAt(0) : nsnull; }
+  inline nsAccessible* LastChild()
+  {
+    PRUint32 childCount = GetChildCount();
+    return childCount != 0 ? GetChildAt(childCount - 1) : nsnull;
+  }
+
 
   /**
    * Return embedded accessible children count.
    */
   PRInt32 GetEmbeddedChildCount();
 
   /**
    * Return embedded accessible child at the given index.
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -229,18 +229,18 @@ nsLinkableAccessible::BindToParent(nsAcc
     mIsOnclick = PR_TRUE;
     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->GetParent()) && !walkUpAcc->IsDoc()) {
-    if (walkUpAcc && walkUpAcc->Role() == nsIAccessibleRole::ROLE_LINK &&
+  while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) {
+    if (walkUpAcc->Role() == nsIAccessibleRole::ROLE_LINK &&
         walkUpAcc->State() & states::LINKED) {
       mIsLink = PR_TRUE;
       mActionAcc = walkUpAcc;
       return;
     }
 
     if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
       mActionAcc = walkUpAcc;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -576,17 +576,17 @@ nsDocAccessible::GetAccessible(nsINode* 
     accessible = const_cast<nsDocAccessible*>(this);
   }
 
 #ifdef DEBUG
   // All cached accessible nodes should be in the parent
   // It will assert if not all the children were created
   // when they were first cached, and no invalidation
   // ever corrected parent accessible's child cache.
-  nsAccessible* parent(accessible->GetParent());
+  nsAccessible* parent = accessible->Parent();
   if (parent)
     parent->TestChildCache(accessible);
 #endif
 
   return accessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1482,18 +1482,18 @@ nsDocAccessible::NotifyOfInitialUpdate()
   CacheChildrenInSubtree(this);
 
   // Fire reorder event after the document tree is constructed. Note, since
   // this reorder event is processed by parent document then events targeted to
   // this document may be fired prior to this reorder event. If this is
   // a problem then consider to keep event processing per tab document.
   if (!IsRoot()) {
     nsRefPtr<AccEvent> reorderEvent =
-      new AccEvent(nsIAccessibleEvent::EVENT_REORDER, GetParent(),
-                   eAutoDetect, AccEvent::eCoalesceFromSameSubtree);
+      new AccEvent(nsIAccessibleEvent::EVENT_REORDER, Parent(), eAutoDetect,
+                   AccEvent::eCoalesceFromSameSubtree);
     ParentDocument()->FireDelayedAccessibleEvent(reorderEvent);
   }
 }
 
 void
 nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
                                     nsIAtom* aRelAttr)
 {
@@ -1812,17 +1812,17 @@ nsDocAccessible::UpdateTree(nsAccessible
                                    ancestor->GetNode());
         break;
       }
 
       // Don't climb above this document.
       if (ancestor == this)
         break;
 
-      ancestor = ancestor->GetParent();
+      ancestor = ancestor->Parent();
     }
   }
 
   // Fire value change event.
   if (aContainer->Role() == nsIAccessibleRole::ROLE_ENTRY) {
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
                                aContainer->GetNode());
   }
@@ -1897,17 +1897,17 @@ nsDocAccessible::UpdateTreeInternal(nsAc
       FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
                                  node, AccEvent::eCoalesceFromSameDocument);
     }
   } else {
     // Update the tree for content removal.
     // The accessible parent may differ from container accessible if
     // the parent doesn't have own DOM node like list accessible for HTML
     // selects.
-    nsAccessible* parent = aChild->GetParent();
+    nsAccessible* parent = aChild->Parent();
     NS_ASSERTION(parent, "No accessible parent?!");
     if (parent)
       parent->RemoveChild(aChild);
 
     UncacheChildrenInSubtree(aChild);
   }
 
   return updateFlags;
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -694,24 +694,24 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
         fireFocus = PR_TRUE;
       // QI failed for nsMenuFrame means it's not on menu bar
       if (menuFrame && menuFrame->IsOnMenuBar() &&
                        !menuFrame->IsOnActiveMenuBar()) {
         // It is a top level menuitem. Only fire a focus event when the menu bar
         // is active.
         return;
       } else {
-        nsAccessible *containerAccessible = accessible->GetParent();
-        if (!containerAccessible)
+        nsAccessible* container = accessible->Parent();
+        if (!container)
           return;
         // It is not top level menuitem
         // Only fire focus event if it is not inside collapsed popup
         // and not a listitem of a combo box
-        if (containerAccessible->State() & states::COLLAPSED) {
-          nsAccessible *containerParent = containerAccessible->GetParent();
+        if (container->State() & states::COLLAPSED) {
+          nsAccessible* containerParent = container->Parent();
           if (!containerParent)
             return;
           if (containerParent->Role() != nsIAccessibleRole::ROLE_COMBOBOX) {
             return;
           }
         }
       }
     }
@@ -791,25 +791,25 @@ nsRootAccessible::GetContentDocShell(nsI
     // Hidden documents don't have accessibles (like SeaMonkey's sidebar),
     // they are of no interest for a11y.
     if (!accDoc)
       return nsnull;
 
     // If ancestor chain of accessibles is not completely visible,
     // don't use this one. This happens for example if it's inside
     // a background tab (tabbed browsing)
-    nsAccessible *parent = accDoc->GetParent();
+    nsAccessible* parent = accDoc->Parent();
     while (parent) {
       if (parent->State() & states::INVISIBLE)
         return nsnull;
 
       if (parent == this)
         break; // Don't check past original root accessible we started with
 
-      parent = parent->GetParent();
+      parent = parent->Parent();
     }
 
     NS_ADDREF(aStart);
     return aStart;
   }
   nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aStart));
   if (treeNode) {
     PRInt32 subDocuments;
@@ -873,17 +873,17 @@ nsRootAccessible::HandlePopupShownEvent(
     // AT's expect to get an EVENT_SHOW for the tooltip. 
     // In event callback the tooltip's accessible will be ready.
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SHOW, aAccessible);
     return;
   }
 
   if (role == nsIAccessibleRole::ROLE_COMBOBOX_LIST) {
     // Fire expanded state change event for comboboxes and autocompeletes.
-    nsAccessible* combobox = aAccessible->GetParent();
+    nsAccessible* combobox = aAccessible->Parent();
     if (!combobox)
       return;
 
     PRUint32 comboboxRole = combobox->Role();
     if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
         comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
       nsRefPtr<AccEvent> event =
         new AccStateChangeEvent(combobox, states::EXPANDED, PR_TRUE);
@@ -909,17 +909,17 @@ nsRootAccessible::HandlePopupHidingEvent
     FireCurrentFocusEvent();
   }
 
   // Fire expanded state change event for comboboxes and autocompletes.
   if (!aAccessible ||
       aAccessible->Role() != nsIAccessibleRole::ROLE_COMBOBOX_LIST)
     return;
 
-  nsAccessible* combobox = aAccessible->GetParent();
+  nsAccessible* combobox = aAccessible->Parent();
   if (!combobox)
     return;
 
   PRUint32 comboboxRole = combobox->Role();
   if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
       comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
     nsRefPtr<AccEvent> event =
       new AccStateChangeEvent(combobox, states::EXPANDED, PR_FALSE);
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -402,18 +402,19 @@ nsHTMLTextFieldAccessible::GetNameIntern
 
   if (mContent->GetBindingParent())
   {
     // XXX: bug 459640
     // There's a binding parent.
     // This means we're part of another control, so use parent accessible for name.
     // This ensures that a textbox inside of a XUL widget gets
     // an accessible name.
-    nsAccessible* parent = GetParent();
-    parent->GetName(aName);
+    nsAccessible* parent = Parent();
+    if (parent)
+      parent->GetName(aName);
   }
 
   if (!aName.IsEmpty())
     return NS_OK;
 
   // text inputs and textareas might have useful placeholder text
   mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::placeholder, aName);
 
@@ -447,17 +448,17 @@ nsHTMLTextFieldAccessible::NativeState()
   PRUint64 state = nsHyperTextAccessibleWrap::NativeState();
 
   // can be focusable, focused, protected. readonly, unavailable, selected
   if (mContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
                             nsAccessibilityAtoms::password, eIgnoreCase)) {
     state |= states::PROTECTED;
   }
   else {
-    nsAccessible* parent = GetParent();
+    nsAccessible* parent = Parent();
     if (parent && parent->Role() == nsIAccessibleRole::ROLE_AUTOCOMPLETE)
       state |= states::HASPOPUP;
   }
 
   if (mContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::readonly)) {
     state |= states::READONLY;
   }
 
@@ -645,17 +646,17 @@ nsHTMLLegendAccessible::GetRelationByTyp
                                           nsIAccessibleRelation **aRelation)
 {
   nsresult rv = nsHyperTextAccessibleWrap::
     GetRelationByType(aRelationType, aRelation);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aRelationType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
     // Look for groupbox parent
-    nsAccessible* groupbox = GetParent();
+    nsAccessible* groupbox = Parent();
 
     if (groupbox && groupbox->Role() == nsIAccessibleRole::ROLE_GROUPING) {
       // XXX: if group box exposes more than one relation of the given type
       // then we fail.
       nsCOMPtr<nsIAccessible> testLabelAccessible =
         nsRelUtils::GetRelatedAccessible(groupbox,
                                          nsIAccessibleRelation::RELATION_LABELLED_BY);
 
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -295,17 +295,17 @@ nsHTMLSelectOptionAccessible::NativeStat
       state |= selectState & states::OPAQUE1;
     }
   }
   else {
     // XXX list frames are weird, don't rely on nsAccessible's general
     // visibility implementation unless they get reimplemented in layout
     state &= ~states::OFFSCREEN;
     // <select> is not collapsed: compare bounds to calculate OFFSCREEN
-    nsAccessible* listAcc = GetParent();
+    nsAccessible* listAcc = Parent();
     if (listAcc) {
       PRInt32 optionX, optionY, optionWidth, optionHeight;
       PRInt32 listX, listY, listWidth, listHeight;
       GetBounds(&optionX, &optionY, &optionWidth, &optionHeight);
       listAcc->GetBounds(&listX, &listY, &listWidth, &listHeight);
       if (optionY < listY || optionY + optionHeight > listY + listHeight) {
         state |= states::OFFSCREEN;
       }
@@ -377,18 +377,19 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessib
 
 NS_IMETHODIMP nsHTMLSelectOptionAccessible::DoAction(PRUint8 index)
 {
   if (index == eAction_Select) {   // default action
     nsCOMPtr<nsIDOMHTMLOptionElement> newHTMLOption(do_QueryInterface(mContent));
     if (!newHTMLOption) 
       return NS_ERROR_FAILURE;
     // Clear old selection
-    nsAccessible* parent = GetParent();
-    NS_ASSERTION(parent, "No parent!");
+    nsAccessible* parent = Parent();
+    if (!parent)
+      return NS_OK;
 
     nsCOMPtr<nsIContent> oldHTMLOptionContent =
       GetFocusedOption(parent->GetContent());
     nsCOMPtr<nsIDOMHTMLOptionElement> oldHTMLOption =
       do_QueryInterface(oldHTMLOptionContent);
     if (oldHTMLOption)
       oldHTMLOption->SetSelected(PR_FALSE);
     // Set new selection
@@ -886,17 +887,17 @@ nsHTMLComboboxListAccessible::NativeStat
 /**
   * Gets the bounds for the areaFrame.
   *     Walks the Frame tree and checks for proper frames.
   */
 void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
 {
   *aBoundingFrame = nsnull;
 
-  nsAccessible* comboAcc = GetParent();
+  nsAccessible* comboAcc = Parent();
   if (!comboAcc)
     return;
 
   if (0 == (comboAcc->State() & states::COLLAPSED)) {
     nsHTMLSelectListAccessible::GetBoundsRect(aBounds, aBoundingFrame);
     return;
   }
 
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -261,17 +261,17 @@ nsHTMLTableCellAccessible::IsSelected(PR
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLTableCellAccessible: protected implementation
 
 already_AddRefed<nsIAccessibleTable>
 nsHTMLTableCellAccessible::GetTableAccessible()
 {
   nsAccessible* parent = this;
-  while ((parent = parent->GetParent())) {
+  while ((parent = parent->Parent())) {
     PRUint32 role = parent->Role();
     if (role == nsIAccessibleRole::ROLE_TABLE ||
         role == nsIAccessibleRole::ROLE_TREE_TABLE) {
       nsIAccessibleTable* tableAcc = nsnull;
       CallQueryInterface(parent, &tableAcc);
       return tableAcc;
     }
   }
@@ -1523,18 +1523,19 @@ nsHTMLTableAccessible::IsProbablyForLayo
 NS_IMETHODIMP
 nsHTMLCaptionAccessible::GetRelationByType(PRUint32 aRelationType,
                                            nsIAccessibleRelation **aRelation)
 {
   nsresult rv = nsHyperTextAccessible::GetRelationByType(aRelationType,
                                                          aRelation);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (aRelationType == nsIAccessibleRelation::RELATION_LABEL_FOR)
-    return nsRelUtils::AddTarget(aRelationType, aRelation, GetParent());
+  if (aRelationType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
+      return nsRelUtils::AddTarget(aRelationType, aRelation, Parent());
+  }
 
   return NS_OK;
 }
 
 PRUint32
 nsHTMLCaptionAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_CAPTION;
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -616,19 +616,19 @@ nsHyperTextAccessible::DOMPointToHyperte
       // This <br> is the hacky "bogus node" used when there is no text in a control
       *aHyperTextOffset = 0;
       return nsnull;
     }
     descendantAcc = GetFirstAvailableAccessible(findNode);
   }
 
   // From the descendant, go up and get the immediate child of this hypertext
-  nsAccessible *childAccAtOffset = nsnull;
+  nsAccessible* childAccAtOffset = nsnull;
   while (descendantAcc) {
-    nsAccessible *parentAcc = descendantAcc->GetParent();
+    nsAccessible* parentAcc = descendantAcc->Parent();
     if (parentAcc == this) {
       childAccAtOffset = descendantAcc;
       break;
     }
 
     // This offset no longer applies because the passed-in text object is not a child
     // of the hypertext. This happens when there are nested hypertexts, e.g.
     // <div>abc<h1>def</h1>ghi</div>
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -280,17 +280,17 @@ nsAccessibleWrap::GetUnignoredChildren(n
       // simply add the element, since it's not ignored.
       aChildrenArray.AppendElement(childAcc);
   }
 }
 
 already_AddRefed<nsIAccessible>
 nsAccessibleWrap::GetUnignoredParent()
 {
-  nsAccessibleWrap *parentWrap = static_cast<nsAccessibleWrap*>(GetParent());
+  nsAccessibleWrap* parentWrap = static_cast<nsAccessibleWrap*>(Parent());
   if (!parentWrap)
     return nsnull;
     
   // recursively return the parent, until we find one that is not ignored.
   if (parentWrap->IsIgnored())
     return parentWrap->GetUnignoredParent();
   
   nsIAccessible *outValue = nsnull;
@@ -308,18 +308,18 @@ nsAccessibleWrap::AncestorIsFlat()
   // We don't create a native object if we're child of a "flat" accessible;
   // for example, on OS X buttons shouldn't have any children, because that
   // makes the OS confused. 
   //
   // To maintain a scripting environment where the XPCOM accessible hierarchy
   // look the same on all platforms, we still let the C++ objects be created
   // though.
 
-  nsAccessible* parent(GetParent());
+  nsAccessible* parent = Parent();
   while (parent) {
     if (nsAccUtils::MustPrune(parent))
       return PR_TRUE;
 
-    parent = parent->GetParent();
+    parent = parent->Parent();
   }
   // no parent was flat
   return PR_FALSE;
 }
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -56,19 +56,16 @@
 #include "nsIWinAccessNode.h"
 #include "ISimpleDOMNode.h"
 #include "nsIDOMElement.h"
 #include "nsIContent.h"
 #include "nsAccessNode.h"
 #include "OLEIDL.H"
 #include "OLEACC.H"
 #include <winuser.h>
-#ifndef WINABLEAPI
-#include <winable.h>
-#endif
 #ifdef MOZ_CRASHREPORTER
 #include "nsICrashReporter.h"
 #endif
 
 #include "nsRefPtrHashtable.h"
 
 typedef LRESULT (STDAPICALLTYPE *LPFNNOTIFYWINEVENT)(DWORD event,HWND hwnd,LONG idObjectType,LONG idObject);
 typedef LRESULT (STDAPICALLTYPE *LPFNGETGUITHREADINFO)(DWORD idThread, GUITHREADINFO* pgui);
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -209,17 +209,17 @@ STDMETHODIMP nsAccessibleWrap::get_accPa
       if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
                                                        IID_IAccessible,
                                                        (void**)ppdispParent))) {
         return S_OK;
       }
     }
   }
 
-  nsAccessible* xpParentAcc = GetParent();
+  nsAccessible* xpParentAcc = Parent();
   if (!xpParentAcc) {
     if (IsApplication())
       return S_OK;
 
     NS_ERROR("No parent accessible. Should we really assert here?");
     return E_UNEXPECTED;
   }
 
@@ -369,17 +369,17 @@ STDMETHODIMP nsAccessibleWrap::get_accRo
   PRUint32 msaaRole = gWindowsRoleMap[xpRole].msaaRole;
   NS_ASSERTION(gWindowsRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY].msaaRole == ROLE_WINDOWS_LAST_ENTRY,
                "MSAA role map skewed");
 
   // Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call the MSAA role
   // a ROLE_OUTLINEITEM for consistency and compatibility.
   // We need this because ARIA has a role of "row" for both grid and treegrid
   if (xpRole == nsIAccessibleRole::ROLE_ROW) {
-    nsAccessible* xpParent = GetParent();
+    nsAccessible* xpParent = Parent();
     if (xpParent && xpParent->Role() == nsIAccessibleRole::ROLE_TREE_TABLE)
       msaaRole = ROLE_SYSTEM_OUTLINEITEM;
   }
   
   // -- Try enumerated role
   if (msaaRole != USE_ROLE_STRING) {
     pvarRole->vt = VT_I4;
     pvarRole->lVal = msaaRole;  // Normal enumerated role
@@ -1155,17 +1155,17 @@ nsAccessibleWrap::role(long *aRole)
                "MSAA role map skewed");
 
   PRUint32 xpRole = Role();
   *aRole = gWindowsRoleMap[xpRole].ia2Role;
 
   // Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call
   // the IA2 role a ROLE_OUTLINEITEM.
   if (xpRole == nsIAccessibleRole::ROLE_ROW) {
-    nsAccessible* xpParent = GetParent();
+    nsAccessible* xpParent = Parent();
     if (xpParent && xpParent->Role() == nsIAccessibleRole::ROLE_TREE_TABLE)
       *aRole = ROLE_SYSTEM_OUTLINEITEM;
   }
 
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
@@ -1763,22 +1763,22 @@ nsAccessibleWrap::GetXPAccessibleFor(con
     // ARIA document.
     if (ARIARole() == nsIAccessibleRole::ROLE_DOCUMENT) {
       nsDocAccessible* document = GetDocAccessible();
       nsAccessible* child =
         document->GetAccessibleByUniqueIDInSubtree(uniqueID);
 
       // Check whether the accessible for the given ID is a child of ARIA
       // document.
-      nsAccessible* parent = child ? child->GetParent() : nsnull;
+      nsAccessible* parent = child ? child->Parent() : nsnull;
       while (parent && parent != document) {
         if (parent == this)
           return child;
 
-        parent = parent->GetParent();
+        parent = parent->Parent();
       }
     }
 
     return nsnull;
   }
 
   // Gecko child indices are 0-based in contrast to indices used in MSAA.
   return GetChildAt(aVarChild.lVal - 1);
--- a/accessible/src/msaa/nsEventMap.h
+++ b/accessible/src/msaa/nsEventMap.h
@@ -34,19 +34,16 @@
  * 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 <winuser.h>
-#ifndef WINABLEAPI
-#include <winable.h>
-#endif
 #include "AccessibleEventId.h"
 
 const PRUint32 kEVENT_WIN_UNKNOWN = 0x00000000;
 const PRUint32 kEVENT_LAST_ENTRY  = 0xffffffff;
 
 static const PRUint32 gWinEventMap[] = {
   kEVENT_WIN_UNKNOWN,                                // nsIAccessibleEvent doesn't have 0 constant
   EVENT_OBJECT_SHOW,                                 // nsIAccessibleEvent::EVENT_SHOW
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -568,18 +568,19 @@ nsXULToolbarButtonAccessible::
 
 void
 nsXULToolbarButtonAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                                          PRInt32 *aSetSize)
 {
   PRInt32 setSize = 0;
   PRInt32 posInSet = 0;
 
-  nsAccessible* parent(GetParent());
-  NS_ENSURE_TRUE(parent,);
+  nsAccessible* parent = Parent();
+  if (!parent)
+    return;
 
   PRInt32 childCount = parent->GetChildCount();
   for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
     nsAccessible* child = parent->GetChildAt(childIdx);
     if (IsSeparator(child)) { // end of a group of buttons
       if (posInSet)
         break; // we've found our group, so we're done
 
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -993,38 +993,38 @@ NS_IMETHODIMP
 nsXULListCellAccessible::GetTable(nsIAccessibleTable **aTable)
 {
   NS_ENSURE_ARG_POINTER(aTable);
   *aTable = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccessible* thisRow = GetParent();
+  nsAccessible* thisRow = Parent();
   if (!thisRow || thisRow->Role() != nsIAccessibleRole::ROLE_ROW)
     return NS_OK;
 
-  nsAccessible* table = thisRow->GetParent();
+  nsAccessible* table = thisRow->Parent();
   if (!table || table->Role() != nsIAccessibleRole::ROLE_TABLE)
     return NS_OK;
 
   CallQueryInterface(table, aTable);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccessible* row = GetParent();
+  nsAccessible* row = Parent();
   if (!row)
     return NS_OK;
 
   *aColumnIndex = 0;
 
   PRInt32 indexInRow = IndexInParent();
   for (PRInt32 idx = 0; idx < indexInRow; idx++) {
     nsAccessible* cell = row->GetChildAt(idx);
@@ -1043,21 +1043,21 @@ NS_IMETHODIMP
 nsXULListCellAccessible::GetRowIndex(PRInt32 *aRowIndex)
 {
   NS_ENSURE_ARG_POINTER(aRowIndex);
   *aRowIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccessible* row = GetParent();
+  nsAccessible* row = Parent();
   if (!row)
     return NS_OK;
 
-  nsAccessible* table = row->GetParent();
+  nsAccessible* table = row->Parent();
   if (!table)
     return NS_OK;
 
   *aRowIndex = 0;
 
   PRInt32 indexInTable = row->IndexInParent();
   for (PRInt32 idx = 0; idx < indexInTable; idx++) {
     row = table->GetChildAt(idx);
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -327,31 +327,32 @@ nsXULMenuitemAccessible::NativeState()
     PRBool isSelected = PR_FALSE;
     nsCOMPtr<nsIDOMXULSelectControlItemElement>
       item(do_QueryInterface(mContent));
     NS_ENSURE_TRUE(item, state);
     item->GetSelected(&isSelected);
 
     // Is collapsed?
     PRBool isCollapsed = PR_FALSE;
-    nsAccessible* parentAcc = GetParent();
-    if (parentAcc->State() & states::INVISIBLE)
+    nsAccessible* parent = Parent();
+    if (parent && parent->State() & states::INVISIBLE)
       isCollapsed = PR_TRUE;
 
     if (isSelected) {
       state |= states::SELECTED;
 
       // Selected and collapsed?
       if (isCollapsed) {
         // Set selected option offscreen/invisible according to combobox state
-        nsAccessible* grandParentAcc = parentAcc->GetParent();
-        NS_ENSURE_TRUE(grandParentAcc, state);
-        NS_ASSERTION(grandParentAcc->Role() == nsIAccessibleRole::ROLE_COMBOBOX,
+        nsAccessible* grandParent = parent->Parent();
+        if (!grandParent)
+          return state;
+        NS_ASSERTION(grandParent->Role() == nsIAccessibleRole::ROLE_COMBOBOX,
                      "grandparent of combobox listitem is not combobox");
-        PRUint64 grandParentState = grandParentAcc->State();
+        PRUint64 grandParentState = grandParent->State();
         state &= ~(states::OFFSCREEN | states::INVISIBLE);
         state |= (grandParentState & states::OFFSCREEN) |
                  (grandParentState & states::INVISIBLE) |
                  (grandParentState & states::OPAQUE1);
       } // isCollapsed
     } // isSelected
   } // ROLE_COMBOBOX_OPTION
 
@@ -399,17 +400,17 @@ nsXULMenuitemAccessible::AccessKey() con
   nsAutoString accesskey;
   mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey,
                     accesskey);
   if (accesskey.IsEmpty())
     return KeyBinding();
 
   PRUint32 modifierKey = 0;
 
-  nsAccessible* parentAcc = GetParent();
+  nsAccessible* parentAcc = Parent();
   if (parentAcc) {
     if (parentAcc->NativeRole() == nsIAccessibleRole::ROLE_MENUBAR) {
       // If top level menu item, add Alt+ or whatever modifier text to string
       // No need to cache pref service, this happens rarely
       if (gMenuAccesskeyModifier == -1) {
         // Need to initialize cached global accesskey pref
         gMenuAccesskeyModifier = Preferences::GetInt("ui.key.menuAccessKey", 0);
       }
@@ -634,18 +635,19 @@ nsXULMenupopupAccessible::NativeState()
 {
   PRUint64 state = nsAccessible::NativeState();
 
 #ifdef DEBUG_A11Y
   // We are onscreen if our parent is active
   PRBool isActive = mContent->HasAttr(kNameSpaceID_None,
                                       nsAccessibilityAtoms::menuactive);
   if (!isActive) {
-    nsAccessible* parent(GetParent());
-    NS_ENSURE_TRUE(parent, state);
+    nsAccessible* parent = Parent();
+    if (!parent)
+      return state;
 
     nsIContent *parentContent = parnet->GetContent();
     NS_ENSURE_TRUE(parentContent, state);
 
     isActive = parentContent->HasAttr(kNameSpaceID_None,
                                       nsAccessibilityAtoms::open);
   }
 
@@ -680,17 +682,17 @@ nsXULMenupopupAccessible::NativeRole()
     PRUint32 role = mParent->Role();
     if (role == nsIAccessibleRole::ROLE_COMBOBOX ||
         role == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
       return nsIAccessibleRole::ROLE_COMBOBOX_LIST;
     }
 
     if (role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
       // Some widgets like the search bar have several popups, owned by buttons.
-      nsAccessible* grandParent = mParent->GetParent();
+      nsAccessible* grandParent = mParent->Parent();
       if (grandParent &&
           grandParent->Role() == nsIAccessibleRole::ROLE_AUTOCOMPLETE)
         return nsIAccessibleRole::ROLE_COMBOBOX_LIST;
     }
   }
 
   return nsIAccessibleRole::ROLE_MENUPOPUP;
 }
--- a/accessible/src/xul/nsXULTextAccessible.cpp
+++ b/accessible/src/xul/nsXULTextAccessible.cpp
@@ -93,17 +93,17 @@ nsXULTextAccessible::GetRelationByType(P
   nsresult rv =
     nsHyperTextAccessibleWrap::GetRelationByType(aRelationType, aRelation);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aRelationType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
     // Caption is the label for groupbox
     nsIContent *parent = mContent->GetParent();
     if (parent && parent->Tag() == nsAccessibilityAtoms::caption) {
-      nsAccessible* parent = GetParent();
+      nsAccessible* parent = Parent();
       if (parent && parent->Role() == nsIAccessibleRole::ROLE_GROUPING)
         return nsRelUtils::AddTarget(aRelationType, aRelation, parent);
     }
   }
 
   return NS_OK;
 }
 
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -1220,17 +1220,17 @@ nsXULTreeColumnsAccessible::GetSiblingAt
   nsCOMPtr<nsITreeBoxObject> tree = nsCoreUtils::GetTreeBoxObject(mContent);
   if (tree) {
     nsCOMPtr<nsITreeView> treeView;
     tree->GetView(getter_AddRefs(treeView));
     if (treeView) {
       PRInt32 rowCount = 0;
       treeView->GetRowCount(&rowCount);
       if (rowCount > 0 && aOffset <= rowCount) {
-        nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(GetParent());
+        nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(Parent());
 
         if (treeAcc)
           return treeAcc->GetTreeItemAccessible(aOffset - 1);
       }
     }
   }
 
   return nsnull;
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -1011,17 +1011,20 @@ NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetTable(nsIAccessibleTable **aTable)
 {
   NS_ENSURE_ARG_POINTER(aTable);
   *aTable = nsnull;
 
   if (IsDefunct())
     return NS_OK;
 
-  CallQueryInterface(mParent->GetParent(), aTable);
+  nsAccessible* grandParent = mParent->Parent();
+  if (grandParent)
+    CallQueryInterface(grandParent, aTable);
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
@@ -1166,19 +1169,22 @@ nsresult
 nsXULTreeGridCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
   NS_ENSURE_ARG_POINTER(aAttributes);
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // "table-cell-index" attribute
-  nsCOMPtr<nsIAccessible> accessible;
-  mParent->GetParent(getter_AddRefs(accessible));
-  nsCOMPtr<nsIAccessibleTable> tableAccessible = do_QueryInterface(accessible);
+  nsAccessible* grandParent = mParent->Parent();
+  if (!grandParent)
+    return NS_OK;
+
+  nsCOMPtr<nsIAccessibleTable> tableAccessible =
+    do_QueryInterface(static_cast<nsIAccessible*>(grandParent));
 
   // XXX - temp fix for crash bug 516047
   if (!tableAccessible)
     return NS_ERROR_FAILURE;
     
   PRInt32 colIdx = GetColumnIndex();
 
   PRInt32 cellIdx = -1;
@@ -1303,17 +1309,17 @@ nsXULTreeGridCellAccessible::GetSiblingA
       column = nsCoreUtils::GetNextSensibleColumn(columnAtOffset);
       column.swap(columnAtOffset);
     }
   }
 
   if (!columnAtOffset)
     return nsnull;
 
-  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(GetParent());
+  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(Parent());
   return rowAcc->GetCellAccessible(columnAtOffset);
 }
 
 void
 nsXULTreeGridCellAccessible::DispatchClickEvent(nsIContent *aContent,
                                                 PRUint32 aActionIndex)
 {
   if (IsDefunct())
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -757,16 +757,22 @@ function synthClick(aNodeOrID, aCheckerO
   {
     // Scroll the node into view, otherwise synth click may fail.
     if (this.DOMNode instanceof nsIDOMNSHTMLElement)
       this.DOMNode.scrollIntoView(true);
 
     synthesizeMouse(this.DOMNode, 1, 1, {});
   }
 
+  this.finalCheck = function synthClick_finalCheck()
+  {
+    // Scroll top window back.
+    window.top.scrollTo(0, 0);
+  }
+
   this.getID = function synthClick_getID()
   {
     return prettyName(aNodeOrID) + " click"; 
   }
 }
 
 /**
  * Mouse move invoker.
--- a/accessible/tests/mochitest/events/test_tree.xul
+++ b/accessible/tests/mochitest/events/test_tree.xul
@@ -98,23 +98,25 @@
 
     /**
      * Check name changed a11y event.
      */
     function nameChangeChecker(aMsg, aRow, aCol)
     {
       this.type = EVENT_NAME_CHANGE;
 
-      this.target getter = function()
+      function targetGetter()
       {
         var acc = getAccessible(gTree);
 
         var tableAcc = getAccessible(acc, [nsIAccessibleTable]);
         return tableAcc.getCellAt(aRow, aCol);
       }
+      Object.defineProperty(this, "target", { get: targetGetter });
+
       this.getID = function getID()
       {
         return aMsg + "name changed";
       }
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // Invokers
--- a/accessible/tests/mochitest/treeupdate/test_contextmenu.xul
+++ b/accessible/tests/mochitest/treeupdate/test_contextmenu.xul
@@ -230,17 +230,17 @@
       var subsubmenuTree =
       {
         name: "item2.0.0",
         role: ROLE_MENUITEM,
         children: []
       };
 
       if (LINUX || SOLARIS)
-        tree.children[2].children[0].\(subsubmenuTree);
+        tree.children[2].children[0].children.push(subsubmenuTree);
       else
         tree.children[2].children[0].children[0].children[0].children.push(subsubmenuTree);
 
       return tree;
     }
 
 
     function doTests()
--- a/accessible/tests/mochitest/treeupdate/test_doc.html
+++ b/accessible/tests/mochitest/treeupdate/test_doc.html
@@ -371,22 +371,22 @@
       }
 
       this.finalCheck = function changeSrc_finalCheck()
       {
         var tree =
           { INTERNAL_FRAME: [
             { DOCUMENT: [
               { ENTRY: [ ] }
-            ] };
+            ] }
           ] };
         testAccessibleTree(this.containerNode, tree);
       }
 
-      this.getID() = function changeSrc_getID()
+      this.getID = function changeSrc_getID()
       {
         return "change src on iframe";
       }
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,213 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1311096050000">
-  <emItems>
-      <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
-                        <versionRange  minVersion="0.1" maxVersion="4.3.0.00" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
-                        <versionRange  minVersion=" " severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
-                        <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion="3.3.1" maxVersion="*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="5.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
-                        <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
-                    </versionRange>
-                  </emItem>
-      <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.0.00" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
-                        </emItem>
-      <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
-                        <versionRange  minVersion="2.1" maxVersion="3.3">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion=" " maxVersion="6.9.8">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i18" id="msntoolbar@msn.com">
-                        <versionRange  minVersion=" " maxVersion="6.*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
-                        </emItem>
-      <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
-                        <versionRange  minVersion="1.2" maxVersion="1.2">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
-                        <versionRange  minVersion="0.1" maxVersion="4.3.0.00" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i23" id="firefox@bandoo.com">
-                        <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
-                        <versionRange  minVersion="3.1.22.0" maxVersion="3.1.22.0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i2" id="fdm_ffext@freedownloadmanager.org">
-                        <versionRange  minVersion="1.0" maxVersion="1.3.1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i5" id="support@daemon-tools.cc">
-                        <versionRange  minVersion=" " maxVersion="1.0.0.5">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
-                        <versionRange  minVersion=" " maxVersion="8.5">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i12" id="masterfiler@gmail.com">
-                        <versionRange  severity="3">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
-                        <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i11" id="yslow@yahoo-inc.com">
-                        <versionRange  minVersion="2.0.5" maxVersion="2.0.5">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.5.7" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
-                        <versionRange  minVersion="2.2" maxVersion="2.2">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
-                        <versionRange  minVersion="2.0" maxVersion="2.0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
-                        </emItem>
-      <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
-                        <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i15" id="personas@christopher.beard">
-                        <versionRange  minVersion="1.6" maxVersion="1.6">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.6" maxVersion="3.6.*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i21" id="support@update-firefox.com">
-                        </emItem>
-    </emItems>
-
-  <pluginItems>
-      <pluginItem  blockID="p26">
-      <match name="name" exp="^Yahoo Application State Plugin$" />      <match name="description" exp="^Yahoo Application State Plugin$" />      <match name="filename" exp="npYState.dll" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p27">
-      <match name="name" exp="QuickTime Plug-in 7[.]1[.]" />            <match name="filename" exp="npqtplugin.?[.]dll" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p28">
-                  <match name="filename" exp="NPFFAddOn.dll" />              <versionRange >
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p31">
-                  <match name="filename" exp="NPMySrch.dll" />              <versionRange >
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p32">
-                  <match name="filename" exp="npViewpoint.dll" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0" maxVersion="*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p33">
-      <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" />            <match name="filename" exp="npdeploytk.dll" />              <versionRange  severity="1">
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p34">
-                  <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.6a1pre" maxVersion="*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-    </pluginItems>
-
-  <gfxItems>
-    <gfxBlacklistEntry  blockID="g35">
-      <os>WINNT 6.1</os>
-      <vendor>0x10de</vendor>
-              <devices>
-                      <device>0x0a6c</device>
-                  </devices>
-            <feature>DIRECT2D</feature>
-      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-      <driverVersion>8.17.12.5896</driverVersion>
-      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
-    </gfxBlacklistEntry>
-    <gfxBlacklistEntry  blockID="g36">
-      <os>WINNT 6.1</os>
-      <vendor>0x10de</vendor>
-              <devices>
-                      <device>0x0a6c</device>
-                  </devices>
-            <feature>DIRECT3D_9_LAYERS</feature>
-      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-      <driverVersion>8.17.12.5896</driverVersion>
-      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
-    </gfxBlacklistEntry>
-    <gfxBlacklistEntry  blockID="g37">
-      <os>WINNT 5.1</os>
-      <vendor>0x10de</vendor>
-            <feature>DIRECT3D_9_LAYERS</feature>
-      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-      <driverVersion>7.0.0.0</driverVersion>
-      <driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
-    </gfxBlacklistEntry>
-    </gfxItems>
-
-
-</blocklist>
\ No newline at end of file
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -58,20 +58,16 @@ tabbrowser {
   -moz-transition: opacity 250ms;
 }
 
 .tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
   position: fixed !important;
   display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
 }
 
-.tabbrowser-tabs[drag] > .tabbrowser-tab {
-  pointer-events: none; /* suppress tooltips */
-}
-
 .tabbrowser-tabs[drag] > .tabbrowser-tab[selected] {
   z-index: 2; /* ensure selected tab stays on top despite -moz-transform */
 }
 
 .tabbrowser-tabs[drag] > .tabbrowser-tab[dragged] {
   -moz-transition: 0s; /* suppress opening animation when reattaching tab */
 }
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2451,17 +2451,17 @@
                 onget="return this.mCurrentBrowser.userTypedValue;"
                 onset="return this.mCurrentBrowser.userTypedValue = val;"/>
 
       <method name="createTooltip">
         <parameter name="event"/>
         <body><![CDATA[
           event.stopPropagation();
           var tab = document.tooltipNode;
-          if (tab.localName != "tab") {
+          if (tab.localName != "tab" || this.tabContainer.draggedTab) {
             event.preventDefault();
             return;
           }
           event.target.setAttribute("label", tab.mOverCloseButton ?
                                              tab.getAttribute("closetabtext") :
                                              tab.getAttribute("label"));
         ]]></body>
       </method>
@@ -3808,16 +3808,29 @@
 
       <handler event="dragstart"><![CDATA[
         if (this.draggedTab)
           return;
         var tab = this._getDragTargetTab(event);
         if (!tab || !tab._fullyOpen || tab.closing)
           return;
 
+#ifdef XP_MACOSX
+        if (event.altKey) {
+#else
+        if (event.ctrlKey) {
+#endif
+          let dt = event.dataTransfer;
+          let spec = this.tabbrowser.getBrowserForTab(tab).currentURI.spec;
+          dt.setData("text/x-moz-url", spec);
+          let favicon = document.getAnonymousElementByAttribute(tab, "class", "tab-icon-image");
+          dt.setDragImage(favicon, 16, 16);
+          return;
+        }
+
         this.setAttribute("drag", "move");
         this.draggedTab = tab;
         tab.setAttribute("dragged", "true");
         let data = tab._dragData = {};
         data._dragStartX = event.screenX;
         if (!tab.pinned)
           data._dragStartX += this.mTabstrip.scrollPosition;
         data._dragDistX = 0;
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -74,16 +74,22 @@ class RemoteAutomation(Automation):
 
     # Set up what we need for the remote environment
     def environment(self, env = None, xrePath = None, crashreporter = True):
         # Because we are running remote, we don't want to mimic the local env
         # so no copying of os.environ
         if env is None:
             env = {}
 
+        # Except for the mochitest results table hiding option, which isn't
+        # passed to runtestsremote.py as an actual option, but through the
+        # MOZ_CRASHREPORTER_DISABLE environment variable.
+        if 'MOZ_HIDE_RESULTS_TABLE' in os.environ:
+            env['MOZ_HIDE_RESULTS_TABLE'] = os.environ['MOZ_HIDE_RESULTS_TABLE']
+
         if crashreporter:
             env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
             env['MOZ_CRASHREPORTER'] = '1'
         else:
             env['MOZ_CRASHREPORTER_DISABLE'] = '1'
 
         return env
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..be1632d8ca90969c3835124b7d8308360d744cea
GIT binary patch
literal 569
zc$^FHW@Zs#U|`^2h-!Fax8`u4{6QdZ2O|RmKZ6WIaz;^pZmM2xVqRuiYH>+u2qy#c
zoJ%r(+po&_l~!;wFtU6FsstO*I^iJKVFjMH_jaxeo`+W5E!_~DxM3~7!Yrf6RSU|t
z<nMnqYm@9L8;?o<e^1U}U3<MNgROaQX~u%x+X6G*3+-Z=V6cqMPW^aLz%#)Jr}7th
zt3~Et%S{Q+E9>NXXSsKe0ZVql><OuQMsF;y_dj5_@%riOx$WDuO<_meHhDgYTpP|-
z;3Y9fNn*<8zf7Eb4PvssdpWzGuF>gbe7HpE*e0fxm6fN@^YQXe*ADPke(S7yx}zgg
zZ~nG!v4pqZme21C+`||E4~e4a=XU3A>?~IU@~jvjA(4}xn39@;8WPigiDC;0?{nw1
zJ<n<f255Nd>KO(#Fbeq3*H*W;G*k~|)SEeLxwI6|WEO@1Z$>6LW?Vrp!2kk4Cc~0O
t5DOzBSRoOCW;L>*n7%+ZlnY2<_=y$bCk#Vb*+3eZfN&L%t^}FD004Z7u^0dV
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit/data/test_bug564667/chrome.manifest
@@ -0,0 +1,16 @@
+# Locally defined URLs
+content  test1       test/
+locale   test1 en-US test/
+skin     test1 test  test/
+
+# Test Override
+content testOverride  test/
+override chrome://testOverride/content file:///test1/override
+
+
+# Load external manifest
+manifest loaded.manifest
+
+# Failure Cases
+overlay   chrome://test1/content/overlay.xul   chrome://test1/content/test1.xul
+style     chrome://test1/content/style.xul     chrome://test1/content/test1.css
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit/data/test_bug564667/loaded.manifest
@@ -0,0 +1,2 @@
+content  test2         test/
+locale   test2  en-US  test/
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit/test_bug564667.js
@@ -0,0 +1,155 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *      the Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *      Hernan Rodriguez Colmeiro <colmeiro@gmail.com>.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 *****
+ */
+
+const UNPACKAGED_ADDON = do_get_file("data/test_bug564667");
+const PACKAGED_ADDON = do_get_file("data/test_bug564667.xpi");
+
+var gIOS = Cc["@mozilla.org/network/io-service;1"].
+           getService(Ci.nsIIOService);
+
+var gCR = Cc["@mozilla.org/chrome/chrome-registry;1"].
+          getService(Ci.nsIChromeRegistry).
+          QueryInterface(Ci.nsIXULOverlayProvider);
+
+/*
+ * Checks that a mapping was added
+ */
+function test_mapping(chromeURL, target) {
+  var uri = gIOS.newURI(chromeURL, null, null);
+
+  try {
+    var result = gCR.convertChromeURL(uri);
+    do_check_eq(result.spec, target);
+  }
+  catch (ex) {
+    do_throw(chromeURL + " not Registered");
+  }
+}
+
+/*
+ * Checks that a mapping was removed
+ */
+function test_removed_mapping(chromeURL, target) {
+  var uri = gIOS.newURI(chromeURL, null, null);
+  try {
+    var result = gCR.convertChromeURL(uri);
+    do_throw(chromeURL + " not removed");
+  }
+  catch (ex) {
+    // This should throw
+  }
+}
+
+/*
+ * Checks if any overlay was added after loading
+ * the manifest files
+ *
+ * @param type The type of overlay: overlay|style
+ */
+function test_no_overlays(chromeURL, target, type) {
+  var type = type || "overlay";
+  var uri = gIOS.newURI(chromeURL, null, null);
+  var present = false, elem;
+
+  var overlays = (type == "overlay") ?
+      gCR.getXULOverlays(uri) : gCR.getStyleOverlays(uri);
+
+  // We shouldn't be allowed to register overlays nor styles
+  if (overlays.hasMoreElements()) {
+    if (type == "styles")
+      do_throw("Style Registered: " + chromeURL);
+    else
+      do_throw("Overlay Registered: " + chromeURL);
+  }
+}
+
+function testManifest(manifestPath, baseURI) {
+
+  // ------------------  Add manifest file ------------------------
+  Components.manager.addBootstrappedManifestLocation(manifestPath);
+
+  // Test Adding Content URL
+  test_mapping("chrome://test1/content", baseURI + "test/test1.xul");
+
+  // Test Adding Locale URL
+  test_mapping("chrome://test1/locale", baseURI + "test/test1.dtd");
+
+  // Test Adding Skin URL
+  test_mapping("chrome://test1/skin", baseURI + "test/test1.css");
+
+  // Test Adding Manifest URL
+  test_mapping("chrome://test2/content", baseURI + "test/test2.xul");
+  test_mapping("chrome://test2/locale", baseURI + "test/test2.dtd");
+
+  // Test Adding Override
+  test_mapping("chrome://testOverride/content", 'file:///test1/override')
+
+  // Test Not-Adding Overlays
+  test_no_overlays("chrome://test1/content/overlay.xul",
+                   "chrome://test1/content/test1.xul");
+
+  // Test Not-Adding Styles
+  test_no_overlays("chrome://test1/content/style.xul",
+                   "chrome://test1/content/test1.css", "styles");
+
+
+  // ------------------  Remove manifest file ------------------------
+  Components.manager.removeBootstrappedManifestLocation(manifestPath);
+
+  // Test Removing Content URL
+  test_removed_mapping("chrome://test1/content", baseURI + "test/test1.xul");
+
+  // Test Removing Content URL
+  test_removed_mapping("chrome://test1/locale", baseURI + "test/test1.dtd");
+
+  // Test Removing Skin URL
+  test_removed_mapping("chrome://test1/skin", baseURI + "test/test1.css");
+
+  // Test Removing Manifest URL
+  test_removed_mapping("chrome://test2/content", baseURI + "test/test2.xul");
+  test_removed_mapping("chrome://test2/locale", baseURI + "test/test2.dtd");
+}
+
+function run_test() {
+  // Test an unpackaged addon
+  testManifest(UNPACKAGED_ADDON, gIOS.newFileURI(UNPACKAGED_ADDON).spec);
+
+  // Test a packaged addon
+  testManifest(PACKAGED_ADDON, "jar:" + gIOS.newFileURI(PACKAGED_ADDON).spec + "!/");
+}
--- a/chrome/test/unit/xpcshell.ini
+++ b/chrome/test/unit/xpcshell.ini
@@ -5,12 +5,13 @@ tail =
 [test_abi.js]
 [test_bug292789.js]
 [test_bug380398.js]
 [test_bug397073.js]
 [test_bug399707.js]
 [test_bug401153.js]
 [test_bug415367.js]
 [test_bug519468.js]
+[test_bug564667.js]
 [test_crlf.js]
 [test_data_protocol_registration.js]
 [test_no_remote_registration.js]
 [test_resolve_uris.js]
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -72,16 +72,17 @@ nsIXPathEvaluatorInternal.h \
 mozISanitizingSerializer.h \
 nsCaseTreatment.h \
 nsContentCID.h \
 nsCopySupport.h \
 nsContentCreatorFunctions.h \
 nsDOMFile.h \
 nsLineBreaker.h \
 nsReferencedElement.h \
+nsTreeSanitizer.h \
 nsXMLNameSpaceMap.h \
 nsDOMEventTargetWrapperCache.h \
 $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
 		Element.h \
--- a/content/base/public/nsContentCID.h
+++ b/content/base/public/nsContentCID.h
@@ -148,40 +148,24 @@
 // {d4f2b600-b5c1-11d6-b483-cc97c63e567c}
 #define NS_HTMLFRAGMENTSINK_CID \
 { 0xd4f2b600, 0xb5c1, 0x11d6, { 0xb4, 0x83, 0xcc, 0x97, 0xc6, 0x3e, 0x56, 0x7c } }
 
 // {13111d00-ce81-11d6-8082-ecf3665af67c}
 #define NS_HTMLFRAGMENTSINK2_CID \
 { 0x13111d00, 0xce81, 0x11d6, { 0x80, 0x82, 0xec, 0xf3, 0x66, 0x5a, 0xf6, 0x7c } }
 
-// {A47E9526-6E48-4574-9D6C-3164E271F74E}
-#define NS_HTMLPARANOIDFRAGMENTSINK_CID \
-{ 0xa47e9526, 0x6e48, 0x4574, { 0x9d, 0x6c, 0x31, 0x64, 0xe2, 0x71, 0xf7, 0x4e } }
-
-// {35aab9d8-db42-4c82-8aba-fad2b1d8f465}
-#define NS_HTMLPARANOIDFRAGMENTSINK2_CID \
-{ 0x35aab9d8, 0xdb42, 0x4c82, { 0x8a, 0xba, 0xfa, 0xd2, 0xb1, 0xd8, 0xf4, 0x65 } }
-
 // {4B664E54-72A2-4bbf-A5C2-66D4DC3066A0}
 #define NS_XMLFRAGMENTSINK_CID \
 { 0x4b664e54, 0x72a2, 0x4bbf, { 0xa5, 0xc2, 0x66, 0xd4, 0xdc, 0x30, 0x66, 0xa0 } }
 
 // {4DC30689-929D-425e-A709-082C6294E542}
 #define NS_XMLFRAGMENTSINK2_CID \
 { 0x4dc30689, 0x929d, 0x425e, { 0xa7, 0x9, 0x8, 0x2c, 0x62, 0x94, 0xe5, 0x42 } }
 
-// {2D78BBF0-E26C-482B-92B3-78A7B2AFC8F7}
-#define NS_XHTMLPARANOIDFRAGMENTSINK_CID  \
-{ 0x2d78bbf0, 0xe26c, 0x482b, { 0x92, 0xb3, 0x78, 0xa7, 0xb2, 0xaf, 0xc8, 0xf7} }
-
-// {921dac9c-ffd4-4b5c-9901-4015b03862e6}
-#define NS_XHTMLPARANOIDFRAGMENTSINK2_CID  \
-{ 0x921dac9c, 0xffd4, 0x4b5c, { 0x99, 0x01, 0x40, 0x15, 0xb0, 0x38, 0x62, 0xe6} }
-
 // {3986B301-097C-11d3-BF87-00105A1B0627}
 #define NS_XULPOPUPLISTENER_CID \
 { 0x3986b301, 0x97c, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
 
 // {1F5C1721-7DC3-11d3-BF87-00105A1B0627}
 #define NS_XULCONTROLLERS_CID \
 { 0x1f5c1721, 0x7dc3, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
 
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -1098,29 +1098,51 @@ public:
    * Get the next node in the pre-order tree traversal of the DOM.  If
    * aRoot is non-null, then it must be an ancestor of |this|
    * (possibly equal to |this|) and only nodes that are descendants of
    * aRoot, not including aRoot itself, will be returned.  Returns
    * null if there are no more nodes to traverse.
    */
   nsIContent* GetNextNode(const nsINode* aRoot = nsnull) const
   {
+    return GetNextNodeImpl(aRoot, PR_FALSE);
+  }
+
+  /**
+   * Get the next node in the pre-order tree traversal of the DOM but ignoring
+   * the children of this node.  If aRoot is non-null, then it must be an
+   * ancestor of |this| (possibly equal to |this|) and only nodes that are
+   * descendants of aRoot, not including aRoot itself, will be returned.
+   * Returns null if there are no more nodes to traverse.
+   */
+  nsIContent* GetNextNonChildNode(const nsINode* aRoot = nsnull) const
+  {
+    return GetNextNodeImpl(aRoot, PR_TRUE);
+  }
+
+private:
+
+  nsIContent* GetNextNodeImpl(const nsINode* aRoot,
+                              const PRBool aSkipChildren) const
+  {
     // Can't use nsContentUtils::ContentIsDescendantOf here, since we
     // can't include it here.
 #ifdef DEBUG
     if (aRoot) {
       const nsINode* cur = this;
       for (; cur; cur = cur->GetNodeParent())
         if (cur == aRoot) break;
       NS_ASSERTION(cur, "aRoot not an ancestor of |this|?");
     }
 #endif
-    nsIContent* kid = GetFirstChild();
-    if (kid) {
-      return kid;
+    if (!aSkipChildren) {
+      nsIContent* kid = GetFirstChild();
+      if (kid) {
+        return kid;
+      }
     }
     if (this == aRoot) {
       return nsnull;
     }
     const nsINode* cur = this;
     while (1) {
       nsIContent* next = cur->GetNextSibling();
       if (next) {
@@ -1130,16 +1152,18 @@ public:
       if (parent == aRoot) {
         return nsnull;
       }
       cur = parent;
     }
     NS_NOTREACHED("How did we get here?");
   }
 
+public:
+
   /**
    * Get the previous nsIContent in the pre-order tree traversal of the DOM.  If
    * aRoot is non-null, then it must be an ancestor of |this|
    * (possibly equal to |this|) and only nsIContents that are descendants of
    * aRoot, including aRoot itself, will be returned.  Returns
    * null if there are no more nsIContents to traverse.
    */
   nsIContent* GetPreviousContent(const nsINode* aRoot = nsnull) const
--- a/content/base/public/nsISelectionPrivate.idl
+++ b/content/base/public/nsISelectionPrivate.idl
@@ -44,23 +44,25 @@ interface nsISelectionListener;
 interface nsIContent;
 
 %{C++
 class nsFrameSelection;
 class nsIFrame;
 class nsIPresShell;
 struct nsTextRangeStyle;
 struct nsPoint;
+#include "nsIFrame.h"
 %}
 
 [ptr] native nsFrameSelection(nsFrameSelection);
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native nsIPresShell(nsIPresShell);
 [ref] native constTextRangeStyleRef(const nsTextRangeStyle);
 [ref] native nsPointRef(nsPoint);
+native nsDirection(nsDirection);
 
 [scriptable, uuid(98552206-ad7a-4d2d-8ce3-b6fa2389298b)]
 interface nsISelectionPrivate : nsISupports
  {
     const short ENDOFPRECEDINGLINE=0;
     const short STARTOFNEXTLINE=1;
     
     attribute boolean interlinePosition;
@@ -123,10 +125,16 @@ interface nsISelectionPrivate : nsISuppo
 
     /**
      * Set the painting style for the range. The range must be a range in
      * the selection. The textRangeStyle will be used by text frame
      * when it is painting the selection.
      */
     [noscript] void setTextRangeStyle(in nsIDOMRange range,
                       in constTextRangeStyleRef textRangeStyle);
+
+    /**
+     * Get the direction of the selection.
+     */
+    [noscript, notxpcom] nsDirection getSelectionDirection();
+    [noscript, notxpcom] void setSelectionDirection(in nsDirection aDirection);
 };
 
new file mode 100644
--- /dev/null
+++ b/content/base/public/nsTreeSanitizer.h
@@ -0,0 +1,210 @@
+/* ***** 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 HTML/SVG/MathML sanitizer code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Henri Sivonen <hsivonen@iki.fi>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 nsTreeSanitizer_h_
+#define nsTreeSanitizer_h_
+
+#include "nsIContent.h"
+#include "mozilla/css/StyleRule.h"
+#include "nsIPrincipal.h"
+#include "mozilla/dom/Element.h"
+
+class NS_STACK_CLASS nsTreeSanitizer {
+
+  public:
+
+    /**
+     * The constructor.
+     *
+     * @param aAllowStyles Whether to allow <style> and style=""
+     * @param aAllowComments Whether to allow comment nodes
+     */
+    nsTreeSanitizer(PRBool aAllowStyles, PRBool aAllowComments);
+
+    static void InitializeStatics();
+    static void ReleaseStatics();
+
+    /**
+     * Sanitizes a disconnected DOM fragment freshly obtained from a parser.
+     * The argument must be of type nsINode::eDOCUMENT_FRAGMENT and,
+     * consequently, must not be in the document. Furthermore, the fragment
+     * must have just come from a parser so that it can't have mutation
+     * event listeners set on it.
+     */
+    void Sanitize(nsIContent* aFragment);
+
+  private:
+
+    /**
+     * Whether <style> and style="" are allowed.
+     */
+    PRBool mAllowStyles;
+
+    /**
+     * Whether comment nodes are allowed.
+     */
+    PRBool mAllowComments;
+
+    /**
+     * Queries if an element must be replaced with its children.
+     * @param aNamespace the namespace of the element the question is about
+     * @param aLocal the local name of the element the question is about
+     * @return true if the element must be replaced with its children and
+     *         false if the element is to be kept
+     */
+    PRBool MustFlatten(PRInt32 aNamespace, nsIAtom* aLocal);
+
+    /**
+     * Queries if an element including its children must be removed.
+     * @param aNamespace the namespace of the element the question is about
+     * @param aLocal the local name of the element the question is about
+     * @param aElement the element node itself for inspecting attributes
+     * @return true if the element and its children must be removed and
+     *         false if the element is to be kept
+     */
+    PRBool MustPrune(PRInt32 aNamespace,
+                     nsIAtom* aLocal,
+                     mozilla::dom::Element* aElement);
+
+    /**
+     * Checks if a given local name (for an attribute) is on the given list
+     * of URL attribute names.
+     * @param aURLs the list of URL attribute names
+     * @param aLocalName the name to search on the list
+     * @return true if aLocalName is on the aURLs list and false otherwise
+     */
+    PRBool IsURL(nsIAtom*** aURLs, nsIAtom* aLocalName);
+
+    /**
+     * Removes dangerous attributes from the element. If the style attribute
+     * is allowed, its value is sanitized. The values of URL attributes are
+     * sanitized, except src isn't sanitized when it is allowed to remain
+     * potentially dangerous.
+     *
+     * @param aElement the element whose attributes should be sanitized
+     * @param aAllowed the whitelist of permitted local names to use
+     * @param aURLs the local names of URL-valued attributes
+     * @param aAllowXLink whether XLink attributes are allowed
+     * @param aAllowStyle whether the style attribute is allowed
+     * @param aAllowDangerousSrc whether to leave the value of the src
+     *                           attribute unsanitized
+     */
+    void SanitizeAttributes(mozilla::dom::Element* aElement,
+                            nsTHashtable<nsISupportsHashKey>* aAllowed,
+                            nsIAtom*** aURLs,
+                            PRBool aAllowXLink,
+                            PRBool aAllowStyle,
+                            PRBool aAllowDangerousSrc);
+
+    /**
+     * Remove the named URL attribute from the element if the URL fails a
+     * security check.
+     *
+     * @param aElement the element whose attribute to possibly modify
+     * @param aNamespace the namespace of the URL attribute
+     * @param aLocalName the local name of the URL attribute
+     */
+    void SanitizeURL(mozilla::dom::Element* aElement,
+                     PRInt32 aNamespace,
+                     nsIAtom* aLocalName);
+
+    /**
+     * Checks a style rule for the presence of the 'binding' CSS property and
+     * removes that property from the rule and reserializes in case the
+     * property was found.
+     *
+     * @param aRule The style rule to check
+     * @param aRuleText the serialized mutated rule if the method returns true
+     * @return true if the rule was modified and false otherwise
+     */
+    PRBool SanitizeStyleRule(mozilla::css::StyleRule* aRule,
+                             nsAutoString &aRuleText);
+
+    /**
+     * Parses a style sheet and reserializes it with the 'binding' property
+     * removed if it was present.
+     *
+     * @param aOrigin the original style sheet source
+     * @param aSanitized the reserialization without 'binding'; only valid if
+     *                   this method return true
+     * @param aDocument the document the style sheet belongs to
+     * @param aBaseURI the base URI to use
+     * @return true if the 'binding' property was encountered and false
+     *              otherwise
+     */
+    PRBool SanitizeStyleSheet(const nsAString& aOriginal,
+                              nsAString& aSanitized,
+                              nsIDocument* aDocument,
+                              nsIURI* aBaseURI);
+
+    /**
+     * The whitelist of HTML elements.
+     */
+    static nsTHashtable<nsISupportsHashKey>* sElementsHTML;
+
+    /**
+     * The whitelist of HTML attributes.
+     */
+    static nsTHashtable<nsISupportsHashKey>* sAttributesHTML;
+
+    /**
+     * The whitelist of SVG elements.
+     */
+    static nsTHashtable<nsISupportsHashKey>* sElementsSVG;
+
+    /**
+     * The whitelist of SVG attributes.
+     */
+    static nsTHashtable<nsISupportsHashKey>* sAttributesSVG;
+
+    /**
+     * The whitelist of SVG elements.
+     */
+    static nsTHashtable<nsISupportsHashKey>* sElementsMathML;
+
+    /**
+     * The whitelist of MathML attributes.
+     */
+    static nsTHashtable<nsISupportsHashKey>* sAttributesMathML;
+
+    /**
+     * Reusable null principal for URL checks.
+     */
+    static nsIPrincipal* sNullPrincipal;
+};
+
+#endif // nsTreeSanitizer_h_
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -134,16 +134,17 @@ CPPSRCS		= \
 		nsStubImageDecoderObserver.cpp \
 		nsStubMutationObserver.cpp \
 		nsStyledElement.cpp \
 		nsStyleLinkElement.cpp \
 		nsSyncLoadService.cpp \
 		nsTextFragment.cpp \
 		nsTextNode.cpp \
 		nsTraversal.cpp \
+		nsTreeSanitizer.cpp \
 		nsTreeWalker.cpp \
 		nsWebSocket.cpp \
 		nsXHTMLContentSerializer.cpp \
 		nsXMLContentSerializer.cpp \
 		nsXMLHttpRequest.cpp \
 		nsXMLNameSpaceMap.cpp \
 		Link.cpp \
 		nsFileDataProtocolHandler.cpp \
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -1722,271 +1722,8 @@ nsContentSink::NotifyDocElementCreated(n
     mozilla::services::GetObserverService();
   if (observerService) {
     nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
     observerService->
       NotifyObservers(domDoc, "document-element-inserted",
                       EmptyString().get());
   }
 }
-
-// URIs: action, href, src, longdesc, usemap, cite
-PRBool 
-IsAttrURI(nsIAtom *aName)
-{
-  return (aName == nsGkAtoms::action ||
-          aName == nsGkAtoms::href ||
-          aName == nsGkAtoms::src ||
-          aName == nsGkAtoms::longdesc ||
-          aName == nsGkAtoms::usemap ||
-          aName == nsGkAtoms::cite ||
-          aName == nsGkAtoms::background);
-}
-
-//
-// these two lists are used by the sanitizing fragment serializers
-// Thanks to Mark Pilgrim and Sam Ruby for the initial whitelist
-//
-nsIAtom** const kDefaultAllowedTags [] = {
-  &nsGkAtoms::a,
-  &nsGkAtoms::abbr,
-  &nsGkAtoms::acronym,
-  &nsGkAtoms::address,
-  &nsGkAtoms::area,
-  &nsGkAtoms::article,
-  &nsGkAtoms::aside,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::audio,
-#endif
-  &nsGkAtoms::b,
-  &nsGkAtoms::bdo,
-  &nsGkAtoms::big,
-  &nsGkAtoms::blockquote,
-  &nsGkAtoms::br,
-  &nsGkAtoms::button,
-  &nsGkAtoms::canvas,
-  &nsGkAtoms::caption,
-  &nsGkAtoms::center,
-  &nsGkAtoms::cite,
-  &nsGkAtoms::code,
-  &nsGkAtoms::col,
-  &nsGkAtoms::colgroup,
-  &nsGkAtoms::command,
-  &nsGkAtoms::datalist,
-  &nsGkAtoms::dd,
-  &nsGkAtoms::del,
-  &nsGkAtoms::details,
-  &nsGkAtoms::dfn,
-  &nsGkAtoms::dir,
-  &nsGkAtoms::div,
-  &nsGkAtoms::dl,
-  &nsGkAtoms::dt,
-  &nsGkAtoms::em,
-  &nsGkAtoms::fieldset,
-  &nsGkAtoms::figcaption,
-  &nsGkAtoms::figure,
-  &nsGkAtoms::font,
-  &nsGkAtoms::footer,
-  &nsGkAtoms::form,
-  &nsGkAtoms::h1,
-  &nsGkAtoms::h2,
-  &nsGkAtoms::h3,
-  &nsGkAtoms::h4,
-  &nsGkAtoms::h5,
-  &nsGkAtoms::h6,
-  &nsGkAtoms::header,
-  &nsGkAtoms::hgroup,
-  &nsGkAtoms::hr,
-  &nsGkAtoms::i,
-  &nsGkAtoms::img,
-  &nsGkAtoms::input,
-  &nsGkAtoms::ins,
-  &nsGkAtoms::kbd,
-  &nsGkAtoms::label,
-  &nsGkAtoms::legend,
-  &nsGkAtoms::li,
-  &nsGkAtoms::listing,
-  &nsGkAtoms::map,
-  &nsGkAtoms::mark,
-  &nsGkAtoms::menu,
-  &nsGkAtoms::meter,
-  &nsGkAtoms::nav,
-  &nsGkAtoms::nobr,
-  &nsGkAtoms::noscript,
-  &nsGkAtoms::ol,
-  &nsGkAtoms::optgroup,
-  &nsGkAtoms::option,
-  &nsGkAtoms::output,
-  &nsGkAtoms::p,
-  &nsGkAtoms::pre,
-  &nsGkAtoms::progress,
-  &nsGkAtoms::q,
-  &nsGkAtoms::rp,
-  &nsGkAtoms::rt,
-  &nsGkAtoms::ruby,
-  &nsGkAtoms::s,
-  &nsGkAtoms::samp,
-  &nsGkAtoms::section,
-  &nsGkAtoms::select,
-  &nsGkAtoms::small,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::source,
-#endif
-  &nsGkAtoms::span,
-  &nsGkAtoms::strike,
-  &nsGkAtoms::strong,
-  &nsGkAtoms::sub,
-  &nsGkAtoms::summary,
-  &nsGkAtoms::sup,
-  &nsGkAtoms::table,
-  &nsGkAtoms::tbody,
-  &nsGkAtoms::td,
-  &nsGkAtoms::textarea,
-  &nsGkAtoms::tfoot,
-  &nsGkAtoms::th,
-  &nsGkAtoms::thead,
-  &nsGkAtoms::time,
-  &nsGkAtoms::tr,
-  &nsGkAtoms::track,
-  &nsGkAtoms::tt,
-  &nsGkAtoms::u,
-  &nsGkAtoms::ul,
-  &nsGkAtoms::var,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::video,
-#endif
-  &nsGkAtoms::wbr,
-  nsnull
-};
-
-nsIAtom** const kDefaultAllowedAttributes [] = {
-  &nsGkAtoms::abbr,
-  &nsGkAtoms::accept,
-  &nsGkAtoms::acceptcharset,
-  &nsGkAtoms::accesskey,
-  &nsGkAtoms::action,
-  &nsGkAtoms::align,
-  &nsGkAtoms::alt,
-  &nsGkAtoms::autocomplete,
-  &nsGkAtoms::autofocus,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::autoplay,
-#endif
-  &nsGkAtoms::axis,
-  &nsGkAtoms::background,
-  &nsGkAtoms::bgcolor,
-  &nsGkAtoms::border,
-  &nsGkAtoms::cellpadding,
-  &nsGkAtoms::cellspacing,
-  &nsGkAtoms::_char,
-  &nsGkAtoms::charoff,
-  &nsGkAtoms::charset,
-  &nsGkAtoms::checked,
-  &nsGkAtoms::cite,
-  &nsGkAtoms::_class,
-  &nsGkAtoms::clear,
-  &nsGkAtoms::cols,
-  &nsGkAtoms::colspan,
-  &nsGkAtoms::color,
-  &nsGkAtoms::contenteditable,
-  &nsGkAtoms::contextmenu,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::controls,
-#endif
-  &nsGkAtoms::compact,
-  &nsGkAtoms::coords,
-  &nsGkAtoms::datetime,
-  &nsGkAtoms::dir,
-  &nsGkAtoms::disabled,
-  &nsGkAtoms::draggable,
-  &nsGkAtoms::enctype,
-  &nsGkAtoms::face,
-  &nsGkAtoms::_for,
-  &nsGkAtoms::frame,
-  &nsGkAtoms::headers,
-  &nsGkAtoms::height,
-  &nsGkAtoms::hidden,
-  &nsGkAtoms::high,
-  &nsGkAtoms::href,
-  &nsGkAtoms::hreflang,
-  &nsGkAtoms::hspace,
-  &nsGkAtoms::icon,
-  &nsGkAtoms::id,
-  &nsGkAtoms::ismap,
-  &nsGkAtoms::itemid,
-  &nsGkAtoms::itemprop,
-  &nsGkAtoms::itemref,
-  &nsGkAtoms::itemscope,
-  &nsGkAtoms::itemtype,
-  &nsGkAtoms::kind,
-  &nsGkAtoms::label,
-  &nsGkAtoms::lang,
-  &nsGkAtoms::list,
-  &nsGkAtoms::longdesc,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::loop,
-  &nsGkAtoms::loopend,
-  &nsGkAtoms::loopstart,
-#endif
-  &nsGkAtoms::low,
-  &nsGkAtoms::max,
-  &nsGkAtoms::maxlength,
-  &nsGkAtoms::media,
-  &nsGkAtoms::method,
-  &nsGkAtoms::min,
-  &nsGkAtoms::mozdonotsend,
-  &nsGkAtoms::multiple,
-  &nsGkAtoms::name,
-  &nsGkAtoms::nohref,
-  &nsGkAtoms::noshade,
-  &nsGkAtoms::novalidate,
-  &nsGkAtoms::nowrap,
-  &nsGkAtoms::open,
-  &nsGkAtoms::optimum,
-  &nsGkAtoms::pattern,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::pixelratio,
-#endif
-  &nsGkAtoms::placeholder,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::playbackrate,
-  &nsGkAtoms::playcount,
-#endif
-  &nsGkAtoms::pointSize,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::poster,
-  &nsGkAtoms::preload,
-#endif
-  &nsGkAtoms::prompt,
-  &nsGkAtoms::pubdate,
-  &nsGkAtoms::radiogroup,
-  &nsGkAtoms::readonly,
-  &nsGkAtoms::rel,
-  &nsGkAtoms::required,
-  &nsGkAtoms::rev,
-  &nsGkAtoms::reversed,
-  &nsGkAtoms::role,
-  &nsGkAtoms::rows,
-  &nsGkAtoms::rowspan,
-  &nsGkAtoms::rules,
-  &nsGkAtoms::scoped,
-  &nsGkAtoms::scope,
-  &nsGkAtoms::selected,
-  &nsGkAtoms::shape,
-  &nsGkAtoms::size,
-  &nsGkAtoms::span,
-  &nsGkAtoms::spellcheck,
-  &nsGkAtoms::src,
-  &nsGkAtoms::srclang,
-  &nsGkAtoms::start,
-  &nsGkAtoms::summary,
-  &nsGkAtoms::tabindex,
-  &nsGkAtoms::target,
-  &nsGkAtoms::title,
-  &nsGkAtoms::type,
-  &nsGkAtoms::usemap,
-  &nsGkAtoms::valign,
-  &nsGkAtoms::value,
-  &nsGkAtoms::vspace,
-  &nsGkAtoms::width,
-  &nsGkAtoms::wrap,
-  nsnull
-};
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -402,14 +402,9 @@ protected:
   static PRInt32 sInteractiveTime;
   // How long to stay in perf mode after initial loading
   static PRInt32 sInitialPerfTime;
   // Should we switch between perf-mode and interactive-mode
   static PRInt32 sEnablePerfMode;
   static PRBool sCanInterruptParser;
 };
 
-// sanitizing content sink whitelists
-extern PRBool IsAttrURI(nsIAtom *aName);
-extern nsIAtom** const kDefaultAllowedTags [];
-extern nsIAtom** const kDefaultAllowedAttributes [];
-
 #endif // _nsContentSink_h_
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -1082,19 +1082,16 @@ nsContentUtils::OfflineAppAllowed(nsIPri
 }
 
 // static
 void
 nsContentUtils::Shutdown()
 {
   sInitialized = PR_FALSE;
 
-  NS_HTMLParanoidFragmentSinkShutdown();
-  NS_XHTMLParanoidFragmentSinkShutdown();
-
   NS_IF_RELEASE(sContentPolicyService);
   sTriedToGetContentPolicy = PR_FALSE;
   PRUint32 i;
   for (i = 0; i < PropertiesFile_COUNT; ++i)
     NS_IF_RELEASE(sStringBundles[i]);
 
   NS_IF_RELEASE(sStringBundleService);
   NS_IF_RELEASE(sConsoleService);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -149,16 +149,17 @@ GK_ATOM(blockquote, "blockquote")
 GK_ATOM(blur, "blur")
 GK_ATOM(body, "body")
 GK_ATOM(boolean, "boolean")
 GK_ATOM(border, "border")
 GK_ATOM(bordercolor, "bordercolor")
 GK_ATOM(both, "both")
 GK_ATOM(bottom, "bottom")
 GK_ATOM(bottomend, "bottomend")
+GK_ATOM(bottomstart, "bottomstart")
 GK_ATOM(bottomleft, "bottomleft")
 GK_ATOM(bottommargin, "bottommargin")
 GK_ATOM(bottompadding, "bottompadding")
 GK_ATOM(bottomright, "bottomright")
 GK_ATOM(box, "box")
 GK_ATOM(br, "br")
 GK_ATOM(braille, "braille")
 GK_ATOM(broadcast, "broadcast")
new file mode 100644
--- /dev/null
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -0,0 +1,1498 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Robert Sayre <sayrer@gmail.com>
+ *   Henri Sivonen <hsivonen@iki.fi>
+ *
+ * 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 "nsTreeSanitizer.h"
+#include "nsCSSParser.h"
+#include "nsCSSProperty.h"
+#include "mozilla/css/Declaration.h"
+#include "mozilla/css/StyleRule.h"
+#include "mozilla/css/Rule.h"
+#include "nsUnicharInputStream.h"
+#include "nsCSSStyleSheet.h"
+#include "nsIDOMCSSRule.h"
+#include "nsAttrName.h"
+#include "nsIScriptSecurityManager.h"
+#include "nsNetUtil.h"
+#include "nsComponentManagerUtils.h"
+#include "nsNullPrincipal.h"
+
+//
+// Thanks to Mark Pilgrim and Sam Ruby for the initial whitelist
+//
+nsIAtom** const kElementsHTML[] = {
+  &nsGkAtoms::a,
+  &nsGkAtoms::abbr,
+  &nsGkAtoms::acronym,
+  &nsGkAtoms::address,
+  &nsGkAtoms::area,
+  &nsGkAtoms::article,
+  &nsGkAtoms::aside,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::audio,
+#endif
+  &nsGkAtoms::b,
+  &nsGkAtoms::bdo,
+  &nsGkAtoms::big,
+  &nsGkAtoms::blockquote,
+  &nsGkAtoms::br,
+  &nsGkAtoms::button,
+  &nsGkAtoms::canvas,
+  &nsGkAtoms::caption,
+  &nsGkAtoms::center,
+  &nsGkAtoms::cite,
+  &nsGkAtoms::code,
+  &nsGkAtoms::col,
+  &nsGkAtoms::colgroup,
+  &nsGkAtoms::command,
+  &nsGkAtoms::datalist,
+  &nsGkAtoms::dd,
+  &nsGkAtoms::del,
+  &nsGkAtoms::details,
+  &nsGkAtoms::dfn,
+  &nsGkAtoms::dir,
+  &nsGkAtoms::div,
+  &nsGkAtoms::dl,
+  &nsGkAtoms::dt,
+  &nsGkAtoms::em,
+  &nsGkAtoms::fieldset,
+  &nsGkAtoms::figcaption,
+  &nsGkAtoms::figure,
+  &nsGkAtoms::font,
+  &nsGkAtoms::footer,
+  &nsGkAtoms::form,
+  &nsGkAtoms::h1,
+  &nsGkAtoms::h2,
+  &nsGkAtoms::h3,
+  &nsGkAtoms::h4,
+  &nsGkAtoms::h5,
+  &nsGkAtoms::h6,
+  &nsGkAtoms::header,
+  &nsGkAtoms::hgroup,
+  &nsGkAtoms::hr,
+  &nsGkAtoms::i,
+  &nsGkAtoms::img,
+  &nsGkAtoms::input,
+  &nsGkAtoms::ins,
+  &nsGkAtoms::kbd,
+  &nsGkAtoms::label,
+  &nsGkAtoms::legend,
+  &nsGkAtoms::li,
+  &nsGkAtoms::link,
+  &nsGkAtoms::listing,
+  &nsGkAtoms::map,
+  &nsGkAtoms::mark,
+  &nsGkAtoms::menu,
+  &nsGkAtoms::meta,
+  &nsGkAtoms::meter,
+  &nsGkAtoms::nav,
+  &nsGkAtoms::nobr,
+  &nsGkAtoms::noscript,
+  &nsGkAtoms::ol,
+  &nsGkAtoms::optgroup,
+  &nsGkAtoms::option,
+  &nsGkAtoms::output,
+  &nsGkAtoms::p,
+  &nsGkAtoms::pre,
+  &nsGkAtoms::progress,
+  &nsGkAtoms::q,
+  &nsGkAtoms::rp,
+  &nsGkAtoms::rt,
+  &nsGkAtoms::ruby,
+  &nsGkAtoms::s,
+  &nsGkAtoms::samp,
+  &nsGkAtoms::section,
+  &nsGkAtoms::select,
+  &nsGkAtoms::small,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::source,
+#endif
+  &nsGkAtoms::span,
+  &nsGkAtoms::strike,
+  &nsGkAtoms::strong,
+  &nsGkAtoms::sub,
+  &nsGkAtoms::summary,
+  &nsGkAtoms::sup,
+  &nsGkAtoms::table,
+  &nsGkAtoms::tbody,
+  &nsGkAtoms::td,
+  &nsGkAtoms::textarea,
+  &nsGkAtoms::tfoot,
+  &nsGkAtoms::th,
+  &nsGkAtoms::thead,
+  &nsGkAtoms::time,
+  &nsGkAtoms::tr,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::track,
+#endif
+  &nsGkAtoms::tt,
+  &nsGkAtoms::u,
+  &nsGkAtoms::ul,
+  &nsGkAtoms::var,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::video,
+#endif
+  &nsGkAtoms::wbr,
+  nsnull
+};
+
+nsIAtom** const kAttributesHTML[] = {
+  &nsGkAtoms::abbr,
+  &nsGkAtoms::accept,
+  &nsGkAtoms::acceptcharset,
+  &nsGkAtoms::accesskey,
+  &nsGkAtoms::action,
+  &nsGkAtoms::align,
+  &nsGkAtoms::alt,
+  &nsGkAtoms::autocomplete,
+  &nsGkAtoms::autofocus,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::autoplay,
+#endif
+  &nsGkAtoms::axis,
+  &nsGkAtoms::background,
+  &nsGkAtoms::bgcolor,
+  &nsGkAtoms::border,
+  &nsGkAtoms::cellpadding,
+  &nsGkAtoms::cellspacing,
+  &nsGkAtoms::_char,
+  &nsGkAtoms::charoff,
+  &nsGkAtoms::charset,
+  &nsGkAtoms::checked,
+  &nsGkAtoms::cite,
+  &nsGkAtoms::_class,
+  &nsGkAtoms::clear,
+  &nsGkAtoms::cols,
+  &nsGkAtoms::colspan,
+  &nsGkAtoms::color,
+  &nsGkAtoms::contenteditable,
+  &nsGkAtoms::contextmenu,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::controls,
+#endif
+  &nsGkAtoms::compact,
+  &nsGkAtoms::coords,
+  &nsGkAtoms::datetime,
+  &nsGkAtoms::dir,
+  &nsGkAtoms::disabled,
+  &nsGkAtoms::draggable,
+  &nsGkAtoms::enctype,
+  &nsGkAtoms::face,
+  &nsGkAtoms::_for,
+  &nsGkAtoms::frame,
+  &nsGkAtoms::headers,
+  &nsGkAtoms::height,
+  &nsGkAtoms::hidden,
+  &nsGkAtoms::high,
+  &nsGkAtoms::href,
+  &nsGkAtoms::hreflang,
+  &nsGkAtoms::hspace,
+  &nsGkAtoms::icon,
+  &nsGkAtoms::id,
+  &nsGkAtoms::ismap,
+  &nsGkAtoms::itemid,
+  &nsGkAtoms::itemprop,
+  &nsGkAtoms::itemref,
+  &nsGkAtoms::itemscope,
+  &nsGkAtoms::itemtype,
+  &nsGkAtoms::kind,
+  &nsGkAtoms::label,
+  &nsGkAtoms::lang,
+  &nsGkAtoms::list,
+  &nsGkAtoms::longdesc,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::loop,
+  &nsGkAtoms::loopend,
+  &nsGkAtoms::loopstart,
+#endif
+  &nsGkAtoms::low,
+  &nsGkAtoms::max,
+  &nsGkAtoms::maxlength,
+  &nsGkAtoms::media,
+  &nsGkAtoms::method,
+  &nsGkAtoms::min,
+  &nsGkAtoms::mozdonotsend,
+  &nsGkAtoms::multiple,
+  &nsGkAtoms::name,
+  &nsGkAtoms::nohref,
+  &nsGkAtoms::noshade,
+  &nsGkAtoms::novalidate,
+  &nsGkAtoms::nowrap,
+  &nsGkAtoms::open,
+  &nsGkAtoms::optimum,
+  &nsGkAtoms::pattern,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::pixelratio,
+#endif
+  &nsGkAtoms::placeholder,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::playbackrate,
+  &nsGkAtoms::playcount,
+#endif
+  &nsGkAtoms::pointSize,
+#ifdef MOZ_MEDIA
+  &nsGkAtoms::poster,
+  &nsGkAtoms::preload,
+#endif
+  &nsGkAtoms::prompt,
+  &nsGkAtoms::pubdate,
+  &nsGkAtoms::radiogroup,
+  &nsGkAtoms::readonly,
+  &nsGkAtoms::rel,
+  &nsGkAtoms::required,
+  &nsGkAtoms::rev,
+  &nsGkAtoms::reversed,
+  &nsGkAtoms::role,
+  &nsGkAtoms::rows,
+  &nsGkAtoms::rowspan,
+  &nsGkAtoms::rules,
+  &nsGkAtoms::scoped,
+  &nsGkAtoms::scope,
+  &nsGkAtoms::selected,
+  &nsGkAtoms::shape,
+  &nsGkAtoms::size,
+  &nsGkAtoms::span,
+  &nsGkAtoms::spellcheck,
+  &nsGkAtoms::src,
+  &nsGkAtoms::srclang,
+  &nsGkAtoms::start,
+  &nsGkAtoms::summary,
+  &nsGkAtoms::tabindex,
+  &nsGkAtoms::target,
+  &nsGkAtoms::title,
+  &nsGkAtoms::type,
+  &nsGkAtoms::usemap,
+  &nsGkAtoms::valign,
+  &nsGkAtoms::value,
+  &nsGkAtoms::vspace,
+  &nsGkAtoms::width,
+  &nsGkAtoms::wrap,
+  nsnull
+};
+
+nsIAtom** const kURLAttributesHTML[] = {
+  &nsGkAtoms::action,
+  &nsGkAtoms::href,
+  &nsGkAtoms::src,
+  &nsGkAtoms::longdesc,
+  &nsGkAtoms::cite,
+  &nsGkAtoms::background,
+  nsnull
+};
+
+nsIAtom** const kElementsSVG[] = {
+#ifdef MOZ_SVG
+  &nsGkAtoms::a, // a
+  &nsGkAtoms::altGlyph, // altGlyph
+  &nsGkAtoms::altGlyphDef, // altGlyphDef
+  &nsGkAtoms::altGlyphItem, // altGlyphItem
+  &nsGkAtoms::animate, // animate
+  &nsGkAtoms::animateColor, // animateColor
+  &nsGkAtoms::animateMotion, // animateMotion
+  &nsGkAtoms::animateTransform, // animateTransform
+  &nsGkAtoms::circle, // circle
+  &nsGkAtoms::clipPath, // clipPath
+  &nsGkAtoms::colorProfile, // color-profile
+  &nsGkAtoms::cursor, // cursor
+  &nsGkAtoms::defs, // defs
+  &nsGkAtoms::desc, // desc
+  &nsGkAtoms::ellipse, // ellipse
+  &nsGkAtoms::elevation, // elevation
+  &nsGkAtoms::erode, // erode
+  &nsGkAtoms::ex, // ex
+  &nsGkAtoms::exact, // exact
+  &nsGkAtoms::exponent, // exponent
+  &nsGkAtoms::feBlend, // feBlend
+  &nsGkAtoms::feColorMatrix, // feColorMatrix
+  &nsGkAtoms::feComponentTransfer, // feComponentTransfer
+  &nsGkAtoms::feComposite, // feComposite
+  &nsGkAtoms::feConvolveMatrix, // feConvolveMatrix
+  &nsGkAtoms::feDiffuseLighting, // feDiffuseLighting
+  &nsGkAtoms::feDisplacementMap, // feDisplacementMap
+  &nsGkAtoms::feDistantLight, // feDistantLight
+  &nsGkAtoms::feFlood, // feFlood
+  &nsGkAtoms::feFuncA, // feFuncA
+  &nsGkAtoms::feFuncB, // feFuncB
+  &nsGkAtoms::feFuncG, // feFuncG
+  &nsGkAtoms::feFuncR, // feFuncR
+  &nsGkAtoms::feGaussianBlur, // feGaussianBlur
+  &nsGkAtoms::feImage, // feImage
+  &nsGkAtoms::feMerge, // feMerge
+  &nsGkAtoms::feMergeNode, // feMergeNode
+  &nsGkAtoms::feMorphology, // feMorphology
+  &nsGkAtoms::feOffset, // feOffset
+  &nsGkAtoms::fePointLight, // fePointLight
+  &nsGkAtoms::feSpecularLighting, // feSpecularLighting
+  &nsGkAtoms::feSpotLight, // feSpotLight
+  &nsGkAtoms::feTile, // feTile
+  &nsGkAtoms::feTurbulence, // feTurbulence
+  &nsGkAtoms::filter, // filter
+  &nsGkAtoms::font, // font
+  &nsGkAtoms::font_face, // font-face
+  &nsGkAtoms::font_face_format, // font-face-format
+  &nsGkAtoms::font_face_name, // font-face-name
+  &nsGkAtoms::font_face_src, // font-face-src
+  &nsGkAtoms::font_face_uri, // font-face-uri
+  &nsGkAtoms::foreignObject, // foreignObject
+  &nsGkAtoms::g, // g
+  &nsGkAtoms::glyph, // glyph
+  &nsGkAtoms::glyphRef, // glyphRef
+  &nsGkAtoms::hkern, // hkern
+  &nsGkAtoms::image, // image
+  &nsGkAtoms::line, // line
+  &nsGkAtoms::linearGradient, // linearGradient
+  &nsGkAtoms::marker, // marker
+  &nsGkAtoms::mask, // mask
+  &nsGkAtoms::metadata, // metadata
+  &nsGkAtoms::missingGlyph, // missingGlyph
+  &nsGkAtoms::mpath, // mpath
+  &nsGkAtoms::path, // path
+  &nsGkAtoms::pattern, // pattern
+  &nsGkAtoms::polygon, // polygon
+  &nsGkAtoms::polyline, // polyline
+  &nsGkAtoms::radialGradient, // radialGradient
+  &nsGkAtoms::rect, // rect
+  &nsGkAtoms::set, // set
+  &nsGkAtoms::stop, // stop
+  &nsGkAtoms::svg, // svg
+  &nsGkAtoms::svgSwitch, // switch
+  &nsGkAtoms::symbol, // symbol
+  &nsGkAtoms::text, // text
+  &nsGkAtoms::textPath, // textPath
+  &nsGkAtoms::title, // title
+  &nsGkAtoms::tref, // tref
+  &nsGkAtoms::tspan, // tspan
+  &nsGkAtoms::use, // use
+  &nsGkAtoms::view, // view
+  &nsGkAtoms::vkern, // vkern
+#endif
+  nsnull
+};
+
+nsIAtom** const kAttributesSVG[] = {
+#ifdef MOZ_SVG
+  // accent-height
+#ifdef MOZ_SMIL
+  &nsGkAtoms::accumulate, // accumulate
+  &nsGkAtoms::additive, // additive
+#endif
+  &nsGkAtoms::alignment_baseline, // alignment-baseline
+  // alphabetic
+  &nsGkAtoms::amplitude, // amplitude
+  // arabic-form
+  // ascent
+#ifdef MOZ_SMIL
+  &nsGkAtoms::attributeName, // attributeName
+  &nsGkAtoms::attributeType, // attributeType
+#endif
+  &nsGkAtoms::azimuth, // azimuth
+  &nsGkAtoms::baseFrequency, // baseFrequency
+  &nsGkAtoms::baseline_shift, // baseline-shift
+  // baseProfile
+  // bbox
+#ifdef MOZ_SMIL
+  &nsGkAtoms::begin, // begin
+#endif
+  &nsGkAtoms::bias, // bias
+#ifdef MOZ_SMIL
+  &nsGkAtoms::by, // by
+  &nsGkAtoms::calcMode, // calcMode
+#endif
+  // cap-height
+  &nsGkAtoms::_class, // class
+  &nsGkAtoms::clip_path, // clip-path
+  &nsGkAtoms::clip_rule, // clip-rule
+  &nsGkAtoms::clipPathUnits, // clipPathUnits
+  &nsGkAtoms::color, // color
+  &nsGkAtoms::colorInterpolation, // color-interpolation
+  &nsGkAtoms::colorInterpolationFilters, // color-interpolation-filters
+  // contentScriptType
+  // contentStyleType
+  &nsGkAtoms::cursor, // cursor
+  &nsGkAtoms::cx, // cx
+  &nsGkAtoms::cy, // cy
+  &nsGkAtoms::d, // d
+  // descent
+  &nsGkAtoms::diffuseConstant, // diffuseConstant
+  &nsGkAtoms::direction, // direction
+  &nsGkAtoms::display, // display
+  &nsGkAtoms::divisor, // divisor
+  &nsGkAtoms::dominant_baseline, // dominant-baseline
+#ifdef MOZ_SMIL
+  &nsGkAtoms::dur, // dur
+#endif
+  &nsGkAtoms::dx, // dx
+  &nsGkAtoms::dy, // dy
+  &nsGkAtoms::edgeMode, // edgeMode
+  &nsGkAtoms::elevation, // elevation
+  // enable-background
+#ifdef MOZ_SMIL
+  &nsGkAtoms::end, // end
+#endif
+  &nsGkAtoms::fill, // fill
+  &nsGkAtoms::fill_opacity, // fill-opacity
+  &nsGkAtoms::fill_rule, // fill-rule
+  &nsGkAtoms::filter, // filter
+  &nsGkAtoms::filterRes, // filterRes
+  &nsGkAtoms::filterUnits, // filterUnits
+  &nsGkAtoms::flood_color, // flood-color
+  &nsGkAtoms::flood_opacity, // flood-opacity
+  // XXX focusable
+  &nsGkAtoms::font, // font
+  &nsGkAtoms::font_family, // font-family
+  &nsGkAtoms::font_size, // font-size
+  &nsGkAtoms::font_size_adjust, // font-size-adjust
+  &nsGkAtoms::font_stretch, // font-stretch
+  &nsGkAtoms::font_style, // font-style
+  &nsGkAtoms::font_variant, // font-variant
+  &nsGkAtoms::fontWeight, // font-weight
+  &nsGkAtoms::format, // format
+  &nsGkAtoms::from, // from
+  &nsGkAtoms::fx, // fx
+  &nsGkAtoms::fy, // fy
+  // g1
+  // g2
+  // glyph-name
+  // glyphRef
+  &nsGkAtoms::glyph_orientation_horizontal, // glyph-orientation-horizontal
+  &nsGkAtoms::glyph_orientation_vertical, // glyph-orientation-vertical
+  &nsGkAtoms::gradientTransform, // gradientTransform
+  &nsGkAtoms::gradientUnits, // gradientUnits
+  &nsGkAtoms::height, // height
+  // horiz-adv-x
+  // horiz-origin-x
+  // horiz-origin-y
+  &nsGkAtoms::id, // id
+  // ideographic
+  &nsGkAtoms::image_rendering, // image-rendering
+  &nsGkAtoms::in, // in
+  &nsGkAtoms::in2, // in2
+  &nsGkAtoms::intercept, // intercept
+  // k
+  &nsGkAtoms::k1, // k1
+  &nsGkAtoms::k2, // k2
+  &nsGkAtoms::k3, // k3
+  &nsGkAtoms::k4, // k4
+  &nsGkAtoms::kerning, // kerning
+  &nsGkAtoms::kernelMatrix, // kernelMatrix
+  &nsGkAtoms::kernelUnitLength, // kernelUnitLength
+#ifdef MOZ_SMIL
+  &nsGkAtoms::keyPoints, // keyPoints
+  &nsGkAtoms::keySplines, // keySplines
+  &nsGkAtoms::keyTimes, // keyTimes
+#endif
+  &nsGkAtoms::lang, // lang
+  // lengthAdjust
+  &nsGkAtoms::letter_spacing, // letter-spacing
+  &nsGkAtoms::lighting_color, // lighting-color
+  &nsGkAtoms::limitingConeAngle, // limitingConeAngle
+  // local
+  &nsGkAtoms::marker, // marker
+  &nsGkAtoms::marker_end, // marker-end
+  &nsGkAtoms::marker_mid, // marker-mid
+  &nsGkAtoms::marker_start, // marker-start
+  &nsGkAtoms::markerHeight, // markerHeight
+  &nsGkAtoms::markerUnits, // markerUnits
+  &nsGkAtoms::markerWidth, // markerWidth
+  &nsGkAtoms::mask, // mask
+  &nsGkAtoms::maskContentUnits, // maskContentUnits
+  &nsGkAtoms::maskUnits, // maskUnits
+  // mathematical
+  &nsGkAtoms::max, // max
+  &nsGkAtoms::media, // media
+  &nsGkAtoms::method, // method
+  &nsGkAtoms::min, // min
+  &nsGkAtoms::mode, // mode
+  &nsGkAtoms::name, // name
+  &nsGkAtoms::numOctaves, // numOctaves
+  &nsGkAtoms::offset, // offset
+  &nsGkAtoms::opacity, // opacity
+  &nsGkAtoms::_operator, // operator
+  &nsGkAtoms::order, // order
+  &nsGkAtoms::orient, // orient
+  &nsGkAtoms::orientation, // orientation
+  // origin
+  // overline-position
+  // overline-thickness
+  &nsGkAtoms::overflow, // overflow
+  // panose-1
+  &nsGkAtoms::path, // path
+  &nsGkAtoms::pathLength, // pathLength
+  &nsGkAtoms::patternContentUnits, // patternContentUnits
+  &nsGkAtoms::patternTransform, // patternTransform
+  &nsGkAtoms::patternUnits, // patternUnits
+  &nsGkAtoms::pointer_events, // pointer-events XXX is this safe?
+  &nsGkAtoms::points, // points
+  &nsGkAtoms::pointsAtX, // pointsAtX
+  &nsGkAtoms::pointsAtY, // pointsAtY
+  &nsGkAtoms::pointsAtZ, // pointsAtZ
+  &nsGkAtoms::preserveAlpha, // preserveAlpha
+  &nsGkAtoms::preserveAspectRatio, // preserveAspectRatio
+  &nsGkAtoms::primitiveUnits, // primitiveUnits
+  &nsGkAtoms::r, // r
+  &nsGkAtoms::radius, // radius
+  &nsGkAtoms::refX, // refX
+  &nsGkAtoms::refY, // refY
+#ifdef MOZ_SMIL
+  &nsGkAtoms::repeatCount, // repeatCount
+  &nsGkAtoms::repeatDur, // repeatDur
+#endif
+  &nsGkAtoms::requiredExtensions, // requiredExtensions
+  &nsGkAtoms::requiredFeatures, // requiredFeatures
+#ifdef MOZ_SMIL
+  &nsGkAtoms::restart, // restart
+#endif
+  &nsGkAtoms::result, // result
+  &nsGkAtoms::rotate, // rotate
+  &nsGkAtoms::rx, // rx
+  &nsGkAtoms::ry, // ry
+  &nsGkAtoms::scale, // scale
+  &nsGkAtoms::seed, // seed
+  &nsGkAtoms::shape_rendering, // shape-rendering
+  &nsGkAtoms::slope, // slope
+  &nsGkAtoms::spacing, // spacing
+  &nsGkAtoms::specularConstant, // specularConstant
+  &nsGkAtoms::specularExponent, // specularExponent
+  &nsGkAtoms::spreadMethod, // spreadMethod
+  &nsGkAtoms::startOffset, // startOffset
+  &nsGkAtoms::stdDeviation, // stdDeviation
+  // stemh
+  // stemv
+  &nsGkAtoms::stitchTiles, // stitchTiles
+  &nsGkAtoms::stop_color, // stop-color
+  &nsGkAtoms::stop_opacity, // stop-opacity
+  // strikethrough-position
+  // strikethrough-thickness
+  &nsGkAtoms::string, // string
+  &nsGkAtoms::stroke, // stroke
+  &nsGkAtoms::stroke_dasharray, // stroke-dasharray
+  &nsGkAtoms::stroke_dashoffset, // stroke-dashoffset
+  &nsGkAtoms::stroke_linecap, // stroke-linecap
+  &nsGkAtoms::stroke_linejoin, // stroke-linejoin
+  &nsGkAtoms::stroke_miterlimit, // stroke-miterlimit
+  &nsGkAtoms::stroke_opacity, // stroke-opacity
+  &nsGkAtoms::stroke_width, // stroke-width
+  &nsGkAtoms::surfaceScale, // surfaceScale
+  &nsGkAtoms::systemLanguage, // systemLanguage
+  &nsGkAtoms::tableValues, // tableValues
+  &nsGkAtoms::target, // target
+  &nsGkAtoms::targetX, // targetX
+  &nsGkAtoms::targetY, // targetY
+  &nsGkAtoms::text_anchor, // text-anchor
+  &nsGkAtoms::text_decoration, // text-decoration
+  // textLength
+  &nsGkAtoms::text_rendering, // text-rendering
+  &nsGkAtoms::title, // title
+#ifdef MOZ_SMIL
+  &nsGkAtoms::to, // to
+#endif
+  &nsGkAtoms::transform, // transform
+  &nsGkAtoms::type, // type
+  // u1
+  // u2
+  // underline-position
+  // underline-thickness
+  // unicode
+  &nsGkAtoms::unicode_bidi, // unicode-bidi
+  // unicode-range
+  // units-per-em
+  // v-alphabetic
+  // v-hanging
+  // v-ideographic
+  // v-mathematical
+  &nsGkAtoms::values, // values
+  // vert-adv-y
+  // vert-origin-x
+  // vert-origin-y
+  &nsGkAtoms::viewBox, // viewBox
+  &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
+  &nsGkAtoms::xChannelSelector, // xChannelSelector
+  &nsGkAtoms::y, // y
+  &nsGkAtoms::y1, // y1
+  &nsGkAtoms::y2, // y2
+  &nsGkAtoms::yChannelSelector, // yChannelSelector
+  &nsGkAtoms::z, // z
+  &nsGkAtoms::zoomAndPan, // zoomAndPan
+#endif
+  nsnull
+};
+
+nsIAtom** const kURLAttributesSVG[] = {
+  nsnull
+};
+
+nsIAtom** const kElementsMathML[] = {
+   &nsGkAtoms::abs_, // abs
+   &nsGkAtoms::_and, // and
+   &nsGkAtoms::annotation_, // annotation
+   &nsGkAtoms::annotation_xml_, // annotation-xml
+   &nsGkAtoms::apply_, // apply
+   &nsGkAtoms::approx_, // approx
+   &nsGkAtoms::arccos_, // arccos
+   &nsGkAtoms::arccosh_, // arccosh
+   &nsGkAtoms::arccot_, // arccot
+   &nsGkAtoms::arccoth_, // arccoth
+   &nsGkAtoms::arccsc_, // arccsc
+   &nsGkAtoms::arccsch_, // arccsch
+   &nsGkAtoms::arcsec_, // arcsec
+   &nsGkAtoms::arcsech_, // arcsech
+   &nsGkAtoms::arcsin_, // arcsin
+   &nsGkAtoms::arcsinh_, // arcsinh
+   &nsGkAtoms::arctan_, // arctan
+   &nsGkAtoms::arctanh_, // arctanh
+   &nsGkAtoms::arg_, // arg
+   &nsGkAtoms::bind_, // bind
+   &nsGkAtoms::bvar_, // bvar
+   &nsGkAtoms::card_, // card
+   &nsGkAtoms::cartesianproduct_, // cartesianproduct
+   &nsGkAtoms::cbytes_, // cbytes
+   &nsGkAtoms::ceiling, // ceiling
+   &nsGkAtoms::cerror_, // cerror
+   &nsGkAtoms::ci_, // ci
+   &nsGkAtoms::cn_, // cn
+   &nsGkAtoms::codomain_, // codomain
+   &nsGkAtoms::complexes_, // complexes
+   &nsGkAtoms::compose_, // compose
+   &nsGkAtoms::condition_, // condition
+   &nsGkAtoms::conjugate_, // conjugate
+   &nsGkAtoms::cos_, // cos
+   &nsGkAtoms::cosh_, // cosh
+   &nsGkAtoms::cot_, // cot
+   &nsGkAtoms::coth_, // coth
+   &nsGkAtoms::cs_, // cs
+   &nsGkAtoms::csc_, // csc
+   &nsGkAtoms::csch_, // csch
+   &nsGkAtoms::csymbol_, // csymbol
+   &nsGkAtoms::curl_, // curl
+   &nsGkAtoms::declare, // declare
+   &nsGkAtoms::degree_, // degree
+   &nsGkAtoms::determinant_, // determinant
+   &nsGkAtoms::diff_, // diff
+   &nsGkAtoms::divergence_, // divergence
+   &nsGkAtoms::divide_, // divide
+   &nsGkAtoms::domain_, // domain
+   &nsGkAtoms::domainofapplication_, // domainofapplication
+   &nsGkAtoms::el_, // el
+   &nsGkAtoms::emptyset_, // emptyset
+   &nsGkAtoms::eq_, // eq
+   &nsGkAtoms::equivalent_, // equivalent
+   &nsGkAtoms::eulergamma_, // eulergamma
+   &nsGkAtoms::exists_, // exists
+   &nsGkAtoms::exp_, // exp
+   &nsGkAtoms::exponentiale_, // exponentiale
+   &nsGkAtoms::factorial_, // factorial
+   &nsGkAtoms::factorof_, // factorof
+   &nsGkAtoms::_false, // false
+   &nsGkAtoms::floor, // floor
+   &nsGkAtoms::fn_, // fn
+   &nsGkAtoms::forall_, // forall
+   &nsGkAtoms::gcd_, // gcd
+   &nsGkAtoms::geq_, // geq
+   &nsGkAtoms::grad, // grad
+   &nsGkAtoms::gt_, // gt
+   &nsGkAtoms::ident_, // ident
+   &nsGkAtoms::image, // image
+   &nsGkAtoms::imaginary_, // imaginary
+   &nsGkAtoms::imaginaryi_, // imaginaryi
+   &nsGkAtoms::implies_, // implies
+   &nsGkAtoms::in, // in
+   &nsGkAtoms::infinity, // infinity
+   &nsGkAtoms::int_, // int
+   &nsGkAtoms::integers_, // integers
+   &nsGkAtoms::intersect_, // intersect
+   &nsGkAtoms::interval_, // interval
+   &nsGkAtoms::inverse_, // inverse
+   &nsGkAtoms::lambda_, // lambda
+   &nsGkAtoms::laplacian_, // laplacian
+   &nsGkAtoms::lcm_, // lcm
+   &nsGkAtoms::leq_, // leq
+   &nsGkAtoms::limit_, // limit
+   &nsGkAtoms::list_, // list
+   &nsGkAtoms::ln_, // ln
+   &nsGkAtoms::log_, // log
+   &nsGkAtoms::logbase_, // logbase
+   &nsGkAtoms::lowlimit_, // lowlimit
+   &nsGkAtoms::lt_, // lt
+   &nsGkAtoms::maction_, // maction
+   &nsGkAtoms::malign_, // malign
+   &nsGkAtoms::maligngroup_, // maligngroup
+   &nsGkAtoms::malignmark_, // malignmark
+   &nsGkAtoms::malignscope_, // malignscope
+   &nsGkAtoms::math, // math
+   &nsGkAtoms::matrix, // matrix
+   &nsGkAtoms::matrixrow_, // matrixrow
+   &nsGkAtoms::max, // max
+   &nsGkAtoms::mean_, // mean
+   &nsGkAtoms::median_, // median
+   &nsGkAtoms::menclose_, // menclose
+   &nsGkAtoms::merror_, // merror
+   &nsGkAtoms::mfenced_, // mfenced
+   &nsGkAtoms::mfrac_, // mfrac
+   &nsGkAtoms::mfraction_, // mfraction
+   &nsGkAtoms::mglyph_, // mglyph
+   &nsGkAtoms::mi_, // mi
+   &nsGkAtoms::min, // min
+   &nsGkAtoms::minus_, // minus
+   &nsGkAtoms::mlabeledtr_, // mlabeledtr
+   &nsGkAtoms::mlongdiv_, // mlongdiv
+   &nsGkAtoms::mmultiscripts_, // mmultiscripts
+   &nsGkAtoms::mn_, // mn
+   &nsGkAtoms::mo_, // mo
+   &nsGkAtoms::mode, // mode
+   &nsGkAtoms::moment_, // moment
+   &nsGkAtoms::momentabout_, // momentabout
+   &nsGkAtoms::mover_, // mover
+   &nsGkAtoms::mpadded_, // mpadded
+   &nsGkAtoms::mphantom_, // mphantom
+   &nsGkAtoms::mprescripts_, // mprescripts
+   &nsGkAtoms::mroot_, // mroot
+   &nsGkAtoms::mrow_, // mrow
+   &nsGkAtoms::ms_, // ms
+   &nsGkAtoms::mscarries_, // mscarries
+   &nsGkAtoms::mscarry_, // mscarry
+   &nsGkAtoms::msgroup_, // msgroup
+   &nsGkAtoms::msline_, // msline
+   &nsGkAtoms::mspace_, // mspace
+   &nsGkAtoms::msqrt_, // msqrt
+   &nsGkAtoms::msrow_, // msrow
+   &nsGkAtoms::mstack_, // mstack
+   &nsGkAtoms::mstyle_, // mstyle
+   &nsGkAtoms::msub_, // msub
+   &nsGkAtoms::msubsup_, // msubsup
+   &nsGkAtoms::msup_, // msup
+   &nsGkAtoms::mtable_, // mtable
+   &nsGkAtoms::mtd_, // mtd
+   &nsGkAtoms::mtext_, // mtext
+   &nsGkAtoms::mtr_, // mtr
+   &nsGkAtoms::munder_, // munder
+   &nsGkAtoms::munderover_, // munderover
+   &nsGkAtoms::naturalnumbers_, // naturalnumbers
+   &nsGkAtoms::neq_, // neq
+   &nsGkAtoms::none, // none
+   &nsGkAtoms::_not, // not
+   &nsGkAtoms::notanumber_, // notanumber
+   &nsGkAtoms::note_, // note
+   &nsGkAtoms::notin_, // notin
+   &nsGkAtoms::notprsubset_, // notprsubset
+   &nsGkAtoms::notsubset_, // notsubset
+   &nsGkAtoms::_or, // or
+   &nsGkAtoms::otherwise, // otherwise
+   &nsGkAtoms::outerproduct_, // outerproduct
+   &nsGkAtoms::partialdiff_, // partialdiff
+   &nsGkAtoms::pi_, // pi
+   &nsGkAtoms::piece_, // piece
+   &nsGkAtoms::piecewise_, // piecewise
+   &nsGkAtoms::plus_, // plus
+   &nsGkAtoms::power_, // power
+   &nsGkAtoms::primes_, // primes
+   &nsGkAtoms::product_, // product
+   &nsGkAtoms::prsubset_, // prsubset
+   &nsGkAtoms::quotient_, // quotient
+   &nsGkAtoms::rationals_, // rationals
+   &nsGkAtoms::real_, // real
+   &nsGkAtoms::reals_, // reals
+   &nsGkAtoms::reln_, // reln
+   &nsGkAtoms::rem, // rem
+   &nsGkAtoms::root_, // root
+   &nsGkAtoms::scalarproduct_, // scalarproduct
+   &nsGkAtoms::sdev_, // sdev
+   &nsGkAtoms::sec_, // sec
+   &nsGkAtoms::sech_, // sech
+   &nsGkAtoms::selector_, // selector
+   &nsGkAtoms::semantics_, // semantics
+   &nsGkAtoms::sep_, // sep
+   &nsGkAtoms::set_, // set
+   &nsGkAtoms::setdiff_, // setdiff
+   &nsGkAtoms::share_, // share
+   &nsGkAtoms::sin_, // sin
+   &nsGkAtoms::sinh_, // sinh
+   &nsGkAtoms::subset_, // subset
+   &nsGkAtoms::sum, // sum
+   &nsGkAtoms::tan_, // tan
+   &nsGkAtoms::tanh_, // tanh
+   &nsGkAtoms::tendsto_, // tendsto
+   &nsGkAtoms::times_, // times
+   &nsGkAtoms::transpose_, // transpose
+   &nsGkAtoms::_true, // true
+   &nsGkAtoms::union_, // union
+   &nsGkAtoms::uplimit_, // uplimit
+   &nsGkAtoms::variance_, // variance
+   &nsGkAtoms::vector_, // vector
+   &nsGkAtoms::vectorproduct_, // vectorproduct
+   &nsGkAtoms::xor_, // xor
+  nsnull
+};
+
+nsIAtom** const kAttributesMathML[] = {
+   &nsGkAtoms::accent_, // accent
+   &nsGkAtoms::accentunder_, // accentunder
+   &nsGkAtoms::actiontype_, // actiontype
+   &nsGkAtoms::align, // align
+   &nsGkAtoms::alignmentscope_, // alignmentscope
+   &nsGkAtoms::alt, // alt
+   &nsGkAtoms::altimg_, // altimg
+   &nsGkAtoms::altimg_height_, // altimg-height
+   &nsGkAtoms::altimg_valign_, // altimg-valign
+   &nsGkAtoms::altimg_width_, // altimg-width
+   &nsGkAtoms::background, // background
+   &nsGkAtoms::base, // base
+   &nsGkAtoms::bevelled_, // bevelled
+   &nsGkAtoms::cd_, // cd
+   &nsGkAtoms::cdgroup_, // cdgroup
+   &nsGkAtoms::charalign_, // charalign
+   &nsGkAtoms::close, // close
+   &nsGkAtoms::closure_, // closure
+   &nsGkAtoms::color, // color
+   &nsGkAtoms::columnalign_, // columnalign
+   &nsGkAtoms::columnalignment_, // columnalignment
+   &nsGkAtoms::columnlines_, // columnlines
+   &nsGkAtoms::columnspacing_, // columnspacing
+   &nsGkAtoms::columnspan_, // columnspan
+   &nsGkAtoms::columnwidth_, // columnwidth
+   &nsGkAtoms::crossout_, // crossout
+   &nsGkAtoms::decimalpoint_, // decimalpoint
+   &nsGkAtoms::definitionURL_, // definitionURL
+   &nsGkAtoms::denomalign_, // denomalign
+   &nsGkAtoms::depth_, // depth
+   &nsGkAtoms::dir, // dir
+   &nsGkAtoms::display, // display
+   &nsGkAtoms::displaystyle_, // displaystyle
+   &nsGkAtoms::edge_, // edge
+   &nsGkAtoms::encoding, // encoding
+   &nsGkAtoms::equalcolumns_, // equalcolumns
+   &nsGkAtoms::equalrows_, // equalrows
+   &nsGkAtoms::fence_, // fence
+   &nsGkAtoms::fontfamily_, // fontfamily
+   &nsGkAtoms::fontsize_, // fontsize
+   &nsGkAtoms::fontstyle_, // fontstyle
+   &nsGkAtoms::fontweight_, // fontweight
+   &nsGkAtoms::form, // form
+   &nsGkAtoms::frame, // frame
+   &nsGkAtoms::framespacing_, // framespacing
+   &nsGkAtoms::groupalign_, // groupalign
+   &nsGkAtoms::height, // height
+   &nsGkAtoms::href, // href
+   &nsGkAtoms::id, // id
+   &nsGkAtoms::indentalign_, // indentalign
+   &nsGkAtoms::indentalignfirst_, // indentalignfirst
+   &nsGkAtoms::indentalignlast_, // indentalignlast
+   &nsGkAtoms::indentshift_, // indentshift
+   &nsGkAtoms::indentshiftfirst_, // indentshiftfirst
+   &nsGkAtoms::indenttarget_, // indenttarget
+   &nsGkAtoms::index, // index
+   &nsGkAtoms::integer, // integer
+   &nsGkAtoms::largeop_, // largeop
+   &nsGkAtoms::length, // length
+   &nsGkAtoms::linebreak_, // linebreak
+   &nsGkAtoms::linebreakmultchar_, // linebreakmultchar
+   &nsGkAtoms::linebreakstyle_, // linebreakstyle
+   &nsGkAtoms::linethickness_, // linethickness
+   &nsGkAtoms::location_, // location
+   &nsGkAtoms::longdivstyle_, // longdivstyle
+   &nsGkAtoms::lquote_, // lquote
+   &nsGkAtoms::lspace_, // lspace
+   &nsGkAtoms::ltr, // ltr
+   &nsGkAtoms::mathbackground_, // mathbackground
+   &nsGkAtoms::mathcolor_, // mathcolor
+   &nsGkAtoms::mathsize_, // mathsize
+   &nsGkAtoms::mathvariant_, // mathvariant
+   &nsGkAtoms::maxsize_, // maxsize
+   &nsGkAtoms::mediummathspace_, // mediummathspace
+   &nsGkAtoms::minlabelspacing_, // minlabelspacing
+   &nsGkAtoms::minsize_, // minsize
+   &nsGkAtoms::monospaced_, // monospaced
+   &nsGkAtoms::movablelimits_, // movablelimits
+   &nsGkAtoms::msgroup_, // msgroup
+   &nsGkAtoms::name, // name
+   &nsGkAtoms::negativemediummathspace_, // negativemediummathspace
+   &nsGkAtoms::negativethickmathspace_, // negativethickmathspace
+   &nsGkAtoms::negativethinmathspace_, // negativethinmathspace
+   &nsGkAtoms::negativeverythickmathspace_, // negativeverythickmathspace
+   &nsGkAtoms::negativeverythinmathspace_, // negativeverythinmathspace
+   &nsGkAtoms::negativeveryverythickmathspace_, // negativeveryverythickmathspace
+   &nsGkAtoms::negativeveryverythinmathspace_, // negativeveryverythinmathspace
+   &nsGkAtoms::newline, // newline
+   &nsGkAtoms::notation_, // notation
+   &nsGkAtoms::numalign_, // numalign
+   &nsGkAtoms::number, // number
+   &nsGkAtoms::open, // open
+   &nsGkAtoms::order, // order
+   &nsGkAtoms::other_, // other
+   &nsGkAtoms::overflow, // overflow
+   &nsGkAtoms::position, // position
+   &nsGkAtoms::role, // role
+   &nsGkAtoms::rowalign_, // rowalign
+   &nsGkAtoms::rowlines_, // rowlines
+   &nsGkAtoms::rowspacing_, // rowspacing
+   &nsGkAtoms::rowspan, // rowspan
+   &nsGkAtoms::rquote_, // rquote
+   &nsGkAtoms::rspace_, // rspace
+   &nsGkAtoms::schemaLocation_, // schemaLocation
+   &nsGkAtoms::scriptlevel_, // scriptlevel
+   &nsGkAtoms::scriptminsize_, // scriptminsize
+   &nsGkAtoms::scriptsize_, // scriptsize
+   &nsGkAtoms::scriptsizemultiplier_, // scriptsizemultiplier
+   &nsGkAtoms::selection_, // selection
+   &nsGkAtoms::separator_, // separator
+   &nsGkAtoms::separators_, // separators
+   &nsGkAtoms::shift_, // shift
+   &nsGkAtoms::side_, // side
+   &nsGkAtoms::src, // src
+   &nsGkAtoms::stackalign_, // stackalign
+   &nsGkAtoms::stretchy_, // stretchy
+   &nsGkAtoms::subscriptshift_, // subscriptshift
+   &nsGkAtoms::superscriptshift_, // superscriptshift
+   &nsGkAtoms::symmetric_, // symmetric
+   &nsGkAtoms::thickmathspace_, // thickmathspace
+   &nsGkAtoms::thinmathspace_, // thinmathspace
+   &nsGkAtoms::type, // type
+   &nsGkAtoms::verythickmathspace_, // verythickmathspace
+   &nsGkAtoms::verythinmathspace_, // verythinmathspace
+   &nsGkAtoms::veryverythickmathspace_, // veryverythickmathspace
+   &nsGkAtoms::veryverythinmathspace_, // veryverythinmathspace
+   &nsGkAtoms::voffset_, // voffset
+   &nsGkAtoms::width, // width
+   &nsGkAtoms::xref_, // xref
+  nsnull
+};
+
+nsIAtom** const kURLAttributesMathML[] = {
+  &nsGkAtoms::href,
+  &nsGkAtoms::src,
+  &nsGkAtoms::definitionURL_,
+  nsnull
+};
+
+nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsHTML = nsnull;
+nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesHTML = nsnull;
+nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsSVG = nsnull;
+nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesSVG = nsnull;
+nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsMathML = nsnull;
+nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesMathML = nsnull;
+nsIPrincipal* nsTreeSanitizer::sNullPrincipal = nsnull;
+
+nsTreeSanitizer::nsTreeSanitizer(PRBool aAllowStyles, PRBool aAllowComments)
+ : mAllowStyles(aAllowStyles)
+ , mAllowComments(aAllowComments)
+{
+  if (!sElementsHTML) {
+    // Initialize lazily to avoid having to initialize at all if the user
+    // doesn't paste HTML or load feeds.
+    InitializeStatics();
+  }
+}
+
+PRBool
+nsTreeSanitizer::MustFlatten(PRInt32 aNamespace, nsIAtom* aLocal)
+{
+  if (aNamespace == kNameSpaceID_XHTML) {
+    return !sElementsHTML->GetEntry(aLocal);
+  }
+  if (aNamespace == kNameSpaceID_SVG) {
+    return !sElementsSVG->GetEntry(aLocal);
+  }
+  if (aNamespace == kNameSpaceID_MathML) {
+    return !sElementsMathML->GetEntry(aLocal);
+  }
+  return PR_TRUE;
+}
+
+PRBool
+nsTreeSanitizer::IsURL(nsIAtom*** aURLs, nsIAtom* aLocalName)
+{
+  nsIAtom** atomPtrPtr;
+  while ((atomPtrPtr = *aURLs)) {
+    if (*atomPtrPtr == aLocalName) {
+      return PR_TRUE;
+    }
+    ++aURLs;
+  }
+  return PR_FALSE;
+}
+
+PRBool
+nsTreeSanitizer::MustPrune(PRInt32 aNamespace,
+                           nsIAtom* aLocal,
+                           mozilla::dom::Element* aElement)
+{
+  // To avoid attacks where a MathML script becomes something that gets
+  // serialized in a way that it parses back as an HTML script, let's just
+  // drop elements with the local name 'script' regardless of namespace.
+  if (nsGkAtoms::script == aLocal) {
+    return PR_TRUE;
+  }
+  if (aNamespace == kNameSpaceID_XHTML) {
+    if (nsGkAtoms::title == aLocal) {
+      // emulate the quirks of the old parser
+      return PR_TRUE;
+    }
+    if ((nsGkAtoms::meta == aLocal || nsGkAtoms::link == aLocal) &&
+        !(aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) ||
+          aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope))) {
+      // emulate old behavior for non-Microdata <meta> and <link> presumably
+      // in <head>. <meta> and <link> are whitelisted in order to avoid
+      // corrupting Microdata when they appear in <body>. Note that
+      // SanitizeAttributes() will remove the rel attribute from <link> and
+      // the name attribute from <meta>.
+      return PR_TRUE;
+    }
+  }
+  if (mAllowStyles) {
+    if (nsGkAtoms::style == aLocal && !(aNamespace == kNameSpaceID_XHTML
+        || aNamespace == kNameSpaceID_SVG)) {
+      return PR_TRUE;
+    }
+    return PR_FALSE;
+  }
+  if (nsGkAtoms::style == aLocal) {
+    return PR_TRUE;
+  }
+  return PR_FALSE;
+}
+
+PRBool
+nsTreeSanitizer::SanitizeStyleRule(mozilla::css::StyleRule *aRule,
+                                   nsAutoString &aRuleText)
+{
+  PRBool didSanitize = PR_FALSE;
+  aRuleText.Truncate();
+  mozilla::css::Declaration* style = aRule->GetDeclaration();
+  if (style) {
+    didSanitize = style->HasProperty(eCSSProperty_binding);
+    style->RemoveProperty(eCSSProperty_binding);
+    style->ToString(aRuleText);
+  }
+  return didSanitize;
+}
+
+PRBool
+nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
+                                    nsAString& aSanitized,
+                                    nsIDocument* aDocument,
+                                    nsIURI* aBaseURI)
+{
+  nsresult rv;
+  aSanitized.Truncate();
+  // aSanitized will hold the permitted CSS text.
+  // -moz-binding is blacklisted.
+  PRBool didSanitize = PR_FALSE;
+  // Create a sheet to hold the parsed CSS
+  nsRefPtr<nsCSSStyleSheet> sheet;
+  rv = NS_NewCSSStyleSheet(getter_AddRefs(sheet));
+  NS_ENSURE_SUCCESS(rv, PR_TRUE);
+  sheet->SetURIs(aDocument->GetDocumentURI(), nsnull, aBaseURI);
+  sheet->SetPrincipal(aDocument->NodePrincipal());
+  // Create the CSS parser, and parse the CSS text.
+  nsCSSParser parser(nsnull, sheet);
+  rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI,
+                         aDocument->NodePrincipal(), 0, PR_FALSE);
+  NS_ENSURE_SUCCESS(rv, PR_TRUE);
+  // Mark the sheet as complete.
+  NS_ABORT_IF_FALSE(!sheet->IsModified(),
+      "should not get marked modified during parsing");
+  sheet->SetComplete();
+  // Loop through all the rules found in the CSS text
+  PRInt32 ruleCount = sheet->StyleRuleCount();
+  for (PRInt32 i = 0; i < ruleCount; ++i) {
+    nsRefPtr<mozilla::css::Rule> rule;
+    rv = sheet->GetStyleRuleAt(i, *getter_AddRefs(rule));
+    if (NS_FAILED(rv))
+      continue; NS_ASSERTION(rule, "We should have a rule by now");
+    switch (rule->GetType()) {
+      default:
+        didSanitize = PR_TRUE;
+        // Ignore these rule types.
+        break;
+      case mozilla::css::Rule::NAMESPACE_RULE:
+      case mozilla::css::Rule::FONT_FACE_RULE: {
+        // Append @namespace and @font-face rules verbatim.
+        nsAutoString cssText;
+        nsCOMPtr<nsIDOMCSSRule> styleRule = do_QueryInterface(rule);
+        if (styleRule) {
+          rv = styleRule->GetCssText(cssText);
+          if (NS_SUCCEEDED(rv)) {
+            aSanitized.Append(cssText);
+          }
+        }
+        break;
+      }
+      case mozilla::css::Rule::STYLE_RULE: {
+        // For style rules, we will just look for and remove the
+        // -moz-binding properties.
+        nsRefPtr<mozilla::css::StyleRule> styleRule = do_QueryObject(rule);
+        NS_ASSERTION(styleRule, "Must be a style rule");
+        nsAutoString decl;
+        PRBool sanitized = SanitizeStyleRule(styleRule, decl);
+        didSanitize = sanitized || didSanitize;
+        if (!sanitized) {
+          styleRule->GetCssText(decl);
+        }
+        aSanitized.Append(decl);
+      }
+    }
+  }
+  return didSanitize;
+}
+
+void
+nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
+                                    nsTHashtable<nsISupportsHashKey>* aAllowed,
+                                    nsIAtom*** aURLs,
+                                    PRBool aAllowXLink,
+                                    PRBool aAllowStyle,
+                                    PRBool aAllowDangerousSrc)
+{
+  PRUint32 ac = aElement->GetAttrCount();
+
+  nsresult rv;
+
+  for (PRInt32 i = ac - 1; i >= 0; --i) {
+    rv = NS_OK;
+    const nsAttrName* attrName = aElement->GetAttrNameAt(i);
+    PRInt32 attrNs = attrName->NamespaceID();
+    nsIAtom* attrLocal = attrName->Atom();
+
+    if (kNameSpaceID_None == attrNs) {
+      if (aAllowStyle && nsGkAtoms::style == attrLocal) {
+        nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI();
+        nsIDocument* document = aElement->GetOwnerDoc();
+        // Pass the CSS Loader object to the parser, to allow parser error
+        // reports to include the outer window ID.
+        nsCSSParser parser(document->CSSLoader());
+        nsRefPtr<mozilla::css::StyleRule> rule;
+        nsAutoString value;
+        aElement->GetAttr(attrNs, attrLocal, value);
+        rv = parser.ParseStyleAttribute(value,
+                                        document->GetDocumentURI(),
+                                        baseURI,
+                                        document->NodePrincipal(),
+                                        getter_AddRefs(rule));
+        if (NS_SUCCEEDED(rv)) {
+          nsAutoString cleanValue;
+          if (SanitizeStyleRule(rule, cleanValue)) {
+            aElement->SetAttr(kNameSpaceID_None,
+                              nsGkAtoms::style,
+                              cleanValue,
+                              PR_FALSE);
+          }
+        }
+        continue;
+      }
+      if (aAllowDangerousSrc && nsGkAtoms::src == attrLocal) {
+        continue;
+      }
+      if (IsURL(aURLs, attrLocal)) {
+        SanitizeURL(aElement, attrNs, attrLocal);
+        continue;
+      }
+      if (aAllowed->GetEntry(attrLocal) &&
+          !(attrLocal == nsGkAtoms::rel &&
+            aElement->IsHTML(nsGkAtoms::link)) &&
+          !(attrLocal == nsGkAtoms::name &&
+            aElement->IsHTML(nsGkAtoms::meta))) {
+        // name="" and rel="" are whitelisted, but treat them as blacklisted
+        // for <meta name> and <link rel> to avoid document-wide metadata
+        // or styling overrides with non-conforming <meta name itemprop> or
+        // <link rel itemprop>
+        continue;
+      }
+      const PRUnichar* localStr = attrLocal->GetUTF16String();
+      // Allow underscore to cater to the MCE editor library.
+      // Allow data-* on SVG and MathML, too, as a forward-compat measure.
+      if (*localStr == '_' || (attrLocal->GetLength() > 5 && localStr[0] == 'd'
+          && localStr[1] == 'a' && localStr[2] == 't' && localStr[3] == 'a'
+          && localStr[4] == '-')) {
+        continue;
+      }
+      // else not allowed
+    } else if (kNameSpaceID_XML == attrNs) {
+      if (nsGkAtoms::base == attrLocal) {
+        SanitizeURL(aElement, attrNs, attrLocal);
+        continue;
+      }
+      if (nsGkAtoms::lang == attrLocal || nsGkAtoms::space == attrLocal) {
+        continue;
+      }
+      // else not allowed
+    } else if (aAllowXLink && kNameSpaceID_XLink == attrNs) {
+      if (nsGkAtoms::href == attrLocal) {
+        SanitizeURL(aElement, attrNs, attrLocal);
+        continue;
+      }
+      if (nsGkAtoms::type == attrLocal || nsGkAtoms::title == attrLocal
+          || nsGkAtoms::show == attrLocal || nsGkAtoms::actuate == attrLocal) {
+        continue;
+      }
+      // else not allowed
+    }
+    aElement->UnsetAttr(kNameSpaceID_None, attrLocal, PR_FALSE);
+    // in case the attribute removal shuffled the attribute order, start the
+    // loop again.
+    --ac;
+    i = ac; // i will be decremented immediately thanks to the for loop
+  }
+
+  // If we've got HTML audio or video, add the controls attribute, because
+  // otherwise the content is unplayable with scripts removed.
+  if (aElement->IsHTML(nsGkAtoms::video) ||
+      aElement->IsHTML(nsGkAtoms::audio)) {
+    aElement->SetAttr(kNameSpaceID_None,
+                      nsGkAtoms::controls,
+                      EmptyString(),
+                      PR_FALSE);
+  }
+}
+
+void
+nsTreeSanitizer::SanitizeURL(mozilla::dom::Element* aElement,
+                             PRInt32 aNamespace,
+                             nsIAtom* aLocalName)
+{
+  nsAutoString value;
+  aElement->GetAttr(aNamespace, aLocalName, value);
+
+  // Get value and remove mandatory quotes
+  static const char* kWhitespace = "\n\r\t\b";
+  const nsAString& v =
+    nsContentUtils::TrimCharsInSet(kWhitespace, value);
+
+  nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
+  PRUint32 flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL;
+
+  nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI();
+  nsCOMPtr<nsIURI> attrURI;
+  nsresult rv = NS_NewURI(getter_AddRefs(attrURI), v, nsnull, baseURI);
+  if (NS_SUCCEEDED(rv)) {
+    rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags);
+  }
+  if (NS_FAILED(rv)) {
+    aElement->UnsetAttr(aNamespace, aLocalName, PR_FALSE);
+  }
+}
+
+void
+nsTreeSanitizer::Sanitize(nsIContent* aFragment) {
+  // If you want to relax these preconditions, be sure to check the code in
+  // here that notifies / does not notify or that fires mutation events if
+  // in tree.
+  NS_PRECONDITION(aFragment->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT),
+      "Argument was not DOM fragment.");
+  NS_PRECONDITION(!aFragment->IsInDoc(), "The fragment is in doc?");
+
+  nsIContent* node = aFragment->GetFirstChild();
+  while (node) {
+    if (node->IsElement()) {
+      mozilla::dom::Element* elt = node->AsElement();
+      nsINodeInfo* nodeInfo = node->NodeInfo();
+      nsIAtom* localName = nodeInfo->NameAtom();
+      PRInt32 ns = nodeInfo->NamespaceID();
+
+      if (MustPrune(ns, localName, elt)) {
+        nsIContent* next = node->GetNextNonChildNode(aFragment);
+        node->GetParent()->RemoveChild(node);
+        node = next;
+        continue;
+      }
+      if (nsGkAtoms::style == localName) {
+        // If styles aren't allowed, style elements got pruned above. Even
+        // if styles are allowed, non-HTML, non-SVG style elements got pruned
+        // above.
+        NS_ASSERTION(ns == kNameSpaceID_XHTML || ns == kNameSpaceID_SVG,
+            "Should have only HTML or SVG here!");
+        nsAutoString styleText;
+        nsContentUtils::GetNodeTextContent(node, PR_FALSE, styleText);
+        nsAutoString sanitizedStyle;
+        nsCOMPtr<nsIURI> baseURI = node->GetBaseURI();
+        if (SanitizeStyleSheet(styleText,
+                               sanitizedStyle,
+                               aFragment->GetOwnerDoc(),
+                               baseURI)) {
+          nsContentUtils::SetNodeTextContent(node, sanitizedStyle, PR_TRUE);
+        } else {
+          // If the node had non-text child nodes, this operation zaps those.
+          nsContentUtils::SetNodeTextContent(node, styleText, PR_TRUE);
+        }
+        if (ns == kNameSpaceID_XHTML) {
+          SanitizeAttributes(elt,
+                             sAttributesHTML,
+                             (nsIAtom***)kURLAttributesHTML,
+                             PR_FALSE,
+                             mAllowStyles,
+                             PR_FALSE);
+        } else {
+          SanitizeAttributes(elt,
+                             sAttributesSVG,
+                             (nsIAtom***)kURLAttributesSVG,
+                             PR_TRUE,
+                             mAllowStyles,
+                             PR_FALSE);
+        }
+        node = node->GetNextNonChildNode(aFragment);
+        continue;
+      }
+      if (MustFlatten(ns, localName)) {
+        nsIContent* next = node->GetNextNode(aFragment);
+        nsIContent* parent = node->GetParent();
+        nsCOMPtr<nsIContent> child; // Must keep the child alive during move
+        nsresult rv;
+        while ((child = node->GetFirstChild())) {
+          parent->InsertBefore(child, node, &rv);
+          if (NS_FAILED(rv)) {
+            break;
+          }
+        }
+        parent->RemoveChild(node);
+        node = next;
+        continue;
+      }
+      NS_ASSERTION(ns == kNameSpaceID_XHTML ||
+                   ns == kNameSpaceID_SVG ||
+                   ns == kNameSpaceID_MathML,
+          "Should have only HTML, MathML or SVG here!");
+      if (ns == kNameSpaceID_XHTML) {
+        SanitizeAttributes(elt,
+                           sAttributesHTML,
+                           (nsIAtom***)kURLAttributesHTML,
+                           PR_FALSE, mAllowStyles,
+                           (nsGkAtoms::img == localName));
+      } else if (ns == kNameSpaceID_SVG) {
+        SanitizeAttributes(elt,
+                           sAttributesSVG,
+                           (nsIAtom***)kURLAttributesSVG,
+                           PR_TRUE,
+                           mAllowStyles,
+                           PR_FALSE);
+      } else {
+        SanitizeAttributes(elt,
+                           sAttributesMathML,
+                           (nsIAtom***)kURLAttributesMathML,
+                           PR_TRUE,
+                           PR_FALSE,
+                           PR_FALSE);
+      }
+      node = node->GetNextNode(aFragment);
+      continue;
+    }
+    NS_ASSERTION(!node->GetFirstChild(), "How come non-element node had kids?");
+    nsIContent* next = node->GetNextNonChildNode(aFragment);
+    if (!mAllowComments && node->IsNodeOfType(nsINode::eCOMMENT)) {
+      node->GetParent()->RemoveChild(node);
+    }
+    node = next;
+  }
+}
+
+void
+nsTreeSanitizer::InitializeStatics()
+{
+  NS_PRECONDITION(!sElementsHTML, "Initializing a second time.");
+
+  sElementsHTML = new nsTHashtable<nsISupportsHashKey> ();
+  sElementsHTML->Init(NS_ARRAY_LENGTH(kElementsHTML));
+  for (PRUint32 i = 0; kElementsHTML[i]; i++) {
+    sElementsHTML->PutEntry(*kElementsHTML[i]);
+  }
+
+  sAttributesHTML = new nsTHashtable<nsISupportsHashKey> ();
+  sAttributesHTML->Init(NS_ARRAY_LENGTH(kAttributesHTML));
+  for (PRUint32 i = 0; kAttributesHTML[i]; i++) {
+    sAttributesHTML->PutEntry(*kAttributesHTML[i]);
+  }
+
+  sElementsSVG = new nsTHashtable<nsISupportsHashKey> ();
+  sElementsSVG->Init(NS_ARRAY_LENGTH(kElementsSVG));
+  for (PRUint32 i = 0; kElementsSVG[i]; i++) {
+    sElementsSVG->PutEntry(*kElementsSVG[i]);
+  }
+
+  sAttributesSVG = new nsTHashtable<nsISupportsHashKey> ();
+  sAttributesSVG->Init(NS_ARRAY_LENGTH(kAttributesSVG));
+  for (PRUint32 i = 0; kAttributesSVG[i]; i++) {
+    sAttributesSVG->PutEntry(*kAttributesSVG[i]);
+  }
+
+  sElementsMathML = new nsTHashtable<nsISupportsHashKey> ();
+  sElementsMathML->Init(NS_ARRAY_LENGTH(kElementsMathML));
+  for (PRUint32 i = 0; kElementsMathML[i]; i++) {
+    sElementsMathML->PutEntry(*kElementsMathML[i]);
+  }
+
+  sAttributesMathML = new nsTHashtable<nsISupportsHashKey> ();
+  sAttributesMathML->Init(NS_ARRAY_LENGTH(kAttributesMathML));
+  for (PRUint32 i = 0; kAttributesMathML[i]; i++) {
+    sAttributesMathML->PutEntry(*kAttributesMathML[i]);
+  }
+
+  nsCOMPtr<nsIPrincipal> principal =
+      do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID);
+  principal.forget(&sNullPrincipal);
+}
+
+void
+nsTreeSanitizer::ReleaseStatics()
+{
+  delete sElementsHTML;
+  sElementsHTML = nsnull;
+
+  delete sAttributesHTML;
+  sAttributesHTML = nsnull;
+
+  delete sElementsSVG;
+  sElementsSVG = nsnull;
+
+  delete sAttributesSVG;
+  sAttributesSVG = nsnull;
+
+  delete sElementsMathML;
+  sElementsMathML = nsnull;
+
+  delete sAttributesMathML;
+  sAttributesMathML = nsnull;
+
+  NS_IF_RELEASE(sNullPrincipal);
+}
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -240,20 +240,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug28293.html \
 		test_bug28293.xhtml \
 		file_bug28293.sjs \
 		test_bug445225.html \
 		file_bug445225_multipart.txt \
 		file_bug445225_multipart.txt^headers^ \
 		test_title.html \
 		test_bug453521.html \
-		test_bug391728.html \
-		file_bug391728.html \
 		test_bug454325.html \
-		file_bug391728_2.html \
 		test_bug456262.html \
 		test_bug482935.html \
 		     bug482935.sjs \
 		test_bug590870.html \
 		file_bug590870.html \
 		test_bug590812.html \
 		file_bug590812.xml \
 		file_bug590812-ref.xhtml \
--- a/content/base/test/chrome/Makefile.in
+++ b/content/base/test/chrome/Makefile.in
@@ -44,16 +44,19 @@ include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = \
     bug421622-referer.sjs \
     $(NULL)
 
 _CHROME_FILES = \
     test_bug206691.xul \
+    test_bug391728.html \
+    file_bug391728.html \
+    file_bug391728_2.html \
     test_bug421622.xul \
     test_bug429785.xul \
     test_bug430050.xul \
     test_bug467123.xul \
     test_title.xul \
     title_window.xul \
     test_bug549682.xul \
     file_bug549682.xul \
rename from content/base/test/file_bug391728.html
rename to content/base/test/chrome/file_bug391728.html
rename from content/base/test/file_bug391728_2.html
rename to content/base/test/chrome/file_bug391728_2.html
rename from content/base/test/test_bug391728.html
rename to content/base/test/chrome/test_bug391728.html
--- a/content/base/test/test_bug391728.html
+++ b/content/base/test/chrome/test_bug391728.html
@@ -1,19 +1,19 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=391728
 -->
 <head>
   <title>Test for Bug 391728</title>
-  <script type="text/javascript" src="/MochiKit/packed.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/PluginUtils.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/PluginUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=391728">Mozilla Bug 391728</a>
 <p id="display"></p>
 <div id="content">
   <iframe id="testframe" width="150" height="250" src="about:blank"></iframe>
 </div>
 <pre id="test">
@@ -37,17 +37,16 @@ function blocked_plugin_detected(event) 
   gBlocked.push(event.target.id);
 }
 
 function unknown_plugin_detected(event) {
   gUnknown.push(event.target.id);
 }
 
 function init_test() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   // Make sure the blocklist is off for the duration of this test
   var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefBranch);
   prefs.setBoolPref("extensions.blocklist.enabled", false);
 
   if (!PluginUtils.withTestPlugin(start_test))
     SimpleTest.finish();
 }
@@ -115,51 +114,47 @@ function test_list(list) {
     ok(list.indexOf("plugin" + i) >= 0, "Plugin " + i + " did not send the event");
   }
   for (i = 1; i <= FALLBACK_COUNT; i++) {
     ok(list.indexOf("fallback" + i) < 0, "Fallback plugin " + i + " should not have sent the event");
   }
 }
 
 function test_normal(plugin) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   is(gUnknown.length, 0, "Should not have been any unknown plugins");
   is(gDisabled.length, 0, "Should not have been any disabled plugins");
   is(gBlocked.length, 0, "Should not have been any blocked plugins");
   test_style("solid");
   plugin.disabled = true;
   load_frame(test_disabled, "file_bug391728");
 }
 
 function test_disabled(plugin) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   is(gUnknown.length, 0, "Should not have been any unknown plugins");
   is(gDisabled.length, PLUGIN_COUNT, "Should have been disabled plugins");
   test_list(gDisabled);
   is(gBlocked.length, 0, "Should not have been any blocked plugins");
   test_style("dotted");
   ok(plugin.disabled, "Plugin lost its disabled status");
   plugin.disabled = false;
   plugin.blocklisted = true;
   load_frame(test_blocked, "file_bug391728");
 }
 
 function test_blocked(plugin) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   is(gUnknown.length, 0, "Should not have been any unknown plugins");
   is(gDisabled.length, 0, "Should not have been any disabled plugins");
   is(gBlocked.length, PLUGIN_COUNT, "Should have been blocked plugins");
   test_list(gBlocked);
   test_style("dashed");
   ok(plugin.blocklisted, "Plugin lost its blocklist status");
   load_frame(test_unknown, "file_bug391728_2");
 }
 
 function test_unknown(plugin) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   is(gUnknown.length, PLUGIN_COUNT, "Should have been unknown plugins");
   test_list(gUnknown);
   is(gDisabled.length, 0, "Should not have been any disabled plugins");
   is(gBlocked.length, 0, "Should not have been any blocked plugins");
   test_style("none");
   finish_test(plugin);
 }
 
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -486,16 +486,18 @@ protected:
     PRBool ValidateFaceEnum(WebGLenum face, const char *info);
     PRBool ValidateBufferUsageEnum(WebGLenum target, const char *info);
     PRBool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
                                       PRUint32 *texelSize, const char *info);
     PRBool ValidateDrawModeEnum(WebGLenum mode, const char *info);
     PRBool ValidateAttribIndex(WebGLuint index, const char *info);
     PRBool ValidateStencilParamsForDrawCall();
     
+    bool  ValidateGLSLIdentifier(const nsAString& name, const char *info);
+
     static PRUint32 GetTexelSize(WebGLenum format, WebGLenum type);
 
     void Invalidate();
     void DestroyResourcesAndContext();
 
     void MakeContextCurrent() { gl->MakeCurrent(); }
 
     // helpers
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1834,16 +1834,19 @@ WebGLContext::GetAttribLocation(nsIWebGL
                                 PRInt32 *retval)
 {
     *retval = 0;
 
     WebGLuint progname;
     if (!GetGLName<WebGLProgram>("getAttribLocation: program", pobj, &progname))
         return NS_OK;
 
+    if (!ValidateGLSLIdentifier(name, "getAttribLocation"))
+        return NS_OK; 
+
     MakeContextCurrent();
     *retval = gl->fGetAttribLocation(progname, NS_LossyConvertUTF16toASCII(name).get());
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
 {
@@ -2656,16 +2659,19 @@ WebGLContext::GetUniformLocation(nsIWebG
 {
     *retval = nsnull;
 
     WebGLuint progname;
     WebGLProgram *prog;
     if (!GetConcreteObjectAndGLName("getUniformLocation: program", pobj, &prog, &progname))
         return NS_OK;
 
+    if (!ValidateGLSLIdentifier(name, "getUniformLocation"))
+        return NS_OK; 
+
     MakeContextCurrent();
 
     GLint intlocation = gl->fGetUniformLocation(progname, NS_LossyConvertUTF16toASCII(name).get());
 
     nsRefPtr<nsIWebGLUniformLocation> loc = prog->GetUniformLocationObject(intlocation);
     *retval = loc.forget().get();
 
     return NS_OK;
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -323,16 +323,27 @@ PRBool WebGLContext::ValidateDrawModeEnu
         case LOCAL_GL_LINES:
             return PR_TRUE;
         default:
             ErrorInvalidEnumInfo(info, mode);
             return PR_FALSE;
     }
 }
 
+bool WebGLContext::ValidateGLSLIdentifier(const nsAString& name, const char *info)
+{
+    const PRUint32 maxSize = 4095;
+    if (name.Length() > maxSize) {
+        ErrorInvalidValue("%s: identifier is %d characters long, exceeds the maximum allowed length of %d characters",
+                          info, name.Length(), maxSize);
+        return false;
+    }
+    return true;
+}
+
 PRUint32 WebGLContext::GetTexelSize(WebGLenum format, WebGLenum type)
 {
     if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
         int multiplier = type == LOCAL_GL_FLOAT ? 4 : 1;
         switch (format) {
             case LOCAL_GL_ALPHA:
             case LOCAL_GL_LUMINANCE:
                 return 1 * multiplier;
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -2718,25 +2718,34 @@ nsHTMLInputElement::GetTextLength(PRInt3
 
   *aTextLength = val.Length();
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::SetSelectionRange(PRInt32 aSelectionStart,
-                                      PRInt32 aSelectionEnd)
+                                      PRInt32 aSelectionEnd,
+                                      const nsAString& aDirection)
 {
   nsresult rv = NS_ERROR_FAILURE;
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
 
   if (formControlFrame) {
     nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
     if (textControlFrame) {
-      rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd);
+      // Default to forward, even if not specified.
+      // Note that we don't currently support directionless selections, so
+      // "none" is treated like "forward".
+      nsITextControlFrame::SelectionDirection dir = nsITextControlFrame::eForward;
+      if (aDirection.EqualsLiteral("backward")) {
+        dir = nsITextControlFrame::eBackward;
+      }
+
+      rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd, dir);
       if (NS_SUCCEEDED(rv)) {
         rv = textControlFrame->ScrollSelectionIntoView();
       }
     }
   }
 
   return rv;
 }
@@ -2748,59 +2757,53 @@ nsHTMLInputElement::GetSelectionStart(PR
   
   PRInt32 selEnd;
   return GetSelectionRange(aSelectionStart, &selEnd);
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::SetSelectionStart(PRInt32 aSelectionStart)
 {
-  nsresult rv = NS_ERROR_FAILURE;
-  nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
-
-  if (formControlFrame) {
-    nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
-    if (textControlFrame) {
-      rv = textControlFrame->SetSelectionStart(aSelectionStart);
-      if (NS_SUCCEEDED(rv)) {
-        rv = textControlFrame->ScrollSelectionIntoView();
-      }
-    }
+  nsAutoString direction;
+  nsresult rv = GetSelectionDirection(direction);
+  NS_ENSURE_SUCCESS(rv, rv);
+  PRInt32 start, end;
+  rv = GetSelectionRange(&start, &end);
+  NS_ENSURE_SUCCESS(rv, rv);
+  start = aSelectionStart;
+  if (end < start) {
+    end = start;
   }
-
-  return rv;
+  return SetSelectionRange(start, end, direction);
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::GetSelectionEnd(PRInt32* aSelectionEnd)
 {
   NS_ENSURE_ARG_POINTER(aSelectionEnd);
   
   PRInt32 selStart;
   return GetSelectionRange(&selStart, aSelectionEnd);
 }
 
 
 NS_IMETHODIMP
 nsHTMLInputElement::SetSelectionEnd(PRInt32 aSelectionEnd)
 {
-  nsresult rv = NS_ERROR_FAILURE;
-  nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
-
-  if (formControlFrame) {
-    nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
-    if (textControlFrame) {
-      rv = textControlFrame->SetSelectionEnd(aSelectionEnd);
-      if (NS_SUCCEEDED(rv)) {
-        rv = textControlFrame->ScrollSelectionIntoView();
-      }
-    }
+  nsAutoString direction;
+  nsresult rv = GetSelectionDirection(direction);
+  NS_ENSURE_SUCCESS(rv, rv);
+  PRInt32 start, end;
+  rv = GetSelectionRange(&start, &end);
+  NS_ENSURE_SUCCESS(rv, rv);
+  end = aSelectionEnd;
+  if (start > end) {
+    start = end;
   }
-
-  return rv;
+  return SetSelectionRange(start, end, direction);
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::GetFiles(nsIDOMFileList** aFileList)
 {
   *aFileList = nsnull;
 
   if (mType != NS_FORM_INPUT_FILE) {
@@ -2831,16 +2834,55 @@ nsHTMLInputElement::GetSelectionRange(PR
     if (textControlFrame)
       rv = textControlFrame->GetSelectionRange(aSelectionStart, aSelectionEnd);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
+nsHTMLInputElement::GetSelectionDirection(nsAString& aDirection)
+{
+  nsresult rv = NS_ERROR_FAILURE;
+  nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
+
+  if (formControlFrame) {
+    nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
+    if (textControlFrame) {
+      nsITextControlFrame::SelectionDirection dir;
+      rv = textControlFrame->GetSelectionRange(nsnull, nsnull, &dir);
+      if (NS_SUCCEEDED(rv)) {
+        if (dir == nsITextControlFrame::eNone) {
+          aDirection.AssignLiteral("none");
+        } else if (dir == nsITextControlFrame::eForward) {
+          aDirection.AssignLiteral("forward");
+        } else if (dir == nsITextControlFrame::eBackward) {
+          aDirection.AssignLiteral("backward");
+        } else {
+          NS_NOTREACHED("Invalid SelectionDirection value");
+        }
+      }
+    }
+  }
+
+  return rv;
+}
+
+NS_IMETHODIMP
+nsHTMLInputElement::SetSelectionDirection(const nsAString& aDirection) {
+  PRInt32 start, end;
+  nsresult rv = GetSelectionRange(&start, &end);
+  if (NS_SUCCEEDED(rv)) {
+    rv = SetSelectionRange(start, end, aDirection);
+  }
+
+  return rv;
+}
+
+NS_IMETHODIMP
 nsHTMLInputElement::GetPhonetic(nsAString& aPhonetic)
 {
   aPhonetic.Truncate(0);
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
 
   if (formControlFrame) {
     nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
     if (textControlFrame)
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -824,58 +824,52 @@ nsHTMLTextAreaElement::GetSelectionStart
   
   PRInt32 selEnd;
   return GetSelectionRange(aSelectionStart, &selEnd);
 }
 
 NS_IMETHODIMP
 nsHTMLTextAreaElement::SetSelectionStart(PRInt32 aSelectionStart)
 {
-  nsresult rv = NS_ERROR_FAILURE;
-  nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
-
-  if (formControlFrame){
-    nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
-    if (textControlFrame) {
-      rv = textControlFrame->SetSelectionStart(aSelectionStart);
-      if (NS_SUCCEEDED(rv)) {
-        rv = textControlFrame->ScrollSelectionIntoView();
-      }
-    }
+  nsAutoString direction;
+  nsresult rv = GetSelectionDirection(direction);
+  NS_ENSURE_SUCCESS(rv, rv);
+  PRInt32 start, end;
+  rv = GetSelectionRange(&start, &end);
+  NS_ENSURE_SUCCESS(rv, rv);
+  start = aSelectionStart;
+  if (end < start) {
+    end = start;
   }
-
-  return rv;
+  return SetSelectionRange(start, end, direction);
 }
 
 NS_IMETHODIMP
 nsHTMLTextAreaElement::GetSelectionEnd(PRInt32 *aSelectionEnd)
 {
   NS_ENSURE_ARG_POINTER(aSelectionEnd);
   
   PRInt32 selStart;
   return GetSelectionRange(&selStart, aSelectionEnd);
 }
 
 NS_IMETHODIMP
 nsHTMLTextAreaElement::SetSelectionEnd(PRInt32 aSelectionEnd)
 {
-  nsresult rv = NS_ERROR_FAILURE;
-  nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
-
-  if (formControlFrame) {
-    nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
-    if (textControlFrame) {
-      rv = textControlFrame->SetSelectionEnd(aSelectionEnd);
-      if (NS_SUCCEEDED(rv)) {
-        rv = textControlFrame->ScrollSelectionIntoView();
-      }
-    }
+  nsAutoString direction;
+  nsresult rv = GetSelectionDirection(direction);
+  NS_ENSURE_SUCCESS(rv, rv);
+  PRInt32 start, end;
+  rv = GetSelectionRange(&start, &end);
+  NS_ENSURE_SUCCESS(rv, rv);
+  end = aSelectionEnd;
+  if (start > end) {
+    start = end;
   }
-
-  return rv;
+  return SetSelectionRange(start, end, direction);
 }
 
 nsresult
 nsHTMLTextAreaElement::GetSelectionRange(PRInt32* aSelectionStart,
                                       PRInt32* aSelectionEnd)
 {
   nsresult rv = NS_ERROR_FAILURE;
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
@@ -884,26 +878,75 @@ nsHTMLTextAreaElement::GetSelectionRange
     nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
     if (textControlFrame)
       rv = textControlFrame->GetSelectionRange(aSelectionStart, aSelectionEnd);
   }
 
   return rv;
 }
 
+nsresult
+nsHTMLTextAreaElement::GetSelectionDirection(nsAString& aDirection)
+{
+  nsresult rv = NS_ERROR_FAILURE;
+  nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
+
+  if (formControlFrame) {
+    nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
+    if (textControlFrame) {
+      nsITextControlFrame::SelectionDirection dir;
+      rv = textControlFrame->GetSelectionRange(nsnull, nsnull, &dir);
+      if (NS_SUCCEEDED(rv)) {
+        if (dir == nsITextControlFrame::eNone) {
+          aDirection.AssignLiteral("none");
+        } else if (dir == nsITextControlFrame::eForward) {
+          aDirection.AssignLiteral("forward");
+        } else if (dir == nsITextControlFrame::eBackward) {
+          aDirection.AssignLiteral("backward");
+        } else {
+          NS_NOTREACHED("Invalid SelectionDirection value");
+        }
+      }
+    }
+  }
+
+  return rv;
+}
+
 NS_IMETHODIMP
-nsHTMLTextAreaElement::SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelectionEnd)
+nsHTMLTextAreaElement::SetSelectionDirection(const nsAString& aDirection) {
+  PRInt32 start, end;
+  nsresult rv = GetSelectionRange(&start, &end);
+  if (NS_SUCCEEDED(rv)) {
+    rv = SetSelectionRange(start, end, aDirection);
+  }
+
+  return rv;
+}
+
+NS_IMETHODIMP
+nsHTMLTextAreaElement::SetSelectionRange(PRInt32 aSelectionStart,
+                                         PRInt32 aSelectionEnd,
+                                         const nsAString& aDirection)
 { 
   nsresult rv = NS_ERROR_FAILURE;
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
 
   if (formControlFrame) {
     nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
     if (textControlFrame) {
-      rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd);
+      // Default to forward, even if not specified.
+      // Note that we don't currently support directionless selections, so
+      // "none" is treated like "forward".
+      nsITextControlFrame::SelectionDirection dir = nsITextControlFrame::eForward;
+      if (aDirection.EqualsLiteral("backward")) {
+        dir = nsITextControlFrame::eBackward;
+      }
+
+      rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd, dir);
       if (NS_SUCCEEDED(rv)) {
         rv = textControlFrame->ScrollSelectionIntoView();
       }
     }
   }
 
   return rv;
 } 
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -272,13 +272,14 @@ include $(topsrcdir)/config/rules.mk
 		test_bug649134.html \
 		test_bug658746.html \
 		test_bug659596.html \
 		test_bug659743.xml \
 		test_bug660663.html \
 		test_bug664299.html \
 		test_bug666200.html \
 		test_bug666666.html \
+		test_bug674558.html \
 		test_restore_from_parser_fragment.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug674558.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=674558
+-->
+<head>
+  <title>Test for Bug 674558</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=674558">Mozilla Bug 674558</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 674558 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+  function textAreaCtor() {
+    return document.createElement("textarea");
+  }
+  var ctors = [textAreaCtor];
+  ["text", "password", "search"].forEach(function(type) {
+    ctors.push(function inputCtor() {
+      var input = document.createElement("input");
+      input.type = type;
+      return input;
+    });
+  });
+
+  for (var ctor in ctors) {
+    test(ctors[ctor]);
+  }
+
+  SimpleTest.finish();
+});
+
+function test(ctor) {
+  var elem = ctor();
+  ok(true, "Testing " + name(elem));
+
+  ok("selectionDirection" in elem, "elem should have the selectionDirection property");
+
+  var content = document.getElementById("content");
+  content.appendChild(elem);
+
+  elem.value = "foobar";
+
+  is(elem.selectionStart, 0, "Default value");
+  is(elem.selectionEnd, 0, "Default value");
+  is(elem.selectionDirection, "forward", "Default value");
+
+  elem.setSelectionRange(1, 3);
+  is(elem.selectionStart, 1, "Correct value");
+  is(elem.selectionEnd, 3, "Correct value");
+  is(elem.selectionDirection, "forward", "If not set, should default to forward");
+
+  // extend to right
+  elem.focus();
+  synthesizeKey("VK_RIGHT", {shiftKey: true});
+
+  is(elem.selectionStart, 1, "Value unchanged");
+  is(elem.selectionEnd, 4, "Correct value");
+  is(elem.selectionDirection, "forward", "Still forward");
+
+  // change the direction
+  elem.selectionDirection = "backward";
+
+  is(elem.selectionStart, 1, "Value unchanged");
+  is(elem.selectionEnd, 4, "Value unchanged");
+  is(elem.selectionDirection, "backward", "Correct value");
+
+  // extend to right again
+  synthesizeKey("VK_RIGHT", {shiftKey: true});
+
+  is(elem.selectionStart, 2, "Correct value");
+  is(elem.selectionEnd, 4, "Value unchanged");
+  is(elem.selectionDirection, "backward", "Still backward");
+
+  elem.selectionEnd = 5;
+
+  is(elem.selectionStart, 2, "Value unchanged");
+  is(elem.selectionEnd, 5, "Correct value");
+  is(elem.selectionDirection, "backward", "Still backward");
+
+  elem.selectionDirection = "none";
+
+  is(elem.selectionStart, 2, "Value unchanged");
+  is(elem.selectionEnd, 5, "Value unchanged");
+  is(elem.selectionDirection, "forward", "none not supported");
+
+  elem.selectionDirection = "backward";
+
+  is(elem.selectionStart, 2, "Value unchanged");
+  is(elem.selectionEnd, 5, "Value unchanged");
+  is(elem.selectionDirection, "backward", "Correct Value");
+
+  elem.selectionDirection = "invalid";
+
+  is(elem.selectionStart, 2, "Value unchanged");
+  is(elem.selectionEnd, 5, "Value unchanged");
+  is(elem.selectionDirection, "forward", "Treated as none");
+
+  elem.selectionDirection = "backward";
+
+  is(elem.selectionStart, 2, "Value unchanged");
+  is(elem.selectionEnd, 5, "Value unchanged");
+  is(elem.selectionDirection, "backward", "Correct Value");
+
+  elem.setSelectionRange(1, 4);
+
+  is(elem.selectionStart, 1, "Correct value");
+  is(elem.selectionEnd, 4, "Correct value");
+  is(elem.selectionDirection, "forward", "Correct value");
+
+  elem.setSelectionRange(1, 1);
+  synthesizeKey("VK_RIGHT", {shiftKey: true});
+  synthesizeKey("VK_RIGHT", {shiftKey: true});
+  synthesizeKey("VK_RIGHT", {shiftKey: true});
+
+  is(elem.selectionStart, 1, "Correct value");
+  is(elem.selectionEnd, 4, "Correct value");
+  is(elem.selectionDirection, "forward", "Correct value");
+
+  elem.setSelectionRange(5, 5);
+  synthesizeKey("VK_LEFT", {shiftKey: true});
+  synthesizeKey("VK_LEFT", {shiftKey: true});
+  synthesizeKey("VK_LEFT", {shiftKey: true});
+
+  is(elem.selectionStart, 2, "Correct value");
+  is(elem.selectionEnd, 5, "Correct value");
+  is(elem.selectionDirection, "backward", "Correct value");
+}
+
+function name(elem) {
+  var tag = elem.localName;
+  if (tag == "input") {
+    tag += "[type=" + elem.type + "]";
+  }
+  return tag;
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -773,512 +773,8 @@ nsHTMLFragmentContentSink::AddAttributes
       // Add attribute to content
       aContent->SetAttr(kNameSpaceID_None, keyAtom, v, PR_FALSE);
     }
   }
 
   return NS_OK;
 }
 
-// nsHTMLParanoidFragmentSink
-
-// Find the whitelist of allowed elements and attributes in
-// nsContentSink.h We share it with nsHTMLParanoidFragmentSink
-
-class nsHTMLParanoidFragmentSink : public nsHTMLFragmentContentSink,
-                                   public nsIParanoidFragmentContentSink
-{
-public:
-  nsHTMLParanoidFragmentSink(PRBool aAllContent = PR_FALSE);
-
-  static nsresult Init();
-  static void Cleanup();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
-  NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
-  NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
-  NS_IMETHOD AddComment(const nsIParserNode& aNode);
-  NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
-
-  nsresult AddAttributes(const nsIParserNode& aNode,
-                         nsIContent* aContent);
-
-  // nsIParanoidFragmentContentSink
-  virtual void AllowStyles();
-  virtual void AllowComments();
-
-protected:
-  nsresult NameFromType(const nsHTMLTag aTag,
-                        nsIAtom **aResult);
-
-  nsresult NameFromNode(const nsIParserNode& aNode,
-                        nsIAtom **aResult);
-
-  // The return value will be true if we have sanitized the rule
-  PRBool SanitizeStyleRule(css::StyleRule *aRule, nsAutoString &aRuleText);
-
-  PRPackedBool mSkip; // used when we descend into <style> or <script>
-  PRPackedBool mProcessStyle; // used when style is explicitly white-listed
-  PRPackedBool mInStyle; // whether we're inside a style element
-  PRPackedBool mProcessComments; // used when comments are allowed
-
-  nsCOMPtr<nsIPrincipal> mNullPrincipal;
-
-  // Use nsTHashTable as a hash set for our whitelists
-  static nsTHashtable<nsISupportsHashKey>* sAllowedTags;
-  static nsTHashtable<nsISupportsHashKey>* sAllowedAttributes;
-};
-
-nsTHashtable<nsISupportsHashKey>* nsHTMLParanoidFragmentSink::sAllowedTags;
-nsTHashtable<nsISupportsHashKey>* nsHTMLParanoidFragmentSink::sAllowedAttributes;
-
-nsHTMLParanoidFragmentSink::nsHTMLParanoidFragmentSink(PRBool aAllContent):
-  nsHTMLFragmentContentSink(aAllContent), mSkip(PR_FALSE),
-  mProcessStyle(PR_FALSE), mInStyle(PR_FALSE), mProcessComments(PR_FALSE)
-{
-}
-
-nsresult
-nsHTMLParanoidFragmentSink::Init()
-{
-  nsresult rv = NS_ERROR_FAILURE;
-  
-  if (sAllowedTags) {
-    return NS_OK;
-  }
-
-  sAllowedTags = new nsTHashtable<nsISupportsHashKey>();
-  if (sAllowedTags) {
-    rv = sAllowedTags->Init(80);
-    for (PRUint32 i = 0; kDefaultAllowedTags[i] && NS_SUCCEEDED(rv); i++) {
-      if (!sAllowedTags->PutEntry(*kDefaultAllowedTags[i])) {
-        rv = NS_ERROR_OUT_OF_MEMORY;
-      }
-    }
-  }
-
-  sAllowedAttributes = new nsTHashtable<nsISupportsHashKey>();
-  if (sAllowedAttributes && NS_SUCCEEDED(rv)) {
-    rv = sAllowedAttributes->Init(80);
-    for (PRUint32 i = 0;
-         kDefaultAllowedAttributes[i] && NS_SUCCEEDED(rv); i++) {
-      if (!sAllowedAttributes->PutEntry(*kDefaultAllowedAttributes[i])) {
-        rv = NS_ERROR_OUT_OF_MEMORY;
-      }
-    }
-  }
-
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to populate whitelist hash sets");
-    Cleanup();
-    return rv; 
-  }
-
-  return rv;
-}
-
-void
-nsHTMLParanoidFragmentSink::Cleanup()
-{
-  if (sAllowedTags) {
-    delete sAllowedTags;
-    sAllowedTags = nsnull;
-  }
-  
-  if (sAllowedAttributes) {
-    delete sAllowedAttributes;
-    sAllowedAttributes = nsnull;
-  }
-}
-
-nsresult
-NS_NewHTMLParanoidFragmentSink(nsIFragmentContentSink** aResult)
-{
-  nsresult rv = nsHTMLParanoidFragmentSink::Init();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsHTMLParanoidFragmentSink* it = new nsHTMLParanoidFragmentSink();
-  NS_ADDREF(*aResult = it);
-  
-  return NS_OK;
-}
-
-nsresult
-NS_NewHTMLParanoidFragmentSink2(nsIFragmentContentSink** aResult)
-{
-  nsHTMLParanoidFragmentSink* it = new nsHTMLParanoidFragmentSink(PR_TRUE);
-  if (!it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  nsresult rv = nsHTMLParanoidFragmentSink::Init();
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ADDREF(*aResult = it);
-  
-  return NS_OK;
-}
-
-void
-NS_HTMLParanoidFragmentSinkShutdown()
-{
-  nsHTMLParanoidFragmentSink::Cleanup();
-}
-
-NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLParanoidFragmentSink, nsHTMLFragmentContentSink, nsIParanoidFragmentContentSink)
-
-nsresult
-nsHTMLParanoidFragmentSink::NameFromType(const nsHTMLTag aTag,
-                                         nsIAtom **aResult)
-{
-  nsIParserService* parserService = nsContentUtils::GetParserService();
-  if (!parserService) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  NS_IF_ADDREF(*aResult = parserService->HTMLIdToAtomTag(aTag));
-  
-  return NS_OK;
-}
-
-nsresult
-nsHTMLParanoidFragmentSink::NameFromNode(const nsIParserNode& aNode,
-                                         nsIAtom **aResult)
-{
-  nsresult rv;
-  eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
-  
-  *aResult = nsnull;
-  if (type == eHTMLTag_userdefined) {
-    *aResult = NS_NewAtom(aNode.GetText());
-  } else {
-    rv = NameFromType(type, aResult);
-  }
-  return rv;
-}
-
-void
-nsHTMLParanoidFragmentSink::AllowStyles()
-{
-  mProcessStyle = PR_TRUE;
-}
-
-void
-nsHTMLParanoidFragmentSink::AllowComments()
-{
-  mProcessComments = PR_TRUE;
-}
-
-// nsHTMLFragmentContentSink
-
-nsresult
-nsHTMLParanoidFragmentSink::AddAttributes(const nsIParserNode& aNode,
-                                          nsIContent* aContent)
-{
-  PRInt32 ac = aNode.GetAttributeCount();
-
-  if (ac == 0) {
-    return NS_OK;
-  }
-
-  nsAutoString k;
-  nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
-
-  nsresult rv;
-  // use this to check for safe URIs in the few attributes that allow them
-  nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
-  PRUint32 flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL;
-  nsCOMPtr<nsIURI> baseURI;
-  if (!mNullPrincipal) {
-      mNullPrincipal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  for (PRInt32 i = ac - 1; i >= 0; i--) {
-    rv = NS_OK;
-    nsContentUtils::ASCIIToLower(aNode.GetKeyAt(i), k);
-    nsCOMPtr<nsIAtom> keyAtom = do_GetAtom(k);
-
-    // Check if this is an allowed attribute, or a style attribute in case
-    // we've been asked to allow style attributes, or an HTML5 data-*
-    // attribute, or an attribute which begins with "_".
-    if ((!sAllowedAttributes || !sAllowedAttributes->GetEntry(keyAtom)) &&
-        (!mProcessStyle || keyAtom != nsGkAtoms::style) &&
-        !(StringBeginsWith(k, NS_LITERAL_STRING("data-")) ||
-          StringBeginsWith(k, NS_LITERAL_STRING("_")))) {
-      continue;
-    }
-
-    // Get value and remove mandatory quotes
-    static const char* kWhitespace = "\n\r\t\b";
-    const nsAString& v =
-      nsContentUtils::TrimCharsInSet(kWhitespace, aNode.GetValueAt(i));
-
-    // check the attributes we allow that contain URIs
-    // special case src attributes for img tags, because they can't
-    // run any dangerous code.
-    if (IsAttrURI(keyAtom) &&
-        !(nodeType == eHTMLTag_img && keyAtom == nsGkAtoms::src)) {
-      if (!baseURI) {
-        baseURI = aContent->GetBaseURI();
-      }
-      nsCOMPtr<nsIURI> attrURI;
-      rv = NS_NewURI(getter_AddRefs(attrURI), v, nsnull, baseURI);
-      if (NS_SUCCEEDED(rv)) {
-        rv = secMan->
-          CheckLoadURIWithPrincipal(mNullPrincipal, attrURI, flags);
-      }
-    }
-    
-    // skip to the next attribute if we encountered issues with the
-    // current value
-    if (NS_FAILED(rv)) {
-      continue;
-    }
-
-    // Filter unsafe stuff from style attributes if they're allowed
-    if (mProcessStyle && keyAtom == nsGkAtoms::style) {
-      if (!baseURI) {
-        baseURI = aContent->GetBaseURI();
-      }
-
-      // Pass the CSS Loader object to the parser, to allow parser error reports
-      // to include the outer window ID.
-      nsCSSParser parser(mTargetDocument->CSSLoader());
-      nsRefPtr<css::StyleRule> rule;
-      rv = parser.ParseStyleAttribute(aNode.GetValueAt(i),
-                                      mTargetDocument->GetDocumentURI(),
-                                      baseURI,
-                                      mTargetDocument->NodePrincipal(),
-                                      getter_AddRefs(rule));
-      if (NS_SUCCEEDED(rv)) {
-        nsAutoString cleanValue;
-        PRBool didSanitize = SanitizeStyleRule(rule, cleanValue);
-        if (didSanitize) {
-          aContent->SetAttr(kNameSpaceID_None, keyAtom, cleanValue, PR_FALSE);
-        } else {
-          aContent->SetAttr(kNameSpaceID_None, keyAtom, v, PR_FALSE);
-        }
-      } else {
-        // we couldn't sanitize the style attribute, ignore it
-        continue;
-      }
-    } else if (nodeType == eHTMLTag_a && keyAtom == nsGkAtoms::name) {
-      NS_ConvertUTF16toUTF8 cname(v);
-      NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
-      // Add attribute to content
-      aContent->SetAttr(kNameSpaceID_None, keyAtom, uv, PR_FALSE);
-    } else {
-      // Add attribute to content
-      aContent->SetAttr(kNameSpaceID_None, keyAtom, v, PR_FALSE);
-    }
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLParanoidFragmentSink::OpenContainer(const nsIParserNode& aNode)
-{
-  nsresult rv = NS_OK;
-  
-  // bail if it's a script or style (when we don't allow processing of stylesheets),
-  // or we're already inside one of those
-  eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
-  if (type == eHTMLTag_script || (!mProcessStyle && type == eHTMLTag_style)) {
-    mSkip = PR_TRUE;
-    return rv;
-  }
-
-  nsCOMPtr<nsIAtom> name;
-  rv = NameFromNode(aNode, getter_AddRefs(name));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // not on whitelist
-  if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
-    // unless it's style, and we're allowing it
-    if (!mProcessStyle || name != nsGkAtoms::style) {
-      return NS_OK;
-    }
-  }
-
-  if (type == eHTMLTag_style) {
-    mInStyle = PR_TRUE;
-  }
-
-  return nsHTMLFragmentContentSink::OpenContainer(aNode);
-}
-
-NS_IMETHODIMP
-nsHTMLParanoidFragmentSink::CloseContainer(const nsHTMLTag aTag)
-{
-  nsresult rv = NS_OK;
-
-  if (mIgnoreNextCloseHead && aTag == eHTMLTag_head) {
-    mIgnoreNextCloseHead = PR_FALSE;
-    return NS_OK;
-  }
-  if (mSkip) {
-    mSkip = PR_FALSE;
-    return rv;
-  }
-
-  nsCOMPtr<nsIAtom> name;
-  rv = NameFromType(aTag, getter_AddRefs(name));
-  NS_ENSURE_SUCCESS(rv, rv);
-  
-  // not on whitelist
-  if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
-    // unless it's style, and we're allowing it
-    if (!mProcessStyle || name != nsGkAtoms::style) {
-      return NS_OK;
-    }
-  }
-
-  if (mInStyle && name == nsGkAtoms::style) {
-    mInStyle = PR_FALSE;
-
-    // Flush the text to make sure that the style text is complete.
-    FlushText();
-
-    // sanitizedStyleText will hold the permitted CSS text.
-    // We use a white-listing approach, so we explicitly allow
-    // the CSS style and font-face rule types.  We also clear
-    // -moz-binding CSS properties.
-    nsAutoString sanitizedStyleText;
-    nsIContent* style = GetCurrentContent();
-    if (style) {
-      PRBool didSanitize = PR_FALSE;
-      // styleText will hold the text inside the style element.
-      nsAutoString styleText;
-      nsContentUtils::GetNodeTextContent(style, PR_FALSE, styleText);
-      // Create a sheet to hold the parsed CSS
-      nsRefPtr<nsCSSStyleSheet> sheet;
-      rv = NS_NewCSSStyleSheet(getter_AddRefs(sheet));
-      if (NS_SUCCEEDED(rv)) {
-        nsCOMPtr<nsIURI> baseURI = style->GetBaseURI();
-        sheet->SetURIs(mTargetDocument->GetDocumentURI(), nsnull, baseURI);
-        sheet->SetPrincipal(mTargetDocument->NodePrincipal());
-        // Create the CSS parser, and parse the CSS text.
-        nsCSSParser parser(nsnull, sheet);
-        rv = parser.ParseSheet(styleText, mTargetDocument->GetDocumentURI(),
-                               baseURI, mTargetDocument->NodePrincipal(),
-                               0, PR_FALSE);
-        // Mark the sheet as complete.
-        if (NS_SUCCEEDED(rv)) {
-          NS_ABORT_IF_FALSE(!sheet->IsModified(),
-                            "should not get marked modified during parsing");
-          sheet->SetComplete();
-        }
-        if (NS_SUCCEEDED(rv)) {
-          // Loop through all the rules found in the CSS text
-          PRInt32 ruleCount = sheet->StyleRuleCount();
-          for (PRInt32 i = 0; i < ruleCount; ++i) {
-            nsRefPtr<css::Rule> rule;
-            rv = sheet->GetStyleRuleAt(i, *getter_AddRefs(rule));
-            if (NS_FAILED(rv))
-              continue;
-            NS_ASSERTION(rule, "We should have a rule by now");
-            switch (rule->GetType()) {
-            default:
-              didSanitize = PR_TRUE;
-              // Ignore these rule types.
-              break;
-            case css::Rule::NAMESPACE_RULE:
-            case css::Rule::FONT_FACE_RULE: {
-              // Append @namespace and @font-face rules verbatim.
-              nsAutoString cssText;
-              nsCOMPtr<nsIDOMCSSRule> styleRule = do_QueryInterface(rule);
-              if (styleRule) {
-                rv = styleRule->GetCssText(cssText);
-                if (NS_SUCCEEDED(rv)) {
-                  sanitizedStyleText.Append(cssText);
-                }
-              }
-              break;
-            }
-            case css::Rule::STYLE_RULE: {
-              // For style rules, we will just look for and remove the
-              // -moz-binding properties.
-              nsRefPtr<css::StyleRule> styleRule = do_QueryObject(rule);
-              NS_ASSERTION(styleRule, "Must be a style rule");
-              nsAutoString decl;
-              didSanitize = SanitizeStyleRule(styleRule, decl) || didSanitize;
-              styleRule->GetCssText(decl);
-              sanitizedStyleText.Append(decl);
-            }
-            }
-          }
-        }
-      }
-      if (didSanitize) {
-        // Replace the style element content with its sanitized style text
-        nsContentUtils::SetNodeTextContent(style, sanitizedStyleText, PR_TRUE);
-      }
-    }
-  }
-
-  return nsHTMLFragmentContentSink::CloseContainer(aTag);
-}
-
-PRBool
-nsHTMLParanoidFragmentSink::SanitizeStyleRule(css::StyleRule *aRule, nsAutoString &aRuleText)
-{
-  PRBool didSanitize = PR_FALSE;
-  aRuleText.Truncate();
-  css::Declaration *style = aRule->GetDeclaration();
-  if (style) {
-    didSanitize = style->HasProperty(eCSSProperty_binding);
-    style->RemoveProperty(eCSSProperty_binding);
-    style->ToString(aRuleText);
-  }
-  return didSanitize;
-}
-
-NS_IMETHODIMP
-nsHTMLParanoidFragmentSink::AddLeaf(const nsIParserNode& aNode)
-{
-  NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
-  
-  nsresult rv = NS_OK;
-
-  // We need to explicitly skip adding leaf nodes in the paranoid sink,
-  // otherwise things like the textnode under <title> get appended to
-  // the fragment itself, and won't be popped off in CloseContainer.
-  if (mSkip || mIgnoreNextCloseHead) {
-    return rv;
-  }
-  
-  if (aNode.GetTokenType() == eToken_start) {
-    nsCOMPtr<nsIAtom> name;
-    rv = NameFromNode(aNode, getter_AddRefs(name));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Don't include base tags in output.
-    if (name == nsGkAtoms::base) {
-      return NS_OK;
-    }
-
-    if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
-      if (!mProcessStyle || name != nsGkAtoms::style) {
-        return NS_OK;
-      }
-    }
-  }
-
-  return nsHTMLFragmentContentSink::AddLeaf(aNode);
-}
-
-NS_IMETHODIMP
-nsHTMLParanoidFragmentSink::AddComment(const nsIParserNode& aNode)
-{
-  if (mProcessComments)
-    return nsHTMLFragmentContentSink::AddComment(aNode);
-  // no comments
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLParanoidFragmentSink::AddProcessingInstruction(const nsIParserNode& aNode)
-{
-  // no PIs
-  return NS_OK;
-}
--- a/content/media/nsBuiltinDecoder.h
+++ b/content/media/nsBuiltinDecoder.h
@@ -322,16 +322,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;
 
+  virtual PRInt64 VideoQueueMemoryInUse() = 0;
+  virtual PRInt64 AudioQueueMemoryInUse() = 0;
+
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 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
   // the main thread.
   virtual void StartBuffering() = 0;
 
@@ -466,16 +469,30 @@ class nsBuiltinDecoder : public nsMediaD
   // are buffered and playable.
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered) {
     if (mDecoderStateMachine) {
       return mDecoderStateMachine->GetBuffered(aBuffered);
     }
     return NS_ERROR_FAILURE;
   }
 
+  virtual PRInt64 VideoQueueMemoryInUse() {
+    if (mDecoderStateMachine) {
+      return mDecoderStateMachine->VideoQueueMemoryInUse();
+    }
+    return 0;
+  }
+
+  virtual PRInt64 AudioQueueMemoryInUse() {
+    if (mDecoderStateMachine) {
+      return mDecoderStateMachine->AudioQueueMemoryInUse();
+    }
+    return 0;
+  }
+
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {
     return mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
   }
 
   // Sets the length of the framebuffer used in MozAudioAvailable events.
   // The new size must be between 512 and 16384.
   virtual nsresult RequestFrameBufferLength(PRUint32 aLength);
 
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -45,18 +45,16 @@
 #include "nsBuiltinDecoderStateMachine.h"
 #include "mozilla/mozalloc.h"
 #include "VideoUtils.h"
 
 using namespace mozilla;
 using mozilla::layers::ImageContainer;
 using mozilla::layers::PlanarYCbCrImage;
 
-using mozilla::layers::PlanarYCbCrImage;
-
 // Verify these values are sane. Once we've checked the frame sizes, we then
 // can do less integer overflow checking.
 PR_STATIC_ASSERT(MAX_VIDEO_WIDTH < PlanarYCbCrImage::MAX_DIMENSION);
 PR_STATIC_ASSERT(MAX_VIDEO_HEIGHT < PlanarYCbCrImage::MAX_DIMENSION);
 PR_STATIC_ASSERT(PlanarYCbCrImage::MAX_DIMENSION < PR_UINT32_MAX / PlanarYCbCrImage::MAX_DIMENSION);
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -385,18 +385,23 @@ template <class T> class MediaQueue : pr
     if (GetSize() < 2) {
       return 0;
     }
     T* last = Peek();
     T* first = PeekFront();
     return last->mTime - first->mTime;
   }
 
+  void LockedForEach(nsDequeFunctor& aFunctor) const {
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+    ForEach(aFunctor);
+  }
+
 private:
-  ReentrantMonitor mReentrantMonitor;
+  mutable ReentrantMonitor mReentrantMonitor;
 
   // PR_TRUE when we've decoded the last frame of data in the
   // bitstream for which we're queueing sample-data.
   PRBool mEndOfStream;
 };
 
 // Encapsulates the decoding and reading of media data. Reading can only be
 // done on the decode thread thread. Never hold the decoder monitor when
@@ -460,16 +465,58 @@ public:
 
   // Populates aBuffered with the time ranges which are buffered. aStartTime
   // must be the presentation time of the first sample/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;
 
+  class VideoQueueMemoryFunctor : public nsDequeFunctor {
+  public:
+    VideoQueueMemoryFunctor() : mResult(0) {}
+
+    virtual void* operator()(void* anObject) {
+      const VideoData* v = static_cast<const VideoData*>(anObject);
+      NS_ASSERTION(v->mImage->GetFormat() == mozilla::layers::Image::PLANAR_YCBCR,
+                   "Wrong format?");
+      mozilla::layers::PlanarYCbCrImage* vi = static_cast<mozilla::layers::PlanarYCbCrImage*>(v->mImage.get());
+
+      mResult += vi->GetDataSize();
+      return nsnull;
+    }
+
+    PRInt64 mResult;
+  };
+
+  PRInt64 VideoQueueMemoryInUse() {
+    VideoQueueMemoryFunctor functor;
+    mVideoQueue.LockedForEach(functor);
+    return functor.mResult;
+  }
+
+  class AudioQueueMemoryFunctor : public nsDequeFunctor {
+  public:
+    AudioQueueMemoryFunctor() : mResult(0) {}
+
+    virtual void* operator()(void* anObject) {
+      const SoundData* soundData = static_cast<const SoundData*>(anObject);
+      mResult += soundData->mSamples * soundData->mChannels * sizeof(SoundDataValue);
+      return nsnull;
+    }
+
+    PRInt64 mResult;
+  };
+
+  PRInt64 AudioQueueMemoryInUse() {
+    AudioQueueMemoryFunctor functor;
+    mAudioQueue.LockedForEach(functor);
+    return functor.mResult;
+  }
+
   // Only used by nsWebMReader for now, so stub here rather than in every
   // reader than inherits from nsBuiltinDecoderReader.
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {}
 
 protected:
 
   // Pumps the decode until we reach frames/samples required to play at
   // time aTarget (usecs).
--- a/content/media/nsBuiltinDecoderStateMachine.h
+++ b/content/media/nsBuiltinDecoderStateMachine.h
@@ -223,16 +223,30 @@ public:
   // The decoder monitor must be obtained before modifying this state.
   // NotifyAll on the monitor must be called when the state is changed so
   // that interested threads can wake up and alter behaviour if appropriate
   // Accessed on state machine, audio, main, and AV thread.
   State mState;
 
   nsresult GetBuffered(nsTimeRanges* aBuffered);
 
+  PRInt64 VideoQueueMemoryInUse() {
+    if (mReader) {
+      return mReader->VideoQueueMemoryInUse();
+    }
+    return 0;
+  }
+
+  PRInt64 AudioQueueMemoryInUse() {
+    if (mReader) {
+      return mReader->AudioQueueMemoryInUse();
+    }
+    return 0;
+  }
+
   void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
     mReader->NotifyDataArrived(aBuffer, aLength, aOffset);
   }
 
   PRInt64 GetEndMediaTime() const {
     mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mEndTime;
--- a/content/media/nsMediaDecoder.cpp
+++ b/content/media/nsMediaDecoder.cpp
@@ -47,16 +47,17 @@
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsNetUtil.h"
 #include "nsHTMLMediaElement.h"
 #include "gfxContext.h"
 #include "nsPresContext.h"
 #include "nsDOMError.h"
 #include "nsDisplayList.h"
 #include "nsSVGEffects.h"
+#include "VideoUtils.h"
 
 using namespace mozilla;
 
 // Number of milliseconds between progress events as defined by spec
 #define PROGRESS_MS 350
 
 // Number of milliseconds of no data before a stall event is fired as defined by spec
 #define STALL_MS 3000
@@ -76,21 +77,23 @@ nsMediaDecoder::nsMediaDecoder() :
   mVideoUpdateLock("nsMediaDecoder.mVideoUpdateLock"),
   mFrameBufferLength(0),
   mPinnedForSeek(PR_FALSE),
   mSizeChanged(PR_FALSE),
   mImageContainerSizeChanged(PR_FALSE),
   mShuttingDown(PR_FALSE)
 {
   MOZ_COUNT_CTOR(nsMediaDecoder);
+  MediaMemoryReporter::AddMediaDecoder(this);
 }
 
 nsMediaDecoder::~nsMediaDecoder()
 {
   MOZ_COUNT_DTOR(nsMediaDecoder);
+  MediaMemoryReporter::RemoveMediaDecoder(this);
 }
 
 PRBool nsMediaDecoder::Init(nsHTMLMediaElement* aElement)
 {
   mElement = aElement;
   return PR_TRUE;
 }
 
@@ -300,8 +303,42 @@ PRBool nsMediaDecoder::CanPlayThrough()
   // our download rate or decode rate estimation is otherwise inaccurate,
   // we don't suddenly discover that we need to buffer. This is particularly
   // required near the start of the media, when not much data is downloaded.
   PRInt64 readAheadMargin =
     static_cast<PRInt64>(stats.mPlaybackRate * CAN_PLAY_THROUGH_MARGIN);
   return stats.mTotalBytes == stats.mDownloadPosition ||
          stats.mDownloadPosition > stats.mPlaybackPosition + readAheadMargin;
 }
+
+namespace mozilla {
+
+MediaMemoryReporter* MediaMemoryReporter::sUniqueInstance;
+
+NS_MEMORY_REPORTER_IMPLEMENT(MediaDecodedVideoMemory,
+                             "explicit/media/decoded-video",
+                             KIND_HEAP,
+                             UNITS_BYTES,
+                             MediaMemoryReporter::GetDecodedVideoMemory,
+                             "Memory used by decoded video frames.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(MediaDecodedAudioMemory,
+                             "explicit/media/decoded-audio",
+                             KIND_HEAP,
+                             UNITS_BYTES,
+                             MediaMemoryReporter::GetDecodedAudioMemory,
+                             "Memory used by decoded audio chunks.")
+
+MediaMemoryReporter::MediaMemoryReporter()
+  : mMediaDecodedVideoMemory(new NS_MEMORY_REPORTER_NAME(MediaDecodedVideoMemory))
+  , mMediaDecodedAudioMemory(new NS_MEMORY_REPORTER_NAME(MediaDecodedAudioMemory))
+{
+  NS_RegisterMemoryReporter(mMediaDecodedVideoMemory);
+  NS_RegisterMemoryReporter(mMediaDecodedAudioMemory);
+}
+
+MediaMemoryReporter::~MediaMemoryReporter()
+{
+  NS_UnregisterMemoryReporter(mMediaDecodedVideoMemory);
+  NS_UnregisterMemoryReporter(mMediaDecodedAudioMemory);
+}
+
+} // namespace mozilla
--- a/content/media/nsMediaDecoder.h
+++ b/content/media/nsMediaDecoder.h
@@ -44,16 +44,17 @@
 #include "nsSize.h"
 #include "prlog.h"
 #include "gfxContext.h"
 #include "gfxRect.h"
 #include "nsITimer.h"
 #include "ImageLayers.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
+#include "nsIMemoryReporter.h"
 
 class nsHTMLMediaElement;
 class nsMediaStream;
 class nsIStreamListener;
 class nsTimeRanges;
 
 // The size to use for audio data frames in MozAudioAvailable events.
 // This value is per channel, and is chosen to give ~43 fps of events,
@@ -364,16 +365,21 @@ public:
   // Constructs the time ranges representing what segments of the media
   // are buffered and playable.
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered) = 0;
 
   // Returns PR_TRUE if we can play the entire media through without stopping
   // to buffer, given the current download and playback rates.
   PRBool CanPlayThrough();
 
+  // Returns the size, in bytes, of the heap memory used by the currently
+  // queued decoded video and audio data.
+  virtual PRInt64 VideoQueueMemoryInUse() = 0;
+  virtual PRInt64 AudioQueueMemoryInUse() = 0;
+
 protected:
 
   // Start timer to update download progress information.
   nsresult StartProgress();
 
   // Stop progress information timer.
   nsresult StopProgress();
 
@@ -453,9 +459,67 @@ protected:
 
   // True if the decoder is being shutdown. At this point all events that
   // are currently queued need to return immediately to prevent javascript
   // being run that operates on the element and decoder during shutdown.
   // Read/Write from the main thread only.
   PRPackedBool mShuttingDown;
 };
 
+namespace mozilla {
+class MediaMemoryReporter
+{
+  MediaMemoryReporter();
+  ~MediaMemoryReporter();
+  static MediaMemoryReporter* sUniqueInstance;
+
+  static MediaMemoryReporter* UniqueInstance() {
+    if (!sUniqueInstance) {
+      sUniqueInstance = new MediaMemoryReporter;
+    }
+    return sUniqueInstance;
+  }
+
+  typedef nsTArray<nsMediaDecoder*> DecodersArray;
+  static DecodersArray& Decoders() {
+    return UniqueInstance()->mDecoders;
+  }
+
+  DecodersArray mDecoders;
+
+  nsCOMPtr<nsIMemoryReporter> mMediaDecodedVideoMemory;
+  nsCOMPtr<nsIMemoryReporter> mMediaDecodedAudioMemory;
+
+public:
+  static void AddMediaDecoder(nsMediaDecoder* aDecoder) {
+    Decoders().AppendElement(aDecoder);
+  }
+
+  static void RemoveMediaDecoder(nsMediaDecoder* aDecoder) {
+    DecodersArray& decoders = Decoders();
+    decoders.RemoveElement(aDecoder);
+    if (decoders.IsEmpty()) {
+      delete sUniqueInstance;
+      sUniqueInstance = nsnull;
+    }
+  }
+
+  static PRInt64 GetDecodedVideoMemory() {
+    DecodersArray& decoders = Decoders();
+    PRInt64 result = 0;
+    for (size_t i = 0; i < decoders.Length(); ++i) {
+      result += decoders[i]->VideoQueueMemoryInUse();
+    }
+    return result;
+  }
+
+  static PRInt64 GetDecodedAudioMemory() {
+    DecodersArray& decoders = Decoders();
+    PRInt64 result = 0;
+    for (size_t i = 0; i < decoders.Length(); ++i) {
+      result += decoders[i]->AudioQueueMemoryInUse();
+    }
+    return result;
+  }
+};
+
+} //namespace mozilla
 #endif
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -364,33 +364,32 @@ nsresult nsOggReader::DecodeVorbis(ogg_p
   }
 
   VorbisPCMValue** pcm = 0;
   PRInt32 samples = 0;
   PRUint32 channels = mVorbisState->mInfo.channels;
   ogg_int64_t endSample = aPacket->granulepos;
   while ((samples = vorbis_synthesis_pcmout(&mVorbisState->mDsp, &pcm)) > 0) {
     mVorbisState->ValidateVorbisPacketSamples(aPacket, samples);
-    SoundDataValue* buffer = new SoundDataValue[samples * channels];
+    nsAutoArrayPtr<SoundDataValue> buffer(new SoundDataValue[samples * channels]);
     for (PRUint32 j = 0; j < channels; ++j) {
       VorbisPCMValue* channel = pcm[j];
       for (PRUint32 i = 0; i < PRUint32(samples); ++i) {
         buffer[i*channels + j] = MOZ_CONVERT_VORBIS_SAMPLE(channel[i]);
       }
     }
 
     PRInt64 duration = mVorbisState->Time((PRInt64)samples);
     PRInt64 startTime = mVorbisState->Time(endSample - samples);
-    SoundData* s = new SoundData(mPageOffset,
-                                 startTime,
-                                 duration,
-                                 samples,
-                                 buffer,
-                                 channels);
-    mAudioQueue.Push(s);
+    mAudioQueue.Push(new SoundData(mPageOffset,
+                                   startTime,
+                                   duration,
+                                   samples,
+                                   buffer.forget(),
+                                   channels));
     endSample -= samples;
     if (vorbis_synthesis_read(&mVorbisState->mDsp, samples) != 0) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -479,17 +479,17 @@ PRBool nsWebMReader::DecodeAudioPacket(n
     if (vorbis_synthesis_blockin(&mVorbisDsp,
                                  &mVorbisBlock) != 0) {
       return PR_FALSE;
     }
 
     VorbisPCMValue** pcm = 0;
     PRInt32 samples = 0;
     while ((samples = vorbis_synthesis_pcmout(&mVorbisDsp, &pcm)) > 0) {
-      SoundDataValue* buffer = new SoundDataValue[samples * mChannels];
+      nsAutoArrayPtr<SoundDataValue> buffer(new SoundDataValue[samples * mChannels]);
       for (PRUint32 j = 0; j < mChannels; ++j) {
         VorbisPCMValue* channel = pcm[j];
         for (PRUint32 i = 0; i < PRUint32(samples); ++i) {
           buffer[i*mChannels + j] = MOZ_CONVERT_VORBIS_SAMPLE(channel[i]);
         }
       }
 
       PRInt64 duration = 0;
@@ -500,23 +500,22 @@ PRBool nsWebMReader::DecodeAudioPacket(n
       PRInt64 total_duration = 0;
       if (!SamplesToUsecs(total_samples, rate, total_duration)) {
         NS_WARNING("Int overflow converting WebM audio total_duration");
         return PR_FALSE;
       }
       
       PRInt64 time = tstamp_usecs + total_duration;
       total_samples += samples;
-      SoundData* s = new SoundData(aOffset,
-                                   time,
-                                   duration,
-                                   samples,
-                                   buffer,
-                                   mChannels);
-      mAudioQueue.Push(s);
+      mAudioQueue.Push(new SoundData(aOffset,
+                                     time,
+                                     duration,
+                                     samples,
+                                     buffer.forget(),
+                                     mChannels));
       mAudioSamples += samples;
       if (vorbis_synthesis_read(&mVorbisDsp, samples) != 0) {
         return PR_FALSE;
       }
     }
   }
 
   return PR_TRUE;
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -474,319 +474,8 @@ nsXMLFragmentContentSink::DidProcessATok
 }
 
 NS_IMETHODIMP
 nsXMLFragmentContentSink::IgnoreFirstContainer()
 {
   NS_NOTREACHED("XML isn't as broken as HTML");
   return NS_ERROR_FAILURE;
 }
-
-
-// nsXHTMLParanoidFragmentSink
-
-// Find the whitelist of allowed elements and attributes in
-// nsContentSink.h We share it with nsHTMLParanoidFragmentSink
-
-class nsXHTMLParanoidFragmentSink : public nsXMLFragmentContentSink
-{
-public:
-  nsXHTMLParanoidFragmentSink(PRBool aAllContent = PR_FALSE);
-
-  static nsresult Init();
-  static void Cleanup();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-  
-  // nsXMLContentSink
-  nsresult AddAttributes(const PRUnichar** aNode, nsIContent* aContent);
-
-  // nsIExpatSink
-  NS_IMETHOD HandleStartElement(const PRUnichar *aName,
-                                const PRUnichar **aAtts,
-                                PRUint32 aAttsCount, PRInt32 aIndex,
-                                PRUint32 aLineNumber);
-    
-  NS_IMETHOD HandleEndElement(const PRUnichar *aName);
-
-  NS_IMETHOD HandleComment(const PRUnichar *aName);
-
-  NS_IMETHOD HandleProcessingInstruction(const PRUnichar *aTarget, 
-                                         const PRUnichar *aData);
-
-  NS_IMETHOD HandleCDataSection(const PRUnichar *aData, 
-                                PRUint32 aLength);
-
-  NS_IMETHOD HandleCharacterData(const PRUnichar *aData,
-                                 PRUint32 aLength);
-protected:
-  PRUint32 mSkipLevel; // used when we descend into <style> or <script>
-
-  nsCOMPtr<nsIPrincipal> mNullPrincipal;
-
-  // Use nsTHashTable as a hash set for our whitelists
-  static nsTHashtable<nsISupportsHashKey>* sAllowedTags;
-  static nsTHashtable<nsISupportsHashKey>* sAllowedAttributes;
-};
-
-nsTHashtable<nsISupportsHashKey>* nsXHTMLParanoidFragmentSink::sAllowedTags;
-nsTHashtable<nsISupportsHashKey>* nsXHTMLParanoidFragmentSink::sAllowedAttributes;
-
-nsXHTMLParanoidFragmentSink::nsXHTMLParanoidFragmentSink(PRBool aAllContent):
-  nsXMLFragmentContentSink(aAllContent), mSkipLevel(0)
-{
-}
-
-nsresult
-nsXHTMLParanoidFragmentSink::Init()
-{
-  nsresult rv = NS_ERROR_FAILURE;
-  
-  if (sAllowedTags) {
-    return NS_OK;
-  }
-
-  sAllowedTags = new nsTHashtable<nsISupportsHashKey>();
-  if (sAllowedTags) {
-    rv = sAllowedTags->Init(80);
-    for (PRUint32 i = 0; kDefaultAllowedTags[i] && NS_SUCCEEDED(rv); i++) {
-      if (!sAllowedTags->PutEntry(*kDefaultAllowedTags[i])) {
-        rv = NS_ERROR_OUT_OF_MEMORY;
-      }
-    }
-  }
-
-  sAllowedAttributes = new nsTHashtable<nsISupportsHashKey>();
-  if (sAllowedAttributes && NS_SUCCEEDED(rv)) {
-    rv = sAllowedAttributes->Init(80);
-    for (PRUint32 i = 0;
-         kDefaultAllowedAttributes[i] && NS_SUCCEEDED(rv); i++) {
-      if (!sAllowedAttributes->PutEntry(*kDefaultAllowedAttributes[i])) {
-        rv = NS_ERROR_OUT_OF_MEMORY;
-      }
-    }
-  }
-
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to populate whitelist hash sets");
-    Cleanup();
-  }
-
-  return rv;
-}
-
-void
-nsXHTMLParanoidFragmentSink::Cleanup()
-{
-  if (sAllowedTags) {
-    delete sAllowedTags;
-    sAllowedTags = nsnull;
-  }
-  
-  if (sAllowedAttributes) {
-    delete sAllowedAttributes;
-    sAllowedAttributes = nsnull;
-  }
-}
-
-nsresult
-NS_NewXHTMLParanoidFragmentSink(nsIFragmentContentSink** aResult)
-{
-  nsresult rv = nsXHTMLParanoidFragmentSink::Init();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsXHTMLParanoidFragmentSink* it = new nsXHTMLParanoidFragmentSink();
-  NS_ADDREF(*aResult = it);
-  
-  return NS_OK;
-}
-
-nsresult
-NS_NewXHTMLParanoidFragmentSink2(nsIFragmentContentSink** aResult)
-{
-  nsXHTMLParanoidFragmentSink* it = new nsXHTMLParanoidFragmentSink(PR_TRUE);
-  if (!it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  nsresult rv = nsXHTMLParanoidFragmentSink::Init();
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ADDREF(*aResult = it);
-  
-  return NS_OK;
-}
-
-void
-NS_XHTMLParanoidFragmentSinkShutdown()
-{
-  nsXHTMLParanoidFragmentSink::Cleanup();
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(nsXHTMLParanoidFragmentSink,
-                             nsXMLFragmentContentSink)
-
-nsresult
-nsXHTMLParanoidFragmentSink::AddAttributes(const PRUnichar** aAtts,
-                                           nsIContent* aContent)
-{
-  nsresult rv = NS_OK;
-
-  // use this to check for safe URIs in the few attributes that allow them
-  nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
-  nsCOMPtr<nsIURI> baseURI;
-  PRUint32 flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL;
-
-  // scrub URI attributes that point at dangerous content
-  // We have to do this here, because this is where we have a base URI,
-  // but we can't do all the scrubbing here, because other parts of the
-  // code get the attributes before this method is called.
-  nsTArray<const PRUnichar *> allowedAttrs;
-  PRInt32 nameSpaceID;
-  nsCOMPtr<nsIAtom> prefix, localName;
-
-  if (!mNullPrincipal) {
-      mNullPrincipal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  while (*aAtts) {
-    nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
-                                   getter_AddRefs(localName), &nameSpaceID);
-    // check the attributes we allow that contain URIs
-    if (IsAttrURI(localName)) {
-      if (!aAtts[1])
-        rv = NS_ERROR_FAILURE;
-      if (!baseURI)
-        baseURI = aContent->GetBaseURI();
-      nsCOMPtr<nsIURI> attrURI;
-      rv = NS_NewURI(getter_AddRefs(attrURI), nsDependentString(aAtts[1]),
-                     nsnull, baseURI);
-      if (NS_SUCCEEDED(rv)) {
-        rv = secMan->CheckLoadURIWithPrincipal(mNullPrincipal, attrURI, flags);
-      }
-    }
-
-    if (NS_SUCCEEDED(rv)) {
-      allowedAttrs.AppendElement(aAtts[0]);
-      allowedAttrs.AppendElement(aAtts[1]);
-    }
-
-    aAtts += 2;
-  }
-  allowedAttrs.AppendElement((const PRUnichar*) nsnull);
-
-  return nsXMLFragmentContentSink::AddAttributes(allowedAttrs.Elements(),
-                                                 aContent);
-}
-
-NS_IMETHODIMP
-nsXHTMLParanoidFragmentSink::HandleStartElement(const PRUnichar *aName,
-                                                const PRUnichar **aAtts,
-                                                PRUint32 aAttsCount,
-                                                PRInt32 aIndex,
-                                                PRUint32 aLineNumber)
-{
-  PRInt32 nameSpaceID;
-  nsCOMPtr<nsIAtom> prefix, localName;
-  nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
-                                 getter_AddRefs(localName), &nameSpaceID);
-  
-  // If the element is not in the XHTML namespace, bounce it
-  if (nameSpaceID != kNameSpaceID_XHTML)
-    return NS_OK;
-  
-  // bounce it if it's not on the whitelist or we're inside
-  // <script> or <style>
-  if (mSkipLevel != 0 ||
-      localName == nsGkAtoms::script ||
-      localName == nsGkAtoms::style) {
-    ++mSkipLevel; // track this so we don't spew script text
-    return NS_OK;
-  }  
-  
-  if (!sAllowedTags || !sAllowedTags->GetEntry(localName))
-    return NS_OK;
-  
-  // It's an allowed element, so let's scrub the attributes
-  nsTArray<const PRUnichar *> allowedAttrs;
-  for (PRUint32 i = 0; i < aAttsCount; i += 2) {
-    nsContentUtils::SplitExpatName(aAtts[i], getter_AddRefs(prefix),
-                                   getter_AddRefs(localName), &nameSpaceID);
-    // Add if it's xmlns, xml: or on the HTML whitelist
-    if (nameSpaceID == kNameSpaceID_XMLNS ||
-        nameSpaceID == kNameSpaceID_XML ||
-        (sAllowedAttributes && sAllowedAttributes->GetEntry(localName))) {
-      allowedAttrs.AppendElement(aAtts[i]);
-      allowedAttrs.AppendElement(aAtts[i + 1]);
-    }
-  }
-  allowedAttrs.AppendElement((const PRUnichar*) nsnull);
-  return
-    nsXMLFragmentContentSink::HandleStartElement(aName,
-                                                 allowedAttrs.Elements(),
-                                                 allowedAttrs.Length() - 1,
-                                                 aIndex,
-                                                 aLineNumber);
-}
-
-NS_IMETHODIMP 
-nsXHTMLParanoidFragmentSink::HandleEndElement(const PRUnichar *aName)
-{
-  PRInt32 nameSpaceID;
-  nsCOMPtr<nsIAtom> prefix, localName;
-  nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
-                                 getter_AddRefs(localName), &nameSpaceID);
-  
-  // If the element is not in the XHTML namespace, bounce it
-  if (nameSpaceID != kNameSpaceID_XHTML) {
-    return NS_OK;
-  }
-  
-  if (mSkipLevel != 0) {
-    --mSkipLevel;
-    return NS_OK;
-  }
-
-  if (!sAllowedTags || !sAllowedTags->GetEntry(localName)) {
-    return NS_OK;
-  }
-
-  return nsXMLFragmentContentSink::HandleEndElement(aName);
-}
-
-NS_IMETHODIMP
-nsXHTMLParanoidFragmentSink::
-HandleProcessingInstruction(const PRUnichar *aTarget, 
-                            const PRUnichar *aData)
-{
-  // We don't do PIs
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXHTMLParanoidFragmentSink::HandleComment(const PRUnichar *aName)
-{
-  // We don't do comments
-  return NS_OK;
-}
-
-// We pass all character data through, unless we're inside <script>
-NS_IMETHODIMP 
-nsXHTMLParanoidFragmentSink::HandleCDataSection(const PRUnichar *aData, 
-                                                PRUint32 aLength)
-{
-  if (mSkipLevel != 0) {
-    return NS_OK;
-  }
-
-  return nsXMLFragmentContentSink::HandleCDataSection(aData, aLength);
-}
-
-NS_IMETHODIMP 
-nsXHTMLParanoidFragmentSink::HandleCharacterData(const PRUnichar *aData, 
-                                                 PRUint32 aLength)
-{
-  if (mSkipLevel != 0) {
-    return NS_OK;
-  }
-
-  return nsXMLFragmentContentSink::HandleCharacterData(aData, aLength);
-}
--- a/docshell/resources/content/netError.xhtml
+++ b/docshell/resources/content/netError.xhtml
@@ -387,17 +387,17 @@
              error types.  -->
         <div id="securityOverrideDiv">
           <a id="securityOverrideLink" href="javascript:showSecuritySection();" >&securityOverride.linkText;</a>
           <div id="securityOverrideContent" style="display: none;">&securityOverride.warningContent;</div>
         </div>
       </div>
 
       <!-- Retry Button -->
-      <button id="errorTryAgain" onclick="retryThis(this);">&retry.label;</button>
+      <button id="errorTryAgain" autocomplete="off" onclick="retryThis(this);">&retry.label;</button>
 
     </div>
 
     <!--
     - Note: It is important to run the script this way, instead of using
     - an onload handler. This is because error pages are loaded as
     - LOAD_BACKGROUND, which means that onload handlers will not be executed.
     -->
--- a/docshell/test/chrome/docshell_helpers.js
+++ b/docshell/test/chrome/docshell_helpers.js
@@ -312,20 +312,17 @@ function pageEventListener(event) {
 function finish() {
   // Work around bug 467960.
   var history = TestWindow.getBrowser().webNavigation.sessionHistory;
   history.PurgeHistory(history.count);
   
   // If the test changed the value of max_total_viewers via a call to
   // enableBFCache(), then restore it now.
   if (typeof(gOrigMaxTotalViewers) != "undefined") {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-    var prefs = Components.classes["@mozilla.org/preferences-service;1"]
-                .getService(Components.interfaces.nsIPrefBranch);
-    prefs.setIntPref("browser.sessionhistory.max_total_viewers",
+    SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers",
       gOrigMaxTotalViewers);
   }
 
   // Close the test window and signal the framework that the test is done.
   let opener = window.opener;
   window.close();
   opener.wrappedJSObject.SimpleTest.finish();
 }
@@ -382,36 +379,31 @@ function waitForTrue(fn, onWaitComplete,
  * Enable or disable the bfcache.
  *
  * Parameters:
  *
  *   enable: if true, set max_total_viewers to -1 (the default); if false, set 
  *           to 0 (disabled), if a number, set it to that specific number
  */
 function enableBFCache(enable) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"]
-              .getService(Components.interfaces.nsIPrefBranch);
-  
   // If this is the first time the test called enableBFCache(),
   // store the original value of max_total_viewers, so it can
   // be restored at the end of the test.
   if (typeof(gOrigMaxTotalViewers) == "undefined") {
-    gOrigMaxTotalViewers =
-      prefs.getIntPref("browser.sessionhistory.max_total_viewers");
+    gOrigMaxTotalViewers = SpecialPowers.getIntPref("browser.sessionhistory.max_total_viewers");
   }
   
   if (typeof(enable) == "boolean") {
     if (enable)
-      prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1);
+      SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers", -1);
     else
-      prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0);    
+      SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers", 0);    
   }
   else if (typeof(enable) == "number") {
-    prefs.setIntPref("browser.sessionhistory.max_total_viewers", enable);    
+    SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers", enable);    
   }
 }
 
 /*
  * get http root for local tests.  Use a single extractJarToTmp instead of 
  * extracting for each test.  
  * Returns a file://path if we have a .jar file
  */
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -5981,17 +5981,17 @@ PostMessageEvent::Run()
     }
   }
 
   // If we bailed before this point we're going to leak mMessage, but
   // that's probably better than crashing.
 
   // Ensure that the buffer is freed even if we fail to post the message
   JSAutoStructuredCloneBuffer buffer;
-  buffer.adopt(cx, mMessage, mMessageLen);
+  buffer.adopt(mMessage, mMessageLen);
   mMessage = nsnull;
   mMessageLen = 0;
 
   nsRefPtr<nsGlobalWindow> targetWindow;
   if (mTargetWindow->IsClosedOrClosing() ||
       !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) ||
       targetWindow->IsClosedOrClosing())
     return NS_OK;
@@ -6035,17 +6035,17 @@ PostMessageEvent::Run()
       return NS_OK;
   }
 
   // Deserialize the structured clone data
   jsval messageData;
   {
     JSAutoRequest ar(cx);
 
-    if (!buffer.read(&messageData, cx, nsnull))
+    if (!buffer.read(cx, &messageData, nsnull))
       return NS_ERROR_DOM_DATA_CLONE_ERR;
   }
 
   // Create the event
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(targetWindow->mDocument);
   if (!domDoc)
     return NS_OK;
   nsCOMPtr<nsIDOMEvent> event;
--- a/dom/indexedDB/AsyncConnectionHelper.cpp
+++ b/dom/indexedDB/AsyncConnectionHelper.cpp
@@ -501,17 +501,17 @@ AsyncConnectionHelper::ConvertCloneBuffe
   NS_ASSERTION(aCx, "Null context!");
   NS_ASSERTION(aResult, "Null pointer!");
 
   JSAutoRequest ar(aCx);
 
   nsresult rv = ConvertCloneBuffersToArrayInternal(aCx, aBuffers, aResult);
 
   for (PRUint32 index = 0; index < aBuffers.Length(); index++) {
-    aBuffers[index].clear(aCx);
+    aBuffers[index].clear();
   }
   aBuffers.Clear();
 
   return rv;
 }
 
 NS_IMETHODIMP_(nsrefcnt)
 TransactionPoolEventTarget::AddRef()
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -470,17 +470,17 @@ IDBCursor::GetValue(JSContext* aCx,
       mRooted = true;
     }
 
     if (!IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, &mCachedValue)) {
       mCachedValue = JSVAL_VOID;
       return NS_ERROR_DOM_DATA_CLONE_ERR;
     }
 
-    mCloneBuffer.clear(aCx);
+    mCloneBuffer.clear();
     mHaveCachedValue = true;
   }
 
   *aValue = mCachedValue;
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -715,17 +715,17 @@ ContinueHelper::GetSuccessResult(JSConte
                  !mObjectKey.IsUnset(), "Bad key!");
 
     // Set new values.
     mCursor->mKey = mKey;
     mCursor->mObjectKey = mObjectKey;
     mCursor->mContinueToKey = Key::UNSETKEY;
 
     mCursor->mCloneBuffer.swap(mCloneBuffer);
-    mCloneBuffer.clear(aCx);
+    mCloneBuffer.clear();
 
     nsresult rv = WrapNative(aCx, mCursor, aVal);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -777,17 +777,17 @@ GetHelper::DoDatabaseWork(mozIStorageCon
 }
 
 nsresult
 GetHelper::GetSuccessResult(JSContext* aCx,
                             jsval* aVal)
 {
   bool result = IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, aVal);
 
-  mCloneBuffer.clear(aCx);
+  mCloneBuffer.clear();
 
   NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 nsresult
 GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
 {
@@ -1051,17 +1051,17 @@ nsresult
 GetAllHelper::GetSuccessResult(JSContext* aCx,
                                jsval* aVal)
 {
   NS_ASSERTION(mCloneBuffers.Length() <= mLimit, "Too many results!");
 
   nsresult rv = ConvertCloneBuffersToArray(aCx, mCloneBuffers, aVal);
 
   for (PRUint32 index = 0; index < mCloneBuffers.Length(); index++) {
-    mCloneBuffers[index].clear(aCx);
+    mCloneBuffers[index].clear();
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
   return NS_OK;
 }
 
 nsresult
 OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -834,48 +834,27 @@ IDBObjectStore::GetStructuredCloneDataFr
   }
 #endif
 
   const PRUint8* data;
   PRUint32 dataLength;
   nsresult rv = aStatement->GetSharedBlob(aIndex, &dataLength, &data);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
-  JSContext* cx;
-  rv = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-  JSAutoRequest ar(cx);
-
-  uint64* newData = static_cast<uint64*>(JS_malloc(cx, dataLength));
-  NS_ENSURE_TRUE(newData, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-  memcpy(newData, data, dataLength);
-  aBuffer.adopt(cx, newData, dataLength);
-
-  return NS_OK;
+  return aBuffer.copy(reinterpret_cast<const uint64 *>(data), dataLength) ?
+         NS_OK :
+         NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
 }
 
 // static
 void
 IDBObjectStore::ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer)
 {
   if (aBuffer.data()) {
-    JSContext* cx;
-    if (NS_SUCCEEDED(nsContentUtils::ThreadJSContextStack()->
-                     GetSafeJSContext(&cx))) {
-      JSAutoRequest ar(cx);
-      aBuffer.clear(cx);
-    }
-    else {
-      NS_WARNING("Couldn't get safe JSContext! Leaking data!");
-      uint64* data;
-      size_t length;
-      aBuffer.steal(&data, &length);
-    }
+    aBuffer.clear();
   }
 }
 
 // static
 bool
 IDBObjectStore::DeserializeValue(JSContext* aCx,
                                  JSAutoStructuredCloneBuffer& aBuffer,
                                  jsval* aValue,
@@ -888,17 +867,17 @@ IDBObjectStore::DeserializeValue(JSConte
 
   if (!aBuffer.data()) {
     *aValue = JSVAL_VOID;
     return true;
   }
 
   JSAutoRequest ar(aCx);
 
-  return aBuffer.read(aValue, aCx, aCallbacks, aClosure);
+  return aBuffer.read(aCx, aValue, aCallbacks, aClosure);
 }
 
 // static
 bool
 IDBObjectStore::SerializeValue(JSContext* aCx,
                                JSAutoStructuredCloneBuffer& aBuffer,
                                jsval aValue,
                                JSStructuredCloneCallbacks* aCallbacks,
@@ -1895,17 +1874,17 @@ AddHelper::DoDatabaseWork(mozIStorageCon
 }
 
 nsresult
 AddHelper::GetSuccessResult(JSContext* aCx,
                             jsval* aVal)
 {
   NS_ASSERTION(!mKey.IsUnset(), "Badness!");
 
-  mCloneBuffer.clear(aCx);
+  mCloneBuffer.clear();
 
   return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal);
 }
 
 nsresult
 GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
 {
   NS_PRECONDITION(aConnection, "Passed a null connection!");
@@ -1950,17 +1929,17 @@ GetHelper::DoDatabaseWork(mozIStorageCon
 }
 
 nsresult
 GetHelper::GetSuccessResult(JSContext* aCx,
                             jsval* aVal)
 {
   bool result = IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, aVal);
 
-  mCloneBuffer.clear(aCx);
+  mCloneBuffer.clear();
 
   NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 nsresult
 DeleteHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
 {
@@ -2525,14 +2504,14 @@ nsresult
 GetAllHelper::GetSuccessResult(JSContext* aCx,
                                jsval* aVal)
 {
   NS_ASSERTION(mCloneBuffers.Length() <= mLimit, "Too many results!");
 
   nsresult rv = ConvertCloneBuffersToArray(aCx, mCloneBuffers, aVal);
 
   for (PRUint32 index = 0; index < mCloneBuffers.Length(); index++) {
-    mCloneBuffers[index].clear(aCx);
+    mCloneBuffers[index].clear();
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
   return NS_OK;
 }
--- a/dom/interfaces/html/nsIDOMHTMLInputElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLInputElement.idl
@@ -49,17 +49,17 @@ interface nsIDOMValidityState;
   *
   * This interface is trying to follow the DOM Level 2 HTML specification:
   * http://www.w3.org/TR/DOM-Level-2-HTML/
   *
   * with changes from the work-in-progress WHATWG HTML specification:
   * http://www.whatwg.org/specs/web-apps/current-work/
   */
 
-[scriptable, uuid(a59ba6b8-6f8b-4003-a8a4-184a51a05050)]
+[scriptable, uuid(66819eba-89b5-4db4-8d27-6368c70761e8)]
 interface nsIDOMHTMLInputElement : nsIDOMHTMLElement
 {
            attribute DOMString             accept;
            attribute DOMString             alt;
 
            attribute DOMString             autocomplete;
            attribute boolean               autofocus;
            attribute boolean               defaultChecked;
@@ -102,18 +102,19 @@ interface nsIDOMHTMLInputElement : nsIDO
   readonly attribute nsIDOMValidityState validity;
   readonly attribute DOMString           validationMessage;
   boolean checkValidity();
   void setCustomValidity(in DOMString error);
 
   void select();
            attribute long                  selectionStart;
            attribute long                  selectionEnd;
-  void setSelectionRange(in long selectionStart, in long selectionEnd);
-          
+  void setSelectionRange(in long selectionStart, in long selectionEnd, [optional] in DOMString direction);
+           attribute DOMString             selectionDirection;
+
 
            attribute long                  tabIndex;
            attribute DOMString             useMap;
   readonly attribute nsIControllers        controllers;	
 	readonly attribute long                  textLength;
 
   void mozGetFileNameArray([optional] out unsigned long aLength,
                            [array,size_is(aLength), retval] out wstring aFileNames);
--- a/dom/interfaces/html/nsIDOMHTMLTextAreaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTextAreaElement.idl
@@ -48,17 +48,17 @@ interface nsIDOMValidityState;
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(905edd3e-c0b3-4d54-8a2c-0eaab6ccb3cf)]
+[scriptable, uuid(43e99aee-e41f-4935-a87d-f2dbafdbfddb)]
 interface nsIDOMHTMLTextAreaElement : nsIDOMHTMLElement
 {
            attribute boolean               autofocus;
            attribute unsigned long         cols;
            attribute boolean               disabled;
   readonly attribute nsIDOMHTMLFormElement form;
            attribute long                  maxLength;
            attribute DOMString             name;
@@ -84,17 +84,18 @@ interface nsIDOMHTMLTextAreaElement : ns
   readonly attribute nsIDOMValidityState   validity;
   readonly attribute DOMString             validationMessage;
   boolean checkValidity();
   void setCustomValidity(in DOMString error);
 
   void select();
            attribute long                  selectionStart;
            attribute long                  selectionEnd;
-  void setSelectionRange(in long selectionStart, in long selectionEnd);
+  void setSelectionRange(in long selectionStart, in long selectionEnd, [optional] in DOMString direction);
+           attribute DOMString             selectionDirection;
 
   // Defined on HTMLElement in the specification.
            attribute long                  tabIndex;
 
 
   // Mozilla extensions
   readonly attribute nsIControllers   controllers;
 };
--- a/dom/plugins/test/mochitest/Makefile.in
+++ b/dom/plugins/test/mochitest/Makefile.in
@@ -94,17 +94,16 @@ include $(topsrcdir)/config/rules.mk
   test_GCrace.html \
   test_propertyAndMethod.html \
   test_bug539565-1.html \
   test_bug539565-2.html \
   test_enumerate.html \
   test_npruntime_construct.html \
   307-xo-redirect.sjs \
   test_redirect_handling.html \
-  test_clear_site_data.html \
   test_zero_opacity.html \
   test_NPPVpluginWantsAllNetworkStreams.html \
   test_npruntime_npnsetexception.html \
   $(NULL)
 
 #  test_plugin_scroll_painting.html \ bug 596491
 
 ifeq ($(OS_ARCH),WINNT)
@@ -113,16 +112,17 @@ ifeq ($(OS_ARCH),WINNT)
   $(NULL)
 
 # test_positioning.html \ disabled due to oddness, perhaps scrolling of the
 # mochitest window?
 endif
 
 _MOCHICHROME_FILES = \
   utils.js \
+  test_clear_site_data.html \
   test_npruntime.xul   \
   test_privatemode.xul \
   test_wmode.xul \
   test_bug479979.xul \
   $(NULL)
 
 ifneq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 _MOCHITEST_FILES += \
--- a/dom/plugins/test/mochitest/test_clear_site_data.html
+++ b/dom/plugins/test/mochitest/test_clear_site_data.html
@@ -1,20 +1,19 @@
 <html>
 <head>
   <title>NPAPI ClearSiteData/GetSitesWithData Functionality</title>
-  <script type="application/javascript" src="/MochiKit/packed.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/PluginUtils.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/PluginUtils.js"></script>
 </head>
 <body>
   <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
 
   <script class="testbody" type="application/javascript">
-    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     SimpleTest.waitForExplicitFinish();
 
     const pluginHostIface = Components.interfaces.nsIPluginHost;
     var pluginHost = Components.classes["@mozilla.org/plugin/host;1"].
                      getService(pluginHostIface);
     const FLAG_CLEAR_ALL = pluginHostIface.FLAG_CLEAR_ALL;
     const FLAG_CLEAR_CACHE = pluginHostIface.FLAG_CLEAR_CACHE;
 
@@ -44,18 +43,16 @@
         fn();
         throw new Error("bad exception");
       } catch (e) {
         is(e.result, result, "Correct exception thrown");
       }
     }
 
     function runTest(pluginTag) {
-      netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
       this.pluginTag = pluginTag;
 
       p.setSitesWithData(
         "foo.com:0:5," +
         "foo.com:0:7," +
         "bar.com:0:10," +
         "baz.com:0:10," +
         "foo.com:1:7," +
--- a/dom/src/Makefile.in
+++ b/dom/src/Makefile.in
@@ -37,11 +37,15 @@
 
 DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS		= jsurl events storage offline json geolocation notification foo
+DIRS		= jsurl events storage offline json geolocation notification
+
+ifdef ENABLE_TESTS
+DIRS		+= foo
+endif
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/nsDeviceMotion.cpp
+++ b/dom/system/nsDeviceMotion.cpp
@@ -197,17 +197,17 @@ NS_IMETHODIMP nsDeviceMotion::RemoveList
 }
 
 NS_IMETHODIMP nsDeviceMotion::AddWindowListener(nsIDOMWindow *aWindow)
 {
   if (mStarted == PR_FALSE) {
     mStarted = PR_TRUE;
     Startup();
   }
-  if (mWindowListeners.IndexOf(aWindow) != NoIndex)
+  if (mWindowListeners.IndexOf(aWindow) == NoIndex)
     mWindowListeners.AppendElement(aWindow);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDeviceMotion::RemoveWindowListener(nsIDOMWindow *aWindow)
 {
   if (mWindowListeners.IndexOf(aWindow) != NoIndex)
     return NS_OK;
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -560,23 +560,23 @@ private:
     MessageEvent* event = GetInstancePrivate(aCx, aObj, name);
     if (!event) {
       return false;
     }
 
     // Deserialize and save the data value if we can.
     if (slot == SLOT_data && event->mData) {
       JSAutoStructuredCloneBuffer buffer;
-      buffer.adopt(aCx, event->mData, event->mDataByteCount);
+      buffer.adopt(event->mData, event->mDataByteCount);
 
       event->mData = NULL;
       event->mDataByteCount = 0;
 
       jsval data;
-      if (!buffer.read(&data) ||
+      if (!buffer.read(aCx, &data) ||
           !JS_SetReservedSlot(aCx, aObj, slot, data)) {
         return false;
       }
 
       *aVp = data;
       return true;
     }
 
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -527,17 +527,17 @@ public:
   {
     aData.steal(&mData, &mDataByteCount);
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     JSAutoStructuredCloneBuffer buffer;
-    buffer.adopt(aCx, mData, mDataByteCount);
+    buffer.adopt(mData, mDataByteCount);
 
     mData = nsnull;
     mDataByteCount = 0;
 
     bool mainRuntime;
     JSObject* target;
     if (mTarget == ParentThread) {
       mainRuntime = !aWorkerPrivate->GetParent();
--- a/dom/workers/XMLHttpRequestPrivate.cpp
+++ b/dom/workers/XMLHttpRequestPrivate.cpp
@@ -950,27 +950,27 @@ public:
       nsIXPConnect* xpc = nsContentUtils::XPConnect();
       NS_ASSERTION(xpc, "This should never be null!");
 
       RuntimeService::AutoSafeJSContext cx;
 
       intN error = 0;
 
       jsval body;
-      if (mBody.read(&body, cx)) {
+      if (mBody.read(cx, &body)) {
         if (NS_FAILED(xpc->JSValToVariant(cx, &body,
                                           getter_AddRefs(variant)))) {
           error = INVALID_STATE_ERR;
         }
       }
       else {
         error = DATA_CLONE_ERR;
       }
 
-      mBody.clear(cx);
+      mBody.clear();
 
       if (error) {
         return error;
       }
     }
 
     if (mHasUploadListeners) {
       NS_ASSERTION(!mProxy->mUploadEventListenersAttached, "Huh?!");
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -79,18 +79,19 @@
 #include "nsIDOMDocumentFragment.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIParser.h"
 #include "nsParserCIID.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsLinebreakConverter.h"
-#include "nsIFragmentContentSink.h"
-#include "nsIContentSink.h"
+#include "nsAHtml5FragmentParser.h"
+#include "nsHtml5Module.h"
+#include "nsTreeSanitizer.h"
 
 // netwerk
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsIMIMEService.h"
 
 // Drag & Drop, Clipboard
 #include "nsIClipboard.h"
@@ -2584,43 +2585,53 @@ nsresult nsHTMLEditor::CreateDOMFragment
 
   nsCOMPtr<nsIDOMDocument> domDoc;
   GetDocument(getter_AddRefs(domDoc));
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
   
   // if we have context info, create a fragment for that
-  nsAutoTArray<nsString, 32> tagStack;
   nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
   nsCOMPtr<nsIDOMNode> contextLeaf, junk;
   if (!aContextStr.IsEmpty())
   {
-    res = ParseFragment(aContextStr, tagStack, doc, address_of(contextAsNode),
+    res = ParseFragment(aContextStr, nsnull, doc, address_of(contextAsNode),
                         aTrustedInput);
     NS_ENSURE_SUCCESS(res, res);
     NS_ENSURE_TRUE(contextAsNode, NS_ERROR_FAILURE);
 
     res = StripFormattingNodes(contextAsNode);
     NS_ENSURE_SUCCESS(res, res);
 
     RemoveBodyAndHead(contextAsNode);
 
     res = FindTargetNode(contextAsNode, contextLeaf);
     if (res == NS_FOUND_TARGET)
       res = NS_OK;
     NS_ENSURE_SUCCESS(res, res);
   }
 
-  // get the tagstack for the context
-  res = CreateTagStack(tagStack, contextLeaf);
-  NS_ENSURE_SUCCESS(res, res);
+  nsCOMPtr<nsIContent> contextLeafAsContent = do_QueryInterface(contextLeaf);
 
   // create fragment for pasted html
-  res = ParseFragment(aInputString, tagStack, doc, outFragNode, aTrustedInput);
+  nsIAtom* contextAtom;
+  if (contextLeafAsContent) {
+    contextAtom = contextLeafAsContent->Tag();
+    if (contextAtom == nsGkAtoms::html) {
+      contextAtom = nsGkAtoms::body;
+    }
+  } else {
+    contextAtom = nsGkAtoms::body;
+  }
+  res = ParseFragment(aInputString,
+                      contextAtom,
+                      doc,
+                      outFragNode,
+                      aTrustedInput);
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(*outFragNode, NS_ERROR_FAILURE);
 
   RemoveBodyAndHead(*outFragNode);
 
   if (contextAsNode)
   {
     // unite the two trees
@@ -2668,110 +2679,47 @@ nsresult nsHTMLEditor::CreateDOMFragment
   }
 
   GetLengthOfDOMNode(*outEndNode, (PRUint32&)*outEndOffset);
   return res;
 }
 
 
 nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr,
-                                     nsTArray<nsString> &aTagStack,
+                                     nsIAtom* aContextLocalName,
                                      nsIDocument* aTargetDocument,
                                      nsCOMPtr<nsIDOMNode> *outNode,
                                      PRBool aTrustedInput)
 {
-  // figure out if we are parsing full context or not
-  PRBool bContext = aTagStack.IsEmpty();
-
-  // create the parser to do the conversion.
-  nsresult res;
-  nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &res);
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(parser, NS_ERROR_FAILURE);
-
-  // create the html fragment sink
-  nsCOMPtr<nsIContentSink> sink;
-  if (aTrustedInput) {
-    if (bContext)
-      sink = do_CreateInstance(NS_HTMLFRAGMENTSINK2_CONTRACTID);
-    else
-      sink = do_CreateInstance(NS_HTMLFRAGMENTSINK_CONTRACTID);
-  } else {
-    if (bContext)
-      sink = do_CreateInstance(NS_HTMLPARANOIDFRAGMENTSINK2_CONTRACTID);
-    else
-      sink = do_CreateInstance(NS_HTMLPARANOIDFRAGMENTSINK_CONTRACTID);
-
-    nsCOMPtr<nsIParanoidFragmentContentSink> paranoidSink(do_QueryInterface(sink));
-    NS_ASSERTION(paranoidSink, "Our content sink is paranoid");
-    if (bContext) {
-      // Allow comments for the context to catch our placeholder cookie
-      paranoidSink->AllowComments();
-    } else {
-      // Allow style elements and attributes for the actual content
-      paranoidSink->AllowStyles();
-    }
+  // The old code created a new parser every time. This is inefficient.
+  // However, the target document is not required to be an HTML document,
+  // So avoid using the cached parser of aDocument. Once bug 596182 is fixed,
+  // use the global parser here.
+  nsCOMPtr<nsIParser> parser = nsHtml5Module::NewHtml5Parser();
+  nsAHtml5FragmentParser* asFragmentParser =
+      static_cast<nsAHtml5FragmentParser*> (parser.get());
+  nsCOMPtr<nsIDOMDocumentFragment> frag;
+  NS_NewDocumentFragment(getter_AddRefs(frag),
+                         aTargetDocument->NodeInfoManager());
+  nsCOMPtr<nsIContent> fragment = do_QueryInterface(frag);
+  asFragmentParser->ParseHtml5Fragment(aFragStr,
+                                      fragment,
+                                      aContextLocalName ?
+                                          aContextLocalName : nsGkAtoms::body,
+                                      kNameSpaceID_XHTML,
+                                      PR_FALSE,
+                                      PR_TRUE);
+  if (!aTrustedInput) {
+    nsTreeSanitizer sanitizer(!!aContextLocalName, !aContextLocalName);
+    sanitizer.Sanitize(fragment);
   }
-
-  NS_ENSURE_TRUE(sink, NS_ERROR_FAILURE);
-  nsCOMPtr<nsIFragmentContentSink> fragSink(do_QueryInterface(sink));
-  NS_ENSURE_TRUE(fragSink, NS_ERROR_FAILURE);
-
-  fragSink->SetTargetDocument(aTargetDocument);
-
-  // parse the fragment
-  parser->SetContentSink(sink);
-  if (bContext)
-    parser->Parse(aFragStr, (void*)0, NS_LITERAL_CSTRING("text/html"), PR_TRUE, eDTDMode_fragment);
-  else
-    parser->ParseFragment(aFragStr, 0, aTagStack, PR_FALSE, NS_LITERAL_CSTRING("text/html"), eDTDMode_quirks);
-  // get the fragment node
-  nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
-  res = fragSink->GetFragment(PR_TRUE, getter_AddRefs(contextfrag));
-  NS_ENSURE_SUCCESS(res, res);
-  *outNode = do_QueryInterface(contextfrag);
-  
-  return res;
+  *outNode = do_QueryInterface(frag);
+  return NS_OK;
 }
 
-nsresult nsHTMLEditor::CreateTagStack(nsTArray<nsString> &aTagStack, nsIDOMNode *aNode)
-{
-  nsresult res = NS_OK;
-  nsCOMPtr<nsIDOMNode> node= aNode;
-  PRBool bSeenBody = PR_FALSE;
-  
-  while (node) 
-  {
-    if (nsTextEditUtils::IsBody(node))
-      bSeenBody = PR_TRUE;
-    nsCOMPtr<nsIDOMNode> temp = node;
-    PRUint16 nodeType;
-    
-    node->GetNodeType(&nodeType);
-    if (nsIDOMNode::ELEMENT_NODE == nodeType)
-    {
-      nsString* tagName = aTagStack.AppendElement();
-      NS_ENSURE_TRUE(tagName, NS_ERROR_OUT_OF_MEMORY);
-
-      node->GetNodeName(*tagName);
-      // printf("%s\n",NS_LossyConvertUTF16toASCII(tagName).get());
-    }
-
-    res = temp->GetParentNode(getter_AddRefs(node));
-    NS_ENSURE_SUCCESS(res, res);  
-  }
-  
-  if (!bSeenBody)
-  {
-      aTagStack.AppendElement(NS_LITERAL_STRING("BODY"));
-  }
-  return res;
-}
-
-
 nsresult nsHTMLEditor::CreateListOfNodesToPaste(nsIDOMNode  *aFragmentAsNode,
                                                 nsCOMArray<nsIDOMNode>& outNodeList,
                                                 nsIDOMNode *aStartNode,
                                                 PRInt32 aStartOffset,
                                                 nsIDOMNode *aEndNode,
                                                 PRInt32 aEndOffset)
 {
   NS_ENSURE_TRUE(aFragmentAsNode, NS_ERROR_NULL_POINTER);
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -623,17 +623,17 @@ protected:
                                         const nsAString & aContextStr,
                                         const nsAString & aInfoStr,
                                         nsCOMPtr<nsIDOMNode> *outFragNode,
                                         nsCOMPtr<nsIDOMNode> *outStartNode,
                                         nsCOMPtr<nsIDOMNode> *outEndNode,
                                         PRInt32 *outStartOffset,
                                         PRInt32 *outEndOffset,
                                         PRBool aTrustedInput);
-  nsresult   ParseFragment(const nsAString & aStr, nsTArray<nsString> &aTagStack,
+  nsresult   ParseFragment(const nsAString & aStr, nsIAtom* aContextLocalName,
                            nsIDocument* aTargetDoc,
                            nsCOMPtr<nsIDOMNode> *outNode,
                            PRBool aTrustedInput);
   nsresult   CreateListOfNodesToPaste(nsIDOMNode  *aFragmentAsNode,
                                       nsCOMArray<nsIDOMNode>& outNodeList,
                                       nsIDOMNode *aStartNode,
                                       PRInt32 aStartOffset,
                                       nsIDOMNode *aEndNode,
--- a/editor/libeditor/html/tests/test_bug520189.html
+++ b/editor/libeditor/html/tests/test_bug520189.html
@@ -57,16 +57,30 @@ https://bugzilla.mozilla.org/show_bug.cg
   <iframe id="oo" src="about:blank"></iframe>
   <div id="pp" contenteditable="true"></div>
   <iframe id="qq" src="about:blank"></iframe>
   <div id="rr" contenteditable="true"></div>
   <iframe id="ss" src="about:blank"></iframe>
   <div id="tt" contenteditable="true"></div>
   <iframe id="uu" src="about:blank"></iframe>
   <div id="vv" contenteditable="true"></div>
+  <div id="sss" contenteditable="true"></div>
+  <iframe id="ssss" src="about:blank"></iframe>
+  <div id="ttt" contenteditable="true"></div>
+  <iframe id="tttt" src="about:blank"></iframe>
+  <div id="uuu" contenteditable="true"></div>
+  <iframe id="uuuu" src="about:blank"></iframe>
+  <div id="vvv" contenteditable="true"></div>
+  <iframe id="vvvv" src="about:blank"></iframe>
+  <div id="www" contenteditable="true"></div>
+  <iframe id="wwww" src="about:blank"></iframe>
+  <div id="xxx" contenteditable="true"></div>
+  <iframe id="xxxx" src="about:blank"></iframe>
+  <div id="yyy" contenteditable="true"></div>
+  <iframe id="yyyy" src="about:blank"></iframe>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 520182 **/
 
 const dataPayload = "foo<iframe src=\"data:text/html,bar\"></iframe>baz";
 const jsPayload = "foo<iframe src=\"javascript:void('bar');\"></iframe>baz";
@@ -87,16 +101,23 @@ const invalidStyle7Payload = "<html><hea
 const invalidStyle8Payload = "foo<style>@-moz-document url(http://example.com/) {};</style>baz";
 const invalidStyle9Payload = "foo<style>@-moz-keyframes bar {};</style>baz";
 const nestedStylePayload = "foo<style>#bar1{-moz-binding:url('data:text/xml,<?xml version=&quot;1.0&quot;><binding xmlns=&quot;http://www.mozilla.org/xbl&quot; id=&quot;binding-1&quot;/>');<style></style>#bar2{-moz-binding:url('data:text/xml,<?xml version=&quot;1.0&quot;><binding xmlns=&quot;http://www.mozilla.org/xbl&quot; id=&quot;binding-2&quot;/>');</style>baz";
 const validImgSrc1Payload = "foo<img src=\"data:image/png,bar\">baz";
 const validImgSrc2Payload = "foo<img src=\"javascript:void('bar');\">baz";
 const validImgSrc3Payload = "foo<img src=\"file:///bar.png\">baz";
 const validDataFooPayload = "foo<span data-bar=\"value\">baz</span>";
 const validDataFoo2Payload = "foo<span _bar=\"value\">baz</span>";
+const svgPayload = "foo<svg><title>svgtitle</title></svg>bar";
+const svg2Payload = "foo<svg><bogussvg/></svg>bar";
+const mathPayload = "foo<math><bogusmath/></math>bar";
+const math2Payload = "foo<math><style>@import \"yyy.css\";</style</math>bar";
+const math3Payload = "foo<math><mi></mi></math>bar";
+const videoPayload = "foo<video></video>bar";
+const microdataPayload = "<head><meta name=foo content=bar><link rel=stylesheet href=url></head><body><meta itemprop=foo content=bar><link itemprop=bar href=url></body>";
 
 var tests = [
   {
     id: "a",
     isIFrame: true,
     payload: dataPayload,
     iframeCount: 0,
     rootElement: function() document.getElementById("a").contentDocument.documentElement
@@ -416,16 +437,107 @@ var tests = [
     rootElement: function() document.getElementById("uu").contentDocument.documentElement,
     checkResult: function(html) is(html.indexOf("@-moz-keyframes"), -1, "Should not have retained the @-moz-keyframes rule")
   },
   {
     id: "vv",
     payload: invalidStyle9Payload,
     rootElement: function() document.getElementById("vv"),
     checkResult: function(html) is(html.indexOf("@-moz-keyframes"), -1, "Should not have retained the @-moz-keyframes rule")
+  },
+  {
+    id: "sss",
+    payload: svgPayload,
+    rootElement: function() document.getElementById("sss"),
+    checkResult: function(html) isnot(html.indexOf("svgtitle"), -1, "Should have retained SVG title")
+  },
+  {
+    id: "ssss",
+    isIFrame: true,
+    payload: svgPayload,
+    rootElement: function() document.getElementById("ssss").contentDocument.documentElement,
+    checkResult: function(html) isnot(html.indexOf("svgtitle"), -1, "Should have retained SVG title")
+  },
+  {
+    id: "ttt",
+    payload: svg2Payload,
+    rootElement: function() document.getElementById("ttt"),
+    checkResult: function(html) is(html.indexOf("bogussvg"), -1, "Should have dropped bogussvg element")
+  },
+  {
+    id: "tttt",
+    isIFrame: true,
+    payload: svg2Payload,
+    rootElement: function() document.getElementById("tttt").contentDocument.documentElement,
+    checkResult: function(html) is(html.indexOf("bogussvg"), -1, "Should have dropped bogussvg element")
+  },
+  {
+    id: "uuu",
+    payload: mathPayload,
+    rootElement: function() document.getElementById("uuu"),
+    checkResult: function(html) is(html.indexOf("bogusmath"), -1, "Should have dropped bogusmath element")
+  },
+  {
+    id: "uuuu",
+    isIFrame: true,
+    payload: mathPayload,
+    rootElement: function() document.getElementById("uuuu").contentDocument.documentElement,
+    checkResult: function(html) is(html.indexOf("bogusmath"), -1, "Should have dropped bogusmath element")
+  },
+  {
+    id: "vvv",
+    payload: math2Payload,
+    rootElement: function() document.getElementById("vvv"),
+    checkResult: function(html) is(html.indexOf("yyy.css"), -1, "Should have dropped MathML style element")
+  },
+  {
+    id: "vvvv",
+    isIFrame: true,
+    payload: math2Payload,
+    rootElement: function() document.getElementById("vvvv").contentDocument.documentElement,
+    checkResult: function(html) is(html.indexOf("yyy.css"), -1, "Should have dropped MathML style element")
+  },
+  {
+    id: "www",
+    payload: math3Payload,
+    rootElement: function() document.getElementById("www"),
+    checkResult: function(html) isnot(html.indexOf("<mi"), -1, "Should not have dropped MathML mi element")
+  },
+  {
+    id: "wwww",
+    isIFrame: true,
+    payload: math3Payload,
+    rootElement: function() document.getElementById("wwww").contentDocument.documentElement,
+    checkResult: function(html) isnot(html.indexOf("<mi"), -1, "Should not have dropped MathML mi element")
+  },
+  {
+    id: "xxx",
+    payload: videoPayload,
+    rootElement: function() document.getElementById("xxx"),
+    checkResult: function(html) isnot(html.indexOf("controls="), -1, "Should have added the controls attribute")
+  },
+  {
+    id: "xxxx",
+    isIFrame: true,
+    payload: videoPayload,
+    rootElement: function() document.getElementById("xxxx").contentDocument.documentElement,
+    checkResult: function(html) isnot(html.indexOf("controls="), -1, "Should have added the controls attribute")
+  },
+  {
+    id: "yyy",
+    payload: microdataPayload,
+    rootElement: function() document.getElementById("yyy"),
+    checkResult: function(html) { is(html.indexOf("name"), -1, "Should have dropped name."); is(html.indexOf("rel"), -1, "Should have dropped rel."); isnot(html.indexOf("itemprop"), -1, "Should not have dropped itemprop."); }
+  },
+  {
+    id: "yyyy",
+    isIFrame: true,
+    payload: microdataPayload,
+    rootElement: function() document.getElementById("yyyy").contentDocument.documentElement,
+    checkResult: function(html) { is(html.indexOf("name"), -1, "Should have dropped name."); is(html.indexOf("rel"), -1, "Should have dropped rel."); isnot(html.indexOf("itemprop"), -1, "Should not have dropped itemprop."); }
   }
 ];
 
 function doNextTest() {
   if (typeof testCounter == "undefined")
     testCounter = 0;
   else if (++testCounter == tests.length) {
     SimpleTest.finish();
--- a/gfx/2d/ShadersD2D.fx
+++ b/gfx/2d/ShadersD2D.fx
@@ -175,17 +175,17 @@ float4 SampleRadialGradientPS( VS_RADIAL
     if (max(isValid.x, isValid.y) <= 0) {
       return float4(0, 0, 0, 0);
     }
 
     float upper_t = lerp(t.y, t.x, isValid.x);
 
     float4 output = tex.Sample(sSampler, float2(upper_t, 0.5));
     // Premultiply
-    output *= output.a;
+    output.rgb *= output.a;
     // Multiply the output color by the input mask for the operation.
     output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
     return output;
 };
 
 float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In) : SV_Target
 {
     // This simpler shader is used for the degenerate case where A is 0,
@@ -202,17 +202,17 @@ float4 SampleRadialGradientA0PS( VS_RADI
     float t = 0.5 * C / B;
 
     if (-radius1 >= t * diff.z) {
       return float4(0, 0, 0, 0);
     }
 
     float4 output = tex.Sample(sSampler, float2(t, 0.5));
     // Premultiply
-    output *= output.a;
+    output.rgb *= output.a;
     // Multiply the output color by the input mask for the operation.
     output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
     return output;
 };
 
 float4 SampleShadowHPS( VS_OUTPUT In) : SV_Target
 {
     float outputStrength = 0;
--- a/gfx/2d/ShadersD2D.h
+++ b/gfx/2d/ShadersD2D.h
@@ -438,17 +438,17 @@ technique10 SampleRadialGradient
                 mul r0.xzw, r0, r1.x
                 mov r1.w, c1.w
                 mad r1.xyz, r0.xzww, c0.z, r1.w
                 cmp r2.x, r1.x, r0.x, r0.w
                 cmp r0.xzw, r1.xyyz, c4.xyxy, c4.zyzw
                 mov r2.y, c3.x
                 texld r1, t0, s1
                 texld r2, r2, s0
-                mul r2, r2.w, r2
+                mul r2.xyz, r2.w, r2
                 mul r1, r1.w, r2
                 add r0.w, r0.w, r0.x
                 cmp r0.x, r0.w, r0.x, r0.z
                 cmp r1, -r0.x, c4.z, r1
                 cmp r0, r0.y, r1, c4.z
                 mov oC0, r0
             
             // approximately 28 instruction slots used (2 texture, 26 arithmetic)
@@ -486,19 +486,19 @@ technique10 SampleRadialGradient
               ret 
             endif 
             max r0.x, r1.y, r1.x
             ge r0.x, l(0.000000), r0.x
             if_nz r0.x
               mov o0.xyzw, l(0,0,0,0)
               ret 
             endif 
-            mul r0.xyzw, r2.wwww, r2.xyzw
-            sample r1.xyzw, v1.xyxx, t1.xyzw, s1
-            mul o0.xyzw, r0.xyzw, r1.wwww
+            mul r2.xyz, r2.wwww, r2.xyzx
+            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
+            mul o0.xyzw, r0.wwww, r2.xyzw
             ret 
             // Approximately 33 instruction slots used
                     
         };
     }
 
     pass P1
     {
@@ -698,17 +698,17 @@ technique10 SampleRadialGradient
                 dp3 r0.x, r0, c0
                 rcp r0.x, r0.x
                 mul r0.x, r0.x, r0.w
                 mov r0.y, c2.x
                 texld r1, t0, s1
                 texld r2, r0, s0
                 mov r0.w, c1.w
                 mad r0.x, r0.x, -c0.z, -r0.w
-                mul r2, r2.w, r2
+                mul r2.xyz, r2.w, r2
                 mul r1, r1.w, r2
                 cmp r0, r0.x, c2.y, r1
                 mov oC0, r0
             
             // approximately 18 instruction slots used (2 texture, 16 arithmetic)
             ps_4_0
             dcl_constantbuffer cb0[6], immediateIndexed
             dcl_sampler s0, mode_default
@@ -729,19 +729,19 @@ technique10 SampleRadialGradient
             mul r0.z, r0.x, cb0[4].z
             ge r0.z, -cb0[5].w, r0.z
             mov r0.y, l(0.500000)
             sample r1.xyzw, r0.xyxx, t0.xyzw, s0
             if_nz r0.z
               mov o0.xyzw, l(0,0,0,0)
               ret 
             endif 
-            mul r0.xyzw, r1.wwww, r1.xyzw
-            sample r1.xyzw, v1.xyxx, t1.xyzw, s1
-            mul o0.xyzw, r0.xyzw, r1.wwww
+            mul r1.xyz, r1.wwww, r1.xyzx
+            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
+            mul o0.xyzw, r0.wwww, r1.xyzw
             ret 
             // Approximately 19 instruction slots used
                     
         };
     }
 
 }
 
@@ -1616,20 +1616,20 @@ technique10 SampleTextureWithShadow
     }
 
 }
 
 #endif
 
 const BYTE d2deffect[] =
 {
-     68,  88,  66,  67, 178,   2, 
-     69, 191, 250,  33,  81, 124, 
-    224,  53, 204,  57,  73,  36, 
-    191, 116,   1,   0,   0,   0, 
+     68,  88,  66,  67, 109, 248, 
+     87, 153, 208, 172, 175,  58, 
+    169, 190, 216,  26, 197,   8, 
+    157,  19,   1,   0,   0,   0, 
       1, 102,   0,   0,   1,   0, 
       0,   0,  36,   0,   0,   0, 
      70,  88,  49,  48, 213, 101, 
       0,   0,   1,  16, 255, 254, 
       3,   0,   0,   0,  14,   0, 
       0,   0,   8,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2401,19 +2401,19 @@ const BYTE d2deffect[] =
      80, 111, 115, 105, 116, 105, 
     111, 110,   0,  84,  69,  88, 
      67,  79,  79,  82,  68,   0, 
     171, 171, 171, 203,  10,   0, 
       0,   0,   0,   0,   0,   1, 
       0,   0,   0,   2,   0,   0, 
       0,   0,   0,   0,   0, 220, 
       9,   0,   0,  68,  88,  66, 
-     67, 246,  85,  96,  22,  53, 
-     16, 231, 164, 220,  13,  79, 
-    114,  29,  26, 138, 193,   1, 
+     67,  75, 110, 115, 165, 159, 
+    108, 132, 208, 154,  90, 141, 
+     18, 236, 102,  72, 112,   1, 
       0,   0,   0, 220,   9,   0, 
       0,   6,   0,   0,   0,  56, 
       0,   0,   0, 128,   2,   0, 
       0,  88,   6,   0,   0, 212, 
       6,   0,   0,  56,   9,   0, 
       0, 168,   9,   0,   0,  65, 
     111, 110,  57,  64,   2,   0, 
       0,  64,   2,   0,   0,   0, 
@@ -2487,17 +2487,17 @@ const BYTE d2deffect[] =
     160,   1,   0,   0,   2,   2, 
       0,   2, 128,   3,   0,   0, 
     160,  66,   0,   0,   3,   1, 
       0,  15, 128,   0,   0, 228, 
     176,   1,   8, 228, 160,  66, 
       0,   0,   3,   2,   0,  15, 
     128,   2,   0, 228, 128,   0, 
       8, 228, 160,   5,   0,   0, 
-      3,   2,   0,  15, 128,   2, 
+      3,   2,   0,   7, 128,   2, 
       0, 255, 128,   2,   0, 228, 
     128,   5,   0,   0,   3,   1, 
       0,  15, 128,   1,   0, 255, 
     128,   2,   0, 228, 128,   2, 
       0,   0,   3,   0,   0,   8, 
     128,   0,   0, 255, 128,   0, 
       0,   0, 128,  88,   0,   0, 
       4,   0,   0,   1, 128,   0, 
@@ -2655,47 +2655,47 @@ const BYTE d2deffect[] =
       3,  10,   0,  16,   0,   0, 
       0,   0,   0,  54,   0,   0, 
       8, 242,  32,  16,   0,   0, 
       0,   0,   0,   2,  64,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,  62, 
       0,   0,   1,  21,   0,   0, 
-      1,  56,   0,   0,   7, 242, 
-      0,  16,   0,   0,   0,   0, 
+      1,  56,   0,   0,   7, 114, 
+      0,  16,   0,   2,   0,   0, 
       0, 246,  15,  16,   0,   2, 
-      0,   0,   0,  70,  14,  16, 
+      0,   0,   0,  70,   2,  16, 
       0,   2,   0,   0,   0,  69, 
       0,   0,   9, 242,   0,  16, 
-      0,   1,   0,   0,   0,  70, 
+      0,   0,   0,   0,   0,  70, 
      16,  16,   0,   1,   0,   0, 
       0,  70, 126,  16,   0,   1, 
       0,   0,   0,   0,  96,  16, 
       0,   1,   0,   0,   0,  56, 
       0,   0,   7, 242,  32,  16, 
-      0,   0,   0,   0,   0,  70, 
-     14,  16,   0,   0,   0,   0, 
-      0, 246,  15,  16,   0,   1, 
+      0,   0,   0,   0,   0, 246, 
+     15,  16,   0,   0,   0,   0, 
+      0,  70,  14,  16,   0,   2, 
       0,   0,   0,  62,   0,   0, 
       1,  83,  84,  65,  84, 116, 
       0,   0,   0,  33,   0,   0, 
       0,   3,   0,   0,   0,   0, 
       0,   0,   0,   3,   0,   0, 
       0,  17,   0,   0,   0,   0, 
       0,   0,   0,   1,   0,   0, 
       0,   3,   0,   0,   0,   2, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   2, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   4,   0,   0,   0,   0, 
+      0,   5,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,  82, 
      68,  69,  70,  92,   2,   0, 
       0,   1,   0,   0,   0, 224, 
@@ -3127,20 +3127,20 @@ const BYTE d2deffect[] =
      83,  86,  95,  80, 111, 115, 
     105, 116, 105, 111, 110,   0, 
      84,  69,  88,  67,  79,  79, 
      82,  68,   0, 171, 171, 171, 
     210,  27,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       2,   0,   0,   0,   0,   0, 
       0,   0, 188,   7,   0,   0, 
-     68,  88,  66,  67, 233,  12, 
-    254, 166,  83, 201,  49,   7, 
-    133, 181, 124, 223, 180,   7, 
-    158, 182,   1,   0,   0,   0, 
+     68,  88,  66,  67, 158, 207, 
+    216, 153, 107, 204, 140, 217, 
+    118, 241, 126, 175, 204, 121, 
+     49,  49,   1,   0,   0,   0, 
     188,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     196,   1,   0,   0,  56,   4, 
       0,   0, 180,   4,   0,   0, 
      24,   7,   0,   0, 136,   7, 
       0,   0,  65, 111, 110,  57, 
     132,   1,   0,   0, 132,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -3192,17 +3192,17 @@ const BYTE d2deffect[] =
      15, 128,   0,   0, 228, 128, 
       0,   8, 228, 160,   1,   0, 
       0,   2,   0,   0,   8, 128, 
       1,   0, 255, 160,   4,   0, 
       0,   4,   0,   0,   1, 128, 
       0,   0,   0, 128,   0,   0, 
     170, 161,   0,   0, 255, 129, 
       5,   0,   0,   3,   2,   0, 
-     15, 128,   2,   0, 255, 128, 
+      7, 128,   2,   0, 255, 128, 
       2,   0, 228, 128,   5,   0, 
       0,   3,   1,   0,  15, 128, 
       1,   0, 255, 128,   2,   0, 
     228, 128,  88,   0,   0,   4, 
       0,   0,  15, 128,   0,   0, 
       0, 128,   2,   0,  85, 160, 
       1,   0, 228, 128,   1,   0, 
       0,   2,   0,   8,  15, 128, 
@@ -3291,47 +3291,47 @@ const BYTE d2deffect[] =
      42,   0,  16,   0,   0,   0, 
       0,   0,  54,   0,   0,   8, 
     242,  32,  16,   0,   0,   0, 
       0,   0,   2,  64,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  62,   0, 
       0,   1,  21,   0,   0,   1, 
-     56,   0,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   1,   0,   0,   0, 
     246,  15,  16,   0,   1,   0, 
-      0,   0,  70,  14,  16,   0, 
+      0,   0,  70,   2,  16,   0, 
       1,   0,   0,   0,  69,   0, 
       0,   9, 242,   0,  16,   0, 
-      1,   0,   0,   0,  70,  16, 
+      0,   0,   0,   0,  70,  16, 
      16,   0,   1,   0,   0,   0, 
      70, 126,  16,   0,   1,   0, 
       0,   0,   0,  96,  16,   0, 
       1,   0,   0,   0,  56,   0, 
       0,   7, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70,  14, 
+      0,   0,   0,   0, 246,  15, 
      16,   0,   0,   0,   0,   0, 
-    246,  15,  16,   0,   1,   0, 
+     70,  14,  16,   0,   1,   0, 
       0,   0,  62,   0,   0,   1, 
      83,  84,  65,  84, 116,   0, 
       0,   0,  19,   0,   0,   0, 
       2,   0,   0,   0,   0,   0, 
       0,   0,   3,   0,   0,   0, 
       9,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       2,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  82,  68, 
      69,  70,  92,   2,   0,   0, 
       1,   0,   0,   0, 224,   0, 
--- a/gfx/layers/ImageLayers.h
+++ b/gfx/layers/ImageLayers.h
@@ -449,16 +449,21 @@ public:
    * @param aData           Input image data.
    * @return                Raw data pointer for the planes or nsnull on failure.
    */
   PRUint8 *CopyData(Data& aDest, gfxIntSize& aDestSize,
                     PRUint32& aDestBufferSize, const Data& aData);
 
   virtual PRUint8* AllocateBuffer(PRUint32 aSize);
 
+  /**
+   * Return the number of bytes of heap memory used to store this image.
+   */
+  virtual PRUint32 GetDataSize() = 0;
+
 protected:
   PlanarYCbCrImage(void* aImplData) : Image(aImplData, PLANAR_YCBCR) {}
 };
 
 /**
  * Currently, the data in a CairoImage surface is treated as being in the
  * device output color space.
  */
--- a/gfx/layers/basic/BasicImages.cpp
+++ b/gfx/layers/basic/BasicImages.cpp
@@ -124,16 +124,18 @@ public:
 
   virtual already_AddRefed<gfxASurface> GetAsSurface();
 
   const Data* GetData() { return &mData; }
 
   void SetOffscreenFormat(gfxImageFormat aFormat) { mOffscreenFormat = aFormat; }
   gfxImageFormat GetOffscreenFormat() { return mOffscreenFormat; }
 
+  PRUint32 GetDataSize() { return mBuffer ? mDelayedConversion ? mBufferSize : mSize.height * mStride : 0; }
+
 protected:
   nsAutoArrayPtr<PRUint8>              mBuffer;
   nsCountedRef<nsMainThreadSurfaceRef> mSurface;
   gfxIntSize                           mScaleHint;
   PRInt32                              mStride;
   gfxImageFormat                       mOffscreenFormat;
   Data                                 mData;
   PRUint32                             mBufferSize;
--- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp
+++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp
@@ -112,17 +112,19 @@ CanvasLayerD3D10::Initialize(const Data&
 
   HANDLE shareHandle = mGLContext ? mGLContext->GetD3DShareHandle() : nsnull;
   if (shareHandle) {
     HRESULT hr = device()->OpenSharedResource(shareHandle, __uuidof(ID3D10Texture2D), getter_AddRefs(mTexture));
     if (SUCCEEDED(hr))
       mUsingSharedTexture = PR_TRUE;
   }
 
-  if (!mUsingSharedTexture) {
+  if (mUsingSharedTexture) {
+    mNeedsYFlip = PR_FALSE;
+  } else {
     CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mBounds.width, mBounds.height, 1, 1);
     desc.Usage = D3D10_USAGE_DYNAMIC;
     desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
 
     HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture));
     if (FAILED(hr)) {
       NS_WARNING("Failed to create texture for CanvasLayer!");
       return;
--- a/gfx/layers/d3d10/ImageLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp
@@ -366,26 +366,26 @@ ImageLayerD3D10::RenderLayer()
       SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
   }
 
   GetContainer()->NotifyPaintedImage(image);
 }
 
 PlanarYCbCrImageD3D10::PlanarYCbCrImageD3D10(ID3D10Device1 *aDevice)
   : PlanarYCbCrImage(static_cast<ImageD3D10*>(this))
+  , mBufferSize(0)
   , mDevice(aDevice)
   , mHasData(PR_FALSE)
 {
 }
 
 void
 PlanarYCbCrImageD3D10::SetData(const PlanarYCbCrImage::Data &aData)
 {
-  PRUint32 dummy;
-  mBuffer = CopyData(mData, mSize, dummy, aData);
+  mBuffer = CopyData(mData, mSize, mBufferSize, aData);
 
   AllocateTextures();
 
   mHasData = PR_TRUE;
 }
 
 void
 PlanarYCbCrImageD3D10::AllocateTextures()
--- a/gfx/layers/d3d10/ImageLayerD3D10.h
+++ b/gfx/layers/d3d10/ImageLayerD3D10.h
@@ -109,19 +109,22 @@ public:
   /*
    * Upload the data from out mData into our textures. For now we use this to
    * make sure the textures are created and filled on the main thread.
    */
   void AllocateTextures();
 
   PRBool HasData() { return mHasData; }
 
+  PRUint32 GetDataSize() { return mBuffer ? mBufferSize : 0; }
+
   virtual already_AddRefed<gfxASurface> GetAsSurface();
 
   nsAutoArrayPtr<PRUint8> mBuffer;
+  PRUint32 mBufferSize;
   nsRefPtr<ID3D10Device1> mDevice;
   Data mData;
   gfxIntSize mSize;
   nsRefPtr<ID3D10Texture2D> mYTexture;
   nsRefPtr<ID3D10Texture2D> mCrTexture;
   nsRefPtr<ID3D10Texture2D> mCbTexture;
   nsRefPtr<ID3D10ShaderResourceView> mYView;
   nsRefPtr<ID3D10ShaderResourceView> mCbView;
--- a/gfx/layers/d3d9/ImageLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp
@@ -392,25 +392,25 @@ ImageLayerD3D9::RenderLayer()
     }
   }
 
   GetContainer()->NotifyPaintedImage(image);
 }
 
 PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9()
   : PlanarYCbCrImage(static_cast<ImageD3D9*>(this))
+  , mBufferSize(0)
   , mHasData(PR_FALSE)
 {
 }
 
 void
 PlanarYCbCrImageD3D9::SetData(const PlanarYCbCrImage::Data &aData)
 {
-  PRUint32 dummy;
-  mBuffer = CopyData(mData, mSize, dummy, aData);
+  mBuffer = CopyData(mData, mSize, mBufferSize, aData);
 
   mHasData = PR_TRUE;
 }
 
 void
 PlanarYCbCrImageD3D9::AllocateTextures(IDirect3DDevice9 *aDevice)
 {
   D3DLOCKED_RECT lockrectY;
--- a/gfx/layers/d3d9/ImageLayerD3D9.h
+++ b/gfx/layers/d3d9/ImageLayerD3D9.h
@@ -119,19 +119,22 @@ public:
    * Free the textures, we call this from the main thread when we're done
    * drawing this frame. We cannot free this from the constructor since it may
    * be destroyed off the main-thread and might not be able to properly clean
    * up its textures
    */
   void FreeTextures();
   PRBool HasData() { return mHasData; }
 
+  PRUint32 GetDataSize() { return mBuffer ? mBufferSize : 0; }
+
   virtual already_AddRefed<gfxASurface> GetAsSurface();
 
   nsAutoArrayPtr<PRUint8> mBuffer;
+  PRUint32 mBufferSize;
   LayerManagerD3D9 *mManager;
   Data mData;
   gfxIntSize mSize;
   nsRefPtr<IDirect3DTexture9> mYTexture;
   nsRefPtr<IDirect3DTexture9> mCrTexture;
   nsRefPtr<IDirect3DTexture9> mCbTexture;
   PRPackedBool mHasData;
 };
--- a/gfx/layers/opengl/ImageLayerOGL.h
+++ b/gfx/layers/opengl/ImageLayerOGL.h
@@ -206,16 +206,18 @@ public:
     return mTextures[0].IsAllocated() && mTextures[1].IsAllocated() &&
            mTextures[2].IsAllocated();
   }
 
   PRUint8* AllocateBuffer(PRUint32 aSize) {
     return mRecycleBin->GetBuffer(aSize);
   }
 
+  PRUint32 GetDataSize() { return mBuffer ? mBufferSize : 0; }
+
   nsAutoArrayPtr<PRUint8> mBuffer;
   PRUint32 mBufferSize;
   nsRefPtr<RecycleBin> mRecycleBin;
   GLTexture mTextures[3];
   Data mData;
   gfxIntSize mSize;
   PRPackedBool mHasData;
 };
--- a/gfx/thebes/GLContextProviderEGL.cpp
+++ b/gfx/thebes/GLContextProviderEGL.cpp
@@ -234,17 +234,17 @@ public:
         : mInitialized(PR_FALSE),
           mEGLLibrary(nsnull)
     {
         mIsANGLE = PR_FALSE;
         mHave_EGL_KHR_image_base = PR_FALSE;
         mHave_EGL_KHR_image_pixmap = PR_FALSE;
         mHave_EGL_KHR_gl_texture_2D_image = PR_FALSE;
         mHave_EGL_KHR_lock_surface = PR_FALSE;
-        mHave_EGL_ANGLE_surface_d3d_share_handle = PR_FALSE;
+        mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = PR_FALSE;
     }
 
     typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
     pfnGetDisplay fGetDisplay;
     typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
     pfnGetCurrentContext fGetCurrentContext;
     typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
     pfnMakeCurrent fMakeCurrent;
@@ -477,26 +477,26 @@ public:
             mHave_EGL_KHR_image_pixmap = PR_FALSE;
             mHave_EGL_KHR_gl_texture_2D_image = PR_FALSE;
         }
 
         if (!fImageTargetTexture2DOES) {
             mHave_EGL_KHR_gl_texture_2D_image = PR_FALSE;
         }
 
-        if (strstr(extensions, "EGL_ANGLE_surface_d3d_share_handle")) {
+        if (strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
             LibrarySymbolLoader::SymLoadStruct d3dSymbols[] = {
                 { (PRFuncPtr*) &fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", NULL } },
                 { NULL, { NULL } }
             };
 
             LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0],
                                              (LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress);
             if (fQuerySurfacePointerANGLE) {
-                mHave_EGL_ANGLE_surface_d3d_share_handle = PR_TRUE;
+                mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = PR_TRUE;
             }
         }
 
         mInitialized = PR_TRUE;
         reporter.SetSuccessful();
         return PR_TRUE;
     }
 
@@ -519,18 +519,18 @@ public:
     PRBool HasKHRImageTexture2D() {
         return mHave_EGL_KHR_gl_texture_2D_image;
     }
 
     PRBool HasKHRLockSurface() {
         return mHave_EGL_KHR_lock_surface;
     }
 
-    PRBool HasANGLESurfaceD3DShareHandle() {
-        return mHave_EGL_ANGLE_surface_d3d_share_handle;
+    PRBool HasANGLESurfaceD3DTexture2DShareHandle() {
+        return mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
     }
 
     void
     DumpEGLConfig(EGLConfig cfg)
     {
         int attrval;
         int err;
 
@@ -602,17 +602,17 @@ private:
     EGLDisplay mEGLDisplay;
 
     PRPackedBool mIsANGLE;
 
     PRPackedBool mHave_EGL_KHR_image_base;
     PRPackedBool mHave_EGL_KHR_image_pixmap;
     PRPackedBool mHave_EGL_KHR_gl_texture_2D_image;
     PRPackedBool mHave_EGL_KHR_lock_surface;
-    PRPackedBool mHave_EGL_ANGLE_surface_d3d_share_handle;
+    PRPackedBool mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
 } sEGLLibrary;
 
 class GLContextEGL : public GLContext
 {
     friend class TextureImageEGL;
 
     static already_AddRefed<GLContextEGL>
     CreateGLContext(const ContextFormat& format,
@@ -893,17 +893,17 @@ public:
     void SetOffscreenSize(const gfxIntSize &aRequestedSize,
                           const gfxIntSize &aActualSize)
     {
         mOffscreenSize = aRequestedSize;
         mOffscreenActualSize = aActualSize;
     }
 
     void *GetD3DShareHandle() {
-        if (!sEGLLibrary.HasANGLESurfaceD3DShareHandle()) {
+        if (!sEGLLibrary.HasANGLESurfaceD3DTexture2DShareHandle()) {
             return nsnull;
         }
 
         void *h = nsnull;
 
 #ifndef EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE
 #define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
 #endif
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -409,24 +409,16 @@ GC(JSContext *cx,
 {
     JSRuntime *rt;
     uint32 preBytes, postBytes;
 
     rt = JS_GetRuntime(cx);
     preBytes = JS_GetGCParameter(rt, JSGC_BYTES);
     JS_GC(cx);
     postBytes = JS_GetGCParameter(rt, JSGC_BYTES);
-    fprintf(stdout, "before %lu, after %lu, break %08lx\n",
-           (unsigned long)preBytes, (unsigned long)postBytes,
-#ifdef XP_UNIX
-           (unsigned long)sbrk(0)
-#else
-           0
-#endif
-           );
 #ifdef JS_GCMETER
     js_DumpGCStats(rt, stdout);
 #endif
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 #ifdef JS_GC_ZEAL
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -670,17 +670,17 @@ check-malloc-function-usage: $(filter-ou
 		"in Makefile.in" "cx->calloc_ or rt->calloc_" $^
 	$(srcdir)/config/check_source_count.py "\bjs_realloc\b" 0 \
 		"in Makefile.in" "cx->realloc_ or rt->realloc_" $^
 	$(srcdir)/config/check_source_count.py "\bjs_free\b" 0 \
 		"in Makefile.in" "cx->free_" $^
 
 	# We desire these numbers to go down, not up. See "User guide to memory
 	# management within SpiderMonkey" in jsutil.h.
-	$(srcdir)/config/check_source_count.py OffTheBooks:: 58 \
+	$(srcdir)/config/check_source_count.py OffTheBooks:: 59 \
 		"in Makefile.in" "{cx,rt}->{new_,new_array,malloc_,calloc_,realloc_}" $^
 	# This should go to zero, if possible.
 	$(srcdir)/config/check_source_count.py UnwantedForeground:: 31 \
 		"in Makefile.in" "{cx,rt}->{free_,delete_,array_delete}" $^
 
 ifneq ($(OS_ARCH),WINNT) # FIXME: this should be made work on Windows too.
 check:: check-malloc-function-usage
 endif
@@ -752,22 +752,16 @@ export::
 
 DEFINES		+= -DEXPORT_JS_API
 
 # mfbt is always packed with us, so if we're building a shared object,
 # we need to declare "exported" mfbt symbols on its behalf when we use
 # its headers.
 DEFINES		+= -DIMPL_MFBT
 
-# Some platforms that have stdint.h include it in system headers.  So
-# to reliably get limit macros defined, we'd always have to define the
-# one below before including any header, but that's obscure and
-# fragile, so we do it here.
-DEFINES		+= -D__STDC_LIMIT_MACROS
-
 INCLUDES	+= -I$(srcdir)
 
 GARBAGE		+= jscpucfg.o jsautocfg.h jsautocfg.tmp jscpucfg
 
 ifneq (,$(CROSS_COMPILE)$(filter-out WINNT,$(OS_ARCH)))
 TARGETS		+= jscpucfg$(HOST_BIN_SUFFIX)
 endif
 
--- a/js/src/jsapi-tests/Makefile.in
+++ b/js/src/jsapi-tests/Makefile.in
@@ -95,22 +95,16 @@ CPPSRCS = \
 # conservative stack scanning, the fix isn't obvious: more investigation
 # needed.
 #CPPSRCS += \
 #  testRegExpInstanceProperties.cpp \
 #  $(NULL)
 
 DEFINES         += -DEXPORT_JS_API
 
-# Some platforms that have stdint.h include it in system headers.  So
-# to reliably get limit macros defined, we'd always have to define the
-# one below before including any header, but that's obscure and
-# fragile, so we do it here.
-DEFINES         += -D__STDC_LIMIT_MACROS
-
 LIBS      = $(DEPTH)/$(LIB_PREFIX)js_static.$(LIB_SUFFIX) $(NSPR_LIBS)
 
 LOCAL_INCLUDES += -I$(topsrcdir) -I..
 
 include $(topsrcdir)/config/rules.mk
 
 check::
 	$(wildcard $(RUN_TEST_PROGRAM)) $(DIST)/bin/jsapi-tests$(BIN_SUFFIX)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5593,17 +5593,108 @@ JS_StructuredClone(JSContext *cx, jsval 
                    void *closure)
 {
     const JSStructuredCloneCallbacks *callbacks =
         optionalCallbacks ?
         optionalCallbacks :
         cx->runtime->structuredCloneCallbacks;
     JSAutoStructuredCloneBuffer buf;
     return buf.write(cx, v, callbacks, closure) &&
-           buf.read(vp, cx, callbacks, closure);
+           buf.read(cx, vp, callbacks, closure);
+}
+
+void
+JSAutoStructuredCloneBuffer::clear()
+{
+    if (data_) {
+        Foreground::free_(data_);
+        data_ = NULL;
+        nbytes_ = 0;
+        version_ = 0;
+    }
+}
+
+void
+JSAutoStructuredCloneBuffer::adopt(JSUint64 *data, size_t nbytes, JSUint32 version)
+{
+    clear();
+    data_ = data;
+    nbytes_ = nbytes;
+    version_ = version;
+}
+
+bool
+JSAutoStructuredCloneBuffer::copy(const JSUint64 *srcData, size_t nbytes, JSUint32 version)
+{
+    JSUint64 *newData = static_cast<JSUint64 *>(OffTheBooks::malloc_(nbytes));
+    if (!newData)
+        return false;
+
+    memcpy(newData, srcData, nbytes);
+
+    clear();
+    data_ = newData;
+    nbytes_ = nbytes;
+    version_ = version;
+    return true;
+}
+void
+JSAutoStructuredCloneBuffer::steal(JSUint64 **datap, size_t *nbytesp, JSUint32 *versionp)
+{
+    *datap = data_;
+    *nbytesp = nbytes_;
+    if (versionp)
+        *versionp = version_;
+
+    data_ = NULL;
+    nbytes_ = 0;
+    version_ = 0;
+}
+
+bool
+JSAutoStructuredCloneBuffer::read(JSContext *cx, jsval *vp,
+                                  const JSStructuredCloneCallbacks *optionalCallbacks,
+                                  void *closure) const
+{
+    JS_ASSERT(cx);
+    JS_ASSERT(data_);
+    return !!JS_ReadStructuredClone(cx, data_, nbytes_, version_, vp,
+                                    optionalCallbacks, closure);
+}
+
+bool
+JSAutoStructuredCloneBuffer::write(JSContext *cx, jsval v,
+                                   const JSStructuredCloneCallbacks *optionalCallbacks,
+                                   void *closure)
+{
+    clear();
+    bool ok = !!JS_WriteStructuredClone(cx, v, &data_, &nbytes_,
+                                        optionalCallbacks, closure);
+    if (!ok) {
+        data_ = NULL;
+        nbytes_ = 0;
+        version_ = JS_STRUCTURED_CLONE_VERSION;
+    }
+    return ok;
+}
+
+void
+JSAutoStructuredCloneBuffer::swap(JSAutoStructuredCloneBuffer &other)
+{
+    JSUint64 *data = other.data_;
+    size_t nbytes = other.nbytes_;
+    JSUint32 version = other.version_;
+
+    other.data_ = this->data_;
+    other.nbytes_ = this->nbytes_;
+    other.version_ = this->version_;
+
+    this->data_ = data;
+    this->nbytes_ = nbytes;
+    this->version_ = version;
 }
 
 JS_PUBLIC_API(void)
 JS_SetStructuredCloneCallbacks(JSRuntime *rt, const JSStructuredCloneCallbacks *callbacks)
 {
     rt->structuredCloneCallbacks = callbacks;
 }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3369,129 +3369,72 @@ JS_WriteStructuredClone(JSContext *cx, j
                         void *closure);
 
 JS_PUBLIC_API(JSBool)
 JS_StructuredClone(JSContext *cx, jsval v, jsval *vp,
                    const JSStructuredCloneCallbacks *optionalCallbacks,
                    void *closure);
 
 #ifdef __cplusplus
+JS_END_EXTERN_C
+
 /* RAII sugar for JS_WriteStructuredClone. */
-class JSAutoStructuredCloneBuffer {
-    JSContext *cx_;
-    uint64 *data_;
+class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) {
+    JSUint64 *data_;
     size_t nbytes_;
-    uint32 version_;
+    JSUint32 version_;
 
   public:
     JSAutoStructuredCloneBuffer()
-        : cx_(NULL), data_(NULL), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION) {}
+        : data_(NULL), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION) {}
 
     ~JSAutoStructuredCloneBuffer() { clear(); }
 
-    JSContext *cx() const { return cx_; }
-    uint64 *data() const { return data_; }
+    JSUint64 *data() const { return data_; }
     size_t nbytes() const { return nbytes_; }
 
-    void clear(JSContext *cx=NULL) {
-        if (data_) {
-            if (!cx)
-                cx = cx_;
-            JS_ASSERT(cx);
-            JS_free(cx, data_);
-            cx_ = NULL;
-            data_ = NULL;
-            nbytes_ = 0;
-            version_ = 0;
-        }
-    }
+    void clear();
+
+    /* Copy some memory. It will be automatically freed by the destructor. */
+    bool copy(const JSUint64 *data, size_t nbytes, JSUint32 version=JS_STRUCTURED_CLONE_VERSION);
 
     /*
      * Adopt some memory. It will be automatically freed by the destructor.
-     * data must have been allocated using JS_malloc.
+     * data must have been allocated by the JS engine (e.g., extracted via
+     * JSAutoStructuredCloneBuffer::steal).
      */
-    void adopt(JSContext *cx, uint64 *data, size_t nbytes,
-               uint32 version=JS_STRUCTURED_CLONE_VERSION) {
-        clear(cx);
-        cx_ = cx;
-        data_ = data;
-        nbytes_ = nbytes;
-        version_ = version;
-    }
+    void adopt(JSUint64 *data, size_t nbytes, JSUint32 version=JS_STRUCTURED_CLONE_VERSION);
 
     /*
      * Remove the buffer so that it will not be automatically freed.
-     * After this, the caller is responsible for calling JS_free(*datap).
+     * After this, the caller is responsible for feeding the memory back to
+     * JSAutoStructuredCloneBuffer::adopt.
      */
-    void steal(uint64 **datap, size_t *nbytesp, JSContext **cxp=NULL,
-               uint32 *versionp=NULL) {
-        *datap = data_;
-        *nbytesp = nbytes_;
-        if (cxp)
-            *cxp = cx_;
-        if (versionp)
-            *versionp = version_;
-
-        cx_ = NULL;
-        data_ = NULL;
-        nbytes_ = 0;
-        version_ = 0;
-    }
-
-    bool read(jsval *vp, JSContext *cx=NULL,
+    void steal(JSUint64 **datap, size_t *nbytesp, JSUint32 *versionp=NULL);
+
+    bool read(JSContext *cx, jsval *vp,
               const JSStructuredCloneCallbacks *optionalCallbacks=NULL,
-              void *closure=NULL) const {
-        if (!cx)
-            cx = cx_;
-        JS_ASSERT(cx);
-        JS_ASSERT(data_);
-        return !!JS_ReadStructuredClone(cx, data_, nbytes_, version_, vp,
-                                        optionalCallbacks, closure);
-    }
+              void *closure=NULL) const;
 
     bool write(JSContext *cx, jsval v,
                const JSStructuredCloneCallbacks *optionalCallbacks=NULL,
-               void *closure=NULL) {
-        clear(cx);
-        cx_ = cx;
-        bool ok = !!JS_WriteStructuredClone(cx, v, &data_, &nbytes_,
-                                            optionalCallbacks, closure);
-        if (!ok) {
-            data_ = NULL;
-            nbytes_ = 0;
-            version_ = JS_STRUCTURED_CLONE_VERSION;
-        }
-        return ok;
-    }
+               void *closure=NULL);
 
     /**
      * Swap ownership with another JSAutoStructuredCloneBuffer.
      */
-    void swap(JSAutoStructuredCloneBuffer &other) {
-        JSContext *cx = other.cx_;
-        uint64 *data = other.data_;
-        size_t nbytes = other.nbytes_;
-        uint32 version = other.version_;
-
-        other.cx_ = this->cx_;
-        other.data_ = this->data_;
-        other.nbytes_ = this->nbytes_;
-        other.version_ = this->version_;
-
-        this->cx_ = cx;
-        this->data_ = data;
-        this->nbytes_ = nbytes;
-        this->version_ = version;
-    }
+    void swap(JSAutoStructuredCloneBuffer &other);
 
   private:
     /* Copy and assignment are not supported. */
     JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer &other);
     JSAutoStructuredCloneBuffer &operator=(const JSAutoStructuredCloneBuffer &other);
 };
+
+JS_BEGIN_EXTERN_C
 #endif
 
 /* API for implementing custom serialization behavior (for ImageData, File, etc.) */
 
 /* The range of tag values the application may use for its own custom object types. */
 #define JS_SCTAG_USER_MIN  ((uint32) 0xFFFF8000)
 #define JS_SCTAG_USER_MAX  ((uint32) 0xFFFFFFFF)
 
--- a/js/src/methodjit/FastArithmetic.cpp
+++ b/js/src/methodjit/FastArithmetic.cpp
@@ -242,22 +242,18 @@ mjit::Compiler::jsop_binary(JSOp op, Voi
         return;
 
     /*
      * Bail out if there are unhandled types or ops.
      * This is temporary while ops are still being implemented.
      */
     if ((op == JSOP_MOD) ||
         (lhs->isTypeKnown() && (lhs->getKnownType() > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET)) ||
-        (rhs->isTypeKnown() && (rhs->getKnownType() > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET)) 
-#if defined(JS_CPU_ARM)
-        /* ARM cannot detect integer overflow with multiplication. */
-        || op == JSOP_MUL
-#endif /* JS_CPU_ARM */
-    ) {
+        (rhs->isTypeKnown() && (rhs->getKnownType() > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET)))
+    {
         bool isStringResult = (op == JSOP_ADD) &&
                               (lhs->isType(JSVAL_TYPE_STRING) ||
                                rhs->isType(JSVAL_TYPE_STRING));
 
         prepareStubCall(Uses(2));
         INLINE_STUBCALL(stub);
         frame.popn(2);
         if (isStringResult)
@@ -440,21 +436,19 @@ mjit::Compiler::jsop_binary_full_simple(
       case JSOP_ADD:
         overflow = masm.branchAdd32(Assembler::Overflow, regs.result, regs.result);
         break;
 
       case JSOP_SUB:
         overflow = masm.branchSub32(Assembler::Overflow, regs.result, regs.result);
         break;
 
-#if !defined(JS_CPU_ARM)
       case JSOP_MUL:
         overflow = masm.branchMul32(Assembler::Overflow, regs.result, regs.result);
         break;
-#endif
 
       default:
         JS_NOT_REACHED("unrecognized op");
     }
     
     JS_ASSERT(overflow.isSet());
 
     /*
@@ -624,17 +618,16 @@ mjit::Compiler::jsop_binary_full(FrameEn
 
       case JSOP_SUB:
         if (reg.isSet())
             overflow = masm.branchSub32(Assembler::Overflow, reg.reg(), regs.result);
         else
             overflow = masm.branchSub32(Assembler::Overflow, Imm32(value), regs.result);
         break;
 
-#if !defined(JS_CPU_ARM)
       case JSOP_MUL:
       {
         JS_ASSERT(reg.isSet());
         
         MaybeJump storeNegZero;
         bool maybeNegZero = true;
         bool hasConstant = (lhs->isConstant() || rhs->isConstant());
         
@@ -677,17 +670,16 @@ mjit::Compiler::jsop_binary_full(FrameEn
                 stubcc.linkExitDirect(storeNegZero.get(), stubcc.masm.label());
             }
             stubcc.masm.storeValue(DoubleValue(-0.0), frame.addressOf(lhs));
             stubcc.masm.loadPayload(frame.addressOf(lhs), regs.result);
             negZeroDone = stubcc.masm.jump();
         }
         break;
       }
-#endif
 
       default:
         JS_NOT_REACHED("unrecognized op");
     }
     op = origOp;
     
     JS_ASSERT(overflow.isSet());
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -33,18 +33,16 @@
  * 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 ***** */
 
-#define __STDC_LIMIT_MACROS
-
 /*
  * JS shell.
  */
 #include <errno.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
--- a/js/src/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/src/xpconnect/src/dom_quickstubs.qsconf
@@ -253,16 +253,17 @@ members = [
     'nsIDOMHTMLInputElement.form',
     'nsIDOMHTMLInputElement.src',
     'nsIDOMHTMLInputElement.name',
     'nsIDOMHTMLInputElement.value',
     'nsIDOMHTMLInputElement.files',
     'nsIDOMHTMLInputElement.textLength',
     'nsIDOMHTMLInputElement.selectionStart',
     'nsIDOMHTMLInputElement.selectionEnd',
+    'nsIDOMHTMLInputElement.selectionDirection',
     'nsIDOMHTMLInputElement.setSelectionRange',
     'nsIDOMHTMLLinkElement.disabled',
     'nsIDOMHTMLOptionElement.index',
     'nsIDOMHTMLOptionElement.selected',
     'nsIDOMHTMLOptionElement.form',
     'nsIDOMHTMLOptionElement.text',
     'nsIDOMHTMLOptionElement.defaultSelected',
     'nsIDOMHTMLOptionElement.value',
@@ -312,16 +313,17 @@ members = [
     'nsIDOMHTMLTextAreaElement.defaultValue',
     'nsIDOMHTMLTextAreaElement.cols',
     'nsIDOMHTMLTextAreaElement.value',
     'nsIDOMHTMLTextAreaElement.type',
     'nsIDOMHTMLTextAreaElement.select',
     'nsIDOMHTMLTextAreaElement.setSelectionRange',
     'nsIDOMHTMLTextAreaElement.selectionStart',
     'nsIDOMHTMLTextAreaElement.selectionEnd',
+    'nsIDOMHTMLTextAreaElement.selectionDirection',
     'nsIDOMHTMLTextAreaElement.textLength',
     'nsIDOMHTMLTextAreaElement.wrap',
     'nsIDOMHTMLTitleElement.text',
     'nsIDOMHTMLCanvasElement.width',
     'nsIDOMHTMLCanvasElement.height',
     'nsIDOMHTMLCanvasElement.getContext',
     'nsIDOMHTMLCanvasElement.toDataURL',
     'nsIDOMNSHTMLElement.contentEditable',
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -526,22 +526,18 @@ MAKE_CTOR(CreateSubtreeIterator,        
 MAKE_CTOR(CreateTextEncoder,              nsIDocumentEncoder,          NS_NewTextEncoder)
 MAKE_CTOR(CreateHTMLCopyTextEncoder,      nsIDocumentEncoder,          NS_NewHTMLCopyTextEncoder)
 MAKE_CTOR(CreateXMLContentSerializer,     nsIContentSerializer,        NS_NewXMLContentSerializer)
 MAKE_CTOR(CreateHTMLContentSerializer,    nsIContentSerializer,        NS_NewHTMLContentSerializer)
 MAKE_CTOR(CreateXHTMLContentSerializer,   nsIContentSerializer,        NS_NewXHTMLContentSerializer)
 MAKE_CTOR(CreatePlainTextSerializer,      nsIContentSerializer,        NS_NewPlainTextSerializer)
 MAKE_CTOR(CreateHTMLFragmentSink,         nsIFragmentContentSink,      NS_NewHTMLFragmentContentSink)
 MAKE_CTOR(CreateHTMLFragmentSink2,        nsIFragmentContentSink,      NS_NewHTMLFragmentContentSink2)
-MAKE_CTOR(CreateHTMLParanoidFragmentSink, nsIFragmentContentSink,      NS_NewHTMLParanoidFragmentSink)
-MAKE_CTOR(CreateHTMLParanoidFragmentSink2,nsIFragmentContentSink,      NS_NewHTMLParanoidFragmentSink2)
 MAKE_CTOR(CreateXMLFragmentSink,          nsIFragmentContentSink,      NS_NewXMLFragmentContentSink)
 MAKE_CTOR(CreateXMLFragmentSink2,         nsIFragmentContentSink,      NS_NewXMLFragmentContentSink2)
-MAKE_CTOR(CreateXHTMLParanoidFragmentSink,nsIFragmentContentSink,      NS_NewXHTMLParanoidFragmentSink)
-MAKE_CTOR(CreateXHTMLParanoidFragmentSink2,nsIFragmentContentSink,     NS_NewXHTMLParanoidFragmentSink2)
 MAKE_CTOR(CreateSanitizingHTMLSerializer, nsIContentSerializer,        NS_NewSanitizingHTMLSerializer)
 MAKE_CTOR(CreateXBLService,               nsIXBLService,               NS_NewXBLService)
 MAKE_CTOR(CreateContentPolicy,            nsIContentPolicy,            NS_NewContentPolicy)
 #ifdef MOZ_XUL
 MAKE_CTOR(CreateXULSortService,           nsIXULSortService,           NS_NewXULSortService)
 // NS_NewXULContentBuilder
 // NS_NewXULTreeBuilder
 MAKE_CTOR(CreateXULDocument,              nsIXULDocument,              NS_NewXULDocument)
@@ -777,23 +773,19 @@ NS_DEFINE_NAMED_CID(NS_CANVASRENDERINGCO
 NS_DEFINE_NAMED_CID(NS_TEXT_ENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLCOPY_TEXT_ENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_XMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_XHTMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_PLAINTEXTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLFRAGMENTSINK_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLFRAGMENTSINK2_CID);
-NS_DEFINE_NAMED_CID(NS_HTMLPARANOIDFRAGMENTSINK_CID);
-NS_DEFINE_NAMED_CID(NS_HTMLPARANOIDFRAGMENTSINK2_CID);
 NS_DEFINE_NAMED_CID(MOZ_SANITIZINGHTMLSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_XMLFRAGMENTSINK_CID);
 NS_DEFINE_NAMED_CID(NS_XMLFRAGMENTSINK2_CID);
-NS_DEFINE_NAMED_CID(NS_XHTMLPARANOIDFRAGMENTSINK_CID);
-NS_DEFINE_NAMED_CID(NS_XHTMLPARANOIDFRAGMENTSINK2_CID);
 NS_DEFINE_NAMED_CID(NS_XBLSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_CONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_DATADOCUMENTCONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_NODATAPROTOCOLCONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_XULCONTROLLERS_CID);
 #ifdef MOZ_XUL
 NS_DEFINE_NAMED_CID(NS_XULSORTSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_XULTEMPLATEBUILDER_CID);
@@ -920,23 +912,19 @@ static const mozilla::Module::CIDEntry k
   { &kNS_TEXT_ENCODER_CID, false, NULL, CreateTextEncoder },
   { &kNS_HTMLCOPY_TEXT_ENCODER_CID, false, NULL, CreateHTMLCopyTextEncoder },
   { &kNS_XMLCONTENTSERIALIZER_CID, false, NULL, CreateXMLContentSerializer },
   { &kNS_HTMLCONTENTSERIALIZER_CID, false, NULL, CreateHTMLContentSerializer },
   { &kNS_XHTMLCONTENTSERIALIZER_CID, false, NULL, CreateXHTMLContentSerializer },
   { &kNS_PLAINTEXTSERIALIZER_CID, false, NULL, CreatePlainTextSerializer },
   { &kNS_HTMLFRAGMENTSINK_CID, false, NULL, CreateHTMLFragmentSink },
   { &kNS_HTMLFRAGMENTSINK2_CID, false, NULL, CreateHTMLFragmentSink2 },
-  { &kNS_HTMLPARANOIDFRAGMENTSINK_CID, false, NULL, CreateHTMLParanoidFragmentSink },
-  { &kNS_HTMLPARANOIDFRAGMENTSINK2_CID, false, NULL, CreateHTMLParanoidFragmentSink2 },
   { &kMOZ_SANITIZINGHTMLSERIALIZER_CID, false, NULL, CreateSanitizingHTMLSerializer },
   { &kNS_XMLFRAGMENTSINK_CID, false, NULL, CreateXMLFragmentSink },
   { &kNS_XMLFRAGMENTSINK2_CID, false, NULL, CreateXMLFragmentSink2 },
-  { &kNS_XHTMLPARANOIDFRAGMENTSINK_CID, false, NULL, CreateXHTMLParanoidFragmentSink },
-  { &kNS_XHTMLPARANOIDFRAGMENTSINK2_CID, false, NULL, CreateXHTMLParanoidFragmentSink2 },
   { &kNS_XBLSERVICE_CID, false, NULL, CreateXBLService },
   { &kNS_CONTENTPOLICY_CID, false, NULL, CreateContentPolicy },
   { &kNS_DATADOCUMENTCONTENTPOLICY_CID, false, NULL, nsDataDocumentContentPolicyConstructor },
   { &kNS_NODATAPROTOCOLCONTENTPOLICY_CID, false, NULL, nsNoDataProtocolContentPolicyConstructor },
   { &kNS_XULCONTROLLERS_CID, false, NULL, NS_NewXULControllers },
 #ifdef MOZ_XUL
   { &kNS_XULSORTSERVICE_CID, false, NULL, CreateXULSortService },
   { &kNS_XULTEMPLATEBUILDER_CID, false, NULL, NS_NewXULContentBuilder },
@@ -1064,23 +1052,19 @@ static const mozilla::Module::ContractID
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "application/xhtml+xml", &kNS_XHTMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "image/svg+xml", &kNS_XMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "text/html", &kNS_HTMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "application/vnd.mozilla.xul+xml", &kNS_XMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "text/plain", &kNS_PLAINTEXTSERIALIZER_CID },
   { NS_PLAINTEXTSINK_CONTRACTID, &kNS_PLAINTEXTSERIALIZER_CID },
   { NS_HTMLFRAGMENTSINK_CONTRACTID, &kNS_HTMLFRAGMENTSINK_CID },
   { NS_HTMLFRAGMENTSINK2_CONTRACTID, &kNS_HTMLFRAGMENTSINK2_CID },
-  { NS_HTMLPARANOIDFRAGMENTSINK_CONTRACTID, &kNS_HTMLPARANOIDFRAGMENTSINK_CID },
-  { NS_HTMLPARANOIDFRAGMENTSINK2_CONTRACTID, &kNS_HTMLPARANOIDFRAGMENTSINK2_CID },
   { MOZ_SANITIZINGHTMLSERIALIZER_CONTRACTID, &kMOZ_SANITIZINGHTMLSERIALIZER_CID },
   { NS_XMLFRAGMENTSINK_CONTRACTID, &kNS_XMLFRAGMENTSINK_CID },
   { NS_XMLFRAGMENTSINK2_CONTRACTID, &kNS_XMLFRAGMENTSINK2_CID },
-  { NS_XHTMLPARANOIDFRAGMENTSINK_CONTRACTID, &kNS_XHTMLPARANOIDFRAGMENTSINK_CID },
-  { NS_XHTMLPARANOIDFRAGMENTSINK2_CONTRACTID, &kNS_XHTMLPARANOIDFRAGMENTSINK2_CID },
   { "@mozilla.org/xbl;1", &kNS_XBLSERVICE_CID },
   { NS_CONTENTPOLICY_CONTRACTID, &kNS_CONTENTPOLICY_CID },
   { NS_DATADOCUMENTCONTENTPOLICY_CONTRACTID, &kNS_DATADOCUMENTCONTENTPOLICY_CID },
   { NS_NODATAPROTOCOLCONTENTPOLICY_CONTRACTID, &kNS_NODATAPROTOCOLCONTENTPOLICY_CID },
   { "@mozilla.org/xul/xul-controllers;1", &kNS_XULCONTROLLERS_CID },
 #ifdef MOZ_XUL
   { "@mozilla.org/xul/xul-sort-service;1", &kNS_XULSORTSERVICE_CID },
   { "@mozilla.org/xul/xul-template-builder;1", &kNS_XULTEMPLATEBUILDER_CID },
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -68,16 +68,17 @@
 #include "nsFloatManager.h"
 #include "nsSprocketLayout.h"
 #include "nsStackLayout.h"
 #include "nsStyleSet.h"
 #include "nsTextControlFrame.h"
 #include "nsXBLWindowKeyHandler.h"
 #include "txMozillaXSLTProcessor.h"
 #include "nsDOMStorage.h"
+#include "nsTreeSanitizer.h"
 #include "nsCellMap.h"
 #include "nsTextFrameTextRunCache.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsTextFragment.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsCrossSiteListenerProxy.h"
 #include "nsHTMLDNSPrefetch.h"
 #include "nsHtml5Module.h"
@@ -342,16 +343,18 @@ nsLayoutStatics::Shutdown()
 #ifdef MOZ_SYDNEYAUDIO
   nsAudioStream::ShutdownLibrary();
 #endif
 
   nsCORSListenerProxy::Shutdown();
   
   nsIPresShell::ReleaseStatics();
 
+  nsTreeSanitizer::ReleaseStatics();
+
   nsHtml5Module::ReleaseStatics();
 
   nsRegion::ShutdownStatic();
 
   NS_ShutdownChainItemPool();
 
   nsFrameList::Shutdown();
 
--- a/layout/forms/nsITextControlFrame.h
+++ b/layout/forms/nsITextControlFrame.h
@@ -45,30 +45,40 @@ class nsIDocShell;
 class nsISelectionController;
 class nsFrameSelection;
 
 class nsITextControlFrame : public nsIFormControlFrame
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsITextControlFrame)
 
+  enum SelectionDirection {
+    eNone,
+    eForward,
+    eBackward
+  };
+
   NS_IMETHOD    GetEditor(nsIEditor **aEditor) = 0;
 
   NS_IMETHOD    GetTextLength(PRInt32* aTextLength) = 0;
   
   /**
    * Fire onChange if the value has changed since it was focused or since it
    * was last fired.
    */
   NS_IMETHOD    CheckFireOnChange() = 0;
   NS_IMETHOD    SetSelectionStart(PRInt32 aSelectionStart) = 0;
   NS_IMETHOD    SetSelectionEnd(PRInt32 aSelectionEnd) = 0;
   
-  NS_IMETHOD    SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelectionEnd) = 0;
-  NS_IMETHOD    GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd) = 0;
+  NS_IMETHOD    SetSelectionRange(PRInt32 aSelectionStart,
+                                  PRInt32 aSelectionEnd,
+                                  SelectionDirection aDirection = eNone) = 0;
+  NS_IMETHOD    GetSelectionRange(PRInt32* aSelectionStart,
+                                  PRInt32* aSelectionEnd,
+                                  SelectionDirection* aDirection = nsnull) = 0;
 
   NS_IMETHOD    GetOwnedSelectionController(nsISelectionController** aSelCon) = 0;
   virtual nsFrameSelection* GetOwnedFrameSelection() = 0;
 
   virtual nsresult GetPhonetic(nsAString& aPhonetic) = 0;
 
   /**
    * Ensure editor is initialized with the proper flags and the default value.
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -800,17 +800,18 @@ nsTextControlFrame::GetTextLength(PRInt3
   *aTextLength = textContents.Length();
   return NS_OK;
 }
 
 nsresult
 nsTextControlFrame::SetSelectionInternal(nsIDOMNode *aStartNode,
                                          PRInt32 aStartOffset,
                                          nsIDOMNode *aEndNode,
-                                         PRInt32 aEndOffset)
+                                         PRInt32 aEndOffset,
+                                         nsITextControlFrame::SelectionDirection aDirection)
 {
   // Create a new range to represent the new selection.
   // Note that we use a new range to avoid having to do
   // isIncreasing checks to avoid possible errors.
 
   nsCOMPtr<nsIDOMRange> range = do_CreateInstance(kRangeCID);
   NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 
@@ -825,20 +826,34 @@ nsTextControlFrame::SetSelectionInternal
   NS_ASSERTION(txtCtrl, "Content not a text control element");
   nsISelectionController* selCon = txtCtrl->GetSelectionController();
   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsISelection> selection;
   selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));  
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
+  nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsDirection direction;
+  if (aDirection == eNone) {
+    // Preserve the direction
+    direction = selPriv->GetSelectionDirection();
+  } else {
+    direction = (aDirection == eBackward) ? eDirPrevious : eDirNext;
+  }
+
   rv = selection->RemoveAllRanges();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = selection->AddRange(range);  // NOTE: can destroy the world
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  selPriv->SetSelectionDirection(direction);
   return rv;
 }
 
 nsresult
 nsTextControlFrame::ScrollSelectionIntoView()
 {
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
   NS_ASSERTION(txtCtrl, "Content not a text control element");
@@ -901,17 +916,18 @@ nsTextControlFrame::SelectAllOrCollapseT
   rv = SetSelectionInternal(rootNode, aSelect ? 0 : numChildren,
                             rootNode, numChildren);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return ScrollSelectionIntoView();
 }
 
 nsresult
-nsTextControlFrame::SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd)
+nsTextControlFrame::SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd,
+                                          nsITextControlFrame::SelectionDirection aDirection)
 {
   NS_ASSERTION(aSelStart <= aSelEnd, "Invalid selection offsets!");
 
   if (aSelStart > aSelEnd)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMNode> startNode, endNode;
   PRInt32 startOffset, endOffset;
@@ -931,33 +947,34 @@ nsTextControlFrame::SetSelectionEndPoint
     // Selection isn't collapsed so we have to calculate
     // the end point too.
 
     rv = OffsetToDOMPoint(aSelEnd, getter_AddRefs(endNode), &endOffset);
 
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  return SetSelectionInternal(startNode, startOffset, endNode, endOffset);
+  return SetSelectionInternal(startNode, startOffset, endNode, endOffset, aDirection);
 }
 
 NS_IMETHODIMP
-nsTextControlFrame::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd)
+nsTextControlFrame::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd,
+                                      nsITextControlFrame::SelectionDirection aDirection)
 {
   nsresult rv = EnsureEditorInitialized();
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aSelStart > aSelEnd) {
     // Simulate what we'd see SetSelectionStart() was called, followed
     // by a SetSelectionEnd().
 
     aSelStart   = aSelEnd;
   }
 
-  return SetSelectionEndPoints(aSelStart, aSelEnd);
+  return SetSelectionEndPoints(aSelStart, aSelEnd, aDirection);
 }
 
 
 NS_IMETHODIMP
 nsTextControlFrame::SetSelectionStart(PRInt32 aSelectionStart)
 {
   nsresult rv = EnsureEditorInitialized();
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1105,24 +1122,33 @@ nsTextControlFrame::OffsetToDOMPoint(PRI
     NS_IF_ADDREF(*aResult = rootNode);
     *aPosition = 0;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd)
+nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart,
+                                      PRInt32* aSelectionEnd,
+                                      SelectionDirection* aDirection)
 {
   // make sure we have an editor
   nsresult rv = EnsureEditorInitialized();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aSelectionStart = 0;
-  *aSelectionEnd = 0;
+  if (aSelectionStart) {
+    *aSelectionStart = 0;
+  }
+  if (aSelectionEnd) {
+    *aSelectionEnd = 0;
+  }
+  if (aDirection) {
+    *aDirection = eNone;
+  }
 
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
   NS_ASSERTION(txtCtrl, "Content not a text control element");
   nsISelectionController* selCon = txtCtrl->GetSelectionController();
   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
   nsCOMPtr<nsISelection> selection;
   rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));  
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1131,16 +1157,34 @@ nsTextControlFrame::GetSelectionRange(PR
   PRInt32 numRanges = 0;
   selection->GetRangeCount(&numRanges);
 
   if (numRanges < 1)
     return NS_OK;
 
   // We only operate on the first range in the selection!
 
+  if (aDirection) {
+    nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection);
+    if (selPriv) {
+      nsDirection direction = selPriv->GetSelectionDirection();
+      if (direction == eDirNext) {
+        *aDirection = eForward;
+      } else if (direction == eDirPrevious) {
+        *aDirection = eBackward;
+      } else {
+        NS_NOTREACHED("Invalid nsDirection enum value");
+      }
+    }
+  }
+
+  if (!aSelectionStart || !aSelectionEnd) {
+    return NS_OK;
+  }
+
   nsCOMPtr<nsIDOMRange> firstRange;
   rv = selection->GetRangeAt(0, getter_AddRefs(firstRange));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(firstRange, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNode> startNode, endNode;
   PRInt32 startOffset = 0, endOffset = 0;
 
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -140,18 +140,22 @@ public:
 
 //==== NSITEXTCONTROLFRAME
 
   NS_IMETHOD    GetEditor(nsIEditor **aEditor);
   NS_IMETHOD    GetTextLength(PRInt32* aTextLength);
   NS_IMETHOD    CheckFireOnChange();
   NS_IMETHOD    SetSelectionStart(PRInt32 aSelectionStart);
   NS_IMETHOD    SetSelectionEnd(PRInt32 aSelectionEnd);
-  NS_IMETHOD    SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelectionEnd);
-  NS_IMETHOD    GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
+  NS_IMETHOD    SetSelectionRange(PRInt32 aSelectionStart,
+                                  PRInt32 aSelectionEnd,
+                                  SelectionDirection aDirection = eNone);
+  NS_IMETHOD    GetSelectionRange(PRInt32* aSelectionStart,
+                                  PRInt32* aSelectionEnd,
+                                  SelectionDirection* aDirection = nsnull);
   NS_IMETHOD    GetOwnedSelectionController(nsISelectionController** aSelCon);
   virtual nsFrameSelection* GetOwnedFrameSelection();
 
   nsresult GetPhonetic(nsAString& aPhonetic);
 
   /**
    * Ensure mEditor is initialized with the proper flags and the default value.
    * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created
@@ -385,19 +389,21 @@ protected:
   nsresult CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
                              nsSize&              aIntrinsicSize);
 
   nsresult ScrollSelectionIntoView();
 
 private:
   //helper methods
   nsresult SetSelectionInternal(nsIDOMNode *aStartNode, PRInt32 aStartOffset,
-                                nsIDOMNode *aEndNode, PRInt32 aEndOffset);
+                                nsIDOMNode *aEndNode, PRInt32 aEndOffset,
+                                SelectionDirection aDirection = eNone);
   nsresult SelectAllOrCollapseToEndOfText(PRBool aSelect);
-  nsresult SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd);
+  nsresult SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd,
+                                 SelectionDirection aDirection = eNone);
 
   // accessors for the notify on input flag
   PRBool GetNotifyOnInput() const { return mNotifyOnInput; }
   void SetNotifyOnInput(PRBool val) { mNotifyOnInput = val; }
 
   /**
    * Return the root DOM element, and implicitly initialize the editor if needed.
    */
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -230,17 +230,9 @@ NS_NewHTMLContentSink(nsIHTMLContentSink
                       nsIDocument* aDoc, nsIURI* aURL,
                       nsISupports* aContainer, // e.g. docshell
                       nsIChannel* aChannel);
 nsresult
 NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aInstancePtrResult);
 nsresult
 NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aInstancePtrResult);
 
-// This strips all but a whitelist of elements and attributes defined
-// in nsContentSink.h
-nsresult
-NS_NewHTMLParanoidFragmentSink(nsIFragmentContentSink** aInstancePtrResult);
-nsresult
-NS_NewHTMLParanoidFragmentSink2(nsIFragmentContentSink** aInstancePtrResult);
-void
-NS_HTMLParanoidFragmentSinkShutdown();
 #endif /* nsHTMLParts_h___ */
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -972,17 +972,17 @@ nsHTMLReflowState::CalculateHypothetical
       aHypotheticalBox.mTop = placeholderOffset.y;
     } else {
       NS_ASSERTION(iter.GetContainer() == blockFrame,
                    "Found placeholder in wrong block!");
       nsBlockFrame::line_iterator lineBox = iter.GetLine();
 
       // How we determine the hypothetical box depends on whether the element
       // would have been inline-level or block-level
-      if (NS_STYLE_DISPLAY_INLINE == mStyleDisplay->mOriginalDisplay) {
+      if (mStyleDisplay->IsOriginalDisplayInlineOutside()) {
         // Use the top of the inline box which the placeholder lives in
         // as the hypothetical box's top.
         aHypotheticalBox.mTop = lineBox->mBounds.y + blockYOffset;
       } else {
         // The element would have been block-level which means it would
         // be below the line containing the placeholder frame, unless
         // all the frames before it are empty.  In that case, it would
         // have been just before this line.
@@ -1024,17 +1024,17 @@ nsHTMLReflowState::CalculateHypothetical
     aHypotheticalBox.mTop = placeholderOffset.y;
   }
 
   // Second, determine the hypothetical box's mLeft & mRight
   // To determine the left and right offsets we need to look at the block's 'direction'
   if (NS_STYLE_DIRECTION_LTR == blockVis->mDirection) {
     // How we determine the hypothetical box depends on whether the element
     // would have been inline-level or block-level
-    if (NS_STYLE_DISPLAY_INLINE == mStyleDisplay->mOriginalDisplay) {
+    if (mStyleDisplay->IsOriginalDisplayInlineOutside()) {
       // The placeholder represents the left edge of the hypothetical box
       aHypotheticalBox.mLeft = placeholderOffset.x;
     } else {
       aHypotheticalBox.mLeft = aBlockLeftContentEdge;
     }
 #ifdef DEBUG
     aHypotheticalBox.mLeftIsExact = PR_TRUE;
 #endif
@@ -1051,17 +1051,17 @@ nsHTMLReflowState::CalculateHypothetical
       aHypotheticalBox.mRight = aBlockLeftContentEdge + aBlockContentWidth;
 #ifdef DEBUG
       aHypotheticalBox.mRightIsExact = PR_FALSE;
 #endif
     }
 
   } else {
     // The placeholder represents the right edge of the hypothetical box
-    if (NS_STYLE_DISPLAY_INLINE == mStyleDisplay->mOriginalDisplay) {
+    if (mStyleDisplay->IsOriginalDisplayInlineOutside()) {
       aHypotheticalBox.mRight = placeholderOffset.x;
     } else {
       aHypotheticalBox.mRight = aBlockLeftContentEdge + aBlockContentWidth;
     }
 #ifdef DEBUG
     aHypotheticalBox.mRightIsExact = PR_TRUE;
 #endif
     
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -5991,16 +5991,26 @@ nsTypedSelection::SelectionLanguageChang
   
   // The caret might have moved, so invalidate the desired X position
   // for future usages of up-arrow or down-arrow
   mFrameSelection->InvalidateDesiredX();
   
   return NS_OK;
 }
 
+NS_IMETHODIMP_(nsDirection)
+nsTypedSelection::GetSelectionDirection() {
+  return mDirection;
+}
+
+NS_IMETHODIMP_(void)
+nsTypedSelection::SetSelectionDirection(nsDirection aDirection) {
+  mDirection = aDirection;
+}
+
 
 // nsAutoCopyListener
 
 nsAutoCopyListener* nsAutoCopyListener::sInstance = nsnull;
 
 NS_IMPL_ISUPPORTS1(nsAutoCopyListener, nsISelectionListener)
 
 /*
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/auto-offset-inline-block-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<title>'auto' offset properties on display:inline-block (reference)</title>
+<style>
+p { font-family: monospace /* avoid kerning */ }
+</style>
+<p>HelloWorld</p>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/abs-pos/auto-offset-inline-block-1.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<title>'auto' offset properties on display:inline-block</title>
+<style>
+p { font-family: monospace /* avoid kerning */ }
+span {
+  display: inline-block;
+  position: absolute;
+}
+</style>
+<p>Hello<span>World</span></p>
--- a/layout/reftests/abs-pos/reftest.list
+++ b/layout/reftests/abs-pos/reftest.list
@@ -1,2 +1,3 @@
 == font-size-wrap.html font-size-wrap-ref.html
 == abs-pos-auto-margin-1.html abs-pos-auto-margin-1-ref.html
+== auto-offset-inline-block-1.html auto-offset-inline-block-1-ref.html
--- a/layout/reftests/native-theme/reftest.list
+++ b/layout/reftests/native-theme/reftest.list
@@ -46,22 +46,30 @@ fails-if(Android) != 492155-4.html about
 != box-shadow-listbox.html box-shadow-listbox-ref.html
 != box-shadow-combobox.html box-shadow-combobox-ref.html
 
 # RTL mirroring tests
 == checkbox-not-mirrored-when-rtl.html checkbox-not-mirrored-when-rtl-ref.html
 skip-if(!cocoaWidget) == menulist-mirrored-when-rtl.xul menulist-mirrored-when-rtl-ref.xul
 skip-if(!cocoaWidget) == searchfield-mirrored-when-rtl.xul searchfield-mirrored-when-rtl-ref.xul
 skip-if(!cocoaWidget) == select-mirrored-when-rtl.html select-mirrored-when-rtl-ref.html
+
 != resizer-bottomend.xul blank-window.xul
 random-if(d2d) == resizer-bottomend.xul resizer-bottomright.xul # bug 581086 
 != resizer-bottomend.xul resizer-bottomend-rtl.xul
 skip-if(gtk2Widget) != resizer-bottomend-rtl.xul blank-window.xul
 skip-if(gtk2Widget) random-if(d2d) == resizer-bottomend-rtl.xul resizer-bottomend-flipped.xul # bug 581086
 
+!= resizer-bottomstart.xul blank-window.xul
+random-if(d2d) == resizer-bottomstart.xul resizer-bottomleft.xul
+random-if(d2d) == resizer-bottomstart.xul resizer-left.xul
+!= resizer-bottomstart.xul resizer-bottomstart-rtl.xul
+skip-if(gtk2Widget) != resizer-bottomstart-rtl.xul blank-window.xul
+skip-if(gtk2Widget) random-if(d2d) == resizer-bottomstart-rtl.xul resizer-bottomend.xul
+
 # Windows-only, depends on native scrollbar metrics
 skip-if(!winWidget) == scroll-thumb-minimum-size-notheme.html scroll-thumb-minimum-size-notheme-ref.html
 # skip-if(!winWidget) == scroll-thumb-minimum-size-theme.html scroll-thumb-minimum-size-theme-ref.html # Bug 512206
 
 == border-radius.html border-radius-ref.html
 
 == checkbox-dynamic-1.html checkbox-dynamic-1-ref.html
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-bottomleft.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="bottomleft"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-bottomstart-rtl.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="bottomstart" style="direction: rtl"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-bottomstart.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="bottomstart"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-left.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="left"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1546,23 +1546,31 @@ struct nsStyleDisplay {
   }
 
   PRBool IsBlockOutside() const {
     return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
            NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
            NS_STYLE_DISPLAY_TABLE == mDisplay;
   }
 
+  static PRBool IsDisplayTypeInlineOutside(PRUint8 aDisplay) {
+    return NS_STYLE_DISPLAY_INLINE == aDisplay ||
+           NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay ||
+           NS_STYLE_DISPLAY_INLINE_TABLE == aDisplay ||
+           NS_STYLE_DISPLAY_INLINE_BOX == aDisplay ||
+           NS_STYLE_DISPLAY_INLINE_GRID == aDisplay ||
+           NS_STYLE_DISPLAY_INLINE_STACK == aDisplay;
+  }
+
   PRBool IsInlineOutside() const {
-    return NS_STYLE_DISPLAY_INLINE == mDisplay ||
-           NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay ||
-           NS_STYLE_DISPLAY_INLINE_TABLE == mDisplay ||
-           NS_STYLE_DISPLAY_INLINE_BOX == mDisplay ||
-           NS_STYLE_DISPLAY_INLINE_GRID == mDisplay ||
-           NS_STYLE_DISPLAY_INLINE_STACK == mDisplay;
+    return IsDisplayTypeInlineOutside(mDisplay);
+  }
+
+  PRBool IsOriginalDisplayInlineOutside() const {
+    return IsDisplayTypeInlineOutside(mOriginalDisplay);
   }
 
   PRBool IsFloating() const {
     return NS_STYLE_FLOAT_NONE != mFloats;
   }
 
   PRBool IsAbsolutelyPositioned() const {return (NS_STYLE_POSITION_ABSOLUTE == mPosition) ||
                                                 (NS_STYLE_POSITION_FIXED == mPosition);}
--- a/layout/style/viewsource.css
+++ b/layout/style/viewsource.css
@@ -98,15 +98,14 @@ pre {
 }
 .markupdeclaration {
  color: steelblue;
  font-style: italic;
 }
 span:not(.error) {
  unicode-bidi: embed;
 }
-.error, .error > .start-tag, .error > .end-tag,
-.error > .comment, .error > .cdata, .error > .doctype,
-.error > .pi, .error > .entity, .error > .attribute-name,
-.error > .attribute-value {
+.error, 
+.error > :-moz-any(.start-tag, .end-tag, .comment, .cdata, .doctype, .pi,
+                   .entity, .attribute-name, .attribute-value) {
   color: red;
   font-weight: bold;
 }
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -1158,20 +1158,18 @@ nsMenuPopupFrame::SetPopupPosition(nsIFr
   nsMargin margin(0, 0, 0, 0);
   GetStyleMargin()->GetMargin(margin);
 
   // the screen rectangle of the root frame, in dev pixels.
   nsRect rootScreenRect = rootFrame->GetScreenRectInAppUnits();
 
   nsDeviceContext* devContext = presContext->DeviceContext();
   nscoord offsetForContextMenu = 0;
-  // if mScreenXPos and mScreenYPos are -1, then we are anchored. If they
-  // have other values, then the popup appears unanchored at that screen
-  // coordinate.
-  if (mScreenXPos == -1 && mScreenYPos == -1) {
+
+  if (IsAnchored()) {
     // if we are anchored, there are certain things we don't want to do when
     // repositioning the popup to fit on the screen, such as end up positioned
     // over the anchor, for instance a popup appearing over the menu label.
     // When doing this reposition, we want to move the popup to the side with
     // the most room. The combination of anchor and alignment dictate if we 
     // readjust above/below or to the left/right.
     if (mAnchorContent) {
       // move the popup according to the anchor and alignment. This will also
--- a/layout/xul/base/src/nsResizerFrame.cpp
+++ b/layout/xul/base/src/nsResizerFrame.cpp
@@ -278,20 +278,19 @@ nsResizerFrame::HandleEvent(nsPresContex
           if (direction.mHorizontal) {
             contentToResize->SetAttr(kNameSpaceID_None, nsGkAtoms::width, widthstr, PR_TRUE);
           }
           if (direction.mVertical) {
             contentToResize->SetAttr(kNameSpaceID_None, nsGkAtoms::height, heightstr, PR_TRUE);
           }
 
           if (weakFrame.IsAlive() &&
-              (oldRect.x != rect.x || oldRect.y != rect.y)) {
-            // XXX This might go very wrong, since menu popups may add
-            // offsets (e.g. from margins) to this position, so the popup's
-            // widget won't end up at the desired position.
+              (oldRect.x != rect.x || oldRect.y != rect.y) &&
+              (!menuPopupFrame->IsAnchored() ||
+               menuPopupFrame->PopupLevel() != ePopupLevelParent)) {
             menuPopupFrame->MoveTo(rect.x, rect.y, PR_TRUE);
           }
         }
         else {
           nsCOMPtr<nsIDOMElementCSSInlineStyle> inlineStyleContent =
             do_QueryInterface(contentToResize);
           if (inlineStyleContent) {
             nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
@@ -326,18 +325,18 @@ nsResizerFrame::HandleEvent(nsPresContex
     break;
   }
 
   if (!doDefault)
     *aEventStatus = nsEventStatus_eConsumeNoDefault;
 
   if (doDefault && weakFrame.IsAlive())
     return nsTitleBarFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
-  else
-    return NS_OK;
+
+  return NS_OK;
 }
 
 nsIContent*
 nsResizerFrame::GetContentToResize(nsIPresShell* aPresShell, nsIBaseWindow** aWindow)
 {
   *aWindow = nsnull;
 
   nsAutoString elementid;
@@ -423,24 +422,24 @@ nsResizerFrame::AdjustDimensions(PRInt32
  */
 nsResizerFrame::Direction
 nsResizerFrame::GetDirection()
 {
   static const nsIContent::AttrValuesArray strings[] =
     {&nsGkAtoms::topleft,    &nsGkAtoms::top,    &nsGkAtoms::topright,
      &nsGkAtoms::left,                           &nsGkAtoms::right,
      &nsGkAtoms::bottomleft, &nsGkAtoms::bottom, &nsGkAtoms::bottomright,
-                                                 &nsGkAtoms::bottomend,
+     &nsGkAtoms::bottomstart,                    &nsGkAtoms::bottomend,
      nsnull};
 
   static const Direction directions[] =
     {{-1, -1}, {0, -1}, {1, -1},
      {-1,  0},          {1,  0},
      {-1,  1}, {0,  1}, {1,  1},
-                        {1,  1}
+     {-1,  1},          {1,  1}
     };
 
   if (!GetContent())
     return directions[0]; // default: topleft
 
   PRInt32 index = GetContent()->FindAttrValueIn(kNameSpaceID_None,
                                                 nsGkAtoms::dir,
                                                 strings, eCaseMatters);
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -3123,38 +3123,41 @@ var ViewableAreaObserver = {
     let oldWidth = parseInt(Browser.styles["viewable-width"].width);
 
     let newWidth = this.width;
     let newHeight = this.height;
     if (newHeight == oldHeight && newWidth == oldWidth)
       return;
 
     // Guess if the window has been resize to handle a virtual keyboard
+    let isDueToKeyboard = (newHeight != oldHeight && newWidth == oldWidth);
     this.isKeyboardOpened = (newHeight < oldHeight && newWidth == oldWidth);
 
     Browser.styles["viewable-height"].height = newHeight + "px";
     Browser.styles["viewable-height"].maxHeight = newHeight + "px";
 
     Browser.styles["viewable-width"].width = newWidth + "px";
     Browser.styles["viewable-width"].maxWidth = newWidth + "px";
 
     let startup = !oldHeight && !oldWidth;
-    for (let i = Browser.tabs.length - 1; i >= 0; i--) {
-      let tab = Browser.tabs[i];
-      let oldContentWindowWidth = tab.browser.contentWindowWidth;
-      tab.updateViewportSize(); // contentWindowWidth may change here.
-
-      // Don't bother updating the zoom level on startup
-      if (!startup) {
-        // If the viewport width is still the same, the page layout has not
-        // changed, so we can keep keep the same content on-screen.
-        if (tab.browser.contentWindowWidth == oldContentWindowWidth)
-          tab.restoreViewportPosition(oldWidth, newWidth);
-
-        tab.updateDefaultZoomLevel();
+    if (!isDueToKeyboard) {
+      for (let i = Browser.tabs.length - 1; i >= 0; i--) {
+        let tab = Browser.tabs[i];
+        let oldContentWindowWidth = tab.browser.contentWindowWidth;
+        tab.updateViewportSize(); // contentWindowWidth may change here.
+  
+        // Don't bother updating the zoom level on startup
+        if (!startup) {
+          // If the viewport width is still the same, the page layout has not
+          // changed, so we can keep keep the same content on-screen.
+          if (tab.browser.contentWindowWidth == oldContentWindowWidth)
+            tab.restoreViewportPosition(oldWidth, newWidth);
+  
+          tab.updateDefaultZoomLevel();
+        }
       }
     }
 
     // setTimeout(callback, 0) to ensure the resize event handler dispatch is finished
     setTimeout(function() {
       let event = document.createEvent("Events");
       event.initEvent("SizeChanged", true, false);
       Elements.browsers.dispatchEvent(event);
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -1327,48 +1327,70 @@ var TouchEventHandler = {
   }
 };
 
 TouchEventHandler.init();
 
 var SelectionHandler = {
   cache: {},
   selectedText: "",
+  contentWindow: null,
   
   init: function() {
     addMessageListener("Browser:SelectionStart", this);
     addMessageListener("Browser:SelectionEnd", this);
     addMessageListener("Browser:SelectionMove", this);
   },
 
   receiveMessage: function(aMessage) {
     let scrollOffset = ContentScroll.getScrollOffset(content);
     let utils = Util.getWindowUtils(content);
     let json = aMessage.json;
 
     switch (aMessage.name) {
       case "Browser:SelectionStart": {
         this.selectedText = "";
 
+        // if this is an iframe, dig down to find the document that was clicked
+        let x = json.x;
+        let y = json.y;
+        let offsetX = 0;
+        let offsetY = 0;
+        let elem = utils.elementFromPoint(x, y, true, false);
+        while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
+          // adjust client coordinates' origin to be top left of iframe viewport
+          let rect = elem.getBoundingClientRect();
+          scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView);
+