blob: 707dd5c7467bb10b81db3d95ab7d69d2f8383e26 [file] [log] [blame]
// 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 "core/css/parser/CSSParserContext.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/ExecutionContext.h"
#include "core/frame/Deprecation.h"
#include "core/frame/Settings.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/imports/HTMLImportsController.h"
#include "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 new CSSParserContext(
context.Url(), WTF::TextEncoding(), kHTMLStandardMode, kHTMLStandardMode,
kDynamicProfile, referrer, true, false, context.SecureContextMode(),
policy_disposition,
context.IsDocument() ? &ToDocument(context) : nullptr);
}
// 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 new CSSParserContext(
other->base_url_, 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,
ReferrerPolicy referrer_policy,
const WTF::TextEncoding& charset,
const Document* use_counter_document) {
return new CSSParserContext(
base_url, 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 new CSSParserContext(KURL(), 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(),
document.GetReferrerPolicy(),
WTF::TextEncoding(), kDynamicProfile);
}
// static
CSSParserContext* CSSParserContext::Create(
const Document& document,
const KURL& base_url_override,
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 == kDynamicProfile) {
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 new CSSParserContext(
base_url_override, charset, mode, match_mode, profile, referrer,
document.IsHTMLDocument(), use_legacy_background_size_shorthand_behavior,
document.SecureContextMode(), policy_disposition, &document);
}
CSSParserContext::CSSParserContext(
const KURL& base_url,
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),
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_ && 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::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_->GetPage()) {
UseCounter* use_counter = &document_->GetPage()->GetUseCounter();
if (use_counter)
use_counter->Count(mode, property);
}
}
bool CSSParserContext::IsDocumentHandleEqual(const Document* other) const {
return document_.Get() == other;
}
void CSSParserContext::Trace(blink::Visitor* visitor) {
visitor->Trace(document_);
}
} // namespace blink