/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2004-2008, 2013, 2014 Apple Inc. All rights reserved.
 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 * Copyright (C) 2011 Motorola Mobility. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "third_party/blink/renderer/core/html/html_element.h"

#include "base/stl_util.h"
#include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
#include "third_party/blink/renderer/bindings/core/v8/string_treat_null_as_empty_string_or_trusted_script.h"
#include "third_party/blink/renderer/core/css/css_color_value.h"
#include "third_party/blink/renderer/core/css/css_markup.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h"
#include "third_party/blink/renderer/core/dom/element_rare_data.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
#include "third_party/blink/renderer/core/dom/node_traversal.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/custom/custom_element.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_registry.h"
#include "third_party/blink/renderer/core/html/custom/element_internals.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/labels_node_list.h"
#include "third_party/blink/renderer/core/html/html_br_element.h"
#include "third_party/blink/renderer/core/html/html_dimension.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/html/html_template_element.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/mathml_names.h"
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script.h"
#include "third_party/blink/renderer/core/xml_names.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/text/bidi_resolver.h"
#include "third_party/blink/renderer/platform/text/bidi_text_run.h"
#include "third_party/blink/renderer/platform/text/text_run_iterator.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"

namespace blink {

using namespace cssvalue;
using namespace html_names;

using AttributeChangedFunction =
    void (HTMLElement::*)(const Element::AttributeModificationParams& params);

struct AttributeTriggers {
  const QualifiedName& attribute;
  WebFeature web_feature;
  const AtomicString& event;
  AttributeChangedFunction function;
};

namespace {

// https://w3c.github.io/editing/execCommand.html#editing-host
bool IsEditingHost(const Node& node) {
  if (!node.IsHTMLElement())
    return false;
  String normalized_value = ToHTMLElement(node).contentEditable();
  if (normalized_value == "true" || normalized_value == "plaintext-only")
    return true;
  return node.GetDocument().InDesignMode() &&
         node.GetDocument().documentElement() == &node;
}

// https://w3c.github.io/editing/execCommand.html#editable
bool IsEditable(const Node& node) {
  if (IsEditingHost(node))
    return false;
  if (node.IsHTMLElement() && ToHTMLElement(node).contentEditable() == "false")
    return false;
  if (!node.parentNode())
    return false;
  if (!IsEditingHost(*node.parentNode()) && !IsEditable(*node.parentNode()))
    return false;
  if (node.IsHTMLElement())
    return true;
  if (IsSVGSVGElement(node))
    return true;
  if (node.IsElementNode() &&
      ToElement(node).HasTagName(mathml_names::kMathTag))
    return true;
  return !node.IsElementNode() && node.parentNode()->IsHTMLElement();
}

const WebFeature kNoWebFeature = static_cast<WebFeature>(0);

}  // anonymous namespace

DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLElement);

String HTMLElement::DebugNodeName() const {
  if (GetDocument().IsHTMLDocument()) {
    return TagQName().HasPrefix() ? Element::nodeName().UpperASCII()
                                  : TagQName().LocalName().UpperASCII();
  }
  return Element::nodeName();
}

String HTMLElement::nodeName() const {
  // localNameUpper may intern and cache an AtomicString.
  DCHECK(IsMainThread());

  // FIXME: Would be nice to have an atomicstring lookup based off uppercase
  // chars that does not have to copy the string on a hit in the hash.
  // FIXME: We should have a way to detect XHTML elements and replace the
  // hasPrefix() check with it.
  if (GetDocument().IsHTMLDocument()) {
    if (!TagQName().HasPrefix())
      return TagQName().LocalNameUpper();
    return Element::nodeName().UpperASCII();
  }
  return Element::nodeName();
}

bool HTMLElement::ShouldSerializeEndTag() const {
  // See https://www.w3.org/TR/DOM-Parsing/
  if (HasTagName(kAreaTag) || HasTagName(kBaseTag) ||
      HasTagName(kBasefontTag) || HasTagName(kBgsoundTag) ||
      HasTagName(kBrTag) || HasTagName(kColTag) || HasTagName(kEmbedTag) ||
      HasTagName(kFrameTag) || HasTagName(kHrTag) || HasTagName(kImgTag) ||
      HasTagName(kInputTag) || HasTagName(kKeygenTag) || HasTagName(kLinkTag) ||
      HasTagName(kMetaTag) || HasTagName(kParamTag) || HasTagName(kSourceTag) ||
      HasTagName(kTrackTag) || HasTagName(kWbrTag))
    return false;
  return true;
}

static inline CSSValueID UnicodeBidiAttributeForDirAuto(HTMLElement* element) {
  if (element->HasTagName(kPreTag) || element->HasTagName(kTextareaTag))
    return CSSValueWebkitPlaintext;
  // FIXME: For bdo element, dir="auto" should result in "bidi-override isolate"
  // but we don't support having multiple values in unicode-bidi yet.
  // See https://bugs.webkit.org/show_bug.cgi?id=73164.
  return CSSValueWebkitIsolate;
}

unsigned HTMLElement::ParseBorderWidthAttribute(
    const AtomicString& value) const {
  unsigned border_width = 0;
  if (value.IsEmpty() || !ParseHTMLNonNegativeInteger(value, border_width)) {
    if (HasTagName(kTableTag) && !value.IsNull())
      return 1;
  }
  return border_width;
}

void HTMLElement::ApplyBorderAttributeToStyle(
    const AtomicString& value,
    MutableCSSPropertyValueSet* style) {
  AddPropertyToPresentationAttributeStyle(style, CSSPropertyBorderWidth,
                                          ParseBorderWidthAttribute(value),
                                          CSSPrimitiveValue::UnitType::kPixels);
  AddPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle,
                                          CSSValueSolid);
}

void HTMLElement::MapLanguageAttributeToLocale(
    const AtomicString& value,
    MutableCSSPropertyValueSet* style) {
  if (!value.IsEmpty()) {
    // Have to quote so the locale id is treated as a string instead of as a CSS
    // keyword.
    AddPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLocale,
                                            SerializeString(value));

    // FIXME: Remove the following UseCounter code when we collect enough
    // data.
    UseCounter::Count(GetDocument(), WebFeature::kLangAttribute);
    if (IsHTMLHtmlElement(*this))
      UseCounter::Count(GetDocument(), WebFeature::kLangAttributeOnHTML);
    else if (IsHTMLBodyElement(*this))
      UseCounter::Count(GetDocument(), WebFeature::kLangAttributeOnBody);
    String html_language = value.GetString();
    wtf_size_t first_separator = html_language.find('-');
    if (first_separator != kNotFound)
      html_language = html_language.Left(first_separator);
    String ui_language = DefaultLanguage();
    first_separator = ui_language.find('-');
    if (first_separator != kNotFound)
      ui_language = ui_language.Left(first_separator);
    first_separator = ui_language.find('_');
    if (first_separator != kNotFound)
      ui_language = ui_language.Left(first_separator);
    if (!DeprecatedEqualIgnoringCase(html_language, ui_language)) {
      UseCounter::Count(GetDocument(),
                        WebFeature::kLangAttributeDoesNotMatchToUILocale);
    }
  } else {
    // The empty string means the language is explicitly unknown.
    AddPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLocale,
                                            CSSValueAuto);
  }
}

bool HTMLElement::IsPresentationAttribute(const QualifiedName& name) const {
  if (name == kAlignAttr || name == kContenteditableAttr ||
      name == kHiddenAttr || name == kLangAttr ||
      name.Matches(xml_names::kLangAttr) || name == kDraggableAttr ||
      name == kDirAttr)
    return true;
  return Element::IsPresentationAttribute(name);
}

static inline bool IsValidDirAttribute(const AtomicString& value) {
  return DeprecatedEqualIgnoringCase(value, "auto") ||
         DeprecatedEqualIgnoringCase(value, "ltr") ||
         DeprecatedEqualIgnoringCase(value, "rtl");
}

