Skip to content

Commit

Permalink
Refactor attachShadow() in Element class to attach a shadow root from…
Browse files Browse the repository at this point in the history
… C++.

This patch refactors Element::attachShadow() and add Element::AttachShadowRootInternal()
in Element.{cpp, h} to attach shadow root from C++ codes, not only from JavaScript
codes, for the changes to add ConvertTemplatesToShadow Roots() in third_party
/WebKit/Source/core/editing/testing/SelectionSample.{cpp, h},
under reviewed in crrev.com/c/668275.
Add bool Element::CanAttachShadowRoot() and ShadowRoot* Element::
AttachShadowRootInternal() not to pass JavaScript's ExceptionState
to attach a shadow root to an element node.

Bug: 
Change-Id: Ia1eee8539c0befeb32ba34f6d9f735f5c129a6d2
Reviewed-on: https://chromium-review.googlesource.com/672083
Commit-Queue: Akari Asai <akariasai@google.com>
Reviewed-by: Hayato Ito <hayato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#503658}
  • Loading branch information
Akari Asai authored and Commit Bot committed Sep 22, 2017
1 parent 8ac701d commit eae28e1
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 25 deletions.
71 changes: 46 additions & 25 deletions third_party/WebKit/Source/core/dom/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2373,27 +2373,30 @@ ShadowRoot* Element::createShadowRoot(const ScriptState* script_state,
return CreateShadowRootInternal(ShadowRootType::V0, exception_state);
}

bool Element::CanAttachShadowRoot() const {
const AtomicString& tag_name = localName();
return IsV0CustomElement() ||
GetCustomElementState() != CustomElementState::kUncustomized ||
tag_name == HTMLNames::articleTag || tag_name == HTMLNames::asideTag ||
tag_name == HTMLNames::blockquoteTag ||
tag_name == HTMLNames::bodyTag || tag_name == HTMLNames::divTag ||
tag_name == HTMLNames::footerTag || tag_name == HTMLNames::h1Tag ||
tag_name == HTMLNames::h2Tag || tag_name == HTMLNames::h3Tag ||
tag_name == HTMLNames::h4Tag || tag_name == HTMLNames::h5Tag ||
tag_name == HTMLNames::h6Tag || tag_name == HTMLNames::headerTag ||
tag_name == HTMLNames::navTag || tag_name == HTMLNames::mainTag ||
tag_name == HTMLNames::pTag || tag_name == HTMLNames::sectionTag ||
tag_name == HTMLNames::spanTag;
}

ShadowRoot* Element::attachShadow(const ScriptState* script_state,
const ShadowRootInit& shadow_root_init_dict,
ExceptionState& exception_state) {
HostsUsingFeatures::CountMainWorldOnly(
script_state, GetDocument(),
HostsUsingFeatures::Feature::kElementAttachShadow);

const AtomicString& tag_name = localName();
bool tag_name_is_supported =
IsV0CustomElement() ||
GetCustomElementState() != CustomElementState::kUncustomized ||
tag_name == HTMLNames::articleTag || tag_name == HTMLNames::asideTag ||
tag_name == HTMLNames::blockquoteTag || tag_name == HTMLNames::bodyTag ||
tag_name == HTMLNames::divTag || tag_name == HTMLNames::footerTag ||
tag_name == HTMLNames::h1Tag || tag_name == HTMLNames::h2Tag ||
tag_name == HTMLNames::h3Tag || tag_name == HTMLNames::h4Tag ||
tag_name == HTMLNames::h5Tag || tag_name == HTMLNames::h6Tag ||
tag_name == HTMLNames::headerTag || tag_name == HTMLNames::navTag ||
tag_name == HTMLNames::mainTag || tag_name == HTMLNames::pTag ||
tag_name == HTMLNames::sectionTag || tag_name == HTMLNames::spanTag;
if (!tag_name_is_supported) {
if (!CanAttachShadowRoot()) {
exception_state.ThrowDOMException(
kNotSupportedError, "This element does not support attachShadow");
return nullptr;
Expand All @@ -2406,8 +2409,6 @@ ShadowRoot* Element::attachShadow(const ScriptState* script_state,
return nullptr;
}

GetDocument().SetShadowCascadeOrder(ShadowCascadeOrder::kShadowCascadeV1);

ShadowRootType type = ShadowRootType::V0;
if (shadow_root_init_dict.hasMode())
type = shadow_root_init_dict.mode() == "open" ? ShadowRootType::kOpen
Expand All @@ -2418,23 +2419,23 @@ ShadowRoot* Element::attachShadow(const ScriptState* script_state,
else if (type == ShadowRootType::kOpen)
UseCounter::Count(GetDocument(), WebFeature::kElementAttachShadowOpen);

ShadowRoot* shadow_root = CreateShadowRootInternal(type, exception_state);

if (shadow_root_init_dict.hasDelegatesFocus()) {
shadow_root->SetDelegatesFocus(shadow_root_init_dict.delegatesFocus());
UseCounter::Count(GetDocument(), WebFeature::kShadowRootDelegatesFocus);
if (!AreAuthorShadowsAllowed()) {
exception_state.ThrowDOMException(
kHierarchyRequestError,
"Author-created shadow roots are disabled for this element.");
return nullptr;
}

return shadow_root;
DCHECK(!shadow_root_init_dict.hasMode() || !GetShadowRoot());
bool delegateFocus = shadow_root_init_dict.hasDelegatesFocus() &&
shadow_root_init_dict.delegatesFocus();
return &AttachShadowRootInternal(type, delegateFocus);
}

ShadowRoot* Element::CreateShadowRootInternal(ShadowRootType type,
ExceptionState& exception_state) {
DCHECK(!ClosedShadowRoot());

if (AlwaysCreateUserAgentShadowRoot())
EnsureUserAgentShadowRoot();

// Some elements make assumptions about what kind of layoutObjects they allow
// as children so we can't allow author shadows on them for now.
if (!AreAuthorShadowsAllowed()) {
Expand All @@ -2444,9 +2445,29 @@ ShadowRoot* Element::CreateShadowRootInternal(ShadowRootType type,
return nullptr;
}

if (AlwaysCreateUserAgentShadowRoot())
EnsureUserAgentShadowRoot();

return &EnsureShadow().AddShadowRoot(*this, type);
}

ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type,
const bool delegate_focus) {
DCHECK(CanAttachShadowRoot());
DCHECK(AreAuthorShadowsAllowed());
DCHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed)
<< type;
DCHECK(!AlwaysCreateUserAgentShadowRoot());

GetDocument().SetShadowCascadeOrder(ShadowCascadeOrder::kShadowCascadeV1);

ShadowRoot& shadow_root = EnsureShadow().AddShadowRoot(*this, type);

shadow_root.SetDelegatesFocus(delegate_focus);

return shadow_root;
}

ShadowRoot* Element::GetShadowRoot() const {
ElementShadow* element_shadow = Shadow();
if (!element_shadow)
Expand Down
4 changes: 4 additions & 0 deletions third_party/WebKit/Source/core/dom/Element.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ class CORE_EXPORT Element : public ContainerNode {
const ShadowRootInit&,
ExceptionState&);
ShadowRoot* CreateShadowRootInternal(ShadowRootType, ExceptionState&);
ShadowRoot& AttachShadowRootInternal(ShadowRootType,
bool delegate_focus = false);

ShadowRoot* OpenShadowRoot() const;
ShadowRoot* ClosedShadowRoot() const;
Expand Down Expand Up @@ -888,6 +890,8 @@ class CORE_EXPORT Element : public ContainerNode {
bool IsDocumentNode() const =
delete; // This will catch anyone doing an unnecessary check.

bool CanAttachShadowRoot() const;

void StyleAttributeChanged(const AtomicString& new_style_string,
AttributeModificationReason);

Expand Down

0 comments on commit eae28e1

Please sign in to comment.