Backout 6ceeca8b4b73 (bug 772332), ce5629b973e4, 1dcff1db63b4, 108d06ef7755 & 7bf6519b3f43 (bug 768756) for bustage
authorEd Morley <emorley@mozilla.com>
Sun, 15 Jul 2012 11:42:31 +0100
changeset 104157 670ad979c4945da2fff70d4312673d7ad0092ae1
parent 104156 7f90b559d0acf105f396ab48db10b0d84197e31c
child 104158 1fdfd85870b9ccef03bca922c9a2ba63feed42ec
push id1316
push userakeybl@mozilla.com
push dateMon, 27 Aug 2012 22:37:00 +0000
treeherdermozilla-beta@db4b09302ee2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs772332, 768756
milestone16.0a1
backs out6ceeca8b4b73beb91dfd868adb98a34ca6ef414c
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
Backout 6ceeca8b4b73 (bug 772332), ce5629b973e4, 1dcff1db63b4, 108d06ef7755 & 7bf6519b3f43 (bug 768756) for bustage
content/smil/nsSMILCSSProperty.cpp
dom/base/nsGlobalWindow.cpp
editor/libeditor/html/Makefile.in
editor/libeditor/html/nsHTMLAbsPosition.cpp
editor/libeditor/html/nsHTMLAnonymousUtils.cpp
editor/libeditor/html/nsHTMLCSSUtils.cpp
editor/libeditor/html/nsHTMLCSSUtils.h
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditorStyle.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
--- a/content/smil/nsSMILCSSProperty.cpp
+++ b/content/smil/nsSMILCSSProperty.cpp
@@ -12,17 +12,17 @@
 #include "nsStyleAnimation.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDOMElement.h"
 
 using namespace mozilla::dom;
 
 // Helper function
 static bool
-GetCSSComputedValue(Element* aElem,
+GetCSSComputedValue(nsIContent* aElem,
                     nsCSSProperty aPropID,
                     nsAString& aResult)
 {
   NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(aPropID),
                     "Can't look up computed value of shorthand property");
   NS_ABORT_IF_FALSE(nsSMILCSSProperty::IsPropertyAnimatable(aPropID),
                     "Shouldn't get here for non-animatable properties");
 
@@ -35,21 +35,26 @@ GetCSSComputedValue(Element* aElem,
   }
 
   nsIPresShell* shell = doc->GetShell();
   if (!shell) {
     NS_WARNING("Unable to look up computed style -- no pres shell");
     return false;
   }
 
-  nsRefPtr<nsComputedDOMStyle> computedStyle =
-    NS_NewComputedDOMStyle(aElem, EmptyString(), shell);
+  nsRefPtr<nsComputedDOMStyle> computedStyle;
+  nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(aElem));
+  nsresult rv = NS_NewComputedDOMStyle(domElement, EmptyString(), shell,
+                                       getter_AddRefs(computedStyle));
 
-  computedStyle->GetPropertyValue(aPropID, aResult);
-  return true;
+  if (NS_SUCCEEDED(rv)) {
+    computedStyle->GetPropertyValue(aPropID, aResult);
+    return true;
+  }
+  return false;
 }
 
 // Class Methods
 nsSMILCSSProperty::nsSMILCSSProperty(nsCSSProperty aPropID,
                                      Element* aElement)
   : mPropID(aPropID), mElement(aElement)
 {
   NS_ABORT_IF_FALSE(IsPropertyAnimatable(mPropID),
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8165,20 +8165,20 @@ nsGlobalWindow::GetComputedStyle(nsIDOME
 
   nsCOMPtr<nsIPresShell> presShell;
   mDocShell->GetPresShell(getter_AddRefs(presShell));
 
   if (!presShell) {
     return NS_OK;
   }
 
-  nsCOMPtr<dom::Element> element = do_QueryInterface(aElt);
-  NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
-  nsRefPtr<nsComputedDOMStyle> compStyle =
-    NS_NewComputedDOMStyle(element, aPseudoElt, presShell);
+  nsRefPtr<nsComputedDOMStyle> compStyle;
+  nsresult rv = NS_NewComputedDOMStyle(aElt, aPseudoElt, presShell,
+                                       getter_AddRefs(compStyle));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   *aReturn = compStyle.forget().get();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
--- a/editor/libeditor/html/Makefile.in
+++ b/editor/libeditor/html/Makefile.in
@@ -43,21 +43,18 @@ CPPSRCS  = \
 ifdef ENABLE_EDITOR_API_LOG
 CPPSRCS += nsHTMLEditorLog.cpp             \
            nsEditorTxnLog.cpp              \
            $(NULL)
 
 DEFINES += -DENABLE_EDITOR_API_LOG
 endif
 
-DEFINES += -D_IMPL_NS_LAYOUT
-
 # don't want the shared lib; force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES        += -I$(topsrcdir)/editor/libeditor/base \
                    -I$(topsrcdir)/editor/libeditor/text \
                    -I$(topsrcdir)/editor/txmgr/src \
                    -I$(topsrcdir)/content/base/src \
-                   -I$(topsrcdir)/layout/style \
                    $(NULL)
--- a/editor/libeditor/html/nsHTMLAbsPosition.cpp
+++ b/editor/libeditor/html/nsHTMLAbsPosition.cpp
@@ -7,17 +7,16 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/Selection.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
 #include "nsAlgorithm.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
-#include "nsComputedDOMStyle.h"
 #include "nsDebug.h"
 #include "nsEditProperty.h"
 #include "nsEditRules.h"
 #include "nsEditor.h"
 #include "nsEditorUtils.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLCSSUtils.h"
@@ -652,19 +651,23 @@ nsHTMLEditor::CheckPositionedElementBGan
   if (bgImageStr.EqualsLiteral("none")) {
     nsAutoString bgColorStr;
     res =
       mHTMLCSSUtils->GetComputedProperty(aElement,
                                          nsEditProperty::cssBackgroundColor,
                                          bgColorStr);
     NS_ENSURE_SUCCESS(res, res);
     if (bgColorStr.EqualsLiteral("transparent")) {
-      nsRefPtr<nsComputedDOMStyle> cssDecl =
-        mHTMLCSSUtils->GetComputedStyle(aElement);
-      NS_ENSURE_STATE(cssDecl);
+      nsCOMPtr<nsIDOMWindow> window;
+      res = mHTMLCSSUtils->GetDefaultViewCSS(aElement, getter_AddRefs(window));
+      NS_ENSURE_SUCCESS(res, res);
+
+      nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
+      res = window->GetComputedStyle(aElement, EmptyString(), getter_AddRefs(cssDecl));
+      NS_ENSURE_SUCCESS(res, res);
 
       // from these declarations, get the one we want and that one only
       nsCOMPtr<nsIDOMCSSValue> colorCssValue;
       res = cssDecl->GetPropertyCSSValue(NS_LITERAL_STRING("color"), getter_AddRefs(colorCssValue));
       NS_ENSURE_SUCCESS(res, res);
 
       PRUint16 type;
       res = colorCssValue->GetCssValueType(&type);
--- a/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
+++ b/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
-#include "nsComputedDOMStyle.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsEditProperty.h"
 #include "nsError.h"
 #include "nsHTMLCSSUtils.h"
 #include "nsHTMLEditor.h"
 #include "nsIAtom.h"
 #include "nsIContent.h"
@@ -416,20 +415,24 @@ nsHTMLEditor::GetPositionAndDimensions(n
                                        positionStr);
     isPositioned = positionStr.EqualsLiteral("absolute");
   }
 
   if (isPositioned) {
     // Yes, it is absolutely positioned
     mResizedObjectIsAbsolutelyPositioned = true;
 
+    nsCOMPtr<nsIDOMWindow> window;
+    res = mHTMLCSSUtils->GetDefaultViewCSS(aElement, getter_AddRefs(window));
+    NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
+
+    nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
     // Get the all the computed css styles attached to the element node
-    nsRefPtr<nsComputedDOMStyle> cssDecl =
-      mHTMLCSSUtils->GetComputedStyle(aElement);
-    NS_ENSURE_STATE(cssDecl);
+    res = window->GetComputedStyle(aElement, EmptyString(), getter_AddRefs(cssDecl));
+    NS_ENSURE_SUCCESS(res, res);
 
     aBorderLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-left-width"));
     aBorderTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-top-width"));
     aMarginLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-left"));
     aMarginTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-top"));
 
     aX = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("left")) +
          aMarginLeft + aBorderLeft;
--- a/editor/libeditor/html/nsHTMLCSSUtils.cpp
+++ b/editor/libeditor/html/nsHTMLCSSUtils.cpp
@@ -2,25 +2,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ChangeCSSInlineStyleTxn.h"
 #include "EditTxn.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/css/Declaration.h"
-#include "mozilla/css/StyleRule.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsColor.h"
-#include "nsComputedDOMStyle.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsDependentSubstring.h"
 #include "nsEditProperty.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLCSSUtils.h"
 #include "nsHTMLEditor.h"
@@ -568,95 +565,104 @@ nsHTMLCSSUtils::CreateCSSPropertyTxn(nsI
   NS_ADDREF(*aTxn);
   return (*aTxn)->Init(mHTMLEditor, aElement, aAttribute, aValue, aRemoveProperty);
 }
 
 nsresult
 nsHTMLCSSUtils::GetSpecifiedProperty(nsIDOMNode *aNode, nsIAtom *aProperty,
                                      nsAString & aValue)
 {
-  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, eSpecified);
+  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, nsnull, SPECIFIED_STYLE_TYPE);
 }
 
 nsresult
 nsHTMLCSSUtils::GetComputedProperty(nsIDOMNode *aNode, nsIAtom *aProperty,
                                     nsAString & aValue)
 {
-  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, eComputed);
-}
+  nsCOMPtr<nsIDOMWindow> window;
+  nsresult res = GetDefaultViewCSS(aNode, getter_AddRefs(window));
+  NS_ENSURE_SUCCESS(res, res);
 
-nsresult
-nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsIDOMNode* aNode, nsIAtom* aProperty,
-                                         nsAString& aValue,
-                                         StyleType aStyleType)
-{
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  return GetCSSInlinePropertyBase(node, aProperty, aValue, aStyleType);
+  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, window, COMPUTED_STYLE_TYPE);
 }
 
 nsresult
 nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsINode* aNode, nsIAtom* aProperty,
                                          nsAString& aValue,
-                                         StyleType aStyleType)
+                                         nsIDOMWindow* aWindow,
+                                         PRUint8 aStyleType)
 {
-  MOZ_ASSERT(aNode && aProperty);
+  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
+  return GetCSSInlinePropertyBase(node, aProperty, aValue, aWindow, aStyleType);
+}
+
+nsresult
+nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsIDOMNode *aNode, nsIAtom *aProperty,
+                                         nsAString& aValue,
+                                         nsIDOMWindow* aWindow,
+                                         PRUint8 aStyleType)
+{
   aValue.Truncate();
+  NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER);
 
-  nsCOMPtr<dom::Element> element = GetElementContainerOrSelf(aNode);
+  nsCOMPtr<nsIDOMElement> element = GetElementContainerOrSelf(aNode);
   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
 