void HTMLElement::CollectStyleForPresentationAttribute(
    const QualifiedName& name,
    const AtomicString& value,
    MutableCSSPropertyValueSet* style) {
  if (name == kAlignAttr) {
    if (DeprecatedEqualIgnoringCase(value, "middle"))
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyTextAlign,
                                              CSSValueCenter);
    else
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyTextAlign,
                                              value);
  } else if (name == kContenteditableAttr) {
    if (value.IsEmpty() || DeprecatedEqualIgnoringCase(value, "true")) {
      AddPropertyToPresentationAttributeStyle(
          style, CSSPropertyWebkitUserModify, CSSValueReadWrite);
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyOverflowWrap,
                                              CSSValueBreakWord);
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLineBreak,
                                              CSSValueAfterWhiteSpace);
      UseCounter::Count(GetDocument(), WebFeature::kContentEditableTrue);
      if (HasTagName(kHTMLTag)) {
        UseCounter::Count(GetDocument(),
                          WebFeature::kContentEditableTrueOnHTML);
      }
    } else if (DeprecatedEqualIgnoringCase(value, "plaintext-only")) {
      AddPropertyToPresentationAttributeStyle(
          style, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyOverflowWrap,
                                              CSSValueBreakWord);
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLineBreak,
                                              CSSValueAfterWhiteSpace);
      UseCounter::Count(GetDocument(),
                        WebFeature::kContentEditablePlainTextOnly);
    } else if (DeprecatedEqualIgnoringCase(value, "false")) {
      AddPropertyToPresentationAttributeStyle(
          style, CSSPropertyWebkitUserModify, CSSValueReadOnly);
    }
  } else if (name == kHiddenAttr) {
    AddPropertyToPresentationAttributeStyle(style, CSSPropertyDisplay,
                                            CSSValueNone);
  } else if (name == kDraggableAttr) {
    UseCounter::Count(GetDocument(), WebFeature::kDraggableAttribute);
    if (DeprecatedEqualIgnoringCase(value, "true")) {
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitUserDrag,
                                              CSSValueElement);
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyUserSelect,
                                              CSSValueNone);
    } else if (DeprecatedEqualIgnoringCase(value, "false")) {
      AddPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitUserDrag,
                                              CSSValueNone);
    }
  } else if (name == kDirAttr) {
    if (DeprecatedEqualIgnoringCase(value, "auto")) {
      AddPropertyToPresentationAttributeStyle(
          style, CSSPropertyUnicodeBidi, UnicodeBidiAttributeForDirAuto(this));
    } else {
      if (IsValidDirAttribute(value))
        AddPropertyToPresentationAttributeStyle(style, CSSPropertyDirection,
                                                value);
      else if (IsHTMLBodyElement(*this))
        AddPropertyToPresentationAttributeStyle(style, CSSPropertyDirection,
                                                "ltr");
      if (!HasTagName(kBdiTag) && !HasTagName(kBdoTag) &&
          !HasTagName(kOutputTag))
        AddPropertyToPresentationAttributeStyle(style, CSSPropertyUnicodeBidi,
                                                CSSValueIsolate);
    }
  } else if (name.Matches(xml_names::kLangAttr)) {
    MapLanguageAttributeToLocale(value, style);
  } else if (name == kLangAttr) {
    // xml:lang has a higher priority than lang.
    if (!FastHasAttribute(xml_names::kLangAttr))
      MapLanguageAttributeToLocale(value, style);
  } else {
    Element::CollectStyleForPresentationAttribute(name, value, style);
  }
}

