Bug 628794. SVG and HTML/XUL .style come from different interfaces. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 07 Apr 2011 22:27:57 -0700
changeset 67659 258a0f209565896cbb47b12757544b0121ebdf1f
parent 67658 f6cb911d37da7a7968164be18da41cc64734a2b6
child 67660 bba58040498cc6042d8efbf76900ab2ea6774e81
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs628794
milestone2.2a1pre
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
Bug 628794. SVG and HTML/XUL .style come from different interfaces. r=peterv
content/base/src/nsStyledElement.cpp
content/base/src/nsStyledElement.h
content/svg/content/src/nsSVGElement.h
js/src/xpconnect/tests/mochitest/Makefile.in
js/src/xpconnect/tests/mochitest/test_bug628794.html
--- a/content/base/src/nsStyledElement.cpp
+++ b/content/base/src/nsStyledElement.cpp
@@ -58,51 +58,53 @@
 #endif
 
 namespace css = mozilla::css;
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 nsIAtom*
-nsStyledElement::GetClassAttributeName() const
+nsStyledElementNotElementCSSInlineStyle::GetClassAttributeName() const
 {
   return nsGkAtoms::_class;
 }
 
 nsIAtom*
-nsStyledElement::GetIDAttributeName() const
+nsStyledElementNotElementCSSInlineStyle::GetIDAttributeName() const
 {
   return nsGkAtoms::id;
 }
 
 nsIAtom*
-nsStyledElement::DoGetID() const
+nsStyledElementNotElementCSSInlineStyle::DoGetID() const
 {
   NS_ASSERTION(HasFlag(NODE_HAS_ID), "Unexpected call");
 
   // The nullcheck here is needed because nsGenericElement::UnsetAttr calls
   // out to various code between removing the attribute and we get a chance to
   // clear the NODE_HAS_ID flag.
 
   const nsAttrValue* attr = mAttrsAndChildren.GetAttr(nsGkAtoms::id);
 
   return attr ? attr->GetAtomValue() : nsnull;
 }
 
 const nsAttrValue*
-nsStyledElement::DoGetClasses() const
+nsStyledElementNotElementCSSInlineStyle::DoGetClasses() const
 {
   NS_ASSERTION(HasFlag(NODE_MAY_HAVE_CLASS), "Unexpected call");
   return mAttrsAndChildren.GetAttr(nsGkAtoms::_class);
 }
 
 PRBool
-nsStyledElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
-                                const nsAString& aValue, nsAttrValue& aResult)
+nsStyledElementNotElementCSSInlineStyle::ParseAttribute(PRInt32 aNamespaceID,
+                                                        nsIAtom* aAttribute,
+                                                        const nsAString& aValue,
+                                                        nsAttrValue& aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::style) {
       SetFlags(NODE_MAY_HAVE_STYLE);
       ParseStyleAttribute(aValue, aResult, PR_FALSE);
       return PR_TRUE;
     }
     if (aAttribute == nsGkAtoms::_class) {
@@ -125,46 +127,50 @@ nsStyledElement::ParseAttribute(PRInt32 
     }
   }
 
   return nsStyledElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                              aResult);
 }
 
 nsresult
-nsStyledElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
-                           PRBool aNotify)
+nsStyledElementNotElementCSSInlineStyle::UnsetAttr(PRInt32 aNameSpaceID,
+                                                   nsIAtom* aAttribute,
+                                                   PRBool aNotify)
 {
   nsAutoRemovableScriptBlocker scriptBlocker;
   if (aAttribute == nsGkAtoms::id && aNameSpaceID == kNameSpaceID_None) {
     // Have to do this before clearing flag. See RemoveFromIdTable
     RemoveFromIdTable();
   }
 
   return nsGenericElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
 }
 
 nsresult
-nsStyledElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aAttribute,
-                              const nsAString* aValue, PRBool aNotify)
+nsStyledElementNotElementCSSInlineStyle::AfterSetAttr(PRInt32 aNamespaceID,
+                                                      nsIAtom* aAttribute,
+                                                      const nsAString* aValue,
+                                                      PRBool aNotify)
 {
   if (aNamespaceID == kNameSpaceID_None && !aValue &&
       aAttribute == nsGkAtoms::id) {
     // The id has been removed when calling UnsetAttr but we kept it because
     // the id is used for some layout stuff between UnsetAttr and AfterSetAttr.
     // Now. the id is really removed so it would not be safe to keep this flag.
     UnsetFlags(NODE_HAS_ID);
   }
 
   return nsGenericElement::AfterSetAttr(aNamespaceID, aAttribute, aValue,
                                         aNotify);
 }
 
 NS_IMETHODIMP