-  if (aStyleType == eComputed) {
-    // Get the all the computed css styles attached to the element node
-    nsRefPtr<nsComputedDOMStyle> cssDecl = GetComputedStyle(element);
-    NS_ENSURE_STATE(cssDecl);
-
-    // from these declarations, get the one we want and that one only
-    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
-      cssDecl->GetPropertyValue(nsDependentAtomString(aProperty), aValue)));
-
-    return NS_OK;
+  switch (aStyleType) {
+    case COMPUTED_STYLE_TYPE:
+      if (element && aWindow) {
+        nsAutoString value, propString;
+        nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
+        aProperty->ToString(propString);
+        // Get the all the computed css styles attached to the element node
+        nsresult res = aWindow->GetComputedStyle(element, EmptyString(), getter_AddRefs(cssDecl));
+        if (NS_FAILED(res) || !cssDecl)
+          return res;
+        // from these declarations, get the one we want and that one only
+        res = cssDecl->GetPropertyValue(propString, value);
+        NS_ENSURE_SUCCESS(res, res);
+        aValue.Assign(value);
+      }
+      break;
+    case SPECIFIED_STYLE_TYPE:
+      if (element) {
+        nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
+        PRUint32 length;
+        nsresult res = GetInlineStyles(element, getter_AddRefs(cssDecl), &length);
+        if (NS_FAILED(res) || !cssDecl) return res;
+        nsAutoString value, propString;
+        aProperty->ToString(propString);
+        res = cssDecl->GetPropertyValue(propString, value);
+        NS_ENSURE_SUCCESS(res, res);
+        aValue.Assign(value);
+      }
+      break;
   }
-
-  MOZ_ASSERT(aStyleType == eSpecified);
-  nsRefPtr<css::StyleRule> rule = element->GetInlineStyleRule();
-  if (!rule) {
-    return NS_OK;
-  }
-  nsCSSProperty prop =
-    nsCSSProps::LookupProperty(nsDependentAtomString(aProperty));
-  MOZ_ASSERT(prop != eCSSProperty_UNKNOWN);
-  rule->GetDeclaration()->GetValue(prop, aValue);
-
   return NS_OK;
 }
 
-already_AddRefed<nsComputedDOMStyle>
-nsHTMLCSSUtils::GetComputedStyle(nsIDOMElement* aElement)
+nsresult
+nsHTMLCSSUtils::GetDefaultViewCSS(nsIDOMNode *aNode, nsIDOMWindow **aViewCSS)
 {
-  nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
-  return GetComputedStyle(element);
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
+  return GetDefaultViewCSS(node, aViewCSS);
 }
 
-already_AddRefed<nsComputedDOMStyle>
-nsHTMLCSSUtils::GetComputedStyle(dom::Element* aElement)
+nsresult
+nsHTMLCSSUtils::GetDefaultViewCSS(nsINode* aNode, nsIDOMWindow** aViewCSS)
 {
-  MOZ_ASSERT(aElement);
-
-  nsIDocument* doc = aElement->GetCurrentDoc();
-  NS_ASSERTION(doc, "Trying to compute style of detached element");
-  NS_ENSURE_TRUE(doc, nsnull);
+  MOZ_ASSERT(aNode);
+  dom::Element* element = GetElementContainerOrSelf(aNode);
+  NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
 
-  nsIPresShell* presShell = doc->GetShell();
-  NS_ASSERTION(presShell, "Trying to compute style without PresShell");
-  NS_ENSURE_TRUE(presShell, nsnull);
-
-  nsRefPtr<nsComputedDOMStyle> style =
-    NS_NewComputedDOMStyle(aElement, EmptyString(), presShell);
-
-  return style.forget();
+  nsCOMPtr<nsIDOMWindow> window = element->OwnerDoc()->GetWindow();
+  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
+  window.forget(aViewCSS);
+  return NS_OK;
 }
 
 // remove the CSS style "aProperty : aPropertyValue" and possibly remove the whole node
 // if it is a span and if its only attribute is _moz_dirty
 nsresult
 nsHTMLCSSUtils::RemoveCSSInlineStyle(nsIDOMNode *aNode, nsIAtom *aProperty, const nsAString & aPropertyValue)
 {
   nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(aNode);
@@ -1055,40 +1061,46 @@ nsHTMLCSSUtils::RemoveCSSEquivalentToHTM
 // the HTML style aHTMLProperty/aAttribute/aValueString for the node aNode;
 // the value of aStyleType controls the styles we retrieve : specified or
 // computed.
 nsresult
 nsHTMLCSSUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                      nsIAtom *aHTMLProperty,
                                                      const nsAString *aAttribute,
                                                      nsAString & aValueString,
-                                                     StyleType aStyleType)
+                                                     PRUint8 aStyleType)
 {
   aValueString.Truncate();
   nsCOMPtr<dom::Element> theElement = GetElementContainerOrSelf(aNode);
   NS_ENSURE_TRUE(theElement, NS_ERROR_NULL_POINTER);
 
   if (!theElement || !IsCSSEditableProperty(theElement, aHTMLProperty,
                                             aAttribute, &aValueString)) {
     return NS_OK;
   }
 
   // Yes, the requested HTML style has a CSS equivalence in this implementation
+  // Retrieve the default ViewCSS if we are asked for computed styles
+  nsCOMPtr<nsIDOMWindow> window;
+  if (COMPUTED_STYLE_TYPE == aStyleType) {
+    nsresult res = GetDefaultViewCSS(theElement, getter_AddRefs(window));
+    NS_ENSURE_SUCCESS(res, res);
+  }
   nsTArray<nsIAtom*> cssPropertyArray;
   nsTArray<nsString> cssValueArray;
   // get the CSS equivalence with last param true indicating we want only the
   // "gettable" properties
   GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute, nsnull,
                                        cssPropertyArray, cssValueArray, true);
   PRInt32 count = cssPropertyArray.Length();
   for (PRInt32 index = 0; index < count; index++) {
     nsAutoString valueString;
     // retrieve the specified/computed value of the property
     nsresult res = GetCSSInlinePropertyBase(theElement, cssPropertyArray[index],
-                                            valueString, aStyleType);
+                                            valueString, window, aStyleType);
     NS_ENSURE_SUCCESS(res, res);
     // append the value to aValueString (possibly with a leading whitespace)
     if (index) {
       aValueString.Append(PRUnichar(' '));
     }
     aValueString.Append(valueString);
   }
   return NS_OK;
