1/* 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2008 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#include "config.h" 22#include "CSSParserValues.h" 23 24#include "CSSPrimitiveValue.h" 25#include "CSSFunctionValue.h" 26#include "CSSSelector.h" 27#include "CSSSelectorList.h" 28#if ENABLE(CSS_VARIABLES) 29#include "CSSVariableValue.h" 30#endif 31 32namespace WebCore { 33 34using namespace WTF; 35 36CSSParserValueList::~CSSParserValueList() 37{ 38 size_t numValues = m_values.size(); 39 for (size_t i = 0; i < numValues; i++) { 40 if (m_values[i].unit == CSSParserValue::Function) 41 delete m_values[i].function; 42 } 43} 44 45void CSSParserValueList::addValue(const CSSParserValue& v) 46{ 47 m_values.append(v); 48} 49 50void CSSParserValueList::insertValueAt(unsigned i, const CSSParserValue& v) 51{ 52 m_values.insert(i, v); 53} 54 55void CSSParserValueList::deleteValueAt(unsigned i) 56{ 57 m_values.remove(i); 58} 59 60void CSSParserValueList::extend(CSSParserValueList& valueList) 61{ 62 for (unsigned int i = 0; i < valueList.size(); ++i) 63 m_values.append(*(valueList.valueAt(i))); 64} 65 66PassRefPtr<CSSValue> CSSParserValue::createCSSValue() 67{ 68 RefPtr<CSSValue> parsedValue; 69 if (id) 70 return CSSPrimitiveValue::createIdentifier(id); 71 72 if (unit == CSSParserValue::Operator) { 73 RefPtr<CSSPrimitiveValue> primitiveValue = CSSPrimitiveValue::createIdentifier(iValue); 74 primitiveValue->setPrimitiveType(CSSPrimitiveValue::CSS_PARSER_OPERATOR); 75 return primitiveValue; 76 } 77 if (unit == CSSParserValue::Function) 78 return CSSFunctionValue::create(function); 79 if (unit >= CSSParserValue::Q_EMS) 80 return CSSPrimitiveValue::createAllowingMarginQuirk(fValue, CSSPrimitiveValue::CSS_EMS); 81 82 CSSPrimitiveValue::UnitTypes primitiveUnit = static_cast<CSSPrimitiveValue::UnitTypes>(unit); 83 switch (primitiveUnit) { 84 case CSSPrimitiveValue::CSS_IDENT: 85 return CSSPrimitiveValue::create(string, CSSPrimitiveValue::CSS_PARSER_IDENTIFIER); 86 case CSSPrimitiveValue::CSS_NUMBER: 87 return CSSPrimitiveValue::create(fValue, isInt ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER); 88 case CSSPrimitiveValue::CSS_STRING: 89 case CSSPrimitiveValue::CSS_URI: 90#if ENABLE(CSS_VARIABLES) 91 case CSSPrimitiveValue::CSS_VARIABLE_NAME: 92#endif 93 case CSSPrimitiveValue::CSS_PARSER_HEXCOLOR: 94 return CSSPrimitiveValue::create(string, primitiveUnit); 95 case CSSPrimitiveValue::CSS_PERCENTAGE: 96 case CSSPrimitiveValue::CSS_EMS: 97 case CSSPrimitiveValue::CSS_EXS: 98 case CSSPrimitiveValue::CSS_PX: 99 case CSSPrimitiveValue::CSS_CM: 100 case CSSPrimitiveValue::CSS_MM: 101 case CSSPrimitiveValue::CSS_IN: 102 case CSSPrimitiveValue::CSS_PT: 103 case CSSPrimitiveValue::CSS_PC: 104 case CSSPrimitiveValue::CSS_DEG: 105 case CSSPrimitiveValue::CSS_RAD: 106 case CSSPrimitiveValue::CSS_GRAD: 107 case CSSPrimitiveValue::CSS_MS: 108 case CSSPrimitiveValue::CSS_S: 109 case CSSPrimitiveValue::CSS_HZ: 110 case CSSPrimitiveValue::CSS_KHZ: 111 case CSSPrimitiveValue::CSS_VW: 112 case CSSPrimitiveValue::CSS_VH: 113 case CSSPrimitiveValue::CSS_VMIN: 114 case CSSPrimitiveValue::CSS_VMAX: 115 case CSSPrimitiveValue::CSS_TURN: 116 case CSSPrimitiveValue::CSS_REMS: 117 case CSSPrimitiveValue::CSS_CHS: 118 return CSSPrimitiveValue::create(fValue, primitiveUnit); 119 case CSSPrimitiveValue::CSS_UNKNOWN: 120 case CSSPrimitiveValue::CSS_DIMENSION: 121 case CSSPrimitiveValue::CSS_ATTR: 122 case CSSPrimitiveValue::CSS_COUNTER: 123 case CSSPrimitiveValue::CSS_RECT: 124 case CSSPrimitiveValue::CSS_RGBCOLOR: 125 case CSSPrimitiveValue::CSS_DPPX: 126 case CSSPrimitiveValue::CSS_DPI: 127 case CSSPrimitiveValue::CSS_DPCM: 128 case CSSPrimitiveValue::CSS_PAIR: 129#if ENABLE(DASHBOARD_SUPPORT) 130 case CSSPrimitiveValue::CSS_DASHBOARD_REGION: 131#endif 132 case CSSPrimitiveValue::CSS_UNICODE_RANGE: 133 case CSSPrimitiveValue::CSS_PARSER_OPERATOR: 134 case CSSPrimitiveValue::CSS_PARSER_INTEGER: 135 case CSSPrimitiveValue::CSS_PARSER_IDENTIFIER: 136 case CSSPrimitiveValue::CSS_COUNTER_NAME: 137 case CSSPrimitiveValue::CSS_SHAPE: 138 case CSSPrimitiveValue::CSS_QUAD: 139 case CSSPrimitiveValue::CSS_CALC: 140 case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER: 141 case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH: 142 return 0; 143 } 144 145 ASSERT_NOT_REACHED(); 146 return 0; 147} 148 149CSSParserSelector::CSSParserSelector() 150 : m_selector(adoptPtr(fastNew<CSSSelector>())) 151{ 152} 153 154CSSParserSelector::CSSParserSelector(const QualifiedName& tagQName) 155 : m_selector(adoptPtr(new CSSSelector(tagQName))) 156{ 157} 158 159CSSParserSelector::~CSSParserSelector() 160{ 161 if (!m_tagHistory) 162 return; 163 Vector<OwnPtr<CSSParserSelector>, 16> toDelete; 164 OwnPtr<CSSParserSelector> selector = m_tagHistory.release(); 165 while (true) { 166 OwnPtr<CSSParserSelector> next = selector->m_tagHistory.release(); 167 toDelete.append(selector.release()); 168 if (!next) 169 break; 170 selector = next.release(); 171 } 172} 173 174void CSSParserSelector::adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector) 175{ 176 CSSSelectorList* selectorList = fastNew<CSSSelectorList>(); 177 selectorList->adoptSelectorVector(selectorVector); 178 m_selector->setSelectorList(adoptPtr(selectorList)); 179} 180 181bool CSSParserSelector::isSimple() const 182{ 183 if (m_selector->selectorList() || m_selector->matchesPseudoElement()) 184 return false; 185 186 if (!m_tagHistory) 187 return true; 188 189 if (m_selector->m_match == CSSSelector::Tag) { 190 // We can't check against anyQName() here because namespace may not be nullAtom. 191 // Example: 192 // @namespace "http://www.w3.org/2000/svg"; 193 // svg:not(:root) { ... 194 if (m_selector->tagQName().localName() == starAtom) 195 return m_tagHistory->isSimple(); 196 } 197 198 return false; 199} 200 201void CSSParserSelector::insertTagHistory(CSSSelector::Relation before, PassOwnPtr<CSSParserSelector> selector, CSSSelector::Relation after) 202{ 203 if (m_tagHistory) 204 selector->setTagHistory(m_tagHistory.release()); 205 setRelation(before); 206 selector->setRelation(after); 207 m_tagHistory = selector; 208} 209 210void CSSParserSelector::appendTagHistory(CSSSelector::Relation relation, PassOwnPtr<CSSParserSelector> selector) 211{ 212 CSSParserSelector* end = this; 213 while (end->tagHistory()) 214 end = end->tagHistory(); 215 end->setRelation(relation); 216 end->setTagHistory(selector); 217} 218 219void CSSParserSelector::prependTagSelector(const QualifiedName& tagQName, bool tagIsForNamespaceRule) 220{ 221 OwnPtr<CSSParserSelector> second = adoptPtr(new CSSParserSelector); 222 second->m_selector = m_selector.release(); 223 second->m_tagHistory = m_tagHistory.release(); 224 m_tagHistory = second.release(); 225 226 m_selector = adoptPtr(new CSSSelector(tagQName, tagIsForNamespaceRule)); 227 m_selector->m_relation = CSSSelector::SubSelector; 228} 229 230} 231 232