-nsStyledElement::SetInlineStyleRule(css::StyleRule* aStyleRule, PRBool aNotify)
+nsStyledElementNotElementCSSInlineStyle::SetInlineStyleRule(css::StyleRule* aStyleRule,
+                                                            PRBool aNotify)
 {
   SetFlags(NODE_MAY_HAVE_STYLE);
   PRBool modification = PR_FALSE;
   nsAutoString oldValueStr;
 
   PRBool hasListeners = aNotify &&
     nsContentUtils::HasMutationListeners(this,
                                          NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
@@ -193,34 +199,35 @@ nsStyledElement::SetInlineStyleRule(css:
     static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION);
 
   return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nsnull,
                           oldValueStr, attrValue, modType, hasListeners,
                           aNotify, nsnull);
 }
 
 css::StyleRule*
-nsStyledElement::GetInlineStyleRule()
+nsStyledElementNotElementCSSInlineStyle::GetInlineStyleRule()
 {
   if (!HasFlag(NODE_MAY_HAVE_STYLE)) {
     return nsnull;
   }
   const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
 
   if (attrVal && attrVal->Type() == nsAttrValue::eCSSStyleRule) {
     return attrVal->GetCSSStyleRuleValue();
   }
 
   return nsnull;
 }
 
 nsresult
-nsStyledElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                            nsIContent* aBindingParent,
-                            PRBool aCompileEventHandlers)
+nsStyledElementNotElementCSSInlineStyle::BindToTree(nsIDocument* aDocument,
+                                                    nsIContent* aParent,
+                                                    nsIContent* aBindingParent,
+                                                    PRBool aCompileEventHandlers)
 {
   nsresult rv = nsStyledElementBase::BindToTree(aDocument, aParent,
                                                 aBindingParent,
                                                 aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aDocument && HasFlag(NODE_HAS_ID) && !GetBindingParent()) {
     aDocument->AddToIdTable(this, DoGetID());
@@ -231,29 +238,30 @@ nsStyledElement::BindToTree(nsIDocument*
     // anything... need to fix that.
     ReparseStyleAttribute(PR_FALSE);
   }
 
   return NS_OK;
 }
 
 void
-nsStyledElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
+nsStyledElementNotElementCSSInlineStyle::UnbindFromTree(PRBool aDeep,
+                                                        PRBool aNullParent)
 {
   RemoveFromIdTable();
 
   nsStyledElementBase::UnbindFromTree(aDeep, aNullParent);
 }
 
 
 // ---------------------------------------------------------------
 // Others and helpers
 
 nsIDOMCSSStyleDeclaration*
-nsStyledElement::GetStyle(nsresult* retval)
+nsStyledElementNotElementCSSInlineStyle::GetStyle(nsresult* retval)
 {
   nsXULElement* xulElement = nsXULElement::FromContent(this);
   if (xulElement) {
     nsresult rv = xulElement->EnsureLocalStyle();
     if (NS_FAILED(rv)) {
       *retval = rv;
       return nsnull;
     }
@@ -273,17 +281,17 @@ nsStyledElement::GetStyle(nsresult* retv
     SetFlags(NODE_MAY_HAVE_STYLE);
   }
 
   *retval = NS_OK;
   return slots->mStyle;
 }
 
 nsresult
-nsStyledElement::ReparseStyleAttribute(PRBool aForceInDataDoc)
+nsStyledElementNotElementCSSInlineStyle::ReparseStyleAttribute(PRBool aForceInDataDoc)
 {
   if (!HasFlag(NODE_MAY_HAVE_STYLE)) {
     return NS_OK;
   }
   const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
   
   if (oldVal && oldVal->Type() != nsAttrValue::eCSSStyleRule) {
     nsAttrValue attrValue;
@@ -295,19 +303,19 @@ nsStyledElement::ReparseStyleAttribute(P
     nsresult rv = mAttrsAndChildren.SetAndTakeAttr(nsGkAtoms::style, attrValue);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   
   return NS_OK;
 }
 
 void
-nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
-                                     nsAttrValue& aResult,
-                                     PRBool aForceInDataDoc)
+nsStyledElementNotElementCSSInlineStyle::ParseStyleAttribute(const nsAString& aValue,
+                                                             nsAttrValue& aResult,
+                                                             PRBool aForceInDataDoc)
 {
   nsIDocument* doc = GetOwnerDoc();
 
   if (doc && (aForceInDataDoc ||
               !doc->IsLoadedAsData() ||
               doc->IsStaticDocument())) {
     PRBool isCSS = PR_TRUE; // assume CSS until proven otherwise
 
--- a/content/base/src/nsStyledElement.h
+++ b/content/base/src/nsStyledElement.h
@@ -52,22 +52,22 @@
 namespace mozilla {
 namespace css {
 class StyleRule;
 }
 }
 
 typedef nsGenericElement nsStyledElementBase;
 
-class nsStyledElement : public nsStyledElementBase
+class nsStyledElementNotElementCSSInlineStyle : public nsStyledElementBase
 {
 
 protected:
 
-  inline nsStyledElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  inline nsStyledElementNotElementCSSInlineStyle(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsStyledElementBase(aNodeInfo)
   {}
 
 public:
 
   // nsIContent interface methods
   virtual nsIAtom* GetClassAttributeName() const;
   virtual nsIAtom* GetIDAttributeName() const;
@@ -109,9 +109,16 @@ protected:
    * Create the style struct from the style attr.  Used when an element is
    * first put into a document.  Only has an effect if the old value is a
    * string.  If aForceInDataDoc is true, will reparse even if we're in a data
    * document.
    */
   nsresult  ReparseStyleAttribute(PRBool aForceInDataDoc);
 };
 
+class nsStyledElement : public nsStyledElementNotElementCSSInlineStyle {
+protected:
+  inline nsStyledElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+    : nsStyledElementNotElementCSSInlineStyle(aNodeInfo)
+  {}
+};
+
 #endif // __NS_STYLEDELEMENT_H_
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -75,17 +75,17 @@ class SVGAnimatedNumberList;
 class SVGNumberList;
 class SVGAnimatedLengthList;
 class SVGUserUnitList;
 class SVGAnimatedPointList;
 class SVGAnimatedPathSegList;
 class SVGAnimatedPreserveAspectRatio;
 }
 
-typedef nsStyledElement nsSVGElementBase;
+typedef nsStyledElementNotElementCSSInlineStyle nsSVGElementBase;
 
 class nsSVGElement : public nsSVGElementBase,    // nsIContent
                      public nsISVGValueObserver  // :nsISupportsWeakReference
 {
 protected:
   nsSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   nsresult Init();
   virtual ~nsSVGElement();
--- a/js/src/xpconnect/tests/mochitest/Makefile.in
+++ b/js/src/xpconnect/tests/mochitest/Makefile.in
@@ -75,16 +75,17 @@ include $(topsrcdir)/config/rules.mk
 		test_frameWrapping.html \
 		test_bug585745.html \
 		test_bug589028.html \
 		test_bug628410.html \
 		bug589028_helper.html \
 		test_bug605167.html \
 		test_bug623437.html \
 		test_bug601299.html \
+		test_bug628794.html \
 		test_bug629227.html \
 		file1_bug629227.html \
 		file2_bug629227.html \
 		test_bug629331.html \
 		test1_bug629331.html \
 		test2_bug629331.html \
 		test_bug618017.html \
 		test_bug636097.html \
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/mochitest/test_bug628794.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=585745
+-->
+<head>
+  <title>Test for Bug 585745</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=585745">Mozilla Bug 585745</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 585745 **/
+
+  var a = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
+  var b = document.createElementNS("http://www.w3.org/1999/xhtml", 'span');
+  var htmlProto = Object.getPrototypeOf(b);
+  var svgProto = Object.getPrototypeOf(a);
+  // XXXbz once bug 560072 is fixed, we should be able to use
+  // getOwnPropertyDescriptor here.
+  Object.defineProperty(svgProto, "style", {
+      get: htmlProto.__lookupGetter__("style"),
+    });
+
+  var threw = false;
+  try {
+    a.style;
+  } catch(e) {
+    threw = true;
+  }
+  is(threw, true,
+     "Getting .style off an svg element should throw in this case");
+</script>
+</pre>
+</body>
+</html>