Bug 1378079 - Part 3: Complete the steps related to custom elements in "create an element for a token". r=hsivonen,smaug

--HG--
extra : rebase_source : c393051fc6f025ff4c013b5349b53c8a5ba2c3c4
This commit is contained in:
Jessica Jong 2017-10-26 14:55:41 +08:00
parent d70b8d543c
commit f783bf3a95
21 changed files with 285 additions and 265 deletions

View File

@ -1051,8 +1051,12 @@ CustomElementReactionsStack::PopAndInvokeElementQueue()
// element, see https://github.com/w3c/webcomponents/issues/635.
// We usually report the error to entry global in gecko, so just follow the
// same behavior here.
// This may be null if it's called from parser, see the case of
// attributeChangedCallback in
// https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token
// In that case, the exception of callback reactions will be automatically
// reported in CallSetup.
nsIGlobalObject* global = GetEntryGlobal();
MOZ_ASSERT(global, "Should always have a entry global here!");
InvokeReactions(elementQueue, global);
}

View File

@ -24,6 +24,7 @@ namespace mozilla {
namespace dom {
class Element;
class NodeInfo;
struct CustomElementDefinition;
} // namespace dom
} // namespace mozilla
@ -41,7 +42,8 @@ nsresult
NS_NewHTMLElement(mozilla::dom::Element** aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser,
const nsAString* aIs = nullptr);
const nsAString* aIs = nullptr,
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
// First argument should be nsHTMLTag, but that adds dependency to parser
// for a bunch of files.

View File