@@ -1101,36 +1113,38 @@ nsHTMLCSSUtils::GetCSSEquivalentToHTMLIn
 //
 // The nsIContent variant returns aIsSet instead of using an out parameter, and
 // does not modify aValue.
 bool
 nsHTMLCSSUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIContent* aContent,
                                                     nsIAtom* aProperty,
                                                     const nsAString* aAttribute,
                                                     const nsAString& aValue,
-                                                    StyleType aStyleType)
+                                                    PRUint8 aStyleType)
 {
   MOZ_ASSERT(aContent && aProperty);
+  MOZ_ASSERT(aStyleType == SPECIFIED_STYLE_TYPE ||
+             aStyleType == COMPUTED_STYLE_TYPE);
   bool isSet;
   nsAutoString value(aValue);
   nsresult res = IsCSSEquivalentToHTMLInlineStyleSet(aContent->AsDOMNode(),
                                                      aProperty, aAttribute,
                                                      isSet, value, aStyleType);
   NS_ASSERTION(NS_SUCCEEDED(res), "IsCSSEquivalentToHTMLInlineStyleSet failed");
   NS_ENSURE_SUCCESS(res, false);
   return isSet;
 }
 
 nsresult
 nsHTMLCSSUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode *aNode,
                                                     nsIAtom *aHTMLProperty,
                                                     const nsAString *aHTMLAttribute,
                                                     bool& aIsSet,
                                                     nsAString& valueString,
-                                                    StyleType aStyleType)
+                                                    PRUint8 aStyleType)
 {
   NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
 
   nsAutoString htmlValueString(valueString);
   aIsSet = false;
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   do {
     valueString.Assign(htmlValueString);
--- a/editor/libeditor/html/nsHTMLCSSUtils.h
+++ b/editor/libeditor/html/nsHTMLCSSUtils.h
@@ -7,30 +7,32 @@
 #define nsHTMLCSSUtils_h__
 
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsTArray.h"                   // for nsTArray
 #include "nscore.h"                     // for nsAString, nsresult, nsnull
 #include "prtypes.h"                    // for PRUint8, PRInt32, PRUint32
 
 class ChangeCSSInlineStyleTxn;
-class nsComputedDOMStyle;
 class nsIAtom;
 class nsIContent;
 class nsIDOMCSSStyleDeclaration;
 class nsIDOMElement;
 class nsIDOMNode;
 class nsINode;
 class nsString;
 namespace mozilla {
 namespace dom {
 class Element;
 }  // namespace dom
 }  // namespace mozilla
 
+#define SPECIFIED_STYLE_TYPE    1
+#define COMPUTED_STYLE_TYPE     2
+
 class nsHTMLEditor;
 class nsIDOMWindow;
 
 typedef void (*nsProcessValueFunc)(const nsAString * aInputString, nsAString & aOutputString,
                                    const char * aDefaultValueString,
                                    const char * aPrependString, const char* aAppendString);
 
 class nsHTMLCSSUtils
@@ -57,18 +59,16 @@ public:
     eCSSEditableProperty_margin_right,
     eCSSEditableProperty_text_align,
     eCSSEditableProperty_text_decoration,
     eCSSEditableProperty_vertical_align,
     eCSSEditableProperty_whitespace,
     eCSSEditableProperty_width
   };
 
-  enum StyleType { eSpecified, eComputed };
-
 
   struct CSSEquivTable {
     nsCSSEditableProperty cssProperty;
     nsProcessValueFunc processValueFunctor;
     const char * defaultValue;
     const char * prependValue;
     const char * appendValue;
     bool gettable;
@@ -171,48 +171,50 @@ public:
 
   /** returns the list of values for the CSS equivalences to
     * the passed HTML style for the passed node
     *
     * @param aNode          [IN] a DOM node
     * @param aHTMLProperty  [IN] an atom containing an HTML property
     * @param aAttribute     [IN] a pointer to an attribute name or nsnull if irrelevant
     * @param aValueString   [OUT] the list of css values
-    * @param aStyleType     [IN] eSpecified or eComputed
+    * @param aStyleType     [IN] SPECIFIED_STYLE_TYPE to query the specified style values
+                                 COMPUTED_STYLE_TYPE  to query the computed style values
     */
   nsresult    GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                    nsIAtom * aHTMLProperty,
                                                    const nsAString * aAttribute,
                                                    nsAString & aValueString,
-                                                   StyleType aStyleType);
+                                                   PRUint8 aStyleType);
 
   /** Does the node aNode (or his parent if it is not an element node) carries
     * the CSS equivalent styles to the HTML style for this node ?
     *
     * @param aNode          [IN] a DOM node
     * @param aHTMLProperty  [IN] an atom containing an HTML property
     * @param aAttribute     [IN] a pointer to an attribute name or nsnull if irrelevant
     * @param aIsSet         [OUT] a boolean being true if the css properties are set
     * @param aValueString   [IN/OUT] the attribute value (in) the list of css values (out)
-    * @param aStyleType     [IN] eSpecified or eComputed
+    * @param aStyleType     [IN] SPECIFIED_STYLE_TYPE to query the specified style values
+    *                            COMPUTED_STYLE_TYPE  to query the computed style values
     *
     * The nsIContent variant returns aIsSet instead of using an out parameter.
     */
   bool IsCSSEquivalentToHTMLInlineStyleSet(nsIContent* aContent,
                                            nsIAtom* aProperty,
                                            const nsAString* aAttribute,
                                            const nsAString& aValue,
-                                           StyleType aStyleType);
+                                           PRUint8 aStyleType);
 
   nsresult    IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode * aNode,
                                                   nsIAtom * aHTMLProperty,
                                                   const nsAString * aAttribute,
                                                   bool & aIsSet,
                                                   nsAString & aValueString,
