Switch blink::Element to use new downcast helpers (1/n)

Bug: 891908
Change-Id: Ic360daeaf226f8f0fb7f36313cfd4c6500749915
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1627351
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Commit-Queue: Abhijeet Kandalkar <abhijeet@igalia.com>
Cr-Commit-Position: refs/heads/master@{#664289}
diff --git a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
index 334ad31..f9e9108 100644
--- a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
+++ b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
@@ -65,7 +65,7 @@
       // https://html.spec.whatwg.org/C/#window-reflecting-body-element-event-handler-set
       document = &node->GetDocument();
     } else {
-      element = ToElement(node);
+      element = To<Element>(node);
       document = &node->GetDocument();
     }
     // EventTarget::GetExecutionContext() sometimes returns the document which
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.cc b/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
index 8d5ba4bc..26dce18 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
@@ -127,8 +127,7 @@
 bool AXObjectCache::IsInsideFocusableElementOrARIAWidget(const Node& node) {
   const Node* cur_node = &node;
   do {
-    if (cur_node->IsElementNode()) {
-      const Element* element = ToElement(cur_node);
+    if (const auto* element = DynamicTo<Element>(cur_node)) {
       if (element->IsFocusable())
         return true;
       String role = element->getAttribute("role");
diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc
index 577f8983..c9e49ed 100644
--- a/third_party/blink/renderer/core/animation/animation_test.cc
+++ b/third_party/blink/renderer/core/animation/animation_test.cc
@@ -959,10 +959,11 @@
   Timing timing;
   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
   auto* keyframe_effect_composited = MakeGarbageCollected<KeyframeEffect>(
-      ToElement(object_composited->GetNode()), MakeSimpleEffectModel(), timing);
+      To<Element>(object_composited->GetNode()), MakeSimpleEffectModel(),
+      timing);
   Animation* animation_composited = timeline->Play(keyframe_effect_composited);
   auto* keyframe_effect_not_composited = MakeGarbageCollected<KeyframeEffect>(
-      ToElement(object_not_composited->GetNode()), MakeSimpleEffectModel(),
+      To<Element>(object_not_composited->GetNode()), MakeSimpleEffectModel(),
       timing);
   Animation* animation_not_composited =
       timeline->Play(keyframe_effect_not_composited);
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc
index 1e7b10f4..47546bf 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline.cc
+++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -314,8 +314,8 @@
     return;
 
   GetActiveScrollTimelineSet().insert(resolved_scroll_source_);
-  if (resolved_scroll_source_->IsElementNode())
-    ToElement(resolved_scroll_source_)->SetNeedsCompositingUpdate();
+  if (auto* element = DynamicTo<Element>(resolved_scroll_source_.Get()))
+    element->SetNeedsCompositingUpdate();
   resolved_scroll_source_->GetDocument()
       .GetLayoutView()
       ->Compositor()
@@ -332,8 +332,8 @@
     return;
 
   GetActiveScrollTimelineSet().erase(resolved_scroll_source_);
-  if (resolved_scroll_source_->IsElementNode())
-    ToElement(resolved_scroll_source_)->SetNeedsCompositingUpdate();
+  if (auto* element = DynamicTo<Element>(resolved_scroll_source_.Get()))
+    element->SetNeedsCompositingUpdate();
   auto* layout_view = resolved_scroll_source_->GetDocument().GetLayoutView();
   if (layout_view && layout_view->Compositor()) {
     layout_view->Compositor()->SetNeedsCompositingUpdate(
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
index 1e6009e..f8ebf9a 100644
--- a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -313,9 +313,10 @@
 Node* CSSComputedStyleDeclaration::StyledNode() const {
   if (!node_)
     return nullptr;
-  if (node_->IsElementNode()) {
+
+  if (auto* node_element = DynamicTo<Element>(node_.Get())) {
     if (PseudoElement* element =
-            ToElement(node_)->GetPseudoElement(pseudo_element_specifier_))
+            node_element->GetPseudoElement(pseudo_element_specifier_))
       return element;
   }
   return node_.Get();
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.cc b/third_party/blink/renderer/core/css/css_style_sheet.cc
index 445d6079..03d68a2a1 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet.cc
+++ b/third_party/blink/renderer/core/css/css_style_sheet.cc
@@ -586,8 +586,9 @@
 
 bool CSSStyleSheet::IsAlternate() const {
   if (owner_node_) {
-    return owner_node_->IsElementNode() &&
-           ToElement(owner_node_)->getAttribute(kRelAttr).Contains("alternate");
+    auto* owner_element = DynamicTo<Element>(owner_node_.Get());
+    return owner_element &&
+           owner_element->getAttribute(kRelAttr).Contains("alternate");
   }
   return alternate_from_constructor_;
 }
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.h b/third_party/blink/renderer/core/css/css_style_sheet.h
index b6cc7a6..f773cdf 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet.h
+++ b/third_party/blink/renderer/core/css/css_style_sheet.h
@@ -194,7 +194,6 @@
   void SetText(const String&, bool allow_import_rules, ExceptionState&);
   void SetMedia(MediaList*);
   void SetAlternateFromConstructor(bool);
-  bool IsAlternate() const;
   bool CanBeActivated(const String& current_preferrable_name) const;
 
   void SetIsConstructed(bool is_constructed) {
@@ -206,6 +205,7 @@
   void Trace(blink::Visitor*) override;
 
  private:
+  bool IsAlternate() const;
   bool IsCSSStyleSheet() const override { return true; }
   String type() const override { return "text/css"; }
 
diff --git a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
index f48127de..5ab8054 100644
--- a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
+++ b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
@@ -200,9 +200,8 @@
   DCHECK(node_);
   if (!pseudo_id_)
     return node_;
-  if (node_->IsElementNode()) {
-    if (PseudoElement* element =
-            (ToElement(node_))->GetPseudoElement(pseudo_id_)) {
+  if (auto* element_node = DynamicTo<Element>(node_.Get())) {
+    if (PseudoElement* element = element_node->GetPseudoElement(pseudo_id_)) {
       return element;
     }
   }
diff --git a/third_party/blink/renderer/core/css/selector_query.cc b/third_party/blink/renderer/core/css/selector_query.cc
index 5d41921..f497bc4 100644
--- a/third_party/blink/renderer/core/css/selector_query.cc
+++ b/third_party/blink/renderer/core/css/selector_query.cc
@@ -197,10 +197,11 @@
 
 inline bool AncestorHasClassName(ContainerNode& root_node,
                                  const AtomicString& class_name) {
-  if (!root_node.IsElementNode())
+  auto* root_node_element = DynamicTo<Element>(root_node);
+  if (!root_node_element)
     return false;
 
-  for (Element* element = &ToElement(root_node); element;
+  for (auto* element = root_node_element; element;
        element = element->parentElement()) {
     if (element->HasClassName(class_name))
       return true;
@@ -345,10 +346,10 @@
     typename SelectorQueryTrait::OutputType& output) const {
   for (ContainerNode* node = NextTraversingShadowTree(root_node, &root_node);
        node; node = NextTraversingShadowTree(*node, &root_node)) {
-    if (!node->IsElementNode())
+    auto* element = DynamicTo<Element>(node);
+    if (!element)
       continue;
     QUERY_STATS_INCREMENT(slow_traversing_shadow_tree_scan);
-    Element* element = ToElement(node);
     if (!SelectorListMatches(root_node, *element))
       continue;
     SelectorQueryTrait::AppendElement(output, *element);
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index b2d8209..f33e2f6 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -1599,9 +1599,9 @@
 }
 
 void StyleEngine::NodeWillBeRemoved(Node& node) {
-  if (node.IsElementNode()) {
+  if (auto* element = DynamicTo<Element>(node)) {
     pending_invalidations_.RescheduleSiblingInvalidationsAsDescendants(
-        ToElement(node));
+        *element);
   }
 
   // Mark closest ancestor with with LayoutObject to have all whitespace
@@ -1620,8 +1620,9 @@
     layout_object = layout_object->Parent();
   DCHECK(layout_object);
   DCHECK(layout_object->GetNode());
-  if (layout_object->GetNode()->IsElementNode()) {
-    whitespace_reattach_set_.insert(ToElement(layout_object->GetNode()));
+  if (auto* layout_object_element =
+          DynamicTo<Element>(layout_object->GetNode())) {
+    whitespace_reattach_set_.insert(layout_object_element);
     GetDocument().ScheduleLayoutTreeUpdateIfNeeded();
   }
 }
@@ -1736,8 +1737,8 @@
   }
   for (ContainerNode* ancestor = root_element.ParentOrShadowHostNode();
        ancestor; ancestor = ancestor->ParentOrShadowHostNode()) {
-    if (ancestor->IsElementNode())
-      ToElement(ancestor)->RecalcStyleForTraversalRootAncestor();
+    if (auto* ancestor_element = DynamicTo<Element>(ancestor))
+      ancestor_element->RecalcStyleForTraversalRootAncestor();
     ancestor->ClearChildNeedsStyleRecalc();
   }
   style_recalc_root_.Clear();
@@ -1757,8 +1758,8 @@
 
   for (ContainerNode* ancestor = root_element.GetReattachParent(); ancestor;
        ancestor = ancestor->GetReattachParent()) {
-    if (ancestor->IsElementNode())
-      ToElement(ancestor)->RebuildLayoutTreeForTraversalRootAncestor();
+    if (auto* ancestor_element = DynamicTo<Element>(ancestor))
+      ancestor_element->RebuildLayoutTreeForTraversalRootAncestor();
     ancestor->ClearChildNeedsStyleRecalc();
     ancestor->ClearChildNeedsReattachLayoutTree();
   }
diff --git a/third_party/blink/renderer/core/css/style_invalidation_root.cc b/third_party/blink/renderer/core/css/style_invalidation_root.cc
index 798ed798..bb29306 100644
--- a/third_party/blink/renderer/core/css/style_invalidation_root.cc
+++ b/third_party/blink/renderer/core/css/style_invalidation_root.cc
@@ -16,7 +16,7 @@
     return &shadow_root->host();
   if (root_node->IsDocumentNode())
     return root_node->GetDocument().documentElement();
-  return ToElement(root_node);
+  return To<Element>(root_node);
 }
 
 #if DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/core/css/style_sheet_candidate.cc b/third_party/blink/renderer/core/css/style_sheet_candidate.cc
index 9db69be..91419b4 100644
--- a/third_party/blink/renderer/core/css/style_sheet_candidate.cc
+++ b/third_party/blink/renderer/core/css/style_sheet_candidate.cc
@@ -40,7 +40,7 @@
 using namespace html_names;
 
 AtomicString StyleSheetCandidate::Title() const {
-  return IsElement() ? ToElement(GetNode()).FastGetAttribute(kTitleAttr)
+  return IsElement() ? To<Element>(GetNode()).FastGetAttribute(kTitleAttr)
                      : g_null_atom;
 }
 
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
index 1138e9e7..8c82115 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -1212,7 +1212,7 @@
 
   auto* template_el =
       ToHTMLTemplateElement(GetDocument().getElementById("template"));
-  auto* child = ToElement(template_el->content()->firstChild());
+  auto* child = To<Element>(template_el->content()->firstChild());
   EXPECT_FALSE(child->isConnected());
   ASSERT_TRUE(child->getDisplayLockForBindings());
 
@@ -1239,7 +1239,7 @@
 
   // Try to lock an element that was moved from a template to a document.
   auto* document_child =
-      ToElement(GetDocument().adoptNode(child, ASSERT_NO_EXCEPTION));
+      To<Element>(GetDocument().adoptNode(child, ASSERT_NO_EXCEPTION));
   GetDocument().getElementById("container")->appendChild(document_child);
 
   {
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
index 644274a..ad63a67 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -50,13 +50,14 @@
 DisplayLockUtilities::ActivatableLockedInclusiveAncestors(Element& element) {
   HeapVector<Member<Element>> elements_to_activate;
   for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(element)) {
-    if (!ancestor.IsElementNode())
+    auto* ancestor_element = DynamicTo<Element>(ancestor);
+    if (!ancestor_element)
       continue;
-    if (auto* context = ToElement(ancestor).GetDisplayLockContext()) {
+    if (auto* context = ancestor_element->GetDisplayLockContext()) {
       DCHECK(context->IsActivatable());
       if (!context->IsLocked())
         continue;
-      elements_to_activate.push_back(&ToElement(ancestor));
+      elements_to_activate.push_back(ancestor_element);
     }
   }
   return elements_to_activate;
@@ -89,9 +90,10 @@
   // structure that we can use to quickly identify nodes that are in the
   // locked subtree.
   for (Node& ancestor : ancestor_view) {
-    if (!ancestor.IsElementNode())
+    auto* ancestor_node = DynamicTo<Element>(ancestor);
+    if (!ancestor_node)
       continue;
-    if (auto* context = ToElement(ancestor).GetDisplayLockContext())
+    if (auto* context = ancestor_node->GetDisplayLockContext())
       scoped_update_forced_list_.push_back(context->GetScopedForcedUpdate());
   }
 }
@@ -127,11 +129,12 @@
   // TODO(crbug.com/924550): Once we figure out a more efficient way to
   // determine whether we're inside a locked subtree or not, change this.
   for (Node& ancestor : FlatTreeTraversal::AncestorsOf(node)) {
-    if (!ancestor.IsElementNode())
+    auto* ancestor_element = DynamicTo<Element>(ancestor);
+    if (!ancestor_element)
       continue;
-    if (auto* context = ToElement(ancestor).GetDisplayLockContext()) {
+    if (auto* context = ancestor_element->GetDisplayLockContext()) {
       if (context->IsLocked())
-        return &ToElement(ancestor);
+        return ancestor_element;
     }
   }
   return nullptr;
@@ -146,11 +149,12 @@
   }
   Element* locked_ancestor = nullptr;
   for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) {
-    if (!ancestor.IsElementNode())
+    auto* ancestor_node = DynamicTo<Element>(ancestor);
+    if (!ancestor_node)
       continue;
-    if (auto* context = ToElement(ancestor).GetDisplayLockContext()) {
+    if (auto* context = ancestor_node->GetDisplayLockContext()) {
       if (context->IsLocked())
-        locked_ancestor = &ToElement(ancestor);
+        locked_ancestor = ancestor_node;
     }
   }
   return locked_ancestor;
diff --git a/third_party/blink/renderer/core/dom/child_frame_disconnector.cc b/third_party/blink/renderer/core/dom/child_frame_disconnector.cc
index 7412bbf..9ef4c7f 100644
--- a/third_party/blink/renderer/core/dom/child_frame_disconnector.cc
+++ b/third_party/blink/renderer/core/dom/child_frame_disconnector.cc
@@ -63,13 +63,12 @@
 #if DCHECK_IS_ON()
 static unsigned CheckConnectedSubframeCountIsConsistent(Node& node) {
   unsigned count = 0;
-
-  if (node.IsElementNode()) {
+  if (auto* element = DynamicTo<Element>(node)) {
     auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(node);
     if (frame_owner_element && frame_owner_element->ContentFrame())
       count++;
 
-    if (ShadowRoot* root = ToElement(node).GetShadowRoot())
+    if (ShadowRoot* root = element->GetShadowRoot())
       count += CheckConnectedSubframeCountIsConsistent(*root);
   }
 
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc
index 31ea369..63b85e3e 100644
--- a/third_party/blink/renderer/core/dom/container_node.cc
+++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -633,8 +633,8 @@
   // e.g. mutation event listener can create a new range.
   GetDocument().NodeWillBeRemoved(child);
 
-  if (child.IsElementNode()) {
-    if (auto* context = ToElement(child).GetDisplayLockContext())
+  if (auto* child_element = DynamicTo<Element>(child)) {
+    if (auto* context = child_element->GetDisplayLockContext())
       context->NotifyWillDisconnect();
   }
 }
@@ -1044,8 +1044,9 @@
       StyleChangeReasonForTracing::CreateWithExtraData(
           style_change_reason::kPseudoClass, style_change_extra_data::g_focus));
 
-  if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocus())
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocus);
+  auto* this_element = DynamicTo<Element>(this);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByFocus())
+    this_element->PseudoStateChanged(CSSSelector::kPseudoFocus);
 
   GetLayoutObject()->InvalidateIfControlStateChanged(kFocusControlState);
   FocusVisibleStateChanged();
@@ -1064,9 +1065,9 @@
                           style_change_reason::kPseudoClass,
                           style_change_extra_data::g_focus_visible));
 
-  if (IsElementNode() &&
-      ToElement(this)->ChildrenOrSiblingsAffectedByFocusVisible())
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusVisible);
+  auto* this_element = DynamicTo<Element>(this);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByFocusVisible())
+    this_element->PseudoStateChanged(CSSSelector::kPseudoFocusVisible);
 }
 
 void ContainerNode::FocusWithinStateChanged() {
@@ -1080,9 +1081,9 @@
                             style_change_reason::kPseudoClass,
                             style_change_extra_data::g_focus_within));
   }
-  if (IsElementNode() &&
-      ToElement(this)->ChildrenOrSiblingsAffectedByFocusWithin())
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusWithin);
+  auto* this_element = DynamicTo<Element>(this);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByFocusWithin())
+    this_element->PseudoStateChanged(CSSSelector::kPseudoFocusWithin);
 }
 
 void ContainerNode::SetFocused(bool received, WebFocusType focus_type) {
@@ -1096,11 +1097,12 @@
 
   // If this is an author shadow host and indirectly focused (has focused
   // element within its shadow root), update focus.
-  if (IsElementNode() && GetDocument().FocusedElement() &&
+  auto* this_element = DynamicTo<Element>(this);
+  if (this_element && GetDocument().FocusedElement() &&
       GetDocument().FocusedElement() != this) {
-    if (ToElement(this)->AuthorShadowRoot())
-      received =
-          received && ToElement(this)->AuthorShadowRoot()->delegatesFocus();
+    if (this_element->AuthorShadowRoot()) {
+      received = received && this_element->AuthorShadowRoot()->delegatesFocus();
+    }
   }
 
   if (IsFocused() == received)
@@ -1115,8 +1117,8 @@
 
   // If :focus sets display: none, we lose focus but still need to recalc our
   // style.
-  if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocus()) {
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocus);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByFocus()) {
+    this_element->PseudoStateChanged(CSSSelector::kPseudoFocus);
   } else {
     SetNeedsStyleRecalc(kLocalStyleChange,
                         StyleChangeReasonForTracing::CreateWithExtraData(
@@ -1125,9 +1127,9 @@
   }
 
   if (RuntimeEnabledFeatures::CSSFocusVisibleEnabled()) {
-    if (IsElementNode() &&
-        ToElement(this)->ChildrenOrSiblingsAffectedByFocusVisible()) {
-      ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusVisible);
+    if (this_element &&
+        this_element->ChildrenOrSiblingsAffectedByFocusVisible()) {
+      this_element->PseudoStateChanged(CSSSelector::kPseudoFocusVisible);
     } else {
       SetNeedsStyleRecalc(kLocalStyleChange,
                           StyleChangeReasonForTracing::CreateWithExtraData(
@@ -1136,9 +1138,8 @@
     }
   }
 
-  if (IsElementNode() &&
-      ToElement(this)->ChildrenOrSiblingsAffectedByFocusWithin()) {
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusWithin);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByFocusWithin()) {
+    this_element->PseudoStateChanged(CSSSelector::kPseudoFocusWithin);
   } else {
     SetNeedsStyleRecalc(kLocalStyleChange,
                         StyleChangeReasonForTracing::CreateWithExtraData(
@@ -1162,9 +1163,9 @@
   Node::SetActive(down);
 
   if (!GetLayoutObject()) {
-    if (IsElementNode() &&
-        ToElement(this)->ChildrenOrSiblingsAffectedByActive()) {
-      ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoActive);
+    auto* this_element = DynamicTo<Element>(this);
+    if (this_element && this_element->ChildrenOrSiblingsAffectedByActive()) {
+      this_element->PseudoStateChanged(CSSSelector::kPseudoActive);
     } else {
       SetNeedsStyleRecalc(kLocalStyleChange,
                           StyleChangeReasonForTracing::CreateWithExtraData(
@@ -1184,8 +1185,9 @@
                             style_change_reason::kPseudoClass,
                             style_change_extra_data::g_active));
   }
-  if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByActive())
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoActive);
+  auto* this_element = DynamicTo<Element>(this);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByActive())
+    this_element->PseudoStateChanged(CSSSelector::kPseudoActive);
 
   GetLayoutObject()->InvalidateIfControlStateChanged(kPressedControlState);
 }
@@ -1201,9 +1203,9 @@
   if (!GetLayoutObject()) {
     if (new_value)
       return;
-    if (IsElementNode() &&
-        ToElement(this)->ChildrenOrSiblingsAffectedByDrag()) {
-      ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoDrag);
+    auto* this_element = DynamicTo<Element>(this);
+    if (this_element && this_element->ChildrenOrSiblingsAffectedByDrag()) {
+      this_element->PseudoStateChanged(CSSSelector::kPseudoDrag);
 
     } else {
       SetNeedsStyleRecalc(kLocalStyleChange,
@@ -1224,8 +1226,9 @@
                             style_change_reason::kPseudoClass,
                             style_change_extra_data::g_drag));
   }
-  if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByDrag())
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoDrag);
+  auto* this_element = DynamicTo<Element>(this);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByDrag())
+    this_element->PseudoStateChanged(CSSSelector::kPseudoDrag);
 }
 
 void ContainerNode::SetHovered(bool over) {
@@ -1244,8 +1247,9 @@
                             style_change_reason::kPseudoClass,
                             style_change_extra_data::g_hover));
   }
-  if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByHover())
-    ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoHover);
+  auto* this_element = DynamicTo<Element>(this);
+  if (this_element && this_element->ChildrenOrSiblingsAffectedByHover())
+    this_element->PseudoStateChanged(CSSSelector::kPseudoHover);
 
   if (LayoutObject* o = GetLayoutObject())
     o->InvalidateIfControlStateChanged(kHoverControlState);
@@ -1403,8 +1407,9 @@
       continue;
     if (auto* child_text_node = DynamicTo<Text>(child))
       child_text_node->RecalcTextStyle(change);
-    else if (child->IsElementNode())
-      ToElement(child)->RecalcStyle(change);
+
+    if (auto* child_element = DynamicTo<Element>(child))
+      child_element->RecalcStyle(change);
   }
 }
 
@@ -1419,10 +1424,10 @@
     return;
   }
 
-  if (!child->IsElementNode())
+  auto* element = DynamicTo<Element>(child);
+  if (!element)
     return;
 
-  Element* element = ToElement(child);
   if (element->NeedsRebuildLayoutTree(whitespace_attacher))
     element->RebuildLayoutTree(whitespace_attacher);
   else
@@ -1482,14 +1487,14 @@
   if (!HasRestyleFlag(DynamicRestyleFlags::kChildrenAffectedByStructuralRules))
     return;
 
