https://github.com/web-platform-tests/wpt
Tip revision: 9b6e516d529b526e06447d171dc2937f646bbe89 authored by Bear Travis on 11 July 2014, 21:52:43 UTC
Adding basic tests for the CSS.supports API as part of the CSS Conditional Rules Module L3.
Adding basic tests for the CSS.supports API as part of the CSS Conditional Rules Module L3.
Tip revision: 9b6e516
attribute-changed-callback.html
<!DOCTYPE html>
<html>
<head>
<title>Custom Elements: attributeChangedCallback</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<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>
<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']);
instance.setAttribute('title', 'foo');
assert_equals(instance.getAttribute('title'), 'foo');
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: null, newValue: 'foo', namespace: null});
instance.removeAttribute('title');
assert_equals(instance.getAttribute('title'), null);
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: 'foo', newValue: null, namespace: null});
}, 'setAttribute and removeAttribute must enqueue and invoke attributeChangedCallback');
test(function () {
var instance = document.createElement(customElement.name);
assert_array_equals(customElement.takeLog().types(), ['constructed']);
instance.setAttributeNS('http://www.w3.org/2000/svg', 'title', 'hello');
assert_equals(instance.getAttribute('title'), 'hello');
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: null, newValue: 'hello', namespace: 'http://www.w3.org/2000/svg'});
instance.removeAttributeNS('http://www.w3.org/2000/svg', 'title');
assert_equals(instance.getAttribute('title'), null);
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: 'hello', newValue: null, namespace: 'http://www.w3.org/2000/svg'});
}, 'setAttributeNS and removeAttributeNS must enqueue and invoke attributeChangedCallback');
test(function () {
var instance = document.createElement(customElement.name);
assert_array_equals(customElement.takeLog().types(), ['constructed']);
var attr = document.createAttribute('id');
attr.value = 'bar';
instance.setAttributeNode(attr);
assert_equals(instance.getAttribute('id'), 'bar');
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'id', oldValue: null, newValue: 'bar', namespace: null});
instance.removeAttributeNode(attr);
assert_equals(instance.getAttribute('id'), null);
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'id', oldValue: 'bar', newValue: null, namespace: null});
}, 'setAttributeNode and removeAttributeNode must enqueue and invoke attributeChangedCallback for an HTML attribute');
test(function () {
const instance = document.createElement(customElement.name);
assert_array_equals(customElement.takeLog().types(), ['constructed']);
const attr = document.createAttributeNS('http://www.w3.org/2000/svg', 'r');
attr.value = '100';
instance.setAttributeNode(attr);
assert_equals(instance.getAttribute('r'), '100');
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'r', oldValue: null, newValue: '100', namespace: 'http://www.w3.org/2000/svg'});
instance.removeAttributeNode(attr);
assert_equals(instance.getAttribute('r'), null);
var logEntries = customElement.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {name: 'r', oldValue: '100', newValue: null, namespace: 'http://www.w3.org/2000/svg'});
}, 'setAttributeNode and removeAttributeNS must enqueue and invoke attributeChangedCallback for an SVG attribute');
test(function () {
const callsToOld = [];
const callsToNew = [];
class CustomElement extends HTMLElement { }
CustomElement.prototype.attributeChangedCallback = function (...args) {
callsToOld.push(create_attribute_changed_callback_log(this, ...args));
}
CustomElement.observedAttributes = ['title'];
customElements.define('element-with-mutated-attribute-changed-callback', CustomElement);
CustomElement.prototype.attributeChangedCallback = function (...args) {
callsToNew.push(create_attribute_changed_callback_log(this, ...args));
}
const instance = document.createElement('element-with-mutated-attribute-changed-callback');
instance.setAttribute('title', 'hi');
assert_equals(instance.getAttribute('title'), 'hi');
assert_array_equals(callsToNew, []);
assert_equals(callsToOld.length, 1);
assert_attribute_log_entry(callsToOld[0], {name: 'title', oldValue: null, newValue: 'hi', namespace: null});
}, 'Mutating attributeChangedCallback after calling customElements.define must not affect the callback being invoked');
test(function () {
const calls = [];
class CustomElement extends HTMLElement {
attributeChangedCallback(...args) {
calls.push(create_attribute_changed_callback_log(this, ...args));
}
}
CustomElement.observedAttributes = ['title'];
customElements.define('element-not-observing-id-attribute', CustomElement);
const instance = document.createElement('element-not-observing-id-attribute');
assert_equals(calls.length, 0);
instance.setAttribute('title', 'hi');
assert_equals(calls.length, 1);
assert_attribute_log_entry(calls[0], {name: 'title', oldValue: null, newValue: 'hi', namespace: null});
instance.setAttribute('id', 'some');
assert_equals(calls.length, 1);
assert_attribute_log_entry(calls[0], {name: 'title', oldValue: null, newValue: 'hi', namespace: null});
}, 'attributedChangedCallback must not be invoked when the observed attributes does not contain the attribute');
test(function () {
const calls = [];
class CustomElement extends HTMLElement { }
CustomElement.prototype.attributeChangedCallback = function (...args) {
calls.push(create_attribute_changed_callback_log(this, ...args));
}
CustomElement.observedAttributes = ['title', 'lang'];
customElements.define('element-with-mutated-observed-attributes', CustomElement);
CustomElement.observedAttributes = ['title', 'id'];
const instance = document.createElement('element-with-mutated-observed-attributes');
instance.setAttribute('title', 'hi');
assert_equals(calls.length, 1);
assert_attribute_log_entry(calls[0], {name: 'title', oldValue: null, newValue: 'hi', namespace: null});
instance.setAttribute('id', 'some');
assert_equals(calls.length, 1);
instance.setAttribute('lang', 'en');
assert_equals(calls.length, 2);
assert_attribute_log_entry(calls[1], {name: 'lang', oldValue: null, newValue: 'en', namespace: null});
}, 'Mutating observedAttributes after calling customElements.define must not affect the set of attributes for which attributedChangedCallback is invoked');
test(function () {
var calls = [];
class CustomElement extends HTMLElement { }
CustomElement.prototype.attributeChangedCallback = function (...args) {
calls.push(create_attribute_changed_callback_log(this, ...args));
}
CustomElement.observedAttributes = { [Symbol.iterator]: function *() { yield 'lang'; yield 'style'; } };
customElements.define('element-with-generator-observed-attributes', CustomElement);
var instance = document.createElement('element-with-generator-observed-attributes');
instance.setAttribute('lang', 'en');
assert_equals(calls.length, 1);
assert_attribute_log_entry(calls[0], {name: 'lang', oldValue: null, newValue: 'en', namespace: null});
instance.setAttribute('lang', 'ja');
assert_equals(calls.length, 2);
assert_attribute_log_entry(calls[1], {name: 'lang', oldValue: 'en', newValue: 'ja', namespace: null});
instance.setAttribute('title', 'hello');
assert_equals(calls.length, 2);
instance.setAttribute('style', 'font-size: 2rem');
assert_equals(calls.length, 3);
assert_attribute_log_entry(calls[2], {name: 'style', oldValue: null, newValue: 'font-size: 2rem', namespace: null});
}, 'attributedChangedCallback must be enqueued for attributes specified in a non-Array iterable observedAttributes');
test(function () {
var calls = [];
class CustomElement extends HTMLElement { }
CustomElement.prototype.attributeChangedCallback = function (...args) {
calls.push(create_attribute_changed_callback_log(this, ...args));
}
CustomElement.observedAttributes = ['style'];
customElements.define('element-with-style-attribute-observation', CustomElement);
var instance = document.createElement('element-with-style-attribute-observation');
assert_equals(calls.length, 0);
instance.style.fontSize = '10px';
assert_equals(calls.length, 1);
assert_attribute_log_entry(calls[0], {name: 'style', oldValue: null, newValue: 'font-size: 10px;', namespace: null});
instance.style.fontSize = '20px';
assert_equals(calls.length, 2);
assert_attribute_log_entry(calls[1], {name: 'style', oldValue: 'font-size: 10px;', newValue: 'font-size: 20px;', namespace: null});
}, 'attributedChangedCallback must be enqueued for style attribute change by mutating inline style declaration');
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('element-with-no-style-attribute-observation', CustomElement);
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');
</script>
</body>
</html>