blob: 39dd7c48a396d25e657bedc1f281b3bde905b812 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/dom/element_rare_data_vector.h"
#include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/aom/accessible_node.h"
#include "third_party/blink/renderer/core/css/container_query_data.h"
#include "third_party/blink/renderer/core/css/cssom/inline_style_property_map.h"
#include "third_party/blink/renderer/core/css/inline_css_style_declaration.h"
#include "third_party/blink/renderer/core/css/out_of_flow_data.h"
#include "third_party/blink/renderer/core/css/style_scope_data.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
#include "third_party/blink/renderer/core/dom/attr.h"
#include "third_party/blink/renderer/core/dom/dataset_dom_string_map.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/has_invalidation_flags.h"
#include "third_party/blink/renderer/core/dom/named_node_map.h"
#include "third_party/blink/renderer/core/dom/names_map.h"
#include "third_party/blink/renderer/core/dom/node_rare_data.h"
#include "third_party/blink/renderer/core/dom/popover_data.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/space_split_string.h"
#include "third_party/blink/renderer/core/editing/ime/edit_context.h"
#include "third_party/blink/renderer/core/html/anchor_element_observer.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_definition.h"
#include "third_party/blink/renderer/core/html/custom/element_internals.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h"
#include "third_party/blink/renderer/core/layout/anchor_position_scroll_data.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observation.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
namespace blink {
ElementRareDataVector::ElementRareDataVector() = default;
ElementRareDataVector::~ElementRareDataVector() {
DCHECK(!GetField(FieldId::kPseudoElementData));
}
unsigned ElementRareDataVector::GetFieldIndex(FieldId field_id) const {
unsigned field_id_int = static_cast<unsigned>(field_id);
DCHECK(fields_bitfield_ & (static_cast<BitfieldType>(1) << field_id_int));
return __builtin_popcount(fields_bitfield_ &
~(~static_cast<BitfieldType>(0) << field_id_int));
}
ElementRareDataField* ElementRareDataVector::GetField(FieldId field_id) const {
if (fields_bitfield_ &
(static_cast<BitfieldType>(1) << static_cast<unsigned>(field_id)))
return fields_[GetFieldIndex(field_id)].Get();
return nullptr;
}
void ElementRareDataVector::SetField(FieldId field_id,
ElementRareDataField* field) {
unsigned field_id_int = static_cast<unsigned>(field_id);
if (fields_bitfield_ & (static_cast<BitfieldType>(1) << field_id_int)) {
if (field) {
fields_[GetFieldIndex(field_id)] = field;
} else {
fields_.EraseAt(GetFieldIndex(field_id));
fields_bitfield_ =
fields_bitfield_ & ~(static_cast<BitfieldType>(1) << field_id_int);
}
} else if (field) {
fields_bitfield_ =
fields_bitfield_ | (static_cast<BitfieldType>(1) << field_id_int);
fields_.insert(GetFieldIndex(field_id), field);
}
}
bool ElementRareDataVector::HasPseudoElements() const {
PseudoElementData* data =
static_cast<PseudoElementData*>(GetField(FieldId::kPseudoElementData));
if (!data)
return false;
return data->HasPseudoElements();
}
void ElementRareDataVector::ClearPseudoElements() {
PseudoElementData* data =
static_cast<PseudoElementData*>(GetField(FieldId::kPseudoElementData));
if (data) {
data->ClearPseudoElements();
SetField(FieldId::kPseudoElementData, nullptr);
}
}
void ElementRareDataVector::SetPseudoElement(
PseudoId pseudo_id,
PseudoElement* element,
const AtomicString& document_transition_tag) {
PseudoElementData* data =
static_cast<PseudoElementData*>(GetField(FieldId::kPseudoElementData));
if (!data) {
if (!element)
return;
data = MakeGarbageCollected<PseudoElementData>();
SetField(FieldId::kPseudoElementData, data);
}
data->SetPseudoElement(pseudo_id, element, document_transition_tag);
}
PseudoElement* ElementRareDataVector::GetPseudoElement(
PseudoId pseudo_id,
const AtomicString& document_transition_tag) const {
PseudoElementData* data =
static_cast<PseudoElementData*>(GetField(FieldId::kPseudoElementData));
if (!data)
return nullptr;
return data->GetPseudoElement(pseudo_id, document_transition_tag);
}
PseudoElementData::PseudoElementVector
ElementRareDataVector::GetPseudoElements() const {
PseudoElementData* data =
static_cast<PseudoElementData*>(GetField(FieldId::kPseudoElementData));
if (!data)
return {};
return data->GetPseudoElements();
}
CSSStyleDeclaration& ElementRareDataVector::EnsureInlineCSSStyleDeclaration(
Element* owner_element) {
return EnsureField<InlineCSSStyleDeclaration>(FieldId::kCssomWrapper,
owner_element);
}
ShadowRoot* ElementRareDataVector::GetShadowRoot() const {
return static_cast<ShadowRoot*>(GetField(FieldId::kShadowRoot));
}
void ElementRareDataVector::SetShadowRoot(ShadowRoot& shadow_root) {
DCHECK(!GetField(FieldId::kShadowRoot));
SetField(FieldId::kShadowRoot, &shadow_root);
}
NamedNodeMap* ElementRareDataVector::AttributeMap() const {
return static_cast<NamedNodeMap*>(GetField(FieldId::kAttributeMap));
}
void ElementRareDataVector::SetAttributeMap(NamedNodeMap* attribute_map) {
SetField(FieldId::kAttributeMap, attribute_map);
}
DOMTokenList* ElementRareDataVector::GetClassList() const {
return static_cast<DOMTokenList*>(GetField(FieldId::kClassList));
}
void ElementRareDataVector::SetClassList(DOMTokenList* class_list) {
SetField(FieldId::kClassList, class_list);
}
DatasetDOMStringMap* ElementRareDataVector::Dataset() const {
return static_cast<DatasetDOMStringMap*>(GetField(FieldId::kDataset));
}
void ElementRareDataVector::SetDataset(DatasetDOMStringMap* dataset) {
SetField(FieldId::kDataset, dataset);
}
ScrollOffset ElementRareDataVector::SavedLayerScrollOffset() const {
if (auto* value =
GetWrappedField<ScrollOffset>(FieldId::kSavedLayerScrollOffset)) {
return *value;
}
static ScrollOffset offset;
return offset;
}
void ElementRareDataVector::SetSavedLayerScrollOffset(ScrollOffset offset) {
SetWrappedField<ScrollOffset>(FieldId::kSavedLayerScrollOffset, offset);
}
ElementAnimations* ElementRareDataVector::GetElementAnimations() {
return static_cast<ElementAnimations*>(GetField(FieldId::kElementAnimations));
}
void ElementRareDataVector::SetElementAnimations(
ElementAnimations* element_animations) {
SetField(FieldId::kElementAnimations, element_animations);
}
AttrNodeList& ElementRareDataVector::EnsureAttrNodeList() {
return EnsureWrappedField<AttrNodeList>(FieldId::kAttrNodeList);
}
AttrNodeList* ElementRareDataVector::GetAttrNodeList() {
return GetWrappedField<AttrNodeList>(FieldId::kAttrNodeList);
}
void ElementRareDataVector::RemoveAttrNodeList() {
SetField(FieldId::kAttrNodeList, nullptr);
}
void ElementRareDataVector::AddAttr(Attr* attr) {
EnsureAttrNodeList().push_back(attr);
}
ElementIntersectionObserverData*
ElementRareDataVector::IntersectionObserverData() const {
return static_cast<ElementIntersectionObserverData*>(
GetField(FieldId::kIntersectionObserverData));
}
ElementIntersectionObserverData&
ElementRareDataVector::EnsureIntersectionObserverData() {
return EnsureField<ElementIntersectionObserverData>(
FieldId::kIntersectionObserverData);
}
ContainerQueryEvaluator* ElementRareDataVector::GetContainerQueryEvaluator()
const {
ContainerQueryData* container_query_data = GetContainerQueryData();
if (!container_query_data)
return nullptr;
return container_query_data->GetContainerQueryEvaluator();
}
void ElementRareDataVector::SetContainerQueryEvaluator(
ContainerQueryEvaluator* evaluator) {
ContainerQueryData* container_query_data = GetContainerQueryData();
if (container_query_data)
container_query_data->SetContainerQueryEvaluator(evaluator);
else if (evaluator)
EnsureContainerQueryData().SetContainerQueryEvaluator(evaluator);
}
const AtomicString& ElementRareDataVector::GetNonce() const {
auto* value = GetWrappedField<AtomicString>(FieldId::kNonce);
return value ? *value : g_null_atom;
}
void ElementRareDataVector::SetNonce(const AtomicString& nonce) {
SetWrappedField<AtomicString>(FieldId::kNonce, nonce);
}
const AtomicString& ElementRareDataVector::IsValue() const {
auto* value = GetWrappedField<AtomicString>(FieldId::kIsValue);
return value ? *value : g_null_atom;
}
void ElementRareDataVector::SetIsValue(const AtomicString& is_value) {
SetWrappedField<AtomicString>(FieldId::kIsValue, is_value);
}
EditContext* ElementRareDataVector::GetEditContext() const {
return static_cast<EditContext*>(GetField(FieldId::kEditContext));
}
void ElementRareDataVector::SetEditContext(EditContext* edit_context) {
SetField(FieldId::kEditContext, edit_context);
}
void ElementRareDataVector::SetPart(DOMTokenList* part) {
SetField(FieldId::kPart, part);
}
DOMTokenList* ElementRareDataVector::GetPart() const {
return static_cast<DOMTokenList*>(GetField(FieldId::kPart));
}
void ElementRareDataVector::SetPartNamesMap(const AtomicString part_names) {
EnsureWrappedField<NamesMap>(FieldId::kPartNamesMap).Set(part_names);
}
const NamesMap* ElementRareDataVector::PartNamesMap() const {
return GetWrappedField<NamesMap>(FieldId::kPartNamesMap);
}
InlineStylePropertyMap& ElementRareDataVector::EnsureInlineStylePropertyMap(
Element* owner_element) {
return EnsureField<InlineStylePropertyMap>(FieldId::kCssomMapWrapper,
owner_element);
}
InlineStylePropertyMap* ElementRareDataVector::GetInlineStylePropertyMap() {
return static_cast<InlineStylePropertyMap*>(
GetField(FieldId::kCssomMapWrapper));
}
const ElementInternals* ElementRareDataVector::GetElementInternals() const {
return static_cast<ElementInternals*>(GetField(FieldId::kElementInternals));
}
ElementInternals& ElementRareDataVector::EnsureElementInternals(
HTMLElement& target) {
return EnsureField<ElementInternals>(FieldId::kElementInternals, target);
}
AccessibleNode* ElementRareDataVector::GetAccessibleNode() const {
return static_cast<AccessibleNode*>(GetField(FieldId::kAccessibleNode));
}
AccessibleNode* ElementRareDataVector::EnsureAccessibleNode(
Element* owner_element) {
return &EnsureField<AccessibleNode>(FieldId::kAccessibleNode, owner_element);
}
void ElementRareDataVector::ClearAccessibleNode() {
SetField(FieldId::kAccessibleNode, nullptr);
}
DisplayLockContext* ElementRareDataVector::EnsureDisplayLockContext(
Element* element) {
return &EnsureField<DisplayLockContext>(FieldId::kDisplayLockContext,
element);
}
DisplayLockContext* ElementRareDataVector::GetDisplayLockContext() const {
return static_cast<DisplayLockContext*>(
GetField(FieldId::kDisplayLockContext));
}
ContainerQueryData& ElementRareDataVector::EnsureContainerQueryData() {
return EnsureField<ContainerQueryData>(FieldId::kContainerQueryData);
}
ContainerQueryData* ElementRareDataVector::GetContainerQueryData() const {
return static_cast<ContainerQueryData*>(
GetField(FieldId::kContainerQueryData));
}
void ElementRareDataVector::ClearContainerQueryData() {
SetField(FieldId::kContainerQueryData, nullptr);
}
StyleScopeData& ElementRareDataVector::EnsureStyleScopeData() {
return EnsureField<StyleScopeData>(FieldId::kStyleScopeData);
}
StyleScopeData* ElementRareDataVector::GetStyleScopeData() const {
return static_cast<StyleScopeData*>(GetField(FieldId::kStyleScopeData));
}
OutOfFlowData& ElementRareDataVector::EnsureOutOfFlowData() {
return EnsureField<OutOfFlowData>(FieldId::kOutOfFlowData);
}
OutOfFlowData* ElementRareDataVector::GetOutOfFlowData() const {
return static_cast<OutOfFlowData*>(GetField(FieldId::kOutOfFlowData));
}
const RegionCaptureCropId* ElementRareDataVector::GetRegionCaptureCropId()
const {
auto* value = GetWrappedField<std::unique_ptr<RegionCaptureCropId>>(
FieldId::kRegionCaptureCropId);
return value ? value->get() : nullptr;
}
void ElementRareDataVector::SetRegionCaptureCropId(
std::unique_ptr<RegionCaptureCropId> crop_id) {
CHECK(!GetRegionCaptureCropId());
CHECK(crop_id);
CHECK(!crop_id->value().is_zero());
SetWrappedField<std::unique_ptr<RegionCaptureCropId>>(
FieldId::kRegionCaptureCropId, std::move(crop_id));
}
const RestrictionTargetId* ElementRareDataVector::GetRestrictionTargetId()
const {
auto* value = GetWrappedField<std::unique_ptr<RestrictionTargetId>>(
FieldId::kRestrictionTargetId);
return value ? value->get() : nullptr;
}
void ElementRareDataVector::SetRestrictionTargetId(
std::unique_ptr<RestrictionTargetId> id) {
CHECK(!GetRestrictionTargetId());
CHECK(id);
CHECK(!id->value().is_zero());
SetWrappedField<std::unique_ptr<RestrictionTargetId>>(
FieldId::kRestrictionTargetId, std::move(id));
}
ElementRareDataVector::ResizeObserverDataMap*
ElementRareDataVector::ResizeObserverData() const {
return GetWrappedField<ElementRareDataVector::ResizeObserverDataMap>(
FieldId::kResizeObserverData);
}
ElementRareDataVector::ResizeObserverDataMap&
ElementRareDataVector::EnsureResizeObserverData() {
return EnsureWrappedField<ElementRareDataVector::ResizeObserverDataMap>(
FieldId::kResizeObserverData);
}
void ElementRareDataVector::SetCustomElementDefinition(
CustomElementDefinition* definition) {
SetField(FieldId::kCustomElementDefinition, definition);
}
CustomElementDefinition* ElementRareDataVector::GetCustomElementDefinition()
const {
return static_cast<CustomElementDefinition*>(
GetField(FieldId::kCustomElementDefinition));
}
void ElementRareDataVector::SetLastRememberedBlockSize(
std::optional<LayoutUnit> size) {
SetOptionalField(FieldId::kLastRememberedBlockSize, size);
}
void ElementRareDataVector::SetLastRememberedInlineSize(
std::optional<LayoutUnit> size) {
SetOptionalField(FieldId::kLastRememberedInlineSize, size);
}
std::optional<LayoutUnit> ElementRareDataVector::LastRememberedBlockSize()
const {
return GetOptionalField<LayoutUnit>(FieldId::kLastRememberedBlockSize);
}
std::optional<LayoutUnit> ElementRareDataVector::LastRememberedInlineSize()
const {
return GetOptionalField<LayoutUnit>(FieldId::kLastRememberedInlineSize);
}
PopoverData* ElementRareDataVector::GetPopoverData() const {
return static_cast<PopoverData*>(GetField(FieldId::kPopoverData));
}
PopoverData& ElementRareDataVector::EnsurePopoverData() {
return EnsureField<PopoverData>(FieldId::kPopoverData);
}
void ElementRareDataVector::RemovePopoverData() {
SetField(FieldId::kPopoverData, nullptr);
}
AnchorPositionScrollData* ElementRareDataVector::GetAnchorPositionScrollData()
const {
return static_cast<AnchorPositionScrollData*>(
GetField(FieldId::kAnchorPositionScrollData));
}
void ElementRareDataVector::RemoveAnchorPositionScrollData() {
SetField(FieldId::kAnchorPositionScrollData, nullptr);
}
AnchorPositionScrollData& ElementRareDataVector::EnsureAnchorPositionScrollData(
Element* anchored_element) {
DCHECK(!GetAnchorPositionScrollData() ||
GetAnchorPositionScrollData()->AnchoredElement() == anchored_element);
return EnsureField<AnchorPositionScrollData>(
FieldId::kAnchorPositionScrollData, anchored_element);
}
AnchorElementObserver& ElementRareDataVector::EnsureAnchorElementObserver(
HTMLElement* element) {
DCHECK(!GetAnchorElementObserver() ||
GetAnchorElementObserver()->GetElement() == element);
return EnsureField<AnchorElementObserver>(FieldId::kAnchorElementObserver,
element);
}
AnchorElementObserver* ElementRareDataVector::GetAnchorElementObserver() const {
return static_cast<AnchorElementObserver*>(
GetField(FieldId::kAnchorElementObserver));
}
void ElementRareDataVector::IncrementImplicitlyAnchoredElementCount() {
EnsureWrappedField<wtf_size_t>(FieldId::kImplicitlyAnchoredElementCount)++;
}
void ElementRareDataVector::DecrementImplicitlyAnchoredElementCount() {
wtf_size_t& anchored_element_count =
EnsureWrappedField<wtf_size_t>(FieldId::kImplicitlyAnchoredElementCount);
DCHECK(anchored_element_count);
anchored_element_count--;
}
bool ElementRareDataVector::HasImplicitlyAnchoredElement() const {
wtf_size_t* anchored_element_count =
GetWrappedField<wtf_size_t>(FieldId::kImplicitlyAnchoredElementCount);
return anchored_element_count ? *anchored_element_count : false;
}
void ElementRareDataVector::Trace(blink::Visitor* visitor) const {
visitor->Trace(fields_);
NodeRareData::Trace(visitor);
}
} // namespace blink