-  Element* element_after_change =
-      !node_after_change || node_after_change->IsElementNode()
-          ? ToElement(node_after_change)
-          : ElementTraversal::NextSibling(*node_after_change);
-  Element* element_before_change =
-      !node_before_change || node_before_change->IsElementNode()
-          ? ToElement(node_before_change)
-          : ElementTraversal::PreviousSibling(*node_before_change);
+  auto* element_after_change = DynamicTo<Element>(node_after_change);
+  if (node_after_change && !element_after_change)
+    element_after_change = ElementTraversal::NextSibling(*node_after_change);
+  auto* element_before_change = DynamicTo<Element>(node_before_change);
+  if (node_before_change && !element_before_change) {
+    element_before_change =
+        ElementTraversal::PreviousSibling(*node_before_change);
+  }
 
   // TODO(futhark@chromium.org): move this code into StyleEngine and collect the
   // various invalidation sets into a single InvalidationLists object and
diff --git a/third_party/blink/renderer/core/dom/document_statistics_collector.cc b/third_party/blink/renderer/core/dom/document_statistics_collector.cc
index 80defe0..308b4f9 100644
--- a/third_party/blink/renderer/core/dom/document_statistics_collector.cc
+++ b/third_party/blink/renderer/core/dom/document_statistics_collector.cc
@@ -117,14 +117,9 @@
 void CollectFeatures(Element& root,
                      WebDistillabilityFeatures& features,
                      bool under_list_item = false) {
-  for (Node& node : NodeTraversal::ChildrenOf(root)) {
+  for (Element& element : ElementTraversal::ChildrenOf(root)) {
     bool is_list_item = false;
-    if (!node.IsElementNode()) {
-      continue;
-    }
-
     features.element_count++;
-    Element& element = ToElement(node);
     if (element.HasTagName(kATag)) {
       features.anchor_count++;
     } else if (element.HasTagName(kFormTag)) {
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 6a0f2bd..4486fe3 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1422,9 +1422,10 @@
   HeapVector<Member<Element>> invisible_ancestors;
   HeapVector<Member<Element>> activated_elements;
   for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) {
-    if (ancestor.IsElementNode() &&
-        ToElement(ancestor).Invisible() != InvisibleState::kMissing) {
-      invisible_ancestors.push_back(ToElement(ancestor));
+    auto* ancestor_element = DynamicTo<Element>(ancestor);
+    if (ancestor_element &&
+        ancestor_element->Invisible() != InvisibleState::kMissing) {
+      invisible_ancestors.push_back(ancestor_element);
       activated_elements.push_back(ancestor.GetTreeScope().Retarget(*this));
     }
   }
@@ -1441,8 +1442,9 @@
   if (!RuntimeEnabledFeatures::InvisibleDOMEnabled())
     return false;
   for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) {
-    if (ancestor.IsElementNode() &&
-        ToElement(ancestor).Invisible() == InvisibleState::kStatic)
+    auto* ancestor_element = DynamicTo<Element>(ancestor);
+    if (ancestor_element &&
+        ancestor_element->Invisible() == InvisibleState::kStatic)
       return true;
   }
   return false;
@@ -1453,8 +1455,9 @@
       !CanParticipateInFlatTree())
     return false;
   for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) {
-    if (ancestor.IsElementNode() &&
-        ToElement(ancestor).Invisible() != InvisibleState::kMissing)
+    auto* ancestor_element = DynamicTo<Element>(ancestor);
+    if (ancestor_element &&
+        ancestor_element->Invisible() != InvisibleState::kMissing)
       return true;
   }
   return false;
@@ -2120,10 +2123,10 @@
 
   if (Fullscreen::IsFullscreenElement(*this)) {
     SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
-    if (insertion_point.IsElementNode()) {
-      ToElement(insertion_point).SetContainsFullScreenElement(false);
-      ToElement(insertion_point)
-          .SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(
+    if (auto* insertion_point_element = DynamicTo<Element>(insertion_point)) {
+      insertion_point_element->SetContainsFullScreenElement(false);
+      insertion_point_element
+          ->SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(
               false);
     }
   }
@@ -3081,7 +3084,7 @@
     CheckForSiblingStyleChanges(
         change.type == kElementRemoved ? kSiblingElementRemoved
                                        : kSiblingElementInserted,
-        ToElement(change.sibling_changed), change.sibling_before_change,
+        To<Element>(change.sibling_changed.Get()), change.sibling_before_change,
         change.sibling_after_change);
 
   if (ShadowRoot* shadow_root = GetShadowRoot())
@@ -3555,14 +3558,15 @@
 
   HeapVector<std::pair<Member<Element>, Member<Element>>> activatable_targets;
   for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) {
-    if (!ancestor.IsElementNode())
+    auto* ancestor_element = DynamicTo<Element>(ancestor);
+    if (!ancestor_element)
       continue;
-    if (auto* context = ToElement(ancestor).GetDisplayLockContext()) {
+    if (auto* context = ancestor_element->GetDisplayLockContext()) {
       // If any of the ancestors is not activatable, we can't activate.
       if (!context->IsActivatable())
         return;
       activatable_targets.push_back(std::make_pair(
-          &ToElement(ancestor), &ancestor.GetTreeScope().Retarget(*this)));
+          ancestor_element, &ancestor.GetTreeScope().Retarget(*this)));
     }
   }
 
@@ -3593,9 +3597,10 @@
   // check whether a node is in a locked subtree quickly.
   // See crbug.com/924550 for more details.
   for (const Node& current : FlatTreeTraversal::InclusiveAncestorsOf(*this)) {
-    if (!current.IsElementNode())
+    auto* current_element = DynamicTo<Element>(current);
+    if (!current_element)
       continue;
-    if (auto* context = ToElement(current).GetDisplayLockContext()) {
+    if (auto* context = current_element->GetDisplayLockContext()) {
       if (!context->IsActivatable())
         return true;
     }
@@ -3788,7 +3793,9 @@
         "This element has no parent node.");
     return;
   }
-  if (!p->IsElementNode()) {
+
+  auto* parent = DynamicTo<Element>(p);
+  if (!parent) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNoModificationAllowedError,
         "This element's parent is of type '" + p->nodeName() +
@@ -3796,7 +3803,6 @@
     return;
   }
 
-  Element* parent = ToElement(p);
   Node* prev = previousSibling();
   Node* next = nextSibling();
 
@@ -3954,7 +3960,7 @@
                                         Element* new_child,
                                         ExceptionState& exception_state) {
   Node* return_value = InsertAdjacent(where, new_child, exception_state);
-  return ToElement(return_value);
+  return To<Element>(return_value);
 }
 
 void Element::insertAdjacentText(const String& where,
@@ -4218,7 +4224,7 @@
   // the first language.
   do {
     if (n->IsElementNode()) {
-      if (const ElementData* element_data = ToElement(n)->GetElementData()) {
+      if (const auto* element_data = To<Element>(n)->GetElementData()) {
         AttributeCollection attributes = element_data->Attributes();
         // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
         if (const Attribute* attribute =
@@ -4666,13 +4672,13 @@
   // the tree, part of the tree might still carry the flag.
   if (!value && Fullscreen::IsFullscreenElement(*this)) {
     for (Node* node = firstChild(); node;) {
-      if (!node->IsElementNode() ||
-          !ToElement(node)->ContainsPersistentVideo()) {
+      auto* element = DynamicTo<Element>(node);
+      if (!element || !element->ContainsPersistentVideo()) {
         node = node->nextSibling();
         break;
       }
 
-      ToElement(node)->SetContainsPersistentVideo(false);
+      element->SetContainsPersistentVideo(false);
       node = node->firstChild();
     }
   }
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index d4a6485..8184c7e 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -1182,6 +1182,11 @@
   return true;
 }
 
+template <>
+struct DowncastTraits<Element> {
+  static bool AllowFrom(const Node& node) { return node.IsElementNode(); }
+};
+
 // Type casting.
 template <typename T>
 inline T& ToElement(Node& node) {