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 |
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 |