| // Copyright 2016 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/css/parser/css_parser_context.h" |
| |
| #include "third_party/blink/renderer/core/css/css_custom_ident_value.h" |
| #include "third_party/blink/renderer/core/css/css_style_sheet.h" |
| #include "third_party/blink/renderer/core/css/css_value_list.h" |
| #include "third_party/blink/renderer/core/css/style_rule_keyframe.h" |
| #include "third_party/blink/renderer/core/css/style_sheet_contents.h" |
| #include "third_party/blink/renderer/core/execution_context/execution_context.h" |
| #include "third_party/blink/renderer/core/feature_policy/feature_policy.h" |
| #include "third_party/blink/renderer/core/feature_policy/layout_animations_policy.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/settings.h" |
| #include "third_party/blink/renderer/core/html/imports/html_imports_controller.h" |
| #include "third_party/blink/renderer/core/loader/document_loader.h" |
| #include "third_party/blink/renderer/core/page/page.h" |
| |
| namespace blink { |
| |
| // static |
| CSSParserContext* CSSParserContext::Create(const ExecutionContext& context) { |
| const Referrer referrer(context.Url().StrippedForUseAsReferrer(), |
| context.GetReferrerPolicy()); |
| |
| ContentSecurityPolicyDisposition policy_disposition; |
| if (ContentSecurityPolicy::ShouldBypassMainWorld(&context)) |
| policy_disposition = kDoNotCheckContentSecurityPolicy; |
| else |
| policy_disposition = kCheckContentSecurityPolicy; |
| |
| return MakeGarbageCollected<CSSParserContext>( |
| context.Url(), true /* origin_clean */, WTF::TextEncoding(), |
| kHTMLStandardMode, kHTMLStandardMode, kLiveProfile, referrer, true, false, |
| context.GetSecureContextMode(), policy_disposition, |
| DynamicTo<Document>(context)); |
| } |
| |
| // static |
| CSSParserContext* CSSParserContext::CreateWithStyleSheet( |
| const CSSParserContext* other, |
| const CSSStyleSheet* style_sheet) { |
| return CSSParserContext::Create( |
| other, CSSStyleSheet::SingleOwnerDocument(style_sheet)); |
| } |
| |
| // static |
| CSSParserContext* CSSParserContext::CreateWithStyleSheetContents( |
| const CSSParserContext* other, |
| const StyleSheetContents* style_sheet_contents) { |
| return CSSParserContext::Create( |
| other, StyleSheetContents::SingleOwnerDocument(style_sheet_contents)); |
| } |
| |
| // static |
| CSSParserContext* CSSParserContext::Create( |
| const CSSParserContext* other, |
| const Document* use_counter_document) { |
| return MakeGarbageCollected<CSSParserContext>( |
| other->base_url_, other->origin_clean_, other->charset_, other->mode_, |
| other->match_mode_, other->profile_, other->referrer_, |
| other->is_html_document_, |
| other->use_legacy_background_size_shorthand_behavior_, |
| other->secure_context_mode_, other->should_check_content_security_policy_, |
| use_counter_document); |
| } |
| |
| // static |
| CSSParserContext* CSSParserContext::Create( |
| const CSSParserContext* other, |
| const KURL& base_url, |
| bool origin_clean, |
| network::mojom::ReferrerPolicy referrer_policy, |
| const WTF::TextEncoding& charset, |
| const Document* use_counter_document) { |
| return MakeGarbageCollected<CSSParserContext>( |
| base_url, origin_clean, charset, other->mode_, other->match_mode_, |
| other->profile_, |
| Referrer(base_url.StrippedForUseAsReferrer(), referrer_policy), |
| other->is_html_document_, |
| other->use_legacy_background_size_shorthand_behavior_, |
| other->secure_context_mode_, other->should_check_content_security_policy_, |
| use_counter_document); |
| } |
| |
| // static |
| CSSParserContext* CSSParserContext::Create( |
| CSSParserMode mode, |
| SecureContextMode secure_context_mode, |
| SelectorProfile profile, |
| const Document* use_counter_document) { |
| return MakeGarbageCollected<CSSParserContext>( |
| KURL(), true /* origin_clean */, WTF::TextEncoding(), mode, mode, profile, |
| Referrer(), false, false, secure_context_mode, |
| kDoNotCheckContentSecurityPolicy, use_counter_document); |
| } |
| |
| // static |
| CSSParserContext* CSSParserContext::Create(const Document& document) { |
| return CSSParserContext::Create( |
| document, document.BaseURL(), true /* origin_clean */, |
| document.GetReferrerPolicy(), WTF::TextEncoding(), kLiveProfile); |
| } |
| |
| // static |
| CSSParserContext* CSSParserContext::Create( |
| const Document& document, |
| const KURL& base_url_override, |
| bool origin_clean, |
| network::mojom::ReferrerPolicy referrer_policy_override, |
| const WTF::TextEncoding& charset, |
| SelectorProfile profile) { |
| CSSParserMode mode = |
| document.InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode; |
| CSSParserMode match_mode; |
| HTMLImportsController* imports_controller = document.ImportsController(); |
| if (imports_controller && profile == kLiveProfile) { |
| match_mode = imports_controller->Master()->InQuirksMode() |
| ? kHTMLQuirksMode |
| : kHTMLStandardMode; |
| } else { |
| match_mode = mode; |
| } |
| |
| const Referrer referrer(base_url_override.StrippedForUseAsReferrer(), |
| referrer_policy_override); |
| |
| bool use_legacy_background_size_shorthand_behavior = |
| document.GetSettings() |
| ? document.GetSettings() |
| ->GetUseLegacyBackgroundSizeShorthandBehavior() |
| : false; |
| |
| ContentSecurityPolicyDisposition policy_disposition; |
| if (ContentSecurityPolicy::ShouldBypassMainWorld(&document)) |
| policy_disposition = kDoNotCheckContentSecurityPolicy; |
| else |
| policy_disposition = kCheckContentSecurityPolicy; |
| |
| return MakeGarbageCollected<CSSParserContext>( |
| base_url_override, origin_clean, charset, mode, match_mode, profile, |
| referrer, document.IsHTMLDocument(), |
| use_legacy_background_size_shorthand_behavior, |
| document.GetSecureContextMode(), policy_disposition, &document); |
| } |
| |
| CSSParserContext::CSSParserContext( |
| const KURL& base_url, |
| bool origin_clean, |
| const WTF::TextEncoding& charset, |
| CSSParserMode mode, |
| CSSParserMode match_mode, |
| SelectorProfile profile, |
| const Referrer& referrer, |
| bool is_html_document, |
| bool use_legacy_background_size_shorthand_behavior, |
| SecureContextMode secure_context_mode, |
| ContentSecurityPolicyDisposition policy_disposition, |
| const Document* use_counter_document) |
| : base_url_(base_url), |
| origin_clean_(origin_clean), |
| charset_(charset), |
| mode_(mode), |
| match_mode_(match_mode), |
| profile_(profile), |
| referrer_(referrer), |
| is_html_document_(is_html_document), |
| use_legacy_background_size_shorthand_behavior_( |
| use_legacy_background_size_shorthand_behavior), |
| secure_context_mode_(secure_context_mode), |
| should_check_content_security_policy_(policy_disposition), |
| document_(use_counter_document) {} |
| |
| bool CSSParserContext::operator==(const CSSParserContext& other) const { |
| return base_url_ == other.base_url_ && origin_clean_ == other.origin_clean_ && |
| charset_ == other.charset_ && mode_ == other.mode_ && |
| match_mode_ == other.match_mode_ && profile_ == other.profile_ && |
| is_html_document_ == other.is_html_document_ && |
| use_legacy_background_size_shorthand_behavior_ == |
| other.use_legacy_background_size_shorthand_behavior_ && |
| secure_context_mode_ == other.secure_context_mode_; |
| } |
| |
| const CSSParserContext* StrictCSSParserContext( |
| SecureContextMode secure_context_mode) { |
| DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<CSSParserContext>>, |
| strict_context_pool, ()); |
| DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<CSSParserContext>>, |
| secure_strict_context_pool, ()); |
| |
| Persistent<CSSParserContext>& context = |
| secure_context_mode == SecureContextMode::kSecureContext |
| ? *secure_strict_context_pool |
| : *strict_context_pool; |
| if (!context) { |
| context = CSSParserContext::Create(kHTMLStandardMode, secure_context_mode); |
| context.RegisterAsStaticReference(); |
| } |
| |
| return context; |
| } |
| |
| bool CSSParserContext::IsOriginClean() const { |
| return origin_clean_; |
| } |
| |
| bool CSSParserContext::IsSecureContext() const { |
| return secure_context_mode_ == SecureContextMode::kSecureContext; |
| } |
| |
| KURL CSSParserContext::CompleteURL(const String& url) const { |
| if (url.IsNull()) |
| return KURL(); |
| if (!Charset().IsValid()) |
| return KURL(BaseURL(), url); |
| return KURL(BaseURL(), url, Charset()); |
| } |
| |
| void CSSParserContext::Count(WebFeature feature) const { |
| if (IsUseCounterRecordingEnabled()) |
| UseCounter::Count(*document_, feature); |
| } |
| |
| void CSSParserContext::CountDeprecation(WebFeature feature) const { |
| if (IsUseCounterRecordingEnabled()) |
| Deprecation::CountDeprecation(*document_, feature); |
| } |
| |
| void CSSParserContext::Count(CSSParserMode mode, CSSPropertyID property) const { |
| if (IsUseCounterRecordingEnabled() && document_->Loader()) { |
| UseCounter* use_counter = &document_->Loader()->GetUseCounter(); |
| if (use_counter) |
| use_counter->Count(mode, property, document_->GetFrame()); |
| } |
| } |
| |
| bool CSSParserContext::IsDocumentHandleEqual(const Document* other) const { |
| return document_.Get() == other; |
| } |
| |
| bool CSSParserContext::IsLayoutAnimationsPolicyEnforced() const { |
| return document_ && !document_->IsFeatureEnabled( |
| mojom::FeaturePolicyFeature::kLayoutAnimations); |
| } |
| |
| void CSSParserContext::ReportLayoutAnimationsViolationIfNeeded( |
| const StyleRuleKeyframe& rule) const { |
| DCHECK(IsLayoutAnimationsPolicyEnforced()); |
| for (size_t i = 0; i < rule.Properties().PropertyCount(); ++i) { |
| const CSSProperty& property = rule.Properties().PropertyAt(i).Property(); |
| if (!LayoutAnimationsPolicy::AffectedCSSProperties().Contains(&property)) |
| continue; |
| LayoutAnimationsPolicy::ReportViolation(property, *document_); |
| } |
| } |
| |
| void CSSParserContext::Trace(blink::Visitor* visitor) { |
| visitor->Trace(document_); |
| } |
| |
| } // namespace blink |