1 /* 2 * (C) 1999-2003 Lars Knoll (knoll (at) kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2007, 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 #include "config.h" 22 #include "core/css/CSSValueList.h" 23 24 #include "core/css/CSSParserValues.h" 25 #include "wtf/text/StringBuilder.h" 26 27 namespace WebCore { 28 29 CSSValueList::CSSValueList(ClassType classType, ValueListSeparator listSeparator) 30 : CSSValue(classType) 31 { 32 m_valueListSeparator = listSeparator; 33 } 34 35 CSSValueList::CSSValueList(ValueListSeparator listSeparator) 36 : CSSValue(ValueListClass) 37 { 38 m_valueListSeparator = listSeparator; 39 } 40 41 CSSValueList::CSSValueList(CSSParserValueList* parserValues) 42 : CSSValue(ValueListClass) 43 { 44 m_valueListSeparator = SpaceSeparator; 45 if (parserValues) { 46 m_values.reserveInitialCapacity(parserValues->size()); 47 for (unsigned i = 0; i < parserValues->size(); ++i) 48 m_values.uncheckedAppend(parserValues->valueAt(i)->createCSSValue()); 49 } 50 } 51 52 bool CSSValueList::removeAll(CSSValue* val) 53 { 54 bool found = false; 55 for (size_t index = 0; index < m_values.size(); index++) { 56 RefPtr<CSSValue>& value = m_values.at(index); 57 if (value && val && value->equals(*val)) { 58 m_values.remove(index); 59 found = true; 60 } 61 } 62 63 return found; 64 } 65 66 bool CSSValueList::hasValue(CSSValue* val) const 67 { 68 for (size_t index = 0; index < m_values.size(); index++) { 69 const RefPtr<CSSValue>& value = m_values.at(index); 70 if (value && val && value->equals(*val)) 71 return true; 72 } 73 return false; 74 } 75 76 PassRefPtr<CSSValueList> CSSValueList::copy() 77 { 78 RefPtr<CSSValueList> newList; 79 switch (m_valueListSeparator) { 80 case SpaceSeparator: 81 newList = createSpaceSeparated(); 82 break; 83 case CommaSeparator: 84 newList = createCommaSeparated(); 85 break; 86 case SlashSeparator: 87 newList = createSlashSeparated(); 88 break; 89 default: 90 ASSERT_NOT_REACHED(); 91 } 92 for (size_t index = 0; index < m_values.size(); index++) 93 newList->append(m_values[index]); 94 return newList.release(); 95 } 96 97 String CSSValueList::customCssText(CssTextFormattingFlags formattingFlag) const 98 { 99 StringBuilder result; 100 String separator; 101 switch (m_valueListSeparator) { 102 case SpaceSeparator: 103 separator = " "; 104 break; 105 case CommaSeparator: 106 separator = ", "; 107 break; 108 case SlashSeparator: 109 separator = " / "; 110 break; 111 default: 112 ASSERT_NOT_REACHED(); 113 } 114 115 unsigned size = m_values.size(); 116 for (unsigned i = 0; i < size; i++) { 117 if (!result.isEmpty()) 118 result.append(separator); 119 if (formattingFlag == AlwaysQuoteCSSString && m_values[i]->isPrimitiveValue()) 120 result.append(toCSSPrimitiveValue(m_values[i].get())->customCssText(AlwaysQuoteCSSString)); 121 else 122 result.append(m_values[i]->cssText()); 123 } 124 125 return result.toString(); 126 } 127 128 bool CSSValueList::equals(const CSSValueList& other) const 129 { 130 return m_valueListSeparator == other.m_valueListSeparator && compareCSSValueVector<CSSValue>(m_values, other.m_values); 131 } 132 133 bool CSSValueList::equals(const CSSValue& other) const 134 { 135 if (m_values.size() != 1) 136 return false; 137 138 const RefPtr<CSSValue>& value = m_values[0]; 139 return value && value->equals(other); 140 } 141 142 String CSSValueList::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const 143 { 144 StringBuilder result; 145 String separator; 146 switch (m_valueListSeparator) { 147 case SpaceSeparator: 148 separator = " "; 149 break; 150 case CommaSeparator: 151 separator = ", "; 152 break; 153 case SlashSeparator: 154 separator = " / "; 155 break; 156 default: 157 ASSERT_NOT_REACHED(); 158 } 159 160 unsigned size = m_values.size(); 161 for (unsigned i = 0; i < size; i++) { 162 if (!result.isEmpty()) 163 result.append(separator); 164 result.append(m_values[i]->serializeResolvingVariables(variables)); 165 } 166 167 return result.toString(); 168 } 169 170 void CSSValueList::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const 171 { 172 size_t size = m_values.size(); 173 for (size_t i = 0; i < size; ++i) 174 m_values[i]->addSubresourceStyleURLs(urls, styleSheet); 175 } 176 177 bool CSSValueList::hasFailedOrCanceledSubresources() const 178 { 179 for (unsigned i = 0; i < m_values.size(); ++i) { 180 if (m_values[i]->hasFailedOrCanceledSubresources()) 181 return true; 182 } 183 return false; 184 } 185 186 CSSValueList::CSSValueList(const CSSValueList& cloneFrom) 187 : CSSValue(cloneFrom.classType(), /* isCSSOMSafe */ true) 188 { 189 m_valueListSeparator = cloneFrom.m_valueListSeparator; 190 m_values.resize(cloneFrom.m_values.size()); 191 for (unsigned i = 0; i < m_values.size(); ++i) 192 m_values[i] = cloneFrom.m_values[i]->cloneForCSSOM(); 193 } 194 195 PassRefPtr<CSSValueList> CSSValueList::cloneForCSSOM() const 196 { 197 return adoptRef(new CSSValueList(*this)); 198 } 199 200 } // namespace WebCore 201