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 24 matching lines...) Expand all Loading... |
35 | 35 |
36 #ifndef NDEBUG | 36 #ifndef NDEBUG |
37 #include "wtf/text/CString.h" | 37 #include "wtf/text/CString.h" |
38 #include <stdio.h> | 38 #include <stdio.h> |
39 #endif | 39 #endif |
40 | 40 |
41 namespace blink { | 41 namespace blink { |
42 | 42 |
43 static size_t sizeForImmutableStylePropertySetWithPropertyCount(unsigned count) | 43 static size_t sizeForImmutableStylePropertySetWithPropertyCount(unsigned count) |
44 { | 44 { |
45 return sizeof(ImmutableStylePropertySet) - sizeof(void*) + sizeof(CSSValue*)
* count + sizeof(StylePropertyMetadata) * count; | 45 return sizeof(ImmutableStylePropertySet) - sizeof(void*) + sizeof(CSSValue)
* count + sizeof(StylePropertyMetadata) * count; |
46 } | 46 } |
47 | 47 |
48 PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> ImmutableStylePropertySet::cre
ate(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode) | 48 PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> ImmutableStylePropertySet::cre
ate(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode) |
49 { | 49 { |
50 ASSERT(count <= MaxArraySize); | 50 ASSERT(count <= MaxArraySize); |
51 #if ENABLE(OILPAN) | 51 #if ENABLE(OILPAN) |
52 void* slot = Heap::allocate<StylePropertySet>(sizeForImmutableStylePropertyS
etWithPropertyCount(count)); | 52 void* slot = Heap::allocate<StylePropertySet>(sizeForImmutableStylePropertyS
etWithPropertyCount(count)); |
53 #else | 53 #else |
54 void* slot = WTF::fastMalloc(sizeForImmutableStylePropertySetWithPropertyCou
nt(count)); | 54 void* slot = WTF::fastMalloc(sizeForImmutableStylePropertySetWithPropertyCou
nt(count)); |
55 #endif // ENABLE(OILPAN) | 55 #endif // ENABLE(OILPAN) |
(...skipping 18 matching lines...) Expand all Loading... |
74 { | 74 { |
75 m_propertyVector.reserveInitialCapacity(length); | 75 m_propertyVector.reserveInitialCapacity(length); |
76 for (unsigned i = 0; i < length; ++i) | 76 for (unsigned i = 0; i < length; ++i) |
77 m_propertyVector.uncheckedAppend(properties[i]); | 77 m_propertyVector.uncheckedAppend(properties[i]); |
78 } | 78 } |
79 | 79 |
80 ImmutableStylePropertySet::ImmutableStylePropertySet(const CSSProperty* properti
es, unsigned length, CSSParserMode cssParserMode) | 80 ImmutableStylePropertySet::ImmutableStylePropertySet(const CSSProperty* properti
es, unsigned length, CSSParserMode cssParserMode) |
81 : StylePropertySet(cssParserMode, length) | 81 : StylePropertySet(cssParserMode, length) |
82 { | 82 { |
83 StylePropertyMetadata* metadataArray = const_cast<StylePropertyMetadata*>(th
is->metadataArray()); | 83 StylePropertyMetadata* metadataArray = const_cast<StylePropertyMetadata*>(th
is->metadataArray()); |
84 RawPtrWillBeMember<CSSValue>* valueArray = const_cast<RawPtrWillBeMember<CSS
Value>*>(this->valueArray()); | 84 CSSValue* valueArray = const_cast<CSSValue*>(this->valueArray()); |
85 for (unsigned i = 0; i < m_arraySize; ++i) { | 85 for (unsigned i = 0; i < m_arraySize; ++i) { |
86 metadataArray[i] = properties[i].metadata(); | 86 metadataArray[i] = properties[i].metadata(); |
87 valueArray[i] = properties[i].value(); | 87 // Can't use operator= here since the valueArray[i] is an invalid CSSVal
ue. |
88 #if !ENABLE(OILPAN) | 88 new(&valueArray[i]) CSSValue(properties[i].value()); |
89 valueArray[i]->ref(); | |
90 #endif | |
91 } | 89 } |
92 } | 90 } |
93 | 91 |
94 ImmutableStylePropertySet::~ImmutableStylePropertySet() | 92 ImmutableStylePropertySet::~ImmutableStylePropertySet() |
95 { | 93 { |
96 #if !ENABLE(OILPAN) | 94 #if !ENABLE(OILPAN) |
97 RawPtrWillBeMember<CSSValue>* valueArray = const_cast<RawPtrWillBeMember<CSS
Value>*>(this->valueArray()); | 95 CSSValue* valueArray = const_cast<CSSValue*>(this->valueArray()); |
98 for (unsigned i = 0; i < m_arraySize; ++i) { | 96 for (unsigned i = 0; i < m_arraySize; ++i) { |
99 // Checking for nullptr here is a workaround to prevent crashing. http:
//crbug.com/449032 | 97 valueArray[i].~CSSValue(); |
100 if (valueArray[i]) | |
101 valueArray[i]->deref(); | |
102 } | 98 } |
103 #endif | 99 #endif |
104 } | 100 } |
105 | 101 |
106 int ImmutableStylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const | 102 int ImmutableStylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const |
107 { | 103 { |
108 // Convert here propertyID into an uint16_t to compare it with the metadata'
s m_propertyID to avoid | 104 // Convert here propertyID into an uint16_t to compare it with the metadata'
s m_propertyID to avoid |
109 // the compiler converting it to an int multiple times in the loop. | 105 // the compiler converting it to an int multiple times in the loop. |
110 uint16_t id = static_cast<uint16_t>(propertyID); | 106 uint16_t id = static_cast<uint16_t>(propertyID); |
111 for (int n = m_arraySize - 1 ; n >= 0; --n) { | 107 for (int n = m_arraySize - 1 ; n >= 0; --n) { |
112 if (metadataArray()[n].m_propertyID == id) { | 108 if (metadataArray()[n].m_propertyID == id) { |
113 // Only enabled properties should be part of the style. | 109 // Only enabled properties should be part of the style. |
114 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); | 110 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); |
115 return n; | 111 return n; |
116 } | 112 } |
117 } | 113 } |
118 | 114 |
119 return -1; | 115 return -1; |
120 } | 116 } |
121 | 117 |
122 DEFINE_TRACE_AFTER_DISPATCH(ImmutableStylePropertySet) | 118 DEFINE_TRACE_AFTER_DISPATCH(ImmutableStylePropertySet) |
123 { | 119 { |
124 const RawPtrWillBeMember<CSSValue>* values = valueArray(); | 120 const CSSValue* values = valueArray(); |
125 for (unsigned i = 0; i < m_arraySize; i++) | 121 for (unsigned i = 0; i < m_arraySize; i++) |
126 visitor->trace(values[i]); | 122 visitor->trace(values[i]); |
127 StylePropertySet::traceAfterDispatch(visitor); | 123 StylePropertySet::traceAfterDispatch(visitor); |
128 } | 124 } |
129 | 125 |
130 MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other) | 126 MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other) |
131 : StylePropertySet(other.cssParserMode()) | 127 : StylePropertySet(other.cssParserMode()) |
132 { | 128 { |
133 if (other.isMutable()) { | 129 if (other.isMutable()) { |
134 m_propertyVector = toMutableStylePropertySet(other).m_propertyVector; | 130 m_propertyVector = toMutableStylePropertySet(other).m_propertyVector; |
135 } else { | 131 } else { |
136 m_propertyVector.reserveInitialCapacity(other.propertyCount()); | 132 m_propertyVector.reserveInitialCapacity(other.propertyCount()); |
137 for (unsigned i = 0; i < other.propertyCount(); ++i) | 133 for (unsigned i = 0; i < other.propertyCount(); ++i) |
138 m_propertyVector.uncheckedAppend(other.propertyAt(i).toCSSProperty()
); | 134 m_propertyVector.uncheckedAppend(other.propertyAt(i).toCSSProperty()
); |
139 } | 135 } |
140 } | 136 } |
141 | 137 |
142 String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const | 138 String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const |
143 { | 139 { |
144 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID); | 140 NullableCSSValue value = getPropertyCSSValue(propertyID); |
145 if (value) | 141 if (value) |
146 return value->cssText(); | 142 return value->cssText(); |
147 | 143 |
148 return StylePropertySerializer(*this).getPropertyValue(propertyID); | 144 return StylePropertySerializer(*this).getPropertyValue(propertyID); |
149 } | 145 } |
150 | 146 |
151 PassRefPtrWillBeRawPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSProper
tyID propertyID) const | 147 NullableCSSValue StylePropertySet::getPropertyCSSValue(CSSPropertyID propertyID)
const |
152 { | 148 { |
153 int foundPropertyIndex = findPropertyIndex(propertyID); | 149 int foundPropertyIndex = findPropertyIndex(propertyID); |
154 if (foundPropertyIndex == -1) | 150 if (foundPropertyIndex == -1) |
155 return nullptr; | 151 return nullptr; |
156 return propertyAt(foundPropertyIndex).value(); | 152 return propertyAt(foundPropertyIndex).value(); |
157 } | 153 } |
158 | 154 |
159 DEFINE_TRACE(StylePropertySet) | 155 DEFINE_TRACE(StylePropertySet) |
160 { | 156 { |
161 if (m_isMutable) | 157 if (m_isMutable) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 } | 189 } |
194 | 190 |
195 int foundPropertyIndex = findPropertyIndex(propertyID); | 191 int foundPropertyIndex = findPropertyIndex(propertyID); |
196 if (foundPropertyIndex == -1) { | 192 if (foundPropertyIndex == -1) { |
197 if (returnText) | 193 if (returnText) |
198 *returnText = ""; | 194 *returnText = ""; |
199 return false; | 195 return false; |
200 } | 196 } |
201 | 197 |
202 if (returnText) | 198 if (returnText) |
203 *returnText = propertyAt(foundPropertyIndex).value()->cssText(); | 199 *returnText = propertyAt(foundPropertyIndex).value().cssText(); |
204 | 200 |
205 // A more efficient removal strategy would involve marking entries as empty | 201 // A more efficient removal strategy would involve marking entries as empty |
206 // and sweeping them when the vector grows too big. | 202 // and sweeping them when the vector grows too big. |
207 m_propertyVector.remove(foundPropertyIndex); | 203 m_propertyVector.remove(foundPropertyIndex); |
208 | 204 |
209 return true; | 205 return true; |
210 } | 206 } |
211 | 207 |
212 bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const | 208 bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const |
213 { | 209 { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 // Setting the value to an empty string just removes the property in both IE
and Gecko. | 243 // 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. | 244 // Setting it to null seems to produce less consistent results, but we treat
it just the same. |
249 if (value.isEmpty()) | 245 if (value.isEmpty()) |
250 return removeProperty(resolveCSSPropertyID(unresolvedProperty)); | 246 return removeProperty(resolveCSSPropertyID(unresolvedProperty)); |
251 | 247 |
252 // When replacing an existing property value, this moves the property to the
end of the list. | 248 // 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. | 249 // Firefox preserves the position, and MSIE moves the property to the beginn
ing. |
254 return CSSParser::parseValue(this, unresolvedProperty, value, important, css
ParserMode(), contextStyleSheet); | 250 return CSSParser::parseValue(this, unresolvedProperty, value, important, css
ParserMode(), contextStyleSheet); |
255 } | 251 } |
256 | 252 |
257 void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtrWi
llBeRawPtr<CSSValue> prpValue, bool important) | 253 void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, CSSValue prp
Value, bool important) |
258 { | 254 { |
259 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); | 255 StylePropertyShorthand shorthand = shorthandForProperty(propertyID); |
260 if (!shorthand.length()) { | 256 if (!shorthand.length()) { |
261 setProperty(CSSProperty(propertyID, prpValue, important)); | 257 setProperty(CSSProperty(propertyID, prpValue, important)); |
262 return; | 258 return; |
263 } | 259 } |
264 | 260 |
265 removePropertiesInSet(shorthand.properties(), shorthand.length()); | 261 removePropertiesInSet(shorthand.properties(), shorthand.length()); |
266 | 262 |
267 RefPtrWillBeRawPtr<CSSValue> value = prpValue; | 263 CSSValue value = prpValue; |
268 for (unsigned i = 0; i < shorthand.length(); ++i) | 264 for (unsigned i = 0; i < shorthand.length(); ++i) |
269 m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, im
portant)); | 265 m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, im
portant)); |
270 } | 266 } |
271 | 267 |
272 bool MutableStylePropertySet::setProperty(const CSSProperty& property, CSSProper
ty* slot) | 268 bool MutableStylePropertySet::setProperty(const CSSProperty& property, CSSProper
ty* slot) |
273 { | 269 { |
274 if (!removeShorthandProperty(property.id())) { | 270 if (!removeShorthandProperty(property.id())) { |
275 CSSProperty* toReplace = slot ? slot : findCSSPropertyWithID(property.id
()); | 271 CSSProperty* toReplace = slot ? slot : findCSSPropertyWithID(property.id
()); |
276 if (toReplace && *toReplace == property) | 272 if (toReplace && *toReplace == property) |
277 return false; | 273 return false; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 setProperty(toMerge.toCSSProperty(), old); | 331 setProperty(toMerge.toCSSProperty(), old); |
336 else | 332 else |
337 m_propertyVector.append(toMerge.toCSSProperty()); | 333 m_propertyVector.append(toMerge.toCSSProperty()); |
338 } | 334 } |
339 } | 335 } |
340 | 336 |
341 bool StylePropertySet::hasFailedOrCanceledSubresources() const | 337 bool StylePropertySet::hasFailedOrCanceledSubresources() const |
342 { | 338 { |
343 unsigned size = propertyCount(); | 339 unsigned size = propertyCount(); |
344 for (unsigned i = 0; i < size; ++i) { | 340 for (unsigned i = 0; i < size; ++i) { |
345 if (propertyAt(i).value()->hasFailedOrCanceledSubresources()) | 341 if (propertyAt(i).value().hasFailedOrCanceledSubresources()) |
346 return true; | 342 return true; |
347 } | 343 } |
348 return false; | 344 return false; |
349 } | 345 } |
350 | 346 |
351 // This is the list of properties we want to copy in the copyBlockProperties() f
unction. | 347 // This is the list of properties we want to copy in the copyBlockProperties() f
unction. |
352 // It is the list of CSS properties that apply specially to block-level elements
. | 348 // It is the list of CSS properties that apply specially to block-level elements
. |
353 static const CSSPropertyID staticBlockProperties[] = { | 349 static const CSSPropertyID staticBlockProperties[] = { |
354 CSSPropertyOrphans, | 350 CSSPropertyOrphans, |
355 CSSPropertyOverflow, // This can be also be applied to replaced elements | 351 CSSPropertyOverflow, // This can be also be applied to replaced elements |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 } | 423 } |
428 | 424 |
429 CSSProperty* MutableStylePropertySet::findCSSPropertyWithID(CSSPropertyID proper
tyID) | 425 CSSProperty* MutableStylePropertySet::findCSSPropertyWithID(CSSPropertyID proper
tyID) |
430 { | 426 { |
431 int foundPropertyIndex = findPropertyIndex(propertyID); | 427 int foundPropertyIndex = findPropertyIndex(propertyID); |
432 if (foundPropertyIndex == -1) | 428 if (foundPropertyIndex == -1) |
433 return 0; | 429 return 0; |
434 return &m_propertyVector.at(foundPropertyIndex); | 430 return &m_propertyVector.at(foundPropertyIndex); |
435 } | 431 } |
436 | 432 |
437 bool StylePropertySet::propertyMatches(CSSPropertyID propertyID, const CSSValue*
propertyValue) const | 433 bool StylePropertySet::propertyMatches(CSSPropertyID propertyID, const CSSValue
propertyValue) const |
438 { | 434 { |
439 int foundPropertyIndex = findPropertyIndex(propertyID); | 435 int foundPropertyIndex = findPropertyIndex(propertyID); |
440 if (foundPropertyIndex == -1) | 436 if (foundPropertyIndex == -1) |
441 return false; | 437 return false; |
442 return propertyAt(foundPropertyIndex).value()->equals(*propertyValue); | 438 return propertyAt(foundPropertyIndex).value().equals(propertyValue); |
443 } | 439 } |
444 | 440 |
445 void MutableStylePropertySet::removeEquivalentProperties(const StylePropertySet*
style) | 441 void MutableStylePropertySet::removeEquivalentProperties(const StylePropertySet*
style) |
446 { | 442 { |
447 Vector<CSSPropertyID> propertiesToRemove; | 443 Vector<CSSPropertyID> propertiesToRemove; |
448 unsigned size = m_propertyVector.size(); | 444 unsigned size = m_propertyVector.size(); |
449 for (unsigned i = 0; i < size; ++i) { | 445 for (unsigned i = 0; i < size; ++i) { |
450 PropertyReference property = propertyAt(i); | 446 PropertyReference property = propertyAt(i); |
451 if (style->propertyMatches(property.id(), property.value())) | 447 if (style->propertyMatches(property.id(), property.value())) |
452 propertiesToRemove.append(property.id()); | 448 propertiesToRemove.append(property.id()); |
(...skipping 20 matching lines...) Expand all Loading... |
473 PassRefPtrWillBeRawPtr<MutableStylePropertySet> StylePropertySet::mutableCopy()
const | 469 PassRefPtrWillBeRawPtr<MutableStylePropertySet> StylePropertySet::mutableCopy()
const |
474 { | 470 { |
475 return adoptRefWillBeNoop(new MutableStylePropertySet(*this)); | 471 return adoptRefWillBeNoop(new MutableStylePropertySet(*this)); |
476 } | 472 } |
477 | 473 |
478 PassRefPtrWillBeRawPtr<MutableStylePropertySet> StylePropertySet::copyProperties
InSet(const Vector<CSSPropertyID>& properties) const | 474 PassRefPtrWillBeRawPtr<MutableStylePropertySet> StylePropertySet::copyProperties
InSet(const Vector<CSSPropertyID>& properties) const |
479 { | 475 { |
480 WillBeHeapVector<CSSProperty, 256> list; | 476 WillBeHeapVector<CSSProperty, 256> list; |
481 list.reserveInitialCapacity(properties.size()); | 477 list.reserveInitialCapacity(properties.size()); |
482 for (unsigned i = 0; i < properties.size(); ++i) { | 478 for (unsigned i = 0; i < properties.size(); ++i) { |
483 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(properties[i]); | 479 NullableCSSValue value = getPropertyCSSValue(properties[i]); |
484 if (value) | 480 if (value) |
485 list.append(CSSProperty(properties[i], value.release(), false)); | 481 list.append(CSSProperty(properties[i], *value, false)); |
486 } | 482 } |
487 return MutableStylePropertySet::create(list.data(), list.size()); | 483 return MutableStylePropertySet::create(list.data(), list.size()); |
488 } | 484 } |
489 | 485 |
490 CSSStyleDeclaration* MutableStylePropertySet::ensureCSSStyleDeclaration() | 486 CSSStyleDeclaration* MutableStylePropertySet::ensureCSSStyleDeclaration() |
491 { | 487 { |
492 // FIXME: get rid of this weirdness of a CSSStyleDeclaration inside of a | 488 // FIXME: get rid of this weirdness of a CSSStyleDeclaration inside of a |
493 // style property set. | 489 // style property set. |
494 if (m_cssomWrapper) { | 490 if (m_cssomWrapper) { |
495 ASSERT(!static_cast<CSSStyleDeclaration*>(m_cssomWrapper.get())->parentR
ule()); | 491 ASSERT(!static_cast<CSSStyleDeclaration*>(m_cssomWrapper.get())->parentR
ule()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 { | 545 { |
550 return adoptRefWillBeNoop(new MutableStylePropertySet(cssParserMode)); | 546 return adoptRefWillBeNoop(new MutableStylePropertySet(cssParserMode)); |
551 } | 547 } |
552 | 548 |
553 PassRefPtrWillBeRawPtr<MutableStylePropertySet> MutableStylePropertySet::create(
const CSSProperty* properties, unsigned count) | 549 PassRefPtrWillBeRawPtr<MutableStylePropertySet> MutableStylePropertySet::create(
const CSSProperty* properties, unsigned count) |
554 { | 550 { |
555 return adoptRefWillBeNoop(new MutableStylePropertySet(properties, count)); | 551 return adoptRefWillBeNoop(new MutableStylePropertySet(properties, count)); |
556 } | 552 } |
557 | 553 |
558 } // namespace blink | 554 } // namespace blink |
OLD | NEW |