Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Unified Diff: third_party/WebKit/Source/core/dom/Node.cpp

Issue 1995203002: Rewrite Shadow DOM distribution engine to support partial synchronous distribution for v1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: wip Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/dom/Node.cpp
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 73143b892f56a21e1bd5d665860c73b5ea0cb673..eb25bc26bb7ab97696bf6668c498f3a86b80bb59 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -59,6 +59,7 @@
#include "core/dom/shadow/FlatTreeTraversal.h"
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/dom/shadow/SlotAssignment.h"
#include "core/editing/EditingUtilities.h"
#include "core/editing/markers/DocumentMarkerController.h"
#include "core/events/Event.h"
@@ -700,11 +701,6 @@ void Node::markAncestorsWithChildNeedsStyleInvalidation()
void Node::markAncestorsWithChildNeedsDistributionRecalc()
{
ScriptForbiddenScope forbidScriptDuringRawIteration;
- if (RuntimeEnabledFeatures::shadowDOMV1Enabled() && inShadowIncludingDocument() && !document().childNeedsDistributionRecalc()) {
- // TODO(hayato): Support a non-document composed tree.
- // TODO(hayato): Enqueue a task only if a 'slotchange' event listner is registered in the document composed tree.
- Microtask::enqueueMicrotask(WTF::bind(&Document::updateDistribution, &document()));
- }
for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
node->setChildNeedsDistributionRecalc();
document().scheduleLayoutTreeUpdateIfNeeded();
@@ -994,19 +990,13 @@ bool Node::isSlotOrActiveInsertionPoint() const
AtomicString Node::slotName() const
{
- DCHECK(slottable());
+ DCHECK(isSlotable());
if (isElementNode())
- return normalizeSlotName(toElement(*this).fastGetAttribute(HTMLNames::slotAttr));
+ return HTMLSlotElement::normalizeSlotName(toElement(*this).fastGetAttribute(HTMLNames::slotAttr));
DCHECK(isTextNode());
return emptyAtom;
}
-// static
-AtomicString Node::normalizeSlotName(const AtomicString& name)
-{
- return (name.isNull() || name.isEmpty()) ? emptyAtom : name;
-}
-
bool Node::isInV1ShadowTree() const
{
ShadowRoot* shadowRoot = containingShadowRoot();
@@ -1037,6 +1027,13 @@ bool Node::isChildOfV0ShadowHost() const
return parentShadow && !parentShadow->isV1();
}
+ShadowRoot* Node::v1ShadowRootOfParent() const
+{
+ if (Element* parent = parentElement())
+ return parent->shadowRootIfV1();
+ return nullptr;
+}
+
Element* Node::shadowHost() const
{
if (ShadowRoot* root = containingShadowRoot())
@@ -2247,20 +2244,18 @@ StaticNodeList* Node::getDestinationInsertionPoints()
HTMLSlotElement* Node::assignedSlot() const
{
- Element* parent = parentElement();
- ShadowRoot* root = parent ? parent->youngestShadowRoot() : nullptr;
- if (root && root->isV1())
- return root->assignedSlotFor(*this);
+ if (ShadowRoot* root = v1ShadowRootOfParent())
+ return root->ensureSlotAssignment().findSlot(*this);
return nullptr;
}
HTMLSlotElement* Node::assignedSlotForBinding()
{
updateDistribution();
- Element* parent = parentElement();
- ShadowRoot* root = parent ? parent->youngestShadowRoot() : nullptr;
- if (root && root->type() == ShadowRootType::Open)
- return root->assignedSlotFor(*this);
+ if (ShadowRoot* root = v1ShadowRootOfParent()) {
+ if (root->type() == ShadowRootType::Open)
+ return root->ensureSlotAssignment().findSlot(*this);
+ }
return nullptr;
}
@@ -2379,12 +2374,36 @@ void Node::setV0CustomElementState(V0CustomElementState newState)
toElement(this)->pseudoStateChanged(CSSSelector::PseudoUnresolved);
}
-void Node::updateAssignmentForInsertedInto(ContainerNode* insertionPoint)
+void Node::checkSlotChange()
{
- if (isShadowHost(insertionPoint)) {
- ShadowRoot* root = insertionPoint->youngestShadowRoot();
- if (root && root->isV1())
- root->assignV1();
+ // Common check logic is used in both cases, "after inserted" and "before removed".
+ if (!isSlotable())
+ return;
+ if (ShadowRoot* root = v1ShadowRootOfParent()) {
+ // Relevant DOM Standard:
+ // https://dom.spec.whatwg.org/#concept-node-insert
+ // - 6.1.2: If parent is a shadow host and node is a slotable, then assign a slot for node.
+ // https://dom.spec.whatwg.org/#concept-node-remove
+ // - 10. If node is assigned, then run assign slotables for node’s assigned slot.
+
+ // Although DOM Standard requires "assign a slot for node / run assing slotables" at this timing,
esprehn 2016/05/23 06:41:00 typo, assign? you probably want to spell check you
+ // we skip it as an optimization.
+ if (HTMLSlotElement* slot = root->ensureSlotAssignment().findSlot(*this))
+ slot->enqueueSlotChangeEvent();
+ } else {
+ // Relevant DOM Standard:
+ // https://dom.spec.whatwg.org/#concept-node-insert
+ // - 6.1.3: If parent is a slot whose assigned nodes is the empty list, then run signal a slot change for parent.
+ // https://dom.spec.whatwg.org/#concept-node-remove
+ // - 11. If parent is a slot whose assigned nodes is the empty list, then run signal a slot change for parent.
+ Element* parent = parentElement();
+ if (parent && isHTMLSlotElement(parent)) {
+ HTMLSlotElement& parentSlot = toHTMLSlotElement(*parent);
+ if (ShadowRoot* root = containingShadowRoot()) {
+ if (root && root->isV1() && !parentSlot.hasAssignedNodesSynchronously())
+ parentSlot.enqueueSlotChangeEvent();
+ }
+ }
}
}

Powered by Google App Engine
This is Rietveld 408576698