📄 cssparser.cpp
字号:
/* * Copyright (C) 2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> * Copyright (C) 2008 Eric Seidel <eric@webkit.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#include "CSSParser.h"#include "CString.h"#include "CSSTimingFunctionValue.h"#include "CSSBorderImageValue.h"#include "CSSCanvasValue.h"#include "CSSCharsetRule.h"#include "CSSCursorImageValue.h"#include "CSSHelper.h"#include "CSSImageValue.h"#include "CSSFontFaceRule.h"#include "CSSFontFaceSrcValue.h"#include "CSSGradientValue.h"#include "CSSImportRule.h"#include "CSSInheritedValue.h"#include "CSSInitialValue.h"#include "CSSMediaRule.h"#include "CSSMutableStyleDeclaration.h"#include "CSSPrimitiveValue.h"#include "CSSProperty.h"#include "CSSPropertyNames.h"#include "CSSQuirkPrimitiveValue.h"#include "CSSReflectValue.h"#include "CSSRuleList.h"#include "CSSSelector.h"#include "CSSStyleRule.h"#include "CSSStyleSheet.h"#include "CSSUnicodeRangeValue.h"#include "CSSValueKeywords.h"#include "CSSValueList.h"#include "CSSVariableDependentValue.h"#include "CSSVariablesDeclaration.h"#include "CSSVariablesRule.h"#include "Counter.h"#include "Document.h"#include "FloatConversion.h"#include "FontFamilyValue.h"#include "FontValue.h"#include "MediaList.h"#include "MediaQueryExp.h"#include "Pair.h"#include "Rect.h"#include "ShadowValue.h"#include "WebKitCSSKeyframeRule.h"#include "WebKitCSSKeyframesRule.h"#include "WebKitCSSTransformValue.h"#include <wtf/dtoa.h>#if ENABLE(DASHBOARD_SUPPORT)#include "DashboardRegion.h"#endif#define YYDEBUG 0#if YYDEBUG > 0extern int cssyydebug;#endifextern int cssyyparse(void* parser);using namespace std;using namespace WTF;#include "CSSPropertyNames.cpp"#include "CSSValueKeywords.c"namespace WebCore {static bool equal(const CSSParserString& a, const char* b){ for (int i = 0; i < a.length; ++i) { if (!b[i]) return false; if (a.characters[i] != b[i]) return false; } return !b[a.length];}static bool equalIgnoringCase(const CSSParserString& a, const char* b){ for (int i = 0; i < a.length; ++i) { if (!b[i]) return false; ASSERT(!isASCIIUpper(b[i])); if (toASCIILower(a.characters[i]) != b[i]) return false; } return !b[a.length];}static bool hasPrefix(const char* string, unsigned length, const char* prefix){ for (unsigned i = 0; i < length; ++i) { if (!prefix[i]) return true; if (string[i] != prefix[i]) return false; } return false;}CSSParser::CSSParser(bool strictParsing) : m_strict(strictParsing) , m_important(false) , m_id(0) , m_styleSheet(0) , m_mediaQuery(0) , m_valueList(0) , m_parsedProperties(static_cast<CSSProperty**>(fastMalloc(32 * sizeof(CSSProperty*)))) , m_numParsedProperties(0) , m_maxParsedProperties(32) , m_inParseShorthand(0) , m_currentShorthand(0) , m_implicitShorthand(false) , m_hasFontFaceOnlyValues(false) , m_defaultNamespace(starAtom) , m_data(0) , yy_start(1) , m_floatingMediaQuery(0) , m_floatingMediaQueryExp(0) , m_floatingMediaQueryExpList(0){#if YYDEBUG > 0 cssyydebug = 1;#endif}CSSParser::~CSSParser(){ clearProperties(); fastFree(m_parsedProperties); clearVariables(); delete m_valueList; fastFree(m_data); if (m_floatingMediaQueryExpList) { deleteAllValues(*m_floatingMediaQueryExpList); delete m_floatingMediaQueryExpList; } delete m_floatingMediaQueryExp; delete m_floatingMediaQuery; deleteAllValues(m_floatingSelectors); deleteAllValues(m_floatingValueLists); deleteAllValues(m_floatingFunctions); deleteAllValues(m_reusableSelectorVector);}void CSSParserString::lower(){ // FIXME: If we need Unicode lowercasing here, then we probably want the real kind // that can potentially change the length of the string rather than the character // by character kind. If we don't need Unicode lowercasing, it would be good to // simplify this function. if (charactersAreAllASCII(characters, length)) { // Fast case for all-ASCII. for (int i = 0; i < length; i++) characters[i] = toASCIILower(characters[i]); } else { for (int i = 0; i < length; i++) characters[i] = Unicode::toLower(characters[i]); }}void CSSParser::setupParser(const char* prefix, const String& string, const char* suffix){ int length = string.length() + strlen(prefix) + strlen(suffix) + 2; fastFree(m_data); m_data = static_cast<UChar*>(fastMalloc(length * sizeof(UChar))); for (unsigned i = 0; i < strlen(prefix); i++) m_data[i] = prefix[i]; memcpy(m_data + strlen(prefix), string.characters(), string.length() * sizeof(UChar)); unsigned start = strlen(prefix) + string.length(); unsigned end = start + strlen(suffix); for (unsigned i = start; i < end; i++) m_data[i] = suffix[i - start]; m_data[length - 1] = 0; m_data[length - 2] = 0; yy_hold_char = 0; yyleng = 0; yytext = yy_c_buf_p = m_data; yy_hold_char = *yy_c_buf_p;}void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string){ m_styleSheet = sheet; m_defaultNamespace = starAtom; // Reset the default namespace. setupParser("", string, ""); cssyyparse(this); m_rule = 0;}PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& string){ m_styleSheet = sheet; setupParser("@-webkit-rule{", string, "} "); cssyyparse(this); return m_rule.release();}PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const String &string){ m_styleSheet = sheet; setupParser("@-webkit-keyframe-rule{ ", string, "} "); cssyyparse(this); return m_keyframe.release();}bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int id, const String& string, bool important){ ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); setupParser("@-webkit-value{", string, "} "); m_id = id; m_important = important; cssyyparse(this); m_rule = 0; bool ok = false; if (m_hasFontFaceOnlyValues) deleteFontFaceOnlyValues(); if (m_numParsedProperties) { ok = true; declaration->addParsedProperties(m_parsedProperties, m_numParsedProperties); clearProperties(); } return ok;}// color will only be changed when string contains a valid css color, making it// possible to set up a default color.bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict){ color = 0; CSSParser parser(true); // First try creating a color specified by name or the "#" syntax. if (!parser.parseColor(string, color, strict)) { RefPtr<CSSMutableStyleDeclaration> dummyStyleDeclaration = CSSMutableStyleDeclaration::create(); // Now try to create a color from the rgb() or rgba() syntax. if (parser.parseColor(dummyStyleDeclaration.get(), string)) { CSSValue* value = parser.m_parsedProperties[0]->value(); if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) { CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); color = primitiveValue->getRGBColorValue(); } } else return false; } return true;}bool CSSParser::parseColor(CSSMutableStyleDeclaration* declaration, const String& string){ ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); setupParser("@-webkit-decls{color:", string, "} "); cssyyparse(this); m_rule = 0; return (m_numParsedProperties && m_parsedProperties[0]->m_id == CSSPropertyColor);}void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorList& selectorList){ RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc); m_styleSheet = dummyStyleSheet.get(); m_selectorListForParseSelector = &selectorList; setupParser("@-webkit-selector{", string, "}"); cssyyparse(this); m_selectorListForParseSelector = 0;}bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const String& string){ ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); setupParser("@-webkit-decls{", string, "} "); cssyyparse(this); m_rule = 0; bool ok = false; if (m_hasFontFaceOnlyValues)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -