Commit 41f06ea8 authored by Kyoko Muto's avatar Kyoko Muto Committed by Commit Bot

Support optional parameter, |slotting|, in element.attachShadow

As the first step of implementing "Imperative Shadow DOM Distribution API",
this CL makes element.attachShadow take an optional parameter, |slotting|,
which should be 'manual' or 'auto'.

This CL also introduces new Runtime flag, ManualSlotting, to guard the new
feature.

BUG=869308

Change-Id: I71b115886c07c0090bef16b66da48c88e723a622
Reviewed-on: https://chromium-review.googlesource.com/1166767
Commit-Queue: Kyoko Muto <kymuto@google.com>
Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582524}
parent b849093f
...@@ -6,23 +6,21 @@ See https://crbug.com/869308 ...@@ -6,23 +6,21 @@ See https://crbug.com/869308
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<div id="host"> <div id="host">
<div id="child1"></div> </div>
<div id="host1">
</div> </div>
<script> <script>
const host = document.querySelector('#host'); const host = document.querySelector('#host');
const child1 = document.querySelector('#child1'); const host1 = document.querySelector('#host1');
const shadow_root = host.attachShadow({ mode: 'open', slotting: 'manual' });
const slot1 = document.createElement('slot');
shadow_root.appendChild(slot1);
test(() => { test(() => {
assert_equals(child1.assignedSlot, null); assert_not_equals(host.attachShadow({ mode: 'open', slotting: 'manual' }),
assert_array_equals(slot1.assignedElements(), []); null, 'slotting manual should work');
assert_not_equals(host1.attachShadow({ mode: 'open', slotting: 'auto' }),
slot1.assign([child1]); null, 'slotting auto should work');
assert_throws(new TypeError(), () => {
assert_equals(child1.assignedSlot, slot1); host.attachShadow({ mode: 'open', slotting: 'exceptional' })},
assert_array_equals(slot1.assignedElements(), [child1]); 'others should throw exception');
}, 'slot.assign(nodes) should work'); }, 'attachShadow can take slotting parameter');
</script> </script>
...@@ -2791,7 +2791,8 @@ ShadowRoot* Element::attachShadow(const ShadowRootInit& shadow_root_init_dict, ...@@ -2791,7 +2791,8 @@ ShadowRoot* Element::attachShadow(const ShadowRootInit& shadow_root_init_dict,
DCHECK(!shadow_root_init_dict.hasMode() || !GetShadowRoot()); DCHECK(!shadow_root_init_dict.hasMode() || !GetShadowRoot());
bool delegates_focus = shadow_root_init_dict.hasDelegatesFocus() && bool delegates_focus = shadow_root_init_dict.hasDelegatesFocus() &&
shadow_root_init_dict.delegatesFocus(); shadow_root_init_dict.delegatesFocus();
return &AttachShadowRootInternal(type, delegates_focus); bool manual_slotting = shadow_root_init_dict.slotting() == "manual";
return &AttachShadowRootInternal(type, delegates_focus, manual_slotting);
} }
ShadowRoot& Element::CreateShadowRootInternal() { ShadowRoot& Element::CreateShadowRootInternal() {
...@@ -2808,7 +2809,8 @@ ShadowRoot& Element::CreateUserAgentShadowRoot() { ...@@ -2808,7 +2809,8 @@ ShadowRoot& Element::CreateUserAgentShadowRoot() {
} }
ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type, ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type,
bool delegates_focus) { bool delegates_focus,
bool manual_slotting) {
// SVG <use> is a special case for using this API to create a closed shadow // SVG <use> is a special case for using this API to create a closed shadow
// root. // root.
DCHECK(CanAttachShadowRoot() || IsSVGUseElement(*this)); DCHECK(CanAttachShadowRoot() || IsSVGUseElement(*this));
...@@ -2819,6 +2821,8 @@ ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type, ...@@ -2819,6 +2821,8 @@ ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type,
GetDocument().SetShadowCascadeOrder(ShadowCascadeOrder::kShadowCascadeV1); GetDocument().SetShadowCascadeOrder(ShadowCascadeOrder::kShadowCascadeV1);
ShadowRoot& shadow_root = CreateAndAttachShadowRoot(type); ShadowRoot& shadow_root = CreateAndAttachShadowRoot(type);
shadow_root.SetDelegatesFocus(delegates_focus); shadow_root.SetDelegatesFocus(delegates_focus);
shadow_root.SetSlotting(manual_slotting ? ShadowRootSlotting::kManual
: ShadowRootSlotting::kAuto);
return shadow_root; return shadow_root;
} }
......
...@@ -514,7 +514,8 @@ class CORE_EXPORT Element : public ContainerNode { ...@@ -514,7 +514,8 @@ class CORE_EXPORT Element : public ContainerNode {
} }
ShadowRoot& CreateUserAgentShadowRoot(); ShadowRoot& CreateUserAgentShadowRoot();
ShadowRoot& AttachShadowRootInternal(ShadowRootType, ShadowRoot& AttachShadowRootInternal(ShadowRootType,
bool delegates_focus = false); bool delegates_focus = false,
bool manual_slotting = false);
// Returns the shadow root attached to this element if it is a shadow host. // Returns the shadow root attached to this element if it is a shadow host.
ShadowRoot* GetShadowRoot() const; ShadowRoot* GetShadowRoot() const;
......
...@@ -74,6 +74,7 @@ ShadowRoot::ShadowRoot(Document& document, ShadowRootType type) ...@@ -74,6 +74,7 @@ ShadowRoot::ShadowRoot(Document& document, ShadowRootType type)
type_(static_cast<unsigned short>(type)), type_(static_cast<unsigned short>(type)),
registered_with_parent_shadow_root_(false), registered_with_parent_shadow_root_(false),
delegates_focus_(false), delegates_focus_(false),
slotting_(static_cast<unsigned short>(ShadowRootSlotting::kAuto)),
needs_distribution_recalc_(false), needs_distribution_recalc_(false),
unused_(0) { unused_(0) {
if (IsV0()) if (IsV0())
......
...@@ -48,6 +48,8 @@ class WhitespaceAttacher; ...@@ -48,6 +48,8 @@ class WhitespaceAttacher;
enum class ShadowRootType { V0, kOpen, kClosed, kUserAgent }; enum class ShadowRootType { V0, kOpen, kClosed, kUserAgent };
enum class ShadowRootSlotting { kManual, kAuto };
class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(ShadowRoot); USING_GARBAGE_COLLECTED_MIXIN(ShadowRoot);
...@@ -156,6 +158,14 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { ...@@ -156,6 +158,14 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
void SetDelegatesFocus(bool flag) { delegates_focus_ = flag; } void SetDelegatesFocus(bool flag) { delegates_focus_ = flag; }
bool delegatesFocus() const { return delegates_focus_; } bool delegatesFocus() const { return delegates_focus_; }
void SetSlotting(ShadowRootSlotting slotting) {
slotting_ = static_cast<unsigned short>(slotting);
}
bool IsManualSlotting() {
return slotting_ ==
static_cast<unsigned short>(ShadowRootSlotting::kManual);
}
bool ContainsShadowRoots() const { return child_shadow_root_count_; } bool ContainsShadowRoots() const { return child_shadow_root_count_; }
StyleSheetList& StyleSheets(); StyleSheetList& StyleSheets();
...@@ -187,8 +197,9 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { ...@@ -187,8 +197,9 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
unsigned short type_ : 2; unsigned short type_ : 2;
unsigned short registered_with_parent_shadow_root_ : 1; unsigned short registered_with_parent_shadow_root_ : 1;
unsigned short delegates_focus_ : 1; unsigned short delegates_focus_ : 1;
unsigned short slotting_ : 1;
unsigned short needs_distribution_recalc_ : 1; unsigned short needs_distribution_recalc_ : 1;
unsigned short unused_ : 11; unsigned short unused_ : 10;
DISALLOW_COPY_AND_ASSIGN(ShadowRoot); DISALLOW_COPY_AND_ASSIGN(ShadowRoot);
}; };
......
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
// Spec: https://w3c.github.io/webcomponents/spec/shadow/#shadowrootinit-dictionary // Spec: https://w3c.github.io/webcomponents/spec/shadow/#shadowrootinit-dictionary
enum ShadowRootMode { "open", "closed" }; enum ShadowRootMode { "open", "closed" };
enum ShadowRootSlottingMode { "manual", "auto" };
dictionary ShadowRootInit { dictionary ShadowRootInit {
required ShadowRootMode mode; required ShadowRootMode mode;
boolean delegatesFocus; boolean delegatesFocus;
[RuntimeEnabled=ManualSlotting] ShadowRootSlottingMode slotting;
}; };
...@@ -652,6 +652,10 @@ ...@@ -652,6 +652,10 @@
origin_trial_feature_name: "LowLatencyCanvas", origin_trial_feature_name: "LowLatencyCanvas",
status: "experimental", status: "experimental",
}, },
{
name:"ManualSlotting",
status:"test",
},
{ {
name: "MediaCapabilities", name: "MediaCapabilities",
origin_trial_feature_name: "MediaCapabilities", origin_trial_feature_name: "MediaCapabilities",
......
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