-                                                  StyleType aStyleType);
+                                                  PRUint8 aStyleType);
 
   /** Adds to the node the CSS inline styles equivalent to the HTML style
     * and return the number of CSS properties set by the call
     *
     * @param aNode          [IN] a DOM node
     * @param aHTMLProperty  [IN] an atom containing an HTML property
     * @param aAttribute     [IN] a pointer to an attribute name or nsnull if irrelevant
     * @param aValue         [IN] the attribute value
@@ -300,22 +302,23 @@ public:
     *
     * @param aNode           [IN] a node
     * @param aElement        [OUT] the deepest element node containing aNode (possibly aNode itself)
     */
   mozilla::dom::Element* GetElementContainerOrSelf(nsINode* aNode);
   already_AddRefed<nsIDOMElement> GetElementContainerOrSelf(nsIDOMNode* aNode);
 
   /**
-   * Gets the computed style for a given element.  Can return null.
+   * Gets the default Window for a given node.
+   *
+   * @param aNode    the node we want the default Window for
+   * @param aWindow  [OUT] the default Window
    */
-  already_AddRefed<nsComputedDOMStyle>
-    GetComputedStyle(nsIDOMElement* aElement);
-  already_AddRefed<nsComputedDOMStyle>
-    GetComputedStyle(mozilla::dom::Element* aElement);
+  nsresult GetDefaultViewCSS(nsINode* aNode, nsIDOMWindow** aWindow);
+  nsresult GetDefaultViewCSS(nsIDOMNode* aNode, nsIDOMWindow** aWindow);
 
 
 private:
 
   /** retrieves the css property atom from an enum
     *
     * @param aProperty          [IN] the enum value for the property
     * @param aAtom              [OUT] the corresponding atom
@@ -375,22 +378,26 @@ private:
                                    ChangeCSSInlineStyleTxn ** aTxn,
                                    bool aRemoveProperty);
 
   /** back-end for GetSpecifiedProperty and GetComputedProperty
    *
    * @param aNode               [IN] a DOM node
    * @param aProperty           [IN] a CSS property
    * @param aValue              [OUT] the retrieved value for this property
-   * @param aStyleType          [IN] eSpecified or eComputed
+   * @param aWindow             [IN] the window we need in case we query computed styles
+   * @param aStyleType          [IN] SPECIFIED_STYLE_TYPE to query the specified style values
+   *                                 COMPUTED_STYLE_TYPE  to query the computed style values
    */
   nsresult GetCSSInlinePropertyBase(nsINode* aNode, nsIAtom* aProperty,
-                                    nsAString& aValue, StyleType aStyleType);
+                                    nsAString& aValue, nsIDOMWindow* aWindow,
+                                    PRUint8 aStyleType);
   nsresult GetCSSInlinePropertyBase(nsIDOMNode* aNode, nsIAtom* aProperty,
-                                    nsAString& aValue, StyleType aStyleType);
+                                    nsAString& aValue, nsIDOMWindow* aWindow,
+                                    PRUint8 aStyleType);
 
 
 private:
   nsHTMLEditor            *mHTMLEditor;
   bool                    mIsCSSPrefChecked; 
 };
 
 #define NS_EDITOR_INDENT_INCREMENT_IN        0.4134f
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -831,17 +831,17 @@ nsHTMLEditRules::GetAlignment(bool *aMix
     if (blockParentContent && 
         mHTMLEditor->mHTMLCSSUtils->IsCSSEditableProperty(blockParentContent, dummyProperty, &typeAttrName))
     {
       // we are in CSS mode and we know how to align this element with CSS
       nsAutoString value;
       // let's get the value(s) of text-align or margin-left/margin-right
       mHTMLEditor->mHTMLCSSUtils->GetCSSEquivalentToHTMLInlineStyleSet(
         blockParentContent, dummyProperty, &typeAttrName, value,
-        nsHTMLCSSUtils::eComputed);
+        COMPUTED_STYLE_TYPE);
       if (value.EqualsLiteral("center") ||
           value.EqualsLiteral("-moz-center") ||
           value.EqualsLiteral("auto auto"))
       {
         *aAlign = nsIHTMLEditor::eCenter;
         return NS_OK;
       }
       if (value.EqualsLiteral("right") ||
@@ -2829,18 +2829,20 @@ nsresult
 nsHTMLEditRules::DeleteNonTableElements(nsINode* aNode)
 {
   MOZ_ASSERT(aNode);
   if (!aNode->IsElement() ||
       !nsHTMLEditUtils::IsTableElementButNotTable(aNode->AsElement())) {
     return mHTMLEditor->DeleteNode(aNode->AsDOMNode());
   }
 
-  for (PRInt32 i = aNode->GetChildCount() - 1; i >= 0; --i) {
-    nsresult rv = DeleteNonTableElements(aNode->GetChildAt(i));
+  for (nsCOMPtr<nsIContent> child = aNode->GetLastChild();
+       child;
+       child = child->GetPreviousSibling()) {
+    nsresult rv = DeleteNonTableElements(child);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return NS_OK;
 }
 
 nsresult
 nsHTMLEditRules::DidDeleteSelection(nsISelection *aSelection, 
                                     nsIEditor::EDirection aDir, 
@@ -7159,19 +7161,18 @@ nsHTMLEditRules::CacheInlineStyles(nsIDO
     if (!useCSS)
     {
       mHTMLEditor->IsTextPropertySetByContent(aNode, mCachedStyles[j].tag,
                                               &(mCachedStyles[j].attr), nsnull,
                                               isSet, &outValue);
     }
     else
     {
-      mHTMLEditor->mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(aNode,
-        mCachedStyles[j].tag, &(mCachedStyles[j].attr), isSet, outValue,
-        nsHTMLCSSUtils::eComputed);
+      mHTMLEditor->mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(aNode, mCachedStyles[j].tag, &(mCachedStyles[j].attr),
+                                                    isSet, outValue, COMPUTED_STYLE_TYPE);
     }
     if (isSet)
     {
       mCachedStyles[j].mPresent = true;
       mCachedStyles[j].value.Assign(outValue);
     }
   }
   return NS_OK;
@@ -7207,17 +7208,17 @@ nsHTMLEditRules::ReapplyCachedStyles()
       bool bFirst, bAny, bAll;
       bFirst = bAny = bAll = false;
 
       nsAutoString curValue;
       if (useCSS) {
         // check computed style first in css case
         bAny = mHTMLEditor->mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(
           selNode, mCachedStyles[i].tag, &(mCachedStyles[i].attr), curValue,
-          nsHTMLCSSUtils::eComputed);
+          COMPUTED_STYLE_TYPE);
       }
       if (!bAny) {
         // then check typeinstate and html style
         nsresult res = mHTMLEditor->GetInlinePropertyBase(mCachedStyles[i].tag,
                                                      &(mCachedStyles[i].attr),
                                                      &(mCachedStyles[i].value),
                                                      &bFirst, &bAny, &bAll,
                                                      &curValue, false);
--- a/editor/libeditor/html/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp
@@ -352,17 +352,17 @@ nsHTMLEditor::SetInlinePropertyOnTextNod
   bool bHasProp;
   if (mHTMLCSSUtils->IsCSSEditableProperty(node, aProperty,
                                            aAttribute, aValue)) {
     // the HTML styles defined by aProperty/aAttribute has a CSS equivalence
     // in this implementation for node; let's check if it carries those css styles
     nsAutoString value(*aValue);
     mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, aAttribute,
                                                        bHasProp, value,
-                                                       nsHTMLCSSUtils::eComputed);
+                                                       COMPUTED_STYLE_TYPE);
   } else {
     IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, bHasProp);
   }
 
   if (bHasProp) return NS_OK;
   
   // do we need to split the text node?
   PRUint32 textLen;
@@ -458,17 +458,17 @@ nsHTMLEditor::SetInlinePropertyOnNodeImp
     NS_ENSURE_SUCCESS(res, res);
     return NS_OK;
   }
 
   // don't need to do anything if property already set on node
   if (mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty,
                                            aAttribute, aValue)) {
     if (mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(
-          aNode, aProperty, aAttribute, *aValue, nsHTMLCSSUtils::eComputed)) {
+          aNode, aProperty, aAttribute, *aValue, COMPUTED_STYLE_TYPE)) {
       return NS_OK;
     }
   } else if (IsTextPropertySetByContent(aNode, aProperty,
                                         aAttribute, aValue)) {
     return NS_OK;
   }
 
   bool useCSS = (IsCSSEnabled() &&
@@ -644,18 +644,19 @@ nsresult nsHTMLEditor::SplitStyleAbovePo
   bool isSet;
   while (tmp && !IsBlockNode(tmp))
   {
     isSet = false;
     if (useCSS && mHTMLCSSUtils->IsCSSEditableProperty(tmp, aProperty, aAttribute)) {
       // the HTML style defined by aProperty/aAttribute has a CSS equivalence
       // in this implementation for the node tmp; let's check if it carries those css styles
       nsAutoString firstValue;
-      mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(tmp, aProperty,
-        aAttribute, isSet, firstValue, nsHTMLCSSUtils::eSpecified);
+      mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(tmp, aProperty, aAttribute,
+                                                         isSet, firstValue,
+                                                         SPECIFIED_STYLE_TYPE);
     }
     if ( (aProperty && NodeIsType(tmp, aProperty)) ||   // node is the correct inline prop
          (aProperty == nsEditProperty::href && nsHTMLEditUtils::IsLink(tmp)) ||
                                                         // node is href - test if really <a href=...
          (!aProperty && NodeIsProperty(tmp)) ||         // or node is any prop, and we asked to split them all
          isSet)                                         // or the style is specified in the style attribute
     {
       // found a style node we need to split
@@ -855,18 +856,19 @@ nsresult nsHTMLEditor::RemoveStyleInside
 
   if (!aChildrenOnly &&
       mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty, aAttribute)) {
     // the HTML style defined by aProperty/aAttribute has a CSS equivalence in
     // this implementation for the node aNode; let's check if it carries those
     // css styles
     nsAutoString propertyValue;
     bool isSet;
-    mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(aNode, aProperty,
-      aAttribute, isSet, propertyValue, nsHTMLCSSUtils::eSpecified);
+    mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(aNode, aProperty, aAttribute,
+                                                       isSet, propertyValue,
+                                                       SPECIFIED_STYLE_TYPE);
     if (isSet) {
       // yes, tmp has the corresponding css declarations in its style attribute
       // let's remove them
       mHTMLCSSUtils->RemoveCSSEquivalentToHTMLStyle(aNode,
                                                     aProperty,
                                                     aAttribute,
                                                     &propertyValue,
                                                     false);
@@ -1146,17 +1148,17 @@ nsHTMLEditor::GetInlinePropertyBase(nsIA
 
       // Bug 747889: we don't support CSS for fontSize values
       if ((aProperty != nsEditProperty::font ||
            !aAttribute->EqualsLiteral("size")) &&
           mHTMLCSSUtils->IsCSSEditableProperty(collapsedNode, aProperty,
                                                aAttribute)) {
         mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(
           collapsedNode, aProperty, aAttribute, isSet, tOutString,
-          nsHTMLCSSUtils::eComputed);
+          COMPUTED_STYLE_TYPE);
         if (outValue) {
           outValue->Assign(tOutString);
         }
         *aFirst = *aAny = *aAll = isSet;
         return NS_OK;
       }
 
       IsTextPropertySetByContent(collapsedNode, aProperty, aAttribute, aValue,
@@ -1238,18 +1240,19 @@ nsHTMLEditor::GetInlinePropertyBase(nsIA
             (aProperty != nsEditProperty::font ||
              !aAttribute->EqualsLiteral("size"))) {
           // the HTML styles defined by aProperty/aAttribute has a CSS
           // equivalence in this implementation for node; let's check if it
           // carries those css styles
           if (aValue) {
             firstValue.Assign(*aValue);
           }
-          mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty,
-            aAttribute, isSet, firstValue, nsHTMLCSSUtils::eComputed);
+          mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, aAttribute,
+                                                             isSet, firstValue,
+                                                             COMPUTED_STYLE_TYPE);
         } else {
           IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, isSet,
                                      &firstValue);
         }
         *aFirst = isSet;
         first = false;
         if (outValue) {
           *outValue = firstValue;
@@ -1260,18 +1263,19 @@ nsHTMLEditor::GetInlinePropertyBase(nsIA
             // Bug 747889: we don't support CSS for fontSize values
             (aProperty != nsEditProperty::font ||
              !aAttribute->EqualsLiteral("size"))) {
           // the HTML styles defined by aProperty/aAttribute has a CSS equivalence
           // in this implementation for node; let's check if it carries those css styles
           if (aValue) {
             theValue.Assign(*aValue);
           }
-          mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty,
-            aAttribute, isSet, theValue, nsHTMLCSSUtils::eComputed);
+          mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, aAttribute,
+                                                             isSet, theValue,
+                                                             COMPUTED_STYLE_TYPE);
         } else {
           IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, isSet,
                                      &theValue);
         }
         if (firstValue != theValue) {
           *aAll = false;
         }
       }
