diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/dom/document.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/dom/document.cc | 667 |
1 files changed, 259 insertions, 408 deletions
diff --git a/chromium/third_party/blink/renderer/core/dom/document.cc b/chromium/third_party/blink/renderer/core/dom/document.cc index 5f48e26bfde..c067ee55319 100644 --- a/chromium/third_party/blink/renderer/core/dom/document.cc +++ b/chromium/third_party/blink/renderer/core/dom/document.cc @@ -33,12 +33,13 @@ // instead of including more headers. If that is infeasible, adjust the limit. // For more info, see // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md -#pragma clang max_tokens_here 1000000 +#pragma clang max_tokens_here 1010000 #include <memory> #include <utility> #include "base/auto_reset.h" +#include "base/debug/dump_without_crashing.h" #include "base/macros.h" #include "base/metrics/histogram_functions.h" #include "base/optional.h" @@ -52,6 +53,7 @@ #include "services/metrics/public/cpp/mojo_ukm_recorder.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_source_id.h" +#include "services/network/public/cpp/web_sandbox_flags.h" #include "services/network/public/mojom/ip_address_space.mojom-blink.h" #include "services/network/public/mojom/trust_tokens.mojom-blink.h" #include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h" @@ -67,7 +69,6 @@ #include "third_party/blink/public/mojom/page_state/page_state.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/public/platform/web_battery_savings.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/public/platform/web_theme_engine.h" #include "third_party/blink/public/web/web_print_page_description.h" @@ -78,9 +79,9 @@ #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_element_creation_options.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" #include "third_party/blink/renderer/bindings/core/v8/v8_element_registration_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_interest_cohort.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h" #include "third_party/blink/renderer/core/accessibility/ax_context.h" @@ -187,6 +188,7 @@ #include "third_party/blink/renderer/core/frame/viewport_data.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/html/anchor_element_metrics.h" +#include "third_party/blink/renderer/core/html/battery_savings.h" #include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" @@ -194,8 +196,6 @@ #include "third_party/blink/renderer/core/html/custom/custom_element_definition.h" #include "third_party/blink/renderer/core/html/custom/custom_element_descriptor.h" #include "third_party/blink/renderer/core/html/custom/custom_element_registry.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h" #include "third_party/blink/renderer/core/html/document_all_name_collection.h" #include "third_party/blink/renderer/core/html/document_name_collection.h" #include "third_party/blink/renderer/core/html/forms/email_input_type.h" @@ -216,6 +216,7 @@ #include "third_party/blink/renderer/core/html/html_meta_element.h" #include "third_party/blink/renderer/core/html/html_object_element.h" #include "third_party/blink/renderer/core/html/html_plugin_element.h" +#include "third_party/blink/renderer/core/html/html_popup_element.h" #include "third_party/blink/renderer/core/html/html_script_element.h" #include "third_party/blink/renderer/core/html/html_title_element.h" #include "third_party/blink/renderer/core/html/html_unknown_element.h" @@ -255,7 +256,7 @@ #include "third_party/blink/renderer/core/loader/http_refresh_scheduler.h" #include "third_party/blink/renderer/core/loader/idleness_detector.h" #include "third_party/blink/renderer/core/loader/interactive_detector.h" -#include "third_party/blink/renderer/core/loader/prerenderer_client.h" +#include "third_party/blink/renderer/core/loader/no_state_prefetch_client.h" #include "third_party/blink/renderer/core/loader/progress_tracker.h" #include "third_party/blink/renderer/core/mathml/mathml_element.h" #include "third_party/blink/renderer/core/mathml/mathml_row_element.h" @@ -414,69 +415,6 @@ bool DefaultFaviconAllowedByCSP(const Document* document, const IconURL& icon) { } // namespace -class DocumentOutliveTimeReporter : public BlinkGCObserver { - public: - explicit DocumentOutliveTimeReporter(Document* document) - : BlinkGCObserver(ThreadState::Current()), document_(document) {} - - ~DocumentOutliveTimeReporter() override { - // As not all documents are destroyed before the process dies, this might - // miss some long-lived documents or leaked documents. - UMA_HISTOGRAM_EXACT_LINEAR( - "Document.OutliveTimeAfterShutdown.DestroyedBeforeProcessDies", - GetOutliveTimeCount() + 1, 101); - } - - void OnCompleteSweepDone() override { - enum GCCount { - kGCCount5, - kGCCount10, - kGCCountMax, - }; - - // There are some cases that a document can live after shutting down because - // the document can still be referenced (e.g. a document opened via - // window.open can be referenced by the opener even after shutting down). To - // avoid such cases as much as possible, outlive time count is started after - // all DomWrapper of the document have disappeared. - if (!gc_age_when_document_detached_) { - if (document_->domWindow() && - DOMWrapperWorld::HasWrapperInAnyWorldInMainThread( - document_->domWindow())) { - return; - } - gc_age_when_document_detached_ = ThreadState::Current()->GcAge(); - } - - int outlive_time_count = GetOutliveTimeCount(); - if (outlive_time_count == 5 || outlive_time_count == 10) { - const char* kUMAString = "Document.OutliveTimeAfterShutdown.GCCount"; - - if (outlive_time_count == 5) - UMA_HISTOGRAM_ENUMERATION(kUMAString, kGCCount5, kGCCountMax); - else if (outlive_time_count == 10) - UMA_HISTOGRAM_ENUMERATION(kUMAString, kGCCount10, kGCCountMax); - else - NOTREACHED(); - } - - if (outlive_time_count == 5 || outlive_time_count == 10 || - outlive_time_count == 20 || outlive_time_count == 50) { - document_->RecordUkmOutliveTimeAfterShutdown(outlive_time_count); - } - } - - private: - int GetOutliveTimeCount() const { - if (!gc_age_when_document_detached_) - return 0; - return ThreadState::Current()->GcAge() - gc_age_when_document_detached_; - } - - WeakPersistent<Document> document_; - int gc_age_when_document_detached_ = 0; -}; - static const unsigned kCMaxWriteRecursionDepth = 21; // This amount of time must have elapsed before we will even consider scheduling @@ -705,6 +643,7 @@ Document::Document(const DocumentInit& initializer, : ContainerNode(nullptr, kCreateDocument), TreeScope(*this), is_initial_empty_document_(initializer.IsInitialEmptyDocument()), + is_prerendering_(initializer.IsPrerendering()), evaluate_media_queries_on_style_recalc_(false), pending_sheet_layout_(kNoLayoutWithPendingSheets), dom_window_(initializer.GetWindow()), @@ -782,7 +721,6 @@ Document::Document(const DocumentInit& initializer, write_recursion_depth_(0), scripted_animation_controller_( MakeGarbageCollected<ScriptedAnimationController>(domWindow())), - registration_context_(initializer.RegistrationContext(this)), element_data_cache_clear_timer_( GetTaskRunner(TaskType::kInternalUserInteraction), this, @@ -813,7 +751,6 @@ Document::Document(const DocumentInit& initializer, ukm_source_id_(initializer.UkmSourceId() == ukm::kInvalidSourceId ? ukm::UkmRecorder::GetNewSourceID() : initializer.UkmSourceId()), - needs_to_record_ukm_outlive_time_(false), viewport_data_(MakeGarbageCollected<ViewportData>(*this)), is_for_external_handler_(initializer.IsForExternalHandler()), fragment_directive_(MakeGarbageCollected<FragmentDirective>()), @@ -826,9 +763,6 @@ Document::Document(const DocumentInit& initializer, ProvideContextFeaturesToDocumentFrom(*this, *GetFrame()->GetPage()); fetcher_ = FrameFetchContext::CreateFetcherForCommittedDocument( *GetFrame()->Loader().GetDocumentLoader(), *this); - CustomElementRegistry* registry = dom_window_->MaybeCustomElements(); - if (registry && registration_context_) - registry->Entangle(registration_context_); cookie_jar_ = MakeGarbageCollected<CookieJar>(this); } else { // We disable fetches for frame-less Documents, including HTML-imported @@ -838,11 +772,12 @@ Document::Document(const DocumentInit& initializer, auto& properties = *MakeGarbageCollected<DetachableResourceFetcherProperties>( *MakeGarbageCollected<NullResourceFetcherProperties>()); - fetcher_ = MakeGarbageCollected<ResourceFetcher>(ResourceFetcherInit( - properties, &FetchContext::NullInstance(), - GetTaskRunner(TaskType::kNetworking), - GetTaskRunner(TaskType::kNetworkingUnfreezable), - nullptr /* loader_factory */, GetExecutionContext())); + fetcher_ = MakeGarbageCollected<ResourceFetcher>( + ResourceFetcherInit(properties, &FetchContext::NullInstance(), + GetTaskRunner(TaskType::kNetworking), + GetTaskRunner(TaskType::kNetworkingUnfreezable), + nullptr /* loader_factory */, GetExecutionContext(), + nullptr /* back_forward_cache_loader_helper */)); if (imports_controller_) { // We don't expect the fetcher to be used, so count such unexpected use. @@ -874,7 +809,7 @@ Document::Document(const DocumentInit& initializer, is_vertical_scroll_enforced_ = GetFrame() && !GetFrame()->IsMainFrame() && - RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() && + RuntimeEnabledFeatures::ExperimentalPoliciesEnabled() && !dom_window_->IsFeatureEnabled( mojom::blink::FeaturePolicyFeature::kVerticalScroll); @@ -884,13 +819,13 @@ Document::Document(const DocumentInit& initializer, lifecycle_.AdvanceTo(DocumentLifecycle::kInactive); - UpdateForcedColors(); - // Since CSSFontSelector requires Document::fetcher_ and StyleEngine owns // CSSFontSelector, need to initialize |style_engine_| after initializing // |fetcher_|. style_engine_ = MakeGarbageCollected<StyleEngine>(*this); + UpdateForcedColors(); + // The parent's parser should be suspended together with all the other // objects, else this new Document would have a new ExecutionContext which // suspended state would not match the one from the parent, and could start @@ -1109,8 +1044,6 @@ Element* Document::CreateElementForBinding(const AtomicString& name, return element; QualifiedName q_name(g_null_atom, local_name, html_names::xhtmlNamespaceURI); - if (RegistrationContext() && V0CustomElement::IsValidName(local_name)) - return RegistrationContext()->CreateCustomTagElement(*this, q_name); return MakeGarbageCollected<HTMLUnknownElement>(q_name, *this); } return MakeGarbageCollected<Element>( @@ -1163,27 +1096,16 @@ Element* Document::CreateElementForBinding( ? html_names::xhtmlNamespaceURI : g_null_atom); - bool is_v1 = - string_or_options.IsElementCreationOptions() || !RegistrationContext(); - // V0 is only allowed with the flag. - DCHECK(is_v1 || RuntimeEnabledFeatures::CustomElementsV0Enabled()); - bool create_v1_builtin = string_or_options.IsElementCreationOptions(); - bool should_create_builtin = - create_v1_builtin || string_or_options.IsString(); + bool create_builtin = string_or_options.IsElementCreationOptions() || + string_or_options.IsString(); // 3. const AtomicString& is = GetTypeExtension(this, string_or_options); // 5. Let element be the result of creating an element given ... Element* element = - CreateElement(q_name, - is_v1 ? CreateElementFlags::ByCreateElementV1() - : CreateElementFlags::ByCreateElementV0(), - should_create_builtin ? is : g_null_atom); - - // 8. If 'is' is non-null, set 'is' attribute - if (!is_v1 && !is.IsEmpty()) - element->setAttribute(html_names::kIsAttr, is); + CreateElement(q_name, CreateElementFlags::ByCreateElement(), + create_builtin ? is : g_null_atom); return element; } @@ -1221,8 +1143,6 @@ Element* Document::createElementNS(const AtomicString& namespace_uri, CreateElementFlags flags = CreateElementFlags::ByCreateElement(); if (CustomElement::ShouldCreateCustomElement(q_name)) return CustomElement::CreateCustomElement(*this, q_name, flags); - if (RegistrationContext() && V0CustomElement::IsValidName(q_name.LocalName())) - return RegistrationContext()->CreateCustomTagElement(*this, q_name); return CreateRawElement(q_name, flags); } @@ -1241,13 +1161,8 @@ Element* Document::createElementNS( if (q_name == QualifiedName::Null()) return nullptr; - bool is_v1 = - string_or_options.IsElementCreationOptions() || !RegistrationContext(); - // V0 is only allowed with the flag. - DCHECK(is_v1 || RuntimeEnabledFeatures::CustomElementsV0Enabled()); - bool create_v1_builtin = string_or_options.IsElementCreationOptions(); - bool should_create_builtin = - create_v1_builtin || string_or_options.IsString(); + bool create_builtin = string_or_options.IsElementCreationOptions() || + string_or_options.IsString(); // 2. const AtomicString& is = GetTypeExtension(this, string_or_options); @@ -1262,14 +1177,8 @@ Element* Document::createElementNS( // 3. Let element be the result of creating an element Element* element = - CreateElement(q_name, - is_v1 ? CreateElementFlags::ByCreateElementV1() - : CreateElementFlags::ByCreateElementV0(), - should_create_builtin ? is : g_null_atom); - - // 4. If 'is' is non-null, set 'is' attribute - if (!is_v1 && !is.IsEmpty()) - element->setAttribute(html_names::kIsAttr, is); + CreateElement(q_name, CreateElementFlags::ByCreateElement(), + create_builtin ? is : g_null_atom); return element; } @@ -1280,7 +1189,7 @@ Element* Document::CreateElement(const QualifiedName& q_name, const CreateElementFlags flags, const AtomicString& is) { CustomElementDefinition* definition = nullptr; - if (flags.IsCustomElementsV1() && + if (flags.IsCustomElements() && q_name.NamespaceURI() == html_names::xhtmlNamespaceURI) { const CustomElementDescriptor desc(is.IsNull() ? q_name.LocalName() : is, q_name.LocalName()); @@ -1295,50 +1204,6 @@ Element* Document::CreateElement(const QualifiedName& q_name, flags, is); } -ScriptValue Document::registerElement(ScriptState* script_state, - const AtomicString& name, - const ElementRegistrationOptions* options, - ExceptionState& exception_state) { - // TODO(crbug.com/937746): Anything caught by this DCHECK is using the - // now-removed Custom Elements v0 API. - DCHECK(false) << "Custom Elements v0 has been removed."; - - if (!RegistrationContext()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "No element registration context is available."); - return ScriptValue(); - } - - // Polymer V1 uses Custom Elements V0. <dom-module> is defined in its base - // library and is a strong signal that this is a Polymer V1. - // This counter is used to research how much users are affected once Custom - // Element V0 is deprecated. - if (name == "dom-module") - UseCounter::Count(*this, WebFeature::kPolymerV1Detected); - - V0CustomElementConstructorBuilder constructor_builder(script_state, options); - RegistrationContext()->RegisterElement(this, &constructor_builder, name, - exception_state); - if (exception_state.HadException()) - return ScriptValue(); - return constructor_builder.BindingsReturnValue(); -} - -V0CustomElementRegistrationContext* Document::RegistrationContext() const { - if (RuntimeEnabledFeatures::CustomElementsV0Enabled()) - return registration_context_.Get(); - return nullptr; -} - -V0CustomElementMicrotaskRunQueue* Document::CustomElementMicrotaskRunQueue() { - if (!custom_element_microtask_run_queue_) { - custom_element_microtask_run_queue_ = - MakeGarbageCollected<V0CustomElementMicrotaskRunQueue>(); - } - return custom_element_microtask_run_queue_.Get(); -} - void Document::ClearImportsController() { fetcher_->ClearContext(); imports_controller_ = nullptr; @@ -1909,9 +1774,9 @@ bool Document::IsPrefetchOnly() const { if (!GetFrame() || !GetFrame()->GetPage()) return false; - PrerendererClient* prerenderer_client = - PrerendererClient::From(GetFrame()->GetPage()); - return prerenderer_client && prerenderer_client->IsPrefetchOnly(); + NoStatePrefetchClient* no_state_prefetch_client = + NoStatePrefetchClient::From(GetFrame()->GetPage()); + return no_state_prefetch_client && no_state_prefetch_client->IsPrefetchOnly(); } AtomicString Document::visibilityState() const { @@ -1931,6 +1796,13 @@ void Document::SetWasDiscarded(bool was_discarded) { } void Document::DidChangeVisibilityState() { + if (load_event_progress_ >= kUnloadVisibilityChangeInProgress) { + // It's possible to get here even after we've started unloading the document + // and dispatched the visibilitychange event, e.g. when we're closing a tab, + // where we would first try to dispatch unload events, and then close the + // tab and update the visibility state. + return; + } DispatchEvent(*Event::CreateBubble(event_type_names::kVisibilitychange)); // Also send out the deprecated version until it can be removed. DispatchEvent( @@ -2076,6 +1948,8 @@ bool Document::ShouldScheduleLayoutTreeUpdate() const { // recalc. if (lifecycle_.GetState() == DocumentLifecycle::kInPreLayout) return false; + if (lifecycle_.GetState() == DocumentLifecycle::kInPerformLayout) + return false; if (!ShouldScheduleLayout()) return false; return true; @@ -2255,38 +2129,27 @@ void Document::PropagateStyleToViewport() { } } - // TODO(954423, 952711): overscroll-behavior (and most likely - // overflow-anchor) should be propagated from the document element and not - // the viewport defining element. + // TODO(954423): overscroll-behavior (and most likely overflow-anchor) + // should be propagated from the document element and not the viewport + // defining element. PROPAGATE_FROM(overflow_style, OverscrollBehaviorX, SetOverscrollBehaviorX, EOverscrollBehavior::kAuto); PROPAGATE_FROM(overflow_style, OverscrollBehaviorY, SetOverscrollBehaviorY, EOverscrollBehavior::kAuto); - // Counts any time scroll snapping and scroll padding break if we change its - // viewport propagation logic. Scroll snapping only breaks if body has - // non-none snap type that is different from the document one. - // TODO(952711): Remove once propagation logic change is complete. + // Counts any time overscroll behavior break if we change its viewport + // propagation logic. Overscroll behavior only breaks if body has non-none + // type that is different from the document one. + // TODO(954423): Remove once propagation logic change is complete. if (document_element_style && body_style) { - bool snap_type_is_different = - !body_style->GetScrollSnapType().is_none && - (body_style->GetScrollSnapType() != - document_element_style->GetScrollSnapType()); - bool scroll_padding_is_different = - body_style->ScrollPaddingTop() != - document_element_style->ScrollPaddingTop() || - body_style->ScrollPaddingBottom() != - document_element_style->ScrollPaddingBottom() || - body_style->ScrollPaddingLeft() != - document_element_style->ScrollPaddingLeft() || - body_style->ScrollPaddingRight() != - document_element_style->ScrollPaddingRight(); - - if (snap_type_is_different) { - UseCounter::Count(*this, WebFeature::kScrollSnapOnViewportBreaks); - } - if (scroll_padding_is_different) { - UseCounter::Count(*this, WebFeature::kScrollPaddingOnViewportBreaks); + bool overscroll_behavior_is_different = + body_style->OverscrollBehaviorX() != + document_element_style->OverscrollBehaviorX() || + body_style->OverscrollBehaviorY() != + document_element_style->OverscrollBehaviorY(); + if (overscroll_behavior_is_different) { + UseCounter::Count(*this, + WebFeature::kOversrollBehaviorOnViewportBreaks); } } @@ -2370,7 +2233,6 @@ static void AssertNodeClean(const Node& node) { DCHECK(!node.ChildNeedsStyleRecalc()); DCHECK(!node.NeedsReattachLayoutTree()); DCHECK(!node.ChildNeedsReattachLayoutTree()); - DCHECK(!node.ChildNeedsDistributionRecalc()); DCHECK(!node.NeedsStyleInvalidation()); DCHECK(!node.ChildNeedsStyleInvalidation()); DCHECK(!node.GetForceReattachLayoutTree()); @@ -2415,21 +2277,36 @@ static void AssertLayoutTreeUpdated(Node& root) { void Document::UpdateStyleAndLayoutTree() { DCHECK(IsMainThread()); - if (Lifecycle().LifecyclePostponed()) + if (!IsActive() || !View() || View()->ShouldThrottleRendering() || + Lifecycle().LifecyclePostponed()) { return; + } HTMLFrameOwnerElement::PluginDisposeSuspendScope suspend_plugin_dispose; ScriptForbiddenScope forbid_script; - if (HTMLFrameOwnerElement* owner = LocalOwner()) { + if (HTMLFrameOwnerElement* owner = LocalOwner()) owner->GetDocument().UpdateStyleAndLayoutTree(); - } - if (!View() || !IsActive()) - return; + UpdateStyleAndLayoutTreeForThisDocument(); +} - if (View()->ShouldThrottleRendering()) +void Document::UpdateStyleAndLayoutTreeForThisDocument() { + DCHECK(IsMainThread()); + if (!IsActive() || !View() || View()->ShouldThrottleRendering() || + Lifecycle().LifecyclePostponed()) { return; + } + +#if DCHECK_IS_ON() + if (HTMLFrameOwnerElement* owner = LocalOwner()) { + DCHECK(!owner->GetDocument() + .GetSlotAssignmentEngine() + .HasPendingSlotAssignmentRecalc()); + DCHECK(!owner->GetDocument().NeedsLayoutTreeUpdate()); + AssertLayoutTreeUpdated(owner->GetDocument()); + } +#endif // RecalcSlotAssignments should be done before checking // NeedsLayoutTreeUpdate(). @@ -2483,9 +2360,8 @@ void Document::UpdateStyleAndLayoutTree() { EvaluateMediaQueryListIfNeeded(); UpdateUseShadowTreesIfNeeded(); - UpdateDistributionForLegacyDistributedNodes(); - GetStyleEngine().UpdateActiveStyle(); + GetStyleEngine().UpdateCounterStyles(); InvalidateStyleAndLayoutForFontUpdates(); UpdateStyleInvalidationIfNeeded(); UpdateStyle(); @@ -2541,7 +2417,7 @@ void Document::UpdateStyle() { PropagateStyleToViewport(); - View()->UpdateCountersAfterStyleChange(); + GetLayoutView()->UpdateMarkersAndCountersAfterStyleChange(); GetLayoutView()->RecalcLayoutOverflow(); DCHECK(!NeedsStyleRecalc()); @@ -2671,6 +2547,7 @@ void Document::UpdateStyleAndLayoutForNode(const Node* node, } void Document::ApplyScrollRestorationLogic() { + DCHECK(View()); // This function in not re-entrant. However, the places that invoke this are // re-entrant. Specifically, UpdateStyleAndLayout() calls this, which in turn // can do a find-in-page for the scroll-to-text feature, which can cause @@ -2744,10 +2621,8 @@ void Document::ApplyScrollRestorationLogic() { } void Document::MarkHasFindInPageRequest() { - // Note that although find-in-page requests happen in non-main frames, we only - // record the main frame results (per UKM policy). Additionally, we only - // record the event once. - if (had_find_in_page_request_ || !IsInMainFrame()) + // Only record the event once in a document. + if (had_find_in_page_request_) return; auto* recorder = UkmRecorder(); @@ -2760,10 +2635,8 @@ void Document::MarkHasFindInPageRequest() { } void Document::MarkHasFindInPageContentVisibilityActiveMatch() { - // Note that although find-in-page in content-visibility requests happen in - // non-main frames, we only record the main frame results (per UKM policy). - // Additionally, we only record the event once. - if (had_find_in_page_render_subtree_active_match_ || !IsInMainFrame()) + // Only record the event once in a document. + if (had_find_in_page_render_subtree_active_match_) return; auto* recorder = UkmRecorder(); @@ -2777,11 +2650,8 @@ void Document::MarkHasFindInPageContentVisibilityActiveMatch() { } void Document::MarkHasFindInPageBeforematchExpandedHiddenMatchable() { - // Note that although find-in-page in content-visibility requests happen in - // non-main frames, we only record the main frame results (per UKM policy). - // Additionally, we only record the event once. - if (had_find_in_page_beforematch_expanded_hidden_matchable_ || - !IsInMainFrame()) + // Only record the event once in a document. + if (had_find_in_page_beforematch_expanded_hidden_matchable_) return; auto* recorder = UkmRecorder(); @@ -2809,7 +2679,7 @@ void Document::UpdateStyleAndLayout(DocumentUpdateReason reason) { if (HTMLFrameOwnerElement* owner = LocalOwner()) owner->GetDocument().UpdateStyleAndLayout(reason); - UpdateStyleAndLayoutTree(); + UpdateStyleAndLayoutTreeForThisDocument(); if (!IsActive()) { if (reason != DocumentUpdateReason::kBeginMainFrame && frame_view) @@ -2823,7 +2693,8 @@ void Document::UpdateStyleAndLayout(DocumentUpdateReason reason) { if (Lifecycle().GetState() < DocumentLifecycle::kLayoutClean) Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean); - ApplyScrollRestorationLogic(); + if (frame_view) + ApplyScrollRestorationLogic(); if (LocalFrameView* frame_view_anchored = View()) frame_view_anchored->PerformScrollAnchoringAdjustments(); @@ -2926,24 +2797,6 @@ void Document::EnsurePaintLocationDataValidForNode( // For all nodes we must have up-to-date style and have performed layout to do // any location-based calculation. UpdateStyleAndLayout(reason); - - // The location of elements that are position: sticky is not known until - // compositing inputs are cleaned. Therefore, for any elements that are either - // sticky or are in a sticky sub-tree (e.g. are affected by a sticky element), - // we need to also clean compositing inputs. - if (View() && node->GetLayoutObject() && - node->GetLayoutObject()->StyleRef().SubtreeIsSticky()) { - bool success = false; - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - // In CAP, compositing inputs are cleaned as part of PrePaint. - success = View()->UpdateAllLifecyclePhasesExceptPaint(reason); - } else { - success = View()->UpdateLifecycleToCompositingInputsClean(reason); - } - // The lifecycle update should always succeed, because forced lifecycles - // from script are never throttled. - DCHECK(success); - } } bool Document::IsPageBoxVisible(uint32_t page_index) { @@ -3172,9 +3025,6 @@ void Document::Shutdown() { if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) layout_view_->CleanUpCompositor(); - if (RegistrationContext()) - RegistrationContext()->DocumentWasDetached(); - MutationObserver::CleanSlotChangeList(*this); hover_element_ = nullptr; @@ -3239,12 +3089,6 @@ void Document::Shutdown() { lifecycle_.AdvanceTo(DocumentLifecycle::kStopped); DCHECK(!View()->IsAttached()); - needs_to_record_ukm_outlive_time_ = IsInMainFrame(); - if (needs_to_record_ukm_outlive_time_) { - // Ensure |ukm_recorder_| and |ukm_source_id_|. - UkmRecorder(); - } - // Don't create a |ukm_recorder_| and |ukm_source_id_| unless necessary. if (IdentifiabilityStudySettings::Get()->IsActive()) { IdentifiabilitySampleCollector::Get()->FlushSource(UkmRecorder(), @@ -3262,9 +3106,6 @@ void Document::Shutdown() { // explicit in each of the callers of Document::detachLayoutTree(). dom_window_ = nullptr; execution_context_ = nullptr; - - document_outlive_time_reporter_ = - std::make_unique<DocumentOutliveTimeReporter>(this); } void Document::RemoveAllEventListeners() { @@ -3392,6 +3233,8 @@ void Document::SetPrinting(PrintingState state) { bool is_printing = Printing(); if (was_printing != is_printing) { + GetDisplayLockDocumentState().NotifyPrintingOrPreviewChanged(); + // We force the color-scheme to light for printing. ColorSchemeChanged(); // StyleResolver::InitialStyleForElement uses different zoom for printing. @@ -3412,10 +3255,6 @@ void Document::SetPrinting(PrintingState state) { } } -void Document::SetIsPaintingPreview(bool is_painting_preview) { - is_painting_preview_ = is_painting_preview; -} - // https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#document-open-steps void Document::open(LocalDOMWindow* entered_window, ExceptionState& exception_state) { @@ -3476,29 +3315,55 @@ void Document::open(LocalDOMWindow* entered_window, if (ignore_opens_and_writes_for_abort_) return; - // If this document is fully active, change |document|'s URL to the URL of the - // responsible document specified by the entry settings object. - if (dom_window_ && entered_window && dom_window_ != entered_window) { - auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->CopyStateFrom(entered_window->GetContentSecurityPolicy()); - // We inherit the sandbox flags of the entered document, so mask on - // the ones contained in the CSP. - dom_window_->GetSecurityContext().ApplySandboxFlags(csp->GetSandboxMask()); - dom_window_->GetSecurityContext().SetContentSecurityPolicy(csp); - dom_window_->GetContentSecurityPolicy()->BindToDelegate( - dom_window_->GetContentSecurityPolicyDelegate()); + // If this document is fully active, then run the URL and history update steps + // for this document with the entered window's url. + if (dom_window_ && entered_window) { + KURL new_url = entered_window->Url(); // Clear the hash fragment from the inherited URL to prevent a // scroll-into-view for any document.open()'d frame. - KURL new_url = entered_window->Url(); - new_url.SetFragmentIdentifier(String()); + if (dom_window_ != entered_window) + new_url.SetFragmentIdentifier(String()); SetURL(new_url); - if (Loader()) - Loader()->UpdateUrlForDocumentOpen(new_url); - dom_window_->GetSecurityContext().SetSecurityOrigin( - entered_window->GetMutableSecurityOrigin()); - dom_window_->SetReferrerPolicy(entered_window->GetReferrerPolicy()); - cookie_url_ = entered_window->document()->CookieURL(); + auto* state_object = Loader()->GetHistoryItem() + ? Loader()->GetHistoryItem()->StateObject() + : nullptr; + Loader()->RunURLAndHistoryUpdateSteps(new_url, state_object); + + if (dom_window_ != entered_window) { + auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); + csp->CopyStateFrom(entered_window->GetContentSecurityPolicy()); + // We inherit the sandbox flags of the entered document, so mask on + // the ones contained in the CSP. The operator| is a bitwise operation on + // the sandbox flags bits. It makes the sandbox policy stricter (or as + // strict) as both policy. + // + // TODO(arthursonzogni): Why merging sandbox flags? + // This doesn't look great at many levels: + // - The browser process won't be notified of the update. + // - The origin won't be made opaque, despite the new flags. + // - The sandbox flags of the document can't be considered to be an + // immutable property anymore. + // + // Ideally: + // - javascript-url document. + // - XSLT document. + // - document.open. + // should not mutate the security properties of the current document. From + // the browser process point of view, all of those operations are not + // considered to produce new documents. No IPCs are sent, it is as if it + // was a no-op. + dom_window_->GetSecurityContext().SetSandboxFlags( + dom_window_->GetSecurityContext().GetSandboxFlags() | + entered_window->GetSandboxFlags()); + dom_window_->GetSecurityContext().SetContentSecurityPolicy(csp); + dom_window_->GetContentSecurityPolicy()->BindToDelegate( + dom_window_->GetContentSecurityPolicyDelegate()); + + dom_window_->GetSecurityContext().SetSecurityOrigin( + entered_window->GetMutableSecurityOrigin()); + cookie_url_ = entered_window->document()->CookieURL(); + } } open(); @@ -3970,20 +3835,11 @@ bool Document::CheckCompletedInternal() { GetFrame()->GetFrameScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kDocumentLoaded, - {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + {SchedulingPolicy::DisableBackForwardCache()}); GetFrame()->GetFrameScheduler()->OnLoad(); AnchorElementMetrics::NotifyOnLoad(*this); DetectJavascriptFrameworksOnLoad(*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()); - } } if (auto* view = View()) { @@ -4110,12 +3966,18 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client, void Document::DispatchUnloadEvents( SecurityOrigin* committing_origin, base::Optional<Document::UnloadEventTiming>* unload_timing) { + // TODO(crbug.com/1161996): Remove this VLOG once the investigation is done. + VLOG(1) << "Document::DispatchUnloadEvents() URL = " << Url(); + PluginScriptForbiddenScope forbid_plugin_destructor_scripting; PageDismissalScope in_page_dismissal; if (parser_) parser_->StopParsing(); if (load_event_progress_ == kLoadEventNotRun || + // TODO(dcheng): We should consider if we can make this conditional check + // stronger with a DCHECK() that this isn't called if the unload event is + // already complete. load_event_progress_ > kUnloadEventInProgress) { return; } @@ -4182,6 +4044,9 @@ void Document::DispatchUnloadEvents( GetFrame()->Loader().SaveScrollAnchor(); + // TODO(crbug.com/1161996): Remove this VLOG once the investigation is done. + VLOG(1) << "Actually dispatching an UnloadEvent: URL = " << Url(); + load_event_progress_ = kUnloadEventInProgress; Event& unload_event = *Event::Create(event_type_names::kUnload); const base::TimeTicks unload_event_start = base::TimeTicks::Now(); @@ -4195,13 +4060,10 @@ void Document::DispatchUnloadEvents( ("DocumentEventTiming.UnloadDuration", 0, 10000000, 50)); unload_histogram.CountMicroseconds(unload_event_end - unload_event_start); - // Fill in the unload timing if the new document origin has access to - // them. - if (committing_origin->CanRequest(Url())) { - auto& timing = unload_timing->emplace(); - timing.unload_event_start = unload_event_start; - timing.unload_event_end = unload_event_end; - } + auto& timing = unload_timing->emplace(); + timing.can_request = committing_origin->CanRequest(Url()); + timing.unload_event_start = unload_event_start; + timing.unload_event_end = unload_event_end; } load_event_progress_ = kUnloadEventHandled; } @@ -4948,8 +4810,7 @@ Document* Document::CloneDocumentWithoutChildren() const { .WithURL(Url()); if (IsA<XMLDocument>(this)) { if (IsXHTMLDocument()) - return XMLDocument::CreateXHTML( - init.WithRegistrationContext(RegistrationContext())); + return XMLDocument::CreateXHTML(init); return MakeGarbageCollected<XMLDocument>(init); } return MakeGarbageCollected<Document>(init); @@ -5103,7 +4964,6 @@ bool Document::SetFocusedElement(Element* new_focused_element, Element* old_focused_element = focused_element_; focused_element_ = nullptr; - UpdateDistributionForFlatTreeTraversal(); Node* ancestor = (old_focused_element && old_focused_element->isConnected() && new_focused_element) ? FlatTreeTraversal::CommonAncestor(*old_focused_element, @@ -5120,7 +4980,8 @@ bool Document::SetFocusedElement(Element* new_focused_element, // Dispatch the blur event and let the node do any other blur related // activities (important for text fields) // If page lost focus, blur event will have already been dispatched - if (GetPage() && (GetPage()->GetFocusController().IsFocused())) { + if (!params.omit_blur_events && GetPage() && + (GetPage()->GetFocusController().IsFocused())) { old_focused_element->DispatchBlurEvent(new_focused_element, params.type, params.source_capabilities); if (focused_element_) { @@ -5469,7 +5330,7 @@ void Document::NodeChildrenWillBeRemoved(ContainerNode& container) { observer->NodeChildrenWillBeRemoved(container); }); - if (ContainsV1ShadowTree()) { + if (ContainsShadowTree()) { for (Node& n : NodeTraversal::ChildrenOf(container)) n.CheckSlotChangeBeforeRemoved(); } @@ -5490,7 +5351,7 @@ void Document::NodeWillBeRemoved(Node& n) { observer->NodeWillBeRemoved(n); }); - if (ContainsV1ShadowTree()) + if (ContainsShadowTree()) n.CheckSlotChangeBeforeRemoved(); if (n.InActiveDocument()) @@ -5897,7 +5758,7 @@ void Document::setDomain(const String& raw_domain, } const String feature_policy_error = - "Setting `document.domain` is disabled by Feature Policy."; + "Setting `document.domain` is disabled by permissions policy."; if (!dom_window_->IsFeatureEnabled( mojom::blink::FeaturePolicyFeature::kDocumentDomain, ReportOptions::kReportOnFailure, feature_policy_error)) { @@ -5905,6 +5766,14 @@ void Document::setDomain(const String& raw_domain, return; } + const String document_policy_error = + "Setting `document.domain` is disabled by document policy."; + if (!dom_window_->IsFeatureEnabled( + mojom::blink::DocumentPolicyFeature::kDocumentDomain, + ReportOptions::kReportOnFailure, document_policy_error)) { + return; + } + if (dom_window_->IsSandboxed( network::mojom::blink::WebSandboxFlags::kDocumentDomain)) { exception_state.ThrowSecurityError( @@ -5954,23 +5823,28 @@ void Document::setDomain(const String& raw_domain, return; } - if (RuntimeEnabledFeatures::OriginIsolationHeaderEnabled(dom_window_) && - dom_window_->GetAgent()->IsOriginIsolated()) { + // We technically only need to IsOriginKeyed(), as IsCrossOriginIsolated() + // implies IsOriginKeyed(). (The spec only checks "is origin-keyed".) But, + // we'll check both, in order to give warning messages that are more specific + // about the cause. Note: this means the order of the checks is important. + + if (RuntimeEnabledFeatures::CrossOriginIsolationEnabled() && + Agent::IsCrossOriginIsolated()) { AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::blink::ConsoleMessageSource::kSecurity, mojom::blink::ConsoleMessageLevel::kWarning, "document.domain mutation is ignored because the surrounding agent " - "cluster is origin-isolated.")); + "cluster is cross-origin isolated.")); return; } - if (RuntimeEnabledFeatures::CrossOriginIsolationEnabled() && - Agent::IsCrossOriginIsolated()) { + if (RuntimeEnabledFeatures::OriginIsolationHeaderEnabled(dom_window_) && + dom_window_->GetAgent()->IsOriginKeyed()) { AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::blink::ConsoleMessageSource::kSecurity, mojom::blink::ConsoleMessageLevel::kWarning, "document.domain mutation is ignored because the surrounding agent " - "cluster is cross-origin isolated.")); + "cluster is origin-keyed.")); return; } @@ -6096,11 +5970,8 @@ net::SiteForCookies Document::SiteForCookies() const { while (current_frame) { const url::Origin cur_security_origin = current_frame->GetSecurityContext()->GetSecurityOrigin()->ToUrlOrigin(); - if (!candidate.IsEquivalent( - net::SiteForCookies::FromOrigin(cur_security_origin))) { - return net::SiteForCookies(); - } - candidate.MarkIfCrossScheme(cur_security_origin); + if (!candidate.CompareWithFrameTreeOriginAndRevise(cur_security_origin)) + return candidate; current_frame = current_frame->Tree().Parent(); } @@ -6358,7 +6229,24 @@ mojom::blink::FlocService* Document::GetFlocService( return data_->floc_service_.get(); } -ScriptPromise Document::interestCohort(ScriptState* script_state) { +ScriptPromise Document::interestCohort(ScriptState* script_state, + ExceptionState& exception_state) { + if (!GetFrame()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidAccessError, + "A browsing context is required when calling document.interestCohort."); + return ScriptPromise(); + } + + if (!GetExecutionContext()->IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kInterestCohort)) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidAccessError, + "The \"interest-cohort\" Permissions Policy denied the use of " + "document.interestCohort."); + return ScriptPromise(); + } + ScriptPromiseResolver* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -6367,14 +6255,26 @@ ScriptPromise Document::interestCohort(ScriptState* script_state) { GetFlocService(ExecutionContext::From(script_state)) ->GetInterestCohort(WTF::Bind( [](ScriptPromiseResolver* resolver, Document* document, - const String& interest_cohort) { + mojom::blink::InterestCohortPtr interest_cohort) { DCHECK(resolver); DCHECK(document); - if (interest_cohort.IsEmpty()) { - resolver->Reject(); + if (interest_cohort->version.IsEmpty()) { + ScriptState* state = resolver->GetScriptState(); + ScriptState::Scope scope(state); + + // TODO(yaoxia): Distinguish between the different causes. + resolver->Reject(V8ThrowDOMException::CreateOrEmpty( + state->GetIsolate(), DOMExceptionCode::kDataError, + "Failed to get the interest cohort: either it is " + "unavailable, or the preferences or content settings has " + "denined the access.")); } else { - resolver->Resolve(interest_cohort); + InterestCohort* result = InterestCohort::Create(); + result->setId(interest_cohort->id); + result->setVersion(interest_cohort->version); + + resolver->Resolve(result); } }, WrapPersistent(resolver), WrapPersistent(this))); @@ -6854,28 +6754,6 @@ DOMWindow* Document::defaultView() const { return dom_window_; } -namespace { - -using performance_manager::mojom::InterventionPolicy; - -// A helper function to set the origin trial freeze policy of a document. -void SetOriginTrialFreezePolicy( - DocumentResourceCoordinator* document_resource_coordinator, - ExecutionContext* context) { - // An explicit opt-out overrides an explicit opt-in if both are present. - if (RuntimeEnabledFeatures::PageFreezeOptOutEnabled(context)) { - document_resource_coordinator->SetOriginTrialFreezePolicy( - InterventionPolicy::kOptOut); - UseCounter::Count(context, WebFeature::kPageFreezeOptOut); - } else if (RuntimeEnabledFeatures::PageFreezeOptInEnabled(context)) { - document_resource_coordinator->SetOriginTrialFreezePolicy( - InterventionPolicy::kOptIn); - UseCounter::Count(context, WebFeature::kPageFreezeOptIn); - } -} - -} // namespace - void Document::RecordAsyncScriptCount() { UMA_HISTOGRAM_COUNTS_100("Blink.Script.AsyncScriptCount", async_script_count_); @@ -6967,7 +6845,7 @@ AllowState Document::GetDeclarativeShadowRootAllowState() const { return declarative_shadow_root_allow_state_; } -void Document::setAllowDeclarativeShadowRoot(bool val) { +void Document::setAllowDeclarativeShadowRoots(bool val) { declarative_shadow_root_allow_state_ = val ? AllowState::kAllow : AllowState::kDeny; } @@ -7029,11 +6907,6 @@ void Document::FinishedParsing() { inspector_mark_load_event::Data(frame)); probe::DomContentLoadedEventFired(frame); frame->GetIdlenessDetector()->DomContentLoadedEventFired(); - - // Forward origin trial freeze policy to the corresponding frame object in - // the resource coordinator. - if (auto* document_resource_coordinator = GetResourceCoordinator()) - SetOriginTrialFreezePolicy(document_resource_coordinator, domWindow()); } // Schedule dropping of the ElementDataCache. We keep it alive for a while @@ -7059,7 +6932,11 @@ void Document::BeginLifecycleUpdatesIfRenderingReady() { if (!HaveRenderBlockingResourcesLoaded()) return; font_preload_manager_->WillBeginRendering(); - View()->BeginLifecycleUpdates(); + // TODO(japhet): If IsActive() is true, View() should always be non-null. + // Speculative fix for https://crbug.com/1171891 + if (auto* view = View()) { + view->BeginLifecycleUpdates(); + } } Vector<IconURL> Document::IconURLs(int icon_types_mask) { @@ -7181,7 +7058,7 @@ void Document::BatterySavingsMetaChanged() { if (!root_element) return; - WebBatterySavingsFlags savings = 0; + BatterySavingsFlags savings = 0; for (HTMLMetaElement& meta_element : Traversal<HTMLMetaElement>::DescendantsOf(*root_element)) { if (EqualIgnoringASCIICase(meta_element.GetName(), "battery-savings")) { @@ -7227,7 +7104,7 @@ HTMLLinkElement* Document::LinkCanonical() const { bool Document::AllowedToUseDynamicMarkUpInsertion( const char* api_name, ExceptionState& exception_state) { - if (!RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled()) { + if (!RuntimeEnabledFeatures::ExperimentalPoliciesEnabled()) { return true; } if (!GetFrame() || GetExecutionContext()->IsFeatureEnabled( @@ -7243,7 +7120,7 @@ bool Document::AllowedToUseDynamicMarkUpInsertion( exception_state.ThrowDOMException( DOMExceptionCode::kNotAllowedError, String::Format( - "The use of method '%s' has been blocked by feature policy. The " + "The use of method '%s' has been blocked by permissions policy. The " "feature " "'document-write' is disabled in this document.", api_name)); @@ -7445,6 +7322,23 @@ HTMLDialogElement* Document::ActiveModalDialog() const { return nullptr; } +bool Document::PopupShowing() const { + return !popup_element_stack_.IsEmpty(); +} +void Document::HideTopmostPopupElement() const { + if (popup_element_stack_.IsEmpty()) + return; + popup_element_stack_.back()->hide(); +} +void Document::HideAllPopupsUntil(const HTMLPopupElement* endpoint) { + while (!popup_element_stack_.IsEmpty() && + popup_element_stack_.back() != endpoint) { + popup_element_stack_.back()->hide(); + } + DCHECK(!endpoint || popup_element_stack_.back() == endpoint) + << "popup element not found in element stack"; +} + void Document::exitPointerLock() { if (!GetPage()) return; @@ -7487,15 +7381,6 @@ void Document::CheckLoadEventSoon() { } bool Document::IsDelayingLoadEvent() { - // Always delay load events until after garbage collection. - // This way we don't have to explicitly delay load events via - // incrementLoadEventDelayCount and decrementLoadEventDelayCount in - // Node destructors. - if (ThreadState::Current()->SweepForbidden()) { - if (!load_event_delay_count_) - CheckLoadEventSoon(); - return true; - } return load_event_delay_count_; } @@ -7645,8 +7530,6 @@ void Document::UpdateHoverActiveState(bool is_active, inner_element_in_document->GetDocument().LocalOwner(); } - UpdateDistributionForFlatTreeTraversal(); - UpdateActiveState(is_active, update_active_chain, inner_element_in_document); UpdateHoverState(inner_element_in_document); } @@ -7800,8 +7683,7 @@ Document& Document::EnsureTemplateDocument() { template_document_ = MakeGarbageCollected<HTMLDocument>( DocumentInit::Create() .WithExecutionContext(execution_context_.Get()) - .WithURL(BlankURL()) - .WithNewRegistrationContext()); + .WithURL(BlankURL())); } else { template_document_ = MakeGarbageCollected<Document>( DocumentInit::Create() @@ -8137,23 +8019,6 @@ void Document::SetShadowCascadeOrder(ShadowCascadeOrder order) { if (order == shadow_cascade_order_) return; - if (order == ShadowCascadeOrder::kShadowCascadeV0) { - may_contain_v0_shadow_ = true; - if (shadow_cascade_order_ == ShadowCascadeOrder::kShadowCascadeV1) { - // ::slotted() rules has to be moved to tree boundary rule sets. - style_engine_->V0ShadowAddedOnV1Document(); - UseCounter::Count(*this, WebFeature::kMixedShadowRootV0AndV1); - } - } - - // For V0 -> V1 upgrade, we need style recalculation for all elements. - if (shadow_cascade_order_ == ShadowCascadeOrder::kShadowCascadeV0 && - order == ShadowCascadeOrder::kShadowCascadeV1) { - GetStyleEngine().MarkAllElementsForStyleRecalc( - StyleChangeReasonForTracing::Create(style_change_reason::kShadow)); - UseCounter::Count(*this, WebFeature::kMixedShadowRootV0AndV1); - } - if (order > shadow_cascade_order_) shadow_cascade_order_ = order; } @@ -8207,12 +8072,6 @@ DOMFeaturePolicy* Document::featurePolicy() { return policy_.Get(); } -const AtomicString& Document::RequiredCSP() { - if (!Loader()) - return g_null_atom; - return GetFrame()->Loader().RequiredCSP(); -} - StylePropertyMapReadOnly* Document::ComputedStyleMap(Element* element) { ElementComputedStyleMap::AddResult add_result = element_computed_style_map_.insert(element, nullptr); @@ -8254,7 +8113,11 @@ void Document::Trace(Visitor* visitor) const { visitor->Trace(lists_invalidated_at_document_); visitor->Trace(node_lists_); visitor->Trace(top_layer_elements_); + visitor->Trace(popup_element_stack_); + visitor->Trace(load_event_delay_timer_); + visitor->Trace(plugin_loading_timer_); visitor->Trace(elem_sheet_); + visitor->Trace(clear_focused_element_timer_); visitor->Trace(node_iterators_); visitor->Trace(ranges_); visitor->Trace(document_explicit_root_intersection_observer_data_); @@ -8273,12 +8136,12 @@ void Document::Trace(Visitor* visitor) const { visitor->Trace(scripted_animation_controller_); visitor->Trace(scripted_idle_task_controller_); visitor->Trace(text_autosizer_); - visitor->Trace(registration_context_); - visitor->Trace(custom_element_microtask_run_queue_); + visitor->Trace(element_data_cache_clear_timer_); visitor->Trace(element_data_cache_); visitor->Trace(use_elements_needing_update_); visitor->Trace(template_document_); visitor->Trace(template_document_host_); + visitor->Trace(did_associate_form_controls_timer_); visitor->Trace(user_action_elements_); visitor->Trace(svg_extensions_); visitor->Trace(document_animations_); @@ -8310,18 +8173,6 @@ void Document::Trace(Visitor* visitor) const { ContainerNode::Trace(visitor); } -void Document::RecordUkmOutliveTimeAfterShutdown(int outlive_time_count) { - if (!needs_to_record_ukm_outlive_time_) - return; - - DCHECK(ukm_recorder_); - DCHECK(ukm_source_id_ != ukm::kInvalidSourceId); - - ukm::builders::Document_OutliveTimeAfterShutdown(ukm_source_id_) - .SetGCCount(outlive_time_count) - .Record(ukm_recorder_.get()); -} - bool Document::CurrentFrameHadRAF() const { return scripted_animation_controller_->CurrentFrameHadRAF(); } @@ -8337,8 +8188,6 @@ SlotAssignmentEngine& Document::GetSlotAssignmentEngine() { } bool Document::IsSlotAssignmentOrLegacyDistributionDirty() const { - if (ChildNeedsDistributionRecalc()) - return true; if (slot_assignment_engine_ && slot_assignment_engine_->HasPendingSlotAssignmentRecalc()) { return true; @@ -8347,9 +8196,6 @@ bool Document::IsSlotAssignmentOrLegacyDistributionDirty() const { } bool Document::IsFocusAllowed() const { - if (GetFrame() && GetFrame()->GetPage()->InsidePortal()) - return false; - if (!GetFrame() || GetFrame()->IsMainFrame() || LocalFrame::HasTransientUserActivation(GetFrame())) { // 'autofocus' runs Element::focus asynchronously at which point the @@ -8473,24 +8319,11 @@ void Document::SetShowBeforeUnloadDialog(bool show_dialog) { } void Document::ColorSchemeChanged() { - InvalidateScrollbars(); UpdateForcedColors(); GetStyleEngine().ColorSchemeChanged(); MediaQueryAffectingValueChanged(MediaValueChange::kOther); } -void Document::InvalidateScrollbars() { - if (PaintLayerScrollableArea* scrollable_area = - GetLayoutView()->GetScrollableArea()) { - if (auto* horizontal_scrollbar = scrollable_area->HorizontalScrollbar()) { - horizontal_scrollbar->SetNeedsPaintInvalidation(kAllParts); - } - if (auto* vertical_scrollbar = scrollable_area->VerticalScrollbar()) { - vertical_scrollbar->SetNeedsPaintInvalidation(kAllParts); - } - } -} - void Document::VisionDeficiencyChanged() { GetStyleEngine().VisionDeficiencyChanged(); } @@ -8504,6 +8337,8 @@ void Document::UpdateForcedColors() { ? web_theme_engine->GetForcedColors() : ForcedColors::kNone; in_forced_colors_mode_ = forced_colors != ForcedColors::kNone; + if (in_forced_colors_mode_) + GetStyleEngine().EnsureUAStyleForForcedColors(); } bool Document::InForcedColorsMode() const { @@ -8591,6 +8426,22 @@ const Node* Document::GetFindInPageActiveMatchNode() const { return find_in_page_active_match_node_; } +bool Document::InStyleRecalc() const { + return lifecycle_.GetState() == DocumentLifecycle::kInStyleRecalc || + style_engine_->InContainerQueryStyleRecalc(); +} + +Document::PaintPreviewScope::PaintPreviewScope(Document& document) + : document_(document) { + document_.is_painting_preview_ = true; + document_.GetDisplayLockDocumentState().NotifyPrintingOrPreviewChanged(); +} + +Document::PaintPreviewScope::~PaintPreviewScope() { + document_.is_painting_preview_ = false; + document_.GetDisplayLockDocumentState().NotifyPrintingOrPreviewChanged(); +} + template class CORE_TEMPLATE_EXPORT Supplement<Document>; } // namespace blink |