| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004 Zack Rusin <zack@kde.org> | 2 * Copyright (C) 2004 Zack Rusin <zack@kde.org> |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. |
| 4 * All rights reserved. | 4 * All rights reserved. |
| 5 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 5 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
| 6 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> | 6 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
| 7 * Copyright (C) 2011 Sencha, Inc. All rights reserved. | 7 * Copyright (C) 2011 Sencha, Inc. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Lesser General Public | 10 * modify it under the terms of the GNU Lesser General Public |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 #include "core/dom/Document.h" | 38 #include "core/dom/Document.h" |
| 39 #include "core/dom/ExceptionCode.h" | 39 #include "core/dom/ExceptionCode.h" |
| 40 #include "core/dom/PseudoElement.h" | 40 #include "core/dom/PseudoElement.h" |
| 41 #include "core/dom/StyleEngine.h" | 41 #include "core/dom/StyleEngine.h" |
| 42 #include "core/layout/LayoutObject.h" | 42 #include "core/layout/LayoutObject.h" |
| 43 #include "core/style/ComputedStyle.h" | 43 #include "core/style/ComputedStyle.h" |
| 44 #include "wtf/text/StringBuilder.h" | 44 #include "wtf/text/StringBuilder.h" |
| 45 | 45 |
| 46 namespace blink { | 46 namespace blink { |
| 47 | 47 |
| 48 namespace { |
| 49 |
| 48 // List of all properties we know how to compute, omitting shorthands. | 50 // List of all properties we know how to compute, omitting shorthands. |
| 49 // NOTE: Do not use this list, use computableProperties() instead | 51 // NOTE: Do not use this list, use computableProperties() instead |
| 50 // to respect runtime enabling of CSS properties. | 52 // to respect runtime enabling of CSS properties. |
| 51 static const CSSPropertyID staticComputableProperties[] = { | 53 const CSSPropertyID computedPropertyArray[] = { |
| 52 CSSPropertyAnimationDelay, CSSPropertyAnimationDirection, | 54 CSSPropertyAnimationDelay, CSSPropertyAnimationDirection, |
| 53 CSSPropertyAnimationDuration, CSSPropertyAnimationFillMode, | 55 CSSPropertyAnimationDuration, CSSPropertyAnimationFillMode, |
| 54 CSSPropertyAnimationIterationCount, CSSPropertyAnimationName, | 56 CSSPropertyAnimationIterationCount, CSSPropertyAnimationName, |
| 55 CSSPropertyAnimationPlayState, CSSPropertyAnimationTimingFunction, | 57 CSSPropertyAnimationPlayState, CSSPropertyAnimationTimingFunction, |
| 56 CSSPropertyBackgroundAttachment, CSSPropertyBackgroundBlendMode, | 58 CSSPropertyBackgroundAttachment, CSSPropertyBackgroundBlendMode, |
| 57 CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, | 59 CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, |
| 58 CSSPropertyBackgroundImage, CSSPropertyBackgroundOrigin, | 60 CSSPropertyBackgroundImage, CSSPropertyBackgroundOrigin, |
| 59 // more-specific background-position-x/y are non-standard | 61 // more-specific background-position-x/y are non-standard |
| 60 CSSPropertyBackgroundPosition, CSSPropertyBackgroundRepeat, | 62 CSSPropertyBackgroundPosition, CSSPropertyBackgroundRepeat, |
| 61 CSSPropertyBackgroundSize, CSSPropertyBorderBottomColor, | 63 CSSPropertyBackgroundSize, CSSPropertyBorderBottomColor, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 CSSPropertyStrokeOpacity, CSSPropertyStrokeWidth, | 170 CSSPropertyStrokeOpacity, CSSPropertyStrokeWidth, |
| 169 CSSPropertyAlignmentBaseline, CSSPropertyBaselineShift, | 171 CSSPropertyAlignmentBaseline, CSSPropertyBaselineShift, |
| 170 CSSPropertyDominantBaseline, CSSPropertyTextAnchor, CSSPropertyWritingMode, | 172 CSSPropertyDominantBaseline, CSSPropertyTextAnchor, CSSPropertyWritingMode, |
| 171 CSSPropertyVectorEffect, CSSPropertyPaintOrder, CSSPropertyD, CSSPropertyCx, | 173 CSSPropertyVectorEffect, CSSPropertyPaintOrder, CSSPropertyD, CSSPropertyCx, |
| 172 CSSPropertyCy, CSSPropertyX, CSSPropertyY, CSSPropertyR, CSSPropertyRx, | 174 CSSPropertyCy, CSSPropertyX, CSSPropertyY, CSSPropertyR, CSSPropertyRx, |
| 173 CSSPropertyRy, CSSPropertyScrollSnapType, CSSPropertyScrollSnapPointsX, | 175 CSSPropertyRy, CSSPropertyScrollSnapType, CSSPropertyScrollSnapPointsX, |
| 174 CSSPropertyScrollSnapPointsY, CSSPropertyScrollSnapCoordinate, | 176 CSSPropertyScrollSnapPointsY, CSSPropertyScrollSnapCoordinate, |
| 175 CSSPropertyScrollSnapDestination, CSSPropertyTranslate, CSSPropertyRotate, | 177 CSSPropertyScrollSnapDestination, CSSPropertyTranslate, CSSPropertyRotate, |
| 176 CSSPropertyScale, CSSPropertyCaretColor}; | 178 CSSPropertyScale, CSSPropertyCaretColor}; |
| 177 | 179 |
| 178 static const Vector<CSSPropertyID>& computableProperties() { | 180 const Vector<CSSPropertyID>& computableProperties() { |
| 179 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ()); | 181 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ()); |
| 180 if (properties.isEmpty()) | 182 if (properties.isEmpty()) { |
| 181 CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector( | 183 CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector( |
| 182 staticComputableProperties, | 184 computedPropertyArray, WTF_ARRAY_LENGTH(computedPropertyArray), |
| 183 WTF_ARRAY_LENGTH(staticComputableProperties), properties); | 185 properties); |
| 186 } |
| 184 return properties; | 187 return properties; |
| 185 } | 188 } |
| 186 | 189 |
| 187 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration( | 190 CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize) { |
| 188 Node* n, | |
| 189 bool allowVisitedStyle, | |
| 190 const String& pseudoElementName) | |
| 191 : m_node(n), | |
| 192 m_pseudoElementSpecifier(CSSSelector::parsePseudoId(pseudoElementName)), | |
| 193 m_allowVisitedStyle(allowVisitedStyle) {} | |
| 194 | |
| 195 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() {} | |
| 196 | |
| 197 String CSSComputedStyleDeclaration::cssText() const { | |
| 198 StringBuilder result; | |
| 199 const Vector<CSSPropertyID>& properties = computableProperties(); | |
| 200 | |
| 201 for (unsigned i = 0; i < properties.size(); i++) { | |
| 202 if (i) | |
| 203 result.append(' '); | |
| 204 result.append(getPropertyName(properties[i])); | |
| 205 result.append(": "); | |
| 206 result.append(getPropertyValue(properties[i])); | |
| 207 result.append(';'); | |
| 208 } | |
| 209 | |
| 210 return result.toString(); | |
| 211 } | |
| 212 | |
| 213 void CSSComputedStyleDeclaration::setCSSText(const String&, | |
| 214 ExceptionState& exceptionState) { | |
| 215 exceptionState.throwDOMException( | |
| 216 NoModificationAllowedError, | |
| 217 "These styles are computed, and therefore read-only."); | |
| 218 } | |
| 219 | |
| 220 static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize) { | |
| 221 DCHECK_NE(keywordSize, 0); | 191 DCHECK_NE(keywordSize, 0); |
| 222 DCHECK_LE(keywordSize, 8); | 192 DCHECK_LE(keywordSize, 8); |
| 223 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1); | 193 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1); |
| 224 } | 194 } |
| 225 | 195 |
| 226 inline static CSSPrimitiveValue* zoomAdjustedPixelValue( | 196 inline CSSPrimitiveValue* zoomAdjustedPixelValue(double value, |
| 227 double value, | 197 const ComputedStyle& style) { |
| 228 const ComputedStyle& style) { | |
| 229 return CSSPrimitiveValue::create(adjustFloatForAbsoluteZoom(value, style), | 198 return CSSPrimitiveValue::create(adjustFloatForAbsoluteZoom(value, style), |
| 230 CSSPrimitiveValue::UnitType::Pixels); | 199 CSSPrimitiveValue::UnitType::Pixels); |
| 231 } | 200 } |
| 232 | 201 |
| 233 const CSSValue* | 202 void logUnimplementedPropertyID(CSSPropertyID propertyID) { |
| 234 CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const { | |
| 235 if (!m_node) | |
| 236 return nullptr; | |
| 237 | |
| 238 m_node->document().updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 239 | |
| 240 const ComputedStyle* style = | |
| 241 m_node->ensureComputedStyle(m_pseudoElementSpecifier); | |
| 242 if (!style) | |
| 243 return nullptr; | |
| 244 | |
| 245 if (int keywordSize = style->getFontDescription().keywordSize()) | |
| 246 return CSSIdentifierValue::create( | |
| 247 cssIdentifierForFontSizeKeyword(keywordSize)); | |
| 248 | |
| 249 return zoomAdjustedPixelValue(style->getFontDescription().computedPixelSize(), | |
| 250 *style); | |
| 251 } | |
| 252 | |
| 253 bool CSSComputedStyleDeclaration::isMonospaceFont() const { | |
| 254 if (!m_node) | |
| 255 return false; | |
| 256 | |
| 257 const ComputedStyle* style = | |
| 258 m_node->ensureComputedStyle(m_pseudoElementSpecifier); | |
| 259 if (!style) | |
| 260 return false; | |
| 261 | |
| 262 return style->getFontDescription().isMonospace(); | |
| 263 } | |
| 264 | |
| 265 static void logUnimplementedPropertyID(CSSPropertyID propertyID) { | |
| 266 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ()); | 203 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ()); |
| 267 if (!propertyIDSet.add(propertyID).isNewEntry) | 204 if (!propertyIDSet.add(propertyID).isNewEntry) |
| 268 return; | 205 return; |
| 269 | 206 |
| 270 DLOG(ERROR) << "Blink does not yet implement getComputedStyle for '" | 207 DLOG(ERROR) << "Blink does not yet implement getComputedStyle for '" |
| 271 << getPropertyName(propertyID) << "'."; | 208 << getPropertyName(propertyID) << "'."; |
| 272 } | 209 } |
| 273 | 210 |
| 274 static bool isLayoutDependent(CSSPropertyID propertyID, | 211 bool isLayoutDependent(CSSPropertyID propertyID, |
| 275 const ComputedStyle* style, | 212 const ComputedStyle* style, |
| 276 LayoutObject* layoutObject) { | 213 LayoutObject* layoutObject) { |
| 277 if (!layoutObject) | 214 if (!layoutObject) |
| 278 return false; | 215 return false; |
| 279 | 216 |
| 280 // Some properties only depend on layout in certain conditions which | 217 // Some properties only depend on layout in certain conditions which |
| 281 // are specified in the main switch statement below. So we can avoid | 218 // are specified in the main switch statement below. So we can avoid |
| 282 // forcing layout in those conditions. The conditions in this switch | 219 // forcing layout in those conditions. The conditions in this switch |
| 283 // statement must remain in sync with the conditions in the main switch. | 220 // statement must remain in sync with the conditions in the main switch. |
| 284 // FIXME: Some of these cases could be narrowed down or optimized better. | 221 // FIXME: Some of these cases could be narrowed down or optimized better. |
| 285 switch (propertyID) { | 222 switch (propertyID) { |
| 286 case CSSPropertyBottom: | 223 case CSSPropertyBottom: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 case CSSPropertyGridTemplateColumns: | 268 case CSSPropertyGridTemplateColumns: |
| 332 case CSSPropertyGridTemplateRows: | 269 case CSSPropertyGridTemplateRows: |
| 333 case CSSPropertyGridTemplate: | 270 case CSSPropertyGridTemplate: |
| 334 case CSSPropertyGrid: | 271 case CSSPropertyGrid: |
| 335 return layoutObject->isLayoutGrid(); | 272 return layoutObject->isLayoutGrid(); |
| 336 default: | 273 default: |
| 337 return false; | 274 return false; |
| 338 } | 275 } |
| 339 } | 276 } |
| 340 | 277 |
| 278 } // namespace |
| 279 |
| 280 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration( |
| 281 Node* n, |
| 282 bool allowVisitedStyle, |
| 283 const String& pseudoElementName) |
| 284 : m_node(n), |
| 285 m_pseudoElementSpecifier(CSSSelector::parsePseudoId(pseudoElementName)), |
| 286 m_allowVisitedStyle(allowVisitedStyle) {} |
| 287 |
| 288 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() {} |
| 289 |
| 290 String CSSComputedStyleDeclaration::cssText() const { |
| 291 StringBuilder result; |
| 292 const Vector<CSSPropertyID>& properties = computableProperties(); |
| 293 |
| 294 for (unsigned i = 0; i < properties.size(); i++) { |
| 295 if (i) |
| 296 result.append(' '); |
| 297 result.append(getPropertyName(properties[i])); |
| 298 result.append(": "); |
| 299 result.append(getPropertyValue(properties[i])); |
| 300 result.append(';'); |
| 301 } |
| 302 |
| 303 return result.toString(); |
| 304 } |
| 305 |
| 306 void CSSComputedStyleDeclaration::setCSSText(const String&, |
| 307 ExceptionState& exceptionState) { |
| 308 exceptionState.throwDOMException( |
| 309 NoModificationAllowedError, |
| 310 "These styles are computed, and therefore read-only."); |
| 311 } |
| 312 |
| 313 const CSSValue* |
| 314 CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const { |
| 315 if (!m_node) |
| 316 return nullptr; |
| 317 |
| 318 m_node->document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 319 |
| 320 const ComputedStyle* style = |
| 321 m_node->ensureComputedStyle(m_pseudoElementSpecifier); |
| 322 if (!style) |
| 323 return nullptr; |
| 324 |
| 325 if (int keywordSize = style->getFontDescription().keywordSize()) { |
| 326 return CSSIdentifierValue::create( |
| 327 cssIdentifierForFontSizeKeyword(keywordSize)); |
| 328 } |
| 329 |
| 330 return zoomAdjustedPixelValue(style->getFontDescription().computedPixelSize(), |
| 331 *style); |
| 332 } |
| 333 |
| 334 bool CSSComputedStyleDeclaration::isMonospaceFont() const { |
| 335 if (!m_node) |
| 336 return false; |
| 337 |
| 338 const ComputedStyle* style = |
| 339 m_node->ensureComputedStyle(m_pseudoElementSpecifier); |
| 340 if (!style) |
| 341 return false; |
| 342 |
| 343 return style->getFontDescription().isMonospace(); |
| 344 } |
| 341 const ComputedStyle* CSSComputedStyleDeclaration::computeComputedStyle() const { | 345 const ComputedStyle* CSSComputedStyleDeclaration::computeComputedStyle() const { |
| 342 Node* styledNode = this->styledNode(); | 346 Node* styledNode = this->styledNode(); |
| 343 ASSERT(styledNode); | 347 ASSERT(styledNode); |
| 344 return styledNode->ensureComputedStyle( | 348 return styledNode->ensureComputedStyle( |
| 345 styledNode->isPseudoElement() ? PseudoIdNone : m_pseudoElementSpecifier); | 349 styledNode->isPseudoElement() ? PseudoIdNone : m_pseudoElementSpecifier); |
| 346 } | 350 } |
| 347 | 351 |
| 348 Node* CSSComputedStyleDeclaration::styledNode() const { | 352 Node* CSSComputedStyleDeclaration::styledNode() const { |
| 349 if (!m_node) | 353 if (!m_node) |
| 350 return nullptr; | 354 return nullptr; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 "These styles are computed, and therefore the '" + | 562 "These styles are computed, and therefore the '" + |
| 559 getPropertyNameString(id) + "' property is read-only."); | 563 getPropertyNameString(id) + "' property is read-only."); |
| 560 } | 564 } |
| 561 | 565 |
| 562 DEFINE_TRACE(CSSComputedStyleDeclaration) { | 566 DEFINE_TRACE(CSSComputedStyleDeclaration) { |
| 563 visitor->trace(m_node); | 567 visitor->trace(m_node); |
| 564 CSSStyleDeclaration::trace(visitor); | 568 CSSStyleDeclaration::trace(visitor); |
| 565 } | 569 } |
| 566 | 570 |
| 567 } // namespace blink | 571 } // namespace blink |
| OLD | NEW |