// static
AttributeTriggers* HTMLElement::TriggersForAttributeName(
    const QualifiedName& attr_name) {
  const AtomicString& kNoEvent = g_null_atom;
  static AttributeTriggers attribute_triggers[] = {
      {kDirAttr, kNoWebFeature, kNoEvent, &HTMLElement::OnDirAttrChanged},
      {kFormAttr, kNoWebFeature, kNoEvent, &HTMLElement::OnFormAttrChanged},
      {kInertAttr, WebFeature::kInertAttribute, kNoEvent,
       &HTMLElement::OnInertAttrChanged},
      {kLangAttr, kNoWebFeature, kNoEvent, &HTMLElement::OnLangAttrChanged},
      {kNonceAttr, kNoWebFeature, kNoEvent, &HTMLElement::OnNonceAttrChanged},
      {kTabindexAttr, kNoWebFeature, kNoEvent,
       &HTMLElement::OnTabIndexAttrChanged},
      {xml_names::kLangAttr, kNoWebFeature, kNoEvent,
       &HTMLElement::OnXMLLangAttrChanged},

      {kOnabortAttr, kNoWebFeature, event_type_names::kAbort, nullptr},
      {kOnactivateinvisibleAttr, kNoWebFeature,
       event_type_names::kActivateinvisible, nullptr},
      {kOnanimationendAttr, kNoWebFeature, event_type_names::kAnimationend,
       nullptr},
      {kOnanimationiterationAttr, kNoWebFeature,
       event_type_names::kAnimationiteration, nullptr},
      {kOnanimationstartAttr, kNoWebFeature, event_type_names::kAnimationstart,
       nullptr},
      {kOnauxclickAttr, kNoWebFeature, event_type_names::kAuxclick, nullptr},
      {kOnbeforecopyAttr, kNoWebFeature, event_type_names::kBeforecopy,
       nullptr},
      {kOnbeforecutAttr, kNoWebFeature, event_type_names::kBeforecut, nullptr},
      {kOnbeforepasteAttr, kNoWebFeature, event_type_names::kBeforepaste,
       nullptr},
      {kOnblurAttr, kNoWebFeature, event_type_names::kBlur, nullptr},
      {kOncancelAttr, kNoWebFeature, event_type_names::kCancel, nullptr},
      {kOncanplayAttr, kNoWebFeature, event_type_names::kCanplay, nullptr},
      {kOncanplaythroughAttr, kNoWebFeature, event_type_names::kCanplaythrough,
       nullptr},
      {kOnchangeAttr, kNoWebFeature, event_type_names::kChange, nullptr},
      {kOnclickAttr, kNoWebFeature, event_type_names::kClick, nullptr},
      {kOncloseAttr, kNoWebFeature, event_type_names::kClose, nullptr},
      {kOncontextmenuAttr, kNoWebFeature, event_type_names::kContextmenu,
       nullptr},
      {kOncopyAttr, kNoWebFeature, event_type_names::kCopy, nullptr},
      {kOncuechangeAttr, kNoWebFeature, event_type_names::kCuechange, nullptr},
      {kOncutAttr, kNoWebFeature, event_type_names::kCut, nullptr},
      {kOndblclickAttr, kNoWebFeature, event_type_names::kDblclick, nullptr},
      {kOndragAttr, kNoWebFeature, event_type_names::kDrag, nullptr},
      {kOndragendAttr, kNoWebFeature, event_type_names::kDragend, nullptr},
      {kOndragenterAttr, kNoWebFeature, event_type_names::kDragenter, nullptr},
      {kOndragleaveAttr, kNoWebFeature, event_type_names::kDragleave, nullptr},
      {kOndragoverAttr, kNoWebFeature, event_type_names::kDragover, nullptr},
      {kOndragstartAttr, kNoWebFeature, event_type_names::kDragstart, nullptr},
      {kOndropAttr, kNoWebFeature, event_type_names::kDrop, nullptr},
      {kOndurationchangeAttr, kNoWebFeature, event_type_names::kDurationchange,
       nullptr},
      {kOnemptiedAttr, kNoWebFeature, event_type_names::kEmptied, nullptr},
      {kOnendedAttr, kNoWebFeature, event_type_names::kEnded, nullptr},
      {kOnerrorAttr, kNoWebFeature, event_type_names::kError, nullptr},
      {kOnfocusAttr, kNoWebFeature, event_type_names::kFocus, nullptr},
      {kOnfocusinAttr, kNoWebFeature, event_type_names::kFocusin, nullptr},
      {kOnfocusoutAttr, kNoWebFeature, event_type_names::kFocusout, nullptr},
      {kOnformdataAttr, kNoWebFeature, event_type_names::kFormdata, nullptr},
      {kOngotpointercaptureAttr, kNoWebFeature,
       event_type_names::kGotpointercapture, nullptr},
      {kOninputAttr, kNoWebFeature, event_type_names::kInput, nullptr},
      {kOninvalidAttr, kNoWebFeature, event_type_names::kInvalid, nullptr},
      {kOnkeydownAttr, kNoWebFeature, event_type_names::kKeydown, nullptr},
      {kOnkeypressAttr, kNoWebFeature, event_type_names::kKeypress, nullptr},
      {kOnkeyupAttr, kNoWebFeature, event_type_names::kKeyup, nullptr},
      {kOnloadAttr, kNoWebFeature, event_type_names::kLoad, nullptr},
      {kOnloadeddataAttr, kNoWebFeature, event_type_names::kLoadeddata,
       nullptr},
      {kOnloadedmetadataAttr, kNoWebFeature, event_type_names::kLoadedmetadata,
       nullptr},
      {kOnloadstartAttr, kNoWebFeature, event_type_names::kLoadstart, nullptr},
      {kOnlostpointercaptureAttr, kNoWebFeature,
       event_type_names::kLostpointercapture, nullptr},
      {kOnmousedownAttr, kNoWebFeature, event_type_names::kMousedown, nullptr},
      {kOnmouseenterAttr, kNoWebFeature, event_type_names::kMouseenter,
       nullptr},
      {kOnmouseleaveAttr, kNoWebFeature, event_type_names::kMouseleave,
       nullptr},
      {kOnmousemoveAttr, kNoWebFeature, event_type_names::kMousemove, nullptr},
      {kOnmouseoutAttr, kNoWebFeature, event_type_names::kMouseout, nullptr},
      {kOnmouseoverAttr, kNoWebFeature, event_type_names::kMouseover, nullptr},
      {kOnmouseupAttr, kNoWebFeature, event_type_names::kMouseup, nullptr},
      {kOnmousewheelAttr, kNoWebFeature, event_type_names::kMousewheel,
       nullptr},
      {kOnoverscrollAttr, kNoWebFeature, event_type_names::kOverscroll,
       nullptr},
      {kOnpasteAttr, kNoWebFeature, event_type_names::kPaste, nullptr},
      {kOnpauseAttr, kNoWebFeature, event_type_names::kPause, nullptr},
      {kOnplayAttr, kNoWebFeature, event_type_names::kPlay, nullptr},
      {kOnplayingAttr, kNoWebFeature, event_type_names::kPlaying, nullptr},
      {kOnpointercancelAttr, kNoWebFeature, event_type_names::kPointercancel,
       nullptr},
      {kOnpointerdownAttr, kNoWebFeature, event_type_names::kPointerdown,
       nullptr},
      {kOnpointerenterAttr, kNoWebFeature, event_type_names::kPointerenter,
       nullptr},
      {kOnpointerleaveAttr, kNoWebFeature, event_type_names::kPointerleave,
       nullptr},
      {kOnpointermoveAttr, kNoWebFeature, event_type_names::kPointermove,
       nullptr},
      {kOnpointeroutAttr, kNoWebFeature, event_type_names::kPointerout,
       nullptr},
      {kOnpointeroverAttr, kNoWebFeature, event_type_names::kPointerover,
       nullptr},
      {kOnpointerrawmoveAttr, kNoWebFeature, event_type_names::kPointerrawmove,
       nullptr},
      {kOnpointerupAttr, kNoWebFeature, event_type_names::kPointerup, nullptr},
      {kOnprogressAttr, kNoWebFeature, event_type_names::kProgress, nullptr},
      {kOnratechangeAttr, kNoWebFeature, event_type_names::kRatechange,
       nullptr},
      {kOnresetAttr, kNoWebFeature, event_type_names::kReset, nullptr},
      {kOnresizeAttr, kNoWebFeature, event_type_names::kResize, nullptr},
      {kOnscrollAttr, kNoWebFeature, event_type_names::kScroll, nullptr},
      {kOnscrollendAttr, kNoWebFeature, event_type_names::kScrollend, nullptr},
      {kOnseekedAttr, kNoWebFeature, event_type_names::kSeeked, nullptr},
      {kOnseekingAttr, kNoWebFeature, event_type_names::kSeeking, nullptr},
      {kOnselectAttr, kNoWebFeature, event_type_names::kSelect, nullptr},
      {kOnselectstartAttr, kNoWebFeature, event_type_names::kSelectstart,
       nullptr},
      {kOnstalledAttr, kNoWebFeature, event_type_names::kStalled, nullptr},
      {kOnsubmitAttr, kNoWebFeature, event_type_names::kSubmit, nullptr},
      {kOnsuspendAttr, kNoWebFeature, event_type_names::kSuspend, nullptr},
      {kOntimeupdateAttr, kNoWebFeature, event_type_names::kTimeupdate,
       nullptr},
      {kOntoggleAttr, kNoWebFeature, event_type_names::kToggle, nullptr},
      {kOntouchcancelAttr, kNoWebFeature, event_type_names::kTouchcancel,
       nullptr},
      {kOntouchendAttr, kNoWebFeature, event_type_names::kTouchend, nullptr},
      {kOntouchmoveAttr, kNoWebFeature, event_type_names::kTouchmove, nullptr},
      {kOntouchstartAttr, kNoWebFeature, event_type_names::kTouchstart,
       nullptr},
      {kOntransitionendAttr, kNoWebFeature,
       event_type_names::kWebkitTransitionEnd, nullptr},
      {kOnvolumechangeAttr, kNoWebFeature, event_type_names::kVolumechange,
       nullptr},
      {kOnwaitingAttr, kNoWebFeature, event_type_names::kWaiting, nullptr},
      {kOnwebkitanimationendAttr, kNoWebFeature,
       event_type_names::kWebkitAnimationEnd, nullptr},
      {kOnwebkitanimationiterationAttr, kNoWebFeature,
       event_type_names::kWebkitAnimationIteration, nullptr},
      {kOnwebkitanimationstartAttr, kNoWebFeature,
       event_type_names::kWebkitAnimationStart, nullptr},
      {kOnwebkitfullscreenchangeAttr, kNoWebFeature,
       event_type_names::kWebkitfullscreenchange, nullptr},
      {kOnwebkitfullscreenerrorAttr, kNoWebFeature,
       event_type_names::kWebkitfullscreenerror, nullptr},
      {kOnwebkittransitionendAttr, kNoWebFeature,
       event_type_names::kWebkitTransitionEnd, nullptr},
      {kOnwheelAttr, kNoWebFeature, event_type_names::kWheel, nullptr},

      {kAriaActivedescendantAttr, WebFeature::kARIAActiveDescendantAttribute,
       kNoEvent, nullptr},
      {kAriaAtomicAttr, WebFeature::kARIAAtomicAttribute, kNoEvent, nullptr},
      {kAriaAutocompleteAttr, WebFeature::kARIAAutocompleteAttribute, kNoEvent,
       nullptr},
      {kAriaBusyAttr, WebFeature::kARIABusyAttribute, kNoEvent, nullptr},
      {kAriaCheckedAttr, WebFeature::kARIACheckedAttribute, kNoEvent, nullptr},
      {kAriaColcountAttr, WebFeature::kARIAColCountAttribute, kNoEvent,
       nullptr},
      {kAriaColindexAttr, WebFeature::kARIAColIndexAttribute, kNoEvent,
       nullptr},
      {kAriaColspanAttr, WebFeature::kARIAColSpanAttribute, kNoEvent, nullptr},
      {kAriaControlsAttr, WebFeature::kARIAControlsAttribute, kNoEvent,
       nullptr},
      {kAriaCurrentAttr, WebFeature::kARIACurrentAttribute, kNoEvent, nullptr},
      {kAriaDescribedbyAttr, WebFeature::kARIADescribedByAttribute, kNoEvent,
       nullptr},
      {kAriaDetailsAttr, WebFeature::kARIADetailsAttribute, kNoEvent, nullptr},
      {kAriaDisabledAttr, WebFeature::kARIADisabledAttribute, kNoEvent,
       nullptr},
      {kAriaDropeffectAttr, WebFeature::kARIADropEffectAttribute, kNoEvent,
       nullptr},
      {kAriaErrormessageAttr, WebFeature::kARIAErrorMessageAttribute, kNoEvent,
       nullptr},
      {kAriaExpandedAttr, WebFeature::kARIAExpandedAttribute, kNoEvent,
       nullptr},
      {kAriaFlowtoAttr, WebFeature::kARIAFlowToAttribute, kNoEvent, nullptr},
      {kAriaGrabbedAttr, WebFeature::kARIAGrabbedAttribute, kNoEvent, nullptr},
      {kAriaHaspopupAttr, WebFeature::kARIAHasPopupAttribute, kNoEvent,
       nullptr},
      {kAriaHelpAttr, WebFeature::kARIAHelpAttribute, kNoEvent, nullptr},
      {kAriaHiddenAttr, WebFeature::kARIAHiddenAttribute, kNoEvent, nullptr},
      {kAriaInvalidAttr, WebFeature::kARIAInvalidAttribute, kNoEvent, nullptr},
      {kAriaKeyshortcutsAttr, WebFeature::kARIAKeyShortcutsAttribute, kNoEvent,
       nullptr},
      {kAriaLabelAttr, WebFeature::kARIALabelAttribute, kNoEvent, nullptr},
      {kAriaLabeledbyAttr, WebFeature::kARIALabeledByAttribute, kNoEvent,
       nullptr},
      {kAriaLabelledbyAttr, WebFeature::kARIALabelledByAttribute, kNoEvent,
       nullptr},
      {kAriaLevelAttr, WebFeature::kARIALevelAttribute, kNoEvent, nullptr},
      {kAriaLiveAttr, WebFeature::kARIALiveAttribute, kNoEvent, nullptr},
      {kAriaModalAttr, WebFeature::kARIAModalAttribute, kNoEvent, nullptr},
      {kAriaMultilineAttr, WebFeature::kARIAMultilineAttribute, kNoEvent,
       nullptr},
      {kAriaMultiselectableAttr, WebFeature::kARIAMultiselectableAttribute,
       kNoEvent, nullptr},
      {kAriaOrientationAttr, WebFeature::kARIAOrientationAttribute, kNoEvent,
       nullptr},
      {kAriaOwnsAttr, WebFeature::kARIAOwnsAttribute, kNoEvent, nullptr},
      {kAriaPlaceholderAttr, WebFeature::kARIAPlaceholderAttribute, kNoEvent,
       nullptr},
      {kAriaPosinsetAttr, WebFeature::kARIAPosInSetAttribute, kNoEvent,
       nullptr},
      {kAriaPressedAttr, WebFeature::kARIAPressedAttribute, kNoEvent, nullptr},
      {kAriaReadonlyAttr, WebFeature::kARIAReadOnlyAttribute, kNoEvent,
       nullptr},
      {kAriaRelevantAttr, WebFeature::kARIARelevantAttribute, kNoEvent,
       nullptr},
      {kAriaRequiredAttr, WebFeature::kARIARequiredAttribute, kNoEvent,
       nullptr},
      {kAriaRoledescriptionAttr, WebFeature::kARIARoleDescriptionAttribute,
       kNoEvent, nullptr},
      {kAriaRowcountAttr, WebFeature::kARIARowCountAttribute, kNoEvent,
       nullptr},
      {kAriaRowindexAttr, WebFeature::kARIARowIndexAttribute, kNoEvent,
       nullptr},
      {kAriaRowspanAttr, WebFeature::kARIARowSpanAttribute, kNoEvent, nullptr},
      {kAriaSelectedAttr, WebFeature::kARIASelectedAttribute, kNoEvent,
       nullptr},
      {kAriaSetsizeAttr, WebFeature::kARIASetSizeAttribute, kNoEvent, nullptr},
      {kAriaSortAttr, WebFeature::kARIASortAttribute, kNoEvent, nullptr},
      {kAriaValuemaxAttr, WebFeature::kARIAValueMaxAttribute, kNoEvent,
       nullptr},
      {kAriaValueminAttr, WebFeature::kARIAValueMinAttribute, kNoEvent,
       nullptr},
      {kAriaValuenowAttr, WebFeature::kARIAValueNowAttribute, kNoEvent,
       nullptr},
      {kAriaValuetextAttr, WebFeature::kARIAValueTextAttribute, kNoEvent,
       nullptr},
      {kAutocapitalizeAttr, WebFeature::kAutocapitalizeAttribute, kNoEvent,
       nullptr},
  };

  using AttributeToTriggerIndexMap = HashMap<QualifiedName, uint32_t>;
  DEFINE_STATIC_LOCAL(AttributeToTriggerIndexMap,
                      attribute_to_trigger_index_map, ());
  if (!attribute_to_trigger_index_map.size()) {
    for (uint32_t i = 0; i < base::size(attribute_triggers); ++i)
      attribute_to_trigger_index_map.insert(attribute_triggers[i].attribute, i);
  }

  auto iter = attribute_to_trigger_index_map.find(attr_name);
  if (iter != attribute_to_trigger_index_map.end())
    return &attribute_triggers[iter->value];
  return nullptr;
}

