Bug 1430034 - Fix attributeChangedCallback isn't fired with correct newValue when the attribute value is an empty string; r=smaug
authorEdgar Chen <echen@mozilla.com>
Mon, 15 Jan 2018 15:24:41 +0800
changeset 453923 ec468ee9dfc697960b74d83b6889223e9be8de95
parent 453922 d83173f047563c621d133423ec14aed04d899316
child 453924 bc54bd9b08c8dce6119d90bf437b9167d763e3d9
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1430034
milestone59.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 1430034 - Fix attributeChangedCallback isn't fired with correct newValue when the attribute value is an empty string; r=smaug MozReview-Commit-ID: L3RvNPNDfUC
dom/base/CustomElementRegistry.cpp
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/custom-elements/attribute-changed-callback.html
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -929,17 +929,17 @@ CustomElementRegistry::Upgrade(Element* 
         nsAutoString attrValue, namespaceURI;
         info.mValue->ToString(attrValue);
         nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID,
                                                             namespaceURI);
 
         LifecycleCallbackArgs args = {
           nsDependentAtomString(attrName),
           VoidString(),
-          (attrValue.IsEmpty() ? VoidString() : attrValue),
+          attrValue,
           (namespaceURI.IsEmpty() ? VoidString() : namespaceURI)
         };
         nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged,
                                                  aElement,
                                                  &args, nullptr, aDefinition);
       }
     }
   }
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -529236,17 +529236,17 @@
    "9f6553b67cad3b479d3beb678653db4e712ed227",
    "support"
   ],
   "custom-elements/adopted-callback.html": [
    "3eaf4dbfe67edd892c9a950c20a87c9b9ed565fa",
    "testharness"
   ],
   "custom-elements/attribute-changed-callback.html": [
-   "1ad26231aa638a0e0f9b76d77bdd93a3712dda98",
+   "320fb2bb26e7495d0829c39c113df3ea7ec1f4ef",
    "testharness"
   ],
   "custom-elements/connected-callbacks.html": [
    "615db12371d6f1f0ed6763abee3a84af9f87c0b2",
    "testharness"
   ],
   "custom-elements/custom-element-reaction-queue.html": [
    "68b226d776736e6044f842c440b42606b63c7175",
--- a/testing/web-platform/tests/custom-elements/attribute-changed-callback.html
+++ b/testing/web-platform/tests/custom-elements/attribute-changed-callback.html
@@ -6,16 +6,17 @@
 <meta name="assert" content="attributeChangedCallback must be enqueued whenever custom element's attribute is added, changed or removed">
 <link rel="help" href="https://w3c.github.io/webcomponents/spec/custom/#dfn-attribute-changed-callback">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="resources/custom-elements-helpers.js"></script>
 </head>
 <body>
 <div id="log"></div>
+<parser-created-element title></parser-created-element>
 <script>
 
 var customElement = define_new_custom_element(['title', 'id', 'r']);
 
 test(function () {
     const instance = document.createElement(customElement.name);
     assert_array_equals(customElement.takeLog().types(), ['constructed']);
 
@@ -213,11 +214,41 @@ test(function () {
     var instance = document.createElement('element-with-no-style-attribute-observation');
     assert_equals(calls.length, 0);
     instance.style.fontSize = '10px';
     assert_equals(calls.length, 0);
     instance.title = 'hello';
     assert_attribute_log_entry(calls[0], {name: 'title', oldValue: null, newValue: 'hello', namespace: null});
 }, 'attributedChangedCallback must not be enqueued when mutating inline style declaration if the style attribute is not observed');
 
+test(function () {
+    var calls = [];
+    class CustomElement extends HTMLElement { }
+    CustomElement.prototype.attributeChangedCallback = function (...args) {
+        calls.push(create_attribute_changed_callback_log(this, ...args));
+    }
+    CustomElement.observedAttributes = ['title'];
+    customElements.define('parser-created-element', CustomElement);
+    assert_attribute_log_entry(calls[0], {name: 'title', oldValue: null, newValue: '', namespace: null});
+}, 'Upgrading a parser created element must enqueue and invoke attributeChangedCallback for an HTML attribute');
+
+test(function () {
+    var calls = [];
+    class CustomElement extends HTMLElement { }
+    CustomElement.prototype.attributeChangedCallback = function (...args) {
+        calls.push(create_attribute_changed_callback_log(this, ...args));
+    }
+    CustomElement.observedAttributes = ['title'];
+    customElements.define('cloned-element-with-attribute', CustomElement);
+
+    var instance = document.createElement('cloned-element-with-attribute');
+    assert_equals(calls.length, 0);
+    instance.title = '';
+    assert_attribute_log_entry(calls[0], {name: 'title', oldValue: null, newValue: '', namespace: null});
+
+    calls = [];
+    var clone = instance.cloneNode(false);
+    assert_attribute_log_entry(calls[0], {name: 'title', oldValue: null, newValue: '', namespace: null});
+}, 'Upgrading a cloned element must enqueue and invoke attributeChangedCallback for an HTML attribute');
+
 </script>
 </body>
 </html>