Bug 1430034 - Fix attributeChangedCallback isn't fired with correct newValue when the attribute value is an empty string;
MozReview-Commit-ID: L3RvNPNDfUC
--- 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
@@ -529211,17 +529211,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>