// static
const AtomicString& HTMLElement::EventNameForAttributeName(
    const QualifiedName& attr_name) {
  AttributeTriggers* triggers = TriggersForAttributeName(attr_name);
  if (triggers)
    return triggers->event;
  return g_null_atom;
}

void HTMLElement::AttributeChanged(const AttributeModificationParams& params) {
  Element::AttributeChanged(params);
  if (params.name == html_names::kDisabledAttr &&
      params.old_value.IsNull() != params.new_value.IsNull()) {
    if (IsFormAssociatedCustomElement()) {
      EnsureElementInternals().DisabledAttributeChanged();
      if (params.reason == AttributeModificationReason::kDirectly &&
          IsDisabledFormControl() &&
          AdjustedFocusedElementInTreeScope() == this)
        blur();
    }
    return;
  }
  if (params.reason != AttributeModificationReason::kDirectly)
    return;
  // adjustedFocusedElementInTreeScope() is not trivial. We should check
  // attribute names, then call adjustedFocusedElementInTreeScope().
  if (params.name == kHiddenAttr && !params.new_value.IsNull()) {
    if (AdjustedFocusedElementInTreeScope() == this)
      blur();
  } else if (params.name == kContenteditableAttr) {
    if (GetDocument().GetFrame()) {
      GetDocument()
          .GetFrame()
          ->GetSpellChecker()
          .RemoveSpellingAndGrammarMarkers(
              *this, SpellChecker::ElementsType::kOnlyNonEditable);
    }
    if (AdjustedFocusedElementInTreeScope() != this)
      return;
    // The attribute change may cause supportsFocus() to return false
    // for the element which had focus.
    //
    // TODO(tkent): We should avoid updating style.  We'd like to check only
    // DOM-level focusability here.
    GetDocument().UpdateStyleAndLayoutTreeForNode(this);
    if (!SupportsFocus())
      blur();
  }
}

void HTMLElement::ParseAttribute(const AttributeModificationParams& params) {
  AttributeTriggers* triggers = TriggersForAttributeName(params.name);
  if (!triggers)
    return;

  if (triggers->event != g_null_atom) {
    SetAttributeEventListener(
        triggers->event,
        CreateAttributeEventListener(this, params.name, params.new_value));
  }

  if (triggers->web_feature != kNoWebFeature) {
    // Count usage of attributes but ignore attributes in user agent shadow DOM.
    if (ShadowRoot* shadow = ContainingShadowRoot()) {
      if (shadow->IsUserAgent())
        UseCounter::Count(GetDocument(), triggers->web_feature);
    }
  }

  if (triggers->function)
    ((*this).*(triggers->function))(params);
}

