1/* 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#ifndef CSSParserValues_h 22#define CSSParserValues_h 23 24#include "CSSSelector.h" 25#include "CSSValueKeywords.h" 26#include "CSSValueList.h" 27#include <wtf/text/AtomicString.h> 28#include <wtf/text/WTFString.h> 29 30namespace WebCore { 31 32class CSSValue; 33class QualifiedName; 34 35struct CSSParserString { 36 void init(LChar* characters, unsigned length) 37 { 38 m_data.characters8 = characters; 39 m_length = length; 40 m_is8Bit = true; 41 } 42 43 void init(UChar* characters, unsigned length) 44 { 45 m_data.characters16 = characters; 46 m_length = length; 47 m_is8Bit = false; 48 } 49 50 void init(const String& string) 51 { 52 m_length = string.length(); 53 if (!m_length || string.is8Bit()) { 54 m_data.characters8 = const_cast<LChar*>(string.characters8()); 55 m_is8Bit = true; 56 } else { 57 m_data.characters16 = const_cast<UChar*>(string.characters16()); 58 m_is8Bit = false; 59 } 60 } 61 62 void clear() 63 { 64 m_data.characters8 = 0; 65 m_length = 0; 66 m_is8Bit = true; 67 } 68 69 bool is8Bit() const { return m_is8Bit; } 70 LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; } 71 UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; } 72 template <typename CharacterType> 73 CharacterType* characters() const; 74 75 unsigned length() const { return m_length; } 76 void setLength(unsigned length) { m_length = length; } 77 78 void lower(); 79 80 UChar operator[](unsigned i) const 81 { 82 ASSERT_WITH_SECURITY_IMPLICATION(i < m_length); 83 if (is8Bit()) 84 return m_data.characters8[i]; 85 return m_data.characters16[i]; 86 } 87 88 bool equalIgnoringCase(const char* str) const 89 { 90 if (is8Bit()) 91 return WTF::equalIgnoringCase(str, characters8(), length()); 92 return WTF::equalIgnoringCase(str, characters16(), length()); 93 } 94 95 operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : String(m_data.characters16, m_length); } 96 operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); } 97 98 union { 99 LChar* characters8; 100 UChar* characters16; 101 } m_data; 102 unsigned m_length; 103 bool m_is8Bit; 104}; 105 106struct CSSParserFunction; 107 108struct CSSParserValue { 109 CSSValueID id; 110 bool isInt; 111 union { 112 double fValue; 113 int iValue; 114 CSSParserString string; 115 CSSParserFunction* function; 116 CSSParserValueList* valueList; 117 }; 118 enum { 119 Operator = 0x100000, 120 Function = 0x100001, 121 ValueList = 0x100002, 122 Q_EMS = 0x100003, 123 }; 124 int unit; 125 126 void setFromValueList(std::unique_ptr<CSSParserValueList>); 127 128 PassRefPtr<CSSValue> createCSSValue(); 129}; 130 131void destroy(const CSSParserValue&); 132 133class CSSParserValueList { 134 WTF_MAKE_FAST_ALLOCATED; 135public: 136 CSSParserValueList() 137 : m_current(0) 138 { 139 } 140 ~CSSParserValueList(); 141 142 void addValue(const CSSParserValue&); 143 void insertValueAt(unsigned, const CSSParserValue&); 144 void deleteValueAt(unsigned); 145 void extend(CSSParserValueList&); 146 147 unsigned size() const { return m_values.size(); } 148 unsigned currentIndex() { return m_current; } 149 CSSParserValue* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; } 150 CSSParserValue* next() { ++m_current; return current(); } 151 CSSParserValue* previous() 152 { 153 if (!m_current) 154 return 0; 155 --m_current; 156 return current(); 157 } 158 void setCurrentIndex(unsigned index) 159 { 160 ASSERT(index < m_values.size()); 161 if (index < m_values.size()) 162 m_current = index; 163 } 164 165 CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; } 166 167 void clear() { m_values.clear(); } 168 169private: 170 unsigned m_current; 171 Vector<CSSParserValue, 4> m_values; 172}; 173 174struct CSSParserFunction { 175 WTF_MAKE_FAST_ALLOCATED; 176public: 177 CSSParserString name; 178 std::unique_ptr<CSSParserValueList> args; 179}; 180 181class CSSParserSelector { 182 WTF_MAKE_FAST_ALLOCATED; 183public: 184 static CSSParserSelector* parsePagePseudoSelector(const CSSParserString& pseudoTypeString); 185 static CSSParserSelector* parsePseudoElementSelector(CSSParserString& pseudoTypeString); 186 static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>* selectorVector); 187 static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString); 188 189 CSSParserSelector(); 190 explicit CSSParserSelector(const QualifiedName&); 191 ~CSSParserSelector(); 192 193 std::unique_ptr<CSSSelector> releaseSelector() { return WTF::move(m_selector); } 194 195 void setValue(const AtomicString& value) { m_selector->setValue(value); } 196 void setAttribute(const QualifiedName& value, bool isCaseInsensitive) { m_selector->setAttribute(value, isCaseInsensitive); } 197 void setArgument(const AtomicString& value) { m_selector->setArgument(value); } 198 void setMatch(CSSSelector::Match value) { m_selector->m_match = value; } 199 void setRelation(CSSSelector::Relation value) { m_selector->m_relation = value; } 200 void setForPage() { m_selector->setForPage(); } 201 202 203 void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectorVector); 204 205 void setPseudoClassValue(const CSSParserString& pseudoClassString); 206 CSSSelector::PseudoClassType pseudoClassType() const { return m_selector->pseudoClassType(); } 207 bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); } 208 209 bool isPseudoElementCueFunction() const 210 { 211#if ENABLE(VIDEO_TRACK) 212 return m_selector->m_match == CSSSelector::PseudoElement && m_selector->pseudoElementType() == CSSSelector::PseudoElementCue; 213#else 214 return false; 215#endif 216 } 217 218 bool isSimple() const; 219 bool hasShadowDescendant() const; 220 221 CSSParserSelector* tagHistory() const { return m_tagHistory.get(); } 222 void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTF::move(selector); } 223 void clearTagHistory() { m_tagHistory.reset(); } 224 void insertTagHistory(CSSSelector::Relation before, std::unique_ptr<CSSParserSelector>, CSSSelector::Relation after); 225 void appendTagHistory(CSSSelector::Relation, std::unique_ptr<CSSParserSelector>); 226 void prependTagSelector(const QualifiedName&, bool tagIsForNamespaceRule = false); 227 228private: 229 std::unique_ptr<CSSSelector> m_selector; 230 std::unique_ptr<CSSParserSelector> m_tagHistory; 231}; 232 233inline bool CSSParserSelector::hasShadowDescendant() const 234{ 235 return m_selector->relation() == CSSSelector::ShadowDescendant; 236} 237 238inline void CSSParserValue::setFromValueList(std::unique_ptr<CSSParserValueList> valueList) 239{ 240 id = CSSValueInvalid; 241 this->valueList = valueList.release(); 242 unit = ValueList; 243} 244} 245 246#endif 247