blob: 497a076dad2ad262f43f59e6fe454d5268b4d8c3 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/css/style_traversal_root.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node_traversal.h"
namespace blink {
void StyleTraversalRoot::Update(ContainerNode* common_ancestor,
Node* dirty_node) {
DCHECK(dirty_node);
DCHECK(dirty_node->isConnected());
AssertRootNodeInvariants();
if (!common_ancestor) {
// This is either first dirty node in which case we are using it as a
// single root, or the document/documentElement which we set as a common
// root.
//
// TODO(futhark): Disallow Document as the root. All traversals start at
// the RootElement().
Element* document_element = dirty_node->GetDocument().documentElement();
if (dirty_node->IsDocumentNode() ||
(root_node_ && dirty_node == document_element)) {
root_type_ = RootType::kCommonRoot;
} else {
DCHECK(!document_element ||
(!root_node_ && root_type_ == RootType::kSingleRoot));
}
root_node_ = dirty_node;
return;
}
DCHECK(root_node_);
#if DCHECK_IS_ON()
DCHECK(Parent(*dirty_node));
DCHECK(!IsDirty(*Parent(*dirty_node)));
#endif // DCHECK_IS_ON()
if (common_ancestor == root_node_ || IsDirty(*common_ancestor)) {
// If our common ancestor candidate is dirty, we are a descendant of the
// current root node.
root_type_ = RootType::kCommonRoot;
return;
}
if (root_type_ == RootType::kCommonRoot) {
// We already have a common root and we don't know if the common ancestor is
// a descendent or ancestor of the current root. Fall back to make the
// document the root node.
root_node_ = &common_ancestor->GetDocument();
return;
}
root_node_ = common_ancestor;
root_type_ = RootType::kCommonRoot;
}
#if DCHECK_IS_ON()
bool StyleTraversalRoot::RootIsBeingRemoved() const {
DCHECK(root_node_);
return !root_node_->isConnected() &&
root_node_->GetDocument().GetStyleEngine().InDOMRemoval();
}
#endif
} // namespace blink