diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-02-13 15:05:36 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-02-14 10:33:47 +0000 |
commit | e684a3455bcc29a6e3e66a004e352dea4e1141e7 (patch) | |
tree | d55b4003bde34d7d05f558f02cfd82b2a66a7aac /chromium/third_party/blink/renderer/core/dom | |
parent | 2b94bfe47ccb6c08047959d1c26e392919550e86 (diff) | |
download | qtwebengine-chromium-e684a3455bcc29a6e3e66a004e352dea4e1141e7.tar.gz |
BASELINE: Update Chromium to 72.0.3626.110 and Ninja to 1.9.0
Change-Id: Ic57220b00ecc929a893c91f5cc552f5d3e99e922
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/dom')
161 files changed, 2820 insertions, 2223 deletions
diff --git a/chromium/third_party/blink/renderer/core/dom/BUILD.gn b/chromium/third_party/blink/renderer/core/dom/BUILD.gn index a2dbb33214b..b9b40b4a345 100644 --- a/chromium/third_party/blink/renderer/core/dom/BUILD.gn +++ b/chromium/third_party/blink/renderer/core/dom/BUILD.gn @@ -139,6 +139,8 @@ blink_core_sources("dom") { "events/window_event_context.h", "first_letter_pseudo_element.cc", "first_letter_pseudo_element.h", + "flat_tree_node_data.cc", + "flat_tree_node_data.h", "flat_tree_traversal.cc", "flat_tree_traversal.h", "frame_request_callback_collection.cc", diff --git a/chromium/third_party/blink/renderer/core/dom/abort_signal.cc b/chromium/third_party/blink/renderer/core/dom/abort_signal.cc index 49b7a502ce7..b1774cbaf12 100644 --- a/chromium/third_party/blink/renderer/core/dom/abort_signal.cc +++ b/chromium/third_party/blink/renderer/core/dom/abort_signal.cc @@ -23,7 +23,7 @@ AbortSignal::AbortSignal(ExecutionContext* execution_context) AbortSignal::~AbortSignal() = default; const AtomicString& AbortSignal::InterfaceName() const { - return EventTargetNames::AbortSignal; + return event_target_names::kAbortSignal; } ExecutionContext* AbortSignal::GetExecutionContext() const { @@ -44,7 +44,7 @@ void AbortSignal::SignalAbort() { std::move(closure).Run(); } abort_algorithms_.clear(); - DispatchEvent(*Event::Create(EventTypeNames::abort)); + DispatchEvent(*Event::Create(event_type_names::kAbort)); } void AbortSignal::Follow(AbortSignal* parentSignal) { diff --git a/chromium/third_party/blink/renderer/core/dom/abort_signal.h b/chromium/third_party/blink/renderer/core/dom/abort_signal.h index 23cadde9933..65b7563ab06 100644 --- a/chromium/third_party/blink/renderer/core/dom/abort_signal.h +++ b/chromium/third_party/blink/renderer/core/dom/abort_signal.h @@ -26,7 +26,7 @@ class CORE_EXPORT AbortSignal final : public EventTargetWithInlineData { // abort_signal.idl bool aborted() const { return aborted_flag_; } - DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort); const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; diff --git a/chromium/third_party/blink/renderer/core/dom/attr.cc b/chromium/third_party/blink/renderer/core/dom/attr.cc index 25afd5d818b..392a07f3fbc 100644 --- a/chromium/third_party/blink/renderer/core/dom/attr.cc +++ b/chromium/third_party/blink/renderer/core/dom/attr.cc @@ -34,8 +34,6 @@ namespace blink { -using namespace HTMLNames; - Attr::Attr(Element& element, const QualifiedName& name) : Node(&element.GetDocument(), kCreateOther), element_(&element), diff --git a/chromium/third_party/blink/renderer/core/dom/character_data.cc b/chromium/third_party/blink/renderer/core/dom/character_data.cc index 8530b0e823e..aef50d33ebc 100644 --- a/chromium/third_party/blink/renderer/core/dom/character_data.cc +++ b/chromium/third_party/blink/renderer/core/dom/character_data.cc @@ -164,8 +164,8 @@ String CharacterData::nodeValue() const { return data_; } -bool CharacterData::ContainsOnlyWhitespace() const { - return data_.ContainsOnlyWhitespace(); +bool CharacterData::ContainsOnlyWhitespaceOrEmpty() const { + return data_.ContainsOnlyWhitespaceOrEmpty(); } void CharacterData::setNodeValue(const String& node_value) { @@ -216,7 +216,7 @@ void CharacterData::DidModifyData(const String& old_data, UpdateSource source) { if (GetDocument().HasListenerType( Document::kDOMCharacterDataModifiedListener)) { DispatchScopedEvent(*MutationEvent::Create( - EventTypeNames::DOMCharacterDataModified, Event::Bubbles::kYes, + event_type_names::kDOMCharacterDataModified, Event::Bubbles::kYes, nullptr, old_data, data_)); } DispatchSubtreeModifiedEvent(); diff --git a/chromium/third_party/blink/renderer/core/dom/character_data.h b/chromium/third_party/blink/renderer/core/dom/character_data.h index 745f963895a..456e8409798 100644 --- a/chromium/third_party/blink/renderer/core/dom/character_data.h +++ b/chromium/third_party/blink/renderer/core/dom/character_data.h @@ -50,7 +50,7 @@ class CORE_EXPORT CharacterData : public Node { void insertData(unsigned offset, const String&, ExceptionState&); void deleteData(unsigned offset, unsigned count, ExceptionState&); - bool ContainsOnlyWhitespace() const; + bool ContainsOnlyWhitespaceOrEmpty() const; StringImpl* DataImpl() { return data_.Impl(); } diff --git a/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc b/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc index 5413c5ee09a..f377fc47895 100644 --- a/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc +++ b/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc @@ -46,7 +46,8 @@ typedef HeapHashMap<Member<Node>, Member<ChildListMutationAccumulator>> AccumulatorMap; static AccumulatorMap& GetAccumulatorMap() { - DEFINE_STATIC_LOCAL(Persistent<AccumulatorMap>, map, (new AccumulatorMap)); + DEFINE_STATIC_LOCAL(Persistent<AccumulatorMap>, map, + (MakeGarbageCollected<AccumulatorMap>())); return *map; } diff --git a/chromium/third_party/blink/renderer/core/dom/container_node.cc b/chromium/third_party/blink/renderer/core/dom/container_node.cc index f94b4d22d1e..cce4bc210c6 100644 --- a/chromium/third_party/blink/renderer/core/dom/container_node.cc +++ b/chromium/third_party/blink/renderer/core/dom/container_node.cc @@ -63,8 +63,6 @@ namespace blink { -using namespace HTMLNames; - static void DispatchChildInsertionEvents(Node&); static void DispatchChildRemovalEvents(Node&); @@ -282,7 +280,8 @@ bool ContainerNode::EnsurePreInsertionValidity( } // We need this extra structural check because prior DOM mutation operations -// dispatched synchronous events, and their handlers might modified DOM trees. +// dispatched synchronous events, so their handlers may have modified DOM +// trees. bool ContainerNode::RecheckNodeInsertionStructuralPrereq( const NodeVector& new_children, const Node* next, @@ -622,13 +621,13 @@ void ContainerNode::WillRemoveChild(Node& child) { DispatchChildRemovalEvents(child); ChildFrameDisconnector(child).Disconnect(); if (GetDocument() != child.GetDocument()) { - // |child| was moved another document by DOM mutation event handler. + // |child| was moved to another document by the DOM mutation event handler. return; } // |nodeWillBeRemoved()| must be run after |ChildFrameDisconnector|, because - // |ChildFrameDisconnector| can run script which may cause state that is to - // be invalidated by removing the node. + // |ChildFrameDisconnector| may remove the node, resulting in an invalid + // state. ScriptForbiddenScope script_forbidden_scope; EventDispatchForbiddenScope assert_no_event_dispatch; // e.g. mutation event listener can create a new range. @@ -728,11 +727,8 @@ void ContainerNode::RemoveBetween(Node* previous_child, DCHECK_EQ(old_child.parentNode(), this); - if (!old_child.NeedsAttach()) { - AttachContext context; - context.clear_invalidation = true; - old_child.DetachLayoutTree(context); - } + if (!old_child.NeedsAttach()) + old_child.DetachLayoutTree(); if (next_child) next_child->SetPreviousSibling(previous_child); @@ -955,6 +951,20 @@ void ContainerNode::NotifyNodeRemoved(Node& root) { } } +void ContainerNode::RemovedFrom(ContainerNode& insertion_point) { + if (isConnected()) { + if (NeedsStyleInvalidation()) { + GetDocument() + .GetStyleEngine() + .GetPendingNodeInvalidations() + .ClearInvalidation(*this); + ClearNeedsStyleInvalidation(); + } + ClearChildNeedsStyleInvalidation(); + } + Node::RemovedFrom(insertion_point); +} + #if DCHECK_IS_ON() namespace { @@ -995,11 +1005,8 @@ void ContainerNode::AttachLayoutTree(AttachContext& context) { } void ContainerNode::DetachLayoutTree(const AttachContext& context) { - AttachContext children_context(context); - children_context.clear_invalidation = true; - for (Node* child = firstChild(); child; child = child->nextSibling()) - child->DetachLayoutTree(children_context); + child->DetachLayoutTree(context); SetChildNeedsStyleRecalc(); Node::DetachLayoutTree(context); @@ -1043,7 +1050,7 @@ void ContainerNode::FocusStateChanged() { SetNeedsStyleRecalc( change_type, StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, StyleChangeExtraData::g_focus)); + style_change_reason::kPseudoClass, style_change_extra_data::g_focus)); if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocus()) ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocus); @@ -1062,8 +1069,8 @@ void ContainerNode::FocusVisibleStateChanged() { : kLocalStyleChange; SetNeedsStyleRecalc(change_type, StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, - StyleChangeExtraData::g_focus_visible)); + style_change_reason::kPseudoClass, + style_change_extra_data::g_focus_visible)); if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocusVisible()) @@ -1078,8 +1085,8 @@ void ContainerNode::FocusWithinStateChanged() { : kLocalStyleChange; SetNeedsStyleRecalc(change_type, StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, - StyleChangeExtraData::g_focus_within)); + style_change_reason::kPseudoClass, + style_change_extra_data::g_focus_within)); } if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocusWithin()) @@ -1116,13 +1123,14 @@ void ContainerNode::SetFocused(bool received, WebFocusType focus_type) { // If :focus sets display: none, we lose focus but still need to recalc our // style. - if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocus()) + if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocus()) { ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocus); - else - SetNeedsStyleRecalc( - kLocalStyleChange, - StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, StyleChangeExtraData::g_focus)); + } else { + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::CreateWithExtraData( + style_change_reason::kPseudoClass, + style_change_extra_data::g_focus)); + } if (RuntimeEnabledFeatures::CSSFocusVisibleEnabled()) { if (IsElementNode() && @@ -1131,8 +1139,8 @@ void ContainerNode::SetFocused(bool received, WebFocusType focus_type) { } else { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, - StyleChangeExtraData::g_focus_visible)); + style_change_reason::kPseudoClass, + style_change_extra_data::g_focus_visible)); } } @@ -1142,8 +1150,8 @@ void ContainerNode::SetFocused(bool received, WebFocusType focus_type) { } else { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, - StyleChangeExtraData::g_focus_within)); + style_change_reason::kPseudoClass, + style_change_extra_data::g_focus_within)); } } @@ -1163,13 +1171,14 @@ void ContainerNode::SetActive(bool down) { if (!GetLayoutObject()) { if (IsElementNode() && - ToElement(this)->ChildrenOrSiblingsAffectedByActive()) + ToElement(this)->ChildrenOrSiblingsAffectedByActive()) { ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoActive); - else - SetNeedsStyleRecalc( - kLocalStyleChange, - StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, StyleChangeExtraData::g_active)); + } else { + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::CreateWithExtraData( + style_change_reason::kPseudoClass, + style_change_extra_data::g_active)); + } return; } @@ -1178,10 +1187,10 @@ void ContainerNode::SetActive(bool down) { GetComputedStyle()->HasPseudoStyle(kPseudoIdFirstLetter) ? kSubtreeStyleChange : kLocalStyleChange; - SetNeedsStyleRecalc( - change_type, - StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, StyleChangeExtraData::g_active)); + SetNeedsStyleRecalc(change_type, + StyleChangeReasonForTracing::CreateWithExtraData( + style_change_reason::kPseudoClass, + style_change_extra_data::g_active)); } if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByActive()) ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoActive); @@ -1200,13 +1209,16 @@ void ContainerNode::SetDragged(bool new_value) { if (!GetLayoutObject()) { if (new_value) return; - if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByDrag()) + if (IsElementNode() && + ToElement(this)->ChildrenOrSiblingsAffectedByDrag()) { ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoDrag); - else - SetNeedsStyleRecalc( - kLocalStyleChange, - StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, StyleChangeExtraData::g_drag)); + + } else { + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::CreateWithExtraData( + style_change_reason::kPseudoClass, + style_change_extra_data::g_drag)); + } return; } @@ -1215,10 +1227,10 @@ void ContainerNode::SetDragged(bool new_value) { GetComputedStyle()->HasPseudoStyle(kPseudoIdFirstLetter) ? kSubtreeStyleChange : kLocalStyleChange; - SetNeedsStyleRecalc( - change_type, - StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, StyleChangeExtraData::g_drag)); + SetNeedsStyleRecalc(change_type, + StyleChangeReasonForTracing::CreateWithExtraData( + style_change_reason::kPseudoClass, + style_change_extra_data::g_drag)); } if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByDrag()) ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoDrag); @@ -1235,10 +1247,10 @@ void ContainerNode::SetHovered(bool over) { StyleChangeType change_type = kLocalStyleChange; if (style && style->HasPseudoStyle(kPseudoIdFirstLetter)) change_type = kSubtreeStyleChange; - SetNeedsStyleRecalc( - change_type, - StyleChangeReasonForTracing::CreateWithExtraData( - StyleChangeReason::kPseudoClass, StyleChangeExtraData::g_hover)); + SetNeedsStyleRecalc(change_type, + StyleChangeReasonForTracing::CreateWithExtraData( + style_change_reason::kPseudoClass, + style_change_extra_data::g_hover)); } if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByHover()) ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoHover); @@ -1305,7 +1317,7 @@ static void DispatchChildInsertionEvents(Node& child) { if (c->parentNode() && document->HasListenerType(Document::kDOMNodeInsertedListener)) { c->DispatchScopedEvent( - *MutationEvent::Create(EventTypeNames::DOMNodeInserted, + *MutationEvent::Create(event_type_names::kDOMNodeInserted, Event::Bubbles::kYes, c->parentNode())); } @@ -1314,7 +1326,7 @@ static void DispatchChildInsertionEvents(Node& child) { Document::kDOMNodeInsertedIntoDocumentListener)) { for (; c; c = NodeTraversal::Next(*c, &child)) { c->DispatchScopedEvent(*MutationEvent::Create( - EventTypeNames::DOMNodeInsertedIntoDocument, Event::Bubbles::kNo)); + event_type_names::kDOMNodeInsertedIntoDocument, Event::Bubbles::kNo)); } } } @@ -1347,8 +1359,9 @@ static void DispatchChildRemovalEvents(Node& child) { Document::InDOMNodeRemovedHandlerState::kDOMNodeRemoved); } NodeChildRemovalTracker scope(child); - c->DispatchScopedEvent(*MutationEvent::Create( - EventTypeNames::DOMNodeRemoved, Event::Bubbles::kYes, c->parentNode())); + c->DispatchScopedEvent( + *MutationEvent::Create(event_type_names::kDOMNodeRemoved, + Event::Bubbles::kYes, c->parentNode())); document.SetInDOMNodeRemovedHandlerState(original_document_state); c->SetInDOMNodeRemovedHandler(original_node_flag); } @@ -1369,7 +1382,7 @@ static void DispatchChildRemovalEvents(Node& child) { NodeChildRemovalTracker scope(child); for (; c; c = NodeTraversal::Next(*c, &child)) { c->DispatchScopedEvent(*MutationEvent::Create( - EventTypeNames::DOMNodeRemovedFromDocument, Event::Bubbles::kNo)); + event_type_names::kDOMNodeRemovedFromDocument, Event::Bubbles::kNo)); } document.SetInDOMNodeRemovedHandlerState(original_document_state); child.SetInDOMNodeRemovedHandler(original_node_flag); diff --git a/chromium/third_party/blink/renderer/core/dom/container_node.h b/chromium/third_party/blink/renderer/core/dom/container_node.h index ebb81ac43ea..afb12644d32 100644 --- a/chromium/third_party/blink/renderer/core/dom/container_node.h +++ b/chromium/third_party/blink/renderer/core/dom/container_node.h @@ -158,6 +158,7 @@ class CORE_EXPORT ContainerNode : public Node { void SetActive(bool = true) override; void SetDragged(bool) override; void SetHovered(bool = true) override; + void RemovedFrom(ContainerNode& insertion_point) override; bool ChildrenOrSiblingsAffectedByFocus() const { return HasRestyleFlag( diff --git a/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc b/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc index bde295e4d08..69f26b6058b 100644 --- a/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc +++ b/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc @@ -30,8 +30,8 @@ #include "third_party/blink/renderer/core/dom/context_features_client_impl.h" +#include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/frame/content_settings_client.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" diff --git a/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h b/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h index bb1c800a842..998d8f7a1bb 100644 --- a/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h +++ b/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h @@ -36,9 +36,11 @@ class ExceptionState; class DatasetDOMStringMap final : public DOMStringMap { public: static DatasetDOMStringMap* Create(Element* element) { - return new DatasetDOMStringMap(element); + return MakeGarbageCollected<DatasetDOMStringMap>(element); } + explicit DatasetDOMStringMap(Element* element) : element_(element) {} + void GetNames(Vector<String>&) override; String item(const String& name) override; bool Contains(const String& name) override; @@ -50,8 +52,6 @@ class DatasetDOMStringMap final : public DOMStringMap { void Trace(blink::Visitor*) override; private: - explicit DatasetDOMStringMap(Element* element) : element_(element) {} - Member<Element> element_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/document.cc b/chromium/third_party/blink/renderer/core/dom/document.cc index 7ba01ff026e..ca5e41dc1be 100644 --- a/chromium/third_party/blink/renderer/core/dom/document.cc +++ b/chromium/third_party/blink/renderer/core/dom/document.cc @@ -46,13 +46,14 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/ukm.mojom-blink.h" +#include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/public/platform/web_prerendering_support.h" #include "third_party/blink/renderer/bindings/core/v8/html_script_element_or_svg_script_element.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" -#include "third_party/blink/renderer/bindings/core/v8/string_or_dictionary.h" +#include "third_party/blink/renderer/bindings/core/v8/string_or_element_creation_options.h" #include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h" #include "third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h" #include "third_party/blink/renderer/bindings/core/v8/v8_element_creation_options.h" @@ -119,6 +120,7 @@ #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/dom/slot_assignment.h" #include "third_party/blink/renderer/core/dom/slot_assignment_engine.h" +#include "third_party/blink/renderer/core/dom/slot_assignment_recalc_forbidden_scope.h" #include "third_party/blink/renderer/core/dom/static_node_list.h" #include "third_party/blink/renderer/core/dom/transform_source.h" #include "third_party/blink/renderer/core/dom/tree_walker.h" @@ -136,7 +138,6 @@ #include "third_party/blink/renderer/core/events/visual_viewport_resize_event.h" #include "third_party/blink/renderer/core/events/visual_viewport_scroll_event.h" #include "third_party/blink/renderer/core/feature_policy/document_policy.h" -#include "third_party/blink/renderer/core/frame/content_settings_client.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/dom_timer.h" #include "third_party/blink/renderer/core/frame/dom_visual_viewport.h" @@ -265,11 +266,11 @@ #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/date_components.h" +#include "third_party/blink/renderer/platform/geometry/length_functions.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instance_counters.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/language.h" -#include "third_party/blink/renderer/platform/length_functions.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" @@ -277,6 +278,7 @@ #include "third_party/blink/renderer/platform/plugins/plugin_script_forbidden_scope.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h" @@ -298,7 +300,7 @@ static WeakDocumentSet& liveDocumentSet(); namespace blink { -using namespace HTMLNames; +using namespace html_names; class DocumentOutliveTimeReporter : public BlinkGCObserver { public: @@ -411,10 +413,10 @@ static inline bool IsValidNameStart(UChar32 c) { // rules (a) and (f) above const uint32_t kNameStartMask = - WTF::Unicode::kLetter_Lowercase | WTF::Unicode::kLetter_Uppercase | - WTF::Unicode::kLetter_Other | WTF::Unicode::kLetter_Titlecase | - WTF::Unicode::kNumber_Letter; - if (!(WTF::Unicode::Category(c) & kNameStartMask)) + WTF::unicode::kLetter_Lowercase | WTF::unicode::kLetter_Uppercase | + WTF::unicode::kLetter_Other | WTF::unicode::kLetter_Titlecase | + WTF::unicode::kNumber_Letter; + if (!(WTF::unicode::Category(c) & kNameStartMask)) return false; // rule (c) above @@ -422,10 +424,10 @@ static inline bool IsValidNameStart(UChar32 c) { return false; // rule (d) above - WTF::Unicode::CharDecompositionType decomp_type = - WTF::Unicode::DecompositionType(c); - if (decomp_type == WTF::Unicode::kDecompositionFont || - decomp_type == WTF::Unicode::kDecompositionCompat) + WTF::unicode::CharDecompositionType decomp_type = + WTF::unicode::DecompositionType(c); + if (decomp_type == WTF::unicode::kDecompositionFont || + decomp_type == WTF::unicode::kDecompositionCompat) return false; return true; @@ -446,10 +448,10 @@ static inline bool IsValidNamePart(UChar32 c) { // rules (b) and (f) above const uint32_t kOtherNamePartMask = - WTF::Unicode::kMark_NonSpacing | WTF::Unicode::kMark_Enclosing | - WTF::Unicode::kMark_SpacingCombining | WTF::Unicode::kLetter_Modifier | - WTF::Unicode::kNumber_DecimalDigit; - if (!(WTF::Unicode::Category(c) & kOtherNamePartMask)) + WTF::unicode::kMark_NonSpacing | WTF::unicode::kMark_Enclosing | + WTF::unicode::kMark_SpacingCombining | WTF::unicode::kLetter_Modifier | + WTF::unicode::kNumber_DecimalDigit; + if (!(WTF::unicode::Category(c) & kOtherNamePartMask)) return false; // rule (c) above @@ -457,10 +459,10 @@ static inline bool IsValidNamePart(UChar32 c) { return false; // rule (d) above - WTF::Unicode::CharDecompositionType decomp_type = - WTF::Unicode::DecompositionType(c); - if (decomp_type == WTF::Unicode::kDecompositionFont || - decomp_type == WTF::Unicode::kDecompositionCompat) + WTF::unicode::CharDecompositionType decomp_type = + WTF::unicode::DecompositionType(c); + if (decomp_type == WTF::unicode::kDecompositionFont || + decomp_type == WTF::unicode::kDecompositionCompat) return false; return true; @@ -539,14 +541,6 @@ static void RunAutofocusTask(ExecutionContext* context) { } } -static void RecordLoadReasonToHistogram(WouldLoadReason reason) { - // TODO(dcheng): Make EnumerationHistogram work with scoped enums. - DEFINE_STATIC_LOCAL(EnumerationHistogram, unseen_frame_histogram, - ("Navigation.DeferredDocumentLoading.StatesV4", - static_cast<int>(WouldLoadReason::kCount))); - unseen_frame_histogram.Count(static_cast<int>(reason)); -} - class Document::NetworkStateObserver final : public GarbageCollectedFinalized<Document::NetworkStateObserver>, public NetworkStateNotifier::NetworkStateObserver, @@ -562,7 +556,7 @@ class Document::NetworkStateObserver final void OnLineStateChange(bool on_line) override { AtomicString event_name = - on_line ? EventTypeNames::online : EventTypeNames::offline; + on_line ? event_type_names::kOnline : event_type_names::kOffline; Document* document = To<Document>(GetExecutionContext()); if (!document->domWindow()) return; @@ -589,11 +583,11 @@ class Document::NetworkStateObserver final }; Document* Document::CreateForTest() { - return new Document(DocumentInit::Create()); + return MakeGarbageCollected<Document>(DocumentInit::Create()); } Document* Document::Create(Document& document) { - Document* new_document = new Document( + Document* new_document = MakeGarbageCollected<Document>( DocumentInit::Create().WithContextDocument(&document).WithURL( BlankURL())); new_document->SetSecurityOrigin(document.GetMutableSecurityOrigin()); @@ -605,6 +599,7 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags document_classes) : ContainerNode(nullptr, kCreateDocument), TreeScope(*this), + ExecutionContext(V8PerIsolateData::MainThreadIsolate()), has_nodes_with_placeholder_style_(false), evaluate_media_queries_on_style_recalc_(false), pending_sheet_layout_(kNoLayoutWithPendingSheets), @@ -639,7 +634,7 @@ Document::Document(const DocumentInit& initializer, ignore_destructive_write_count_(0), throw_on_dynamic_markup_insertion_count_(0), ignore_opens_during_unload_count_(0), - markers_(new DocumentMarkerController(*this)), + markers_(MakeGarbageCollected<DocumentMarkerController>(*this)), update_focus_appearance_timer_( GetTaskRunner(TaskType::kInternalUserInteraction), this, @@ -680,8 +675,9 @@ Document::Document(const DocumentInit& initializer, this, &Document::ElementDataCacheClearTimerFired), timeline_(DocumentTimeline::Create(this)), - pending_animations_(new PendingAnimations(*this)), - worklet_animation_controller_(new WorkletAnimationController(this)), + pending_animations_(MakeGarbageCollected<PendingAnimations>(*this)), + worklet_animation_controller_( + MakeGarbageCollected<WorkletAnimationController>(this)), template_document_host_(nullptr), did_associate_form_controls_timer_( GetTaskRunner(TaskType::kInternalLoading), @@ -691,7 +687,6 @@ Document::Document(const DocumentInit& initializer, has_viewport_units_(false), parser_sync_policy_(kAllowAsynchronousParsing), node_count_(0), - would_load_reason_(WouldLoadReason::kInvalid), password_count_(0), logged_field_edit_(false), secure_context_state_(SecureContextState::kUnknown), @@ -700,8 +695,10 @@ Document::Document(const DocumentInit& initializer, slot_assignment_recalc_forbidden_recursion_depth_(0), #endif needs_to_record_ukm_outlive_time_(false), - viewport_data_(new ViewportData(*this)), - agent_cluster_id_(base::UnguessableToken::Create()) { + viewport_data_(MakeGarbageCollected<ViewportData>(*this)), + agent_cluster_id_(base::UnguessableToken::Create()), + parsed_feature_policies_( + static_cast<int>(mojom::FeaturePolicyFeature::kMaxValue) + 1) { if (frame_) { DCHECK(frame_->GetPage()); ProvideContextFeaturesToDocumentFrom(*this, *frame_->GetPage()); @@ -852,6 +849,10 @@ Location* Document::location() const { return domWindow()->location(); } +bool Document::ShouldInstallV8Extensions() const { + return frame_->Client()->AllowScriptExtensions(); +} + void Document::ChildrenChanged(const ChildrenChange& change) { ContainerNode::ChildrenChanged(change); document_element_ = ElementTraversal::FirstWithin(*this); @@ -890,7 +891,7 @@ AtomicString Document::ConvertLocalName(const AtomicString& name) { Element* Document::CreateRawElement(const QualifiedName& qname, CreateElementFlags flags) { Element* element = nullptr; - if (qname.NamespaceURI() == HTMLNames::xhtmlNamespaceURI) { + if (qname.NamespaceURI() == html_names::xhtmlNamespaceURI) { // https://html.spec.whatwg.org/multipage/dom.html#elements-in-the-dom:element-interface element = HTMLElementFactory::Create(qname.LocalName(), *this, flags); if (!element) { @@ -903,7 +904,7 @@ Element* Document::CreateRawElement(const QualifiedName& qname, element = HTMLUnknownElement::Create(qname, *this); } saw_elements_in_known_namespaces_ = true; - } else if (qname.NamespaceURI() == SVGNames::svgNamespaceURI) { + } else if (qname.NamespaceURI() == svg_names::kNamespaceURI) { element = SVGElementFactory::Create(qname.LocalName(), *this, flags); if (!element) element = SVGUnknownElement::Create(qname, *this); @@ -936,13 +937,14 @@ Element* Document::CreateElementForBinding(const AtomicString& name, if (CustomElement::ShouldCreateCustomElement(local_name)) { return CustomElement::CreateCustomElement( *this, - QualifiedName(g_null_atom, local_name, HTMLNames::xhtmlNamespaceURI), + QualifiedName(g_null_atom, local_name, html_names::xhtmlNamespaceURI), CreateElementFlags::ByCreateElement()); } if (auto* element = HTMLElementFactory::Create( local_name, *this, CreateElementFlags::ByCreateElement())) return element; - QualifiedName q_name(g_null_atom, local_name, HTMLNames::xhtmlNamespaceURI); + QualifiedName q_name(g_null_atom, local_name, + html_names::xhtmlNamespaceURI); if (RegistrationContext() && V0CustomElement::IsValidName(local_name)) return RegistrationContext()->CreateCustomTagElement(*this, q_name); return HTMLUnknownElement::Create(q_name, *this); @@ -950,37 +952,32 @@ Element* Document::CreateElementForBinding(const AtomicString& name, return Element::Create(QualifiedName(g_null_atom, name, g_null_atom), this); } -String GetTypeExtension(Document* document, - const StringOrDictionary& string_or_options, - ExceptionState& exception_state) { +AtomicString GetTypeExtension( + Document* document, + const StringOrElementCreationOptions& string_or_options) { if (string_or_options.IsNull()) - return String(); + return AtomicString(); if (string_or_options.IsString()) { UseCounter::Count(document, WebFeature::kDocumentCreateElement2ndArgStringHandling); - return string_or_options.GetAsString(); + return AtomicString(string_or_options.GetAsString()); } - if (string_or_options.IsDictionary()) { - Dictionary dict = string_or_options.GetAsDictionary(); - ElementCreationOptions impl; - V8ElementCreationOptions::ToImpl(dict.GetIsolate(), dict.V8Value(), impl, - exception_state); - if (exception_state.HadException()) - return String(); - - if (impl.hasIs()) - return impl.is(); + if (string_or_options.IsElementCreationOptions()) { + const ElementCreationOptions& options = + *string_or_options.GetAsElementCreationOptions(); + if (options.hasIs()) + return AtomicString(options.is()); } - return String(); + return AtomicString(); } // https://dom.spec.whatwg.org/#dom-document-createelement Element* Document::CreateElementForBinding( const AtomicString& local_name, - const StringOrDictionary& string_or_options, + const StringOrElementCreationOptions& string_or_options, ExceptionState& exception_state) { if (string_or_options.IsNull()) { return CreateElementForBinding(local_name, exception_state); @@ -998,17 +995,17 @@ Element* Document::CreateElementForBinding( const AtomicString& converted_local_name = ConvertLocalName(local_name); QualifiedName q_name(g_null_atom, converted_local_name, IsXHTMLDocument() || IsHTMLDocument() - ? HTMLNames::xhtmlNamespaceURI + ? html_names::xhtmlNamespaceURI : g_null_atom); - bool is_v1 = string_or_options.IsDictionary() || !RegistrationContext(); - bool create_v1_builtin = string_or_options.IsDictionary(); + bool is_v1 = + string_or_options.IsElementCreationOptions() || !RegistrationContext(); + bool create_v1_builtin = string_or_options.IsElementCreationOptions(); bool should_create_builtin = create_v1_builtin || string_or_options.IsString(); // 3. - const AtomicString& is = - AtomicString(GetTypeExtension(this, string_or_options, exception_state)); + const AtomicString& is = GetTypeExtension(this, string_or_options); // 5. Let element be the result of creating an element given ... Element* element = @@ -1019,7 +1016,7 @@ Element* Document::CreateElementForBinding( // 8. If 'is' is non-null, set 'is' attribute if (!is_v1 && !is.IsEmpty()) - element->setAttribute(HTMLNames::isAttr, is); + element->setAttribute(html_names::kIsAttr, is); return element; } @@ -1063,10 +1060,11 @@ Element* Document::createElementNS(const AtomicString& namespace_uri, } // https://dom.spec.whatwg.org/#internal-createelementns-steps -Element* Document::createElementNS(const AtomicString& namespace_uri, - const AtomicString& qualified_name, - const StringOrDictionary& string_or_options, - ExceptionState& exception_state) { +Element* Document::createElementNS( + const AtomicString& namespace_uri, + const AtomicString& qualified_name, + const StringOrElementCreationOptions& string_or_options, + ExceptionState& exception_state) { if (string_or_options.IsNull()) return createElementNS(namespace_uri, qualified_name, exception_state); @@ -1076,14 +1074,14 @@ Element* Document::createElementNS(const AtomicString& namespace_uri, if (q_name == QualifiedName::Null()) return nullptr; - bool is_v1 = string_or_options.IsDictionary() || !RegistrationContext(); - bool create_v1_builtin = string_or_options.IsDictionary(); + bool is_v1 = + string_or_options.IsElementCreationOptions() || !RegistrationContext(); + bool create_v1_builtin = string_or_options.IsElementCreationOptions(); bool should_create_builtin = create_v1_builtin || string_or_options.IsString(); // 2. - const AtomicString& is = - AtomicString(GetTypeExtension(this, string_or_options, exception_state)); + const AtomicString& is = GetTypeExtension(this, string_or_options); if (!IsValidElementName(this, qualified_name)) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidCharacterError, @@ -1102,7 +1100,7 @@ Element* Document::createElementNS(const AtomicString& namespace_uri, // 4. If 'is' is non-null, set 'is' attribute if (!is_v1 && !is.IsEmpty()) - element->setAttribute(HTMLNames::isAttr, is); + element->setAttribute(html_names::kIsAttr, is); return element; } @@ -1114,7 +1112,7 @@ Element* Document::CreateElement(const QualifiedName& q_name, const AtomicString& is) { CustomElementDefinition* definition = nullptr; if (flags.IsCustomElementsV1() && - q_name.NamespaceURI() == HTMLNames::xhtmlNamespaceURI) { + q_name.NamespaceURI() == html_names::xhtmlNamespaceURI) { const CustomElementDescriptor desc(is.IsNull() ? q_name.LocalName() : is, q_name.LocalName()); if (CustomElementRegistry* registry = CustomElement::Registry(*this)) @@ -1131,13 +1129,13 @@ Element* Document::CreateElement(const QualifiedName& q_name, ScriptPromise Document::createCSSStyleSheet(ScriptState* script_state, const String& text, ExceptionState& exception_state) { - return Document::createCSSStyleSheet(script_state, text, CSSStyleSheetInit(), - exception_state); + return Document::createCSSStyleSheet( + script_state, text, CSSStyleSheetInit::Create(), exception_state); } ScriptPromise Document::createCSSStyleSheet(ScriptState* script_state, const String& text, - const CSSStyleSheetInit& options, + const CSSStyleSheetInit* options, ExceptionState& exception_state) { // Even though this function returns a Promise, it actually does all the work // at once here because CSS parsing is done synchronously on the main thread. @@ -1145,8 +1143,7 @@ ScriptPromise Document::createCSSStyleSheet(ScriptState* script_state, CSSStyleSheet* sheet = CSSStyleSheet::Create(*this, options, exception_state); sheet->SetText(text, true /* allow_import_rules */, exception_state); sheet->SetAssociatedDocument(this); - return ScriptPromise::Cast(script_state, - ScriptValue::From(script_state, sheet)); + return ScriptPromise::Cast(script_state, ToV8(sheet, script_state)); } CSSStyleSheet* Document::createCSSStyleSheetSync( @@ -1154,13 +1151,13 @@ CSSStyleSheet* Document::createCSSStyleSheetSync( const String& text, ExceptionState& exception_state) { return Document::createCSSStyleSheetSync( - script_state, text, CSSStyleSheetInit(), exception_state); + script_state, text, CSSStyleSheetInit::Create(), exception_state); } CSSStyleSheet* Document::createCSSStyleSheetSync( ScriptState* script_state, const String& text, - const CSSStyleSheetInit& options, + const CSSStyleSheetInit* options, ExceptionState& exception_state) { CSSStyleSheet* sheet = CSSStyleSheet::Create(*this, options, exception_state); sheet->SetText(text, false /* allow_import_rules */, exception_state); @@ -1172,7 +1169,7 @@ CSSStyleSheet* Document::createCSSStyleSheetSync( CSSStyleSheet* Document::createEmptyCSSStyleSheet( ScriptState* script_state, - const CSSStyleSheetInit& options, + const CSSStyleSheetInit* options, ExceptionState& exception_state) { CSSStyleSheet* sheet = CSSStyleSheet::Create(*this, options, exception_state); sheet->SetAssociatedDocument(this); @@ -1182,13 +1179,13 @@ CSSStyleSheet* Document::createEmptyCSSStyleSheet( CSSStyleSheet* Document::createEmptyCSSStyleSheet( ScriptState* script_state, ExceptionState& exception_state) { - return Document::createEmptyCSSStyleSheet(script_state, CSSStyleSheetInit(), - exception_state); + return Document::createEmptyCSSStyleSheet( + script_state, CSSStyleSheetInit::Create(), exception_state); } ScriptValue Document::registerElement(ScriptState* script_state, const AtomicString& name, - const ElementRegistrationOptions& options, + const ElementRegistrationOptions* options, ExceptionState& exception_state) { if (!RegistrationContext()) { exception_state.ThrowDOMException( @@ -1423,7 +1420,7 @@ bool Document::HasValidNamespaceForElements(const QualifiedName& q_name) { return false; // createElementNS("http://www.example.com", "xml:lang") if (q_name.Prefix() == g_xml_atom && - q_name.NamespaceURI() != XMLNames::xmlNamespaceURI) + q_name.NamespaceURI() != xml_names::kNamespaceURI) return false; // Required by DOM Level 3 Core and unspecified by DOM Level 2 Core: @@ -1432,8 +1429,8 @@ bool Document::HasValidNamespaceForElements(const QualifiedName& q_name) { // createElementNS(null, "xmlns:bar"), createElementNS(null, "xmlns") if (q_name.Prefix() == g_xmlns_atom || (q_name.Prefix().IsEmpty() && q_name.LocalName() == g_xmlns_atom)) - return q_name.NamespaceURI() == XMLNSNames::xmlnsNamespaceURI; - return q_name.NamespaceURI() != XMLNSNames::xmlnsNamespaceURI; + return q_name.NamespaceURI() == xmlns_names::kNamespaceURI; + return q_name.NamespaceURI() != xmlns_names::kNamespaceURI; } bool Document::HasValidNamespaceForAttributes(const QualifiedName& q_name) { @@ -1479,7 +1476,7 @@ void Document::SetReadyState(DocumentReadyState ready_state) { } ready_state_ = ready_state; - DispatchEvent(*Event::Create(EventTypeNames::readystatechange)); + DispatchEvent(*Event::Create(event_type_names::kReadystatechange)); } bool Document::IsLoadCompleted() const { @@ -1500,7 +1497,7 @@ void Document::SetContentLanguage(const AtomicString& language) { // Document's style depends on the content language. SetNeedsStyleRecalc(kSubtreeStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kLanguage)); + style_change_reason::kLanguage)); } void Document::setXMLVersion(const String& version, @@ -1642,9 +1639,9 @@ static inline String CanonicalizedTitle(Document* document, bool pending_whitespace = false; for (unsigned i = 0; i < length; ++i) { UChar32 c = characters[i]; - if ((c <= WTF::Unicode::kSpaceCharacter && - c != WTF::Unicode::kLineTabulationCharacter) || - c == WTF::Unicode::kDeleteCharacter) { + if ((c <= WTF::unicode::kSpaceCharacter && + c != WTF::unicode::kLineTabulationCharacter) || + c == WTF::unicode::kDeleteCharacter) { if (builder_index != 0) pending_whitespace = true; } else { @@ -1688,31 +1685,25 @@ void Document::DispatchDidReceiveTitle() { void Document::setTitle(const String& title) { // Title set by JavaScript -- overrides any title elements. - if (!title_element_) { - if (IsHTMLDocument() || IsXHTMLDocument()) { + Element* element = documentElement(); + if (IsSVGSVGElement(element)) { + if (!title_element_) { + title_element_ = SVGTitleElement::Create(*this); + element->InsertBefore(title_element_.Get(), element->firstChild()); + } + if (auto* svg_title = ToSVGTitleElementOrNull(title_element_)) + svg_title->SetText(title); + } else if (element && element->IsHTMLElement()) { + if (!title_element_) { HTMLElement* head_element = head(); if (!head_element) return; title_element_ = HTMLTitleElement::Create(*this); head_element->AppendChild(title_element_.Get()); - } else if (IsSVGDocument()) { - Element* element = documentElement(); - if (!IsSVGSVGElement(element)) - return; - title_element_ = SVGTitleElement::Create(*this); - element->InsertBefore(title_element_.Get(), element->firstChild()); } - } else { - if (!IsHTMLDocument() && !IsXHTMLDocument() && !IsSVGDocument()) - title_element_ = nullptr; + if (auto* html_title = ToHTMLTitleElementOrNull(title_element_)) + html_title->setText(title); } - - if (auto* html_title = ToHTMLTitleElementOrNull(title_element_)) - html_title->setText(title); - else if (auto* svg_title = ToSVGTitleElementOrNull(title_element_)) - svg_title->SetText(title); - else - UpdateTitle(title); } void Document::SetTitleElement(Element* title_element) { @@ -1815,9 +1806,10 @@ void Document::SetWasDiscarded(bool was_discarded) { } void Document::DidChangeVisibilityState() { - DispatchEvent(*Event::CreateBubble(EventTypeNames::visibilitychange)); + DispatchEvent(*Event::CreateBubble(event_type_names::kVisibilitychange)); // Also send out the deprecated version until it can be removed. - DispatchEvent(*Event::CreateBubble(EventTypeNames::webkitvisibilitychange)); + DispatchEvent( + *Event::CreateBubble(event_type_names::kWebkitvisibilitychange)); if (GetPageVisibilityState() == mojom::PageVisibilityState::kVisible) Timeline().SetAllCompositorPending(); @@ -1930,9 +1922,7 @@ bool Document::NeedsFullLayoutTreeUpdate() const { return true; if (NeedsStyleInvalidation()) return true; - // FIXME: The childNeedsDistributionRecalc bit means either self or children, - // we should fix that. - if (ChildNeedsDistributionRecalc()) + if (IsSlotAssignmentOrLegacyDistributionDirty()) return true; if (DocumentAnimations::NeedsAnimationTimingUpdate(*this)) return true; @@ -1965,7 +1955,7 @@ void Document::ScheduleLayoutTreeUpdate() { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScheduleStyleRecalculation", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorRecalculateStylesEvent::Data(GetFrame())); + inspector_recalculate_styles_event::Data(GetFrame())); ++style_version_; } @@ -1993,7 +1983,8 @@ void Document::SetupFontBuilder(ComputedStyle& document_style) { void Document::PropagateStyleToViewport() { DCHECK(InStyleRecalc()); - DCHECK(documentElement()); + if (!documentElement()) + return; HTMLElement* body = this->body(); @@ -2015,67 +2006,70 @@ void Document::PropagateStyleToViewport() { // http://www.w3.org/TR/css3-background/#body-background // <html> root element with no background steals background from its first // <body> child. - // Also see LayoutBoxModelObject::backgroundStolenForBeingBody() - if (IsHTMLHtmlElement(documentElement()) && IsHTMLBodyElement(body) && - !background_style->HasBackground()) + // Also see LayoutBoxModelObject::BackgroundTransfersToView() + if (IsHTMLHtmlElement(documentElement()) && + document_element_style->Display() != EDisplay::kNone && + IsHTMLBodyElement(body) && !background_style->HasBackground()) { background_style = body_style; - - Color background_color = - background_style->VisitedDependentColor(GetCSSPropertyBackgroundColor()); - FillLayer background_layers = background_style->BackgroundLayers(); - for (auto* current_layer = &background_layers; current_layer; - current_layer = current_layer->Next()) { - // http://www.w3.org/TR/css3-background/#root-background - // The root element background always have painting area of the whole - // canvas. - current_layer->SetClip(EFillBox::kBorder); - - // The root element doesn't scroll. It always propagates its layout overflow - // to the viewport. Positioning background against either box is equivalent - // to positioning against the scrolled box of the viewport. - if (current_layer->Attachment() == EFillAttachment::kScroll) - current_layer->SetAttachment(EFillAttachment::kLocal); } - EImageRendering image_rendering = background_style->ImageRendering(); - const ComputedStyle* overflow_style = nullptr; - if (Element* element = ViewportDefiningElement(document_element_style)) { - if (element == body) { - overflow_style = body_style; - } else { - DCHECK_EQ(element, documentElement()); - overflow_style = document_element_style; - - // The body element has its own scrolling box, independent from the - // viewport. This is a bit of a weird edge case in the CSS spec that we - // might want to try to eliminate some day (eg. for ScrollTopLeftInterop - - // see http://crbug.com/157855). - if (body_style && !body_style->IsOverflowVisible()) - UseCounter::Count(*this, WebFeature::kBodyScrollsInAdditionToViewport); + Color background_color = Color::kTransparent; + FillLayer background_layers(EFillLayerType::kBackground, true); + EImageRendering image_rendering = EImageRendering::kAuto; + + if (background_style->Display() != EDisplay::kNone) { + background_color = background_style->VisitedDependentColor( + GetCSSPropertyBackgroundColor()); + background_layers = background_style->BackgroundLayers(); + for (auto* current_layer = &background_layers; current_layer; + current_layer = current_layer->Next()) { + // http://www.w3.org/TR/css3-background/#root-background + // The root element background always have painting area of the whole + // canvas. + current_layer->SetClip(EFillBox::kBorder); + + // The root element doesn't scroll. It always propagates its layout + // overflow to the viewport. Positioning background against either box is + // equivalent to positioning against the scrolled box of the viewport. + if (current_layer->Attachment() == EFillAttachment::kScroll) + current_layer->SetAttachment(EFillAttachment::kLocal); } + image_rendering = background_style->ImageRendering(); } - EOverflowAnchor overflow_anchor = EOverflowAnchor::kAuto; - EOverflow overflow_x = EOverflow::kAuto; - EOverflow overflow_y = EOverflow::kAuto; - GapLength column_gap; - if (overflow_style) { - overflow_anchor = overflow_style->OverflowAnchor(); - overflow_x = overflow_style->OverflowX(); - overflow_y = overflow_style->OverflowY(); - // Visible overflow on the viewport is meaningless, and the spec says to - // treat it as 'auto': - if (overflow_x == EOverflow::kVisible) - overflow_x = EOverflow::kAuto; - if (overflow_y == EOverflow::kVisible) - overflow_y = EOverflow::kAuto; - if (overflow_anchor == EOverflowAnchor::kVisible) - overflow_anchor = EOverflowAnchor::kAuto; - // Column-gap is (ab)used by the current paged overflow implementation (in - // lack of other ways to specify gaps between pages), so we have to - // propagate it too. - column_gap = overflow_style->ColumnGap(); - } + const ComputedStyle* overflow_style = nullptr; + Element* viewport_element = ViewportDefiningElement(); + DCHECK(viewport_element); + if (viewport_element == body) { + overflow_style = body_style; + } else { + DCHECK_EQ(viewport_element, documentElement()); + overflow_style = document_element_style; + + // The body element has its own scrolling box, independent from the + // viewport. This is a bit of a weird edge case in the CSS spec that we + // might want to try to eliminate some day (eg. for ScrollTopLeftInterop - + // see http://crbug.com/157855). + if (body_style && !body_style->IsOverflowVisible()) + UseCounter::Count(*this, WebFeature::kBodyScrollsInAdditionToViewport); + } + DCHECK(overflow_style); + + EOverflowAnchor overflow_anchor = overflow_style->OverflowAnchor(); + EOverflow overflow_x = overflow_style->OverflowX(); + EOverflow overflow_y = overflow_style->OverflowY(); + // Visible overflow on the viewport is meaningless, and the spec says to + // treat it as 'auto': + if (overflow_x == EOverflow::kVisible) + overflow_x = EOverflow::kAuto; + if (overflow_y == EOverflow::kVisible) + overflow_y = EOverflow::kAuto; + if (overflow_anchor == EOverflowAnchor::kVisible) + overflow_anchor = EOverflowAnchor::kAuto; + // Column-gap is (ab)used by the current paged overflow implementation (in + // lack of other ways to specify gaps between pages), so we have to + // propagate it too. + GapLength column_gap = overflow_style->ColumnGap(); ScrollSnapType snap_type = overflow_style->GetScrollSnapType(); ScrollBehavior scroll_behavior = document_element_style->GetScrollBehavior(); @@ -2155,23 +2149,33 @@ void Document::PropagateStyleToViewport() { #if DCHECK_IS_ON() static void AssertLayoutTreeUpdated(Node& root) { - for (Node& node : NodeTraversal::InclusiveDescendantsOf(root)) { - DCHECK(!node.NeedsStyleRecalc()); - DCHECK(!node.ChildNeedsStyleRecalc()); - DCHECK(!node.NeedsReattachLayoutTree()); - DCHECK(!node.ChildNeedsReattachLayoutTree()); - DCHECK(!node.ChildNeedsDistributionRecalc()); - DCHECK(!node.NeedsStyleInvalidation()); - DCHECK(!node.ChildNeedsStyleInvalidation()); + Node* node = &root; + while (node) { + if (RuntimeEnabledFeatures::DisplayLockingEnabled() && + node->IsElementNode() && + ToElement(node)->StyleRecalcBlockedByDisplayLock()) { + node = NodeTraversal::NextSkippingChildren(*node); + continue; + } + + DCHECK(!node->NeedsStyleRecalc()); + DCHECK(!node->ChildNeedsStyleRecalc()); + DCHECK(!node->NeedsReattachLayoutTree()); + DCHECK(!node->ChildNeedsReattachLayoutTree()); + DCHECK(!node->ChildNeedsDistributionRecalc()); + DCHECK(!node->NeedsStyleInvalidation()); + DCHECK(!node->ChildNeedsStyleInvalidation()); + DCHECK(!node->GetForceReattachLayoutTree()); // Make sure there is no node which has a LayoutObject, but doesn't have a // parent in a flat tree. If there is such a node, we forgot to detach the // node. DocumentNode is only an exception. - DCHECK((node.IsDocumentNode() || !node.GetLayoutObject() || - FlatTreeTraversal::Parent(node))) - << node; + DCHECK((node->IsDocumentNode() || !node->GetLayoutObject() || + FlatTreeTraversal::Parent(*node))) + << *node; - if (ShadowRoot* shadow_root = node.GetShadowRoot()) + if (ShadowRoot* shadow_root = node->GetShadowRoot()) AssertLayoutTreeUpdated(*shadow_root); + node = NodeTraversal::Next(*node); } } #endif @@ -2198,10 +2202,7 @@ void Document::UpdateStyleAndLayoutTree() { // NeedsLayoutTreeUpdate(). GetSlotAssignmentEngine().RecalcSlotAssignments(); -#if DCHECK_IS_ON() - NestingLevelIncrementer slot_assignment_recalc_forbidden_scope( - slot_assignment_recalc_forbidden_recursion_depth_); -#endif + SlotAssignmentRecalcForbiddenScope forbid_slot_recalc(*this); if (!NeedsLayoutTreeUpdate()) { if (Lifecycle().GetState() < DocumentLifecycle::kStyleClean) { @@ -2225,7 +2226,7 @@ void Document::UpdateStyleAndLayoutTree() { CHECK(Lifecycle().StateAllowsTreeMutations()); TRACE_EVENT_BEGIN1("blink,devtools.timeline", "UpdateLayoutTree", "beginData", - InspectorRecalculateStylesEvent::Data(GetFrame())); + inspector_recalculate_styles_event::Data(GetFrame())); unsigned start_element_count = GetStyleEngine().StyleForElementCount(); @@ -2339,7 +2340,6 @@ void Document::UpdateStyle() { ViewportDefiningElementDidChange(); } GetStyleEngine().MarkForWhitespaceReattachment(); - PropagateStyleToViewport(); if (document_element->NeedsReattachLayoutTree() || document_element->ChildNeedsReattachLayoutTree()) { TRACE_EVENT0("blink,blink_style", "Document::rebuildLayoutTree"); @@ -2350,13 +2350,13 @@ void Document::UpdateStyle() { } } GetStyleEngine().ClearWhitespaceReattachSet(); + ClearChildNeedsStyleRecalc(); + ClearChildNeedsReattachLayoutTree(); + PropagateStyleToViewport(); View()->UpdateCountersAfterStyleChange(); GetLayoutView()->RecalcOverflow(); - ClearChildNeedsStyleRecalc(); - ClearChildNeedsReattachLayoutTree(); - DCHECK(!NeedsStyleRecalc()); DCHECK(!ChildNeedsStyleRecalc()); DCHECK(!NeedsReattachLayoutTree()); @@ -2414,7 +2414,8 @@ void Document::NotifyLayoutTreeOfSubtreeChanges() { lifecycle_.AdvanceTo(DocumentLifecycle::kLayoutSubtreeChangeClean); } -bool Document::NeedsLayoutTreeUpdateForNode(const Node& node) const { +bool Document::NeedsLayoutTreeUpdateForNode(const Node& node, + bool ignore_adjacent_style) const { if (!node.CanParticipateInFlatTree()) return false; if (!NeedsLayoutTreeUpdate()) @@ -2434,7 +2435,7 @@ bool Document::NeedsLayoutTreeUpdateForNode(const Node& node) const { } } if (ancestor->NeedsStyleRecalc() || ancestor->NeedsStyleInvalidation() || - ancestor->NeedsAdjacentStyleRecalc()) { + (ancestor->NeedsAdjacentStyleRecalc() && !ignore_adjacent_style)) { return true; } } @@ -2543,6 +2544,10 @@ void Document::ClearFocusedElementTimerFired(TimerBase*) { // lets us get reasonable answers. The long term solution to this problem is // to instead suspend JavaScript execution. void Document::UpdateStyleAndLayoutTreeIgnorePendingStylesheets() { + if (RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) { + UpdateStyleAndLayoutTree(); + return; + } if (Lifecycle().LifecyclePostponed()) return; // See comment for equivalent CHECK in Document::UpdateStyleAndLayoutTree. @@ -2573,7 +2578,7 @@ void Document::UpdateStyleAndLayoutTreeIgnorePendingStylesheets() { // but here we need up-to-date style immediately. SetNeedsStyleRecalc(kSubtreeStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kCleanupPlaceholderStyles)); + style_change_reason::kCleanupPlaceholderStyles)); } } UpdateStyleAndLayoutTree(); @@ -2584,7 +2589,8 @@ void Document::UpdateStyleAndLayoutIgnorePendingStylesheets( LocalFrameView* local_view = View(); if (local_view) local_view->WillStartForcedLayout(); - UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); + if (!RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) + UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); UpdateStyleAndLayout(); if (local_view) { @@ -2761,7 +2767,7 @@ void Document::Initialize() { if (TextAutosizer* autosizer = GetTextAutosizer()) autosizer->UpdatePageInfo(); - frame_->DocumentAttached(); + frame_->DidAttachDocument(); lifecycle_.AdvanceTo(DocumentLifecycle::kStyleClean); if (View()) @@ -2770,10 +2776,12 @@ void Document::Initialize() { // Observer(s) should not be initialized until the document is initialized / // attached to a frame. Otherwise ContextLifecycleObserver::contextDestroyed // wouldn't be fired. - network_state_observer_ = new NetworkStateObserver(*this); + network_state_observer_ = MakeGarbageCollected<NetworkStateObserver>(*this); } void Document::Shutdown() { + if (num_canvases_ > 0) + UMA_HISTOGRAM_COUNTS_100("Blink.Canvas.NumCanvasesPerPage", num_canvases_); TRACE_EVENT0("blink", "Document::shutdown"); CHECK(!frame_ || frame_->Tree().ChildCount() == 0); if (!IsActive()) @@ -3325,8 +3333,7 @@ HTMLHeadElement* Document::head() const { return Traversal<HTMLHeadElement>::FirstChild(*de); } -Element* Document::ViewportDefiningElement( - const ComputedStyle* root_style) const { +Element* Document::ViewportDefiningElement() const { // If a BODY element sets non-visible overflow, it is to be propagated to the // viewport, as long as the following conditions are all met: // (1) The root element is HTML. @@ -3338,11 +3345,9 @@ Element* Document::ViewportDefiningElement( Element* body_element = body(); if (!root_element) return nullptr; - if (!root_style) { - root_style = root_element->GetComputedStyle(); - if (!root_style) - return nullptr; - } + const ComputedStyle* root_style = root_element->GetComputedStyle(); + if (!root_style) + return nullptr; if (body_element && root_style->IsOverflowVisible() && IsHTMLHtmlElement(*root_element)) return body_element; @@ -3588,6 +3593,15 @@ bool Document::CheckCompletedInternal() { } AnchorElementMetrics::MaybeReportViewportMetricsOnLoad(*this); + + // If this is a document associated with a resource loading hints based + // preview, then record the resource loading hints UKM now that the load is + // finished. + PreviewsResourceLoadingHints* hints = + Loader()->GetPreviewsResourceLoadingHints(); + if (hints) { + hints->RecordUKM(UkmRecorder()); + } } return true; @@ -3607,7 +3621,7 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client, return false; BeforeUnloadEvent& before_unload_event = *BeforeUnloadEvent::Create(); - before_unload_event.initEvent(EventTypeNames::beforeunload, false, true); + before_unload_event.initEvent(event_type_names::kBeforeunload, false, true); load_event_progress_ = kBeforeUnloadEventInProgress; const TimeTicks beforeunload_event_start = CurrentTimeTicks(); dom_window_->DispatchEvent(before_unload_event, this); @@ -3701,7 +3715,7 @@ void Document::DispatchUnloadEvents() { if (LocalDOMWindow* window = domWindow()) { const TimeTicks pagehide_event_start = CurrentTimeTicks(); window->DispatchEvent( - *PageTransitionEvent::Create(EventTypeNames::pagehide, false), + *PageTransitionEvent::Create(event_type_names::kPagehide, false), this); const TimeTicks pagehide_event_end = CurrentTimeTicks(); DEFINE_STATIC_LOCAL( @@ -3719,7 +3733,8 @@ void Document::DispatchUnloadEvents() { // Dispatch visibilitychange event, but don't bother doing // other notifications as we're about to be unloaded. const TimeTicks pagevisibility_hidden_event_start = CurrentTimeTicks(); - DispatchEvent(*Event::CreateBubble(EventTypeNames::visibilitychange)); + DispatchEvent( + *Event::CreateBubble(event_type_names::kVisibilitychange)); const TimeTicks pagevisibility_hidden_event_end = CurrentTimeTicks(); DEFINE_STATIC_LOCAL(CustomCountHistogram, pagevisibility_histogram, ("DocumentEventTiming.PageVibilityHiddenDuration", @@ -3728,7 +3743,7 @@ void Document::DispatchUnloadEvents() { pagevisibility_hidden_event_end - pagevisibility_hidden_event_start); DispatchEvent( - *Event::CreateBubble(EventTypeNames::webkitvisibilitychange)); + *Event::CreateBubble(event_type_names::kWebkitvisibilitychange)); } if (!frame_) return; @@ -3738,7 +3753,7 @@ void Document::DispatchUnloadEvents() { DocumentLoader* document_loader = frame_->Loader().GetProvisionalDocumentLoader(); load_event_progress_ = kUnloadEventInProgress; - Event& unload_event = *Event::Create(EventTypeNames::unload); + Event& unload_event = *Event::Create(event_type_names::kUnload); if (document_loader && document_loader->GetTiming().UnloadEventStart().is_null() && document_loader->GetTiming().UnloadEventEnd().is_null()) { @@ -3781,12 +3796,13 @@ void Document::DispatchFreezeEvent() { DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled()); const TimeTicks freeze_event_start = CurrentTimeTicks(); SetFreezingInProgress(true); - DispatchEvent(*Event::Create(EventTypeNames::freeze)); + DispatchEvent(*Event::Create(event_type_names::kFreeze)); SetFreezingInProgress(false); const TimeTicks freeze_event_end = CurrentTimeTicks(); DEFINE_STATIC_LOCAL(CustomCountHistogram, freeze_histogram, ("DocumentEventTiming.FreezeDuration", 0, 10000000, 50)); freeze_histogram.CountMicroseconds(freeze_event_end - freeze_event_start); + UseCounter::Count(*this, WebFeature::kPageLifeCycleFreeze); } Document::PageDismissalType Document::PageDismissalEventBeingDispatched() @@ -3922,7 +3938,8 @@ void Document::write(const String& text, DCHECK(parser_); PerformanceMonitor::ReportGenericViolation( this, PerformanceMonitor::kDiscouragedAPIUse, - "Avoid using document.write().", base::TimeDelta(), nullptr); + "Avoid using document.write(). https://developers.google.com/web/updates/2016/08/removing-document-write", + base::TimeDelta(), nullptr); probe::breakableLocation(this, "Document.write"); parser_->insert(text); } @@ -4109,12 +4126,12 @@ void Document::ProcessBaseElement() { base && (!href || !target); base = Traversal<HTMLBaseElement>::Next(*base)) { if (!href) { - const AtomicString& value = base->FastGetAttribute(hrefAttr); + const AtomicString& value = base->FastGetAttribute(kHrefAttr); if (!value.IsNull()) href = &value; } if (!target) { - const AtomicString& value = base->FastGetAttribute(targetAttr); + const AtomicString& value = base->FastGetAttribute(kTargetAttr); if (!value.IsNull()) target = &value; } @@ -4303,13 +4320,14 @@ String Document::OutgoingReferrer() const { return referrer_document->url_.StrippedForUseAsReferrer(); } -ReferrerPolicy Document::GetReferrerPolicy() const { - ReferrerPolicy policy = ExecutionContext::GetReferrerPolicy(); +network::mojom::ReferrerPolicy Document::GetReferrerPolicy() const { + network::mojom::ReferrerPolicy policy = ExecutionContext::GetReferrerPolicy(); // For srcdoc documents without their own policy, walk up the frame // tree to find the document that is either not a srcdoc or doesn't // have its own policy. This algorithm is defined in // https://html.spec.whatwg.org/multipage/window-object.html#set-up-a-window-environment-settings-object. - if (!frame_ || policy != kReferrerPolicyDefault || !IsSrcdocDocument()) { + if (!frame_ || policy != network::mojom::ReferrerPolicy::kDefault || + !IsSrcdocDocument()) { return policy; } LocalFrame* frame = ToLocalFrame(frame_->Tree().Parent()); @@ -4593,7 +4611,7 @@ void Document::StyleResolverMayHaveChanged() { if (HasNodesWithPlaceholderStyle()) { SetNeedsStyleRecalc(kSubtreeStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kCleanupPlaceholderStyles)); + style_change_reason::kCleanupPlaceholderStyles)); } if (DidLayoutWithPendingStylesheets() && @@ -4732,14 +4750,14 @@ bool Document::SetFocusedElement(Element* new_focused_element, } // 'focusout' is a DOM level 3 name for the bubbling blur event. - old_focused_element->DispatchFocusOutEvent(EventTypeNames::focusout, + old_focused_element->DispatchFocusOutEvent(event_type_names::kFocusout, new_focused_element, params.source_capabilities); // 'DOMFocusOut' is a DOM level 2 name for compatibility. // FIXME: We should remove firing DOMFocusOutEvent event when we are sure // no content depends on it, probably when <rdar://problem/8503958> is // resolved. - old_focused_element->DispatchFocusOutEvent(EventTypeNames::DOMFocusOut, + old_focused_element->DispatchFocusOutEvent(event_type_names::kDOMFocusOut, new_focused_element, params.source_capabilities); @@ -4802,7 +4820,7 @@ bool Document::SetFocusedElement(Element* new_focused_element, goto SetFocusedElementDone; } // DOM level 3 bubbling focus event. - focused_element_->DispatchFocusInEvent(EventTypeNames::focusin, + focused_element_->DispatchFocusInEvent(event_type_names::kFocusin, old_focused_element, params.type, params.source_capabilities); @@ -4815,7 +4833,7 @@ bool Document::SetFocusedElement(Element* new_focused_element, // For DOM level 2 compatibility. // FIXME: We should remove firing DOMFocusInEvent event when we are sure // no content depends on it, probably when <rdar://problem/8503958> is m. - focused_element_->DispatchFocusInEvent(EventTypeNames::DOMFocusIn, + focused_element_->DispatchFocusInEvent(event_type_names::kDOMFocusIn, old_focused_element, params.type, params.source_capabilities); @@ -4873,6 +4891,7 @@ Element* Document::SequentialFocusNavigationStartingPoint( return focused_element_.Get(); if (!sequential_focus_navigation_starting_point_) return nullptr; + DCHECK(sequential_focus_navigation_starting_point_->IsConnected()); if (!sequential_focus_navigation_starting_point_->collapsed()) { Node* node = sequential_focus_navigation_starting_point_->startContainer(); DCHECK_EQ(node, @@ -4900,11 +4919,25 @@ Element* Document::SequentialFocusNavigationStartingPoint( // document tree. if (Node* next_node = sequential_focus_navigation_starting_point_->FirstNode()) { - if (type == kWebFocusTypeForward) - return ElementTraversal::Previous(*next_node); + if (next_node->IsShadowRoot()) + return next_node->OwnerShadowHost(); + // TODO(tkent): Using FlatTreeTraversal is inconsistent with + // FocusController. Ideally we should find backward/forward focusable + // elements before the starting point is disconnected. crbug.com/606582 + if (type == kWebFocusTypeForward) { + Node* previous = next_node; + do { + previous = FlatTreeTraversal::Previous(*previous); + } while (previous && !previous->IsElementNode()); + return ToElement(previous); + } if (next_node->IsElementNode()) return ToElement(next_node); - return ElementTraversal::Next(*next_node); + Node* next = next_node; + do { + next = FlatTreeTraversal::Next(*next); + } while (next && !next->IsElementNode()); + return ToElement(next); } return nullptr; } @@ -4985,8 +5018,11 @@ void Document::DidMoveTreeToNewDocument(const Node& root) { void Document::NodeChildrenWillBeRemoved(ContainerNode& container) { EventDispatchForbiddenScope assert_no_event_dispatch; - for (Range* range : ranges_) + for (Range* range : ranges_) { range->NodeChildrenWillBeRemoved(container); + if (range == sequential_focus_navigation_starting_point_) + range->FixupRemovedChildrenAcrossShadowBoundary(container); + } for (NodeIterator* ni : node_iterators_) { for (Node& n : NodeTraversal::ChildrenOf(container)) @@ -5005,8 +5041,11 @@ void Document::NodeWillBeRemoved(Node& n) { for (NodeIterator* ni : node_iterators_) ni->NodeWillBeRemoved(n); - for (Range* range : ranges_) + for (Range* range : ranges_) { range->NodeWillBeRemoved(n); + if (range == sequential_focus_navigation_starting_point_) + range->FixupRemovedNodeAcrossShadowBoundary(n); + } NotifyNodeWillBeRemoved(n); @@ -5087,14 +5126,14 @@ void Document::EnqueueScrollEventForNode(Node* target) { // Per the W3C CSSOM View Module only scroll events fired at the document // should bubble. Event* scroll_event = target->IsDocumentNode() - ? Event::CreateBubble(EventTypeNames::scroll) - : Event::Create(EventTypeNames::scroll); + ? Event::CreateBubble(event_type_names::kScroll) + : Event::Create(event_type_names::kScroll); scroll_event->SetTarget(target); EnsureScriptedAnimationController().EnqueuePerFrameEvent(scroll_event); } void Document::EnqueueResizeEvent() { - Event* event = Event::Create(EventTypeNames::resize); + Event* event = Event::Create(event_type_names::kResize); event->SetTarget(domWindow()); EnsureScriptedAnimationController().EnqueuePerFrameEvent(event); } @@ -5132,7 +5171,7 @@ const OriginAccessEntry& Document::AccessEntryFromURL() { if (!access_entry_from_url_) { access_entry_from_url_ = std::make_unique<OriginAccessEntry>( Url().Protocol(), Url().Host(), - network::cors::OriginAccessEntry::kAllowRegisterableDomains); + network::mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains); } return *access_entry_from_url_; } @@ -5189,7 +5228,7 @@ Event* Document::createEvent(ScriptState* script_state, // createEvent for TouchEvent should throw DOM exception if touch event // feature detection is not enabled. See crbug.com/392584#c22 if (DeprecatedEqualIgnoringCase(event_type, "TouchEvent") && - !OriginTrials::TouchEventFeatureDetectionEnabled(execution_context)) + !origin_trials::TouchEventFeatureDetectionEnabled(execution_context)) break; return event; } @@ -5208,43 +5247,43 @@ void Document::AddMutationEventListenerTypeIfEnabled( void Document::AddListenerTypeIfNeeded(const AtomicString& event_type, EventTarget& event_target) { - if (event_type == EventTypeNames::DOMSubtreeModified) { + if (event_type == event_type_names::kDOMSubtreeModified) { UseCounter::Count(*this, WebFeature::kDOMSubtreeModifiedEvent); AddMutationEventListenerTypeIfEnabled(kDOMSubtreeModifiedListener); - } else if (event_type == EventTypeNames::DOMNodeInserted) { + } else if (event_type == event_type_names::kDOMNodeInserted) { UseCounter::Count(*this, WebFeature::kDOMNodeInsertedEvent); AddMutationEventListenerTypeIfEnabled(kDOMNodeInsertedListener); - } else if (event_type == EventTypeNames::DOMNodeRemoved) { + } else if (event_type == event_type_names::kDOMNodeRemoved) { UseCounter::Count(*this, WebFeature::kDOMNodeRemovedEvent); AddMutationEventListenerTypeIfEnabled(kDOMNodeRemovedListener); - } else if (event_type == EventTypeNames::DOMNodeRemovedFromDocument) { + } else if (event_type == event_type_names::kDOMNodeRemovedFromDocument) { UseCounter::Count(*this, WebFeature::kDOMNodeRemovedFromDocumentEvent); AddMutationEventListenerTypeIfEnabled(kDOMNodeRemovedFromDocumentListener); - } else if (event_type == EventTypeNames::DOMNodeInsertedIntoDocument) { + } else if (event_type == event_type_names::kDOMNodeInsertedIntoDocument) { UseCounter::Count(*this, WebFeature::kDOMNodeInsertedIntoDocumentEvent); AddMutationEventListenerTypeIfEnabled(kDOMNodeInsertedIntoDocumentListener); - } else if (event_type == EventTypeNames::DOMCharacterDataModified) { + } else if (event_type == event_type_names::kDOMCharacterDataModified) { UseCounter::Count(*this, WebFeature::kDOMCharacterDataModifiedEvent); AddMutationEventListenerTypeIfEnabled(kDOMCharacterDataModifiedListener); - } else if (event_type == EventTypeNames::webkitAnimationStart || - event_type == EventTypeNames::animationstart) { + } else if (event_type == event_type_names::kWebkitAnimationStart || + event_type == event_type_names::kAnimationstart) { AddListenerType(kAnimationStartListener); - } else if (event_type == EventTypeNames::webkitAnimationEnd || - event_type == EventTypeNames::animationend) { + } else if (event_type == event_type_names::kWebkitAnimationEnd || + event_type == event_type_names::kAnimationend) { AddListenerType(kAnimationEndListener); - } else if (event_type == EventTypeNames::webkitAnimationIteration || - event_type == EventTypeNames::animationiteration) { + } else if (event_type == event_type_names::kWebkitAnimationIteration || + event_type == event_type_names::kAnimationiteration) { AddListenerType(kAnimationIterationListener); if (View()) { // Need to re-evaluate time-to-effect-change for any running animations. View()->ScheduleAnimation(); } - } else if (event_type == EventTypeNames::webkitTransitionEnd || - event_type == EventTypeNames::transitionend) { + } else if (event_type == event_type_names::kWebkitTransitionEnd || + event_type == event_type_names::kTransitionend) { AddListenerType(kTransitionEndListener); - } else if (event_type == EventTypeNames::scroll) { + } else if (event_type == event_type_names::kScroll) { AddListenerType(kScrollListener); - } else if (event_type == EventTypeNames::load) { + } else if (event_type == event_type_names::kLoad) { if (Node* node = event_target.ToNode()) { if (IsHTMLStyleElement(*node)) { AddListenerType(kLoadListenerAtCapturePhaseOrAtStyleElement); @@ -5271,23 +5310,21 @@ void Document::WillChangeFrameOwnerProperties(int margin_width, DCHECK(GetFrame() && GetFrame()->Owner()); FrameOwner* owner = GetFrame()->Owner(); - if (RuntimeEnabledFeatures::DisplayNoneIFrameCreatesNoLayoutObjectEnabled()) { - if (documentElement()) { - if (is_display_none != owner->IsDisplayNone()) - documentElement()->LazyReattachIfAttached(); - } + if (documentElement()) { + if (is_display_none != owner->IsDisplayNone()) + documentElement()->LazyReattachIfAttached(); } // body() may become null as a result of modification event listeners, so we // check before each call. if (margin_width != owner->MarginWidth()) { if (auto* body_element = body()) { - body_element->SetIntegralAttribute(marginwidthAttr, margin_width); + body_element->SetIntegralAttribute(kMarginwidthAttr, margin_width); } } if (margin_height != owner->MarginHeight()) { if (auto* body_element = body()) { - body_element->SetIntegralAttribute(marginheightAttr, margin_height); + body_element->SetIntegralAttribute(kMarginheightAttr, margin_height); } } if (scrolling_mode != owner->ScrollingMode() && View()) { @@ -5380,6 +5417,15 @@ void Document::setDomain(const String& raw_domain, ExceptionState& exception_state) { UseCounter::Count(*this, WebFeature::kDocumentSetDomain); + const String feature_policy_error = + "Setting `document.domain` is disabled by Feature Policy."; + if (!IsFeatureEnabled(mojom::FeaturePolicyFeature::kDocumentDomain, + ReportOptions::kReportOnFailure, + feature_policy_error)) { + exception_state.ThrowSecurityError(feature_policy_error); + return; + } + if (!frame_) { exception_state.ThrowSecurityError( "A browsing context is required to set a domain."); @@ -5422,7 +5468,7 @@ void Document::setDomain(const String& raw_domain, new_domain != "null") { OriginAccessEntry access_entry( GetSecurityOrigin()->Protocol(), new_domain, - network::cors::OriginAccessEntry::kAllowSubdomains); + network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains); network::cors::OriginAccessEntry::MatchResult result = access_entry.MatchesOrigin(*GetSecurityOrigin()); if (result == network::cors::OriginAccessEntry::kDoesNotMatchOrigin) { @@ -5457,19 +5503,18 @@ void Document::setDomain(const String& raw_domain, String Document::lastModified() const { DateComponents date; bool found_date = false; - if (frame_) { + AtomicString http_last_modified = override_last_modified_; + if (http_last_modified.IsEmpty() && frame_) { if (DocumentLoader* document_loader = Loader()) { - const AtomicString& http_last_modified = - document_loader->GetResponse().HttpHeaderField( - HTTPNames::Last_Modified); - if (!http_last_modified.IsEmpty()) { - double date_value = ParseDate(http_last_modified); - if (!std::isnan(date_value)) { - date.SetMillisecondsSinceEpochForDateTime( - ConvertToLocalTime(date_value)); - found_date = true; - } - } + http_last_modified = document_loader->GetResponse().HttpHeaderField( + http_names::kLastModified); + } + } + if (!http_last_modified.IsEmpty()) { + double date_value = ParseDate(http_last_modified); + if (!std::isnan(date_value)) { + date.SetMillisecondsSinceEpochForDateTime(ConvertToLocalTime(date_value)); + found_date = true; } } // FIXME: If this document came from the file system, the HTML5 @@ -5521,7 +5566,7 @@ const KURL Document::SiteForCookies() const { if (!top.IsLocalFrame()) { remote_entry.emplace( top_document_url.Protocol(), top_document_url.Host(), - network::cors::OriginAccessEntry::kAllowRegisterableDomains); + network::mojom::CorsOriginAccessMatchMode::kAllowRegisterableDomains); } const OriginAccessEntry& access_entry = remote_entry ? *remote_entry @@ -5740,7 +5785,7 @@ void Document::SetEncodingData(const DocumentEncodingData& new_data) { if (title_element_ && Encoding() != new_data.Encoding() && !ElementTraversal::FirstWithin(*title_element_) && Encoding() == Latin1Encoding() && - title_element_->textContent().ContainsOnlyLatin1()) { + title_element_->textContent().ContainsOnlyLatin1OrEmpty()) { CString original_bytes = title_element_->textContent().Latin1(); std::unique_ptr<TextCodec> codec = NewTextCodec(new_data.Encoding()); String correctly_decoded_title = @@ -5760,7 +5805,7 @@ void Document::SetEncodingData(const DocumentEncodingData& new_data) { visually_ordered_ = should_use_visual_ordering; SetNeedsStyleRecalc(kSubtreeStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kVisuallyOrdered)); + style_change_reason::kVisuallyOrdered)); } } @@ -5881,11 +5926,9 @@ void Document::setDesignMode(const String& value) { if (new_value == design_mode_) return; design_mode_ = new_value; - StyleChangeType type = RuntimeEnabledFeatures::LayoutNGEnabled() - ? kNeedsReattachStyleChange - : kSubtreeStyleChange; - SetNeedsStyleRecalc(type, StyleChangeReasonForTracing::Create( - StyleChangeReason::kDesignMode)); + SetNeedsStyleRecalc( + kSubtreeStyleChange, + StyleChangeReasonForTracing::Create(style_change_reason::kDesignMode)); } Document* Document::ParentDocument() const { @@ -5952,7 +5995,7 @@ const SVGDocumentExtensions* Document::SvgExtensions() { SVGDocumentExtensions& Document::AccessSVGExtensions() { if (!svg_extensions_) - svg_extensions_ = new SVGDocumentExtensions(this); + svg_extensions_ = MakeGarbageCollected<SVGDocumentExtensions>(this); return *svg_extensions_; } @@ -6023,7 +6066,7 @@ void Document::FinishedParsing() { // dispatched in a queued task, see https://crbug.com/425790 if (document_timing_.DomContentLoadedEventStart().is_null()) document_timing_.MarkDomContentLoadedEventStart(); - DispatchEvent(*Event::CreateBubble(EventTypeNames::DOMContentLoaded)); + DispatchEvent(*Event::CreateBubble(event_type_names::kDOMContentLoaded)); if (document_timing_.DomContentLoadedEventEnd().is_null()) document_timing_.MarkDomContentLoadedEventEnd(); SetParsingState(kFinishedParsing); @@ -6067,7 +6110,7 @@ void Document::FinishedParsing() { TRACE_EVENT_INSTANT1("devtools.timeline", "MarkDOMContent", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorMarkLoadEvent::Data(frame)); + inspector_mark_load_event::Data(frame)); probe::domContentLoadedEventFired(frame); frame->GetIdlenessDetector()->DomContentLoadedEventFired(); } @@ -6514,7 +6557,7 @@ bool Document::CanExecuteScripts(ReasonForCallingCanExecuteScripts reason) { // main world's CSP (such as for privileged isolated worlds). See // https://crbug.com/811528. if (IsSandboxed(kSandboxScripts) && - !GetFrame()->GetScriptController().ShouldBypassMainWorldCSP()) { + !ContentSecurityPolicy::ShouldBypassMainWorld(this)) { // FIXME: This message should be moved off the console once a solution to // https://bugs.webkit.org/show_bug.cgi?id=103274 exists. if (reason == kAboutToExecuteScript) { @@ -6527,20 +6570,20 @@ bool Document::CanExecuteScripts(ReasonForCallingCanExecuteScripts reason) { return false; } - ContentSettingsClient* settings_client = - GetFrame()->GetContentSettingsClient(); - if (!settings_client) + // No scripting on a detached frame. + if (!GetFrame()->Client()) return false; - Settings* settings = GetFrame()->GetSettings(); - if (!settings_client->AllowScript(settings && settings->GetScriptEnabled())) { - if (reason == kAboutToExecuteScript) - settings_client->DidNotAllowScript(); - - return false; - } + WebContentSettingsClient* settings_client = + GetFrame()->GetContentSettingsClient(); - return true; + Settings* settings = GetFrame()->GetSettings(); + bool script_enabled = settings && settings->GetScriptEnabled(); + if (settings_client) + script_enabled = settings_client->AllowScript(script_enabled); + if (!script_enabled && reason == kAboutToExecuteScript && settings_client) + settings_client->DidNotAllowScript(); + return script_enabled; } bool Document::IsRenderingReady() const { @@ -6555,7 +6598,7 @@ bool Document::AllowInlineEventHandler(Node* node, Element* element = node && node->IsElementNode() ? ToElement(node) : nullptr; if (!ContentSecurityPolicy::ShouldBypassMainWorld(this) && !GetContentSecurityPolicy()->AllowInlineEventHandler( - element, listener->Code(), context_url, context_line)) + element, listener->ScriptBody(), context_url, context_line)) return false; // HTML says that inline script needs browsing context to create its execution @@ -6667,8 +6710,10 @@ Document::EnsureIntersectionObserverController() { } ResizeObserverController& Document::EnsureResizeObserverController() { - if (!resize_observer_controller_) - resize_observer_controller_ = new ResizeObserverController(); + if (!resize_observer_controller_) { + resize_observer_controller_ = + MakeGarbageCollected<ResizeObserverController>(); + } return *resize_observer_controller_; } @@ -6886,7 +6931,7 @@ ScriptedIdleTaskController& Document::EnsureScriptedIdleTaskController() { int Document::RequestIdleCallback( ScriptedIdleTaskController::IdleTask* idle_task, - const IdleRequestOptions& options) { + const IdleRequestOptions* options) { return EnsureScriptedIdleTaskController().RegisterCallback(idle_task, options); } @@ -6951,8 +6996,7 @@ bool Document::ThreadedParsingEnabledForTesting() { } SnapCoordinator* Document::GetSnapCoordinator() { - if (RuntimeEnabledFeatures::CSSScrollSnapPointsEnabled() && - !snap_coordinator_) + if (!snap_coordinator_) snap_coordinator_ = SnapCoordinator::Create(); return snap_coordinator_.Get(); @@ -7223,48 +7267,48 @@ void Document::SetBodyAttribute(const QualifiedName& name, } const AtomicString& Document::bgColor() const { - return BodyAttributeValue(bgcolorAttr); + return BodyAttributeValue(kBgcolorAttr); } void Document::setBgColor(const AtomicString& value) { if (!IsFrameSet()) - SetBodyAttribute(bgcolorAttr, value); + SetBodyAttribute(kBgcolorAttr, value); } const AtomicString& Document::fgColor() const { - return BodyAttributeValue(textAttr); + return BodyAttributeValue(kTextAttr); } void Document::setFgColor(const AtomicString& value) { if (!IsFrameSet()) - SetBodyAttribute(textAttr, value); + SetBodyAttribute(kTextAttr, value); } const AtomicString& Document::alinkColor() const { - return BodyAttributeValue(alinkAttr); + return BodyAttributeValue(kAlinkAttr); } void Document::setAlinkColor(const AtomicString& value) { if (!IsFrameSet()) - SetBodyAttribute(alinkAttr, value); + SetBodyAttribute(kAlinkAttr, value); } const AtomicString& Document::linkColor() const { - return BodyAttributeValue(linkAttr); + return BodyAttributeValue(kLinkAttr); } void Document::setLinkColor(const AtomicString& value) { if (!IsFrameSet()) - SetBodyAttribute(linkAttr, value); + SetBodyAttribute(kLinkAttr, value); } const AtomicString& Document::vlinkColor() const { - return BodyAttributeValue(vlinkAttr); + return BodyAttributeValue(kVlinkAttr); } void Document::setVlinkColor(const AtomicString& value) { if (!IsFrameSet()) - SetBodyAttribute(vlinkAttr, value); + SetBodyAttribute(kVlinkAttr, value); } template <unsigned type> @@ -7376,7 +7420,7 @@ void Document::SetShadowCascadeOrder(ShadowCascadeOrder order) { order == ShadowCascadeOrder::kShadowCascadeV1) { SetNeedsStyleRecalc( kSubtreeStyleChange, - StyleChangeReasonForTracing::Create(StyleChangeReason::kShadow)); + StyleChangeReasonForTracing::Create(style_change_reason::kShadow)); UseCounter::Count(*this, WebFeature::kMixedShadowRootV0AndV1); } @@ -7474,12 +7518,12 @@ scoped_refptr<base::SingleThreadTaskRunner> Document::GetTaskRunner( // cases, though, there isn't a good candidate (most commonly when either the // passed-in document or ContextDocument() used to be attached to a Frame but // has since been detached). - return Platform::Current()->CurrentThread()->GetTaskRunner(); + return Thread::Current()->GetTaskRunner(); } Policy* Document::policy() { if (!policy_) - policy_ = new DocumentPolicy(this); + policy_ = MakeGarbageCollected<DocumentPolicy>(this); return policy_.Get(); } @@ -7579,21 +7623,6 @@ void Document::Trace(blink::Visitor* visitor) { SynchronousMutationNotifier::Trace(visitor); } -void Document::RecordDeferredLoadReason(WouldLoadReason reason) { - DCHECK(would_load_reason_ == WouldLoadReason::kInvalid || - reason != WouldLoadReason::kCreated); - DCHECK(reason != WouldLoadReason::kInvalid); - DCHECK(GetFrame()); - DCHECK(GetFrame()->IsCrossOriginSubframe()); - if (reason <= would_load_reason_ || - !GetFrame()->Loader().StateMachine()->CommittedFirstRealDocumentLoad()) - return; - for (int i = static_cast<int>(would_load_reason_) + 1; - i <= static_cast<int>(reason); ++i) - RecordLoadReasonToHistogram(static_cast<WouldLoadReason>(i)); - would_load_reason_ = reason; -} - void Document::RecordUkmOutliveTimeAfterShutdown(int outlive_time_count) { if (!needs_to_record_ukm_outlive_time_) return; @@ -7639,10 +7668,11 @@ SlotAssignmentEngine& Document::GetSlotAssignmentEngine() { return *slot_assignment_engine_; } -bool Document::IsSlotAssignmentOrLegacyDistributionDirty() { +bool Document::IsSlotAssignmentOrLegacyDistributionDirty() const { if (ChildNeedsDistributionRecalc()) return true; - if (GetSlotAssignmentEngine().HasPendingSlotAssignmentRecalc()) { + if (slot_assignment_engine_ && + slot_assignment_engine_->HasPendingSlotAssignmentRecalc()) { return true; } return false; @@ -7656,20 +7686,28 @@ bool Document::IsLazyLoadPolicyEnforced() const { LazyLoadImageObserver& Document::EnsureLazyLoadImageObserver() { if (!lazy_load_image_observer_) - lazy_load_image_observer_ = new LazyLoadImageObserver(); + lazy_load_image_observer_ = MakeGarbageCollected<LazyLoadImageObserver>(); return *lazy_load_image_observer_; } void Document::ReportFeaturePolicyViolation( - mojom::FeaturePolicyFeature feature) const { + mojom::FeaturePolicyFeature feature, + mojom::FeaturePolicyDisposition disposition, + const String& message) const { if (!RuntimeEnabledFeatures::FeaturePolicyReportingEnabled()) return; - if (!GetFrame()) + LocalFrame* frame = GetFrame(); + if (!frame) return; const String& feature_name = GetNameForFeature(feature); - FeaturePolicyViolationReportBody* body = new FeaturePolicyViolationReportBody( - feature_name, "Feature policy violation", SourceLocation::Capture()); - Report* report = new Report("feature-policy", Url().GetString(), body); + FeaturePolicyViolationReportBody* body = + MakeGarbageCollected<FeaturePolicyViolationReportBody>( + feature_name, "Feature policy violation", + (disposition == mojom::FeaturePolicyDisposition::kReport ? "report" + : "enforce"), + SourceLocation::Capture()); + Report* report = MakeGarbageCollected<Report>("feature-policy-violation", + Url().GetString(), body); ReportingContext::From(this)->QueueReport(report); bool is_null; @@ -7679,9 +7717,24 @@ void Document::ReportFeaturePolicyViolation( column_number = is_null ? 0 : column_number; // Send the feature policy violation report to the Reporting API. - GetFrame()->GetReportingService()->QueueFeaturePolicyViolationReport( - Url(), feature_name, "Feature policy violation", body->sourceFile(), - line_number, column_number); + frame->GetReportingService()->QueueFeaturePolicyViolationReport( + Url(), feature_name, + (disposition == mojom::FeaturePolicyDisposition::kReport ? "report" + : "enforce"), + "Feature policy violation", body->sourceFile(), line_number, + column_number); + // TODO(iclelland): Report something different in report-only mode + if (disposition == mojom::FeaturePolicyDisposition::kEnforce) { + frame->Console().AddMessage(ConsoleMessage::Create( + kViolationMessageSource, kErrorMessageLevel, + (message.IsEmpty() ? ("Feature policy violation: " + feature_name + + " is not allowed in this document.") + : message))); + } +} + +void Document::IncrementNumberOfCanvases() { + num_canvases_++; } void Document::SendViolationReport( @@ -7721,7 +7774,7 @@ template class CORE_TEMPLATE_EXPORT Supplement<Document>; #ifndef NDEBUG static WeakDocumentSet& liveDocumentSet() { DEFINE_STATIC_LOCAL(blink::Persistent<WeakDocumentSet>, set, - (new WeakDocumentSet)); + (blink::MakeGarbageCollected<WeakDocumentSet>())); return *set; } diff --git a/chromium/third_party/blink/renderer/core/dom/document.h b/chromium/third_party/blink/renderer/core/dom/document.h index e5e57044bbf..18de74e9ce7 100644 --- a/chromium/third_party/blink/renderer/core/dom/document.h +++ b/chromium/third_party/blink/renderer/core/dom/document.h @@ -35,6 +35,7 @@ #include "base/memory/scoped_refptr.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/mojom/frame/navigation_initiator.mojom-blink.h" #include "third_party/blink/public/platform/web_focus_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" @@ -61,12 +62,14 @@ #include "third_party/blink/renderer/core/frame/hosts_using_features.h" #include "third_party/blink/renderer/core/html/custom/v0_custom_element.h" #include "third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/timer.h" -#include "third_party/blink/renderer/platform/web_task_runner.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/bit_vector.h" #include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" @@ -177,7 +180,7 @@ class SerializedScriptValue; class Settings; class SlotAssignmentEngine; class SnapCoordinator; -class StringOrDictionary; +class StringOrElementCreationOptions; class StyleEngine; class StyleResolver; class StylePropertyMapReadOnly; @@ -226,26 +229,6 @@ enum ShadowCascadeOrder { kShadowCascadeV1 }; -// Collect data about deferred loading of offscreen cross-origin documents. All -// cross-origin documents log Created. Only those that would load log a reason. -// We can then see the % of cross-origin documents that never have to load. -// See https://crbug.com/635105. -// Logged to UMA, don't re-arrange entries without creating a new histogram. -enum class WouldLoadReason { - kInvalid, - kCreated, - k3ScreensAway, - k2ScreensAway, - k1ScreenAway, - kVisible, - // If outer and inner frames aren't in the same process we can't determine - // if the inner frame is visible, so just load it. - // TODO(dgrogan): Revisit after https://crbug.com/650433 is fixed. - kNoParent, - - kCount, -}; - enum class SecureContextState { kUnknown, kNonSecure, kSecure }; using DocumentClassFlags = unsigned char; @@ -267,7 +250,7 @@ class CORE_EXPORT Document : public ContainerNode, public: static Document* Create(const DocumentInit& init) { - return new Document(init); + return MakeGarbageCollected<Document>(init); } static Document* CreateForTest(); // Factory for web-exposed Document constructor. The argument document must be @@ -275,7 +258,10 @@ class CORE_EXPORT Document : public ContainerNode, // source of ExecutionContext and security origin of the new document. // https://dom.spec.whatwg.org/#dom-document-document static Document* Create(Document&); + + Document(const DocumentInit&, DocumentClassFlags = kDefaultDocumentClass); ~Document() override; + static Range* CreateRangeAdjustedToTreeScope(const TreeScope&, const Position&); @@ -291,6 +277,10 @@ class CORE_EXPORT Document : public ContainerNode, using SecurityContext::GetContentSecurityPolicy; using TreeScope::getElementById; + // ExecutionContext overrides: + bool IsDocument() const final { return true; } + bool ShouldInstallV8Extensions() const final; + bool CanContainRangeEndPoint() const override { return true; } SelectorQueryCache& GetSelectorQueryCache(); @@ -301,22 +291,23 @@ class CORE_EXPORT Document : public ContainerNode, // DOM methods & attributes for Document - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); - DEFINE_ATTRIBUTE_EVENT_LISTENER(freeze); - DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror); - DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(resume); - DEFINE_ATTRIBUTE_EVENT_LISTENER(search); - DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation); - DEFINE_ATTRIBUTE_EVENT_LISTENER(visibilitychange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy, kBeforecopy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut, kBeforecut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste, kBeforepaste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(freeze, kFreeze); + DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange, kPointerlockchange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror, kPointerlockerror); + DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(resume, kResume); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch); + DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation, + kSecuritypolicyviolation); + DEFINE_ATTRIBUTE_EVENT_LISTENER(visibilitychange, kVisibilitychange); ViewportData& GetViewportData() const { return *viewport_data_; } String OutgoingReferrer() const override; - ReferrerPolicy GetReferrerPolicy() const override; + network::mojom::ReferrerPolicy GetReferrerPolicy() const override; void SetDoctype(DocumentType*); DocumentType* doctype() const { return doc_type_.Get(); } @@ -330,14 +321,14 @@ class CORE_EXPORT Document : public ContainerNode, Element* CreateElementForBinding(const AtomicString& local_name, ExceptionState& = ASSERT_NO_EXCEPTION); Element* CreateElementForBinding(const AtomicString& local_name, - const StringOrDictionary&, + const StringOrElementCreationOptions&, ExceptionState&); Element* createElementNS(const AtomicString& namespace_uri, const AtomicString& qualified_name, ExceptionState&); Element* createElementNS(const AtomicString& namespace_uri, const AtomicString& qualified_name, - const StringOrDictionary&, + const StringOrElementCreationOptions&, ExceptionState&); DocumentFragment* createDocumentFragment(); Text* createTextNode(const String& data); @@ -363,7 +354,7 @@ class CORE_EXPORT Document : public ContainerNode, const CreateElementFlags = CreateElementFlags()); CSSStyleSheet* createEmptyCSSStyleSheet(ScriptState*, - const CSSStyleSheetInit&, + const CSSStyleSheetInit*, ExceptionState&); CSSStyleSheet* createEmptyCSSStyleSheet(ScriptState*, ExceptionState&); @@ -374,12 +365,12 @@ class CORE_EXPORT Document : public ContainerNode, ScriptPromise createCSSStyleSheet(ScriptState*, const String&, - const CSSStyleSheetInit&, + const CSSStyleSheetInit*, ExceptionState&); CSSStyleSheet* createCSSStyleSheetSync(ScriptState*, const String&, - const CSSStyleSheetInit&, + const CSSStyleSheetInit*, ExceptionState&); CSSStyleSheet* createCSSStyleSheetSync(ScriptState*, @@ -540,7 +531,9 @@ class CORE_EXPORT Document : public ContainerNode, void SetupFontBuilder(ComputedStyle& document_style); bool NeedsLayoutTreeUpdate() const; - bool NeedsLayoutTreeUpdateForNode(const Node&) const; + bool NeedsLayoutTreeUpdateForNode(const Node&, + bool ignore_adjacent_style = false) const; + // Update ComputedStyles and attach LayoutObjects if necessary, but don't // lay out. void UpdateStyleAndLayoutTree(); @@ -594,7 +587,7 @@ class CORE_EXPORT Document : public ContainerNode, NOTREACHED(); } - // If you have a Document, use layoutView() instead which is faster. + // If you have a Document, use GetLayoutView() instead which is faster. void GetLayoutObject() const = delete; LayoutView* GetLayoutView() const { return layout_view_; } @@ -954,6 +947,9 @@ class CORE_EXPORT Document : public ContainerNode, String domain() const; void setDomain(const String& new_domain, ExceptionState&); + void OverrideLastModified(const AtomicString& modified) { + override_last_modified_ = modified; + } String lastModified() const; // The cookieURL is used to query the cookie database for this document's @@ -1003,14 +999,8 @@ class CORE_EXPORT Document : public ContainerNode, HTMLHeadElement* head() const; - // Decide which element is to define the viewport's overflow policy. If - // |rootStyle| is set, use that as the style for the root element, rather than - // obtaining it on our own. The reason for this is that style may not have - // been associated with the elements yet - in which case it may have been - // calculated on the fly (without associating it with the actual element) - // somewhere. - Element* ViewportDefiningElement( - const ComputedStyle* root_style = nullptr) const; + // Decide which element is to define the viewport's overflow policy. + Element* ViewportDefiningElement() const; DocumentMarkerController& Markers() const { return *markers_; } @@ -1220,7 +1210,7 @@ class CORE_EXPORT Document : public ContainerNode, base::TimeTicks monotonic_animation_start_time); int RequestIdleCallback(ScriptedIdleTaskController::IdleTask*, - const IdleRequestOptions&); + const IdleRequestOptions*); void CancelIdleCallback(int id); EventTarget* ErrorEventTarget() final; @@ -1234,7 +1224,7 @@ class CORE_EXPORT Document : public ContainerNode, ScriptValue registerElement(ScriptState*, const AtomicString& name, - const ElementRegistrationOptions&, + const ElementRegistrationOptions*, ExceptionState&); V0CustomElementRegistrationContext* RegistrationContext() const { return registration_context_.Get(); @@ -1403,9 +1393,6 @@ class CORE_EXPORT Document : public ContainerNode, bool IsInMainFrame() const; - void RecordDeferredLoadReason(WouldLoadReason); - WouldLoadReason DeferredLoadReason() { return would_load_reason_; } - const PropertyRegistry* GetPropertyRegistry() const; PropertyRegistry* GetPropertyRegistry(); @@ -1467,7 +1454,7 @@ class CORE_EXPORT Document : public ContainerNode, SlotAssignmentEngine& GetSlotAssignmentEngine(); - bool IsSlotAssignmentOrLegacyDistributionDirty(); + bool IsSlotAssignmentOrLegacyDistributionDirty() const; #if DCHECK_IS_ON() unsigned& SlotAssignmentRecalcForbiddenRecursionDepth() { @@ -1504,11 +1491,22 @@ class CORE_EXPORT Document : public ContainerNode, return agent_cluster_id_; } - void ReportFeaturePolicyViolation(mojom::FeaturePolicyFeature) const override; + void ReportFeaturePolicyViolation( + mojom::FeaturePolicyFeature, + mojom::FeaturePolicyDisposition, + const String& message = g_empty_string) const override; - protected: - Document(const DocumentInit&, DocumentClassFlags = kDefaultDocumentClass); + bool IsParsedFeaturePolicy(mojom::FeaturePolicyFeature feature) const { + return parsed_feature_policies_.QuickGet(static_cast<int>(feature)); + } + + void SetParsedFeaturePolicy(mojom::FeaturePolicyFeature feature) { + parsed_feature_policies_.QuickSet(static_cast<int>(feature)); + } + void IncrementNumberOfCanvases(); + + protected: void DidUpdateSecurityOrigin() final; void ClearXMLVersion() { xml_version_ = String(); } @@ -1577,8 +1575,6 @@ class CORE_EXPORT Document : public ContainerNode, void BeginLifecycleUpdatesIfRenderingReady(); - bool IsDocument() const final { return true; } - void ChildrenChanged(const ChildrenChange&) override; String nodeName() const final; @@ -1894,8 +1890,6 @@ class CORE_EXPORT Document : public ContainerNode, Member<SnapCoordinator> snap_coordinator_; - WouldLoadReason would_load_reason_; - Member<PropertyRegistry> property_registry_; unsigned password_count_; @@ -1939,6 +1933,9 @@ class CORE_EXPORT Document : public ContainerNode, // This is set through feature policy 'vertical-scroll'. bool is_vertical_scroll_enforced_ = false; + // The number of canvas elements on the document + int num_canvases_ = 0; + // A list of all the navigation_initiator bindings owned by this document. // Used to report CSP violations that result from CSP blocking // navigation requests that were initiated by this document. @@ -1949,6 +1946,12 @@ class CORE_EXPORT Document : public ContainerNode, // https://tc39.github.io/ecma262/#sec-agent-clusters const base::UnguessableToken agent_cluster_id_; + + // Tracks which feature policies have already been parsed, so as not to count + // them multiple times. + BitVector parsed_feature_policies_; + + AtomicString override_last_modified_; }; extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Document>; diff --git a/chromium/third_party/blink/renderer/core/dom/document.idl b/chromium/third_party/blink/renderer/core/dom/document.idl index 83d8beb183b..0477c21d353 100644 --- a/chromium/third_party/blink/renderer/core/dom/document.idl +++ b/chromium/third_party/blink/renderer/core/dom/document.idl @@ -176,9 +176,8 @@ typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement; // FIXME: The registerElement return type should be Function. [RuntimeEnabled=CustomElementsV0, CallWith=ScriptState, CustomElementCallbacks, RaisesException, DeprecateAs=DocumentRegisterElement] any registerElement(DOMString type, optional ElementRegistrationOptions options); // https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-instantiate - // FIXME: The typeExtension arguments should not be nullable. - [CustomElementCallbacks, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName, (DOMString or Dictionary)? options); - [CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName, (DOMString or Dictionary)? options); + [CustomElementCallbacks, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName, (DOMString or ElementCreationOptions) options); + [CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName, (DOMString or ElementCreationOptions) options); // Page Visibility // https://w3c.github.io/page-visibility/#extensions-to-the-document-interface diff --git a/chromium/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h b/chromium/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h index e09780ba578..84cad84b563 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h +++ b/chromium/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h @@ -14,9 +14,9 @@ class DocumentAndElementEventHandlers { STATIC_ONLY(DocumentAndElementEventHandlers); public: - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(copy); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cut); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(paste); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(copy, kCopy); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cut, kCut); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(paste, kPaste); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/dom/document_fragment.cc b/chromium/third_party/blink/renderer/core/dom/document_fragment.cc index 1e836ce4a3a..b32f0044c32 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_fragment.cc +++ b/chromium/third_party/blink/renderer/core/dom/document_fragment.cc @@ -35,7 +35,8 @@ DocumentFragment::DocumentFragment(Document* document, : ContainerNode(document, construction_type) {} DocumentFragment* DocumentFragment::Create(Document& document) { - return new DocumentFragment(&document, Node::kCreateDocumentFragment); + return MakeGarbageCollected<DocumentFragment>(&document, + Node::kCreateDocumentFragment); } String DocumentFragment::nodeName() const { diff --git a/chromium/third_party/blink/renderer/core/dom/document_fragment.h b/chromium/third_party/blink/renderer/core/dom/document_fragment.h index cb87be03206..fd362515738 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_fragment.h +++ b/chromium/third_party/blink/renderer/core/dom/document_fragment.h @@ -36,6 +36,8 @@ class CORE_EXPORT DocumentFragment : public ContainerNode { public: static DocumentFragment* Create(Document&); + DocumentFragment(Document*, ConstructionType = kCreateContainer); + void ParseHTML(const String&, Element* context_element, ParserContentPolicy = kAllowScriptingContent); @@ -47,7 +49,6 @@ class CORE_EXPORT DocumentFragment : public ContainerNode { virtual bool IsTemplateContent() const { return false; } protected: - DocumentFragment(Document*, ConstructionType = kCreateContainer); String nodeName() const final; private: diff --git a/chromium/third_party/blink/renderer/core/dom/document_init.cc b/chromium/third_party/blink/renderer/core/dom/document_init.cc index f8dc05ee14f..a1db021d271 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_init.cc +++ b/chromium/third_party/blink/renderer/core/dom/document_init.cc @@ -129,7 +129,7 @@ DocumentInit::InsecureNavigationsToUpgrade() const { bool DocumentInit::IsHostedInReservedIPRange() const { if (DocumentLoader* loader = MasterDocumentLoader()) { if (!loader->GetResponse().RemoteIPAddress().IsEmpty()) { - return NetworkUtils::IsReservedIPAddress( + return network_utils::IsReservedIPAddress( loader->GetResponse().RemoteIPAddress()); } } diff --git a/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h b/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h index 2cb5634b39b..5d02b2874ec 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h +++ b/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h @@ -87,6 +87,9 @@ class CORE_EXPORT DocumentLifecycle { kStopped, }; + // This must be kept coordinated with WebWidget::LifecycleUpdateReason + enum LifecycleUpdateReason { kBeginMainFrame, kTest, kOther }; + class Scope { STACK_ALLOCATED(); diff --git a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc index a9c99cd4980..d184e49935d 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc +++ b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc @@ -17,7 +17,7 @@ DocumentParserTiming& DocumentParserTiming::From(Document& document) { DocumentParserTiming* timing = Supplement<Document>::From<DocumentParserTiming>(document); if (!timing) { - timing = new DocumentParserTiming(document); + timing = MakeGarbageCollected<DocumentParserTiming>(document); ProvideTo(document, timing); } return *timing; diff --git a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h index 4cea8dc7f16..8cd533d7092 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h +++ b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h @@ -22,6 +22,7 @@ class DocumentParserTiming final public: static const char kSupplementName[]; + explicit DocumentParserTiming(Document&); virtual ~DocumentParserTiming() = default; static DocumentParserTiming& From(Document&); @@ -99,7 +100,6 @@ class DocumentParserTiming final void Trace(blink::Visitor*) override; private: - explicit DocumentParserTiming(Document&); void NotifyDocumentParserTimingChanged(); TimeTicks parser_start_; diff --git a/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc b/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc index de59cff236a..6be49cd3556 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc +++ b/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc @@ -21,7 +21,7 @@ namespace blink { -using namespace HTMLNames; +using namespace html_names; namespace { @@ -124,19 +124,19 @@ void CollectFeatures(Element& root, features.element_count++; Element& element = ToElement(node); - if (element.HasTagName(aTag)) { + if (element.HasTagName(kATag)) { features.anchor_count++; - } else if (element.HasTagName(formTag)) { + } else if (element.HasTagName(kFormTag)) { features.form_count++; - } else if (element.HasTagName(inputTag)) { + } else if (element.HasTagName(kInputTag)) { const HTMLInputElement& input = ToHTMLInputElement(element); - if (input.type() == InputTypeNames::text) { + if (input.type() == input_type_names::kText) { features.text_input_count++; - } else if (input.type() == InputTypeNames::password) { + } else if (input.type() == input_type_names::kPassword) { features.password_input_count++; } - } else if (element.HasTagName(pTag) || element.HasTagName(preTag)) { - if (element.HasTagName(pTag)) { + } else if (element.HasTagName(kPTag) || element.HasTagName(kPreTag)) { + if (element.HasTagName(kPTag)) { features.p_count++; } else { features.pre_count++; @@ -156,7 +156,7 @@ void CollectFeatures(Element& root, features.moz_score_all_linear = std::min(features.moz_score_all_linear, kMozScoreAllLinearSaturation); } - } else if (element.HasTagName(liTag)) { + } else if (element.HasTagName(kLiTag)) { is_list_item = true; } CollectFeatures(element, features, under_list_item || is_list_item); diff --git a/chromium/third_party/blink/renderer/core/dom/document_test.cc b/chromium/third_party/blink/renderer/core/dom/document_test.cc index 45b22787b3b..f20a13bac88 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/document_test.cc @@ -33,9 +33,11 @@ #include <memory> #include "build/build_config.h" +#include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_application_cache_host.h" +#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/core/dom/document_fragment.h" @@ -56,7 +58,6 @@ #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" -#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h" #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -73,7 +74,7 @@ class DocumentTest : public PageTestBase { void DocumentTest::SetHtmlInnerHTML(const char* html_content) { GetDocument().documentElement()->SetInnerHTMLFromString( String::FromUTF8(html_content)); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); } namespace { @@ -357,8 +358,8 @@ TEST_F(DocumentTest, DomTreeVersionForRemoval) { Document& doc = GetDocument(); { DocumentFragment* fragment = DocumentFragment::Create(doc); - fragment->appendChild(Element::Create(HTMLNames::divTag, &doc)); - fragment->appendChild(Element::Create(HTMLNames::spanTag, &doc)); + fragment->appendChild(Element::Create(html_names::kDivTag, &doc)); + fragment->appendChild(Element::Create(html_names::kSpanTag, &doc)); uint64_t original_version = doc.DomTreeVersion(); fragment->RemoveChildren(); EXPECT_EQ(original_version + 1, doc.DomTreeVersion()) @@ -367,8 +368,8 @@ TEST_F(DocumentTest, DomTreeVersionForRemoval) { { DocumentFragment* fragment = DocumentFragment::Create(doc); - Node* child = Element::Create(HTMLNames::divTag, &doc); - child->appendChild(Element::Create(HTMLNames::spanTag, &doc)); + Node* child = Element::Create(html_names::kDivTag, &doc); + child->appendChild(Element::Create(html_names::kSpanTag, &doc)); fragment->appendChild(child); uint64_t original_version = doc.DomTreeVersion(); fragment->removeChild(child); @@ -417,50 +418,50 @@ TEST_F(DocumentTest, LinkManifest) { // Check that we use the first manifest with <link rel=manifest> auto* link = HTMLLinkElement::Create(GetDocument(), CreateElementFlags()); - link->setAttribute(blink::HTMLNames::relAttr, "manifest"); - link->setAttribute(blink::HTMLNames::hrefAttr, "foo.json"); + link->setAttribute(blink::html_names::kRelAttr, "manifest"); + link->setAttribute(blink::html_names::kHrefAttr, "foo.json"); GetDocument().head()->AppendChild(link); EXPECT_EQ(link, GetDocument().LinkManifest()); auto* link2 = HTMLLinkElement::Create(GetDocument(), CreateElementFlags()); - link2->setAttribute(blink::HTMLNames::relAttr, "manifest"); - link2->setAttribute(blink::HTMLNames::hrefAttr, "bar.json"); + link2->setAttribute(blink::html_names::kRelAttr, "manifest"); + link2->setAttribute(blink::html_names::kHrefAttr, "bar.json"); GetDocument().head()->InsertBefore(link2, link); EXPECT_EQ(link2, GetDocument().LinkManifest()); GetDocument().head()->AppendChild(link2); EXPECT_EQ(link, GetDocument().LinkManifest()); // Check that crazy URLs are accepted. - link->setAttribute(blink::HTMLNames::hrefAttr, "http:foo.json"); + link->setAttribute(blink::html_names::kHrefAttr, "http:foo.json"); EXPECT_EQ(link, GetDocument().LinkManifest()); // Check that empty URLs are accepted. - link->setAttribute(blink::HTMLNames::hrefAttr, ""); + link->setAttribute(blink::html_names::kHrefAttr, ""); EXPECT_EQ(link, GetDocument().LinkManifest()); // Check that URLs from different origins are accepted. - link->setAttribute(blink::HTMLNames::hrefAttr, + link->setAttribute(blink::html_names::kHrefAttr, "http://example.org/manifest.json"); EXPECT_EQ(link, GetDocument().LinkManifest()); - link->setAttribute(blink::HTMLNames::hrefAttr, + link->setAttribute(blink::html_names::kHrefAttr, "http://foo.example.org/manifest.json"); EXPECT_EQ(link, GetDocument().LinkManifest()); - link->setAttribute(blink::HTMLNames::hrefAttr, + link->setAttribute(blink::html_names::kHrefAttr, "http://foo.bar/manifest.json"); EXPECT_EQ(link, GetDocument().LinkManifest()); // More than one token in @rel is accepted. - link->setAttribute(blink::HTMLNames::relAttr, "foo bar manifest"); + link->setAttribute(blink::html_names::kRelAttr, "foo bar manifest"); EXPECT_EQ(link, GetDocument().LinkManifest()); // Such as spaces around the token. - link->setAttribute(blink::HTMLNames::relAttr, " manifest "); + link->setAttribute(blink::html_names::kRelAttr, " manifest "); EXPECT_EQ(link, GetDocument().LinkManifest()); // Check that rel=manifest actually matters. - link->setAttribute(blink::HTMLNames::relAttr, ""); + link->setAttribute(blink::html_names::kRelAttr, ""); EXPECT_EQ(link2, GetDocument().LinkManifest()); - link->setAttribute(blink::HTMLNames::relAttr, "manifest"); + link->setAttribute(blink::html_names::kRelAttr, "manifest"); // Check that link outside of the <head> are ignored. GetDocument().head()->RemoveChild(link); @@ -472,58 +473,68 @@ TEST_F(DocumentTest, LinkManifest) { GetDocument().head()->AppendChild(link2); // Check that some attribute values do not have an effect. - link->setAttribute(blink::HTMLNames::crossoriginAttr, "use-credentials"); + link->setAttribute(blink::html_names::kCrossoriginAttr, "use-credentials"); EXPECT_EQ(link, GetDocument().LinkManifest()); - link->setAttribute(blink::HTMLNames::hreflangAttr, "klingon"); + link->setAttribute(blink::html_names::kHreflangAttr, "klingon"); EXPECT_EQ(link, GetDocument().LinkManifest()); - link->setAttribute(blink::HTMLNames::typeAttr, "image/gif"); + link->setAttribute(blink::html_names::kTypeAttr, "image/gif"); EXPECT_EQ(link, GetDocument().LinkManifest()); - link->setAttribute(blink::HTMLNames::sizesAttr, "16x16"); + link->setAttribute(blink::html_names::kSizesAttr, "16x16"); EXPECT_EQ(link, GetDocument().LinkManifest()); - link->setAttribute(blink::HTMLNames::mediaAttr, "print"); + link->setAttribute(blink::html_names::kMediaAttr, "print"); EXPECT_EQ(link, GetDocument().LinkManifest()); } TEST_F(DocumentTest, referrerPolicyParsing) { - EXPECT_EQ(kReferrerPolicyDefault, GetDocument().GetReferrerPolicy()); + EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault, + GetDocument().GetReferrerPolicy()); struct TestCase { const char* policy; - ReferrerPolicy expected; + network::mojom::ReferrerPolicy expected; bool is_legacy; } tests[] = { - {"", kReferrerPolicyDefault, false}, + {"", network::mojom::ReferrerPolicy::kDefault, false}, // Test that invalid policy values are ignored. - {"not-a-real-policy", kReferrerPolicyDefault, false}, - {"not-a-real-policy,also-not-a-real-policy", kReferrerPolicyDefault, + {"not-a-real-policy", network::mojom::ReferrerPolicy::kDefault, false}, + {"not-a-real-policy,also-not-a-real-policy", + network::mojom::ReferrerPolicy::kDefault, false}, + {"not-a-real-policy,unsafe-url", network::mojom::ReferrerPolicy::kAlways, false}, - {"not-a-real-policy,unsafe-url", kReferrerPolicyAlways, false}, - {"unsafe-url,not-a-real-policy", kReferrerPolicyAlways, false}, - // Test parsing each of the policy values. - {"always", kReferrerPolicyAlways, true}, - {"default", kReferrerPolicyNoReferrerWhenDowngrade, true}, - {"never", kReferrerPolicyNever, true}, - {"no-referrer", kReferrerPolicyNever, false}, - {"default", kReferrerPolicyNoReferrerWhenDowngrade, true}, - {"no-referrer-when-downgrade", kReferrerPolicyNoReferrerWhenDowngrade, + {"unsafe-url,not-a-real-policy", network::mojom::ReferrerPolicy::kAlways, false}, - {"origin", kReferrerPolicyOrigin, false}, - {"origin-when-crossorigin", kReferrerPolicyOriginWhenCrossOrigin, true}, - {"origin-when-cross-origin", kReferrerPolicyOriginWhenCrossOrigin, false}, - {"same-origin", kReferrerPolicySameOrigin, false}, - {"strict-origin", kReferrerPolicyStrictOrigin, false}, + // Test parsing each of the policy values. + {"always", network::mojom::ReferrerPolicy::kAlways, true}, + {"default", network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, + true}, + {"never", network::mojom::ReferrerPolicy::kNever, true}, + {"no-referrer", network::mojom::ReferrerPolicy::kNever, false}, + {"default", network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, + true}, + {"no-referrer-when-downgrade", + network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, false}, + {"origin", network::mojom::ReferrerPolicy::kOrigin, false}, + {"origin-when-crossorigin", + network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, true}, + {"origin-when-cross-origin", + network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, false}, + {"same-origin", network::mojom::ReferrerPolicy::kSameOrigin, false}, + {"strict-origin", network::mojom::ReferrerPolicy::kStrictOrigin, false}, {"strict-origin-when-cross-origin", - kReferrerPolicyStrictOriginWhenCrossOrigin, false}, - {"unsafe-url", kReferrerPolicyAlways}, + network::mojom::ReferrerPolicy:: + kNoReferrerWhenDowngradeOriginWhenCrossOrigin, + false}, + {"unsafe-url", network::mojom::ReferrerPolicy::kAlways}, }; for (auto test : tests) { - GetDocument().SetReferrerPolicy(kReferrerPolicyDefault); + GetDocument().SetReferrerPolicy(network::mojom::ReferrerPolicy::kDefault); if (test.is_legacy) { // Legacy keyword support must be explicitly enabled for the policy to // parse successfully. GetDocument().ParseAndSetReferrerPolicy(test.policy); - EXPECT_EQ(kReferrerPolicyDefault, GetDocument().GetReferrerPolicy()); + EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault, + GetDocument().GetReferrerPolicy()); GetDocument().ParseAndSetReferrerPolicy(test.policy, true); } else { GetDocument().ParseAndSetReferrerPolicy(test.policy); @@ -558,19 +569,19 @@ TEST_F(DocumentTest, StyleVersion) { EXPECT_TRUE(element); uint64_t previous_style_version = GetDocument().StyleVersion(); - element->setAttribute(blink::HTMLNames::classAttr, "notfound"); + element->setAttribute(blink::html_names::kClassAttr, "notfound"); EXPECT_EQ(previous_style_version, GetDocument().StyleVersion()); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); previous_style_version = GetDocument().StyleVersion(); - element->setAttribute(blink::HTMLNames::classAttr, "a"); + element->setAttribute(blink::html_names::kClassAttr, "a"); EXPECT_NE(previous_style_version, GetDocument().StyleVersion()); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); previous_style_version = GetDocument().StyleVersion(); - element->setAttribute(blink::HTMLNames::classAttr, "a b"); + element->setAttribute(blink::html_names::kClassAttr, "a b"); EXPECT_NE(previous_style_version, GetDocument().StyleVersion()); } @@ -620,13 +631,13 @@ TEST_F(DocumentTest, SynchronousMutationNotifier) { EXPECT_EQ(GetDocument(), observer.LifecycleContext()); EXPECT_EQ(0, observer.CountContextDestroyedCalled()); - Element* div_node = GetDocument().CreateRawElement(HTMLNames::divTag); + Element* div_node = GetDocument().CreateRawElement(html_names::kDivTag); GetDocument().body()->AppendChild(div_node); - Element* bold_node = GetDocument().CreateRawElement(HTMLNames::bTag); + Element* bold_node = GetDocument().CreateRawElement(html_names::kBTag); div_node->AppendChild(bold_node); - Element* italic_node = GetDocument().CreateRawElement(HTMLNames::iTag); + Element* italic_node = GetDocument().CreateRawElement(html_names::kITag); div_node->AppendChild(italic_node); Node* text_node = GetDocument().createTextNode("0123456789"); @@ -686,7 +697,7 @@ TEST_F(DocumentTest, SynchronousMutationNotifierMergeTextNodes) { TEST_F(DocumentTest, SynchronousMutationNotifierMoveTreeToNewDocument) { auto& observer = *new TestSynchronousMutationObserver(GetDocument()); - Node* move_sample = GetDocument().CreateRawElement(HTMLNames::divTag); + Node* move_sample = GetDocument().CreateRawElement(html_names::kDivTag); move_sample->appendChild(GetDocument().createTextNode("a123")); move_sample->appendChild(GetDocument().createTextNode("b456")); GetDocument().body()->AppendChild(move_sample); @@ -710,7 +721,8 @@ TEST_F(DocumentTest, SynchronousMutationNotifieReplaceChild) { auto& observer = *new TestSynchronousMutationObserver(GetDocument()); Element* const replaced_node = GetDocument().body(); GetDocument().documentElement()->ReplaceChild( - GetDocument().CreateRawElement(HTMLNames::divTag), GetDocument().body()); + GetDocument().CreateRawElement(html_names::kDivTag), + GetDocument().body()); ASSERT_EQ(2u, observer.ChildrenChangedNodes().size()); EXPECT_EQ(GetDocument().documentElement(), observer.ChildrenChangedNodes()[0]); @@ -820,9 +832,10 @@ TEST_F(DocumentTest, ValidationMessageCleanup) { // true. It's necessary to kick unload process. GetDocument().ImplicitOpen(kForceSynchronousParsing); GetDocument().CancelParsing(); - GetDocument().AppendChild(GetDocument().CreateRawElement(HTMLNames::htmlTag)); + GetDocument().AppendChild( + GetDocument().CreateRawElement(html_names::kHTMLTag)); SetHtmlInnerHTML("<body><input required></body>"); - Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); + Element* script = GetDocument().CreateRawElement(html_names::kScriptTag); script->setTextContent( "window.onunload = function() {" "document.querySelector('input').reportValidity(); };"); @@ -968,17 +981,19 @@ TEST_F(DocumentTest, CanExecuteScriptsWithSandboxAndIsolatedWorld) { ScriptState* isolated_world_without_csp_script_state = ToScriptState(frame, *world_without_csp); ASSERT_TRUE(world_without_csp->IsIsolatedWorld()); - EXPECT_FALSE(world_without_csp->IsolatedWorldHasContentSecurityPolicy()); + EXPECT_FALSE(IsolatedWorldCSP::Get().HasContentSecurityPolicy( + kIsolatedWorldWithoutCSPId)); constexpr int kIsolatedWorldWithCSPId = 2; scoped_refptr<DOMWrapperWorld> world_with_csp = DOMWrapperWorld::EnsureIsolatedWorld(isolate, kIsolatedWorldWithCSPId); - DOMWrapperWorld::SetIsolatedWorldContentSecurityPolicy( + IsolatedWorldCSP::Get().SetContentSecurityPolicy( kIsolatedWorldWithCSPId, String::FromUTF8("script-src *")); ScriptState* isolated_world_with_csp_script_state = ToScriptState(frame, *world_with_csp); ASSERT_TRUE(world_with_csp->IsIsolatedWorld()); - EXPECT_TRUE(world_with_csp->IsolatedWorldHasContentSecurityPolicy()); + EXPECT_TRUE(IsolatedWorldCSP::Get().HasContentSecurityPolicy( + kIsolatedWorldWithCSPId)); { // Since the page is sandboxed, main world script execution shouldn't be @@ -1143,7 +1158,7 @@ class ParameterizedViewportFitDocumentTest } GetDocument().documentElement()->SetInnerHTMLFromString(html.ToString()); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); } }; diff --git a/chromium/third_party/blink/renderer/core/dom/document_type.h b/chromium/third_party/blink/renderer/core/dom/document_type.h index 2a3648cf904..fa4bf122c21 100644 --- a/chromium/third_party/blink/renderer/core/dom/document_type.h +++ b/chromium/third_party/blink/renderer/core/dom/document_type.h @@ -36,19 +36,20 @@ class DocumentType final : public Node { const String& name, const String& public_id, const String& system_id) { - return new DocumentType(document, name, public_id, system_id); + return MakeGarbageCollected<DocumentType>(document, name, public_id, + system_id); } - const String& name() const { return name_; } - const String& publicId() const { return public_id_; } - const String& systemId() const { return system_id_; } - - private: DocumentType(Document*, const String& name, const String& public_id, const String& system_id); + const String& name() const { return name_; } + const String& publicId() const { return public_id_; } + const String& systemId() const { return system_id_; } + + private: String nodeName() const override; NodeType getNodeType() const override; Node* Clone(Document&, CloneChildrenFlag) const override; diff --git a/chromium/third_party/blink/renderer/core/dom/dom_exception.cc b/chromium/third_party/blink/renderer/core/dom/dom_exception.cc index 1676d597178..85e29a72e65 100644 --- a/chromium/third_party/blink/renderer/core/dom/dom_exception.cc +++ b/chromium/third_party/blink/renderer/core/dom/dom_exception.cc @@ -174,7 +174,7 @@ DOMException* DOMException::Create(DOMExceptionCode exception_code, const String& sanitized_message, const String& unsanitized_message) { const DOMExceptionEntry* entry = FindErrorEntry(exception_code); - return new DOMException( + return MakeGarbageCollected<DOMException>( ToLegacyErrorCode(entry->code), entry->name ? entry->name : "Error", sanitized_message.IsNull() ? String(entry->message) : sanitized_message, unsanitized_message); @@ -182,7 +182,8 @@ DOMException* DOMException::Create(DOMExceptionCode exception_code, // static DOMException* DOMException::Create(const String& message, const String& name) { - return new DOMException(FindLegacyErrorCode(name), name, message, String()); + return MakeGarbageCollected<DOMException>(FindLegacyErrorCode(name), name, + message, String()); } // static diff --git a/chromium/third_party/blink/renderer/core/dom/dom_exception.h b/chromium/third_party/blink/renderer/core/dom/dom_exception.h index e96e5e8abbf..acc876f0db7 100644 --- a/chromium/third_party/blink/renderer/core/dom/dom_exception.h +++ b/chromium/third_party/blink/renderer/core/dom/dom_exception.h @@ -49,6 +49,11 @@ class CORE_EXPORT DOMException final : public ScriptWrappable { // Constructor exposed to script. static DOMException* Create(const String& message, const String& name); + DOMException(unsigned short legacy_code, + const String& name, + const String& sanitized_message, + const String& unsanitized_message); + static String GetErrorName(DOMExceptionCode); static String GetErrorMessage(DOMExceptionCode); @@ -68,11 +73,6 @@ class CORE_EXPORT DOMException final : public ScriptWrappable { String ToStringForConsole() const; private: - DOMException(unsigned short legacy_code, - const String& name, - const String& sanitized_message, - const String& unsanitized_message); - unsigned short legacy_code_; String name_; String sanitized_message_; diff --git a/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc b/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc index c360933eb10..3dac1a5a6f6 100644 --- a/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc +++ b/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc @@ -84,9 +84,9 @@ XMLDocument* DOMImplementation::createDocument( XMLDocument* doc = nullptr; DocumentInit init = DocumentInit::Create().WithContextDocument(document_->ContextDocument()); - if (namespace_uri == SVGNames::svgNamespaceURI) { + if (namespace_uri == svg_names::kNamespaceURI) { doc = XMLDocument::CreateSVG(init); - } else if (namespace_uri == HTMLNames::xhtmlNamespaceURI) { + } else if (namespace_uri == html_names::xhtmlNamespaceURI) { doc = XMLDocument::CreateXHTML( init.WithRegistrationContext(document_->RegistrationContext())); } else { diff --git a/chromium/third_party/blink/renderer/core/dom/dom_implementation.h b/chromium/third_party/blink/renderer/core/dom/dom_implementation.h index 36016c3cce8..b30c6f1b66d 100644 --- a/chromium/third_party/blink/renderer/core/dom/dom_implementation.h +++ b/chromium/third_party/blink/renderer/core/dom/dom_implementation.h @@ -40,9 +40,11 @@ class CORE_EXPORT DOMImplementation final : public ScriptWrappable { public: static DOMImplementation* Create(Document& document) { - return new DOMImplementation(document); + return MakeGarbageCollected<DOMImplementation>(document); } + explicit DOMImplementation(Document&); + // DOM methods & attributes for DOMImplementation bool hasFeature() { return true; } DocumentType* createDocumentType(const AtomicString& qualified_name, @@ -69,8 +71,6 @@ class CORE_EXPORT DOMImplementation final : public ScriptWrappable { void Trace(blink::Visitor*) override; private: - explicit DOMImplementation(Document&); - Member<Document> document_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/dom_string_list.h b/chromium/third_party/blink/renderer/core/dom/dom_string_list.h index adb66dfa73f..529413a20ce 100644 --- a/chromium/third_party/blink/renderer/core/dom/dom_string_list.h +++ b/chromium/third_party/blink/renderer/core/dom/dom_string_list.h @@ -40,7 +40,11 @@ class CORE_EXPORT DOMStringList final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - static DOMStringList* Create() { return new DOMStringList(); } + static DOMStringList* Create() { + return MakeGarbageCollected<DOMStringList>(); + } + + explicit DOMStringList() = default; bool IsEmpty() const { return strings_.IsEmpty(); } void clear() { strings_.clear(); } @@ -56,8 +60,6 @@ class CORE_EXPORT DOMStringList final : public ScriptWrappable { operator const Vector<String>&() const { return strings_; } private: - explicit DOMStringList() = default; - Vector<String> strings_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/dom_token_list.h b/chromium/third_party/blink/renderer/core/dom/dom_token_list.h index 5c50df16f1d..00c1f1f2319 100644 --- a/chromium/third_party/blink/renderer/core/dom/dom_token_list.h +++ b/chromium/third_party/blink/renderer/core/dom/dom_token_list.h @@ -44,8 +44,10 @@ class CORE_EXPORT DOMTokenList : public ScriptWrappable { public: static DOMTokenList* Create(Element& element, const QualifiedName& attr) { - return new DOMTokenList(element, attr); + return MakeGarbageCollected<DOMTokenList>(element, attr); } + DOMTokenList(Element& element, const QualifiedName& attr) + : element_(element), attribute_name_(attr) {} ~DOMTokenList() override = default; void Trace(blink::Visitor*) override; @@ -75,8 +77,6 @@ class CORE_EXPORT DOMTokenList : public ScriptWrappable { void Remove(const AtomicString&); protected: - DOMTokenList(Element& element, const QualifiedName& attr) - : element_(element), attribute_name_(attr) {} Element& GetElement() const { return *element_; } virtual bool ValidateTokenValue(const AtomicString&, ExceptionState&) const; diff --git a/chromium/third_party/blink/renderer/core/dom/element.cc b/chromium/third_party/blink/renderer/core/dom/element.cc index 20396498651..c0561e2fc14 100644 --- a/chromium/third_party/blink/renderer/core/dom/element.cc +++ b/chromium/third_party/blink/renderer/core/dom/element.cc @@ -86,7 +86,6 @@ #include "third_party/blink/renderer/core/editing/editing_utilities.h" #include "third_party/blink/renderer/core/editing/ephemeral_range.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" -#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h" #include "third_party/blink/renderer/core/editing/selection_template.h" #include "third_party/blink/renderer/core/editing/serializers/serialization.h" #include "third_party/blink/renderer/core/editing/set_selection_options.h" @@ -134,12 +133,7 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/pointer_lock_controller.h" #include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" -#include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h" -#include "third_party/blink/renderer/core/page/scrolling/scroll_customization_callbacks.h" -#include "third_party/blink/renderer/core/page/scrolling/scroll_state.h" -#include "third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h" #include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h" -#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h" #include "third_party/blink/renderer/core/page/spatial_navigation.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" @@ -167,31 +161,61 @@ namespace blink { +using namespace html_names; + +enum class ClassStringContent { kEmpty, kWhiteSpaceOnly, kHasClasses }; + namespace { -// We need to retain the scroll customization callbacks until the element -// they're associated with is destroyed. It would be simplest if the callbacks -// could be stored in ElementRareData, but we can't afford the space increase. -// Instead, keep the scroll customization callbacks here. The other option would -// be to store these callbacks on the Page or document, but that necessitates a -// bunch more logic for transferring the callbacks between Pages when elements -// are moved around. -ScrollCustomizationCallbacks& GetScrollCustomizationCallbacks() { - DEFINE_STATIC_LOCAL(Persistent<ScrollCustomizationCallbacks>, - scroll_customization_callbacks, - (new ScrollCustomizationCallbacks)); - return *scroll_customization_callbacks; +bool IsRootEditableElementWithCounting(const Element& element) { + bool is_editable = IsRootEditableElement(element); + Document& doc = element.GetDocument(); + if (!doc.IsActive()) + return is_editable; + // -webkit-user-modify doesn't affect text control elements. + if (element.IsTextControl()) + return is_editable; + const auto* style = element.GetComputedStyle(); + if (!style) + return is_editable; + auto user_modify = style->UserModify(); + const AtomicString& ce_value = element.FastGetAttribute(kContenteditableAttr); + if (ce_value.IsNull() || DeprecatedEqualIgnoringCase(ce_value, "false")) { + if (user_modify == EUserModify::kReadWritePlaintextOnly) { + UseCounter::Count(doc, WebFeature::kPlainTextEditingEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyPlainTextEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective); + } else if (user_modify == EUserModify::kReadWrite) { + UseCounter::Count(doc, WebFeature::kWebKitUserModifyReadWriteEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective); + } + } else if (ce_value.IsEmpty() || + DeprecatedEqualIgnoringCase(ce_value, "true")) { + if (user_modify == EUserModify::kReadWritePlaintextOnly) { + UseCounter::Count(doc, WebFeature::kPlainTextEditingEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyPlainTextEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective); + } else if (user_modify == EUserModify::kReadOnly) { + UseCounter::Count(doc, WebFeature::kWebKitUserModifyReadOnlyEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective); + } + } else if (DeprecatedEqualIgnoringCase(ce_value, "plaintext-only")) { + UseCounter::Count(doc, WebFeature::kPlainTextEditingEffective); + if (user_modify == EUserModify::kReadWrite) { + UseCounter::Count(doc, WebFeature::kWebKitUserModifyReadWriteEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective); + } else if (user_modify == EUserModify::kReadOnly) { + UseCounter::Count(doc, WebFeature::kWebKitUserModifyReadOnlyEffective); + UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective); + } + } + return is_editable; } } // namespace -using namespace HTMLNames; -using namespace XMLNames; - -enum class ClassStringContent { kEmpty, kWhiteSpaceOnly, kHasClasses }; - Element* Element::Create(const QualifiedName& tag_name, Document* document) { - return new Element(tag_name, document, kCreateElement); + return MakeGarbageCollected<Element>(tag_name, document, kCreateElement); } Element::Element(const QualifiedName& tag_name, @@ -238,12 +262,12 @@ void Element::SetTabIndexExplicitly() { } void Element::setTabIndex(int value) { - SetIntegralAttribute(tabindexAttr, value); + SetIntegralAttribute(kTabindexAttr, value); } int Element::tabIndex() const { return HasElementFlag(ElementFlags::kTabIndexWasSetExplicitly) - ? GetIntegralAttribute(tabindexAttr) + ? GetIntegralAttribute(kTabindexAttr) : 0; } @@ -374,7 +398,7 @@ ElementAnimations* Element::GetElementAnimations() const { ElementAnimations& Element::EnsureElementAnimations() { ElementRareData& rare_data = EnsureElementRareData(); if (!rare_data.GetElementAnimations()) - rare_data.SetElementAnimations(new ElementAnimations()); + rare_data.SetElementAnimations(MakeGarbageCollected<ElementAnimations>()); return *rare_data.GetElementAnimations(); } @@ -412,7 +436,7 @@ void Element::SynchronizeAllAttributes() const { inline void Element::SynchronizeAttribute(const QualifiedName& name) const { if (!GetElementData()) return; - if (UNLIKELY(name == styleAttr && + if (UNLIKELY(name == kStyleAttr && GetElementData()->style_attribute_is_dirty_)) { DCHECK(IsStyledElement()); SynchronizeStyleAttributeInternal(); @@ -431,7 +455,7 @@ void Element::SynchronizeAttribute(const AtomicString& local_name) const { if (!GetElementData()) return; if (GetElementData()->style_attribute_is_dirty_ && - LowercaseIfNecessary(local_name) == styleAttr.LocalName()) { + LowercaseIfNecessary(local_name) == kStyleAttr.LocalName()) { DCHECK(IsStyledElement()); SynchronizeStyleAttributeInternal(); return; @@ -477,19 +501,15 @@ void Element::setNonce(const AtomicString& nonce) { } void Element::scrollIntoView(ScrollIntoViewOptionsOrBoolean arg) { - ScrollIntoViewOptions options; + ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create(); if (arg.IsBoolean()) { if (arg.GetAsBoolean()) - options.setBlock("start"); + options->setBlock("start"); else - options.setBlock("end"); - options.setInlinePosition("nearest"); + options->setBlock("end"); + options->setInlinePosition("nearest"); } else if (arg.IsScrollIntoViewOptions()) { options = arg.GetAsScrollIntoViewOptions(); - if (!RuntimeEnabledFeatures::CSSOMSmoothScrollEnabled() && - options.behavior() == "smooth") { - options.setBehavior("instant"); - } } scrollIntoViewWithOptions(options); } @@ -500,15 +520,15 @@ void Element::scrollIntoView(bool align_to_top) { scrollIntoView(arg); } -static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions& options, +static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions* options, ScrollOrientation axis, bool is_horizontal_writing_mode, bool is_flipped_blocks_mode) { String alignment = ((axis == kHorizontalScroll && is_horizontal_writing_mode) || (axis == kVerticalScroll && !is_horizontal_writing_mode)) - ? options.inlinePosition() - : options.block(); + ? options->inlinePosition() + : options->block(); if (alignment == "center") return ScrollAlignment::kAlignCenterAlways; @@ -536,17 +556,17 @@ static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions& options, : ScrollAlignment::kAlignToEdgeIfNeeded; } -void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions& options) { +void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions* options) { GetDocument().EnsurePaintLocationDataValidForNode(this); ScrollIntoViewNoVisualUpdate(options); } void Element::ScrollIntoViewNoVisualUpdate( - const ScrollIntoViewOptions& options) { + const ScrollIntoViewOptions* options) { if (!GetLayoutObject() || !GetDocument().GetPage()) return; - ScrollBehavior behavior = (options.behavior() == "smooth") + ScrollBehavior behavior = (options->behavior() == "smooth") ? kScrollBehaviorSmooth : kScrollBehaviorAuto; @@ -588,182 +608,6 @@ void Element::scrollIntoViewIfNeeded(bool center_if_needed) { } } -void Element::setDistributeScroll(V8ScrollStateCallback* scroll_state_callback, - const String& native_scroll_behavior) { - GetScrollCustomizationCallbacks().SetDistributeScroll( - this, ScrollStateCallbackV8Impl::Create(scroll_state_callback, - native_scroll_behavior)); -} - -void Element::setApplyScroll(V8ScrollStateCallback* scroll_state_callback, - const String& native_scroll_behavior) { - SetApplyScroll(ScrollStateCallbackV8Impl::Create(scroll_state_callback, - native_scroll_behavior)); -} - -void Element::SetApplyScroll(ScrollStateCallback* scroll_state_callback) { - GetScrollCustomizationCallbacks().SetApplyScroll(this, scroll_state_callback); -} - -void Element::RemoveApplyScroll() { - GetScrollCustomizationCallbacks().RemoveApplyScroll(this); -} - -ScrollStateCallback* Element::GetApplyScroll() { - return GetScrollCustomizationCallbacks().GetApplyScroll(this); -} - -void Element::NativeDistributeScroll(ScrollState& scroll_state) { - if (scroll_state.FullyConsumed()) - return; - - scroll_state.distributeToScrollChainDescendant(); - - // The scroll doesn't propagate, and we're currently scrolling an element - // other than this one, prevent the scroll from propagating to this element. - if (scroll_state.DeltaConsumedForScrollSequence() && - scroll_state.CurrentNativeScrollingElement() != this) { - return; - } - - const double delta_x = scroll_state.deltaX(); - const double delta_y = scroll_state.deltaY(); - - CallApplyScroll(scroll_state); - - if (delta_x != scroll_state.deltaX() || delta_y != scroll_state.deltaY()) - scroll_state.SetCurrentNativeScrollingElement(this); -} - -void Element::CallDistributeScroll(ScrollState& scroll_state) { - TRACE_EVENT0("input", "Element::CallDistributeScroll"); - ScrollStateCallback* callback = - GetScrollCustomizationCallbacks().GetDistributeScroll(this); - - // TODO(bokan): Need to add tests before we allow calling custom callbacks - // for non-touch modalities. For now, just call into the native callback but - // allow the viewport scroll callback so we don't disable overscroll. - // crbug.com/623079. - bool disable_custom_callbacks = !scroll_state.isDirectManipulation() && - !GetDocument() - .GetPage() - ->GlobalRootScrollerController() - .IsViewportScrollCallback(callback); - - disable_custom_callbacks |= - !RootScrollerUtil::IsGlobal(this) && - RuntimeEnabledFeatures::ScrollCustomizationEnabled() && - !GetScrollCustomizationCallbacks().InScrollPhase(this); - - if (!callback || disable_custom_callbacks) { - NativeDistributeScroll(scroll_state); - return; - } - if (callback->NativeScrollBehavior() != - WebNativeScrollBehavior::kPerformAfterNativeScroll) - callback->Invoke(&scroll_state); - if (callback->NativeScrollBehavior() != - WebNativeScrollBehavior::kDisableNativeScroll) - NativeDistributeScroll(scroll_state); - if (callback->NativeScrollBehavior() == - WebNativeScrollBehavior::kPerformAfterNativeScroll) - callback->Invoke(&scroll_state); -} - -void Element::NativeApplyScroll(ScrollState& scroll_state) { - // All elements in the scroll chain should be boxes. - DCHECK(!GetLayoutObject() || GetLayoutObject()->IsBox()); - - if (scroll_state.FullyConsumed()) - return; - - FloatSize delta(scroll_state.deltaX(), scroll_state.deltaY()); - - if (delta.IsZero()) - return; - - // TODO(esprehn): This should use - // updateStyleAndLayoutIgnorePendingStylesheetsForNode. - GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); - - LayoutBox* box_to_scroll = nullptr; - - if (this == GetDocument().documentElement()) - box_to_scroll = GetDocument().GetLayoutView(); - else if (GetLayoutObject()) - box_to_scroll = ToLayoutBox(GetLayoutObject()); - - if (!box_to_scroll) - return; - - ScrollableArea* scrollable_area = - box_to_scroll->EnclosingBox()->GetScrollableArea(); - - if (!scrollable_area) - return; - - ScrollResult result = scrollable_area->UserScroll( - ScrollGranularity(static_cast<int>(scroll_state.deltaGranularity())), - delta); - - if (!result.DidScroll()) - return; - - // FIXME: Native scrollers should only consume the scroll they - // apply. See crbug.com/457765. - scroll_state.ConsumeDeltaNative(delta.Width(), delta.Height()); - - // We need to setCurrentNativeScrollingElement in both the - // distributeScroll and applyScroll default implementations so - // that if JS overrides one of these methods, but not the - // other, this bookkeeping remains accurate. - scroll_state.SetCurrentNativeScrollingElement(this); -}; - -void Element::CallApplyScroll(ScrollState& scroll_state) { - TRACE_EVENT0("input", "Element::CallApplyScroll"); - // Hits ASSERTs when trying to determine whether we need to scroll on main - // or CC. http://crbug.com/625676. - DisableCompositingQueryAsserts disabler; - - if (!GetDocument().GetPage()) { - // We should always have a Page if we're scrolling. See - // crbug.com/689074 for details. - return; - } - - ScrollStateCallback* callback = - GetScrollCustomizationCallbacks().GetApplyScroll(this); - - // TODO(bokan): Need to add tests before we allow calling custom callbacks - // for non-touch modalities. For now, just call into the native callback but - // allow the viewport scroll callback so we don't disable overscroll. - // crbug.com/623079. - bool disable_custom_callbacks = !scroll_state.isDirectManipulation() && - !GetDocument() - .GetPage() - ->GlobalRootScrollerController() - .IsViewportScrollCallback(callback); - disable_custom_callbacks |= - !RootScrollerUtil::IsGlobal(this) && - RuntimeEnabledFeatures::ScrollCustomizationEnabled() && - !GetScrollCustomizationCallbacks().InScrollPhase(this); - - if (!callback || disable_custom_callbacks) { - NativeApplyScroll(scroll_state); - return; - } - if (callback->NativeScrollBehavior() != - WebNativeScrollBehavior::kPerformAfterNativeScroll) - callback->Invoke(&scroll_state); - if (callback->NativeScrollBehavior() != - WebNativeScrollBehavior::kDisableNativeScroll) - NativeApplyScroll(scroll_state); - if (callback->NativeScrollBehavior() == - WebNativeScrollBehavior::kPerformAfterNativeScroll) - callback->Invoke(&scroll_state); -} - int Element::OffsetLeft() { GetDocument().EnsurePaintLocationDataValidForNode(this); if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject()) @@ -953,8 +797,8 @@ void Element::setScrollLeft(double new_left) { if (GetDocument().ScrollingElementNoLayout() == this) { if (LocalDOMWindow* window = GetDocument().domWindow()) { - ScrollToOptions options; - options.setLeft(new_left); + ScrollToOptions* options = ScrollToOptions::Create(); + options->setLeft(new_left); window->scrollTo(options); } } else { @@ -964,12 +808,13 @@ void Element::setScrollLeft(double new_left) { FloatPoint end_point(new_left * box->Style()->EffectiveZoom(), box->ScrollTop().ToFloat()); - if (RuntimeEnabledFeatures::CSSScrollSnapPointsEnabled()) { - end_point = GetDocument() - .GetSnapCoordinator() - ->GetSnapPositionForPoint(*box, end_point, true, false) - .value_or(end_point); - } + std::unique_ptr<SnapSelectionStrategy> strategy = + SnapSelectionStrategy::CreateForEndPosition( + gfx::ScrollOffset(end_point), true, false); + end_point = GetDocument() + .GetSnapCoordinator() + ->GetSnapPosition(*box, *strategy) + .value_or(end_point); box->SetScrollLeft(LayoutUnit::FromFloatRound(end_point.X())); } } @@ -984,8 +829,8 @@ void Element::setScrollTop(double new_top) { if (GetDocument().ScrollingElementNoLayout() == this) { if (LocalDOMWindow* window = GetDocument().domWindow()) { - ScrollToOptions options; - options.setTop(new_top); + ScrollToOptions* options = ScrollToOptions::Create(); + options->setTop(new_top); window->scrollTo(options); } } else { @@ -995,12 +840,13 @@ void Element::setScrollTop(double new_top) { FloatPoint end_point(box->ScrollLeft().ToFloat(), new_top * box->Style()->EffectiveZoom()); - if (RuntimeEnabledFeatures::CSSScrollSnapPointsEnabled()) { - end_point = GetDocument() - .GetSnapCoordinator() - ->GetSnapPositionForPoint(*box, end_point, false, true) - .value_or(end_point); - } + std::unique_ptr<SnapSelectionStrategy> strategy = + SnapSelectionStrategy::CreateForEndPosition( + gfx::ScrollOffset(end_point), false, true); + end_point = GetDocument() + .GetSnapCoordinator() + ->GetSnapPosition(*box, *strategy) + .value_or(end_point); box->SetScrollTop(LayoutUnit::FromFloatRound(end_point.Y())); } } @@ -1050,13 +896,13 @@ int Element::scrollHeight() { } void Element::scrollBy(double x, double y) { - ScrollToOptions scroll_to_options; - scroll_to_options.setLeft(x); - scroll_to_options.setTop(y); + ScrollToOptions* scroll_to_options = ScrollToOptions::Create(); + scroll_to_options->setLeft(x); + scroll_to_options->setTop(y); scrollBy(scroll_to_options); } -void Element::scrollBy(const ScrollToOptions& scroll_to_options) { +void Element::scrollBy(const ScrollToOptions* scroll_to_options) { if (!InActiveDocument()) return; @@ -1072,13 +918,13 @@ void Element::scrollBy(const ScrollToOptions& scroll_to_options) { } void Element::scrollTo(double x, double y) { - ScrollToOptions scroll_to_options; - scroll_to_options.setLeft(x); - scroll_to_options.setTop(y); + ScrollToOptions* scroll_to_options = ScrollToOptions::Create(); + scroll_to_options->setLeft(x); + scroll_to_options->setTop(y); scrollTo(scroll_to_options); } -void Element::scrollTo(const ScrollToOptions& scroll_to_options) { +void Element::scrollTo(const ScrollToOptions* scroll_to_options) { if (!InActiveDocument()) return; @@ -1093,86 +939,84 @@ void Element::scrollTo(const ScrollToOptions& scroll_to_options) { } } -void Element::ScrollLayoutBoxBy(const ScrollToOptions& scroll_to_options) { - double left = - scroll_to_options.hasLeft() - ? ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.left()) - : 0.0; - double top = - scroll_to_options.hasTop() - ? ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.top()) - : 0.0; +void Element::ScrollLayoutBoxBy(const ScrollToOptions* scroll_to_options) { + gfx::ScrollOffset displacement; + if (scroll_to_options->hasLeft()) { + displacement.set_x( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->left())); + } + if (scroll_to_options->hasTop()) { + displacement.set_y( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->top())); + } ScrollBehavior scroll_behavior = kScrollBehaviorAuto; - ScrollableArea::ScrollBehaviorFromString(scroll_to_options.behavior(), + ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(), scroll_behavior); LayoutBox* box = GetLayoutBox(); if (box) { - float current_scaled_left = box->ScrollLeft().ToFloat(); - float current_scaled_top = box->ScrollTop().ToFloat(); - float new_scaled_left = - left * box->Style()->EffectiveZoom() + current_scaled_left; - float new_scaled_top = - top * box->Style()->EffectiveZoom() + current_scaled_top; - - FloatPoint new_scaled_position(new_scaled_left, new_scaled_top); - if (RuntimeEnabledFeatures::CSSScrollSnapPointsEnabled()) { - new_scaled_position = - GetDocument() - .GetSnapCoordinator() - ->GetSnapPositionForPoint(*box, new_scaled_position, - scroll_to_options.hasLeft(), - scroll_to_options.hasTop()) - .value_or(new_scaled_position); - } - box->ScrollToPosition(new_scaled_position, scroll_behavior); + gfx::ScrollOffset current_position(box->ScrollLeft().ToFloat(), + box->ScrollTop().ToFloat()); + displacement.Scale(box->Style()->EffectiveZoom()); + gfx::ScrollOffset new_offset(current_position + displacement); + FloatPoint new_position(new_offset.x(), new_offset.y()); + + std::unique_ptr<SnapSelectionStrategy> strategy = + SnapSelectionStrategy::CreateForEndAndDirection(current_position, + displacement); + new_position = GetDocument() + .GetSnapCoordinator() + ->GetSnapPosition(*box, *strategy) + .value_or(new_position); + box->ScrollToPosition(new_position, scroll_behavior); } } -void Element::ScrollLayoutBoxTo(const ScrollToOptions& scroll_to_options) { +void Element::ScrollLayoutBoxTo(const ScrollToOptions* scroll_to_options) { ScrollBehavior scroll_behavior = kScrollBehaviorAuto; - ScrollableArea::ScrollBehaviorFromString(scroll_to_options.behavior(), + ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(), scroll_behavior); LayoutBox* box = GetLayoutBox(); if (box) { - float scaled_left = box->ScrollLeft().ToFloat(); - float scaled_top = box->ScrollTop().ToFloat(); - if (scroll_to_options.hasLeft()) - scaled_left = - ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.left()) * - box->Style()->EffectiveZoom(); - if (scroll_to_options.hasTop()) - scaled_top = - ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.top()) * - box->Style()->EffectiveZoom(); - - FloatPoint new_scaled_position(scaled_left, scaled_top); - if (RuntimeEnabledFeatures::CSSScrollSnapPointsEnabled()) { - new_scaled_position = - GetDocument() - .GetSnapCoordinator() - ->GetSnapPositionForPoint(*box, new_scaled_position, - scroll_to_options.hasLeft(), - scroll_to_options.hasTop()) - .value_or(new_scaled_position); + FloatPoint new_position(box->ScrollLeft().ToFloat(), + box->ScrollTop().ToFloat()); + if (scroll_to_options->hasLeft()) { + new_position.SetX( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->left()) * + box->Style()->EffectiveZoom()); + } + if (scroll_to_options->hasTop()) { + new_position.SetY( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->top()) * + box->Style()->EffectiveZoom()); } - box->ScrollToPosition(new_scaled_position, scroll_behavior); + + std::unique_ptr<SnapSelectionStrategy> strategy = + SnapSelectionStrategy::CreateForEndPosition( + gfx::ScrollOffset(new_position), scroll_to_options->hasLeft(), + scroll_to_options->hasTop()); + new_position = GetDocument() + .GetSnapCoordinator() + ->GetSnapPosition(*box, *strategy) + .value_or(new_position); + box->ScrollToPosition(new_position, scroll_behavior); } } -void Element::ScrollFrameBy(const ScrollToOptions& scroll_to_options) { - double left = - scroll_to_options.hasLeft() - ? ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.left()) - : 0.0; - double top = - scroll_to_options.hasTop() - ? ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.top()) - : 0.0; +void Element::ScrollFrameBy(const ScrollToOptions* scroll_to_options) { + gfx::ScrollOffset displacement; + if (scroll_to_options->hasLeft()) { + displacement.set_x( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->left())); + } + if (scroll_to_options->hasTop()) { + displacement.set_y( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->top())); + } ScrollBehavior scroll_behavior = kScrollBehaviorAuto; - ScrollableArea::ScrollBehaviorFromString(scroll_to_options.behavior(), + ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(), scroll_behavior); LocalFrame* frame = GetDocument().GetFrame(); if (!frame || !frame->View() || !GetDocument().GetPage()) @@ -1182,30 +1026,26 @@ void Element::ScrollFrameBy(const ScrollToOptions& scroll_to_options) { if (!viewport) return; - float new_scaled_left = - left * frame->PageZoomFactor() + viewport->GetScrollOffset().Width(); - float new_scaled_top = - top * frame->PageZoomFactor() + viewport->GetScrollOffset().Height(); + displacement.Scale(frame->PageZoomFactor()); + FloatPoint new_position = viewport->ScrollPosition() + + FloatPoint(displacement.x(), displacement.y()); - FloatPoint new_scaled_position = viewport->ScrollOffsetToPosition( - ScrollOffset(new_scaled_left, new_scaled_top)); - if (RuntimeEnabledFeatures::CSSScrollSnapPointsEnabled()) { - new_scaled_position = - GetDocument() - .GetSnapCoordinator() - ->GetSnapPositionForPoint( - *GetDocument().GetLayoutView(), new_scaled_position, - scroll_to_options.hasLeft(), scroll_to_options.hasTop()) - .value_or(new_scaled_position); - } - viewport->SetScrollOffset( - viewport->ScrollPositionToOffset(new_scaled_position), - kProgrammaticScroll, scroll_behavior); + gfx::ScrollOffset current_position(viewport->ScrollPosition()); + std::unique_ptr<SnapSelectionStrategy> strategy = + SnapSelectionStrategy::CreateForEndAndDirection(current_position, + displacement); + new_position = + GetDocument() + .GetSnapCoordinator() + ->GetSnapPosition(*GetDocument().GetLayoutView(), *strategy) + .value_or(new_position); + viewport->SetScrollOffset(viewport->ScrollPositionToOffset(new_position), + kProgrammaticScroll, scroll_behavior); } -void Element::ScrollFrameTo(const ScrollToOptions& scroll_to_options) { +void Element::ScrollFrameTo(const ScrollToOptions* scroll_to_options) { ScrollBehavior scroll_behavior = kScrollBehaviorAuto; - ScrollableArea::ScrollBehaviorFromString(scroll_to_options.behavior(), + ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(), scroll_behavior); LocalFrame* frame = GetDocument().GetFrame(); if (!frame || !frame->View() || !GetDocument().GetPage()) @@ -1215,31 +1055,30 @@ void Element::ScrollFrameTo(const ScrollToOptions& scroll_to_options) { if (!viewport) return; - float scaled_left = viewport->GetScrollOffset().Width(); - float scaled_top = viewport->GetScrollOffset().Height(); - if (scroll_to_options.hasLeft()) - scaled_left = - ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.left()) * - frame->PageZoomFactor(); - if (scroll_to_options.hasTop()) - scaled_top = - ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options.top()) * - frame->PageZoomFactor(); - - FloatPoint new_scaled_position = - viewport->ScrollOffsetToPosition(ScrollOffset(scaled_left, scaled_top)); - if (RuntimeEnabledFeatures::CSSScrollSnapPointsEnabled()) { - new_scaled_position = - GetDocument() - .GetSnapCoordinator() - ->GetSnapPositionForPoint( - *GetDocument().GetLayoutView(), new_scaled_position, - scroll_to_options.hasLeft(), scroll_to_options.hasTop()) - .value_or(new_scaled_position); - } - viewport->SetScrollOffset( - viewport->ScrollPositionToOffset(new_scaled_position), - kProgrammaticScroll, scroll_behavior); + ScrollOffset new_offset = viewport->GetScrollOffset(); + if (scroll_to_options->hasLeft()) { + new_offset.SetWidth( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->left()) * + frame->PageZoomFactor()); + } + if (scroll_to_options->hasTop()) { + new_offset.SetHeight( + ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->top()) * + frame->PageZoomFactor()); + } + + FloatPoint new_position = viewport->ScrollOffsetToPosition(new_offset); + std::unique_ptr<SnapSelectionStrategy> strategy = + SnapSelectionStrategy::CreateForEndPosition( + gfx::ScrollOffset(new_position), scroll_to_options->hasLeft(), + scroll_to_options->hasTop()); + new_position = + GetDocument() + .GetSnapCoordinator() + ->GetSnapPosition(*GetDocument().GetLayoutView(), *strategy) + .value_or(new_position); + new_offset = viewport->ScrollPositionToOffset(new_position); + viewport->SetScrollOffset(new_offset, kProgrammaticScroll, scroll_behavior); } bool Element::HasNonEmptyLayoutSize() const { @@ -1420,7 +1259,7 @@ AccessibleNode* Element::accessibleNode() { } InvisibleState Element::Invisible() const { - const AtomicString& value = FastGetAttribute(invisibleAttr); + const AtomicString& value = FastGetAttribute(kInvisibleAttr); if (value.IsNull()) return InvisibleState::kMissing; if (EqualIgnoringASCIICase(value, "static")) @@ -1469,7 +1308,7 @@ void Element::InvisibleAttributeChanged(const AtomicString& old_value, if (old_value.IsNull() != new_value.IsNull()) { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kInvisibleChange)); + style_change_reason::kInvisibleChange)); } if (EqualIgnoringASCIICase(old_value, "static") && !IsInsideInvisibleStaticSubtree()) { @@ -1481,9 +1320,9 @@ void Element::InvisibleAttributeChanged(const AtomicString& old_value, void Element::DefaultEventHandler(Event& event) { if (RuntimeEnabledFeatures::InvisibleDOMEnabled() && - event.type() == EventTypeNames::activateinvisible && + event.type() == event_type_names::kActivateinvisible && event.target() == this) { - removeAttribute(invisibleAttr); + removeAttribute(kInvisibleAttr); event.SetDefaultHandled(); return; } @@ -1746,7 +1585,7 @@ void Element::AttributeChanged(const AttributeModificationParams& params) { *parent_shadow_root, name, params.new_value)) parent_shadow_root->SetNeedsDistributionRecalc(); } - if (name == HTMLNames::slotAttr && params.old_value != params.new_value) { + if (name == html_names::kSlotAttr && params.old_value != params.new_value) { if (ShadowRoot* root = V1ShadowRootOfParent()) root->DidChangeHostChildSlotName(params.old_value, params.new_value); } @@ -1755,7 +1594,7 @@ void Element::AttributeChanged(const AttributeModificationParams& params) { GetDocument().IncDOMTreeVersion(); - if (name == HTMLNames::idAttr) { + if (name == html_names::kIdAttr) { AtomicString old_id = GetElementData()->IdForStyleResolution(); AtomicString new_id = MakeIdForStyleResolution( params.new_value, GetDocument().InQuirksMode()); @@ -1763,33 +1602,33 @@ void Element::AttributeChanged(const AttributeModificationParams& params) { GetElementData()->SetIdForStyleResolution(new_id); GetDocument().GetStyleEngine().IdChangedForElement(old_id, new_id, *this); } - } else if (name == classAttr) { + } else if (name == kClassAttr) { ClassAttributeChanged(params.new_value); if (HasRareData() && GetElementRareData()->GetClassList()) { GetElementRareData()->GetClassList()->DidUpdateAttributeValue( params.old_value, params.new_value); } - } else if (name == HTMLNames::nameAttr) { + } else if (name == html_names::kNameAttr) { SetHasName(!params.new_value.IsNull()); - } else if (name == HTMLNames::partAttr) { + } else if (name == html_names::kPartAttr) { if (RuntimeEnabledFeatures::CSSPartPseudoElementEnabled()) { - EnsureElementRareData().SetPart(params.new_value); + part().DidUpdateAttributeValue(params.old_value, params.new_value); GetDocument().GetStyleEngine().PartChangedForElement(*this); } - } else if (name == HTMLNames::partmapAttr) { + } else if (name == html_names::kExportpartsAttr) { if (RuntimeEnabledFeatures::CSSPartPseudoElementEnabled()) { EnsureElementRareData().SetPartNamesMap(params.new_value); - GetDocument().GetStyleEngine().PartmapChangedForElement(*this); + GetDocument().GetStyleEngine().ExportpartsChangedForElement(*this); } } else if (IsStyledElement()) { - if (name == styleAttr) { + if (name == kStyleAttr) { StyleAttributeChanged(params.new_value, params.reason); } else if (IsPresentationAttribute(name)) { GetElementData()->presentation_attribute_style_is_dirty_ = true; SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::FromAttribute(name)); } else if (RuntimeEnabledFeatures::InvisibleDOMEnabled() && - name == HTMLNames::invisibleAttr && + name == html_names::kInvisibleAttr && params.old_value != params.new_value) { InvisibleAttributeChanged(params.old_value, params.new_value); } @@ -1805,7 +1644,7 @@ void Element::AttributeChanged(const AttributeModificationParams& params) { } if (params.reason == AttributeModificationReason::kDirectly && - name == tabindexAttr && AdjustedFocusedElementInTreeScope() == this) { + name == kTabindexAttr && AdjustedFocusedElementInTreeScope() == this) { // The attribute change may cause supportsFocus() to return false // for the element which had focus. // @@ -1886,7 +1725,7 @@ bool Element::ShouldInvalidateDistributionWhenAttributeChanged( const SelectRuleFeatureSet& feature_set = shadow_root.V0().EnsureSelectFeatureSet(); - if (name == HTMLNames::idAttr) { + if (name == html_names::kIdAttr) { AtomicString old_id = GetElementData()->IdForStyleResolution(); AtomicString new_id = MakeIdForStyleResolution(new_value, GetDocument().InQuirksMode()); @@ -1898,7 +1737,7 @@ bool Element::ShouldInvalidateDistributionWhenAttributeChanged( } } - if (name == HTMLNames::classAttr) { + if (name == html_names::kClassAttr) { const AtomicString& new_class_string = new_value; if (ClassStringHasClassName(new_class_string) == ClassStringContent::kHasClasses) { @@ -2026,7 +1865,7 @@ const AtomicString& Element::LocateNamespacePrefix( } const AtomicString Element::ImageSourceURL() const { - return getAttribute(srcAttr); + return getAttribute(kSrcAttr); } bool Element::LayoutObjectIsNeeded(const ComputedStyle& style) const { @@ -2058,6 +1897,8 @@ Node::InsertionNotificationRequest Element::InsertedInto( if (LocalFrameView* frame_view = GetDocument().View()) frame_view->SetIntersectionObservationState(LocalFrameView::kRequired); } + if (rare_data->GetDisplayLockContext()) + rare_data->GetDisplayLockContext()->NotifyConnectedMayHaveChanged(); } if (isConnected()) { @@ -2095,7 +1936,10 @@ void Element::RemovedFrom(ContainerNode& insertion_point) { // AttachLayoutTree again. We don't clear pseudo elements on // DetachLayoutTree() if we intend to attach again to avoid recreating the // pseudo elements. - GetElementRareData()->ClearPseudoElements(); + ElementRareData* rare_data = GetElementRareData(); + rare_data->ClearPseudoElements(); + if (rare_data->GetDisplayLockContext()) + rare_data->GetDisplayLockContext()->NotifyConnectedMayHaveChanged(); } if (Fullscreen::IsFullscreenElement(*this)) { @@ -2132,13 +1976,6 @@ void Element::RemovedFrom(ContainerNode& insertion_point) { CustomElement::EnqueueDisconnectedCallback(this); else if (IsUpgradedV0CustomElement()) V0CustomElement::DidDetach(this, insertion_point.GetDocument()); - - if (NeedsStyleInvalidation()) { - GetDocument() - .GetStyleEngine() - .GetPendingNodeInvalidations() - .ClearInvalidation(*this); - } } GetDocument().GetRootScrollerController().ElementRemoved(*this); @@ -2187,14 +2024,13 @@ void Element::AttachLayoutTree(AttachContext& context) { data->ClearComputedStyle(); } - if (CanParticipateInFlatTree()) { - LayoutTreeBuilderForElement builder(*this, GetNonAttachedStyle()); + ComputedStyle* style = GetNonAttachedStyle(); + if (style && CanParticipateInFlatTree()) { + LayoutTreeBuilderForElement builder(*this, style); builder.CreateLayoutObjectIfNeeded(); - if (ComputedStyle* style = builder.ResolvedStyle()) { - if (!GetLayoutObject() && ShouldStoreNonLayoutObjectComputedStyle(*style)) - StoreNonLayoutObjectComputedStyle(style); - } + if (!GetLayoutObject() && ShouldStoreNonLayoutObjectComputedStyle(*style)) + StoreNonLayoutObjectComputedStyle(style); } if (HasRareData() && !GetLayoutObject() && @@ -2240,6 +2076,9 @@ void Element::AttachLayoutTree(AttachContext& context) { } else { context.previous_in_flow = children_context.previous_in_flow; } + + if (auto* display_lock_context = GetDisplayLockContext()) + display_lock_context->DidAttachLayoutTree(); } void Element::DetachLayoutTree(const AttachContext& context) { @@ -2293,13 +2132,6 @@ void Element::DetachLayoutTree(const AttachContext& context) { GetDocument().UserActionElements().DidDetach(*this); } - if (context.clear_invalidation) { - GetDocument() - .GetStyleEngine() - .GetPendingNodeInvalidations() - .ClearInvalidation(*this); - } - SetNeedsResizeObserverUpdate(); DCHECK(NeedsAttach()); @@ -2315,8 +2147,9 @@ scoped_refptr<ComputedStyle> Element::StyleForLayoutObject() { element_animations->CssAnimations().ClearPendingUpdate(); if (RuntimeEnabledFeatures::InvisibleDOMEnabled() && - hasAttribute(HTMLNames::invisibleAttr)) { - auto style = ComputedStyle::Create(); + hasAttribute(html_names::kInvisibleAttr)) { + auto style = + GetDocument().GetStyleResolver()->InitialStyleForElement(GetDocument()); style->SetDisplay(EDisplay::kNone); return style; } @@ -2379,6 +2212,10 @@ void Element::RecalcStyleForTraversalRootAncestor() { void Element::RecalcStyle(StyleRecalcChange change) { DCHECK(GetDocument().InStyleRecalc()); DCHECK(!GetDocument().Lifecycle().InDetach()); + + if (StyleRecalcBlockedByDisplayLock()) + return; + // If we are re-attaching in a Shadow DOM v0 tree, we recalc down to the // distributed nodes to propagate kReattach down the flat tree (See // V0InsertionPoint::DidRecalcStyle). That means we may have a shadow- @@ -2456,7 +2293,6 @@ void Element::RecalcStyle(StyleRecalcChange change) { } if (ShouldCallRecalcStyleForChildren(change)) { - UpdatePseudoElement(kPseudoIdBefore, change); if (change > kUpdatePseudoElements || ChildNeedsStyleRecalc()) { @@ -2481,6 +2317,7 @@ void Element::RecalcStyle(StyleRecalcChange change) { if (HasCustomStyleCallbacks()) DidRecalcStyle(change); + NotifyDisplayLockDidRecalcStyle(); } scoped_refptr<ComputedStyle> Element::PropagateInheritedProperties( @@ -2546,6 +2383,9 @@ StyleRecalcChange Element::RecalcOwnStyle(StyleRecalcChange change) { } } + if (GetForceReattachLayoutTree()) + local_change = kReattach; + if (change == kReattach || local_change == kReattach) { SetNonAttachedStyle(new_style); SetNeedsReattachLayoutTree(); @@ -2733,7 +2573,7 @@ ShadowRoot& Element::CreateAndAttachShadowRoot(ShadowRootType type) { shadow_root->InsertedInto(*this); SetChildNeedsStyleRecalc(); SetNeedsStyleRecalc(kSubtreeStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kShadow)); + style_change_reason::kShadow)); probe::didPushShadowRoot(this, shadow_root); @@ -2773,11 +2613,13 @@ void Element::ClearAnimationStyleChange() { } void Element::SetNeedsAnimationStyleRecalc() { + if (GetDocument().InStyleRecalc()) + return; if (GetStyleChangeType() != kNoStyleChange) return; SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kAnimation)); + style_change_reason::kAnimation)); SetAnimationStyleChange(true); } @@ -2833,6 +2675,18 @@ const AtomicString& Element::IsValue() const { return g_null_atom; } +void Element::SetDidAttachInternals() { + EnsureElementRareData().SetDidAttachInternals(); +} + +bool Element::DidAttachInternals() const { + return HasRareData() && GetElementRareData()->DidAttachInternals(); +} + +ElementInternals& Element::EnsureElementInternals() { + return EnsureElementRareData().EnsureElementInternals(ToHTMLElement(*this)); +} + ShadowRoot* Element::createShadowRoot(ExceptionState& exception_state) { if (ShadowRoot* root = GetShadowRoot()) { if (root->IsUserAgent()) { @@ -2873,21 +2727,22 @@ bool Element::CanAttachShadowRoot() const { // because IsValidName is not cheap. return (IsCustomElement() && CustomElement::IsValidName(tag_name)) || (IsV0CustomElement() && V0CustomElement::IsValidName(tag_name)) || - tag_name == HTMLNames::articleTag || tag_name == HTMLNames::asideTag || - tag_name == HTMLNames::blockquoteTag || - tag_name == HTMLNames::bodyTag || tag_name == HTMLNames::divTag || - tag_name == HTMLNames::footerTag || tag_name == HTMLNames::h1Tag || - tag_name == HTMLNames::h2Tag || tag_name == HTMLNames::h3Tag || - tag_name == HTMLNames::h4Tag || tag_name == HTMLNames::h5Tag || - tag_name == HTMLNames::h6Tag || tag_name == HTMLNames::headerTag || - tag_name == HTMLNames::navTag || tag_name == HTMLNames::mainTag || - tag_name == HTMLNames::pTag || tag_name == HTMLNames::sectionTag || - tag_name == HTMLNames::spanTag; -} - -ShadowRoot* Element::attachShadow(const ShadowRootInit& shadow_root_init_dict, + tag_name == html_names::kArticleTag || + tag_name == html_names::kAsideTag || + tag_name == html_names::kBlockquoteTag || + tag_name == html_names::kBodyTag || tag_name == html_names::kDivTag || + tag_name == html_names::kFooterTag || tag_name == html_names::kH1Tag || + tag_name == html_names::kH2Tag || tag_name == html_names::kH3Tag || + tag_name == html_names::kH4Tag || tag_name == html_names::kH5Tag || + tag_name == html_names::kH6Tag || tag_name == html_names::kHeaderTag || + tag_name == html_names::kNavTag || tag_name == html_names::kMainTag || + tag_name == html_names::kPTag || tag_name == html_names::kSectionTag || + tag_name == html_names::kSpanTag; +} + +ShadowRoot* Element::attachShadow(const ShadowRootInit* shadow_root_init_dict, ExceptionState& exception_state) { - DCHECK(shadow_root_init_dict.hasMode()); + DCHECK(shadow_root_init_dict->hasMode()); if (!CanAttachShadowRoot()) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, @@ -2902,7 +2757,7 @@ ShadowRoot* Element::attachShadow(const ShadowRootInit& shadow_root_init_dict, return nullptr; } - ShadowRootType type = shadow_root_init_dict.mode() == "open" + ShadowRootType type = shadow_root_init_dict->mode() == "open" ? ShadowRootType::kOpen : ShadowRootType::kClosed; @@ -2911,10 +2766,10 @@ ShadowRoot* Element::attachShadow(const ShadowRootInit& shadow_root_init_dict, else UseCounter::Count(GetDocument(), WebFeature::kElementAttachShadowClosed); - DCHECK(!shadow_root_init_dict.hasMode() || !GetShadowRoot()); - bool delegates_focus = shadow_root_init_dict.hasDelegatesFocus() && - shadow_root_init_dict.delegatesFocus(); - bool manual_slotting = shadow_root_init_dict.slotting() == "manual"; + DCHECK(!shadow_root_init_dict->hasMode() || !GetShadowRoot()); + bool delegates_focus = shadow_root_init_dict->hasDelegatesFocus() && + shadow_root_init_dict->delegatesFocus(); + bool manual_slotting = shadow_root_init_dict->slotting() == "manual"; return &AttachShadowRootInternal(type, delegates_focus, manual_slotting); } @@ -3160,7 +3015,7 @@ Attr* Element::removeAttributeNode(Attr* attr, } void Element::ParseAttribute(const AttributeModificationParams& params) { - if (params.name == tabindexAttr) { + if (params.name == kTabindexAttr) { int tabindex = 0; if (params.new_value.IsEmpty() || !ParseHTMLInteger(params.new_value, tabindex)) { @@ -3169,7 +3024,7 @@ void Element::ParseAttribute(const AttributeModificationParams& params) { // We only set when value is in integer range. SetTabIndexExplicitly(); } - } else if (params.name == XMLNames::langAttr) { + } else if (params.name == xml_names::kLangAttr) { PseudoStateChanged(CSSSelector::kPseudoLang); } } @@ -3261,7 +3116,7 @@ void Element::removeAttribute(const AtomicString& name) { AtomicString local_name = LowercaseIfNecessary(name); wtf_size_t index = GetElementData()->Attributes().FindIndex(local_name); if (index == kNotFound) { - if (UNLIKELY(local_name == styleAttr) && + if (UNLIKELY(local_name == kStyleAttr) && GetElementData()->style_attribute_is_dirty_ && IsStyledElement()) RemoveAllInlineStyleProperties(); return; @@ -3315,7 +3170,7 @@ bool Element::hasAttributeNS(const AtomicString& namespace_uri, return GetElementData()->Attributes().Find(q_name); } -void Element::focus(FocusOptions options) { +void Element::focus(const FocusOptions* options) { focus(FocusParams(SelectionBehaviorOnFocus::kRestore, kWebFocusTypeNone, nullptr, options)); } @@ -3374,12 +3229,12 @@ void Element::focus(const FocusParams& params) { void Element::UpdateFocusAppearance( SelectionBehaviorOnFocus selection_behavior) { - UpdateFocusAppearanceWithOptions(selection_behavior, FocusOptions()); + UpdateFocusAppearanceWithOptions(selection_behavior, FocusOptions::Create()); } void Element::UpdateFocusAppearanceWithOptions( SelectionBehaviorOnFocus selection_behavior, - const FocusOptions& options) { + const FocusOptions* options) { if (selection_behavior == SelectionBehaviorOnFocus::kNone) return; if (IsRootEditableElement(*this)) { @@ -3407,11 +3262,11 @@ void Element::UpdateFocusAppearanceWithOptions( .SetShouldClearTypingStyle(true) .SetDoNotSetFocus(true) .Build()); - if (!options.preventScroll()) + if (!options->preventScroll()) frame->Selection().RevealSelection(); } else if (GetLayoutObject() && !GetLayoutObject()->IsLayoutEmbeddedContent()) { - if (!options.preventScroll()) { + if (!options->preventScroll()) { GetLayoutObject()->ScrollRectToVisible(BoundingBoxForScrollIntoView(), WebScrollIntoViewParams()); } @@ -3439,7 +3294,7 @@ bool Element::SupportsFocus() const { // it won't be focusable. Furthermore, supportsFocus cannot just return true // always or else tabIndex() will change for all HTML elements. return HasElementFlag(ElementFlags::kTabIndexWasSetExplicitly) || - IsRootEditableElement(*this) || + IsRootEditableElementWithCounting(*this) || (IsShadowHost(this) && AuthorShadowRoot() && AuthorShadowRoot()->delegatesFocus()) || SupportsSpatialNavigationFocus(); @@ -3455,33 +3310,40 @@ bool Element::SupportsSpatialNavigationFocus() const { if (!IsSpatialNavigationEnabled(GetDocument().GetFrame()) || SpatialNavigationIgnoresEventHandlers(GetDocument().GetFrame())) return false; - if (HasEventListeners(EventTypeNames::click) || - HasEventListeners(EventTypeNames::keydown) || - HasEventListeners(EventTypeNames::keypress) || - HasEventListeners(EventTypeNames::keyup)) + if (HasEventListeners(event_type_names::kClick) || + HasEventListeners(event_type_names::kKeydown) || + HasEventListeners(event_type_names::kKeypress) || + HasEventListeners(event_type_names::kKeyup)) return true; if (!IsSVGElement()) return false; - return (HasEventListeners(EventTypeNames::focus) || - HasEventListeners(EventTypeNames::blur) || - HasEventListeners(EventTypeNames::focusin) || - HasEventListeners(EventTypeNames::focusout)); + return (HasEventListeners(event_type_names::kFocus) || + HasEventListeners(event_type_names::kBlur) || + HasEventListeners(event_type_names::kFocusin) || + HasEventListeners(event_type_names::kFocusout)); } bool Element::IsFocusable() const { - // Style cannot be cleared out for non-active documents, so in that case the - // needsLayoutTreeUpdateForNode check is invalid. - DCHECK(!GetDocument().IsActive() || - !GetDocument().NeedsLayoutTreeUpdateForNode(*this)); - return isConnected() && SupportsFocus() && !IsInert() && IsFocusableStyle(); + return Element::IsMouseFocusable() || Element::IsKeyboardFocusable(); } bool Element::IsKeyboardFocusable() const { - return IsFocusable() && tabIndex() >= 0; + // No point in checking NeedsLayoutTreeUpdateForNode when the document + // isn't active (style can't be invalidated in a non-active document). + DCHECK(!GetDocument().IsActive() || + !GetDocument().NeedsLayoutTreeUpdateForNode(*this)); + return isConnected() && !IsInert() && IsFocusableStyle() && + ((SupportsFocus() && tabIndex() >= 0) || + (RuntimeEnabledFeatures::KeyboardFocusableScrollersEnabled() && + IsScrollableNode(this))); } bool Element::IsMouseFocusable() const { - return IsFocusable(); + // No point in checking NeedsLayoutTreeUpdateForNode when the document + // isn't active (style can't be invalidated in a non-active document). + DCHECK(!GetDocument().IsActive() || + !GetDocument().NeedsLayoutTreeUpdateForNode(*this)); + return isConnected() && !IsInert() && IsFocusableStyle() && SupportsFocus(); } bool Element::IsFocusedElementInDocument() const { @@ -3496,17 +3358,17 @@ Element* Element::AdjustedFocusedElementInTreeScope() const { void Element::DispatchFocusEvent(Element* old_focused_element, WebFocusType type, InputDeviceCapabilities* source_capabilities) { - DispatchEvent(*FocusEvent::Create(EventTypeNames::focus, Event::Bubbles::kNo, - GetDocument().domWindow(), 0, - old_focused_element, source_capabilities)); + DispatchEvent(*FocusEvent::Create( + event_type_names::kFocus, Event::Bubbles::kNo, GetDocument().domWindow(), + 0, old_focused_element, source_capabilities)); } void Element::DispatchBlurEvent(Element* new_focused_element, WebFocusType type, InputDeviceCapabilities* source_capabilities) { - DispatchEvent(*FocusEvent::Create(EventTypeNames::blur, Event::Bubbles::kNo, - GetDocument().domWindow(), 0, - new_focused_element, source_capabilities)); + DispatchEvent(*FocusEvent::Create( + event_type_names::kBlur, Event::Bubbles::kNo, GetDocument().domWindow(), + 0, new_focused_element, source_capabilities)); } void Element::DispatchFocusInEvent( @@ -3517,8 +3379,8 @@ void Element::DispatchFocusInEvent( #if DCHECK_IS_ON() DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden()); #endif - DCHECK(event_type == EventTypeNames::focusin || - event_type == EventTypeNames::DOMFocusIn); + DCHECK(event_type == event_type_names::kFocusin || + event_type == event_type_names::kDOMFocusIn); DispatchScopedEvent(*FocusEvent::Create( event_type, Event::Bubbles::kYes, GetDocument().domWindow(), 0, old_focused_element, source_capabilities)); @@ -3531,8 +3393,8 @@ void Element::DispatchFocusOutEvent( #if DCHECK_IS_ON() DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden()); #endif - DCHECK(event_type == EventTypeNames::focusout || - event_type == EventTypeNames::DOMFocusOut); + DCHECK(event_type == event_type_names::kFocusout || + event_type == event_type_names::kDOMFocusOut); DispatchScopedEvent(*FocusEvent::Create( event_type, Event::Bubbles::kYes, GetDocument().domWindow(), 0, new_focused_element, source_capabilities)); @@ -3704,34 +3566,28 @@ void Element::SetNeedsResizeObserverUpdate() { } } -void Element::WillBeginCustomizedScrollPhase( - ScrollCustomization::ScrollDirection direction) { - DCHECK(!GetScrollCustomizationCallbacks().InScrollPhase(this)); - LayoutBox* box = GetLayoutBox(); - if (!box) - return; - - ScrollCustomization::ScrollDirection scroll_customization = - box->Style()->ScrollCustomization(); +ScriptPromise Element::acquireDisplayLock(ScriptState* script_state, + V8DisplayLockCallback* callback) { + auto* context = EnsureElementRareData().EnsureDisplayLockContext( + this, GetExecutionContext()); + context->RequestLock(callback, script_state); + auto lock_promise = context->Promise(); - GetScrollCustomizationCallbacks().SetInScrollPhase( - this, direction & scroll_customization); -} + // Only support "mode 2" display locking, which requires that the lock is + // acquired before the element is connected. Note that we need to call this + // after actually getting the promise to avoid ScriptPromiseResolver asserts. + // TODO(vmpstr): Implement mode 1. + if (isConnected()) + context->RejectAndCleanUp(); -void Element::DidEndCustomizedScrollPhase() { - GetScrollCustomizationCallbacks().SetInScrollPhase(this, false); + return lock_promise; } -ScriptPromise Element::acquireDisplayLock(ScriptState* script_state, - V8DisplayLockCallback* callback) { - // For now, just invoke the callback, and resolve the promise immediately. - // TODO(vmpstr): Finish implementation. - callback->InvokeAndReportException(nullptr, new DisplayLockContext); - - auto* resolver = ScriptPromiseResolver::Create(script_state); - const auto& promise = resolver->Promise(); - resolver->Resolve(); - return promise; +DisplayLockContext* Element::GetDisplayLockContext() const { + if (!RuntimeEnabledFeatures::DisplayLockingEnabled()) + return nullptr; + return HasRareData() ? GetElementRareData()->GetDisplayLockContext() + : nullptr; } // Step 1 of http://domparsing.spec.whatwg.org/#insertadjacenthtml() @@ -3848,19 +3704,6 @@ bool Element::HasProcessedPointerCapture(int pointer_id) const { pointer_id, this); } -String Element::innerText() { - // We need to update layout, since plainText uses line boxes in the layout - // tree. - GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this); - - if (!GetLayoutObject() && !HasDisplayContentsStyle()) - return textContent(true); - - return PlainText( - EphemeralRange::RangeOfContents(*this), - TextIteratorBehavior::Builder().SetForInnerText(true).Build()); -} - String Element::outerText() { // Getting outerText is the same as getting innerText, only // setting is different. You would think this should get the plain @@ -3912,7 +3755,7 @@ String Element::TextFromChildren() { const AtomicString& Element::ShadowPseudoId() const { if (ShadowRoot* root = ContainingShadowRoot()) { if (root->IsUserAgent()) - return FastGetAttribute(pseudoAttr); + return FastGetAttribute(kPseudoAttr); } return g_null_atom; } @@ -3922,7 +3765,7 @@ void Element::SetShadowPseudoId(const AtomicString& id) { CSSSelector::kPseudoWebKitCustomElement || CSSSelector::ParsePseudoType(id, false) == CSSSelector::kPseudoBlinkInternalElement); - setAttribute(pseudoAttr, id); + setAttribute(kPseudoAttr, id); } bool Element::IsInDescendantTreeOf(const Element* shadow_host) const { @@ -3950,6 +3793,23 @@ const ComputedStyle* Element::EnsureComputedStyle( return nullptr; } + // EnsureComputedStyle is expected to be called to forcibly compute style for + // elements in display:none subtrees on otherwise style-clean documents. If + // you hit this DCHECK, consider if you really need ComputedStyle for + // display:none elements. If not, use GetComputedStyle() instead. + // Regardlessly, you need to UpdateStyleAndLayoutTree() before calling + // EnsureComputedStyle. In some cases you might be fine using GetComputedStyle + // without updating the style, but in most cases you want a clean tree for + // that as well. + // + // Adjacent styling bits may be set and affect NeedsLayoutTreeUpdateForNode as + // part of EnsureComputedStyle in an ancestor chain. + // (see CSSComputedStyleDeclarationTest::NeedsAdjacentStyleRecalc). It is OK + // that it happens, but we need to ignore the effect on + // NeedsLayoutTreeUpdateForNode here. + DCHECK(!GetDocument().NeedsLayoutTreeUpdateForNode( + *this, true /* ignore_adjacent_style */)); + // FIXME: Find and use the layoutObject from the pseudo element instead of the // actual element so that the 'length' properties, which are only known by the // layoutObject because it did the layout, will be correct and so that the @@ -4041,10 +3901,10 @@ AtomicString Element::ComputeInheritedLanguage() const { if (const ElementData* element_data = ToElement(n)->GetElementData()) { AttributeCollection attributes = element_data->Attributes(); // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 - if (const Attribute* attribute = attributes.Find(XMLNames::langAttr)) + if (const Attribute* attribute = attributes.Find(xml_names::kLangAttr)) value = attribute->Value(); else if (const Attribute* attribute = - attributes.Find(HTMLNames::langAttr)) + attributes.Find(html_names::kLangAttr)) value = attribute->Value(); } } else if (auto* document = DynamicTo<Document>(n)) { @@ -4329,8 +4189,8 @@ Element* Element::closest(const AtomicString& selectors) { DOMTokenList& Element::classList() { ElementRareData& rare_data = EnsureElementRareData(); if (!rare_data.GetClassList()) { - DOMTokenList* class_list = DOMTokenList::Create(*this, classAttr); - class_list->DidUpdateAttributeValue(g_null_atom, getAttribute(classAttr)); + DOMTokenList* class_list = DOMTokenList::Create(*this, kClassAttr); + class_list->DidUpdateAttributeValue(g_null_atom, getAttribute(kClassAttr)); rare_data.SetClassList(class_list); } return *rare_data.GetClassList(); @@ -4348,7 +4208,7 @@ KURL Element::HrefURL() const { // doesn't <link> implement URLUtils? if (IsHTMLAnchorElement(*this) || IsHTMLAreaElement(*this) || IsHTMLLinkElement(*this)) - return GetURLAttribute(hrefAttr); + return GetURLAttribute(kHrefAttr); if (auto* svg_a = ToSVGAElementOrNull(*this)) return svg_a->LegacyHrefURL(GetDocument()); return KURL(); @@ -4432,7 +4292,8 @@ double Element::GetFloatingPointAttribute(const QualifiedName& attribute_name, void Element::SetFloatingPointAttribute(const QualifiedName& attribute_name, double value) { - setAttribute(attribute_name, AtomicString::Number(value)); + String serialized_value = SerializeForNumberType(value); + setAttribute(attribute_name, AtomicString(serialized_value)); } void Element::SetContainsFullScreenElement(bool flag) { @@ -4497,11 +4358,11 @@ void Element::SetIsInTopLayer(bool in_top_layer) { if (IsInTopLayer() == in_top_layer) return; SetElementFlag(ElementFlags::kIsInTopLayer, in_top_layer); - - // We must ensure a reattach occurs so the layoutObject is inserted in the - // correct sibling order under LayoutView according to its top layer position, - // or in its usual place if not in the top layer. - LazyReattachIfAttached(); + if (!isConnected()) + return; + SetForceReattachLayoutTree(); + SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( + style_change_reason::kFullscreen)); } void Element::requestPointerLock() { @@ -4511,7 +4372,7 @@ void Element::requestPointerLock() { } SpellcheckAttributeState Element::GetSpellcheckAttributeState() const { - const AtomicString& value = FastGetAttribute(spellcheckAttr); + const AtomicString& value = FastGetAttribute(kSpellcheckAttr); if (value == g_null_atom) return kSpellcheckAttributeDefault; if (DeprecatedEqualIgnoringCase(value, "true") || @@ -4544,7 +4405,7 @@ bool Element::IsSpellCheckingEnabled() const { #if DCHECK_IS_ON() bool Element::FastAttributeLookupAllowed(const QualifiedName& name) const { - if (name == HTMLNames::styleAttr) + if (name == html_names::kStyleAttr) return false; if (IsSVGElement()) @@ -4604,7 +4465,7 @@ inline void Element::UpdateId(TreeScope& scope, void Element::WillModifyAttribute(const QualifiedName& name, const AtomicString& old_value, const AtomicString& new_value) { - if (name == HTMLNames::nameAttr) { + if (name == html_names::kNameAttr) { UpdateName(old_value, new_value); } @@ -4633,7 +4494,7 @@ void Element::WillModifyAttribute(const QualifiedName& name, DISABLE_CFI_PERF void Element::DidAddAttribute(const QualifiedName& name, const AtomicString& value) { - if (name == HTMLNames::idAttr) + if (name == html_names::kIdAttr) UpdateId(g_null_atom, value); AttributeChanged(AttributeModificationParams( name, g_null_atom, value, AttributeModificationReason::kDirectly)); @@ -4644,7 +4505,7 @@ void Element::DidAddAttribute(const QualifiedName& name, void Element::DidModifyAttribute(const QualifiedName& name, const AtomicString& old_value, const AtomicString& new_value) { - if (name == HTMLNames::idAttr) + if (name == html_names::kIdAttr) UpdateId(old_value, new_value); AttributeChanged(AttributeModificationParams( name, old_value, new_value, AttributeModificationReason::kDirectly)); @@ -4654,7 +4515,7 @@ void Element::DidModifyAttribute(const QualifiedName& name, void Element::DidRemoveAttribute(const QualifiedName& name, const AtomicString& old_value) { - if (name == HTMLNames::idAttr) + if (name == html_names::kIdAttr) UpdateId(old_value, g_null_atom); AttributeChanged(AttributeModificationParams( name, old_value, g_null_atom, AttributeModificationReason::kDirectly)); @@ -4703,7 +4564,7 @@ void Element::DidMoveToNewDocument(Document& old_document) { if (HasID()) SetIdAttribute(GetIdAttribute()); if (HasClass()) - setAttribute(HTMLNames::classAttr, GetClassAttribute()); + setAttribute(html_names::kClassAttr, GetClassAttribute()); } // TODO(tkent): Even if Documents' modes are same, keeping // ShareableElementData owned by old_document isn't right. @@ -4932,7 +4793,7 @@ void Element::SynchronizeStyleAttributeInternal() const { GetElementData()->style_attribute_is_dirty_ = false; const CSSPropertyValueSet* inline_style = InlineStyle(); const_cast<Element*>(this)->SetSynchronizedLazyAttribute( - styleAttr, + kStyleAttr, inline_style ? AtomicString(inline_style->AsText()) : g_empty_atom); } @@ -5027,32 +4888,32 @@ void Element::StyleAttributeChanged( SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kStyleSheetChange)); + style_change_reason::kStyleSheetChange)); probe::didInvalidateStyleAttr(this); } void Element::InlineStyleChanged() { DCHECK(IsStyledElement()); SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kInline)); + style_change_reason::kInline)); DCHECK(GetElementData()); GetElementData()->style_attribute_is_dirty_ = true; probe::didInvalidateStyleAttr(this); if (MutationObserverInterestGroup* recipients = MutationObserverInterestGroup::CreateForAttributesMutation( - *this, styleAttr)) { + *this, kStyleAttr)) { // We don't use getAttribute() here to get a style attribute value // before the change. AtomicString old_value; if (const Attribute* attribute = - GetElementData()->Attributes().Find(styleAttr)) + GetElementData()->Attributes().Find(kStyleAttr)) old_value = attribute->Value(); recipients->EnqueueMutationRecord( - MutationRecord::CreateAttributes(this, styleAttr, old_value)); + MutationRecord::CreateAttributes(this, kStyleAttr, old_value)); // Need to synchronize every time so that following MutationRecords will // have correct oldValues. - SynchronizeAttribute(styleAttr); + SynchronizeAttribute(kStyleAttr); } } @@ -5241,23 +5102,33 @@ void Element::Trace(blink::Visitor* visitor) { ContainerNode::Trace(visitor); } -bool Element::HasPartName() const { +bool Element::HasPart() const { if (!RuntimeEnabledFeatures::CSSPartPseudoElementEnabled()) return false; if (HasRareData()) { - if (auto* part_names = GetElementRareData()->PartNames()) { - return part_names->size() > 0; + if (auto* part = GetElementRareData()->GetPart()) { + return part->length() > 0; } } return false; } -const SpaceSplitString* Element::PartNames() const { +DOMTokenList* Element::GetPart() const { return RuntimeEnabledFeatures::CSSPartPseudoElementEnabled() && HasRareData() - ? GetElementRareData()->PartNames() + ? GetElementRareData()->GetPart() : nullptr; } +DOMTokenList& Element::part() { + ElementRareData& rare_data = EnsureElementRareData(); + DOMTokenList* part = rare_data.GetPart(); + if (!part) { + part = DOMTokenList::Create(*this, kPartAttr); + rare_data.SetPart(part); + } + return *part; +} + bool Element::HasPartNamesMap() const { const NamesMap* names_map = PartNamesMap(); return names_map && names_map->size() > 0; @@ -5269,4 +5140,14 @@ const NamesMap* Element::PartNamesMap() const { : nullptr; } +bool Element::StyleRecalcBlockedByDisplayLock() const { + auto* context = GetDisplayLockContext(); + return context && !context->ShouldStyle(); +} + +void Element::NotifyDisplayLockDidRecalcStyle() { + if (auto* context = GetDisplayLockContext()) + context->DidStyle(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/dom/element.h b/chromium/third_party/blink/renderer/core/dom/element.h index 36d8ccd308e..430fd713515 100644 --- a/chromium/third_party/blink/renderer/core/dom/element.h +++ b/chromium/third_party/blink/renderer/core/dom/element.h @@ -38,7 +38,6 @@ #include "third_party/blink/renderer/core/html/focus_options.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/resize_observer/resize_observer.h" -#include "third_party/blink/renderer/core/scroll/scroll_customization.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/scroll/scroll_types.h" @@ -58,7 +57,9 @@ class DOMRectList; class DOMStringMap; class DOMTokenList; class Document; +class DisplayLockContext; class ElementAnimations; +class ElementInternals; class ElementIntersectionObserverData; class ElementRareData; class ExceptionState; @@ -74,8 +75,6 @@ class PseudoStyleRequest; class ResizeObservation; class ScrollIntoViewOptions; class ScrollIntoViewOptionsOrBoolean; -class ScrollState; -class ScrollStateCallback; class ScrollToOptions; class ShadowRoot; class ShadowRootInit; @@ -89,7 +88,6 @@ class StylePropertyMapReadOnly; class USVStringOrTrustedURL; class V0CustomElementDefinition; class V8DisplayLockCallback; -class V8ScrollStateCallback; enum SpellcheckAttributeState { kSpellcheckAttributeTrue, @@ -134,11 +132,11 @@ struct FocusParams { STACK_ALLOCATED(); public: - FocusParams() = default; + FocusParams() : options(FocusOptions::Create()) {} FocusParams(SelectionBehaviorOnFocus selection, WebFocusType focus_type, InputDeviceCapabilities* capabilities, - FocusOptions focus_options = FocusOptions()) + const FocusOptions* focus_options = FocusOptions::Create()) : selection_behavior(selection), type(focus_type), source_capabilities(capabilities), @@ -148,7 +146,7 @@ struct FocusParams { SelectionBehaviorOnFocus::kRestore; WebFocusType type = kWebFocusTypeNone; Member<InputDeviceCapabilities> source_capabilities = nullptr; - FocusOptions options = FocusOptions(); + Member<const FocusOptions> options; }; typedef HeapVector<TraceWrapperMember<Attr>> AttrNodeList; @@ -158,12 +156,14 @@ class CORE_EXPORT Element : public ContainerNode { public: static Element* Create(const QualifiedName&, Document*); + + Element(const QualifiedName& tag_name, Document*, ConstructionType); ~Element() override; - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); - DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy, kBeforecopy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut, kBeforecut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste, kBeforepaste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch); bool hasAttribute(const QualifiedName&) const; const AtomicString& getAttribute(const QualifiedName&) const; @@ -291,8 +291,8 @@ class CORE_EXPORT Element : public ContainerNode { void scrollIntoView(ScrollIntoViewOptionsOrBoolean); void scrollIntoView(bool align_to_top = true); - void scrollIntoViewWithOptions(const ScrollIntoViewOptions&); - void ScrollIntoViewNoVisualUpdate(const ScrollIntoViewOptions&); + void scrollIntoViewWithOptions(const ScrollIntoViewOptions*); + void ScrollIntoViewNoVisualUpdate(const ScrollIntoViewOptions*); void scrollIntoViewIfNeeded(bool center_if_needed = true); int OffsetLeft(); @@ -313,9 +313,9 @@ class CORE_EXPORT Element : public ContainerNode { int scrollHeight(); void scrollBy(double x, double y); - virtual void scrollBy(const ScrollToOptions&); + virtual void scrollBy(const ScrollToOptions*); void scrollTo(double x, double y); - virtual void scrollTo(const ScrollToOptions&); + virtual void scrollTo(const ScrollToOptions*); IntRect BoundsInViewport() const; // Returns an intersection rectangle of the bounds rectangle and the visual @@ -534,8 +534,7 @@ class CORE_EXPORT Element : public ContainerNode { // throws an exception. Multiple shadow roots are allowed only when // createShadowRoot() is used without any parameters from JavaScript. ShadowRoot* createShadowRoot(ExceptionState&); - ShadowRoot* attachShadow(const ShadowRootInit&, - ExceptionState&); + ShadowRoot* attachShadow(const ShadowRootInit*, ExceptionState&); ShadowRoot& CreateV0ShadowRootForTesting() { return CreateShadowRootInternal(); @@ -631,27 +630,13 @@ class CORE_EXPORT Element : public ContainerNode { virtual Image* ImageContents() { return nullptr; } virtual void focus(const FocusParams& = FocusParams()); - void focus(FocusOptions); + void focus(const FocusOptions*); void UpdateFocusAppearance(SelectionBehaviorOnFocus); virtual void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus, - const FocusOptions&); + const FocusOptions*); virtual void blur(); - void setDistributeScroll(V8ScrollStateCallback*, - const String& native_scroll_behavior); - void NativeDistributeScroll(ScrollState&); - void setApplyScroll(V8ScrollStateCallback*, - const String& native_scroll_behavior); - void SetApplyScroll(ScrollStateCallback*); - void RemoveApplyScroll(); - void NativeApplyScroll(ScrollState&); - - void CallDistributeScroll(ScrollState&); - void CallApplyScroll(ScrollState&); - - ScrollStateCallback* GetApplyScroll(); - // Whether this element can receive focus at all. Most elements are not // focusable but some elements, such as form controls and links, are. Unlike // layoutObjectIsFocusable(), this method may be called when layout is not up @@ -826,6 +811,9 @@ class CORE_EXPORT Element : public ContainerNode { // https://dom.spec.whatwg.org/#concept-element-is-value void SetIsValue(const AtomicString&); const AtomicString& IsValue() const; + void SetDidAttachInternals(); + bool DidAttachInternals() const; + ElementInternals& EnsureElementInternals(); bool ContainsFullScreenElement() const { return HasElementFlag(ElementFlags::kContainsFullScreenElement); @@ -855,8 +843,13 @@ class CORE_EXPORT Element : public ContainerNode { const SpaceSplitString& ClassNames() const; bool HasClassName(const AtomicString& class_name) const; - bool HasPartName() const; - const SpaceSplitString* PartNames() const; + // Returns true if the element has 1 or more part names. + bool HasPart() const; + // Returns the list of part names if it has ever been created. + DOMTokenList* GetPart() const; + // IDL method. + // Returns the list of part names, creating it if it doesn't exist. + DOMTokenList& part(); bool HasPartNamesMap() const; const NamesMap* PartNamesMap() const; @@ -905,14 +898,12 @@ class CORE_EXPORT Element : public ContainerNode { EnsureResizeObserverData(); void SetNeedsResizeObserverUpdate(); - void WillBeginCustomizedScrollPhase(ScrollCustomization::ScrollDirection); - void DidEndCustomizedScrollPhase(); - ScriptPromise acquireDisplayLock(ScriptState*, V8DisplayLockCallback*); + DisplayLockContext* GetDisplayLockContext() const; - protected: - Element(const QualifiedName& tag_name, Document*, ConstructionType); + bool StyleRecalcBlockedByDisplayLock() const; + protected: const ElementData* GetElementData() const { return element_data_.Get(); } UniqueElementData& EnsureUniqueElementData(); @@ -970,10 +961,10 @@ class CORE_EXPORT Element : public ContainerNode { virtual void ParserDidSetAttributes() {} private: - void ScrollLayoutBoxBy(const ScrollToOptions&); - void ScrollLayoutBoxTo(const ScrollToOptions&); - void ScrollFrameBy(const ScrollToOptions&); - void ScrollFrameTo(const ScrollToOptions&); + void ScrollLayoutBoxBy(const ScrollToOptions*); + void ScrollLayoutBoxTo(const ScrollToOptions*); + void ScrollFrameBy(const ScrollToOptions*); + void ScrollFrameTo(const ScrollToOptions*); bool HasElementFlag(ElementFlags mask) const { return HasRareData() && HasElementFlagInternal(mask); @@ -1120,6 +1111,8 @@ class CORE_EXPORT Element : public ContainerNode { void DetachAttrNodeFromElementWithValue(Attr*, const AtomicString& value); void DetachAttrNodeAtIndex(Attr*, wtf_size_t index); + void NotifyDisplayLockDidRecalcStyle(); + Member<ElementData> element_data_; }; @@ -1254,23 +1247,23 @@ inline const AtomicString& Element::IdForStyleResolution() const { } inline const AtomicString& Element::GetIdAttribute() const { - return HasID() ? FastGetAttribute(HTMLNames::idAttr) : g_null_atom; + return HasID() ? FastGetAttribute(html_names::kIdAttr) : g_null_atom; } inline const AtomicString& Element::GetNameAttribute() const { - return HasName() ? FastGetAttribute(HTMLNames::nameAttr) : g_null_atom; + return HasName() ? FastGetAttribute(html_names::kNameAttr) : g_null_atom; } inline const AtomicString& Element::GetClassAttribute() const { if (!HasClass()) return g_null_atom; if (IsSVGElement()) - return getAttribute(HTMLNames::classAttr); - return FastGetAttribute(HTMLNames::classAttr); + return getAttribute(html_names::kClassAttr); + return FastGetAttribute(html_names::kClassAttr); } inline void Element::SetIdAttribute(const AtomicString& value) { - setAttribute(HTMLNames::idAttr, value); + setAttribute(html_names::kIdAttr, value); } inline const SpaceSplitString& Element::ClassNames() const { diff --git a/chromium/third_party/blink/renderer/core/dom/element.idl b/chromium/third_party/blink/renderer/core/dom/element.idl index a1e311a7651..6c6e91778ca 100644 --- a/chromium/third_party/blink/renderer/core/dom/element.idl +++ b/chromium/third_party/blink/renderer/core/dom/element.idl @@ -36,6 +36,7 @@ interface Element : Node { [Affects=Nothing, CEReactions, Reflect=class] attribute DOMString className; [Affects=Nothing, SameObject, PerWorldBindings, PutForwards=value] readonly attribute DOMTokenList classList; [Unscopable, CEReactions, Reflect] attribute DOMString slot; + [RuntimeEnabled=CSSPartPseudoElement, Affects=Nothing, SameObject, PerWorldBindings, PutForwards=value] readonly attribute DOMTokenList part; // Pointer Events // https://w3c.github.io/pointerevents/#extensions-to-the-element-interface @@ -100,12 +101,12 @@ interface Element : Node { // TODO(sunyunjia): Add default value for scrollIntoView() once // crbug.com/734599 is fixed. void scrollIntoView(optional (ScrollIntoViewOptions or boolean) arg); - [RuntimeEnabled=CSSOMSmoothScroll, ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options); - [RuntimeEnabled=CSSOMSmoothScroll, ImplementedAs=scrollTo] void scroll(unrestricted double x, unrestricted double y); - [RuntimeEnabled=CSSOMSmoothScroll] void scrollTo(optional ScrollToOptions options); - [RuntimeEnabled=CSSOMSmoothScroll] void scrollTo(unrestricted double x, unrestricted double y); - [RuntimeEnabled=CSSOMSmoothScroll] void scrollBy(optional ScrollToOptions options); - [RuntimeEnabled=CSSOMSmoothScroll] void scrollBy(unrestricted double x, unrestricted double y); + [ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options); + [ImplementedAs=scrollTo] void scroll(unrestricted double x, unrestricted double y); + void scrollTo(optional ScrollToOptions options); + void scrollTo(unrestricted double x, unrestricted double y); + void scrollBy(optional ScrollToOptions options); + void scrollBy(unrestricted double x, unrestricted double y); [Affects=Nothing] attribute unrestricted double scrollTop; [Affects=Nothing] attribute unrestricted double scrollLeft; [Affects=Nothing] readonly attribute long scrollWidth; @@ -115,10 +116,6 @@ interface Element : Node { [Affects=Nothing] readonly attribute long clientWidth; [Affects=Nothing] readonly attribute long clientHeight; - // Scroll Customization API. See crbug.com/410974 for details. - [RuntimeEnabled=ScrollCustomization] void setApplyScroll(ScrollStateCallback scrollStateCallback, NativeScrollBehavior nativeScrollBehavior); - [RuntimeEnabled=ScrollCustomization] void setDistributeScroll(ScrollStateCallback scrollStateCallback, NativeScrollBehavior nativeScrollBehavior); - // Typed OM // https://drafts.css-houdini.org/css-typed-om/#inline-stylepropertymap-objects [SameObject, MeasureAs=CSSTypedOMStylePropertyMap] readonly attribute StylePropertyMap attributeStyleMap; diff --git a/chromium/third_party/blink/renderer/core/dom/element_data.cc b/chromium/third_party/blink/renderer/core/dom/element_data.cc index 2275ad72e34..a772eead2ba 100644 --- a/chromium/third_party/blink/renderer/core/dom/element_data.cc +++ b/chromium/third_party/blink/renderer/core/dom/element_data.cc @@ -87,8 +87,8 @@ void ElementData::FinalizeGarbageCollectedObject() { UniqueElementData* ElementData::MakeUniqueCopy() const { if (IsUnique()) - return new UniqueElementData(ToUniqueElementData(*this)); - return new UniqueElementData(ToShareableElementData(*this)); + return MakeGarbageCollected<UniqueElementData>(ToUniqueElementData(*this)); + return MakeGarbageCollected<UniqueElementData>(ToShareableElementData(*this)); } bool ElementData::IsEquivalent(const ElementData* other) const { @@ -173,7 +173,7 @@ UniqueElementData::UniqueElementData(const ShareableElementData& other) } UniqueElementData* UniqueElementData::Create() { - return new UniqueElementData; + return MakeGarbageCollected<UniqueElementData>(); } ShareableElementData* UniqueElementData::MakeShareableCopy() const { diff --git a/chromium/third_party/blink/renderer/core/dom/element_data_cache.h b/chromium/third_party/blink/renderer/core/dom/element_data_cache.h index 4c915fb6441..9e115429704 100644 --- a/chromium/third_party/blink/renderer/core/dom/element_data_cache.h +++ b/chromium/third_party/blink/renderer/core/dom/element_data_cache.h @@ -39,7 +39,11 @@ class ShareableElementData; class ElementDataCache final : public GarbageCollected<ElementDataCache> { public: - static ElementDataCache* Create() { return new ElementDataCache; } + static ElementDataCache* Create() { + return MakeGarbageCollected<ElementDataCache>(); + } + + ElementDataCache(); ShareableElementData* CachedShareableElementDataWithAttributes( const Vector<Attribute>&); @@ -47,8 +51,6 @@ class ElementDataCache final : public GarbageCollected<ElementDataCache> { void Trace(blink::Visitor*); private: - ElementDataCache(); - typedef HeapHashMap<unsigned, Member<ShareableElementData>, AlreadyHashed> ShareableElementDataCache; ShareableElementDataCache shareable_element_data_cache_; diff --git a/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc b/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc index eb67c03c2db..4846d42dbc1 100644 --- a/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc +++ b/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/css/cssom/inline_style_property_map.h" +#include "third_party/blink/renderer/core/html/custom/element_internals.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/core/style/computed_style.h" @@ -40,8 +41,9 @@ namespace blink { struct SameSizeAsElementRareData : NodeRareData { IntSize scroll_offset; - void* pointers_or_strings[5]; - Member<void*> members[14]; + void* pointers_or_strings[4]; + Member<void*> members[17]; + bool flags[1]; }; ElementRareData::ElementRareData(NodeRenderingData* node_layout_data) @@ -55,15 +57,18 @@ ElementRareData::~ElementRareData() { CSSStyleDeclaration& ElementRareData::EnsureInlineCSSStyleDeclaration( Element* owner_element) { - if (!cssom_wrapper_) - cssom_wrapper_ = new InlineCSSStyleDeclaration(owner_element); + if (!cssom_wrapper_) { + cssom_wrapper_ = + MakeGarbageCollected<InlineCSSStyleDeclaration>(owner_element); + } return *cssom_wrapper_; } InlineStylePropertyMap& ElementRareData::EnsureInlineStylePropertyMap( Element* owner_element) { if (!cssom_map_wrapper_) { - cssom_map_wrapper_ = new InlineStylePropertyMap(owner_element); + cssom_map_wrapper_ = + MakeGarbageCollected<InlineStylePropertyMap>(owner_element); } return *cssom_map_wrapper_; } @@ -79,21 +84,31 @@ void ElementRareData::ClearComputedStyle() { AttrNodeList& ElementRareData::EnsureAttrNodeList() { if (!attr_node_list_) - attr_node_list_ = new AttrNodeList; + attr_node_list_ = MakeGarbageCollected<AttrNodeList>(); return *attr_node_list_; } ElementRareData::ResizeObserverDataMap& ElementRareData::EnsureResizeObserverData() { - if (!resize_observer_data_) - resize_observer_data_ = new HeapHashMap<TraceWrapperMember<ResizeObserver>, - Member<ResizeObservation>>(); + if (!resize_observer_data_) { + resize_observer_data_ = + MakeGarbageCollected<HeapHashMap<TraceWrapperMember<ResizeObserver>, + Member<ResizeObservation>>>(); + } return *resize_observer_data_; } +ElementInternals& ElementRareData::EnsureElementInternals(HTMLElement& target) { + if (element_internals_) + return *element_internals_; + element_internals_ = MakeGarbageCollected<ElementInternals>(target); + return *element_internals_; +} + void ElementRareData::TraceAfterDispatch(blink::Visitor* visitor) { visitor->Trace(dataset_); visitor->Trace(class_list_); + visitor->Trace(part_); visitor->Trace(shadow_root_); visitor->Trace(attribute_map_); visitor->Trace(attr_node_list_); @@ -102,8 +117,10 @@ void ElementRareData::TraceAfterDispatch(blink::Visitor* visitor) { visitor->Trace(cssom_map_wrapper_); visitor->Trace(pseudo_element_data_); visitor->Trace(accessible_node_); + visitor->Trace(display_lock_context_); visitor->Trace(v0_custom_element_definition_); visitor->Trace(custom_element_definition_); + visitor->Trace(element_internals_); visitor->Trace(intersection_observer_data_); visitor->Trace(resize_observer_data_); NodeRareData::TraceAfterDispatch(visitor); diff --git a/chromium/third_party/blink/renderer/core/dom/element_rare_data.h b/chromium/third_party/blink/renderer/core/dom/element_rare_data.h index b73961b318c..6f8d1dbc904 100644 --- a/chromium/third_party/blink/renderer/core/dom/element_rare_data.h +++ b/chromium/third_party/blink/renderer/core/dom/element_rare_data.h @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/aom/accessible_node.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/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" @@ -47,15 +48,18 @@ namespace blink { +class Element; +class HTMLElement; class ResizeObservation; class ResizeObserver; class ElementRareData : public NodeRareData { public: static ElementRareData* Create(NodeRenderingData* node_layout_data) { - return new ElementRareData(node_layout_data); + return MakeGarbageCollected<ElementRareData>(node_layout_data); } + explicit ElementRareData(NodeRenderingData*); ~ElementRareData(); void SetPseudoElement(PseudoId, PseudoElement*); @@ -96,15 +100,12 @@ class ElementRareData : public NodeRareData { class_list_ = class_list; } - void SetPart(const AtomicString part_names) { + void SetPart(DOMTokenList* part) { if (!RuntimeEnabledFeatures::CSSPartPseudoElementEnabled()) return; - if (!part_names_) { - part_names_.reset(new SpaceSplitString()); - } - part_names_->Set(part_names); + part_ = part; } - const SpaceSplitString* PartNames() const { return part_names_.get(); } + DOMTokenList* GetPart() const { return part_.Get(); } void SetPartNamesMap(const AtomicString part_names) { if (!RuntimeEnabledFeatures::CSSPartPseudoElementEnabled()) @@ -153,6 +154,9 @@ class ElementRareData : public NodeRareData { } void SetIsValue(const AtomicString& is_value) { is_value_ = is_value; } const AtomicString& IsValue() const { return is_value_; } + void SetDidAttachInternals() { did_attach_internals_ = true; } + bool DidAttachInternals() const { return did_attach_internals_; } + ElementInternals& EnsureElementInternals(HTMLElement& target); AccessibleNode* GetAccessibleNode() const { return accessible_node_.Get(); } AccessibleNode* EnsureAccessibleNode(Element* owner_element) { @@ -174,7 +178,8 @@ class ElementRareData : public NodeRareData { } ElementIntersectionObserverData& EnsureIntersectionObserverData() { if (!intersection_observer_data_) { - intersection_observer_data_ = new ElementIntersectionObserverData(); + intersection_observer_data_ = + MakeGarbageCollected<ElementIntersectionObserverData>(); } return *intersection_observer_data_; } @@ -187,6 +192,17 @@ class ElementRareData : public NodeRareData { } ResizeObserverDataMap& EnsureResizeObserverData(); + DisplayLockContext* EnsureDisplayLockContext(Element* element, + ExecutionContext* context) { + if (!display_lock_context_ || display_lock_context_->IsResolved()) { + display_lock_context_ = new DisplayLockContext(element, context); + } + return display_lock_context_.Get(); + } + DisplayLockContext* GetDisplayLockContext() const { + return display_lock_context_; + } + const AtomicString& GetNonce() const { return nonce_; } void SetNonce(const AtomicString& nonce) { nonce_ = nonce; } @@ -199,7 +215,7 @@ class ElementRareData : public NodeRareData { TraceWrapperMember<DatasetDOMStringMap> dataset_; TraceWrapperMember<ShadowRoot> shadow_root_; TraceWrapperMember<DOMTokenList> class_list_; - std::unique_ptr<SpaceSplitString> part_names_; + TraceWrapperMember<DOMTokenList> part_; std::unique_ptr<NamesMap> part_names_map_; TraceWrapperMember<NamedNodeMap> attribute_map_; TraceWrapperMember<AttrNodeList> attr_node_list_; @@ -216,12 +232,14 @@ class ElementRareData : public NodeRareData { Member<V0CustomElementDefinition> v0_custom_element_definition_; Member<CustomElementDefinition> custom_element_definition_; AtomicString is_value_; + TraceWrapperMember<ElementInternals> element_internals_; Member<PseudoElementData> pseudo_element_data_; TraceWrapperMember<AccessibleNode> accessible_node_; - explicit ElementRareData(NodeRenderingData*); + WeakMember<DisplayLockContext> display_lock_context_; + bool did_attach_internals_ = false; }; inline LayoutSize DefaultMinimumSizeForResizing() { diff --git a/chromium/third_party/blink/renderer/core/dom/element_test.cc b/chromium/third_party/blink/renderer/core/dom/element_test.cc index 74d0347e52a..db52ab4c9c8 100644 --- a/chromium/third_party/blink/renderer/core/dom/element_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/element_test.cc @@ -7,6 +7,7 @@ #include <memory> #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -24,7 +25,8 @@ TEST_F(ElementTest, SupportsFocus) { Document& document = GetDocument(); DCHECK(IsHTMLHtmlElement(document.documentElement())); document.setDesignMode("on"); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_TRUE(document.documentElement()->SupportsFocus()) << "<html> with designMode=on should be focusable."; } @@ -217,7 +219,8 @@ TEST_F(ElementTest, StickySubtreesAreTrackedCorrectly) { // ensure that the sticky subtree update behavior survives forking. document.getElementById("child")->SetInlineStyleProperty( CSSPropertyWebkitRubyPosition, CSSValueAfter); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(DocumentLifecycle::kPaintClean, document.Lifecycle().GetState()); EXPECT_EQ(RubyPosition::kBefore, outer_sticky->StyleRef().GetRubyPosition()); @@ -239,7 +242,8 @@ TEST_F(ElementTest, StickySubtreesAreTrackedCorrectly) { // fork it's StyleRareInheritedData to maintain the sticky subtree bit. document.getElementById("outerSticky") ->SetInlineStyleProperty(CSSPropertyPosition, CSSValueStatic); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(DocumentLifecycle::kPaintClean, document.Lifecycle().GetState()); EXPECT_FALSE(outer_sticky->StyleRef().SubtreeIsSticky()); @@ -362,40 +366,42 @@ TEST_F(ElementTest, PartAttribute) { ASSERT_TRUE(has_two_parts); { - EXPECT_TRUE(has_one_part->HasPartName()); - const SpaceSplitString* part_names = has_one_part->PartNames(); - ASSERT_TRUE(part_names); - ASSERT_EQ(1UL, part_names->size()); - ASSERT_EQ("partname", (*part_names)[0].Ascii()); + EXPECT_TRUE(has_one_part->HasPart()); + const DOMTokenList* part = has_one_part->GetPart(); + ASSERT_TRUE(part); + ASSERT_EQ(1UL, part->length()); + ASSERT_EQ("partname", part->value()); } { - EXPECT_TRUE(has_two_parts->HasPartName()); - const SpaceSplitString* part_names = has_two_parts->PartNames(); - ASSERT_TRUE(part_names); - ASSERT_EQ(2UL, part_names->size()); - ASSERT_EQ("partname1", (*part_names)[0].Ascii()); - ASSERT_EQ("partname2", (*part_names)[1].Ascii()); + EXPECT_TRUE(has_two_parts->HasPart()); + const DOMTokenList* part = has_two_parts->GetPart(); + ASSERT_TRUE(part); + ASSERT_EQ(2UL, part->length()); + ASSERT_EQ("partname1 partname2", part->value()); } { - EXPECT_FALSE(has_no_part->HasPartName()); - EXPECT_FALSE(has_no_part->PartNames()); + EXPECT_FALSE(has_no_part->HasPart()); + EXPECT_FALSE(has_no_part->GetPart()); + + // Calling the DOM API should force creation of an empty DOMTokenList. + const DOMTokenList& part = has_no_part->part(); + EXPECT_FALSE(has_no_part->HasPart()); + EXPECT_EQ(&part, has_no_part->GetPart()); // Now update the attribute value and make sure it's reflected. has_no_part->setAttribute("part", "partname"); - const SpaceSplitString* part_names = has_no_part->PartNames(); - ASSERT_TRUE(part_names); - ASSERT_EQ(1UL, part_names->size()); - ASSERT_EQ("partname", (*part_names)[0].Ascii()); + ASSERT_EQ(1UL, part.length()); + ASSERT_EQ("partname", part.value()); } } -TEST_F(ElementTest, PartmapAttribute) { +TEST_F(ElementTest, ExportpartsAttribute) { Document& document = GetDocument(); SetBodyContent(R"HTML( - <span id='has_one_mapping' partmap='partname1 partname2'></span> - <span id='has_two_mappings' partmap='partname1 partname2, partname3 partname4'></span> + <span id='has_one_mapping' exportparts='partname1: partname2'></span> + <span id='has_two_mappings' exportparts='partname1: partname2, partname3: partname4'></span> <span id='has_no_mapping'></span> )HTML"); @@ -432,7 +438,7 @@ TEST_F(ElementTest, PartmapAttribute) { EXPECT_FALSE(has_no_mapping->PartNamesMap()); // Now update the attribute value and make sure it's reflected. - has_no_mapping->setAttribute("partmap", "partname1 partname2"); + has_no_mapping->setAttribute("exportparts", "partname1: partname2"); const NamesMap* part_names_map = has_no_mapping->PartNamesMap(); ASSERT_TRUE(part_names_map); ASSERT_EQ(1UL, part_names_map->size()); diff --git a/chromium/third_party/blink/renderer/core/dom/element_traversal.h b/chromium/third_party/blink/renderer/core/dom/element_traversal.h index 0a9e5933b50..19098838323 100644 --- a/chromium/third_party/blink/renderer/core/dom/element_traversal.h +++ b/chromium/third_party/blink/renderer/core/dom/element_traversal.h @@ -56,13 +56,14 @@ class HasTagName { // that defines operator(). HasTagName above is an example of a matcher. // // For example, a caller could do this: -// Traversal<Element>::firstChild(someNode, HasTagName(HTMLNames::titleTag)); +// Traversal<Element>::firstChild(some_node, +// HasTagName(html_names::kTitleTag)); // -// This invocation would return the first child of |someNode| (which has to be a -// ContainerNode) for which HasTagName(HTMLNames::titleTag) returned true, so it -// would return the first child of |someNode| which is a <title> element. If the -// caller needs to traverse a Node this way, it's necessary to first check -// Node::isContainerNode() and then use toContainerNode(). +// This invocation would return the first child of |some_node| (which has to be +// a ContainerNode) for which HasTagName(html_names::kTitleTag) returned true, +// so it would return the first child of |someNode| which is a <title> element. +// If the caller needs to traverse a Node this way, it's necessary to first +// check Node::IsContainerNode() and then use ToContainerNode(). // // When looking for a specific element type, it is more efficient to do this: // Traversal<HTMLTitleElement>::firstChild(someNode); diff --git a/chromium/third_party/blink/renderer/core/dom/element_visibility_observer_test.cc b/chromium/third_party/blink/renderer/core/dom/element_visibility_observer_test.cc index 5cc0d1a8953..f629fe863d5 100644 --- a/chromium/third_party/blink/renderer/core/dom/element_visibility_observer_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/element_visibility_observer_test.cc @@ -20,7 +20,7 @@ namespace { class ElementVisibilityObserverTest : public ::testing::Test { protected: - FrameTestHelpers::WebViewHelper helper_; + frame_test_helpers::WebViewHelper helper_; }; TEST_F(ElementVisibilityObserverTest, ObserveElementWithoutDocumentFrame) { @@ -28,8 +28,9 @@ TEST_F(ElementVisibilityObserverTest, ObserveElementWithoutDocumentFrame) { Document& document = *helper_.LocalMainFrame()->GetFrame()->GetDocument(); HTMLElement* element = HTMLDivElement::Create( *DOMImplementation::Create(document)->createHTMLDocument("test")); - ElementVisibilityObserver* observer = new ElementVisibilityObserver( - element, ElementVisibilityObserver::VisibilityCallback()); + ElementVisibilityObserver* observer = + MakeGarbageCollected<ElementVisibilityObserver>( + element, ElementVisibilityObserver::VisibilityCallback()); observer->Start(); observer->Stop(); // It should not crash. @@ -39,12 +40,13 @@ TEST_F(ElementVisibilityObserverTest, ObserveElementWithRemoteFrameParent) { helper_.InitializeRemote(); WebLocalFrameImpl* child_frame = - FrameTestHelpers::CreateLocalChild(*helper_.RemoteMainFrame()); + frame_test_helpers::CreateLocalChild(*helper_.RemoteMainFrame()); Document& document = *child_frame->GetFrame()->GetDocument(); Persistent<HTMLElement> element = HTMLDivElement::Create(document); ElementVisibilityObserver* observer = - new ElementVisibilityObserver(element, WTF::BindRepeating([](bool) {})); + MakeGarbageCollected<ElementVisibilityObserver>( + element, WTF::BindRepeating([](bool) {})); observer->Start(); observer->DeliverObservationsForTesting(); observer->Stop(); diff --git a/chromium/third_party/blink/renderer/core/dom/empty_node_list.h b/chromium/third_party/blink/renderer/core/dom/empty_node_list.h index be910c0d6bf..85b73df2943 100644 --- a/chromium/third_party/blink/renderer/core/dom/empty_node_list.h +++ b/chromium/third_party/blink/renderer/core/dom/empty_node_list.h @@ -39,8 +39,10 @@ namespace blink { class EmptyNodeList final : public NodeList { public: static EmptyNodeList* Create(Node& root_node) { - return new EmptyNodeList(root_node); + return MakeGarbageCollected<EmptyNodeList>(root_node); } + + explicit EmptyNodeList(Node& root_node) : owner_(root_node) {} ~EmptyNodeList() override; Node& OwnerNode() const { return *owner_; } @@ -48,8 +50,6 @@ class EmptyNodeList final : public NodeList { void Trace(blink::Visitor*) override; private: - explicit EmptyNodeList(Node& root_node) : owner_(root_node) {} - unsigned length() const override { return 0; } Node* item(unsigned) const override { return nullptr; } diff --git a/chromium/third_party/blink/renderer/core/dom/events/README.md b/chromium/third_party/blink/renderer/core/dom/events/README.md new file mode 100644 index 00000000000..5b371c17e2e --- /dev/null +++ b/chromium/third_party/blink/renderer/core/dom/events/README.md @@ -0,0 +1,11 @@ +# DOM Events + +[Rendered](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/dom/events/README.md) + +The `renderer/core/dom/events` directory contains the implementation of [DOM Events]. + +[DOM Events]: https://dom.spec.whatwg.org/#events + +Please avoid to put any kind of specific event's implementation in this directory, such as [UI Events]. + +[UI Events]: https://w3c.github.io/uievents/ diff --git a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc index 15e459ae093..746d8e4d995 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc @@ -10,10 +10,18 @@ AddEventListenerOptionsResolved::AddEventListenerOptionsResolved() : passive_forced_for_document_target_(false), passive_specified_(false) {} AddEventListenerOptionsResolved::AddEventListenerOptionsResolved( - const AddEventListenerOptions& options) - : AddEventListenerOptions(options), - passive_forced_for_document_target_(false), - passive_specified_(false) {} + const AddEventListenerOptions* options) + : passive_forced_for_document_target_(false), passive_specified_(false) { + DCHECK(options); + // AddEventListenerOptions + if (options->hasPassive()) + setPassive(options->passive()); + if (options->hasOnce()) + setOnce(options->once()); + // EventListenerOptions + if (options->hasCapture()) + setCapture(options->capture()); +} AddEventListenerOptionsResolved::~AddEventListenerOptionsResolved() = default; diff --git a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h index 533519827e3..fcb23b68aa8 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h +++ b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h @@ -15,11 +15,14 @@ namespace blink { // and the result and the reasons why changes occurred are stored in this class. class CORE_EXPORT AddEventListenerOptionsResolved : public AddEventListenerOptions { - DISALLOW_NEW(); - public: - AddEventListenerOptionsResolved(); - AddEventListenerOptionsResolved(const AddEventListenerOptions&); + static AddEventListenerOptionsResolved* Create() { + return new AddEventListenerOptionsResolved(); + } + static AddEventListenerOptionsResolved* Create( + const AddEventListenerOptions* options) { + return new AddEventListenerOptionsResolved(options); + } ~AddEventListenerOptionsResolved() override; void SetPassiveForcedForDocumentTarget(bool forced) { @@ -37,6 +40,9 @@ class CORE_EXPORT AddEventListenerOptionsResolved void Trace(blink::Visitor*) override; private: + AddEventListenerOptionsResolved(); + AddEventListenerOptionsResolved(const AddEventListenerOptions*); + bool passive_forced_for_document_target_; bool passive_specified_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc b/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc index 902d22a3f91..a5ae410abad 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc @@ -27,7 +27,7 @@ #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h" -#include "third_party/blink/renderer/core/event_names.h" +#include "third_party/blink/renderer/core/event_interface_names.h" namespace blink { @@ -35,12 +35,12 @@ CustomEvent::CustomEvent() = default; CustomEvent::CustomEvent(ScriptState* script_state, const AtomicString& type, - const CustomEventInit& initializer) + const CustomEventInit* initializer) : Event(type, initializer) { world_ = WrapRefCounted(&script_state->World()); - if (initializer.hasDetail()) { - detail_.Set(initializer.detail().GetIsolate(), - initializer.detail().V8Value()); + if (initializer->hasDetail()) { + detail_.Set(initializer->detail().GetIsolate(), + initializer->detail().V8Value()); } } @@ -72,7 +72,7 @@ ScriptValue CustomEvent::detail(ScriptState* script_state) const { } const AtomicString& CustomEvent::InterfaceName() const { - return EventNames::CustomEvent; + return event_interface_names::kCustomEvent; } void CustomEvent::Trace(blink::Visitor* visitor) { diff --git a/chromium/third_party/blink/renderer/core/dom/events/custom_event.h b/chromium/third_party/blink/renderer/core/dom/events/custom_event.h index 72c81b2cbe2..9d2f33faac0 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/custom_event.h +++ b/chromium/third_party/blink/renderer/core/dom/events/custom_event.h @@ -44,7 +44,7 @@ class CORE_EXPORT CustomEvent final : public Event { static CustomEvent* Create(ScriptState* script_state, const AtomicString& type, - const CustomEventInit& initializer) { + const CustomEventInit* initializer) { return new CustomEvent(script_state, type, initializer); } @@ -64,7 +64,7 @@ class CORE_EXPORT CustomEvent final : public Event { CustomEvent(); CustomEvent(ScriptState*, const AtomicString& type, - const CustomEventInit& initializer); + const CustomEventInit* initializer); scoped_refptr<DOMWrapperWorld> world_; TraceWrapperV8Reference<v8::Value> detail_; diff --git a/chromium/third_party/blink/renderer/core/dom/events/event.cc b/chromium/third_party/blink/renderer/core/dom/events/event.cc index 0239dfb8d4c..7b3b0bf7f99 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event.cc @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/dom/events/window_event_context.h" #include "third_party/blink/renderer/core/dom/static_node_list.h" +#include "third_party/blink/renderer/core/event_interface_names.h" #include "third_party/blink/renderer/core/events/focus_event.h" #include "third_party/blink/renderer/core/events/mouse_event.h" #include "third_party/blink/renderer/core/events/pointer_event.h" @@ -45,16 +46,16 @@ static bool IsEventTypeScopedInV0(const AtomicString& event_type) { // WebKit never allowed selectstart event to cross the the shadow DOM // boundary. Changing this breaks existing sites. // See https://bugs.webkit.org/show_bug.cgi?id=52195 for details. - return event_type == EventTypeNames::abort || - event_type == EventTypeNames::change || - event_type == EventTypeNames::error || - event_type == EventTypeNames::load || - event_type == EventTypeNames::reset || - event_type == EventTypeNames::resize || - event_type == EventTypeNames::scroll || - event_type == EventTypeNames::select || - event_type == EventTypeNames::selectstart || - event_type == EventTypeNames::slotchange; + return event_type == event_type_names::kAbort || + event_type == event_type_names::kChange || + event_type == event_type_names::kError || + event_type == event_type_names::kLoad || + event_type == event_type_names::kReset || + event_type == event_type_names::kResize || + event_type == event_type_names::kScroll || + event_type == event_type_names::kSelect || + event_type == event_type_names::kSelectstart || + event_type == event_type_names::kSlotchange; } Event::Event() : Event("", Bubbles::kNo, Cancelable::kNo) { @@ -108,13 +109,13 @@ Event::Event(const AtomicString& event_type, platform_time_stamp_(platform_time_stamp) {} Event::Event(const AtomicString& event_type, - const EventInit& initializer, + const EventInit* initializer, TimeTicks platform_time_stamp) : Event(event_type, - initializer.bubbles() ? Bubbles::kYes : Bubbles::kNo, - initializer.cancelable() ? Cancelable::kYes : Cancelable::kNo, - initializer.composed() ? ComposedMode::kComposed - : ComposedMode::kScoped, + initializer->bubbles() ? Bubbles::kYes : Bubbles::kNo, + initializer->cancelable() ? Cancelable::kYes : Cancelable::kNo, + initializer->composed() ? ComposedMode::kComposed + : ComposedMode::kScoped, platform_time_stamp) {} Event::~Event() = default; @@ -172,7 +173,7 @@ void Event::setLegacyReturnValue(ScriptState* script_state, bool return_value) { } const AtomicString& Event::InterfaceName() const { - return EventNames::Event; + return event_interface_names::kEvent; } bool Event::HasInterface(const AtomicString& name) const { @@ -298,7 +299,7 @@ void Event::SetUnderlyingEvent(Event* ue) { void Event::InitEventPath(Node& node) { if (!event_path_) { - event_path_ = new EventPath(node, this); + event_path_ = MakeGarbageCollected<EventPath>(node, this); } else { event_path_->InitializeWith(node, this); } diff --git a/chromium/third_party/blink/renderer/core/dom/events/event.h b/chromium/third_party/blink/renderer/core/dom/events/event.h index b1229004af9..654b6faaaa0 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event.h +++ b/chromium/third_party/blink/renderer/core/dom/events/event.h @@ -87,25 +87,44 @@ class CORE_EXPORT Event : public ScriptWrappable { kPassiveDefault, }; - static Event* Create() { return new Event; } + static Event* Create() { return MakeGarbageCollected<Event>(); } static Event* Create(const AtomicString& type) { - return new Event(type, Bubbles::kNo, Cancelable::kNo); + return MakeGarbageCollected<Event>(type, Bubbles::kNo, Cancelable::kNo); } static Event* CreateCancelable(const AtomicString& type) { - return new Event(type, Bubbles::kNo, Cancelable::kYes); + return MakeGarbageCollected<Event>(type, Bubbles::kNo, Cancelable::kYes); } static Event* CreateBubble(const AtomicString& type) { - return new Event(type, Bubbles::kYes, Cancelable::kNo); + return MakeGarbageCollected<Event>(type, Bubbles::kYes, Cancelable::kNo); } static Event* CreateCancelableBubble(const AtomicString& type) { - return new Event(type, Bubbles::kYes, Cancelable::kYes); + return MakeGarbageCollected<Event>(type, Bubbles::kYes, Cancelable::kYes); } - static Event* Create(const AtomicString& type, const EventInit& initializer) { - return new Event(type, initializer); + static Event* Create(const AtomicString& type, const EventInit* initializer) { + return MakeGarbageCollected<Event>(type, initializer); } + Event(); + Event(const AtomicString& type, + Bubbles, + Cancelable, + ComposedMode, + TimeTicks platform_time_stamp); + Event(const AtomicString& type, + Bubbles, + Cancelable, + TimeTicks platform_time_stamp); + Event(const AtomicString& type, + Bubbles, + Cancelable, + ComposedMode = ComposedMode::kScoped); + Event(const AtomicString& type, + const EventInit*, + TimeTicks platform_time_stamp); + Event(const AtomicString& type, const EventInit* init) + : Event(type, init, CurrentTimeTicks()) {} ~Event() override; void initEvent(const AtomicString& type, bool bubbles, bool cancelable); @@ -294,26 +313,6 @@ class CORE_EXPORT Event : public ScriptWrappable { void Trace(blink::Visitor*) override; protected: - Event(); - Event(const AtomicString& type, - Bubbles, - Cancelable, - ComposedMode, - TimeTicks platform_time_stamp); - Event(const AtomicString& type, - Bubbles, - Cancelable, - TimeTicks platform_time_stamp); - Event(const AtomicString& type, - Bubbles, - Cancelable, - ComposedMode = ComposedMode::kScoped); - Event(const AtomicString& type, - const EventInit&, - TimeTicks platform_time_stamp); - Event(const AtomicString& type, const EventInit& init) - : Event(type, init, CurrentTimeTicks()) {} - virtual void ReceivedTarget(); void SetBubbles(bool bubble) { bubbles_ = bubble; } diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc index a6710b309ec..e217aa91d2d 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc @@ -37,6 +37,7 @@ #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" #include "third_party/blink/renderer/core/dom/events/window_event_context.h" #include "third_party/blink/renderer/core/events/mouse_event.h" +#include "third_party/blink/renderer/core/frame/ad_tracker.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -69,7 +70,7 @@ EventDispatcher::EventDispatcher(Node& node, Event& event) void EventDispatcher::DispatchScopedEvent(Node& node, Event& event) { // We need to set the target here because it can go away by the time we // actually fire the event. - event.SetTarget(EventPath::EventTargetRespectingTargetRules(node)); + event.SetTarget(&EventPath::EventTargetRespectingTargetRules(node)); ScopedEventQueue::Instance()->EnqueueEvent(event); } @@ -84,7 +85,7 @@ void EventDispatcher::DispatchSimulatedClick( // dispatchSimulatedClick(). DEFINE_STATIC_LOCAL(Persistent<HeapHashSet<Member<Node>>>, nodes_dispatching_simulated_clicks, - (new HeapHashSet<Member<Node>>)); + (MakeGarbageCollected<HeapHashSet<Member<Node>>>())); if (IsDisabledFormControl(&node)) return; @@ -95,18 +96,18 @@ void EventDispatcher::DispatchSimulatedClick( nodes_dispatching_simulated_clicks->insert(&node); if (mouse_event_options == kSendMouseOverUpDownEvents) - EventDispatcher(node, *MouseEvent::Create(EventTypeNames::mouseover, + EventDispatcher(node, *MouseEvent::Create(event_type_names::kMouseover, node.GetDocument().domWindow(), underlying_event, creation_scope)) .Dispatch(); if (mouse_event_options != kSendNoEvents) { - EventDispatcher(node, *MouseEvent::Create(EventTypeNames::mousedown, + EventDispatcher(node, *MouseEvent::Create(event_type_names::kMousedown, node.GetDocument().domWindow(), underlying_event, creation_scope)) .Dispatch(); node.SetActive(true); - EventDispatcher(node, *MouseEvent::Create(EventTypeNames::mouseup, + EventDispatcher(node, *MouseEvent::Create(event_type_names::kMouseup, node.GetDocument().domWindow(), underlying_event, creation_scope)) .Dispatch(); @@ -116,7 +117,7 @@ void EventDispatcher::DispatchSimulatedClick( node.SetActive(false); // always send click - EventDispatcher(node, *MouseEvent::Create(EventTypeNames::click, + EventDispatcher(node, *MouseEvent::Create(event_type_names::kClick, node.GetDocument().domWindow(), underlying_event, creation_scope)) .Dispatch(); @@ -139,7 +140,7 @@ DispatchEventResult EventDispatcher::Dispatch() { return DispatchEventResult::kNotCanceled; } std::unique_ptr<EventTiming> eventTiming; - if (OriginTrials::EventTimingEnabled(&node_->GetDocument())) { + if (origin_trials::EventTimingEnabled(&node_->GetDocument())) { LocalFrame* frame = node_->GetDocument().GetFrame(); if (frame && frame->DomWindow()) { UseCounter::Count(node_->GetDocument(), @@ -150,13 +151,29 @@ DispatchEventResult EventDispatcher::Dispatch() { } event_->GetEventPath().EnsureWindowEventContext(); + const bool is_click = + event_->IsMouseEvent() && event_->type() == event_type_names::kClick; + + if (is_click && event_->isTrusted()) { + Document& document = node_->GetDocument(); + LocalFrame* frame = document.GetFrame(); + if (frame) { + // A genuine mouse click cannot be triggered by script so we don't expect + // there are any script in the stack. + DCHECK(!frame->GetAdTracker() || + !frame->GetAdTracker()->IsAdScriptInStack()); + if (frame->IsAdSubframe()) { + UseCounter::Count(document, WebFeature::kAdClick); + } + } + } + // 6. Let isActivationEvent be true, if event is a MouseEvent object and // event's type attribute is "click", and false otherwise. // // We need to include non-standard textInput event for HTMLInputElement. const bool is_activation_event = - (event_->IsMouseEvent() && event_->type() == EventTypeNames::click) || - event_->type() == EventTypeNames::textInput; + is_click || event_->type() == event_type_names::kTextInput; // 7. Let activationTarget be target, if isActivationEvent is true and target // has activation behavior, and null otherwise. @@ -167,21 +184,21 @@ DispatchEventResult EventDispatcher::Dispatch() { if (is_activation_event && !activation_target && event_->bubbles()) { wtf_size_t size = event_->GetEventPath().size(); for (wtf_size_t i = 1; i < size; ++i) { - Node* target = event_->GetEventPath()[i].GetNode(); - if (target->HasActivationBehavior()) { - activation_target = target; + Node& target = event_->GetEventPath()[i].GetNode(); + if (target.HasActivationBehavior()) { + activation_target = ⌖ break; } } } - event_->SetTarget(EventPath::EventTargetRespectingTargetRules(*node_)); + event_->SetTarget(&EventPath::EventTargetRespectingTargetRules(*node_)); #if DCHECK_IS_ON() DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden()); #endif DCHECK(event_->target()); TRACE_EVENT1("devtools.timeline", "EventDispatch", "data", - InspectorEventDispatchEvent::Data(*event_)); + inspector_event_dispatch_event::Data(*event_)); EventDispatchHandlingState* pre_dispatch_event_handler_result = nullptr; if (DispatchEventPreProcess(activation_target, pre_dispatch_event_handler_result) == @@ -289,7 +306,7 @@ inline void EventDispatcher::DispatchEventAtBubbling() { inline void EventDispatcher::DispatchEventPostProcess( Node* activation_target, EventDispatchHandlingState* pre_dispatch_event_handler_result) { - event_->SetTarget(EventPath::EventTargetRespectingTargetRules(*node_)); + event_->SetTarget(&EventPath::EventTargetRespectingTargetRules(*node_)); // https://dom.spec.whatwg.org/#concept-event-dispatch // 14. Unset event’s dispatch flag, stop propagation flag, and stop immediate // propagation flag. @@ -302,7 +319,7 @@ inline void EventDispatcher::DispatchEventPostProcess( event_->SetCurrentTarget(nullptr); bool is_click = event_->IsMouseEvent() && - ToMouseEvent(*event_).type() == EventTypeNames::click; + ToMouseEvent(*event_).type() == event_type_names::kClick; if (is_click) { // Fire an accessibility event indicating a node was clicked on. This is // safe if event_->target()->ToNode() returns null. @@ -331,7 +348,7 @@ inline void EventDispatcher::DispatchEventPostProcess( // fastclick.js seems to generate these. crbug.com/642698 // TODO(dtapuska): Change this to a target SDK quirk crbug.com/643705 if (!is_trusted_or_click && event_->IsMouseEvent() && - event_->type() == EventTypeNames::mousedown && + event_->type() == event_type_names::kMousedown && IsHTMLSelectElement(*node_)) { if (Settings* settings = node_->GetDocument().GetSettings()) { is_trusted_or_click = settings->GetWideViewportQuirkEnabled(); @@ -353,9 +370,9 @@ inline void EventDispatcher::DispatchEventPostProcess( if (!event_->DefaultHandled() && event_->bubbles()) { wtf_size_t size = event_->GetEventPath().size(); for (wtf_size_t i = 1; i < size; ++i) { - event_->GetEventPath()[i].GetNode()->WillCallDefaultEventHandler( + event_->GetEventPath()[i].GetNode().WillCallDefaultEventHandler( *event_); - event_->GetEventPath()[i].GetNode()->DefaultEventHandler(*event_); + event_->GetEventPath()[i].GetNode().DefaultEventHandler(*event_); DCHECK(!event_->defaultPrevented()); if (event_->DefaultHandled()) break; @@ -367,7 +384,7 @@ inline void EventDispatcher::DispatchEventPostProcess( // it to open. This measures a possible breakage of not allowing untrusted // events to open select boxes. if (!event_->isTrusted() && event_->IsMouseEvent() && - event_->type() == EventTypeNames::mousedown && + event_->type() == event_type_names::kMousedown && IsHTMLSelectElement(*node_)) { UseCounter::Count(node_->GetDocument(), WebFeature::kUntrustedMouseDownEventDispatchedToSelect); diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_listener.h b/chromium/third_party/blink/renderer/core/dom/events/event_listener.h index d658c3c82b4..b5b2e7449db 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_listener.h +++ b/chromium/third_party/blink/renderer/core/dom/events/event_listener.h @@ -47,15 +47,29 @@ class CORE_EXPORT EventListener : public CustomWrappableAdapter { kConditionEventListenerType, }; + explicit EventListener(ListenerType type) : type_(type) {} ~EventListener() override = default; - virtual bool operator==(const EventListener&) const = 0; - virtual void handleEvent(ExecutionContext*, Event*) = 0; - virtual const String& Code() const { return g_empty_string; } + + // Invokes this event listener. + virtual void Invoke(ExecutionContext*, Event*) = 0; + + // Returns true if this implements IDL EventHandler family. + virtual bool IsEventHandler() const { return false; } + + // Returns true if this implements IDL EventHandler family and the value is + // a content attribute (or compiled from a content attribute). virtual bool IsEventHandlerForContentAttribute() const { return false; } + + // Returns an uncompiled script body. + // https://html.spec.whatwg.org/C/webappapis.html#internal-raw-uncompiled-handler + virtual const String& ScriptBody() const { return g_empty_string; } + + // Returns true if this event listener was created in the current world. virtual bool BelongsToTheCurrentWorld(ExecutionContext*) const { return false; } - virtual bool IsEventHandler() const { return false; } + + virtual bool operator==(const EventListener&) const = 0; ListenerType GetType() const { return type_; } @@ -69,9 +83,6 @@ class CORE_EXPORT EventListener : public CustomWrappableAdapter { const char* NameInHeapSnapshot() const override { return "EventListener"; } - protected: - explicit EventListener(ListenerType type) : type_(type) {} - private: ListenerType type_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc index de300766682..f508802ea06 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc @@ -97,7 +97,7 @@ Vector<AtomicString> EventListenerMap::EventTypes() const { static bool AddListenerToVector(EventListenerVector* vector, EventListener* listener, - const AddEventListenerOptionsResolved& options, + const AddEventListenerOptionsResolved* options, RegisteredEventListener* registered_listener) { *registered_listener = RegisteredEventListener(listener, options); @@ -110,7 +110,7 @@ static bool AddListenerToVector(EventListenerVector* vector, bool EventListenerMap::Add(const AtomicString& event_type, EventListener* listener, - const AddEventListenerOptionsResolved& options, + const AddEventListenerOptionsResolved* options, RegisteredEventListener* registered_listener) { CheckNoActiveIterators(); @@ -120,7 +120,8 @@ bool EventListenerMap::Add(const AtomicString& event_type, registered_listener); } - entries_.push_back(std::make_pair(event_type, new EventListenerVector)); + entries_.push_back( + std::make_pair(event_type, MakeGarbageCollected<EventListenerVector>())); return AddListenerToVector(entries_.back().second.Get(), listener, options, registered_listener); } @@ -128,7 +129,7 @@ bool EventListenerMap::Add(const AtomicString& event_type, static bool RemoveListenerFromVector( EventListenerVector* listener_vector, const EventListener* listener, - const EventListenerOptions& options, + const EventListenerOptions* options, wtf_size_t* index_of_removed_listener, RegisteredEventListener* registered_listener) { auto* const begin = listener_vector->data(); @@ -154,7 +155,7 @@ static bool RemoveListenerFromVector( bool EventListenerMap::Remove(const AtomicString& event_type, const EventListener* listener, - const EventListenerOptions& options, + const EventListenerOptions* options, wtf_size_t* index_of_removed_listener, RegisteredEventListener* registered_listener) { CheckNoActiveIterators(); @@ -191,7 +192,7 @@ static void CopyListenersNotCreatedFromMarkupToTarget( for (auto& event_listener : *listener_vector) { if (event_listener.Callback()->IsEventHandlerForContentAttribute()) continue; - AddEventListenerOptionsResolved options = event_listener.Options(); + AddEventListenerOptionsResolved* options = event_listener.Options(); target->addEventListener(event_type, event_listener.Callback(), options); } } diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h index d2ee92dac25..57da2d12a25 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h +++ b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h @@ -60,11 +60,11 @@ class CORE_EXPORT EventListenerMap final { void Clear(); bool Add(const AtomicString& event_type, EventListener*, - const AddEventListenerOptionsResolved&, + const AddEventListenerOptionsResolved*, RegisteredEventListener* registered_listener); bool Remove(const AtomicString& event_type, const EventListener*, - const EventListenerOptions&, + const EventListenerOptions*, wtf_size_t* index_of_removed_listener, RegisteredEventListener* registered_listener); EventListenerVector* Find(const AtomicString& event_type); diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_path.cc b/chromium/third_party/blink/renderer/core/dom/events/event_path.cc index b5f52b1b952..a353eb91562 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_path.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_path.cc @@ -30,7 +30,6 @@ #include "third_party/blink/renderer/core/dom/events/window_event_context.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/dom/v0_insertion_point.h" -#include "third_party/blink/renderer/core/event_names.h" #include "third_party/blink/renderer/core/events/touch_event.h" #include "third_party/blink/renderer/core/events/touch_event_context.h" #include "third_party/blink/renderer/core/html/html_slot_element.h" @@ -39,13 +38,13 @@ namespace blink { -EventTarget* EventPath::EventTargetRespectingTargetRules(Node& reference_node) { +EventTarget& EventPath::EventTargetRespectingTargetRules(Node& reference_node) { if (reference_node.IsPseudoElement()) { DCHECK(reference_node.parentNode()); - return reference_node.parentNode(); + return *reference_node.parentNode(); } - return &reference_node; + return reference_node; } static inline bool ShouldStopAtShadowRoot(Event& event, @@ -134,8 +133,9 @@ void EventPath::CalculatePath() { node_event_contexts_.ReserveCapacity(nodes_in_path.size()); for (Node* node_in_path : nodes_in_path) { + DCHECK(node_in_path); node_event_contexts_.push_back(NodeEventContext( - node_in_path, EventTargetRespectingTargetRules(*node_in_path))); + *node_in_path, EventTargetRespectingTargetRules(*node_in_path))); } } @@ -154,7 +154,7 @@ void EventPath::CalculateTreeOrderAndSetNearestAncestorClosedTree() { continue; } TreeScopeEventContext* parent_tree_scope_event_context = - GetTreeScopeEventContext(parent); + GetTreeScopeEventContext(*parent); DCHECK(parent_tree_scope_event_context); parent_tree_scope_event_context->AddChild(*tree_scope_event_context.Get()); } @@ -163,8 +163,7 @@ void EventPath::CalculateTreeOrderAndSetNearestAncestorClosedTree() { } TreeScopeEventContext* EventPath::GetTreeScopeEventContext( - TreeScope* tree_scope) { - DCHECK(tree_scope); + TreeScope& tree_scope) { for (TreeScopeEventContext* tree_scope_event_context : tree_scope_event_contexts_) { if (tree_scope_event_context->GetTreeScope() == tree_scope) { @@ -180,7 +179,7 @@ TreeScopeEventContext* EventPath::EnsureTreeScopeEventContext( if (!tree_scope) return nullptr; TreeScopeEventContext* tree_scope_event_context = - GetTreeScopeEventContext(tree_scope); + GetTreeScopeEventContext(*tree_scope); if (!tree_scope_event_context) { tree_scope_event_context = TreeScopeEventContext::Create(*tree_scope); tree_scope_event_contexts_.push_back(tree_scope_event_context); @@ -190,7 +189,7 @@ TreeScopeEventContext* EventPath::EnsureTreeScopeEventContext( if (parent_tree_scope_event_context && parent_tree_scope_event_context->Target()) { tree_scope_event_context->SetTarget( - parent_tree_scope_event_context->Target()); + *parent_tree_scope_event_context->Target()); } else if (current_target) { tree_scope_event_context->SetTarget( EventTargetRespectingTargetRules(*current_target)); @@ -207,11 +206,11 @@ void EventPath::CalculateAdjustedTargets() { TreeScopeEventContext* last_tree_scope_event_context = nullptr; for (auto& context : node_event_contexts_) { - Node* current_node = context.GetNode(); - TreeScope& current_tree_scope = current_node->GetTreeScope(); + Node& current_node = context.GetNode(); + TreeScope& current_tree_scope = current_node.GetTreeScope(); if (last_tree_scope != ¤t_tree_scope) { last_tree_scope_event_context = - EnsureTreeScopeEventContext(current_node, ¤t_tree_scope); + EnsureTreeScopeEventContext(¤t_node, ¤t_tree_scope); } DCHECK(last_tree_scope_event_context); context.SetTreeScopeEventContext(last_tree_scope_event_context); @@ -222,7 +221,7 @@ void EventPath::CalculateAdjustedTargets() { void EventPath::BuildRelatedNodeMap(const Node& related_node, RelatedTargetMap& related_target_map) { EventPath* related_target_event_path = - new EventPath(const_cast<Node&>(related_node)); + MakeGarbageCollected<EventPath>(const_cast<Node&>(related_node)); for (const auto& tree_scope_event_context : related_target_event_path->tree_scope_event_contexts_) { related_target_map.insert(&tree_scope_event_context->GetTreeScope(), @@ -274,7 +273,7 @@ void EventPath::RetargetRelatedTarget(const Node& related_target_node) { EventTarget* adjusted_related_target = FindRelatedNode( tree_scope_event_context->GetTreeScope(), related_node_map); DCHECK(adjusted_related_target); - tree_scope_event_context.Get()->SetRelatedTarget(adjusted_related_target); + tree_scope_event_context.Get()->SetRelatedTarget(*adjusted_related_target); } } @@ -307,7 +306,7 @@ bool ShouldStopEventPath(EventTarget& adjusted_target, void EventPath::ShrinkForRelatedTarget(const Node& event_target_node, const Node& event_related_target_node) { for (wtf_size_t i = 0; i < size(); ++i) { - if (ShouldStopEventPath(*at(i).Target(), *at(i).RelatedTarget(), + if (ShouldStopEventPath(*(*this)[i].Target(), *(*this)[i].RelatedTarget(), event_target_node, event_related_target_node)) { Shrink(i); break; @@ -323,11 +322,11 @@ void EventPath::AdjustForTouchEvent(const TouchEvent& touch_event) { HeapVector<Member<TreeScope>> tree_scopes; for (const auto& tree_scope_event_context : tree_scope_event_contexts_) { - TouchEventContext* touch_event_context = + TouchEventContext& touch_event_context = tree_scope_event_context->EnsureTouchEventContext(); - adjusted_touches.push_back(&touch_event_context->Touches()); - adjusted_target_touches.push_back(&touch_event_context->TargetTouches()); - adjusted_changed_touches.push_back(&touch_event_context->ChangedTouches()); + adjusted_touches.push_back(&touch_event_context.Touches()); + adjusted_target_touches.push_back(&touch_event_context.TargetTouches()); + adjusted_changed_touches.push_back(&touch_event_context.ChangedTouches()); tree_scopes.push_back(&tree_scope_event_context->GetTreeScope()); } @@ -378,8 +377,7 @@ void EventPath::AdjustTouchList( bool EventPath::DisabledFormControlExistsInPath() const { for (const auto& context : node_event_contexts_) { - const Node* target_node = context.GetNode(); - if (target_node && IsDisabledFormControl(target_node)) + if (IsDisabledFormControl(&context.GetNode())) return true; } return false; @@ -387,8 +385,7 @@ bool EventPath::DisabledFormControlExistsInPath() const { bool EventPath::HasEventListenersInPath(const AtomicString& event_type) const { for (const auto& context : node_event_contexts_) { - const Node* target_node = context.GetNode(); - if (target_node && target_node->HasEventListeners(event_type)) + if (context.GetNode().HasEventListeners(event_type)) return true; } return false; @@ -401,9 +398,10 @@ NodeEventContext& EventPath::TopNodeEventContext() { void EventPath::EnsureWindowEventContext() { DCHECK(event_); - if (!window_event_context_) - window_event_context_ = - new WindowEventContext(*event_, TopNodeEventContext()); + if (!window_event_context_) { + window_event_context_ = MakeGarbageCollected<WindowEventContext>( + *event_, TopNodeEventContext()); + } } #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_path.h b/chromium/third_party/blink/renderer/core/dom/events/event_path.h index 8dc3a5a0459..be0d71d2c43 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_path.h +++ b/chromium/third_party/blink/renderer/core/dom/events/event_path.h @@ -62,7 +62,6 @@ class CORE_EXPORT EventPath final const NodeEventContext& operator[](wtf_size_t index) const { return node_event_contexts_[index]; } - NodeEventContext& at(wtf_size_t index) { return node_event_contexts_[index]; } NodeEventContext& Last() { return node_event_contexts_[size() - 1]; } WindowEventContext& GetWindowEventContext() { @@ -82,7 +81,7 @@ class CORE_EXPORT EventPath final NodeEventContext& TopNodeEventContext(); - static EventTarget* EventTargetRespectingTargetRules(Node&); + static EventTarget& EventTargetRespectingTargetRules(Node&); void Trace(blink::Visitor*); void Clear() { @@ -112,7 +111,7 @@ class CORE_EXPORT EventPath final HeapVector<Member<TouchList>> adjusted_touch_list, const HeapVector<Member<TreeScope>>& tree_scopes); - TreeScopeEventContext* GetTreeScopeEventContext(TreeScope*); + TreeScopeEventContext* GetTreeScopeEventContext(TreeScope&); TreeScopeEventContext* EnsureTreeScopeEventContext(Node* current_target, TreeScope*); diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_path_test.cc b/chromium/third_party/blink/renderer/core/dom/events/event_path_test.cc index a405a3a1ff7..6f3b6dc0300 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_path_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_path_test.cc @@ -18,7 +18,7 @@ class EventPathTest : public PageTestBase {}; TEST_F(EventPathTest, ShouldBeEmptyForPseudoElementWithoutParentElement) { Element* div = GetDocument().CreateRawElement( - HTMLNames::divTag, CreateElementFlags::ByCreateElement()); + html_names::kDivTag, CreateElementFlags::ByCreateElement()); PseudoElement* pseudo = PseudoElement::Create(div, kPseudoIdFirstLetter); pseudo->Dispose(); EventPath event_path(*pseudo); diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc b/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc index 78bea34c911..55abadf355f 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc @@ -35,7 +35,7 @@ namespace blink { EventQueue* EventQueue::Create(ExecutionContext* context, TaskType task_type) { - return new EventQueue(context, task_type); + return MakeGarbageCollected<EventQueue>(context, task_type); } EventQueue::EventQueue(ExecutionContext* context, TaskType task_type) diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_queue.h b/chromium/third_party/blink/renderer/core/dom/events/event_queue.h index 1906634e688..a1ecfb3d427 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_queue.h +++ b/chromium/third_party/blink/renderer/core/dom/events/event_queue.h @@ -43,6 +43,8 @@ class CORE_EXPORT EventQueue final public: static EventQueue* Create(ExecutionContext*, TaskType); + + EventQueue(ExecutionContext*, TaskType); ~EventQueue(); void Trace(blink::Visitor*) override; @@ -51,8 +53,6 @@ class CORE_EXPORT EventQueue final bool HasPendingEvents() const; private: - EventQueue(ExecutionContext*, TaskType); - bool RemoveEvent(Event&); void DispatchEvent(Event*); diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target.cc b/chromium/third_party/blink/renderer/core/dom/events/event_target.cc index a8f3eb98f6a..42faeb2a461 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_target.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_target.cc @@ -93,13 +93,13 @@ Settings* WindowSettings(LocalDOMWindow* executing_window) { } bool IsTouchScrollBlockingEvent(const AtomicString& event_type) { - return event_type == EventTypeNames::touchstart || - event_type == EventTypeNames::touchmove; + return event_type == event_type_names::kTouchstart || + event_type == event_type_names::kTouchmove; } bool IsWheelScrollBlockingEvent(const AtomicString& event_type) { - return event_type == EventTypeNames::mousewheel || - event_type == EventTypeNames::wheel; + return event_type == event_type_names::kMousewheel || + event_type == event_type_names::kWheel; } bool IsScrollBlockingEvent(const AtomicString& event_type) { @@ -108,8 +108,8 @@ bool IsScrollBlockingEvent(const AtomicString& event_type) { } bool IsInstrumentedForAsyncStack(const AtomicString& event_type) { - return event_type == EventTypeNames::load || - event_type == EventTypeNames::error; + return event_type == event_type_names::kLoad || + event_type == event_type_names::kError; } base::TimeDelta BlockedEventsWarningThreshold(ExecutionContext* context, @@ -231,20 +231,20 @@ bool EventTarget::IsTopLevelNode() { void EventTarget::SetDefaultAddEventListenerOptions( const AtomicString& event_type, EventListener* event_listener, - AddEventListenerOptionsResolved& options) { - options.SetPassiveSpecified(options.hasPassive()); + AddEventListenerOptionsResolved* options) { + options->SetPassiveSpecified(options->hasPassive()); if (!IsScrollBlockingEvent(event_type)) { - if (!options.hasPassive()) - options.setPassive(false); + if (!options->hasPassive()) + options->setPassive(false); return; } LocalDOMWindow* executing_window = ExecutingWindow(); if (executing_window) { - if (options.hasPassive()) { + if (options->hasPassive()) { UseCounter::Count(executing_window->document(), - options.passive() + options->passive() ? WebFeature::kAddEventListenerPassiveTrue : WebFeature::kAddEventListenerPassiveFalse); } @@ -252,31 +252,31 @@ void EventTarget::SetDefaultAddEventListenerOptions( if (RuntimeEnabledFeatures::PassiveDocumentEventListenersEnabled() && IsTouchScrollBlockingEvent(event_type)) { - if (!options.hasPassive() && IsTopLevelNode()) { - options.setPassive(true); - options.SetPassiveForcedForDocumentTarget(true); + if (!options->hasPassive() && IsTopLevelNode()) { + options->setPassive(true); + options->SetPassiveForcedForDocumentTarget(true); return; } } if (IsWheelScrollBlockingEvent(event_type) && IsTopLevelNode()) { - if (options.hasPassive()) { + if (options->hasPassive()) { if (executing_window) { UseCounter::Count( executing_window->document(), - options.passive() + options->passive() ? WebFeature::kAddDocumentLevelPassiveTrueWheelEventListener : WebFeature::kAddDocumentLevelPassiveFalseWheelEventListener); } - } else { // !options.hasPassive() + } else { // !options->hasPassive() if (executing_window) { UseCounter::Count( executing_window->document(), WebFeature::kAddDocumentLevelPassiveDefaultWheelEventListener); } if (RuntimeEnabledFeatures::PassiveDocumentWheelEventListenersEnabled()) { - options.setPassive(true); - options.SetPassiveForcedForDocumentTarget(true); + options->setPassive(true); + options->SetPassiveForcedForDocumentTarget(true); return; } } @@ -286,8 +286,8 @@ void EventTarget::SetDefaultAddEventListenerOptions( // a bound function name of "ssc_wheel" treat and no passive value default // passive to true. See crbug.com/501568. if (RuntimeEnabledFeatures::SmoothScrollJSInterventionEnabled() && - event_type == EventTypeNames::mousewheel && ToLocalDOMWindow() && - event_listener && !options.hasPassive()) { + event_type == event_type_names::kMousewheel && ToLocalDOMWindow() && + event_listener && !options->hasPassive()) { JSBasedEventListener* v8_listener = JSBasedEventListener::Cast(event_listener); if (!v8_listener) @@ -301,7 +301,7 @@ void EventTarget::SetDefaultAddEventListenerOptions( v8::Isolate::GetCurrent(), v8::Local<v8::Function>::Cast(callback_object)->GetName())) == 0) { - options.setPassive(true); + options->setPassive(true); if (executing_window) { UseCounter::Count(executing_window->document(), WebFeature::kSmoothScrollJSInterventionActivated); @@ -321,23 +321,23 @@ void EventTarget::SetDefaultAddEventListenerOptions( if (Settings* settings = WindowSettings(ExecutingWindow())) { switch (settings->GetPassiveListenerDefault()) { case PassiveListenerDefault::kFalse: - if (!options.hasPassive()) - options.setPassive(false); + if (!options->hasPassive()) + options->setPassive(false); break; case PassiveListenerDefault::kTrue: - if (!options.hasPassive()) - options.setPassive(true); + if (!options->hasPassive()) + options->setPassive(true); break; case PassiveListenerDefault::kForceAllTrue: - options.setPassive(true); + options->setPassive(true); break; } } else { - if (!options.hasPassive()) - options.setPassive(false); + if (!options->hasPassive()) + options->setPassive(false); } - if (!options.passive() && !options.PassiveSpecified()) { + if (!options->passive() && !options->PassiveSpecified()) { String message_text = String::Format( "Added non-passive event listener to a scroll-blocking '%s' event. " "Consider marking event handler as 'passive' to make the page more " @@ -354,8 +354,9 @@ void EventTarget::SetDefaultAddEventListenerOptions( bool EventTarget::addEventListener(const AtomicString& event_type, EventListener* listener, bool use_capture) { - AddEventListenerOptionsResolved options; - options.setCapture(use_capture); + AddEventListenerOptionsResolved* options = + AddEventListenerOptionsResolved::Create(); + options->setCapture(use_capture); SetDefaultAddEventListenerOptions(event_type, listener, options); return AddEventListenerInternal(event_type, listener, options); } @@ -367,16 +368,24 @@ bool EventTarget::addEventListener( if (options_union.IsBoolean()) return addEventListener(event_type, listener, options_union.GetAsBoolean()); if (options_union.IsAddEventListenerOptions()) { - AddEventListenerOptionsResolved options = + AddEventListenerOptionsResolved* resolved_options = + AddEventListenerOptionsResolved::Create(); + AddEventListenerOptions* options = options_union.GetAsAddEventListenerOptions(); - return addEventListener(event_type, listener, options); + if (options->hasPassive()) + resolved_options->setPassive(options->passive()); + if (options->hasOnce()) + resolved_options->setOnce(options->once()); + if (options->hasCapture()) + resolved_options->setCapture(options->capture()); + return addEventListener(event_type, listener, resolved_options); } return addEventListener(event_type, listener); } bool EventTarget::addEventListener(const AtomicString& event_type, EventListener* listener, - AddEventListenerOptionsResolved& options) { + AddEventListenerOptionsResolved* options) { SetDefaultAddEventListenerOptions(event_type, listener, options); return AddEventListenerInternal(event_type, listener, options); } @@ -384,7 +393,7 @@ bool EventTarget::addEventListener(const AtomicString& event_type, bool EventTarget::AddEventListenerInternal( const AtomicString& event_type, EventListener* listener, - const AddEventListenerOptionsResolved& options) { + const AddEventListenerOptionsResolved* options) { if (!listener) return false; @@ -415,17 +424,17 @@ void EventTarget::AddedEventListener( RegisteredEventListener& registered_listener) { if (const LocalDOMWindow* executing_window = ExecutingWindow()) { if (const Document* document = executing_window->document()) { - if (event_type == EventTypeNames::auxclick) + if (event_type == event_type_names::kAuxclick) UseCounter::Count(*document, WebFeature::kAuxclickAddListenerCount); - else if (event_type == EventTypeNames::appinstalled) + else if (event_type == event_type_names::kAppinstalled) UseCounter::Count(*document, WebFeature::kAppInstalledEventAddListener); - else if (EventUtil::IsPointerEventType(event_type)) + else if (event_util::IsPointerEventType(event_type)) UseCounter::Count(*document, WebFeature::kPointerEventAddListenerCount); - else if (event_type == EventTypeNames::slotchange) + else if (event_type == event_type_names::kSlotchange) UseCounter::Count(*document, WebFeature::kSlotChangeEventAddListener); } } - if (EventUtil::IsDOMMutationEventType(event_type)) { + if (event_util::IsDOMMutationEventType(event_type)) { if (ExecutionContext* context = GetExecutionContext()) { String message_text = String::Format( "Added synchronous DOM mutation listener to a '%s' event. " @@ -441,8 +450,8 @@ void EventTarget::AddedEventListener( bool EventTarget::removeEventListener(const AtomicString& event_type, const EventListener* listener, bool use_capture) { - EventListenerOptions options; - options.setCapture(use_capture); + EventListenerOptions* options = EventListenerOptions::Create(); + options->setCapture(use_capture); return RemoveEventListenerInternal(event_type, listener, options); } @@ -455,7 +464,7 @@ bool EventTarget::removeEventListener( options_union.GetAsBoolean()); } if (options_union.IsEventListenerOptions()) { - EventListenerOptions options = options_union.GetAsEventListenerOptions(); + EventListenerOptions* options = options_union.GetAsEventListenerOptions(); return removeEventListener(event_type, listener, options); } return removeEventListener(event_type, listener); @@ -463,14 +472,14 @@ bool EventTarget::removeEventListener( bool EventTarget::removeEventListener(const AtomicString& event_type, const EventListener* listener, - EventListenerOptions& options) { + EventListenerOptions* options) { return RemoveEventListenerInternal(event_type, listener, options); } bool EventTarget::RemoveEventListenerInternal( const AtomicString& event_type, const EventListener* listener, - const EventListenerOptions& options) { + const EventListenerOptions* options) { if (!listener) return false; @@ -596,20 +605,20 @@ DispatchEventResult EventTarget::DispatchEventInternal(Event& event) { } static const AtomicString& LegacyType(const Event& event) { - if (event.type() == EventTypeNames::transitionend) - return EventTypeNames::webkitTransitionEnd; + if (event.type() == event_type_names::kTransitionend) + return event_type_names::kWebkitTransitionEnd; - if (event.type() == EventTypeNames::animationstart) - return EventTypeNames::webkitAnimationStart; + if (event.type() == event_type_names::kAnimationstart) + return event_type_names::kWebkitAnimationStart; - if (event.type() == EventTypeNames::animationend) - return EventTypeNames::webkitAnimationEnd; + if (event.type() == event_type_names::kAnimationend) + return event_type_names::kWebkitAnimationEnd; - if (event.type() == EventTypeNames::animationiteration) - return EventTypeNames::webkitAnimationIteration; + if (event.type() == event_type_names::kAnimationiteration) + return event_type_names::kWebkitAnimationIteration; - if (event.type() == EventTypeNames::wheel) - return EventTypeNames::mousewheel; + if (event.type() == event_type_names::kWheel) + return event_type_names::kMousewheel; return g_empty_atom; } @@ -621,27 +630,27 @@ void EventTarget::CountLegacyEvents( WebFeature unprefixed_feature; WebFeature prefixed_feature; WebFeature prefixed_and_unprefixed_feature; - if (legacy_type_name == EventTypeNames::webkitTransitionEnd) { + if (legacy_type_name == event_type_names::kWebkitTransitionEnd) { prefixed_feature = WebFeature::kPrefixedTransitionEndEvent; unprefixed_feature = WebFeature::kUnprefixedTransitionEndEvent; prefixed_and_unprefixed_feature = WebFeature::kPrefixedAndUnprefixedTransitionEndEvent; - } else if (legacy_type_name == EventTypeNames::webkitAnimationEnd) { + } else if (legacy_type_name == event_type_names::kWebkitAnimationEnd) { prefixed_feature = WebFeature::kPrefixedAnimationEndEvent; unprefixed_feature = WebFeature::kUnprefixedAnimationEndEvent; prefixed_and_unprefixed_feature = WebFeature::kPrefixedAndUnprefixedAnimationEndEvent; - } else if (legacy_type_name == EventTypeNames::webkitAnimationStart) { + } else if (legacy_type_name == event_type_names::kWebkitAnimationStart) { prefixed_feature = WebFeature::kPrefixedAnimationStartEvent; unprefixed_feature = WebFeature::kUnprefixedAnimationStartEvent; prefixed_and_unprefixed_feature = WebFeature::kPrefixedAndUnprefixedAnimationStartEvent; - } else if (legacy_type_name == EventTypeNames::webkitAnimationIteration) { + } else if (legacy_type_name == event_type_names::kWebkitAnimationIteration) { prefixed_feature = WebFeature::kPrefixedAnimationIterationEvent; unprefixed_feature = WebFeature::kUnprefixedAnimationIterationEvent; prefixed_and_unprefixed_feature = WebFeature::kPrefixedAndUnprefixedAnimationIterationEvent; - } else if (legacy_type_name == EventTypeNames::mousewheel) { + } else if (legacy_type_name == event_type_names::kMousewheel) { prefixed_feature = WebFeature::kMouseWheelEvent; unprefixed_feature = WebFeature::kWheelEvent; prefixed_and_unprefixed_feature = WebFeature::kMouseWheelAndWheelEvent; @@ -715,66 +724,66 @@ bool EventTarget::FireEventListeners(Event& event, // excludes new event listeners. if (const LocalDOMWindow* executing_window = ExecutingWindow()) { if (const Document* document = executing_window->document()) { - if (CheckTypeThenUseCount(event, EventTypeNames::beforeunload, + if (CheckTypeThenUseCount(event, event_type_names::kBeforeunload, WebFeature::kDocumentBeforeUnloadFired, document)) { if (executing_window != executing_window->top()) UseCounter::Count(*document, WebFeature::kSubFrameBeforeUnloadFired); - } else if (CheckTypeThenUseCount(event, EventTypeNames::unload, + } else if (CheckTypeThenUseCount(event, event_type_names::kUnload, WebFeature::kDocumentUnloadFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::pagehide, + } else if (CheckTypeThenUseCount(event, event_type_names::kPagehide, WebFeature::kDocumentPageHideFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::pageshow, + } else if (CheckTypeThenUseCount(event, event_type_names::kPageshow, WebFeature::kDocumentPageShowFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::DOMFocusIn, + } else if (CheckTypeThenUseCount(event, event_type_names::kDOMFocusIn, WebFeature::kDOMFocusInOutEvent, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::DOMFocusOut, + } else if (CheckTypeThenUseCount(event, event_type_names::kDOMFocusOut, WebFeature::kDOMFocusInOutEvent, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::focusin, + } else if (CheckTypeThenUseCount(event, event_type_names::kFocusin, WebFeature::kFocusInOutEvent, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::focusout, + } else if (CheckTypeThenUseCount(event, event_type_names::kFocusout, WebFeature::kFocusInOutEvent, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::textInput, + } else if (CheckTypeThenUseCount(event, event_type_names::kTextInput, WebFeature::kTextInputFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::touchstart, + } else if (CheckTypeThenUseCount(event, event_type_names::kTouchstart, WebFeature::kTouchStartFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::mousedown, + } else if (CheckTypeThenUseCount(event, event_type_names::kMousedown, WebFeature::kMouseDownFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::pointerdown, + } else if (CheckTypeThenUseCount(event, event_type_names::kPointerdown, WebFeature::kPointerDownFired, document)) { if (event.IsPointerEvent() && static_cast<PointerEvent&>(event).pointerType() == "touch") { UseCounter::Count(*document, WebFeature::kPointerDownFiredForTouch); } - } else if (CheckTypeThenUseCount(event, EventTypeNames::pointerenter, + } else if (CheckTypeThenUseCount(event, event_type_names::kPointerenter, WebFeature::kPointerEnterLeaveFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::pointerleave, + } else if (CheckTypeThenUseCount(event, event_type_names::kPointerleave, WebFeature::kPointerEnterLeaveFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::pointerover, + } else if (CheckTypeThenUseCount(event, event_type_names::kPointerover, WebFeature::kPointerOverOutFired, document)) { - } else if (CheckTypeThenUseCount(event, EventTypeNames::pointerout, + } else if (CheckTypeThenUseCount(event, event_type_names::kPointerout, WebFeature::kPointerOverOutFired, document)) { } else if (event.eventPhase() == Event::kCapturingPhase || event.eventPhase() == Event::kBubblingPhase) { if (CheckTypeThenUseCount( - event, EventTypeNames::DOMNodeRemoved, + event, event_type_names::kDOMNodeRemoved, WebFeature::kDOMNodeRemovedEventListenedAtNonTarget, document)) { } else if (CheckTypeThenUseCount( - event, EventTypeNames::DOMNodeRemovedFromDocument, + event, event_type_names::kDOMNodeRemovedFromDocument, WebFeature:: kDOMNodeRemovedFromDocumentEventListenedAtNonTarget, document)) { @@ -838,7 +847,7 @@ bool EventTarget::FireEventListeners(Event& event, // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling // event listeners, even though that violates some versions of the DOM spec. - listener->handleEvent(context, &event); + listener->Invoke(context, &event); fired_listener = true; // If we're about to report this event listener as blocking, make sure it diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target.h b/chromium/third_party/blink/renderer/core/dom/events/event_target.h index f9e4fc6c8f4..69d0db56ec5 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_target.h +++ b/chromium/third_party/blink/renderer/core/dom/events/event_target.h @@ -40,7 +40,6 @@ #include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h" #include "third_party/blink/renderer/core/dom/events/event_dispatch_result.h" #include "third_party/blink/renderer/core/dom/events/event_listener_map.h" -#include "third_party/blink/renderer/core/event_names.h" #include "third_party/blink/renderer/core/event_target_names.h" #include "third_party/blink/renderer/core/event_type_names.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -141,7 +140,7 @@ class CORE_EXPORT EventTarget : public ScriptWrappable { const AddEventListenerOptionsOrBoolean&); bool addEventListener(const AtomicString& event_type, EventListener*, - AddEventListenerOptionsResolved&); + AddEventListenerOptionsResolved*); bool removeEventListener(const AtomicString& event_type, const EventListener*, @@ -151,7 +150,7 @@ class CORE_EXPORT EventTarget : public ScriptWrappable { const EventListenerOptionsOrBoolean&); bool removeEventListener(const AtomicString& event_type, const EventListener*, - EventListenerOptions&); + EventListenerOptions*); virtual void RemoveAllEventListeners(); DispatchEventResult DispatchEvent(Event&); @@ -191,10 +190,10 @@ class CORE_EXPORT EventTarget : public ScriptWrappable { virtual bool AddEventListenerInternal(const AtomicString& event_type, EventListener*, - const AddEventListenerOptionsResolved&); + const AddEventListenerOptionsResolved*); virtual bool RemoveEventListenerInternal(const AtomicString& event_type, const EventListener*, - const EventListenerOptions&); + const EventListenerOptions*); // Called when an event listener has been successfully added. virtual void AddedEventListener(const AtomicString& event_type, @@ -216,7 +215,7 @@ class CORE_EXPORT EventTarget : public ScriptWrappable { LocalDOMWindow* ExecutingWindow(); void SetDefaultAddEventListenerOptions(const AtomicString& event_type, EventListener*, - AddEventListenerOptionsResolved&); + AddEventListenerOptionsResolved*); RegisteredEventListener* GetAttributeRegisteredEventListener( const AtomicString& event_type); @@ -252,62 +251,61 @@ class CORE_EXPORT EventTargetWithInlineData : public EventTarget { GC_PLUGIN_IGNORE("513199") EventTargetData event_target_data_; }; +// Macros to define an attribute event listener. +// |lower_name| - Lower-cased event type name. e.g. |focus| +// |symbol_name| - C++ symbol name in event_type_names namespace. e.g. |kFocus| // FIXME: These macros should be split into separate DEFINE and DECLARE // macros to avoid causing so many header includes. -#define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \ - EventListener* on##attribute() { \ - return GetAttributeEventListener(EventTypeNames::attribute); \ - } \ - void setOn##attribute(EventListener* listener) { \ - SetAttributeEventListener(EventTypeNames::attribute, listener); \ - } -#define DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(attribute) \ - static EventListener* on##attribute(EventTarget& eventTarget) { \ - return eventTarget.GetAttributeEventListener(EventTypeNames::attribute); \ - } \ - static void setOn##attribute(EventTarget& eventTarget, \ - EventListener* listener) { \ - eventTarget.SetAttributeEventListener(EventTypeNames::attribute, \ - listener); \ +#define DEFINE_ATTRIBUTE_EVENT_LISTENER(lower_name, symbol_name) \ + EventListener* on##lower_name() { \ + return GetAttributeEventListener(event_type_names::symbol_name); \ + } \ + void setOn##lower_name(EventListener* listener) { \ + SetAttributeEventListener(event_type_names::symbol_name, listener); \ } -#define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ - EventListener* on##attribute() { \ - return GetDocument().GetWindowAttributeEventListener( \ - EventTypeNames::attribute); \ - } \ - void setOn##attribute(EventListener* listener) { \ - GetDocument().SetWindowAttributeEventListener(EventTypeNames::attribute, \ - listener); \ +#define DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(lower_name, symbol_name) \ + static EventListener* on##lower_name(EventTarget& eventTarget) { \ + return eventTarget.GetAttributeEventListener( \ + event_type_names::symbol_name); \ + } \ + static void setOn##lower_name(EventTarget& eventTarget, \ + EventListener* listener) { \ + eventTarget.SetAttributeEventListener(event_type_names::symbol_name, \ + listener); \ } -#define DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ - static EventListener* on##attribute(EventTarget& eventTarget) { \ - if (Node* node = eventTarget.ToNode()) \ - return node->GetDocument().GetWindowAttributeEventListener( \ - EventTypeNames::attribute); \ - DCHECK(eventTarget.ToLocalDOMWindow()); \ - return eventTarget.GetAttributeEventListener(EventTypeNames::attribute); \ - } \ - static void setOn##attribute(EventTarget& eventTarget, \ - EventListener* listener) { \ - if (Node* node = eventTarget.ToNode()) \ - node->GetDocument().SetWindowAttributeEventListener( \ - EventTypeNames::attribute, listener); \ - else { \ - DCHECK(eventTarget.ToLocalDOMWindow()); \ - eventTarget.SetAttributeEventListener(EventTypeNames::attribute, \ - listener); \ - } \ +#define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(lower_name, symbol_name) \ + EventListener* on##lower_name() { \ + return GetDocument().GetWindowAttributeEventListener( \ + event_type_names::symbol_name); \ + } \ + void setOn##lower_name(EventListener* listener) { \ + GetDocument().SetWindowAttributeEventListener( \ + event_type_names::symbol_name, listener); \ } -#define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \ - EventListener* on##attribute() { \ - return GetAttributeEventListener(EventTypeNames::eventName); \ - } \ - void setOn##attribute(EventListener* listener) { \ - SetAttributeEventListener(EventTypeNames::eventName, listener); \ +#define DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(lower_name, symbol_name) \ + static EventListener* on##lower_name(EventTarget& eventTarget) { \ + if (Node* node = eventTarget.ToNode()) { \ + return node->GetDocument().GetWindowAttributeEventListener( \ + event_type_names::symbol_name); \ + } \ + DCHECK(eventTarget.ToLocalDOMWindow()); \ + return eventTarget.GetAttributeEventListener( \ + event_type_names::symbol_name); \ + } \ + static void setOn##lower_name(EventTarget& eventTarget, \ + EventListener* listener) { \ + if (Node* node = eventTarget.ToNode()) { \ + node->GetDocument().SetWindowAttributeEventListener( \ + event_type_names::symbol_name, listener); \ + } else { \ + DCHECK(eventTarget.ToLocalDOMWindow()); \ + eventTarget.SetAttributeEventListener(event_type_names::symbol_name, \ + listener); \ + } \ } DISABLE_CFI_PERF diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc index 08bf850212e..91a841a8799 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc @@ -7,11 +7,11 @@ namespace blink { EventTargetImpl* EventTargetImpl::Create(ScriptState* script_state) { - return new EventTargetImpl(script_state); + return MakeGarbageCollected<EventTargetImpl>(script_state); } const AtomicString& EventTargetImpl::InterfaceName() const { - return EventTargetNames::EventTargetImpl; + return event_target_names::kEventTargetImpl; } ExecutionContext* EventTargetImpl::GetExecutionContext() const { diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h index 943d6fdc62a..77fe99923fe 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h +++ b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h @@ -27,14 +27,12 @@ class CORE_EXPORT EventTargetImpl final : public EventTargetWithInlineData, public: static EventTargetImpl* Create(ScriptState*); + EventTargetImpl(ScriptState*); ~EventTargetImpl() override = default; const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; void Trace(blink::Visitor*) override; - - private: - EventTargetImpl(ScriptState*); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target_test.cc b/chromium/third_party/blink/renderer/core/dom/events/event_target_test.cc index 9eb3ca70d0c..c1d92286196 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/event_target_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/event_target_test.cc @@ -24,7 +24,8 @@ TEST_F(EventTargetTest, PreventDefaultNotCalled) { HistogramTester histogram_tester; GetDocument().GetFrame()->GetScriptController().ExecuteScriptInMainWorld( "window.addEventListener('touchstart', function(e) {}, {});" - "window.dispatchEvent(new TouchEvent('touchstart', {cancelable: " + "window.dispatchEvent(new TouchEvent('touchstart', " + "{cancelable: " "false}));"); histogram_tester.ExpectTotalCount("Event.PassiveForcedEventDispatchCancelled", @@ -39,7 +40,8 @@ TEST_F(EventTargetTest, PreventDefaultCalled) { GetDocument().GetFrame()->GetScriptController().ExecuteScriptInMainWorld( "window.addEventListener('touchstart', function(e) " "{e.preventDefault();}, {});" - "window.dispatchEvent(new TouchEvent('touchstart', {cancelable: " + "window.dispatchEvent(new TouchEvent('touchstart', " + "{cancelable: " "false}));"); histogram_tester.ExpectTotalCount("Event.PassiveForcedEventDispatchCancelled", diff --git a/chromium/third_party/blink/renderer/core/dom/events/listener_leak_test.cc b/chromium/third_party/blink/renderer/core/dom/events/listener_leak_test.cc index 6b178219e10..bf97de00785 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/listener_leak_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/listener_leak_test.cc @@ -27,12 +27,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" #include "third_party/blink/public/web/web_view.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" +#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" #include "v8/include/v8-profiler.h" @@ -40,6 +41,8 @@ namespace blink { +namespace { + const v8::HeapGraphNode* GetProperty(v8::Isolate* isolate, const v8::HeapGraphNode* node, v8::HeapGraphEdge::Type type, @@ -55,8 +58,7 @@ const v8::HeapGraphNode* GetProperty(v8::Isolate* isolate, return nullptr; } -int GetNumObjects(const char* constructor) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); +int GetNumObjects(v8::Isolate* isolate, const char* constructor) { v8::HandleScope scope(isolate); v8::HeapProfiler* profiler = isolate->GetHeapProfiler(); const v8::HeapSnapshot* snapshot = profiler->TakeHeapSnapshot(); @@ -84,15 +86,23 @@ int GetNumObjects(const char* constructor) { return count; } +} // namespace + class ListenerLeakTest : public testing::Test { public: - void RunTest(const std::string& filename) { + void RunTestAndGC(const std::string& filename) { std::string base_url("http://www.example.com/"); std::string file_name(filename); - URLTestHelpers::RegisterMockedURLLoadFromBase( + url_test_helpers::RegisterMockedURLLoadFromBase( WebString::FromUTF8(base_url), blink::test::CoreTestDataPath(), WebString::FromUTF8(file_name)); web_view_helper.InitializeAndLoad(base_url + file_name); + V8GCController::CollectAllGarbageForTesting( + isolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty); + } + + v8::Isolate* isolate() const { + return ToIsolate(web_view_helper.LocalMainFrame()->GetFrame()); } void TearDown() override { @@ -102,21 +112,21 @@ class ListenerLeakTest : public testing::Test { } protected: - FrameTestHelpers::WebViewHelper web_view_helper; + frame_test_helpers::WebViewHelper web_view_helper; }; // This test tries to create a reference cycle between node and its listener. // See http://crbug/17400. TEST_F(ListenerLeakTest, ReferenceCycle) { - RunTest("listener/listener_leak1.html"); - ASSERT_EQ(0, GetNumObjects("EventListenerLeakTestObject1")); + RunTestAndGC("listener/listener_leak1.html"); + ASSERT_EQ(0, GetNumObjects(isolate(), "EventListenerLeakTestObject1")); } // This test sets node onclick many times to expose a possible memory // leak where all listeners get referenced by the node. TEST_F(ListenerLeakTest, HiddenReferences) { - RunTest("listener/listener_leak2.html"); - ASSERT_EQ(1, GetNumObjects("EventListenerLeakTestObject2")); + RunTestAndGC("listener/listener_leak2.html"); + ASSERT_EQ(1, GetNumObjects(isolate(), "EventListenerLeakTestObject2")); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc index 48d5de7df4b..16d26106b99 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc @@ -35,10 +35,8 @@ namespace blink { -NodeEventContext::NodeEventContext(Node* node, EventTarget* current_target) - : node_(node), current_target_(current_target) { - DCHECK(node_); -} +NodeEventContext::NodeEventContext(Node& node, EventTarget& current_target) + : node_(node), current_target_(current_target) {} void NodeEventContext::Trace(blink::Visitor* visitor) { visitor->Trace(node_); diff --git a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h index 4bbb99b7e7f..21c2ca244f5 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h +++ b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h @@ -42,10 +42,10 @@ class CORE_EXPORT NodeEventContext { public: // FIXME: Use ContainerNode instead of Node. - NodeEventContext(Node*, EventTarget* current_target); + NodeEventContext(Node&, EventTarget& current_target); void Trace(blink::Visitor*); - Node* GetNode() const { return node_.Get(); } + Node& GetNode() const { return *node_; } void SetTreeScopeEventContext( TreeScopeEventContext* tree_scope_event_context) { diff --git a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc index 91efc198321..93685d95475 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc @@ -41,15 +41,15 @@ RegisteredEventListener::RegisteredEventListener() RegisteredEventListener::RegisteredEventListener( EventListener* listener, - const AddEventListenerOptionsResolved& options) + const AddEventListenerOptionsResolved* options) : callback_(listener), - use_capture_(options.capture()), - passive_(options.passive()), - once_(options.once()), + use_capture_(options->capture()), + passive_(options->passive()), + once_(options->once()), blocked_event_warning_emitted_(false), passive_forced_for_document_target_( - options.PassiveForcedForDocumentTarget()), - passive_specified_(options.PassiveSpecified()) {} + options->PassiveForcedForDocumentTarget()), + passive_specified_(options->PassiveSpecified()) {} RegisteredEventListener& RegisteredEventListener::operator=( const RegisteredEventListener& that) = default; @@ -58,13 +58,15 @@ void RegisteredEventListener::Trace(Visitor* visitor) { visitor->Trace(callback_); } -AddEventListenerOptionsResolved RegisteredEventListener::Options() const { - AddEventListenerOptionsResolved result; - result.setCapture(use_capture_); - result.setPassive(passive_); - result.SetPassiveForcedForDocumentTarget(passive_forced_for_document_target_); - result.setOnce(once_); - result.SetPassiveSpecified(passive_specified_); +AddEventListenerOptionsResolved* RegisteredEventListener::Options() const { + AddEventListenerOptionsResolved* result = + AddEventListenerOptionsResolved::Create(); + result->setCapture(use_capture_); + result->setPassive(passive_); + result->SetPassiveForcedForDocumentTarget( + passive_forced_for_document_target_); + result->setOnce(once_); + result->SetPassiveSpecified(passive_specified_); return result; } @@ -74,12 +76,12 @@ void RegisteredEventListener::SetCallback(EventListener* listener) { bool RegisteredEventListener::Matches( const EventListener* listener, - const EventListenerOptions& options) const { + const EventListenerOptions* options) const { // Equality is soley based on the listener and useCapture flags. DCHECK(callback_); DCHECK(listener); return *callback_ == *listener && - static_cast<bool>(use_capture_) == options.capture(); + static_cast<bool>(use_capture_) == options->capture(); } bool RegisteredEventListener::ShouldFire(const Event& event) const { diff --git a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h index ac6bb8ca70c..248e143f347 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h +++ b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h @@ -44,12 +44,12 @@ class RegisteredEventListener final { public: RegisteredEventListener(); RegisteredEventListener(EventListener* listener, - const AddEventListenerOptionsResolved& options); + const AddEventListenerOptionsResolved* options); RegisteredEventListener& operator=(const RegisteredEventListener& that); void Trace(Visitor* visitor); - AddEventListenerOptionsResolved Options() const; + AddEventListenerOptionsResolved* Options() const; const EventListener* Callback() const { return callback_; } @@ -78,7 +78,7 @@ class RegisteredEventListener final { } bool Matches(const EventListener* listener, - const EventListenerOptions& options) const; + const EventListenerOptions* options) const; bool ShouldFire(const Event&) const; diff --git a/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc b/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc index c45ab23c18c..3409af0dc7e 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc @@ -42,7 +42,8 @@ namespace blink { ScopedEventQueue* ScopedEventQueue::instance_ = nullptr; ScopedEventQueue::ScopedEventQueue() - : queued_events_(new HeapVector<Member<Event>>()), scoping_level_(0) {} + : queued_events_(MakeGarbageCollected<HeapVector<Member<Event>>>()), + scoping_level_(0) {} ScopedEventQueue::~ScopedEventQueue() { DCHECK(!scoping_level_); diff --git a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc index 866c2a6d20d..2133bac406e 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc @@ -67,7 +67,7 @@ HeapVector<Member<EventTarget>>& TreeScopeEventContext::EnsureEventPath( if (event_path_) return *event_path_; - event_path_ = new HeapVector<Member<EventTarget>>(); + event_path_ = MakeGarbageCollected<HeapVector<Member<EventTarget>>>(); LocalDOMWindow* window = path.GetWindowEventContext().Window(); event_path_->ReserveCapacity(path.size() + (window ? 1 : 0)); @@ -80,14 +80,14 @@ HeapVector<Member<EventTarget>>& TreeScopeEventContext::EnsureEventPath( return *event_path_; } -TouchEventContext* TreeScopeEventContext::EnsureTouchEventContext() { +TouchEventContext& TreeScopeEventContext::EnsureTouchEventContext() { if (!touch_event_context_) touch_event_context_ = TouchEventContext::Create(); - return touch_event_context_.Get(); + return *touch_event_context_; } TreeScopeEventContext* TreeScopeEventContext::Create(TreeScope& tree_scope) { - return new TreeScopeEventContext(tree_scope); + return MakeGarbageCollected<TreeScopeEventContext>(tree_scope); } TreeScopeEventContext::TreeScopeEventContext(TreeScope& tree_scope) diff --git a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h index d167c660640..eac6b4a0d04 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h +++ b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h @@ -48,21 +48,23 @@ class CORE_EXPORT TreeScopeEventContext final : public GarbageCollected<TreeScopeEventContext> { public: static TreeScopeEventContext* Create(TreeScope&); + + TreeScopeEventContext(TreeScope&); void Trace(blink::Visitor*); TreeScope& GetTreeScope() const { return *tree_scope_; } ContainerNode& RootNode() const { return tree_scope_->RootNode(); } EventTarget* Target() const { return target_.Get(); } - void SetTarget(EventTarget*); + void SetTarget(EventTarget&); EventTarget* RelatedTarget() const { return related_target_.Get(); } - void SetRelatedTarget(EventTarget*); + void SetRelatedTarget(EventTarget&); TouchEventContext* GetTouchEventContext() const { return touch_event_context_.Get(); } - TouchEventContext* EnsureTouchEventContext(); + TouchEventContext& EnsureTouchEventContext(); HeapVector<Member<EventTarget>>& EnsureEventPath(EventPath&); @@ -84,8 +86,6 @@ class CORE_EXPORT TreeScopeEventContext final } private: - TreeScopeEventContext(TreeScope&); - void CheckReachableNode(EventTarget&); bool IsUnclosedTreeOf(const TreeScopeEventContext& other); @@ -118,16 +118,14 @@ inline void TreeScopeEventContext::CheckReachableNode(EventTarget& target) { inline void TreeScopeEventContext::CheckReachableNode(EventTarget&) {} #endif -inline void TreeScopeEventContext::SetTarget(EventTarget* target) { - DCHECK(target); - CheckReachableNode(*target); +inline void TreeScopeEventContext::SetTarget(EventTarget& target) { + CheckReachableNode(target); target_ = target; } inline void TreeScopeEventContext::SetRelatedTarget( - EventTarget* related_target) { - DCHECK(related_target); - CheckReachableNode(*related_target); + EventTarget& related_target) { + CheckReachableNode(related_target); related_target_ = related_target; } diff --git a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc index 3e00f04ccd8..3e3de47918c 100644 --- a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc +++ b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc @@ -39,7 +39,7 @@ WindowEventContext::WindowEventContext( const NodeEventContext& top_node_event_context) { // We don't dispatch load events to the window. This quirk was originally // added because Mozilla doesn't propagate load events to the window object. - if (event.type() == EventTypeNames::load) + if (event.type() == event_type_names::kLoad) return; auto* document = DynamicTo<Document>(top_node_event_context.GetNode()); if (!document) diff --git a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc index 4693d518554..a689ec3a7aa 100644 --- a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc +++ b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc @@ -44,16 +44,16 @@ namespace blink { // (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), // that precedes or follows the first letter should be included" static inline bool IsPunctuationForFirstLetter(UChar32 c) { - WTF::Unicode::CharCategory char_category = WTF::Unicode::Category(c); - return char_category == WTF::Unicode::kPunctuation_Open || - char_category == WTF::Unicode::kPunctuation_Close || - char_category == WTF::Unicode::kPunctuation_InitialQuote || - char_category == WTF::Unicode::kPunctuation_FinalQuote || - char_category == WTF::Unicode::kPunctuation_Other; + WTF::unicode::CharCategory char_category = WTF::unicode::Category(c); + return char_category == WTF::unicode::kPunctuation_Open || + char_category == WTF::unicode::kPunctuation_Close || + char_category == WTF::unicode::kPunctuation_InitialQuote || + char_category == WTF::unicode::kPunctuation_FinalQuote || + char_category == WTF::unicode::kPunctuation_Other; } static inline bool IsSpaceForFirstLetter(UChar c) { - return IsSpaceOrNewline(c) || c == WTF::Unicode::kNoBreakSpaceCharacter; + return IsSpaceOrNewline(c) || c == WTF::unicode::kNoBreakSpaceCharacter; } unsigned FirstLetterPseudoElement::FirstLetterLength(const String& text) { @@ -231,7 +231,7 @@ void FirstLetterPseudoElement::UpdateTextFragments() { // needs to re-create the line boxes. The remaining text layoutObject // will be marked by the LayoutText::setText. child_fragment->SetNeedsLayoutAndPrefWidthsRecalc( - LayoutInvalidationReason::kTextChanged); + layout_invalidation_reason::kTextChanged); break; } } @@ -252,8 +252,9 @@ void FirstLetterPseudoElement::ClearRemainingTextLayoutObject() { // first letter, we need to UpdateFirstLetter to render the new first letter // or remove the ::first-letter pseudo if there is no text left. Do that as // part of a style recalc for this ::first-letter. - SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kPseudoClass)); + SetNeedsStyleRecalc( + kLocalStyleChange, + StyleChangeReasonForTracing::Create(style_change_reason::kPseudoClass)); } void FirstLetterPseudoElement::AttachLayoutTree(AttachContext& context) { @@ -310,12 +311,13 @@ void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects(LayoutText* fi LayoutTextFragment* remaining_text; if (first_letter_text->GetNode()) { - remaining_text = - new LayoutTextFragment(first_letter_text->GetNode(), old_text.Impl(), - length, remaining_length); + remaining_text = LayoutTextFragment::Create( + *first_letter_text->Style(), first_letter_text->GetNode(), + old_text.Impl(), length, remaining_length); } else { remaining_text = LayoutTextFragment::CreateAnonymous( - *this, old_text.Impl(), length, remaining_length); + *first_letter_text->Style(), *this, old_text.Impl(), length, + remaining_length); } remaining_text->SetFirstLetterPseudoElement(this); @@ -331,40 +333,16 @@ void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects(LayoutText* fi GetLayoutObject()->Parent()->AddChild(remaining_text, next_sibling); // Construct text fragment for the first letter. - LayoutTextFragment* letter = - LayoutTextFragment::CreateAnonymous(*this, old_text.Impl(), 0, length); + ComputedStyle* const letter_style = MutableComputedStyle(); + LayoutTextFragment* letter = LayoutTextFragment::CreateAnonymous( + *letter_style, *this, old_text.Impl(), 0, length); letter->SetFirstLetterPseudoElement(this); - letter->SetStyle(MutableComputedStyle()); + letter->SetStyle(letter_style); GetLayoutObject()->AddChild(letter); first_letter_text->Destroy(); } -void FirstLetterPseudoElement::DidRecalcStyle(StyleRecalcChange) { - LayoutObject* layout_object = GetLayoutObject(); - if (!layout_object) - return; - - // The layout objects inside pseudo elements are anonymous so they don't get - // notified of RecalcStyle and must have the style propagated downward - // manually similar to LayoutObject::PropagateStyleToAnonymousChildren. - for (LayoutObject* child = layout_object->NextInPreOrder(layout_object); - child; child = child->NextInPreOrder(layout_object)) { - // We need to re-calculate the correct style for the first letter element - // and then apply that to the container and the text fragment inside. - if (child->Style()->StyleType() == kPseudoIdFirstLetter) { - child->SetPseudoStyle(layout_object->MutableStyle()); - continue; - } - - // We only manage the style for the generated content items. - if (!child->IsText() && !child->IsQuote() && !child->IsImage()) - continue; - - child->SetPseudoStyle(layout_object->MutableStyle()); - } -} - Node* FirstLetterPseudoElement::InnerNodeForHitTesting() const { // When we hit a first letter during hit testing, hover state and events // should be triggered on the parent of the real text node where the first diff --git a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h index 192dc999bfc..1c5235c9e49 100644 --- a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h +++ b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h @@ -39,9 +39,10 @@ class LayoutTextFragment; class CORE_EXPORT FirstLetterPseudoElement final : public PseudoElement { public: static FirstLetterPseudoElement* Create(Element* parent) { - return new FirstLetterPseudoElement(parent); + return MakeGarbageCollected<FirstLetterPseudoElement>(parent); } + explicit FirstLetterPseudoElement(Element*); ~FirstLetterPseudoElement() override; static LayoutText* FirstLetterTextLayoutObject(const Element&); @@ -59,10 +60,7 @@ class CORE_EXPORT FirstLetterPseudoElement final : public PseudoElement { Node* InnerNodeForHitTesting() const override; private: - explicit FirstLetterPseudoElement(Element*); - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; - void DidRecalcStyle(StyleRecalcChange) override; void AttachFirstLetterTextLayoutObjects(LayoutText* first_letter_text); diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc new file mode 100644 index 00000000000..163ec4338a1 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc @@ -0,0 +1,17 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/dom/flat_tree_node_data.h" + +#include "third_party/blink/renderer/core/html/html_slot_element.h" + +namespace blink { + +void FlatTreeNodeData::Trace(Visitor* visitor) { + visitor->Trace(assigned_slot_); + visitor->Trace(previous_in_assigned_nodes_); + visitor->Trace(next_in_assigned_nodes_); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h new file mode 100644 index 00000000000..96d98836eb3 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h @@ -0,0 +1,51 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_FLAT_TREE_NODE_DATA_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_FLAT_TREE_NODE_DATA_H_ + +#include "base/macros.h" +#include "third_party/blink/renderer/platform/heap/handle.h" + +namespace blink { + +class Node; +class HTMLSlotElement; + +class FlatTreeNodeData final : public GarbageCollected<FlatTreeNodeData> { + public: + FlatTreeNodeData() {} + void Clear() { + assigned_slot_ = nullptr; + previous_in_assigned_nodes_ = nullptr; + next_in_assigned_nodes_ = nullptr; + } + void Trace(Visitor*); + + private: + void SetAssignedSlot(HTMLSlotElement* assigned_slot) { + assigned_slot_ = assigned_slot; + } + + void SetPreviousInAssignedNodes(Node* previous) { + previous_in_assigned_nodes_ = previous; + } + void SetNextInAssignedNodes(Node* next) { next_in_assigned_nodes_ = next; } + + HTMLSlotElement* AssignedSlot() { return assigned_slot_; } + Node* PreviousInAssignedNodes() { return previous_in_assigned_nodes_; } + Node* NextInAssignedNodes() { return next_in_assigned_nodes_; } + + friend class FlatTreeTraversal; + friend class HTMLSlotElement; + + WeakMember<HTMLSlotElement> assigned_slot_; + WeakMember<Node> previous_in_assigned_nodes_; + WeakMember<Node> next_in_assigned_nodes_; + DISALLOW_COPY_AND_ASSIGN(FlatTreeNodeData); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_FLAT_TREE_NODE_DATA_H_ diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc index f98a8b5775a..92e6ec38f32 100644 --- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc +++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc @@ -27,6 +27,8 @@ #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/flat_tree_node_data.h" +#include "third_party/blink/renderer/core/dom/slot_assignment.h" #include "third_party/blink/renderer/core/html/html_shadow_element.h" #include "third_party/blink/renderer/core/html/html_slot_element.h" @@ -114,12 +116,28 @@ Node* FlatTreeTraversal::TraverseSiblings(const Node& node, Node* FlatTreeTraversal::TraverseSiblingsForV1HostChild( const Node& node, TraversalDirection direction) { - HTMLSlotElement* slot = node.AssignedSlot(); - if (!slot) + ShadowRoot* shadow_root = node.ParentElementShadowRoot(); + DCHECK(shadow_root); + if (!shadow_root->HasSlotAssignment()) { + // The shadow root doesn't have any slot. return nullptr; - return direction == kTraversalDirectionForward - ? slot->AssignedNodeNextTo(node) - : slot->AssignedNodePreviousTo(node); + } + shadow_root->GetSlotAssignment().RecalcAssignment(); + + FlatTreeNodeData* flat_tree_node_data = node.GetFlatTreeNodeData(); + if (!flat_tree_node_data) { + // This node has never been assigned to any slot. + return nullptr; + } + if (flat_tree_node_data->AssignedSlot()) { + return direction == kTraversalDirectionForward + ? flat_tree_node_data->NextInAssignedNodes() + : flat_tree_node_data->PreviousInAssignedNodes(); + } + // This node is not assigned to any slot. + DCHECK(!flat_tree_node_data->NextInAssignedNodes()); + DCHECK(!flat_tree_node_data->PreviousInAssignedNodes()); + return nullptr; } Node* FlatTreeTraversal::TraverseSiblingsForV0Distribution( diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h index f12b457cdcc..da283a34310 100644 --- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h +++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h @@ -60,6 +60,9 @@ class CORE_EXPORT FlatTreeTraversal { static Node* Next(const Node&); static Node* Next(const Node&, const Node* stay_within); static Node* Previous(const Node&); + // Returns the previous of |node| in preorder. When |stay_within| is given, + // returns nullptr if the previous is not a descendant of |stay_within|. + static Node* Previous(const Node& node, const Node* stay_within); static Node* FirstChild(const Node&); static Node* LastChild(const Node&); @@ -282,6 +285,17 @@ inline Node* FlatTreeTraversal::TraversePrevious(const Node& node) { return TraverseParent(node); } +inline Node* FlatTreeTraversal::Previous(const Node& node, + const Node* stay_within) { + if (!stay_within) + return Previous(node); + DCHECK(IsDescendantOf(node, *stay_within)); + Node* previous = Previous(node); + if (previous == stay_within) + return nullptr; + return previous; +} + inline Node* FlatTreeTraversal::FirstChild(const Node& node) { AssertPrecondition(node); Node* result = TraverseChild(node, kTraversalDirectionForward); diff --git a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc index d5f54e1149c..02b71b6619e 100644 --- a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc +++ b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc @@ -22,7 +22,7 @@ FrameRequestCallbackCollection::RegisterCallback(FrameCallback* callback) { TRACE_EVENT_INSTANT1("devtools.timeline", "RequestAnimationFrame", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorAnimationFrameEvent::Data(context_, id)); + inspector_animation_frame_event::Data(context_, id)); probe::AsyncTaskScheduledBreakable(context_, "requestAnimationFrame", callback); return id; @@ -36,7 +36,7 @@ void FrameRequestCallbackCollection::CancelCallback(CallbackId id) { callbacks_.EraseAt(i); TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorAnimationFrameEvent::Data(context_, id)); + inspector_animation_frame_event::Data(context_, id)); return; } } @@ -46,7 +46,7 @@ void FrameRequestCallbackCollection::CancelCallback(CallbackId id) { callback); TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorAnimationFrameEvent::Data(context_, id)); + inspector_animation_frame_event::Data(context_, id)); callback->SetIsCancelled(true); // will be removed at the end of executeCallbacks() return; @@ -74,7 +74,7 @@ void FrameRequestCallbackCollection::ExecuteCallbacks( if (!callback->IsCancelled()) { TRACE_EVENT1( "devtools.timeline", "FireAnimationFrame", "data", - InspectorAnimationFrameEvent::Data(context_, callback->Id())); + inspector_animation_frame_event::Data(context_, callback->Id())); probe::AsyncTask async_task(context_, callback); probe::UserCallback probe(context_, "requestAnimationFrame", AtomicString(), true); diff --git a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h index 0aca9b30f38..3d69e24d821 100644 --- a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h +++ b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h @@ -59,17 +59,19 @@ class GC_PLUGIN_IGNORE("crbug.com/841830") class CORE_EXPORT V8FrameCallback : public FrameCallback { public: static V8FrameCallback* Create(V8FrameRequestCallback* callback) { - return new V8FrameCallback(callback); + return MakeGarbageCollected<V8FrameCallback>(callback); } void Trace(blink::Visitor*) override; const char* NameInHeapSnapshot() const override { return "V8FrameCallback"; } + + explicit V8FrameCallback(V8FrameRequestCallback*); ~V8FrameCallback() override = default; + void Invoke(double) override; private: - explicit V8FrameCallback(V8FrameRequestCallback*); TraceWrapperMember<V8FrameRequestCallback> callback_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h b/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h index e01c6ca6dbd..36f277a1940 100644 --- a/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h +++ b/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h @@ -39,85 +39,86 @@ class GlobalEventHandlers { STATIC_ONLY(GlobalEventHandlers); public: - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(activateinvisible); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(auxclick); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplay); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplaythrough); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(change); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(click); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(close); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(contextmenu); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cuechange); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dblclick); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drag); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragend); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragenter); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragleave); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragover); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragstart); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drop); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(durationchange); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(emptied); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ended); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(focus); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(formdata); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(gotpointercapture); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(input); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(invalid); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keydown); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keypress); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keyup); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(load); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadeddata); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadedmetadata); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadstart); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(lostpointercapture); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousedown); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseenter); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseleave); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousemove); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseout); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseover); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseup); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousewheel); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pause); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(play); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(playing); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointercancel); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerdown); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerenter); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerleave); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointermove); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerout); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerover); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerrawmove); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerup); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(resize); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeked); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeking); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(select); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectionchange); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectstart); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(stalled); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(submit); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(suspend); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(timeupdate); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(toggle); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchcancel); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchend); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchmove); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchstart); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting); - DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(wheel); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort, kAbort); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(activateinvisible, kActivateinvisible); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(auxclick, kAuxclick); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur, kBlur); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel, kCancel); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplay, kCanplay); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplaythrough, kCanplaythrough); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(change, kChange); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(click, kClick); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(close, kClose); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(contextmenu, kContextmenu); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cuechange, kCuechange); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dblclick, kDblclick); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drag, kDrag); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragend, kDragend); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragenter, kDragenter); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragleave, kDragleave); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragover, kDragover); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragstart, kDragstart); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drop, kDrop); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(durationchange, kDurationchange); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(emptied, kEmptied); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ended, kEnded); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error, kError); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(focus, kFocus); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(formdata, kFormdata); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(gotpointercapture, kGotpointercapture); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(input, kInput); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(invalid, kInvalid); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keydown, kKeydown); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keypress, kKeypress); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keyup, kKeyup); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(load, kLoad); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadeddata, kLoadeddata); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadedmetadata, kLoadedmetadata); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(lostpointercapture, + kLostpointercapture); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousedown, kMousedown); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseenter, kMouseenter); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseleave, kMouseleave); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousemove, kMousemove); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseout, kMouseout); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseover, kMouseover); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseup, kMouseup); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousewheel, kMousewheel); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pause, kPause); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(play, kPlay); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(playing, kPlaying); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointercancel, kPointercancel); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerdown, kPointerdown); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerenter, kPointerenter); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerleave, kPointerleave); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointermove, kPointermove); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerout, kPointerout); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerover, kPointerover); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerrawmove, kPointerrawmove); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerup, kPointerup); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress, kProgress); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange, kRatechange); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset, kReset); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(resize, kResize); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeked, kSeeked); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeking, kSeeking); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(select, kSelect); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectionchange, kSelectionchange); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectstart, kSelectstart); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(stalled, kStalled); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(submit, kSubmit); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(suspend, kSuspend); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(timeupdate, kTimeupdate); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(toggle, kToggle); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchcancel, kTouchcancel); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchend, kTouchend); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchmove, kTouchmove); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchstart, kTouchstart); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange, kVolumechange); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting, kWaiting); + DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(wheel, kWheel); }; } // namespace diff --git a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc index 044076bfbcb..7c73ad21e8a 100644 --- a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc +++ b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc @@ -30,7 +30,7 @@ namespace blink { IdTargetObserverRegistry* IdTargetObserverRegistry::Create() { - return new IdTargetObserverRegistry(); + return MakeGarbageCollected<IdTargetObserverRegistry>(); } void IdTargetObserverRegistry::Trace(blink::Visitor* visitor) { @@ -45,7 +45,7 @@ void IdTargetObserverRegistry::AddObserver(const AtomicString& id, IdToObserverSetMap::AddResult result = registry_.insert(id.Impl(), nullptr); if (result.is_new_entry) - result.stored_value->value = new ObserverSet(); + result.stored_value->value = MakeGarbageCollected<ObserverSet>(); result.stored_value->value->insert(observer); } diff --git a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h index 5c94327cc2e..fd7d78960a3 100644 --- a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h +++ b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h @@ -43,12 +43,14 @@ class IdTargetObserverRegistry final public: static IdTargetObserverRegistry* Create(); + + IdTargetObserverRegistry() : notifying_observers_in_set_(nullptr) {} + void Trace(blink::Visitor*); void NotifyObservers(const AtomicString& id); bool HasObservers(const AtomicString& id) const; private: - IdTargetObserverRegistry() : notifying_observers_in_set_(nullptr) {} void AddObserver(const AtomicString& id, IdTargetObserver*); void RemoveObserver(const AtomicString& id, IdTargetObserver*); void NotifyObserversInternal(const AtomicString& id); diff --git a/chromium/third_party/blink/renderer/core/dom/idle_deadline.cc b/chromium/third_party/blink/renderer/core/dom/idle_deadline.cc index a30fe7c2767..f59ec80c193 100644 --- a/chromium/third_party/blink/renderer/core/dom/idle_deadline.cc +++ b/chromium/third_party/blink/renderer/core/dom/idle_deadline.cc @@ -16,10 +16,8 @@ IdleDeadline::IdleDeadline(TimeTicks deadline, CallbackType callback_type) double IdleDeadline::timeRemaining() const { TimeDelta time_remaining = deadline_ - CurrentTimeTicks(); - if (time_remaining < TimeDelta() || Platform::Current() - ->CurrentThread() - ->Scheduler() - ->ShouldYieldForHighPriorityWork()) { + if (time_remaining < TimeDelta() || + ThreadScheduler::Current()->ShouldYieldForHighPriorityWork()) { return 0; } diff --git a/chromium/third_party/blink/renderer/core/dom/idle_deadline.h b/chromium/third_party/blink/renderer/core/dom/idle_deadline.h index 59c37cd7593..471935fd748 100644 --- a/chromium/third_party/blink/renderer/core/dom/idle_deadline.h +++ b/chromium/third_party/blink/renderer/core/dom/idle_deadline.h @@ -19,9 +19,11 @@ class CORE_EXPORT IdleDeadline : public ScriptWrappable { enum class CallbackType { kCalledWhenIdle, kCalledByTimeout }; static IdleDeadline* Create(TimeTicks deadline, CallbackType callback_type) { - return new IdleDeadline(deadline, callback_type); + return MakeGarbageCollected<IdleDeadline>(deadline, callback_type); } + IdleDeadline(TimeTicks deadline, CallbackType); + double timeRemaining() const; bool didTimeout() const { @@ -29,8 +31,6 @@ class CORE_EXPORT IdleDeadline : public ScriptWrappable { } private: - IdleDeadline(TimeTicks deadline, CallbackType); - TimeTicks deadline_; CallbackType callback_type_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc b/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc index aebde6e91d8..5c04f0f4e0f 100644 --- a/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc @@ -8,7 +8,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" -#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h" +#include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h" #include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -48,11 +48,9 @@ class MockIdleDeadlineScheduler final : public ThreadScheduler { return base::TimeTicks(); } - void AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void AddTaskObserver(Thread::TaskObserver* task_observer) override {} - void RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void RemoveTaskObserver(Thread::TaskObserver* task_observer) override {} void AddRAILModeObserver(scheduler::WebRAILModeObserver*) override {} @@ -74,7 +72,7 @@ class IdleDeadlineTest : public testing::Test { WTF::ScopedMockClock clock_; }; -TEST_F(IdleDeadlineTest, deadlineInFuture) { +TEST_F(IdleDeadlineTest, DeadlineInFuture) { IdleDeadline* deadline = IdleDeadline::Create(TimeTicks() + TimeDelta::FromSecondsD(1.25), IdleDeadline::CallbackType::kCalledWhenIdle); @@ -82,18 +80,16 @@ TEST_F(IdleDeadlineTest, deadlineInFuture) { EXPECT_FLOAT_EQ(250.0, deadline->timeRemaining()); } -TEST_F(IdleDeadlineTest, deadlineInPast) { +TEST_F(IdleDeadlineTest, DeadlineInPast) { IdleDeadline* deadline = IdleDeadline::Create(TimeTicks() + TimeDelta::FromSecondsD(0.75), IdleDeadline::CallbackType::kCalledWhenIdle); EXPECT_FLOAT_EQ(0, deadline->timeRemaining()); } -TEST_F(IdleDeadlineTest, yieldForHighPriorityWork) { +TEST_F(IdleDeadlineTest, YieldForHighPriorityWork) { MockIdleDeadlineScheduler scheduler; - ScopedTestingPlatformSupport<TestingPlatformSupportWithCustomScheduler, - ThreadScheduler*> - platform(&scheduler); + ScopedSchedulerOverrider scheduler_overrider(&scheduler); IdleDeadline* deadline = IdleDeadline::Create(TimeTicks() + TimeDelta::FromSecondsD(1.25), diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc index ba586f17e2b..24f2266c427 100644 --- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc +++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc @@ -76,6 +76,7 @@ LayoutTreeBuilderForElement::LayoutTreeBuilderForElement(Element& element, ComputedStyle* style) : LayoutTreeBuilder(element, nullptr), style_(style) { DCHECK(element.CanParticipateInFlatTree()); + DCHECK(style_); // TODO(ecobos): Move the first-letter logic inside ParentLayoutObject too? // It's an extra (unnecessary) check for text nodes, though. if (element.IsFirstLetterPseudoElement()) { @@ -127,36 +128,24 @@ bool LayoutTreeBuilderForElement::ShouldCreateLayoutObject() const { !CanHaveGeneratedChildren(*parent_layout_object)) { return false; } - return node_->LayoutObjectIsNeeded(Style()); -} - -ComputedStyle& LayoutTreeBuilderForElement::Style() const { - if (!style_) { - // TODO(futhark@chromium.org): this should never happen, but we currently - // have crashes in the wild because of this (https://crbug.com/875796). - // Please report if you ever end up here. - NOTREACHED(); - style_ = node_->StyleForLayoutObject(); - } - return *style_; + return node_->LayoutObjectIsNeeded(*style_); } DISABLE_CFI_PERF void LayoutTreeBuilderForElement::CreateLayoutObject() { - ComputedStyle& style = Style(); ReattachLegacyLayoutObjectList& legacy_layout_objects = node_->GetDocument().GetReattachLegacyLayoutObjectList(); if (legacy_layout_objects.IsForcingLegacyLayout()) { DCHECK(!node_->GetLayoutObject()); - style.SetForceLegacyLayout(true); + style_->SetForceLegacyLayout(true); } - LayoutObject* new_layout_object = node_->CreateLayoutObject(style); + LayoutObject* new_layout_object = node_->CreateLayoutObject(*style_); if (!new_layout_object) return; LayoutObject* parent_layout_object = ParentLayoutObject(); - if (!parent_layout_object->IsChildAllowed(new_layout_object, style)) { + if (!parent_layout_object->IsChildAllowed(new_layout_object, *style_)) { new_layout_object->Destroy(); return; } @@ -171,7 +160,7 @@ void LayoutTreeBuilderForElement::CreateLayoutObject() { LayoutObject* next_layout_object = NextLayoutObject(); node_->SetLayoutObject(new_layout_object); new_layout_object->SetStyle( - &style); // SetStyle() can depend on LayoutObject() already being set. + style_); // SetStyle() can depend on LayoutObject() already being set. // Note: Adding new_layout_object instead of LayoutObject(). LayoutObject() // may be a child of new_layout_object. diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h index 0f53a0781a8..f71adc0d85b 100644 --- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h +++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h @@ -105,16 +105,13 @@ class LayoutTreeBuilderForElement : public LayoutTreeBuilder<Element> { CreateLayoutObject(); } - ComputedStyle* ResolvedStyle() const { return style_.get(); } - private: LayoutObject* ParentLayoutObject() const; LayoutObject* NextLayoutObject() const; bool ShouldCreateLayoutObject() const; - ComputedStyle& Style() const; void CreateLayoutObject(); - mutable scoped_refptr<ComputedStyle> style_; + scoped_refptr<ComputedStyle> style_; }; class LayoutTreeBuilderForText : public LayoutTreeBuilder<Text> { diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc index 11da8b7a25b..9c02d00533a 100644 --- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc +++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc @@ -304,6 +304,16 @@ LayoutObject* LayoutTreeBuilderTraversal::NextInTopLayer( wtf_size_t position = top_layer_elements.Find(&element); DCHECK_NE(position, kNotFound); for (wtf_size_t i = position + 1; i < top_layer_elements.size(); ++i) { + if (top_layer_elements[i]->NeedsReattachLayoutTree()) { + // top_layer_elements[i] is either about to have its LayoutObject removed + // from the LayoutView or it has just been moved to the top layer and the + // current LayoutObject is not in LayoutView and should not be considered + // as a LayoutObject sibling. For the former case we could use it as a + // sibling, but for the latter using it as a sibling will confuse the + // AddChild code as it will not have a common non-anonymous layout tree + // ancestor. + continue; + } if (LayoutObject* layout_object = top_layer_elements[i]->GetLayoutObject()) return layout_object; } diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h b/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h index 04699837f5e..2a1d02984e0 100644 --- a/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h +++ b/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h @@ -113,21 +113,22 @@ ALWAYS_INLINE bool LiveNodeListBase::ShouldInvalidateTypeOnAttributeChange( const QualifiedName& attr_name) { switch (type) { case kInvalidateOnClassAttrChange: - return attr_name == HTMLNames::classAttr; + return attr_name == html_names::kClassAttr; case kInvalidateOnNameAttrChange: - return attr_name == HTMLNames::nameAttr; + return attr_name == html_names::kNameAttr; case kInvalidateOnIdNameAttrChange: - return attr_name == HTMLNames::idAttr || attr_name == HTMLNames::nameAttr; + return attr_name == html_names::kIdAttr || + attr_name == html_names::kNameAttr; case kInvalidateOnForAttrChange: - return attr_name == HTMLNames::forAttr; + return attr_name == html_names::kForAttr; case kInvalidateForFormControls: - return attr_name == HTMLNames::nameAttr || - attr_name == HTMLNames::idAttr || - attr_name == HTMLNames::forAttr || - attr_name == HTMLNames::formAttr || - attr_name == HTMLNames::typeAttr; + return attr_name == html_names::kNameAttr || + attr_name == html_names::kIdAttr || + attr_name == html_names::kForAttr || + attr_name == html_names::kFormAttr || + attr_name == html_names::kTypeAttr; case kInvalidateOnHRefAttrChange: - return attr_name == HTMLNames::hrefAttr; + return attr_name == html_names::kHrefAttr; case kDoNotInvalidateOnAttributeChanges: return false; case kInvalidateOnAnyAttrChange: diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc index ac2ea2359e9..34227f76acd 100644 --- a/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc +++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc @@ -55,9 +55,13 @@ class MutationObserver::V8DelegateImpl final public: static V8DelegateImpl* Create(V8MutationCallback* callback, ExecutionContext* execution_context) { - return new V8DelegateImpl(callback, execution_context); + return MakeGarbageCollected<V8DelegateImpl>(callback, execution_context); } + V8DelegateImpl(V8MutationCallback* callback, + ExecutionContext* execution_context) + : ContextClient(execution_context), callback_(callback) {} + ExecutionContext* GetExecutionContext() const override { return ContextClient::GetExecutionContext(); } @@ -76,10 +80,6 @@ class MutationObserver::V8DelegateImpl final } private: - V8DelegateImpl(V8MutationCallback* callback, - ExecutionContext* execution_context) - : ContextClient(execution_context), callback_(callback) {} - TraceWrapperMember<V8MutationCallback> callback_; }; @@ -94,14 +94,15 @@ struct MutationObserver::ObserverLessThan { MutationObserver* MutationObserver::Create(Delegate* delegate) { DCHECK(IsMainThread()); - return new MutationObserver(delegate->GetExecutionContext(), delegate); + return MakeGarbageCollected<MutationObserver>(delegate->GetExecutionContext(), + delegate); } MutationObserver* MutationObserver::Create(ScriptState* script_state, V8MutationCallback* callback) { DCHECK(IsMainThread()); ExecutionContext* execution_context = ExecutionContext::From(script_state); - return new MutationObserver( + return MakeGarbageCollected<MutationObserver>( execution_context, V8DelegateImpl::Create(callback, execution_context)); } @@ -116,42 +117,44 @@ MutationObserver::~MutationObserver() { } void MutationObserver::observe(Node* node, - const MutationObserverInit& observer_init, + const MutationObserverInit* observer_init, ExceptionState& exception_state) { DCHECK(node); MutationObserverOptions options = 0; - if (observer_init.hasAttributeOldValue() && observer_init.attributeOldValue()) + if (observer_init->hasAttributeOldValue() && + observer_init->attributeOldValue()) options |= kAttributeOldValue; HashSet<AtomicString> attribute_filter; - if (observer_init.hasAttributeFilter()) { - for (const auto& name : observer_init.attributeFilter()) + if (observer_init->hasAttributeFilter()) { + for (const auto& name : observer_init->attributeFilter()) attribute_filter.insert(AtomicString(name)); options |= kAttributeFilter; } - bool attributes = observer_init.hasAttributes() && observer_init.attributes(); - if (attributes || (!observer_init.hasAttributes() && - (observer_init.hasAttributeOldValue() || - observer_init.hasAttributeFilter()))) + bool attributes = + observer_init->hasAttributes() && observer_init->attributes(); + if (attributes || (!observer_init->hasAttributes() && + (observer_init->hasAttributeOldValue() || + observer_init->hasAttributeFilter()))) options |= kMutationTypeAttributes; - if (observer_init.hasCharacterDataOldValue() && - observer_init.characterDataOldValue()) + if (observer_init->hasCharacterDataOldValue() && + observer_init->characterDataOldValue()) options |= kCharacterDataOldValue; bool character_data = - observer_init.hasCharacterData() && observer_init.characterData(); - if (character_data || (!observer_init.hasCharacterData() && - observer_init.hasCharacterDataOldValue())) + observer_init->hasCharacterData() && observer_init->characterData(); + if (character_data || (!observer_init->hasCharacterData() && + observer_init->hasCharacterDataOldValue())) options |= kMutationTypeCharacterData; - if (observer_init.childList()) + if (observer_init->childList()) options |= kMutationTypeChildList; - if (observer_init.subtree()) + if (observer_init->subtree()) options |= kSubtree; if (!(options & kMutationTypeAttributes)) { @@ -220,7 +223,7 @@ void MutationObserver::ObservationEnded( static MutationObserverSet& ActiveMutationObservers() { DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, active_observers, - (new MutationObserverSet)); + (MakeGarbageCollected<MutationObserverSet>())); return *active_observers; } @@ -231,13 +234,13 @@ using SlotChangeList = HeapVector<Member<HTMLSlotElement>>; // https://html.spec.whatwg.org/multipage/browsers.html#unit-of-related-similar-origin-browsing-contexts static SlotChangeList& ActiveSlotChangeList() { DEFINE_STATIC_LOCAL(Persistent<SlotChangeList>, slot_change_list, - (new SlotChangeList)); + (MakeGarbageCollected<SlotChangeList>())); return *slot_change_list; } static MutationObserverSet& SuspendedMutationObservers() { DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspended_observers, - (new MutationObserverSet)); + (MakeGarbageCollected<MutationObserverSet>())); return *suspended_observers; } diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer.h b/chromium/third_party/blink/renderer/core/dom/mutation_observer.h index 6b2c8ca210d..5013393edca 100644 --- a/chromium/third_party/blink/renderer/core/dom/mutation_observer.h +++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer.h @@ -100,9 +100,10 @@ class CORE_EXPORT MutationObserver final static void EnqueueSlotChange(HTMLSlotElement&); static void CleanSlotChangeList(Document&); + MutationObserver(ExecutionContext*, Delegate*); ~MutationObserver() override; - void observe(Node*, const MutationObserverInit&, ExceptionState&); + void observe(Node*, const MutationObserverInit*, ExceptionState&); MutationRecordVector takeRecords(); void disconnect(); void ObservationStarted(MutationObserverRegistration*); @@ -121,7 +122,6 @@ class CORE_EXPORT MutationObserver final private: struct ObserverLessThan; - MutationObserver(ExecutionContext*, Delegate*); void Deliver(); bool ShouldBeSuspended() const; void CancelInspectorAsyncTasks(); diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc index 49d85ba1c20..e6c553ecf22 100644 --- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc +++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc @@ -47,7 +47,8 @@ MutationObserverInterestGroup* MutationObserverInterestGroup::CreateIfNeeded( if (observers.IsEmpty()) return nullptr; - return new MutationObserverInterestGroup(observers, old_value_flag); + return MakeGarbageCollected<MutationObserverInterestGroup>(observers, + old_value_flag); } MutationObserverInterestGroup::MutationObserverInterestGroup( diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h index bdf9c03bf95..341a5cbda19 100644 --- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h +++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h @@ -75,6 +75,11 @@ class MutationObserverInterestGroup final &attribute_name); } + MutationObserverInterestGroup( + HeapHashMap<Member<MutationObserver>, MutationRecordDeliveryOptions>& + observers, + MutationRecordDeliveryOptions old_value_flag); + bool IsOldValueRequested(); void EnqueueMutationRecord(MutationRecord*); @@ -86,10 +91,6 @@ class MutationObserverInterestGroup final MutationType, MutationRecordDeliveryOptions old_value_flag, const QualifiedName* attribute_name = nullptr); - MutationObserverInterestGroup( - HeapHashMap<Member<MutationObserver>, MutationRecordDeliveryOptions>& - observers, - MutationRecordDeliveryOptions old_value_flag); bool HasOldValue(MutationRecordDeliveryOptions options) { return options & old_value_flag_; diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc index 8f4cc214102..156a106ee30 100644 --- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc +++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc @@ -40,8 +40,8 @@ MutationObserverRegistration* MutationObserverRegistration::Create( Node* registration_node, MutationObserverOptions options, const HashSet<AtomicString>& attribute_filter) { - return new MutationObserverRegistration(observer, registration_node, options, - attribute_filter); + return MakeGarbageCollected<MutationObserverRegistration>( + observer, registration_node, options, attribute_filter); } MutationObserverRegistration::MutationObserverRegistration( @@ -80,7 +80,7 @@ void MutationObserverRegistration::ObservedSubtreeNodeWillDetach(Node& node) { observer_->SetHasTransientRegistration(); if (!transient_registration_nodes_) { - transient_registration_nodes_ = new NodeHashSet; + transient_registration_nodes_ = MakeGarbageCollected<NodeHashSet>(); DCHECK(registration_node_); DCHECK(!registration_node_keep_alive_); diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h index ff5af8ec2f9..bfcff43fb48 100644 --- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h +++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h @@ -53,6 +53,11 @@ class CORE_EXPORT MutationObserverRegistration final Node*, MutationObserverOptions, const HashSet<AtomicString>& attribute_filter); + + MutationObserverRegistration(MutationObserver&, + Node*, + MutationObserverOptions, + const HashSet<AtomicString>& attribute_filter); ~MutationObserverRegistration(); void ResetObservation(MutationObserverOptions, @@ -89,11 +94,6 @@ class CORE_EXPORT MutationObserverRegistration final } private: - MutationObserverRegistration(MutationObserver&, - Node*, - MutationObserverOptions, - const HashSet<AtomicString>& attribute_filter); - TraceWrapperMember<MutationObserver> observer_; WeakMember<Node> registration_node_; Member<Node> registration_node_keep_alive_; diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc index b4f620ca95b..4f8b0290f53 100644 --- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc @@ -35,15 +35,15 @@ class EmptyMutationCallback : public MutationObserver::Delegate { TEST(MutationObserverTest, DisconnectCrash) { Persistent<Document> document = HTMLDocument::CreateForTest(); - auto* root = ToHTMLElement(document->CreateRawElement(HTMLNames::htmlTag)); + auto* root = ToHTMLElement(document->CreateRawElement(html_names::kHTMLTag)); document->AppendChild(root); root->SetInnerHTMLFromString("<head><title>\n</title></head><body></body>"); Node* head = root->firstChild()->firstChild(); DCHECK(head); Persistent<MutationObserver> observer = MutationObserver::Create(new EmptyMutationCallback(*document)); - MutationObserverInit init; - init.setCharacterDataOldValue(false); + MutationObserverInit* init = MutationObserverInit::Create(); + init->setCharacterDataOldValue(false); observer->observe(head, init, ASSERT_NO_EXCEPTION); head->remove(); diff --git a/chromium/third_party/blink/renderer/core/dom/name_node_list.cc b/chromium/third_party/blink/renderer/core/dom/name_node_list.cc index 946c27b2910..eb473a200ff 100644 --- a/chromium/third_party/blink/renderer/core/dom/name_node_list.cc +++ b/chromium/third_party/blink/renderer/core/dom/name_node_list.cc @@ -28,8 +28,6 @@ namespace blink { -using namespace HTMLNames; - NameNodeList::NameNodeList(ContainerNode& root_node, const AtomicString& name) : LiveNodeList(root_node, kNameNodeListType, kInvalidateOnNameAttrChange), name_(name) {} diff --git a/chromium/third_party/blink/renderer/core/dom/name_node_list.h b/chromium/third_party/blink/renderer/core/dom/name_node_list.h index f290cb49cfe..f496bf736d4 100644 --- a/chromium/third_party/blink/renderer/core/dom/name_node_list.h +++ b/chromium/third_party/blink/renderer/core/dom/name_node_list.h @@ -37,14 +37,13 @@ class CORE_EXPORT NameNodeList final : public LiveNodeList { CollectionType type, const AtomicString& name) { DCHECK_EQ(type, kNameNodeListType); - return new NameNodeList(root_node, name); + return MakeGarbageCollected<NameNodeList>(root_node, name); } + NameNodeList(ContainerNode& root_node, const AtomicString& name); ~NameNodeList() override; private: - NameNodeList(ContainerNode& root_node, const AtomicString& name); - bool ElementMatches(const Element&) const override; AtomicString name_; diff --git a/chromium/third_party/blink/renderer/core/dom/named_node_map.cc b/chromium/third_party/blink/renderer/core/dom/named_node_map.cc index 691c73b8c28..f0b19a3c7f9 100644 --- a/chromium/third_party/blink/renderer/core/dom/named_node_map.cc +++ b/chromium/third_party/blink/renderer/core/dom/named_node_map.cc @@ -33,8 +33,6 @@ namespace blink { -using namespace HTMLNames; - Attr* NamedNodeMap::getNamedItem(const AtomicString& name) const { return element_->getAttributeNode(name); } diff --git a/chromium/third_party/blink/renderer/core/dom/named_node_map.h b/chromium/third_party/blink/renderer/core/dom/named_node_map.h index 905c349b782..a8209b6c484 100644 --- a/chromium/third_party/blink/renderer/core/dom/named_node_map.h +++ b/chromium/third_party/blink/renderer/core/dom/named_node_map.h @@ -41,7 +41,12 @@ class NamedNodeMap final : public ScriptWrappable { public: static NamedNodeMap* Create(Element* element) { - return new NamedNodeMap(element); + return MakeGarbageCollected<NamedNodeMap>(element); + } + + explicit NamedNodeMap(Element* element) : element_(element) { + // Only supports NamedNodeMaps with Element associated. + DCHECK(element_); } // Public DOM interface. @@ -67,11 +72,6 @@ class NamedNodeMap final : public ScriptWrappable { void Trace(blink::Visitor*) override; private: - explicit NamedNodeMap(Element* element) : element_(element) { - // Only supports NamedNodeMaps with Element associated. - DCHECK(element_); - } - Member<Element> element_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/names_map.cc b/chromium/third_party/blink/renderer/core/dom/names_map.cc index 8acb1e5af77..ad7dbc30b11 100644 --- a/chromium/third_party/blink/renderer/core/dom/names_map.cc +++ b/chromium/third_party/blink/renderer/core/dom/names_map.cc @@ -45,15 +45,34 @@ void NamesMap::Add(const AtomicString& key, const AtomicString& value) { // second and => is not used to separate key and value. It also allows an ident // token on its own as a short-hand for forwarding with the same name. -// The states that can occur while parsing the part map. {...} denotes the new -// states that can be reached from this state. +// The states that can occur while parsing the part map and their transitions. +// A "+" indicates that this transition should consume the current character. +// A "*" indicates that this is invalid input, usually the decision here is +// to just do our best and recover gracefully. enum State { - kPreKey, // Searching for the start of a key. {kPreKey, kKey} - kKey, // Searching for the end of a key. {kKey, kPreValue} - kPreValue, // Searching for the start of a value. {kPreValue, kPreKey, - // kValue} - kValue, // Searching for the end of a value. {kValue, kPreKey, kPostValue} - kPostValue, // Searching for the comma after the value. {kPostValue, kPreKey} + kPreKey, // Searching for the start of a key: + // space, comma, colon* -> kPreKey+ + // else -> kKey + kKey, // Searching for the end of a key: + // comma -> kPreKey+ + // colon -> kPreValue+ + // space -> kPostKey+ + // else -> kKey+ + kPostKey, // Searching for a delimiter: + // comma -> kPreKey+ + // colon -> kPreValue+ + // space, else* -> kPostKey+ + kPreValue, // Searching for the start of a value: + // comma -> kPreKey+ + // colon*, space -> kPreValue+ + // else -> kValue+ + kValue, // Searching for the end of a value: + // comma -> kPreKey+ + // colon*, space -> kPostValue+ + // else -> kValue+ + kPostValue, // Searching for the comma after the value: + // comma -> kPreKey+ + // colon*, else -> kPostValue+ }; template <typename CharacterType> @@ -69,24 +88,55 @@ void NamesMap::Set(const AtomicString& source, State state = kPreKey; AtomicString key; while (cur < length) { + // Almost all cases break, ensuring that some input is consumed and we avoid + // an infinite loop. For the few transitions which should happen without + // consuming input we fall through into the new state's case. This makes it + // easy to see the cases which don't consume input and check that they lead + // to a case which does. + // + // The only state which should set a value for key is kKey, as we leave the + // state. switch (state) { case kPreKey: - // Skip any number of spaces and commas. When we find something else, it - // is the start of a key. - if (!IsHTMLSpaceOrComma<CharacterType>(characters[cur])) { - start = cur; - state = kKey; + // Skip any number of spaces, commas and colons. When we find something + // else, it is the start of a key. + if ((IsHTMLSpaceOrComma<CharacterType>(characters[cur]) || + IsColon<CharacterType>(characters[cur]))) { + break; } - break; + start = cur; + state = kKey; + FALLTHROUGH; case kKey: - // At a space or comma, we have found the end of the key. - if (IsHTMLSpaceOrComma<CharacterType>(characters[cur])) { + // At a comma this was a key without a value, the implicit value is the + // same as the key. + if (IsComma<CharacterType>(characters[cur])) { + key = AtomicString(characters + start, cur - start); + Add(key, key); + state = kPreKey; + // At a colon, we have found the end of the key and we expect a value. + } else if (IsColon<CharacterType>(characters[cur])) { key = AtomicString(characters + start, cur - start); state = kPreValue; - } else { - break; + // At a space, we have found the end of the key. + } else if (IsHTMLSpace<CharacterType>(characters[cur])) { + key = AtomicString(characters + start, cur - start); + state = kPostKey; } - FALLTHROUGH; + break; + case kPostKey: + // At a comma this was a key without a value, the implicit value is the + // same as the key. + if (IsComma<CharacterType>(characters[cur])) { + Add(key, key); + state = kPreKey; + // At a colon this was a key with a value, we expect a value. + } else if (IsColon<CharacterType>(characters[cur])) { + state = kPreValue; + } + // Spaces should be consumed. We consume other characters too + // although the input is invalid + break; case kPreValue: // At a comma this was a key without a value, the implicit value is the // same as the key. @@ -95,20 +145,26 @@ void NamesMap::Set(const AtomicString& source, state = kPreKey; // If we reach a non-space character, we have found the start of the // value. - } else if (IsNotHTMLSpace<CharacterType>(characters[cur])) { + } else if (IsColon<CharacterType>(characters[cur]) || + IsHTMLSpace<CharacterType>(characters[cur])) { + break; + } else { start = cur; state = kValue; } break; case kValue: - // At a comma or space, we have found the end of the value. - if (IsHTMLSpaceOrComma<CharacterType>(characters[cur])) { + // At a comma, we have found the end of the value and expect + // the next key. + if (IsComma<CharacterType>(characters[cur])) { + Add(key, AtomicString(characters + start, cur - start)); + state = kPreKey; + // At a space or colon, we have found the end of the value, + // although a colon is invalid here. + } else if (IsHTMLSpace<CharacterType>(characters[cur]) || + IsColon<CharacterType>(characters[cur])) { Add(key, AtomicString(characters + start, cur - start)); - if (IsComma<CharacterType>(characters[cur])) { - state = kPreKey; - } else { - state = kPostValue; - } + state = kPostValue; } break; case kPostValue: @@ -130,6 +186,7 @@ void NamesMap::Set(const AtomicString& source, // The string ends with a key. key = AtomicString(characters + start, cur - start); FALLTHROUGH; + case kPostKey: case kPreValue: // The string ends after a key but with nothing else useful. Add(key, key); diff --git a/chromium/third_party/blink/renderer/core/dom/names_map_test.cc b/chromium/third_party/blink/renderer/core/dom/names_map_test.cc index db30cc82447..995fade172d 100644 --- a/chromium/third_party/blink/renderer/core/dom/names_map_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/names_map_test.cc @@ -29,26 +29,38 @@ TEST(NamesMapTest, Set) { Vector<std::pair<String, ExpectedMap>> test_cases({ // Various valid values. {"foo", {{"foo", "foo"}}}, - {"foo bar", {{"foo", "bar"}}}, - {"foo bar, foo buz", {{"foo", "bar buz"}}}, - {"foo bar, buz", {{"foo", "bar"}, {"buz", "buz"}}}, - {"foo bar, buz bar", {{"foo", "bar"}, {"buz", "bar"}}}, - {"foo, buz bar", {{"foo", "foo"}, {"buz", "bar"}}}, + {"foo: bar", {{"foo", "bar"}}}, + {"foo : bar", {{"foo", "bar"}}}, + {"foo: bar, foo: buz", {{"foo", "bar buz"}}}, + {"foo: bar, buz", {{"foo", "bar"}, {"buz", "buz"}}}, + {"foo: bar, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo, buz: bar", {{"foo", "foo"}, {"buz", "bar"}}}, // This is an error but qux should be ignored. - {"foo bar qux, buz bar", {{"foo", "bar"}, {"buz", "bar"}}}, - {"foo bar, buz bar qux", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar qux, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar, buz: bar qux", {{"foo", "bar"}, {"buz", "bar"}}}, - // This is an error but the extra comma should be ignored. - {",foo bar, buz bar", {{"foo", "bar"}, {"buz", "bar"}}}, - {"foo bar,, buz bar", {{"foo", "bar"}, {"buz", "bar"}}}, - {"foo bar, buz bar,", {{"foo", "bar"}, {"buz", "bar"}}}, - {"foo bar, buz bar,,", {{"foo", "bar"}, {"buz", "bar"}}}, + // This is an error but the extra commas and colons should be ignored. + {"foo:", {{"foo", "foo"}}}, + {"foo:,", {{"foo", "foo"}}}, + {"foo :", {{"foo", "foo"}}}, + {"foo :,", {{"foo", "foo"}}}, + {"foo: bar, buz:", {{"foo", "bar"}, {"buz", "buz"}}}, + {"foo: bar, buz :", {{"foo", "bar"}, {"buz", "buz"}}}, + {",foo: bar, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar,, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar, buz: bar,", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar, buz: bar,,", {{"foo", "bar"}, {"buz", "bar"}}}, + {":foo: bar, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar:, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: :bar, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar, buz: bar:", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar, buz: bar::", {{"foo", "bar"}, {"buz", "bar"}}}, // Spaces in odd places. - {" foo bar, buz bar", {{"foo", "bar"}, {"buz", "bar"}}}, - {"foo bar, buz bar", {{"foo", "bar"}, {"buz", "bar"}}}, - {"foo bar, buz bar ", {{"foo", "bar"}, {"buz", "bar"}}}, + {" foo: bar, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar, buz: bar", {{"foo", "bar"}, {"buz", "bar"}}}, + {"foo: bar, buz: bar ", {{"foo", "bar"}, {"buz", "bar"}}}, }); NamesMap map; diff --git a/chromium/third_party/blink/renderer/core/dom/node.cc b/chromium/third_party/blink/renderer/core/dom/node.cc index 600d9c401b4..89e4681f15a 100644 --- a/chromium/third_party/blink/renderer/core/dom/node.cc +++ b/chromium/third_party/blink/renderer/core/dom/node.cc @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/bindings/core/v8/node_or_string.h" +#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/css/css_selector.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" @@ -47,6 +48,7 @@ #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h" #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h" #include "third_party/blink/renderer/core/dom/events/event_listener.h" +#include "third_party/blink/renderer/core/dom/flat_tree_node_data.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/get_root_node_options.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" @@ -95,11 +97,20 @@ #include "third_party/blink/renderer/core/input/input_device_capabilities.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" +#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/mathml_names.h" #include "third_party/blink/renderer/core/page/context_menu_controller.h" #include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h" +#include "third_party/blink/renderer/core/page/scrolling/scroll_customization_callbacks.h" +#include "third_party/blink/renderer/core/page/scrolling/scroll_state.h" +#include "third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h" +#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" +#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image.h" #include "third_party/blink/renderer/core/svg/svg_element.h" +#include "third_party/blink/renderer/core/trustedtypes/trusted_script.h" #include "third_party/blink/renderer/platform/bindings/dom_data_store.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/microtask.h" @@ -119,6 +130,20 @@ namespace blink { namespace { +// We need to retain the scroll customization callbacks until the element +// they're associated with is destroyed. It would be simplest if the callbacks +// could be stored in ElementRareData, but we can't afford the space increase. +// Instead, keep the scroll customization callbacks here. The other option would +// be to store these callbacks on the Page or document, but that necessitates a +// bunch more logic for transferring the callbacks between Pages when elements +// are moved around. +ScrollCustomizationCallbacks& GetScrollCustomizationCallbacks() { + DEFINE_STATIC_LOCAL(Persistent<ScrollCustomizationCallbacks>, + scroll_customization_callbacks, + (new ScrollCustomizationCallbacks)); + return *scroll_customization_callbacks; +} + // TODO(crbug.com/545926): Unsafe hack to avoid triggering the // ThreadRestrictionVerifier on StringImpl. This should be fixed completely, and // we should always avoid accessing these strings from the impl thread. @@ -135,7 +160,7 @@ void AppendUnsafe(StringBuilder& builder, const String& off_thread_string) { } // namespace -using namespace HTMLNames; +using namespace html_names; struct SameSizeAsNode : EventTarget { uint32_t node_flags_; @@ -436,9 +461,206 @@ Node& Node::TreeRoot() const { return const_cast<Node&>(*node); } -Node* Node::getRootNode(const GetRootNodeOptions& options) const { - return (options.hasComposed() && options.composed()) ? &ShadowIncludingRoot() - : &TreeRoot(); +Node* Node::getRootNode(const GetRootNodeOptions* options) const { + return (options->hasComposed() && options->composed()) + ? &ShadowIncludingRoot() + : &TreeRoot(); +} + +void Node::setDistributeScroll(V8ScrollStateCallback* scroll_state_callback, + const String& native_scroll_behavior) { + GetScrollCustomizationCallbacks().SetDistributeScroll( + this, ScrollStateCallbackV8Impl::Create(scroll_state_callback, + native_scroll_behavior)); +} + +void Node::setApplyScroll(V8ScrollStateCallback* scroll_state_callback, + const String& native_scroll_behavior) { + SetApplyScroll(ScrollStateCallbackV8Impl::Create(scroll_state_callback, + native_scroll_behavior)); +} + +void Node::SetApplyScroll(ScrollStateCallback* scroll_state_callback) { + GetScrollCustomizationCallbacks().SetApplyScroll(this, scroll_state_callback); +} + +void Node::RemoveApplyScroll() { + GetScrollCustomizationCallbacks().RemoveApplyScroll(this); +} + +ScrollStateCallback* Node::GetApplyScroll() { + return GetScrollCustomizationCallbacks().GetApplyScroll(this); +} + +void Node::NativeDistributeScroll(ScrollState& scroll_state) { + if (scroll_state.FullyConsumed()) + return; + + scroll_state.distributeToScrollChainDescendant(); + + // The scroll doesn't propagate, and we're currently scrolling an element + // other than this one, prevent the scroll from propagating to this element. + if (scroll_state.DeltaConsumedForScrollSequence() && + scroll_state.CurrentNativeScrollingNode() != this) { + return; + } + + const double delta_x = scroll_state.deltaX(); + const double delta_y = scroll_state.deltaY(); + + CallApplyScroll(scroll_state); + + if (delta_x != scroll_state.deltaX() || delta_y != scroll_state.deltaY()) + scroll_state.SetCurrentNativeScrollingNode(this); +} + +void Node::NativeApplyScroll(ScrollState& scroll_state) { + if (!GetLayoutObject()) + return; + + // All elements in the scroll chain should be boxes. + DCHECK(GetLayoutObject()->IsBox()); + + if (scroll_state.FullyConsumed()) + return; + + FloatSize delta(scroll_state.deltaX(), scroll_state.deltaY()); + + if (delta.IsZero()) + return; + + // TODO(esprehn): This should use + // updateStyleAndLayoutIgnorePendingStylesheetsForNode. + GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); + + LayoutBox* box_to_scroll = ToLayoutBox(GetLayoutObject()); + + ScrollableArea* scrollable_area = + box_to_scroll->EnclosingBox()->GetScrollableArea(); + + if (!scrollable_area) + return; + + ScrollResult result = scrollable_area->UserScroll( + ScrollGranularity(static_cast<int>(scroll_state.deltaGranularity())), + delta); + + if (!result.DidScroll()) + return; + + // FIXME: Native scrollers should only consume the scroll they + // apply. See crbug.com/457765. + scroll_state.ConsumeDeltaNative(delta.Width(), delta.Height()); + + // We need to setCurrentNativeScrollingElement in both the + // distributeScroll and applyScroll default implementations so + // that if JS overrides one of these methods, but not the + // other, this bookkeeping remains accurate. + scroll_state.SetCurrentNativeScrollingNode(this); +} + +void Node::CallDistributeScroll(ScrollState& scroll_state) { + TRACE_EVENT0("input", "Node::CallDistributeScroll"); + ScrollStateCallback* callback = + GetScrollCustomizationCallbacks().GetDistributeScroll(this); + + // TODO(bokan): Need to add tests before we allow calling custom callbacks + // for non-touch modalities. For now, just call into the native callback but + // allow the viewport scroll callback so we don't disable overscroll. + // crbug.com/623079. + bool disable_custom_callbacks = !scroll_state.isDirectManipulation() && + !GetDocument() + .GetPage() + ->GlobalRootScrollerController() + .IsViewportScrollCallback(callback); + + bool is_global_root_scroller = + GetLayoutObject() && GetLayoutObject()->IsGlobalRootScroller(); + + disable_custom_callbacks |= + !is_global_root_scroller && + RuntimeEnabledFeatures::ScrollCustomizationEnabled() && + !GetScrollCustomizationCallbacks().InScrollPhase(this); + + if (!callback || disable_custom_callbacks) { + NativeDistributeScroll(scroll_state); + return; + } + if (callback->NativeScrollBehavior() != + WebNativeScrollBehavior::kPerformAfterNativeScroll) + callback->Invoke(&scroll_state); + if (callback->NativeScrollBehavior() != + WebNativeScrollBehavior::kDisableNativeScroll) + NativeDistributeScroll(scroll_state); + if (callback->NativeScrollBehavior() == + WebNativeScrollBehavior::kPerformAfterNativeScroll) + callback->Invoke(&scroll_state); +} + +void Node::CallApplyScroll(ScrollState& scroll_state) { + TRACE_EVENT0("input", "Node::CallApplyScroll"); + // Hits ASSERTs when trying to determine whether we need to scroll on main + // or CC. http://crbug.com/625676. + DisableCompositingQueryAsserts disabler; + + if (!GetDocument().GetPage()) { + // We should always have a Page if we're scrolling. See + // crbug.com/689074 for details. + return; + } + + ScrollStateCallback* callback = + GetScrollCustomizationCallbacks().GetApplyScroll(this); + + // TODO(bokan): Need to add tests before we allow calling custom callbacks + // for non-touch modalities. For now, just call into the native callback but + // allow the viewport scroll callback so we don't disable overscroll. + // crbug.com/623079. + bool disable_custom_callbacks = !scroll_state.isDirectManipulation() && + !GetDocument() + .GetPage() + ->GlobalRootScrollerController() + .IsViewportScrollCallback(callback); + + bool is_global_root_scroller = + GetLayoutObject() && GetLayoutObject()->IsGlobalRootScroller(); + + disable_custom_callbacks |= + !is_global_root_scroller && + RuntimeEnabledFeatures::ScrollCustomizationEnabled() && + !GetScrollCustomizationCallbacks().InScrollPhase(this); + + if (!callback || disable_custom_callbacks) { + NativeApplyScroll(scroll_state); + return; + } + if (callback->NativeScrollBehavior() != + WebNativeScrollBehavior::kPerformAfterNativeScroll) + callback->Invoke(&scroll_state); + if (callback->NativeScrollBehavior() != + WebNativeScrollBehavior::kDisableNativeScroll) + NativeApplyScroll(scroll_state); + if (callback->NativeScrollBehavior() == + WebNativeScrollBehavior::kPerformAfterNativeScroll) + callback->Invoke(&scroll_state); +} + +void Node::WillBeginCustomizedScrollPhase( + scroll_customization::ScrollDirection direction) { + DCHECK(!GetScrollCustomizationCallbacks().InScrollPhase(this)); + LayoutBox* box = GetLayoutBox(); + if (!box) + return; + + scroll_customization::ScrollDirection scroll_customization = + box->Style()->ScrollCustomization(); + + GetScrollCustomizationCallbacks().SetInScrollPhase( + this, direction & scroll_customization); +} + +void Node::DidEndCustomizedScrollPhase() { + GetScrollCustomizationCallbacks().SetInScrollPhase(this, false); } Node* Node::insertBefore(Node* new_child, @@ -882,6 +1104,14 @@ void Node::MarkAncestorsWithChildNeedsStyleRecalc() { ancestor->SetChildNeedsStyleRecalc(); if (ancestor->NeedsStyleRecalc()) break; + // If we reach a locked ancestor, we should abort since the ancestor marking + // will be done when the lock is committed. + if (RuntimeEnabledFeatures::DisplayLockingEnabled()) { + if (ancestor->IsElementNode() && + ToElement(ancestor)->StyleRecalcBlockedByDisplayLock()) { + break; + } + } } if (!isConnected()) return; @@ -889,6 +1119,23 @@ void Node::MarkAncestorsWithChildNeedsStyleRecalc() { // early return here is a performance optimization. if (parent_dirty) return; + + // If we're in a locked subtree, then we should not update the style recalc + // roots. These would be updated when we commit the lock. + // TODO(vmpstr): There's currently no easy way to determine whether we're in a + // locked subtree other than navigating up the ancestor chain. We can probably + // do better and only do this walk if there is in fact a lock somewhere in the + // document. + if (RuntimeEnabledFeatures::DisplayLockingEnabled()) { + for (auto* ancestor_copy = ancestor; ancestor_copy; + ancestor_copy = ancestor_copy->ParentOrShadowHostNode()) { + if (ancestor_copy->IsElementNode() && + ToElement(ancestor_copy)->StyleRecalcBlockedByDisplayLock()) { + return; + } + } + } + GetDocument().GetStyleEngine().UpdateStyleRecalcRoot(ancestor, this); GetDocument().ScheduleLayoutTreeUpdateIfNeeded(); } @@ -947,7 +1194,7 @@ void Node::SetNeedsStyleRecalc(StyleChangeType change_type, TRACE_EVENT_INSTANT1( TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "StyleRecalcInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorStyleRecalcInvalidationTrackingEvent::Data(this, reason)); + inspector_style_recalc_invalidation_tracking_event::Data(this, reason)); StyleChangeType existing_change_type = GetStyleChangeType(); if (change_type > existing_change_type) @@ -965,6 +1212,7 @@ void Node::SetNeedsStyleRecalc(StyleChangeType change_type, void Node::ClearNeedsStyleRecalc() { node_flags_ &= ~kStyleChangeMask; + ClearFlag(kForceReattachLayoutTree); if (IsElementNode() && HasRareData()) ToElement(*this).SetAnimationStyleChange(false); @@ -1004,7 +1252,7 @@ bool Node::IsInert() const { ? ToElement(this) : FlatTreeTraversal::ParentElement(*this); while (element) { - if (element->hasAttribute(HTMLNames::inertAttr)) + if (element->hasAttribute(html_names::kInertAttr)) return true; element = FlatTreeTraversal::ParentElement(*element); } @@ -1028,6 +1276,21 @@ void Node::ClearNodeLists() { RareData()->ClearNodeLists(); } +FlatTreeNodeData& Node::EnsureFlatTreeNodeData() { + return EnsureRareData().EnsureFlatTreeNodeData(); +} + +FlatTreeNodeData* Node::GetFlatTreeNodeData() const { + if (!HasRareData()) + return nullptr; + return RareData()->GetFlatTreeNodeData(); +} + +void Node::ClearFlatTreeNodeData() { + if (FlatTreeNodeData* data = GetFlatTreeNodeData()) + data->Clear(); +} + bool Node::IsDescendantOf(const Node* other) const { // Return true if other is an ancestor of this, otherwise false if (!other || !other->hasChildren() || isConnected() != other->isConnected()) @@ -1164,7 +1427,6 @@ void Node::DetachLayoutTree(const AttachContext& context) { GetLayoutObject()->DestroyAndCleanupAnonymousWrappers(); SetLayoutObject(nullptr); SetStyleChange(kNeedsReattachStyleChange); - ClearChildNeedsStyleInvalidation(); } const ComputedStyle* Node::VirtualEnsureComputedStyle( @@ -1208,7 +1470,7 @@ bool Node::CanStartSelection() const { bool Node::IsStyledElement() const { return IsHTMLElement() || IsSVGElement() || (IsElementNode() && - ToElement(this)->namespaceURI() == MathMLNames::mathmlNamespaceURI); + ToElement(this)->namespaceURI() == mathml_names::kNamespaceURI); } bool Node::CanParticipateInFlatTree() const { @@ -1223,9 +1485,10 @@ bool Node::IsActiveSlotOrActiveV0InsertionPoint() const { AtomicString Node::SlotName() const { DCHECK(IsSlotable()); - if (IsElementNode()) + if (IsElementNode()) { return HTMLSlotElement::NormalizeSlotName( - ToElement(*this).FastGetAttribute(HTMLNames::slotAttr)); + ToElement(*this).FastGetAttribute(html_names::kSlotAttr)); + } DCHECK(IsTextNode()); return g_empty_atom; } @@ -1524,6 +1787,23 @@ String Node::textContent(bool convert_brs_to_newlines) const { return content.ToString(); } +void Node::setTextContent(const StringOrTrustedScript& string_or_trusted_script, + ExceptionState& exception_state) { + String value = + string_or_trusted_script.IsString() + ? string_or_trusted_script.GetAsString() + : string_or_trusted_script.IsTrustedScript() + ? string_or_trusted_script.GetAsTrustedScript()->toString() + : g_empty_string; + setTextContent(value); +} + +void Node::textContent(StringOrTrustedScript& result) { + String value = textContent(); + if (!value.IsNull()) + result.SetString(value); +} + void Node::setTextContent(const String& text) { switch (getNodeType()) { case kAttributeNode: @@ -1776,9 +2056,9 @@ String Node::ToString() const { builder.Append(nodeValue().EncodeForDebugging()); return builder.ToString(); } - DumpAttributeDesc(*this, HTMLNames::idAttr, builder); - DumpAttributeDesc(*this, HTMLNames::classAttr, builder); - DumpAttributeDesc(*this, HTMLNames::styleAttr, builder); + DumpAttributeDesc(*this, html_names::kIdAttr, builder); + DumpAttributeDesc(*this, html_names::kClassAttr, builder); + DumpAttributeDesc(*this, html_names::kStyleAttr, builder); if (HasEditableStyle(*this)) builder.Append(" (editable)"); if (GetDocument().FocusedElement() == this) @@ -1991,7 +2271,9 @@ void Node::ShowTreeForThisAcrossFrame() const { // -------- Element* Node::EnclosingLinkEventParentOrSelf() const { - const Node* result = nullptr; + // https://crbug.com/784492 + DCHECK(this); + for (const Node* node = this; node; node = FlatTreeTraversal::Parent(*node)) { // For imagemaps, the enclosing link node is the associated area element not // the image itself. So we don't let images be the enclosingLinkNode, even @@ -1999,16 +2281,15 @@ Element* Node::EnclosingLinkEventParentOrSelf() const { if (node->IsLink() && !IsHTMLImageElement(*node)) { // Casting to Element is safe because only HTMLAnchorElement, // HTMLImageElement and SVGAElement can return true for isLink(). - result = node; - break; + return ToElement(const_cast<Node*>(node)); } } - return ToElement(const_cast<Node*>(result)); + return nullptr; } const AtomicString& Node::InterfaceName() const { - return EventTargetNames::Node; + return event_target_names::kNode; } ExecutionContext* Node::GetExecutionContext() const { @@ -2110,7 +2391,7 @@ using EventTargetDataMap = HeapHashMap<WeakMember<Node>, TraceWrapperMember<EventTargetData>>; static EventTargetDataMap& GetEventTargetDataMap() { DEFINE_STATIC_LOCAL(Persistent<EventTargetDataMap>, map, - (new EventTargetDataMap)); + (MakeGarbageCollected<EventTargetDataMap>())); return *map; } @@ -2123,7 +2404,7 @@ EventTargetData& Node::EnsureEventTargetData() { return *GetEventTargetDataMap().at(this); DCHECK(!GetEventTargetDataMap().Contains(this)); SetHasEventTargetData(true); - EventTargetData* data = new EventTargetData; + EventTargetData* data = MakeGarbageCollected<EventTargetData>(); GetEventTargetDataMap().Set(this, data); return *data; } @@ -2280,8 +2561,8 @@ void Node::HandleLocalEvents(Event& event) { if (HasEventListeners(event.type())) { UseCounter::Count(GetDocument(), WebFeature::kDispatchMouseEventOnDisabledFormControl); - if (event.type() == EventTypeNames::mousedown || - event.type() == EventTypeNames::mouseup) { + if (event.type() == event_type_names::kMousedown || + event.type() == event_type_names::kMouseup) { UseCounter::Count( GetDocument(), WebFeature::kDispatchMouseUpDownEventOnDisabledFormControl); @@ -2313,8 +2594,8 @@ void Node::DispatchSubtreeModifiedEvent() { if (!GetDocument().HasListenerType(Document::kDOMSubtreeModifiedListener)) return; - DispatchScopedEvent(*MutationEvent::Create(EventTypeNames::DOMSubtreeModified, - Event::Bubbles::kYes)); + DispatchScopedEvent(*MutationEvent::Create( + event_type_names::kDOMSubtreeModified, Event::Bubbles::kYes)); } DispatchEventResult Node::DispatchDOMActivateEvent(int detail, @@ -2323,7 +2604,7 @@ DispatchEventResult Node::DispatchDOMActivateEvent(int detail, DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden()); #endif UIEvent& event = *UIEvent::Create(); - event.initUIEvent(EventTypeNames::DOMActivate, true, true, + event.initUIEvent(event_type_names::kDOMActivate, true, true, GetDocument().domWindow(), detail); event.SetUnderlyingEvent(&underlying_event); event.SetComposed(underlying_event.composed()); @@ -2343,41 +2624,44 @@ void Node::DispatchSimulatedClick(Event* underlying_event, void Node::DispatchInputEvent() { // Legacy 'input' event for forms set value and checked. - DispatchScopedEvent(*Event::CreateBubble(EventTypeNames::input)); + Event* event = Event::CreateBubble(event_type_names::kInput); + event->SetComposed(true); + DispatchScopedEvent(*event); } void Node::DefaultEventHandler(Event& event) { if (event.target() != this) return; const AtomicString& event_type = event.type(); - if (event_type == EventTypeNames::keydown || - event_type == EventTypeNames::keypress) { + if (event_type == event_type_names::kKeydown || + event_type == event_type_names::kKeypress) { if (event.IsKeyboardEvent()) { if (LocalFrame* frame = GetDocument().GetFrame()) { frame->GetEventHandler().DefaultKeyboardEventHandler( ToKeyboardEvent(&event)); } } - } else if (event_type == EventTypeNames::click) { + } else if (event_type == event_type_names::kClick) { int detail = event.IsUIEvent() ? ToUIEvent(event).detail() : 0; if (DispatchDOMActivateEvent(detail, event) != DispatchEventResult::kNotCanceled) event.SetDefaultHandled(); - } else if (event_type == EventTypeNames::contextmenu && + } else if (event_type == event_type_names::kContextmenu && event.IsMouseEvent()) { if (Page* page = GetDocument().GetPage()) { page->GetContextMenuController().HandleContextMenuEvent( ToMouseEvent(&event)); } - } else if (event_type == EventTypeNames::textInput) { - if (event.HasInterface(EventNames::TextEvent)) { + } else if (event_type == event_type_names::kTextInput) { + if (event.HasInterface(event_interface_names::kTextEvent)) { if (LocalFrame* frame = GetDocument().GetFrame()) { frame->GetEventHandler().DefaultTextInputEventHandler( ToTextEvent(&event)); } } } else if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled() && - event_type == EventTypeNames::mousedown && event.IsMouseEvent()) { + event_type == event_type_names::kMousedown && + event.IsMouseEvent()) { auto& mouse_event = ToMouseEvent(event); if (mouse_event.button() == static_cast<short>(WebPointerProperties::Button::kMiddle)) { @@ -2407,7 +2691,7 @@ void Node::DefaultEventHandler(Event& event) { frame->GetEventHandler().StartMiddleClickAutoscroll(layout_object); } } - } else if (event_type == EventTypeNames::mouseup && event.IsMouseEvent()) { + } else if (event_type == event_type_names::kMouseup && event.IsMouseEvent()) { auto& mouse_event = ToMouseEvent(event); if (mouse_event.button() == static_cast<short>(WebPointerProperties::Button::kBack)) { @@ -2432,7 +2716,7 @@ void Node::WillCallDefaultEventHandler(const Event& event) { if (!IsFocused() || GetDocument().LastFocusType() != kWebFocusTypeMouse) return; - if (event.type() != EventTypeNames::keydown || + if (event.type() != event_type_names::kKeydown || GetDocument().HadKeyboardEvent()) return; @@ -2456,9 +2740,9 @@ bool Node::HasActivationBehavior() const { bool Node::WillRespondToMouseMoveEvents() { if (IsDisabledFormControl(this)) return false; - return HasEventListeners(EventTypeNames::mousemove) || - HasEventListeners(EventTypeNames::mouseover) || - HasEventListeners(EventTypeNames::mouseout); + return HasEventListeners(event_type_names::kMousemove) || + HasEventListeners(event_type_names::kMouseover) || + HasEventListeners(event_type_names::kMouseout); } bool Node::WillRespondToMouseClickEvents() { @@ -2466,19 +2750,19 @@ bool Node::WillRespondToMouseClickEvents() { return false; GetDocument().UpdateStyleAndLayoutTree(); return HasEditableStyle(*this) || - HasEventListeners(EventTypeNames::mouseup) || - HasEventListeners(EventTypeNames::mousedown) || - HasEventListeners(EventTypeNames::click) || - HasEventListeners(EventTypeNames::DOMActivate); + HasEventListeners(event_type_names::kMouseup) || + HasEventListeners(event_type_names::kMousedown) || + HasEventListeners(event_type_names::kClick) || + HasEventListeners(event_type_names::kDOMActivate); } bool Node::WillRespondToTouchEvents() { if (IsDisabledFormControl(this)) return false; - return HasEventListeners(EventTypeNames::touchstart) || - HasEventListeners(EventTypeNames::touchmove) || - HasEventListeners(EventTypeNames::touchcancel) || - HasEventListeners(EventTypeNames::touchend); + return HasEventListeners(event_type_names::kTouchstart) || + HasEventListeners(event_type_names::kTouchmove) || + HasEventListeners(event_type_names::kTouchcancel) || + HasEventListeners(event_type_names::kTouchend); } unsigned Node::ConnectedSubframeCount() const { @@ -2690,6 +2974,11 @@ void Node::CheckSlotChange(SlotChangeType slot_change_type) { } } +bool Node::IsEffectiveRootScroller() const { + return GetLayoutObject() ? GetLayoutObject()->IsEffectiveRootScroller() + : false; +} + WebPluginContainerImpl* Node::GetWebPluginContainer() const { if (!IsHTMLObjectElement(this) && !IsHTMLEmbedElement(this)) { return nullptr; diff --git a/chromium/third_party/blink/renderer/core/dom/node.h b/chromium/third_party/blink/renderer/core/dom/node.h index 20acc9cae2a..32e30eb5b52 100644 --- a/chromium/third_party/blink/renderer/core/dom/node.h +++ b/chromium/third_party/blink/renderer/core/dom/node.h @@ -34,6 +34,7 @@ #include "third_party/blink/renderer/core/dom/mutation_observer_options.h" #include "third_party/blink/renderer/core/dom/node_rare_data.h" #include "third_party/blink/renderer/core/dom/tree_scope.h" +#include "third_party/blink/renderer/core/scroll/scroll_customization.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" @@ -50,6 +51,7 @@ class Element; class Event; class EventDispatchHandlingState; class ExceptionState; +class FlatTreeNodeData; class GetRootNodeOptions; class HTMLQualifiedName; class HTMLSlotElement; @@ -67,11 +69,15 @@ class NodeRareData; class QualifiedName; class RegisteredEventListener; class SVGQualifiedName; +class ScrollState; +class ScrollStateCallback; class ShadowRoot; template <typename NodeType> class StaticNodeTypeList; using StaticNodeList = StaticNodeTypeList<Node>; +class StringOrTrustedScript; class StyleChangeReasonForTracing; +class V8ScrollStateCallback; class WebPluginContainerImpl; const int kNodeStyleChangeShift = 18; @@ -189,7 +195,23 @@ class CORE_EXPORT Node : public EventTarget { NodeList* childNodes(); Node* firstChild() const; Node* lastChild() const; - Node* getRootNode(const GetRootNodeOptions&) const; + Node* getRootNode(const GetRootNodeOptions*) const; + + // Scroll Customization API. See crbug.com/410974 for details. + void setDistributeScroll(V8ScrollStateCallback*, + const String& native_scroll_behavior); + void setApplyScroll(V8ScrollStateCallback*, + const String& native_scroll_behavior); + void SetApplyScroll(ScrollStateCallback*); + void RemoveApplyScroll(); + ScrollStateCallback* GetApplyScroll(); + void NativeDistributeScroll(ScrollState&); + void NativeApplyScroll(ScrollState&); + void CallDistributeScroll(ScrollState&); + void CallApplyScroll(ScrollState&); + void WillBeginCustomizedScrollPhase(scroll_customization::ScrollDirection); + void DidEndCustomizedScrollPhase(); + Node& TreeRoot() const; Node& ShadowIncludingRoot() const; // closed-shadow-hidden is defined at @@ -236,6 +258,8 @@ class CORE_EXPORT Node : public EventTarget { String textContent(bool convert_brs_to_newlines = false) const; void setTextContent(const String&); + void textContent(StringOrTrustedScript& result); + virtual void setTextContent(const StringOrTrustedScript&, ExceptionState&); bool SupportsAltText(); @@ -442,6 +466,9 @@ class CORE_EXPORT Node : public EventTarget { void SetNeedsStyleRecalc(StyleChangeType, const StyleChangeReasonForTracing&); void ClearNeedsStyleRecalc(); + // Propagates a dirty bit breadcrumb for this element up the ancestor chain. + void MarkAncestorsWithChildNeedsStyleRecalc(); + bool NeedsReattachLayoutTree() const { return GetFlag(kNeedsReattachLayoutTree); } @@ -461,6 +488,11 @@ class CORE_EXPORT Node : public EventTarget { void MarkAncestorsWithChildNeedsReattachLayoutTree(); + void SetForceReattachLayoutTree() { SetFlag(kForceReattachLayoutTree); } + bool GetForceReattachLayoutTree() { + return GetFlag(kForceReattachLayoutTree); + } + bool NeedsDistributionRecalc() const; bool ChildNeedsDistributionRecalc() const { @@ -512,7 +544,7 @@ class CORE_EXPORT Node : public EventTarget { // Please don't use this function. // Background: When we investigated the usage of (old) UpdateDistribution, - // some caller's intents were unclear. Thus, we had to introduce this funtion + // some caller's intents were unclear. Thus, we had to introduce this function // for the sake of safety. If we can figure out the intent of each caller, we // can replace that with calling UpdateDistributionForFlatTreeTraversal (or // just RecalcSlotAssignments()) on a case-by-case basis. @@ -611,7 +643,7 @@ class CORE_EXPORT Node : public EventTarget { // Whether or not a selection can be started in this object virtual bool CanStartSelection() const; - // ----------------------------------------------------------------------------- + // --------------------------------------------------------------------------- // Integration with layout tree // As layoutObject() includes a branch you should avoid calling it repeatedly @@ -637,7 +669,6 @@ class CORE_EXPORT Node : public EventTarget { // objects when we need to do whitespace re-attachment. LayoutObject* previous_in_flow = nullptr; bool performing_reattach = false; - bool clear_invalidation = false; // True if the previous_in_flow member is up-to-date, even if it is nullptr. bool use_previous_in_flow = false; @@ -666,20 +697,26 @@ class CORE_EXPORT Node : public EventTarget { // such a method (on Document and Element). bool ShouldCallRecalcStyle(StyleRecalcChange); + // --------------------------------------------------------------------------- + // Inline ComputedStyle accessors + // + // Note that the following 'inline' functions are not defined in this header, + // but in node_computed_style.h. Please include that file if you want to use + // these functions. + // Wrapper for nodes that don't have a layoutObject, but still cache the style // (like HTMLOptionElement). - ComputedStyle* MutableComputedStyle() const; - const ComputedStyle* GetComputedStyle() const; - const ComputedStyle* ParentComputedStyle() const; - - const ComputedStyle& ComputedStyleRef() const; + inline ComputedStyle* MutableComputedStyle() const; + inline const ComputedStyle* GetComputedStyle() const; + inline const ComputedStyle* ParentComputedStyle() const; + inline const ComputedStyle& ComputedStyleRef() const; const ComputedStyle* EnsureComputedStyle( PseudoId pseudo_element_specifier = kPseudoIdNone) { return VirtualEnsureComputedStyle(pseudo_element_specifier); } - // ----------------------------------------------------------------------------- + // --------------------------------------------------------------------------- // Notification of document structure changes (see container_node.h for more // notification methods) // @@ -743,6 +780,10 @@ class CORE_EXPORT Node : public EventTarget { NodeListsNodeData* NodeLists(); void ClearNodeLists(); + FlatTreeNodeData* GetFlatTreeNodeData() const; + FlatTreeNodeData& EnsureFlatTreeNodeData(); + void ClearFlatTreeNodeData(); + virtual bool WillRespondToMouseMoveEvents(); virtual bool WillRespondToMouseClickEvents(); virtual bool WillRespondToTouchEvents(); @@ -842,6 +883,8 @@ class CORE_EXPORT Node : public EventTarget { return GetFlag(kInDOMNodeRemovedHandler); } + bool IsEffectiveRootScroller() const; + // If the node is a plugin, then this returns its WebPluginContainer. WebPluginContainerImpl* GetWebPluginContainer() const; @@ -900,11 +943,13 @@ class CORE_EXPORT Node : public EventTarget { // Temporary flag for some UseCounter items. crbug.com/859391. kInDOMNodeRemovedHandler = 1 << 29, + kForceReattachLayoutTree = 1 << 30, + kDefaultNodeFlags = kIsFinishedParsingChildrenFlag | kNeedsReattachStyleChange }; - // 3 bits remaining. + // 1 bit remaining. bool GetFlag(NodeFlags mask) const { return node_flags_ & mask; } void SetFlag(bool f, NodeFlags mask) { @@ -928,8 +973,6 @@ class CORE_EXPORT Node : public EventTarget { kCreateDocument = kCreateContainer | kIsConnectedFlag, kCreateV0InsertionPoint = kCreateHTMLElement | kIsV0InsertionPointFlag, kCreateEditingText = kCreateText | kHasNameOrIsEditingTextFlag, - kCreatePseudoElement = kDefaultNodeFlags | kIsContainerFlag | - kIsElementFlag | kNeedsReattachLayoutTree, }; Node(TreeScope*, ConstructionType); @@ -963,7 +1006,6 @@ class CORE_EXPORT Node : public EventTarget { void SetTreeScope(TreeScope* scope) { tree_scope_ = scope; } - void MarkAncestorsWithChildNeedsStyleRecalc(); static void MarkAncestorsWithChildNeedsStyleRecalc(Node* child) { child->MarkAncestorsWithChildNeedsStyleRecalc(); } diff --git a/chromium/third_party/blink/renderer/core/dom/node.idl b/chromium/third_party/blink/renderer/core/dom/node.idl index bc3277043de..73f5989dc29 100644 --- a/chromium/third_party/blink/renderer/core/dom/node.idl +++ b/chromium/third_party/blink/renderer/core/dom/node.idl @@ -38,6 +38,10 @@ interface Node : EventTarget { readonly attribute USVString baseURI; + // Scroll Customization API. See crbug.com/410974 for details. + [RuntimeEnabled=ScrollCustomization] void setApplyScroll(ScrollStateCallback scrollStateCallback, NativeScrollBehavior nativeScrollBehavior); + [RuntimeEnabled=ScrollCustomization] void setDistributeScroll(ScrollStateCallback scrollStateCallback, NativeScrollBehavior nativeScrollBehavior); + [Affects=Nothing, Measure] readonly attribute boolean isConnected; [Affects=Nothing, PerWorldBindings] readonly attribute Document? ownerDocument; [Affects=Nothing, PerWorldBindings, ImplementedAs=ParentNodeWithCounting] readonly attribute Node? parentNode; @@ -52,7 +56,7 @@ interface Node : EventTarget { [Affects=Nothing, CEReactions, CustomElementCallbacks] attribute DOMString? nodeValue; - [Affects=Nothing, CEReactions, CustomElementCallbacks] attribute DOMString? textContent; + [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute ScriptString? textContent; [CEReactions, CustomElementCallbacks] void normalize(); [NewObject, DoNotTestNewObject, CEReactions, CustomElementCallbacks, RaisesException] Node cloneNode(optional boolean deep = false); diff --git a/chromium/third_party/blink/renderer/core/dom/node_iterator.cc b/chromium/third_party/blink/renderer/core/dom/node_iterator.cc index eae9578a213..7c514b0bee0 100644 --- a/chromium/third_party/blink/renderer/core/dom/node_iterator.cc +++ b/chromium/third_party/blink/renderer/core/dom/node_iterator.cc @@ -185,7 +185,7 @@ void NodeIterator::UpdateForNodeRemoval(Node& removed_node, if (node) reference_node.node = node; } else { - // FIXME: This branch doesn't appear to have any LayoutTests. + // FIXME: This branch doesn't appear to have any web tests. node = NodeTraversal::Next(removed_node, root()); // Move out from under the node being removed if the reference node is // a descendant of the node being removed. diff --git a/chromium/third_party/blink/renderer/core/dom/node_iterator.h b/chromium/third_party/blink/renderer/core/dom/node_iterator.h index 8fb47a744d7..b3707560da9 100644 --- a/chromium/third_party/blink/renderer/core/dom/node_iterator.h +++ b/chromium/third_party/blink/renderer/core/dom/node_iterator.h @@ -41,9 +41,11 @@ class NodeIterator final : public ScriptWrappable, public NodeIteratorBase { static NodeIterator* Create(Node* root_node, unsigned what_to_show, V8NodeFilter* filter) { - return new NodeIterator(root_node, what_to_show, filter); + return MakeGarbageCollected<NodeIterator>(root_node, what_to_show, filter); } + NodeIterator(Node*, unsigned what_to_show, V8NodeFilter*); + Node* nextNode(ExceptionState&); Node* previousNode(ExceptionState&); void detach(); @@ -59,8 +61,6 @@ class NodeIterator final : public ScriptWrappable, public NodeIteratorBase { void Trace(blink::Visitor*) override; private: - NodeIterator(Node*, unsigned what_to_show, V8NodeFilter*); - class NodePointer { DISALLOW_NEW(); diff --git a/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h b/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h index 74ee59eb2e7..e562e8badda 100644 --- a/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h +++ b/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h @@ -136,7 +136,11 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> { return list; } - static NodeListsNodeData* Create() { return new NodeListsNodeData; } + static NodeListsNodeData* Create() { + return MakeGarbageCollected<NodeListsNodeData>(); + } + + NodeListsNodeData() : child_node_list_(nullptr) {} void InvalidateCaches(const QualifiedName* attr_name = nullptr); @@ -173,8 +177,6 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> { void Trace(blink::Visitor*); private: - NodeListsNodeData() : child_node_list_(nullptr) {} - // Can be a ChildNodeList or an EmptyNodeList. TraceWrapperMember<NodeList> child_node_list_; NodeListAtomicNameCacheMap atomic_name_caches_; diff --git a/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc b/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc index f340e29198f..89c6f58e7d3 100644 --- a/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc +++ b/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc @@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/dom/container_node.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/element_rare_data.h" +#include "third_party/blink/renderer/core/dom/flat_tree_node_data.h" #include "third_party/blink/renderer/core/dom/mutation_observer_registration.h" #include "third_party/blink/renderer/core/dom/node_lists_node_data.h" #include "third_party/blink/renderer/core/page/page.h" @@ -43,12 +44,12 @@ namespace blink { struct SameSizeAsNodeRareData { void* pointer_; - Member<void*> willbe_member_[2]; + Member<void*> willbe_member_[3]; unsigned bitfields_; }; NodeMutationObserverData* NodeMutationObserverData::Create() { - return new NodeMutationObserverData; + return MakeGarbageCollected<NodeMutationObserverData>(); } static_assert(sizeof(NodeRareData) == sizeof(SameSizeAsNodeRareData), @@ -83,6 +84,7 @@ void NodeMutationObserverData::RemoveRegistration( void NodeRareData::TraceAfterDispatch(blink::Visitor* visitor) { visitor->Trace(mutation_observer_data_); + visitor->Trace(flat_tree_node_data_); // Do not keep empty NodeListsNodeData objects around. if (node_lists_ && node_lists_->IsEmpty()) node_lists_.Clear(); @@ -114,6 +116,12 @@ NodeListsNodeData& NodeRareData::CreateNodeLists() { return *node_lists_; } +FlatTreeNodeData& NodeRareData::EnsureFlatTreeNodeData() { + if (!flat_tree_node_data_) + flat_tree_node_data_ = MakeGarbageCollected<FlatTreeNodeData>(); + return *flat_tree_node_data_; +} + // Ensure the 10 bits reserved for the connected_frame_count_ cannot overflow. static_assert(Page::kMaxNumberOfFrames < (1 << NodeRareData::kConnectedFrameCountBits), diff --git a/chromium/third_party/blink/renderer/core/dom/node_rare_data.h b/chromium/third_party/blink/renderer/core/dom/node_rare_data.h index 394632d899b..2e4ec9c7c6a 100644 --- a/chromium/third_party/blink/renderer/core/dom/node_rare_data.h +++ b/chromium/third_party/blink/renderer/core/dom/node_rare_data.h @@ -32,6 +32,7 @@ namespace blink { class ComputedStyle; enum class DynamicRestyleFlags; enum class ElementFlags; +class FlatTreeNodeData; class LayoutObject; class MutationObserverRegistration; class NodeListsNodeData; @@ -41,6 +42,8 @@ class NodeMutationObserverData final public: static NodeMutationObserverData* Create(); + NodeMutationObserverData() = default; + const HeapVector<TraceWrapperMember<MutationObserverRegistration>>& Registry() { return registry_; @@ -59,8 +62,6 @@ class NodeMutationObserverData final void Trace(blink::Visitor* visitor); private: - NodeMutationObserverData() = default; - HeapVector<TraceWrapperMember<MutationObserverRegistration>> registry_; HeapHashSet<TraceWrapperMember<MutationObserverRegistration>> transient_registry_; @@ -119,7 +120,16 @@ class NodeRareData : public GarbageCollectedFinalized<NodeRareData>, public NodeRareDataBase { public: static NodeRareData* Create(NodeRenderingData* node_layout_data) { - return new NodeRareData(node_layout_data); + return MakeGarbageCollected<NodeRareData>(node_layout_data); + } + + explicit NodeRareData(NodeRenderingData* node_layout_data) + : NodeRareDataBase(node_layout_data), + connected_frame_count_(0), + element_flags_(0), + restyle_flags_(0), + is_element_rare_data_(false) { + CHECK_NE(node_layout_data, nullptr); } void ClearNodeLists() { node_lists_.Clear(); } @@ -134,6 +144,9 @@ class NodeRareData : public GarbageCollectedFinalized<NodeRareData>, return *node_lists_; } + FlatTreeNodeData* GetFlatTreeNodeData() const { return flat_tree_node_data_; } + FlatTreeNodeData& EnsureFlatTreeNodeData(); + NodeMutationObserverData* MutationObserverData() { return mutation_observer_data_.Get(); } @@ -182,21 +195,12 @@ class NodeRareData : public GarbageCollectedFinalized<NodeRareData>, void TraceAfterDispatch(blink::Visitor*); void FinalizeGarbageCollectedObject(); - protected: - explicit NodeRareData(NodeRenderingData* node_layout_data) - : NodeRareDataBase(node_layout_data), - connected_frame_count_(0), - element_flags_(0), - restyle_flags_(0), - is_element_rare_data_(false) { - CHECK_NE(node_layout_data, nullptr); - } - private: NodeListsNodeData& CreateNodeLists(); TraceWrapperMember<NodeListsNodeData> node_lists_; TraceWrapperMember<NodeMutationObserverData> mutation_observer_data_; + Member<FlatTreeNodeData> flat_tree_node_data_; unsigned connected_frame_count_ : kConnectedFrameCountBits; unsigned element_flags_ : kNumberOfElementFlags; diff --git a/chromium/third_party/blink/renderer/core/dom/node_test.cc b/chromium/third_party/blink/renderer/core/dom/node_test.cc index 6f0641ce0b5..56563b04feb 100644 --- a/chromium/third_party/blink/renderer/core/dom/node_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/node_test.cc @@ -267,7 +267,7 @@ TEST_F(NodeTest, AttachContext_PreviousInFlow_Slotted) { ShadowRootType::kOpen); shadow_root.SetInnerHTMLFromString( "<div id=root style='display:contents'><span></span><slot></slot></div>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* root = shadow_root.getElementById("root"); Element* span = GetDocument().getElementById("inline"); @@ -297,19 +297,21 @@ TEST_F(NodeTest, HasMediaControlAncestor_Fail) { } TEST_F(NodeTest, HasMediaControlAncestor_MediaControlElement) { - FakeMediaControlElement* node = new FakeMediaControlElement(GetDocument()); + FakeMediaControlElement* node = + MakeGarbageCollected<FakeMediaControlElement>(GetDocument()); EXPECT_TRUE(node->HasMediaControlAncestor()); EXPECT_TRUE(InitializeUserAgentShadowTree(node)->HasMediaControlAncestor()); } TEST_F(NodeTest, HasMediaControlAncestor_MediaControls) { - FakeMediaControls* node = new FakeMediaControls(GetDocument()); + FakeMediaControls* node = + MakeGarbageCollected<FakeMediaControls>(GetDocument()); EXPECT_TRUE(node->HasMediaControlAncestor()); EXPECT_TRUE(InitializeUserAgentShadowTree(node)->HasMediaControlAncestor()); } TEST_F(NodeTest, appendChildProcessingInstructionNoStyleRecalc) { - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc()); ProcessingInstruction* pi = ProcessingInstruction::Create(GetDocument(), "A", "B"); @@ -318,7 +320,7 @@ TEST_F(NodeTest, appendChildProcessingInstructionNoStyleRecalc) { } TEST_F(NodeTest, appendChildCommentNoStyleRecalc) { - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc()); Comment* comment = Comment::Create(GetDocument(), "comment"); GetDocument().body()->appendChild(comment, ASSERT_NO_EXCEPTION); @@ -331,7 +333,7 @@ TEST_F(NodeTest, LazyReattachCommentAndPI) { ProcessingInstruction* pi = ProcessingInstruction::Create(GetDocument(), "A", "B"); body->appendChild(pi, ASSERT_NO_EXCEPTION); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Node* comment = body->firstChild(); EXPECT_EQ(Node::kCommentNode, comment->getNodeType()); diff --git a/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc b/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc index 988c02cdaf3..8c31f852a2c 100644 --- a/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc +++ b/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc @@ -152,23 +152,24 @@ unsigned NthIndexCache::NthLastOfTypeIndex(Element& element) { void NthIndexCache::CacheNthIndexDataForParent(Element& element) { DCHECK(element.parentNode()); if (!parent_map_) - parent_map_ = new ParentMap(); + parent_map_ = MakeGarbageCollected<ParentMap>(); ParentMap::AddResult add_result = parent_map_->insert(element.parentNode(), nullptr); DCHECK(add_result.is_new_entry); - add_result.stored_value->value = new NthIndexData(*element.parentNode()); + add_result.stored_value->value = + MakeGarbageCollected<NthIndexData>(*element.parentNode()); } NthIndexCache::IndexByType& NthIndexCache::EnsureTypeIndexMap( ContainerNode& parent) { if (!parent_map_for_type_) - parent_map_for_type_ = new ParentMapForType(); + parent_map_for_type_ = MakeGarbageCollected<ParentMapForType>(); ParentMapForType::AddResult add_result = parent_map_for_type_->insert(&parent, nullptr); if (add_result.is_new_entry) - add_result.stored_value->value = new IndexByType(); + add_result.stored_value->value = MakeGarbageCollected<IndexByType>(); DCHECK(add_result.stored_value->value); return *add_result.stored_value->value; @@ -179,8 +180,8 @@ void NthIndexCache::CacheNthOfTypeIndexDataForParent(Element& element) { IndexByType::AddResult add_result = EnsureTypeIndexMap(*element.parentNode()) .insert(element.tagName(), nullptr); DCHECK(add_result.is_new_entry); - add_result.stored_value->value = - new NthIndexData(*element.parentNode(), element.TagQName()); + add_result.stored_value->value = MakeGarbageCollected<NthIndexData>( + *element.parentNode(), element.TagQName()); } unsigned NthIndexData::NthIndex(Element& element) const { diff --git a/chromium/third_party/blink/renderer/core/dom/pausable_object_test.cc b/chromium/third_party/blink/renderer/core/dom/pausable_object_test.cc index 3d4081bd4c3..c43ea1e1457 100644 --- a/chromium/third_party/blink/renderer/core/dom/pausable_object_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/pausable_object_test.cc @@ -73,8 +73,8 @@ class PausableObjectTest : public testing::Test { PausableObjectTest::PausableObjectTest() : src_page_holder_(DummyPageHolder::Create(IntSize(800, 600))), dest_page_holder_(DummyPageHolder::Create(IntSize(800, 600))), - pausable_object_( - new MockPausableObject(&src_page_holder_->GetDocument())) { + pausable_object_(MakeGarbageCollected<MockPausableObject>( + &src_page_holder_->GetDocument())) { pausable_object_->PauseIfNeeded(); } diff --git a/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc b/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc index 6fd4deabd8a..78e52699a7d 100644 --- a/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc +++ b/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc @@ -46,7 +46,7 @@ namespace blink { -using namespace HTMLNames; +using namespace html_names; struct PresentationAttributeCacheKey { PresentationAttributeCacheKey() : tag_name(nullptr) {} @@ -76,7 +76,7 @@ using PresentationAttributeCache = AlreadyHashed>; static PresentationAttributeCache& GetPresentationAttributeCache() { DEFINE_STATIC_LOCAL(Persistent<PresentationAttributeCache>, cache, - (new PresentationAttributeCache)); + (MakeGarbageCollected<PresentationAttributeCache>())); return *cache; } @@ -105,7 +105,7 @@ static void MakePresentationAttributeCacheKey( return; // FIXME: Background URL may depend on the base URL and can't be shared. // Disallow caching. - if (attr.GetName() == backgroundAttr) + if (attr.GetName() == kBackgroundAttr) return; result.attributes_and_values.push_back( std::make_pair(attr.LocalName().Impl(), attr.Value())); @@ -182,7 +182,7 @@ CSSPropertyValueSet* ComputePresentationAttributeStyle(Element& element) { return style; PresentationAttributeCacheEntry* new_entry = - new PresentationAttributeCacheEntry; + MakeGarbageCollected<PresentationAttributeCacheEntry>(); new_entry->key = cache_key; new_entry->value = style; diff --git a/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc b/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc index bfe8e343948..8178485b71f 100644 --- a/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc +++ b/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc @@ -53,7 +53,7 @@ inline ProcessingInstruction::ProcessingInstruction(Document& document, ProcessingInstruction* ProcessingInstruction::Create(Document& document, const String& target, const String& data) { - return new ProcessingInstruction(document, target, data); + return MakeGarbageCollected<ProcessingInstruction>(document, target, data); } ProcessingInstruction::~ProcessingInstruction() = default; @@ -87,8 +87,11 @@ Node* ProcessingInstruction::Clone(Document& factory, CloneChildrenFlag) const { } void ProcessingInstruction::DidAttributeChanged() { - if (sheet_) + if (sheet_) { + if (sheet_->IsLoading()) + RemovePendingSheet(); ClearSheet(); + } String href; String charset; @@ -151,7 +154,8 @@ void ProcessingInstruction::Process(const String& href, const String& charset) { return; ResourceLoaderOptions options; - options.initiator_info.name = FetchInitiatorTypeNames::processinginstruction; + options.initiator_info.name = + fetch_initiator_type_names::kProcessinginstruction; FetchParameters params(ResourceRequest(GetDocument().CompleteURL(href)), options); loading_ = true; @@ -179,8 +183,7 @@ bool ProcessingInstruction::IsLoading() const { bool ProcessingInstruction::SheetLoaded() { if (!IsLoading()) { if (!DocumentXSLT::SheetLoaded(GetDocument(), this)) - GetDocument().GetStyleEngine().RemovePendingSheet(*this, - style_engine_context_); + RemovePendingSheet(); return true; } return false; @@ -264,6 +267,9 @@ void ProcessingInstruction::RemovedFrom(ContainerNode& insertion_point) { *this, insertion_point); } + if (IsLoading()) + RemovePendingSheet(); + if (sheet_) { DCHECK_EQ(sheet_->ownerNode(), this); ClearSheet(); @@ -275,12 +281,14 @@ void ProcessingInstruction::RemovedFrom(ContainerNode& insertion_point) { void ProcessingInstruction::ClearSheet() { DCHECK(sheet_); - if (sheet_->IsLoading()) - GetDocument().GetStyleEngine().RemovePendingSheet(*this, - style_engine_context_); sheet_.Release()->ClearOwnerNode(); } +void ProcessingInstruction::RemovePendingSheet() { + GetDocument().GetStyleEngine().RemovePendingSheet(*this, + style_engine_context_); +} + void ProcessingInstruction::Trace(blink::Visitor* visitor) { visitor->Trace(sheet_); visitor->Trace(listener_for_xslt_); diff --git a/chromium/third_party/blink/renderer/core/dom/processing_instruction.h b/chromium/third_party/blink/renderer/core/dom/processing_instruction.h index 66e8683eb92..8341102cbd7 100644 --- a/chromium/third_party/blink/renderer/core/dom/processing_instruction.h +++ b/chromium/third_party/blink/renderer/core/dom/processing_instruction.h @@ -41,6 +41,8 @@ class CORE_EXPORT ProcessingInstruction final : public CharacterData, static ProcessingInstruction* Create(Document&, const String& target, const String& data); + + ProcessingInstruction(Document&, const String& target, const String& data); ~ProcessingInstruction() override; void Trace(blink::Visitor*) override; @@ -72,8 +74,6 @@ class CORE_EXPORT ProcessingInstruction final : public CharacterData, void ClearEventListenerForXSLT(); private: - ProcessingInstruction(Document&, const String& target, const String& data); - String nodeName() const override; NodeType getNodeType() const override; Node* Clone(Document&, CloneChildrenFlag) const override; @@ -91,6 +91,7 @@ class CORE_EXPORT ProcessingInstruction final : public CharacterData, void ParseStyleSheet(const String& sheet); void ClearSheet(); + void RemovePendingSheet(); String DebugName() const override { return "ProcessingInstruction"; } diff --git a/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc b/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc index a2a656c9639..805af538212 100644 --- a/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc +++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc @@ -41,7 +41,7 @@ namespace blink { PseudoElement* PseudoElement::Create(Element* parent, PseudoId pseudo_id) { if (pseudo_id == kPseudoIdFirstLetter) return FirstLetterPseudoElement::Create(parent); - return new PseudoElement(parent, pseudo_id); + return MakeGarbageCollected<PseudoElement>(parent, pseudo_id); } const QualifiedName& PseudoElementTagName(PseudoId pseudo_id) { @@ -90,14 +90,14 @@ String PseudoElement::PseudoElementNameForEvents(PseudoId pseudo_id) { PseudoElement::PseudoElement(Element* parent, PseudoId pseudo_id) : Element(PseudoElementTagName(pseudo_id), &parent->GetDocument(), - kCreatePseudoElement), + kCreateElement), pseudo_id_(pseudo_id) { DCHECK_NE(pseudo_id, kPseudoIdNone); parent->GetTreeScope().AdoptIfNeeded(*this); SetParentOrShadowHostNode(parent); SetHasCustomStyleCallbacks(); if ((pseudo_id == kPseudoIdBefore || pseudo_id == kPseudoIdAfter) && - parent->HasTagName(HTMLNames::inputTag)) { + parent->HasTagName(html_names::kInputTag)) { UseCounter::Count(parent->GetDocument(), WebFeature::kPseudoBeforeAfterForInputElement); } @@ -184,29 +184,6 @@ bool PseudoElement::LayoutObjectIsNeeded(const ComputedStyle& style) const { return PseudoElementLayoutObjectIsNeeded(&style); } -void PseudoElement::DidRecalcStyle(StyleRecalcChange change) { - // If the pseudo element is being re-attached, its anonymous LayoutObjects for - // generated content will be destroyed and possibly recreated during layout - // tree rebuild. Thus, propagating style to generated content now is futile. - if (change == kReattach) - return; - if (!GetLayoutObject()) - return; - - // The layoutObjects inside pseudo elements are anonymous so they don't get - // notified of recalcStyle and must have the style propagated downward - // manually similar to LayoutObject::PropagateStyleToAnonymousChildren. - LayoutObject* layout_object = GetLayoutObject(); - for (LayoutObject* child = layout_object->NextInPreOrder(layout_object); - child; child = child->NextInPreOrder(layout_object)) { - // We only manage the style for the generated content items. - if (!child->IsText() && !child->IsQuote() && !child->IsImage()) - continue; - - child->SetPseudoStyle(layout_object->MutableStyle()); - } -} - Node* PseudoElement::InnerNodeForHitTesting() const { return ParentOrShadowHostNode(); } diff --git a/chromium/third_party/blink/renderer/core/dom/pseudo_element.h b/chromium/third_party/blink/renderer/core/dom/pseudo_element.h index df0e5571928..d3da1693511 100644 --- a/chromium/third_party/blink/renderer/core/dom/pseudo_element.h +++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element.h @@ -38,6 +38,8 @@ class CORE_EXPORT PseudoElement : public Element { public: static PseudoElement* Create(Element* parent, PseudoId); + PseudoElement(Element*, PseudoId); + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; void AttachLayoutTree(AttachContext&) override; bool LayoutObjectIsNeeded(const ComputedStyle&) const override; @@ -58,12 +60,7 @@ class CORE_EXPORT PseudoElement : public Element { virtual void Dispose(); - protected: - PseudoElement(Element*, PseudoId); - private: - void DidRecalcStyle(StyleRecalcChange) override; - PseudoId pseudo_id_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h b/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h index 2ab87d442b5..76db5ac2b0d 100644 --- a/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h +++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h @@ -14,6 +14,9 @@ namespace blink { class PseudoElementData final : public GarbageCollected<PseudoElementData> { public: static PseudoElementData* Create(); + + PseudoElementData() = default; + void SetPseudoElement(PseudoId, PseudoElement*); PseudoElement* GetPseudoElement(PseudoId) const; bool HasPseudoElements() const; @@ -26,7 +29,6 @@ class PseudoElementData final : public GarbageCollected<PseudoElementData> { } private: - PseudoElementData() = default; Member<PseudoElement> generated_before_; Member<PseudoElement> generated_after_; Member<PseudoElement> generated_first_letter_; @@ -35,7 +37,7 @@ class PseudoElementData final : public GarbageCollected<PseudoElementData> { }; inline PseudoElementData* PseudoElementData::Create() { - return new PseudoElementData(); + return MakeGarbageCollected<PseudoElementData>(); } inline bool PseudoElementData::HasPseudoElements() const { diff --git a/chromium/third_party/blink/renderer/core/dom/qualified_name.h b/chromium/third_party/blink/renderer/core/dom/qualified_name.h index ea0348d47cc..48ff2473771 100644 --- a/chromium/third_party/blink/renderer/core/dom/qualified_name.h +++ b/chromium/third_party/blink/renderer/core/dom/qualified_name.h @@ -52,7 +52,7 @@ class CORE_EXPORT QualifiedName { USING_FAST_MALLOC(QualifiedName); public: - class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> { + class CORE_EXPORT QualifiedNameImpl : public RefCounted<QualifiedNameImpl> { public: static scoped_refptr<QualifiedNameImpl> Create( const AtomicString& prefix, @@ -223,6 +223,8 @@ CORE_EXPORT std::ostream& operator<<(std::ostream&, const QualifiedName&); } // namespace blink +WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::QualifiedName); + namespace WTF { template <> diff --git a/chromium/third_party/blink/renderer/core/dom/range.cc b/chromium/third_party/blink/renderer/core/dom/range.cc index 7832ffd3a74..2a626e82804 100644 --- a/chromium/third_party/blink/renderer/core/dom/range.cc +++ b/chromium/third_party/blink/renderer/core/dom/range.cc @@ -129,7 +129,7 @@ inline Range::Range(Document& owner_document) } Range* Range::Create(Document& owner_document) { - return new Range(owner_document); + return MakeGarbageCollected<Range>(owner_document); } inline Range::Range(Document& owner_document, @@ -153,17 +153,17 @@ Range* Range::Create(Document& owner_document, unsigned start_offset, Node* end_container, unsigned end_offset) { - return new Range(owner_document, start_container, start_offset, end_container, - end_offset); + return MakeGarbageCollected<Range>(owner_document, start_container, + start_offset, end_container, end_offset); } Range* Range::Create(Document& owner_document, const Position& start, const Position& end) { - return new Range(owner_document, start.ComputeContainerNode(), - start.ComputeOffsetInContainerNode(), - end.ComputeContainerNode(), - end.ComputeOffsetInContainerNode()); + return MakeGarbageCollected<Range>( + owner_document, start.ComputeContainerNode(), + start.ComputeOffsetInContainerNode(), end.ComputeContainerNode(), + end.ComputeOffsetInContainerNode()); } void Range::Dispose() { @@ -1435,12 +1435,33 @@ static inline void BoundaryNodeChildrenWillBeRemoved( } } +static void BoundaryShadowNodeChildrenWillBeRemoved( + RangeBoundaryPoint& boundary, + ContainerNode& container) { + for (Node* node_to_be_removed = container.firstChild(); node_to_be_removed; + node_to_be_removed = node_to_be_removed->nextSibling()) { + for (Node* n = &boundary.Container(); n; + n = n->ParentOrShadowHostElement()) { + if (n == node_to_be_removed) { + boundary.SetToStartOfNode(container); + return; + } + } + } +} + void Range::NodeChildrenWillBeRemoved(ContainerNode& container) { DCHECK_EQ(container.GetDocument(), owner_document_); BoundaryNodeChildrenWillBeRemoved(start_, container); BoundaryNodeChildrenWillBeRemoved(end_, container); } +void Range::FixupRemovedChildrenAcrossShadowBoundary(ContainerNode& container) { + DCHECK_EQ(container.GetDocument(), owner_document_); + BoundaryShadowNodeChildrenWillBeRemoved(start_, container); + BoundaryShadowNodeChildrenWillBeRemoved(end_, container); +} + static inline void BoundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node& node_to_be_removed) { if (boundary.ChildBefore() == node_to_be_removed) { @@ -1456,6 +1477,19 @@ static inline void BoundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, } } +static inline void BoundaryShadowNodeWillBeRemoved(RangeBoundaryPoint& boundary, + Node& node_to_be_removed) { + DCHECK_NE(boundary.ChildBefore(), node_to_be_removed); + + for (Node* node = &boundary.Container(); node; + node = node->ParentOrShadowHostElement()) { + if (node == node_to_be_removed) { + boundary.SetToBeforeChild(node_to_be_removed); + return; + } + } +} + void Range::NodeWillBeRemoved(Node& node) { DCHECK_EQ(node.GetDocument(), owner_document_); DCHECK_NE(node, owner_document_.Get()); @@ -1468,6 +1502,11 @@ void Range::NodeWillBeRemoved(Node& node) { BoundaryNodeWillBeRemoved(end_, node); } +void Range::FixupRemovedNodeAcrossShadowBoundary(Node& node) { + BoundaryShadowNodeWillBeRemoved(start_, node); + BoundaryShadowNodeWillBeRemoved(end_, node); +} + static inline void BoundaryTextInserted(RangeBoundaryPoint& boundary, const CharacterData& text, unsigned offset, @@ -1579,11 +1618,12 @@ void Range::expand(const String& unit, ExceptionState& exception_state) { VisiblePosition start = CreateVisiblePosition(StartPosition()); VisiblePosition end = CreateVisiblePosition(EndPosition()); if (unit == "word") { - start = StartOfWord(start); - end = EndOfWord(end); + start = CreateVisiblePosition(StartOfWordPosition(start.DeepEquivalent())); + end = CreateVisiblePosition(EndOfWordPosition(end.DeepEquivalent())); } else if (unit == "sentence") { - start = StartOfSentence(start); - end = EndOfSentence(end); + start = + CreateVisiblePosition(StartOfSentencePosition(start.DeepEquivalent())); + end = CreateVisiblePosition(EndOfSentence(end.DeepEquivalent())); } else if (unit == "block") { start = StartOfParagraph(start); end = EndOfParagraph(end); diff --git a/chromium/third_party/blink/renderer/core/dom/range.h b/chromium/third_party/blink/renderer/core/dom/range.h index 66f75b09717..ec46883ee63 100644 --- a/chromium/third_party/blink/renderer/core/dom/range.h +++ b/chromium/third_party/blink/renderer/core/dom/range.h @@ -61,6 +61,13 @@ class CORE_EXPORT Range final : public ScriptWrappable { unsigned end_offset); static Range* Create(Document&, const Position&, const Position&); + explicit Range(Document&); + Range(Document&, + Node* start_container, + unsigned start_offset, + Node* end_container, + unsigned end_offset); + void Dispose(); Document& OwnerDocument() const { @@ -148,6 +155,11 @@ class CORE_EXPORT Range final : public ScriptWrappable { void NodeChildrenWillBeRemoved(ContainerNode&); void NodeWillBeRemoved(Node&); + // They are special fixups only for sequential focus navigation + // starting point. + void FixupRemovedChildrenAcrossShadowBoundary(ContainerNode& container); + void FixupRemovedNodeAcrossShadowBoundary(Node& node); + void DidInsertText(const CharacterData&, unsigned offset, unsigned length); void DidRemoveText(const CharacterData&, unsigned offset, unsigned length); void DidMergeTextNodes(const NodeWithIndex& old_node, unsigned offset); @@ -167,13 +179,6 @@ class CORE_EXPORT Range final : public ScriptWrappable { void Trace(blink::Visitor*) override; private: - explicit Range(Document&); - Range(Document&, - Node* start_container, - unsigned start_offset, - Node* end_container, - unsigned end_offset); - void SetDocument(Document&); void CheckNodeBA(Node*, ExceptionState&) const; diff --git a/chromium/third_party/blink/renderer/core/dom/range_test.cc b/chromium/third_party/blink/renderer/core/dom/range_test.cc index 2855792021d..187b7735f5e 100644 --- a/chromium/third_party/blink/renderer/core/dom/range_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/range_test.cc @@ -40,7 +40,7 @@ TEST_F(RangeTest, extractContentsWithDOMMutationEvent) { GetDocument().body()->SetInnerHTMLFromString("<span><b>abc</b>def</span>"); GetDocument().GetSettings()->SetScriptEnabled(true); Element* const script_element = - GetDocument().CreateRawElement(HTMLNames::scriptTag); + GetDocument().CreateRawElement(html_names::kScriptTag); script_element->setTextContent( "let count = 0;" "const span = document.querySelector('span');" @@ -54,7 +54,7 @@ TEST_F(RangeTest, extractContentsWithDOMMutationEvent) { Element* const span_element = GetDocument().QuerySelector("span"); Range* const range = Range::Create(GetDocument(), span_element, 0, span_element, 1); - Element* const result = GetDocument().CreateRawElement(HTMLNames::divTag); + Element* const result = GetDocument().CreateRawElement(html_names::kDivTag); result->AppendChild(range->extractContents(ASSERT_NO_EXCEPTION)); EXPECT_EQ("<b>abc</b>", result->InnerHTMLAsString()) @@ -302,7 +302,7 @@ TEST_F(RangeTest, BoundingRectMustIndependentFromSelection) { SelectionInDOMTree::Builder() .SetBaseAndExtent(EphemeralRange(range)) .Build()); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_EQ(Selection().SelectedText(), "x x"); const FloatRect rect_after = range->BoundingRect(); EXPECT_EQ(rect_before, rect_after); diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc index 685a7871c3e..0bcedc826eb 100644 --- a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc +++ b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc @@ -28,6 +28,7 @@ #include "third_party/blink/renderer/core/css/media_query_list_listener.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/event_interface_names.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" @@ -66,7 +67,7 @@ void ScriptedAnimationController::Unpause() { } void ScriptedAnimationController::DispatchEventsAndCallbacksForPrinting() { - DispatchEvents(EventNames::MediaQueryListEvent); + DispatchEvents(event_interface_names::kMediaQueryListEvent); CallMediaQueryListListeners(); } diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h index 6c8855f65b4..a1ca3e62ab0 100644 --- a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h +++ b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h @@ -47,8 +47,10 @@ class CORE_EXPORT ScriptedAnimationController public NameClient { public: static ScriptedAnimationController* Create(Document* document) { - return new ScriptedAnimationController(document); + return MakeGarbageCollected<ScriptedAnimationController>(document); } + + explicit ScriptedAnimationController(Document*); virtual ~ScriptedAnimationController() = default; void Trace(blink::Visitor*); @@ -88,8 +90,6 @@ class CORE_EXPORT ScriptedAnimationController bool NextFrameHasPendingRAF() const { return next_frame_has_pending_raf_; } private: - explicit ScriptedAnimationController(Document*); - void ScheduleAnimationIfNeeded(); void RunTasks(); diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc index 9afaa953e7d..8be822368a7 100644 --- a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc @@ -121,7 +121,7 @@ class RunTaskEventListener final : public EventListener { public: RunTaskEventListener(base::RepeatingClosure task) : EventListener(kCPPEventListenerType), task_(std::move(task)) {} - void handleEvent(ExecutionContext*, Event*) override { task_.Run(); } + void Invoke(ExecutionContext*, Event*) override { task_.Run(); } bool operator==(const EventListener& other) const override { return this == &other; } diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc index f38852efb04..d9bb0cbdd94 100644 --- a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc +++ b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc @@ -38,10 +38,7 @@ class IdleRequestCallbackWrapper callback_wrapper->Controller()) { // If we are going to yield immediately, reschedule the callback for // later. - if (Platform::Current() - ->CurrentThread() - ->Scheduler() - ->ShouldYieldForHighPriorityWork()) { + if (ThreadScheduler::Current()->ShouldYieldForHighPriorityWork()) { controller->ScheduleCallback(std::move(callback_wrapper), /* timeout_millis */ 0); return; @@ -94,7 +91,7 @@ void ScriptedIdleTaskController::V8IdleTask::invoke(IdleDeadline* deadline) { ScriptedIdleTaskController::ScriptedIdleTaskController( ExecutionContext* context) : PausableObject(context), - scheduler_(Platform::Current()->CurrentThread()->Scheduler()), + scheduler_(ThreadScheduler::Current()), next_callback_id_(0), paused_(false) { PauseIfNeeded(); @@ -122,12 +119,12 @@ int ScriptedIdleTaskController::NextCallbackId() { ScriptedIdleTaskController::CallbackId ScriptedIdleTaskController::RegisterCallback( IdleTask* idle_task, - const IdleRequestOptions& options) { + const IdleRequestOptions* options) { DCHECK(idle_task); CallbackId id = NextCallbackId(); idle_tasks_.Set(id, idle_task); - long long timeout_millis = options.timeout(); + long long timeout_millis = options->timeout(); probe::AsyncTaskScheduled(GetExecutionContext(), "requestIdleCallback", idle_task); @@ -137,7 +134,7 @@ ScriptedIdleTaskController::RegisterCallback( ScheduleCallback(std::move(callback_wrapper), timeout_millis); TRACE_EVENT_INSTANT1("devtools.timeline", "RequestIdleCallback", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorIdleCallbackRequestEvent::Data( + inspector_idle_callback_request_event::Data( GetExecutionContext(), id, timeout_millis)); return id; } @@ -163,7 +160,7 @@ void ScriptedIdleTaskController::CancelCallback(CallbackId id) { TRACE_EVENT_INSTANT1( "devtools.timeline", "CancelIdleCallback", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorIdleCallbackCancelEvent::Data(GetExecutionContext(), id)); + inspector_idle_callback_cancel_event::Data(GetExecutionContext(), id)); if (!IsValidCallbackId(id)) return; @@ -214,7 +211,7 @@ void ScriptedIdleTaskController::RunCallback( TRACE_EVENT1( "devtools.timeline", "FireIdleCallback", "data", - InspectorIdleCallbackFireEvent::Data( + inspector_idle_callback_fire_event::Data( GetExecutionContext(), id, allotted_time.InMillisecondsF(), callback_type == IdleDeadline::CallbackType::kCalledByTimeout)); idle_task->invoke(IdleDeadline::Create(deadline, callback_type)); diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h index 55adb1fe191..c734b7cef99 100644 --- a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h +++ b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h @@ -31,8 +31,10 @@ class CORE_EXPORT ScriptedIdleTaskController public: static ScriptedIdleTaskController* Create(ExecutionContext* context) { - return new ScriptedIdleTaskController(context); + return MakeGarbageCollected<ScriptedIdleTaskController>(context); } + + explicit ScriptedIdleTaskController(ExecutionContext*); ~ScriptedIdleTaskController() override; void Trace(blink::Visitor*) override; @@ -58,18 +60,20 @@ class CORE_EXPORT ScriptedIdleTaskController class V8IdleTask : public IdleTask { public: static V8IdleTask* Create(V8IdleRequestCallback* callback) { - return new V8IdleTask(callback); + return MakeGarbageCollected<V8IdleTask>(callback); } + + explicit V8IdleTask(V8IdleRequestCallback*); ~V8IdleTask() override = default; + void invoke(IdleDeadline*) override; void Trace(blink::Visitor*) override; private: - explicit V8IdleTask(V8IdleRequestCallback*); TraceWrapperMember<V8IdleRequestCallback> callback_; }; - int RegisterCallback(IdleTask*, const IdleRequestOptions&); + int RegisterCallback(IdleTask*, const IdleRequestOptions*); void CancelCallback(CallbackId); // PausableObject interface. @@ -83,7 +87,6 @@ class CORE_EXPORT ScriptedIdleTaskController private: friend class internal::IdleRequestCallbackWrapper; - explicit ScriptedIdleTaskController(ExecutionContext*); void ScheduleCallback(scoped_refptr<internal::IdleRequestCallbackWrapper>, long long timeout_millis); diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc index 3da0c695f5e..b17a00e9b99 100644 --- a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc @@ -6,12 +6,11 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_callback.h" #include "third_party/blink/renderer/core/dom/idle_request_options.h" #include "third_party/blink/renderer/core/testing/null_execution_context.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" -#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h" +#include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h" #include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -56,11 +55,9 @@ class MockScriptedIdleTaskControllerScheduler final : public ThreadScheduler { return base::TimeTicks(); } - void AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void AddTaskObserver(Thread::TaskObserver* task_observer) override {} - void RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void RemoveTaskObserver(Thread::TaskObserver* task_observer) override {} void AddRAILModeObserver(scheduler::WebRAILModeObserver*) override {} @@ -86,7 +83,9 @@ class MockIdleTask : public ScriptedIdleTaskController::IdleTask { class ScriptedIdleTaskControllerTest : public testing::Test { public: - void SetUp() override { execution_context_ = new NullExecutionContext(); } + void SetUp() override { + execution_context_ = MakeGarbageCollected<NullExecutionContext>(); + } protected: Persistent<ExecutionContext> execution_context_; @@ -94,16 +93,14 @@ class ScriptedIdleTaskControllerTest : public testing::Test { TEST_F(ScriptedIdleTaskControllerTest, RunCallback) { MockScriptedIdleTaskControllerScheduler scheduler(ShouldYield::DONT_YIELD); - ScopedTestingPlatformSupport<TestingPlatformSupportWithCustomScheduler, - ThreadScheduler*> - platform(&scheduler); + ScopedSchedulerOverrider scheduler_overrider(&scheduler); NullExecutionContext execution_context; ScriptedIdleTaskController* controller = ScriptedIdleTaskController::Create(execution_context_); Persistent<MockIdleTask> idle_task(new MockIdleTask()); - IdleRequestOptions options; + IdleRequestOptions* options = IdleRequestOptions::Create(); EXPECT_FALSE(scheduler.HasIdleTask()); int id = controller->RegisterCallback(idle_task, options); EXPECT_TRUE(scheduler.HasIdleTask()); @@ -117,16 +114,14 @@ TEST_F(ScriptedIdleTaskControllerTest, RunCallback) { TEST_F(ScriptedIdleTaskControllerTest, DontRunCallbackWhenAskedToYield) { MockScriptedIdleTaskControllerScheduler scheduler(ShouldYield::YIELD); - ScopedTestingPlatformSupport<TestingPlatformSupportWithCustomScheduler, - ThreadScheduler*> - platform(&scheduler); + ScopedSchedulerOverrider scheduler_overrider(&scheduler); NullExecutionContext execution_context; ScriptedIdleTaskController* controller = ScriptedIdleTaskController::Create(execution_context_); Persistent<MockIdleTask> idle_task(new MockIdleTask()); - IdleRequestOptions options; + IdleRequestOptions* options = IdleRequestOptions::Create(); int id = controller->RegisterCallback(idle_task, options); EXPECT_NE(0, id); diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_task_queue.cc b/chromium/third_party/blink/renderer/core/dom/scripted_task_queue.cc index ce70145f354..0b3319f95b5 100644 --- a/chromium/third_party/blink/renderer/core/dom/scripted_task_queue.cc +++ b/chromium/third_party/blink/renderer/core/dom/scripted_task_queue.cc @@ -11,6 +11,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_task_queue_post_callback.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc b/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc index e2bb4c07f16..b555a8709c7 100644 --- a/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc @@ -40,8 +40,8 @@ class ShadowDOMVTest : public SimTest {}; TEST_F(ShadowDOMVTest, FeatureSetId) { LoadURL("about:blank"); - auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); - auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); + auto* host = GetDocument().CreateRawElement(html_names::kDivTag); + auto* content = GetDocument().CreateRawElement(html_names::kContentTag); content->setAttribute("select", "#foo"); host->CreateV0ShadowRootForTesting().AppendChild(content); EXPECT_TRUE(HasSelectorForIdInShadow(host, "foo")); @@ -57,8 +57,8 @@ TEST_F(ShadowDOMVTest, FeatureSetId) { TEST_F(ShadowDOMVTest, FeatureSetClassName) { LoadURL("about:blank"); - auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); - auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); + auto* host = GetDocument().CreateRawElement(html_names::kDivTag); + auto* content = GetDocument().CreateRawElement(html_names::kContentTag); content->setAttribute("select", ".foo"); host->CreateV0ShadowRootForTesting().AppendChild(content); EXPECT_TRUE(HasSelectorForClassInShadow(host, "foo")); @@ -74,8 +74,8 @@ TEST_F(ShadowDOMVTest, FeatureSetClassName) { TEST_F(ShadowDOMVTest, FeatureSetAttributeName) { LoadURL("about:blank"); - auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); - auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); + auto* host = GetDocument().CreateRawElement(html_names::kDivTag); + auto* content = GetDocument().CreateRawElement(html_names::kContentTag); content->setAttribute("select", "div[foo]"); host->CreateV0ShadowRootForTesting().AppendChild(content); EXPECT_TRUE(HasSelectorForAttributeInShadow(host, "foo")); @@ -91,8 +91,8 @@ TEST_F(ShadowDOMVTest, FeatureSetAttributeName) { TEST_F(ShadowDOMVTest, FeatureSetMultipleSelectors) { LoadURL("about:blank"); - auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); - auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); + auto* host = GetDocument().CreateRawElement(html_names::kDivTag); + auto* content = GetDocument().CreateRawElement(html_names::kContentTag); content->setAttribute("select", "#foo,.bar,div[baz]"); host->CreateV0ShadowRootForTesting().AppendChild(content); EXPECT_TRUE(HasSelectorForIdInShadow(host, "foo")); @@ -108,7 +108,7 @@ TEST_F(ShadowDOMVTest, FeatureSetMultipleSelectors) { TEST_F(ShadowDOMVTest, FeatureSetSubtree) { LoadURL("about:blank"); - auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); + auto* host = GetDocument().CreateRawElement(html_names::kDivTag); host->CreateV0ShadowRootForTesting().SetInnerHTMLFromString(R"HTML( <div> <div></div> @@ -126,12 +126,12 @@ TEST_F(ShadowDOMVTest, FeatureSetSubtree) { TEST_F(ShadowDOMVTest, FeatureSetMultipleShadowRoots) { LoadURL("about:blank"); - auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); + auto* host = GetDocument().CreateRawElement(html_names::kDivTag); auto& host_shadow = host->CreateV0ShadowRootForTesting(); host_shadow.SetInnerHTMLFromString("<content select='#foo'></content>"); - auto* child = GetDocument().CreateRawElement(HTMLNames::divTag); + auto* child = GetDocument().CreateRawElement(html_names::kDivTag); auto& child_root = child->CreateV0ShadowRootForTesting(); - auto* child_content = GetDocument().CreateRawElement(HTMLNames::contentTag); + auto* child_content = GetDocument().CreateRawElement(html_names::kContentTag); child_content->setAttribute("select", "#bar"); child_root.AppendChild(child_content); host_shadow.AppendChild(child); diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root.cc b/chromium/third_party/blink/renderer/core/dom/shadow_root.cc index f2d520004ab..04bd6ddae57 100644 --- a/chromium/third_party/blink/renderer/core/dom/shadow_root.cc +++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.cc @@ -76,7 +76,7 @@ ShadowRoot::ShadowRoot(Document& document, ShadowRootType type) needs_distribution_recalc_(false), unused_(0) { if (IsV0()) - shadow_root_v0_ = new ShadowRootV0(*this); + shadow_root_v0_ = MakeGarbageCollected<ShadowRootV0>(*this); } ShadowRoot::~ShadowRoot() = default; @@ -164,21 +164,6 @@ void ShadowRoot::RebuildLayoutTree(WhitespaceAttacher& whitespace_attacher) { ClearChildNeedsReattachLayoutTree(); } -void ShadowRoot::AttachLayoutTree(AttachContext& context) { - Node::AttachContext children_context(context); - DocumentFragment::AttachLayoutTree(children_context); -} - -void ShadowRoot::DetachLayoutTree(const AttachContext& context) { - Node::AttachContext children_context(context); - children_context.clear_invalidation = true; - GetDocument() - .GetStyleEngine() - .GetPendingNodeInvalidations() - .ClearInvalidation(*this); - DocumentFragment::DetachLayoutTree(children_context); -} - Node::InsertionNotificationRequest ShadowRoot::InsertedInto( ContainerNode& insertion_point) { DocumentFragment::InsertedInto(insertion_point); @@ -217,12 +202,6 @@ void ShadowRoot::RemovedFrom(ContainerNode& insertion_point) { root->RemoveChildShadowRoot(); registered_with_parent_shadow_root_ = false; } - if (NeedsStyleInvalidation()) { - GetDocument() - .GetStyleEngine() - .GetPendingNodeInvalidations() - .ClearInvalidation(*this); - } } DocumentFragment::RemovedFrom(insertion_point); diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root.h b/chromium/third_party/blink/renderer/core/dom/shadow_root.h index 5abe0c54124..2f981ad6eaa 100644 --- a/chromium/third_party/blink/renderer/core/dom/shadow_root.h +++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.h @@ -56,9 +56,11 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { public: static ShadowRoot* Create(Document& document, ShadowRootType type) { - return new ShadowRoot(document, type); + return MakeGarbageCollected<ShadowRoot>(document, type); } + ShadowRoot(Document&, ShadowRootType); + // Disambiguate between Node and TreeScope hierarchies; TreeScope's // implementation is simpler. using TreeScope::GetDocument; @@ -105,9 +107,6 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { } bool IsUserAgent() const { return GetType() == ShadowRootType::kUserAgent; } - void AttachLayoutTree(AttachContext&) override; - void DetachLayoutTree(const AttachContext& = AttachContext()) override; - InsertionNotificationRequest InsertedInto(ContainerNode&) override; void RemovedFrom(ContainerNode&) override; @@ -130,6 +129,8 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { return *slot_assignment_; } + bool HasSlotAssignment() { return slot_assignment_; } + HTMLSlotElement* AssignedSlotFor(const Node&); void DidAddSlot(HTMLSlotElement&); void DidChangeHostChildSlotName(const AtomicString& old_value, @@ -173,7 +174,6 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { void Trace(blink::Visitor*) override; private: - ShadowRoot(Document&, ShadowRootType); ~ShadowRoot() override; void ChildrenChanged(const ChildrenChange&) override; diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.cc b/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.cc index 41971edecbb..64c9cc4a80b 100644 --- a/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.cc +++ b/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.cc @@ -125,8 +125,9 @@ inline void DistributionPool::DetachNonDistributedNodes() { const HeapVector<Member<V0InsertionPoint>>& ShadowRootV0::DescendantInsertionPoints() { - DEFINE_STATIC_LOCAL(Persistent<HeapVector<Member<V0InsertionPoint>>>, - empty_list, (new HeapVector<Member<V0InsertionPoint>>)); + DEFINE_STATIC_LOCAL( + Persistent<HeapVector<Member<V0InsertionPoint>>>, empty_list, + (MakeGarbageCollected<HeapVector<Member<V0InsertionPoint>>>())); if (descendant_insertion_points_is_valid_) return descendant_insertion_points_; @@ -195,8 +196,10 @@ void ShadowRootV0::DidDistributeNode(const Node* node, V0InsertionPoint* insertion_point) { NodeToDestinationInsertionPoints::AddResult result = node_to_insertion_points_.insert(node, nullptr); - if (result.is_new_entry) - result.stored_value->value = new DestinationInsertionPoints; + if (result.is_new_entry) { + result.stored_value->value = + MakeGarbageCollected<DestinationInsertionPoints>(); + } result.stored_value->value->push_back(insertion_point); } diff --git a/chromium/third_party/blink/renderer/core/dom/sink_document.cc b/chromium/third_party/blink/renderer/core/dom/sink_document.cc index 05cf16aca90..609caf3ea93 100644 --- a/chromium/third_party/blink/renderer/core/dom/sink_document.cc +++ b/chromium/third_party/blink/renderer/core/dom/sink_document.cc @@ -33,13 +33,13 @@ namespace blink { class SinkDocumentParser : public RawDataDocumentParser { public: static SinkDocumentParser* Create(SinkDocument* document) { - return new SinkDocumentParser(document); + return MakeGarbageCollected<SinkDocumentParser>(document); } - private: explicit SinkDocumentParser(SinkDocument* document) : RawDataDocumentParser(document) {} + private: // Ignore all data. void AppendBytes(const char*, size_t) override {} }; diff --git a/chromium/third_party/blink/renderer/core/dom/sink_document.h b/chromium/third_party/blink/renderer/core/dom/sink_document.h index ef4f353d2a3..7a5f3f0f57d 100644 --- a/chromium/third_party/blink/renderer/core/dom/sink_document.h +++ b/chromium/third_party/blink/renderer/core/dom/sink_document.h @@ -33,12 +33,12 @@ namespace blink { class SinkDocument final : public HTMLDocument { public: static SinkDocument* Create(const DocumentInit& initializer) { - return new SinkDocument(initializer); + return MakeGarbageCollected<SinkDocument>(initializer); } - private: explicit SinkDocument(const DocumentInit&); + private: DocumentParser* CreateParser() override; }; diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc b/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc index fd2164fd0e8..bd70c6e1626 100644 --- a/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc +++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc @@ -9,6 +9,7 @@ #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/slot_assignment_engine.h" +#include "third_party/blink/renderer/core/dom/slot_assignment_recalc_forbidden_scope.h" #include "third_party/blink/renderer/core/html/forms/html_opt_group_element.h" #include "third_party/blink/renderer/core/html/forms/html_select_element.h" #include "third_party/blink/renderer/core/html/html_details_element.h" @@ -226,10 +227,13 @@ void SlotAssignment::RecalcAssignment() { #if DCHECK_IS_ON() DCHECK(!owner_->GetDocument().IsSlotAssignmentRecalcForbidden()); #endif + // To detect recursive RecalcAssignment, which shouldn't happen. + SlotAssignmentRecalcForbiddenScope forbid_slot_recalc(owner_->GetDocument()); + needs_assignment_recalc_ = false; for (Member<HTMLSlotElement> slot : Slots()) - slot->ClearAssignedNodes(); + slot->WillRecalcAssignedNodes(); const bool is_user_agent = owner_->IsUserAgent(); @@ -266,10 +270,12 @@ void SlotAssignment::RecalcAssignment() { } } - if (slot) + if (slot) { slot->AppendAssignedNode(child); - else + } else { + child.ClearFlatTreeNodeData(); child.LazyReattachIfAttached(); + } } if (owner_->isConnected()) { @@ -279,7 +285,7 @@ void SlotAssignment::RecalcAssignment() { } for (auto& slot : Slots()) - slot->RecalcFlatTreeChildren(); + slot->DidRecalcAssignedNodes(); } const HeapVector<Member<HTMLSlotElement>>& SlotAssignment::Slots() { diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment.h b/chromium/third_party/blink/renderer/core/dom/slot_assignment.h index 47bb170f96e..36230f6404e 100644 --- a/chromium/third_party/blink/renderer/core/dom/slot_assignment.h +++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment.h @@ -18,9 +18,11 @@ class ShadowRoot; class SlotAssignment final : public GarbageCollected<SlotAssignment> { public: static SlotAssignment* Create(ShadowRoot& owner) { - return new SlotAssignment(owner); + return MakeGarbageCollected<SlotAssignment>(owner); } + explicit SlotAssignment(ShadowRoot& owner); + // Relevant DOM Standard: https://dom.spec.whatwg.org/#find-a-slot HTMLSlotElement* FindSlot(const Node&); HTMLSlotElement* FindSlotByName(const AtomicString& slot_name) const; @@ -60,8 +62,6 @@ class SlotAssignment final : public GarbageCollected<SlotAssignment> { void RecalcAssignment(); private: - explicit SlotAssignment(ShadowRoot& owner); - enum class SlotMutationType { kRemoved, kRenamed, diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h b/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h index a0c6bf2e5db..ae8a0f6a20d 100644 --- a/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h +++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h @@ -14,7 +14,11 @@ class ShadowRoot; class SlotAssignmentEngine final : public GarbageCollected<SlotAssignmentEngine> { public: - static SlotAssignmentEngine* Create() { return new SlotAssignmentEngine(); } + static SlotAssignmentEngine* Create() { + return MakeGarbageCollected<SlotAssignmentEngine>(); + } + + explicit SlotAssignmentEngine(); void AddShadowRootNeedingRecalc(ShadowRoot&); void RemoveShadowRootNeedingRecalc(ShadowRoot&); @@ -31,8 +35,6 @@ class SlotAssignmentEngine final void Trace(blink::Visitor*); private: - explicit SlotAssignmentEngine(); - HeapHashSet<WeakMember<ShadowRoot>> shadow_roots_needing_recalc_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc b/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc index 86a27fcef74..65eb6550d7f 100644 --- a/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc @@ -69,7 +69,7 @@ void RemoveWhiteSpaceOnlyTextNode(ContainerNode& container) { for (Node* descendant : CollectFromIterable(NodeTraversal::InclusiveDescendantsOf(container))) { if (Text* text = ToTextOrNull(descendant)) { - if (text->ContainsOnlyWhitespace()) + if (text->ContainsOnlyWhitespaceOrEmpty()) text->remove(); } else if (Element* element = ToElementOrNull(descendant)) { if (ShadowRoot* shadow_root = element->OpenShadowRoot()) diff --git a/chromium/third_party/blink/renderer/core/dom/space_split_string.h b/chromium/third_party/blink/renderer/core/dom/space_split_string.h index 1e1afbf4508..6589128b19c 100644 --- a/chromium/third_party/blink/renderer/core/dom/space_split_string.h +++ b/chromium/third_party/blink/renderer/core/dom/space_split_string.h @@ -65,7 +65,7 @@ class CORE_EXPORT SpaceSplitString { const AtomicString& operator[](wtf_size_t i) const { return (*data_)[i]; } private: - class Data : public RefCounted<Data> { + class CORE_EXPORT Data : public RefCounted<Data> { public: static scoped_refptr<Data> Create(const AtomicString&); static scoped_refptr<Data> CreateUnique(const Data&); diff --git a/chromium/third_party/blink/renderer/core/dom/static_node_list.h b/chromium/third_party/blink/renderer/core/dom/static_node_list.h index 884b32ad17d..9e911b1e163 100644 --- a/chromium/third_party/blink/renderer/core/dom/static_node_list.h +++ b/chromium/third_party/blink/renderer/core/dom/static_node_list.h @@ -44,7 +44,9 @@ class StaticNodeTypeList final : public NodeList { public: static StaticNodeTypeList* Adopt(HeapVector<Member<NodeType>>& nodes); - static StaticNodeTypeList* CreateEmpty() { return new StaticNodeTypeList; } + static StaticNodeTypeList* CreateEmpty() { + return MakeGarbageCollected<StaticNodeTypeList>(); + } ~StaticNodeTypeList() override; diff --git a/chromium/third_party/blink/renderer/core/dom/static_range.cc b/chromium/third_party/blink/renderer/core/dom/static_range.cc index 99fd39618a1..c5d3f6cb54e 100644 --- a/chromium/third_party/blink/renderer/core/dom/static_range.cc +++ b/chromium/third_party/blink/renderer/core/dom/static_range.cc @@ -33,11 +33,11 @@ StaticRange::StaticRange(Document& document, // static StaticRange* StaticRange::Create(const EphemeralRange& range) { DCHECK(!range.IsNull()); - return new StaticRange(range.GetDocument(), - range.StartPosition().ComputeContainerNode(), - range.StartPosition().ComputeOffsetInContainerNode(), - range.EndPosition().ComputeContainerNode(), - range.EndPosition().ComputeOffsetInContainerNode()); + return MakeGarbageCollected<StaticRange>( + range.GetDocument(), range.StartPosition().ComputeContainerNode(), + range.StartPosition().ComputeOffsetInContainerNode(), + range.EndPosition().ComputeContainerNode(), + range.EndPosition().ComputeOffsetInContainerNode()); } void StaticRange::setStart(Node* container, unsigned offset) { diff --git a/chromium/third_party/blink/renderer/core/dom/static_range.h b/chromium/third_party/blink/renderer/core/dom/static_range.h index 728016d595e..8989453af29 100644 --- a/chromium/third_party/blink/renderer/core/dom/static_range.h +++ b/chromium/third_party/blink/renderer/core/dom/static_range.h @@ -21,23 +21,30 @@ class CORE_EXPORT StaticRange final : public ScriptWrappable { public: static StaticRange* Create(Document& document) { - return new StaticRange(document); + return MakeGarbageCollected<StaticRange>(document); } static StaticRange* Create(Document& document, Node* start_container, unsigned start_offset, Node* end_container, unsigned end_offset) { - return new StaticRange(document, start_container, start_offset, - end_container, end_offset); + return MakeGarbageCollected<StaticRange>( + document, start_container, start_offset, end_container, end_offset); } static StaticRange* Create(const Range* range) { - return new StaticRange(range->OwnerDocument(), range->startContainer(), - range->startOffset(), range->endContainer(), - range->endOffset()); + return MakeGarbageCollected<StaticRange>( + range->OwnerDocument(), range->startContainer(), range->startOffset(), + range->endContainer(), range->endOffset()); } static StaticRange* Create(const EphemeralRange&); + explicit StaticRange(Document&); + StaticRange(Document&, + Node* start_container, + unsigned start_offset, + Node* end_container, + unsigned end_offset); + Node* startContainer() const { return start_container_.Get(); } void setStartContainer(Node* start_container) { start_container_ = start_container; @@ -64,13 +71,6 @@ class CORE_EXPORT StaticRange final : public ScriptWrappable { void Trace(blink::Visitor*) override; private: - explicit StaticRange(Document&); - StaticRange(Document&, - Node* start_container, - unsigned start_offset, - Node* end_container, - unsigned end_offset); - Member<Document> owner_document_; // Required by |toRange()|. Member<Node> start_container_; unsigned start_offset_; diff --git a/chromium/third_party/blink/renderer/core/dom/tag_collection.h b/chromium/third_party/blink/renderer/core/dom/tag_collection.h index 8358b1ab64c..d9842209221 100644 --- a/chromium/third_party/blink/renderer/core/dom/tag_collection.h +++ b/chromium/third_party/blink/renderer/core/dom/tag_collection.h @@ -36,18 +36,18 @@ class TagCollection : public HTMLCollection { CollectionType type, const AtomicString& qualified_name) { DCHECK_EQ(type, kTagCollectionType); - return new TagCollection(root_node, kTagCollectionType, qualified_name); + return MakeGarbageCollected<TagCollection>(root_node, kTagCollectionType, + qualified_name); } + TagCollection(ContainerNode& root_node, + CollectionType, + const AtomicString& qualified_name); ~TagCollection() override; bool ElementMatches(const Element&) const; protected: - TagCollection(ContainerNode& root_node, - CollectionType, - const AtomicString& qualified_name); - AtomicString qualified_name_; }; @@ -56,20 +56,19 @@ class TagCollectionNS : public HTMLCollection { static TagCollectionNS* Create(ContainerNode& root_node, const AtomicString& namespace_uri, const AtomicString& local_name) { - return new TagCollectionNS(root_node, kTagCollectionNSType, namespace_uri, - local_name); + return MakeGarbageCollected<TagCollectionNS>( + root_node, kTagCollectionNSType, namespace_uri, local_name); } - ~TagCollectionNS() override; - - bool ElementMatches(const Element&) const; - - private: TagCollectionNS(ContainerNode& root_node, CollectionType, const AtomicString& namespace_uri, const AtomicString& local_name); + ~TagCollectionNS() override; + + bool ElementMatches(const Element&) const; + private: AtomicString namespace_uri_; AtomicString local_name_; }; diff --git a/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h b/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h index f7432c1cbfc..a68faf52563 100644 --- a/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h +++ b/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h @@ -35,9 +35,13 @@ class TemplateContentDocumentFragment final : public DocumentFragment { public: static TemplateContentDocumentFragment* Create(Document& document, Element* host) { - return new TemplateContentDocumentFragment(document, host); + return MakeGarbageCollected<TemplateContentDocumentFragment>(document, + host); } + TemplateContentDocumentFragment(Document& document, Element* host) + : DocumentFragment(&document, kCreateDocumentFragment), host_(host) {} + Element* Host() const { return host_; } void Trace(blink::Visitor* visitor) override { @@ -46,9 +50,6 @@ class TemplateContentDocumentFragment final : public DocumentFragment { } private: - TemplateContentDocumentFragment(Document& document, Element* host) - : DocumentFragment(&document, kCreateDocumentFragment), host_(host) {} - bool IsTemplateContent() const override { return true; } Member<Element> host_; diff --git a/chromium/third_party/blink/renderer/core/dom/text.cc b/chromium/third_party/blink/renderer/core/dom/text.cc index 8ea980ab00e..6a91669ed26 100644 --- a/chromium/third_party/blink/renderer/core/dom/text.cc +++ b/chromium/third_party/blink/renderer/core/dom/text.cc @@ -46,11 +46,11 @@ namespace blink { Text* Text::Create(Document& document, const String& data) { - return new Text(document, data, kCreateText); + return MakeGarbageCollected<Text>(document, data, kCreateText); } Text* Text::CreateEditingText(Document& document, const String& data) { - return new Text(document, data, kCreateEditingText); + return MakeGarbageCollected<Text>(document, data, kCreateEditingText); } Node* Text::MergeNextSiblingNodesIfPossible() { @@ -288,7 +288,7 @@ bool Text::TextLayoutObjectIsNeeded(const AttachContext& context, if (style.Display() == EDisplay::kNone) return false; - if (!ContainsOnlyWhitespace()) + if (!ContainsOnlyWhitespaceOrEmpty()) return true; if (!CanHaveWhitespaceChildren(parent, style, context)) diff --git a/chromium/third_party/blink/renderer/core/dom/text.h b/chromium/third_party/blink/renderer/core/dom/text.h index 8e78c674c25..e44317ab67a 100644 --- a/chromium/third_party/blink/renderer/core/dom/text.h +++ b/chromium/third_party/blink/renderer/core/dom/text.h @@ -42,6 +42,9 @@ class CORE_EXPORT Text : public CharacterData { static Text* Create(Document&, const String&); static Text* CreateEditingText(Document&, const String&); + Text(TreeScope& tree_scope, const String& data, ConstructionType type) + : CharacterData(tree_scope, data, type) {} + LayoutText* GetLayoutObject() const; // mergeNextSiblingNodesIfPossible() merges next sibling nodes if possible @@ -71,10 +74,6 @@ class CORE_EXPORT Text : public CharacterData { void Trace(blink::Visitor*) override; - protected: - Text(TreeScope& tree_scope, const String& data, ConstructionType type) - : CharacterData(tree_scope, data, type) {} - private: String nodeName() const override; Node* Clone(Document&, CloneChildrenFlag) const override; diff --git a/chromium/third_party/blink/renderer/core/dom/text_test.cc b/chromium/third_party/blink/renderer/core/dom/text_test.cc index 5813957432a..ed16d8cd5f4 100644 --- a/chromium/third_party/blink/renderer/core/dom/text_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/text_test.cc @@ -21,7 +21,7 @@ TEST_F(TextTest, SetDataToChangeFirstLetterTextNode) { Node* sample = GetDocument().getElementById("sample"); Text* text = ToText(sample->firstChild()); text->setData(" "); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_FALSE(text->GetLayoutObject()->IsTextFragment()); } @@ -34,14 +34,14 @@ TEST_F(TextTest, RemoveFirstLetterPseudoElementWhenNoLetter) { Range* range = Range::Create(GetDocument(), text, 0, text, 2); range->deleteContents(ASSERT_NO_EXCEPTION); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_FALSE(text->GetLayoutObject()->IsTextFragment()); } TEST_F(TextTest, TextLayoutObjectIsNeeded_CannotHaveChildren) { SetBodyContent("<img id=image>"); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* img = GetDocument().getElementById("image"); ASSERT_TRUE(img); @@ -61,7 +61,7 @@ TEST_F(TextTest, TextLayoutObjectIsNeeded_CannotHaveChildren) { TEST_F(TextTest, TextLayoutObjectIsNeeded_EditingText) { SetBodyContent("<span id=parent></span>"); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* parent = GetDocument().getElementById("parent"); ASSERT_TRUE(parent); @@ -91,7 +91,7 @@ TEST_F(TextTest, TextLayoutObjectIsNeeded_EditingText) { TEST_F(TextTest, TextLayoutObjectIsNeeded_Empty) { SetBodyContent("<span id=parent></span>"); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* parent = GetDocument().getElementById("parent"); ASSERT_TRUE(parent); @@ -112,7 +112,7 @@ TEST_F(TextTest, TextLayoutObjectIsNeeded_Whitespace) { SetBodyContent( "<div id=block></div>Ends with whitespace " "<span id=inline></span>Nospace<br id=br>"); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); LayoutObject* block = GetDocument().getElementById("block")->GetLayoutObject(); @@ -180,7 +180,7 @@ TEST_F(TextTest, TextLayoutObjectIsNeeded_PreserveNewLine) { <div id=pre-line style='white-space:pre-line'></div> <div id=pre-wrap style='white-space:pre-wrap'></div> )HTML"); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Text* text = Text::Create(GetDocument(), " "); diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc index b02ac81a903..4d70591c129 100644 --- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc +++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc @@ -41,10 +41,8 @@ namespace blink { -using namespace HTMLNames; - TreeOrderedMap* TreeOrderedMap::Create() { - return new TreeOrderedMap; + return MakeGarbageCollected<TreeOrderedMap>(); } TreeOrderedMap::TreeOrderedMap() = default; @@ -80,7 +78,8 @@ inline bool KeyMatchesSlotName(const AtomicString& key, void TreeOrderedMap::Add(const AtomicString& key, Element& element) { DCHECK(key); - Map::AddResult add_result = map_.insert(key, new MapEntry(element)); + Map::AddResult add_result = + map_.insert(key, MakeGarbageCollected<MapEntry>(element)); if (add_result.is_new_entry) return; @@ -156,7 +155,7 @@ const HeapVector<Member<Element>>& TreeOrderedMap::GetAllElementsById( const TreeScope& scope) const { DCHECK(key); DEFINE_STATIC_LOCAL(Persistent<HeapVector<Member<Element>>>, empty_vector, - (new HeapVector<Member<Element>>)); + (MakeGarbageCollected<HeapVector<Member<Element>>>())); Map::iterator it = map_.find(key); if (it == map_.end()) diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h index 8a5eba0d681..5ca8d4fbbe9 100644 --- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h +++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h @@ -50,6 +50,8 @@ class TreeOrderedMap : public GarbageCollected<TreeOrderedMap> { public: static TreeOrderedMap* Create(); + TreeOrderedMap(); + void Add(const AtomicString&, Element&); void Remove(const AtomicString&, Element&); @@ -91,8 +93,6 @@ class TreeOrderedMap : public GarbageCollected<TreeOrderedMap> { #endif private: - TreeOrderedMap(); - template <bool keyMatches(const AtomicString&, const Element&)> Element* Get(const AtomicString&, const TreeScope&) const; diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope.cc b/chromium/third_party/blink/renderer/core/dom/tree_scope.cc index 70fe641e338..1c645585bff 100644 --- a/chromium/third_party/blink/renderer/core/dom/tree_scope.cc +++ b/chromium/third_party/blink/renderer/core/dom/tree_scope.cc @@ -57,7 +57,7 @@ namespace blink { -using namespace HTMLNames; +using namespace html_names; TreeScope::TreeScope(ContainerNode& root_node, Document& document) : root_node_(&root_node), @@ -128,7 +128,7 @@ Element* TreeScope::getElementById(const AtomicString& element_id) const { const HeapVector<Member<Element>>& TreeScope::GetAllElementsById( const AtomicString& element_id) const { DEFINE_STATIC_LOCAL(Persistent<HeapVector<Member<Element>>>, empty_vector, - (new HeapVector<Member<Element>>)); + (MakeGarbageCollected<HeapVector<Member<Element>>>())); if (element_id.IsEmpty()) return *empty_vector; if (!elements_by_id_) @@ -189,7 +189,9 @@ HTMLMapElement* TreeScope::GetImageMap(const String& url) const { if (!image_maps_by_name_) return nullptr; wtf_size_t hash_pos = url.find('#'); - String name = hash_pos == kNotFound ? url : url.Substring(hash_pos + 1); + if (hash_pos == kNotFound) + return nullptr; + String name = url.Substring(hash_pos + 1); return ToHTMLMapElement( image_maps_by_name_->GetElementByMapName(AtomicString(name), *this)); } @@ -329,8 +331,10 @@ HeapVector<Member<Element>> TreeScope::ElementsFromPoint(double x, } SVGTreeScopeResources& TreeScope::EnsureSVGTreeScopedResources() { - if (!svg_tree_scoped_resources_) - svg_tree_scoped_resources_ = new SVGTreeScopeResources(this); + if (!svg_tree_scoped_resources_) { + svg_tree_scoped_resources_ = + MakeGarbageCollected<SVGTreeScopeResources>(this); + } return *svg_tree_scoped_resources_; } @@ -485,7 +489,7 @@ Element* TreeScope::AdjustedFocusedElement() const { return nullptr; } - EventPath* event_path = new EventPath(*element); + EventPath* event_path = MakeGarbageCollected<EventPath>(*element); for (const auto& context : event_path->NodeEventContexts()) { if (context.GetNode() == RootNode()) { // context.target() is one of the followings: @@ -598,7 +602,7 @@ Element* TreeScope::GetElementByAccessKey(const String& key) const { Element* result = nullptr; Node& root = RootNode(); for (Element& element : ElementTraversal::DescendantsOf(root)) { - if (DeprecatedEqualIgnoringCase(element.FastGetAttribute(accesskeyAttr), + if (DeprecatedEqualIgnoringCase(element.FastGetAttribute(kAccesskeyAttr), key)) result = &element; if (ShadowRoot* shadow_root = element.GetShadowRoot()) { @@ -615,10 +619,11 @@ void TreeScope::SetNeedsStyleRecalcForViewportUnits() { if (ShadowRoot* root = element->GetShadowRoot()) root->SetNeedsStyleRecalcForViewportUnits(); const ComputedStyle* style = element->GetComputedStyle(); - if (style && style->HasViewportUnits()) + if (style && style->HasViewportUnits()) { element->SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( - StyleChangeReason::kViewportUnits)); + style_change_reason::kViewportUnits)); + } } } diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc b/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc index 0a795edaa1e..cc574e3c7e3 100644 --- a/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc @@ -17,14 +17,14 @@ TEST(TreeScopeAdopterTest, SimpleMove) { Document* doc1 = Document::CreateForTest(); Document* doc2 = Document::CreateForTest(); - Element* html1 = doc1->CreateRawElement(HTMLNames::htmlTag); + Element* html1 = doc1->CreateRawElement(html_names::kHTMLTag); doc1->AppendChild(html1); - Element* div1 = doc1->CreateRawElement(HTMLNames::divTag); + Element* div1 = doc1->CreateRawElement(html_names::kDivTag); html1->AppendChild(div1); - Element* html2 = doc2->CreateRawElement(HTMLNames::htmlTag); + Element* html2 = doc2->CreateRawElement(html_names::kHTMLTag); doc2->AppendChild(html2); - Element* div2 = doc1->CreateRawElement(HTMLNames::divTag); + Element* div2 = doc1->CreateRawElement(html_names::kDivTag); html2->AppendChild(div2); EXPECT_EQ(div1->ownerDocument(), doc1); @@ -45,9 +45,9 @@ TEST(TreeScopeAdopterTest, AdoptV1ShadowRootToV0Document) { Document* doc1 = Document::CreateForTest(); Document* doc2 = Document::CreateForTest(); - Element* html1 = doc1->CreateRawElement(HTMLNames::htmlTag); + Element* html1 = doc1->CreateRawElement(html_names::kHTMLTag); doc1->AppendChild(html1); - Element* div1 = doc1->CreateRawElement(HTMLNames::divTag); + Element* div1 = doc1->CreateRawElement(html_names::kDivTag); html1->AppendChild(div1); EXPECT_EQ(doc1->GetShadowCascadeOrder(), ShadowCascadeOrder::kShadowCascadeNone); @@ -56,9 +56,9 @@ TEST(TreeScopeAdopterTest, AdoptV1ShadowRootToV0Document) { ShadowCascadeOrder::kShadowCascadeV0); EXPECT_TRUE(doc1->MayContainV0Shadow()); - Element* html2 = doc2->CreateRawElement(HTMLNames::htmlTag); + Element* html2 = doc2->CreateRawElement(html_names::kHTMLTag); doc2->AppendChild(html2); - Element* div2 = doc1->CreateRawElement(HTMLNames::divTag); + Element* div2 = doc1->CreateRawElement(html_names::kDivTag); html2->AppendChild(div2); div2->AttachShadowRootInternal(ShadowRootType::kOpen); @@ -81,9 +81,9 @@ TEST(TreeScopeAdopterTest, AdoptV0ShadowRootToV1Document) { Document* doc1 = Document::CreateForTest(); Document* doc2 = Document::CreateForTest(); - Element* html1 = doc1->CreateRawElement(HTMLNames::htmlTag); + Element* html1 = doc1->CreateRawElement(html_names::kHTMLTag); doc1->AppendChild(html1); - Element* div1 = doc1->CreateRawElement(HTMLNames::divTag); + Element* div1 = doc1->CreateRawElement(html_names::kDivTag); html1->AppendChild(div1); EXPECT_EQ(doc1->GetShadowCascadeOrder(), ShadowCascadeOrder::kShadowCascadeNone); @@ -92,9 +92,9 @@ TEST(TreeScopeAdopterTest, AdoptV0ShadowRootToV1Document) { ShadowCascadeOrder::kShadowCascadeV1); EXPECT_FALSE(doc1->MayContainV0Shadow()); - Element* html2 = doc2->CreateRawElement(HTMLNames::htmlTag); + Element* html2 = doc2->CreateRawElement(html_names::kHTMLTag); doc2->AppendChild(html2); - Element* div2 = doc1->CreateRawElement(HTMLNames::divTag); + Element* div2 = doc1->CreateRawElement(html_names::kDivTag); html2->AppendChild(div2); div2->CreateV0ShadowRootForTesting(); @@ -115,13 +115,13 @@ TEST(TreeScopeAdopterTest, AdoptV0ShadowRootToV1Document) { TEST(TreeScopeAdopterTest, AdoptV0InV1ToNewDocument) { Document* old_doc = Document::CreateForTest(); - Element* html = old_doc->CreateRawElement(HTMLNames::htmlTag); + Element* html = old_doc->CreateRawElement(html_names::kHTMLTag); old_doc->AppendChild(html); - Element* host1 = old_doc->CreateRawElement(HTMLNames::divTag); + Element* host1 = old_doc->CreateRawElement(html_names::kDivTag); html->AppendChild(host1); ShadowRoot& shadow_root_v1 = host1->AttachShadowRootInternal(ShadowRootType::kOpen); - Element* host2 = old_doc->CreateRawElement(HTMLNames::divTag); + Element* host2 = old_doc->CreateRawElement(html_names::kDivTag); shadow_root_v1.AppendChild(host2); host2->CreateV0ShadowRootForTesting(); diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc b/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc index 62334700cb9..67aa3e2191a 100644 --- a/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc @@ -15,7 +15,7 @@ TEST(TreeScopeTest, CommonAncestorOfSameTrees) { Document* document = Document::CreateForTest(); EXPECT_EQ(document, document->CommonAncestorTreeScope(*document)); - Element* html = document->CreateRawElement(HTMLNames::htmlTag); + Element* html = document->CreateRawElement(html_names::kHTMLTag); document->AppendChild(html); ShadowRoot& shadow_root = html->CreateV0ShadowRootForTesting(); EXPECT_EQ(shadow_root, shadow_root.CommonAncestorTreeScope(shadow_root)); @@ -27,7 +27,7 @@ TEST(TreeScopeTest, CommonAncestorOfInclusiveTrees) { // shadowRoot Document* document = Document::CreateForTest(); - Element* html = document->CreateRawElement(HTMLNames::htmlTag); + Element* html = document->CreateRawElement(html_names::kHTMLTag); document->AppendChild(html); ShadowRoot& shadow_root = html->CreateV0ShadowRootForTesting(); @@ -41,11 +41,11 @@ TEST(TreeScopeTest, CommonAncestorOfSiblingTrees) { // A B Document* document = Document::CreateForTest(); - Element* html = document->CreateRawElement(HTMLNames::htmlTag); + Element* html = document->CreateRawElement(html_names::kHTMLTag); document->AppendChild(html); - Element* head = document->CreateRawElement(HTMLNames::headTag); + Element* head = document->CreateRawElement(html_names::kHeadTag); html->AppendChild(head); - Element* body = document->CreateRawElement(HTMLNames::bodyTag); + Element* body = document->CreateRawElement(html_names::kBodyTag); html->AppendChild(body); ShadowRoot& shadow_root_a = head->CreateV0ShadowRootForTesting(); @@ -63,17 +63,17 @@ TEST(TreeScopeTest, CommonAncestorOfTreesAtDifferentDepths) { // A Document* document = Document::CreateForTest(); - Element* html = document->CreateRawElement(HTMLNames::htmlTag); + Element* html = document->CreateRawElement(html_names::kHTMLTag); document->AppendChild(html); - Element* head = document->CreateRawElement(HTMLNames::headTag); + Element* head = document->CreateRawElement(html_names::kHeadTag); html->AppendChild(head); - Element* body = document->CreateRawElement(HTMLNames::bodyTag); + Element* body = document->CreateRawElement(html_names::kBodyTag); html->AppendChild(body); ShadowRoot& shadow_root_y = head->CreateV0ShadowRootForTesting(); ShadowRoot& shadow_root_b = body->CreateV0ShadowRootForTesting(); - Element* div_in_y = document->CreateRawElement(HTMLNames::divTag); + Element* div_in_y = document->CreateRawElement(html_names::kDivTag); shadow_root_y.AppendChild(div_in_y); ShadowRoot& shadow_root_a = div_in_y->CreateV0ShadowRootForTesting(); diff --git a/chromium/third_party/blink/renderer/core/dom/tree_walker.h b/chromium/third_party/blink/renderer/core/dom/tree_walker.h index 97d51f00efa..43f338bde1d 100644 --- a/chromium/third_party/blink/renderer/core/dom/tree_walker.h +++ b/chromium/third_party/blink/renderer/core/dom/tree_walker.h @@ -41,9 +41,11 @@ class TreeWalker final : public ScriptWrappable, public NodeIteratorBase { static TreeWalker* Create(Node* root_node, unsigned what_to_show, V8NodeFilter* filter) { - return new TreeWalker(root_node, what_to_show, filter); + return MakeGarbageCollected<TreeWalker>(root_node, what_to_show, filter); } + TreeWalker(Node*, unsigned what_to_show, V8NodeFilter*); + Node* currentNode() const { return current_.Get(); } void setCurrentNode(Node*); @@ -58,8 +60,6 @@ class TreeWalker final : public ScriptWrappable, public NodeIteratorBase { void Trace(blink::Visitor*) override; private: - TreeWalker(Node*, unsigned what_to_show, V8NodeFilter*); - Node* SetCurrent(Node*); template <typename Strategy> Node* TraverseSiblings(ExceptionState&); diff --git a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc index f086e03482c..930d432559c 100644 --- a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc +++ b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc @@ -41,8 +41,6 @@ namespace blink { -using namespace HTMLNames; - V0InsertionPoint::V0InsertionPoint(const QualifiedName& tag_name, Document& document) : HTMLElement(tag_name, document, kCreateV0InsertionPoint), @@ -159,7 +157,7 @@ void V0InsertionPoint::DidRecalcStyle(StyleRecalcChange change) { node->SetNeedsStyleRecalc( style_change_type, StyleChangeReasonForTracing::Create( - StyleChangeReason::kPropagateInheritChangeToDistributedNodes)); + style_change_reason::kPropagateInheritChangeToDistributedNodes)); } } diff --git a/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc b/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc index 5cedf79b315..9541ae52fa7 100644 --- a/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc +++ b/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc @@ -43,7 +43,7 @@ namespace blink { static inline const AtomicString& LinkAttribute(const Element& element) { DCHECK(element.IsLink()); if (element.IsHTMLElement()) - return element.FastGetAttribute(HTMLNames::hrefAttr); + return element.FastGetAttribute(html_names::kHrefAttr); DCHECK(element.IsSVGElement()); return SVGURIReference::LegacyHrefString(ToSVGElement(element)); } diff --git a/chromium/third_party/blink/renderer/core/dom/visited_link_state.h b/chromium/third_party/blink/renderer/core/dom/visited_link_state.h index 4c4a310cd99..7b663e99667 100644 --- a/chromium/third_party/blink/renderer/core/dom/visited_link_state.h +++ b/chromium/third_party/blink/renderer/core/dom/visited_link_state.h @@ -43,9 +43,11 @@ class Document; class VisitedLinkState : public GarbageCollectedFinalized<VisitedLinkState> { public: static VisitedLinkState* Create(const Document& document) { - return new VisitedLinkState(document); + return MakeGarbageCollected<VisitedLinkState>(document); } + explicit VisitedLinkState(const Document&); + void InvalidateStyleForAllLinks(bool invalidate_visited_link_hashes); void InvalidateStyleForLink(LinkHash); @@ -58,7 +60,6 @@ class VisitedLinkState : public GarbageCollectedFinalized<VisitedLinkState> { void Trace(blink::Visitor*); private: - explicit VisitedLinkState(const Document&); const Document& GetDocument() const { return *document_; } EInsideLink DetermineLinkStateSlowCase(const Element&); diff --git a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc index f1c7ea9c996..df1a7ede828 100644 --- a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc +++ b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc @@ -40,6 +40,8 @@ void WhitespaceAttacher::DidReattach(Node* node, LayoutObject* prev_in_flow) { void WhitespaceAttacher::DidReattachText(Text* text) { DCHECK(text); + if (text->data().IsEmpty()) + return; DidReattach(text, text->GetLayoutObject()); SetLastTextNode(text); if (!text->GetLayoutObject()) @@ -54,11 +56,11 @@ void WhitespaceAttacher::DidReattachElement(Element* element, void WhitespaceAttacher::DidVisitText(Text* text) { DCHECK(text); + if (text->data().IsEmpty()) + return; if (!last_text_node_ || !last_text_node_needs_reattach_) { - if (text->data().IsEmpty()) - return; SetLastTextNode(text); - if (reattach_all_whitespace_nodes_ && text->ContainsOnlyWhitespace()) + if (reattach_all_whitespace_nodes_ && text->ContainsOnlyWhitespaceOrEmpty()) last_text_node_needs_reattach_ = true; return; } @@ -73,11 +75,11 @@ void WhitespaceAttacher::DidVisitText(Text* text) { if (LayoutObject* text_layout_object = text->GetLayoutObject()) { ReattachWhitespaceSiblings(text_layout_object); } else { - if (last_text_node_->ContainsOnlyWhitespace()) + if (last_text_node_->ContainsOnlyWhitespaceOrEmpty()) last_text_node_->ReattachLayoutTreeIfNeeded(Node::AttachContext()); } SetLastTextNode(text); - if (reattach_all_whitespace_nodes_ && text->ContainsOnlyWhitespace()) + if (reattach_all_whitespace_nodes_ && text->ContainsOnlyWhitespaceOrEmpty()) last_text_node_needs_reattach_ = true; } @@ -116,7 +118,8 @@ void WhitespaceAttacher::ReattachWhitespaceSiblings( for (Node* sibling = last_text_node_; sibling; sibling = LayoutTreeBuilderTraversal::NextLayoutSibling(*sibling)) { LayoutObject* sibling_layout_object = sibling->GetLayoutObject(); - if (sibling->IsTextNode() && ToText(sibling)->ContainsOnlyWhitespace()) { + if (sibling->IsTextNode() && + ToText(sibling)->ContainsOnlyWhitespaceOrEmpty()) { bool had_layout_object = !!sibling_layout_object; ToText(sibling)->ReattachLayoutTreeIfNeeded(context); sibling_layout_object = sibling->GetLayoutObject(); @@ -170,7 +173,7 @@ void WhitespaceAttacher::UpdateLastTextNodeFromDisplayContents() { LayoutObject* layout_object = sibling->GetLayoutObject(); if (sibling->IsTextNode()) { Text* text = ToText(sibling); - if (text->ContainsOnlyWhitespace()) { + if (text->ContainsOnlyWhitespaceOrEmpty()) { last_text_node_ = text; return; } diff --git a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc index 34f52617063..b1bc4f58bb0 100644 --- a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc +++ b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc @@ -18,7 +18,7 @@ class WhitespaceAttacherTest : public PageTestBase {}; TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedBlock) { GetDocument().body()->SetInnerHTMLFromString("<div id=block></div> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* div = GetDocument().getElementById("block"); Text* text = ToText(div->nextSibling()); @@ -38,7 +38,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedBlock) { TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedInline) { GetDocument().body()->SetInnerHTMLFromString("<span id=inline></span> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); Text* text = ToText(span->nextSibling()); @@ -58,7 +58,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedInline) { TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedWhitespace) { GetDocument().body()->SetInnerHTMLFromString( "<span id=inline></span> <!-- --> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); Text* first_whitespace = ToText(span->nextSibling()); @@ -84,7 +84,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedWhitespace) { TEST_F(WhitespaceAttacherTest, VisitBlockAfterReattachedWhitespace) { GetDocument().body()->SetInnerHTMLFromString("<div id=block></div> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* div = GetDocument().getElementById("block"); Text* text = ToText(div->nextSibling()); @@ -102,7 +102,7 @@ TEST_F(WhitespaceAttacherTest, VisitBlockAfterReattachedWhitespace) { TEST_F(WhitespaceAttacherTest, VisitInlineAfterReattachedWhitespace) { GetDocument().body()->SetInnerHTMLFromString("<span id=inline></span> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); Text* text = ToText(span->nextSibling()); @@ -123,7 +123,7 @@ TEST_F(WhitespaceAttacherTest, VisitInlineAfterReattachedWhitespace) { TEST_F(WhitespaceAttacherTest, VisitTextAfterReattachedWhitespace) { GetDocument().body()->SetInnerHTMLFromString("Text<!-- --> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Text* text = ToText(GetDocument().body()->firstChild()); Text* whitespace = ToText(text->nextSibling()->nextSibling()); @@ -146,7 +146,7 @@ TEST_F(WhitespaceAttacherTest, VisitTextAfterReattachedWhitespace) { TEST_F(WhitespaceAttacherTest, ReattachWhitespaceInsideBlockExitingScope) { GetDocument().body()->SetInnerHTMLFromString("<div id=block> </div>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* div = GetDocument().getElementById("block"); Text* text = ToText(div->firstChild()); @@ -168,7 +168,7 @@ TEST_F(WhitespaceAttacherTest, ReattachWhitespaceInsideBlockExitingScope) { TEST_F(WhitespaceAttacherTest, ReattachWhitespaceInsideInlineExitingScope) { GetDocument().body()->SetInnerHTMLFromString("<span id=inline> </span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); Text* text = ToText(span->firstChild()); @@ -195,7 +195,7 @@ TEST_F(WhitespaceAttacherTest, SlottedWhitespaceAfterReattachedBlock) { ShadowRoot& shadow_root = host->AttachShadowRootInternal(ShadowRootType::kOpen); shadow_root.SetInnerHTMLFromString("<div id=block></div><slot></slot>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* div = shadow_root.getElementById("block"); Text* text = ToText(host->firstChild()); @@ -222,7 +222,7 @@ TEST_F(WhitespaceAttacherTest, SlottedWhitespaceAfterReattachedInline) { ShadowRoot& shadow_root = host->AttachShadowRootInternal(ShadowRootType::kOpen); shadow_root.SetInnerHTMLFromString("<span id=inline></span><slot></slot>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = shadow_root.getElementById("inline"); Text* text = ToText(host->firstChild()); @@ -245,7 +245,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceInDisplayContentsAfterReattachedBlock) { GetDocument().body()->SetInnerHTMLFromString( "<div id=block></div><span style='display:contents'> </span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* div = GetDocument().getElementById("block"); Element* contents = ToElement(div->nextSibling()); @@ -271,7 +271,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceInDisplayContentsAfterReattachedInline) { GetDocument().body()->SetInnerHTMLFromString( "<span id=inline></span><span style='display:contents'> </span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); Element* contents = ToElement(span->nextSibling()); @@ -296,7 +296,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceAfterEmptyDisplayContentsAfterReattachedBlock) { GetDocument().body()->SetInnerHTMLFromString( "<div id=block></div><span style='display:contents'></span> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* div = GetDocument().getElementById("block"); Element* contents = ToElement(div->nextSibling()); @@ -324,7 +324,7 @@ TEST_F(WhitespaceAttacherTest, GetDocument().body()->SetInnerHTMLFromString( "<div id=block></div><span style='display:contents'>" "<span style='display:none'></span></span> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* div = GetDocument().getElementById("block"); Element* contents = ToElement(div->nextSibling()); @@ -352,7 +352,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceDeepInsideDisplayContents) { "<span id=inline></span><span style='display:contents'>" "<span style='display:none'></span>" "<span id=inner style='display:contents'> </span></span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); Element* contents = ToElement(span->nextSibling()); @@ -378,7 +378,7 @@ TEST_F(WhitespaceAttacherTest, MultipleDisplayContents) { "<span style='display:contents'></span>" "<span style='display:contents'></span>" "<span style='display:contents'> </span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); Element* first_contents = ToElement(span->nextSibling()); @@ -412,7 +412,7 @@ TEST_F(WhitespaceAttacherTest, SlottedWhitespaceInsideDisplayContents) { shadow_root.SetInnerHTMLFromString( "<span id=inline></span>" "<div style='display:contents'><slot></slot></div>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = shadow_root.getElementById("inline"); Element* contents = ToElement(span->nextSibling()); @@ -434,7 +434,7 @@ TEST_F(WhitespaceAttacherTest, SlottedWhitespaceInsideDisplayContents) { TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeSpace) { GetDocument().body()->SetInnerHTMLFromString("<span id=inline></span> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); ASSERT_TRUE(span); @@ -446,7 +446,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeSpace) { EXPECT_TRUE(text->GetLayoutObject()); span->remove(); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_FALSE(text->previousSibling()); EXPECT_TRUE(text->IsTextNode()); @@ -457,7 +457,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeSpace) { TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeOutOfFlowBeforeSpace) { GetDocument().body()->SetInnerHTMLFromString( "<span id=inline></span><div id=float style='float:right'></div> "); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Element* span = GetDocument().getElementById("inline"); ASSERT_TRUE(span); @@ -473,7 +473,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeOutOfFlowBeforeSpace) { EXPECT_TRUE(text->GetLayoutObject()); span->remove(); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_TRUE(text->IsTextNode()); EXPECT_FALSE(text->nextSibling()); @@ -482,7 +482,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeOutOfFlowBeforeSpace) { TEST_F(WhitespaceAttacherTest, RemoveSpaceBeforeSpace) { GetDocument().body()->SetInnerHTMLFromString("<span> <!-- --> </span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Node* span = GetDocument().body()->firstChild(); ASSERT_TRUE(span); @@ -498,7 +498,7 @@ TEST_F(WhitespaceAttacherTest, RemoveSpaceBeforeSpace) { EXPECT_FALSE(space2->GetLayoutObject()); space1->remove(); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_TRUE(space2->GetLayoutObject()); } @@ -508,7 +508,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeDisplayContentsWithSpace) { "<style>div { display: contents }</style>" "<div><span id=inline></span></div>" "<div><div><div id=innerdiv> </div></div></div>text"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Node* span = GetDocument().getElementById("inline"); ASSERT_TRUE(span); @@ -519,7 +519,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeDisplayContentsWithSpace) { EXPECT_TRUE(space->GetLayoutObject()); span->remove(); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_FALSE(space->GetLayoutObject()); } @@ -527,7 +527,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeDisplayContentsWithSpace) { TEST_F(WhitespaceAttacherTest, RemoveBlockBeforeSpace) { GetDocument().body()->SetInnerHTMLFromString( "A<div id=block></div> <span>B</span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); Node* div = GetDocument().getElementById("block"); ASSERT_TRUE(div); @@ -538,7 +538,7 @@ TEST_F(WhitespaceAttacherTest, RemoveBlockBeforeSpace) { EXPECT_FALSE(space->GetLayoutObject()); div->remove(); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_TRUE(space->GetLayoutObject()); } diff --git a/chromium/third_party/blink/renderer/core/dom/xml_document.h b/chromium/third_party/blink/renderer/core/dom/xml_document.h index 6496f1bfd49..ae6bfc66009 100644 --- a/chromium/third_party/blink/renderer/core/dom/xml_document.h +++ b/chromium/third_party/blink/renderer/core/dom/xml_document.h @@ -36,19 +36,19 @@ class XMLDocument final : public Document { public: static XMLDocument* Create(const DocumentInit& initializer) { - return new XMLDocument(initializer, kXMLDocumentClass); + return MakeGarbageCollected<XMLDocument>(initializer, kXMLDocumentClass); } static XMLDocument* CreateXHTML(const DocumentInit& initializer) { - return new XMLDocument(initializer, - kXMLDocumentClass | kXHTMLDocumentClass); + return MakeGarbageCollected<XMLDocument>( + initializer, kXMLDocumentClass | kXHTMLDocumentClass); } static XMLDocument* CreateSVG(const DocumentInit& initializer) { - return new XMLDocument(initializer, kXMLDocumentClass | kSVGDocumentClass); + return MakeGarbageCollected<XMLDocument>( + initializer, kXMLDocumentClass | kSVGDocumentClass); } - protected: XMLDocument(const DocumentInit&, DocumentClassFlags document_classes); }; |