blob: 9e99d3bc5ffb35722155ae164ad3d108ba3ee6da [file] [log] [blame]
// Copyright 2014 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/CSSParser.h"
#include "core/css/CSSColorValue.h"
#include "core/css/CSSKeyframeRule.h"
#include "core/css/StyleColor.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/parser/CSSParserFastPaths.h"
#include "core/css/parser/CSSParserImpl.h"
#include "core/css/parser/CSSPropertyParser.h"
#include "core/css/parser/CSSSelectorParser.h"
#include "core/css/parser/CSSSupportsParser.h"
#include "core/css/parser/CSSTokenizer.h"
#include "core/css/parser/CSSVariableParser.h"
#include "core/layout/LayoutTheme.h"
#include <memory>
namespace blink {
bool CSSParser::parseDeclarationList(const CSSParserContext& context, MutableStylePropertySet* propertySet, const String& declaration)
{
return CSSParserImpl::parseDeclarationList(propertySet, declaration, context);
}
void CSSParser::parseDeclarationListForInspector(const CSSParserContext& context, const String& declaration, CSSParserObserver& observer)
{
CSSParserImpl::parseDeclarationListForInspector(declaration, context, observer);
}
CSSSelectorList CSSParser::parseSelector(const CSSParserContext& context, StyleSheetContents* styleSheetContents, const String& selector)
{
CSSTokenizer::Scope scope(selector);
return CSSSelectorParser::parseSelector(scope.tokenRange(), context, styleSheetContents);
}
CSSSelectorList CSSParser::parsePageSelector(const CSSParserContext& context, StyleSheetContents* styleSheetContents, const String& selector)
{
CSSTokenizer::Scope scope(selector);
return CSSParserImpl::parsePageSelector(scope.tokenRange(), styleSheetContents);
}
StyleRuleBase* CSSParser::parseRule(const CSSParserContext& context, StyleSheetContents* styleSheet, const String& rule)
{
return CSSParserImpl::parseRule(rule, context, styleSheet, CSSParserImpl::AllowImportRules);
}
void CSSParser::parseSheet(const CSSParserContext& context, StyleSheetContents* styleSheet, const String& text)
{
return CSSParserImpl::parseStyleSheet(text, context, styleSheet);
}
void CSSParser::parseSheetForInspector(const CSSParserContext& context, StyleSheetContents* styleSheet, const String& text, CSSParserObserver& observer)
{
return CSSParserImpl::parseStyleSheetForInspector(text, context, styleSheet, observer);
}
bool CSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID unresolvedProperty, const String& string, bool important, StyleSheetContents* styleSheet)
{
if (string.isEmpty())
return false;
CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty);
CSSParserMode parserMode = declaration->cssParserMode();
CSSValue* value = CSSParserFastPaths::maybeParseValue(resolvedProperty, string, parserMode);
if (value)
return declaration->setProperty(CSSProperty(resolvedProperty, *value, important));
CSSParserContext context(parserMode, 0);
if (styleSheet) {
context = styleSheet->parserContext();
context.setMode(parserMode);
}
return parseValue(declaration, unresolvedProperty, string, important, context);
}
bool CSSParser::parseValueForCustomProperty(MutableStylePropertySet* declaration, const AtomicString& propertyName, const String& value, bool important, StyleSheetContents* styleSheet)
{
ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled() && CSSVariableParser::isValidVariableName(propertyName));
if (value.isEmpty())
return false;
CSSParserMode parserMode = declaration->cssParserMode();
CSSParserContext context(parserMode, 0);
if (styleSheet) {
context = styleSheet->parserContext();
context.setMode(parserMode);
}
return CSSParserImpl::parseVariableValue(declaration, propertyName, value, important, context);
}
ImmutableStylePropertySet* CSSParser::parseCustomPropertySet(CSSParserTokenRange range)
{
return CSSParserImpl::parseCustomPropertySet(range);
}
bool CSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID unresolvedProperty, const String& string, bool important, const CSSParserContext& context)
{
return CSSParserImpl::parseValue(declaration, unresolvedProperty, string, important, context);
}
CSSValue* CSSParser::parseSingleValue(CSSPropertyID propertyID, const String& string, const CSSParserContext& context)
{
if (string.isEmpty())
return nullptr;
if (CSSValue* value = CSSParserFastPaths::maybeParseValue(propertyID, string, context.mode()))
return value;
CSSTokenizer::Scope scope(string);
return CSSPropertyParser::parseSingleValue(propertyID, scope.tokenRange(), context);
}
ImmutableStylePropertySet* CSSParser::parseInlineStyleDeclaration(const String& styleString, Element* element)
{
return CSSParserImpl::parseInlineStyleDeclaration(styleString, element);
}
std::unique_ptr<Vector<double>> CSSParser::parseKeyframeKeyList(const String& keyList)
{
return CSSParserImpl::parseKeyframeKeyList(keyList);
}
StyleRuleKeyframe* CSSParser::parseKeyframeRule(const CSSParserContext& context, const String& rule)
{
StyleRuleBase* keyframe = CSSParserImpl::parseRule(rule, context, nullptr, CSSParserImpl::KeyframeRules);
return toStyleRuleKeyframe(keyframe);
}
bool CSSParser::parseSupportsCondition(const String& condition)
{
CSSTokenizer::Scope scope(condition);
CSSParserImpl parser(strictCSSParserContext());
return CSSSupportsParser::supportsCondition(scope.tokenRange(), parser) == CSSSupportsParser::Supported;
}
bool CSSParser::parseColor(Color& color, const String& string, bool strict)
{
if (string.isEmpty())
return false;
// The regular color parsers don't resolve named colors, so explicitly
// handle these first.
Color namedColor;
if (namedColor.setNamedColor(string)) {
color = namedColor;
return true;
}
CSSValue* value = CSSParserFastPaths::parseColor(string, strict ? HTMLStandardMode : HTMLQuirksMode);
// TODO(timloh): Why is this always strict mode?
if (!value)
value = parseSingleValue(CSSPropertyColor, string, strictCSSParserContext());
if (!value || !value->isColorValue())
return false;
color = toCSSColorValue(*value).value();
return true;
}
bool CSSParser::parseSystemColor(Color& color, const String& colorString)
{
CSSValueID id = cssValueKeywordID(colorString);
if (!StyleColor::isSystemColor(id))
return false;
color = LayoutTheme::theme().systemColor(id);
return true;
}
const CSSValue* CSSParser::parseFontFaceDescriptor(CSSPropertyID propertyID, const String& propertyValue, const CSSParserContext& context)
{
StringBuilder builder;
builder.append("@font-face { ");
builder.append(getPropertyNameString(propertyID));
builder.append(" : ");
builder.append(propertyValue);
builder.append("; }");
StyleRuleBase* rule = parseRule(context, nullptr, builder.toString());
if (!rule || !rule->isFontFaceRule())
return nullptr;
return toStyleRuleFontFace(rule)->properties().getPropertyCSSValue(propertyID);
}
} // namespace blink