Bug 1281670 - Keep reparsing style attribute if we had parsed it once. r=bz
authorEdgar Chen <echen@mozilla.com>
Mon, 08 Aug 2016 18:29:11 +0800
changeset 350193 ff1148ab6819c4f0d8c69ceff4b40f54958923cb
parent 350192 f1cf1b0ff3086988d2bd91e1751deaf708fd3892
child 350194 f7e33d3604f581bb96229d95b89e3d135af14a30
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1281670
milestone51.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
Bug 1281670 - Keep reparsing style attribute if we had parsed it once. r=bz MozReview-Commit-ID: 4TeWC3Oepe4
dom/base/nsStyledElement.cpp
dom/base/nsStyledElement.h
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/domparsing/style_attribute_html.html
--- a/dom/base/nsStyledElement.cpp
+++ b/dom/base/nsStyledElement.cpp
@@ -149,32 +149,44 @@ nsStyledElement::ReparseStyleAttribute(b
     // want to fire off mutation events or document notifications anyway
     nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   
   return NS_OK;
 }
 
+nsICSSDeclaration*
+nsStyledElement::GetExistingStyle()
+{
+  Element::nsDOMSlots* slots = GetExistingDOMSlots();
+  if (!slots) {
+    return nullptr;
+  }
+
+  return slots->mStyle;
+}
+
 void
 nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
                                      nsAttrValue& aResult,
                                      bool aForceInDataDoc)
 {
   nsIDocument* doc = OwnerDoc();
   bool isNativeAnon = IsInNativeAnonymousSubtree();
 
   if (!isNativeAnon &&
       !nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(),
                                          doc->GetDocumentURI(), 0, aValue,
                                          nullptr))
     return;
 
   if (aForceInDataDoc ||
       !doc->IsLoadedAsData() ||
+      GetExistingStyle() ||
       doc->IsStaticDocument()) {
     bool isCSS = true; // assume CSS until proven otherwise
 
     if (!isNativeAnon) {  // native anonymous content always assumes CSS
       nsAutoString styleType;
       doc->GetHeaderData(nsGkAtoms::headerContentStyleType, styleType);
       if (!styleType.IsEmpty()) {
         static const char textCssStr[] = "text/css";
--- a/dom/base/nsStyledElement.h
+++ b/dom/base/nsStyledElement.h
@@ -52,16 +52,18 @@ public:
                                              bool aNotify) override;
 
   nsICSSDeclaration* Style();
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_STYLED_ELEMENT_IID)
 
 protected:
 
+  nsICSSDeclaration* GetExistingStyle();
+
   /**
    * Parse a style attr value into a CSS rulestruct (or, if there is no
    * document, leave it as a string) and return as nsAttrValue.
    *
    * @param aValue the value to parse
    * @param aResult the resulting HTMLValue [OUT]
    */
   void ParseStyleAttribute(const nsAString& aValue,
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -37629,16 +37629,22 @@
       },
       "testharness": {
         "css-shapes/basic-shape-circle-ellipse-serialization.html": [
           {
             "path": "css-shapes/basic-shape-circle-ellipse-serialization.html",
             "url": "/css-shapes/basic-shape-circle-ellipse-serialization.html"
           }
         ],
+        "domparsing/style_attribute_html.html": [
+          {
+            "path": "domparsing/style_attribute_html.html",
+            "url": "/domparsing/style_attribute_html.html"
+          }
+        ],
         "html/semantics/forms/the-form-element/form-submission-sandbox.html": [
           {
             "path": "html/semantics/forms/the-form-element/form-submission-sandbox.html",
             "url": "/html/semantics/forms/the-form-element/form-submission-sandbox.html"
           }
         ]
       }
     },
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/domparsing/style_attribute_html.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Style attribute in HTML</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+
+var div;
+setup(function() {
+    var input = '<div style="color: red">Foo</div>';
+    var doc = (new DOMParser()).parseFromString(input, 'text/html');
+    div = doc.querySelector('div');
+});
+
+test(function() {
+    var style = div.style;
+    assert_equals(style.cssText, 'color: red;');
+    assert_equals(style.color, 'red');
+    assert_equals(div.getAttribute("style"), 'color: red',
+                  'Value of style attribute should match the string value that was set');
+}, 'Parsing of initial style attribute');
+
+test(function() {
+    var style = div.style;
+    div.setAttribute('style', 'color:: invalid');
+    assert_equals(style.cssText, '');
+    assert_equals(style.color, '');
+    assert_equals(div.getAttribute('style'), 'color:: invalid',
+                  'Value of style attribute should match the string value that was set');
+}, 'Parsing of invalid style attribute');
+
+test(function() {
+    var style = div.style;
+    div.setAttribute('style', 'color: green');
+    assert_equals(style.cssText, 'color: green;');
+    assert_equals(style.color, 'green');
+    assert_equals(div.getAttribute('style'), 'color: green',
+                  'Value of style attribute should match the string value that was set');
+}, 'Parsing of style attribute');
+
+test(function() {
+    var style = div.style;
+    style.backgroundColor = 'blue';
+    assert_equals(style.cssText, 'color: green; background-color: blue;',
+                  'Should not drop the existing style');
+    assert_equals(style.color, 'green',
+                  'Should not drop the existing style');
+    assert_equals(div.getAttribute('style'), 'color: green; background-color: blue;',
+                  'Should update style attribute');
+}, 'Update style.backgroundColor');
+
+</script>