@@ -1426,18 +1430,21 @@ nsresult nsHTMLEditor::RemoveInlinePrope
       {
         // we're done with this range!
         if (useCSS && mHTMLCSSUtils->IsCSSEditableProperty(startNode, aProperty, aAttribute)) {
           // the HTML style defined by aProperty/aAttribute has a CSS equivalence
           // in this implementation for startNode
           nsAutoString cssValue;
           bool isSet = false;
           mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(startNode,
-            aProperty, aAttribute, isSet , cssValue,
-            nsHTMLCSSUtils::eComputed);
+                                                    aProperty,
+                                                    aAttribute,
+                                                    isSet ,
+                                                    cssValue,
+                                                    COMPUTED_STYLE_TYPE);
           if (isSet) {
             // startNode's computed style indicates the CSS equivalence to the HTML style to
             // remove is applied; but we found no element in the ancestors of startNode
             // carrying specified styles; assume it comes from a rule and let's try to
             // insert a span "inverting" the style
             nsAutoString value; value.AssignLiteral("-moz-editor-invert-value");
             PRInt32 startOffset, endOffset;
             range->GetStartOffset(&startOffset);
@@ -1483,18 +1490,22 @@ nsresult nsHTMLEditor::RemoveInlinePrope
           node = arrayOfNodes[j];
           res = RemoveStyleInside(node, aProperty, aAttribute);
           NS_ENSURE_SUCCESS(res, res);
           if (useCSS && mHTMLCSSUtils->IsCSSEditableProperty(node, aProperty, aAttribute)) {
             // the HTML style defined by aProperty/aAttribute has a CSS equivalence
             // in this implementation for node
             nsAutoString cssValue;
             bool isSet = false;
-            mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty,
-              aAttribute, isSet , cssValue, nsHTMLCSSUtils::eComputed);
+            mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node,
+                                                               aProperty,
+                                                               aAttribute,
+                                                               isSet ,
+                                                               cssValue,
+                                                               COMPUTED_STYLE_TYPE);
             if (isSet) {
               // startNode's computed style indicates the CSS equivalence to the HTML style to
               // remove is applied; but we found no element in the ancestors of startNode
               // carrying specified styles; assume it comes from a rule and let's try to
               // insert a span "inverting" the style
               if (mHTMLCSSUtils->IsCSSInvertable(aProperty, aAttribute)) {
                 nsAutoString value; value.AssignLiteral("-moz-editor-invert-value");
                 SetInlinePropertyOnNode(node, aProperty, aAttribute, &value);
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -55,87 +55,59 @@ using namespace mozilla::dom;
 
 /*
  * This is the implementation of the readonly CSSStyleDeclaration that is
  * returned by the getComputedStyle() function.
  */
 
 static nsComputedDOMStyle *sCachedComputedDOMStyle;
 
-already_AddRefed<nsComputedDOMStyle>
-NS_NewComputedDOMStyle(dom::Element* aElement, const nsAString& aPseudoElt,
-                       nsIPresShell* aPresShell)
+nsresult
+NS_NewComputedDOMStyle(nsIDOMElement *aElement, const nsAString &aPseudoElt,
+                       nsIPresShell *aPresShell,
+                       nsComputedDOMStyle **aComputedStyle)
 {
   nsRefPtr<nsComputedDOMStyle> computedStyle;
   if (sCachedComputedDOMStyle) {
     // There's an unused nsComputedDOMStyle cached, use it.
     // But before we use it, re-initialize the object.
 
     // Oh yeah baby, placement new!
-    computedStyle = new (sCachedComputedDOMStyle)
-      nsComputedDOMStyle(aElement, aPseudoElt, aPresShell);
+    computedStyle = new (sCachedComputedDOMStyle) nsComputedDOMStyle();
 
     sCachedComputedDOMStyle = nsnull;
   } else {
     // No nsComputedDOMStyle cached, create a new one.
 
-    computedStyle = new nsComputedDOMStyle(aElement, aPseudoElt, aPresShell);
+    computedStyle = new nsComputedDOMStyle();
+    NS_ENSURE_TRUE(computedStyle, NS_ERROR_OUT_OF_MEMORY);
   }
 
-  return computedStyle.forget();
+  nsresult rv = computedStyle->Init(aElement, aPseudoElt, aPresShell);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aComputedStyle = nsnull;
+  computedStyle.swap(*aComputedStyle);
+
+  return NS_OK;
 }
 
 static nsIFrame*
 GetContainingBlockFor(nsIFrame* aFrame) {
   if (!aFrame) {
     return nsnull;
   }
   return aFrame->GetContainingBlock();
 }
 
-nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
-                                       const nsAString& aPseudoElt,
-                                       nsIPresShell* aPresShell)
+nsComputedDOMStyle::nsComputedDOMStyle()
   : mDocumentWeak(nsnull), mOuterFrame(nsnull),
     mInnerFrame(nsnull), mPresShell(nsnull),
     mExposeVisitedStyle(false)
 {
-  MOZ_ASSERT(aElement && aPresShell);
-
-  mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument());
-
-  mContent = aElement;
-
-  if (!DOMStringIsNull(aPseudoElt) && !aPseudoElt.IsEmpty() &&
-      aPseudoElt.First() == PRUnichar(':')) {
-    // deal with two-colon forms of aPseudoElt
-    nsAString::const_iterator start, end;
-    aPseudoElt.BeginReading(start);
-    aPseudoElt.EndReading(end);
-    NS_ASSERTION(start != end, "aPseudoElt is not empty!");
-    ++start;
-    bool haveTwoColons = true;
-    if (start == end || *start != PRUnichar(':')) {
-      --start;
-      haveTwoColons = false;
-    }
-    mPseudo = do_GetAtom(Substring(start, end));
-    MOZ_ASSERT(mPseudo);
-
-    // There aren't any non-CSS2 pseudo-elements with a single ':'
-    if (!haveTwoColons &&
-        !nsCSSPseudoElements::IsCSS2PseudoElement(mPseudo)) {
-      // XXXbz I'd really rather we threw an exception or something, but
-      // the DOM spec sucks.
-      mPseudo = nsnull;
-    }
-  }
-
-  nsPresContext *presCtx = aPresShell->GetPresContext();
-  MOZ_ASSERT(presCtx);
 }
 
 
 nsComputedDOMStyle::~nsComputedDOMStyle()
 {
 }
 
 void
@@ -192,16 +164,64 @@ static void doDestroyComputedDOMStyle(ns
 }
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsComputedDOMStyle)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsComputedDOMStyle,
                                               doDestroyComputedDOMStyle(this))
 
 
 NS_IMETHODIMP