@ -251,7 +251,8 @@ DoCustomElementCreate(Element** aElement, nsIDocument* aDoc, nsAtom* aLocalName,
nsresult
NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
FromParser aFromParser, const nsAString* aIs)
FromParser aFromParser, const nsAString* aIs,
mozilla::dom::CustomElementDefinition* aDefinition)
{
*aResult = nullptr;
@ -268,8 +269,8 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
// We only handle the "synchronous custom elements flag is set" now.
// For the unset case (e.g. cloning a node), see bug 1319342 for that.
// Step 4.
CustomElementDefinition* definition = nullptr;
if (CustomElementRegistry::IsCustomElementEnabled()) {
CustomElementDefinition* definition = aDefinition;
if (!definition && CustomElementRegistry::IsCustomElementEnabled()) {
definition =
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->LocalName(),
@ -294,9 +295,20 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
bool synchronousCustomElements = aFromParser != dom::FROM_PARSER_FRAGMENT ||
aFromParser == dom::NOT_FROM_PARSER;
// Per discussion in https://github.com/w3c/webcomponents/issues/635,
// use entry global in those places that are called from JS APIs.
nsIGlobalObject* global = GetEntryGlobal();
MOZ_ASSERT(global);
// use entry global in those places that are called from JS APIs and use the
// node document's global object if it is called from parser.
nsIGlobalObject* global;
if (aFromParser == dom::NOT_FROM_PARSER) {
global = GetEntryGlobal();
} else {
global = nodeInfo->GetDocument()->GetScopeObject();
}
if (!global) {
// In browser chrome code, one may have access to a document which doesn't
// have scope object anymore.
return NS_ERROR_FAILURE;
}
AutoEntryScript aes(global, "create custom elements");
JSContext* cx = aes.cx();
ErrorResult rv;
@ -336,6 +348,7 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
// Step 6.2.
NS_IF_ADDREF(*aResult = NS_NewHTMLElement(nodeInfo.forget(), aFromParser));
(*aResult)->SetCustomElementData(new CustomElementData(definition->mType));
nsContentUtils::EnqueueUpgradeReaction(*aResult, definition);
return NS_OK;
}

View File

@ -10,6 +10,7 @@ support-files =
[test_content_element.html]
[test_custom_element_adopt_callbacks.html]
[test_custom_element_callback_innerhtml.html]
skip-if = true # disabled - See bug 1390396
[test_custom_element_clone_callbacks_extended.html]
[test_custom_element_htmlconstructor.html]
skip-if = os == 'android' # bug 1323645
@ -20,6 +21,7 @@ support-files =
[test_custom_element_in_shadow.html]
skip-if = true # disabled - See bug 1390396
[test_custom_element_register_invalid_callbacks.html]
[test_custom_element_throw_on_dynamic_markup_insertion.html]
[test_custom_element_get.html]
[test_custom_element_when_defined.html]
[test_custom_element_upgrade.html]
@ -34,7 +36,6 @@ support-files =
[test_document_adoptnode.html]
[test_document_importnode.html]
[test_document_register.html]
[test_document_register_base_queue.html]
[test_document_register_lifecycle.html]
skip-if = true # disabled - See bug 1390396
[test_document_register_parser.html]

View File

@ -0,0 +1,66 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1378079
-->
<head>
<title>Test throw on dynamic markup insertion when creating element synchronously from parser</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1378079">Bug 1378079</a>
<div id="container"></div>
<script>
class DoDocumentOpenInCtor extends HTMLElement {
constructor() {
super();
document.open();
}
};
customElements.define('x-document-open-in-ctor', DoDocumentOpenInCtor);
class DoDocumentWriteInCtor extends HTMLElement {
constructor() {
super();
document.write('<div>This should not be shown</div>');
}
};
customElements.define('x-document-write-in-ctor', DoDocumentWriteInCtor);
class DoDocumentCloseInCtor extends HTMLElement {
constructor() {
super();
document.close();
}
};
customElements.define('x-document-close-in-ctor', DoDocumentCloseInCtor);
window.errors = [];
window.onerror = function(message, url, lineNumber, columnNumber, error) {
errors.push(error.name);
return true;
}
var expectedErrorCount = 0;
document.write("<x-document-open-in-ctor></x-document-open-in-ctor>");
expectedErrorCount++;
is(window.errors.length, expectedErrorCount, "expectedErrorCount should be " + expectedErrorCount);
is(window.errors[expectedErrorCount - 1], 'InvalidStateError', "Error name should be 'InvalidStateError'");
document.write("<x-document-write-in-ctor></x-document-write-in-ctor>");
expectedErrorCount++;
is(window.errors.length, expectedErrorCount, "expectedErrorCount should be " + expectedErrorCount);
is(window.errors[expectedErrorCount - 1], 'InvalidStateError', "Error name should be 'InvalidStateError'");
document.write("<x-document-close-in-ctor></x-document-close-in-ctor>");
expectedErrorCount++;
is(window.errors.length, expectedErrorCount, "expectedErrorCount should be " + expectedErrorCount);
is(window.errors[expectedErrorCount - 1], 'InvalidStateError', "Error name should be 'InvalidStateError'");
</script>
</body>
</html>

View File

@ -1,48 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=783129
-->
<head>
<title>Test for document.registerElement lifecycle callback</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script>
var p = Object.create(HTMLElement.prototype);
var createdCallbackCallCount = 0;
// By the time the base element queue is processed via the microtask,
// both x-hello elements should be in the document.
p.createdCallback = function() {
var one = document.getElementById("one");
var two = document.getElementById("two");
isnot(one, null, "First x-hello element should be in the tree.");
isnot(two, null, "Second x-hello element should be in the tree.");
createdCallbackCallCount++;
if (createdCallbackCallCount == 2) {
SimpleTest.finish();
}
if (createdCallbackCallCount > 2) {
ok(false, "Created callback called too much.");
}
};
p.attributeChangedCallback = function(name, oldValue, newValue) {
ok(false, "Attribute changed callback should not be called because callbacks should not be queued until created callback invoked.");
};
document.registerElement("x-hello", { prototype: p });
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129">Bug 783129</a>
<x-hello id="one"></x-hello>
<x-hello id="two"></x-hello>
<script>
</script>
</body>
</html>

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783129
var extendedButtonProto = Object.create(HTMLButtonElement.prototype);
var buttonCallbackCalled = false;
extendedButtonProto.createdCallback = function() {
extendedButtonProto.connectedCallback = function() {
is(buttonCallbackCalled, false, "created callback for x-button should only be called once.");
is(this.tagName, "BUTTON", "Only the <button> element should be upgraded.");
buttonCallbackCalled = true;
@ -21,7 +21,7 @@ document.registerElement("x-button", { prototype: extendedButtonProto, extends:
var divProto = Object.create(HTMLDivElement.prototype);
var divCallbackCalled = false;
divProto.createdCallback = function() {
divProto.connectedCallback = function() {
is(divCallbackCalled, false, "created callback for x-div should only be called once.");
is(buttonCallbackCalled, true, "crated callback should be called for x-button before x-div.");
is(this.tagName, "X-DIV", "Only the <x-div> element should be upgraded.");

View File

@ -74,6 +74,29 @@ class MOZ_STACK_CLASS nsHtml5OtherDocUpdate {
nsCOMPtr<nsIDocument> mDocument;
};
/**
* Helper class to temporary break out of the document update batch. Use this
* with caution as this will cause blocked scripts to run.
*/
class MOZ_RAII mozAutoPauseContentUpdate final
{
public:
explicit mozAutoPauseContentUpdate(nsIDocument* aDocument)
: mDocument(aDocument)
{
MOZ_ASSERT(mDocument);
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
}
~mozAutoPauseContentUpdate()
{
mDocument->BeginUpdate(UPDATE_CONTENT_MODEL);
}
private:
nsCOMPtr<nsIDocument> mDocument;
};
nsHtml5TreeOperation::nsHtml5TreeOperation()
: mOpCode(eTreeOpUninitialized)
{
@ -327,6 +350,48 @@ nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
return NS_OK;
}
void
nsHtml5TreeOperation::SetHTMLElementAttributes(dom::Element* aElement,
nsAtom* aName,
nsHtml5HtmlAttributes* aAttributes)
{
int32_t len = aAttributes->getLength();
for (int32_t i = 0; i < len; i++) {
nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
nsAtom* klass = val.MaybeAsAtom();
if (klass) {
aElement->SetSingleClassFromParser(klass);
} else {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
RefPtr<nsAtom> localName =
Reget(aAttributes->getLocalNameNoBoundsCheck(i));
RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
val.ToString(value);
if (nsGkAtoms::a == aName && nsGkAtoms::name == localName) {
// This is an HTML5-incompliant Geckoism.
// Remove when fixing bug 582361
NS_ConvertUTF16toUTF8 cname(value);
NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
aElement->SetAttr(nsuri,
localName,
prefix,
uv,
false);
} else {
aElement->SetAttr(nsuri,
localName,
prefix,
value,
false);
}
}
}
}
nsIContent*
nsHtml5TreeOperation::CreateHTMLElement(
nsAtom* aName,
@ -346,109 +411,132 @@ nsHtml5TreeOperation::CreateHTMLElement(
aName, nullptr, kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE);
NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
nsCOMPtr<dom::Element> newElement = aCreator(nodeInfo.forget(), aFromParser);
dom::Element* newContent = nullptr;
nsIDocument* document = nodeInfo->GetDocument();
bool willExecuteScript = false;
bool isCustomElement = false;
nsString isValue;
dom::CustomElementDefinition* definition = nullptr;
MOZ_ASSERT(newElement, "Element creation created null pointer.");
dom::Element* newContent = newElement;
aBuilder->HoldElement(newElement.forget());
if (aCreator == NS_NewCustomElement) {
// Not inlining the call below into NS_NewCustomElement itself, because
// in the near future, the code here will need to break out of an update
// batch here.
nsContentUtils::SetupCustomElement(newContent);
}
if (MOZ_UNLIKELY(aName == nsGkAtoms::style || aName == nsGkAtoms::link)) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
ssle->InitStyleLinkElement(false);
ssle->SetEnableUpdates(false);
}
} else if (MOZ_UNLIKELY(isKeygen)) {
// Adapted from CNavDTD
nsresult rv;
nsCOMPtr<nsIFormProcessor> theFormProcessor =
do_GetService(kFormProcessorCID, &rv);
if (NS_FAILED(rv)) {
return newContent;
// Avoid overhead by checking if custom elements pref is enabled or not.
if (nsContentUtils::IsCustomElementsEnabled()) {
if (aAttributes) {
nsHtml5String is = aAttributes->getValue(nsHtml5AttributeName::ATTR_IS);
if (is) {
is.ToString(isValue);
}
}
nsTArray<nsString> theContent;
nsAutoString theAttribute;
isCustomElement = (aCreator == NS_NewCustomElement || !isValue.IsEmpty());
if (isCustomElement && aFromParser != dom::FROM_PARSER_FRAGMENT) {
definition = nsContentUtils::LookupCustomElementDefinition(document,
nodeInfo->LocalName(), nodeInfo->NamespaceID(),
(isValue.IsEmpty() ? nullptr : &isValue));
(void) theFormProcessor->ProvideContent(NS_LITERAL_STRING("select"),
theContent,
theAttribute);
newContent->SetAttr(kNameSpaceID_None,
nsGkAtoms::moztype,
nullptr,
theAttribute,
false);
RefPtr<dom::NodeInfo> optionNodeInfo = aNodeInfoManager->GetNodeInfo(
nsGkAtoms::option, nullptr, kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE);
for (uint32_t i = 0; i < theContent.Length(); ++i) {
RefPtr<dom::NodeInfo> ni = optionNodeInfo;
nsCOMPtr<dom::Element> optionElt =
NS_NewHTMLOptionElement(ni.forget(), aFromParser);
RefPtr<nsTextNode> optionText = new nsTextNode(aNodeInfoManager);
(void) optionText->SetText(theContent[i], false);
optionElt->AppendChildTo(optionText, false);
newContent->AppendChildTo(optionElt, false);
}
newContent->DoneAddingChildren(false);
}
if (!aAttributes) {
return newContent;
}
int32_t len = aAttributes->getLength();
for (int32_t i = 0; i < len; i++) {
nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
nsAtom* klass = val.MaybeAsAtom();
if (klass) {
newContent->SetSingleClassFromParser(klass);
} else {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
RefPtr<nsAtom> localName =
Reget(aAttributes->getLocalNameNoBoundsCheck(i));
RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
val.ToString(value);
if (nsGkAtoms::a == aName && nsGkAtoms::name == localName) {
// This is an HTML5-incompliant Geckoism.
// Remove when fixing bug 582361
NS_ConvertUTF16toUTF8 cname(value);
NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
newContent->SetAttr(nsuri,
localName,
prefix,
uv,
false);
} else {
newContent->SetAttr(nsuri,
localName,
prefix,
value,
false);
// Custom element setup may be needed if there is an "is" attribute.
if (nsContentUtils::IsWebComponentsEnabled() &&
kNameSpaceID_None == nsuri &&
!prefix && nsGkAtoms::is == localName) {
nsContentUtils::SetupCustomElement(newContent, &value);
}
if (definition) {
willExecuteScript = true;
}
}
}
if (willExecuteScript) { // This will cause custom element constructors to run
AutoSetThrowOnDynamicMarkupInsertionCounter
throwOnDynamicMarkupInsertionCounter(document);
mozAutoPauseContentUpdate autoPauseContentUpdate(document);
{
nsAutoMicroTask mt;
}
dom::AutoCEReaction
autoCEReaction(document->GetDocGroup()->CustomElementReactionsStack());
nsCOMPtr<dom::Element> newElement;
NS_NewHTMLElement(getter_AddRefs(newElement), nodeInfo.forget(),
aFromParser, (isValue.IsEmpty() ? nullptr : &isValue),
definition);
MOZ_ASSERT(newElement, "Element creation created null pointer.");
newContent = newElement;
aBuilder->HoldElement(newElement.forget());
if (MOZ_UNLIKELY(aName == nsGkAtoms::style || aName == nsGkAtoms::link)) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
ssle->InitStyleLinkElement(false);
ssle->SetEnableUpdates(false);
}
}
if (!aAttributes) {
return newContent;
}
SetHTMLElementAttributes(newContent, aName, aAttributes);
} else {
nsCOMPtr<dom::Element> newElement;
if (isCustomElement) {
NS_NewHTMLElement(getter_AddRefs(newElement), nodeInfo.forget(),
aFromParser, (isValue.IsEmpty() ? nullptr : &isValue),
definition);
} else {
newElement = aCreator(nodeInfo.forget(), aFromParser);
}
MOZ_ASSERT(newElement, "Element creation created null pointer.");
newContent = newElement;
aBuilder->HoldElement(newElement.forget());
if (MOZ_UNLIKELY(aName == nsGkAtoms::style || aName == nsGkAtoms::link)) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
ssle->InitStyleLinkElement(false);
ssle->SetEnableUpdates(false);
}
} else if (MOZ_UNLIKELY(isKeygen)) {
// Adapted from CNavDTD
nsresult rv;
nsCOMPtr<nsIFormProcessor> theFormProcessor =
do_GetService(kFormProcessorCID, &rv);
if (NS_FAILED(rv)) {
return newContent;
}
nsTArray<nsString> theContent;
nsAutoString theAttribute;
(void) theFormProcessor->ProvideContent(NS_LITERAL_STRING("select"),
theContent,
theAttribute);
newContent->SetAttr(kNameSpaceID_None,
nsGkAtoms::moztype,
nullptr,
theAttribute,
false);
RefPtr<dom::NodeInfo> optionNodeInfo = aNodeInfoManager->GetNodeInfo(
nsGkAtoms::option, nullptr, kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE);
for (uint32_t i = 0; i < theContent.Length(); ++i) {
RefPtr<dom::NodeInfo> ni = optionNodeInfo;
nsCOMPtr<dom::Element> optionElt =
NS_NewHTMLOptionElement(ni.forget(), aFromParser);
RefPtr<nsTextNode> optionText = new nsTextNode(aNodeInfoManager);
(void) optionText->SetText(theContent[i], false);
optionElt->AppendChildTo(optionText, false);
newContent->AppendChildTo(optionElt, false);
}
newContent->DoneAddingChildren(false);
}
if (!aAttributes) {
return newContent;
}
SetHTMLElementAttributes(newContent, aName, aAttributes);
}
return newContent;
}

View File

@ -151,6 +151,10 @@ class nsHtml5TreeOperation final {
nsHtml5HtmlAttributes* aAttributes,
nsHtml5DocumentBuilder* aBuilder);
static void SetHTMLElementAttributes(mozilla::dom::Element* aElement,
nsAtom* aName,
nsHtml5HtmlAttributes* aAttributes);
static nsIContent* CreateHTMLElement(
nsAtom* aName,
nsHtml5HtmlAttributes* aAttributes,

View File

@ -3,9 +3,6 @@
[Microtasks evaluate immediately when the stack is empty inside the parser]
expected: FAIL
[Microtasks evaluate immediately when the stack is empty inside the parser, causing the checks on no attributes to fail]
expected: FAIL
[Microtasks evaluate afterward when the stack is not empty using createElement()]
expected: FAIL

View File

@ -1,5 +0,0 @@
[parser-constructs-custom-element-synchronously.html]
type: testharness
[HTML parser must only append nodes that appear before a custom element before instantiating the custom element]
expected: FAIL

View File

@ -1,5 +0,0 @@
[parser-sets-attributes-and-children.html]
type: testharness
[HTML parser must set the attributes or append children before calling constructor]
expected: FAIL

View File

@ -1,8 +0,0 @@
[parser-uses-constructed-element.html]
type: testharness
[HTML parser must use the returned value of the custom element constructor instead of the one created before super() call]
expected: FAIL
[HTML parser must use the returned value of the custom element constructor instead using the one created in super() call]
expected: FAIL

View File

@ -6,21 +6,9 @@
[execCommand on Document must enqueue a disconnected reaction when deleting a custom element from a contenteditable element]
expected: FAIL
[body on Document must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[open on Document must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[write on Document must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[write on Document must enqueue connectedCallback after constructing a custom element]
expected: FAIL
[writeln on Document must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[writeln on Document must enqueue connectedCallback after constructing a custom element]
expected: FAIL

View File

@ -20,22 +20,3 @@
[undefined must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document]
expected: FAIL
[innerHTML on Element must enqueue a connected reaction for a newly constructed custom element]
expected: FAIL
[innerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
expected: FAIL
[outerHTML on Element must enqueue a connected reaction for a newly constructed custom element]
expected: FAIL
[outerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
expected: FAIL
[insertAdjacentHTML on Element must enqueue a connected reaction for a newly constructed custom element]
expected: FAIL
[insertAdjacentHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
expected: FAIL

View File

@ -1,5 +0,0 @@
[HTMLAnchorElement.html]
type: testharness
[text on HTMLAnchorElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL

View File

@ -1,8 +1,5 @@
[HTMLOutputElement.html]
type: testharness
[value on HTMLOutputElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[defaultValue on HTMLOutputElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL

View File

@ -1,32 +0,0 @@
[HTMLTableElement.html]
type: testharness
[caption on HTMLTableElement must enqueue connectedCallback when inserting a custom element]
expected: FAIL
[caption on HTMLTableElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[deleteCaption() on HTMLTableElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[tHead on HTMLTableElement must enqueue connectedCallback when inserting a custom element]
expected: FAIL
[tHead on HTMLTableElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[deleteTHead() on HTMLTableElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[tFoot on HTMLTableElement must enqueue connectedCallback when inserting a custom element]
expected: FAIL
[tFoot on HTMLTableElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[deleteTFoot() on HTMLTableElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[deleteRow() on HTMLTableElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL

View File

@ -1,5 +0,0 @@
[HTMLTableRowElement.html]
type: testharness
[deleteCell() on HTMLTableRowElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL

View File

@ -1,8 +0,0 @@
[HTMLTableSectionElement.html]
type: testharness
[deleteRow() on HTMLTableSectionElement on thead must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[deleteRow() on HTMLTableSectionElement on tfoot must enqueue disconnectedCallback when removing a custom element]
expected: FAIL

View File

@ -1,5 +0,0 @@
[Range.html]
type: testharness
[createContextualFragment on Range must construct a custom element]
expected: FAIL