Commit 979a7404 authored by Hayato Ito's avatar Hayato Ito Committed by Commit Bot

Reject customized built-in elements in attachShadow

Element::CanAttachShadowRoot() needs to be updated because it returns wrongly true for
customized built-in elements.

The spec: https://dom.spec.whatwg.org/#dom-element-attachshadow

Bug: 823033
Change-Id: Ia9aeb47569414830f5435f37f85d96101b9fe432
Reviewed-on: https://chromium-review.googlesource.com/970142Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Commit-Queue: Hayato Ito <hayato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545026}
parent cd755eea
<!DOCTYPE html>
<title>Shadow DOM: Attaching a ShadowRoot for custom elements</title>
<meta name="author" title="Hayato Ito" href="mailto:hayato@chromium.org">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-element-attachshadow">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
class MyAutonomousCustomElement extends HTMLElement {
}
customElements.define('my-custom', MyAutonomousCustomElement);
test(() => {
assert_true(document.createElement('my-custom').attachShadow({mode: "open"}) instanceof ShadowRoot);
}, 'Element.attachShadow must create an instance of ShadowRoot for autonomous custom elements');
class MyCustomizedBuiltinElement extends HTMLInputElement {
}
customElements.define('my-input', MyCustomizedBuiltinElement, { extends: 'input' });
test(() => {
assert_throws({'name': 'NotSupportedError'}, () => {
document.createElement('input', {is: 'my-input'}).attachShadow({mode: "open"});
});
}, 'Element.attachShadow must throw a NotSupportedError for customized built-in elements');
</script>
</body>
</html>
......@@ -2550,8 +2550,10 @@ ShadowRoot* Element::createShadowRoot(const ScriptState* script_state,
bool Element::CanAttachShadowRoot() const {
const AtomicString& tag_name = localName();
return IsV0CustomElement() ||
GetCustomElementState() != CustomElementState::kUncustomized ||
// Checking Is{V0}CustomElement() here is just an optimization
// because IsValidName is not cheap.
return (IsCustomElement() && CustomElement::IsValidName(tag_name)) ||
(IsV0CustomElement() && V0CustomElement::IsValidName(tag_name)) ||
tag_name == HTMLNames::articleTag || tag_name == HTMLNames::asideTag ||
tag_name == HTMLNames::blockquoteTag ||
tag_name == HTMLNames::bodyTag || tag_name == HTMLNames::divTag ||
......@@ -2616,7 +2618,6 @@ ShadowRoot& Element::CreateUserAgentShadowRoot() {
ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type,
bool delegates_focus) {
DCHECK(CanAttachShadowRoot());
DCHECK(AreAuthorShadowsAllowed());
DCHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed)
<< type;
DCHECK(!AlwaysCreateUserAgentShadowRoot());
......
......@@ -265,6 +265,9 @@ class CORE_EXPORT Node : public EventTarget {
return static_cast<CustomElementState>(node_flags_ &
kCustomElementStateMask);
}
bool IsCustomElement() const {
return GetCustomElementState() != CustomElementState::kUncustomized;
}
void SetCustomElementState(CustomElementState);
bool IsV0CustomElement() const { return GetFlag(kV0CustomElementFlag); }
enum V0CustomElementState {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment