summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/html/html_slot_element.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/html/html_slot_element.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element.cc104
1 files changed, 71 insertions, 33 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/html_slot_element.cc b/chromium/third_party/blink/renderer/core/html/html_slot_element.cc
index fd8cc754219..c0d3b990d97 100644
--- a/chromium/third_party/blink/renderer/core/html/html_slot_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_slot_element.cc
@@ -72,8 +72,6 @@ HTMLSlotElement* HTMLSlotElement::CreateUserAgentCustomAssignSlot(
HTMLSlotElement::HTMLSlotElement(Document& document)
: HTMLElement(html_names::kSlotTag, document) {
UseCounter::Count(document, WebFeature::kHTMLSlotElement);
- if (!RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled())
- SetHasCustomStyleCallbacks();
}
// static
@@ -171,6 +169,21 @@ const HeapVector<Member<Element>> HTMLSlotElement::AssignedElementsForBinding(
return elements;
}
+bool HTMLSlotElement::CheckNodesValidity(HeapVector<Member<Node>> nodes,
+ ExceptionState& exception_state) {
+ auto* host = OwnerShadowHost();
+ for (auto& node : nodes) {
+ if (node->parentNode() != host) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Node: '" + node->nodeName() +
+ "' is invalid for manual slot assignment.");
+ return false;
+ }
+ }
+ return true;
+}
+
void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes,
ExceptionState& exception_state) {
if (!SupportsAssignment() || !ContainingShadowRoot()->IsManualSlotting()) {
@@ -180,24 +193,39 @@ void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes,
return;
}
- assigned_nodes_candidates_.clear();
- auto* host = OwnerShadowHost();
- bool has_invalid_node = false;
+ if (!CheckNodesValidity(nodes, exception_state))
+ return;
+
+ ContainingShadowRoot()->GetSlotAssignment().ClearCandidateNodes(
+ assigned_nodes_candidates_);
+ HeapLinkedHashSet<Member<Node>> candidates;
+ bool updated = false;
for (auto& node : nodes) {
- if (node->parentNode() != host) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotAllowedError,
- "Node: '" + node->nodeName() +
- "' is invalid for manual slot assignment.");
- assigned_nodes_candidates_.clear();
- has_invalid_node = true;
- break;
+ // Before assignment, see if this node belongs to another slot.
+ updated |= ContainingShadowRoot()
+ ->GetSlotAssignment()
+ .UpdateCandidateNodeAssignedSlot(*node, *this);
+ candidates.AppendOrMoveToLast(node);
+ }
+
+ bool candidates_changed =
+ (updated || (candidates.size() != assigned_nodes_candidates_.size()));
+ if (!candidates_changed) {
+ for (auto it1 = candidates.begin(),
+ it2 = assigned_nodes_candidates_.begin();
+ it1 != candidates.end(); ++it1, ++it2) {
+ if (!(*it1 == *it2)) {
+ candidates_changed = true;
+ break;
+ }
}
- assigned_nodes_candidates_.insert(node);
}
- if (!has_invalid_node)
+ if (candidates_changed) {
+ assigned_nodes_candidates_.Swap(candidates);
ContainingShadowRoot()->GetSlotAssignment().SetNeedsAssignmentRecalc();
+ DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
+ }
}
void HTMLSlotElement::AppendAssignedNode(Node& host_child) {
@@ -205,6 +233,34 @@ void HTMLSlotElement::AppendAssignedNode(Node& host_child) {
assigned_nodes_.push_back(&host_child);
}
+void HTMLSlotElement::UpdateManuallyAssignedNodesOrdering() {
+ if (assigned_nodes_.IsEmpty() || assigned_nodes_candidates_.IsEmpty())
+ return;
+
+ // TODO: (1067153) Add perf benchmark test for large assigned list.
+ HeapHashSet<Member<Node>> prev_nodes;
+ for (auto& node : assigned_nodes_) {
+ prev_nodes.insert(node);
+ }
+ assigned_nodes_.clear();
+ for (auto& node : assigned_nodes_candidates_) {
+ if (prev_nodes.Contains(node))
+ assigned_nodes_.push_back(node);
+ }
+}
+
+void HTMLSlotElement::RemoveAssignedNodeCandidate(Node& node) {
+ auto it = assigned_nodes_candidates_.find(&node);
+ if (it != assigned_nodes_candidates_.end()) {
+ assigned_nodes_candidates_.erase(it);
+ DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
+ }
+}
+
+void HTMLSlotElement::ClearAssignedNodesCandidates() {
+ assigned_nodes_candidates_.clear();
+}
+
void HTMLSlotElement::ClearAssignedNodes() {
assigned_nodes_.clear();
}
@@ -411,26 +467,8 @@ void HTMLSlotElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
}
-void HTMLSlotElement::DidRecalcStyle(const StyleRecalcChange change) {
- DCHECK(!RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled());
- if (!change.RecalcChildren())
- return;
- for (auto& node : assigned_nodes_) {
- if (!change.TraverseChild(*node))
- continue;
- if (auto* element = DynamicTo<Element>(node.Get()))
- element->RecalcStyle(change);
- else if (auto* text_node = DynamicTo<Text>(node.Get()))
- text_node->RecalcTextStyle(change);
- }
-}
-
void HTMLSlotElement::RecalcStyleForSlotChildren(
const StyleRecalcChange change) {
- if (!RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) {
- RecalcDescendantStyles(change);
- return;
- }
for (auto& node : flat_tree_children_) {
if (!change.TraverseChild(*node))
continue;