DocumentFragment* HTMLElement::TextToFragment(const String& text,
                                              ExceptionState& exception_state) {
  DocumentFragment* fragment = DocumentFragment::Create(GetDocument());
  unsigned i, length = text.length();
  UChar c = 0;
  for (unsigned start = 0; start < length;) {
    // Find next line break.
    for (i = start; i < length; i++) {
      c = text[i];
      if (c == '\r' || c == '\n')
        break;
    }

    if (i > start) {
      fragment->AppendChild(
          Text::Create(GetDocument(), text.Substring(start, i - start)),
          exception_state);
      if (exception_state.HadException())
        return nullptr;
    }

    if (i == length)
      break;

    fragment->AppendChild(HTMLBRElement::Create(GetDocument()),
                          exception_state);
    if (exception_state.HadException())
      return nullptr;

    // Make sure \r\n doesn't result in two line breaks.
    if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
      i++;

    start = i + 1;  // Character after line break.
  }

  return fragment;
}

void HTMLElement::setInnerText(
    const StringOrTrustedScript& string_or_trusted_script,
    ExceptionState& exception_state) {
  String value;
  if (string_or_trusted_script.IsString())
    value = string_or_trusted_script.GetAsString();
  else if (string_or_trusted_script.IsTrustedScript())
    value = string_or_trusted_script.GetAsTrustedScript()->toString();
  setInnerText(value, exception_state);
}

void HTMLElement::setInnerText(
    const StringTreatNullAsEmptyStringOrTrustedScript& string_or_trusted_script,
    ExceptionState& exception_state) {
  StringOrTrustedScript tmp;
  if (string_or_trusted_script.IsString())
    tmp.SetString(string_or_trusted_script.GetAsString());
  else if (string_or_trusted_script.IsTrustedScript())
    tmp.SetTrustedScript(string_or_trusted_script.GetAsTrustedScript());
  setInnerText(tmp, exception_state);
}

void HTMLElement::innerText(
    StringTreatNullAsEmptyStringOrTrustedScript& result) {
  result.SetString(innerText());
}

void HTMLElement::innerText(StringOrTrustedScript& result) {
  result.SetString(innerText());
}

String HTMLElement::innerText() {
  return Element::innerText();
}

void HTMLElement::setInnerText(const String& text,
                               ExceptionState& exception_state) {
  // FIXME: This doesn't take whitespace collapsing into account at all.

  if (!text.Contains('\n') && !text.Contains('\r')) {
    if (text.IsEmpty()) {
      RemoveChildren();
      return;
    }
    ReplaceChildrenWithText(this, text, exception_state);
    return;
  }

  // Add text nodes and <br> elements.
  DocumentFragment* fragment = TextToFragment(text, exception_state);
  if (!exception_state.HadException())
    ReplaceChildrenWithFragment(this, fragment, exception_state);
}

void HTMLElement::setOuterText(const String& text,
                               ExceptionState& exception_state) {
  ContainerNode* parent = parentNode();
  if (!parent) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kNoModificationAllowedError,
        "The element has no parent.");
    return;
  }

  Node* prev = previousSibling();
  Node* next = nextSibling();
  Node* new_child = nullptr;

  // Convert text to fragment with <br> tags instead of linebreaks if needed.
  if (text.Contains('\r') || text.Contains('\n'))
    new_child = TextToFragment(text, exception_state);
  else
    new_child = Text::Create(GetDocument(), text);

  // textToFragment might cause mutation events.
  if (!parentNode())
    exception_state.ThrowDOMException(DOMExceptionCode::kHierarchyRequestError,
                                      "The element has no parent.");

  if (exception_state.HadException())
    return;

  parent->ReplaceChild(new_child, this, exception_state);

  Node* node = next ? next->previousSibling() : nullptr;
  if (!exception_state.HadException() && node && node->IsTextNode())
    MergeWithNextTextNode(ToText(node), exception_state);

  if (!exception_state.HadException() && prev && prev->IsTextNode())
    MergeWithNextTextNode(ToText(prev), exception_state);
}

void HTMLElement::ApplyAlignmentAttributeToStyle(
    const AtomicString& alignment,
    MutableCSSPropertyValueSet* style) {
  // Vertical alignment with respect to the current baseline of the text
  // right or left means floating images.
  CSSValueID float_value = CSSValueInvalid;
  CSSValueID vertical_align_value = CSSValueInvalid;

  if (DeprecatedEqualIgnoringCase(alignment, "absmiddle")) {
    vertical_align_value = CSSValueMiddle;
  } else if (DeprecatedEqualIgnoringCase(alignment, "absbottom")) {
    vertical_align_value = CSSValueBottom;
  } else if (DeprecatedEqualIgnoringCase(alignment, "left")) {
    float_value = CSSValueLeft;
    vertical_align_value = CSSValueTop;
  } else if (DeprecatedEqualIgnoringCase(alignment, "right")) {
    float_value = CSSValueRight;
    vertical_align_value = CSSValueTop;
  } else if (DeprecatedEqualIgnoringCase(alignment, "top")) {
    vertical_align_value = CSSValueTop;
  } else if (DeprecatedEqualIgnoringCase(alignment, "middle")) {
    vertical_align_value = CSSValueWebkitBaselineMiddle;
  } else if (DeprecatedEqualIgnoringCase(alignment, "center")) {
    vertical_align_value = CSSValueMiddle;
  } else if (DeprecatedEqualIgnoringCase(alignment, "bottom")) {
    vertical_align_value = CSSValueBaseline;
  } else if (DeprecatedEqualIgnoringCase(alignment, "texttop")) {
    vertical_align_value = CSSValueTextTop;
  }

  if (float_value != CSSValueInvalid)
    AddPropertyToPresentationAttributeStyle(style, CSSPropertyFloat,
                                            float_value);

  if (vertical_align_value != CSSValueInvalid)
    AddPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign,
                                            vertical_align_value);
}

bool HTMLElement::HasCustomFocusLogic() const {
  return false;
}

String HTMLElement::contentEditable() const {
  const AtomicString& value = FastGetAttribute(kContenteditableAttr);

  if (value.IsNull())
    return "inherit";
  if (value.IsEmpty() || DeprecatedEqualIgnoringCase(value, "true"))
    return "true";
  if (DeprecatedEqualIgnoringCase(value, "false"))
    return "false";
  if (DeprecatedEqualIgnoringCase(value, "plaintext-only"))
    return "plaintext-only";

  return "inherit";
}

void HTMLElement::setContentEditable(const String& enabled,
                                     ExceptionState& exception_state) {
  if (DeprecatedEqualIgnoringCase(enabled, "true"))
    setAttribute(kContenteditableAttr, "true");
  else if (DeprecatedEqualIgnoringCase(enabled, "false"))
    setAttribute(kContenteditableAttr, "false");
  else if (DeprecatedEqualIgnoringCase(enabled, "plaintext-only"))
    setAttribute(kContenteditableAttr, "plaintext-only");
  else if (DeprecatedEqualIgnoringCase(enabled, "inherit"))
    removeAttribute(kContenteditableAttr);
  else
    exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
                                      "The value provided ('" + enabled +
                                          "') is not one of 'true', 'false', "
                                          "'plaintext-only', or 'inherit'.");
}

const AtomicString& HTMLElement::autocapitalize() const {
  DEFINE_STATIC_LOCAL(const AtomicString, kOff, ("off"));
  DEFINE_STATIC_LOCAL(const AtomicString, kNone, ("none"));
  DEFINE_STATIC_LOCAL(const AtomicString, kCharacters, ("characters"));
  DEFINE_STATIC_LOCAL(const AtomicString, kWords, ("words"));
  DEFINE_STATIC_LOCAL(const AtomicString, kSentences, ("sentences"));

  const AtomicString& value = FastGetAttribute(kAutocapitalizeAttr);
  if (value.IsEmpty())
    return g_empty_atom;

  if (EqualIgnoringASCIICase(value, kNone) ||
      EqualIgnoringASCIICase(value, kOff))
    return kNone;
  if (EqualIgnoringASCIICase(value, kCharacters))
    return kCharacters;
  if (EqualIgnoringASCIICase(value, kWords))
    return kWords;
  // "sentences", "on", or an invalid value
  return kSentences;
}

