Bug 1419662 - Fix incorrect custom element type in CustomElementData. f=echen, r=smaug

This commit is contained in:
John Dai 2018-01-07 18:45:00 +02:00
Родитель acbc94ee21
Коммит d480d5e221
8 изменённых файлов: 121 добавлений и 7 удалений

Просмотреть файл

@ -4402,6 +4402,15 @@ Element::SetCustomElementData(CustomElementData* aData)
{
nsExtendedDOMSlots *slots = ExtendedDOMSlots();
MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set.");
#if DEBUG
nsAtom* name = NodeInfo()->NameAtom();
nsAtom* type = aData->GetCustomElementType();
if (nsContentUtils::IsCustomElementName(name)) {
MOZ_ASSERT(type == name);
} else {
MOZ_ASSERT(type != name);
}
#endif
slots->mCustomElementData = aData;
}

Просмотреть файл

@ -9989,9 +9989,6 @@ nsContentUtils::NewXULOrHTMLElement(Element** aResult, mozilla::dom::NodeInfo* a
"Can only create XUL or XHTML elements.");
nsAtom *name = nodeInfo->NameAtom();
RefPtr<nsAtom> tagAtom = nodeInfo->NameAtom();
RefPtr<nsAtom> typeAtom = aIs ? NS_Atomize(*aIs) : tagAtom;
int32_t tag = eHTMLTag_unknown;
bool isCustomElementName = false;
if (nodeInfo->NamespaceEquals(kNameSpaceID_XHTML)) {
@ -10001,7 +9998,14 @@ nsContentUtils::NewXULOrHTMLElement(Element** aResult, mozilla::dom::NodeInfo* a
} else {
isCustomElementName = nsContentUtils::IsCustomElementName(name);
}
RefPtr<nsAtom> tagAtom = nodeInfo->NameAtom();
RefPtr<nsAtom> typeAtom;
bool isCustomElement = isCustomElementName || aIs;
if (isCustomElement) {
typeAtom = isCustomElementName ? tagAtom : NS_Atomize(*aIs);
}
MOZ_ASSERT_IF(aDefinition, isCustomElement);
// https://dom.spec.whatwg.org/#concept-create-element

Просмотреть файл

@ -504,7 +504,13 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
cloneElem->GetAttr(kNameSpaceID_None, nsGkAtoms::is, extension);
}
if (data || !extension.IsEmpty()) {
if ((data && data->GetCustomElementType() == tagAtom) ||
!extension.IsEmpty()) {
// The typeAtom can be determined by extension, because we only need to
// consider two cases: 1) Original node is a autonomous custom element
// which has CustomElementData. 2) Original node is a built-in custom
// element or normal element, but it has `is` attribute when it is being
// cloned.
RefPtr<nsAtom> typeAtom = extension.IsEmpty() ? tagAtom : NS_Atomize(extension);
cloneElem->SetCustomElementData(new CustomElementData(typeAtom));
CustomElementDefinition* definition =

Просмотреть файл

@ -409,7 +409,7 @@ nsHtml5TreeOperation::CreateHTMLElement(
if (isCustomElement && aFromParser != dom::FROM_PARSER_FRAGMENT) {
RefPtr<nsAtom> tagAtom = nodeInfo->NameAtom();
RefPtr<nsAtom> typeAtom =
isValue.IsEmpty() ? tagAtom : NS_Atomize(isValue);
(aCreator == NS_NewCustomElement) ? tagAtom : NS_Atomize(isValue);
definition = nsContentUtils::LookupCustomElementDefinition(document,
nodeInfo->LocalName(), nodeInfo->NamespaceID(), typeAtom);

Просмотреть файл

@ -305751,6 +305751,12 @@
{}
]
],
"custom-elements/parser/parser-constructs-custom-elements-with-is.html": [
[
"/custom-elements/parser/parser-constructs-custom-elements-with-is.html",
{}
]
],
"custom-elements/parser/parser-constructs-custom-elements.html": [
[
"/custom-elements/parser/parser-constructs-custom-elements.html",
@ -523823,7 +523829,7 @@
"testharness"
],
"custom-elements/Document-createElement.html": [
"074c9f703cc7feb1dfc3d07aedd08460bd591d42",
"fb10e851deb193aed700c8ab6790c216766cc362",
"testharness"
],
"custom-elements/HTMLElement-constructor.html": [
@ -523882,6 +523888,10 @@
"dc0ca4a066d9a05362a81b263594965763919e46",
"testharness"
],
"custom-elements/parser/parser-constructs-custom-elements-with-is.html": [
"7a7df7aab092906b5a753c0d122b971aff01517a",
"testharness"
],
"custom-elements/parser/parser-constructs-custom-elements.html": [
"228d4a90d57dc942692becc6f126ec9130b3a4e0",
"testharness"
@ -524027,7 +524037,7 @@
"testharness"
],
"custom-elements/upgrading/Node-cloneNode.html": [
"cc121ea56de1b8e1074062b5dda69f57e2add665",
"264a2631a79370bce8392657ba52c8b0c949b7e1",
"testharness"
],
"custom-elements/upgrading/upgrading-enqueue-reactions.html": [

Просмотреть файл

@ -29,6 +29,21 @@ test(function () {
}, 'document.createElement must create an instance of custom elements');
test(function () {
class AutonomousCustomElement extends HTMLElement {};
class IsCustomElement extends HTMLElement {};
customElements.define('autonomous-custom-element', AutonomousCustomElement);
customElements.define('is-custom-element', IsCustomElement);
var instance = document.createElement('autonomous-custom-element', { is: "is-custom-element"});
assert_true(instance instanceof AutonomousCustomElement);
assert_equals(instance.localName, 'autonomous-custom-element');
assert_equals(instance.namespaceURI, 'http://www.w3.org/1999/xhtml', 'A custom element HTML must use HTML namespace');
}, 'document.createElement must create an instance of autonomous custom elements when it has is attribute');
function assert_reports(expected, testFunction, message) {
var uncaughtError = null;
window.onerror = function (message, url, lineNumber, columnNumber, error) { uncaughtError = error; return true; }

Просмотреть файл

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>Custom Elements: Changes to the HTML parser</title>
<meta name="author" title="John Dai" href="mailto:jdai@mozilla.com">
<meta name="assert" content="HTML parser creates a custom element which contains is attribute">
<link rel="help" href="https://html.spec.whatwg.org/#create-an-element-for-the-token">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<autonomous-custom-element id="instance1" is="is-custom-element"></autonomous-custom-element>
<script>
class AutonomousCustomElement extends HTMLElement { };
class IsCustomElement extends HTMLElement { };
customElements.define('autonomous-custom-element', AutonomousCustomElement);
customElements.define('is-custom-element', IsCustomElement);
test(function () {
var customElement = document.getElementById('instance1');
assert_true(customElement instanceof HTMLElement, 'A resolved custom element must be an instance of HTMLElement');
assert_false(customElement instanceof HTMLUnknownElement, 'A resolved custom element must NOT be an instance of HTMLUnknownElement');
assert_true(customElement instanceof AutonomousCustomElement, 'A resolved custom element must be an instance of that custom element');
assert_equals(customElement.localName, 'autonomous-custom-element');
assert_equals(customElement.namespaceURI, 'http://www.w3.org/1999/xhtml', 'A custom element HTML must use HTML namespace');
}, 'HTML parser must create a defined autonomous custom element when customElements.define comes after HTML parser creation');
</script>
<autonomous-custom-element id="instance2" is="is-custom-element"></autonomous-custom-element>
<script>
test(function () {
var customElement = document.getElementById('instance2');
assert_true(customElement instanceof HTMLElement, 'A resolved custom element must be an instance of HTMLElement');
assert_false(customElement instanceof HTMLUnknownElement, 'A resolved custom element must NOT be an instance of HTMLUnknownElement');
assert_true(customElement instanceof AutonomousCustomElement, 'A resolved custom element must be an instance of that custom element');
assert_equals(customElement.localName, 'autonomous-custom-element');
assert_equals(customElement.namespaceURI, 'http://www.w3.org/1999/xhtml', 'A custom element HTML must use HTML namespace');
}, 'HTML parser must create a defined autonomous custom element when customElements.define comes before HTML parser creation');
</script>
</body>
</html>

Просмотреть файл

@ -30,6 +30,25 @@ test(function () {
'A cloned custom element must be an instance of the custom element');
}, 'Node.prototype.cloneNode(false) must be able to clone a custom element');
test(function () {
class AutonomousCustomElement extends HTMLElement {};
class IsCustomElement extends HTMLElement {};
customElements.define('autonomous-custom-element', AutonomousCustomElement);
customElements.define('is-custom-element', IsCustomElement);
var instance = document.createElement('autonomous-custom-element', { is: "is-custom-element"});
assert_true(instance instanceof HTMLElement);
assert_true(instance instanceof AutonomousCustomElement);
var clone = instance.cloneNode(false);
assert_not_equals(instance, clone);
assert_true(clone instanceof HTMLElement,
'A cloned custom element must be an instance of HTMLElement');
assert_true(clone instanceof AutonomousCustomElement,
'A cloned custom element must be an instance of the custom element');
}, 'Node.prototype.cloneNode(false) must be able to clone as a autonomous custom element when it contains is attribute');
test_with_window(function (contentWindow) {
var contentDocument = contentWindow.document;
class MyCustomElement extends contentWindow.HTMLElement {}