OLD | NEW |
---|---|
1 /* | 1 /* |
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) | 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. |
4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. | 4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. |
5 * Copyright (C) 2013 Intel Corporation. All rights reserved. | 5 * Copyright (C) 2013 Intel Corporation. All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 if (metadataArray()[n].m_propertyID == id) { | 112 if (metadataArray()[n].m_propertyID == id) { |
113 // Only enabled properties should be part of the style. | 113 // Only enabled properties should be part of the style. |
114 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); | 114 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); |
115 return n; | 115 return n; |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 return -1; | 119 return -1; |
120 } | 120 } |
121 | 121 |
122 int ImmutableStylePropertySet::findCustomPropertyIndex(const AtomicString& prope rtyName) const | |
123 { | |
124 // Convert here propertyID into an uint16_t to compare it with the metadata' s m_propertyID to avoid | |
125 // the compiler converting it to an int multiple times in the loop. | |
126 const uint16_t variableId = static_cast<uint16_t>(CSSPropertyVariable); | |
127 | |
128 for (int n = m_arraySize - 1 ; n >= 0; --n) { | |
129 if (metadataArray()[n].m_propertyID == variableId | |
130 && toCSSCustomPropertyDeclaration(valueArray()[n])->name() == proper tyName) | |
131 return n; | |
132 } | |
133 | |
134 return -1; | |
135 } | |
136 | |
122 DEFINE_TRACE_AFTER_DISPATCH(ImmutableStylePropertySet) | 137 DEFINE_TRACE_AFTER_DISPATCH(ImmutableStylePropertySet) |
123 { | 138 { |
124 const RawPtrWillBeMember<CSSValue>* values = valueArray(); | 139 const RawPtrWillBeMember<CSSValue>* values = valueArray(); |
125 for (unsigned i = 0; i < m_arraySize; i++) | 140 for (unsigned i = 0; i < m_arraySize; i++) |
126 visitor->trace(values[i]); | 141 visitor->trace(values[i]); |
127 StylePropertySet::traceAfterDispatch(visitor); | 142 StylePropertySet::traceAfterDispatch(visitor); |
128 } | 143 } |
129 | 144 |
130 MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other) | 145 MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other) |
131 : StylePropertySet(other.cssParserMode()) | 146 : StylePropertySet(other.cssParserMode()) |
132 { | 147 { |
133 if (other.isMutable()) { | 148 if (other.isMutable()) { |
134 m_propertyVector = toMutableStylePropertySet(other).m_propertyVector; | 149 m_propertyVector = toMutableStylePropertySet(other).m_propertyVector; |
135 } else { | 150 } else { |
136 m_propertyVector.reserveInitialCapacity(other.propertyCount()); | 151 m_propertyVector.reserveInitialCapacity(other.propertyCount()); |
137 for (unsigned i = 0; i < other.propertyCount(); ++i) | 152 for (unsigned i = 0; i < other.propertyCount(); ++i) |
138 m_propertyVector.uncheckedAppend(other.propertyAt(i).toCSSProperty() ); | 153 m_propertyVector.uncheckedAppend(other.propertyAt(i).toCSSProperty() ); |
139 } | 154 } |
140 } | 155 } |
141 | 156 |
142 String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const | 157 String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const |
143 { | 158 { |
144 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID); | 159 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID); |
145 if (value) | 160 if (value) |
146 return value->cssText(); | 161 return value->cssText(); |
147 | 162 |
148 return StylePropertySerializer(*this).getPropertyValue(propertyID); | 163 return StylePropertySerializer(*this).getPropertyValue(propertyID); |
149 } | 164 } |
150 | 165 |
166 String StylePropertySet::getCustomPropertyValue(const AtomicString& propertyName ) const | |
167 { | |
168 RefPtrWillBeRawPtr<CSSValue> value = getCustomPropertyCSSValue(propertyName) ; | |
169 return value ? value->cssText() : ""; | |
170 } | |
171 | |
151 PassRefPtrWillBeRawPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSProper tyID propertyID) const | 172 PassRefPtrWillBeRawPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSProper tyID propertyID) const |
152 { | 173 { |
153 int foundPropertyIndex = findPropertyIndex(propertyID); | 174 int foundPropertyIndex = findPropertyIndex(propertyID); |
154 if (foundPropertyIndex == -1) | 175 if (foundPropertyIndex == -1) |
155 return nullptr; | 176 return nullptr; |
156 return propertyAt(foundPropertyIndex).value(); | 177 return propertyAt(foundPropertyIndex).value(); |
157 } | 178 } |
158 | 179 |
180 PassRefPtrWillBeRawPtr<CSSCustomPropertyDeclaration> StylePropertySet::getCustom PropertyCSSValue(const AtomicString& propertyName) const | |
181 { | |
182 int foundPropertyIndex = findCustomPropertyIndex(propertyName); | |
183 if (foundPropertyIndex == -1) | |
184 return nullptr; | |
185 return toCSSCustomPropertyDeclaration(propertyAt(foundPropertyIndex).value() ); | |
186 } | |
187 | |
159 DEFINE_TRACE(StylePropertySet) | 188 DEFINE_TRACE(StylePropertySet) |
160 { | 189 { |
161 if (m_isMutable) | 190 if (m_isMutable) |
162 toMutableStylePropertySet(this)->traceAfterDispatch(visitor); | 191 toMutableStylePropertySet(this)->traceAfterDispatch(visitor); |
163 else | 192 else |
164 toImmutableStylePropertySet(this)->traceAfterDispatch(visitor); | 193 toImmutableStylePropertySet(this)->traceAfterDispatch(visitor); |
165 } | 194 } |
166 | 195 |
167 #if ENABLE(OILPAN) | 196 #if ENABLE(OILPAN) |
168 void StylePropertySet::finalizeGarbageCollectedObject() | 197 void StylePropertySet::finalizeGarbageCollectedObject() |
169 { | 198 { |
170 if (m_isMutable) | 199 if (m_isMutable) |
171 toMutableStylePropertySet(this)->~MutableStylePropertySet(); | 200 toMutableStylePropertySet(this)->~MutableStylePropertySet(); |
172 else | 201 else |
173 toImmutableStylePropertySet(this)->~ImmutableStylePropertySet(); | 202 toImmutableStylePropertySet(this)->~ImmutableStylePropertySet(); |
174 } | 203 } |
175 #endif | 204 #endif |
176 | 205 |
177 bool MutableStylePropertySet::removeShorthandProperty(CSSPropertyID propertyID) | 206 bool MutableStylePropertySet::removeShorthandProperty(CSSPropertyID propertyID) |
178 { | 207 { |
179 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); | 208 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); |
180 if (!shorthand.length()) | 209 if (!shorthand.length()) |
181 return false; | 210 return false; |
182 | 211 |
183 return removePropertiesInSet(shorthand.properties(), shorthand.length()); | 212 return removePropertiesInSet(shorthand.properties(), shorthand.length()); |
184 } | 213 } |
185 | 214 |
215 bool MutableStylePropertySet::removePropertyAtIndex(int propertyIndex, String* r eturnText) | |
216 { | |
217 if (propertyIndex == -1) { | |
218 if (returnText) | |
219 *returnText = ""; | |
220 return false; | |
221 } | |
222 | |
223 if (returnText) | |
224 *returnText = propertyAt(propertyIndex).value()->cssText(); | |
225 | |
226 // A more efficient removal strategy would involve marking entries as empty | |
227 // and sweeping them when the vector grows too big. | |
228 m_propertyVector.remove(propertyIndex); | |
229 | |
230 return true; | |
231 } | |
232 | |
186 bool MutableStylePropertySet::removeProperty(CSSPropertyID propertyID, String* r eturnText) | 233 bool MutableStylePropertySet::removeProperty(CSSPropertyID propertyID, String* r eturnText) |
187 { | 234 { |
188 if (removeShorthandProperty(propertyID)) { | 235 if (removeShorthandProperty(propertyID)) { |
189 // FIXME: Return an equivalent shorthand when possible. | 236 // FIXME: Return an equivalent shorthand when possible. |
190 if (returnText) | 237 if (returnText) |
191 *returnText = ""; | 238 *returnText = ""; |
192 return true; | 239 return true; |
193 } | 240 } |
194 | 241 |
195 int foundPropertyIndex = findPropertyIndex(propertyID); | 242 int foundPropertyIndex = findPropertyIndex(propertyID); |
196 if (foundPropertyIndex == -1) { | 243 return removePropertyAtIndex(foundPropertyIndex, returnText); |
197 if (returnText) | 244 } |
198 *returnText = ""; | |
199 return false; | |
200 } | |
201 | 245 |
202 if (returnText) | 246 bool MutableStylePropertySet::removeCustomProperty(const AtomicString& propertyN ame, String* returnText) |
203 *returnText = propertyAt(foundPropertyIndex).value()->cssText(); | 247 { |
204 | 248 int foundPropertyIndex = findCustomPropertyIndex(propertyName); |
205 // A more efficient removal strategy would involve marking entries as empty | 249 return removePropertyAtIndex(foundPropertyIndex, returnText); |
206 // and sweeping them when the vector grows too big. | |
207 m_propertyVector.remove(foundPropertyIndex); | |
208 | |
209 return true; | |
210 } | 250 } |
211 | 251 |
212 bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const | 252 bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const |
213 { | 253 { |
214 int foundPropertyIndex = findPropertyIndex(propertyID); | 254 int foundPropertyIndex = findPropertyIndex(propertyID); |
215 if (foundPropertyIndex != -1) | 255 if (foundPropertyIndex != -1) |
216 return propertyAt(foundPropertyIndex).isImportant(); | 256 return propertyAt(foundPropertyIndex).isImportant(); |
217 | 257 |
218 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); | 258 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); |
219 if (!shorthand.length()) | 259 if (!shorthand.length()) |
220 return false; | 260 return false; |
221 | 261 |
222 for (unsigned i = 0; i < shorthand.length(); ++i) { | 262 for (unsigned i = 0; i < shorthand.length(); ++i) { |
223 if (!propertyIsImportant(shorthand.properties()[i])) | 263 if (!propertyIsImportant(shorthand.properties()[i])) |
224 return false; | 264 return false; |
225 } | 265 } |
226 return true; | 266 return true; |
227 } | 267 } |
228 | 268 |
269 bool StylePropertySet::customPropertyIsImportant(const AtomicString& propertyNam e) const | |
270 { | |
271 int foundPropertyIndex = findCustomPropertyIndex(propertyName); | |
272 if (foundPropertyIndex != -1) | |
273 return propertyAt(foundPropertyIndex).isImportant(); | |
274 return false; | |
275 } | |
276 | |
229 CSSPropertyID StylePropertySet::getPropertyShorthand(CSSPropertyID propertyID) c onst | 277 CSSPropertyID StylePropertySet::getPropertyShorthand(CSSPropertyID propertyID) c onst |
230 { | 278 { |
231 int foundPropertyIndex = findPropertyIndex(propertyID); | 279 int foundPropertyIndex = findPropertyIndex(propertyID); |
232 if (foundPropertyIndex == -1) | 280 if (foundPropertyIndex == -1) |
233 return CSSPropertyInvalid; | 281 return CSSPropertyInvalid; |
234 return propertyAt(foundPropertyIndex).shorthandID(); | 282 return propertyAt(foundPropertyIndex).shorthandID(); |
235 } | 283 } |
236 | 284 |
237 bool StylePropertySet::isPropertyImplicit(CSSPropertyID propertyID) const | 285 bool StylePropertySet::isPropertyImplicit(CSSPropertyID propertyID) const |
238 { | 286 { |
239 int foundPropertyIndex = findPropertyIndex(propertyID); | 287 int foundPropertyIndex = findPropertyIndex(propertyID); |
240 if (foundPropertyIndex == -1) | 288 if (foundPropertyIndex == -1) |
241 return false; | 289 return false; |
242 return propertyAt(foundPropertyIndex).isImplicit(); | 290 return propertyAt(foundPropertyIndex).isImplicit(); |
243 } | 291 } |
244 | 292 |
245 bool MutableStylePropertySet::setProperty(CSSPropertyID unresolvedProperty, cons t String& value, bool important, StyleSheetContents* contextStyleSheet) | 293 bool MutableStylePropertySet::setProperty(CSSPropertyID unresolvedProperty, cons t String& value, bool important, StyleSheetContents* contextStyleSheet) |
246 { | 294 { |
247 // Setting the value to an empty string just removes the property in both IE and Gecko. | 295 // Setting the value to an empty string just removes the property in both IE and Gecko. |
248 // Setting it to null seems to produce less consistent results, but we treat it just the same. | 296 // Setting it to null seems to produce less consistent results, but we treat it just the same. |
249 if (value.isEmpty()) | 297 if (value.isEmpty()) |
250 return removeProperty(resolveCSSPropertyID(unresolvedProperty)); | 298 return removeProperty(resolveCSSPropertyID(unresolvedProperty)); |
251 | 299 |
252 // When replacing an existing property value, this moves the property to the end of the list. | 300 // When replacing an existing property value, this moves the property to the end of the list. |
253 // Firefox preserves the position, and MSIE moves the property to the beginn ing. | 301 // Firefox preserves the position, and MSIE moves the property to the beginn ing. |
254 return CSSParser::parseValue(this, unresolvedProperty, value, important, con textStyleSheet); | 302 return CSSParser::parseValue(this, unresolvedProperty, value, important, con textStyleSheet); |
255 } | 303 } |
256 | 304 |
305 bool MutableStylePropertySet::setCustomProperty(const AtomicString& propertyName , const String& value, bool important, StyleSheetContents* contextStyleSheet) | |
306 { | |
307 if (value.isEmpty()) | |
308 return removeCustomProperty(propertyName); | |
309 return CSSParser::parseValueForCustomProperty(this, propertyName, value, imp ortant, contextStyleSheet); | |
310 } | |
311 | |
257 void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtrWi llBeRawPtr<CSSValue> prpValue, bool important) | 312 void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtrWi llBeRawPtr<CSSValue> prpValue, bool important) |
258 { | 313 { |
259 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); | 314 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); |
260 if (!shorthand.length()) { | 315 if (!shorthand.length()) { |
261 setProperty(CSSProperty(propertyID, prpValue, important)); | 316 setProperty(CSSProperty(propertyID, prpValue, important)); |
262 return; | 317 return; |
263 } | 318 } |
264 | 319 |
265 removePropertiesInSet(shorthand.properties(), shorthand.length()); | 320 removePropertiesInSet(shorthand.properties(), shorthand.length()); |
266 | 321 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 String StylePropertySet::asText() const | 378 String StylePropertySet::asText() const |
324 { | 379 { |
325 return StylePropertySerializer(*this).asText(); | 380 return StylePropertySerializer(*this).asText(); |
326 } | 381 } |
327 | 382 |
328 void MutableStylePropertySet::mergeAndOverrideOnConflict(const StylePropertySet* other) | 383 void MutableStylePropertySet::mergeAndOverrideOnConflict(const StylePropertySet* other) |
329 { | 384 { |
330 unsigned size = other->propertyCount(); | 385 unsigned size = other->propertyCount(); |
331 for (unsigned n = 0; n < size; ++n) { | 386 for (unsigned n = 0; n < size; ++n) { |
332 PropertyReference toMerge = other->propertyAt(n); | 387 PropertyReference toMerge = other->propertyAt(n); |
388 // TODO(leviw): This probably doesn't work correctly with Custom Propert ies | |
333 CSSProperty* old = findCSSPropertyWithID(toMerge.id()); | 389 CSSProperty* old = findCSSPropertyWithID(toMerge.id()); |
334 if (old) | 390 if (old) |
335 setProperty(toMerge.toCSSProperty(), old); | 391 setProperty(toMerge.toCSSProperty(), old); |
336 else | 392 else |
337 m_propertyVector.append(toMerge.toCSSProperty()); | 393 m_propertyVector.append(toMerge.toCSSProperty()); |
338 } | 394 } |
339 } | 395 } |
340 | 396 |
341 bool StylePropertySet::hasFailedOrCanceledSubresources() const | 397 bool StylePropertySet::hasFailedOrCanceledSubresources() const |
342 { | 398 { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 } | 435 } |
380 if (newIndex != oldSize) { | 436 if (newIndex != oldSize) { |
381 m_propertyVector.shrink(newIndex); | 437 m_propertyVector.shrink(newIndex); |
382 return true; | 438 return true; |
383 } | 439 } |
384 return false; | 440 return false; |
385 } | 441 } |
386 | 442 |
387 CSSProperty* MutableStylePropertySet::findCSSPropertyWithID(CSSPropertyID proper tyID) | 443 CSSProperty* MutableStylePropertySet::findCSSPropertyWithID(CSSPropertyID proper tyID) |
388 { | 444 { |
445 // TODO(leviw): Calling this with a custom property should probably assert, or this | |
446 // method should alternatively take a string used for custom properties and check it | |
447 // in that case. | |
448 if (propertyID == CSSPropertyVariable) | |
449 return nullptr; | |
450 | |
389 int foundPropertyIndex = findPropertyIndex(propertyID); | 451 int foundPropertyIndex = findPropertyIndex(propertyID); |
390 if (foundPropertyIndex == -1) | 452 if (foundPropertyIndex == -1) |
391 return nullptr; | 453 return nullptr; |
392 return &m_propertyVector.at(foundPropertyIndex); | 454 return &m_propertyVector.at(foundPropertyIndex); |
393 } | 455 } |
394 | 456 |
395 bool StylePropertySet::propertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const | 457 bool StylePropertySet::propertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const |
396 { | 458 { |
397 int foundPropertyIndex = findPropertyIndex(propertyID); | 459 int foundPropertyIndex = findPropertyIndex(propertyID); |
398 if (foundPropertyIndex == -1) | 460 if (foundPropertyIndex == -1) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 return true; | 535 return true; |
474 } | 536 } |
475 return false; | 537 return false; |
476 }; | 538 }; |
477 | 539 |
478 const CSSProperty* it = std::find_if(begin, end, compare); | 540 const CSSProperty* it = std::find_if(begin, end, compare); |
479 | 541 |
480 return (it == end) ? -1 : it - begin; | 542 return (it == end) ? -1 : it - begin; |
481 } | 543 } |
482 | 544 |
545 int MutableStylePropertySet::findCustomPropertyIndex(const AtomicString& propert yName) const | |
546 { | |
547 const CSSProperty* begin = m_propertyVector.data(); | |
548 const CSSProperty* end = begin + m_propertyVector.size(); | |
549 // Convert here propertyID into an uint16_t to compare it with the metadata' s m_propertyID to avoid | |
550 // the compiler converting it to an int multiple times in the loop. | |
551 const uint16_t variableId = static_cast<uint16_t>(CSSPropertyVariable); | |
552 | |
553 auto compare = [variableId, propertyName](const CSSProperty& property) -> bo ol { | |
554 if (property.metadata().m_propertyID == variableId) { | |
555 return toCSSCustomPropertyDeclaration(property.value())->name() == p ropertyName; | |
556 } | |
557 return false; | |
558 }; | |
559 | |
560 const CSSProperty* it = std::find_if(begin, end, compare); | |
561 | |
562 return (it == end) ? -1 : it - begin; | |
563 } | |
564 | |
alancutter (OOO until 2018)
2015/11/17 07:10:42
The copy paste in this file is pretty unappealing.
leviw_travelin_and_unemployed
2015/11/17 07:23:44
If that saved us code duplication I'd agree. I'm n
alancutter (OOO until 2018)
2015/11/18 21:22:51
Explicit template specialisation isn't something I
| |
483 DEFINE_TRACE_AFTER_DISPATCH(MutableStylePropertySet) | 565 DEFINE_TRACE_AFTER_DISPATCH(MutableStylePropertySet) |
484 { | 566 { |
485 #if ENABLE(OILPAN) | 567 #if ENABLE(OILPAN) |
486 visitor->trace(m_cssomWrapper); | 568 visitor->trace(m_cssomWrapper); |
487 visitor->trace(m_propertyVector); | 569 visitor->trace(m_propertyVector); |
488 #endif | 570 #endif |
489 StylePropertySet::traceAfterDispatch(visitor); | 571 StylePropertySet::traceAfterDispatch(visitor); |
490 } | 572 } |
491 | 573 |
492 unsigned StylePropertySet::averageSizeInBytes() | 574 unsigned StylePropertySet::averageSizeInBytes() |
(...skipping 19 matching lines...) Expand all Loading... | |
512 { | 594 { |
513 return adoptRefWillBeNoop(new MutableStylePropertySet(cssParserMode)); | 595 return adoptRefWillBeNoop(new MutableStylePropertySet(cssParserMode)); |
514 } | 596 } |
515 | 597 |
516 PassRefPtrWillBeRawPtr<MutableStylePropertySet> MutableStylePropertySet::create( const CSSProperty* properties, unsigned count) | 598 PassRefPtrWillBeRawPtr<MutableStylePropertySet> MutableStylePropertySet::create( const CSSProperty* properties, unsigned count) |
517 { | 599 { |
518 return adoptRefWillBeNoop(new MutableStylePropertySet(properties, count)); | 600 return adoptRefWillBeNoop(new MutableStylePropertySet(properties, count)); |
519 } | 601 } |
520 | 602 |
521 } // namespace blink | 603 } // namespace blink |
OLD | NEW |