void HTMLElement::setAutocapitalize(const AtomicString& value) {
  setAttribute(kAutocapitalizeAttr, value);
}

bool HTMLElement::isContentEditableForBinding() const {
  return IsEditingHost(*this) || IsEditable(*this);
}

bool HTMLElement::draggable() const {
  return DeprecatedEqualIgnoringCase(getAttribute(kDraggableAttr), "true");
}

void HTMLElement::setDraggable(bool value) {
  setAttribute(kDraggableAttr, value ? "true" : "false");
}

bool HTMLElement::spellcheck() const {
  return IsSpellCheckingEnabled();
}

void HTMLElement::setSpellcheck(bool enable) {
  setAttribute(kSpellcheckAttr, enable ? "true" : "false");
}

void HTMLElement::click() {
  DispatchSimulatedClick(nullptr, kSendNoEvents,
                         SimulatedClickCreationScope::kFromScript);
}

void HTMLElement::AccessKeyAction(bool send_mouse_events) {
  DispatchSimulatedClick(
      nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents);
}

String HTMLElement::title() const {
  return FastGetAttribute(kTitleAttr);
}

int HTMLElement::tabIndex() const {
  if (SupportsFocus())
    return Element::tabIndex();
  return -1;
}

TranslateAttributeMode HTMLElement::GetTranslateAttributeMode() const {
  const AtomicString& value = getAttribute(kTranslateAttr);

  if (value == g_null_atom)
    return kTranslateAttributeInherit;
  if (DeprecatedEqualIgnoringCase(value, "yes") ||
      DeprecatedEqualIgnoringCase(value, ""))
    return kTranslateAttributeYes;
  if (DeprecatedEqualIgnoringCase(value, "no"))
    return kTranslateAttributeNo;

  return kTranslateAttributeInherit;
}

bool HTMLElement::translate() const {
  for (const HTMLElement* element = this; element;
       element = Traversal<HTMLElement>::FirstAncestor(*element)) {
    TranslateAttributeMode mode = element->GetTranslateAttributeMode();
    if (mode != kTranslateAttributeInherit) {
      DCHECK(mode == kTranslateAttributeYes || mode == kTranslateAttributeNo);
      return mode == kTranslateAttributeYes;
    }
  }

  // Default on the root element is translate=yes.
  return true;
}

void HTMLElement::setTranslate(bool enable) {
  setAttribute(kTranslateAttr, enable ? "yes" : "no");
}

// Returns the conforming 'dir' value associated with the state the attribute is
// in (in its canonical case), if any, or the empty string if the attribute is
// in a state that has no associated keyword value or if the attribute is not in
// a defined state (e.g. the attribute is missing and there is no missing value
// default).
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#limited-to-only-known-values
static inline const AtomicString& ToValidDirValue(const AtomicString& value) {
  DEFINE_STATIC_LOCAL(const AtomicString, ltr_value, ("ltr"));
  DEFINE_STATIC_LOCAL(const AtomicString, rtl_value, ("rtl"));
  DEFINE_STATIC_LOCAL(const AtomicString, auto_value, ("auto"));

  if (DeprecatedEqualIgnoringCase(value, ltr_value))
    return ltr_value;
  if (DeprecatedEqualIgnoringCase(value, rtl_value))
    return rtl_value;
  if (DeprecatedEqualIgnoringCase(value, auto_value))
    return auto_value;
  return g_null_atom;
}

const AtomicString& HTMLElement::dir() {
  return ToValidDirValue(FastGetAttribute(kDirAttr));
}

void HTMLElement::setDir(const AtomicString& value) {
  setAttribute(kDirAttr, value);
}

HTMLFormElement* HTMLElement::FindFormAncestor() const {
  return Traversal<HTMLFormElement>::FirstAncestor(*this);
}

static inline bool ElementAffectsDirectionality(const Node* node) {
  return node->IsHTMLElement() && (IsHTMLBDIElement(ToHTMLElement(*node)) ||
                                   ToHTMLElement(*node).hasAttribute(kDirAttr));
}

void HTMLElement::ChildrenChanged(const ChildrenChange& change) {
  Element::ChildrenChanged(change);
  AdjustDirectionalityIfNeededAfterChildrenChanged(change);
}

bool HTMLElement::HasDirectionAuto() const {
  // <bdi> defaults to dir="auto"
  // https://html.spec.whatwg.org/multipage/semantics.html#the-bdi-element
  const AtomicString& direction = FastGetAttribute(kDirAttr);
  return (IsHTMLBDIElement(*this) && direction == g_null_atom) ||
         DeprecatedEqualIgnoringCase(direction, "auto");
}

TextDirection HTMLElement::DirectionalityIfhasDirAutoAttribute(
    bool& is_auto) const {
  is_auto = HasDirectionAuto();
  if (!is_auto)
    return TextDirection::kLtr;
  return Directionality();
}

TextDirection HTMLElement::Directionality(
    Node** strong_directionality_text_node) const {
  if (auto* input_element = ToHTMLInputElementOrNull(*this)) {
    bool has_strong_directionality;
    TextDirection text_direction = DetermineDirectionality(
        input_element->value(), &has_strong_directionality);
    if (strong_directionality_text_node) {
      *strong_directionality_text_node =
          has_strong_directionality
              ? const_cast<HTMLInputElement*>(input_element)
              : nullptr;
    }
    return text_direction;
  }

  Node* node = FlatTreeTraversal::FirstChild(*this);
  while (node) {
    // Skip bdi, script, style and text form controls.
    if (DeprecatedEqualIgnoringCase(node->nodeName(), "bdi") ||
        IsHTMLScriptElement(*node) || IsHTMLStyleElement(*node) ||
        (node->IsElementNode() && ToElement(node)->IsTextControl()) ||
        (node->IsElementNode() &&
         ToElement(node)->ShadowPseudoId() == "-webkit-input-placeholder")) {
      node = FlatTreeTraversal::NextSkippingChildren(*node, this);
      continue;
    }

    // Skip elements with valid dir attribute
    if (node->IsElementNode()) {
      AtomicString dir_attribute_value =
          ToElement(node)->FastGetAttribute(kDirAttr);
      if (IsValidDirAttribute(dir_attribute_value)) {
        node = FlatTreeTraversal::NextSkippingChildren(*node, this);
        continue;
      }
    }

    if (node->IsTextNode()) {
      bool has_strong_directionality;
      TextDirection text_direction = DetermineDirectionality(
          node->textContent(true), &has_strong_directionality);
      if (has_strong_directionality) {
        if (strong_directionality_text_node)
          *strong_directionality_text_node = node;
        return text_direction;
      }
    }
    node = FlatTreeTraversal::Next(*node, this);
  }
  if (strong_directionality_text_node)
    *strong_directionality_text_node = nullptr;
  return TextDirection::kLtr;
}

bool HTMLElement::SelfOrAncestorHasDirAutoAttribute() const {
  // TODO(esprehn): Storing this state in the computed style is bad, we
  // should be able to answer questions about the shape of the DOM and the
  // text contained inside it without having style.
  if (const ComputedStyle* style = GetComputedStyle())
    return style->SelfOrAncestorHasDirAutoAttribute();
  return false;
}