+nsComputedDOMStyle::Init(nsIDOMElement *aElement,
+                         const nsAString& aPseudoElt,
+                         nsIPresShell *aPresShell)
+{
+  NS_ENSURE_ARG_POINTER(aElement);
+  NS_ENSURE_ARG_POINTER(aPresShell);
+
+  mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument());
+
+  mContent = do_QueryInterface(aElement);
+  if (!mContent) {
+    // This should not happen, all our elements support nsIContent!
+
+    return NS_ERROR_FAILURE;
+  }
+
+  if (!DOMStringIsNull(aPseudoElt) && !aPseudoElt.IsEmpty() &&
+      aPseudoElt.First() == PRUnichar(':')) {
+    // deal with two-colon forms of aPseudoElt
+    nsAString::const_iterator start, end;
+    aPseudoElt.BeginReading(start);
+    aPseudoElt.EndReading(end);
+    NS_ASSERTION(start != end, "aPseudoElt is not empty!");
+    ++start;
+    bool haveTwoColons = true;
+    if (start == end || *start != PRUnichar(':')) {
+      --start;
+      haveTwoColons = false;
+    }
+    mPseudo = do_GetAtom(Substring(start, end));
+    NS_ENSURE_TRUE(mPseudo, NS_ERROR_OUT_OF_MEMORY);
+
+    // There aren't any non-CSS2 pseudo-elements with a single ':'
+    if (!haveTwoColons &&
+        !nsCSSPseudoElements::IsCSS2PseudoElement(mPseudo)) {
+      // XXXbz I'd really rather we threw an exception or something, but
+      // the DOM spec sucks.
+      mPseudo = nsnull;
+    }
+  }
+
+  nsPresContext *presCtx = aPresShell->GetPresContext();
+  NS_ENSURE_TRUE(presCtx, NS_ERROR_FAILURE);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsComputedDOMStyle::GetPropertyValue(const nsCSSProperty aPropID,
                                      nsAString& aValue)
 {
   // This is mostly to avoid code duplication with GetPropertyCSSValue(); if
   // perf ever becomes an issue here (doubtful), we can look into changing
   // this.
   return GetPropertyValue(
     NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(aPropID)),
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -27,23 +27,25 @@ class nsIPresShell;
 class nsComputedDOMStyle : public nsDOMCSSDeclaration,
                            public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(nsComputedDOMStyle,
                                                      nsICSSDeclaration)
 
+  NS_IMETHOD Init(nsIDOMElement *aElement,
+                  const nsAString& aPseudoElt,
+                  nsIPresShell *aPresShell);
+
   NS_DECL_NSICSSDECLARATION
 
   NS_DECL_NSIDOMCSSSTYLEDECLARATION
 
-  nsComputedDOMStyle(mozilla::dom::Element* aElement,
-                     const nsAString& aPseudoElt,
-                     nsIPresShell* aPresShell);
+  nsComputedDOMStyle();
   virtual ~nsComputedDOMStyle();
 
   static void Shutdown();
 
   virtual nsINode *GetParentObject()
   {
     return mContent;
   }
@@ -504,15 +506,15 @@ private:
 
   bool mExposeVisitedStyle;
 
 #ifdef DEBUG
   bool mFlushedPendingReflows;
 #endif
 };
 
-already_AddRefed<nsComputedDOMStyle>
-NS_NewComputedDOMStyle(mozilla::dom::Element* aElement,
-                       const nsAString& aPseudoElt,
-                       nsIPresShell* aPresShell);
+nsresult
+NS_NewComputedDOMStyle(nsIDOMElement *aElement, const nsAString &aPseudoElt,
+                       nsIPresShell *aPresShell,
+                       nsComputedDOMStyle **aComputedStyle);
 
 #endif /* nsComputedDOMStyle_h__ */