diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-16 09:59:13 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-20 10:28:53 +0000 |
commit | 6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch) | |
tree | c8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/third_party/blink/renderer/core/frame | |
parent | 3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff) | |
download | qtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz |
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/frame')
138 files changed, 3065 insertions, 2405 deletions
diff --git a/chromium/third_party/blink/renderer/core/frame/BUILD.gn b/chromium/third_party/blink/renderer/core/frame/BUILD.gn index 3c8b749feb3..92712039ea6 100644 --- a/chromium/third_party/blink/renderer/core/frame/BUILD.gn +++ b/chromium/third_party/blink/renderer/core/frame/BUILD.gn @@ -19,6 +19,7 @@ blink_core_sources("frame") { "csp/csp_directive_list.h", "csp/csp_source.cc", "csp/csp_source.h", + "csp/csp_violation_report_body.h", "csp/execution_context_csp_delegate.cc", "csp/execution_context_csp_delegate.h", "csp/media_list_directive.cc", @@ -107,8 +108,12 @@ blink_core_sources("frame") { "navigator_language.cc", "navigator_language.h", "navigator_on_line.h", + "navigator_scheduling.cc", + "navigator_scheduling.h", "navigator_user_activation.cc", "navigator_user_activation.h", + "navigator_user_agent.cc", + "navigator_user_agent.h", "opened_frame_tracker.cc", "opened_frame_tracker.h", "page_scale_constraints.cc", @@ -152,6 +157,8 @@ blink_core_sources("frame") { "rotation_viewport_anchor.h", "sandbox_flags.cc", "sandbox_flags.h", + "scheduling.cc", + "scheduling.h", "screen.cc", "screen.h", "screen_orientation_controller.cc", diff --git a/chromium/third_party/blink/renderer/core/frame/OWNERS b/chromium/third_party/blink/renderer/core/frame/OWNERS index 7d06251e6e7..67496f48f2e 100644 --- a/chromium/third_party/blink/renderer/core/frame/OWNERS +++ b/chromium/third_party/blink/renderer/core/frame/OWNERS @@ -2,5 +2,8 @@ bokan@chromium.org dcheng@chromium.org japhet@chromium.org +per-file *_type_converter*.*=set noparent +per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS + # TEAM: platform-architecture-dev@chromium.org # COMPONENT: Blink>Internals diff --git a/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc b/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc index 41c3968f2fe..3bfe8ef871b 100644 --- a/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc +++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc @@ -33,7 +33,7 @@ bool IsKnownAdExecutionContext(ExecutionContext* execution_context) { } // namespace AdTracker::AdTracker(LocalFrame* local_root) : local_root_(local_root) { - local_root_->GetProbeSink()->addAdTracker(this); + local_root_->GetProbeSink()->AddAdTracker(this); } AdTracker::~AdTracker() { @@ -43,7 +43,7 @@ AdTracker::~AdTracker() { void AdTracker::Shutdown() { if (!local_root_) return; - local_root_->GetProbeSink()->removeAdTracker(this); + local_root_->GetProbeSink()->RemoveAdTracker(this); local_root_ = nullptr; } @@ -108,28 +108,25 @@ void AdTracker::Did(const probe::CallFunction& probe) { DidExecuteScript(); } -void AdTracker::WillSendRequest(ExecutionContext* execution_context, - unsigned long identifier, - DocumentLoader* loader, - ResourceRequest& request, - const ResourceResponse& redirect_response, - const FetchInitiatorInfo& initiator_info, - ResourceType resource_type) { - // If the resource is not already marked as an ad, check if the document - // loading the resource is an ad or if any executing script is an ad. - if (!request.IsAdResource() && - (IsKnownAdExecutionContext(execution_context) || IsAdScriptInStack())) { - request.SetIsAdResource(); - } +bool AdTracker::CalculateIfAdSubresource(ExecutionContext* execution_context, + const ResourceRequest& request, + ResourceType resource_type, + bool known_ad) { + // Check if the document loading the resource is an ad or if any executing + // script is an ad. + known_ad = known_ad || IsKnownAdExecutionContext(execution_context) || + IsAdScriptInStack(); // If it is a script marked as an ad and it's not in an ad context, append it // to the known ad script set. We don't need to keep track of ad scripts in ad // contexts, because any script executed inside an ad context is considered an // ad script by IsKnownAdScript. - if (resource_type == ResourceType::kScript && request.IsAdResource() && + if (resource_type == ResourceType::kScript && known_ad && !IsKnownAdExecutionContext(execution_context)) { AppendToKnownAdScripts(*execution_context, request.Url().GetString()); } + + return known_ad; } bool AdTracker::IsAdScriptInStack() { @@ -167,7 +164,7 @@ bool AdTracker::IsKnownAdScript(ExecutionContext* execution_context, auto it = known_ad_scripts_.find(execution_context); if (it == known_ad_scripts_.end()) return false; - return it->value.find(url) != it->value.end(); + return it->value.Contains(url); } // This is a separate function for testing purposes. diff --git a/chromium/third_party/blink/renderer/core/frame/ad_tracker.h b/chromium/third_party/blink/renderer/core/frame/ad_tracker.h index 544605c95f7..b88ff12f613 100644 --- a/chromium/third_party/blink/renderer/core/frame/ad_tracker.h +++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker.h @@ -16,11 +16,8 @@ namespace blink { class ExecutionContext; -class DocumentLoader; class ResourceRequest; -class ResourceResponse; enum class ResourceType : uint8_t; -struct FetchInitiatorInfo; namespace probe { class CallFunction; @@ -40,19 +37,16 @@ class CORE_EXPORT AdTracker : public GarbageCollectedFinalized<AdTracker> { void Will(const probe::CallFunction&); void Did(const probe::CallFunction&); - // Called when a resource request is about to be sent. This will do the - // following: - // - Mark a resource request as an ad if any executing scripts contain an ad. - // - If the marked resource is a script, also save it to keep track of all - // those script resources that have been identified as ads. + // Called when a subresource request is about to be sent or is redirected. + // Returns true if: + // - If the resource is loaded in an ad iframe + // - If ad script is in the v8 stack + // - |known_ad| is true // Virtual for testing. - virtual void WillSendRequest(ExecutionContext*, - unsigned long identifier, - DocumentLoader*, - ResourceRequest&, - const ResourceResponse& redirect_response, - const FetchInitiatorInfo&, - ResourceType); + virtual bool CalculateIfAdSubresource(ExecutionContext* execution_context, + const ResourceRequest& request, + ResourceType resource_type, + bool known_ad); // Returns true if any script in the pseudo call stack has previously been // identified as an ad resource. diff --git a/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc index 617ca7c1b28..ffcb1eaea84 100644 --- a/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc @@ -54,22 +54,20 @@ class TestAdTracker : public AdTracker { return execution_context_; } - void WillSendRequest(ExecutionContext* execution_context, - unsigned long identifier, - DocumentLoader* document_loader, - ResourceRequest& resource_request, - const ResourceResponse& redirect_response, - const FetchInitiatorInfo& fetch_initiator_info, - ResourceType resource_type) override { + bool CalculateIfAdSubresource(ExecutionContext* execution_context, + const ResourceRequest& resource_request, + ResourceType resource_type, + bool ad_request) override { if (!ad_suffix_.IsEmpty() && resource_request.Url().GetString().EndsWith(ad_suffix_)) { - resource_request.SetIsAdResource(); + ad_request = true; } - AdTracker::WillSendRequest(execution_context, identifier, document_loader, - resource_request, redirect_response, - fetch_initiator_info, resource_type); - is_ad_.insert(resource_request.Url().GetString(), - resource_request.IsAdResource()); + + ad_request = AdTracker::CalculateIfAdSubresource( + execution_context, resource_request, resource_type, ad_request); + + is_ad_.insert(resource_request.Url().GetString(), ad_request); + return ad_request; } private: @@ -260,8 +258,8 @@ TEST_F(AdTrackerSimTest, ScriptDetectedByContext) { )SCRIPT"); // The child frame should be an ad subframe. - LocalFrame* child_frame = - ToLocalFrame(GetDocument().GetFrame()->Tree().FirstChild()); + auto* child_frame = + To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild()); EXPECT_TRUE(child_frame->IsAdSubframe()); // Now run unknown script in the child's context. It should be considered an @@ -271,6 +269,26 @@ TEST_F(AdTrackerSimTest, ScriptDetectedByContext) { EXPECT_TRUE(ad_tracker_->IsAdScriptInStack()); } +TEST_F(AdTrackerSimTest, RedirectToAdUrl) { + SimSubresourceRequest redirect_script( + "https://example.com/redirect_script.js", + "https://example.com/ad_script.js", "text/javascript"); + SimSubresourceRequest ad_script("https://example.com/ad_script.js", + "text/javascript"); + + ad_tracker_->SetAdSuffix("ad_script.js"); + + main_resource_->Complete( + "<body><script src='redirect_script.js'></script></body>"); + + ad_script.Complete(""); + + EXPECT_FALSE(ad_tracker_->RequestWithUrlTaggedAsAd( + "https://example.com/redirect_script.js")); + EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd( + "https://example.com/ad_script.js")); +} + TEST_F(AdTrackerSimTest, AdResourceDetectedByContext) { SimSubresourceRequest ad_script("https://example.com/ad_script.js", "text/javascript"); @@ -287,8 +305,8 @@ TEST_F(AdTrackerSimTest, AdResourceDetectedByContext) { )SCRIPT"); // The child frame should be an ad subframe. - LocalFrame* child_frame = - ToLocalFrame(GetDocument().GetFrame()->Tree().FirstChild()); + auto* child_frame = + To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild()); EXPECT_TRUE(child_frame->IsAdSubframe()); // Load a resource from the frame. It should be detected as an ad resource due @@ -319,7 +337,7 @@ TEST_F(AdTrackerSimTest, InlineAdScriptRunningInNonAdContext) { )SCRIPT"); // Verify that the new frame is an ad frame. - EXPECT_TRUE(ToLocalFrame(GetDocument().GetFrame()->Tree().FirstChild()) + EXPECT_TRUE(To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild()) ->IsAdSubframe()); // Create a new sibling frame to the ad frame. The ad context calls the non-ad @@ -333,8 +351,9 @@ TEST_F(AdTrackerSimTest, InlineAdScriptRunningInNonAdContext) { )HTML"); // The new sibling frame should also be identified as an ad. - EXPECT_TRUE(ToLocalFrame(GetDocument().GetFrame()->Tree().Find("ad_sibling")) - ->IsAdSubframe()); + EXPECT_TRUE( + To<LocalFrame>(GetDocument().GetFrame()->Tree().Find("ad_sibling")) + ->IsAdSubframe()); } // Image loaded by ad script is tagged as ad. @@ -365,8 +384,10 @@ TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScript) { TEST_F(AdTrackerSimTest, FrameLoadedWhileExecutingAdScript) { const char kAdUrl[] = "https://example.com/ad_script.js"; const char kVanillaUrl[] = "https://example.com/vanilla_page.html"; + const char kVanillaImgUrl[] = "https://example.com/vanilla_img.jpg"; SimSubresourceRequest ad_resource(kAdUrl, "text/javascript"); SimRequest vanilla_page(kVanillaUrl, "text/html"); + SimSubresourceRequest vanilla_image(kVanillaImgUrl, "image/jpeg"); ad_tracker_->SetAdSuffix("ad_script.js"); @@ -377,11 +398,14 @@ TEST_F(AdTrackerSimTest, FrameLoadedWhileExecutingAdScript) { iframe.src = "vanilla_page.html"; document.body.appendChild(iframe); )SCRIPT"); - vanilla_page.Complete(""); + vanilla_page.Complete("<img src=vanilla_img.jpg></img>"); + vanilla_image.Complete(""); EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl)); EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl)); - EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl)); + Frame* child_frame = GetDocument().GetFrame()->Tree().FirstChild(); + EXPECT_TRUE(To<LocalFrame>(child_frame)->IsAdSubframe()); + EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaImgUrl)); } // A script tagged as an ad in one frame shouldn't cause it to be considered @@ -417,8 +441,7 @@ TEST_F(AdTrackerSimTest, Contexts) { // Verify that library.js is an ad script in the subframe's context but not // in the main frame's context. Frame* subframe = GetDocument().GetFrame()->Tree().FirstChild(); - ASSERT_TRUE(subframe->IsLocalFrame()); - LocalFrame* local_subframe = ToLocalFrame(subframe); + auto* local_subframe = To<LocalFrame>(subframe); EXPECT_TRUE(IsKnownAdScript(local_subframe->GetDocument(), String("https://example.com/library.js"))); @@ -444,8 +467,7 @@ TEST_F(AdTrackerSimTest, SameOriginSubframeFromAdScript) { iframe_resource.Complete("iframe data"); Frame* subframe = GetDocument().GetFrame()->Tree().FirstChild(); - ASSERT_TRUE(subframe->IsLocalFrame()); - LocalFrame* local_subframe = ToLocalFrame(subframe); + auto* local_subframe = To<LocalFrame>(subframe); EXPECT_TRUE(local_subframe->IsAdSubframe()); } @@ -467,8 +489,7 @@ TEST_F(AdTrackerSimTest, SameOriginDocWrittenSubframeFromAdScript) { )SCRIPT"); Frame* subframe = GetDocument().GetFrame()->Tree().FirstChild(); - ASSERT_TRUE(subframe->IsLocalFrame()); - LocalFrame* local_subframe = ToLocalFrame(subframe); + auto* local_subframe = To<LocalFrame>(subframe); EXPECT_TRUE(local_subframe->IsAdSubframe()); } diff --git a/chromium/third_party/blink/renderer/core/frame/bar_prop.h b/chromium/third_party/blink/renderer/core/frame/bar_prop.h index 5d73c76cb3b..d4b28a47fa9 100644 --- a/chromium/third_party/blink/renderer/core/frame/bar_prop.h +++ b/chromium/third_party/blink/renderer/core/frame/bar_prop.h @@ -29,7 +29,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_BAR_PROP_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_BAR_PROP_H_ -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/core/frame/bar_prop.idl b/chromium/third_party/blink/renderer/core/frame/bar_prop.idl index 433d23a9de5..6bd3b1c6162 100644 --- a/chromium/third_party/blink/renderer/core/frame/bar_prop.idl +++ b/chromium/third_party/blink/renderer/core/frame/bar_prop.idl @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://html.spec.whatwg.org/#barprop +// https://html.spec.whatwg.org/C/#barprop interface BarProp { readonly attribute boolean visible; diff --git a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc index f30eb4eb1e4..e4112a61f19 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc @@ -154,7 +154,7 @@ ContentSecurityPolicy::ContentSecurityPolicy() style_hash_algorithms_used_(kContentSecurityPolicyHashAlgorithmNone), sandbox_mask_(0), treat_as_public_address_(false), - require_safe_types_(false), + require_trusted_types_(false), insecure_request_policy_(kLeaveInsecureRequestsAlone) {} void ContentSecurityPolicy::BindToDelegate( @@ -198,7 +198,7 @@ void ContentSecurityPolicy::ApplyPolicySideEffectsToDelegate() { if (treat_as_public_address_) delegate_->SetAddressSpace(mojom::IPAddressSpace::kPublic); - if (require_safe_types_) + if (require_trusted_types_) delegate_->SetRequireTrustedTypes(); delegate_->AddInsecureRequestPolicy(insecure_request_policy_); @@ -463,128 +463,64 @@ void ContentSecurityPolicy::FillInCSPHashValues( } // static -bool ContentSecurityPolicy::CheckScriptHashAgainstPolicy( +bool ContentSecurityPolicy::CheckHashAgainstPolicy( Vector<CSPHashValue>& csp_hash_values, const Member<CSPDirectiveList>& policy, InlineType inline_type) { for (const auto& csp_hash_value : csp_hash_values) { - if (policy->AllowScriptHash(csp_hash_value, inline_type)) { + if (policy->AllowHash(csp_hash_value, inline_type)) return true; - } - } - return false; -} - -// static -bool ContentSecurityPolicy::CheckStyleHashAgainstPolicy( - Vector<CSPHashValue>& csp_hash_values, - const Member<CSPDirectiveList>& policy, - InlineType inline_type) { - for (const auto& csp_hash_value : csp_hash_values) { - if (policy->AllowStyleHash(csp_hash_value, inline_type)) { - return true; - } } return false; } -bool ContentSecurityPolicy::AllowJavaScriptURLs( - Element* element, - const String& source, - const String& context_url, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy reporting_policy) const { - // Javascript URLs may be whitelisted by hash, if - // 'unsafe-hashes' is present in a policy. Check against the digest - // of the |source| and also check whether inline script is allowed. - Vector<CSPHashValue> csp_hash_values; - FillInCSPHashValues(source, script_hash_algorithms_used_, &csp_hash_values); - - bool is_allowed = true; - for (const auto& policy : policies_) { - is_allowed &= CheckScriptHashAgainstPolicy(csp_hash_values, policy, - InlineType::kAttribute) || - policy->AllowJavaScriptURLs(element, source, context_url, - context_line, reporting_policy); - } - return is_allowed; -} - -bool ContentSecurityPolicy::AllowInlineEventHandler( +bool ContentSecurityPolicy::AllowInline( + InlineType inline_type, Element* element, - const String& source, + const String& content, + const String& nonce, const String& context_url, const WTF::OrdinalNumber& context_line, SecurityViolationReportingPolicy reporting_policy) const { - // Inline event handlers may be whitelisted by hash, if - // 'unsafe-hashes' is present in a policy. Check against the digest - // of the |source| and also check whether inline script is allowed. - Vector<CSPHashValue> csp_hash_values; - FillInCSPHashValues(source, script_hash_algorithms_used_, &csp_hash_values); + DCHECK(element || inline_type == InlineType::kInlineEventHandler || + inline_type == InlineType::kJavaScriptURL); - bool is_allowed = true; - for (const auto& policy : policies_) { - is_allowed &= - CheckScriptHashAgainstPolicy(csp_hash_values, policy, - InlineType::kAttribute) || - policy->AllowInlineEventHandlers(element, source, context_url, - context_line, reporting_policy); + const bool is_script = IsScriptInlineType(inline_type); + if (!is_script && override_inline_style_allowed_) { + return true; } - return is_allowed; -} - -bool ContentSecurityPolicy::AllowInlineScript( - Element* element, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - const String& script_content, - InlineType inline_type, - SecurityViolationReportingPolicy reporting_policy) const { - DCHECK(element); - Vector<CSPHashValue> csp_hash_values; - FillInCSPHashValues(script_content, script_hash_algorithms_used_, - &csp_hash_values); + FillInCSPHashValues( + content, + is_script ? script_hash_algorithms_used_ : style_hash_algorithms_used_, + &csp_hash_values); bool is_allowed = true; for (const auto& policy : policies_) { + // May be whitelisted by hash, if 'unsafe-hashes' is present in a policy. + // Check against the digest of the |content| and also check whether inline + // script is allowed. is_allowed &= - CheckScriptHashAgainstPolicy(csp_hash_values, policy, inline_type) || - policy->AllowInlineScript(element, context_url, nonce, context_line, - reporting_policy, script_content); + CheckHashAgainstPolicy(csp_hash_values, policy, inline_type) || + policy->AllowInline(inline_type, element, content, nonce, context_url, + context_line, reporting_policy); } return is_allowed; } -bool ContentSecurityPolicy::AllowInlineStyle( - Element* element, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - const String& style_content, - InlineType inline_type, - SecurityViolationReportingPolicy reporting_policy) const { - DCHECK(element); - - if (override_inline_style_allowed_) - return true; - - Vector<CSPHashValue> csp_hash_values; - FillInCSPHashValues(style_content, style_hash_algorithms_used_, - &csp_hash_values); +bool ContentSecurityPolicy::IsScriptInlineType(InlineType inline_type) { + switch (inline_type) { + case ContentSecurityPolicy::InlineType::kJavaScriptURL: + case ContentSecurityPolicy::InlineType::kInlineEventHandler: + case ContentSecurityPolicy::InlineType::kInlineScriptElement: + return true; - bool is_allowed = true; - for (const auto& policy : policies_) { - is_allowed &= - CheckStyleHashAgainstPolicy(csp_hash_values, policy, inline_type) || - policy->AllowInlineStyle(element, context_url, nonce, context_line, - reporting_policy, style_content, inline_type); + case ContentSecurityPolicy::InlineType::kInlineStyleAttribute: + case ContentSecurityPolicy::InlineType::kInlineStyleElement: + return false; } - - return is_allowed; } bool ContentSecurityPolicy::AllowEval( @@ -650,46 +586,6 @@ bool ContentSecurityPolicy::AllowPluginTypeForDocument( return true; } -bool ContentSecurityPolicy::AllowScriptFromSource( - const KURL& url, - const String& nonce, - const IntegrityMetadataSet& hashes, - ParserDisposition parser_disposition, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) { - Count(parser_disposition == kParserInserted - ? WebFeature::kScriptWithCSPBypassingSchemeParserInserted - : WebFeature::kScriptWithCSPBypassingSchemeNotParserInserted); - - // If we're running experimental features, bypass CSP only for - // non-parser-inserted resources whose scheme otherwise bypasses CSP. If - // we're not running experimental features, bypass CSP for all resources - // regardless of parser state. Once we have more data via the - // 'ScriptWithCSPBypassingScheme*' metrics, make a decision about what - // behavior to ship. https://crbug.com/653521 - if ((parser_disposition == kNotParserInserted || - !ExperimentalFeaturesEnabled()) && - // The schemes where javascript:-URLs are blocked are usually privileged - // pages, so do not allow the CSP to be bypassed either. - !SchemeRegistry::ShouldTreatURLSchemeAsNotAllowingJavascriptURLs( - delegate_->GetSecurityOrigin()->Protocol())) { - return true; - } - } - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowScriptFromSource(url, nonce, hashes, parser_disposition, - redirect_status, reporting_policy); - } - return is_allowed; -} - bool ContentSecurityPolicy::AllowRequestWithoutIntegrity( mojom::RequestContextType context, const KURL& url, @@ -705,74 +601,60 @@ bool ContentSecurityPolicy::AllowRequestWithoutIntegrity( return true; } -bool ContentSecurityPolicy::AllowRequest( - mojom::RequestContextType context, - const KURL& url, - const String& nonce, - const IntegrityMetadataSet& integrity_metadata, - ParserDisposition parser_disposition, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (integrity_metadata.IsEmpty() && - !AllowRequestWithoutIntegrity(context, url, redirect_status, - reporting_policy, check_header_type)) { - return false; - } - +static base::Optional<ContentSecurityPolicy::DirectiveType> +GetDirectiveTypeFromRequestContextType(mojom::RequestContextType context) { switch (context) { case mojom::RequestContextType::AUDIO: case mojom::RequestContextType::TRACK: case mojom::RequestContextType::VIDEO: - return AllowMediaFromSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kMediaSrc; + case mojom::RequestContextType::BEACON: case mojom::RequestContextType::EVENT_SOURCE: case mojom::RequestContextType::FETCH: case mojom::RequestContextType::PING: case mojom::RequestContextType::XML_HTTP_REQUEST: case mojom::RequestContextType::SUBRESOURCE: - return AllowConnectToSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kConnectSrc; + case mojom::RequestContextType::EMBED: case mojom::RequestContextType::OBJECT: - return AllowObjectFromSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kObjectSrc; + case mojom::RequestContextType::PREFETCH: - return AllowPrefetchFromSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kPrefetchSrc; + case mojom::RequestContextType::FAVICON: case mojom::RequestContextType::IMAGE: case mojom::RequestContextType::IMAGE_SET: - return AllowImageFromSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kImgSrc; + case mojom::RequestContextType::FONT: - return AllowFontFromSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kFontSrc; + case mojom::RequestContextType::FORM: - return AllowFormAction(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kFormAction; + case mojom::RequestContextType::FRAME: case mojom::RequestContextType::IFRAME: - return AllowFrameFromSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kFrameSrc; + case mojom::RequestContextType::IMPORT: case mojom::RequestContextType::SCRIPT: case mojom::RequestContextType::XSLT: - return AllowScriptFromSource(url, nonce, integrity_metadata, - parser_disposition, redirect_status, - reporting_policy, check_header_type); + return ContentSecurityPolicy::DirectiveType::kScriptSrcElem; + case mojom::RequestContextType::MANIFEST: - return AllowManifestFromSource(url, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kManifestSrc; + case mojom::RequestContextType::SERVICE_WORKER: case mojom::RequestContextType::SHARED_WORKER: case mojom::RequestContextType::WORKER: - return AllowWorkerContextFromSource(url, redirect_status, - reporting_policy, check_header_type); + return ContentSecurityPolicy::DirectiveType::kWorkerSrc; + case mojom::RequestContextType::STYLE: - return AllowStyleFromSource(url, nonce, redirect_status, reporting_policy, - check_header_type); + return ContentSecurityPolicy::DirectiveType::kStyleSrcElem; + case mojom::RequestContextType::CSP_REPORT: case mojom::RequestContextType::DOWNLOAD: case mojom::RequestContextType::HYPERLINK: @@ -780,209 +662,147 @@ bool ContentSecurityPolicy::AllowRequest( case mojom::RequestContextType::LOCATION: case mojom::RequestContextType::PLUGIN: case mojom::RequestContextType::UNSPECIFIED: - return true; + return base::nullopt; } - NOTREACHED(); - return true; -} - -void ContentSecurityPolicy::UsesScriptHashAlgorithms(uint8_t algorithms) { - script_hash_algorithms_used_ |= algorithms; -} - -void ContentSecurityPolicy::UsesStyleHashAlgorithms(uint8_t algorithms) { - style_hash_algorithms_used_ |= algorithms; } -bool ContentSecurityPolicy::AllowObjectFromSource( +bool ContentSecurityPolicy::AllowRequest( + mojom::RequestContextType context, const KURL& url, + const String& nonce, + const IntegrityMetadataSet& integrity_metadata, + ParserDisposition parser_disposition, RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowObjectFromSource(url, redirect_status, reporting_policy); + if (integrity_metadata.IsEmpty() && + !AllowRequestWithoutIntegrity(context, url, redirect_status, + reporting_policy, check_header_type)) { + return false; } - return is_allowed; -} - -bool ContentSecurityPolicy::AllowPrefetchFromSource( - const KURL& url, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) + base::Optional<ContentSecurityPolicy::DirectiveType> type = + GetDirectiveTypeFromRequestContextType(context); + if (!type) return true; + return AllowFromSource(*type, url, redirect_status, reporting_policy, + check_header_type, nonce, integrity_metadata, + parser_disposition); +} - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowPrefetchFromSource(url, redirect_status, reporting_policy); - } +void ContentSecurityPolicy::UsesScriptHashAlgorithms(uint8_t algorithms) { + script_hash_algorithms_used_ |= algorithms; +} - return is_allowed; +void ContentSecurityPolicy::UsesStyleHashAlgorithms(uint8_t algorithms) { + style_hash_algorithms_used_ |= algorithms; } -bool ContentSecurityPolicy::AllowFrameFromSource( +bool ContentSecurityPolicy::AllowFromSource( + ContentSecurityPolicy::DirectiveType type, const KURL& url, RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowFrameFromSource(url, redirect_status, reporting_policy); - } + CheckHeaderType check_header_type, + const String& nonce, + const IntegrityMetadataSet& hashes, + ParserDisposition parser_disposition) const { + SchemeRegistry::PolicyAreas area = SchemeRegistry::kPolicyAreaAll; + if (type == ContentSecurityPolicy::DirectiveType::kImgSrc) + area = SchemeRegistry::kPolicyAreaImage; + else if (type == ContentSecurityPolicy::DirectiveType::kStyleSrcElem) + area = SchemeRegistry::kPolicyAreaStyle; + + if (ShouldBypassContentSecurityPolicy(url, area)) { + if (type != ContentSecurityPolicy::DirectiveType::kScriptSrcElem) + return true; - return is_allowed; -} + Count(parser_disposition == kParserInserted + ? WebFeature::kScriptWithCSPBypassingSchemeParserInserted + : WebFeature::kScriptWithCSPBypassingSchemeNotParserInserted); -bool ContentSecurityPolicy::AllowImageFromSource( - const KURL& url, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url, SchemeRegistry::kPolicyAreaImage)) - return true; + // If we're running experimental features, bypass CSP only for + // non-parser-inserted resources whose scheme otherwise bypasses CSP. If + // we're not running experimental features, bypass CSP for all resources + // regardless of parser state. Once we have more data via the + // 'ScriptWithCSPBypassingScheme*' metrics, make a decision about what + // behavior to ship. https://crbug.com/653521 + if ((parser_disposition == kNotParserInserted || + !ExperimentalFeaturesEnabled()) && + // The schemes where javascript:-URLs are blocked are usually + // privileged pages, so do not allow the CSP to be bypassed either. + !SchemeRegistry::ShouldTreatURLSchemeAsNotAllowingJavascriptURLs( + delegate_->GetSecurityOrigin()->Protocol())) { + return true; + } + } bool is_allowed = true; for (const auto& policy : policies_) { if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) continue; is_allowed &= - policy->AllowImageFromSource(url, redirect_status, reporting_policy); + policy->AllowFromSource(type, url, redirect_status, reporting_policy, + nonce, hashes, parser_disposition); } return is_allowed; } -bool ContentSecurityPolicy::AllowStyleFromSource( - const KURL& url, - const String& nonce, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url, SchemeRegistry::kPolicyAreaStyle)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= policy->AllowStyleFromSource(url, nonce, redirect_status, - reporting_policy); - } - return is_allowed; +bool ContentSecurityPolicy::AllowBaseURI(const KURL& url) const { + // `base-uri` isn't affected by 'upgrade-insecure-requests', so we use + // CheckHeaderType::kCheckAll to check both report-only and enforce headers + // here. + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kBaseURI, url); } -bool ContentSecurityPolicy::AllowFontFromSource( +bool ContentSecurityPolicy::AllowConnectToSource( const KURL& url, RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowFontFromSource(url, redirect_status, reporting_policy); - } - - return is_allowed; + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kConnectSrc, url, + redirect_status, reporting_policy, check_header_type); } -bool ContentSecurityPolicy::AllowMediaFromSource( - const KURL& url, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowMediaFromSource(url, redirect_status, reporting_policy); - } - - return is_allowed; +bool ContentSecurityPolicy::AllowFormAction(const KURL& url) const { + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kFormAction, + url); } -bool ContentSecurityPolicy::AllowConnectToSource( +bool ContentSecurityPolicy::AllowImageFromSource( const KURL& url, RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kImgSrc, url, + redirect_status, reporting_policy, check_header_type); +} - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowConnectToSource(url, redirect_status, reporting_policy); - } +bool ContentSecurityPolicy::AllowMediaFromSource(const KURL& url) const { + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kMediaSrc, url); +} - return is_allowed; +bool ContentSecurityPolicy::AllowObjectFromSource(const KURL& url) const { + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kObjectSrc, url); } -bool ContentSecurityPolicy::AllowFormAction( +bool ContentSecurityPolicy::AllowScriptFromSource( const KURL& url, + const String& nonce, + const IntegrityMetadataSet& hashes, + ParserDisposition parser_disposition, RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowFormAction(url, redirect_status, reporting_policy); - } - - return is_allowed; + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + url, redirect_status, reporting_policy, + check_header_type, nonce, hashes, parser_disposition); } -bool ContentSecurityPolicy::AllowBaseURI( - const KURL& url, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - // `base-uri` isn't affected by 'upgrade-insecure-requests', so we'll check - // both report-only and enforce headers here. - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(CheckHeaderType::kCheckAll, - policy->HeaderType())) - continue; - is_allowed &= policy->AllowBaseURI(url, redirect_status, reporting_policy); - } - - return is_allowed; +bool ContentSecurityPolicy::AllowWorkerContextFromSource( + const KURL& url) const { + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kWorkerSrc, url); } bool ContentSecurityPolicy::AllowTrustedTypePolicy( @@ -999,44 +819,6 @@ bool ContentSecurityPolicy::AllowTrustedTypePolicy( return is_allowed; } -bool ContentSecurityPolicy::AllowWorkerContextFromSource( - const KURL& url, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowWorkerFromSource(url, redirect_status, reporting_policy); - } - - return is_allowed; -} - -bool ContentSecurityPolicy::AllowManifestFromSource( - const KURL& url, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - CheckHeaderType check_header_type) const { - if (ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies_) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - policy->AllowManifestFromSource(url, redirect_status, reporting_policy); - } - - return is_allowed; -} - bool ContentSecurityPolicy::AllowAncestors( LocalFrame* frame, const KURL& url, @@ -1055,6 +837,15 @@ bool ContentSecurityPolicy::IsFrameAncestorsEnforced() const { return false; } +bool ContentSecurityPolicy::AllowTrustedTypeAssignmentFailure( + const String& message) const { + bool allow = true; + for (const auto& policy : policies_) { + allow &= policy->AllowTrustedTypeAssignmentFailure(message); + } + return allow; +} + bool ContentSecurityPolicy::IsActive() const { return !policies_.IsEmpty(); } @@ -1084,7 +875,7 @@ void ContentSecurityPolicy::TreatAsPublicAddress() { void ContentSecurityPolicy::RequireTrustedTypes() { // We store whether CSP demands a policy. The caller still needs to check // whether the feature is enabled in the first place. - require_safe_types_ = true; + require_trusted_types_ = true; } void ContentSecurityPolicy::EnforceStrictMixedContentChecking() { @@ -1163,6 +954,9 @@ static void GatherSecurityPolicyViolationEventData( StripURLForUseInReport(delegate->GetSecurityOrigin(), blocked_url, redirect_status, effective_type)); break; + case ContentSecurityPolicy::kTrustedTypesViolation: + init->setBlockedURI("trusted-types"); + break; } } @@ -1404,7 +1198,7 @@ void ContentSecurityPolicy::ReportUnsupportedDirective(const String& name) { String message = "Unrecognized Content-Security-Policy directive '" + name + "'.\n"; - MessageLevel level = kErrorMessageLevel; + mojom::ConsoleMessageLevel level = mojom::ConsoleMessageLevel::kError; if (EqualIgnoringASCIICase(name, kAllow)) { message = kAllowMessage; } else if (EqualIgnoringASCIICase(name, kOptions)) { @@ -1414,7 +1208,7 @@ void ContentSecurityPolicy::ReportUnsupportedDirective(const String& name) { } else if (GetDirectiveType(name) != DirectiveType::kUndefined) { message = "The Content-Security-Policy directive '" + name + "' is implemented behind a flag which is currently disabled.\n"; - level = kInfoMessageLevel; + level = mojom::ConsoleMessageLevel::kInfo; } LogToConsole(message, level); @@ -1523,7 +1317,7 @@ void ContentSecurityPolicy::ReportMissingReportURI(const String& policy) { } void ContentSecurityPolicy::LogToConsole(const String& message, - MessageLevel level) { + mojom::ConsoleMessageLevel level) { LogToConsole(ConsoleMessage::Create(kSecurityMessageSource, level, message)); } diff --git a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h index 2f70e785623..3866754dd47 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h +++ b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h @@ -29,13 +29,13 @@ #include <memory> #include <utility> +#include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h" #include "third_party/blink/public/platform/web_content_security_policy_struct.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/execution_context/security_context.h" #include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/core/inspector/console_types.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h" @@ -138,9 +138,20 @@ class CORE_EXPORT ContentSecurityPolicy // https://w3c.github.io/webappsec-csp/#violation-resource. By the time we // generate a report, we're guaranteed that the value isn't 'null', so we // don't need that state in this enum. - enum ViolationType { kInlineViolation, kEvalViolation, kURLViolation }; + enum ViolationType { + kInlineViolation, + kEvalViolation, + kURLViolation, + kTrustedTypesViolation + }; - enum class InlineType { kBlock, kAttribute }; + enum class InlineType { + kJavaScriptURL, + kInlineEventHandler, + kInlineScriptElement, + kInlineStyleAttribute, + kInlineStyleElement + }; enum class DirectiveType { kBaseURI, @@ -217,27 +228,6 @@ class CORE_EXPORT ContentSecurityPolicy Vector<CSPHeaderAndType> Headers() const; - // |element| will not be present for navigations to javascript URLs, - // as those checks happen in the middle of the navigation algorithm, - // and we generally don't have access to the responsible element. - bool AllowJavaScriptURLs(Element*, - const String& source, - const String& context_url, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport) const; - - // |element| will be present almost all of the time, but because of - // strangeness around targeting handlers for '<body>', '<svg>', and - // '<frameset>', it will be 'nullptr' for handlers on those - // elements. - bool AllowInlineEventHandler( - Element*, - const String& source, - const String& context_url, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport) const; // When the reporting status is |SendReport|, the |ExceptionStatus| // should indicate whether the caller will throw a JavaScript // exception in the event of a violation. When the caller will throw @@ -267,100 +257,55 @@ class CORE_EXPORT ContentSecurityPolicy SecurityViolationReportingPolicy = SecurityViolationReportingPolicy::kReport) const; - bool AllowObjectFromSource( - const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowPrefetchFromSource( - const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowFrameFromSource(const KURL&, + // AllowFromSource() wrappers. + bool AllowBaseURI(const KURL&) const; + bool AllowConnectToSource(const KURL&, RedirectStatus = RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy = SecurityViolationReportingPolicy::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; + bool AllowFormAction(const KURL&) const; bool AllowImageFromSource(const KURL&, RedirectStatus = RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy = SecurityViolationReportingPolicy::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowFontFromSource(const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowMediaFromSource(const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowConnectToSource(const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowFormAction(const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowBaseURI(const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport) const; - bool AllowTrustedTypePolicy(const String& policy_name) const; - bool AllowWorkerContextFromSource( + bool AllowMediaFromSource(const KURL&) const; + bool AllowObjectFromSource(const KURL&) const; + bool AllowScriptFromSource( const KURL&, + const String& nonce, + const IntegrityMetadataSet&, + ParserDisposition, RedirectStatus = RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy = SecurityViolationReportingPolicy::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; + bool AllowWorkerContextFromSource(const KURL&) const; - bool AllowManifestFromSource( - const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; + bool AllowTrustedTypePolicy(const String& policy_name) const; // Passing 'String()' into the |nonce| arguments in the following methods // represents an unnonced resource load. - bool AllowScriptFromSource( - const KURL&, - const String& nonce, - const IntegrityMetadataSet& hashes, - ParserDisposition, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowStyleFromSource(const KURL&, - const String& nonce, - RedirectStatus = RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport, - CheckHeaderType = CheckHeaderType::kCheckAll) const; - bool AllowInlineScript(Element*, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - const String& script_content, - InlineType, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport) const; - bool AllowInlineStyle(Element*, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - const String& style_content, - InlineType, - SecurityViolationReportingPolicy = - SecurityViolationReportingPolicy::kReport) const; + // + // For kJavaScriptURL case, |element| will not be present for navigations to + // javascript URLs, as those checks happen in the middle of the navigation + // algorithm, and we generally don't have access to the responsible element. + // + // For kInlineEventHandler case, |element| will be present almost all of the + // time, but because of strangeness around targeting handlers for '<body>', + // '<svg>', and '<frameset>', it will be 'nullptr' for handlers on those + // elements. + bool AllowInline(InlineType, + Element*, + const String& content, + const String& nonce, + const String& context_url, + const WTF::OrdinalNumber& context_line, + SecurityViolationReportingPolicy = + SecurityViolationReportingPolicy::kReport) const; + + static bool IsScriptInlineType(InlineType); // |allowAncestors| does not need to know whether the resource was a // result of a redirect. After a redirect, source paths are usually @@ -392,6 +337,10 @@ class CORE_EXPORT ContentSecurityPolicy SecurityViolationReportingPolicy::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; + // Determine whether to enforce the assignment failure. Also handle reporting. + // Returns whether enforcing Trusted Types CSP directives are present. + bool AllowTrustedTypeAssignmentFailure(const String& message) const; + void UsesScriptHashAlgorithms(uint8_t content_security_policy_hash_algorithm); void UsesStyleHashAlgorithms(uint8_t content_security_policy_hash_algorithm); @@ -463,7 +412,7 @@ class CORE_EXPORT ContentSecurityPolicy void EnforceSandboxFlags(SandboxFlags); void TreatAsPublicAddress(); void RequireTrustedTypes(); - bool IsRequireTrustedTypes() const { return require_safe_types_; } + bool IsRequireTrustedTypes() const { return require_trusted_types_; } String EvalDisabledErrorMessage() const; // Upgrade-Insecure-Requests and Block-All-Mixed-Content are represented in @@ -548,6 +497,7 @@ class CORE_EXPORT ContentSecurityPolicy FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceInline); FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceSinglePolicy); FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceMultiplePolicy); + FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, EmptyCSPIsNoOp); FRIEND_TEST_ALL_PREFIXES(BaseFetchContextTest, CanRequest); FRIEND_TEST_ALL_PREFIXES(BaseFetchContextTest, CheckCSPForRequest); FRIEND_TEST_ALL_PREFIXES(BaseFetchContextTest, @@ -557,7 +507,9 @@ class CORE_EXPORT ContentSecurityPolicy void ApplyPolicySideEffectsToDelegate(); - void LogToConsole(const String& message, MessageLevel = kErrorMessageLevel); + void LogToConsole( + const String& message, + mojom::ConsoleMessageLevel = mojom::ConsoleMessageLevel::kError); void AddAndReportPolicyFromHeaderValue(const String&, ContentSecurityPolicyHeaderType, @@ -570,18 +522,25 @@ class CORE_EXPORT ContentSecurityPolicy const Vector<String>& report_endpoints, bool use_reporting_api); + bool AllowFromSource(ContentSecurityPolicy::DirectiveType, + const KURL&, + RedirectStatus = RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy = + SecurityViolationReportingPolicy::kReport, + CheckHeaderType = CheckHeaderType::kCheckAll, + const String& = String(), + const IntegrityMetadataSet& = IntegrityMetadataSet(), + ParserDisposition = kParserInserted) const; + static void FillInCSPHashValues(const String& source, uint8_t hash_algorithms_used, Vector<CSPHashValue>* csp_hash_values); // checks a vector of csp hashes against policy, probably a good idea // to use in tandem with FillInCSPHashValues. - static bool CheckScriptHashAgainstPolicy(Vector<CSPHashValue>&, - const Member<CSPDirectiveList>&, - InlineType); - static bool CheckStyleHashAgainstPolicy(Vector<CSPHashValue>&, - const Member<CSPDirectiveList>&, - InlineType); + static bool CheckHashAgainstPolicy(Vector<CSPHashValue>&, + const Member<CSPDirectiveList>&, + InlineType); bool ShouldBypassContentSecurityPolicy( const KURL&, @@ -604,7 +563,7 @@ class CORE_EXPORT ContentSecurityPolicy // State flags used to configure the environment after parsing a policy. SandboxFlags sandbox_mask_; bool treat_as_public_address_; - bool require_safe_types_; + bool require_trusted_types_; String disable_eval_error_message_; WebInsecureRequestPolicy insecure_request_policy_; diff --git a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index f6065a4d9e4..00685e17e63 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc @@ -68,16 +68,15 @@ TEST_F(ContentSecurityPolicyTest, ParseInsecureRequestPolicy) { kContentSecurityPolicyHeaderSourceHTTP); EXPECT_EQ(test.expected_policy, csp->GetInsecureRequestPolicy()); - execution_context = CreateExecutionContext(); - execution_context->SetSecurityOrigin(secure_origin); - execution_context->SetURL(secure_url); - csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - EXPECT_EQ(test.expected_policy, - execution_context->GetInsecureRequestPolicy()); + Document* document = Document::CreateForTest(); + document->SetSecurityOrigin(secure_origin); + document->SetURL(secure_url); + csp->BindToDelegate(document->GetContentSecurityPolicyDelegate()); + EXPECT_EQ(test.expected_policy, document->GetInsecureRequestPolicy()); bool expect_upgrade = test.expected_policy & kUpgradeInsecureRequests; EXPECT_EQ(expect_upgrade, - execution_context->InsecureNavigationsToUpgrade()->Contains( - execution_context->Url().Host().Impl()->GetHash())); + document->InsecureNavigationsToUpgrade()->Contains( + document->Url().Host().Impl()->GetHash())); } // Report-Only @@ -733,10 +732,11 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) { policy->DidReceiveHeader(String("script-src ") + test.policy, kContentSecurityPolicyHeaderTypeEnforce, kContentSecurityPolicyHeaderSourceHTTP); - EXPECT_EQ(test.allowed, - policy->AllowInlineScript( - element, context_url, String(test.nonce), context_line, - content, ContentSecurityPolicy::InlineType::kBlock)); + EXPECT_EQ( + test.allowed, + policy->AllowInline( + ContentSecurityPolicy::InlineType::kInlineScriptElement, element, + content, String(test.nonce), context_url, context_line)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); // Enforce 'style-src' @@ -745,10 +745,11 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) { policy->DidReceiveHeader(String("style-src ") + test.policy, kContentSecurityPolicyHeaderTypeEnforce, kContentSecurityPolicyHeaderSourceHTTP); - EXPECT_EQ(test.allowed, - policy->AllowInlineStyle( - element, context_url, String(test.nonce), context_line, - content, ContentSecurityPolicy::InlineType::kBlock)); + EXPECT_EQ( + test.allowed, + policy->AllowInline( + ContentSecurityPolicy::InlineType::kInlineStyleElement, element, + content, String(test.nonce), context_url, context_line)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); // Report 'script-src' @@ -757,9 +758,9 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) { policy->DidReceiveHeader(String("script-src ") + test.policy, kContentSecurityPolicyHeaderTypeReport, kContentSecurityPolicyHeaderSourceHTTP); - EXPECT_TRUE(policy->AllowInlineScript( - element, context_url, String(test.nonce), context_line, content, - ContentSecurityPolicy::InlineType::kBlock)); + EXPECT_TRUE(policy->AllowInline( + ContentSecurityPolicy::InlineType::kInlineScriptElement, element, + content, String(test.nonce), context_url, context_line)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); // Report 'style-src' @@ -768,9 +769,9 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) { policy->DidReceiveHeader(String("style-src ") + test.policy, kContentSecurityPolicyHeaderTypeReport, kContentSecurityPolicyHeaderSourceHTTP); - EXPECT_TRUE(policy->AllowInlineStyle( - element, context_url, String(test.nonce), context_line, content, - ContentSecurityPolicy::InlineType::kBlock)); + EXPECT_TRUE(policy->AllowInline( + ContentSecurityPolicy::InlineType::kInlineStyleElement, element, + content, String(test.nonce), context_url, context_line)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); } } @@ -1428,6 +1429,52 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesReserved) { EXPECT_FALSE(csp->AllowTrustedTypePolicy("'three'")); } +TEST_F(ContentSecurityPolicyTest, TrustedTypeEnforce) { + execution_context->SetRequireTrustedTypesForTesting(); + csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); + csp->DidReceiveHeader("trusted-types one\ntwo\rthree", + kContentSecurityPolicyHeaderTypeEnforce, + kContentSecurityPolicyHeaderSourceHTTP); + EXPECT_TRUE(csp->IsRequireTrustedTypes()); + EXPECT_FALSE(csp->AllowTrustedTypeAssignmentFailure("blabla")); +} + +TEST_F(ContentSecurityPolicyTest, TrustedTypeReport) { + execution_context->SetRequireTrustedTypesForTesting(); + csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); + csp->DidReceiveHeader("trusted-types one\ntwo\rthree", + kContentSecurityPolicyHeaderTypeReport, + kContentSecurityPolicyHeaderSourceHTTP); + EXPECT_TRUE(csp->IsRequireTrustedTypes()); + EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla")); +} + +TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndEnforce) { + execution_context->SetRequireTrustedTypesForTesting(); + csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); + csp->DidReceiveHeader("trusted-types one", + kContentSecurityPolicyHeaderTypeReport, + kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("trusted-types two", + kContentSecurityPolicyHeaderTypeEnforce, + kContentSecurityPolicyHeaderSourceHTTP); + EXPECT_TRUE(csp->IsRequireTrustedTypes()); + EXPECT_FALSE(csp->AllowTrustedTypeAssignmentFailure("blabla")); +} + +TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndNonTTEnforce) { + execution_context->SetRequireTrustedTypesForTesting(); + csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); + csp->DidReceiveHeader("trusted-types one", + kContentSecurityPolicyHeaderTypeReport, + kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("script-src none", + kContentSecurityPolicyHeaderTypeEnforce, + kContentSecurityPolicyHeaderSourceHTTP); + EXPECT_TRUE(csp->IsRequireTrustedTypes()); + EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla")); +} + TEST_F(ContentSecurityPolicyTest, DirectiveNameCaseInsensitive) { KURL example_url("http://example.com"); KURL not_example_url("http://not-example.com"); @@ -1475,10 +1522,12 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) { HTMLScriptElement::Create(*document, CreateElementFlags::ByParser()); EXPECT_TRUE(csp->Headers().IsEmpty()); - EXPECT_TRUE( - csp->AllowJavaScriptURLs(element, source, context_url, ordinal_number)); - EXPECT_TRUE(csp->AllowInlineEventHandler(element, source, context_url, - ordinal_number)); + EXPECT_TRUE(csp->AllowInline( + ContentSecurityPolicy::InlineType::kJavaScriptURL, element, source, + String() /* nonce */, context_url, ordinal_number)); + EXPECT_TRUE(csp->AllowInline( + ContentSecurityPolicy::InlineType::kInlineEventHandler, element, source, + String() /* nonce */, context_url, ordinal_number)); EXPECT_TRUE(csp->AllowEval(nullptr, SecurityViolationReportingPolicy::kReport, ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); @@ -1490,27 +1539,42 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) { EXPECT_TRUE(csp->AllowPluginTypeForDocument( *document, "application/x-type-1", "application/x-type-1", example_url, SecurityViolationReportingPolicy::kSuppressReporting)); + + ContentSecurityPolicy::DirectiveType types_to_test[] = { + ContentSecurityPolicy::DirectiveType::kBaseURI, + ContentSecurityPolicy::DirectiveType::kConnectSrc, + ContentSecurityPolicy::DirectiveType::kFontSrc, + ContentSecurityPolicy::DirectiveType::kFormAction, + ContentSecurityPolicy::DirectiveType::kFrameSrc, + ContentSecurityPolicy::DirectiveType::kImgSrc, + ContentSecurityPolicy::DirectiveType::kManifestSrc, + ContentSecurityPolicy::DirectiveType::kMediaSrc, + ContentSecurityPolicy::DirectiveType::kObjectSrc, + ContentSecurityPolicy::DirectiveType::kPrefetchSrc, + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + ContentSecurityPolicy::DirectiveType::kStyleSrcElem, + ContentSecurityPolicy::DirectiveType::kWorkerSrc}; + for (auto type : types_to_test) { + EXPECT_TRUE(csp->AllowFromSource(type, example_url)); + } + EXPECT_TRUE(csp->AllowObjectFromSource(example_url)); - EXPECT_TRUE(csp->AllowPrefetchFromSource(example_url)); - EXPECT_TRUE(csp->AllowFrameFromSource(example_url)); EXPECT_TRUE(csp->AllowImageFromSource(example_url)); - EXPECT_TRUE(csp->AllowFontFromSource(example_url)); EXPECT_TRUE(csp->AllowMediaFromSource(example_url)); EXPECT_TRUE(csp->AllowConnectToSource(example_url)); EXPECT_TRUE(csp->AllowFormAction(example_url)); EXPECT_TRUE(csp->AllowBaseURI(example_url)); - EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy")); EXPECT_TRUE(csp->AllowWorkerContextFromSource(example_url)); - EXPECT_TRUE(csp->AllowManifestFromSource(example_url)); EXPECT_TRUE(csp->AllowScriptFromSource( example_url, nonce, IntegrityMetadataSet(), kParserInserted)); - EXPECT_TRUE(csp->AllowStyleFromSource(example_url, nonce)); - EXPECT_TRUE(csp->AllowInlineScript( - element, context_url, nonce, ordinal_number, source, - ContentSecurityPolicy::InlineType::kBlock)); - EXPECT_TRUE(csp->AllowInlineStyle(element, context_url, nonce, ordinal_number, - source, - ContentSecurityPolicy::InlineType::kBlock)); + + EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy")); + EXPECT_TRUE( + csp->AllowInline(ContentSecurityPolicy::InlineType::kInlineScriptElement, + element, source, nonce, context_url, ordinal_number)); + EXPECT_TRUE( + csp->AllowInline(ContentSecurityPolicy::InlineType::kInlineStyleElement, + element, source, nonce, context_url, ordinal_number)); EXPECT_TRUE(csp->AllowAncestors(document->GetFrame(), example_url)); EXPECT_FALSE(csp->IsFrameAncestorsEnforced()); EXPECT_TRUE(csp->AllowRequestWithoutIntegrity( diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index 0e3acb41065..e0d298eb511 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc @@ -74,6 +74,45 @@ bool ParseBase64Digest(String base64, DigestValue* hash) { return true; } +// TODO(hiroshige): The following two methods are slightly different. +// Investigate the correct behavior and merge them. +ContentSecurityPolicy::DirectiveType +GetDirectiveTypeForAllowInlineFromInlineType( + ContentSecurityPolicy::InlineType inline_type) { + switch (inline_type) { + case ContentSecurityPolicy::InlineType::kJavaScriptURL: + case ContentSecurityPolicy::InlineType::kInlineScriptElement: + return ContentSecurityPolicy::DirectiveType::kScriptSrcElem; + + case ContentSecurityPolicy::InlineType::kInlineEventHandler: + return ContentSecurityPolicy::DirectiveType::kScriptSrcAttr; + + case ContentSecurityPolicy::InlineType::kInlineStyleAttribute: + return ContentSecurityPolicy::DirectiveType::kStyleSrcAttr; + + case ContentSecurityPolicy::InlineType::kInlineStyleElement: + return ContentSecurityPolicy::DirectiveType::kStyleSrcElem; + } +} + +ContentSecurityPolicy::DirectiveType GetDirectiveTypeForAllowHashFromInlineType( + ContentSecurityPolicy::InlineType inline_type) { + switch (inline_type) { + case ContentSecurityPolicy::InlineType::kInlineScriptElement: + return ContentSecurityPolicy::DirectiveType::kScriptSrcElem; + + case ContentSecurityPolicy::InlineType::kJavaScriptURL: + case ContentSecurityPolicy::InlineType::kInlineEventHandler: + return ContentSecurityPolicy::DirectiveType::kScriptSrcAttr; + + case ContentSecurityPolicy::InlineType::kInlineStyleAttribute: + return ContentSecurityPolicy::DirectiveType::kStyleSrcAttr; + + case ContentSecurityPolicy::InlineType::kInlineStyleElement: + return ContentSecurityPolicy::DirectiveType::kStyleSrcElem; + } +} + } // namespace CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, @@ -129,14 +168,15 @@ void CSPDirectiveList::ReportViolation( const ContentSecurityPolicy::DirectiveType effective_type, const String& console_message, const KURL& blocked_url, - ResourceRequest::RedirectStatus redirect_status) const { + ResourceRequest::RedirectStatus redirect_status, + ContentSecurityPolicy::ViolationType violation_type) const { String message = IsReportOnly() ? "[Report Only] " + console_message : console_message; - policy_->LogToConsole(ConsoleMessage::Create(kSecurityMessageSource, - kErrorMessageLevel, message)); + policy_->LogToConsole(ConsoleMessage::Create( + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, message)); policy_->ReportViolation(directive_text, effective_type, message, blocked_url, report_endpoints_, use_reporting_api_, header_, - header_type_, ContentSecurityPolicy::kURLViolation, + header_type_, violation_type, std::unique_ptr<SourceLocation>(), nullptr, // localFrame redirect_status); @@ -150,9 +190,10 @@ void CSPDirectiveList::ReportViolationWithFrame( LocalFrame* frame) const { String message = IsReportOnly() ? "[Report Only] " + console_message : console_message; - policy_->LogToConsole(ConsoleMessage::Create(kSecurityMessageSource, - kErrorMessageLevel, message), - frame); + policy_->LogToConsole( + ConsoleMessage::Create(kSecurityMessageSource, + mojom::ConsoleMessageLevel::kError, message), + frame); policy_->ReportViolation(directive_text, effective_type, message, blocked_url, report_endpoints_, use_reporting_api_, header_, header_type_, ContentSecurityPolicy::kURLViolation, @@ -172,9 +213,9 @@ void CSPDirectiveList::ReportViolationWithLocation( IsReportOnly() ? "[Report Only] " + console_message : console_message; std::unique_ptr<SourceLocation> source_location = SourceLocation::Capture(context_url, context_line.OneBasedInt(), 0); - policy_->LogToConsole(ConsoleMessage::Create(kSecurityMessageSource, - kErrorMessageLevel, message, - source_location->Clone())); + policy_->LogToConsole(ConsoleMessage::Create( + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, message, + source_location->Clone())); policy_->ReportViolation(directive_text, effective_type, message, blocked_url, report_endpoints_, use_reporting_api_, header_, header_type_, @@ -199,7 +240,8 @@ void CSPDirectiveList::ReportEvalViolation( if (IsReportOnly() || exception_status == ContentSecurityPolicy::kWillNotThrowException) { ConsoleMessage* console_message = ConsoleMessage::Create( - kSecurityMessageSource, kErrorMessageLevel, report_message); + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, + report_message); policy_->LogToConsole(console_message); } policy_->ReportViolation(directive_text, effective_type, message, blocked_url, @@ -269,6 +311,19 @@ void CSPDirectiveList::ReportMixedContent( } } +bool CSPDirectiveList::AllowTrustedTypeAssignmentFailure( + const String& message) const { + if (!trusted_types_) + return true; + + ReportViolation(ContentSecurityPolicy::GetDirectiveName( + ContentSecurityPolicy::DirectiveType::kTrustedTypes), + ContentSecurityPolicy::DirectiveType::kTrustedTypes, message, + KURL(), RedirectStatus::kFollowedRedirect, + ContentSecurityPolicy::kTrustedTypesViolation); + return IsReportOnly(); +} + bool CSPDirectiveList::CheckSource( SourceListDirective* directive, const KURL& url, @@ -601,99 +656,70 @@ bool CSPDirectiveList::CheckAncestorsAndReportViolation( return DenyIfEnforcingPolicy(); } -bool CSPDirectiveList::AllowJavaScriptURLs( +bool CSPDirectiveList::AllowInline( + ContentSecurityPolicy::InlineType inline_type, Element* element, - const String& source, - const String& context_url, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy reporting_policy) const { - SourceListDirective* directive = - OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrcElem); - if (reporting_policy == SecurityViolationReportingPolicy::kReport) { - return CheckInlineAndReportViolation( - directive, - "Refused to run the JavaScript URL because it violates the following " - "Content Security Policy directive: ", - element, source, context_url, context_line, true, "sha256-...", - ContentSecurityPolicy::DirectiveType::kScriptSrcElem); - } - - return !directive || directive->AllowAllInline(); -} - -bool CSPDirectiveList::AllowInlineEventHandlers( - Element* element, - const String& source, + const String& content, + const String& nonce, const String& context_url, const WTF::OrdinalNumber& context_line, SecurityViolationReportingPolicy reporting_policy) const { - SourceListDirective* directive = - OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrcAttr); - if (reporting_policy == SecurityViolationReportingPolicy::kReport) { - return CheckInlineAndReportViolation( - directive, - "Refused to execute inline event handler because it violates the " - "following Content Security Policy directive: ", - element, source, context_url, context_line, true, "sha256-...", - ContentSecurityPolicy::DirectiveType::kScriptSrcAttr); - } - - return !directive || directive->AllowAllInline(); -} + ContentSecurityPolicy::DirectiveType type = + GetDirectiveTypeForAllowInlineFromInlineType(inline_type); -bool CSPDirectiveList::AllowInlineScript( - Element* element, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy reporting_policy, - const String& content) const { - SourceListDirective* directive = - OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrcElem); + SourceListDirective* directive = OperativeDirective(type); if (IsMatchingNoncePresent(directive, nonce)) return true; - if (element && IsHTMLScriptElement(element) && + + if (inline_type == ContentSecurityPolicy::InlineType::kInlineScriptElement && + element && IsHTMLScriptElement(element) && !ToHTMLScriptElement(element)->Loader()->IsParserInserted() && - AllowDynamic(ContentSecurityPolicy::DirectiveType::kScriptSrcElem)) { + AllowDynamic(type)) { return true; } if (reporting_policy == SecurityViolationReportingPolicy::kReport) { - return CheckInlineAndReportViolation( - directive, - "Refused to execute inline script because it violates the following " - "Content Security Policy directive: ", - element, content, context_url, context_line, true, - GetSha256String(content), - ContentSecurityPolicy::DirectiveType::kScriptSrcElem); - } + String hash_value; + switch (inline_type) { + case ContentSecurityPolicy::InlineType::kJavaScriptURL: + case ContentSecurityPolicy::InlineType::kInlineEventHandler: + hash_value = "sha256-..."; + break; + + case ContentSecurityPolicy::InlineType::kInlineScriptElement: + case ContentSecurityPolicy::InlineType::kInlineStyleAttribute: + case ContentSecurityPolicy::InlineType::kInlineStyleElement: + hash_value = GetSha256String(content); + break; + } - return !directive || directive->AllowAllInline(); -} + String message; + switch (inline_type) { + case ContentSecurityPolicy::InlineType::kJavaScriptURL: + message = "run the JavaScript URL"; + break; -bool CSPDirectiveList::AllowInlineStyle( - Element* element, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy reporting_policy, - const String& content, - ContentSecurityPolicy::InlineType inline_type) const { - ContentSecurityPolicy::DirectiveType effective_type = - inline_type == ContentSecurityPolicy::InlineType::kAttribute - ? ContentSecurityPolicy::DirectiveType::kStyleSrcAttr - : ContentSecurityPolicy::DirectiveType::kStyleSrcElem; - SourceListDirective* directive = OperativeDirective(effective_type); + case ContentSecurityPolicy::InlineType::kInlineEventHandler: + message = "execute inline event handler"; + break; - if (IsMatchingNoncePresent(directive, nonce)) - return true; + case ContentSecurityPolicy::InlineType::kInlineScriptElement: + message = "execute inline script"; + break; + + case ContentSecurityPolicy::InlineType::kInlineStyleAttribute: + case ContentSecurityPolicy::InlineType::kInlineStyleElement: + message = "apply inline style"; + break; + } - if (reporting_policy == SecurityViolationReportingPolicy::kReport) { return CheckInlineAndReportViolation( directive, - "Refused to apply inline style because it violates the following " - "Content Security Policy directive: ", - element, content, context_url, context_line, false, - GetSha256String(content), effective_type); + "Refused to " + message + + " because it violates the following Content Security Policy " + "directive: ", + element, content, context_url, context_line, + ContentSecurityPolicy::IsScriptInlineType(inline_type), hash_value, + type); } return !directive || directive->AllowAllInline(); @@ -750,217 +776,62 @@ bool CSPDirectiveList::AllowPluginType( : CheckMediaType(plugin_types_.Get(), type, type_attribute); } -bool CSPDirectiveList::AllowScriptFromSource( - const KURL& url, - const String& nonce, - const IntegrityMetadataSet& hashes, - ParserDisposition parser_disposition, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - SourceListDirective* directive = - OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrcElem); - if (IsMatchingNoncePresent(directive, nonce)) - return true; - if (parser_disposition == kNotParserInserted && - AllowDynamic(ContentSecurityPolicy::DirectiveType::kScriptSrcElem)) - return true; - if (AreAllMatchingHashesPresent(directive, hashes)) - return true; - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - directive, url, - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - redirect_status) - : CheckSource(directive, url, redirect_status); -} - -bool CSPDirectiveList::AllowObjectFromSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - if (url.ProtocolIsAbout()) - return true; - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kObjectSrc), - url, ContentSecurityPolicy::DirectiveType::kObjectSrc, - redirect_status) - : CheckSource( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kObjectSrc), - url, redirect_status); -} - -bool CSPDirectiveList::AllowPrefetchFromSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kPrefetchSrc), - url, ContentSecurityPolicy::DirectiveType::kPrefetchSrc, - redirect_status) - : CheckSource( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kPrefetchSrc), - url, redirect_status); -} - -bool CSPDirectiveList::AllowFrameFromSource( +bool CSPDirectiveList::AllowFromSource( + ContentSecurityPolicy::DirectiveType type, const KURL& url, ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - if (url.ProtocolIsAbout()) - return true; - - // 'frame-src' overrides 'child-src', which overrides the default - // sources. So, we do this nested set of calls to 'operativeDirective()' to - // grab 'frame-src' if it exists, 'child-src' if it doesn't, and 'defaut-src' - // if neither are available. - SourceListDirective* directive = - OperativeDirective(ContentSecurityPolicy::DirectiveType::kFrameSrc); - - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - directive, url, - ContentSecurityPolicy::DirectiveType::kFrameSrc, - redirect_status) - : CheckSource(directive, url, redirect_status); -} - -bool CSPDirectiveList::AllowImageFromSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kImgSrc), - url, ContentSecurityPolicy::DirectiveType::kImgSrc, - redirect_status) - : CheckSource(OperativeDirective( - ContentSecurityPolicy::DirectiveType::kImgSrc), - url, redirect_status); -} - -bool CSPDirectiveList::AllowStyleFromSource( - const KURL& url, + SecurityViolationReportingPolicy reporting_policy, const String& nonce, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - SourceListDirective* directive = - OperativeDirective(ContentSecurityPolicy::DirectiveType::kStyleSrcElem); + const IntegrityMetadataSet& hashes, + ParserDisposition parser_disposition) const { + DCHECK(type == ContentSecurityPolicy::DirectiveType::kBaseURI || + type == ContentSecurityPolicy::DirectiveType::kConnectSrc || + type == ContentSecurityPolicy::DirectiveType::kFontSrc || + type == ContentSecurityPolicy::DirectiveType::kFormAction || + type == ContentSecurityPolicy::DirectiveType::kFrameSrc || + type == ContentSecurityPolicy::DirectiveType::kImgSrc || + type == ContentSecurityPolicy::DirectiveType::kManifestSrc || + type == ContentSecurityPolicy::DirectiveType::kMediaSrc || + type == ContentSecurityPolicy::DirectiveType::kObjectSrc || + type == ContentSecurityPolicy::DirectiveType::kPrefetchSrc || + type == ContentSecurityPolicy::DirectiveType::kScriptSrcElem || + type == ContentSecurityPolicy::DirectiveType::kStyleSrcElem || + type == ContentSecurityPolicy::DirectiveType::kWorkerSrc); + + if (type == ContentSecurityPolicy::DirectiveType::kObjectSrc || + type == ContentSecurityPolicy::DirectiveType::kFrameSrc) { + if (url.ProtocolIsAbout()) + return true; + } - if (IsMatchingNoncePresent(directive, nonce)) + if (type == ContentSecurityPolicy::DirectiveType::kWorkerSrc && + AllowDynamicWorker()) return true; - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - directive, url, - ContentSecurityPolicy::DirectiveType::kStyleSrcElem, - redirect_status) - : CheckSource(directive, url, redirect_status); -} - -bool CSPDirectiveList::AllowFontFromSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kFontSrc), - url, ContentSecurityPolicy::DirectiveType::kFontSrc, - redirect_status) - : CheckSource(OperativeDirective( - ContentSecurityPolicy::DirectiveType::kFontSrc), - url, redirect_status); -} - -bool CSPDirectiveList::AllowMediaFromSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kMediaSrc), - url, ContentSecurityPolicy::DirectiveType::kMediaSrc, - redirect_status) - : CheckSource(OperativeDirective( - ContentSecurityPolicy::DirectiveType::kMediaSrc), - url, redirect_status); -} - -bool CSPDirectiveList::AllowManifestFromSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kManifestSrc), - url, ContentSecurityPolicy::DirectiveType::kManifestSrc, - redirect_status) - : CheckSource( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kManifestSrc), - url, redirect_status); -} -bool CSPDirectiveList::AllowConnectToSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kConnectSrc), - url, ContentSecurityPolicy::DirectiveType::kConnectSrc, - redirect_status) - : CheckSource( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kConnectSrc), - url, redirect_status); -} + if (type == ContentSecurityPolicy::DirectiveType::kScriptSrcElem || + type == ContentSecurityPolicy::DirectiveType::kStyleSrcElem) { + if (IsMatchingNoncePresent(OperativeDirective(type), nonce)) + return true; + } -bool CSPDirectiveList::AllowFormAction( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kFormAction), - url, ContentSecurityPolicy::DirectiveType::kFormAction, - redirect_status) - : CheckSource( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kFormAction), - url, redirect_status); -} + if (type == ContentSecurityPolicy::DirectiveType::kScriptSrcElem) { + if (parser_disposition == kNotParserInserted && AllowDynamic(type)) + return true; + if (AreAllMatchingHashesPresent(OperativeDirective(type), hashes)) + return true; + } -bool CSPDirectiveList::AllowBaseURI( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { bool result = reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kBaseURI), - url, ContentSecurityPolicy::DirectiveType::kBaseURI, - redirect_status) - : CheckSource(OperativeDirective( - ContentSecurityPolicy::DirectiveType::kBaseURI), - url, redirect_status); - - if (result && - !CheckSource( - OperativeDirective(ContentSecurityPolicy::DirectiveType::kBaseURI), - url, redirect_status)) { - policy_->Count(WebFeature::kBaseWouldBeBlockedByDefaultSrc); + ? CheckSourceAndReportViolation(OperativeDirective(type), url, type, + redirect_status) + : CheckSource(OperativeDirective(type), url, redirect_status); + + if (type == ContentSecurityPolicy::DirectiveType::kBaseURI) { + if (result && + !CheckSource(OperativeDirective(type), url, redirect_status)) { + policy_->Count(WebFeature::kBaseWouldBeBlockedByDefaultSrc); + } } return result; @@ -983,24 +854,6 @@ bool CSPDirectiveList::AllowTrustedTypePolicy(const String& policy_name) const { return DenyIfEnforcingPolicy(); } -bool CSPDirectiveList::AllowWorkerFromSource( - const KURL& url, - ResourceRequest::RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy) const { - if (AllowDynamicWorker()) - return true; - - return reporting_policy == SecurityViolationReportingPolicy::kReport - ? CheckSourceAndReportViolation( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kWorkerSrc), - url, ContentSecurityPolicy::DirectiveType::kWorkerSrc, - redirect_status) - : CheckSource( - OperativeDirective( - ContentSecurityPolicy::DirectiveType::kWorkerSrc), - url, redirect_status); -} bool CSPDirectiveList::AllowAncestors( LocalFrame* frame, @@ -1019,33 +872,27 @@ bool CSPDirectiveList::AllowAncestors( bool CSPDirectiveList::AllowHash( const CSPHashValue& hash_value, - const ContentSecurityPolicy::InlineType type, - const ContentSecurityPolicy::DirectiveType directive_type) const { - if (type == ContentSecurityPolicy::InlineType::kAttribute) { - if (!policy_->ExperimentalFeaturesEnabled()) - return false; - if (!CheckUnsafeHashesAllowed(OperativeDirective(directive_type))) - return false; - } - return CheckHash(OperativeDirective(directive_type), hash_value); -} + const ContentSecurityPolicy::InlineType inline_type) const { + ContentSecurityPolicy::DirectiveType directive_type = + GetDirectiveTypeForAllowHashFromInlineType(inline_type); + switch (directive_type) { + case ContentSecurityPolicy::DirectiveType::kScriptSrcAttr: + case ContentSecurityPolicy::DirectiveType::kStyleSrcAttr: + if (!policy_->ExperimentalFeaturesEnabled()) + return false; + if (!CheckUnsafeHashesAllowed(OperativeDirective(directive_type))) + return false; + break; -bool CSPDirectiveList::AllowScriptHash( - const CSPHashValue& hash_value, - ContentSecurityPolicy::InlineType type) const { - return AllowHash(hash_value, type, - type == ContentSecurityPolicy::InlineType::kAttribute - ? ContentSecurityPolicy::DirectiveType::kScriptSrcAttr - : ContentSecurityPolicy::DirectiveType::kScriptSrcElem); -} + case ContentSecurityPolicy::DirectiveType::kScriptSrcElem: + case ContentSecurityPolicy::DirectiveType::kStyleSrcElem: + break; -bool CSPDirectiveList::AllowStyleHash( - const CSPHashValue& hash_value, - ContentSecurityPolicy::InlineType type) const { - return AllowHash(hash_value, type, - type == ContentSecurityPolicy::InlineType::kAttribute - ? ContentSecurityPolicy::DirectiveType::kStyleSrcAttr - : ContentSecurityPolicy::DirectiveType::kStyleSrcElem); + default: + NOTREACHED(); + break; + } + return CheckHash(OperativeDirective(directive_type), hash_value); } bool CSPDirectiveList::AllowDynamic( @@ -1249,7 +1096,7 @@ void CSPDirectiveList::ParseReportURI(const String& name, const String& value) { } // Remove report-uri in meta policies, per - // https://html.spec.whatwg.org/#attr-meta-http-equiv-content-security-policy. + // https://html.spec.whatwg.org/C/#attr-meta-http-equiv-content-security-policy. if (header_source_ == kContentSecurityPolicyHeaderSourceMeta) { policy_->ReportInvalidDirectiveInMeta(name); return; @@ -1376,10 +1223,6 @@ void CSPDirectiveList::TreatAsPublicAddress(const String& name, void CSPDirectiveList::RequireTrustedTypes(const String& name, const String& value) { - if (IsReportOnly()) { - policy_->ReportInvalidInReportOnly(name); - return; - } if (trusted_types_) { policy_->ReportDuplicateDirective(name); return; diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h index c56732b6d0b..27af666ad57 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h +++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h @@ -52,29 +52,14 @@ class CORE_EXPORT CSPDirectiveList return header_source_; } - bool AllowJavaScriptURLs(Element*, - const String& source, - const String& context_url, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy) const; - bool AllowInlineEventHandlers(Element*, - const String& source, - const String& context_url, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy) const; - bool AllowInlineScript(Element*, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy, - const String& script_content) const; - bool AllowInlineStyle(Element*, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy, - const String& style_content, - ContentSecurityPolicy::InlineType inline_type) const; + bool AllowInline(ContentSecurityPolicy::InlineType, + Element*, + const String& content, + const String& nonce, + const String& context_url, + const WTF::OrdinalNumber& context_line, + SecurityViolationReportingPolicy) const; + bool AllowEval(ScriptState*, SecurityViolationReportingPolicy, ContentSecurityPolicy::ExceptionStatus, @@ -88,51 +73,16 @@ class CORE_EXPORT CSPDirectiveList const KURL&, SecurityViolationReportingPolicy) const; - bool AllowScriptFromSource(const KURL&, - const String& nonce, - const IntegrityMetadataSet& hashes, - ParserDisposition, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowStyleFromSource(const KURL&, - const String& nonce, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - - bool AllowObjectFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowPrefetchFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowFrameFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowImageFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowFontFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowMediaFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowManifestFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowConnectToSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowFormAction(const KURL&, + bool AllowFromSource(ContentSecurityPolicy::DirectiveType, + const KURL&, ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; - bool AllowBaseURI(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; + SecurityViolationReportingPolicy, + const String& nonce = String(), + const IntegrityMetadataSet& = IntegrityMetadataSet(), + ParserDisposition = kParserInserted) const; + bool AllowTrustedTypePolicy(const String& policy_name) const; - bool AllowWorkerFromSource(const KURL&, - ResourceRequest::RedirectStatus, - SecurityViolationReportingPolicy) const; + // |allowAncestors| does not need to know whether the resource was a // result of a redirect. After a redirect, source paths are usually // ignored to stop a page from learning the path to which the @@ -142,10 +92,6 @@ class CORE_EXPORT CSPDirectiveList bool AllowAncestors(LocalFrame*, const KURL&, SecurityViolationReportingPolicy) const; - bool AllowScriptHash(const CSPHashValue&, - ContentSecurityPolicy::InlineType) const; - bool AllowStyleHash(const CSPHashValue&, - ContentSecurityPolicy::InlineType) const; bool AllowDynamic(ContentSecurityPolicy::DirectiveType) const; bool AllowDynamicWorker() const; @@ -154,6 +100,8 @@ class CORE_EXPORT CSPDirectiveList ResourceRequest::RedirectStatus, SecurityViolationReportingPolicy) const; + bool AllowTrustedTypeAssignmentFailure(const String& message) const; + bool StrictMixedContentChecking() const { return strict_mixed_content_checking_enforced_; } @@ -184,6 +132,9 @@ class CORE_EXPORT CSPDirectiveList bool ShouldSendCSPHeader(ResourceType) const; + bool AllowHash(const CSPHashValue& hash_value, + const ContentSecurityPolicy::InlineType inline_type) const; + // The algorithm is described here: // https://w3c.github.io/webappsec-csp/embedded/#subsume-policy bool Subsumes(const CSPDirectiveListVector&); @@ -241,7 +192,9 @@ class CORE_EXPORT CSPDirectiveList const ContentSecurityPolicy::DirectiveType, const String& console_message, const KURL& blocked_url, - ResourceRequest::RedirectStatus) const; + ResourceRequest::RedirectStatus, + ContentSecurityPolicy::ViolationType violation_type = + ContentSecurityPolicy::kURLViolation) const; void ReportViolationWithFrame(const String& directive_text, const ContentSecurityPolicy::DirectiveType, const String& console_message, @@ -336,11 +289,6 @@ class CORE_EXPORT CSPDirectiveList const ContentSecurityPolicy::DirectiveType, const CSPDirectiveListVector& policies); - bool AllowHash( - const CSPHashValue& hash_value, - const ContentSecurityPolicy::InlineType type, - const ContentSecurityPolicy::DirectiveType directive_type) const; - Member<ContentSecurityPolicy> policy_; String header_; diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc index 071629017ac..3414b2e7847 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc @@ -213,19 +213,21 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceNoNonce) { Member<CSPDirectiveList> directive_list = CreateList(test.list, kContentSecurityPolicyHeaderTypeReport); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - script_src, String(), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + script_src, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(), IntegrityMetadataSet(), kParserInserted)); // Enforce directive_list = CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - script_src, String(), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + script_src, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(), IntegrityMetadataSet(), kParserInserted)); } } @@ -270,65 +272,73 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) { CreateList(String("script-src ") + test.list, kContentSecurityPolicyHeaderTypeReport); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - resource, String(test.nonce), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce), IntegrityMetadataSet(), kParserInserted)); // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, kContentSecurityPolicyHeaderTypeEnforce); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - resource, String(test.nonce), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce), IntegrityMetadataSet(), kParserInserted)); // Report-only 'style-src' directive_list = CreateList(String("style-src ") + test.list, kContentSecurityPolicyHeaderTypeReport); EXPECT_EQ(test.expected, - directive_list->AllowStyleFromSource( - resource, String(test.nonce), + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce))); // Enforce 'style-src' directive_list = CreateList(String("style-src ") + test.list, kContentSecurityPolicyHeaderTypeEnforce); EXPECT_EQ(test.expected, - directive_list->AllowStyleFromSource( - resource, String(test.nonce), + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce))); // Report-only 'style-src' directive_list = CreateList(String("default-src ") + test.list, kContentSecurityPolicyHeaderTypeReport); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - resource, String(test.nonce), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce))); EXPECT_EQ(test.expected, - directive_list->AllowStyleFromSource( - resource, String(test.nonce), + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce))); // Enforce 'style-src' directive_list = CreateList(String("default-src ") + test.list, kContentSecurityPolicyHeaderTypeEnforce); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - resource, String(test.nonce), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce), IntegrityMetadataSet(), kParserInserted)); EXPECT_EQ(test.expected, - directive_list->AllowStyleFromSource( - resource, String(test.nonce), + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + SecurityViolationReportingPolicy::kSuppressReporting, + String(test.nonce))); } } @@ -415,19 +425,21 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceWithHash) { CreateList(String("script-src ") + test.list, kContentSecurityPolicyHeaderTypeReport); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - resource, String(), integrity_metadata, kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(), integrity_metadata, kParserInserted)); // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, kContentSecurityPolicyHeaderTypeEnforce); EXPECT_EQ(test.expected, - directive_list->AllowScriptFromSource( - resource, String(), integrity_metadata, kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)); + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting, + String(), integrity_metadata, kParserInserted)); } } @@ -593,8 +605,9 @@ TEST_F(CSPDirectiveListTest, WorkerSrc) { Member<CSPDirectiveList> directive_list = CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); EXPECT_EQ(test.allowed, - directive_list->AllowWorkerFromSource( - resource, ResourceRequest::RedirectStatus::kNoRedirect, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource, + ResourceRequest::RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy::kSuppressReporting)); } } @@ -638,8 +651,9 @@ TEST_F(CSPDirectiveListTest, WorkerSrcChildSrcFallback) { Member<CSPDirectiveList> directive_list = CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); EXPECT_EQ(test.allowed, - directive_list->AllowWorkerFromSource( - resource, ResourceRequest::RedirectStatus::kNoRedirect, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource, + ResourceRequest::RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy::kSuppressReporting)); } } @@ -977,7 +991,7 @@ TEST_F(CSPDirectiveListTest, OperativeDirectiveGivenType) { // Start the tests with all directives present. directive_string = all_directives.str(); - while (test.fallback_list.size()) { + while (!test.fallback_list.empty()) { directive_list = CreateList(directive_string.c_str(), kContentSecurityPolicyHeaderTypeEnforce); diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc index 85264b2a20f..6d6a493bf7e 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc @@ -115,7 +115,7 @@ CSPSource::SchemeMatchingResult CSPSource::SchemeMatches( bool CSPSource::HostMatches(const String& host) const { bool match; - bool equal_hosts = host_ == host; + bool equal_hosts = EqualIgnoringASCIICase(host_, host); if (host_wildcard_ == kHasWildcard) { if (host_.IsEmpty()) { // host-part = "*" diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_source_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_source_test.cc index 529f86d11c2..8e3f0b1c87a 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/csp_source_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_source_test.cc @@ -284,6 +284,22 @@ TEST_F(CSPSourceTest, HostMatches) { // Please see http://crbug.com/692505 EXPECT_FALSE(source.Matches(KURL(base, "http://.foo.bar"))); } + + // Host matching is case-insensitive. + { + CSPSource source(csp.Get(), "", "FoO.BaR", 0, "", CSPSource::kNoWildcard, + CSPSource::kNoWildcard); + EXPECT_TRUE(source.Matches(KURL(base, "http://foo.bar"))); + EXPECT_FALSE(source.Matches(KURL(base, "http://sub.foo.bar"))); + } + + // Wildcarded host matching is case-insensitive. + { + CSPSource source(csp.Get(), "", "FoO.BaR", 0, "", CSPSource::kHasWildcard, + CSPSource::kNoWildcard); + EXPECT_TRUE(source.Matches(KURL(base, "http://sub.foo.bar"))); + EXPECT_FALSE(source.Matches(KURL(base, "http://foo.bar"))); + } } TEST_F(CSPSourceTest, DoesNotSubsume) { diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h b/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h new file mode 100644 index 00000000000..d3c753acb61 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h @@ -0,0 +1,74 @@ +// Copyright 2019 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_FRAME_CSP_CSP_VIOLATION_REPORT_BODY_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CSP_VIOLATION_REPORT_BODY_H_ + +#include "third_party/blink/renderer/bindings/core/v8/source_location.h" +#include "third_party/blink/renderer/core/events/security_policy_violation_event_init.h" +#include "third_party/blink/renderer/core/frame/report_body.h" + +namespace blink { + +class CORE_EXPORT CSPViolationReportBody : public ReportBody { + DEFINE_WRAPPERTYPEINFO(); + + public: + static CSPViolationReportBody* Create( + const SecurityPolicyViolationEventInit& violation_data) { + return MakeGarbageCollected<CSPViolationReportBody>(violation_data); + } + + CSPViolationReportBody(const SecurityPolicyViolationEventInit& violation_data) + : document_url_(violation_data.documentURI()), + referrer_(violation_data.referrer()), + blocked_url_(violation_data.blockedURI()), + effective_directive_(violation_data.effectiveDirective()), + original_policy_(violation_data.originalPolicy()), + source_file_(violation_data.sourceFile()), + sample_(violation_data.sample()), + disposition_(violation_data.disposition()), + status_code_(violation_data.statusCode()), + line_number_(source_file_ ? violation_data.lineNumber() : 0), + column_number_(source_file_ ? violation_data.columnNumber() : 0) {} + + ~CSPViolationReportBody() override = default; + + String documentURL() const { return document_url_; } + String referrer() const { return referrer_; } + String blockedURL() const { return blocked_url_; } + String effectiveDirective() const { return effective_directive_; } + String originalPolicy() const { return original_policy_; } + String sourceFile() const { return source_file_; } + String sample() const { return sample_; } + String disposition() const { return disposition_; } + uint16_t statusCode() const { return status_code_; } + + uint32_t lineNumber(bool& is_null) const { + is_null = !source_file_; + return line_number_; + } + + uint32_t columnNumber(bool& is_null) const { + is_null = !source_file_; + return column_number_; + } + + private: + const String document_url_; + const String referrer_; + const String blocked_url_; + const String effective_directive_; + const String original_policy_; + const String source_file_; + const String sample_; + const String disposition_; + const uint16_t status_code_; + const uint32_t line_number_; + const uint32_t column_number_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CSP_VIOLATION_REPORT_BODY_H_ diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.idl b/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.idl new file mode 100644 index 00000000000..0ab4e1d0185 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.idl @@ -0,0 +1,21 @@ +// Copyright 2019 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. + +// https://www.w3.org/TR/CSP3/#cspviolationreportbody + +[ + NoInterfaceObject +] interface CSPViolationReportBody : ReportBody { + readonly attribute USVString documentURL; + readonly attribute USVString? referrer; + readonly attribute USVString? blockedURL; + readonly attribute DOMString effectiveDirective; + readonly attribute DOMString originalPolicy; + readonly attribute USVString? sourceFile; + readonly attribute DOMString? sample; + readonly attribute SecurityPolicyViolationEventDisposition disposition; + readonly attribute unsigned short statusCode; + readonly attribute unsigned long? lineNumber; + readonly attribute unsigned long? columnNumber; +}; diff --git a/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc b/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc index 9fa20c76811..49d53871e3a 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc @@ -9,8 +9,11 @@ #include "third_party/blink/renderer/core/events/security_policy_violation_event.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/execution_context/security_context.h" +#include "third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" +#include "third_party/blink/renderer/core/frame/report.h" +#include "third_party/blink/renderer/core/frame/reporting_context.h" #include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/ping_loader.h" @@ -75,11 +78,14 @@ void ExecutionContextCSPDelegate::AddInsecureRequestPolicy( // Step 4. Insert tuple into settings’s upgrade insecure navigations set. // [spec text] Count(WebFeature::kUpgradeInsecureRequestsEnabled); - if (!Url().Host().IsEmpty()) { + // We don't add the hash if |document| is null, to prevent + // WorkerGlobalScope::Url() before it's ready. https://crbug.com/861564 + // This should be safe, because the insecure navigations set is not used + // in non-Document contexts. + if (document && !Url().Host().IsEmpty()) { uint32_t hash = Url().Host().Impl()->GetHash(); security_context.AddInsecureNavigationUpgrade(hash); - if (document) - document->DidEnforceInsecureNavigationsSet(); + document->DidEnforceInsecureNavigationsSet(); } } } @@ -136,7 +142,7 @@ void ExecutionContextCSPDelegate::PostViolationReport( ContentSecurityPolicy::GetDirectiveType( violation_data.effectiveDirective())); - // TODO(mkwst): Support POSTing violation reports from a Worker. + // TODO(crbug/929370): Support POSTing violation reports from a Worker. Document* document = GetDocument(); if (!document) return; @@ -151,6 +157,13 @@ void ExecutionContextCSPDelegate::PostViolationReport( DEFINE_STATIC_LOCAL(ReportingServiceProxyPtrHolder, reporting_service_proxy_holder, ()); + // Construct and route the report to the ReportingContext, to be observed + // by any ReportingObservers. + CSPViolationReportBody* body = CSPViolationReportBody::Create(violation_data); + Report* observed_report = + MakeGarbageCollected<Report>("csp-violation", Url().GetString(), body); + ReportingContext::From(document)->QueueReport(observed_report); + for (const auto& report_endpoint : report_endpoints) { if (use_reporting_api) { // https://w3c.github.io/webappsec-csp/#report-violation @@ -202,7 +215,7 @@ void ExecutionContextCSPDelegate::DisableEval(const String& error_message) { void ExecutionContextCSPDelegate::ReportBlockedScriptExecutionToInspector( const String& directive_text) { - probe::scriptExecutionBlockedByCSP(execution_context_, directive_text); + probe::ScriptExecutionBlockedByCSP(execution_context_, directive_text); } void ExecutionContextCSPDelegate::DidAddContentSecurityPolicies( diff --git a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc index 236e891d740..28b43313e8f 100644 --- a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc @@ -1408,4 +1408,20 @@ TEST_F(SourceListDirectiveTest, AllowHostWildcard) { } } +TEST_F(SourceListDirectiveTest, AllowHostMixedCase) { + KURL base; + // Non-wildcard sources should match hosts case-insensitively. + { + String sources = "http://ExAmPle.com"; + SourceListDirective source_list("default-src", sources, csp.Get()); + EXPECT_TRUE(source_list.Allows(KURL(base, "http://example.com"))); + } + // Wildcard sources should match hosts case-insensitively. + { + String sources = "http://*.ExAmPle.com"; + SourceListDirective source_list("default-src", sources, csp.Get()); + EXPECT_TRUE(source_list.Allows(KURL(base, "http://www.example.com"))); + } +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/deprecation.cc b/chromium/third_party/blink/renderer/core/frame/deprecation.cc index b3e2678e41e..ec51f3210e3 100644 --- a/chromium/third_party/blink/renderer/core/frame/deprecation.cc +++ b/chromium/third_party/blink/renderer/core/frame/deprecation.cc @@ -6,8 +6,8 @@ #include "services/service_manager/public/cpp/connector.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" +#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/reporting.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/deprecation_report_body.h" @@ -56,6 +56,9 @@ enum Milestone { kM71, kM72, kM73, + kM74, + kM75, + kM76, }; // Returns estimated milestone dates as human-readable strings. @@ -94,6 +97,12 @@ const char* MilestoneString(Milestone milestone) { return "M72, around January 2019"; case kM73: return "M73, around March 2019"; + case kM74: + return "M74, around April 2019"; + case kM75: + return "M75, around June 2019"; + case kM76: + return "M76, around July 2019"; } NOTREACHED(); @@ -137,12 +146,36 @@ double MilestoneDate(Milestone milestone) { return 1548734400000; // January 29, 2019. case kM73: return 1552363200000; // March 12, 2019. + case kM74: + return 1555992000000; // April 23, 2019. + case kM75: + return 1559620800000; // June 4, 2019. + case kM76: + return 1564459200000; // Jul 30, 2019. } NOTREACHED(); return 0; } +String GetDeviceSensorDeprecationMessage(const char* event_name, + const char* status_url) { + static constexpr char kConcreteMessage[] = + "The `%s` event is deprecated on insecure origins and will be removed in " + "%s. Event handlers can still be registered but are no longer invoked " + "since %s. See %s for more details."; + static constexpr char kGenericMessage[] = + "The `%s` event is deprecated on insecure origins and will be removed. " + "See %s for more details."; + + if (blink::RuntimeEnabledFeatures:: + RestrictDeviceSensorEventsToSecureContextsEnabled()) { + return String::Format(kConcreteMessage, event_name, MilestoneString(kM76), + MilestoneString(kM74), status_url); + } + return String::Format(kGenericMessage, event_name, status_url); +} + struct DeprecationInfo { String id; Milestone anticipated_removal; @@ -271,25 +304,22 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) { // Powerful features on insecure origins (https://goo.gl/rStTGz) case WebFeature::kDeviceMotionInsecureOrigin: - return {"DeviceMotionInsecureOrigin", kUnknown, - "The devicemotion event is deprecated on insecure origins, and " - "support will be removed in the future. You should consider " - "switching your application to a secure origin, such as HTTPS. " - "See https://goo.gl/rStTGz for more details."}; + return {"DeviceMotionInsecureOrigin", kM76, + GetDeviceSensorDeprecationMessage( + "devicemotion", + "https://www.chromestatus.com/feature/5688035094036480")}; case WebFeature::kDeviceOrientationInsecureOrigin: - return {"DeviceOrientationInsecureOrigin", kUnknown, - "The deviceorientation event is deprecated on insecure origins, " - "and support will be removed in the future. You should consider " - "switching your application to a secure origin, such as HTTPS. " - "See https://goo.gl/rStTGz for more details."}; + return {"DeviceOrientationInsecureOrigin", kM76, + GetDeviceSensorDeprecationMessage( + "deviceorientation", + "https://www.chromestatus.com/feature/5468407470227456")}; case WebFeature::kDeviceOrientationAbsoluteInsecureOrigin: - return {"DeviceOrientationAbsoluteInsecureOrigin", kUnknown, - "The deviceorientationabsolute event is deprecated on insecure " - "origins, and support will be removed in the future. You should " - "consider switching your application to a secure origin, such as " - "HTTPS. See https://goo.gl/rStTGz for more details."}; + return {"DeviceOrientationAbsoluteInsecureOrigin", kM76, + GetDeviceSensorDeprecationMessage( + "deviceorientationabsolute", + "https://www.chromestatus.com/feature/5468407470227456")}; case WebFeature::kGeolocationInsecureOrigin: case WebFeature::kGeolocationInsecureOriginIframe: @@ -439,12 +469,6 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) { "\"supportedNetworks\" field", kM64, "5725727580225536")}; - case WebFeature::kDeprecatedTimingFunctionStepMiddle: - return { - "DeprecatedTimingFunctionStepMiddle", kM62, - WillBeRemoved("The step timing function with step position 'middle'", - kM62, "5189363944128512")}; - case WebFeature::kHTMLImports: return {"DeprecatedHTMLImports", kM73, ReplacedWillBeRemoved("HTML Imports", "ES modules", kM73, @@ -565,6 +589,68 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) { "https://webrtc.org/web-apis/chrome/unified-plan/.", MilestoneString(kM72))}; + case WebFeature::kNoSysexWebMIDIWithoutPermission: + return {"NoSysexWebMIDIWithoutPermission", kM75, + String::Format( + "Web MIDI will ask a permission to use even if the sysex is " + "not specified in the MIDIOptions since %s. See " + "https://www.chromestatus.com/feature/5138066234671104 for " + "more details.", + MilestoneString(kM75))}; + + case WebFeature::kNoSysexWebMIDIOnInsecureOrigin: + return {"NoSysexWebMIDIOnInsecureOrigin", kM75, + String::Format( + "Web MIDI will be deprecated on insecure origins since %s. " + "You should consider switching your application to a secure " + "origin, such as HTTPS. See " + "https://www.chromestatus.com/feature/5138066234671104 for " + "more details.", + MilestoneString(kM75))}; + + case WebFeature::kCustomCursorIntersectsViewport: + return { + "CustomCursorIntersectsViewport", kM75, + WillBeRemoved( + "Custom cursors with size greater than 32x32 DIP intersecting " + "native UI", + kM75, "5825971391299584")}; + +#define REMOVE_APPEARANCE_KEYWORD_M75(id, keyword) \ + case WebFeature::kCSSValueAppearance##id: \ + return {"CSSValueAppearance" #id, kM75, \ + WillBeRemoved("The keyword '" keyword \ + "' for -webkit-appearance CSS property", \ + kM75, "5075579829223424")} + + REMOVE_APPEARANCE_KEYWORD_M75(ButtonBevel, "button-bevel"); + REMOVE_APPEARANCE_KEYWORD_M75(Caret, "caret"); + REMOVE_APPEARANCE_KEYWORD_M75(Listitem, "listitem"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaControlsBackground, + "media-controls-background"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaControlsFullscreenBackground, + "media-controls-fullscreen-background"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaCurrentTimeDisplay, + "media-current-time-display"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaEnterFullscreenButton, + "media-enter-fullscreen-button"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaExitFullscreenButton, + "media-exit-fullscreen-button"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaMuteButton, "media-mute-button"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaOverlayPlayButton, + "media-overlay-play-button"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaPlayButton, "media-play-button"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaTimeRemainingDisplay, + "media-time-remaining-display"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaToggleClosedCaptionsButton, + "media-toggle-closed-captions-button"); + REMOVE_APPEARANCE_KEYWORD_M75(MediaVolumeSliderContainer, + "media-volume-slider-container"); + REMOVE_APPEARANCE_KEYWORD_M75(MenulistTextfield, "menulist-textfield"); + REMOVE_APPEARANCE_KEYWORD_M75(MenulistText, "menulist-text"); + REMOVE_APPEARANCE_KEYWORD_M75(ProgressBarValue, "progress-bar-value"); +#undef REMOVE_APPEARANCE_KEYWORD_M75 + // Features that aren't deprecated don't have a deprecation message. default: return {"NotDeprecated", kUnknown, ""}; @@ -625,8 +711,9 @@ void Deprecation::WarnOnDeprecatedProperties( String message = DeprecationMessage(unresolved_property); if (!message.IsEmpty()) { page->GetDeprecation().Suppress(unresolved_property); - ConsoleMessage* console_message = ConsoleMessage::Create( - kDeprecationMessageSource, kWarningMessageLevel, message); + ConsoleMessage* console_message = + ConsoleMessage::Create(kDeprecationMessageSource, + mojom::ConsoleMessageLevel::kWarning, message); frame->Console().AddMessage(console_message); } } @@ -709,7 +796,8 @@ void Deprecation::GenerateReport(const LocalFrame* frame, WebFeature feature) { // Send the deprecation message to the console as a warning. DCHECK(!info.message.IsEmpty()); ConsoleMessage* console_message = ConsoleMessage::Create( - kDeprecationMessageSource, kWarningMessageLevel, info.message); + kDeprecationMessageSource, mojom::ConsoleMessageLevel::kWarning, + info.message); frame->Console().AddMessage(console_message); if (!frame || !frame->Client()) diff --git a/chromium/third_party/blink/renderer/core/frame/dom_timer.h b/chromium/third_party/blink/renderer/core/frame/dom_timer.h index bdc854356b2..8d433eb7439 100644 --- a/chromium/third_party/blink/renderer/core/frame/dom_timer.h +++ b/chromium/third_party/blink/renderer/core/frame/dom_timer.h @@ -29,8 +29,8 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h b/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h index e15c6c5f2c8..645fee38069 100644 --- a/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h +++ b/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h @@ -43,7 +43,7 @@ class DOMTimerCoordinator { // Timers created during the execution of other timers, and // repeating timers, are throttled. Timer nesting level tracks the // number of linked timers or repetitions of a timer. See - // https://html.spec.whatwg.org/#timers + // https://html.spec.whatwg.org/C/#timers int TimerNestingLevel() { return timer_nesting_level_; } // Sets the timer nesting level. Set when a timer executes so that diff --git a/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h b/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h index be5c2cb9e2a..0b1ef8eebc9 100644 --- a/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h +++ b/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h @@ -34,9 +34,9 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" namespace blink { @@ -68,8 +68,8 @@ class CORE_EXPORT DOMVisualViewport final : public EventTargetWithInlineData { double height() const; double scale() const; - DEFINE_ATTRIBUTE_EVENT_LISTENER(resize, kResize); - DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll); + DEFINE_ATTRIBUTE_EVENT_LISTENER(resize, kResize) + DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll) private: Member<LocalDOMWindow> window_; diff --git a/chromium/third_party/blink/renderer/core/frame/dom_window.cc b/chromium/third_party/blink/renderer/core/frame/dom_window.cc index 6d293ff99ce..3b7d287204e 100644 --- a/chromium/third_party/blink/renderer/core/frame/dom_window.cc +++ b/chromium/third_party/blink/renderer/core/frame/dom_window.cc @@ -132,7 +132,7 @@ void DOMWindow::postMessage(v8::Isolate* isolate, const WindowPostMessageOptions* options, ExceptionState& exception_state) { LocalDOMWindow* incumbent_window = IncumbentDOMWindow(isolate); - UseCounter::Count(incumbent_window->GetFrame(), + UseCounter::Count(incumbent_window->document(), WebFeature::kWindowPostMessage); Transferables transferables; @@ -247,8 +247,9 @@ String DOMWindow::CrossDomainAccessErrorMessage( // aren't replicated. For now, construct the URL using the replicated // origin for RemoteFrames. If the target frame is remote and sandboxed, // there isn't anything else to show other than "null" for its origin. - KURL target_url = IsLocalDOMWindow() - ? blink::ToLocalDOMWindow(this)->document()->Url() + auto* local_dom_window = DynamicTo<LocalDOMWindow>(this); + KURL target_url = local_dom_window + ? local_dom_window->document()->Url() : KURL(NullURL(), target_origin->ToString()); if (GetFrame()->GetSecurityContext()->IsSandboxed(kSandboxOrigin) || accessing_window->document()->IsSandboxed(kSandboxOrigin)) { @@ -332,7 +333,7 @@ void DOMWindow::Close(LocalDOMWindow* incumbent_window) { !allow_scripts_to_close_windows) { active_document->domWindow()->GetFrameConsole()->AddMessage( ConsoleMessage::Create( - kJSMessageSource, kWarningMessageLevel, + kJSMessageSource, mojom::ConsoleMessageLevel::kWarning, "Scripts may close only the windows that were opened by it.")); return; } @@ -341,10 +342,10 @@ void DOMWindow::Close(LocalDOMWindow* incumbent_window) { return; ExecutionContext* execution_context = nullptr; - if (IsLocalDOMWindow()) { - execution_context = blink::ToLocalDOMWindow(this)->GetExecutionContext(); + if (auto* local_dom_window = DynamicTo<LocalDOMWindow>(this)) { + execution_context = local_dom_window->GetExecutionContext(); } - probe::breakableLocation(execution_context, "DOMWindow.close"); + probe::BreakableLocation(execution_context, "DOMWindow.close"); page->CloseSoon(); @@ -457,25 +458,26 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message, String source_origin = security_origin->ToString(); - KURL target_url = IsLocalDOMWindow() - ? blink::ToLocalDOMWindow(this)->document()->Url() + auto* local_dom_window = DynamicTo<LocalDOMWindow>(this); + KURL target_url = local_dom_window + ? local_dom_window->document()->Url() : KURL(NullURL(), GetFrame() ->GetSecurityContext() ->GetSecurityOrigin() ->ToString()); if (MixedContentChecker::IsMixedContent(source_document->GetSecurityOrigin(), target_url)) { - UseCounter::Count(source->GetFrame(), + UseCounter::Count(source_document, WebFeature::kPostMessageFromSecureToInsecure); } else if (MixedContentChecker::IsMixedContent( GetFrame()->GetSecurityContext()->GetSecurityOrigin(), source_document->Url())) { - UseCounter::Count(source->GetFrame(), + UseCounter::Count(source_document, WebFeature::kPostMessageFromInsecureToSecure); if (MixedContentChecker::IsMixedContent( GetFrame()->Tree().Top().GetSecurityContext()->GetSecurityOrigin(), source_document->Url())) { - UseCounter::Count(source->GetFrame(), + UseCounter::Count(source_document, WebFeature::kPostMessageFromInsecureToSecureToplevel); } } @@ -484,7 +486,7 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message, target_url, RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy::kSuppressReporting)) { UseCounter::Count( - source->GetFrame(), + source_document, WebFeature::kPostMessageOutgoingWouldBeBlockedByConnectSrc); } UserActivation* user_activation = nullptr; diff --git a/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc b/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc index 2b3fbebdf31..65877942578 100644 --- a/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc +++ b/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc @@ -299,25 +299,23 @@ void EventHandlerRegistry::NotifyHandlersChanged( break; } - if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()) { - if (handler_class == kTouchStartOrMoveEventBlocking || - handler_class == kTouchStartOrMoveEventBlockingLowLatency) { - if (auto* node = target->ToNode()) { - if (auto* layout_object = node->GetLayoutObject()) { - layout_object->MarkEffectiveWhitelistedTouchActionChanged(); - auto* continuation = layout_object->VirtualContinuation(); - while (continuation) { - continuation->MarkEffectiveWhitelistedTouchActionChanged(); - continuation = continuation->VirtualContinuation(); - } + if (handler_class == kTouchStartOrMoveEventBlocking || + handler_class == kTouchStartOrMoveEventBlockingLowLatency) { + if (auto* node = target->ToNode()) { + if (auto* layout_object = node->GetLayoutObject()) { + layout_object->MarkEffectiveWhitelistedTouchActionChanged(); + auto* continuation = layout_object->VirtualContinuation(); + while (continuation) { + continuation->MarkEffectiveWhitelistedTouchActionChanged(); + continuation = continuation->VirtualContinuation(); } - } else if (auto* dom_window = target->ToLocalDOMWindow()) { - // This event handler is on a window. Ensure the layout view is - // invalidated because the layout view tracks the window's blocking - // touch event rects. - if (auto* layout_view = dom_window->GetFrame()->ContentLayoutObject()) - layout_view->MarkEffectiveWhitelistedTouchActionChanged(); } + } else if (auto* dom_window = target->ToLocalDOMWindow()) { + // This event handler is on a window. Ensure the layout view is + // invalidated because the layout view tracks the window's blocking + // touch event rects. + if (auto* layout_view = dom_window->GetFrame()->ContentLayoutObject()) + layout_view->MarkEffectiveWhitelistedTouchActionChanged(); } } } diff --git a/chromium/third_party/blink/renderer/core/frame/find_in_page.h b/chromium/third_party/blink/renderer/core/frame/find_in_page.h index ba979ce75e7..9203f5629da 100644 --- a/chromium/third_party/blink/renderer/core/frame/find_in_page.h +++ b/chromium/third_party/blink/renderer/core/frame/find_in_page.h @@ -12,8 +12,8 @@ #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_plugin_container.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/editing/finder/text_finder.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/persistent.h" diff --git a/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc b/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc index 49188a6bfd1..9f51782771f 100644 --- a/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/frame/find_in_page.h" +#include "base/bind.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h" #include "third_party/blink/renderer/core/editing/finder/text_finder.h" diff --git a/chromium/third_party/blink/renderer/core/frame/frame.cc b/chromium/third_party/blink/renderer/core/frame/frame.cc index ec10f62c150..13132d5c122 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame.cc @@ -118,6 +118,8 @@ void Frame::DisconnectOwnerElement() { if (owner_->ContentFrame() == this) owner_->ClearContentFrame(); + owner_->SetNeedsOcclusionTracking(false); + owner_ = nullptr; } @@ -130,8 +132,7 @@ bool Frame::IsMainFrame() const { } HTMLFrameOwnerElement* Frame::DeprecatedLocalOwner() const { - return owner_ && owner_->IsLocal() ? ToHTMLFrameOwnerElement(owner_) - : nullptr; + return DynamicTo<HTMLFrameOwnerElement>(owner_.Get()); } static ChromeClient& GetEmptyChromeClient() { @@ -190,16 +191,18 @@ void Frame::NotifyUserActivationInLocalTree() { node->user_activation_state_.Activate(); // See FrameTreeNode::NotifyUserActivation() for details about this block. - if (IsLocalFrame() && RuntimeEnabledFeatures::UserActivationV2Enabled() && + auto* local_frame = DynamicTo<LocalFrame>(this); + if (local_frame && RuntimeEnabledFeatures::UserActivationV2Enabled() && RuntimeEnabledFeatures::UserActivationSameOriginVisibilityEnabled()) { const SecurityOrigin* security_origin = - ToLocalFrame(this)->GetSecurityContext()->GetSecurityOrigin(); + local_frame->GetSecurityContext()->GetSecurityOrigin(); Frame& root = Tree().Top(); for (Frame* node = &root; node; node = node->Tree().TraverseNext(&root)) { - if (node->IsLocalFrame() && + auto* local_frame_node = DynamicTo<LocalFrame>(node); + if (local_frame_node && security_origin->CanAccess( - ToLocalFrame(node)->GetSecurityContext()->GetSecurityOrigin())) { + local_frame_node->GetSecurityContext()->GetSecurityOrigin())) { node->user_activation_state_.Activate(); } } @@ -231,9 +234,10 @@ void Frame::SetOwner(FrameOwner* owner) { } void Frame::UpdateInertIfPossible() { - if (owner_ && owner_->IsLocal()) { - ToHTMLFrameOwnerElement(owner_)->UpdateDistributionForFlatTreeTraversal(); - if (ToHTMLFrameOwnerElement(owner_)->IsInert()) + if (auto* frame_owner_element = + DynamicTo<HTMLFrameOwnerElement>(owner_.Get())) { + frame_owner_element->UpdateDistributionForFlatTreeTraversal(); + if (frame_owner_element->IsInert()) SetIsInert(true); } } diff --git a/chromium/third_party/blink/renderer/core/frame/frame.h b/chromium/third_party/blink/renderer/core/frame/frame.h index d6b924b7f83..d5bb4219533 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame.h +++ b/chromium/third_party/blink/renderer/core/frame/frame.h @@ -42,9 +42,9 @@ #include "third_party/blink/renderer/core/frame/navigation_rate_limiter.h" #include "third_party/blink/renderer/core/loader/frame_loader_types.h" #include "third_party/blink/renderer/core/page/frame_tree.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/wtf/forward.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/frame/frame_client.h b/chromium/third_party/blink/renderer/core/frame/frame_client.h index 0bd60f893b7..5fb93df9461 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_client.h +++ b/chromium/third_party/blink/renderer/core/frame/frame_client.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_CLIENT_H_ #include "base/unguessable_token.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -33,6 +34,8 @@ class CORE_EXPORT FrameClient : public GarbageCollectedFinalized<FrameClient> { virtual void FrameFocused() const = 0; + virtual void VisibilityChanged(blink::mojom::FrameVisibility visibility) = 0; + virtual base::UnguessableToken GetDevToolsFrameToken() const = 0; virtual ~FrameClient() = default; diff --git a/chromium/third_party/blink/renderer/core/frame/frame_console.cc b/chromium/third_party/blink/renderer/core/frame/frame_console.cc index 607e38de922..5e8cf02b13f 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_console.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame_console.cc @@ -61,7 +61,7 @@ bool FrameConsole::AddMessageToStorage(ConsoleMessage* console_message) { } void FrameConsole::ReportMessageToClient(MessageSource source, - MessageLevel level, + mojom::ConsoleMessageLevel level, const String& message, SourceLocation* location) { if (source == kNetworkMessageSource) @@ -105,7 +105,7 @@ void FrameConsole::ReportResourceResponseReceived( String::Number(response.HttpStatusCode()) + " (" + response.HttpStatusText() + ')'; ConsoleMessage* console_message = ConsoleMessage::CreateForRequest( - kNetworkMessageSource, kErrorMessageLevel, message, + kNetworkMessageSource, mojom::ConsoleMessageLevel::kError, message, response.CurrentRequestUrl().GetString(), loader, request_identifier); AddMessage(console_message); } @@ -122,8 +122,8 @@ void FrameConsole::DidFailLoading(DocumentLoader* loader, message.Append(error.LocalizedDescription()); } AddMessageToStorage(ConsoleMessage::CreateForRequest( - kNetworkMessageSource, kErrorMessageLevel, message.ToString(), - error.FailingURL(), loader, request_identifier)); + kNetworkMessageSource, mojom::ConsoleMessageLevel::kError, + message.ToString(), error.FailingURL(), loader, request_identifier)); } void FrameConsole::Trace(blink::Visitor* visitor) { diff --git a/chromium/third_party/blink/renderer/core/frame/frame_console.h b/chromium/third_party/blink/renderer/core/frame/frame_console.h index 71722a5c754..192da822c9e 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_console.h +++ b/chromium/third_party/blink/renderer/core/frame/frame_console.h @@ -29,8 +29,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_CONSOLE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_CONSOLE_H_ +#include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/inspector/console_types.h" #include "third_party/blink/renderer/core/loader/console_logger_impl_base.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -69,7 +69,7 @@ class CORE_EXPORT FrameConsole final bool AddMessageToStorage(ConsoleMessage*); void ReportMessageToClient(MessageSource, - MessageLevel, + mojom::ConsoleMessageLevel, const String& message, SourceLocation*); diff --git a/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc b/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc index c69be2adb6b..d3f3eb167a5 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc @@ -32,6 +32,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/picture_layer.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" @@ -43,7 +44,6 @@ #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" -#include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h" namespace blink { @@ -96,7 +96,7 @@ void FrameOverlay::Update() { // state. cc::Layer* cc_layer = layer_->CcLayer(); cc_layer->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kFrameOverlay); + cc::MainThreadScrollingReason::kFrameOverlay); } layer_->SetLayerState(PropertyTreeState::Root(), IntPoint()); diff --git a/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc b/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc index eac7cc1a41b..d84e728eff5 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc @@ -81,7 +81,7 @@ class MockFrameOverlayCanvas : public SkCanvas { MOCK_METHOD2(onDrawRect, void(const SkRect&, const SkPaint&)); }; -INSTANTIATE_PAINT_TEST_CASE_P(FrameOverlayTest); +INSTANTIATE_PAINT_TEST_SUITE_P(FrameOverlayTest); TEST_P(FrameOverlayTest, AcceleratedCompositing) { std::unique_ptr<FrameOverlay> frame_overlay = CreateSolidYellowOverlay(); diff --git a/chromium/third_party/blink/renderer/core/frame/frame_owner.h b/chromium/third_party/blink/renderer/core/frame/frame_owner.h index 2c5244703b8..6e9974d3322 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_owner.h +++ b/chromium/third_party/blink/renderer/core/frame/frame_owner.h @@ -8,8 +8,8 @@ #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/sandbox_flags.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" namespace blink { @@ -56,9 +56,13 @@ class CORE_EXPORT FrameOwner : public GarbageCollectedMixin { // relevant for SVG documents that are embedded via <object> or <embed>. virtual void IntrinsicSizingInfoChanged() = 0; + // Indicates that a child frame requires its parent frame to track whether the + // child frame is occluded or has visual effects applied. + virtual void SetNeedsOcclusionTracking(bool) = 0; + // Returns the 'name' content attribute value of the browsing context // container. - // https://html.spec.whatwg.org/multipage/browsers.html#browsing-context-container + // https://html.spec.whatwg.org/C/#browsing-context-container virtual AtomicString BrowsingContextContainerName() const = 0; virtual ScrollbarMode ScrollingMode() const = 0; virtual int MarginWidth() const = 0; @@ -98,6 +102,7 @@ class CORE_EXPORT DummyFrameOwner final bool CanRenderFallbackContent() const override { return false; } void RenderFallbackContent(Frame*) override {} void IntrinsicSizingInfoChanged() override {} + void SetNeedsOcclusionTracking(bool) override {} AtomicString BrowsingContextContainerName() const override { return AtomicString(); } diff --git a/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc b/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc index 02eaf6cc202..32f30d1f646 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc @@ -63,7 +63,7 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/serialized_resource.h" +#include "third_party/blink/renderer/platform/mhtml/serialized_resource.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -85,40 +85,31 @@ class SerializerMarkupAccumulator : public MarkupAccumulator { public: SerializerMarkupAccumulator(FrameSerializer::Delegate&, const Document&, - HeapVector<Member<Node>>&); + HeapVector<Member<const Element>>&); ~SerializerMarkupAccumulator() override; protected: - void AppendCustomAttributes(StringBuilder&, - const Element&, - Namespaces*) override; - void AppendText(StringBuilder& out, Text&) override; + void AppendCustomAttributes(const Element&) override; bool ShouldIgnoreAttribute(const Element&, const Attribute&) const override; bool ShouldIgnoreElement(const Element&) const override; - void AppendElement(StringBuilder& out, const Element&, Namespaces*) override; - void AppendAttribute(StringBuilder& out, - const Element&, - const Attribute&, - Namespaces*) override; - void AppendStartTag(Node&, Namespaces* = nullptr) override; - void AppendEndTag(const Element&) override; + AtomicString AppendElement(const Element&) override; + void AppendAttribute(const Element&, const Attribute&) override; std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override; private: - void AppendAttributeValue(StringBuilder& out, const String& attribute_value); - void AppendRewrittenAttribute(StringBuilder& out, - const Element&, + void AppendAttributeValue(const String& attribute_value); + void AppendRewrittenAttribute(const Element&, const String& attribute_name, const String& attribute_value); FrameSerializer::Delegate& delegate_; Member<const Document> document_; - // FIXME: |FrameSerializer| uses |m_nodes| for collecting nodes in document - // included into serialized text then extracts image, object, etc. The size - // of this vector isn't small for large document. It is better to use + // FIXME: |FrameSerializer| uses |elements_| for collecting elements in + // document included into serialized text then extracts image, object, etc. + // The size of this vector isn't small for large document. It is better to use // callback like functionality. - HeapVector<Member<Node>>& nodes_; + HeapVector<Member<const Element>>& elements_; // Elements with links rewritten via appendAttribute method. HeapHashSet<Member<const Element>> elements_with_rewritten_links_; @@ -127,26 +118,19 @@ class SerializerMarkupAccumulator : public MarkupAccumulator { SerializerMarkupAccumulator::SerializerMarkupAccumulator( FrameSerializer::Delegate& delegate, const Document& document, - HeapVector<Member<Node>>& nodes) + HeapVector<Member<const Element>>& elements) : MarkupAccumulator(kResolveAllURLs), delegate_(delegate), document_(&document), - nodes_(nodes) {} + elements_(elements) {} SerializerMarkupAccumulator::~SerializerMarkupAccumulator() = default; void SerializerMarkupAccumulator::AppendCustomAttributes( - StringBuilder& result, - const Element& element, - Namespaces* namespaces) { + const Element& element) { Vector<Attribute> attributes = delegate_.GetCustomAttributes(element); for (const auto& attribute : attributes) - AppendAttribute(result, element, attribute, namespaces); -} - -void SerializerMarkupAccumulator::AppendText(StringBuilder& result, - Text& text) { - MarkupAccumulator::AppendText(result, text); + AppendAttribute(element, attribute); } bool SerializerMarkupAccumulator::ShouldIgnoreAttribute( @@ -168,32 +152,32 @@ bool SerializerMarkupAccumulator::ShouldIgnoreElement( return delegate_.ShouldIgnoreElement(element); } -void SerializerMarkupAccumulator::AppendElement(StringBuilder& result, - const Element& element, - Namespaces* namespaces) { - MarkupAccumulator::AppendElement(result, element, namespaces); +AtomicString SerializerMarkupAccumulator::AppendElement( + const Element& element) { + AtomicString prefix = MarkupAccumulator::AppendElement(element); // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an // element like this, without special cases for XHTML if (IsHTMLHeadElement(element)) { - result.Append("<meta http-equiv=\"Content-Type\" content=\""); - AppendAttributeValue(result, document_->SuggestedMIMEType()); - result.Append("; charset="); - AppendAttributeValue(result, document_->characterSet()); + markup_.Append("<meta http-equiv=\"Content-Type\" content=\""); + AppendAttributeValue(document_->SuggestedMIMEType()); + markup_.Append("; charset="); + AppendAttributeValue(document_->characterSet()); if (document_->IsXHTMLDocument()) - result.Append("\" />"); + markup_.Append("\" />"); else - result.Append("\">"); + markup_.Append("\">"); } + elements_.push_back(&element); // FIXME: For object (plugins) tags and video tag we could replace them by an // image of their current contents. + + return prefix; } -void SerializerMarkupAccumulator::AppendAttribute(StringBuilder& out, - const Element& element, - const Attribute& attribute, - Namespaces* namespaces) { +void SerializerMarkupAccumulator::AppendAttribute(const Element& element, + const Attribute& attribute) { // Check if link rewriting can affect the attribute. bool is_link_attribute = element.HasLegalLinkAttribute(attribute.GetName()); bool is_src_doc_attribute = IsHTMLFrameElementBase(element) && @@ -204,7 +188,7 @@ void SerializerMarkupAccumulator::AppendAttribute(StringBuilder& out, if (delegate_.RewriteLink(element, new_link_for_the_element)) { if (is_link_attribute) { // Rewrite element links. - AppendRewrittenAttribute(out, element, attribute.GetName().ToString(), + AppendRewrittenAttribute(element, attribute.GetName().ToString(), new_link_for_the_element); } else { DCHECK(is_src_doc_attribute); @@ -212,7 +196,7 @@ void SerializerMarkupAccumulator::AppendAttribute(StringBuilder& out, // serialized subframe to use html contents from the link provided by // Delegate::rewriteLink rather than html contents from srcdoc // attribute. - AppendRewrittenAttribute(out, element, html_names::kSrcAttr.LocalName(), + AppendRewrittenAttribute(element, html_names::kSrcAttr.LocalName(), new_link_for_the_element); } return; @@ -220,17 +204,7 @@ void SerializerMarkupAccumulator::AppendAttribute(StringBuilder& out, } // Fallback to appending the original attribute. - MarkupAccumulator::AppendAttribute(out, element, attribute, namespaces); -} - -void SerializerMarkupAccumulator::AppendStartTag(Node& node, - Namespaces* namespaces) { - MarkupAccumulator::AppendStartTag(node, namespaces); - nodes_.push_back(&node); -} - -void SerializerMarkupAccumulator::AppendEndTag(const Element& element) { - MarkupAccumulator::AppendEndTag(element); + MarkupAccumulator::AppendAttribute(element, attribute); } std::pair<Node*, Element*> SerializerMarkupAccumulator::GetAuxiliaryDOMTree( @@ -239,14 +213,12 @@ std::pair<Node*, Element*> SerializerMarkupAccumulator::GetAuxiliaryDOMTree( } void SerializerMarkupAccumulator::AppendAttributeValue( - StringBuilder& out, const String& attribute_value) { - MarkupFormatter::AppendAttributeValue(out, attribute_value, + MarkupFormatter::AppendAttributeValue(markup_, attribute_value, document_->IsHTMLDocument()); } void SerializerMarkupAccumulator::AppendRewrittenAttribute( - StringBuilder& out, const Element& element, const String& attribute_name, const String& attribute_value) { @@ -257,11 +229,11 @@ void SerializerMarkupAccumulator::AppendRewrittenAttribute( // Append the rewritten attribute. // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an // attribute like this. - out.Append(' '); - out.Append(attribute_name); - out.Append("=\""); - AppendAttributeValue(out, attribute_value); - out.Append("\""); + markup_.Append(' '); + markup_.Append(attribute_name); + markup_.Append("=\""); + AppendAttributeValue(attribute_value); + markup_.Append("\""); } // TODO(tiger): Right now there is no support for rewriting URLs inside CSS @@ -295,15 +267,15 @@ void FrameSerializer::SerializeFrame(const LocalFrame& frame) { return; } - HeapVector<Member<Node>> serialized_nodes; + HeapVector<Member<const Element>> serialized_elements; { TRACE_EVENT0("page-serialization", "FrameSerializer::serializeFrame HTML"); SCOPED_BLINK_UMA_HISTOGRAM_TIMER( "PageSerialization.SerializationTime.Html"); SerializerMarkupAccumulator accumulator(delegate_, document, - serialized_nodes); + serialized_elements); String text = - SerializeNodes<EditingStrategy>(accumulator, document, kIncludeNode); + accumulator.SerializeNodes<EditingStrategy>(document, kIncludeNode); CString frame_html = document.Encoding().Encode(text, WTF::kEntitiesForUnencodables); @@ -314,38 +286,35 @@ void FrameSerializer::SerializeFrame(const LocalFrame& frame) { should_collect_problem_metric_ = delegate_.ShouldCollectProblemMetric() && frame.IsMainFrame(); - for (Node* node : serialized_nodes) { + for (const Element* node : serialized_elements) { DCHECK(node); - if (!node->IsElementNode()) - continue; - - Element& element = ToElement(*node); + const Element& element = *node; // We have to process in-line style as it might contain some resources // (typically background images). if (element.IsStyledElement()) { RetrieveResourcesForProperties(element.InlineStyle(), document); - RetrieveResourcesForProperties(element.PresentationAttributeStyle(), - document); + RetrieveResourcesForProperties( + const_cast<Element&>(element).PresentationAttributeStyle(), document); } - if (auto* image = ToHTMLImageElementOrNull(element)) { - KURL url = + if (const auto* image = ToHTMLImageElementOrNull(element)) { + KURL image_url = document.CompleteURL(image->getAttribute(html_names::kSrcAttr)); ImageResourceContent* cached_image = image->CachedImage(); - AddImageToResources(cached_image, url); - } else if (auto* input = ToHTMLInputElementOrNull(element)) { + AddImageToResources(cached_image, image_url); + } else if (const auto* input = ToHTMLInputElementOrNull(element)) { if (input->type() == input_type_names::kImage && input->ImageLoader()) { - KURL url = input->Src(); + KURL image_url = input->Src(); ImageResourceContent* cached_image = input->ImageLoader()->GetContent(); - AddImageToResources(cached_image, url); + AddImageToResources(cached_image, image_url); } - } else if (auto* link = ToHTMLLinkElementOrNull(element)) { + } else if (const auto* link = ToHTMLLinkElementOrNull(element)) { if (CSSStyleSheet* sheet = link->sheet()) { - KURL url = + KURL sheet_url = document.CompleteURL(link->getAttribute(html_names::kHrefAttr)); - SerializeCSSStyleSheet(*sheet, url); + SerializeCSSStyleSheet(*sheet, sheet_url); } - } else if (auto* style = ToHTMLStyleElementOrNull(element)) { + } else if (const auto* style = ToHTMLStyleElementOrNull(element)) { if (CSSStyleSheet* sheet = style->sheet()) SerializeCSSStyleSheet(*sheet, NullURL()); } @@ -458,11 +427,11 @@ void FrameSerializer::SerializeCSSRule(CSSRule* rule) { switch (rule->type()) { case CSSRule::kStyleRule: RetrieveResourcesForProperties( - &ToCSSStyleRule(rule)->GetStyleRule()->Properties(), document); + &To<CSSStyleRule>(rule)->GetStyleRule()->Properties(), document); break; case CSSRule::kImportRule: { - CSSImportRule* import_rule = ToCSSImportRule(rule); + CSSImportRule* import_rule = To<CSSImportRule>(rule); KURL sheet_base_url = rule->parentStyleSheet()->BaseURL(); DCHECK(sheet_base_url.IsValid()); KURL import_url = KURL(sheet_base_url, import_rule->href()); @@ -482,7 +451,7 @@ void FrameSerializer::SerializeCSSRule(CSSRule* rule) { case CSSRule::kFontFaceRule: RetrieveResourcesForProperties( - &ToCSSFontFaceRule(rule)->StyleRule()->Properties(), document); + &To<CSSFontFaceRule>(rule)->StyleRule()->Properties(), document); break; // Rules in which no external resources can be referenced @@ -504,12 +473,8 @@ bool FrameSerializer::ShouldAddURL(const KURL& url) { void FrameSerializer::AddToResources( const String& mime_type, - ResourceHasCacheControlNoStoreHeader has_cache_control_no_store_header, scoped_refptr<const SharedBuffer> data, const KURL& url) { - if (delegate_.ShouldSkipResource(has_cache_control_no_store_header)) - return; - if (!data) { DLOG(ERROR) << "No data for resource " << url.GetString(); return; @@ -536,9 +501,6 @@ void FrameSerializer::AddImageToResources(ImageResourceContent* image, scoped_refptr<const SharedBuffer> data = image->GetImage()->Data(); AddToResources(image->GetResponse().MimeType(), - image->HasCacheControlNoStoreHeader() - ? kHasCacheControlNoStoreHeader - : kNoCacheControlNoStoreHeader, data, url); // If we're already reporting time for CSS serialization don't report it for @@ -560,11 +522,7 @@ void FrameSerializer::AddFontToResources(FontResource& font) { scoped_refptr<const SharedBuffer> data(font.ResourceBuffer()); - AddToResources(font.GetResponse().MimeType(), - font.HasCacheControlNoStoreHeader() - ? kHasCacheControlNoStoreHeader - : kNoCacheControlNoStoreHeader, - data, font.Url()); + AddToResources(font.GetResponse().MimeType(), data, font.Url()); } void FrameSerializer::RetrieveResourcesForProperties( diff --git a/chromium/third_party/blink/renderer/core/frame/frame_serializer.h b/chromium/third_party/blink/renderer/core/frame/frame_serializer.h index d372a972126..28491e7b2ef 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_serializer.h +++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer.h @@ -63,11 +63,6 @@ class CORE_EXPORT FrameSerializer final { STACK_ALLOCATED(); public: - enum ResourceHasCacheControlNoStoreHeader { - kNoCacheControlNoStoreHeader, - kHasCacheControlNoStoreHeader - }; - class Delegate { public: virtual ~Delegate() = default; @@ -97,11 +92,6 @@ class CORE_EXPORT FrameSerializer final { // with a given URI. Used to deduplicate resources across multiple frames. virtual bool ShouldSkipResourceWithURL(const KURL&) { return false; } - // Tells whether to skip serialization of a subresource. - virtual bool ShouldSkipResource(ResourceHasCacheControlNoStoreHeader) { - return false; - } - // Returns custom attributes that need to add in order to serialize the // element. virtual Vector<Attribute> GetCustomAttributes(const Element&) { @@ -145,7 +135,6 @@ class CORE_EXPORT FrameSerializer final { bool ShouldAddURL(const KURL&); void AddToResources(const String& mime_type, - ResourceHasCacheControlNoStoreHeader, scoped_refptr<const SharedBuffer>, const KURL&); void AddImageToResources(ImageResourceContent*, const KURL&); diff --git a/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc b/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc index 83ecd24c346..8a513ed05ba 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc @@ -45,8 +45,8 @@ #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/loader/fetch/resource_error.h" +#include "third_party/blink/renderer/platform/mhtml/serialized_resource.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" -#include "third_party/blink/renderer/platform/serialized_resource.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" @@ -97,7 +97,7 @@ class FrameSerializerTest : public testing::Test, WebURLResponse response; response.SetMIMEType("text/html"); - response.SetHTTPStatusCode(status_code); + response.SetHttpStatusCode(status_code); platform_->GetURLLoaderMockFactory()->RegisterErrorURL( KURL(base_url_, file), response, error); @@ -124,7 +124,7 @@ class FrameSerializerTest : public testing::Test, for (; frame; frame = frame->Tree().TraverseNext()) { // This is safe, because tests do not do cross-site navigation // (and therefore don't have remote frames). - serializer.SerializeFrame(*ToLocalFrame(frame)); + serializer.SerializeFrame(*To<LocalFrame>(frame)); } } diff --git a/chromium/third_party/blink/renderer/core/frame/frame_test.cc b/chromium/third_party/blink/renderer/core/frame/frame_test.cc index aabd268726f..58ebe05ed71 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame_test.cc @@ -8,6 +8,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/loader/document_loader.h" +#include "third_party/blink/renderer/core/testing/document_interface_broker_test_helpers.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -214,4 +215,23 @@ TEST_F(FrameTest, UserActivationHistograms) { histograms.ExpectTotalCount("UserActivation.Consumption.FrameResult", 3); } +TEST_F(FrameTest, TestDocumentInterfaceBrokerOverride) { + mojom::blink::DocumentInterfaceBrokerPtr doc; + FrameHostTestDocumentInterfaceBroker frame_interface_broker( + &GetDocument().GetFrame()->GetDocumentInterfaceBroker(), + mojo::MakeRequest(&doc)); + GetDocument().GetFrame()->SetDocumentInterfaceBrokerForTesting( + doc.PassInterface().PassHandle()); + + mojom::blink::FrameHostTestInterfacePtr frame_test; + GetDocument() + .GetFrame() + ->GetDocumentInterfaceBroker() + .GetFrameHostTestInterface(mojo::MakeRequest(&frame_test)); + frame_test->GetName(base::BindOnce([](const WTF::String& result) { + EXPECT_EQ(result, kGetNameTestResponse); + })); + frame_interface_broker.Flush(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc index d15a9b145e6..58eb54f6549 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc @@ -32,6 +32,7 @@ #include <utility> +#include "base/bind.h" #include "cc/test/test_ukm_recorder_factory.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" @@ -106,14 +107,15 @@ T* CreateDefaultClientIfNeeded(T* client, std::unique_ptr<T>& owned_client) { } // namespace void LoadFrameDontWait(WebLocalFrame* frame, const WebURL& url) { - WebLocalFrameImpl* impl = ToWebLocalFrameImpl(frame); + auto* impl = To<WebLocalFrameImpl>(frame); if (url.ProtocolIs("javascript")) { impl->LoadJavaScriptURL(url); } else { auto params = std::make_unique<WebNavigationParams>(); - params->request = WebURLRequest(url); + params->url = url; params->navigation_timings.navigation_start = base::TimeTicks::Now(); params->navigation_timings.fetch_start = base::TimeTicks::Now(); + FillNavigationParamsResponse(params.get()); impl->CommitNavigation(std::move(params), nullptr /* extra_data */); } } @@ -126,7 +128,7 @@ void LoadFrame(WebLocalFrame* frame, const std::string& url) { void LoadHTMLString(WebLocalFrame* frame, const std::string& html, const WebURL& base_url) { - WebLocalFrameImpl* impl = ToWebLocalFrameImpl(frame); + auto* impl = To<WebLocalFrameImpl>(frame); impl->CommitNavigation( WebNavigationParams::CreateWithHTMLString(html, base_url), nullptr /* extra_data */); @@ -136,15 +138,15 @@ void LoadHTMLString(WebLocalFrame* frame, void LoadHistoryItem(WebLocalFrame* frame, const WebHistoryItem& item, mojom::FetchCacheMode cache_mode) { - WebLocalFrameImpl* impl = ToWebLocalFrameImpl(frame); + auto* impl = To<WebLocalFrameImpl>(frame); HistoryItem* history_item = item; auto params = std::make_unique<WebNavigationParams>(); - params->request = - WrappedResourceRequest(history_item->GenerateResourceRequest(cache_mode)); + params->url = history_item->Url(); params->frame_load_type = WebFrameLoadType::kBackForward; params->history_item = item; params->navigation_timings.navigation_start = base::TimeTicks::Now(); params->navigation_timings.fetch_start = base::TimeTicks::Now(); + FillNavigationParamsResponse(params.get()); impl->CommitNavigation(std::move(params), nullptr /* extra_data */); PumpPendingRequestsForFrameToLoad(frame); } @@ -167,6 +169,15 @@ void PumpPendingRequestsForFrameToLoad(WebLocalFrame* frame) { test::EnterRunLoop(); } +void FillNavigationParamsResponse(WebNavigationParams* params) { + KURL kurl(params->url); + // Empty documents and srcdoc will be handled by DocumentLoader. + if (DocumentLoader::WillLoadUrlAsEmpty(kurl) || kurl.IsAboutSrcdocURL()) + return; + Platform::Current()->GetURLLoaderMockFactory()->FillNavigationParamsResponse( + params); +} + WebMouseEvent CreateMouseEvent(WebInputEvent::Type type, WebMouseEvent::Button button, const IntPoint& point, @@ -187,7 +198,7 @@ WebLocalFrameImpl* CreateLocalChild(WebLocalFrame& parent, std::unique_ptr<TestWebFrameClient> owned_client; client = CreateDefaultClientIfNeeded(client, owned_client); mojom::blink::DocumentInterfaceBrokerPtrInfo document_interface_broker; - WebLocalFrameImpl* frame = ToWebLocalFrameImpl(parent.CreateLocalChild( + auto* frame = To<WebLocalFrameImpl>(parent.CreateLocalChild( scope, client, nullptr, mojo::MakeRequest(&document_interface_broker).PassMessagePipe())); client->Bind(frame, std::move(owned_client)); @@ -201,7 +212,7 @@ WebLocalFrameImpl* CreateLocalChild( DCHECK(self_owned); TestWebFrameClient* client = self_owned.get(); mojom::blink::DocumentInterfaceBrokerPtrInfo document_interface_broker; - WebLocalFrameImpl* frame = ToWebLocalFrameImpl(parent.CreateLocalChild( + auto* frame = To<WebLocalFrameImpl>(parent.CreateLocalChild( scope, client, nullptr, mojo::MakeRequest(&document_interface_broker).PassMessagePipe())); client->Bind(frame, std::move(self_owned)); @@ -213,11 +224,10 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame, std::unique_ptr<TestWebFrameClient> owned_client; client = CreateDefaultClientIfNeeded(client, owned_client); mojom::blink::DocumentInterfaceBrokerPtrInfo document_interface_broker; - WebLocalFrameImpl* frame = - ToWebLocalFrameImpl(WebLocalFrame::CreateProvisional( - client, nullptr, - mojo::MakeRequest(&document_interface_broker).PassMessagePipe(), - &old_frame, WebSandboxFlags::kNone, ParsedFeaturePolicy())); + auto* frame = To<WebLocalFrameImpl>(WebLocalFrame::CreateProvisional( + client, nullptr, + mojo::MakeRequest(&document_interface_broker).PassMessagePipe(), + &old_frame, WebSandboxFlags::kNone, ParsedFeaturePolicy())); client->Bind(frame, std::move(owned_client)); std::unique_ptr<TestWebWidgetClient> widget_client; // Create a local root, if necessary. @@ -230,10 +240,11 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame, widget_client = std::make_unique<TestWebWidgetClient>(); WebFrameWidget* frame_widget = WebFrameWidget::CreateForChildLocalRoot(widget_client.get(), frame); - frame_widget->Resize(WebSize()); // The WebWidget requires a LayerTreeView to be set, either by the // WebWidgetClient itself or by someone else. We do that here. - frame_widget->SetLayerTreeView(widget_client->layer_tree_view()); + frame_widget->SetLayerTreeView(widget_client->layer_tree_view(), + widget_client->animation_host()); + frame_widget->Resize(WebSize()); } if (widget_client) client->BindWidgetClient(std::move(widget_client)); @@ -257,7 +268,7 @@ WebLocalFrameImpl* CreateLocalChild(WebRemoteFrame& parent, std::unique_ptr<TestWebFrameClient> owned_client; client = CreateDefaultClientIfNeeded(client, owned_client); mojom::blink::DocumentInterfaceBrokerPtrInfo document_interface_broker; - WebLocalFrameImpl* frame = ToWebLocalFrameImpl(parent.CreateLocalChild( + auto* frame = To<WebLocalFrameImpl>(parent.CreateLocalChild( WebTreeScopeType::kDocument, name, WebSandboxFlags::kNone, client, nullptr, mojo::MakeRequest(&document_interface_broker).PassMessagePipe(), previous_sibling, ParsedFeaturePolicy(), properties, @@ -269,12 +280,13 @@ WebLocalFrameImpl* CreateLocalChild(WebRemoteFrame& parent, CreateDefaultClientIfNeeded(widget_client, owned_widget_client); WebFrameWidget* frame_widget = WebFrameWidget::CreateForChildLocalRoot(widget_client, frame); + // The WebWidget requires a LayerTreeView to be set, either by the + // WebWidgetClient itself or by someone else. We do that here. + frame_widget->SetLayerTreeView(widget_client->layer_tree_view(), + widget_client->animation_host()); // Set an initial size for subframes. if (frame->Parent()) frame_widget->Resize(WebSize()); - // The WebWidget requires a LayerTreeView to be set, either by the - // WebWidgetClient itself or by someone else. We do that here. - frame_widget->SetLayerTreeView(widget_client->layer_tree_view()); client->BindWidgetClient(std::move(owned_widget_client)); return frame; } @@ -328,12 +340,19 @@ WebViewImpl* WebViewHelper::InitializeWithOpener( test_web_widget_client_ = CreateDefaultClientIfNeeded( web_widget_client, owned_test_web_widget_client_); + // TODO(danakj): Make this part of attaching the main frame's WebFrameWidget. + // This happens before CreateForMainFrame as the WebFrameWidget binding to the + // WebLocalFrameImpl sets up animations. + web_view_->MainFrameWidget()->SetLayerTreeView( + test_web_widget_client_->layer_tree_view(), + test_web_widget_client_->animation_host()); // TODO(dcheng): The main frame widget currently has a special case. // Eliminate this once WebView is no longer a WebWidget. blink::WebFrameWidget::CreateForMainFrame(test_web_widget_client_, frame); - // TODO(danakj): Make this part of attaching the main frame's WebFrameWidget. - web_view_->MainFrameWidget()->SetLayerTreeView( - test_web_widget_client_->layer_tree_view()); + // We inform the WebView when it has a local main frame attached once the + // WebFrame it fully set up and the WebWidgetClient is initialized (which is + // the case by this point). + web_view_->DidAttachLocalMainFrame(test_web_widget_client_); // Set an initial size for subframes. if (frame->Parent()) @@ -394,16 +413,19 @@ WebViewImpl* WebViewHelper::InitializeRemote( test_web_widget_client_ = CreateDefaultClientIfNeeded( web_widget_client, owned_test_web_widget_client_); + web_view_->MainFrameWidget()->SetLayerTreeView( + test_web_widget_client_->layer_tree_view(), + test_web_widget_client_->animation_host()); // TODO(danakj): Remove this! Make WebViewImpl not need a WebWidgetClient when // the main frame is remote. - web_view_->SetWebWidgetClient(test_web_widget_client_); + web_view_->DidAttachRemoteMainFrame(test_web_widget_client_); return web_view_; } void WebViewHelper::LoadAhem() { LocalFrame* local_frame = - ToLocalFrame(WebFrame::ToCoreFrame(*LocalMainFrame())); + To<LocalFrame>(WebFrame::ToCoreFrame(*LocalMainFrame())); DCHECK(local_frame); RenderingTest::LoadAhem(*local_frame); } @@ -421,7 +443,7 @@ void WebViewHelper::Reset() { } WebLocalFrameImpl* WebViewHelper::LocalMainFrame() const { - return ToWebLocalFrameImpl(web_view_->MainFrame()); + return To<WebLocalFrameImpl>(web_view_->MainFrame()); } WebRemoteFrameImpl* WebViewHelper::RemoteMainFrame() const { @@ -465,7 +487,7 @@ void TestWebFrameClient::Bind(WebLocalFrame* frame, std::unique_ptr<TestWebFrameClient> self_owned) { DCHECK(!frame_); DCHECK(!self_owned || self_owned.get() == this); - frame_ = ToWebLocalFrameImpl(frame); + frame_ = To<WebLocalFrameImpl>(frame); self_owned_ = std::move(self_owned); } @@ -476,10 +498,8 @@ void TestWebFrameClient::BindWidgetClient( } void TestWebFrameClient::FrameDetached(DetachType type) { - if (frame_->FrameWidget()) { - frame_->FrameWidget()->WillCloseLayerTreeView(); + if (frame_->FrameWidget()) frame_->FrameWidget()->Close(); - } owned_widget_client_.reset(); frame_->Close(); @@ -531,6 +551,8 @@ void TestWebFrameClient::CommitNavigation( if (!frame_) return; auto params = WebNavigationParams::CreateFromInfo(*info); + if (info->archive_status != WebNavigationInfo::ArchiveStatus::Present) + FillNavigationParamsResponse(params.get()); frame_->CommitNavigation(std::move(params), nullptr /* extra_data */); } @@ -605,6 +627,25 @@ content::LayerTreeView* LayerTreeViewFactory::Initialize( TestWebWidgetClient::TestWebWidgetClient( content::LayerTreeViewDelegate* delegate) { layer_tree_view_ = layer_tree_view_factory_.Initialize(delegate); + animation_host_ = layer_tree_view_->animation_host(); +} + +void TestWebWidgetClient::SetRootLayer(scoped_refptr<cc::Layer> layer) { + layer_tree_host()->SetRootLayer(std::move(layer)); +} + +void TestWebWidgetClient::SetBackgroundColor(SkColor color) { + layer_tree_host()->set_background_color(color); +} + +void TestWebWidgetClient::RegisterViewportLayers( + const cc::ViewportLayers& layers) { + layer_tree_host()->RegisterViewportLayers(layers); +} + +void TestWebWidgetClient::RegisterSelection( + const cc::LayerSelection& selection) { + layer_tree_host()->RegisterSelection(selection); } void TestWebWidgetClient::DidMeaningfulLayout( @@ -633,6 +674,7 @@ WebView* TestWebViewClient::CreateView(WebLocalFrame* opener, WebNavigationPolicy, bool, WebSandboxFlags, + const FeaturePolicy::FeatureState&, const SessionStorageNamespaceId&) { auto webview_helper = std::make_unique<WebViewHelper>(); WebView* result = webview_helper->InitializeWithOpener(opener); diff --git a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h index bd4aa756469..d457bcae85d 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h +++ b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h @@ -60,6 +60,7 @@ #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" #include "third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #define EXPECT_FLOAT_POINT_EQ(expected, actual) \ @@ -82,15 +83,18 @@ EXPECT_FLOAT_EQ((expected).Height(), (actual).Height()); \ } while (false) -namespace blink { +namespace cc { +class AnimationHost; +} +namespace blink { class WebFrame; class WebLocalFrameImpl; +struct WebNavigationParams; class WebRemoteFrameImpl; class WebSettings; namespace frame_test_helpers { - class TestWebFrameClient; class TestWebRemoteFrameClient; class TestWebWidgetClient; @@ -114,6 +118,9 @@ void LoadHistoryItem(WebLocalFrame*, void ReloadFrame(WebLocalFrame*); void ReloadFrameBypassingCache(WebLocalFrame*); +// Fills navigation params if needed. Params should have the proper url set up. +void FillNavigationParamsResponse(WebNavigationParams*); + // Pumps pending resource requests while waiting for a frame to load. Consider // using one of the above helper methods whenever possible. void PumpPendingRequestsForFrameToLoad(WebLocalFrame*); @@ -170,6 +177,8 @@ WebRemoteFrameImpl* CreateRemoteChild(WebRemoteFrame& parent, // A class that constructs and owns a LayerTreeView for blink // unit tests. class LayerTreeViewFactory { + DISALLOW_NEW(); + public: // Use this to make a LayerTreeView with a stub delegate. content::LayerTreeView* Initialize(); @@ -191,8 +200,16 @@ class TestWebWidgetClient : public WebWidgetClient { // WebWidgetClient: void ScheduleAnimation() override { animation_scheduled_ = true; } + void SetRootLayer(scoped_refptr<cc::Layer> layer) override; + void RegisterViewportLayers(const cc::ViewportLayers& layOAers) override; + void RegisterSelection(const cc::LayerSelection& selection) override; + void SetBackgroundColor(SkColor color) override; content::LayerTreeView* layer_tree_view() { return layer_tree_view_; } + cc::LayerTreeHost* layer_tree_host() { + return layer_tree_view_->layer_tree_host(); + } + cc::AnimationHost* animation_host() { return animation_host_; } bool AnimationScheduled() { return animation_scheduled_; } void ClearAnimationScheduled() { animation_scheduled_ = false; } @@ -211,6 +228,7 @@ class TestWebWidgetClient : public WebWidgetClient { private: content::LayerTreeView* layer_tree_view_ = nullptr; + cc::AnimationHost* animation_host_ = nullptr; LayerTreeViewFactory layer_tree_view_factory_; bool animation_scheduled_ = false; int visually_non_empty_layout_count_ = 0; @@ -236,6 +254,7 @@ class TestWebViewClient : public WebViewClient { WebNavigationPolicy, bool, WebSandboxFlags, + const FeaturePolicy::FeatureState&, const SessionStorageNamespaceId&) override; private: @@ -246,6 +265,8 @@ class TestWebViewClient : public WebViewClient { // Convenience class for handling the lifetime of a WebView and its associated // mainframe in tests. class WebViewHelper { + USING_FAST_MALLOC(WebViewHelper); + public: WebViewHelper(); ~WebViewHelper(); diff --git a/chromium/third_party/blink/renderer/core/frame/frame_view.h b/chromium/third_party/blink/renderer/core/frame/frame_view.h index 429a2e036c9..18d4cf9e953 100644 --- a/chromium/third_party/blink/renderer/core/frame/frame_view.h +++ b/chromium/third_party/blink/renderer/core/frame/frame_view.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_VIEW_H_ #include "third_party/blink/renderer/core/frame/embedded_content_view.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -14,7 +15,11 @@ struct IntrinsicSizingInfo; class CORE_EXPORT FrameView : public EmbeddedContentView { public: ~FrameView() override = default; - virtual void UpdateViewportIntersectionsForSubtree() = 0; + + // parent_flags is the result of calling GetIntersectionObservationFlags on + // the LocalFrameView parent of this FrameView (if any). It contains dirty + // bits based on whether geometry may have changed in the parent frame. + virtual bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) = 0; virtual bool GetIntrinsicSizingInfo(IntrinsicSizingInfo&) const = 0; virtual bool HasIntrinsicSizingInfo() const = 0; @@ -22,11 +27,12 @@ class CORE_EXPORT FrameView : public EmbeddedContentView { bool IsFrameView() const override { return true; } }; -DEFINE_TYPE_CASTS(FrameView, - EmbeddedContentView, - embedded_content_view, - embedded_content_view->IsFrameView(), - embedded_content_view.IsFrameView()); +template <> +struct DowncastTraits<FrameView> { + static bool AllowFrom(const EmbeddedContentView& embedded_content_view) { + return embedded_content_view.IsFrameView(); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc index 3c0cb048b5e..cac7afe483a 100644 --- a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc +++ b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc @@ -91,9 +91,10 @@ void FullscreenController::DidEnterFullscreen() { // Notify all local frames that we have entered fullscreen. for (Frame* frame = web_view_base_->GetPage()->MainFrame(); frame; frame = frame->Tree().TraverseNext()) { - if (!frame->IsLocalFrame()) + auto* local_frame = DynamicTo<LocalFrame>(frame); + if (!local_frame) continue; - if (Document* document = ToLocalFrame(frame)->GetDocument()) + if (Document* document = local_frame->GetDocument()) Fullscreen::DidEnterFullscreen(*document); } pending_frames_->clear(); @@ -124,8 +125,9 @@ void FullscreenController::DidExitFullscreen() { continue; } - DCHECK(frame->IsLocalFrame() && ToLocalFrame(frame)->IsLocalRoot()); - if (Document* document = ToLocalFrame(frame)->GetDocument()) + auto* local_frame = To<LocalFrame>(frame); + DCHECK(local_frame->IsLocalRoot()); + if (Document* document = local_frame->GetDocument()) Fullscreen::DidExitFullscreen(*document); // Skip over all descendant frames. @@ -172,8 +174,7 @@ void FullscreenController::EnterFullscreen(LocalFrame& frame, DCHECK(state_ == State::kInitial); blink::WebFullscreenOptions blink_options; // Only clone options if the feature is enabled. - if (RuntimeEnabledFeatures::FullscreenOptionsEnabled()) - blink_options.prefers_navigation_bar = options->navigationUI() != "hide"; + blink_options.prefers_navigation_bar = options->navigationUI() != "hide"; GetWebFrameClient(frame).EnterFullscreen(blink_options); state_ = State::kEnteringFullscreen; diff --git a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h index ab6676c1dd2..3bffc9a7557 100644 --- a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h +++ b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h @@ -39,6 +39,7 @@ #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/heap/persistent.h" +#include "third_party/blink/renderer/platform/wtf/allocator.h" namespace blink { @@ -50,6 +51,8 @@ class WebViewImpl; // and out of fullscreen, including restoring scroll offset and scale after // exiting fullscreen. It is (indirectly) used by the Fullscreen class. class CORE_EXPORT FullscreenController { + USING_FAST_MALLOC(FullscreenController); + public: static std::unique_ptr<FullscreenController> Create(WebViewImpl*); diff --git a/chromium/third_party/blink/renderer/core/frame/history.cc b/chromium/third_party/blink/renderer/core/frame/history.cc index 32923260452..b7753d118e1 100644 --- a/chromium/third_party/blink/renderer/core/frame/history.cc +++ b/chromium/third_party/blink/renderer/core/frame/history.cc @@ -201,7 +201,7 @@ void History::go(ScriptState* script_state, // We intentionally call reload() for the current frame if delta is zero. // Otherwise, navigation happens on the root frame. // This behavior is designed in the following spec. - // https://html.spec.whatwg.org/multipage/browsers.html#dom-history-go + // https://html.spec.whatwg.org/C/#dom-history-go GetFrame()->Reload(WebFrameLoadType::kReload, ClientRedirectPolicy::kClientRedirect); } diff --git a/chromium/third_party/blink/renderer/core/frame/history.h b/chromium/third_party/blink/renderer/core/frame/history.h index f16dd789fc4..9c970acb36d 100644 --- a/chromium/third_party/blink/renderer/core/frame/history.h +++ b/chromium/third_party/blink/renderer/core/frame/history.h @@ -29,7 +29,7 @@ #include "base/gtest_prod_util.h" #include "third_party/blink/public/web/web_frame_load_type.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/loader/frame_loader_types.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/core/frame/history.idl b/chromium/third_party/blink/renderer/core/frame/history.idl index 1d3633dd101..182cfa0504c 100644 --- a/chromium/third_party/blink/renderer/core/frame/history.idl +++ b/chromium/third_party/blink/renderer/core/frame/history.idl @@ -23,7 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://html.spec.whatwg.org/#the-history-interface +// https://html.spec.whatwg.org/C/#the-history-interface enum ScrollRestoration {"auto", "manual"}; diff --git a/chromium/third_party/blink/renderer/core/frame/intervention.cc b/chromium/third_party/blink/renderer/core/frame/intervention.cc index 1f9c5daa7e7..f3f654ef34d 100644 --- a/chromium/third_party/blink/renderer/core/frame/intervention.cc +++ b/chromium/third_party/blink/renderer/core/frame/intervention.cc @@ -5,8 +5,8 @@ #include "third_party/blink/renderer/core/frame/intervention.h" #include "services/service_manager/public/cpp/connector.h" +#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/reporting.mojom-blink.h" #include "third_party/blink/renderer/core/frame/frame_console.h" #include "third_party/blink/renderer/core/frame/intervention_report_body.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -27,7 +27,7 @@ void Intervention::GenerateReport(const LocalFrame* frame, // Send the message to the console. Document* document = frame->GetDocument(); document->AddConsoleMessage(ConsoleMessage::Create( - kInterventionMessageSource, kErrorMessageLevel, message)); + kInterventionMessageSource, mojom::ConsoleMessageLevel::kError, message)); if (!frame->Client()) return; diff --git a/chromium/third_party/blink/renderer/core/frame/link_highlights.cc b/chromium/third_party/blink/renderer/core/frame/link_highlights.cc index 9f570e96278..41bfc965d20 100644 --- a/chromium/third_party/blink/renderer/core/frame/link_highlights.cc +++ b/chromium/third_party/blink/renderer/core/frame/link_highlights.cc @@ -6,6 +6,7 @@ #include <memory> +#include "cc/animation/animation_host.h" #include "cc/layers/picture_layer.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" @@ -15,7 +16,6 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/link_highlight_impl.h" -#include "third_party/blink/renderer/platform/animation/compositor_animation_host.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" namespace blink { @@ -93,19 +93,19 @@ void LinkHighlights::StartHighlightAnimationIfNeeded() { } void LinkHighlights::LayerTreeViewInitialized( - WebLayerTreeView& layer_tree_view) { + WebLayerTreeView& layer_tree_view, + cc::AnimationHost& animation_host) { + animation_host_ = &animation_host; if (Platform::Current()->IsThreadedAnimationEnabled()) { timeline_ = CompositorAnimationTimeline::Create(); - animation_host_ = std::make_unique<CompositorAnimationHost>( - layer_tree_view.CompositorAnimationHost()); - animation_host_->AddTimeline(*timeline_); + animation_host_->AddAnimationTimeline(timeline_->GetAnimationTimeline()); } } void LinkHighlights::WillCloseLayerTreeView(WebLayerTreeView& layer_tree_view) { RemoveAllHighlights(); if (timeline_) { - animation_host_->RemoveTimeline(*timeline_); + animation_host_->RemoveAnimationTimeline(timeline_->GetAnimationTimeline()); timeline_.reset(); } animation_host_ = nullptr; @@ -122,16 +122,6 @@ bool LinkHighlights::NeedsHighlightEffectInternal( return false; } -CompositorElementId LinkHighlights::element_id(const LayoutObject& object) { - for (auto& highlight : link_highlights_) { - if (auto* node = highlight->GetNode()) { - if (node->GetLayoutObject() == &object) - return highlight->element_id(); - } - } - return CompositorElementId(); -} - void LinkHighlights::Paint(GraphicsContext& context) const { DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); for (const auto& highlight : link_highlights_) diff --git a/chromium/third_party/blink/renderer/core/frame/link_highlights.h b/chromium/third_party/blink/renderer/core/frame/link_highlights.h index fc58e13eb67..7dd6fc98f8c 100644 --- a/chromium/third_party/blink/renderer/core/frame/link_highlights.h +++ b/chromium/third_party/blink/renderer/core/frame/link_highlights.h @@ -11,12 +11,14 @@ #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" #include "third_party/blink/renderer/platform/heap/handle.h" -namespace blink { +namespace cc { +class AnimationHost; +} +namespace blink { class GraphicsContext; class Page; class LinkHighlightImpl; -class CompositorAnimationHost; class CompositorAnimationTimeline; class WebLayerTreeView; class LocalFrame; @@ -49,7 +51,7 @@ class CORE_EXPORT LinkHighlights final void StartHighlightAnimationIfNeeded(); - void LayerTreeViewInitialized(WebLayerTreeView&); + void LayerTreeViewInitialized(WebLayerTreeView&, cc::AnimationHost&); void WillCloseLayerTreeView(WebLayerTreeView&); bool IsEmpty() const { return link_highlights_.IsEmpty(); } @@ -60,8 +62,6 @@ class CORE_EXPORT LinkHighlights final return NeedsHighlightEffectInternal(object); } - CompositorElementId element_id(const LayoutObject& object); - // For CompositeAfterPaint. void Paint(GraphicsContext&) const; @@ -87,7 +87,7 @@ class CORE_EXPORT LinkHighlights final Member<Page> page_; Vector<std::unique_ptr<LinkHighlightImpl>> link_highlights_; - std::unique_ptr<CompositorAnimationHost> animation_host_; + cc::AnimationHost* animation_host_ = nullptr; std::unique_ptr<CompositorAnimationTimeline> timeline_; }; diff --git a/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc b/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc index 2adb444114a..de8d95f1be2 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc @@ -29,6 +29,7 @@ #include <memory> #include <utility> +#include "cc/input/snap_selection_strategy.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_screen_info.h" @@ -48,7 +49,6 @@ #include "third_party/blink/renderer/core/css/media_query_matcher.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/css/style_media.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/dom/document_init.h" #include "third_party/blink/renderer/core/dom/dom_implementation.h" #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h" @@ -64,6 +64,7 @@ #include "third_party/blink/renderer/core/events/message_event.h" #include "third_party/blink/renderer/core/events/page_transition_event.h" #include "third_party/blink/renderer/core/events/pop_state_event.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/frame/bar_prop.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/dom_visual_viewport.h" @@ -98,6 +99,7 @@ #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/script/modulator.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" #include "third_party/blink/renderer/core/timing/dom_window_performance.h" #include "third_party/blink/renderer/core/timing/window_performance.h" @@ -106,7 +108,6 @@ #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/microtask.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.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/weborigin/security_origin.h" @@ -327,7 +328,7 @@ void LocalDOMWindow::EnqueuePageshowEvent(PageshowEventPersistence persisted) { void LocalDOMWindow::EnqueueHashchangeEvent(const String& old_url, const String& new_url) { - // https://html.spec.whatwg.org/#history-traversal + // https://html.spec.whatwg.org/C/#history-traversal EnqueueWindowEvent(*HashChangeEvent::Create(old_url, new_url), TaskType::kDOMManipulation); } @@ -428,8 +429,8 @@ void LocalDOMWindow::SendOrientationChangeEvent() { for (wtf_size_t i = 0; i < frames.size(); i++) { for (Frame* child = frames[i]->Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - if (child->IsLocalFrame()) - frames.push_back(ToLocalFrame(child)); + if (auto* child_local_frame = DynamicTo<LocalFrame>(child)) + frames.push_back(child_local_frame); } } @@ -586,9 +587,9 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck( "The target origin provided ('" + intended_target_origin->ToString() + "') does not match the recipient window's origin ('" + document()->GetSecurityOrigin()->ToString() + "')."); - ConsoleMessage* console_message = - ConsoleMessage::Create(kSecurityMessageSource, kErrorMessageLevel, - message, std::move(location)); + ConsoleMessage* console_message = ConsoleMessage::Create( + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, message, + std::move(location)); GetFrameConsole()->AddMessage(console_message); return; } @@ -599,7 +600,7 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck( sender, RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy::kSuppressReporting)) { UseCounter::Count( - GetFrame(), WebFeature::kPostMessageIncomingWouldBeBlockedByConnectSrc); + document(), WebFeature::kPostMessageIncomingWouldBeBlockedByConnectSrc); } DispatchEvent(*event); @@ -613,10 +614,10 @@ DOMSelection* LocalDOMWindow::getSelection() { } Element* LocalDOMWindow::frameElement() const { - if (!(GetFrame() && GetFrame()->Owner() && GetFrame()->Owner()->IsLocal())) + if (!GetFrame()) return nullptr; - return ToHTMLFrameOwnerElement(GetFrame()->Owner()); + return DynamicTo<HTMLFrameOwnerElement>(GetFrame()->Owner()); } void LocalDOMWindow::blur() {} @@ -659,7 +660,7 @@ void LocalDOMWindow::alert(ScriptState* script_state, const String& message) { if (document()->IsSandboxed(kSandboxModals)) { UseCounter::Count(document(), WebFeature::kDialogInSandboxedContext); GetFrameConsole()->AddMessage(ConsoleMessage::Create( - kSecurityMessageSource, kErrorMessageLevel, + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, "Ignored call to 'alert()'. The document is sandboxed, and the " "'allow-modals' keyword is not set.")); return; @@ -688,7 +689,7 @@ bool LocalDOMWindow::confirm(ScriptState* script_state, const String& message) { if (document()->IsSandboxed(kSandboxModals)) { UseCounter::Count(document(), WebFeature::kDialogInSandboxedContext); GetFrameConsole()->AddMessage(ConsoleMessage::Create( - kSecurityMessageSource, kErrorMessageLevel, + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, "Ignored call to 'confirm()'. The document is sandboxed, and the " "'allow-modals' keyword is not set.")); return false; @@ -719,7 +720,7 @@ String LocalDOMWindow::prompt(ScriptState* script_state, if (document()->IsSandboxed(kSandboxModals)) { UseCounter::Count(document(), WebFeature::kDialogInSandboxedContext); GetFrameConsole()->AddMessage(ConsoleMessage::Create( - kSecurityMessageSource, kErrorMessageLevel, + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, "Ignored call to 'prompt()'. The document is sandboxed, and the " "'allow-modals' keyword is not set.")); return String(); @@ -775,34 +776,36 @@ int LocalDOMWindow::outerHeight() const { if (!GetFrame()) return 0; - Page* page = GetFrame()->GetPage(); + LocalFrame* frame = GetFrame(); + Page* page = frame->GetPage(); if (!page) return 0; ChromeClient& chrome_client = page->GetChromeClient(); if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { return static_cast<int>( - lroundf(chrome_client.RootWindowRect().Height() * + lroundf(chrome_client.RootWindowRect(*frame).Height() * chrome_client.GetScreenInfo().device_scale_factor)); } - return chrome_client.RootWindowRect().Height(); + return chrome_client.RootWindowRect(*frame).Height(); } int LocalDOMWindow::outerWidth() const { if (!GetFrame()) return 0; - Page* page = GetFrame()->GetPage(); + LocalFrame* frame = GetFrame(); + Page* page = frame->GetPage(); if (!page) return 0; ChromeClient& chrome_client = page->GetChromeClient(); if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { return static_cast<int>( - lroundf(chrome_client.RootWindowRect().Width() * + lroundf(chrome_client.RootWindowRect(*frame).Width() * chrome_client.GetScreenInfo().device_scale_factor)); } - return chrome_client.RootWindowRect().Width(); + return chrome_client.RootWindowRect(*frame).Width(); } IntSize LocalDOMWindow::GetViewportSize() const { @@ -824,9 +827,8 @@ IntSize LocalDOMWindow::GetViewportSize() const { // FIXME: This is potentially too much work. We really only need to know the // dimensions of the parent frame's layoutObject. if (Frame* parent = GetFrame()->Tree().Parent()) { - if (parent && parent->IsLocalFrame()) - ToLocalFrame(parent) - ->GetDocument() + if (auto* parent_local_frame = DynamicTo<LocalFrame>(parent)) + parent_local_frame->GetDocument() ->UpdateStyleAndLayoutIgnorePendingStylesheets(); } @@ -850,37 +852,39 @@ int LocalDOMWindow::innerWidth() const { } int LocalDOMWindow::screenX() const { - if (!GetFrame()) + LocalFrame* frame = GetFrame(); + if (!frame) return 0; - Page* page = GetFrame()->GetPage(); + Page* page = frame->GetPage(); if (!page) return 0; ChromeClient& chrome_client = page->GetChromeClient(); if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { return static_cast<int>( - lroundf(chrome_client.RootWindowRect().X() * + lroundf(chrome_client.RootWindowRect(*frame).X() * chrome_client.GetScreenInfo().device_scale_factor)); } - return chrome_client.RootWindowRect().X(); + return chrome_client.RootWindowRect(*frame).X(); } int LocalDOMWindow::screenY() const { - if (!GetFrame()) + LocalFrame* frame = GetFrame(); + if (!frame) return 0; - Page* page = GetFrame()->GetPage(); + Page* page = frame->GetPage(); if (!page) return 0; ChromeClient& chrome_client = page->GetChromeClient(); if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { return static_cast<int>( - lroundf(chrome_client.RootWindowRect().Y() * + lroundf(chrome_client.RootWindowRect(*frame).Y() * chrome_client.GetScreenInfo().device_scale_factor)); } - return chrome_client.RootWindowRect().Y(); + return chrome_client.RootWindowRect(*frame).Y(); } double LocalDOMWindow::scrollX() const { @@ -1023,8 +1027,8 @@ void LocalDOMWindow::scrollBy(const ScrollToOptions* scroll_to_options) const { y * GetFrame()->PageZoomFactor()); FloatPoint new_scaled_position = current_position + scaled_delta; - std::unique_ptr<SnapSelectionStrategy> strategy = - SnapSelectionStrategy::CreateForEndAndDirection( + std::unique_ptr<cc::SnapSelectionStrategy> strategy = + cc::SnapSelectionStrategy::CreateForEndAndDirection( gfx::ScrollOffset(current_position), gfx::ScrollOffset(scaled_delta)); new_scaled_position = document() @@ -1087,8 +1091,8 @@ void LocalDOMWindow::scrollTo(const ScrollToOptions* scroll_to_options) const { FloatPoint new_scaled_position = viewport->ScrollOffsetToPosition(ScrollOffset(scaled_x, scaled_y)); - std::unique_ptr<SnapSelectionStrategy> strategy = - SnapSelectionStrategy::CreateForEndPosition( + std::unique_ptr<cc::SnapSelectionStrategy> strategy = + cc::SnapSelectionStrategy::CreateForEndPosition( gfx::ScrollOffset(new_scaled_position), scroll_to_options->hasLeft(), scroll_to_options->hasTop()); new_scaled_position = @@ -1108,58 +1112,62 @@ void LocalDOMWindow::moveBy(int x, int y) const { if (!GetFrame() || !GetFrame()->IsMainFrame()) return; - Page* page = GetFrame()->GetPage(); + LocalFrame* frame = GetFrame(); + Page* page = frame->GetPage(); if (!page) return; - IntRect window_rect = page->GetChromeClient().RootWindowRect(); + IntRect window_rect = page->GetChromeClient().RootWindowRect(*frame); window_rect.SaturatedMove(x, y); // Security check (the spec talks about UniversalBrowserWrite to disable this // check...) - page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *GetFrame()); + page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *frame); } void LocalDOMWindow::moveTo(int x, int y) const { if (!GetFrame() || !GetFrame()->IsMainFrame()) return; - Page* page = GetFrame()->GetPage(); + LocalFrame* frame = GetFrame(); + Page* page = frame->GetPage(); if (!page) return; - IntRect window_rect = page->GetChromeClient().RootWindowRect(); + IntRect window_rect = page->GetChromeClient().RootWindowRect(*frame); window_rect.SetLocation(IntPoint(x, y)); // Security check (the spec talks about UniversalBrowserWrite to disable this // check...) - page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *GetFrame()); + page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *frame); } void LocalDOMWindow::resizeBy(int x, int y) const { if (!GetFrame() || !GetFrame()->IsMainFrame()) return; - Page* page = GetFrame()->GetPage(); + LocalFrame* frame = GetFrame(); + Page* page = frame->GetPage(); if (!page) return; - IntRect fr = page->GetChromeClient().RootWindowRect(); + IntRect fr = page->GetChromeClient().RootWindowRect(*frame); IntSize dest = fr.Size() + IntSize(x, y); IntRect update(fr.Location(), dest); - page->GetChromeClient().SetWindowRectWithAdjustment(update, *GetFrame()); + page->GetChromeClient().SetWindowRectWithAdjustment(update, *frame); } void LocalDOMWindow::resizeTo(int width, int height) const { if (!GetFrame() || !GetFrame()->IsMainFrame()) return; - Page* page = GetFrame()->GetPage(); + LocalFrame* frame = GetFrame(); + Page* page = frame->GetPage(); if (!page) return; - IntRect fr = page->GetChromeClient().RootWindowRect(); + IntRect fr = page->GetChromeClient().RootWindowRect(*frame); IntSize dest = IntSize(width, height); IntRect update(fr.Location(), dest); - page->GetChromeClient().SetWindowRectWithAdjustment(update, *GetFrame()); + page->GetChromeClient().SetWindowRectWithAdjustment(update, *frame); } int LocalDOMWindow::requestAnimationFrame(V8FrameRequestCallback* callback) { @@ -1308,7 +1316,7 @@ void LocalDOMWindow::WarnUnusedPreloads(TimerBase* base) { "event. Please make sure it has an appropriate `as` value and it is " + "preloaded intentionally."; GetFrameConsole()->AddMessage(ConsoleMessage::Create( - kJSMessageSource, kWarningMessageLevel, message)); + kJSMessageSource, mojom::ConsoleMessageLevel::kWarning, message)); } } @@ -1350,7 +1358,7 @@ void LocalDOMWindow::DispatchLoadEvent() { TRACE_EVENT_INSTANT1("devtools.timeline", "MarkLoad", TRACE_EVENT_SCOPE_THREAD, "data", inspector_mark_load_event::Data(GetFrame())); - probe::loadEventFired(GetFrame()); + probe::LoadEventFired(GetFrame()); } DispatchEventResult LocalDOMWindow::DispatchEvent(Event& event, @@ -1397,8 +1405,8 @@ void LocalDOMWindow::PrintErrorMessage(const String& message) const { if (message.IsEmpty()) return; - GetFrameConsole()->AddMessage( - ConsoleMessage::Create(kJSMessageSource, kErrorMessageLevel, message)); + GetFrameConsole()->AddMessage(ConsoleMessage::Create( + kJSMessageSource, mojom::ConsoleMessageLevel::kError, message)); } DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate, diff --git a/chromium/third_party/blink/renderer/core/frame/local_dom_window.h b/chromium/third_party/blink/renderer/core/frame/local_dom_window.h index 7b4a71dac5e..26c60d876db 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/chromium/third_party/blink/renderer/core/frame/local_dom_window.h @@ -36,6 +36,7 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include <memory> @@ -108,7 +109,7 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow, explicit LocalDOMWindow(LocalFrame&); ~LocalDOMWindow() override; - LocalFrame* GetFrame() const { return ToLocalFrame(DOMWindow::GetFrame()); } + LocalFrame* GetFrame() const { return To<LocalFrame>(DOMWindow::GetFrame()); } void Trace(blink::Visitor*) override; @@ -228,7 +229,7 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow, int webkitRequestAnimationFrame(V8FrameRequestCallback*); void cancelAnimationFrame(int id); - // https://html.spec.whatwg.org/#windoworworkerglobalscope-mixin + // https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin void queueMicrotask(V8VoidFunction*); // Idle callback extensions @@ -249,19 +250,19 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow, bool isSecureContext() const; - DEFINE_ATTRIBUTE_EVENT_LISTENER(animationend, kAnimationend); - DEFINE_ATTRIBUTE_EVENT_LISTENER(animationiteration, kAnimationiteration); - DEFINE_ATTRIBUTE_EVENT_LISTENER(animationstart, kAnimationstart); - DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch); - DEFINE_ATTRIBUTE_EVENT_LISTENER(transitionend, kTransitionend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(animationend, kAnimationend) + DEFINE_ATTRIBUTE_EVENT_LISTENER(animationiteration, kAnimationiteration) + DEFINE_ATTRIBUTE_EVENT_LISTENER(animationstart, kAnimationstart) + DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch) + DEFINE_ATTRIBUTE_EVENT_LISTENER(transitionend, kTransitionend) - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, kWebkitAnimationStart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, kWebkitAnimationStart) DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, - kWebkitAnimationIteration); - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, kWebkitAnimationEnd); - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, kWebkitTransitionEnd); + kWebkitAnimationIteration) + DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, kWebkitAnimationEnd) + DEFINE_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, kWebkitTransitionEnd) - DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange) void RegisterEventListenerObserver(EventListenerObserver*); @@ -381,11 +382,12 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow, mutable Member<TrustedTypePolicyFactory> trusted_types_; }; -DEFINE_TYPE_CASTS(LocalDOMWindow, - DOMWindow, - x, - x->IsLocalDOMWindow(), - x.IsLocalDOMWindow()); +template <> +struct DowncastTraits<LocalDOMWindow> { + static bool AllowFrom(const DOMWindow& window) { + return window.IsLocalDOMWindow(); + } +}; inline String LocalDOMWindow::status() const { return status_; diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.cc b/chromium/third_party/blink/renderer/core/frame/local_frame.cc index 9c8ffb99f78..a7b483e821f 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc @@ -42,9 +42,10 @@ #include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/public/platform/web_url_request.h" +#include "third_party/blink/public/web/web_content_capture_client.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" -#include "third_party/blink/renderer/core/aom/computed_accessible_node.h" +#include "third_party/blink/renderer/core/content_capture/content_capture_manager.h" #include "third_party/blink/renderer/core/core_initializer.h" #include "third_party/blink/renderer/core/core_probe_sink.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" @@ -64,6 +65,7 @@ #include "third_party/blink/renderer/core/events/current_input_event.h" #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/frame/ad_tracker.h" +#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/event_handler_registry.h" #include "third_party/blink/renderer/core/frame/frame_console.h" #include "third_party/blink/renderer/core/frame/frame_overlay.h" @@ -92,6 +94,8 @@ #include "third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.h" #include "third_party/blink/renderer/core/page/drag_controller.h" #include "third_party/blink/renderer/core/page/focus_controller.h" +#include "third_party/blink/renderer/core/page/plugin_data.h" +#include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h" #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" @@ -113,8 +117,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/network/network_state_notifier.h" #include "third_party/blink/renderer/platform/network/network_utils.h" -#include "third_party/blink/renderer/platform/plugins/plugin_data.h" -#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_scheduler.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -124,17 +126,13 @@ namespace blink { namespace { inline float ParentPageZoomFactor(LocalFrame* frame) { - Frame* parent = frame->Tree().Parent(); - if (!parent || !parent->IsLocalFrame()) - return 1; - return ToLocalFrame(parent)->PageZoomFactor(); + auto* parent_local_frame = DynamicTo<LocalFrame>(frame->Tree().Parent()); + return parent_local_frame ? parent_local_frame->PageZoomFactor() : 1; } inline float ParentTextZoomFactor(LocalFrame* frame) { - Frame* parent = frame->Tree().Parent(); - if (!parent || !parent->IsLocalFrame()) - return 1; - return ToLocalFrame(parent)->TextZoomFactor(); + auto* parent_local_frame = DynamicTo<LocalFrame>(frame->Tree().Parent()); + return parent_local_frame ? parent_local_frame->TextZoomFactor() : 1; } bool ShouldUseClientLoFiForRequest( @@ -222,10 +220,12 @@ LocalFrame* LocalFrame::Create(LocalFrameClient* client, client, page, owner, interface_registry ? interface_registry : InterfaceRegistry::GetEmptyInterfaceRegistry()); - PageScheduler* page_scheduler = page.GetPageScheduler(); - if (frame->IsMainFrame() && page_scheduler) - page_scheduler->SetIsMainFrameLocal(true); - probe::frameAttachedToParent(frame); + + if (frame->IsMainFrame()) { + if (PageScheduler* page_scheduler = page.GetPageScheduler()) + page_scheduler->SetIsMainFrameLocal(true); + } + probe::FrameAttachedToParent(frame); return frame; } @@ -316,8 +316,8 @@ void LocalFrame::Trace(blink::Visitor* visitor) { visitor->Trace(console_); visitor->Trace(input_method_controller_); visitor->Trace(text_suggestion_controller_); - visitor->Trace(computed_node_mapping_); visitor->Trace(smooth_scroll_sequencer_); + visitor->Trace(content_capture_manager_); Frame::Trace(visitor); Supplementable<LocalFrame>::Trace(visitor); } @@ -364,7 +364,7 @@ void LocalFrame::DetachImpl(FrameDetachType type) { } idleness_detector_->Shutdown(); if (inspector_trace_events_) - probe_sink_->removeInspectorTraceEvents(inspector_trace_events_); + probe_sink_->RemoveInspectorTraceEvents(inspector_trace_events_); inspector_task_runner_->Dispose(); PluginScriptForbiddenScope forbid_plugin_destructor_scripting; @@ -393,6 +393,12 @@ void LocalFrame::DetachImpl(FrameDetachType type) { loader_.StopAllLoaders(); loader_.Detach(); GetDocument()->Shutdown(); + + if (content_capture_manager_) { + content_capture_manager_->Shutdown(); + content_capture_manager_ = nullptr; + } + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. // It seems to crash because Frame is detached before LocalFrameView. // Verify here that any LocalFrameView has been detached by now. @@ -433,7 +439,7 @@ void LocalFrame::DetachImpl(FrameDetachType type) { DomWindow()->FrameDestroyed(); - probe::frameDetachedFromParent(this); + probe::FrameDetachedFromParent(this); supplements_.clear(); frame_scheduler_.reset(); @@ -456,11 +462,11 @@ void LocalFrame::PrintNavigationErrorMessage(const Frame& target_frame, const char* reason) { // URLs aren't available for RemoteFrames, so the error message uses their // origin instead. + auto* target_local_frame = DynamicTo<LocalFrame>(&target_frame); String target_frame_description = - target_frame.IsLocalFrame() + target_local_frame ? "with URL '" + - ToLocalFrame(target_frame).GetDocument()->Url().GetString() + - "'" + target_local_frame->GetDocument()->Url().GetString() + "'" : "with origin '" + target_frame.GetSecurityContext() ->GetSecurityOrigin() @@ -475,8 +481,8 @@ void LocalFrame::PrintNavigationErrorMessage(const Frame& target_frame, } void LocalFrame::PrintNavigationWarning(const String& message) { - console_->AddMessage( - ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel, message)); + console_->AddMessage(ConsoleMessage::Create( + kJSMessageSource, mojom::ConsoleMessageLevel::kWarning, message)); } bool LocalFrame::ShouldClose() { @@ -530,9 +536,9 @@ void LocalFrame::Reload(WebFrameLoadType load_type, if (const WebInputEvent* input_event = CurrentInputEvent::Get()) request.SetInputStartTime(input_event->TimeStamp()); if (client_redirect_policy == ClientRedirectPolicy::kClientRedirect) { - probe::frameScheduledNavigation(this, request.GetResourceRequest().Url(), + probe::FrameScheduledNavigation(this, request.GetResourceRequest().Url(), 0.0, ClientNavigationReason::kReload); - probe::frameClearedScheduledNavigation(this); + probe::FrameClearedScheduledNavigation(this); } loader_.StartNavigation(request, load_type); @@ -543,7 +549,7 @@ LocalWindowProxy* LocalFrame::WindowProxy(DOMWrapperWorld& world) { } LocalDOMWindow* LocalFrame::DomWindow() const { - return ToLocalDOMWindow(dom_window_); + return To<LocalDOMWindow>(dom_window_.Get()); } void LocalFrame::SetDOMWindow(LocalDOMWindow* dom_window) { @@ -630,7 +636,7 @@ void LocalFrame::PropagateInertToChildFrames() { // inert element in an ancestor Frame. Otherwise, decide whether a child // Frame element is inert because of an element in this Frame. child->SetIsInert(is_inert_ || - ToHTMLFrameOwnerElement(child->Owner())->IsInert()); + To<HTMLFrameOwnerElement>(child->Owner())->IsInert()); } } @@ -651,9 +657,8 @@ bool LocalFrame::BubbleLogicalScrollFromChildFrame( ScrollGranularity granularity, Frame* child) { FrameOwner* owner = child->Owner(); - DCHECK(owner); - DCHECK(owner->IsLocal()); - HTMLFrameOwnerElement* owner_element = ToHTMLFrameOwnerElement(owner); + auto* owner_element = DynamicTo<HTMLFrameOwnerElement>(owner); + DCHECK(owner_element); return GetEventHandler().BubblingScroll(direction, granularity, owner_element); @@ -661,9 +666,8 @@ bool LocalFrame::BubbleLogicalScrollFromChildFrame( LocalFrame& LocalFrame::LocalFrameRoot() const { const LocalFrame* cur_frame = this; - while (cur_frame && cur_frame->Tree().Parent() && - cur_frame->Tree().Parent()->IsLocalFrame()) - cur_frame = ToLocalFrame(cur_frame->Tree().Parent()); + while (cur_frame && IsA<LocalFrame>(cur_frame->Tree().Parent())) + cur_frame = To<LocalFrame>(cur_frame->Tree().Parent()); return const_cast<LocalFrame&>(*cur_frame); } @@ -721,11 +725,11 @@ void LocalFrame::SetPrinting(bool printing, // Subframes of the one we're printing don't lay out to the page size. for (Frame* child = Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - if (child->IsLocalFrame()) { + if (auto* child_local_frame = DynamicTo<LocalFrame>(child)) { if (printing) - ToLocalFrame(child)->StartPrinting(); + child_local_frame->StartPrinting(); else - ToLocalFrame(child)->EndPrinting(); + child_local_frame->EndPrinting(); } } @@ -751,10 +755,12 @@ bool LocalFrame::ShouldUsePrintingLayout() const { // frame. In such case, we can not check its document or other internal // status. However, if the parent is in printing mode, this frame's printing // must have started with |use_printing_layout| as false in print context. - return !Tree().Parent() || - (Tree().Parent()->IsLocalFrame() && - !ToLocalFrame(Tree().Parent())->GetDocument()->Printing()) || - (!Tree().Parent()->IsLocalFrame() && Client()->UsePrintingLayout()); + auto* parent = Tree().Parent(); + if (!parent) + return true; + auto* local_parent = DynamicTo<LocalFrame>(parent); + return local_parent ? !local_parent->GetDocument()->Printing() + : Client()->UsePrintingLayout(); } FloatSize LocalFrame::ResizePageRectsKeepingRatio( @@ -815,9 +821,10 @@ void LocalFrame::SetPageAndTextZoomFactors(float page_zoom_factor, for (Frame* child = Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - if (child->IsLocalFrame()) - ToLocalFrame(child)->SetPageAndTextZoomFactors(page_zoom_factor_, - text_zoom_factor_); + if (auto* child_local_frame = DynamicTo<LocalFrame>(child)) { + child_local_frame->SetPageAndTextZoomFactors(page_zoom_factor_, + text_zoom_factor_); + } } document->MediaQueryAffectingValueChanged(); @@ -835,8 +842,8 @@ void LocalFrame::DeviceScaleFactorChanged() { StyleChangeReasonForTracing::Create(style_change_reason::kZoom)); for (Frame* child = Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - if (child->IsLocalFrame()) - ToLocalFrame(child)->DeviceScaleFactorChanged(); + if (auto* child_local_frame = DynamicTo<LocalFrame>(child)) + child_local_frame->DeviceScaleFactorChanged(); } } @@ -902,9 +909,8 @@ bool LocalFrame::ShouldReuseDefaultView( // Since sandboxing turns the origin into an opaque origin it needs to also // be considered when deciding whether to reuse it. // Spec: - // https://html.spec.whatwg.org/multipage/browsing-the-web.html#initialise-the-document-object - if (csp && - SecurityContext::IsSandboxed(kSandboxOrigin, csp->GetSandboxMask())) { + // https://html.spec.whatwg.org/C/#initialise-the-document-object + if (csp && (csp->GetSandboxMask() & kSandboxOrigin)) { return false; } @@ -977,7 +983,7 @@ inline LocalFrame::LocalFrame(LocalFrameClient* client, probe_sink_ = MakeGarbageCollected<CoreProbeSink>(); performance_monitor_ = MakeGarbageCollected<PerformanceMonitor>(this); inspector_trace_events_ = MakeGarbageCollected<InspectorTraceEvents>(); - probe_sink_->addInspectorTraceEvents(inspector_trace_events_); + probe_sink_->AddInspectorTraceEvents(inspector_trace_events_); if (RuntimeEnabledFeatures::AdTaggingEnabled()) { ad_tracker_ = MakeGarbageCollected<AdTracker>(this); } @@ -1032,9 +1038,10 @@ bool LocalFrame::CanNavigate(const Frame& target_frame, // Top navigation in sandbox with or w/o 'allow-top-navigation'. if (target_frame != this && sandboxed && target_frame == Tree().Top()) { - UseCounter::Count(this, WebFeature::kTopNavInSandbox); + UseCounter::Count(GetDocument(), WebFeature::kTopNavInSandbox); if (!has_user_gesture) { - UseCounter::Count(this, WebFeature::kTopNavInSandboxWithoutGesture); + UseCounter::Count(GetDocument(), + WebFeature::kTopNavInSandboxWithoutGesture); } } @@ -1055,11 +1062,11 @@ bool LocalFrame::CanNavigate(const Frame& target_frame, if (IsAdSubframe()) framebust_params |= kAdBit; - UseCounter::Count(this, WebFeature::kTopNavigationFromSubFrame); + UseCounter::Count(GetDocument(), WebFeature::kTopNavigationFromSubFrame); if (sandboxed) { // Sandboxed with 'allow-top-navigation'. - UseCounter::Count(this, WebFeature::kTopNavInSandboxWithPerm); + UseCounter::Count(GetDocument(), WebFeature::kTopNavInSandboxWithPerm); if (!has_user_gesture) { - UseCounter::Count(this, + UseCounter::Count(GetDocument(), WebFeature::kTopNavInSandboxWithPermButNoGesture); } } @@ -1098,18 +1105,16 @@ bool LocalFrame::CanNavigate(const Frame& target_frame, if (!RuntimeEnabledFeatures:: FramebustingNeedsSameOriginOrUserGestureEnabled() || allow_popups_and_redirects) { + auto* target_local_frame = DynamicTo<LocalFrame>(&target_frame); String target_frame_description = - target_frame.IsLocalFrame() ? "with URL '" + - ToLocalFrame(target_frame) - .GetDocument() - ->Url() - .GetString() + - "'" - : "with origin '" + - target_frame.GetSecurityContext() - ->GetSecurityOrigin() - ->ToString() + - "'"; + target_local_frame + ? "with URL '" + + target_local_frame->GetDocument()->Url().GetString() + "'" + : "with origin '" + + target_frame.GetSecurityContext() + ->GetSecurityOrigin() + ->ToString() + + "'"; String message = "Frame with URL '" + GetDocument()->Url().GetString() + "' attempted to navigate its top-level window " + target_frame_description + @@ -1137,7 +1142,8 @@ bool LocalFrame::CanNavigate(const Frame& target_frame, !HasTransientUserActivation(this, false /* check_if_main_thread */) && !target_frame.GetSecurityContext()->GetSecurityOrigin()->CanAccess( SecurityOrigin::Create(destination_url).get())) { - UseCounter::Count(this, WebFeature::kOpenerNavigationWithoutGesture); + UseCounter::Count(GetDocument(), + WebFeature::kOpenerNavigationWithoutGesture); } if (!is_allowed_navigation && !error_reason.IsNull()) @@ -1275,8 +1281,8 @@ void LocalFrame::SetIsAdSubframeIfNecessary() { // If the parent frame is local, directly determine if it's an ad. If it's // remote, then it is up to the embedder that moved this frame out-of- // process to set this frame as an ad via SetIsAdSubframe before commit. - bool parent_is_ad = - parent->IsLocalFrame() && ToLocalFrame(parent)->IsAdSubframe(); + auto* parent_local_frame = DynamicTo<LocalFrame>(parent); + bool parent_is_ad = parent_local_frame && parent_local_frame->IsAdSubframe(); if (parent_is_ad || ad_tracker_->IsAdScriptInStack()) { SetIsAdSubframe(parent_is_ad ? blink::mojom::AdFrameType::kChildAd @@ -1284,17 +1290,47 @@ void LocalFrame::SetIsAdSubframeIfNecessary() { } } +ContentCaptureManager* LocalFrame::GetContentCaptureManager() { + DCHECK(Client()); + if (!IsLocalRoot()) + return nullptr; + + if (auto* content_capture_client = Client()->GetWebContentCaptureClient()) { + if (!content_capture_manager_) { + content_capture_manager_ = MakeGarbageCollected<ContentCaptureManager>( + *this, content_capture_client->GetNodeHolderType()); + } + } else if (content_capture_manager_) { + content_capture_manager_->Shutdown(); + content_capture_manager_ = nullptr; + } + return content_capture_manager_; +} + service_manager::InterfaceProvider& LocalFrame::GetInterfaceProvider() { DCHECK(Client()); return *Client()->GetInterfaceProvider(); } +void LocalFrame::BindDocumentInterfaceBroker( + mojo::ScopedMessagePipeHandle js_handle) { + DCHECK(Client()); + Client()->BindDocumentInterfaceBroker(std::move(js_handle)); +} + mojom::blink::DocumentInterfaceBroker& LocalFrame::GetDocumentInterfaceBroker() { DCHECK(Client()); return *Client()->GetDocumentInterfaceBroker(); } +mojo::ScopedMessagePipeHandle LocalFrame::SetDocumentInterfaceBrokerForTesting( + mojo::ScopedMessagePipeHandle blink_handle) { + DCHECK(Client()); + return Client()->SetDocumentInterfaceBrokerForTesting( + std::move(blink_handle)); +} + AssociatedInterfaceProvider* LocalFrame::GetRemoteNavigationAssociatedInterfaces() { DCHECK(Client()); @@ -1314,7 +1350,7 @@ FrameResourceCoordinator* LocalFrame::GetFrameResourceCoordinator() { auto* local_frame_client = Client(); if (!local_frame_client) return nullptr; - frame_resource_coordinator_ = FrameResourceCoordinator::Create( + frame_resource_coordinator_ = FrameResourceCoordinator::MaybeCreate( local_frame_client->GetInterfaceProvider()); } return frame_resource_coordinator_.get(); @@ -1333,7 +1369,7 @@ void LocalFrame::SetAdTrackerForTesting(AdTracker* ad_tracker) { ad_tracker_ = ad_tracker; } -DEFINE_WEAK_IDENTIFIER_MAP(LocalFrame); +DEFINE_WEAK_IDENTIFIER_MAP(LocalFrame) FrameNavigationDisabler::FrameNavigationDisabler(LocalFrame& frame) : frame_(&frame) { @@ -1414,11 +1450,11 @@ WebPluginContainerImpl* LocalFrame::GetWebPluginContainer(Node* node) const { void LocalFrame::SetViewportIntersectionFromParent( const IntRect& viewport_intersection, - bool occluded_or_obscured) { + FrameOcclusionState occlusion_state) { if (remote_viewport_intersection_ != viewport_intersection || - occluded_or_obscured_by_ancestor_ != occluded_or_obscured) { + occlusion_state_ != occlusion_state) { remote_viewport_intersection_ = viewport_intersection; - occluded_or_obscured_by_ancestor_ = occluded_or_obscured; + occlusion_state_ = occlusion_state; if (View()) { View()->SetIntersectionObservationState(LocalFrameView::kRequired); View()->ScheduleAnimation(); @@ -1426,6 +1462,14 @@ void LocalFrame::SetViewportIntersectionFromParent( } } +FrameOcclusionState LocalFrame::GetOcclusionState() const { + if (IsMainFrame()) + return kGuaranteedNotOccluded; + if (IsLocalRoot()) + return occlusion_state_; + return LocalFrameRoot().GetOcclusionState(); +} + void LocalFrame::ForceSynchronousDocumentInstall( const AtomicString& mime_type, scoped_refptr<SharedBuffer> data) { @@ -1481,17 +1525,6 @@ bool LocalFrame::IsUsingDataSavingPreview() const { WebURLRequest::kNoScriptOn); } -ComputedAccessibleNode* LocalFrame::GetOrCreateComputedAccessibleNode( - AXID ax_id, - WebComputedAXTree* tree) { - if (computed_node_mapping_.find(ax_id) == computed_node_mapping_.end()) { - ComputedAccessibleNode* node = - ComputedAccessibleNode::Create(ax_id, tree, this); - computed_node_mapping_.insert(ax_id, node); - } - return computed_node_mapping_.at(ax_id); -} - bool LocalFrame::IsAdSubframe() const { return ad_frame_type_ != blink::mojom::AdFrameType::kNonAd; } @@ -1573,6 +1606,10 @@ int64_t LocalFrame::GetUkmSourceId() { return document->UkmSourceID(); } +void LocalFrame::UpdateTaskTime(base::TimeDelta time) { + Client()->DidChangeCpuTiming(time); +} + const mojom::blink::ReportingServiceProxyPtr& LocalFrame::GetReportingService() const { if (!reporting_service_) { @@ -1754,4 +1791,54 @@ void LocalFrame::ForciblyPurgeV8Memory() { Loader().StopAllLoaders(); } +void LocalFrame::PauseContext() { + if (Document* document = GetDocument()) { + document->Fetcher()->SetDefersLoading(true); + document->SetLifecycleState(lifecycle_state_); + } + Loader().SetDefersLoading(true); + GetFrameScheduler()->SetPaused(true); +} + +void LocalFrame::UnpauseContext() { + if (Document* document = GetDocument()) { + document->Fetcher()->SetDefersLoading(false); + document->SetLifecycleState(mojom::FrameLifecycleState::kRunning); + } + Loader().SetDefersLoading(false); + GetFrameScheduler()->SetPaused(false); +} + +void LocalFrame::SetLifecycleState(mojom::FrameLifecycleState state) { + if (state == lifecycle_state_) + return; + bool is_frozen = lifecycle_state_ != mojom::FrameLifecycleState::kRunning; + bool freeze = state != mojom::FrameLifecycleState::kRunning; + + // TODO(dtapuska): Determine if we should dispatch events if we are + // transitioning across frozen states. ie. kPaused->kFrozen should + // pause media. + + // If we are transitioning from one frozen state to another just return. + if (is_frozen == freeze) + return; + mojom::FrameLifecycleState old_state = lifecycle_state_; + lifecycle_state_ = state; + + if (freeze) { + if (lifecycle_state_ != mojom::FrameLifecycleState::kPaused) + DidFreeze(); + PauseContext(); + } else { + UnpauseContext(); + if (old_state != mojom::FrameLifecycleState::kPaused) + DidResume(); + } +} + +void LocalFrame::MaybeLogAdClickNavigation() { + if (HasTransientUserActivation() && IsAdSubframe()) + UseCounter::Count(GetDocument(), WebFeature::kAdClickNavigation); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.h b/chromium/third_party/blink/renderer/core/frame/local_frame.h index 92ea3730539..8c8492e0c53 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h @@ -33,12 +33,13 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/strong_binding_set.h" +#include "third_party/blink/public/common/frame/occlusion_state.h" #include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink.h" #include "third_party/blink/public/mojom/loader/previews_resource_loading_hints.mojom-blink.h" -#include "third_party/blink/public/platform/reporting.mojom-blink.h" +#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h" #include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/renderer/core/accessibility/axid.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/dom/weak_identifier_map.h" @@ -67,7 +68,7 @@ namespace blink { class AdTracker; class AssociatedInterfaceProvider; class Color; -class ComputedAccessibleNode; +class ContentCaptureManager; class ContentSecurityPolicy; class Document; class Editor; @@ -102,7 +103,6 @@ class SharedBuffer; class SmoothScrollSequencer; class SpellChecker; class TextSuggestionController; -class WebComputedAXTree; class WebContentSettingsClient; class WebPluginContainerImpl; class WebURLLoaderFactory; @@ -210,6 +210,9 @@ class CORE_EXPORT LocalFrame final : public Frame, CoreProbeSink* GetProbeSink() { return probe_sink_.Get(); } scoped_refptr<InspectorTaskRunner> GetInspectorTaskRunner(); + // Returns ContentCaptureManager in LocalFrameRoot. + ContentCaptureManager* GetContentCaptureManager(); + // Activates the user activation states of the |LocalFrame| (provided it's // non-null) and all its ancestors. Also creates a |UserGestureIndicator| // that contains a |UserGestureToken| with the given status. @@ -302,7 +305,10 @@ class CORE_EXPORT LocalFrame final : public Frame, bool CanNavigate(const Frame&, const KURL& destination_url = KURL()); service_manager::InterfaceProvider& GetInterfaceProvider(); + void BindDocumentInterfaceBroker(mojo::ScopedMessagePipeHandle js_handle); mojom::blink::DocumentInterfaceBroker& GetDocumentInterfaceBroker(); + mojo::ScopedMessagePipeHandle SetDocumentInterfaceBrokerForTesting( + mojo::ScopedMessagePipeHandle blink_handle); InterfaceRegistry* GetInterfaceRegistry() { return interface_registry_; } // Returns an AssociatedInterfaceProvider the frame can use to request @@ -355,13 +361,11 @@ class CORE_EXPORT LocalFrame final : public Frame, // Called on a view for a LocalFrame with a RemoteFrame parent. This makes // viewport intersection and occlusion/obscuration available that accounts for // remote ancestor frames and their respective scroll positions, clips, etc. - void SetViewportIntersectionFromParent(const IntRect&, bool); + void SetViewportIntersectionFromParent(const IntRect&, FrameOcclusionState); IntRect RemoteViewportIntersection() const { return remote_viewport_intersection_; } - bool MayBeOccludedOrObscuredByRemoteAncestor() const { - return occluded_or_obscured_by_ancestor_; - } + FrameOcclusionState GetOcclusionState() const; // Replaces the initial empty document with a Document suitable for // |mime_type| and populated with the contents of |data|. Only intended for @@ -384,9 +388,6 @@ class CORE_EXPORT LocalFrame final : public Frame, // preview. bool IsUsingDataSavingPreview() const; - ComputedAccessibleNode* GetOrCreateComputedAccessibleNode(AXID, - WebComputedAXTree*); - // True if AdTracker heuristics have determined that this frame is an ad. // Calculated in the constructor but LocalFrames created on behalf of OOPIF // aren't set until just before commit (ReadyToCommitNavigation time) by the @@ -433,6 +434,17 @@ class CORE_EXPORT LocalFrame final : public Frame, // To be called from OomInterventionImpl. void ForciblyPurgeV8Memory(); + void SetLifecycleState(mojom::FrameLifecycleState state); + + // For a navigation initiated from this LocalFrame with user gesture, record + // the UseCounter AdClickNavigation if this frame is an adframe. + // + // TODO(crbug.com/939370): Currently this is called in a couple of sites, + // which is fragile and prone to break. If we have the ad status in + // RemoteFrame, we could call it at FrameLoader::StartNavigation where all + // navigations go through. + void MaybeLogAdClickNavigation(); + private: friend class FrameNavigationDisabler; @@ -465,6 +477,7 @@ class CORE_EXPORT LocalFrame final : public Frame, // FrameScheduler::Delegate overrides: ukm::UkmRecorder* GetUkmRecorder() override; ukm::SourceId GetUkmSourceId() override; + void UpdateTaskTime(base::TimeDelta time) override; // Activates the user activation states of this frame and all its ancestors. void NotifyUserActivation(); @@ -478,6 +491,9 @@ class CORE_EXPORT LocalFrame final : public Frame, void SetFrameColorOverlay(SkColor color); + void PauseContext(); + void UnpauseContext(); + std::unique_ptr<FrameScheduler> frame_scheduler_; // Holds all PauseSubresourceLoadingHandles allowing either |this| to delete @@ -530,6 +546,7 @@ class CORE_EXPORT LocalFrame final : public Frame, // SmoothScrollSequencer is only populated for local roots; all local frames // use the instance owned by their local root. Member<SmoothScrollSequencer> smooth_scroll_sequencer_; + Member<ContentCaptureManager> content_capture_manager_; InterfaceRegistry* const interface_registry_; // This is declared mutable so that the service endpoint can be cached by @@ -537,13 +554,9 @@ class CORE_EXPORT LocalFrame final : public Frame, mutable mojom::blink::ReportingServiceProxyPtr reporting_service_; IntRect remote_viewport_intersection_; - bool occluded_or_obscured_by_ancestor_ = false; + FrameOcclusionState occlusion_state_ = kUnknownOcclusionState; std::unique_ptr<FrameResourceCoordinator> frame_resource_coordinator_; - // Used to keep track of which ComputedAccessibleNodes have already been - // instantiated in this frame to avoid constructing duplicates. - HeapHashMap<AXID, Member<ComputedAccessibleNode>> computed_node_mapping_; - // Per-frame URLLoader factory. std::unique_ptr<WebURLLoaderFactory> url_loader_factory_; @@ -563,6 +576,9 @@ class CORE_EXPORT LocalFrame final : public Frame, const bool is_save_data_enabled_; std::unique_ptr<FrameOverlay> frame_color_overlay_; + + mojom::FrameLifecycleState lifecycle_state_ = + mojom::FrameLifecycleState::kRunning; }; inline FrameLoader& LocalFrame::Loader() const { @@ -620,11 +636,10 @@ inline EventHandler& LocalFrame::GetEventHandler() const { return *event_handler_; } -DEFINE_TYPE_CASTS(LocalFrame, - Frame, - localFrame, - localFrame->IsLocalFrame(), - localFrame.IsLocalFrame()); +template <> +struct DowncastTraits<LocalFrame> { + static bool AllowFrom(const Frame& frame) { return frame.IsLocalFrame(); } +}; DECLARE_WEAK_IDENTIFIER_MAP(LocalFrame); diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_client.h b/chromium/third_party/blink/renderer/core/frame/local_frame_client.h index da19c0a3644..0f22851870a 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_client.h @@ -34,6 +34,7 @@ #include <memory> #include "third_party/blink/public/common/feature_policy/feature_policy.h" +#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/mojom/frame/navigation_initiator.mojom-blink.h" #include "third_party/blink/public/mojom/portal/portal.mojom-blink.h" #include "third_party/blink/public/platform/web_content_security_policy_struct.h" @@ -100,7 +101,9 @@ class ResourceResponse; class SecurityOrigin; class WebApplicationCacheHost; class WebApplicationCacheHostClient; +class WebContentCaptureClient; class WebCookieJar; +class WebDedicatedWorkerHostFactoryClient; class WebLayerTreeView; class WebLocalFrame; class WebMediaPlayer; @@ -122,6 +125,10 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { public: ~LocalFrameClient() override = default; + virtual WebContentCaptureClient* GetWebContentCaptureClient() const { + return nullptr; + } + virtual WebLocalFrame* GetWebFrame() const { return nullptr; } virtual bool HasWebView() const = 0; // mainly for assertions @@ -208,13 +215,6 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { // The frame ran content with certificate errors with the given URL. virtual void DidRunContentWithCertificateErrors() = 0; - // The frame loaded a resource with a legacy Symantec certificate that is - // slated for distrust (indicated by |did_fail| being false) or has already - // been distrusted (indicated by |did_fail| being true). Prints a console - // message (possibly overridden by the embedder) to warn about the - // certificate. - virtual void ReportLegacySymantecCert(const KURL&, bool did_fail) {} - // The frame loaded a resource with a legacy TLS version that will be removed // in the future. Prints a console message to warn about this. virtual void ReportLegacyTLSVersion(const KURL&) {} @@ -222,6 +222,9 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { // Will be called when |PerformanceTiming| events are updated virtual void DidChangePerformanceTiming() {} + // Will be called when |CpuTiming| events are updated + virtual void DidChangeCpuTiming(base::TimeDelta time) {} + // Will be called when a particular loading code path has been used. This // propogates renderer loading behavior to the browser process for histograms. virtual void DidObserveLoadingBehavior(WebLoadingBehaviorFlag) {} @@ -259,6 +262,7 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; virtual String UserAgent() = 0; + virtual blink::UserAgentMetadata UserAgentMetadata() = 0; virtual String DoNotTrackValue() = 0; @@ -386,10 +390,26 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { return nullptr; } + // Binds |js_handle| to the currently bound implementation of + // DocumentInterfaceBroker to share the same broker between C++ and JavaScript + // clients. + virtual void BindDocumentInterfaceBroker( + mojo::ScopedMessagePipeHandle js_handle) {} + virtual mojom::blink::DocumentInterfaceBroker* GetDocumentInterfaceBroker() { return nullptr; } + // Used in tests to set a custom override for DocumentInterfaceBroker methods. + // |blink_handle| is bound to the test implementation on the caller side. + // Returns the handle to the previously bound 'production' implementation, + // which will be used to forward the calls to methods that have not been + // overridden. + virtual mojo::ScopedMessagePipeHandle SetDocumentInterfaceBrokerForTesting( + mojo::ScopedMessagePipeHandle blink_handle) { + return mojo::ScopedMessagePipeHandle(); + } + virtual AssociatedInterfaceProvider* GetRemoteNavigationAssociatedInterfaces() { return nullptr; @@ -450,13 +470,29 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { const KURL&, const String&) { return false; - }; + } + + // When a plugin element is handled externally, this method is used to obtain + // a scriptable object which exposes custom API such as postMessage. + virtual v8::Local<v8::Object> GetScriptableObject(HTMLPlugInElement&, + v8::Isolate*) { + return v8::Local<v8::Object>(); + } - // Returns a new WebWorkerFetchContext for a dedicated worker or worklet. + // Returns a new WebWorkerFetchContext for a dedicated worker (in the + // non-PlzDedicatedWorker case) or worklet. virtual scoped_refptr<WebWorkerFetchContext> CreateWorkerFetchContext() { return nullptr; } + // Returns a new WebWorkerFetchContext for PlzDedicatedWorker. + // (https://crbug.com/906991) + virtual scoped_refptr<WebWorkerFetchContext> + CreateWorkerFetchContextForPlzDedicatedWorker( + WebDedicatedWorkerHostFactoryClient*) { + return nullptr; + } + virtual std::unique_ptr<WebContentSettingsClient> CreateWorkerContentSettingsClient() { return nullptr; @@ -467,6 +503,13 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { // Returns whether we are associated with a print context who suggests to use // printing layout. virtual bool UsePrintingLayout() const { return false; } + + // Called to get the FeatureState inherited from an opener if any. This works + // with disowned openers, i.e., even if Frame::Opener() is nullptr, there + // could be a non-empty feature state which is taken from the the original + // opener of the frame. This is similar to how sandbox flags are propagated to + // the opened new browsing contexts. + virtual const FeaturePolicy::FeatureState& GetOpenerFeatureState() const = 0; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc index c1aafd6c52a..a3ddc968d67 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc @@ -178,7 +178,7 @@ TEST_F(LocalFrameTest, IsUsingDataSavingPreview) { } TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWithFeatureDisabled) { - ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test(false); + ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(false); std::unique_ptr<DummyPageHolder> page_holder = DummyPageHolder::Create( IntSize(800, 600), nullptr, nullptr, &DisableDataSaverHoldbackInSettings); EXPECT_FALSE(page_holder->GetFrame().IsLazyLoadingImageAllowed()); diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc index 152ba1b4b8c..eb627f550da 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc @@ -14,7 +14,7 @@ namespace blink { LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer( - LocalFrameUkmAggregator* aggregator, + scoped_refptr<LocalFrameUkmAggregator> aggregator, size_t metric_index) : aggregator_(aggregator), metric_index_(metric_index), @@ -91,7 +91,7 @@ LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id, absolute_record.average_metric_name = metric_name; absolute_record.average_metric_name.append(".Average"); absolute_record.reset(); - auto uma_name = uma_preamble; + String uma_name = uma_preamble; uma_name.append(metric_name); uma_name.append(uma_postscript); absolute_record.uma_counter.reset( @@ -107,13 +107,13 @@ LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id, percentage_record.average_metric_name.append(".AverageRatio"); percentage_record.reset(); for (auto bucket_substring : threshold_substrings) { - String uma_name = uma_percentage_preamble; - uma_name.append(metric_name); - uma_name.append(uma_percentage_postscript); - uma_name.append(bucket_substring); + String uma_percentage_name = uma_percentage_preamble; + uma_percentage_name.append(metric_name); + uma_percentage_name.append(uma_percentage_postscript); + uma_percentage_name.append(bucket_substring); percentage_record.uma_counters_per_bucket.push_back( - std::make_unique<CustomCountHistogram>(uma_name.Utf8().data(), 0, - 10000000, 50)); + std::make_unique<CustomCountHistogram>( + uma_percentage_name.Utf8().data(), 0, 10000000, 50)); } } } diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h index 5cb8e2774b2..d03679c8d0d 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_FRAME_UKM_AGGREGATOR_H_ #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -118,7 +119,8 @@ class CustomCountHistogram; auto scoped_ukm_hierarchical_timer = \ aggregator.GetScopedTimer(static_cast<size_t>(ukm_enum)); -class CORE_EXPORT LocalFrameUkmAggregator { +class CORE_EXPORT LocalFrameUkmAggregator + : public RefCounted<LocalFrameUkmAggregator> { public: // Changing these values requires changing the names of metrics specified // below. For every metric name added here, add an entry in the @@ -132,6 +134,8 @@ class CORE_EXPORT LocalFrameUkmAggregator { kStyleAndLayout, kForcedStyleAndLayout, kScrollingCoordinator, + kHandleInputEvents, + kAnimate, kCount }; @@ -149,7 +153,9 @@ class CORE_EXPORT LocalFrameUkmAggregator { "PrePaint", "StyleAndLayout", "ForcedStyleAndLayout", - "ScrollingCoordinator"}; + "ScrollingCoordinator", + "HandleInputEvents", + "Animate"}; return *strings; } @@ -168,6 +174,8 @@ class CORE_EXPORT LocalFrameUkmAggregator { // aggregator that created the scoped timer. It will also record an event // into the histogram counter. class CORE_EXPORT ScopedUkmHierarchicalTimer { + STACK_ALLOCATED(); + public: ScopedUkmHierarchicalTimer(ScopedUkmHierarchicalTimer&&); ~ScopedUkmHierarchicalTimer(); @@ -175,9 +183,10 @@ class CORE_EXPORT LocalFrameUkmAggregator { private: friend class LocalFrameUkmAggregator; - ScopedUkmHierarchicalTimer(LocalFrameUkmAggregator*, size_t metric_index); + ScopedUkmHierarchicalTimer(scoped_refptr<LocalFrameUkmAggregator>, + size_t metric_index); - LocalFrameUkmAggregator* aggregator_; + scoped_refptr<LocalFrameUkmAggregator> aggregator_; const size_t metric_index_; const TimeTicks start_time_; @@ -202,6 +211,8 @@ class CORE_EXPORT LocalFrameUkmAggregator { void BeginMainFrame(); + bool InMainFrame() { return in_main_frame_update_; } + private: struct AbsoluteMetricRecord { String worst_case_metric_name; diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc index c2cbfe55002..8a9ffec4ff3 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc @@ -17,8 +17,8 @@ class LocalFrameUkmAggregatorTest : public testing::Test { void SetUp() override { clock_.emplace(); - aggregator_.reset(new LocalFrameUkmAggregator( - ukm::UkmRecorder::GetNewSourceID(), &recorder_)); + aggregator_ = base::MakeRefCounted<LocalFrameUkmAggregator>( + ukm::UkmRecorder::GetNewSourceID(), &recorder_); } void TearDown() override { @@ -67,7 +67,7 @@ class LocalFrameUkmAggregatorTest : public testing::Test { private: base::Optional<WTF::ScopedMockClock> clock_; - std::unique_ptr<LocalFrameUkmAggregator> aggregator_; + scoped_refptr<LocalFrameUkmAggregator> aggregator_; ukm::TestUkmRecorder recorder_; }; diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc index cb48172ae6c..cd2459665c7 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc @@ -30,17 +30,21 @@ #include <memory> #include <utility> +#include "base/feature_list.h" #include "base/memory/ptr_util.h" +#include "base/metrics/field_trial_params.h" #include "base/numerics/safe_conversions.h" +#include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/picture_layer.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_rect.h" #include "third_party/blink/public/platform/web_scroll_into_view_params.h" +#include "third_party/blink/renderer/core/accessibility/apply_dark_mode.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/animation/document_animations.h" #include "third_party/blink/renderer/core/css/font_face_set_document.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" -#include "third_party/blink/renderer/core/dom/element_visibility_observer.h" #include "third_party/blink/renderer/core/dom/static_node_list.h" #include "third_party/blink/renderer/core/editing/compute_layer_selection.h" #include "third_party/blink/renderer/core/editing/drag_caret.h" @@ -50,6 +54,7 @@ #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/frame/browser_controls.h" #include "third_party/blink/renderer/core/frame/event_handler_registry.h" +#include "third_party/blink/renderer/core/frame/find_in_page.h" #include "third_party/blink/renderer/core/frame/frame_overlay.h" #include "third_party/blink/renderer/core/frame/frame_view_auto_size_info.h" #include "third_party/blink/renderer/core/frame/link_highlights.h" @@ -76,6 +81,7 @@ #include "third_party/blink/renderer/core/input/event_handler.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/intersection_observer/intersection_observation.h" +#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h" #include "third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h" #include "third_party/blink/renderer/core/intersection_observer/intersection_observer_init.h" #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h" @@ -119,6 +125,7 @@ #include "third_party/blink/renderer/core/paint/pre_paint_tree_walk.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/resize_observer/resize_observer_controller.h" +#include "third_party/blink/renderer/core/scroll/scroll_alignment.h" #include "third_party/blink/renderer/core/scroll/scroll_animator_base.h" #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -143,7 +150,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" -#include "third_party/blink/renderer/platform/scroll/scroll_alignment.h" #include "third_party/blink/renderer/platform/transforms/transform_state.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -182,14 +188,33 @@ void LogCursorSizeCounter(LocalFrame* frame, const Cursor& cursor) { IntSize scaled_size = image->Size(); scaled_size.Scale(1 / cursor.ImageScaleFactor()); if (scaled_size.Width() > 64 || scaled_size.Height() > 64) { - UseCounter::Count(frame, WebFeature::kCursorImageGT64x64); + UseCounter::Count(frame->GetDocument(), WebFeature::kCursorImageGT64x64); } else if (scaled_size.Width() > 32 || scaled_size.Height() > 32) { - UseCounter::Count(frame, WebFeature::kCursorImageGT32x32); + UseCounter::Count(frame->GetDocument(), WebFeature::kCursorImageGT32x32); } else { - UseCounter::Count(frame, WebFeature::kCursorImageLE32x32); + UseCounter::Count(frame->GetDocument(), WebFeature::kCursorImageLE32x32); } } +// Default value and parameter name for how long we want to delay the +// compositor commit beyond the start of document lifdecycle updates to avoid +// flash between navigations. The delay should be small enough so that it won't +// confuse users expecting a new page to appear after navigation and the omnibar +// has updated the url display. +constexpr int kAvoidFlashCommitDelayDefaultInMs = 200; +constexpr char kAvoidFlashCommitDelayParameterName[] = "commit_delay"; + +// Get the field trial parameter value for AvoidFlashBetweenNavigation. +base::TimeDelta GetCommitDelayForAvoidFlashBetweenNavigation() { + DCHECK(base::FeatureList::IsEnabled( + blink::features::kAvoidFlashBetweenNavigation)); + return base::TimeDelta::FromMilliseconds( + base::GetFieldTrialParamByFeatureAsInt( + blink::features::kAvoidFlashBetweenNavigation, + kAvoidFlashCommitDelayParameterName, + kAvoidFlashCommitDelayDefaultInMs)); +} + } // namespace // The maximum number of updatePlugins iterations that should be done before @@ -285,7 +310,6 @@ LocalFrameView::~LocalFrameView() { void LocalFrameView::Trace(blink::Visitor* visitor) { visitor->Trace(frame_); - visitor->Trace(parent_); visitor->Trace(fragment_anchor_); visitor->Trace(scrollable_areas_); visitor->Trace(animating_scrollable_areas_); @@ -325,9 +349,10 @@ template <typename Function> void LocalFrameView::ForAllChildLocalFrameViews(const Function& function) { for (Frame* child = frame_->Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - if (!child->IsLocalFrame()) + auto* child_local_frame = DynamicTo<LocalFrame>(child); + if (!child_local_frame) continue; - if (LocalFrameView* child_view = ToLocalFrame(child)->View()) + if (LocalFrameView* child_view = child_local_frame->View()) function(*child_view); } } @@ -343,13 +368,21 @@ void LocalFrameView::ForAllNonThrottledLocalFrameViews( for (Frame* child = frame_->Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - if (!child->IsLocalFrame()) + auto* child_local_frame = DynamicTo<LocalFrame>(child); + if (!child_local_frame) continue; - if (LocalFrameView* child_view = ToLocalFrame(child)->View()) + if (LocalFrameView* child_view = child_local_frame->View()) child_view->ForAllNonThrottledLocalFrameViews(function); } } +void LocalFrameView::OnViewportIntersectionChanged( + const HeapVector<Member<IntersectionObserverEntry>>& entries) { + bool is_visible = entries.back()->intersectionRatio() > 0; + UpdateVisibility(is_visible); + UpdateRenderThrottlingStatus(!is_visible, subtree_throttled_); +} + void LocalFrameView::SetupRenderThrottling() { if (visibility_observer_) return; @@ -362,16 +395,12 @@ void LocalFrameView::SetupRenderThrottling() { if (!target_element) return; - visibility_observer_ = MakeGarbageCollected<ElementVisibilityObserver>( - target_element, WTF::BindRepeating( - [](LocalFrameView* frame_view, bool is_visible) { - if (!frame_view) - return; - frame_view->UpdateRenderThrottlingStatus( - !is_visible, frame_view->subtree_throttled_); - }, - WrapWeakPersistent(this))); - visibility_observer_->Start(); + visibility_observer_ = IntersectionObserver::Create( + {}, {IntersectionObserver::kMinimumThreshold}, + &target_element->GetDocument(), + WTF::BindRepeating(&LocalFrameView::OnViewportIntersectionChanged, + WrapWeakPersistent(this))); + visibility_observer_->observe(target_element); } void LocalFrameView::Dispose() { @@ -514,7 +543,7 @@ ScrollingCoordinatorContext* LocalFrameView::GetScrollingContext() const { return scrolling_context_.get(); } -CompositorAnimationHost* LocalFrameView::GetCompositorAnimationHost() const { +cc::AnimationHost* LocalFrameView::GetCompositorAnimationHost() const { if (GetScrollingContext()->GetCompositorAnimationHost()) return GetScrollingContext()->GetCompositorAnimationHost(); @@ -628,6 +657,16 @@ void LocalFrameView::PerformPreLayoutTasks() { } document->UpdateStyleAndLayoutTree(); + + // Update style for all embedded SVG documents underneath this frame, so + // that intrinsic size computation for any embedded objects has up-to-date + // information before layout. + ForAllChildLocalFrameViews([](LocalFrameView& view) { + Document& document = *view.GetFrame().GetDocument(); + if (document.IsSVGDocument()) + document.UpdateStyleAndLayoutTree(); + }); + Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean); if (was_resized) @@ -751,7 +790,7 @@ void LocalFrameView::UpdateLayout() { ScriptForbiddenScope forbid_script; if (IsInPerformLayout() || ShouldThrottleRendering() || - !frame_->GetDocument()->IsActive()) + !frame_->GetDocument()->IsActive() || frame_->IsProvisional()) return; TRACE_EVENT0("blink,benchmark", "LocalFrameView::layout"); @@ -916,7 +955,7 @@ void LocalFrameView::UpdateLayout() { // Remove or update this code. crbug.com/460596 TRACE_EVENT_END1("devtools.timeline", "Layout", "endData", inspector_layout_event::EndData(root_for_this_layout)); - probe::didChangeViewport(frame_.Get()); + probe::DidChangeViewport(frame_.Get()); nested_layout_count_--; if (nested_layout_count_) @@ -1014,6 +1053,32 @@ DocumentLifecycle& LocalFrameView::Lifecycle() const { return frame_->GetDocument()->Lifecycle(); } +void LocalFrameView::RunPostLifecycleSteps() { + RunIntersectionObserverSteps(); + UpdateThrottlingStatusForSubtree(); +} + +void LocalFrameView::RunIntersectionObserverSteps() { +#if DCHECK_IS_ON() + bool was_dirty = NeedsLayout(); +#endif + if (ShouldThrottleRendering() || Lifecycle().LifecyclePostponed() || + !frame_->GetDocument()->IsActive()) { + return; + } + TRACE_EVENT0("blink,benchmark", + "LocalFrameView::UpdateViewportIntersectionsForSubtree"); + SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(), + LocalFrameUkmAggregator::kIntersectionObservation); + bool needs_occlusion_tracking = UpdateViewportIntersectionsForSubtree(0); + if (FrameOwner* owner = frame_->Owner()) + owner->SetNeedsOcclusionTracking(needs_occlusion_tracking); +#if DCHECK_IS_ON() + DCHECK(was_dirty || !NeedsLayout()); +#endif + DeliverSynchronousIntersectionObservations(); +} + LayoutSVGRoot* LocalFrameView::EmbeddedReplacedContent() const { auto* layout_view = this->GetLayoutView(); if (!layout_view) @@ -1334,11 +1399,6 @@ bool LocalFrameView::InvalidateViewportConstrainedObjects() { } } - TRACE_EVENT_INSTANT1( - TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), - "ScrollInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", - inspector_scroll_invalidation_tracking_event::Data(*layout_object)); - // If the fixed layer has a blur/drop-shadow filter applied on at least one // of its parents, we cannot scroll using the fast path, otherwise the // outsets of the filter will be moved around the page. @@ -1349,7 +1409,19 @@ bool LocalFrameView::InvalidateViewportConstrainedObjects() { } void LocalFrameView::ProcessUrlFragment(const KURL& url, bool should_scroll) { - fragment_anchor_ = FragmentAnchor::TryCreate(url, should_scroll, *frame_); + // We want to create the anchor even if we don't need to scroll. This ensures + // all the side effects like setting CSS :target are correctly set. + FragmentAnchor* anchor = FragmentAnchor::TryCreate(url, *frame_); + + if (anchor && should_scroll) { + fragment_anchor_ = anchor; + fragment_anchor_->Installed(); + + // Layout needs to be clean for scrolling but if layout is needed, we'll + // invoke after layout is completed so no need to do it here. + if (!NeedsLayout()) + InvokeFragmentAnchor(); + } } void LocalFrameView::SetLayoutSize(const IntSize& size) { @@ -1666,8 +1738,7 @@ void LocalFrameView::UpdateBaseBackgroundColorRecursively( } void LocalFrameView::InvokeFragmentAnchor() { - FragmentAnchor* fragment_anchor = fragment_anchor_; - if (!fragment_anchor) + if (!fragment_anchor_) return; if (!fragment_anchor_->Invoke()) @@ -1806,7 +1877,7 @@ void LocalFrameView::SendResizeEventIfNeeded() { frame_->GetDocument()->EnqueueResizeEvent(); if (frame_->IsMainFrame()) - probe::didResizeMainFrame(frame_.Get()); + probe::DidResizeMainFrame(frame_.Get()); } float LocalFrameView::InputEventsScaleFactor() const { @@ -1907,8 +1978,8 @@ LocalFrameView* LocalFrameView::ParentFrameView() const { return nullptr; Frame* parent_frame = frame_->Tree().Parent(); - if (parent_frame && parent_frame->IsLocalFrame()) - return ToLocalFrame(parent_frame)->View(); + if (auto* parent_local_frame = DynamicTo<LocalFrame>(parent_frame)) + return parent_local_frame->View(); return nullptr; } @@ -1974,8 +2045,10 @@ void LocalFrameView::UpdateLifecyclePhasesForPrinting() { auto* detached_frame_view = this; while (detached_frame_view->is_attached_ && - detached_frame_view != local_frame_view_root) - detached_frame_view = detached_frame_view->parent_.Get(); + detached_frame_view != local_frame_view_root) { + detached_frame_view = detached_frame_view->ParentFrameView(); + CHECK(detached_frame_view); + } if (detached_frame_view == local_frame_view_root) return; @@ -1997,11 +2070,6 @@ bool LocalFrameView::UpdateLifecycleToLayoutClean() { DocumentLifecycle::LifecycleUpdateReason::kOther); } -void LocalFrameView::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) { - LocalFrameUkmAggregator& ukm_aggregator = EnsureUkmAggregator(); - ukm_aggregator.RecordEndOfFrameMetrics(frame_begin_time, CurrentTimeTicks()); -} - void LocalFrameView::ScheduleVisualUpdateForPaintInvalidationIfNeeded() { LocalFrame& local_frame_root = GetFrame().LocalFrameRoot(); if (local_frame_root.View()->current_update_lifecycle_phases_target_state_ < @@ -2054,8 +2122,9 @@ void LocalFrameView::DispatchEventsForPrintingOnAllFrames() { DCHECK(frame_->IsMainFrame()); for (Frame* current_frame = frame_; current_frame; current_frame = current_frame->Tree().TraverseNext(frame_)) { - if (current_frame->IsLocalFrame()) - ToLocalFrame(current_frame)->GetDocument()->DispatchEventsForPrinting(); + auto* current_local_frame = DynamicTo<LocalFrame>(current_frame); + if (current_local_frame) + current_local_frame->GetDocument()->DispatchEventsForPrinting(); } } @@ -2138,18 +2207,16 @@ bool LocalFrameView::UpdateLifecyclePhases( base::AutoReset<bool> past_layout_lifecycle_resetter( &past_layout_lifecycle_update_, false); - // If we're throttling, then we don't need to update lifecycle phases, only - // the throttling status. + // If we're throttling, then we don't need to update lifecycle phases. The + // throttling status will get updated in RunPostLifecycleSteps(). if (ShouldThrottleRendering()) { - UpdateThrottlingStatusForSubtree(); return Lifecycle().GetState() == target_state; } - if (reason == DocumentLifecycle::LifecycleUpdateReason::kBeginMainFrame) - EnsureUkmAggregator().BeginMainFrame(); - - for (auto& observer : lifecycle_observers_) - observer->WillStartLifecycleUpdate(); + ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) { + for (auto& observer : frame_view.lifecycle_observers_) + observer->WillStartLifecycleUpdate(); + }); // If we're in PrintBrowser mode, setup a print context. // TODO(vmpstr): It doesn't seem like we need to do this every lifecycle @@ -2162,19 +2229,10 @@ bool LocalFrameView::UpdateLifecyclePhases( // Run the lifecycle updates. UpdateLifecyclePhasesInternal(target_state); - // Update intersection observations if needed. - if (target_state == DocumentLifecycle::kPaintClean) { - TRACE_EVENT0("blink,benchmark", - "LocalFrameView::UpdateViewportIntersectionsForSubtree"); - SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(), - LocalFrameUkmAggregator::kIntersectionObservation); - UpdateViewportIntersectionsForSubtree(); - } - - UpdateThrottlingStatusForSubtree(); - - for (auto& observer : lifecycle_observers_) - observer->DidFinishLifecycleUpdate(); + ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) { + for (auto& observer : frame_view.lifecycle_observers_) + observer->DidFinishLifecycleUpdate(); + }); return Lifecycle().GetState() == target_state; } @@ -2410,7 +2468,8 @@ void LocalFrameView::RunPaintLifecyclePhase() { // Notify the controller that the artifact has been pushed and some // lifecycle state can be freed (such as raster invalidations). - paint_controller_->FinishCycle(); + if (paint_controller_) + paint_controller_->FinishCycle(); // PaintController for BlinkGenPropertyTrees is transient. if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() && @@ -2419,8 +2478,10 @@ void LocalFrameView::RunPaintLifecyclePhase() { // |PaintController::FinishCycle| but that will be a no-op because // the paint controller is transient, so force the changed state to be // cleared here. - paint_controller_->ClearPropertyTreeChangedStateTo( - PropertyTreeState::Root()); + if (paint_controller_) { + paint_controller_->ClearPropertyTreeChangedStateTo( + PropertyTreeState::Root()); + } auto* root = GetLayoutView()->Compositor()->PaintRootGraphicsLayer(); if (root) { ForAllGraphicsLayers(*root, [](GraphicsLayer& layer) { @@ -2464,6 +2525,18 @@ void LocalFrameView::PerformScrollAnchoringAdjustments() { static void RecordGraphicsLayerAsForeignLayer( GraphicsContext& context, const GraphicsLayer* graphics_layer) { + // Copy the first chunk's safe opaque background color over to the cc::Layer + // in the foreign layer wrapper. + if (graphics_layer->DrawsContent()) { + auto& chunks = + graphics_layer->GetPaintController().GetPaintArtifact().PaintChunks(); + SkColor safe_background_color = SK_ColorWHITE; + if (chunks.size()) { + safe_background_color = chunks[0].safe_opaque_background_color; + } + graphics_layer->CcLayer()->SetSafeOpaqueBackgroundColor( + safe_background_color); + } // TODO(trchen): Currently the GraphicsLayer hierarchy is still built during // CompositingUpdate, and we have to clear them here to ensure no extraneous // layers are still attached. In future we will disable all those layer @@ -2519,13 +2592,10 @@ static void CollectLinkHighlightLayersForLayerListRecursively( return; for (auto* highlight : layer->GetLinkHighlights()) { - DCHECK(highlight->effect()) - << "Highlight effect node should have been created in PrePaint."; - auto* highlight_layer = highlight->Layer(); auto property_tree_state = layer->GetPropertyTreeState(); - property_tree_state.SetEffect(highlight->effect()); + property_tree_state.SetEffect(highlight->Effect()); RecordForeignLayer(context, DisplayItem::kForeignLayerLinkHighlight, - highlight_layer, property_tree_state); + highlight->Layer(), property_tree_state); } for (const auto* child : layer->Children()) @@ -2562,19 +2632,16 @@ void LocalFrameView::PaintTree() { auto* web_local_frame_impl = WebLocalFrameImpl::FromFrame(frame_); bool has_dev_tools_overlays = web_local_frame_impl && web_local_frame_impl->HasDevToolsOverlays(); - if (GetLayoutView()->Layer()->NeedsRepaint() || has_dev_tools_overlays) { + if (!GetLayoutView()->Layer()->NeedsRepaint() && !has_dev_tools_overlays) { + paint_controller_->UpdateUMACountsOnFullyCached(); + } else { GraphicsContext graphics_context(*paint_controller_); if (RuntimeEnabledFeatures::PrintBrowserEnabled()) graphics_context.SetPrinting(true); if (Settings* settings = frame_->GetSettings()) { - HighContrastSettings high_contrast_settings; - high_contrast_settings.mode = settings->GetHighContrastMode(); - high_contrast_settings.grayscale = settings->GetHighContrastGrayscale(); - high_contrast_settings.contrast = settings->GetHighContrastContrast(); - high_contrast_settings.image_policy = - settings->GetHighContrastImagePolicy(); - graphics_context.SetHighContrast(high_contrast_settings); + graphics_context.SetDarkMode( + BuildDarkModeSettings(*settings, *GetLayoutView())); } PaintInternal(graphics_context, kGlobalPaintNormalPhase, @@ -2584,7 +2651,6 @@ void LocalFrameView::PaintTree() { frame_->GetPage()->GetValidationMessageClient().PaintOverlay( graphics_context); - frame_->PaintFrameColorOverlay(graphics_context); ForAllNonThrottledLocalFrameViews( [&graphics_context](LocalFrameView& view) { view.frame_->PaintFrameColorOverlay(graphics_context); @@ -2610,7 +2676,7 @@ void LocalFrameView::PaintTree() { } // TODO(sataya.m):Main frame doesn't create RootFrameViewport in some - // webkit_unit_tests (http://crbug.com/644788). + // blink_unittests (http://crbug.com/644788). if (viewport_scrollable_area_) { if (GraphicsLayer* layer_for_horizontal_scrollbar = viewport_scrollable_area_->LayerForHorizontalScrollbar()) { @@ -2633,7 +2699,6 @@ void LocalFrameView::PaintTree() { frame_->GetPage()->GetLinkHighlights().UpdateGeometry(); frame_->GetPage()->GetValidationMessageClient().PaintOverlay(); - frame_->PaintFrameColorOverlay(); ForAllNonThrottledLocalFrameViews( [](LocalFrameView& view) { view.frame_->PaintFrameColorOverlay(); }); @@ -2648,38 +2713,11 @@ void LocalFrameView::PaintTree() { frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kPaintClean); if (auto* layout_view = frame_view.GetLayoutView()) layout_view->Layer()->ClearNeedsRepaintRecursively(); + if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled()) + frame_view.GetPaintTimingDetector().NotifyPaintFinished(); }); - if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() && - !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - // BlinkGenPropertyTrees just needs a transient PaintController to - // collect the foreign layers which doesn't need caching. It also - // shouldn't affect caching status of DisplayItemClients because it's - // FinishCycle() is not synchronized with other PaintControllers. - paint_controller_ = PaintController::Create(PaintController::kTransient); - - GraphicsContext context(*paint_controller_); - // Note: Some blink unit tests run without turning on compositing which - // means we don't create viewport layers. OOPIFs also don't have their own - // viewport layers. - if (GetLayoutView()->Compositor()->InCompositingMode() && - GetFrame() == GetPage()->MainFrame()) { - // TODO(bokan): We should eventually stop creating layers for the visual - // viewport. At that point, we can remove this. However, for now, CC - // still has some dependencies on the viewport scale and scroll layers. - CollectViewportLayersForLayerList(context, - frame_->GetPage()->GetVisualViewport()); - } - // With BlinkGenPropertyTrees, |PaintRootGraphicsLayer| is the ancestor of - // all drawable layers (see: PaintLayerCompositor::PaintRootGraphicsLayer) - // so we do not need to collect scrollbars separately. - auto* root = layout_view->Compositor()->PaintRootGraphicsLayer(); - CollectDrawableLayersForLayerListRecursively(context, root); - // Link highlights paint after all other layers. - if (!frame_->GetPage()->GetLinkHighlights().IsEmpty()) - CollectLinkHighlightLayersForLayerListRecursively(context, root); - paint_controller_->CommitNewDisplayItems(); - } + PaintController::ReportUMACounts(); } const cc::Layer* LocalFrameView::RootCcLayer() const { @@ -2736,9 +2774,48 @@ void LocalFrameView::PushPaintArtifactToCompositor( settings.prefer_compositing_to_lcd_text = page->GetSettings().GetPreferCompositingToLCDTextEnabled(); + // Skip updating property trees, pushing cc::Layers, and issuing raster + // invalidations if possible. + if (!paint_artifact_compositor_->NeedsUpdate()) + return; + + if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() && + !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + // BlinkGenPropertyTrees just needs a transient PaintController to + // collect the foreign layers which doesn't need caching. It also + // shouldn't affect caching status of DisplayItemClients because it's + // FinishCycle() is not synchronized with other PaintControllers. + paint_controller_ = PaintController::Create(PaintController::kTransient); + + GraphicsContext context(*paint_controller_); + // Note: Some blink unit tests run without turning on compositing which + // means we don't create viewport layers. OOPIFs also don't have their own + // viewport layers. + if (GetLayoutView()->Compositor()->InCompositingMode() && + GetFrame() == GetPage()->MainFrame()) { + // TODO(bokan): We should eventually stop creating layers for the visual + // viewport. At that point, we can remove this. However, for now, CC + // still has some dependencies on the viewport scale and scroll layers. + CollectViewportLayersForLayerList(context, + frame_->GetPage()->GetVisualViewport()); + } + // With BlinkGenPropertyTrees, |PaintRootGraphicsLayer| is the ancestor of + // all drawable layers (see: PaintLayerCompositor::PaintRootGraphicsLayer) + // so we do not need to collect scrollbars separately. + auto* root = GetLayoutView()->Compositor()->PaintRootGraphicsLayer(); + CollectDrawableLayersForLayerListRecursively(context, root); + // Link highlights paint after all other layers. + if (!frame_->GetPage()->GetLinkHighlights().IsEmpty()) + CollectLinkHighlightLayersForLayerListRecursively(context, root); + + paint_controller_->CommitNewDisplayItems(); + } + paint_artifact_compositor_->Update( paint_controller_->GetPaintArtifactShared(), composited_element_ids, viewport_properties, settings); + + probe::LayerTreePainted(&GetFrame()); } std::unique_ptr<JSONObject> LocalFrameView::CompositedLayersAsJSON( @@ -2802,9 +2879,10 @@ void LocalFrameView::UpdateStyleAndLayoutIfNeededRecursive() { HeapVector<Member<LocalFrameView>> frame_views; for (Frame* child = frame_->Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - if (!child->IsLocalFrame()) + auto* child_local_frame = DynamicTo<LocalFrame>(child); + if (!child_local_frame) continue; - if (LocalFrameView* view = ToLocalFrame(child)->View()) + if (LocalFrameView* view = child_local_frame->View()) frame_views.push_back(view); } @@ -3198,9 +3276,10 @@ void LocalFrameView::SetTracksPaintInvalidations( for (Frame* frame = &frame_->Tree().Top(); frame; frame = frame->Tree().TraverseNext()) { - if (!frame->IsLocalFrame()) + auto* local_frame = DynamicTo<LocalFrame>(frame); + if (!local_frame) continue; - if (auto* layout_view = ToLocalFrame(frame)->ContentLayoutObject()) { + if (auto* layout_view = local_frame->ContentLayoutObject()) { layout_view->GetFrameView()->tracked_object_paint_invalidations_ = base::WrapUnique(track_paint_invalidations ? new Vector<ObjectPaintInvalidation> @@ -3315,23 +3394,16 @@ void LocalFrameView::RemoveAnimatingScrollableArea( } void LocalFrameView::AttachToLayout() { - // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. CHECK(!is_attached_); if (frame_->GetDocument()) CHECK_NE(Lifecycle().GetState(), DocumentLifecycle::kStopping); is_attached_ = true; - parent_ = ParentFrameView(); - if (!parent_) { - Frame* parent_frame = frame_->Tree().Parent(); - CHECK(parent_frame); - CHECK(parent_frame->IsLocalFrame()); - CHECK(parent_frame->View()); - } - CHECK(parent_); - if (parent_->IsVisible()) + LocalFrameView* parent_view = ParentFrameView(); + CHECK(parent_view); + if (parent_view->IsVisible()) SetParentVisible(true); SetupRenderThrottling(); - subtree_throttled_ = ParentFrameView()->CanThrottleRendering(); + subtree_throttled_ = parent_view->CanThrottleRendering(); // We may have updated paint properties in detached frame subtree for // printing (see UpdateLifecyclePhasesForPrinting()). The paint properties @@ -3343,16 +3415,7 @@ void LocalFrameView::AttachToLayout() { } void LocalFrameView::DetachFromLayout() { - // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. CHECK(is_attached_); - LocalFrameView* parent = ParentFrameView(); - if (!parent) { - Frame* parent_frame = frame_->Tree().Parent(); - CHECK(parent_frame); - CHECK(parent_frame->IsLocalFrame()); - CHECK(parent_frame->View()); - } - CHECK(parent == parent_); SetParentVisible(false); is_attached_ = false; @@ -3413,12 +3476,19 @@ void LocalFrameView::FrameRectsChanged() { SetLayoutSizeInternal(Size()); ForAllChildViewsAndPlugins([](EmbeddedContentView& embedded_content_view) { - if (!embedded_content_view.IsLocalFrameView() || - !ToLocalFrameView(embedded_content_view).ShouldThrottleRendering()) + auto* local_frame_view = DynamicTo<LocalFrameView>(embedded_content_view); + if (!local_frame_view || !local_frame_view->ShouldThrottleRendering()) embedded_content_view.FrameRectsChanged(); }); GetFrame().Client()->FrameRectsChanged(FrameRect()); + + // It's possible for changing the frame rect to not generate a layout + // or any other event tracked by accessibility, we've seen this with + // Android WebView. Ensure that the root of the accessibility tree is + // invalidated so that it gets the right bounding rect. + if (AXObjectCache* cache = ExistingAXObjectCache()) + cache->HandleFrameRectsChanged(*GetFrame().GetDocument()); } void LocalFrameView::SetLayoutSizeInternal(const IntSize& size) { @@ -3440,14 +3510,24 @@ void LocalFrameView::ClipPaintRect(FloatRect* paint_rect) const { // with CompositeAfterPaint. DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - // Paint the whole rect if "mainFrameClipsContent" is false, meaning that + // Paint the whole rect if "MainFrameClipsContent" is false, meaning that // WebPreferences::record_whole_document is true. if (!frame_->GetSettings()->GetMainFrameClipsContent()) return; - paint_rect->Intersect( - GetPage()->GetChromeClient().VisibleContentRectForPainting().value_or( - IntRect(IntPoint(), Size()))); + // By default we consider the bounds of the FrameView to be what is considered + // visible for the Frame. + IntRect visible_rect = IntRect(IntPoint(), Size()); + // Non-main frames always clip to their FrameView bounds. Main frames can + // have this behaviour modified by devtools. + if (frame_->IsMainFrame()) { + // If devtools is overriding the viewport, then the FrameView's bounds are + // not what we should paint, instead we should paint inside the bounds + // specified by devtools. + GetPage()->GetChromeClient().OverrideVisibleRectForMainFrame(*frame_, + &visible_rect); + } + paint_rect->Intersect(visible_rect); } void LocalFrameView::DidChangeScrollOffset() { @@ -3593,6 +3673,9 @@ void LocalFrameView::PaintOutsideOfLifecycle( const CullRect& cull_rect) { DCHECK(PaintOutsideOfLifecycleIsAllowed(context, *this)); + base::AutoReset<bool> past_layout_lifecycle_resetter( + &past_layout_lifecycle_update_, true); + ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) { frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPaint); }); @@ -3610,6 +3693,9 @@ void LocalFrameView::PaintContentsOutsideOfLifecycle( const CullRect& cull_rect) { DCHECK(PaintOutsideOfLifecycleIsAllowed(context, *this)); + base::AutoReset<bool> past_layout_lifecycle_resetter( + &past_layout_lifecycle_update_, true); + ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) { frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPaint); }); @@ -3801,37 +3887,56 @@ void LocalFrameView::CollectAnnotatedRegions( CollectAnnotatedRegions(*curr, regions); } -void LocalFrameView::UpdateViewportIntersectionsForSubtree() { +bool LocalFrameView::UpdateViewportIntersectionsForSubtree( + unsigned parent_flags) { // TODO(dcheng): Since LocalFrameView tree updates are deferred, FrameViews // might still be in the LocalFrameView hierarchy even though the associated // Document is already detached. Investigate if this check and a similar check // in lifecycle updates are still needed when there are no more deferred // LocalFrameView updates: https://crbug.com/561683 if (!GetFrame().GetDocument()->IsActive()) - return; + return false; + + unsigned flags = GetIntersectionObservationFlags(parent_flags); + bool needs_occlusion_tracking = false; if (!NeedsLayout()) { // Notify javascript IntersectionObservers - if (GetFrame().GetDocument()->GetIntersectionObserverController()) { - GetFrame() - .GetDocument() - ->GetIntersectionObserverController() - ->ComputeTrackedIntersectionObservations(); + if (IntersectionObserverController* controller = + GetFrame().GetDocument()->GetIntersectionObserverController()) { + needs_occlusion_tracking |= + controller->ComputeTrackedIntersectionObservations(flags); } + intersection_observation_state_ = kNotNeeded; } for (Frame* child = frame_->Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - child->View()->UpdateViewportIntersectionsForSubtree(); + needs_occlusion_tracking |= + child->View()->UpdateViewportIntersectionsForSubtree(flags); } for (HTMLPortalElement* portal : DocumentPortals::From(*frame_->GetDocument()).GetPortals()) { - if (portal->ContentFrame()) - portal->ContentFrame()->View()->UpdateViewportIntersectionsForSubtree(); + if (portal->ContentFrame()) { + needs_occlusion_tracking |= + portal->ContentFrame()->View()->UpdateViewportIntersectionsForSubtree( + flags); + } } - intersection_observation_state_ = kNotNeeded; + return needs_occlusion_tracking; +} + +void LocalFrameView::DeliverSynchronousIntersectionObservations() { + if (IntersectionObserverController* controller = + GetFrame().GetDocument()->GetIntersectionObserverController()) { + controller->DeliverIntersectionObservations( + IntersectionObserver::kDeliverDuringPostLifecycleSteps); + } + ForAllChildLocalFrameViews([](LocalFrameView& frame_view) { + frame_view.DeliverSynchronousIntersectionObservations(); + }); } void LocalFrameView::UpdateThrottlingStatusForSubtree() { @@ -3854,10 +3959,6 @@ void LocalFrameView::UpdateThrottlingStatusForSubtree() { }); } -void LocalFrameView::UpdateRenderThrottlingStatusForTesting() { - visibility_observer_->DeliverObservationsForTesting(); -} - void LocalFrameView::CrossOriginStatusChanged() { // Cross-domain status is not stored as a dirty bit within LocalFrameView, // so force-invalidate throttling status when it changes regardless of @@ -3973,10 +4074,11 @@ void LocalFrameView::SetIntersectionObservationState( void LocalFrameView::SetPaintArtifactCompositorNeedsUpdate() const { LocalFrameView* root = GetFrame().LocalFrameRoot().View(); if (root && root->paint_artifact_compositor_) - root->paint_artifact_compositor_->SetNeedsUpdate(true); + root->paint_artifact_compositor_->SetNeedsUpdate(); } -unsigned LocalFrameView::GetIntersectionObservationFlags() const { +unsigned LocalFrameView::GetIntersectionObservationFlags( + unsigned parent_flags) const { unsigned flags = 0; const LocalFrame& target_frame = GetFrame(); @@ -3989,21 +4091,15 @@ unsigned LocalFrameView::GetIntersectionObservationFlags() const { // Observers with explicit roots only need to be checked on the same frame, // since in this case target and root must be in the same document. - if (intersection_observation_state_ != kNotNeeded) - flags |= IntersectionObservation::kExplicitRootObserversNeedUpdate; + if (intersection_observation_state_ != kNotNeeded) { + flags |= (IntersectionObservation::kExplicitRootObserversNeedUpdate | + IntersectionObservation::kImplicitRootObserversNeedUpdate); + } // For observers with implicit roots, we need to check state on the whole - // local frame tree. - const LocalFrameView* local_root_view = target_frame.LocalFrameRoot().View(); - for (const LocalFrameView* view = this; view; - view = view->ParentFrameView()) { - if (view->intersection_observation_state_ != kNotNeeded) { - flags |= IntersectionObservation::kImplicitRootObserversNeedUpdate; - break; - } - if (view == local_root_view) - break; - } + // local frame tree, as passed down from the parent. + flags |= (parent_flags & + IntersectionObservation::kImplicitRootObserversNeedUpdate); return flags; } @@ -4055,10 +4151,32 @@ void LocalFrameView::BeginLifecycleUpdates() { SetupRenderThrottling(); UpdateRenderThrottlingStatus(hidden_for_throttling_, subtree_throttled_); + // The compositor will "defer commits" for the main frame until we // explicitly request them. - if (GetFrame().IsMainFrame()) - GetFrame().GetPage()->GetChromeClient().BeginLifecycleUpdates(); + if (!GetFrame().IsMainFrame()) + return; + + // Determine if we want to defer commits to the compositor once lifecycle + // updates start. Doing so allows us to update the page lifecycle but not + // present the results to screen until we see first contentful paint is + // available or until a timer expires. + // This is enabled only if kAvoidFlashBetweenNavigation is enabled, and + // the document loading is a regular HTML served over HTTP/HTTPs. + Document* document = GetFrame().GetDocument(); + if (base::FeatureList::IsEnabled( + blink::features::kAvoidFlashBetweenNavigation) && + document && document->Url().ProtocolIsInHTTPFamily() && + document->IsHTMLDocument()) { + GetFrame().GetPage()->GetChromeClient().StartDeferringCommits( + GetCommitDelayForAvoidFlashBetweenNavigation()); + } + GetFrame().GetPage()->GetChromeClient().BeginLifecycleUpdates(); +} + +void LocalFrameView::StopDeferringCommits() { + if (GetFrame().GetPage()) + GetFrame().GetPage()->GetChromeClient().StopDeferringCommits(); } void LocalFrameView::SetInitialViewportSize(const IntSize& viewport_size) { @@ -4099,12 +4217,13 @@ void LocalFrameView::UpdateSubFrameScrollOnMainReason( MainThreadScrollingReasons reasons = parent_reason; if (!GetPage()->GetSettings().GetThreadedScrollingEnabled()) - reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; + reasons |= cc::MainThreadScrollingReason::kThreadedScrollingDisabled; - if (!frame.IsLocalFrame()) + auto* local_frame = DynamicTo<LocalFrame>(&frame); + if (!local_frame) return; - LocalFrameView& frame_view = *ToLocalFrame(frame).View(); + LocalFrameView& frame_view = *local_frame->View(); if (frame_view.ShouldThrottleRendering()) return; @@ -4113,7 +4232,7 @@ void LocalFrameView::UpdateSubFrameScrollOnMainReason( reasons |= frame_view.MainThreadScrollingReasonsPerFrame(); if (GraphicsLayer* layer_for_scrolling = - ToLocalFrame(frame).View()->LayoutViewport()->LayerForScrolling()) { + local_frame->View()->LayoutViewport()->LayerForScrolling()) { if (cc::Layer* platform_layer_for_scrolling = layer_for_scrolling->CcLayer()) { if (reasons) { @@ -4122,7 +4241,7 @@ void LocalFrameView::UpdateSubFrameScrollOnMainReason( // Clear all main thread scrolling reasons except the one that's set // if there is a running scroll animation. platform_layer_for_scrolling->ClearMainThreadScrollingReasons( - ~MainThreadScrollingReason::kHandlingScrollFromMainThread); + ~cc::MainThreadScrollingReason::kHandlingScrollFromMainThread); } } } @@ -4135,7 +4254,7 @@ void LocalFrameView::UpdateSubFrameScrollOnMainReason( if (frame.IsMainFrame()) main_thread_scrolling_reasons_ = reasons; - DCHECK(!MainThreadScrollingReason::HasNonCompositedScrollReasons( + DCHECK(!cc::MainThreadScrollingReason::HasNonCompositedScrollReasons( main_thread_scrolling_reasons_)); } @@ -4147,8 +4266,10 @@ MainThreadScrollingReasons LocalFrameView::MainThreadScrollingReasonsPerFrame() if (ShouldThrottleRendering()) return reasons; - if (HasBackgroundAttachmentFixedObjects()) - reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; + if (HasBackgroundAttachmentFixedObjects()) { + reasons |= + cc::MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; + } // Force main-thread scrolling if the frame has uncomposited position: fixed // elements. Note: we care about this not only for input-scrollable frames @@ -4159,7 +4280,7 @@ MainThreadScrollingReasons LocalFrameView::MainThreadScrollingReasonsPerFrame() GetLayoutView()->StyleRef().VisibleToHitTesting() && HasVisibleSlowRepaintViewportConstrainedObjects()) { reasons |= - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects; + cc::MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects; } return reasons; } @@ -4170,7 +4291,7 @@ MainThreadScrollingReasons LocalFrameView::GetMainThreadScrollingReasons() static_cast<MainThreadScrollingReasons>(0); if (!GetPage()->GetSettings().GetThreadedScrollingEnabled()) - reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; + reasons |= cc::MainThreadScrollingReason::kThreadedScrollingDisabled; if (!GetPage()->MainFrame()->IsLocalFrame()) return reasons; @@ -4186,13 +4307,14 @@ MainThreadScrollingReasons LocalFrameView::GetMainThreadScrollingReasons() // whether the target frame should be scrolled on main thread regardless // other subframes on the same page. for (Frame* frame = frame_; frame; frame = frame->Tree().Parent()) { - if (!frame->IsLocalFrame()) + auto* local_frame = DynamicTo<LocalFrame>(frame); + if (!local_frame) continue; - reasons |= - ToLocalFrame(frame)->View()->MainThreadScrollingReasonsPerFrame(); + reasons |= local_frame->View()->MainThreadScrollingReasonsPerFrame(); } - DCHECK(!MainThreadScrollingReason::HasNonCompositedScrollReasons(reasons)); + DCHECK( + !cc::MainThreadScrollingReason::HasNonCompositedScrollReasons(reasons)); return reasons; } @@ -4215,7 +4337,7 @@ String LocalFrameView::MainThreadScrollingReasonsAsText() { } } - return String(MainThreadScrollingReason::AsText(reasons).c_str()); + return String(cc::MainThreadScrollingReason::AsText(reasons).c_str()); } bool LocalFrameView::MapToVisualRectInTopFrameSpace(LayoutRect& rect) { @@ -4250,9 +4372,9 @@ LayoutUnit LocalFrameView::CaretWidth() const { LocalFrameUkmAggregator& LocalFrameView::EnsureUkmAggregator() { if (!ukm_aggregator_) { - ukm_aggregator_.reset( - new LocalFrameUkmAggregator(frame_->GetDocument()->UkmSourceID(), - frame_->GetDocument()->UkmRecorder())); + ukm_aggregator_ = base::MakeRefCounted<LocalFrameUkmAggregator>( + frame_->GetDocument()->UkmSourceID(), + frame_->GetDocument()->UkmRecorder()); } return *ukm_aggregator_; } @@ -4267,4 +4389,21 @@ void LocalFrameView::UnregisterFromLifecycleNotifications( lifecycle_observers_.erase(observer); } +void LocalFrameView::UpdateVisibility(bool is_visible) { + blink::mojom::FrameVisibility visibility; + if (!is_attached_) { + visibility = blink::mojom::FrameVisibility::kNotRendered; + } else if (!is_visible) { + visibility = blink::mojom::FrameVisibility::kRenderedOutOfViewport; + } else { + visibility = blink::mojom::FrameVisibility::kRenderedInViewport; + } + if (visibility_ == visibility) + return; + visibility_ = visibility; + if (auto* client = GetFrame().Client()) { + client->VisibilityChanged(visibility); + } +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_view.h b/chromium/third_party/blink/renderer/core/frame/local_frame_view.h index fb5bd13d66a..572188420ed 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_view.h @@ -30,6 +30,7 @@ #include <utility> #include "third_party/blink/public/common/manifest/web_display_mode.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/public/platform/shape_properties.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/frame_view.h" @@ -46,27 +47,29 @@ #include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h" #include "third_party/blink/renderer/platform/graphics/subtree_paint_property_update_reason.h" #include "third_party/blink/renderer/platform/timer.h" +#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/skia/include/core/SkColor.h" namespace cc { +class AnimationHost; class Layer; } namespace blink { - class AXObjectCache; class ChromeClient; -class CompositorAnimationHost; class CompositorAnimationTimeline; class Cursor; class DisplayItemClient; class DocumentLifecycle; -class ElementVisibilityObserver; class FloatRect; class FloatSize; class FragmentAnchor; class Frame; class FrameViewAutoSizeInfo; +class IntersectionObserver; +class IntersectionObserverEntry; class JSONObject; class JankTracker; class KURL; @@ -216,7 +219,7 @@ class CORE_EXPORT LocalFrameView final // Get the InstersectionObservation::ComputeFlags for target elements in this // view. - unsigned GetIntersectionObservationFlags() const; + unsigned GetIntersectionObservationFlags(unsigned parent_flags) const; void SetPaintArtifactCompositorNeedsUpdate() const; @@ -369,8 +372,11 @@ class CORE_EXPORT LocalFrameView final // desired state. bool UpdateLifecycleToLayoutClean(); - // Record any UMA and UKM metrics that depend on the end of a main frame. - void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time); + // This for doing work that needs to run synchronously at the end of lifecyle + // updates, but needs to happen outside of the lifecycle code. It's OK to + // schedule another animation frame here, but the layout tree should not be + // invalidated. + void RunPostLifecycleSteps(); void ScheduleVisualUpdateForPaintInvalidationIfNeeded(); @@ -599,10 +605,6 @@ class CORE_EXPORT LocalFrameView final bool IsHiddenForThrottling() const { return hidden_for_throttling_; } void SetupRenderThrottling(); - // For testing, run pending intersection observer notifications for this - // frame. - void UpdateRenderThrottlingStatusForTesting(); - void BeginLifecycleUpdates(); // Shorthands of LayoutView's corresponding methods. @@ -656,7 +658,7 @@ class CORE_EXPORT LocalFrameView final LayoutUnit CaretWidth() const; - size_t PaintFrameCount() const { return paint_frame_count_; }; + size_t PaintFrameCount() const { return paint_frame_count_; } // Return the ScrollableArea in a FrameView with the given ElementId, if any. // This is not recursive and will only return ScrollableAreas owned by this @@ -698,7 +700,7 @@ class CORE_EXPORT LocalFrameView final void ScrollableAreasDidChange(); ScrollingCoordinatorContext* GetScrollingContext() const; - CompositorAnimationHost* GetCompositorAnimationHost() const; + cc::AnimationHost* GetCompositorAnimationHost() const; CompositorAnimationTimeline* GetCompositorAnimationTimeline() const; JankTracker& GetJankTracker() { return *jank_tracker_; } @@ -727,6 +729,8 @@ class CORE_EXPORT LocalFrameView final private: #if DCHECK_IS_ON() class DisallowLayoutInvalidationScope { + STACK_ALLOCATED(); + public: DisallowLayoutInvalidationScope(LocalFrameView* view) : local_frame_view_(view) { @@ -771,6 +775,8 @@ class CORE_EXPORT LocalFrameView final void SetupPrintContext(); void ClearPrintContext(); + void StopDeferringCommits(); + // Returns whether the lifecycle was succesfully updated to the // target state. bool UpdateLifecyclePhases(DocumentLifecycle::LifecycleState target_state, @@ -795,6 +801,8 @@ class CORE_EXPORT LocalFrameView final void PrePaint(); void PaintTree(); void UpdateStyleAndLayoutIfNeededRecursive(); + void OnViewportIntersectionChanged( + const HeapVector<Member<IntersectionObserverEntry>>& entries); void PushPaintArtifactToCompositor( CompositorElementIdSet& composited_element_ids); @@ -807,6 +815,8 @@ class CORE_EXPORT LocalFrameView final DocumentLifecycle& Lifecycle() const; + void RunIntersectionObserverSteps(); + // Methods to do point conversion via layoutObjects, in order to take // transforms into account. IntRect ConvertToContainingEmbeddedContentView(const IntRect&) const; @@ -854,7 +864,9 @@ class CORE_EXPORT LocalFrameView final template <typename Function> void ForAllNonThrottledLocalFrameViews(const Function&); - void UpdateViewportIntersectionsForSubtree() override; + bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override; + void DeliverSynchronousIntersectionObservations(); + void UpdateThrottlingStatusForSubtree(); void NotifyResizeObservers(); @@ -865,18 +877,21 @@ class CORE_EXPORT LocalFrameView final void LayoutFromRootObject(LayoutObject& root); + void UpdateVisibility(bool is_visible); + LayoutSize size_; typedef HashSet<scoped_refptr<LayoutEmbeddedObject>> EmbeddedObjectSet; EmbeddedObjectSet part_update_set_; Member<LocalFrame> frame_; - Member<LocalFrameView> parent_; IntRect frame_rect_; bool is_attached_; bool self_visible_; bool parent_visible_; + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; WebDisplayMode display_mode_; @@ -977,7 +992,7 @@ class CORE_EXPORT LocalFrameView final bool needs_focus_on_fragment_; - Member<ElementVisibilityObserver> visibility_observer_; + Member<IntersectionObserver> visibility_observer_; IntRect remote_viewport_intersection_; @@ -1001,7 +1016,7 @@ class CORE_EXPORT LocalFrameView final MainThreadScrollingReasons main_thread_scrolling_reasons_; - std::unique_ptr<LocalFrameUkmAggregator> ukm_aggregator_; + scoped_refptr<LocalFrameUkmAggregator> ukm_aggregator_; unsigned forced_layout_stack_depth_; TimeTicks forced_layout_start_time_; @@ -1062,11 +1077,12 @@ inline std::ostream& operator<<( return os << info.name << " reason=" << info.reason; } -DEFINE_TYPE_CASTS(LocalFrameView, - EmbeddedContentView, - embedded_content_view, - embedded_content_view->IsLocalFrameView(), - embedded_content_view.IsLocalFrameView()); +template <> +struct DowncastTraits<LocalFrameView> { + static bool AllowFrom(const EmbeddedContentView& embedded_content_view) { + return embedded_content_view.IsLocalFrameView(); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc index 028a3b7a84a..eec11905ac5 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc @@ -329,5 +329,30 @@ TEST_F(LocalFrameViewSimTest, FragmentNavChangesFocusWhileRenderingBlocked) { << "Scroll offset wasn't changed after load completed."; } +TEST_F(LocalFrameViewSimTest, ForcedLayoutWithIncompleteSVGChildFrame) { + SimRequest main_resource("https://example.com/test.html", "text/html"); + SimRequest svg_resource("https://example.com/file.svg", "image/svg+xml"); + + LoadURL("https://example.com/test.html"); + + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <object data="file.svg"></object> + )HTML"); + + // Write the SVG document so that there is something to layout, but don't let + // the resource finish loading. + svg_resource.Write(R"SVG( + <svg xmlns="http://www.w3.org/2000/svg"></svg> + )SVG"); + + // Mark the top-level document for layout and then force layout. This will + // cause the layout tree in the <object> object to be built. + GetDocument().View()->SetNeedsLayout(); + GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); + + svg_resource.Finish(); +} + } // namespace } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/location.cc b/chromium/third_party/blink/renderer/core/frame/location.cc index 24cb53f3652..fb8f1fd0c61 100644 --- a/chromium/third_party/blink/renderer/core/frame/location.cc +++ b/chromium/third_party/blink/renderer/core/frame/location.cc @@ -246,7 +246,7 @@ void Location::reload() { return; // reload() is not cross-origin accessible, so |dom_window_| will always be // local. - ToLocalDOMWindow(dom_window_) + To<LocalDOMWindow>(dom_window_.Get()) ->GetFrame() ->Reload(WebFrameLoadType::kReload, ClientRedirectPolicy::kClientRedirect); @@ -291,17 +291,19 @@ void Location::SetLocation(const String& url, return; // Check the source browsing context's CSP to fulfill the CSP check - // requirement of https://html.spec.whatwg.org/#navigate for javascript URLs. - // Although the spec states we should perform this check on task execution, - // we do this prior to dispatch since the parent frame's CSP may be + // requirement of https://html.spec.whatwg.org/C/#navigate for javascript + // URLs. Although the spec states we should perform this check on task + // execution, we do this prior to dispatch since the parent frame's CSP may be // inaccessible if the target frame is out of process. Document* current_document = current_window->document(); if (current_document && completed_url.ProtocolIsJavaScript() && !ContentSecurityPolicy::ShouldBypassMainWorld(current_document)) { String script_source = DecodeURLEscapeSequences( completed_url.GetString(), DecodeURLMode::kUTF8OrIsomorphic); - if (!current_document->GetContentSecurityPolicy()->AllowJavaScriptURLs( - nullptr, script_source, current_document->Url(), OrdinalNumber())) { + if (!current_document->GetContentSecurityPolicy()->AllowInline( + ContentSecurityPolicy::InlineType::kJavaScriptURL, + nullptr /* element */, script_source, String() /* nonce */, + current_document->Url(), OrdinalNumber())) { return; } } @@ -319,13 +321,15 @@ void Location::SetLocation(const String& url, WebFrameLoadType frame_load_type = WebFrameLoadType::kStandard; if (set_location_policy == SetLocationPolicy::kReplaceThisFrame) frame_load_type = WebFrameLoadType::kReplaceCurrentItem; + + current_window->GetFrame()->MaybeLogAdClickNavigation(); dom_window_->GetFrame()->ScheduleNavigation(*current_window->document(), completed_url, frame_load_type, UserGestureStatus::kNone); } Document* Location::GetDocument() const { - return ToLocalDOMWindow(dom_window_)->document(); + return To<LocalDOMWindow>(dom_window_.Get())->document(); } bool Location::IsAttached() const { diff --git a/chromium/third_party/blink/renderer/core/frame/location.idl b/chromium/third_party/blink/renderer/core/frame/location.idl index ba5f5683496..ea47333ddb7 100644 --- a/chromium/third_party/blink/renderer/core/frame/location.idl +++ b/chromium/third_party/blink/renderer/core/frame/location.idl @@ -39,7 +39,7 @@ // *existing* document at a different origin. // However, *reading* |href|, or accessing any component, is a security // problem, since that allows tracking navigation. - // https://html.spec.whatwg.org/multipage/browsers.html#crossoriginproperties-(-o-) + // https://html.spec.whatwg.org/C/#crossoriginproperties-(-o-) [CallWith=Isolate, CrossOrigin, RaisesException, Unforgeable] void replace(URLString url); [Unforgeable] void reload(); diff --git a/chromium/third_party/blink/renderer/core/frame/mhtml_archive_test.cc b/chromium/third_party/blink/renderer/core/frame/mhtml_archive_test.cc index 82125009a35..03adaecb24c 100644 --- a/chromium/third_party/blink/renderer/core/frame/mhtml_archive_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/mhtml_archive_test.cc @@ -36,7 +36,7 @@ #include "third_party/blink/renderer/platform/date_components.h" #include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h" #include "third_party/blink/renderer/platform/mhtml/mhtml_parser.h" -#include "third_party/blink/renderer/platform/serialized_resource.h" +#include "third_party/blink/renderer/platform/mhtml/serialized_resource.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -45,8 +45,8 @@ #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "third_party/blink/renderer/platform/wtf/time.h" +using blink::mojom::MHTMLLoadResult; using blink::url_test_helpers::ToKURL; -using LoadResult = blink::MHTMLArchive::LoadResult; namespace blink { namespace test { @@ -184,20 +184,19 @@ class MHTMLArchiveTest : public testing::Test { void CheckLoadResult(const KURL url, scoped_refptr<const SharedBuffer> data, - LoadResult expected_result) { + MHTMLLoadResult expected_result) { // Set up histogram testing (takes snapshot of histogram data). base::HistogramTester histogram_tester; // Attempt loading the archive and check the returned pointer. MHTMLArchive* archive = MHTMLArchive::Create(url, data); - if (expected_result == LoadResult::kSuccess) - EXPECT_NE(nullptr, archive); - else - EXPECT_EQ(nullptr, archive); + ASSERT_TRUE(archive); + + EXPECT_EQ(archive->LoadResult(), expected_result); // Check that the correct count, and only the correct count, increased. - histogram_tester.ExpectUniqueSample(MHTMLArchive::kLoadResultUmaName, - expected_result, 1); + histogram_tester.ExpectUniqueSample( + "PageSerialization.MhtmlLoading.LoadResult", expected_result, 1); } private: @@ -356,26 +355,26 @@ TEST_F(MHTMLArchiveTest, MHTMLFromScheme) { scoped_refptr<SharedBuffer> data = SharedBuffer::Create(mhtml_data().data(), mhtml_data().size()); - KURL http_url = ToKURL("http://www.example.com"); - KURL content_url = ToKURL("content://foo"); - KURL file_url = ToKURL("file://foo"); - KURL special_scheme_url = ToKURL("fooscheme://bar"); // MHTMLArchives can only be initialized from local schemes, http/https // schemes, and content scheme(Android specific). - CheckLoadResult(http_url, data.get(), LoadResult::kSuccess); + CheckLoadResult(ToKURL("http://www.example.com"), data.get(), + MHTMLLoadResult::kSuccess); #if defined(OS_ANDROID) - CheckLoadResult(content_url, data.get(), LoadResult::kSuccess); + CheckLoadResult(ToKURL("content://foo"), data.get(), + MHTMLLoadResult::kSuccess); #else - CheckLoadResult(content_url, data.get(), LoadResult::kUrlSchemeNotAllowed); + CheckLoadResult(ToKURL("content://foo"), data.get(), + MHTMLLoadResult::kUrlSchemeNotAllowed); #endif - CheckLoadResult(file_url, data.get(), LoadResult::kSuccess); - CheckLoadResult(special_scheme_url, data.get(), - LoadResult::kUrlSchemeNotAllowed); + CheckLoadResult(ToKURL("file://foo"), data.get(), MHTMLLoadResult::kSuccess); + CheckLoadResult(ToKURL("fooscheme://bar"), data.get(), + MHTMLLoadResult::kUrlSchemeNotAllowed); SchemeRegistry::RegisterURLSchemeAsLocal("fooscheme"); - CheckLoadResult(special_scheme_url, data.get(), LoadResult::kSuccess); + CheckLoadResult(ToKURL("fooscheme://bar"), data.get(), + MHTMLLoadResult::kSuccess); } TEST_F(MHTMLArchiveTest, MHTMLDate) { @@ -402,13 +401,13 @@ TEST_F(MHTMLArchiveTest, MHTMLDate) { TEST_F(MHTMLArchiveTest, EmptyArchive) { // Test failure to load when |data| is null. KURL http_url = ToKURL("http://www.example.com"); - CheckLoadResult(http_url, nullptr, LoadResult::kEmptyFile); + CheckLoadResult(http_url, nullptr, MHTMLLoadResult::kEmptyFile); // Test failure to load when |data| is non-null but empty. const char* buf = ""; scoped_refptr<SharedBuffer> data = SharedBuffer::Create(buf, static_cast<size_t>(0u)); - CheckLoadResult(http_url, data.get(), LoadResult::kEmptyFile); + CheckLoadResult(http_url, data.get(), MHTMLLoadResult::kEmptyFile); } TEST_F(MHTMLArchiveTest, NoMainResource) { @@ -424,7 +423,7 @@ TEST_F(MHTMLArchiveTest, NoMainResource) { SharedBuffer::Create(mhtml_data().data(), mhtml_data().size()); KURL http_url = ToKURL("http://www.example.com"); - CheckLoadResult(http_url, data.get(), LoadResult::kMissingMainResource); + CheckLoadResult(http_url, data.get(), MHTMLLoadResult::kMissingMainResource); } TEST_F(MHTMLArchiveTest, InvalidMHTML) { @@ -437,7 +436,7 @@ TEST_F(MHTMLArchiveTest, InvalidMHTML) { scoped_refptr<SharedBuffer> data = SharedBuffer::Create(mhtml_data().data(), mhtml_data().size()); - CheckLoadResult(ToKURL(kURL), data.get(), LoadResult::kInvalidArchive); + CheckLoadResult(ToKURL(kURL), data.get(), MHTMLLoadResult::kInvalidArchive); } } // namespace test diff --git a/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc b/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc index 65dd524db54..366c16105ad 100644 --- a/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc @@ -32,7 +32,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.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/core/dom/class_collection.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -44,6 +43,7 @@ #include "third_party/blink/renderer/core/frame/location.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" @@ -62,22 +62,22 @@ class MHTMLLoadingTest : public testing::Test { protected: void SetUp() override { helper_.Initialize(); } - void TearDown() override { - platform_->GetURLLoaderMockFactory() - ->UnregisterAllURLsAndClearMemoryCache(); - } - - void RegisterMockedURLLoad(const std::string& url, - const std::string& file_name) { - url_test_helpers::RegisterMockedURLLoad( - ToKURL(url), - test::CoreTestDataPath(WebString::FromUTF8("mhtml/" + file_name)), - WebString::FromUTF8("multipart/related")); - } - - void LoadURLInTopFrame(const WebURL& url) { - frame_test_helpers::LoadFrame(helper_.GetWebView()->MainFrameImpl(), - url.GetString().Utf8().data()); + void LoadURLInTopFrame(const WebURL& url, const std::string& file_name) { + scoped_refptr<SharedBuffer> buffer = test::ReadFromFile( + test::CoreTestDataPath(WebString::FromUTF8("mhtml/" + file_name))); + WebLocalFrameImpl* frame = helper_.GetWebView()->MainFrameImpl(); + auto params = std::make_unique<WebNavigationParams>(); + params->url = url; + params->response = WebURLResponse(url); + params->response.SetMIMEType("multipart/related"); + params->response.SetHttpStatusCode(200); + params->response.SetExpectedContentLength(buffer->size()); + auto body_loader = std::make_unique<StaticDataNavigationBodyLoader>(); + body_loader->Write(*buffer); + body_loader->Finish(); + params->body_loader = std::move(body_loader); + frame->CommitNavigation(std::move(params), nullptr /* extra_data */); + frame_test_helpers::PumpPendingRequestsForFrameToLoad(frame); } Page* GetPage() const { return helper_.GetWebView()->GetPage(); } @@ -92,12 +92,9 @@ class MHTMLLoadingTest : public testing::Test { TEST_F(MHTMLLoadingTest, CheckDomain) { const char kFileURL[] = "file:///simple_test.mht"; - // Register the mocked frame and load it. - WebURL url = ToKURL(kFileURL); - RegisterMockedURLLoad(kFileURL, "simple_test.mht"); - LoadURLInTopFrame(url); + LoadURLInTopFrame(ToKURL(kFileURL), "simple_test.mht"); ASSERT_TRUE(GetPage()); - LocalFrame* frame = ToLocalFrame(GetPage()->MainFrame()); + LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame()); ASSERT_TRUE(frame); Document* document = frame->GetDocument(); ASSERT_TRUE(document); @@ -113,11 +110,9 @@ TEST_F(MHTMLLoadingTest, CheckDomain) { TEST_F(MHTMLLoadingTest, EnforceSandboxFlags) { const char kURL[] = "http://www.example.com"; - // Register the mocked frame and load it. - RegisterMockedURLLoad(kURL, "page_with_javascript.mht"); - LoadURLInTopFrame(ToKURL(kURL)); + LoadURLInTopFrame(ToKURL(kURL), "page_with_javascript.mht"); ASSERT_TRUE(GetPage()); - LocalFrame* frame = ToLocalFrame(GetPage()->MainFrame()); + LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame()); ASSERT_TRUE(frame); Document* document = frame->GetDocument(); ASSERT_TRUE(document); @@ -138,7 +133,7 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlags) { // Make sure the subframe is also sandboxed. LocalFrame* child_frame = - ToLocalFrame(GetPage()->MainFrame()->Tree().FirstChild()); + To<LocalFrame>(GetPage()->MainFrame()->Tree().FirstChild()); ASSERT_TRUE(child_frame); Document* child_document = child_frame->GetDocument(); ASSERT_TRUE(child_document); @@ -159,11 +154,9 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlags) { TEST_F(MHTMLLoadingTest, EnforceSandboxFlagsInXSLT) { const char kURL[] = "http://www.example.com"; - // Register the mocked frame and load it. - RegisterMockedURLLoad(kURL, "xslt.mht"); - LoadURLInTopFrame(ToKURL(kURL)); + LoadURLInTopFrame(ToKURL(kURL), "xslt.mht"); ASSERT_TRUE(GetPage()); - LocalFrame* frame = ToLocalFrame(GetPage()->MainFrame()); + LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame()); ASSERT_TRUE(frame); Document* document = frame->GetDocument(); ASSERT_TRUE(document); @@ -183,11 +176,9 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlagsInXSLT) { TEST_F(MHTMLLoadingTest, ShadowDom) { const char kURL[] = "http://www.example.com"; - // Register the mocked frame and load it. - RegisterMockedURLLoad(kURL, "shadow.mht"); - LoadURLInTopFrame(ToKURL(kURL)); + LoadURLInTopFrame(ToKURL(kURL), "shadow.mht"); ASSERT_TRUE(GetPage()); - LocalFrame* frame = ToLocalFrame(GetPage()->MainFrame()); + LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame()); ASSERT_TRUE(frame); Document* document = frame->GetDocument(); ASSERT_TRUE(document); @@ -211,11 +202,9 @@ TEST_F(MHTMLLoadingTest, ShadowDom) { TEST_F(MHTMLLoadingTest, FormControlElements) { const char kURL[] = "http://www.example.com"; - // Register the mocked frame and load it. - RegisterMockedURLLoad(kURL, "form.mht"); - LoadURLInTopFrame(ToKURL(kURL)); + LoadURLInTopFrame(ToKURL(kURL), "form.mht"); ASSERT_TRUE(GetPage()); - LocalFrame* frame = ToLocalFrame(GetPage()->MainFrame()); + LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame()); ASSERT_TRUE(frame); Document* document = frame->GetDocument(); ASSERT_TRUE(document); @@ -232,11 +221,9 @@ TEST_F(MHTMLLoadingTest, FormControlElements) { TEST_F(MHTMLLoadingTest, LoadMHTMLContainingSoftLineBreaks) { const char kURL[] = "http://www.example.com"; - // Register the mocked frame and load it. - RegisterMockedURLLoad(kURL, "soft_line_break.mht"); - LoadURLInTopFrame(ToKURL(kURL)); + LoadURLInTopFrame(ToKURL(kURL), "soft_line_break.mht"); ASSERT_TRUE(GetPage()); - LocalFrame* frame = ToLocalFrame(GetPage()->MainFrame()); + LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame()); ASSERT_TRUE(frame); // We should not have problem to concatenate header lines separated by soft // line breaks. diff --git a/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc b/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc index 625602adde2..84b2de15210 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc +++ b/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc @@ -47,9 +47,9 @@ bool NavigationRateLimiter::CanProceed() { // the browser process with the FrameHostMsg_DidAddMessageToConsole IPC. if (!error_message_sent_) { error_message_sent_ = true; - if (frame_->IsLocalFrame()) { - ToLocalFrame(frame_)->Console().AddMessage(ConsoleMessage::Create( - kJSMessageSource, kWarningMessageLevel, + if (auto* local_frame = DynamicTo<LocalFrame>(frame_.Get())) { + local_frame->Console().AddMessage(ConsoleMessage::Create( + kJSMessageSource, mojom::ConsoleMessageLevel::kWarning, "Throttling navigation to prevent the browser from hanging. See " "https://crbug.com/882238. Command line switch " "--disable-ipc-flooding-protection can be used to bypass the " diff --git a/chromium/third_party/blink/renderer/core/frame/navigator.cc b/chromium/third_party/blink/renderer/core/frame/navigator.cc index 2d22c0bea63..71b32975210 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator.cc +++ b/chromium/third_party/blink/renderer/core/frame/navigator.cc @@ -23,6 +23,7 @@ #include "third_party/blink/renderer/core/frame/navigator.h" +#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -33,7 +34,7 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/language.h" -#include "third_party/blink/renderer/platform/memory_coordinator.h" +#include "third_party/blink/renderer/platform/memory_pressure_listener.h" namespace blink { @@ -72,6 +73,14 @@ String Navigator::userAgent() const { return GetFrame()->Loader().UserAgent(); } +UserAgentMetadata Navigator::GetUserAgentMetadata() const { + // If the frame is already detached it no longer has a meaningful useragent. + if (!GetFrame() || !GetFrame()->GetPage()) + return blink::UserAgentMetadata(); + + return GetFrame()->Loader().UserAgentMetadata(); +} + bool Navigator::cookieEnabled() const { if (!GetFrame()) return false; diff --git a/chromium/third_party/blink/renderer/core/frame/navigator.h b/chromium/third_party/blink/renderer/core/frame/navigator.h index 302f29d2511..16ed6e3e980 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator.h +++ b/chromium/third_party/blink/renderer/core/frame/navigator.h @@ -20,13 +20,15 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_H_ +#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/frame/navigator_concurrent_hardware.h" #include "third_party/blink/renderer/core/frame/navigator_device_memory.h" #include "third_party/blink/renderer/core/frame/navigator_id.h" #include "third_party/blink/renderer/core/frame/navigator_language.h" #include "third_party/blink/renderer/core/frame/navigator_on_line.h" +#include "third_party/blink/renderer/core/frame/navigator_user_agent.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -42,6 +44,7 @@ class CORE_EXPORT Navigator final : public ScriptWrappable, public NavigatorID, public NavigatorLanguage, public NavigatorOnLine, + public NavigatorUserAgent, public DOMWindowClient, public Supplementable<Navigator> { DEFINE_WRAPPERTYPEINFO(); @@ -67,8 +70,13 @@ class CORE_EXPORT Navigator final : public ScriptWrappable, String userAgent() const override; String GetAcceptLanguages() override; + UserAgentMetadata GetUserAgentMetadata() const override; + void SetUserAgentMetadataForTesting(UserAgentMetadata); void Trace(blink::Visitor*) override; + + private: + UserAgentMetadata metadata_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/navigator.idl b/chromium/third_party/blink/renderer/core/frame/navigator.idl index 473881930b2..9b1c3303a6f 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator.idl +++ b/chromium/third_party/blink/renderer/core/frame/navigator.idl @@ -17,7 +17,7 @@ Boston, MA 02110-1301, USA. */ -// https://html.spec.whatwg.org/#the-navigator-object +// https://html.spec.whatwg.org/C/#the-navigator-object interface Navigator { // objects implementing this interface also implement the interfaces given below @@ -39,3 +39,4 @@ Navigator implements NavigatorID; Navigator implements NavigatorLanguage; Navigator implements NavigatorOnLine; Navigator implements NavigatorAutomationInformation; +Navigator implements NavigatorUserAgent; diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl b/chromium/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl index af79103d69b..8976b5f8744 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl +++ b/chromium/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://html.spec.whatwg.org/multipage/workers.html#navigator.hardwareconcurrency +// https://html.spec.whatwg.org/C/#navigator.hardwareconcurrency [ NoInterfaceObject, diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_cookies.idl b/chromium/third_party/blink/renderer/core/frame/navigator_cookies.idl index c77322a1428..12b9b923089 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator_cookies.idl +++ b/chromium/third_party/blink/renderer/core/frame/navigator_cookies.idl @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://html.spec.whatwg.org/multipage/webappapis.html#cookies +// https://html.spec.whatwg.org/C/#cookies [NoInterfaceObject] interface NavigatorCookies { diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_id.idl b/chromium/third_party/blink/renderer/core/frame/navigator_id.idl index 9e60756d688..a402a6968e8 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator_id.idl +++ b/chromium/third_party/blink/renderer/core/frame/navigator_id.idl @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://html.spec.whatwg.org/#client-identification +// https://html.spec.whatwg.org/C/#client-identification [ NoInterfaceObject, // Always used on target of 'implements' diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_language.cc b/chromium/third_party/blink/renderer/core/frame/navigator_language.cc index d2f3e4cc36c..423c88735c3 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator_language.cc +++ b/chromium/third_party/blink/renderer/core/frame/navigator_language.cc @@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/language.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -37,19 +38,22 @@ AtomicString NavigatorLanguage::language() { } const Vector<String>& NavigatorLanguage::languages() { - if (languages_dirty_) { - String accept_languages_override; - probe::applyAcceptLanguageOverride(context_, &accept_languages_override); + EnsureUpdatedLanguage(); + return languages_; +} - if (!accept_languages_override.IsNull()) { - languages_ = ParseAndSanitize(accept_languages_override); - } else { - languages_ = ParseAndSanitize(GetAcceptLanguages()); - } +AtomicString NavigatorLanguage::SerializeLanguagesForClientHintHeader() { + EnsureUpdatedLanguage(); - languages_dirty_ = false; + StringBuilder builder; + for (size_t i = 0; i < languages_.size(); i++) { + if (i) + builder.Append(", "); + builder.Append('"'); + builder.Append(languages_[i]); + builder.Append('"'); } - return languages_; + return builder.ToAtomicString(); } bool NavigatorLanguage::IsLanguagesDirty() const { @@ -61,6 +65,25 @@ void NavigatorLanguage::SetLanguagesDirty() { languages_.clear(); } +void NavigatorLanguage::SetLanguagesForTesting(const String& languages) { + languages_ = ParseAndSanitize(languages); +} + +void NavigatorLanguage::EnsureUpdatedLanguage() { + if (languages_dirty_) { + String accept_languages_override; + probe::ApplyAcceptLanguageOverride(context_, &accept_languages_override); + + if (!accept_languages_override.IsNull()) { + languages_ = ParseAndSanitize(accept_languages_override); + } else { + languages_ = ParseAndSanitize(GetAcceptLanguages()); + } + + languages_dirty_ = false; + } +} + void NavigatorLanguage::Trace(blink::Visitor* visitor) { visitor->Trace(context_); } diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_language.h b/chromium/third_party/blink/renderer/core/frame/navigator_language.h index b6507f9f4e6..b18dec31120 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator_language.h +++ b/chromium/third_party/blink/renderer/core/frame/navigator_language.h @@ -19,6 +19,10 @@ class CORE_EXPORT NavigatorLanguage : public GarbageCollectedMixin { const Vector<String>& languages(); bool IsLanguagesDirty() const; void SetLanguagesDirty(); + AtomicString SerializeLanguagesForClientHintHeader(); + + // Accepts a comma-separated list of languages. + void SetLanguagesForTesting(const String& languages); void Trace(blink::Visitor*) override; @@ -28,6 +32,8 @@ class CORE_EXPORT NavigatorLanguage : public GarbageCollectedMixin { virtual String GetAcceptLanguages() = 0; private: + void EnsureUpdatedLanguage(); + Vector<String> languages_; }; diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_language.idl b/chromium/third_party/blink/renderer/core/frame/navigator_language.idl index f587304069d..7a72f53336d 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator_language.idl +++ b/chromium/third_party/blink/renderer/core/frame/navigator_language.idl @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://html.spec.whatwg.org/#language-preferences +// https://html.spec.whatwg.org/C/#language-preferences [ NoInterfaceObject, diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_on_line.idl b/chromium/third_party/blink/renderer/core/frame/navigator_on_line.idl index d9f71c118b5..16dda054d2f 100644 --- a/chromium/third_party/blink/renderer/core/frame/navigator_on_line.idl +++ b/chromium/third_party/blink/renderer/core/frame/navigator_on_line.idl @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://html.spec.whatwg.org/#navigator.online +// https://html.spec.whatwg.org/C/#navigator.online [ NoInterfaceObject, // Always used on target of 'implements' diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc new file mode 100644 index 00000000000..3ca2c271fae --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc @@ -0,0 +1,42 @@ +// Copyright 2019 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/frame/navigator_scheduling.h" + +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/scheduling.h" + +namespace blink { + +const char NavigatorScheduling::kSupplementName[] = "NavigatorScheduling"; + +NavigatorScheduling& NavigatorScheduling::From(Navigator& navigator) { + NavigatorScheduling* supplement = + Supplement<Navigator>::From<NavigatorScheduling>(navigator); + if (!supplement) { + supplement = MakeGarbageCollected<NavigatorScheduling>(navigator); + ProvideTo(navigator, supplement); + } + return *supplement; +} + +Scheduling* NavigatorScheduling::scheduling(Navigator& navigator) { + return From(navigator).scheduling(); +} + +Scheduling* NavigatorScheduling::scheduling() { + return scheduling_; +} + +void NavigatorScheduling::Trace(blink::Visitor* visitor) { + visitor->Trace(scheduling_); + Supplement<Navigator>::Trace(visitor); +} + +NavigatorScheduling::NavigatorScheduling(Navigator& navigator) + : Supplement<Navigator>(navigator) { + scheduling_ = MakeGarbageCollected<Scheduling>(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h new file mode 100644 index 00000000000..90e39bc8d2a --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h @@ -0,0 +1,39 @@ +// Copyright 2019 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_FRAME_NAVIGATOR_SCHEDULING_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_SCHEDULING_H_ + +#include "third_party/blink/renderer/core/frame/navigator.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/supplementable.h" + +namespace blink { + +class Scheduling; + +class CORE_EXPORT NavigatorScheduling final + : public GarbageCollected<NavigatorScheduling>, + public Supplement<Navigator> { + USING_GARBAGE_COLLECTED_MIXIN(NavigatorScheduling); + + public: + static const char kSupplementName[]; + + static Scheduling* scheduling(Navigator& navigator); + Scheduling* scheduling(); + + explicit NavigatorScheduling(Navigator&); + + void Trace(blink::Visitor*) override; + + private: + static NavigatorScheduling& From(Navigator&); + + Member<Scheduling> scheduling_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_SCHEDULING_H_ diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.idl b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.idl new file mode 100644 index 00000000000..5fa172844d9 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.idl @@ -0,0 +1,12 @@ +// Copyright 2019 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. + +// https://github.com/tdresser/is-input-pending +[ + Exposed=Window, + ImplementedAs=NavigatorScheduling, + OriginTrialEnabled=ExperimentalIsInputPending +] partial interface Navigator { + readonly attribute Scheduling scheduling; +}; diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.cc b/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.cc new file mode 100644 index 00000000000..12e44f4fe08 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.cc @@ -0,0 +1,30 @@ +// Copyright 2019 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/frame/navigator_user_agent.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/core/frame/user_agent.h" + +namespace blink { + +ScriptPromise NavigatorUserAgent::getUserAgent(ScriptState* script_state) { + ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); + ScriptPromise promise = resolver->Promise(); + + blink::UserAgentMetadata metadata = GetUserAgentMetadata(); + blink::UserAgent* idl_metadata = blink::UserAgent::Create(); + + idl_metadata->setBrand(String::FromUTF8(metadata.brand.data())); + idl_metadata->setVersion(String::FromUTF8(metadata.full_version.data())); + idl_metadata->setPlatform(String::FromUTF8(metadata.platform.data())); + idl_metadata->setArchitecture(String::FromUTF8(metadata.architecture.data())); + idl_metadata->setModel(String::FromUTF8(metadata.model.data())); + resolver->Resolve(idl_metadata); + + return promise; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.h b/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.h new file mode 100644 index 00000000000..def5dda212e --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.h @@ -0,0 +1,25 @@ +// Copyright 2019 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_FRAME_NAVIGATOR_USER_AGENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_USER_AGENT_H_ + +#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class ScriptPromise; +class ScriptState; +class CORE_EXPORT NavigatorUserAgent { + public: + ScriptPromise getUserAgent(ScriptState*); + + virtual UserAgentMetadata GetUserAgentMetadata() const = 0; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_USER_AGENT_H_ diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.idl b/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.idl new file mode 100644 index 00000000000..b9aa92422bc --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.idl @@ -0,0 +1,12 @@ +// Copyright 2019 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. + +// https://github.com/WICG/ua-client-hints +[ + NoInterfaceObject, // Always used on target of 'implements' + RuntimeEnabled=UserAgentClientHint, + Exposed=Window +] interface NavigatorUserAgent { + [SecureContext, CallWith=ScriptState] Promise<UserAgent> getUserAgent(); +}; diff --git a/chromium/third_party/blink/renderer/core/frame/opened_frame_tracker.h b/chromium/third_party/blink/renderer/core/frame/opened_frame_tracker.h index b89c6069d71..60c44d6c0bc 100644 --- a/chromium/third_party/blink/renderer/core/frame/opened_frame_tracker.h +++ b/chromium/third_party/blink/renderer/core/frame/opened_frame_tracker.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_OPENED_FRAME_TRACKER_H_ #include "base/macros.h" +#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" namespace blink { @@ -16,6 +17,8 @@ class WebFrame; // Due to layering restrictions, we need to hide the implementation, since // public/web/ cannot depend on wtf/. class OpenedFrameTracker { + USING_FAST_MALLOC(OpenedFrameTracker); + public: OpenedFrameTracker(); ~OpenedFrameTracker(); diff --git a/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc b/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc index 148e0a75309..55ba414bb37 100644 --- a/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc +++ b/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc @@ -201,9 +201,9 @@ void PageScaleConstraintsSet::AdjustForAndroidWebViewQuirks( bool reset_initial_scale = false; if (description.zoom == -1) { if (description.max_width.IsAuto() || - description.max_width.GetType() == kExtendToZoom) + description.max_width.IsExtendToZoom()) reset_initial_scale = true; - if (use_wide_viewport || description.max_width.GetType() == kDeviceWidth) + if (use_wide_viewport || description.max_width.IsDeviceWidth()) reset_initial_scale = true; } if (reset_initial_scale) @@ -226,8 +226,7 @@ void PageScaleConstraintsSet::AdjustForAndroidWebViewQuirks( if (page_defined_constraints_.maximum_scale != -1) page_defined_constraints_.maximum_scale *= target_density_dpi_factor; if (wide_viewport_quirk_enabled && - (!use_wide_viewport || - description.max_width.GetType() == kDeviceWidth)) { + (!use_wide_viewport || description.max_width.IsDeviceWidth())) { adjusted_layout_size_width /= target_density_dpi_factor; adjusted_layout_size_height /= target_density_dpi_factor; } @@ -236,7 +235,7 @@ void PageScaleConstraintsSet::AdjustForAndroidWebViewQuirks( if (wide_viewport_quirk_enabled) { if (use_wide_viewport && (description.max_width.IsAuto() || - description.max_width.GetType() == kExtendToZoom) && + description.max_width.IsExtendToZoom()) && description.zoom != 1.0f) { if (layout_fallback_width) adjusted_layout_size_width = layout_fallback_width; @@ -244,9 +243,8 @@ void PageScaleConstraintsSet::AdjustForAndroidWebViewQuirks( adjusted_layout_size_width, FloatSize(icb_size_)); } else if (!use_wide_viewport) { const float non_wide_scale = - description.zoom < 1 && - description.max_width.GetType() != kDeviceWidth && - description.max_width.GetType() != kDeviceHeight + description.zoom < 1 && !description.max_width.IsDeviceWidth() && + !description.max_width.IsDeviceHeight() ? -1 : old_initial_scale; adjusted_layout_size_width = GetLayoutWidthForNonWideViewport( @@ -254,9 +252,9 @@ void PageScaleConstraintsSet::AdjustForAndroidWebViewQuirks( target_density_dpi_factor; float new_initial_scale = target_density_dpi_factor; if (user_agent_constraints_.initial_scale != -1 && - (description.max_width.GetType() == kDeviceWidth || + (description.max_width.IsDeviceWidth() || ((description.max_width.IsAuto() || - description.max_width.GetType() == kExtendToZoom) && + description.max_width.IsExtendToZoom()) && description.zoom == -1))) { adjusted_layout_size_width /= user_agent_constraints_.initial_scale; new_initial_scale = user_agent_constraints_.initial_scale; @@ -284,8 +282,8 @@ void PageScaleConstraintsSet::AdjustForAndroidWebViewQuirks( page_defined_constraints_.maximum_scale = page_defined_constraints_.initial_scale; if (description.max_width.IsAuto() || - description.max_width.GetType() == kExtendToZoom || - description.max_width.GetType() == kDeviceWidth) { + description.max_width.IsExtendToZoom() || + description.max_width.IsDeviceWidth()) { adjusted_layout_size_width = icb_size_.Width() / target_density_dpi_factor; adjusted_layout_size_height = ComputeHeightByAspectRatio( diff --git a/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h b/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h index 327d5289bc1..be27df6d5c2 100644 --- a/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h +++ b/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h @@ -7,7 +7,7 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" diff --git a/chromium/third_party/blink/renderer/core/frame/pausable_task.h b/chromium/third_party/blink/renderer/core/frame/pausable_task.h index e62b19ed02e..c829c8e266d 100644 --- a/chromium/third_party/blink/renderer/core/frame/pausable_task.h +++ b/chromium/third_party/blink/renderer/core/frame/pausable_task.h @@ -9,7 +9,7 @@ #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/heap/self_keep_alive.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" diff --git a/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc b/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc index 40ebca757b3..83dda1201f0 100644 --- a/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc +++ b/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc @@ -28,7 +28,7 @@ constexpr auto kLongTaskSubTaskThreshold = TimeDelta::FromMilliseconds(12); void PerformanceMonitor::BypassLongCompileThresholdOnceForTesting() { bypass_long_compile_threshold_ = true; -}; +} // static base::TimeDelta PerformanceMonitor::Threshold(ExecutionContext* context, @@ -76,7 +76,7 @@ PerformanceMonitor::PerformanceMonitor(LocalFrame* local_root) : local_root_(local_root) { std::fill(std::begin(thresholds_), std::end(thresholds_), base::TimeDelta()); Thread::Current()->AddTaskTimeObserver(this); - local_root_->GetProbeSink()->addPerformanceMonitor(this); + local_root_->GetProbeSink()->AddPerformanceMonitor(this); } PerformanceMonitor::~PerformanceMonitor() { @@ -108,7 +108,7 @@ void PerformanceMonitor::Shutdown() { subscriptions_.clear(); UpdateInstrumentation(); Thread::Current()->RemoveTaskTimeObserver(this); - local_root_->GetProbeSink()->removePerformanceMonitor(this); + local_root_->GetProbeSink()->RemovePerformanceMonitor(this); local_root_ = nullptr; } @@ -238,7 +238,7 @@ void PerformanceMonitor::Did(const probe::CallFunction& probe) { return; String name = user_callback->name ? String(user_callback->name) - : String(user_callback->atomicName); + : String(user_callback->atomic_name); String text = String::Format("'%s' handler took %" PRId64 "ms", name.Utf8().data(), duration.InMilliseconds()); InnerReportGenericViolation(probe.context, handler_type, text, duration, diff --git a/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h b/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h index 98b35b80f3e..32eb8937f59 100644 --- a/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h +++ b/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h @@ -13,7 +13,6 @@ namespace blink { class HTMLVideoElement; class ScriptPromiseResolver; -struct PictureInPictureControlInfo; // PictureInPictureController allows to know if Picture-in-Picture is allowed // for a video element in Blink outside of modules/ module. It @@ -72,17 +71,8 @@ class CORE_EXPORT PictureInPictureController virtual void RemoveFromAutoPictureInPictureElementsList( HTMLVideoElement*) = 0; - // Should be called when a custom control on a video element in - // Picture-in-Picture is clicked. |control_id| is the identifier for its - // custom control. This is defined by the site that calls the web API. - virtual void OnPictureInPictureControlClicked( - const WebString& control_id) = 0; - - // Assign custom controls to be added to the Picture-in-Picture window. - virtual void SetPictureInPictureCustomControls( - HTMLVideoElement*, - const std::vector<PictureInPictureControlInfo>&) = 0; - + // Notifies that one of the states used by Picture-in-Picture has changed. + virtual void OnPictureInPictureStateChange() = 0; void Trace(blink::Visitor*) override; diff --git a/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h b/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h index ccacdd3f462..52f1eb421cd 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h +++ b/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h @@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/frame/dom_window.h" #include "third_party/blink/renderer/core/frame/remote_frame.h" -#include "third_party/blink/renderer/platform/wtf/assertions.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -19,7 +19,9 @@ class RemoteDOMWindow final : public DOMWindow { explicit RemoteDOMWindow(RemoteFrame&); - RemoteFrame* GetFrame() const { return ToRemoteFrame(DOMWindow::GetFrame()); } + RemoteFrame* GetFrame() const { + return To<RemoteFrame>(DOMWindow::GetFrame()); + } // EventTarget overrides: ExecutionContext* GetExecutionContext() const override; @@ -48,11 +50,12 @@ class RemoteDOMWindow final : public DOMWindow { bool has_user_gesture); }; -DEFINE_TYPE_CASTS(RemoteDOMWindow, - DOMWindow, - x, - x->IsRemoteDOMWindow(), - x.IsRemoteDOMWindow()); +template <> +struct DowncastTraits<RemoteDOMWindow> { + static bool AllowFrom(const DOMWindow& window) { + return window.IsRemoteDOMWindow(); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc index 18e376f2170..b6e0e2c9f54 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc @@ -18,11 +18,11 @@ #include "third_party/blink/renderer/core/loader/frame_load_request.h" #include "third_party/blink/renderer/core/loader/frame_loader.h" #include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h" -#include "third_party/blink/renderer/platform/plugins/plugin_script_forbidden_scope.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" namespace blink { @@ -63,7 +63,7 @@ void RemoteFrame::ScheduleNavigation(Document& origin_document, UserGestureStatus user_gesture_status) { if (!origin_document.GetSecurityOrigin()->CanDisplay(url)) { origin_document.AddConsoleMessage(ConsoleMessage::Create( - kSecurityMessageSource, kErrorMessageLevel, + kSecurityMessageSource, mojom::ConsoleMessageLevel::kError, "Not allowed to load local resource: " + url.ElidedString())); return; } @@ -125,7 +125,7 @@ void RemoteFrame::DetachImpl(FrameDetachType type) { // That combined with wrappers (owned and kept alive by RemoteFrame) keeping // persistent strong references to RemoteDOMWindow will prevent the GCing // of all these objects. Break the cycle by notifying of detachment. - ToRemoteDOMWindow(dom_window_)->FrameDetached(); + To<RemoteDOMWindow>(dom_window_.Get())->FrameDetached(); if (cc_layer_) SetCcLayer(nullptr, false, false); } @@ -176,10 +176,9 @@ bool RemoteFrame::BubbleLogicalScrollFromChildFrame( ScrollDirection direction, ScrollGranularity granularity, Frame* child) { - DCHECK(child->IsLocalFrame()); DCHECK(child->Client()); - ToLocalFrame(child)->Client()->BubbleLogicalScrollInParentFrame(direction, - granularity); + To<LocalFrame>(child)->Client()->BubbleLogicalScrollInParentFrame( + direction, granularity); return false; } @@ -219,8 +218,9 @@ bool RemoteFrame::IsIgnoredForHitTest() const { HTMLFrameOwnerElement* owner = DeprecatedLocalOwner(); if (!owner || !owner->GetLayoutObject()) return false; - return owner->GetLayoutObject()->Style()->PointerEvents() == - EPointerEvents::kNone; + return owner->OwnerType() == FrameOwnerElementType::kPortal || + (owner->GetLayoutObject()->Style()->PointerEvents() == + EPointerEvents::kNone); } void RemoteFrame::SetCcLayer(cc::Layer* cc_layer, @@ -238,7 +238,7 @@ void RemoteFrame::SetCcLayer(cc::Layer* cc_layer, PointerEventsChanged(); } - ToHTMLFrameOwnerElement(Owner())->SetNeedsCompositingUpdate(); + To<HTMLFrameOwnerElement>(Owner())->SetNeedsCompositingUpdate(); } void RemoteFrame::AdvanceFocus(WebFocusType type, LocalFrame* source) { diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame.h b/chromium/third_party/blink/renderer/core/frame/remote_frame.h index a2d54a2dee2..23ad42bac2d 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame.h +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.h @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/execution_context/remote_security_context.h" #include "third_party/blink/renderer/core/frame/frame.h" #include "third_party/blink/renderer/core/frame/remote_frame_view.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace cc { class Layer; @@ -89,11 +90,10 @@ inline RemoteFrameView* RemoteFrame::View() const { return view_.Get(); } -DEFINE_TYPE_CASTS(RemoteFrame, - Frame, - remoteFrame, - remoteFrame->IsRemoteFrame(), - remoteFrame.IsRemoteFrame()); +template <> +struct DowncastTraits<RemoteFrame> { + static bool AllowFrom(const Frame& frame) { return frame.IsRemoteFrame(); } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h index b9c8598e311..bdc360bcbb7 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_CLIENT_H_ #include "cc/paint/paint_canvas.h" +#include "third_party/blink/public/common/frame/occlusion_state.h" #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h" #include "third_party/blink/public/platform/web_focus_type.h" #include "third_party/blink/public/web/web_frame_load_type.h" @@ -54,12 +55,10 @@ class RemoteFrameClient : public FrameClient { virtual void UpdateRemoteViewportIntersection( const IntRect& viewport_intersection, - bool occluded_or_obscured) = 0; + FrameOcclusionState occlusion_state) = 0; virtual void AdvanceFocus(WebFocusType, LocalFrame* source) = 0; - virtual void VisibilityChanged(bool visible) = 0; - virtual void SetIsInert(bool) = 0; virtual void SetInheritedEffectiveTouchAction(TouchAction) = 0; diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc index ffb4e27bada..fc31e195248 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc @@ -155,9 +155,9 @@ void RemoteFrameClientImpl::FrameRectsChanged( void RemoteFrameClientImpl::UpdateRemoteViewportIntersection( const IntRect& viewport_intersection, - bool occluded_or_obscured) { + FrameOcclusionState occlusion_state) { web_frame_->Client()->UpdateRemoteViewportIntersection(viewport_intersection, - occluded_or_obscured); + occlusion_state); } void RemoteFrameClientImpl::AdvanceFocus(WebFocusType type, @@ -166,8 +166,9 @@ void RemoteFrameClientImpl::AdvanceFocus(WebFocusType type, WebLocalFrameImpl::FromFrame(source)); } -void RemoteFrameClientImpl::VisibilityChanged(bool visible) { - web_frame_->Client()->VisibilityChanged(visible); +void RemoteFrameClientImpl::VisibilityChanged( + blink::mojom::FrameVisibility visibility) { + web_frame_->Client()->VisibilityChanged(visibility); } void RemoteFrameClientImpl::SetIsInert(bool inert) { diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h index 06878012e4c..1a3f7067df7 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h @@ -48,9 +48,10 @@ class RemoteFrameClientImpl final : public RemoteFrameClient { bool has_user_gesture) const override; void FrameRectsChanged(const IntRect& local_frame_rect, const IntRect& screen_space_rect) override; - void UpdateRemoteViewportIntersection(const IntRect&, bool) override; + void UpdateRemoteViewportIntersection(const IntRect&, + FrameOcclusionState) override; void AdvanceFocus(WebFocusType, LocalFrame*) override; - void VisibilityChanged(bool visible) override; + void VisibilityChanged(blink::mojom::FrameVisibility) override; void SetIsInert(bool) override; void SetInheritedEffectiveTouchAction(TouchAction) override; void UpdateRenderThrottlingStatus(bool is_throttled, diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc index bdab3d1115b..b35efa69d3d 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc @@ -31,6 +31,7 @@ RemoteFrameOwner::RemoteFrameOwner( allow_fullscreen_(frame_owner_properties.allow_fullscreen), allow_payment_request_(frame_owner_properties.allow_payment_request), is_display_none_(frame_owner_properties.is_display_none), + needs_occlusion_tracking_(false), required_csp_(frame_owner_properties.required_csp), container_policy_(container_policy), frame_owner_element_type_(frame_owner_element_type) {} @@ -55,7 +56,7 @@ void RemoteFrameOwner::ClearContentFrame() { } void RemoteFrameOwner::AddResourceTiming(const ResourceTimingInfo& info) { - LocalFrame* frame = ToLocalFrame(frame_); + LocalFrame* frame = To<LocalFrame>(frame_.Get()); WebResourceTimingInfo resource_timing = Performance::GenerateResourceTiming( *frame->Tree().Parent()->GetSecurityContext()->GetSecurityOrigin(), info, *frame->GetDocument()); @@ -64,7 +65,7 @@ void RemoteFrameOwner::AddResourceTiming(const ResourceTimingInfo& info) { void RemoteFrameOwner::DispatchLoad() { WebLocalFrameImpl* web_frame = - WebLocalFrameImpl::FromFrame(ToLocalFrame(*frame_)); + WebLocalFrameImpl::FromFrame(To<LocalFrame>(*frame_)); web_frame->Client()->DispatchLoad(); } @@ -72,7 +73,7 @@ void RemoteFrameOwner::RenderFallbackContent(Frame* failed_frame) { if (frame_owner_element_type_ != FrameOwnerElementType::kObject) return; DCHECK(failed_frame->IsLocalFrame()); - LocalFrame* local_frame = ToLocalFrame(failed_frame); + LocalFrame* local_frame = To<LocalFrame>(failed_frame); DCHECK(local_frame->IsProvisional() || ContentFrame() == local_frame); WebLocalFrameImpl::FromFrame(local_frame) ->Client() @@ -80,7 +81,7 @@ void RemoteFrameOwner::RenderFallbackContent(Frame* failed_frame) { } void RemoteFrameOwner::IntrinsicSizingInfoChanged() { - LocalFrame& local_frame = ToLocalFrame(*frame_); + LocalFrame& local_frame = To<LocalFrame>(*frame_); IntrinsicSizingInfo intrinsic_sizing_info; bool result = local_frame.View()->GetIntrinsicSizingInfo(intrinsic_sizing_info); @@ -92,6 +93,15 @@ void RemoteFrameOwner::IntrinsicSizingInfoChanged() { ->IntrinsicSizingInfoChanged(intrinsic_sizing_info); } +void RemoteFrameOwner::SetNeedsOcclusionTracking(bool needs_tracking) { + if (needs_tracking == needs_occlusion_tracking_) + return; + needs_occlusion_tracking_ = needs_tracking; + WebLocalFrameImpl* web_frame = + WebLocalFrameImpl::FromFrame(To<LocalFrame>(*frame_)); + web_frame->Client()->SetNeedsOcclusionTracking(needs_tracking); +} + bool RemoteFrameOwner::ShouldLazyLoadChildren() const { // Don't use lazy load for children inside an OOPIF, since there's a good // chance that the parent FrameOwner was previously deferred by lazy load diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h index 2d3a436d5cb..040cbe3d3ea 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h @@ -9,7 +9,8 @@ #include "third_party/blink/public/web/web_frame_owner_properties.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/frame_owner.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -52,6 +53,7 @@ class CORE_EXPORT RemoteFrameOwner final } void RenderFallbackContent(Frame*) override; void IntrinsicSizingInfoChanged() override; + void SetNeedsOcclusionTracking(bool) override; AtomicString BrowsingContextContainerName() const override { return browsing_context_container_name_; @@ -107,16 +109,16 @@ class CORE_EXPORT RemoteFrameOwner final bool allow_fullscreen_; bool allow_payment_request_; bool is_display_none_; + bool needs_occlusion_tracking_; WebString required_csp_; ParsedFeaturePolicy container_policy_; const FrameOwnerElementType frame_owner_element_type_; }; -DEFINE_TYPE_CASTS(RemoteFrameOwner, - FrameOwner, - owner, - owner->IsRemote(), - owner.IsRemote()); +template <> +struct DowncastTraits<RemoteFrameOwner> { + static bool AllowFrom(const FrameOwner& owner) { return owner.IsRemote(); } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc index 5697f4bfd5e..ea41020bb2b 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc @@ -6,12 +6,12 @@ #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/element_visibility_observer.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/remote_frame.h" #include "third_party/blink/renderer/core/frame/remote_frame_client.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" +#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h" #include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -40,7 +40,7 @@ LocalFrameView* RemoteFrameView::ParentFrameView() const { // |is_attached_| is only set from AttachToLayout(), which ensures that the // parent is a local frame. - return ToLocalFrame(remote_frame_->Tree().Parent())->View(); + return To<LocalFrame>(remote_frame_->Tree().Parent())->View(); } LocalFrameView* RemoteFrameView::ParentLocalRootFrameView() const { @@ -53,7 +53,9 @@ LocalFrameView* RemoteFrameView::ParentLocalRootFrameView() const { // |is_attached_| is only set from AttachToLayout(), which ensures that the // parent is a local frame. - return ToLocalFrame(remote_frame_->Tree().Parent())->LocalFrameRoot().View(); + return To<LocalFrame>(remote_frame_->Tree().Parent()) + ->LocalFrameRoot() + .View(); } void RemoteFrameView::AttachToLayout() { @@ -61,8 +63,8 @@ void RemoteFrameView::AttachToLayout() { is_attached_ = true; if (ParentFrameView()->IsVisible()) SetParentVisible(true); + UpdateVisibility(true); - SetupRenderThrottling(); subtree_throttled_ = ParentFrameView()->CanThrottleRendering(); FrameRectsChanged(); @@ -80,78 +82,89 @@ RemoteFrameView* RemoteFrameView::Create(RemoteFrame* remote_frame) { return view; } -void RemoteFrameView::UpdateViewportIntersectionsForSubtree() { - LayoutEmbeddedContent* owner = remote_frame_->OwnerLayoutObject(); - if (!owner) - return; - - LocalFrameView* local_root_view = ParentLocalRootFrameView(); - if (!local_root_view) - return; +bool RemoteFrameView::UpdateViewportIntersectionsForSubtree( + unsigned parent_flags) { + if (!(parent_flags & + IntersectionObservation::kImplicitRootObserversNeedUpdate)) { + return needs_occlusion_tracking_; + } + // This should only run in child frames. + HTMLFrameOwnerElement* owner_element = remote_frame_->DeprecatedLocalOwner(); + DCHECK(owner_element); + LayoutEmbeddedContent* owner = owner_element->GetLayoutEmbeddedContent(); + if (!owner) + return needs_occlusion_tracking_; IntRect viewport_intersection; - bool occluded_or_obscured = false; - DocumentLifecycle::LifecycleState parent_state = - owner->GetDocument().Lifecycle().GetState(); + DocumentLifecycle::LifecycleState parent_lifecycle_state = + owner_element->GetDocument().Lifecycle().GetState(); + FrameOcclusionState occlusion_state = + owner_element->GetDocument().GetFrame()->GetOcclusionState(); + bool should_compute_occlusion = + needs_occlusion_tracking_ && occlusion_state == kGuaranteedNotOccluded && + parent_lifecycle_state >= DocumentLifecycle::kPrePaintClean && + RuntimeEnabledFeatures::IntersectionObserverV2Enabled(); // If the parent LocalFrameView is throttled and out-of-date, then we can't // get any useful information. - if (parent_state >= DocumentLifecycle::kLayoutClean) { - // Start with rect in remote frame's coordinate space. Then - // mapToVisualRectInAncestorSpace will move it to the local root's - // coordinate space and account for any clip from containing elements such - // as a scrollable div. Passing nullptr as an argument to - // mapToVisualRectInAncestorSpace causes it to be clipped to the viewport, - // even if there are RemoteFrame ancestors in the frame tree. - LayoutRect rect(0, 0, frame_rect_.Width(), frame_rect_.Height()); - rect.Move(owner->PhysicalContentBoxOffset()); - if (owner->MapToVisualRectInAncestorSpace(nullptr, rect, - kUseGeometryMapper)) { - IntRect root_visible_rect(IntPoint(), local_root_view->Size()); - IntRect intersected_rect = EnclosingIntRect(rect); - intersected_rect.Intersect(root_visible_rect); - - // Translate the intersection rect from the root frame's coordinate space - // to the remote frame's coordinate space. - FloatRect viewport_intersection_float = - remote_frame_->OwnerLayoutObject() - ->AncestorToLocalQuad( - local_root_view->GetLayoutView(), FloatQuad(intersected_rect), - kTraverseDocumentBoundaries | kUseTransforms) - .BoundingBox(); - viewport_intersection_float.Move( - -remote_frame_->OwnerLayoutObject()->PhysicalContentBoxOffset()); - viewport_intersection = EnclosingIntRect(viewport_intersection_float); - } - } - - if (parent_state >= DocumentLifecycle::kPrePaintClean && - RuntimeEnabledFeatures::IntersectionObserverV2Enabled()) { - // TODO(layout-dev): As an optimization, we should only check for - // occlusion and effects if the remote frame needs it, i.e., if it has at - // least one active IntersectionObserver with trackVisibility:true. - if (owner->GetDocument() - .GetFrame() - ->LocalFrameRoot() - .MayBeOccludedOrObscuredByRemoteAncestor() || - owner->HasDistortingVisualEffects()) { - occluded_or_obscured = true; + if (parent_lifecycle_state >= DocumentLifecycle::kLayoutClean) { + unsigned geometry_flags = + IntersectionGeometry::kShouldUseReplacedContentRect; + if (should_compute_occlusion) + geometry_flags |= IntersectionGeometry::kShouldComputeVisibility; + + IntersectionGeometry geometry(nullptr, *owner_element, {}, + {IntersectionObserver::kMinimumThreshold}, + geometry_flags); + // geometry.IntersectionRect() is in absolute coordinates of the owning + // document. Map it down to absolute coordinates in the child document. + LayoutRect intersection_rect = LayoutRect( + owner + ->AncestorToLocalQuad( + nullptr, FloatQuad(FloatRect(geometry.IntersectionRect())), + kUseTransforms) + .BoundingBox()); + // Map from the box coordinates of the owner to the inner frame. + intersection_rect.Move(-owner->PhysicalContentBoxOffset()); + // Don't let EnclosingIntRect turn an empty rect into a non-empty one. + if (intersection_rect.IsEmpty()) { + viewport_intersection = + IntRect(FlooredIntPoint(intersection_rect.Location()), IntSize()); } else { - HitTestResult result(owner->HitTestForOcclusion()); - occluded_or_obscured = - result.InnerNode() && result.InnerNode() != owner->GetNode(); + viewport_intersection = EnclosingIntRect(intersection_rect); } + if (should_compute_occlusion && !geometry.IsVisible()) + occlusion_state = kPossiblyOccluded; + } else if (occlusion_state == kGuaranteedNotOccluded) { + occlusion_state = kUnknownOcclusionState; } + // TODO(szager): There are some redundant IPC's here; clean them up. + bool is_visible_for_throttling = !viewport_intersection.IsEmpty(); + UpdateVisibility(is_visible_for_throttling); + UpdateRenderThrottlingStatus(!is_visible_for_throttling, subtree_throttled_); + if (viewport_intersection == last_viewport_intersection_ && - occluded_or_obscured == last_occluded_or_obscured_) { - return; + occlusion_state == last_occlusion_state_) { + return needs_occlusion_tracking_; } last_viewport_intersection_ = viewport_intersection; - last_occluded_or_obscured_ = occluded_or_obscured; + last_occlusion_state_ = occlusion_state; remote_frame_->Client()->UpdateRemoteViewportIntersection( - viewport_intersection, occluded_or_obscured); + viewport_intersection, occlusion_state); + + return needs_occlusion_tracking_; +} + +void RemoteFrameView::SetNeedsOcclusionTracking(bool needs_tracking) { + if (needs_occlusion_tracking_ == needs_tracking) + return; + needs_occlusion_tracking_ = needs_tracking; + if (needs_tracking) { + if (LocalFrameView* parent_view = ParentLocalRootFrameView()) + parent_view->ScheduleAnimation(); + } } IntRect RemoteFrameView::GetCompositingRect() { @@ -297,12 +310,12 @@ void RemoteFrameView::UpdateGeometry() { void RemoteFrameView::Hide() { self_visible_ = false; - remote_frame_->Client()->VisibilityChanged(false); + UpdateVisibility(scroll_visible_); } void RemoteFrameView::Show() { self_visible_ = true; - remote_frame_->Client()->VisibilityChanged(true); + UpdateVisibility(scroll_visible_); } void RemoteFrameView::SetParentVisible(bool visible) { @@ -312,26 +325,24 @@ void RemoteFrameView::SetParentVisible(bool visible) { parent_visible_ = visible; if (!self_visible_) return; - - remote_frame_->Client()->VisibilityChanged(self_visible_ && parent_visible_); + UpdateVisibility(scroll_visible_); } -void RemoteFrameView::SetupRenderThrottling() { - if (visibility_observer_) - return; +void RemoteFrameView::UpdateVisibility(bool scroll_visible) { + blink::mojom::FrameVisibility visibility; + scroll_visible_ = scroll_visible; + if (self_visible_ && parent_visible_) { + visibility = scroll_visible + ? blink::mojom::FrameVisibility::kRenderedInViewport + : blink::mojom::FrameVisibility::kRenderedOutOfViewport; + } else { + visibility = blink::mojom::FrameVisibility::kNotRendered; + } - Element* target_element = GetFrame().DeprecatedLocalOwner(); - if (!target_element) + if (visibility == visibility_) return; - - visibility_observer_ = MakeGarbageCollected<ElementVisibilityObserver>( - target_element, WTF::BindRepeating( - [](RemoteFrameView* remote_view, bool is_visible) { - remote_view->UpdateRenderThrottlingStatus( - !is_visible, remote_view->subtree_throttled_); - }, - WrapWeakPersistent(this))); - visibility_observer_->Start(); + visibility_ = visibility; + remote_frame_->Client()->VisibilityChanged(visibility); } void RemoteFrameView::UpdateRenderThrottlingStatus(bool hidden, diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h index 9389744405e..a246b3bbcf4 100644 --- a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h +++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h @@ -6,6 +6,8 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_VIEW_H_ #include "cc/paint/paint_canvas.h" +#include "third_party/blink/public/common/frame/occlusion_state.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document_lifecycle.h" #include "third_party/blink/renderer/core/frame/frame_view.h" #include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h" @@ -18,8 +20,9 @@ class PaintCanvas; namespace blink { class CullRect; -class ElementVisibilityObserver; class GraphicsContext; +class IntersectionObserver; +class IntersectionObserverEntry; class LocalFrameView; class RemoteFrame; @@ -57,7 +60,9 @@ class RemoteFrameView final : public GarbageCollectedFinalized<RemoteFrameView>, void Show() override; void SetParentVisible(bool) override; - void UpdateViewportIntersectionsForSubtree() override; + bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override; + void SetNeedsOcclusionTracking(bool); + bool NeedsOcclusionTracking() const { return needs_occlusion_tracking_; } bool GetIntrinsicSizingInfo(IntrinsicSizingInfo&) const override; @@ -82,9 +87,11 @@ class RemoteFrameView final : public GarbageCollectedFinalized<RemoteFrameView>, // owner. LocalFrameView* ParentLocalRootFrameView() const; + void OnViewportIntersectionChanged( + const HeapVector<Member<IntersectionObserverEntry>>& entries); void UpdateRenderThrottlingStatus(bool hidden, bool subtree_throttled); bool CanThrottleRendering() const; - void SetupRenderThrottling(); + void UpdateVisibility(bool scroll_visible); // The properties and handling of the cycle between RemoteFrame // and its RemoteFrameView corresponds to that between LocalFrame @@ -93,16 +100,20 @@ class RemoteFrameView final : public GarbageCollectedFinalized<RemoteFrameView>, Member<RemoteFrame> remote_frame_; bool is_attached_; IntRect last_viewport_intersection_; - bool last_occluded_or_obscured_ = false; + FrameOcclusionState last_occlusion_state_ = kUnknownOcclusionState; IntRect frame_rect_; bool self_visible_; bool parent_visible_; + bool scroll_visible_ = true; + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; - Member<ElementVisibilityObserver> visibility_observer_; + Member<IntersectionObserver> visibility_observer_; bool subtree_throttled_ = false; bool hidden_for_throttling_ = false; IntrinsicSizingInfo intrinsic_sizing_info_; bool has_intrinsic_sizing_info_ = false; + bool needs_occlusion_tracking_ = false; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/reporting_context.h b/chromium/third_party/blink/renderer/core/frame/reporting_context.h index 4b86d997728..09d5960f2b0 100644 --- a/chromium/third_party/blink/renderer/core/frame/reporting_context.h +++ b/chromium/third_party/blink/renderer/core/frame/reporting_context.h @@ -21,7 +21,8 @@ class ReportingObserver; class CORE_EXPORT ReportingContext final : public GarbageCollectedFinalized<ReportingContext>, public Supplement<ExecutionContext> { - USING_GARBAGE_COLLECTED_MIXIN(ReportingContext) + USING_GARBAGE_COLLECTED_MIXIN(ReportingContext); + public: static const char kSupplementName[]; diff --git a/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.cc b/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.cc index 1a805ce357e..3f22e7a6f45 100644 --- a/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.cc +++ b/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.cc @@ -54,8 +54,8 @@ void ResizeViewportAnchor::EndScope() { LocalFrameView* ResizeViewportAnchor::RootFrameView() { if (Frame* frame = page_->MainFrame()) { - if (frame->IsLocalFrame()) - return ToLocalFrame(frame)->View(); + if (LocalFrame* local_frame = DynamicTo<LocalFrame>(frame)) + return local_frame->View(); } return nullptr; } diff --git a/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h b/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h index 6c9daa71b07..7401c0387e0 100644 --- a/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h +++ b/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h @@ -8,8 +8,8 @@ #include "base/macros.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc index b982371827a..b58470f5d98 100644 --- a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc +++ b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc @@ -4,18 +4,19 @@ #include "third_party/blink/renderer/core/frame/root_frame_viewport.h" +#include "cc/input/snap_selection_strategy.h" #include "third_party/blink/public/platform/web_scroll_into_view_params.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/scroll_anchor.h" #include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" +#include "third_party/blink/renderer/core/scroll/scroll_alignment.h" #include "third_party/blink/renderer/core/scroll/scroll_animator_base.h" #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h" #include "third_party/blink/renderer/platform/geometry/double_rect.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" -#include "third_party/blink/renderer/platform/scroll/scroll_alignment.h" namespace blink { namespace { @@ -295,9 +296,9 @@ LayoutRect RootFrameViewport::ScrollIntoView( new_scroll_offset = ClampToUserScrollableOffset(new_scroll_offset); FloatPoint end_point = ScrollOffsetToPosition(new_scroll_offset); - std::unique_ptr<SnapSelectionStrategy> strategy = - SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(end_point), - true, true); + std::unique_ptr<cc::SnapSelectionStrategy> strategy = + cc::SnapSelectionStrategy::CreateForEndPosition( + gfx::ScrollOffset(end_point), true, true); if (GetLayoutBox()) { end_point = GetLayoutBox() ->GetDocument() diff --git a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h index a18c1ed1b7e..372f4360d9c 100644 --- a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h +++ b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h @@ -8,6 +8,8 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/scroll/scrollable_area.h" +#include "third_party/blink/renderer/platform/graphics/scroll_types.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -150,11 +152,12 @@ class CORE_EXPORT RootFrameViewport final Member<ScrollableArea> layout_viewport_; }; -DEFINE_TYPE_CASTS(RootFrameViewport, - ScrollableArea, - scrollableArea, - scrollableArea->IsRootFrameViewport(), - scrollableArea.IsRootFrameViewport()); +template <> +struct DowncastTraits<RootFrameViewport> { + static bool AllowFrom(const ScrollableArea& scrollable_area) { + return scrollable_area.IsRootFrameViewport(); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc index 50dfcfce455..f33f50ebaf8 100644 --- a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc @@ -9,14 +9,14 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_scroll_into_view_params.h" +#include "third_party/blink/renderer/core/scroll/scroll_alignment.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/core/scroll/scrollable_area.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h" #include "third_party/blink/renderer/platform/geometry/double_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" -#include "third_party/blink/renderer/platform/scroll/scroll_alignment.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" namespace { blink::ScrollbarThemeMock scrollbar_theme_; diff --git a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc index c87d81d4eb5..fa7863d60c8 100644 --- a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc +++ b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc @@ -49,10 +49,11 @@ Node* FindNonEmptyAnchorNode(const FloatPoint& absolute_point, if (node_size.Width() * node_size.Height() > max_node_area) { IntSize point_offset = view_rect.Size(); point_offset.Scale(kViewportAnchorRelativeEpsilon); - HitTestLocation location(point + point_offset); + HitTestLocation alternative_location(point + point_offset); node = event_handler - .HitTestResultAtLocation(location, HitTestRequest::kReadOnly | - HitTestRequest::kActive) + .HitTestResultAtLocation( + alternative_location, + HitTestRequest::kReadOnly | HitTestRequest::kActive) .InnerNode(); } diff --git a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc index 24cada8b0bb..5de482ca06e 100644 --- a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc +++ b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/frame/sandbox_flags.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" +#include "third_party/blink/renderer/core/feature_policy/feature_policy.h" #include "third_party/blink/renderer/core/html/html_iframe_element.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -74,9 +75,7 @@ SandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy, sandbox_token, "allow-top-navigation-by-user-activation")) { flags &= ~kSandboxTopNavigationByUserActivation; } else if (EqualIgnoringASCIICase( - sandbox_token, "allow-downloads-without-user-activation") && - RuntimeEnabledFeatures:: - BlockingDownloadsInSandboxWithoutUserActivationEnabled()) { + sandbox_token, "allow-downloads-without-user-activation")) { flags &= ~kSandboxDownloads; } else { token_errors.Append(token_errors.IsEmpty() ? "'" : ", '"); @@ -96,6 +95,43 @@ SandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy, return flags; } +void ApplySandboxFlagsToParsedFeaturePolicy( + SandboxFlags sandbox_flags, + ParsedFeaturePolicy& parsed_feature_policy) { + if ((sandbox_flags & kSandboxTopNavigation)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kTopNavigation, + parsed_feature_policy); + } + if ((sandbox_flags & kSandboxForms)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kFormSubmission, + parsed_feature_policy); + } + if ((sandbox_flags & kSandboxScripts)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kScript, + parsed_feature_policy); + } + if ((sandbox_flags & kSandboxPopups)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kPopups, + parsed_feature_policy); + } + if ((sandbox_flags & kSandboxPointerLock)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kPointerLock, + parsed_feature_policy); + } + if ((sandbox_flags & kSandboxModals)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kModals, + parsed_feature_policy); + } + if ((sandbox_flags & kSandboxOrientationLock)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kOrientationLock, + parsed_feature_policy); + } + if ((sandbox_flags & kSandboxPresentationController)) { + DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kPresentation, + parsed_feature_policy); + } +} + STATIC_ASSERT_ENUM(WebSandboxFlags::kNone, kSandboxNone); STATIC_ASSERT_ENUM(WebSandboxFlags::kNavigation, kSandboxNavigation); STATIC_ASSERT_ENUM(WebSandboxFlags::kPlugins, kSandboxPlugins); diff --git a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h index 336416e0364..01a0e55c4fd 100644 --- a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h +++ b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h @@ -27,6 +27,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SANDBOX_FLAGS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SANDBOX_FLAGS_H_ +#include <vector> + +#include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/renderer/core/dom/space_split_string.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -67,6 +70,11 @@ typedef int SandboxFlags; SandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy, String& invalid_tokens_error_message); +// Applies the sandbox flags as parsed feature policies; If a flag is present +// both in the provided flags and in the parsed feature as a feature policy, +// the parsed policy takes precedence. +void ApplySandboxFlagsToParsedFeaturePolicy(SandboxFlags, ParsedFeaturePolicy&); + } // namespace blink #endif diff --git a/chromium/third_party/blink/renderer/core/frame/scheduling.cc b/chromium/third_party/blink/renderer/core/frame/scheduling.cc new file mode 100644 index 00000000000..bd915e17b38 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/scheduling.cc @@ -0,0 +1,63 @@ +// Copyright 2019 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/frame/scheduling.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/origin_trials/origin_trials.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h" +#include "third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" + +namespace blink { + +bool Scheduling::isInputPending(ScriptState* script_state, + const Vector<String>& input_types) const { + DCHECK(origin_trials::ExperimentalIsInputPendingEnabled( + ExecutionContext::From(script_state))); + + if (!Platform::Current()->IsLockedToSite()) { + // As we're interested in checking pending events for as many frames as we + // can on the main thread, restrict the API to the case where all frames in + // a process are part of the same site to avoid leaking cross-site inputs. + ExecutionContext::From(script_state) + ->AddConsoleMessage(ConsoleMessage::Create( + kJSMessageSource, mojom::ConsoleMessageLevel::kWarning, + "isInputPending requires site-per-process (crbug.com/910421).")); + return false; + } + + auto* scheduler = ThreadScheduler::Current(); + auto input_info = scheduler->GetPendingUserInputInfo(); + if (input_types.size() == 0) { + // If unspecified, return true if any input type is pending. + return input_info.HasPendingInputType( + scheduler::PendingUserInputType::kAny); + } + + bool has_pending_input = false; + for (const String& input_type_string : input_types) { + const auto pending_input_type = scheduler::PendingUserInput::TypeFromString( + AtomicString(input_type_string)); + if (pending_input_type == scheduler::PendingUserInputType::kNone) { + StringBuilder message; + message.Append("Unknown input event type \""); + message.Append(input_type_string); + message.Append("\". Skipping."); + ExecutionContext::From(script_state) + ->AddConsoleMessage(ConsoleMessage::Create( + kJSMessageSource, mojom::ConsoleMessageLevel::kWarning, + message.ToString())); + } + + if (!has_pending_input) + has_pending_input |= input_info.HasPendingInputType(pending_input_type); + } + return has_pending_input; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/scheduling.h b/chromium/third_party/blink/renderer/core/frame/scheduling.h new file mode 100644 index 00000000000..ebd1564b48e --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/scheduling.h @@ -0,0 +1,25 @@ +// Copyright 2019 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_FRAME_SCHEDULING_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SCHEDULING_H_ + +#include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +// Low-level scheduling primitives for JS scheduler implementations. +class Scheduling : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + bool isInputPending(ScriptState*, const Vector<String>& input_types) const; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SCHEDULING_H_ diff --git a/chromium/third_party/blink/renderer/core/frame/scheduling.idl b/chromium/third_party/blink/renderer/core/frame/scheduling.idl new file mode 100644 index 00000000000..6da751656ea --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/scheduling.idl @@ -0,0 +1,9 @@ +// Copyright 2019 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. + +// https://github.com/tdresser/is-input-pending +[OriginTrialEnabled=ExperimentalIsInputPending] +interface Scheduling { + [CallWith=ScriptState, MeasureAs=SchedulingIsInputPending, OriginTrialEnabled=ExperimentalIsInputPending] boolean isInputPending(optional sequence<DOMString> inputTypes = []); +}; diff --git a/chromium/third_party/blink/renderer/core/frame/screen.h b/chromium/third_party/blink/renderer/core/frame/screen.h index 06342fa8d66..bcf0265c5e0 100644 --- a/chromium/third_party/blink/renderer/core/frame/screen.h +++ b/chromium/third_party/blink/renderer/core/frame/screen.h @@ -30,7 +30,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SCREEN_H_ #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/supplementable.h" diff --git a/chromium/third_party/blink/renderer/core/frame/settings.cc b/chromium/third_party/blink/renderer/core/frame/settings.cc index 1c2bbcf5a96..ad503d2955d 100644 --- a/chromium/third_party/blink/renderer/core/frame/settings.cc +++ b/chromium/third_party/blink/renderer/core/frame/settings.cc @@ -31,6 +31,7 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" +#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" namespace blink { @@ -106,4 +107,17 @@ bool Settings::MockScrollbarsEnabled() { return ScrollbarTheme::MockScrollbarsEnabled(); } +void Settings::SetForceDarkModeEnabled(bool enabled) { + if (force_dark_mode_ == enabled) + return; + force_dark_mode_ = enabled; + + if (force_dark_mode_) { + SetHighContrastMode(DarkMode::kInvertLightness); + SetHighContrastImagePolicy(DarkModeImagePolicy::kFilterSmart); + } else { + SetHighContrastMode(DarkMode::kOff); + } +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/settings.h b/chromium/third_party/blink/renderer/core/frame/settings.h index 3df729d1550..688bf8e3d61 100644 --- a/chromium/third_party/blink/renderer/core/frame/settings.h +++ b/chromium/third_party/blink/renderer/core/frame/settings.h @@ -48,7 +48,7 @@ #include "third_party/blink/renderer/core/settings_macros.h" #include "third_party/blink/renderer/platform/fonts/generic_font_family_settings.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" -#include "third_party/blink/renderer/platform/graphics/high_contrast_settings.h" +#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" #include "third_party/blink/renderer/platform/graphics/image_animation_policy.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -81,6 +81,9 @@ class CORE_EXPORT Settings { return text_autosizing_window_size_override_; } + void SetForceDarkModeEnabled(bool enabled); + bool ForceDarkModeEnabled() const { return force_dark_mode_; } + SETTINGS_GETTERS_AND_SETTERS // FIXME: This does not belong here. @@ -100,6 +103,7 @@ class CORE_EXPORT Settings { IntSize text_autosizing_window_size_override_; bool text_autosizing_enabled_ : 1; bool bypass_csp_ = false; + bool force_dark_mode_ = false; SETTINGS_MEMBER_VARIABLES diff --git a/chromium/third_party/blink/renderer/core/frame/settings.json5 b/chromium/third_party/blink/renderer/core/frame/settings.json5 index e6c29b1b15b..59c9d0397a4 100644 --- a/chromium/third_party/blink/renderer/core/frame/settings.json5 +++ b/chromium/third_party/blink/renderer/core/frame/settings.json5 @@ -273,17 +273,6 @@ initial: false, }, - // Limited use by features which behave differently depending on the input - // devices available. For example, the pointer and hover media queries. - // Note that we need to be careful when basing behavior or UI on this - - // just because a device is present doesn't mean the user cares about it - // or uses it (i.e. Chromebook Pixel users generally don't want to give up - // screen real estate just because they happen to have a touchscreen). - { - name: "deviceSupportsTouch", - initial: false, - }, - // This value indicates the number of simultaneous multi-touch points supported // by the currently connected screen/digitizer that supports the most points. // From Pointer Events spec: @@ -585,6 +574,7 @@ { name: "forceAndroidOverlayScrollbar", initial: false, + invalidate: "ScrollbarLayout", }, // Set the timeout seconds of the network-quiet timers in IdlenessDetector. @@ -847,13 +837,6 @@ type: "PassiveListenerDefault", }, - // Some platforms have media subsystems which are too buggy to allow preloading - // of content by default. See http://crbug.com/612909 for details. - { - name: "forcePreloadNoneForMediaElements", - initial: false, - }, - { name: "hideScrollbars", initial: false, @@ -902,30 +885,40 @@ }, // - // High contrast mode + // Dark mode // { + // TODO(crbug.com/938511): Rename this to "darkMode" (not "darkModeMode"). name: "highContrastMode", - initial: "HighContrastMode::kOff", - type: "HighContrastMode", + initial: "DarkMode::kOff", + type: "DarkMode", + invalidate: "Paint", }, { + // TODO(crbug.com/938511): Rename this to "darkModeGrayscale". name: "highContrastGrayscale", initial: false, + invalidate: "Paint", }, { + // TODO(crbug.com/938511): Rename this to "darkModeContrast". name: "highContrastContrast", initial: 0, type: "double", + invalidate: "Paint", }, { + // TODO(crbug.com/938511): Rename this to "darkModeImagePolicy". name: "highContrastImagePolicy", - initial: "HighContrastImagePolicy::kFilterAll", - type: "HighContrastImagePolicy", + initial: "DarkModeImagePolicy::kFilterAll", + type: "DarkModeImagePolicy", + invalidate: "Paint", }, { - name: "mediaDownloadInProductHelpEnabled", - initial: false, + name: "darkModePagePolicy", + initial: "DarkModePagePolicy::kFilterByBackground", + type: "DarkModePagePolicy", + invalidate: "Paint", }, { name: "navigatorPlatformOverride", @@ -950,32 +943,32 @@ // { name: "lazyFrameLoadingDistanceThresholdPxUnknown", - initial: 800, + initial: 6000, type: "int", }, { name: "lazyFrameLoadingDistanceThresholdPxOffline", - initial: 800, + initial: 8000, type: "int", }, { name: "lazyFrameLoadingDistanceThresholdPxSlow2G", - initial: 800, + initial: 8000, type: "int", }, { name: "lazyFrameLoadingDistanceThresholdPx2G", - initial: 800, + initial: 6000, type: "int", }, { name: "lazyFrameLoadingDistanceThresholdPx3G", - initial: 800, + initial: 5000, type: "int", }, { name: "lazyFrameLoadingDistanceThresholdPx4G", - initial: 800, + initial: 4000, type: "int", }, @@ -984,32 +977,32 @@ // { name: "lazyImageLoadingDistanceThresholdPxUnknown", - initial: 800, + initial: 5000, type: "int", }, { name: "lazyImageLoadingDistanceThresholdPxOffline", - initial: 800, + initial: 8000, type: "int", }, { name: "lazyImageLoadingDistanceThresholdPxSlow2G", - initial: 800, + initial: 8000, type: "int", }, { name: "lazyImageLoadingDistanceThresholdPx2G", - initial: 800, + initial: 6000, type: "int", }, { name: "lazyImageLoadingDistanceThresholdPx3G", - initial: 800, + initial: 4000, type: "int", }, { name: "lazyImageLoadingDistanceThresholdPx4G", - initial: 800, + initial: 3000, type: "int", }, diff --git a/chromium/third_party/blink/renderer/core/frame/settings_delegate.h b/chromium/third_party/blink/renderer/core/frame/settings_delegate.h index 548edcff823..deceb0abd52 100644 --- a/chromium/third_party/blink/renderer/core/frame/settings_delegate.h +++ b/chromium/third_party/blink/renderer/core/frame/settings_delegate.h @@ -67,6 +67,8 @@ class CORE_EXPORT SettingsDelegate { kMediaControlsChange, kPluginsChange, kHighlightAdsChange, + kPaintChange, + kScrollbarLayoutChange, }; virtual void SettingsChanged(ChangeType) = 0; diff --git a/chromium/third_party/blink/renderer/core/frame/smart_clip.cc b/chromium/third_party/blink/renderer/core/frame/smart_clip.cc index dda9cb4b971..538490eeea8 100644 --- a/chromium/third_party/blink/renderer/core/frame/smart_clip.cc +++ b/chromium/third_party/blink/renderer/core/frame/smart_clip.cc @@ -54,8 +54,8 @@ static IntRect ConvertToContentCoordinatesWithoutCollapsingToZero( } static Node* NodeInsideFrame(Node* node) { - if (node->IsFrameOwnerElement()) - return ToHTMLFrameOwnerElement(node)->contentDocument(); + if (auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(node)) + return frame_owner_element->contentDocument(); return nullptr; } diff --git a/chromium/third_party/blink/renderer/core/frame/use_counter.cc b/chromium/third_party/blink/renderer/core/frame/use_counter.cc index ec72ff34402..043255e59c8 100644 --- a/chromium/third_party/blink/renderer/core/frame/use_counter.cc +++ b/chromium/third_party/blink/renderer/core/frame/use_counter.cc @@ -1320,7 +1320,7 @@ void UseCounter::CountIfFeatureWouldBeBlockedByFeaturePolicy( if (!frame.GetSecurityContext()->GetSecurityOrigin()->CanAccess(topOrigin)) { // This frame is cross-origin with the top-level frame, and so would be // blocked without a feature policy. - UseCounter::Count(&frame, blocked_cross_origin); + UseCounter::Count(frame.GetDocument(), blocked_cross_origin); return; } @@ -1330,7 +1330,7 @@ void UseCounter::CountIfFeatureWouldBeBlockedByFeaturePolicy( const Frame* f = &frame; while (!f->IsMainFrame()) { if (!f->GetSecurityContext()->GetSecurityOrigin()->CanAccess(topOrigin)) { - UseCounter::Count(&frame, blocked_same_origin); + UseCounter::Count(frame.GetDocument(), blocked_same_origin); return; } f = f->Tree().Parent(); @@ -1375,16 +1375,6 @@ void UseCounter::DidCommitLoad(const LocalFrame* frame) { } } -// TODO(loonybear): Replace Count(LocalFrame*) by Count(DocumentLoader*). -void UseCounter::Count(const LocalFrame* frame, WebFeature feature) { - if (!frame) - return; - DocumentLoader* loader = frame->GetDocument() - ? frame->GetDocument()->Loader() - : frame->Loader().GetProvisionalDocumentLoader(); - UseCounter::Count(loader, feature); -} - void UseCounter::Count(DocumentLoader* loader, WebFeature feature) { if (!loader) return; @@ -1441,7 +1431,7 @@ void UseCounter::CountCrossOriginIframe(const Document& document, WebFeature feature) { LocalFrame* frame = document.GetFrame(); if (frame && frame->IsCrossOriginSubframe()) - Count(frame, feature); + Count(document, feature); } void UseCounter::ReportAndTraceMeasurementByCSSSampleId(int sample_id, diff --git a/chromium/third_party/blink/renderer/core/frame/use_counter.h b/chromium/third_party/blink/renderer/core/frame/use_counter.h index c3708c5c7bc..4d92c9c94ef 100644 --- a/chromium/third_party/blink/renderer/core/frame/use_counter.h +++ b/chromium/third_party/blink/renderer/core/frame/use_counter.h @@ -46,7 +46,7 @@ class ExecutionContext; class LocalFrame; class StyleSheetContents; // Definition for UseCounter features can be found in: -// third_party/blink/public/platform/web_feature.mojom +// third_party/blink/public/mojom/web_feature/web_feature.mojom // UseCounter is used for counting the number of times features of // Blink are used on real web pages and help us know commonly @@ -100,10 +100,6 @@ class CORE_EXPORT UseCounter { }; // "count" sets the bit for this feature to 1. Repeated calls are ignored. - // Count(const LocalFrame*) is being deprecated since during a navigation it - // may pick the wrong DocumentLoader (will guess and avoid using the - // provisional document loader when both loaders are present). - static void Count(const LocalFrame*, WebFeature); static void Count(DocumentLoader*, WebFeature); static void Count(const Document&, WebFeature); static void Count(ExecutionContext*, WebFeature); diff --git a/chromium/third_party/blink/renderer/core/frame/user_activation.idl b/chromium/third_party/blink/renderer/core/frame/user_activation.idl index 24b22ec20ed..f6a9ea05cb0 100644 --- a/chromium/third_party/blink/renderer/core/frame/user_activation.idl +++ b/chromium/third_party/blink/renderer/core/frame/user_activation.idl @@ -5,6 +5,6 @@ // https://github.com/dtapuska/useractivation [RuntimeEnabled=UserActivationAPI] interface UserActivation { - readonly attribute boolean hasBeenActive; - readonly attribute boolean isActive; + [Measure] readonly attribute boolean hasBeenActive; + [Measure] readonly attribute boolean isActive; }; diff --git a/chromium/third_party/blink/renderer/core/frame/user_agent.idl b/chromium/third_party/blink/renderer/core/frame/user_agent.idl new file mode 100644 index 00000000000..2223b791477 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/user_agent.idl @@ -0,0 +1,14 @@ +// Copyright 2019 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. + +// https://github.com/WICG/ua-client-hints +[ + Exposed=Window +] dictionary UserAgent { + DOMString brand = ""; + DOMString version = ""; + DOMString platform = ""; + DOMString architecture = ""; + DOMString model = ""; +}; diff --git a/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc b/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc index b22e342c3df..0f69691208d 100644 --- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc @@ -32,6 +32,7 @@ #include <memory> +#include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/picture_layer.h" #include "cc/layers/scrollbar_layer_interface.h" #include "third_party/blink/public/platform/task_type.h" @@ -143,7 +144,7 @@ void VisualViewport::UpdatePaintPropertyNodesIfNeeded( if (inner_viewport_container_layer_) { inner_viewport_container_layer_->SetLayerState( - PropertyTreeState(transform_parent, clip_parent, effect_parent), + PropertyTreeState(*transform_parent, *clip_parent, *effect_parent), IntPoint()); } @@ -178,8 +179,7 @@ void VisualViewport::UpdatePaintPropertyNodesIfNeeded( if (page_scale_layer_) { page_scale_layer_->SetLayerState( - PropertyTreeState(scale_transform_node_.get(), clip_parent, - effect_parent), + PropertyTreeState(*scale_transform_node_, *clip_parent, *effect_parent), IntPoint()); } @@ -198,7 +198,7 @@ void VisualViewport::UpdatePaintPropertyNodesIfNeeded( if (MainFrame() && !MainFrame()->GetSettings()->GetThreadedScrollingEnabled()) { state.main_thread_scrolling_reasons = - MainThreadScrollingReason::kThreadedScrollingDisabled; + cc::MainThreadScrollingReason::kThreadedScrollingDisabled; } if (!scroll_node_) { @@ -226,8 +226,8 @@ void VisualViewport::UpdatePaintPropertyNodesIfNeeded( if (inner_viewport_scroll_layer_) { inner_viewport_scroll_layer_->SetLayerState( - PropertyTreeState(translation_transform_node_.get(), clip_parent, - effect_parent), + PropertyTreeState(*translation_transform_node_, *clip_parent, + *effect_parent), IntPoint()); } @@ -247,8 +247,8 @@ void VisualViewport::UpdatePaintPropertyNodesIfNeeded( } overlay_scrollbar_horizontal_->SetLayerState( - PropertyTreeState(transform_parent, context.current.clip, - horizontal_scrollbar_effect_node_.get()), + PropertyTreeState(*transform_parent, *context.current.clip, + *horizontal_scrollbar_effect_node_), ScrollbarOffset(ScrollbarOrientation::kHorizontalScrollbar)); } @@ -267,8 +267,8 @@ void VisualViewport::UpdatePaintPropertyNodesIfNeeded( } overlay_scrollbar_vertical_->SetLayerState( - PropertyTreeState(transform_parent, context.current.clip, - vertical_scrollbar_effect_node_.get()), + PropertyTreeState(*transform_parent, *context.current.clip, + *vertical_scrollbar_effect_node_), ScrollbarOffset(ScrollbarOrientation::kVerticalScrollbar)); } } @@ -512,7 +512,7 @@ bool VisualViewport::DidSetScaleOrLocation(float scale, MainFrame()->GetEventHandler().MayUpdateHoverWhenContentUnderMouseChanged( MouseEventManager::UpdateHoverReason::kScrollOffsetChanged); - probe::didChangeViewport(MainFrame()); + probe::DidChangeViewport(MainFrame()); MainFrame()->Loader().SaveScrollState(); ClampToBoundaries(); @@ -1088,7 +1088,7 @@ bool VisualViewport::ShouldDisableDesktopWorkarounds() const { constraints.minimum_scale != -1); } -CompositorAnimationHost* VisualViewport::GetCompositorAnimationHost() const { +cc::AnimationHost* VisualViewport::GetCompositorAnimationHost() const { DCHECK(GetPage().MainFrame()->IsLocalFrame()); ScrollingCoordinator* c = GetPage().GetScrollingCoordinator(); return c ? c->GetCompositorAnimationHost() : nullptr; diff --git a/chromium/third_party/blink/renderer/core/frame/visual_viewport.h b/chromium/third_party/blink/renderer/core/frame/visual_viewport.h index 2ca09611cb7..92597c15146 100644 --- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.h +++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.h @@ -38,16 +38,19 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/core/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" -namespace blink { +namespace cc { +class AnimationHost; +} +namespace blink { class EffectPaintPropertyNode; class GraphicsContext; class GraphicsLayer; @@ -224,7 +227,7 @@ class CORE_EXPORT VisualViewport final GraphicsLayer* LayerForHorizontalScrollbar() const override; GraphicsLayer* LayerForVerticalScrollbar() const override; bool ScheduleAnimation() override; - CompositorAnimationHost* GetCompositorAnimationHost() const override; + cc::AnimationHost* GetCompositorAnimationHost() const override; CompositorAnimationTimeline* GetCompositorAnimationTimeline() const override; IntRect VisibleContentRect( IncludeScrollbarsInRect = kExcludeScrollbars) const override; diff --git a/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc index 078b245ce53..5bd7181bbf5 100644 --- a/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc @@ -209,7 +209,7 @@ class VisualViewportTest : public testing::Test, frame_test_helpers::WebViewHelper helper_; }; -INSTANTIATE_PAINT_TEST_CASE_P(VisualViewportTest); +INSTANTIATE_PAINT_TEST_SUITE_P(VisualViewportTest); // Test that resizing the VisualViewport works as expected and that resizing the // WebView resizes the VisualViewport. @@ -380,8 +380,9 @@ TEST_P(VisualViewportTest, TestResizeAfterVerticalScroll) { visual_viewport.GetScrollTranslationNode()->Matrix()); EXPECT_EQ(TransformationMatrix().Scale(2).Translate(0, -300), GeometryMapper::SourceToDestinationProjection( - visual_viewport.GetScrollTranslationNode(), - &TransformPaintPropertyNode::Root())); + *visual_viewport.GetScrollTranslationNode(), + TransformPaintPropertyNode::Root()) + .Matrix()); } // Perform the resizing @@ -404,8 +405,9 @@ TEST_P(VisualViewportTest, TestResizeAfterVerticalScroll) { visual_viewport.GetScrollTranslationNode()->Matrix()); EXPECT_EQ(TransformationMatrix().Scale(4).Translate(0, -75), GeometryMapper::SourceToDestinationProjection( - visual_viewport.GetScrollTranslationNode(), - &TransformPaintPropertyNode::Root())); + *visual_viewport.GetScrollTranslationNode(), + TransformPaintPropertyNode::Root()) + .Matrix()); } } @@ -468,8 +470,9 @@ TEST_P(VisualViewportTest, TestResizeAfterHorizontalScroll) { visual_viewport.GetScrollTranslationNode()->Matrix()); EXPECT_EQ(TransformationMatrix().Scale(2).Translate(-150, 0), GeometryMapper::SourceToDestinationProjection( - visual_viewport.GetScrollTranslationNode(), - &TransformPaintPropertyNode::Root())); + *visual_viewport.GetScrollTranslationNode(), + TransformPaintPropertyNode::Root()) + .Matrix()); } WebView()->MainFrameWidget()->Resize(IntSize(200, 100)); @@ -491,8 +494,9 @@ TEST_P(VisualViewportTest, TestResizeAfterHorizontalScroll) { visual_viewport.GetScrollTranslationNode()->Matrix()); EXPECT_EQ(TransformationMatrix().Scale(4).Translate(-150, 0), GeometryMapper::SourceToDestinationProjection( - visual_viewport.GetScrollTranslationNode(), - &TransformPaintPropertyNode::Root())); + *visual_viewport.GetScrollTranslationNode(), + TransformPaintPropertyNode::Root()) + .Matrix()); } } @@ -959,16 +963,17 @@ TEST_P(VisualViewportTest, TestSavedToHistoryItem) { RegisterMockedHttpURLLoad("200-by-300.html"); NavigateTo(base_url_ + "200-by-300.html"); - EXPECT_EQ(nullptr, ToLocalFrame(WebView()->GetPage()->MainFrame()) - ->Loader() - .GetDocumentLoader() - ->GetHistoryItem() - ->GetViewState()); + EXPECT_FALSE(To<LocalFrame>(WebView()->GetPage()->MainFrame()) + ->Loader() + .GetDocumentLoader() + ->GetHistoryItem() + ->GetViewState() + .has_value()); VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport(); visual_viewport.SetScale(2); - EXPECT_EQ(2, ToLocalFrame(WebView()->GetPage()->MainFrame()) + EXPECT_EQ(2, To<LocalFrame>(WebView()->GetPage()->MainFrame()) ->Loader() .GetDocumentLoader() ->GetHistoryItem() @@ -978,7 +983,7 @@ TEST_P(VisualViewportTest, TestSavedToHistoryItem) { visual_viewport.SetLocation(FloatPoint(10, 20)); EXPECT_EQ(ScrollOffset(10, 20), - ToLocalFrame(WebView()->GetPage()->MainFrame()) + To<LocalFrame>(WebView()->GetPage()->MainFrame()) ->Loader() .GetDocumentLoader() ->GetHistoryItem() @@ -2154,7 +2159,7 @@ TEST_P(VisualViewportTest, ResizeCompositedAndFixedBackground) { UpdateAllLifecyclePhases(); Document* document = - ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); + To<LocalFrame>(web_view_impl->GetPage()->MainFrame())->GetDocument(); GraphicsLayer* backgroundLayer = document->GetLayoutView() ->Layer() ->GetCompositedLayerMapping() @@ -2196,6 +2201,10 @@ static void ConfigureAndroidNonCompositing(WebSettings* settings) { // Make sure a non-composited background-attachment:fixed background gets // resized by browser controls. TEST_P(VisualViewportTest, ResizeNonCompositedAndFixedBackground) { + // This test needs the |FastMobileScrolling| feature to be disabled + // although it is stable on Android. + ScopedFastMobileScrollingForTest fast_mobile_scrolling(false); + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; @@ -2228,7 +2237,7 @@ TEST_P(VisualViewportTest, ResizeNonCompositedAndFixedBackground) { base_url); UpdateAllLifecyclePhases(); Document* document = - ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); + To<LocalFrame>(web_view_impl->GetPage()->MainFrame())->GetDocument(); document->View()->SetTracksPaintInvalidations(true); web_view_impl->ResizeWithBrowserControls(WebSize(page_width, smallest_height), browser_controls_height, 0, true); @@ -2298,7 +2307,7 @@ TEST_P(VisualViewportTest, ResizeNonFixedBackgroundNoLayoutOrInvalidation) { base_url); UpdateAllLifecyclePhases(); Document* document = - ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); + To<LocalFrame>(web_view_impl->GetPage()->MainFrame())->GetDocument(); // A resize will do a layout synchronously so manually check that we don't // setNeedsLayout from viewportSizeChanged. @@ -2346,7 +2355,7 @@ TEST_P(VisualViewportTest, InvalidateLayoutViewWhenDocumentSmallerThanView) { frame_test_helpers::LoadFrame(web_view_impl->MainFrameImpl(), "about:blank"); UpdateAllLifecyclePhases(); Document* document = - ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); + To<LocalFrame>(web_view_impl->GetPage()->MainFrame())->GetDocument(); // Do a resize to check for invalidations. document->View()->SetTracksPaintInvalidations(true); @@ -2430,22 +2439,20 @@ TEST_P(VisualViewportTest, EnsureEffectNodeForScrollbars) { GetFrame()->GetPage()->GetChromeClient().WindowToViewportScalar( theme.ScrollbarThickness(kRegularScrollbar)))); - EXPECT_TRUE(vertical_scrollbar_state.Effect()); - EXPECT_EQ(vertical_scrollbar_state.Effect()->GetCompositorElementId(), + EXPECT_EQ(vertical_scrollbar_state.Effect().GetCompositorElementId(), visual_viewport.GetScrollbarElementId( ScrollbarOrientation::kVerticalScrollbar)); EXPECT_EQ(vertical_scrollbar->GetOffsetFromTransformNode(), IntPoint(400 - scrollbar_thickness, 0)); - EXPECT_TRUE(horizontal_scrollbar_state.Effect()); - EXPECT_EQ(horizontal_scrollbar_state.Effect()->GetCompositorElementId(), + EXPECT_EQ(horizontal_scrollbar_state.Effect().GetCompositorElementId(), visual_viewport.GetScrollbarElementId( ScrollbarOrientation::kHorizontalScrollbar)); EXPECT_EQ(horizontal_scrollbar->GetOffsetFromTransformNode(), IntPoint(0, 400 - scrollbar_thickness)); - EXPECT_EQ(vertical_scrollbar_state.Effect()->Parent(), - horizontal_scrollbar_state.Effect()->Parent()); + EXPECT_EQ(vertical_scrollbar_state.Effect().Parent(), + horizontal_scrollbar_state.Effect().Parent()); } // Make sure we don't crash when the visual viewport's height is 0. This can diff --git a/chromium/third_party/blink/renderer/core/frame/web_feature.h b/chromium/third_party/blink/renderer/core/frame/web_feature.h index a6d56e4a407..c5b655e7a3c 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_feature.h +++ b/chromium/third_party/blink/renderer/core/frame/web_feature.h @@ -9,7 +9,7 @@ // is heavy on the compiler. Those who do not need the definition, but could do // with just a forward-declaration, should include WebFeatureForward.h instead. -#include "third_party/blink/public/platform/web_feature.mojom-blink.h" +#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" namespace blink { using WebFeature = mojom::WebFeature; diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc index 224dd0b51ee..83d68f25ab8 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc @@ -305,9 +305,8 @@ void WebFrameSerializerImpl::OpenTagToString(Element* element, // Find out if we need to do frame-specific link rewriting. WebFrame* frame = nullptr; - if (element->IsFrameOwnerElement()) { - frame = - WebFrame::FromFrame(ToHTMLFrameOwnerElement(element)->ContentFrame()); + if (auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(element)) { + frame = WebFrame::FromFrame(frame_owner_element->ContentFrame()); } WebString rewritten_frame_link; bool should_rewrite_frame_src = @@ -447,7 +446,7 @@ WebFrameSerializerImpl::WebFrameSerializerImpl( xml_entities_(true) { // Must specify available webframe. DCHECK(frame); - specified_web_local_frame_impl_ = ToWebLocalFrameImpl(frame); + specified_web_local_frame_impl_ = To<WebLocalFrameImpl>(frame); // Make sure we have non null client and delegate. DCHECK(client); DCHECK(delegate); diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc index 2267de355f5..02e37c10a3a 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc @@ -32,6 +32,8 @@ #include "third_party/blink/renderer/core/page/focus_controller.h" #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/platform/graphics/animation_worklet_mutator_dispatcher_impl.h" +#include "third_party/blink/renderer/platform/graphics/compositor_mutator_client.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" namespace blink { @@ -55,13 +57,12 @@ WebFrameWidgetBase::WebFrameWidgetBase(WebWidgetClient& client) WebFrameWidgetBase::~WebFrameWidgetBase() = default; void WebFrameWidgetBase::BindLocalRoot(WebLocalFrame& local_root) { - local_root_ = ToWebLocalFrameImpl(local_root); + local_root_ = To<WebLocalFrameImpl>(local_root); local_root_->SetFrameWidget(this); - - Initialize(); } void WebFrameWidgetBase::Close() { + mutator_dispatcher_ = nullptr; local_root_->SetFrameWidget(nullptr); local_root_ = nullptr; client_ = nullptr; @@ -450,4 +451,18 @@ WebLocalFrame* WebFrameWidgetBase::FocusedWebLocalFrameInWidget() const { return WebLocalFrameImpl::FromFrame(FocusedLocalFrameInWidget()); } +base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> +WebFrameWidgetBase::EnsureCompositorMutatorDispatcher( + scoped_refptr<base::SingleThreadTaskRunner>* mutator_task_runner) { + if (!mutator_task_runner_) { + GetLayerTreeView()->SetMutatorClient( + AnimationWorkletMutatorDispatcherImpl::CreateCompositorThreadClient( + &mutator_dispatcher_, &mutator_task_runner_)); + } + + DCHECK(mutator_task_runner_); + *mutator_task_runner = mutator_task_runner_; + return mutator_dispatcher_; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h index f2b86f7ae9a..1ae9637611d 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h +++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h @@ -16,8 +16,10 @@ #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_image.h" #include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace cc { +class AnimationHost; class Layer; } @@ -27,7 +29,6 @@ class Point; namespace blink { class AnimationWorkletMutatorDispatcherImpl; -class CompositorAnimationHost; class GraphicsLayer; class HitTestResult; class PageWidgetEventHandler; @@ -53,13 +54,15 @@ class CORE_EXPORT WebFrameWidgetBase void BindLocalRoot(WebLocalFrame&); - // Called once the local root is bound via |BindLocalRoot()|. - virtual void Initialize() = 0; virtual bool ForSubframe() const = 0; virtual void IntrinsicSizingInfoChanged(const IntrinsicSizingInfo&) {} - virtual base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> + + // Creates or returns cached mutator dispatcher. This usually requires a + // round trip to the compositor. The returned WeakPtr must only be + // dereferenced on the output |mutator_task_runner|. + base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> EnsureCompositorMutatorDispatcher( - scoped_refptr<base::SingleThreadTaskRunner>* mutator_task_runner) = 0; + scoped_refptr<base::SingleThreadTaskRunner>* mutator_task_runner); // Sets the root graphics layer. |GraphicsLayer| can be null when detaching // the root layer. @@ -70,7 +73,7 @@ class CORE_EXPORT WebFrameWidgetBase virtual void SetRootLayer(scoped_refptr<cc::Layer> layer) = 0; virtual WebLayerTreeView* GetLayerTreeView() const = 0; - virtual CompositorAnimationHost* AnimationHost() const = 0; + virtual cc::AnimationHost* AnimationHost() const = 0; virtual HitTestResult CoreHitTestResultAt(const gfx::Point&) = 0; @@ -189,10 +192,21 @@ class CORE_EXPORT WebFrameWidgetBase static bool ignore_input_events_; scoped_refptr<UserGestureToken> pointer_lock_gesture_token_; + // This is owned by the LayerTreeHostImpl, and should only be used on the + // compositor thread, so we keep the TaskRunner where you post tasks to + // make that happen. + base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> mutator_dispatcher_; + scoped_refptr<base::SingleThreadTaskRunner> mutator_task_runner_; + friend class WebViewImpl; }; -DEFINE_TYPE_CASTS(WebFrameWidgetBase, WebFrameWidget, widget, true, true); +template <> +struct DowncastTraits<WebFrameWidgetBase> { + // All concrete implementations of WebFrameWidget are derived from + // WebFrameWidgetBase. + static bool AllowFrom(const WebFrameWidget& widget) { return true; } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index f927f69844e..a837a358c10 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc @@ -60,6 +60,7 @@ #include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/remote_frame.h" #include "third_party/blink/renderer/core/frame/settings.h" @@ -67,6 +68,7 @@ #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/frame/web_view_frame_widget.h" #include "third_party/blink/renderer/core/html/forms/html_text_area_element.h" +#include "third_party/blink/renderer/core/html/html_plugin_element.h" #include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h" #include "third_party/blink/renderer/core/input/event_handler.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -79,10 +81,7 @@ #include "third_party/blink/renderer/core/page/pointer_lock_controller.h" #include "third_party/blink/renderer/core/page/validation_message_client.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" -#include "third_party/blink/renderer/platform/animation/compositor_animation_host.h" -#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.h" #include "third_party/blink/renderer/platform/graphics/color.h" -#include "third_party/blink/renderer/platform/graphics/compositor_mutator_client.h" #include "third_party/blink/renderer/platform/keyboard_codes.h" namespace blink { @@ -114,7 +113,7 @@ WebFrameWidget* WebFrameWidget::CreateForMainFrame(WebWidgetClient* client, // |main_frame|'s WebViewImpl. // Note: this can't DCHECK that the view's main frame points to // |main_frame|, as provisional frames violate this precondition. - WebLocalFrameImpl& main_frame_impl = ToWebLocalFrameImpl(*main_frame); + WebLocalFrameImpl& main_frame_impl = To<WebLocalFrameImpl>(*main_frame); DCHECK(main_frame_impl.ViewImpl()); WebViewImpl& web_view_impl = *main_frame_impl.ViewImpl(); @@ -152,33 +151,29 @@ WebFrameWidgetImpl* WebFrameWidgetImpl::Create(WebWidgetClient& client) { WebFrameWidgetImpl::WebFrameWidgetImpl(WebWidgetClient& client) : WebFrameWidgetBase(client), - mutator_dispatcher_(nullptr), - layer_tree_view_(nullptr), - root_layer_(nullptr), - root_graphics_layer_(nullptr), - is_accelerated_compositing_active_(false), - layer_tree_view_closed_(false), - suppress_next_keypress_event_(false), - ime_accept_events_(true), self_keep_alive_(this) {} WebFrameWidgetImpl::~WebFrameWidgetImpl() = default; void WebFrameWidgetImpl::Trace(blink::Visitor* visitor) { - visitor->Trace(mouse_capture_node_); + visitor->Trace(mouse_capture_element_); WebFrameWidgetBase::Trace(visitor); } // WebWidget ------------------------------------------------------------------ void WebFrameWidgetImpl::Close() { + if (layer_tree_view_) { + GetPage()->WillCloseLayerTreeView(*layer_tree_view_, + LocalRootImpl()->GetFrame()->View()); + } + WebFrameWidgetBase::Close(); - mutator_dispatcher_ = nullptr; layer_tree_view_ = nullptr; + animation_host_ = nullptr; root_layer_ = nullptr; root_graphics_layer_ = nullptr; - animation_host_ = nullptr; self_keep_alive_.Clear(); } @@ -232,13 +227,7 @@ void WebFrameWidgetImpl::SendResizeEventAndRepaint() { LocalRootImpl()->GetFrame()->GetDocument()->EnqueueResizeEvent(); } - DCHECK(Client()); - if (IsAcceleratedCompositingActive()) { - UpdateLayerTreeViewport(); - } else { - WebRect damaged_rect(0, 0, size_->width, size_->height); - Client()->DidInvalidateRect(damaged_rect); - } + UpdateLayerTreeViewport(); } void WebFrameWidgetImpl::ResizeVisualViewport(const WebSize& new_size) { @@ -284,7 +273,8 @@ void WebFrameWidgetImpl::SetSuppressFrameRequestsWorkaroundFor704763Only( GetPage()->Animator().SetSuppressFrameRequestsWorkaroundFor704763Only( suppress_frame_requests); } -void WebFrameWidgetImpl::BeginFrame(base::TimeTicks last_frame_time) { +void WebFrameWidgetImpl::BeginFrame(base::TimeTicks last_frame_time, + bool record_main_frame_metrics) { TRACE_EVENT1("blink", "WebFrameWidgetImpl::beginFrame", "frameTime", last_frame_time); DCHECK(!last_frame_time.is_null()); @@ -294,19 +284,53 @@ void WebFrameWidgetImpl::BeginFrame(base::TimeTicks last_frame_time) { DocumentLifecycle::AllowThrottlingScope throttling_scope( LocalRootImpl()->GetFrame()->GetDocument()->Lifecycle()); - PageWidgetDelegate::Animate(*GetPage(), last_frame_time); + if (record_main_frame_metrics) { + SCOPED_UMA_AND_UKM_TIMER( + LocalRootImpl()->GetFrame()->View()->EnsureUkmAggregator(), + LocalFrameUkmAggregator::kAnimate); + PageWidgetDelegate::Animate(*GetPage(), last_frame_time); + } else { + PageWidgetDelegate::Animate(*GetPage(), last_frame_time); + } // Animate can cause the local frame to detach. if (LocalRootImpl()) GetPage()->GetValidationMessageClient().LayoutOverlay(); } +void WebFrameWidgetImpl::DidBeginFrame() { + DCHECK(LocalRootImpl()->GetFrame()); + PageWidgetDelegate::DidBeginFrame(*LocalRootImpl()->GetFrame()); +} + +void WebFrameWidgetImpl::BeginRafAlignedInput() { + raf_aligned_input_start_time_ = CurrentTimeTicks(); +} + +void WebFrameWidgetImpl::EndRafAlignedInput() { + if (LocalRootImpl()) { + LocalRootImpl()->GetFrame()->View()->EnsureUkmAggregator().RecordSample( + LocalFrameUkmAggregator::kHandleInputEvents, + raf_aligned_input_start_time_, CurrentTimeTicks()); + } +} + +void WebFrameWidgetImpl::RecordStartOfFrameMetrics() { + if (!LocalRootImpl()) + return; + + LocalRootImpl()->GetFrame()->View()->EnsureUkmAggregator().BeginMainFrame(); +} + void WebFrameWidgetImpl::RecordEndOfFrameMetrics( base::TimeTicks frame_begin_time) { if (!LocalRootImpl()) return; - LocalRootImpl()->GetFrame()->View()->RecordEndOfFrameMetrics( - frame_begin_time); + LocalRootImpl() + ->GetFrame() + ->View() + ->EnsureUkmAggregator() + .RecordEndOfFrameMetrics(frame_begin_time, CurrentTimeTicks()); } void WebFrameWidgetImpl::UpdateLifecycle(LifecycleUpdate requested_update, @@ -412,12 +436,12 @@ WebInputEventResult WebFrameWidgetImpl::HandleInputEvent( return WebInputEventResult::kHandledSystem; } - if (mouse_capture_node_ && + if (mouse_capture_element_ && WebInputEvent::IsMouseEventType(input_event.GetType())) { TRACE_EVENT1("input", "captured mouse event", "type", input_event.GetType()); // Save m_mouseCaptureNode since mouseCaptureLost() will clear it. - Node* node = mouse_capture_node_; + HTMLPlugInElement* target = mouse_capture_element_; // Not all platforms call mouseCaptureLost() directly. if (input_event.GetType() == WebInputEvent::kMouseUp) @@ -439,7 +463,7 @@ WebInputEventResult WebFrameWidgetImpl::HandleInputEvent( case WebInputEvent::kMouseDown: event_type = event_type_names::kMousedown; gesture_indicator = LocalFrame::NotifyUserActivation( - node->GetDocument().GetFrame(), UserGestureToken::kNewGesture); + target->GetDocument().GetFrame(), UserGestureToken::kNewGesture); mouse_capture_gesture_token_ = gesture_indicator->CurrentToken(); break; case WebInputEvent::kMouseUp: @@ -454,9 +478,9 @@ WebInputEventResult WebFrameWidgetImpl::HandleInputEvent( WebMouseEvent transformed_event = TransformWebMouseEvent(LocalRootImpl()->GetFrameView(), static_cast<const WebMouseEvent&>(input_event)); - if (LocalFrame* frame = node->GetDocument().GetFrame()) { + if (LocalFrame* frame = target->GetDocument().GetFrame()) { frame->GetEventHandler().HandleTargetedMouseEvent( - node, transformed_event, event_type, + target, transformed_event, event_type, TransformWebMouseEventVector( LocalRootImpl()->GetFrameView(), coalesced_event.GetCoalescedEventsPointers()), @@ -497,9 +521,6 @@ bool WebFrameWidgetImpl::ScrollFocusedEditableElementIntoView() { return true; } -void WebFrameWidgetImpl::Initialize() { -} - void WebFrameWidgetImpl::IntrinsicSizingInfoChanged( const IntrinsicSizingInfo& sizing_info) { WebIntrinsicSizingInfo web_sizing_info; @@ -510,26 +531,12 @@ void WebFrameWidgetImpl::IntrinsicSizingInfoChanged( Client()->IntrinsicSizingInfoChanged(web_sizing_info); } -base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> -WebFrameWidgetImpl::EnsureCompositorMutatorDispatcher( - scoped_refptr<base::SingleThreadTaskRunner>* mutator_task_runner) { - if (!mutator_task_runner_) { - layer_tree_view_->SetMutatorClient( - AnimationWorkletMutatorDispatcherImpl::CreateCompositorThreadClient( - &mutator_dispatcher_, &mutator_task_runner_)); - } - - DCHECK(mutator_task_runner_); - *mutator_task_runner = mutator_task_runner_; - return mutator_dispatcher_; -} - void WebFrameWidgetImpl::ApplyViewportChanges(const ApplyViewportChangesArgs&) { } void WebFrameWidgetImpl::MouseCaptureLost() { TRACE_EVENT_ASYNC_END0("input", "capturing mouse", this); - mouse_capture_node_ = nullptr; + mouse_capture_element_ = nullptr; } void WebFrameWidgetImpl::SetFocus(bool enable) { @@ -602,29 +609,16 @@ bool WebFrameWidgetImpl::IsAcceleratedCompositingActive() const { return is_accelerated_compositing_active_; } -void WebFrameWidgetImpl::WillCloseLayerTreeView() { - if (layer_tree_view_) { - GetPage()->WillCloseLayerTreeView(*layer_tree_view_, - LocalRootImpl()->GetFrame()->View()); - } - - SetIsAcceleratedCompositingActive(false); - mutator_dispatcher_ = nullptr; - layer_tree_view_ = nullptr; - animation_host_ = nullptr; - layer_tree_view_closed_ = true; -} - void WebFrameWidgetImpl::SetRemoteViewportIntersection( const WebRect& viewport_intersection, - bool occluded_or_obscured) { + FrameOcclusionState occlusion_state) { // Remote viewports are only applicable to local frames with remote ancestors. DCHECK(LocalRootImpl()->Parent() && LocalRootImpl()->Parent()->IsWebRemoteFrame() && LocalRootImpl()->GetFrame()); LocalRootImpl()->GetFrame()->SetViewportIntersectionFromParent( - viewport_intersection, occluded_or_obscured); + viewport_intersection, occlusion_state); } void WebFrameWidgetImpl::SetIsInert(bool inert) { @@ -686,17 +680,18 @@ void WebFrameWidgetImpl::HandleMouseDown(LocalFrame& main_frame, location)); result.SetToShadowHostIfInRestrictedShadowRoot(); Node* hit_node = result.InnerNode(); - if (!result.GetScrollbar() && hit_node && hit_node->GetLayoutObject() && - hit_node->GetLayoutObject()->IsEmbeddedObject()) { - mouse_capture_node_ = hit_node; + hit_node->GetLayoutObject()->IsEmbeddedObject() && + hit_node->IsHTMLElement() && + ToHTMLElement(hit_node)->IsPluginElement()) { + mouse_capture_element_ = ToHTMLPlugInElement(hit_node); TRACE_EVENT_ASYNC_BEGIN0("input", "capturing mouse", this); } } PageWidgetEventHandler::HandleMouseDown(main_frame, event); - if (event.button == WebMouseEvent::Button::kLeft && mouse_capture_node_) { + if (event.button == WebMouseEvent::Button::kLeft && mouse_capture_element_) { mouse_capture_gesture_token_ = main_frame.GetEventHandler().TakeLastMouseDownGestureToken(); } @@ -743,11 +738,10 @@ void WebFrameWidgetImpl::MouseContextMenu(const WebMouseEvent& event) { // is refactored, at which point focusedOrMainFrame will never return a // RemoteFrame. // See https://crbug.com/341918. - if (!target_frame->IsLocalFrame()) + LocalFrame* target_local_frame = DynamicTo<LocalFrame>(target_frame); + if (!target_local_frame) return; - LocalFrame* target_local_frame = ToLocalFrame(target_frame); - { ContextMenuAllowedScope scope; target_local_frame->GetEventHandler().SendContextMenuEvent( @@ -861,12 +855,10 @@ WebInputEventResult WebFrameWidgetImpl::HandleKeyEvent( // event. suppress_next_keypress_event_ = false; - Frame* focused_frame = FocusedCoreFrame(); - if (!focused_frame || !focused_frame->IsLocalFrame()) + auto* frame = DynamicTo<LocalFrame>(FocusedCoreFrame()); + if (!frame) return WebInputEventResult::kNotHandled; - LocalFrame* frame = ToLocalFrame(focused_frame); - WebInputEventResult result = frame->GetEventHandler().KeyEvent(event); if (result != WebInputEventResult::kNotHandled) { if (WebInputEvent::kRawKeyDown == event.GetType()) { @@ -919,7 +911,7 @@ WebInputEventResult WebFrameWidgetImpl::HandleCharEvent( bool suppress = suppress_next_keypress_event_; suppress_next_keypress_event_ = false; - LocalFrame* frame = ToLocalFrame(FocusedCoreFrame()); + LocalFrame* frame = To<LocalFrame>(FocusedCoreFrame()); if (!frame) { return suppress ? WebInputEventResult::kHandledSuppressed : WebInputEventResult::kNotHandled; @@ -970,16 +962,13 @@ Element* WebFrameWidgetImpl::FocusedElement() const { return document->FocusedElement(); } -void WebFrameWidgetImpl::SetLayerTreeView(WebLayerTreeView* layer_tree_view) { +void WebFrameWidgetImpl::SetLayerTreeView(WebLayerTreeView* layer_tree_view, + cc::AnimationHost* animation_host) { DCHECK(Client()); - DCHECK(!mutator_dispatcher_); layer_tree_view_ = layer_tree_view; - if (Platform::Current()->IsThreadedAnimationEnabled()) { - animation_host_ = std::make_unique<CompositorAnimationHost>( - layer_tree_view_->CompositorAnimationHost()); - } + animation_host_ = animation_host; - GetPage()->LayerTreeViewInitialized(*layer_tree_view_, + GetPage()->LayerTreeViewInitialized(*layer_tree_view_, *animation_host_, LocalRootImpl()->GetFrame()->View()); // TODO(kenrb): Currently GPU rasterization is always enabled for OOPIFs. @@ -989,31 +978,20 @@ void WebFrameWidgetImpl::SetLayerTreeView(WebLayerTreeView* layer_tree_view) { // be moved from WebViewImpl into WebFrameWidget and used for all local // frame roots. https://crbug.com/712794 layer_tree_view_->HeuristicsForGpuRasterizationUpdated(true); - - // WebFrameWidgetImpl is used for child frames, which always have a - // transparent background color. - layer_tree_view_->SetBackgroundColor(SK_ColorTRANSPARENT); } void WebFrameWidgetImpl::SetIsAcceleratedCompositingActive(bool active) { - // In the middle of shutting down; don't try to spin back up a compositor. - // FIXME: compositing startup/shutdown should be refactored so that it - // turns on explicitly rather than lazily, which causes this awkwardness. - if (layer_tree_view_closed_) + if (!active) return; - - DCHECK(!active || layer_tree_view_); - - if (is_accelerated_compositing_active_ == active) + if (is_accelerated_compositing_active_) return; + DCHECK(layer_tree_view_); - if (active) { - TRACE_EVENT0("blink", - "WebViewImpl::setIsAcceleratedCompositingActive(true)"); - layer_tree_view_->SetRootLayer(root_layer_); - UpdateLayerTreeViewport(); - is_accelerated_compositing_active_ = true; - } + TRACE_EVENT0("blink", + "WebFrameWidgetImpl::SetIsAcceleratedCompositingActive(true)"); + Client()->SetRootLayer(root_layer_); + UpdateLayerTreeViewport(); + is_accelerated_compositing_active_ = true; } PaintLayerCompositor* WebFrameWidgetImpl::Compositor() const { @@ -1028,15 +1006,19 @@ void WebFrameWidgetImpl::SetRootGraphicsLayer(GraphicsLayer* layer) { root_graphics_layer_ = layer; root_layer_ = layer ? layer->CcLayer() : nullptr; - SetIsAcceleratedCompositingActive(layer); + SetIsAcceleratedCompositingActive(!!layer); + // TODO(danakj): Is this called after Close?? (With a null layer?) if (!layer_tree_view_) return; - if (root_layer_) - layer_tree_view_->SetRootLayer(root_layer_); - else - layer_tree_view_->ClearRootLayer(); + // WebFrameWidgetImpl is used for child frames, which always have a + // transparent background color. + Client()->SetBackgroundColor(SK_ColorTRANSPARENT); + + // TODO(danakj): SetIsAcceleratedCompositingActive() also sets the root layer + // if it's not null.. + Client()->SetRootLayer(root_layer_); } void WebFrameWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) { @@ -1044,21 +1026,25 @@ void WebFrameWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) { SetIsAcceleratedCompositingActive(!!layer); + // TODO(danakj): Is this called after Close?? (With a null layer?) if (!layer_tree_view_) return; - if (root_layer_) - layer_tree_view_->SetRootLayer(root_layer_); - else - layer_tree_view_->ClearRootLayer(); + // WebFrameWidgetImpl is used for child frames, which always have a + // transparent background color. + Client()->SetBackgroundColor(SK_ColorTRANSPARENT); + + // TODO(danakj): SetIsAcceleratedCompositingActive() also sets the root layer + // if it's not null.. + Client()->SetRootLayer(root_layer_); } WebLayerTreeView* WebFrameWidgetImpl::GetLayerTreeView() const { return layer_tree_view_; } -CompositorAnimationHost* WebFrameWidgetImpl::AnimationHost() const { - return animation_host_.get(); +cc::AnimationHost* WebFrameWidgetImpl::AnimationHost() const { + return animation_host_; } HitTestResult WebFrameWidgetImpl::CoreHitTestResultAt( diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index 622592b3f59..d4992a6581f 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h @@ -43,11 +43,11 @@ #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/page/page_widget_delegate.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/graphics/apply_viewport_changes.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/heap/self_keep_alive.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" namespace cc { @@ -55,11 +55,9 @@ class Layer; } namespace blink { - -class AnimationWorkletMutatorDispatcherImpl; -class CompositorAnimationHost; class Frame; class Element; +class HTMLPlugInElement; class LocalFrame; class PaintLayerCompositor; class UserGestureToken; @@ -84,7 +82,12 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase, void DidEnterFullscreen() override; void DidExitFullscreen() override; void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final; - void BeginFrame(base::TimeTicks last_frame_time) override; + void BeginFrame(base::TimeTicks last_frame_time, + bool record_main_frame_metrics) override; + void DidBeginFrame() override; + void BeginRafAlignedInput() override; + void EndRafAlignedInput() override; + void RecordStartOfFrameMetrics() override; void RecordEndOfFrameMetrics(base::TimeTicks) override; void UpdateLifecycle(LifecycleUpdate requested_update, LifecycleUpdateReason reason) override; @@ -102,8 +105,8 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase, void SetFocus(bool enable) override; bool SelectionBounds(WebRect& anchor, WebRect& focus) const override; bool IsAcceleratedCompositingActive() const override; - void WillCloseLayerTreeView() override; - void SetRemoteViewportIntersection(const WebRect&, bool) override; + void SetRemoteViewportIntersection(const WebRect&, + FrameOcclusionState) override; void SetIsInert(bool) override; void SetInheritedEffectiveTouchAction(TouchAction) override; void UpdateRenderThrottlingStatus(bool is_throttled, @@ -120,16 +123,9 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase, Element* FocusedElement() const; PaintLayerCompositor* Compositor() const; - // Create or return cached mutation distributor. This usually requires a - // round trip to the compositor. The output task runner is the one to use - // for sending mutations using the WeakPtr. - base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> - EnsureCompositorMutatorDispatcher(scoped_refptr<base::SingleThreadTaskRunner>* - mutator_task_runner) override; // WebFrameWidgetBase overrides: - void Initialize() override; - void SetLayerTreeView(WebLayerTreeView*) override; + void SetLayerTreeView(WebLayerTreeView*, cc::AnimationHost*) override; bool ForSubframe() const override { return true; } void IntrinsicSizingInfoChanged(const IntrinsicSizingInfo&) override; void DidCreateLocalRootView() override; @@ -137,7 +133,7 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase, void SetRootGraphicsLayer(GraphicsLayer*) override; void SetRootLayer(scoped_refptr<cc::Layer>) override; WebLayerTreeView* GetLayerTreeView() const override; - CompositorAnimationHost* AnimationHost() const override; + cc::AnimationHost* AnimationHost() const override; HitTestResult CoreHitTestResultAt(const gfx::Point&) override; void ZoomToFindInPageRect(const WebRect& rect_in_root_frame) override; @@ -151,7 +147,7 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase, GraphicsLayer* RootGraphicsLayer() const override { return root_graphics_layer_; - }; + } void Trace(blink::Visitor*) override; @@ -190,41 +186,29 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase, base::Optional<WebSize> size_; - // If set, the (plugin) node which has mouse capture. - Member<Node> mouse_capture_node_; + // If set, the (plugin) element which has mouse capture. + Member<HTMLPlugInElement> mouse_capture_element_; scoped_refptr<UserGestureToken> mouse_capture_gesture_token_; - // This is owned by the LayerTreeHostImpl, and should only be used on the - // compositor thread, so we keep the TaskRunner where you post tasks to - // make that happen. - base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> mutator_dispatcher_; - scoped_refptr<base::SingleThreadTaskRunner> mutator_task_runner_; - - WebLayerTreeView* layer_tree_view_; + WebLayerTreeView* layer_tree_view_ = nullptr; + cc::AnimationHost* animation_host_ = nullptr; scoped_refptr<cc::Layer> root_layer_; - GraphicsLayer* root_graphics_layer_; - std::unique_ptr<CompositorAnimationHost> animation_host_; - bool is_accelerated_compositing_active_; - bool layer_tree_view_closed_; + GraphicsLayer* root_graphics_layer_ = nullptr; + base::TimeTicks raf_aligned_input_start_time_; + bool is_accelerated_compositing_active_ = false; - bool suppress_next_keypress_event_; + bool suppress_next_keypress_event_ = false; bool did_suspend_parsing_ = false; // TODO(ekaramad): Can we remove this and make sure IME events are not called // when there is no page focus? // Represents whether or not this object should process incoming IME events. - bool ime_accept_events_; + bool ime_accept_events_ = true; SelfKeepAlive<WebFrameWidgetImpl> self_keep_alive_; }; -DEFINE_TYPE_CASTS(WebFrameWidgetImpl, - WebFrameWidgetBase, - widget, - widget->ForSubframe(), - widget.ForSubframe()); - } // namespace blink #endif diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 6197e91bd3c..6f19b08f41c 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc @@ -112,6 +112,7 @@ #include "third_party/blink/public/web/web_associated_url_loader_options.h" #include "third_party/blink/public/web/web_autofill_client.h" #include "third_party/blink/public/web/web_console_message.h" +#include "third_party/blink/public/web/web_content_capture_client.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_dom_event.h" #include "third_party/blink/public/web/web_form_element.h" @@ -177,6 +178,7 @@ #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" +#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/find_in_page.h" #include "third_party/blink/renderer/core/frame/frame_console.h" @@ -230,6 +232,7 @@ #include "third_party/blink/renderer/core/page/print_context.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/scroll/scroll_types.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" #include "third_party/blink/renderer/core/timing/dom_window_performance.h" #include "third_party/blink/renderer/core/timing/window_performance.h" @@ -251,7 +254,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" @@ -309,7 +311,7 @@ class ChromePrintContext : public PrintContext { // The page rect gets scaled and translated, so specify the entire // print content area here as the recording rect. FloatRect bounds(0, 0, printed_page_height_, printed_page_width_); - PaintRecordBuilder builder(&canvas->getMetaData()); + PaintRecordBuilder builder(canvas->GetPrintingMetafile()); builder.Context().SetPrinting(true); builder.Context().BeginRecording(bounds); float scale = SpoolPage(builder.Context(), page_number); @@ -337,7 +339,7 @@ class ChromePrintContext : public PrintContext { int total_height = num_pages * (page_size_in_pixels.Height() + 1) - 1; FloatRect all_pages_rect(0, 0, page_width, total_height); - PaintRecordBuilder builder(&canvas->getMetaData()); + PaintRecordBuilder builder(canvas->GetPrintingMetafile()); GraphicsContext& context = builder.Context(); context.SetPrinting(true); context.BeginRecording(all_pages_rect); @@ -403,7 +405,8 @@ class ChromePrintContext : public PrintContext { PropertyTreeState property_tree_state = frame_view->GetLayoutView()->FirstFragment().LocalBorderBoxProperties(); - PaintRecordBuilder builder(&context.Canvas()->getMetaData(), &context); + PaintRecordBuilder builder(context.Canvas()->GetPrintingMetafile(), + &context); frame_view->PaintContentsOutsideOfLifecycle( builder.Context(), kGlobalPaintNormalPhase, CullRect(page_rect)); @@ -428,8 +431,8 @@ class ChromePrintContext : public PrintContext { HeapVector<Member<Document>> documents; for (Frame* current_frame = GetFrame(); current_frame; current_frame = current_frame->Tree().TraverseNext(GetFrame())) { - if (current_frame->IsLocalFrame()) - documents.push_back(ToLocalFrame(current_frame)->GetDocument()); + if (auto* current_local_frame = DynamicTo<LocalFrame>(current_frame)) + documents.push_back(current_local_frame->GetDocument()); } for (auto& doc : documents) @@ -487,7 +490,7 @@ class ChromePluginPrintContext final : public ChromePrintContext { // NativeTheme doesn't play well with scaling. Scaling is done browser side // instead. Returns the scale to be applied. float SpoolPage(GraphicsContext& context, int page_number) override { - PaintRecordBuilder builder(&context.Canvas()->getMetaData()); + PaintRecordBuilder builder(context.Canvas()->GetPrintingMetafile()); plugin_->PrintPage(page_number, builder.Context()); context.DrawRecord(builder.EndRecording()); @@ -734,35 +737,8 @@ void WebLocalFrameImpl::SetIsolatedWorldInfo(int world_id, void WebLocalFrameImpl::AddMessageToConsole(const WebConsoleMessage& message) { DCHECK(GetFrame()); - - MessageLevel web_core_message_level = kInfoMessageLevel; - switch (message.level) { - case mojom::ConsoleMessageLevel::kVerbose: - web_core_message_level = kVerboseMessageLevel; - break; - case mojom::ConsoleMessageLevel::kInfo: - web_core_message_level = kInfoMessageLevel; - break; - case mojom::ConsoleMessageLevel::kWarning: - web_core_message_level = kWarningMessageLevel; - break; - case mojom::ConsoleMessageLevel::kError: - web_core_message_level = kErrorMessageLevel; - break; - } - - MessageSource message_source = message.nodes.empty() - ? kOtherMessageSource - : kRecommendationMessageSource; - Vector<DOMNodeId> nodes; - for (const blink::WebNode& web_node : message.nodes) - nodes.push_back(DOMNodeIds::IdForNode(&(*web_node))); - ConsoleMessage* console_message = ConsoleMessage::Create( - message_source, web_core_message_level, message.text, - SourceLocation::Create(message.url, message.line_number, - message.column_number, nullptr)); - console_message->SetNodes(GetFrame(), std::move(nodes)); - GetFrame()->GetDocument()->AddConsoleMessage(console_message); + GetFrame()->GetDocument()->AddConsoleMessage( + ConsoleMessage::CreateFromWebConsoleMessage(message, GetFrame())); } void WebLocalFrameImpl::Alert(const WebString& message) { @@ -914,7 +890,11 @@ void WebLocalFrameImpl::StartReload(WebFrameLoadType frame_load_type) { } void WebLocalFrameImpl::ReloadImage(const WebNode& web_node) { - const Node* node = web_node.ConstUnwrap<Node>(); + Node* node = web_node; // Use implicit WebNode->Node* cast. + HitTestResult hit_test_result; + hit_test_result.SetInnerNode(node); + hit_test_result.SetToShadowHostIfInRestrictedShadowRoot(); + node = hit_test_result.InnerNodeOrImageMapImage(); if (auto* image_element = ToHTMLImageElementOrNull(*node)) image_element->ForceReload(); } @@ -1490,7 +1470,7 @@ void WebLocalFrameImpl::DispatchPrintEventRecursively( Event* event = event_type == event_type_names::kBeforeprint ? static_cast<Event*>(BeforePrintEvent::Create()) : static_cast<Event*>(AfterPrintEvent::Create()); - ToLocalFrame(frame)->DomWindow()->DispatchEvent(*event); + To<LocalFrame>(frame.Get())->DomWindow()->DispatchEvent(*event); } } @@ -1544,18 +1524,6 @@ void WebLocalFrameImpl::PrintEnd() { print_context_.Clear(); } -bool WebLocalFrameImpl::IsPrintScalingDisabledForPlugin(const WebNode& node) { - DCHECK(GetFrame()); - WebPluginContainerImpl* plugin_container = - node.IsNull() ? GetFrame()->GetWebPluginContainer() - : ToWebPluginContainerImpl(node.PluginContainer()); - - if (!plugin_container || !plugin_container->SupportsPaginatedPrint()) - return false; - - return plugin_container->IsPrintScalingDisabled(); -} - bool WebLocalFrameImpl::GetPrintPresetOptionsForPlugin( const WebNode& node, WebPrintPresetOptions* preset_options) { @@ -1631,10 +1599,12 @@ WebLocalFrame* WebLocalFrame::CreateMainFrame( mojo::ScopedMessagePipeHandle document_interface_broker_handle, WebFrame* opener, const WebString& name, - WebSandboxFlags sandbox_flags) { + WebSandboxFlags sandbox_flags, + const FeaturePolicy::FeatureState& opener_feature_state) { return WebLocalFrameImpl::CreateMainFrame( web_view, client, interface_registry, - std::move(document_interface_broker_handle), opener, name, sandbox_flags); + std::move(document_interface_broker_handle), opener, name, sandbox_flags, + opener_feature_state); } WebLocalFrame* WebLocalFrame::CreateProvisional( @@ -1669,11 +1639,14 @@ WebLocalFrameImpl* WebLocalFrameImpl::CreateMainFrame( mojo::ScopedMessagePipeHandle document_interface_broker_handle, WebFrame* opener, const WebString& name, - WebSandboxFlags sandbox_flags) { + WebSandboxFlags sandbox_flags, + const FeaturePolicy::FeatureState& opener_feature_state) { WebLocalFrameImpl* frame = MakeGarbageCollected<WebLocalFrameImpl>( WebTreeScopeType::kDocument, client, interface_registry, std::move(document_interface_broker_handle)); frame->SetOpener(opener); + if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) + frame->opener_feature_state_ = opener_feature_state; Page& page = *static_cast<WebViewImpl*>(web_view)->GetPage(); DCHECK(!page.MainFrame()); frame->InitializeCoreFrame(page, nullptr, name); @@ -1714,16 +1687,19 @@ WebLocalFrameImpl* WebLocalFrameImpl::CreateProvisional( LocalFrame* new_frame = web_frame->GetFrame(); new_frame->SetOwner(old_frame->Owner()); - if (new_frame->Owner() && new_frame->Owner()->IsRemote()) { - ToRemoteFrameOwner(new_frame->Owner()) - ->SetSandboxFlags(static_cast<SandboxFlags>(flags)); - ToRemoteFrameOwner(new_frame->Owner()) - ->SetContainerPolicy(container_policy); + if (auto* remote_frame_owner = + DynamicTo<RemoteFrameOwner>(new_frame->Owner())) { + remote_frame_owner->SetSandboxFlags(static_cast<SandboxFlags>(flags)); + remote_frame_owner->SetContainerPolicy(container_policy); } else if (!new_frame->Owner()) { // Provisional main frames need to force sandbox flags. This is necessary // to inherit sandbox flags when a sandboxed frame does a window.open() // which triggers a cross-process navigation. new_frame->Loader().ForceSandboxFlags(static_cast<SandboxFlags>(flags)); + // If there is an opener (even disowned), the opener policies must be + // inherited the same way as sandbox flag. + web_frame->opener_feature_state_ = + ToWebRemoteFrameImpl(old_web_frame)->OpenerFeatureState(); } return web_frame; @@ -1839,7 +1815,7 @@ LocalFrame* WebLocalFrameImpl::CreateChildFrame( // element might not have the attribute, and there might be other attributes // which can identify the element. WebLocalFrameImpl* webframe_child = - ToWebLocalFrameImpl(client_->CreateChildFrame( + To<WebLocalFrameImpl>(client_->CreateChildFrame( this, scope, name, owner_element->getAttribute( owner_element->SubResourceAttributeName()), @@ -1935,14 +1911,14 @@ WebLocalFrameImpl* WebLocalFrameImpl::FromFrame(LocalFrame& frame) { LocalFrameClient* client = frame.Client(); if (!client || !client->IsLocalFrameClientImpl()) return nullptr; - return ToWebLocalFrameImpl(client->GetWebFrame()); + return To<WebLocalFrameImpl>(client->GetWebFrame()); } WebLocalFrameImpl* WebLocalFrameImpl::FromFrameOwnerElement(Element* element) { - if (!element->IsFrameOwnerElement()) + auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(element); + if (!frame_owner_element) return nullptr; - return FromFrame( - ToLocalFrame(ToHTMLFrameOwnerElement(element)->ContentFrame())); + return FromFrame(To<LocalFrame>(frame_owner_element->ContentFrame())); } WebViewImpl* WebLocalFrameImpl::ViewImpl() const { @@ -1998,6 +1974,15 @@ WebAutofillClient* WebLocalFrameImpl::AutofillClient() { return autofill_client_; } +void WebLocalFrameImpl::SetContentCaptureClient( + WebContentCaptureClient* content_capture_client) { + content_capture_client_ = content_capture_client; +} + +WebContentCaptureClient* WebLocalFrameImpl::ContentCaptureClient() const { + return content_capture_client_; +} + bool WebLocalFrameImpl::IsLocalRoot() const { return frame_->IsLocalRoot(); } @@ -2011,8 +1996,9 @@ WebLocalFrameImpl* WebLocalFrameImpl::LocalRoot() { // when the WebLocalFrame exists but the core LocalFrame does not. // TODO(alexmos, dcheng): Clean this up to only calculate this in one place. WebLocalFrameImpl* local_root = this; - while (local_root->Parent() && local_root->Parent()->IsWebLocalFrame()) - local_root = ToWebLocalFrameImpl(local_root->Parent()); + while (auto* web_local_frame = + DynamicTo<WebLocalFrameImpl>(local_root->Parent())) + local_root = web_local_frame; return local_root; } @@ -2041,8 +2027,7 @@ void WebLocalFrameImpl::CommitNavigation( std::unique_ptr<WebNavigationParams> navigation_params, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { DCHECK(GetFrame()); - DCHECK(!navigation_params->request.IsNull()); - DCHECK(!navigation_params->request.Url().ProtocolIs("javascript")); + DCHECK(!navigation_params->url.ProtocolIs("javascript")); if (GetTextFinder()) GetTextFinder()->ClearActiveFindMatch(); GetFrame()->Loader().CommitNavigation( @@ -2204,7 +2189,8 @@ void WebLocalFrameImpl::BlinkFeatureUsageReport(const std::set<int>& features) { DCHECK(!features.empty()); // Assimilate all features used/performed by the browser into UseCounter. for (int feature : features) { - UseCounter::Count(GetFrame(), static_cast<WebFeature>(feature)); + UseCounter::Count(GetFrame()->GetDocument(), + static_cast<WebFeature>(feature)); } } @@ -2260,11 +2246,13 @@ void WebLocalFrameImpl::SendOrientationChangeEvent() { } void WebLocalFrameImpl::DidCallAddSearchProvider() { - UseCounter::Count(GetFrame(), WebFeature::kExternalAddSearchProvider); + UseCounter::Count(GetFrame()->GetDocument(), + WebFeature::kExternalAddSearchProvider); } void WebLocalFrameImpl::DidCallIsSearchProviderInstalled() { - UseCounter::Count(GetFrame(), WebFeature::kExternalIsSearchProviderInstalled); + UseCounter::Count(GetFrame()->GetDocument(), + WebFeature::kExternalIsSearchProviderInstalled); } void WebLocalFrameImpl::DispatchMessageEventWithOriginCheck( @@ -2313,14 +2301,6 @@ void WebLocalFrameImpl::WillDetachParent() { void WebLocalFrameImpl::SetFrameWidget(WebFrameWidgetBase* frame_widget) { frame_widget_ = frame_widget; - - // This is needed because the local frame root's widget may not be set when - // Document::Initialize() called AttachmentCompositorAnimationTimeline() - // (which requires frame widget to be effective). - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && frame_widget) { - if (auto* document = GetFrame()->GetDocument()) - document->AttachCompositorAnimationTimeline(); - } } WebFrameWidget* WebLocalFrameImpl::FrameWidget() const { @@ -2517,6 +2497,7 @@ void WebLocalFrameImpl::PerformMediaPlayerAction( } void WebLocalFrameImpl::OnPortalActivated() { + GetFrame()->GetPage()->SetInsidePortal(false); PortalActivateEvent* event = PortalActivateEvent::Create(); GetFrame()->DomWindow()->DispatchEvent(*event); } @@ -2571,4 +2552,9 @@ void WebLocalFrameImpl::BindDevToolsAgent( std::move(devtools_agent_request))); } +void WebLocalFrameImpl::SetLifecycleState(mojom::FrameLifecycleState state) { + DCHECK(GetFrame()); + GetFrame()->SetLifecycleState(state); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h index d5e92aad674..1d365801c70 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h @@ -39,6 +39,7 @@ #include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink.h" #include "third_party/blink/public/mojom/devtools/devtools_agent.mojom-blink.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/public/mojom/portal/portal.mojom-blink.h" #include "third_party/blink/public/platform/web_file_system_type.h" #include "third_party/blink/public/web/web_history_commit_type.h" @@ -51,6 +52,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/heap/self_keep_alive.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/compiler.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -61,6 +63,7 @@ class FindInPage; class HTMLPortalElement; class IntSize; class LocalFrameClientImpl; +class ResourceError; class ScrollableArea; class TextFinder; class WebAssociatedURLLoader; @@ -218,7 +221,6 @@ class CORE_EXPORT WebLocalFrameImpl final float GetPrintPageShrink(int page) override; void PrintEnd() override; void DispatchAfterPrintEvent() override; - bool IsPrintScalingDisabledForPlugin(const WebNode&) override; bool GetPrintPresetOptionsForPlugin(const WebNode&, WebPrintPresetOptions*) override; bool HasCustomPageSizeStyle(int page_index) override; @@ -252,6 +254,8 @@ class CORE_EXPORT WebLocalFrameImpl final mojo::ScopedMessagePipeHandle) override; void SetAutofillClient(WebAutofillClient*) override; WebAutofillClient* AutofillClient() override; + void SetContentCaptureClient(WebContentCaptureClient*) override; + WebContentCaptureClient* ContentCaptureClient() const override; bool IsLocalRoot() const override; bool IsProvisional() const override; WebLocalFrameImpl* LocalRoot() override; @@ -322,6 +326,8 @@ class CORE_EXPORT WebLocalFrameImpl final const WebNavigationInfo&, std::unique_ptr<WebDocumentLoader::ExtraData>) override; + void SetLifecycleState(mojom::FrameLifecycleState state) override; + void InitializeCoreFrame(Page&, FrameOwner*, const AtomicString& name); LocalFrame* GetFrame() const { return frame_.Get(); } @@ -339,7 +345,8 @@ class CORE_EXPORT WebLocalFrameImpl final mojo::ScopedMessagePipeHandle, WebFrame* opener, const WebString& name, - WebSandboxFlags); + WebSandboxFlags, + const FeaturePolicy::FeatureState&); static WebLocalFrameImpl* CreateProvisional(WebLocalFrameClient*, InterfaceRegistry*, mojo::ScopedMessagePipeHandle, @@ -432,6 +439,10 @@ class CORE_EXPORT WebLocalFrameImpl final // Returns true if our print context suggests using printing layout. bool UsePrintingLayout() const; + const FeaturePolicy::FeatureState& OpenerFeatureState() const { + return opener_feature_state_; + } + virtual void Trace(blink::Visitor*); private: @@ -474,6 +485,9 @@ class CORE_EXPORT WebLocalFrameImpl final Member<WebDevToolsAgentImpl> dev_tools_agent_; WebAutofillClient* autofill_client_; + + WebContentCaptureClient* content_capture_client_ = nullptr; + WebContentSettingsClient* content_settings_client_ = nullptr; Member<FindInPage> find_in_page_; @@ -491,6 +505,10 @@ class CORE_EXPORT WebLocalFrameImpl final WebSpellCheckPanelHostClient* spell_check_panel_host_client_; + // Feature policy state inherited from an opener. It is always empty for child + // frames. + FeaturePolicy::FeatureState opener_feature_state_; + // Oilpan: WebLocalFrameImpl must remain alive until close() is called. // Accomplish that by keeping a self-referential Persistent<>. It is // cleared upon close(). @@ -503,11 +521,12 @@ class CORE_EXPORT WebLocalFrameImpl final #endif }; -DEFINE_TYPE_CASTS(WebLocalFrameImpl, - WebFrame, - frame, - frame->IsWebLocalFrame(), - frame.IsWebLocalFrame()); +template <> +struct DowncastTraits<WebLocalFrameImpl> { + static bool AllowFrom(const WebFrame& frame) { + return frame.IsWebLocalFrame(); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc index 8831aafb924..e7be575b5a8 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc @@ -12,22 +12,18 @@ namespace blink { WebViewFrameWidget::WebViewFrameWidget(WebWidgetClient& client, WebViewImpl& web_view) : WebFrameWidgetBase(client), web_view_(&web_view), self_keep_alive_(this) { - // TODO(danakj): SetLayerTreeView() here as well, then we can Close() the - // WebViewImpl's widget bits in Close(). - web_view_->SetWebWidgetClient(&client); } WebViewFrameWidget::~WebViewFrameWidget() = default; void WebViewFrameWidget::Close() { - // TODO(danakj): Close() the WebViewImpl here, when we reset the LayerTreeView - // in the constructor. - web_view_->SetWebWidgetClient(nullptr); + // Closing the WebViewFrameWidget happens in response to the local main frame + // being detached from the Page/WebViewImpl. + // TODO(danakj): Close the WebWidget parts of WebViewImpl here. This should + // drop the WebWidgetClient from it as well. For now, WebViewImpl requires a + // WebWidgetClient to always be present so this does nothing. web_view_ = nullptr; WebFrameWidgetBase::Close(); - - // Note: this intentionally does not forward to WebView::close(), to make it - // easier to untangle the cleanup logic later. self_keep_alive_.Clear(); } @@ -56,8 +52,25 @@ void WebViewFrameWidget::SetSuppressFrameRequestsWorkaroundFor704763Only( web_view_->SetSuppressFrameRequestsWorkaroundFor704763Only( suppress_frame_requests); } -void WebViewFrameWidget::BeginFrame(base::TimeTicks last_frame_time) { - web_view_->BeginFrame(last_frame_time); +void WebViewFrameWidget::BeginFrame(base::TimeTicks last_frame_time, + bool record_main_frame_metrics) { + web_view_->BeginFrame(last_frame_time, record_main_frame_metrics); +} + +void WebViewFrameWidget::DidBeginFrame() { + web_view_->DidBeginFrame(); +} + +void WebViewFrameWidget::BeginRafAlignedInput() { + web_view_->BeginRafAlignedInput(); +} + +void WebViewFrameWidget::EndRafAlignedInput() { + web_view_->EndRafAlignedInput(); +} + +void WebViewFrameWidget::RecordStartOfFrameMetrics() { + web_view_->RecordStartOfFrameMetrics(); } void WebViewFrameWidget::RecordEndOfFrameMetrics( @@ -136,10 +149,6 @@ bool WebViewFrameWidget::IsAcceleratedCompositingActive() const { return web_view_->IsAcceleratedCompositingActive(); } -void WebViewFrameWidget::WillCloseLayerTreeView() { - web_view_->WillCloseLayerTreeView(); -} - WebURL WebViewFrameWidget::GetURLForDebugTrace() { return web_view_->GetURLForDebugTrace(); } @@ -153,20 +162,13 @@ bool WebViewFrameWidget::ScrollFocusedEditableElementIntoView() { return web_view_->ScrollFocusedEditableElementIntoView(); } -void WebViewFrameWidget::Initialize() {} - -void WebViewFrameWidget::SetLayerTreeView(WebLayerTreeView*) { +void WebViewFrameWidget::SetLayerTreeView(WebLayerTreeView*, + cc::AnimationHost*) { // The WebViewImpl already has its LayerTreeView, the WebWidgetClient // thus does not initialize and set another one here. NOTREACHED(); } -base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> -WebViewFrameWidget::EnsureCompositorMutatorDispatcher( - scoped_refptr<base::SingleThreadTaskRunner>* mutator_task_runner) { - return web_view_->EnsureCompositorMutatorDispatcher(mutator_task_runner); -} - void WebViewFrameWidget::SetRootGraphicsLayer(GraphicsLayer* layer) { web_view_->SetRootGraphicsLayer(layer); } @@ -183,7 +185,7 @@ WebLayerTreeView* WebViewFrameWidget::GetLayerTreeView() const { return web_view_->LayerTreeView(); } -CompositorAnimationHost* WebViewFrameWidget::AnimationHost() const { +cc::AnimationHost* WebViewFrameWidget::AnimationHost() const { return web_view_->AnimationHost(); } diff --git a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h index fdffbc96842..dad1e282533 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h +++ b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h @@ -48,7 +48,12 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase { void DidEnterFullscreen() override; void DidExitFullscreen() override; void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final; - void BeginFrame(base::TimeTicks last_frame_time) override; + void BeginFrame(base::TimeTicks last_frame_time, + bool record_main_frame_metrics) override; + void DidBeginFrame() override; + void BeginRafAlignedInput() override; + void EndRafAlignedInput() override; + void RecordStartOfFrameMetrics() override; void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override; void UpdateLifecycle(LifecycleUpdate requested_update, LifecycleUpdateReason reason) override; @@ -71,7 +76,6 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase { void SetFocus(bool) override; bool SelectionBounds(WebRect& anchor, WebRect& focus) const override; bool IsAcceleratedCompositingActive() const override; - void WillCloseLayerTreeView() override; WebURL GetURLForDebugTrace() override; // WebFrameWidget overrides: @@ -80,17 +84,13 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase { WebHitTestResult HitTestResultAt(const gfx::Point&) override; // WebFrameWidgetBase overrides: - void Initialize() override; - void SetLayerTreeView(WebLayerTreeView*) override; + void SetLayerTreeView(WebLayerTreeView*, cc::AnimationHost*) override; bool ForSubframe() const override { return false; } - base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> - EnsureCompositorMutatorDispatcher( - scoped_refptr<base::SingleThreadTaskRunner>*) override; void SetRootGraphicsLayer(GraphicsLayer*) override; GraphicsLayer* RootGraphicsLayer() const override; void SetRootLayer(scoped_refptr<cc::Layer>) override; WebLayerTreeView* GetLayerTreeView() const override; - CompositorAnimationHost* AnimationHost() const override; + cc::AnimationHost* AnimationHost() const override; HitTestResult CoreHitTestResultAt(const gfx::Point&) override; void ZoomToFindInPageRect(const WebRect& rect_in_root_frame) override; diff --git a/chromium/third_party/blink/renderer/core/frame/window.idl b/chromium/third_party/blink/renderer/core/frame/window.idl index a0396aacddb..e681b67bdb1 100644 --- a/chromium/third_party/blink/renderer/core/frame/window.idl +++ b/chromium/third_party/blink/renderer/core/frame/window.idl @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://html.spec.whatwg.org/#the-window-object +// https://html.spec.whatwg.org/C/#the-window-object // FIXME: explain all uses of [CrossOrigin] [ @@ -88,17 +88,17 @@ [CrossOrigin, CallWith=Isolate, RaisesException] void postMessage(any message, optional WindowPostMessageOptions options); // WindowOrWorkerGlobalScope mixin - // https://html.spec.whatwg.org/#windoworworkerglobalscope-mixin + // https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin [Replaceable] readonly attribute DOMString origin; void queueMicrotask(VoidFunction callback); // AnimationFrameProvider mixin - // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#animation-frames + // https://html.spec.whatwg.org/C/#animation-frames [MeasureAs=UnprefixedRequestAnimationFrame] long requestAnimationFrame(FrameRequestCallback callback); void cancelAnimationFrame(long handle); // HTML obsolete features - // https://html.spec.whatwg.org/#Window-partial + // https://html.spec.whatwg.org/C/#Window-partial [MeasureAs=WindowCaptureEvents] void captureEvents(); [MeasureAs=WindowReleaseEvents] void releaseEvents(); diff --git a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h index d1c9a72d911..07ab42dc0f3 100644 --- a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h +++ b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h @@ -39,27 +39,25 @@ class WindowEventHandlers { STATIC_ONLY(WindowEventHandlers); public: - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(afterprint, kAfterprint); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeprint, kBeforeprint); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload, kBeforeunload); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange, kHashchange); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(languagechange, - kLanguagechange); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(message, kMessage); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline, kOffline); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(online, kOnline); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pagehide, kPagehide); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pageshow, kPageshow); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate, kPopstate); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(portalactivate, - kPortalactivate); + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(afterprint, kAfterprint) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeprint, kBeforeprint) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload, kBeforeunload) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange, kHashchange) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(languagechange, kLanguagechange) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(message, kMessage) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline, kOffline) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(online, kOnline) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pagehide, kPagehide) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pageshow, kPageshow) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate, kPopstate) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(portalactivate, kPortalactivate) DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(rejectionhandled, - kRejectionhandled); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage, kStorage); + kRejectionhandled) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage, kStorage) DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unhandledrejection, - kUnhandledrejection); - DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload, kUnload); + kUnhandledrejection) + DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload, kUnload) }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl index 2ee41eae597..595cf78a3bd 100644 --- a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl +++ b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl @@ -27,7 +27,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://html.spec.whatwg.org/multipage/webappapis.html#windoweventhandlers +// https://html.spec.whatwg.org/C/#windoweventhandlers [ LegacyTreatAsPartialInterface, diff --git a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl index e19ec9076bd..219aab546f6 100644 --- a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl +++ b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl @@ -28,7 +28,7 @@ // https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin // https://html.spec.whatwg.org/C/timers-and-user-prompts.html#timers -// https://html.spec.whatwg.org/#imagebitmapsource +// https://html.spec.whatwg.org/C/#imagebitmapsource typedef (HTMLImageElement or SVGImageElement or HTMLVideoElement or |