void HTMLElement::AdjustDirectionalityIfNeededAfterChildAttributeChanged(
    Element* child) {
  DCHECK(SelfOrAncestorHasDirAutoAttribute());
  const ComputedStyle* style = GetComputedStyle();
  if (style && style->Direction() != Directionality()) {
    for (Element* element_to_adjust = this; element_to_adjust;
         element_to_adjust =
             FlatTreeTraversal::ParentElement(*element_to_adjust)) {
      if (ElementAffectsDirectionality(element_to_adjust)) {
        element_to_adjust->SetNeedsStyleRecalc(
            kLocalStyleChange, StyleChangeReasonForTracing::Create(
                                   style_change_reason::kWritingModeChange));
        return;
      }
    }
  }
}

void HTMLElement::CalculateAndAdjustDirectionality() {
  TextDirection text_direction = Directionality();
  const ComputedStyle* style = GetComputedStyle();
  if (style && style->Direction() != text_direction) {
    SetNeedsStyleRecalc(kLocalStyleChange,
                        StyleChangeReasonForTracing::Create(
                            style_change_reason::kWritingModeChange));
  }
}

void HTMLElement::AdjustDirectionalityIfNeededAfterChildrenChanged(
    const ChildrenChange& change) {
  if (!SelfOrAncestorHasDirAutoAttribute())
    return;

  UpdateDistributionForFlatTreeTraversal();

  for (Element* element_to_adjust = this; element_to_adjust;
       element_to_adjust =
           FlatTreeTraversal::ParentElement(*element_to_adjust)) {
    if (ElementAffectsDirectionality(element_to_adjust)) {
      ToHTMLElement(element_to_adjust)->CalculateAndAdjustDirectionality();
      return;
    }
  }
}

Node::InsertionNotificationRequest HTMLElement::InsertedInto(
    ContainerNode& insertion_point) {
  // Process the superclass first to ensure that `InActiveDocument()` is
  // updated.
  Element::InsertedInto(insertion_point);

  if (GetDocument().GetContentSecurityPolicy()->HasHeaderDeliveredPolicy() &&
      InActiveDocument() && FastHasAttribute(kNonceAttr)) {
    setAttribute(kNonceAttr, g_empty_atom);
  }
  if (IsFormAssociatedCustomElement())
    EnsureElementInternals().InsertedInto(insertion_point);

  return kInsertionDone;
}

void HTMLElement::RemovedFrom(ContainerNode& insertion_point) {
  Element::RemovedFrom(insertion_point);
  if (IsFormAssociatedCustomElement())
    EnsureElementInternals().RemovedFrom(insertion_point);
}

void HTMLElement::DidMoveToNewDocument(Document& old_document) {
  if (IsFormAssociatedCustomElement())
    EnsureElementInternals().DidMoveToNewDocument(old_document);
  Element::DidMoveToNewDocument(old_document);
}

void HTMLElement::AddHTMLLengthToStyle(MutableCSSPropertyValueSet* style,
                                       CSSPropertyID property_id,
                                       const String& value,
                                       AllowPercentage allow_percentage) {
  HTMLDimension dimension;
  if (!ParseDimensionValue(value, dimension))
    return;
  if (property_id == CSSPropertyWidth &&
      (dimension.IsPercentage() || dimension.IsRelative())) {
    UseCounter::Count(GetDocument(), WebFeature::kHTMLElementDeprecatedWidth);
  }
  if (dimension.IsRelative())
    return;
  if (dimension.IsPercentage() && allow_percentage != kAllowPercentageValues)
    return;
  CSSPrimitiveValue::UnitType unit =
      dimension.IsPercentage() ? CSSPrimitiveValue::UnitType::kPercentage
                               : CSSPrimitiveValue::UnitType::kPixels;
  AddPropertyToPresentationAttributeStyle(style, property_id, dimension.Value(),
                                          unit);
}

static RGBA32 ParseColorStringWithCrazyLegacyRules(const String& color_string) {
  // Per spec, only look at the first 128 digits of the string.
  const size_t kMaxColorLength = 128;
  // We'll pad the buffer with two extra 0s later, so reserve two more than the
  // max.
  Vector<char, kMaxColorLength + 2> digit_buffer;

  wtf_size_t i = 0;
  // Skip a leading #.
  if (color_string[0] == '#')
    i = 1;

  // Grab the first 128 characters, replacing non-hex characters with 0.
  // Non-BMP characters are replaced with "00" due to them appearing as two
  // "characters" in the String.
  for (; i < color_string.length() && digit_buffer.size() < kMaxColorLength;
       i++) {
    if (!IsASCIIHexDigit(color_string[i]))
      digit_buffer.push_back('0');
    else
      digit_buffer.push_back(color_string[i]);
  }

  if (!digit_buffer.size())
    return Color::kBlack;

  // Pad the buffer out to at least the next multiple of three in size.
  digit_buffer.push_back('0');
  digit_buffer.push_back('0');

  if (digit_buffer.size() < 6)
    return MakeRGB(ToASCIIHexValue(digit_buffer[0]),
                   ToASCIIHexValue(digit_buffer[1]),
                   ToASCIIHexValue(digit_buffer[2]));

  // Split the digits into three components, then search the last 8 digits of
  // each component.
  DCHECK_GE(digit_buffer.size(), 6u);
  wtf_size_t component_length = digit_buffer.size() / 3;
  wtf_size_t component_search_window_length =
      std::min<wtf_size_t>(component_length, 8);
  wtf_size_t red_index = component_length - component_search_window_length;
  wtf_size_t green_index =
      component_length * 2 - component_search_window_length;
  wtf_size_t blue_index = component_length * 3 - component_search_window_length;
  // Skip digits until one of them is non-zero, or we've only got two digits
  // left in the component.
  while (digit_buffer[red_index] == '0' && digit_buffer[green_index] == '0' &&
         digit_buffer[blue_index] == '0' &&
         (component_length - red_index) > 2) {
    red_index++;
    green_index++;
    blue_index++;
  }
  DCHECK_LT(red_index + 1, component_length);
  DCHECK_GE(green_index, component_length);
  DCHECK_LT(green_index + 1, component_length * 2);
  DCHECK_GE(blue_index, component_length * 2);
  SECURITY_DCHECK(blue_index + 1 < digit_buffer.size());

  int red_value =
      ToASCIIHexValue(digit_buffer[red_index], digit_buffer[red_index + 1]);
  int green_value =
      ToASCIIHexValue(digit_buffer[green_index], digit_buffer[green_index + 1]);
  int blue_value =
      ToASCIIHexValue(digit_buffer[blue_index], digit_buffer[blue_index + 1]);
  return MakeRGB(red_value, green_value, blue_value);
}

// Color parsing that matches HTML's "rules for parsing a legacy color value"
bool HTMLElement::ParseColorWithLegacyRules(const String& attribute_value,
                                            Color& parsed_color) {
  // An empty string doesn't apply a color. (One containing only whitespace
  // does, which is why this check occurs before stripping.)
  if (attribute_value.IsEmpty())
    return false;

  String color_string = attribute_value.StripWhiteSpace();

  // "transparent" doesn't apply a color either.
  if (DeprecatedEqualIgnoringCase(color_string, "transparent"))
    return false;

  // If the string is a 3/6-digit hex color or a named CSS color, use that.
  // Apply legacy rules otherwise. Note color.setFromString() accepts 4/8-digit
  // hex color, so restrict its use with length checks here to support legacy
  // HTML attributes.

  bool success = false;
  if ((color_string.length() == 4 || color_string.length() == 7) &&
      color_string[0] == '#')
    success = parsed_color.SetFromString(color_string);
  if (!success)
    success = parsed_color.SetNamedColor(color_string);
  if (!success) {
    parsed_color.SetRGB(ParseColorStringWithCrazyLegacyRules(color_string));
    success = true;
  }

  return success;
}

void HTMLElement::AddHTMLColorToStyle(MutableCSSPropertyValueSet* style,
                                      CSSPropertyID property_id,
                                      const String& attribute_value) {
  Color parsed_color;
  if (!ParseColorWithLegacyRules(attribute_value, parsed_color))
    return;

  style->SetProperty(property_id, *CSSColorValue::Create(parsed_color.Rgb()));
}

LabelsNodeList* HTMLElement::labels() {
  if (!IsLabelable())
    return nullptr;
  return EnsureCachedCollection<LabelsNodeList>(kLabelsNodeListType);
}

bool HTMLElement::IsInteractiveContent() const {
  return false;
}

void HTMLElement::DefaultEventHandler(Event& event) {
  if (event.type() == event_type_names::kKeypress && event.IsKeyboardEvent()) {
    HandleKeypressEvent(ToKeyboardEvent(event));
    if (event.DefaultHandled())
      return;
  }

  Element::DefaultEventHandler(event);
}

bool HTMLElement::MatchesReadOnlyPseudoClass() const {
  return !MatchesReadWritePseudoClass();
}

bool HTMLElement::MatchesReadWritePseudoClass() const {
  if (FastHasAttribute(kContenteditableAttr)) {
    const AtomicString& value = FastGetAttribute(kContenteditableAttr);

    if (value.IsEmpty() || DeprecatedEqualIgnoringCase(value, "true") ||
        DeprecatedEqualIgnoringCase(value, "plaintext-only"))
      return true;
    if (DeprecatedEqualIgnoringCase(value, "false"))
      return false;
    // All other values should be treated as "inherit".
  }

  return parentElement() && HasEditableStyle(*parentElement());
}

void HTMLElement::HandleKeypressEvent(KeyboardEvent& event) {
  if (!IsSpatialNavigationEnabled(GetDocument().GetFrame()) || !SupportsFocus())
    return;
  GetDocument().UpdateStyleAndLayoutTree();
  // if the element is a text form control (like <input type=text> or
  // <textarea>) or has contentEditable attribute on, we should enter a space or
  // newline even in spatial navigation mode instead of handling it as a "click"
  // action.
  if (IsTextControl() || HasEditableStyle(*this))
    return;
  int char_code = event.charCode();
  if (char_code == '\r' || char_code == ' ') {
    DispatchSimulatedClick(&event);
    event.SetDefaultHandled();
  }
}

int HTMLElement::offsetLeftForBinding() {
  GetDocument().EnsurePaintLocationDataValidForNode(this);
  Element* offset_parent = unclosedOffsetParent();
  if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
    return AdjustForAbsoluteZoom::AdjustLayoutUnit(
               LayoutUnit(layout_object->PixelSnappedOffsetLeft(offset_parent)),
               layout_object->StyleRef())
        .Round();
  return 0;
}

int HTMLElement::offsetTopForBinding() {
  GetDocument().EnsurePaintLocationDataValidForNode(this);
  Element* offset_parent = unclosedOffsetParent();
  if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
    return AdjustForAbsoluteZoom::AdjustLayoutUnit(
               LayoutUnit(layout_object->PixelSnappedOffsetTop(offset_parent)),
               layout_object->StyleRef())
        .Round();
  return 0;
}

int HTMLElement::offsetWidthForBinding() {
  GetDocument().EnsurePaintLocationDataValidForNode(this);
  Element* offset_parent = unclosedOffsetParent();
  if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
    return AdjustForAbsoluteZoom::AdjustLayoutUnit(
               LayoutUnit(
                   layout_object->PixelSnappedOffsetWidth(offset_parent)),
               layout_object->StyleRef())
        .Round();
  return 0;
}

DISABLE_CFI_PERF
int HTMLElement::offsetHeightForBinding() {
  GetDocument().EnsurePaintLocationDataValidForNode(this);
  Element* offset_parent = unclosedOffsetParent();
  if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
    return AdjustForAbsoluteZoom::AdjustLayoutUnit(
               LayoutUnit(
                   layout_object->PixelSnappedOffsetHeight(offset_parent)),
               layout_object->StyleRef())
        .Round();
  return 0;
}

Element* HTMLElement::unclosedOffsetParent() {
  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);

  LayoutObject* layout_object = GetLayoutObject();
  if (!layout_object)
    return nullptr;

  return layout_object->OffsetParent(this);
}

void HTMLElement::OnDirAttrChanged(const AttributeModificationParams& params) {
  // If an ancestor has dir=auto, and this node has the first character,
  // changes to dir attribute may affect the ancestor.
  if (!CanParticipateInFlatTree())
    return;
  UpdateDistributionForFlatTreeTraversal();
  Element* parent = FlatTreeTraversal::ParentElement(*this);
  if (parent && parent->IsHTMLElement() &&
      ToHTMLElement(parent)->SelfOrAncestorHasDirAutoAttribute()) {
    ToHTMLElement(parent)
        ->AdjustDirectionalityIfNeededAfterChildAttributeChanged(this);
  }

  if (DeprecatedEqualIgnoringCase(params.new_value, "auto"))
    CalculateAndAdjustDirectionality();
}

void HTMLElement::OnFormAttrChanged(const AttributeModificationParams& params) {
  if (IsFormAssociatedCustomElement())
    EnsureElementInternals().FormAttributeChanged();
}

void HTMLElement::OnInertAttrChanged(
    const AttributeModificationParams& params) {
  UpdateDistributionForUnknownReasons();
  if (GetDocument().GetFrame()) {
    GetDocument().GetFrame()->SetIsInert(GetDocument().LocalOwner() &&
                                         GetDocument().LocalOwner()->IsInert());
  }
}

void HTMLElement::OnLangAttrChanged(const AttributeModificationParams& params) {
  PseudoStateChanged(CSSSelector::kPseudoLang);
}

void HTMLElement::OnNonceAttrChanged(
    const AttributeModificationParams& params) {
  if (params.new_value != g_empty_atom)
    setNonce(params.new_value);
}

void HTMLElement::OnTabIndexAttrChanged(
    const AttributeModificationParams& params) {
  Element::ParseAttribute(params);
}

void HTMLElement::OnXMLLangAttrChanged(
    const AttributeModificationParams& params) {
  Element::ParseAttribute(params);
}

ElementInternals* HTMLElement::attachInternals(
    ExceptionState& exception_state) {
  CustomElementRegistry* registry = CustomElement::Registry(*this);
  auto* definition =
      registry ? registry->DefinitionForName(localName()) : nullptr;
  if (!definition) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "Unable to attach ElementInternals to non-custom elements.");
    return nullptr;
  }
  if (!definition->Descriptor().IsAutonomous()) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "Unable to attach ElementInternals to a customized built-in element.");
    return nullptr;
  }
  if (definition->DisableInternals()) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "ElementInternals is disabled by disabledFeature static field.");
    return nullptr;
  }
  if (DidAttachInternals()) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "ElementInternals for the specified element was already attached.");
    return nullptr;
  }
  SetDidAttachInternals();
  return &EnsureElementInternals();
}

bool HTMLElement::IsFormAssociatedCustomElement() const {
  return GetCustomElementState() == CustomElementState::kCustom &&
         GetCustomElementDefinition()->IsFormAssociated();
}

bool HTMLElement::SupportsFocus() const {
  return Element::SupportsFocus() && !IsDisabledFormControl();
};

bool HTMLElement::IsDisabledFormControl() const {
  if (!IsFormAssociatedCustomElement())
    return false;
  return const_cast<HTMLElement*>(this)
      ->EnsureElementInternals()
      .IsActuallyDisabled();
}

bool HTMLElement::MatchesEnabledPseudoClass() const {
  return IsFormAssociatedCustomElement() && !const_cast<HTMLElement*>(this)
                                                 ->EnsureElementInternals()
                                                 .IsActuallyDisabled();
}

bool HTMLElement::MatchesValidityPseudoClasses() const {
  return IsFormAssociatedCustomElement();
}

bool HTMLElement::IsValidElement() {
  return IsFormAssociatedCustomElement() &&
         EnsureElementInternals().IsValidElement();
}

}  // namespace blink

#ifndef NDEBUG

// For use in the debugger
void dumpInnerHTML(blink::HTMLElement*);

void dumpInnerHTML(blink::HTMLElement* element) {
  printf("%s\n", element->InnerHTMLAsString().Ascii().data());
}
#endif
