blob: a0e8c8c2c3e750cb632db338224aa64cc4df1632 [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
2 * Copyright (C) 2004 Zack Rusin <zack@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6 * Copyright (C) 2011 Sencha, Inc. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24#include "config.h"
25#include "core/css/CSSComputedStyleDeclaration.h"
26
27#include "CSSPropertyNames.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010028#include "FontFamilyNames.h"
Ben Murdoche69819b2013-07-17 14:56:49 +010029#include "RuntimeEnabledFeatures.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010030#include "core/css/BasicShapeFunctions.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010031#include "core/css/CSSArrayFunctionValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010032#include "core/css/CSSAspectRatioValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010033#include "core/css/CSSBorderImage.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010034#include "core/css/CSSFilterValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010035#include "core/css/CSSFunctionValue.h"
36#include "core/css/CSSLineBoxContainValue.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010037#include "core/css/CSSMixFunctionValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010038#include "core/css/CSSParser.h"
39#include "core/css/CSSPrimitiveValue.h"
40#include "core/css/CSSPrimitiveValueMappings.h"
41#include "core/css/CSSReflectValue.h"
42#include "core/css/CSSSelector.h"
43#include "core/css/CSSTimingFunctionValue.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010044#include "core/css/CSSTransformValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010045#include "core/css/CSSValueList.h"
46#include "core/css/CSSValuePool.h"
47#include "core/css/FontFeatureValue.h"
48#include "core/css/FontValue.h"
49#include "core/css/Pair.h"
50#include "core/css/Rect.h"
51#include "core/css/ShadowValue.h"
52#include "core/css/StylePropertySet.h"
53#include "core/css/StylePropertyShorthand.h"
Torne (Richard Coles)81a51572013-05-13 16:52:28 +010054#include "core/css/resolver/StyleResolver.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010055#include "core/dom/Document.h"
56#include "core/dom/ExceptionCode.h"
57#include "core/dom/PseudoElement.h"
58#include "core/dom/WebCoreMemoryInstrumentation.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010059#include "core/page/RuntimeCSSEnabled.h"
60#include "core/page/animation/AnimationController.h"
61#include "core/platform/graphics/FontFeatureSettings.h"
62#include "core/rendering/RenderBox.h"
63#include "core/rendering/RenderView.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010064#include "core/rendering/style/ContentData.h"
65#include "core/rendering/style/CounterContent.h"
66#include "core/rendering/style/CursorList.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010067#include "core/rendering/style/RenderStyle.h"
Ben Murdoch591b9582013-07-10 11:41:44 +010068#include "core/rendering/style/ShapeValue.h"
69#include "wtf/text/StringBuilder.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010070
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010071#include "core/platform/graphics/filters/custom/CustomFilterArrayParameter.h"
72#include "core/platform/graphics/filters/custom/CustomFilterNumberParameter.h"
73#include "core/platform/graphics/filters/custom/CustomFilterOperation.h"
74#include "core/platform/graphics/filters/custom/CustomFilterParameter.h"
75#include "core/platform/graphics/filters/custom/CustomFilterTransformParameter.h"
76
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010077#include "core/rendering/style/StyleCustomFilterProgram.h"
78
79namespace WebCore {
80
81// List of all properties we know how to compute, omitting shorthands.
82// NOTE: Do not use this list, use computableProperties() instead
83// to respect runtime enabling of CSS properties.
84static const CSSPropertyID staticComputableProperties[] = {
85 CSSPropertyBackgroundAttachment,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010086 CSSPropertyBackgroundBlendMode,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010087 CSSPropertyBackgroundClip,
88 CSSPropertyBackgroundColor,
89 CSSPropertyBackgroundImage,
90 CSSPropertyBackgroundOrigin,
91 CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
92 CSSPropertyBackgroundRepeat,
93 CSSPropertyBackgroundSize,
94 CSSPropertyBorderBottomColor,
95 CSSPropertyBorderBottomLeftRadius,
96 CSSPropertyBorderBottomRightRadius,
97 CSSPropertyBorderBottomStyle,
98 CSSPropertyBorderBottomWidth,
99 CSSPropertyBorderCollapse,
100 CSSPropertyBorderImageOutset,
101 CSSPropertyBorderImageRepeat,
102 CSSPropertyBorderImageSlice,
103 CSSPropertyBorderImageSource,
104 CSSPropertyBorderImageWidth,
105 CSSPropertyBorderLeftColor,
106 CSSPropertyBorderLeftStyle,
107 CSSPropertyBorderLeftWidth,
108 CSSPropertyBorderRightColor,
109 CSSPropertyBorderRightStyle,
110 CSSPropertyBorderRightWidth,
111 CSSPropertyBorderTopColor,
112 CSSPropertyBorderTopLeftRadius,
113 CSSPropertyBorderTopRightRadius,
114 CSSPropertyBorderTopStyle,
115 CSSPropertyBorderTopWidth,
116 CSSPropertyBottom,
117 CSSPropertyBoxShadow,
118 CSSPropertyBoxSizing,
119 CSSPropertyCaptionSide,
120 CSSPropertyClear,
121 CSSPropertyClip,
122 CSSPropertyColor,
123 CSSPropertyCursor,
124 CSSPropertyDirection,
125 CSSPropertyDisplay,
126 CSSPropertyEmptyCells,
127 CSSPropertyFloat,
128 CSSPropertyFontFamily,
129 CSSPropertyFontSize,
130 CSSPropertyFontStyle,
131 CSSPropertyFontVariant,
132 CSSPropertyFontWeight,
133 CSSPropertyHeight,
134 CSSPropertyImageRendering,
135 CSSPropertyLeft,
136 CSSPropertyLetterSpacing,
137 CSSPropertyLineHeight,
138 CSSPropertyListStyleImage,
139 CSSPropertyListStylePosition,
140 CSSPropertyListStyleType,
141 CSSPropertyMarginBottom,
142 CSSPropertyMarginLeft,
143 CSSPropertyMarginRight,
144 CSSPropertyMarginTop,
145 CSSPropertyMaxHeight,
146 CSSPropertyMaxWidth,
147 CSSPropertyMinHeight,
148 CSSPropertyMinWidth,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100149 CSSPropertyMixBlendMode,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100150 CSSPropertyOpacity,
151 CSSPropertyOrphans,
152 CSSPropertyOutlineColor,
153 CSSPropertyOutlineOffset,
154 CSSPropertyOutlineStyle,
155 CSSPropertyOutlineWidth,
156 CSSPropertyOverflowWrap,
157 CSSPropertyOverflowX,
158 CSSPropertyOverflowY,
159 CSSPropertyPaddingBottom,
160 CSSPropertyPaddingLeft,
161 CSSPropertyPaddingRight,
162 CSSPropertyPaddingTop,
163 CSSPropertyPageBreakAfter,
164 CSSPropertyPageBreakBefore,
165 CSSPropertyPageBreakInside,
166 CSSPropertyPointerEvents,
167 CSSPropertyPosition,
168 CSSPropertyResize,
169 CSSPropertyRight,
170 CSSPropertySpeak,
171 CSSPropertyTableLayout,
172 CSSPropertyTabSize,
173 CSSPropertyTextAlign,
Ben Murdoche69819b2013-07-17 14:56:49 +0100174 CSSPropertyTextAlignLast,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100175 CSSPropertyTextDecoration,
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100176 CSSPropertyTextDecorationLine,
177 CSSPropertyTextDecorationStyle,
178 CSSPropertyTextDecorationColor,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100179#if ENABLE(CSS3_TEXT)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100180 CSSPropertyWebkitTextUnderlinePosition,
181#endif // CSS3_TEXT
182 CSSPropertyTextIndent,
183 CSSPropertyTextRendering,
184 CSSPropertyTextShadow,
185 CSSPropertyTextOverflow,
186 CSSPropertyTextTransform,
187 CSSPropertyTop,
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100188 CSSPropertyTouchAction,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100189 CSSPropertyTransitionDelay,
190 CSSPropertyTransitionDuration,
191 CSSPropertyTransitionProperty,
192 CSSPropertyTransitionTimingFunction,
193 CSSPropertyUnicodeBidi,
194 CSSPropertyVerticalAlign,
195 CSSPropertyVisibility,
196 CSSPropertyWhiteSpace,
197 CSSPropertyWidows,
198 CSSPropertyWidth,
199 CSSPropertyWordBreak,
200 CSSPropertyWordSpacing,
201 CSSPropertyWordWrap,
202 CSSPropertyZIndex,
203 CSSPropertyZoom,
204
205 CSSPropertyWebkitAnimationDelay,
206 CSSPropertyWebkitAnimationDirection,
207 CSSPropertyWebkitAnimationDuration,
208 CSSPropertyWebkitAnimationFillMode,
209 CSSPropertyWebkitAnimationIterationCount,
210 CSSPropertyWebkitAnimationName,
211 CSSPropertyWebkitAnimationPlayState,
212 CSSPropertyWebkitAnimationTimingFunction,
213 CSSPropertyWebkitAppearance,
214 CSSPropertyWebkitBackfaceVisibility,
215 CSSPropertyWebkitBackgroundClip,
216 CSSPropertyWebkitBackgroundComposite,
217 CSSPropertyWebkitBackgroundOrigin,
218 CSSPropertyWebkitBackgroundSize,
219 CSSPropertyWebkitBorderFit,
220 CSSPropertyWebkitBorderHorizontalSpacing,
221 CSSPropertyWebkitBorderImage,
222 CSSPropertyWebkitBorderVerticalSpacing,
223 CSSPropertyWebkitBoxAlign,
224 CSSPropertyWebkitBoxDecorationBreak,
225 CSSPropertyWebkitBoxDirection,
226 CSSPropertyWebkitBoxFlex,
227 CSSPropertyWebkitBoxFlexGroup,
228 CSSPropertyWebkitBoxLines,
229 CSSPropertyWebkitBoxOrdinalGroup,
230 CSSPropertyWebkitBoxOrient,
231 CSSPropertyWebkitBoxPack,
232 CSSPropertyWebkitBoxReflect,
233 CSSPropertyWebkitBoxShadow,
234 CSSPropertyWebkitClipPath,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100235 CSSPropertyWebkitColumnBreakAfter,
236 CSSPropertyWebkitColumnBreakBefore,
237 CSSPropertyWebkitColumnBreakInside,
238 CSSPropertyWebkitColumnAxis,
239 CSSPropertyWebkitColumnCount,
240 CSSPropertyWebkitColumnGap,
241 CSSPropertyWebkitColumnProgression,
242 CSSPropertyWebkitColumnRuleColor,
243 CSSPropertyWebkitColumnRuleStyle,
244 CSSPropertyWebkitColumnRuleWidth,
245 CSSPropertyWebkitColumnSpan,
246 CSSPropertyWebkitColumnWidth,
247 CSSPropertyWebkitFilter,
Ben Murdoch591b9582013-07-10 11:41:44 +0100248 CSSPropertyAlignContent,
249 CSSPropertyAlignItems,
250 CSSPropertyAlignSelf,
251 CSSPropertyFlexBasis,
252 CSSPropertyFlexGrow,
253 CSSPropertyFlexShrink,
254 CSSPropertyFlexDirection,
255 CSSPropertyFlexWrap,
256 CSSPropertyJustifyContent,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100257 CSSPropertyWebkitFontKerning,
258 CSSPropertyWebkitFontSmoothing,
259 CSSPropertyWebkitFontVariantLigatures,
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100260 CSSPropertyGridAutoColumns,
261 CSSPropertyGridAutoFlow,
262 CSSPropertyGridAutoRows,
Ben Murdoch591b9582013-07-10 11:41:44 +0100263 CSSPropertyGridColumnEnd,
264 CSSPropertyGridColumnStart,
265 CSSPropertyGridDefinitionColumns,
266 CSSPropertyGridDefinitionRows,
267 CSSPropertyGridRowEnd,
268 CSSPropertyGridRowStart,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100269 CSSPropertyWebkitHighlight,
270 CSSPropertyWebkitHyphenateCharacter,
271 CSSPropertyWebkitHyphenateLimitAfter,
272 CSSPropertyWebkitHyphenateLimitBefore,
273 CSSPropertyWebkitHyphenateLimitLines,
274 CSSPropertyWebkitHyphens,
275 CSSPropertyWebkitLineAlign,
276 CSSPropertyWebkitLineBoxContain,
277 CSSPropertyWebkitLineBreak,
278 CSSPropertyWebkitLineClamp,
279 CSSPropertyWebkitLineGrid,
280 CSSPropertyWebkitLineSnap,
281 CSSPropertyWebkitLocale,
282 CSSPropertyWebkitMarginBeforeCollapse,
283 CSSPropertyWebkitMarginAfterCollapse,
284 CSSPropertyWebkitMarqueeDirection,
285 CSSPropertyWebkitMarqueeIncrement,
286 CSSPropertyWebkitMarqueeRepetition,
287 CSSPropertyWebkitMarqueeStyle,
288 CSSPropertyWebkitMaskBoxImage,
289 CSSPropertyWebkitMaskBoxImageOutset,
290 CSSPropertyWebkitMaskBoxImageRepeat,
291 CSSPropertyWebkitMaskBoxImageSlice,
292 CSSPropertyWebkitMaskBoxImageSource,
293 CSSPropertyWebkitMaskBoxImageWidth,
294 CSSPropertyWebkitMaskClip,
295 CSSPropertyWebkitMaskComposite,
296 CSSPropertyWebkitMaskImage,
297 CSSPropertyWebkitMaskOrigin,
298 CSSPropertyWebkitMaskPosition,
299 CSSPropertyWebkitMaskRepeat,
300 CSSPropertyWebkitMaskSize,
Ben Murdoch591b9582013-07-10 11:41:44 +0100301 CSSPropertyOrder,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100302 CSSPropertyWebkitPerspective,
303 CSSPropertyWebkitPerspectiveOrigin,
304 CSSPropertyWebkitPrintColorAdjust,
305 CSSPropertyWebkitRtlOrdering,
306 CSSPropertyWebkitShapeInside,
307 CSSPropertyWebkitShapeOutside,
308 CSSPropertyWebkitTapHighlightColor,
309 CSSPropertyWebkitTextCombine,
310 CSSPropertyWebkitTextDecorationsInEffect,
311 CSSPropertyWebkitTextEmphasisColor,
312 CSSPropertyWebkitTextEmphasisPosition,
313 CSSPropertyWebkitTextEmphasisStyle,
314 CSSPropertyWebkitTextFillColor,
315 CSSPropertyWebkitTextOrientation,
316 CSSPropertyWebkitTextSecurity,
317 CSSPropertyWebkitTextStrokeColor,
318 CSSPropertyWebkitTextStrokeWidth,
319 CSSPropertyWebkitTransform,
320 CSSPropertyWebkitTransformOrigin,
321 CSSPropertyWebkitTransformStyle,
322 CSSPropertyWebkitTransitionDelay,
323 CSSPropertyWebkitTransitionDuration,
324 CSSPropertyWebkitTransitionProperty,
325 CSSPropertyWebkitTransitionTimingFunction,
326 CSSPropertyWebkitUserDrag,
327 CSSPropertyWebkitUserModify,
328 CSSPropertyWebkitUserSelect,
329 CSSPropertyWebkitWritingMode,
330 CSSPropertyWebkitFlowInto,
331 CSSPropertyWebkitFlowFrom,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100332 CSSPropertyWebkitRegionBreakAfter,
333 CSSPropertyWebkitRegionBreakBefore,
334 CSSPropertyWebkitRegionBreakInside,
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100335 CSSPropertyWebkitRegionFragment,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100336 CSSPropertyWebkitAppRegion,
337 CSSPropertyWebkitWrapFlow,
338 CSSPropertyWebkitShapeMargin,
339 CSSPropertyWebkitShapePadding,
340 CSSPropertyWebkitWrapThrough,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100341 CSSPropertyBufferedRendering,
342 CSSPropertyClipPath,
343 CSSPropertyClipRule,
344 CSSPropertyMask,
345 CSSPropertyFilter,
346 CSSPropertyFloodColor,
347 CSSPropertyFloodOpacity,
348 CSSPropertyLightingColor,
349 CSSPropertyStopColor,
350 CSSPropertyStopOpacity,
351 CSSPropertyColorInterpolation,
352 CSSPropertyColorInterpolationFilters,
353 CSSPropertyColorRendering,
354 CSSPropertyFill,
355 CSSPropertyFillOpacity,
356 CSSPropertyFillRule,
357 CSSPropertyMarkerEnd,
358 CSSPropertyMarkerMid,
359 CSSPropertyMarkerStart,
360 CSSPropertyMaskType,
361 CSSPropertyShapeRendering,
362 CSSPropertyStroke,
363 CSSPropertyStrokeDasharray,
364 CSSPropertyStrokeDashoffset,
365 CSSPropertyStrokeLinecap,
366 CSSPropertyStrokeLinejoin,
367 CSSPropertyStrokeMiterlimit,
368 CSSPropertyStrokeOpacity,
369 CSSPropertyStrokeWidth,
370 CSSPropertyAlignmentBaseline,
371 CSSPropertyBaselineShift,
372 CSSPropertyDominantBaseline,
373 CSSPropertyKerning,
374 CSSPropertyTextAnchor,
375 CSSPropertyWritingMode,
376 CSSPropertyGlyphOrientationHorizontal,
377 CSSPropertyGlyphOrientationVertical,
378 CSSPropertyWebkitSvgShadow,
379 CSSPropertyVectorEffect
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100380};
381
382static const Vector<CSSPropertyID>& computableProperties()
383{
384 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
385 if (properties.isEmpty())
386 RuntimeCSSEnabled::filterEnabledCSSPropertiesIntoVector(staticComputableProperties, WTF_ARRAY_LENGTH(staticComputableProperties), properties);
387 return properties;
388}
389
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100390static CSSValueID valueForRepeatRule(int rule)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100391{
392 switch (rule) {
393 case RepeatImageRule:
394 return CSSValueRepeat;
395 case RoundImageRule:
396 return CSSValueRound;
397 case SpaceImageRule:
398 return CSSValueSpace;
399 default:
400 return CSSValueStretch;
401 }
402}
403
404static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
405{
406 // Create the slices.
407 RefPtr<CSSPrimitiveValue> top;
408 RefPtr<CSSPrimitiveValue> right;
409 RefPtr<CSSPrimitiveValue> bottom;
410 RefPtr<CSSPrimitiveValue> left;
411
412 if (image.imageSlices().top().isPercent())
413 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
414 else
415 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
416
417 if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top()
418 && image.imageSlices().left() == image.imageSlices().top()) {
419 right = top;
420 bottom = top;
421 left = top;
422 } else {
423 if (image.imageSlices().right().isPercent())
424 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
425 else
426 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
427
428 if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) {
429 bottom = top;
430 left = right;
431 } else {
432 if (image.imageSlices().bottom().isPercent())
433 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
434 else
435 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
436
437 if (image.imageSlices().left() == image.imageSlices().right())
438 left = right;
439 else {
440 if (image.imageSlices().left().isPercent())
441 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
442 else
443 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
444 }
445 }
446 }
447
448 RefPtr<Quad> quad = Quad::create();
449 quad->setTop(top);
450 quad->setRight(right);
451 quad->setBottom(bottom);
452 quad->setLeft(left);
453
454 return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill());
455}
456
457static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
458{
459 // Create the slices.
460 RefPtr<CSSPrimitiveValue> top;
461 RefPtr<CSSPrimitiveValue> right;
462 RefPtr<CSSPrimitiveValue> bottom;
463 RefPtr<CSSPrimitiveValue> left;
464
465 if (box.top().isRelative())
466 top = cssValuePool().createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER);
467 else
468 top = cssValuePool().createValue(box.top());
469
470 if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
471 right = top;
472 bottom = top;
473 left = top;
474 } else {
475 if (box.right().isRelative())
476 right = cssValuePool().createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER);
477 else
478 right = cssValuePool().createValue(box.right());
479
480 if (box.bottom() == box.top() && box.right() == box.left()) {
481 bottom = top;
482 left = right;
483 } else {
484 if (box.bottom().isRelative())
485 bottom = cssValuePool().createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
486 else
487 bottom = cssValuePool().createValue(box.bottom());
488
489 if (box.left() == box.right())
490 left = right;
491 else {
492 if (box.left().isRelative())
493 left = cssValuePool().createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER);
494 else
495 left = cssValuePool().createValue(box.left());
496 }
497 }
498 }
499
500 RefPtr<Quad> quad = Quad::create();
501 quad->setTop(top);
502 quad->setRight(right);
503 quad->setBottom(bottom);
504 quad->setLeft(left);
505
506 return cssValuePool().createValue(quad.release());
507}
508
509static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
510{
511 RefPtr<CSSPrimitiveValue> horizontalRepeat;
512 RefPtr<CSSPrimitiveValue> verticalRepeat;
513
514 horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
515 if (image.horizontalRule() == image.verticalRule())
516 verticalRepeat = horizontalRepeat;
517 else
518 verticalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.verticalRule()));
519 return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release()));
520}
521
522static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
523{
524 if (!image.hasImage())
525 return cssValuePool().createIdentifierValue(CSSValueNone);
526
527 // Image first.
528 RefPtr<CSSValue> imageValue;
529 if (image.image())
530 imageValue = image.image()->cssValue();
531
532 // Create the image slice.
533 RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
534
535 // Create the border area slices.
536 RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices());
537
538 // Create the border outset.
539 RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset());
540
541 // Create the repeat rules.
542 RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
543
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100544 return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100545}
546
547inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle* style)
548{
549 return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
550}
551
552inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style)
553{
554 return cssValuePool().createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
555}
556
557static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style)
558{
559 if (length.isFixed())
560 return zoomAdjustedPixelValue(length.value(), style);
561 return cssValuePool().createValue(length);
562}
563
564static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style)
565{
566 if (!reflection)
567 return cssValuePool().createIdentifierValue(CSSValueNone);
568
569 RefPtr<CSSPrimitiveValue> offset;
570 if (reflection->offset().isPercent())
571 offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
572 else
573 offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
574
575 RefPtr<CSSPrimitiveValue> direction;
576 switch (reflection->direction()) {
577 case ReflectionBelow:
578 direction = cssValuePool().createIdentifierValue(CSSValueBelow);
579 break;
580 case ReflectionAbove:
581 direction = cssValuePool().createIdentifierValue(CSSValueAbove);
582 break;
583 case ReflectionLeft:
584 direction = cssValuePool().createIdentifierValue(CSSValueLeft);
585 break;
586 case ReflectionRight:
587 direction = cssValuePool().createIdentifierValue(CSSValueRight);
588 break;
589 }
590
591 return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask()));
592}
593
594static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle* style)
595{
596 RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
597 if (layer->isBackgroundOriginSet()) {
598 ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
599 positionList->append(cssValuePool().createValue(layer->backgroundXOrigin()));
600 }
601 positionList->append(zoomAdjustedPixelValueForLength(layer->xPosition(), style));
602 if (layer->isBackgroundOriginSet()) {
603 ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
604 positionList->append(cssValuePool().createValue(layer->backgroundYOrigin()));
605 }
606 positionList->append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
607 return positionList.release();
608}
609
610static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView)
611{
612 if (!style)
613 return 0;
614
615 Length l;
616 switch (propertyID) {
617 case CSSPropertyLeft:
618 l = style->left();
619 break;
620 case CSSPropertyRight:
621 l = style->right();
622 break;
623 case CSSPropertyTop:
624 l = style->top();
625 break;
626 case CSSPropertyBottom:
627 l = style->bottom();
628 break;
629 default:
630 return 0;
631 }
632
633 if (l.isPercent() && renderer && renderer->isBox()) {
634 LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
635 toRenderBox(renderer)->containingBlockLogicalWidthForContent() :
636 toRenderBox(renderer)->containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
637 return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize, 0), style);
Ben Murdoch591b9582013-07-10 11:41:44 +0100638 }
639 if (l.isViewportPercentage())
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100640 return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style);
641 if (l.isAuto()) {
642 // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
643 // In other words if left is auto and right is not auto, then left's computed value is negative right().
644 // So we should get the opposite length unit and see if it is auto.
645 return cssValuePool().createValue(l);
646 }
647
648 return zoomAdjustedPixelValueForLength(l, style);
649}
650
651PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
652{
653 // This function does NOT look at visited information, so that computed style doesn't expose that.
654 if (!color.isValid())
655 return cssValuePool().createColorValue(style->color().rgb());
656 return cssValuePool().createColorValue(color.rgb());
657}
658
659static PassRefPtr<CSSValueList> getBorderRadiusCornerValues(LengthSize radius, const RenderStyle* style, RenderView* renderView)
660{
661 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
662 if (radius.width().type() == Percent)
663 list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
664 else
665 list->append(zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style));
666 if (radius.height().type() == Percent)
667 list->append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
668 else
669 list->append(zoomAdjustedPixelValue(valueForLength(radius.height(), 0, renderView), style));
670 return list.release();
671}
672
673static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, RenderView* renderView)
674{
675 if (radius.width() == radius.height()) {
676 if (radius.width().type() == Percent)
677 return cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
678 return zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style);
679 }
680 return getBorderRadiusCornerValues(radius, style, renderView);
681}
682
683static PassRefPtr<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* style, RenderView* renderView)
684{
685 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
686 bool showHorizontalBottomLeft = style->borderTopRightRadius().width() != style->borderBottomLeftRadius().width();
687 bool showHorizontalBottomRight = style->borderBottomRightRadius().width() != style->borderTopLeftRadius().width();
688 bool showHorizontalTopRight = style->borderTopRightRadius().width() != style->borderTopLeftRadius().width();
689
690 bool showVerticalBottomLeft = style->borderTopRightRadius().height() != style->borderBottomLeftRadius().height();
691 bool showVerticalBottomRight = (style->borderBottomRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomLeft;
692 bool showVerticalTopRight = (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomRight;
693 bool showVerticalTopLeft = (style->borderTopLeftRadius().width() != style->borderTopLeftRadius().height());
694
695 RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style->borderTopLeftRadius(), style, renderView);
696 RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style->borderTopRightRadius(), style, renderView);
697 RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style->borderBottomRightRadius(), style, renderView);
698 RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style->borderBottomLeftRadius(), style, renderView);
699
700 RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
701 horizontalRadii->append(topLeftRadius->item(0));
702 if (showHorizontalTopRight)
703 horizontalRadii->append(topRightRadius->item(0));
704 if (showHorizontalBottomRight)
705 horizontalRadii->append(bottomRightRadius->item(0));
706 if (showHorizontalBottomLeft)
707 horizontalRadii->append(bottomLeftRadius->item(0));
708
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100709 list->append(horizontalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100710
711 if (showVerticalTopLeft) {
712 RefPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated();
713 verticalRadii->append(topLeftRadius->item(1));
714 if (showVerticalTopRight)
715 verticalRadii->append(topRightRadius->item(1));
716 if (showVerticalBottomRight)
717 verticalRadii->append(bottomRightRadius->item(1));
718 if (showVerticalBottomLeft)
719 verticalRadii->append(bottomLeftRadius->item(1));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100720 list->append(verticalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100721 }
722 return list.release();
723}
724
725static LayoutRect sizingBox(RenderObject* renderer)
726{
727 if (!renderer->isBox())
728 return LayoutRect();
729
730 RenderBox* box = toRenderBox(renderer);
731 return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect();
732}
733
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100734static PassRefPtr<CSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle* style)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100735{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100736 RefPtr<CSSTransformValue> transformValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100737 if (transform.isAffine()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100738 transformValue = CSSTransformValue::create(CSSTransformValue::MatrixTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100739
740 transformValue->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
741 transformValue->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
742 transformValue->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
743 transformValue->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
744 transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
745 transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
746 } else {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100747 transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100748
749 transformValue->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
750 transformValue->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
751 transformValue->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
752 transformValue->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
753
754 transformValue->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
755 transformValue->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
756 transformValue->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
757 transformValue->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
758
759 transformValue->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
760 transformValue->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
761 transformValue->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
762 transformValue->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
763
764 transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
765 transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
766 transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
767 transformValue->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
768 }
769
770 return transformValue.release();
771}
772
773static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style)
774{
775 if (!renderer || !renderer->hasTransform() || !style->hasTransform())
776 return cssValuePool().createIdentifierValue(CSSValueNone);
777
778 IntRect box;
779 if (renderer->isBox())
780 box = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect());
781
782 TransformationMatrix transform;
783 style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
784
785 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
786 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
787 list->append(matrixTransformValue(transform, style));
788
789 return list.release();
790}
791
792static PassRefPtr<CSSValue> valueForCustomFilterArrayParameter(const CustomFilterArrayParameter* arrayParameter)
793{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100794 RefPtr<CSSArrayFunctionValue> arrayParameterValue = CSSArrayFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100795 for (unsigned i = 0, size = arrayParameter->size(); i < size; ++i)
796 arrayParameterValue->append(cssValuePool().createValue(arrayParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
797 return arrayParameterValue.release();
798}
799
800static PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter)
801{
802 RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated();
803 for (unsigned i = 0; i < numberParameter->size(); ++i)
804 numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
805 return numberParameterValue.release();
806}
807
808static PassRefPtr<CSSValue> valueForCustomFilterTransformParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterTransformParameter* transformParameter)
809{
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100810 IntSize size;
811 if (renderer && renderer->isBox())
812 size = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()).size();
813
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100814 TransformationMatrix transform;
815 transformParameter->applyTransform(transform, size);
816 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
817 return matrixTransformValue(transform, style);
818}
819
820static PassRefPtr<CSSValue> valueForCustomFilterParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterParameter* parameter)
821{
822 // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture.
823 ASSERT(parameter);
824 switch (parameter->parameterType()) {
825 case CustomFilterParameter::ARRAY:
826 return valueForCustomFilterArrayParameter(static_cast<const CustomFilterArrayParameter*>(parameter));
827 case CustomFilterParameter::NUMBER:
828 return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter));
829 case CustomFilterParameter::TRANSFORM:
830 return valueForCustomFilterTransformParameter(renderer, style, static_cast<const CustomFilterTransformParameter*>(parameter));
831 }
832
833 ASSERT_NOT_REACHED();
834 return 0;
835}
836
837PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle* style) const
838{
839 if (style->filter().operations().isEmpty())
840 return cssValuePool().createIdentifierValue(CSSValueNone);
841
842 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
843
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100844 RefPtr<CSSFilterValue> filterValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100845
846 Vector<RefPtr<FilterOperation> >::const_iterator end = style->filter().operations().end();
847 for (Vector<RefPtr<FilterOperation> >::const_iterator it = style->filter().operations().begin(); it != end; ++it) {
848 FilterOperation* filterOperation = (*it).get();
849 switch (filterOperation->getOperationType()) {
850 case FilterOperation::REFERENCE: {
851 ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100852 filterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100853 filterValue->append(cssValuePool().createValue(referenceOperation->url(), CSSPrimitiveValue::CSS_STRING));
854 break;
855 }
856 case FilterOperation::GRAYSCALE: {
857 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100858 filterValue = CSSFilterValue::create(CSSFilterValue::GrayscaleFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100859 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
860 break;
861 }
862 case FilterOperation::SEPIA: {
863 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100864 filterValue = CSSFilterValue::create(CSSFilterValue::SepiaFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100865 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
866 break;
867 }
868 case FilterOperation::SATURATE: {
869 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100870 filterValue = CSSFilterValue::create(CSSFilterValue::SaturateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100871 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
872 break;
873 }
874 case FilterOperation::HUE_ROTATE: {
875 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100876 filterValue = CSSFilterValue::create(CSSFilterValue::HueRotateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100877 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_DEG));
878 break;
879 }
880 case FilterOperation::INVERT: {
881 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100882 filterValue = CSSFilterValue::create(CSSFilterValue::InvertFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100883 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
884 break;
885 }
886 case FilterOperation::OPACITY: {
887 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100888 filterValue = CSSFilterValue::create(CSSFilterValue::OpacityFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100889 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
890 break;
891 }
892 case FilterOperation::BRIGHTNESS: {
893 BasicComponentTransferFilterOperation* brightnessOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100894 filterValue = CSSFilterValue::create(CSSFilterValue::BrightnessFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100895 filterValue->append(cssValuePool().createValue(brightnessOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
896 break;
897 }
898 case FilterOperation::CONTRAST: {
899 BasicComponentTransferFilterOperation* contrastOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100900 filterValue = CSSFilterValue::create(CSSFilterValue::ContrastFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100901 filterValue->append(cssValuePool().createValue(contrastOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
902 break;
903 }
904 case FilterOperation::BLUR: {
905 BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100906 filterValue = CSSFilterValue::create(CSSFilterValue::BlurFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100907 filterValue->append(zoomAdjustedPixelValue(blurOperation->stdDeviation().value(), style));
908 break;
909 }
910 case FilterOperation::DROP_SHADOW: {
911 DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100912 filterValue = CSSFilterValue::create(CSSFilterValue::DropShadowFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100913 // We want our computed style to look like that of a text shadow (has neither spread nor inset style).
Ben Murdoche69819b2013-07-17 14:56:49 +0100914 OwnPtr<ShadowData> shadow = ShadowData::create(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, dropShadowOperation->color());
915 filterValue->append(valueForShadow(shadow.get(), CSSPropertyTextShadow, style));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100916 break;
917 }
918 case FilterOperation::VALIDATED_CUSTOM:
919 // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
920 ASSERT_NOT_REACHED();
921 break;
922 case FilterOperation::CUSTOM: {
923 CustomFilterOperation* customOperation = static_cast<CustomFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100924 filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100925
926 // The output should be verbose, even if the values are the default ones.
927
928 ASSERT(customOperation->program());
929 StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program());
930
931 RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
932 if (program->vertexShader())
933 shadersList->append(program->vertexShader()->cssValue());
934 else
935 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
936
937 const CustomFilterProgramMixSettings mixSettings = program->mixSettings();
938 if (program->fragmentShader()) {
939 if (program->programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100940 RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100941 mixFunction->append(program->fragmentShader()->cssValue());
942 mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
943 mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
944 shadersList->append(mixFunction.release());
945 } else
946 shadersList->append(program->fragmentShader()->cssValue());
947 }
948 else
949 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
950
951 filterValue->append(shadersList.release());
952
953 RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated();
954 meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER));
955 meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
956
957 // FIXME: The specification doesn't have any "attached" identifier. Should we add one?
958 // https://bugs.webkit.org/show_bug.cgi?id=72700
959 if (customOperation->meshType() == MeshTypeDetached)
960 meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached));
961
962 filterValue->append(meshParameters.release());
963
964 const CustomFilterParameterList& parameters = customOperation->parameters();
965 size_t parametersSize = parameters.size();
966 if (!parametersSize)
967 break;
968 RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated();
969 for (size_t i = 0; i < parametersSize; ++i) {
970 const CustomFilterParameter* parameter = parameters.at(i).get();
971 RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated();
972 parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING));
973 parameterCSSNameAndValue->append(valueForCustomFilterParameter(renderer, style, parameter));
974 parametersCSSValue->append(parameterCSSNameAndValue.release());
975 }
976
977 filterValue->append(parametersCSSValue.release());
978 break;
979 }
980 default:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100981 filterValue = CSSFilterValue::create(CSSFilterValue::UnknownFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100982 break;
983 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100984 list->append(filterValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100985 }
986
987 return list.release();
988}
989
990static PassRefPtr<CSSValue> valueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle* style, RenderView* renderView)
991{
992 if (!trackBreadth.isLength()) {
993 String flex = String::number(trackBreadth.flex());
994 flex.append("fr");
995 return cssValuePool().createValue(flex, CSSPrimitiveValue::CSS_DIMENSION);
996 }
997
998 const Length& trackBreadthLength = trackBreadth.length();
999 if (trackBreadthLength.isAuto())
1000 return cssValuePool().createIdentifierValue(CSSValueAuto);
1001 if (trackBreadthLength.isViewportPercentage())
1002 return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style);
1003 return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
1004}
1005
1006static PassRefPtr<CSSValue> valueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle* style, RenderView* renderView)
1007{
1008 switch (trackSize.type()) {
1009 case LengthTrackSizing:
1010 return valueForGridTrackBreadth(trackSize.length(), style, renderView);
1011 case MinMaxTrackSizing:
1012 RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1013 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView));
1014 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView));
1015 return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
1016 }
1017 ASSERT_NOT_REACHED();
1018 return 0;
1019}
1020
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001021static void addValuesForNamedGridLinesAtIndex(const NamedGridLinesMap& namedGridLines, size_t i, CSSValueList& list)
1022{
1023 // Note that this won't return the results in the order specified in the style sheet,
1024 // which is probably fine as we stil *do* return all the expected values.
1025 NamedGridLinesMap::const_iterator it = namedGridLines.begin();
1026 NamedGridLinesMap::const_iterator end = namedGridLines.end();
1027 for (; it != end; ++it) {
1028 const Vector<size_t>& linesIndexes = it->value;
1029 for (size_t j = 0; j < linesIndexes.size(); ++j) {
1030 if (linesIndexes[j] != i)
1031 continue;
1032
1033 list.append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1034 break;
1035 }
1036 }
1037}
1038
1039static PassRefPtr<CSSValue> valueForGridTrackList(const Vector<GridTrackSize>& trackSizes, const NamedGridLinesMap& namedGridLines, const RenderStyle* style, RenderView* renderView)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001040{
1041 // Handle the 'none' case here.
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001042 if (!trackSizes.size()) {
1043 ASSERT(namedGridLines.isEmpty());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001044 return cssValuePool().createIdentifierValue(CSSValueNone);
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001045 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001046
1047 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001048 for (size_t i = 0; i < trackSizes.size(); ++i) {
1049 addValuesForNamedGridLinesAtIndex(namedGridLines, i, *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001050 list->append(valueForGridTrackSize(trackSizes[i], style, renderView));
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001051 }
1052 // Those are the trailing <string>* allowed in the syntax.
1053 addValuesForNamedGridLinesAtIndex(namedGridLines, trackSizes.size(), *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001054 return list.release();
1055}
1056
1057static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
1058{
1059 if (position.isAuto())
1060 return cssValuePool().createIdentifierValue(CSSValueAuto);
1061
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001062 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001063 if (position.isSpan()) {
1064 list->append(cssValuePool().createIdentifierValue(CSSValueSpan));
1065 list->append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1066 } else
1067 list->append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1068
1069 if (!position.namedGridLine().isNull())
1070 list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001071 return list;
1072}
1073static PassRefPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation)
1074{
1075 RefPtr<CSSValue> propertyValue;
1076 if (animation->animationMode() == CSSAnimationData::AnimateNone)
1077 propertyValue = cssValuePool().createIdentifierValue(CSSValueNone);
1078 else if (animation->animationMode() == CSSAnimationData::AnimateAll)
1079 propertyValue = cssValuePool().createIdentifierValue(CSSValueAll);
1080 else
1081 propertyValue = cssValuePool().createValue(getPropertyNameString(animation->property()), CSSPrimitiveValue::CSS_STRING);
1082 return propertyValue.release();
1083}
1084static PassRefPtr<CSSValue> getTransitionPropertyValue(const CSSAnimationDataList* animList)
1085{
1086 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1087 if (animList) {
1088 for (size_t i = 0; i < animList->size(); ++i)
1089 list->append(createTransitionPropertyValue(animList->animation(i)));
1090 } else
1091 list->append(cssValuePool().createIdentifierValue(CSSValueAll));
1092 return list.release();
1093}
1094
1095static PassRefPtr<CSSValue> getDelayValue(const CSSAnimationDataList* animList)
1096{
1097 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1098 if (animList) {
1099 for (size_t i = 0; i < animList->size(); ++i)
1100 list->append(cssValuePool().createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
1101 } else {
1102 // Note that initialAnimationDelay() is used for both transitions and animations
1103 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
1104 }
1105 return list.release();
1106}
1107
1108static PassRefPtr<CSSValue> getDurationValue(const CSSAnimationDataList* animList)
1109{
1110 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1111 if (animList) {
1112 for (size_t i = 0; i < animList->size(); ++i)
1113 list->append(cssValuePool().createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
1114 } else {
1115 // Note that initialAnimationDuration() is used for both transitions and animations
1116 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
1117 }
1118 return list.release();
1119}
1120
1121static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1122{
1123 if (timingFunction->isCubicBezierTimingFunction()) {
1124 const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
1125 if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1126 CSSValueID valueId = CSSValueInvalid;
1127 switch (bezierTimingFunction->timingFunctionPreset()) {
1128 case CubicBezierTimingFunction::Ease:
1129 valueId = CSSValueEase;
1130 break;
1131 case CubicBezierTimingFunction::EaseIn:
1132 valueId = CSSValueEaseIn;
1133 break;
1134 case CubicBezierTimingFunction::EaseOut:
1135 valueId = CSSValueEaseOut;
1136 break;
1137 case CubicBezierTimingFunction::EaseInOut:
1138 valueId = CSSValueEaseInOut;
1139 break;
1140 default:
1141 ASSERT_NOT_REACHED();
1142 return 0;
1143 }
1144 return cssValuePool().createIdentifierValue(valueId);
1145 }
1146 return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
1147 }
1148
1149 if (timingFunction->isStepsTimingFunction()) {
1150 const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
1151 return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
1152 }
1153
1154 return CSSLinearTimingFunctionValue::create();
1155}
1156
1157static PassRefPtr<CSSValue> getTimingFunctionValue(const CSSAnimationDataList* animList)
1158{
1159 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1160 if (animList) {
1161 for (size_t i = 0; i < animList->size(); ++i)
1162 list->append(createTimingFunctionValue(animList->animation(i)->timingFunction().get()));
1163 } else
1164 // Note that initialAnimationTimingFunction() is used for both transitions and animations
1165 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
1166 return list.release();
1167}
1168
1169static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1170{
1171 if (!lineBoxContain)
1172 return cssValuePool().createIdentifierValue(CSSValueNone);
1173 return CSSLineBoxContainValue::create(lineBoxContain);
1174}
1175
1176CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1177 : m_node(n)
1178 , m_allowVisitedStyle(allowVisitedStyle)
1179 , m_refCount(1)
1180{
1181 unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1182 m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
1183 AtomicString(pseudoElementName.substring(nameWithoutColonsStart))));
1184}
1185
1186CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1187{
1188}
1189
1190void CSSComputedStyleDeclaration::ref()
1191{
1192 ++m_refCount;
1193}
1194
1195void CSSComputedStyleDeclaration::deref()
1196{
1197 ASSERT(m_refCount);
1198 if (!--m_refCount)
1199 delete this;
1200}
1201
1202String CSSComputedStyleDeclaration::cssText() const
1203{
1204 StringBuilder result;
1205 const Vector<CSSPropertyID>& properties = computableProperties();
1206
1207 for (unsigned i = 0; i < properties.size(); i++) {
1208 if (i)
1209 result.append(' ');
1210 result.append(getPropertyName(properties[i]));
1211 result.append(": ", 2);
1212 result.append(getPropertyValue(properties[i]));
1213 result.append(';');
1214 }
1215
1216 return result.toString();
1217}
1218
1219void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
1220{
Ben Murdoche69819b2013-07-17 14:56:49 +01001221 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001222}
1223
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001224static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001225{
1226 ASSERT_ARG(keywordSize, keywordSize);
1227 ASSERT_ARG(keywordSize, keywordSize <= 8);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001228 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001229}
1230
1231PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
1232{
1233 if (!m_node)
1234 return 0;
1235
1236 m_node->document()->updateLayoutIgnorePendingStylesheets();
1237
1238 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1239 if (!style)
1240 return 0;
1241
1242 if (int keywordSize = style->fontDescription().keywordSize())
1243 return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
1244
1245
1246 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get());
1247}
1248
1249bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
1250{
1251 if (!m_node)
1252 return false;
1253
1254 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1255 if (!style)
1256 return false;
1257
1258 return style->fontDescription().useFixedDefaultSize();
1259}
1260
1261PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle* style) const
1262{
1263 if (!shadow)
1264 return cssValuePool().createIdentifierValue(CSSValueNone);
1265
1266 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1267 for (const ShadowData* s = shadow; s; s = s->next()) {
1268 RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style);
1269 RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style);
1270 RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style);
1271 RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : zoomAdjustedPixelValue(s->spread(), style);
1272 RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset);
1273 RefPtr<CSSPrimitiveValue> color = cssValuePool().createColorValue(s->color().rgb());
1274 list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
1275 }
1276 return list.release();
1277}
1278
1279PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const
1280{
1281 return getPropertyCSSValue(propertyID, UpdateLayout);
1282}
1283
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001284static CSSValueID identifierForFamily(const AtomicString& family)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001285{
1286 if (family == cursiveFamily)
1287 return CSSValueCursive;
1288 if (family == fantasyFamily)
1289 return CSSValueFantasy;
1290 if (family == monospaceFamily)
1291 return CSSValueMonospace;
1292 if (family == pictographFamily)
1293 return CSSValueWebkitPictograph;
1294 if (family == sansSerifFamily)
1295 return CSSValueSansSerif;
1296 if (family == serifFamily)
1297 return CSSValueSerif;
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001298 return CSSValueInvalid;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001299}
1300
1301static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1302{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001303 if (CSSValueID familyIdentifier = identifierForFamily(family))
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001304 return cssValuePool().createIdentifierValue(familyIdentifier);
1305 return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
1306}
1307
1308static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1309{
1310 // Blink value is ignored.
1311 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001312 if (textDecoration & TextDecorationUnderline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001313 list->append(cssValuePool().createIdentifierValue(CSSValueUnderline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001314 if (textDecoration & TextDecorationOverline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001315 list->append(cssValuePool().createIdentifierValue(CSSValueOverline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001316 if (textDecoration & TextDecorationLineThrough)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001317 list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough));
1318
1319 if (!list->length())
1320 return cssValuePool().createIdentifierValue(CSSValueNone);
Ben Murdoch591b9582013-07-10 11:41:44 +01001321 return list.release();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001322}
1323
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001324static PassRefPtr<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1325{
1326 switch (textDecorationStyle) {
1327 case TextDecorationStyleSolid:
1328 return cssValuePool().createIdentifierValue(CSSValueSolid);
1329 case TextDecorationStyleDouble:
1330 return cssValuePool().createIdentifierValue(CSSValueDouble);
1331 case TextDecorationStyleDotted:
1332 return cssValuePool().createIdentifierValue(CSSValueDotted);
1333 case TextDecorationStyleDashed:
1334 return cssValuePool().createIdentifierValue(CSSValueDashed);
1335 case TextDecorationStyleWavy:
1336 return cssValuePool().createIdentifierValue(CSSValueWavy);
1337 }
1338
1339 ASSERT_NOT_REACHED();
1340 return cssValuePool().createExplicitInitialValue();
1341}
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001342
1343static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1344{
1345 // For backwards compatibility, if both values are equal, just return one of them. And
1346 // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1347 if (xRepeat == yRepeat)
1348 return cssValuePool().createValue(xRepeat);
1349 if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1350 return cssValuePool().createIdentifierValue(CSSValueRepeatX);
1351 if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1352 return cssValuePool().createIdentifierValue(CSSValueRepeatY);
1353
1354 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1355 list->append(cssValuePool().createValue(xRepeat));
1356 list->append(cssValuePool().createValue(yRepeat));
1357 return list.release();
1358}
1359
1360static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style)
1361{
1362 if (fillSize.type == Contain)
1363 return cssValuePool().createIdentifierValue(CSSValueContain);
1364
1365 if (fillSize.type == Cover)
1366 return cssValuePool().createIdentifierValue(CSSValueCover);
1367
1368 if (fillSize.size.height().isAuto())
1369 return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1370
1371 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1372 list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1373 list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1374 return list.release();
1375}
1376
1377static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style)
1378{
1379 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1380 for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1381 if (contentData->isCounter()) {
1382 const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter();
1383 ASSERT(counter);
1384 list->append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1385 } else if (contentData->isImage()) {
1386 const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image();
1387 ASSERT(image);
1388 list->append(image->cssValue());
1389 } else if (contentData->isText())
1390 list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING));
1391 }
1392 if (!style->regionThread().isNull())
1393 list->append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1394 return list.release();
1395}
1396
1397static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1398{
1399 const CounterDirectiveMap* map = style->counterDirectives();
1400 if (!map)
1401 return 0;
1402
1403 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1404 for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1405 list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1406 short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1407 list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1408 }
1409 return list.release();
1410}
1411
1412static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1413{
1414 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ());
1415 if (!propertyIDSet.add(propertyID).isNewEntry)
1416 return;
1417
1418 LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1419}
1420
1421static PassRefPtr<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
1422{
1423 const FontFamily& firstFamily = style->fontDescription().family();
1424 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1425 for (const FontFamily* family = &firstFamily; family; family = family->next())
1426 list->append(valueForFamily(family->family()));
1427 return list.release();
1428}
1429
1430static PassRefPtr<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style, RenderView* renderView)
1431{
1432 Length length = style->lineHeight();
1433 if (length.isNegative())
1434 return cssValuePool().createIdentifierValue(CSSValueNormal);
1435 if (length.isPercent())
1436 // This is imperfect, because it doesn't include the zoom factor and the real computation
1437 // for how high to be in pixels does include things like minimum font size and the zoom factor.
1438 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1439 // that here either.
1440 return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style);
1441 return zoomAdjustedPixelValue(valueForLength(length, 0, renderView), style);
1442}
1443
1444static PassRefPtr<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style)
1445{
1446 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style);
1447}
1448
1449static PassRefPtr<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
1450{
1451 if (style->fontDescription().italic())
1452 return cssValuePool().createIdentifierValue(CSSValueItalic);
1453 return cssValuePool().createIdentifierValue(CSSValueNormal);
1454}
1455
1456static PassRefPtr<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style)
1457{
1458 if (style->fontDescription().smallCaps())
1459 return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
1460 return cssValuePool().createIdentifierValue(CSSValueNormal);
1461}
1462
1463static PassRefPtr<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
1464{
1465 switch (style->fontDescription().weight()) {
1466 case FontWeight100:
1467 return cssValuePool().createIdentifierValue(CSSValue100);
1468 case FontWeight200:
1469 return cssValuePool().createIdentifierValue(CSSValue200);
1470 case FontWeight300:
1471 return cssValuePool().createIdentifierValue(CSSValue300);
1472 case FontWeightNormal:
1473 return cssValuePool().createIdentifierValue(CSSValueNormal);
1474 case FontWeight500:
1475 return cssValuePool().createIdentifierValue(CSSValue500);
1476 case FontWeight600:
1477 return cssValuePool().createIdentifierValue(CSSValue600);
1478 case FontWeightBold:
1479 return cssValuePool().createIdentifierValue(CSSValueBold);
1480 case FontWeight800:
1481 return cssValuePool().createIdentifierValue(CSSValue800);
1482 case FontWeight900:
1483 return cssValuePool().createIdentifierValue(CSSValue900);
1484 }
1485 ASSERT_NOT_REACHED();
1486 return cssValuePool().createIdentifierValue(CSSValueNormal);
1487}
1488
Ben Murdoch591b9582013-07-10 11:41:44 +01001489static bool isLayoutDependent(CSSPropertyID propertyID, PassRefPtr<RenderStyle> style, RenderObject* renderer)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001490{
Ben Murdoch591b9582013-07-10 11:41:44 +01001491 // Some properties only depend on layout in certain conditions which
1492 // are specified in the main switch statement below. So we can avoid
1493 // forcing layout in those conditions. The conditions in this switch
1494 // statement must remain in sync with the conditions in the main switch.
1495 // FIXME: Some of these cases could be narrowed down or optimized better.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001496 switch (propertyID) {
1497 case CSSPropertyBottom:
1498 case CSSPropertyHeight:
1499 case CSSPropertyLeft:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001500 case CSSPropertyRight:
1501 case CSSPropertyTop:
1502 case CSSPropertyWebkitPerspectiveOrigin:
1503 case CSSPropertyWebkitTransform:
1504 case CSSPropertyWebkitTransformOrigin:
1505 case CSSPropertyWidth:
1506 case CSSPropertyWebkitFilter:
1507 return true;
Ben Murdoch591b9582013-07-10 11:41:44 +01001508 case CSSPropertyMargin:
1509 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed() || !style->marginTop().isFixed() || !style->marginLeft().isFixed() || !style->marginRight().isFixed());
1510 case CSSPropertyMarginLeft:
1511 return renderer && renderer->isBox() && (!style || !style->marginLeft().isFixed());
1512 case CSSPropertyMarginRight:
1513 return renderer && renderer->isBox() && (!style || !style->marginRight().isFixed());
1514 case CSSPropertyMarginTop:
1515 return renderer && renderer->isBox() && (!style || !style->marginTop().isFixed());
1516 case CSSPropertyMarginBottom:
1517 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed());
1518 case CSSPropertyPadding:
1519 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed() || !style->paddingTop().isFixed() || !style->paddingLeft().isFixed() || !style->paddingRight().isFixed());
1520 case CSSPropertyPaddingBottom:
1521 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed());
1522 case CSSPropertyPaddingLeft:
1523 return renderer && renderer->isBox() && (!style || !style->paddingLeft().isFixed());
1524 case CSSPropertyPaddingRight:
1525 return renderer && renderer->isBox() && (!style || !style->paddingRight().isFixed());
1526 case CSSPropertyPaddingTop:
1527 return renderer && renderer->isBox() && (!style || !style->paddingTop().isFixed());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001528 default:
1529 return false;
1530 }
1531}
1532
Ben Murdoch591b9582013-07-10 11:41:44 +01001533PassRefPtr<RenderStyle> CSSComputedStyleDeclaration::computeRenderStyle(CSSPropertyID propertyID) const
1534{
1535 Node* styledNode = this->styledNode();
1536 ASSERT(styledNode);
1537 RenderObject* renderer = styledNode->renderer();
Ben Murdoche69819b2013-07-17 14:56:49 +01001538 if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID) && !RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
Ben Murdoch591b9582013-07-10 11:41:44 +01001539 AnimationUpdateBlock animationUpdateBlock(renderer->animation());
1540 if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) {
1541 // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
1542 return renderer->animation()->getAnimatedStyleForRenderer(renderer)->getCachedPseudoStyle(m_pseudoElementSpecifier);
1543 }
1544 return renderer->animation()->getAnimatedStyleForRenderer(renderer);
1545 }
1546 return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
1547}
1548
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001549Node* CSSComputedStyleDeclaration::styledNode() const
1550{
1551 if (!m_node)
1552 return 0;
1553 if (m_node->isElementNode()) {
1554 if (PseudoElement* element = toElement(m_node.get())->pseudoElement(m_pseudoElementSpecifier))
1555 return element;
1556 }
1557 return m_node.get();
1558}
1559
1560PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1561{
1562 Node* styledNode = this->styledNode();
1563 if (!styledNode)
1564 return 0;
Ben Murdoch591b9582013-07-10 11:41:44 +01001565 RenderObject* renderer = styledNode->renderer();
1566 RefPtr<RenderStyle> style;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001567
1568 if (updateLayout) {
1569 Document* document = styledNode->document();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001570
Ben Murdoch591b9582013-07-10 11:41:44 +01001571 document->updateStyleForNodeIfNeeded(styledNode);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001572
1573 // The style recalc could have caused the styled node to be discarded or replaced
1574 // if it was a PseudoElement so we need to update it.
1575 styledNode = this->styledNode();
Ben Murdoch591b9582013-07-10 11:41:44 +01001576 renderer = styledNode->renderer();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001577
Ben Murdoch591b9582013-07-10 11:41:44 +01001578 style = computeRenderStyle(propertyID);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001579
Ben Murdoch591b9582013-07-10 11:41:44 +01001580 bool forceFullLayout = isLayoutDependent(propertyID, style, renderer)
1581 || styledNode->isInShadowTree()
1582 || (document->styleResolverIfExists() && document->styleResolverIfExists()->hasViewportDependentMediaQueries() && document->ownerElement())
1583 || document->seamlessParentIFrame();
1584
1585 if (forceFullLayout) {
1586 document->updateLayoutIgnorePendingStylesheets();
1587 styledNode = this->styledNode();
1588 style = computeRenderStyle(propertyID);
1589 renderer = styledNode->renderer();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001590 }
Ben Murdoch591b9582013-07-10 11:41:44 +01001591 } else {
1592 style = computeRenderStyle(propertyID);
1593 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001594
1595 if (!style)
1596 return 0;
1597
1598 propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
1599
1600 switch (propertyID) {
1601 case CSSPropertyInvalid:
1602 case CSSPropertyVariable:
1603 break;
1604
1605 case CSSPropertyBackgroundColor:
1606 return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
1607 case CSSPropertyBackgroundImage:
1608 case CSSPropertyWebkitMaskImage: {
1609 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
1610 if (!layers)
1611 return cssValuePool().createIdentifierValue(CSSValueNone);
1612
1613 if (!layers->next()) {
1614 if (layers->image())
1615 return layers->image()->cssValue();
1616
1617 return cssValuePool().createIdentifierValue(CSSValueNone);
1618 }
1619
1620 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1621 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1622 if (currLayer->image())
1623 list->append(currLayer->image()->cssValue());
1624 else
1625 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1626 }
1627 return list.release();
1628 }
1629 case CSSPropertyBackgroundSize:
1630 case CSSPropertyWebkitBackgroundSize:
1631 case CSSPropertyWebkitMaskSize: {
1632 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
1633 if (!layers->next())
1634 return fillSizeToCSSValue(layers->size(), style.get());
1635
1636 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1637 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1638 list->append(fillSizeToCSSValue(currLayer->size(), style.get()));
1639
1640 return list.release();
1641 }
1642 case CSSPropertyBackgroundRepeat:
1643 case CSSPropertyWebkitMaskRepeat: {
1644 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
1645 if (!layers->next())
1646 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
1647
1648 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1649 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1650 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
1651
1652 return list.release();
1653 }
1654 case CSSPropertyWebkitBackgroundComposite:
1655 case CSSPropertyWebkitMaskComposite: {
1656 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
1657 if (!layers->next())
1658 return cssValuePool().createValue(layers->composite());
1659
1660 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1661 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1662 list->append(cssValuePool().createValue(currLayer->composite()));
1663
1664 return list.release();
1665 }
1666 case CSSPropertyBackgroundAttachment: {
1667 const FillLayer* layers = style->backgroundLayers();
1668 if (!layers->next())
1669 return cssValuePool().createValue(layers->attachment());
1670
1671 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1672 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1673 list->append(cssValuePool().createValue(currLayer->attachment()));
1674
1675 return list.release();
1676 }
1677 case CSSPropertyBackgroundClip:
1678 case CSSPropertyBackgroundOrigin:
1679 case CSSPropertyWebkitBackgroundClip:
1680 case CSSPropertyWebkitBackgroundOrigin:
1681 case CSSPropertyWebkitMaskClip:
1682 case CSSPropertyWebkitMaskOrigin: {
1683 const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
1684 bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
1685 if (!layers->next()) {
1686 EFillBox box = isClip ? layers->clip() : layers->origin();
1687 return cssValuePool().createValue(box);
1688 }
1689
1690 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1691 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1692 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
1693 list->append(cssValuePool().createValue(box));
1694 }
1695
1696 return list.release();
1697 }
1698 case CSSPropertyBackgroundPosition:
1699 case CSSPropertyWebkitMaskPosition: {
1700 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
1701 if (!layers->next())
1702 return createPositionListForLayer(propertyID, layers, style.get());
1703
1704 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1705 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1706 list->append(createPositionListForLayer(propertyID, currLayer, style.get()));
1707 return list.release();
1708 }
1709 case CSSPropertyBackgroundPositionX:
1710 case CSSPropertyWebkitMaskPositionX: {
1711 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
1712 if (!layers->next())
1713 return cssValuePool().createValue(layers->xPosition());
1714
1715 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1716 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1717 list->append(cssValuePool().createValue(currLayer->xPosition()));
1718
1719 return list.release();
1720 }
1721 case CSSPropertyBackgroundPositionY:
1722 case CSSPropertyWebkitMaskPositionY: {
1723 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
1724 if (!layers->next())
1725 return cssValuePool().createValue(layers->yPosition());
1726
1727 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1728 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1729 list->append(cssValuePool().createValue(currLayer->yPosition()));
1730
1731 return list.release();
1732 }
1733 case CSSPropertyBorderCollapse:
1734 if (style->borderCollapse())
1735 return cssValuePool().createIdentifierValue(CSSValueCollapse);
1736 return cssValuePool().createIdentifierValue(CSSValueSeparate);
1737 case CSSPropertyBorderSpacing: {
1738 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1739 list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()));
1740 list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()));
1741 return list.release();
1742 }
1743 case CSSPropertyWebkitBorderHorizontalSpacing:
1744 return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get());
1745 case CSSPropertyWebkitBorderVerticalSpacing:
1746 return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get());
1747 case CSSPropertyBorderImageSource:
1748 if (style->borderImageSource())
1749 return style->borderImageSource()->cssValue();
1750 return cssValuePool().createIdentifierValue(CSSValueNone);
1751 case CSSPropertyBorderTopColor:
1752 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
1753 case CSSPropertyBorderRightColor:
1754 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
1755 case CSSPropertyBorderBottomColor:
1756 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
1757 case CSSPropertyBorderLeftColor:
1758 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
1759 case CSSPropertyBorderTopStyle:
1760 return cssValuePool().createValue(style->borderTopStyle());
1761 case CSSPropertyBorderRightStyle:
1762 return cssValuePool().createValue(style->borderRightStyle());
1763 case CSSPropertyBorderBottomStyle:
1764 return cssValuePool().createValue(style->borderBottomStyle());
1765 case CSSPropertyBorderLeftStyle:
1766 return cssValuePool().createValue(style->borderLeftStyle());
1767 case CSSPropertyBorderTopWidth:
1768 return zoomAdjustedPixelValue(style->borderTopWidth(), style.get());
1769 case CSSPropertyBorderRightWidth:
1770 return zoomAdjustedPixelValue(style->borderRightWidth(), style.get());
1771 case CSSPropertyBorderBottomWidth:
1772 return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get());
1773 case CSSPropertyBorderLeftWidth:
1774 return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get());
1775 case CSSPropertyBottom:
1776 return getPositionOffsetValue(style.get(), CSSPropertyBottom, renderer, m_node->document()->renderView());
1777 case CSSPropertyWebkitBoxAlign:
1778 return cssValuePool().createValue(style->boxAlign());
1779 case CSSPropertyWebkitBoxDecorationBreak:
1780 if (style->boxDecorationBreak() == DSLICE)
1781 return cssValuePool().createIdentifierValue(CSSValueSlice);
1782 return cssValuePool().createIdentifierValue(CSSValueClone);
1783 case CSSPropertyWebkitBoxDirection:
1784 return cssValuePool().createValue(style->boxDirection());
1785 case CSSPropertyWebkitBoxFlex:
1786 return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
1787 case CSSPropertyWebkitBoxFlexGroup:
1788 return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
1789 case CSSPropertyWebkitBoxLines:
1790 return cssValuePool().createValue(style->boxLines());
1791 case CSSPropertyWebkitBoxOrdinalGroup:
1792 return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
1793 case CSSPropertyWebkitBoxOrient:
1794 return cssValuePool().createValue(style->boxOrient());
1795 case CSSPropertyWebkitBoxPack:
1796 return cssValuePool().createValue(style->boxPack());
1797 case CSSPropertyWebkitBoxReflect:
1798 return valueForReflection(style->boxReflect(), style.get());
1799 case CSSPropertyBoxShadow:
1800 case CSSPropertyWebkitBoxShadow:
1801 return valueForShadow(style->boxShadow(), propertyID, style.get());
1802 case CSSPropertyCaptionSide:
1803 return cssValuePool().createValue(style->captionSide());
1804 case CSSPropertyClear:
1805 return cssValuePool().createValue(style->clear());
1806 case CSSPropertyColor:
1807 return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
1808 case CSSPropertyWebkitPrintColorAdjust:
1809 return cssValuePool().createValue(style->printColorAdjust());
1810 case CSSPropertyWebkitColumnAxis:
1811 return cssValuePool().createValue(style->columnAxis());
1812 case CSSPropertyWebkitColumnCount:
1813 if (style->hasAutoColumnCount())
1814 return cssValuePool().createIdentifierValue(CSSValueAuto);
1815 return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
1816 case CSSPropertyWebkitColumnGap:
1817 if (style->hasNormalColumnGap())
1818 return cssValuePool().createIdentifierValue(CSSValueNormal);
1819 return zoomAdjustedPixelValue(style->columnGap(), style.get());
1820 case CSSPropertyWebkitColumnProgression:
1821 return cssValuePool().createValue(style->columnProgression());
1822 case CSSPropertyWebkitColumnRuleColor:
1823 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
1824 case CSSPropertyWebkitColumnRuleStyle:
1825 return cssValuePool().createValue(style->columnRuleStyle());
1826 case CSSPropertyWebkitColumnRuleWidth:
1827 return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get());
1828 case CSSPropertyWebkitColumnSpan:
1829 return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
1830 case CSSPropertyWebkitColumnBreakAfter:
1831 return cssValuePool().createValue(style->columnBreakAfter());
1832 case CSSPropertyWebkitColumnBreakBefore:
1833 return cssValuePool().createValue(style->columnBreakBefore());
1834 case CSSPropertyWebkitColumnBreakInside:
1835 return cssValuePool().createValue(style->columnBreakInside());
1836 case CSSPropertyWebkitColumnWidth:
1837 if (style->hasAutoColumnWidth())
1838 return cssValuePool().createIdentifierValue(CSSValueAuto);
1839 return zoomAdjustedPixelValue(style->columnWidth(), style.get());
1840 case CSSPropertyTabSize:
1841 return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
1842 case CSSPropertyWebkitRegionBreakAfter:
1843 return cssValuePool().createValue(style->regionBreakAfter());
1844 case CSSPropertyWebkitRegionBreakBefore:
1845 return cssValuePool().createValue(style->regionBreakBefore());
1846 case CSSPropertyWebkitRegionBreakInside:
1847 return cssValuePool().createValue(style->regionBreakInside());
1848 case CSSPropertyCursor: {
1849 RefPtr<CSSValueList> list;
1850 CursorList* cursors = style->cursors();
1851 if (cursors && cursors->size() > 0) {
1852 list = CSSValueList::createCommaSeparated();
1853 for (unsigned i = 0; i < cursors->size(); ++i)
1854 if (StyleImage* image = cursors->at(i).image())
1855 list->append(image->cssValue());
1856 }
1857 RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
1858 if (list) {
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001859 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001860 return list.release();
1861 }
1862 return value.release();
1863 }
1864 case CSSPropertyDirection:
1865 return cssValuePool().createValue(style->direction());
1866 case CSSPropertyDisplay:
1867 return cssValuePool().createValue(style->display());
1868 case CSSPropertyEmptyCells:
1869 return cssValuePool().createValue(style->emptyCells());
Ben Murdoch591b9582013-07-10 11:41:44 +01001870 case CSSPropertyAlignContent:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001871 return cssValuePool().createValue(style->alignContent());
Ben Murdoch591b9582013-07-10 11:41:44 +01001872 case CSSPropertyAlignItems:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001873 return cssValuePool().createValue(style->alignItems());
Ben Murdoch591b9582013-07-10 11:41:44 +01001874 case CSSPropertyAlignSelf:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001875 if (style->alignSelf() == AlignAuto) {
1876 Node* parent = styledNode->parentNode();
1877 if (parent && parent->computedStyle())
1878 return cssValuePool().createValue(parent->computedStyle()->alignItems());
1879 return cssValuePool().createValue(AlignStretch);
1880 }
1881 return cssValuePool().createValue(style->alignSelf());
Ben Murdoch591b9582013-07-10 11:41:44 +01001882 case CSSPropertyFlex:
1883 return getCSSPropertyValuesForShorthandProperties(flexShorthand());
1884 case CSSPropertyFlexBasis:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001885 return cssValuePool().createValue(style->flexBasis());
Ben Murdoch591b9582013-07-10 11:41:44 +01001886 case CSSPropertyFlexDirection:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001887 return cssValuePool().createValue(style->flexDirection());
Ben Murdoch591b9582013-07-10 11:41:44 +01001888 case CSSPropertyFlexFlow:
1889 return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
1890 case CSSPropertyFlexGrow:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001891 return cssValuePool().createValue(style->flexGrow());
Ben Murdoch591b9582013-07-10 11:41:44 +01001892 case CSSPropertyFlexShrink:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001893 return cssValuePool().createValue(style->flexShrink());
Ben Murdoch591b9582013-07-10 11:41:44 +01001894 case CSSPropertyFlexWrap:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001895 return cssValuePool().createValue(style->flexWrap());
Ben Murdoch591b9582013-07-10 11:41:44 +01001896 case CSSPropertyJustifyContent:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001897 return cssValuePool().createValue(style->justifyContent());
Ben Murdoch591b9582013-07-10 11:41:44 +01001898 case CSSPropertyOrder:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001899 return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
1900 case CSSPropertyFloat:
1901 if (style->display() != NONE && style->hasOutOfFlowPosition())
1902 return cssValuePool().createIdentifierValue(CSSValueNone);
1903 return cssValuePool().createValue(style->floating());
1904 case CSSPropertyFont: {
1905 RefPtr<FontValue> computedFont = FontValue::create();
1906 computedFont->style = fontStyleFromStyle(style.get());
1907 computedFont->variant = fontVariantFromStyle(style.get());
1908 computedFont->weight = fontWeightFromStyle(style.get());
1909 computedFont->size = fontSizeFromStyle(style.get());
1910 computedFont->lineHeight = lineHeightFromStyle(style.get(), m_node->document()->renderView());
1911 computedFont->family = fontFamilyFromStyle(style.get());
1912 return computedFont.release();
1913 }
1914 case CSSPropertyFontFamily: {
1915 RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get());
1916 // If there's only a single family, return that as a CSSPrimitiveValue.
1917 // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
1918 if (fontFamilyList->length() == 1)
1919 return fontFamilyList->item(0);
1920 return fontFamilyList.release();
1921 }
1922 case CSSPropertyFontSize:
1923 return fontSizeFromStyle(style.get());
1924 case CSSPropertyFontStyle:
1925 return fontStyleFromStyle(style.get());
1926 case CSSPropertyFontVariant:
1927 return fontVariantFromStyle(style.get());
1928 case CSSPropertyFontWeight:
1929 return fontWeightFromStyle(style.get());
1930 case CSSPropertyWebkitFontFeatureSettings: {
1931 const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings();
1932 if (!featureSettings || !featureSettings->size())
1933 return cssValuePool().createIdentifierValue(CSSValueNormal);
1934 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1935 for (unsigned i = 0; i < featureSettings->size(); ++i) {
1936 const FontFeature& feature = featureSettings->at(i);
1937 RefPtr<FontFeatureValue> featureValue = FontFeatureValue::create(feature.tag(), feature.value());
1938 list->append(featureValue.release());
1939 }
1940 return list.release();
1941 }
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001942 case CSSPropertyGridAutoColumns:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001943 return valueForGridTrackSize(style->gridAutoColumns(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001944 case CSSPropertyGridAutoFlow:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001945 return cssValuePool().createValue(style->gridAutoFlow());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001946 case CSSPropertyGridAutoRows:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001947 return valueForGridTrackSize(style->gridAutoRows(), style.get(), m_node->document()->renderView());
Ben Murdoch591b9582013-07-10 11:41:44 +01001948 case CSSPropertyGridDefinitionColumns:
1949 return valueForGridTrackList(style->gridDefinitionColumns(), style->namedGridColumnLines(), style.get(), m_node->document()->renderView());
1950 case CSSPropertyGridDefinitionRows:
1951 return valueForGridTrackList(style->gridDefinitionRows(), style->namedGridRowLines(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001952
Ben Murdoch591b9582013-07-10 11:41:44 +01001953 case CSSPropertyGridColumnStart:
1954 return valueForGridPosition(style->gridColumnStart());
1955 case CSSPropertyGridColumnEnd:
1956 return valueForGridPosition(style->gridColumnEnd());
1957 case CSSPropertyGridRowStart:
1958 return valueForGridPosition(style->gridRowStart());
1959 case CSSPropertyGridRowEnd:
1960 return valueForGridPosition(style->gridRowEnd());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001961 case CSSPropertyGridColumn:
1962 return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
1963 case CSSPropertyGridRow:
1964 return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
1965 case CSSPropertyGridArea:
1966 return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001967
1968 case CSSPropertyHeight:
1969 if (renderer) {
1970 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
1971 // the "height" property does not apply for non-replaced inline elements.
1972 if (!renderer->isReplaced() && renderer->isInline())
1973 return cssValuePool().createIdentifierValue(CSSValueAuto);
1974 return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get());
1975 }
1976 return zoomAdjustedPixelValueForLength(style->height(), style.get());
1977 case CSSPropertyWebkitHighlight:
1978 if (style->highlight() == nullAtom)
1979 return cssValuePool().createIdentifierValue(CSSValueNone);
1980 return cssValuePool().createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
1981 case CSSPropertyWebkitHyphens:
1982 return cssValuePool().createValue(style->hyphens());
1983 case CSSPropertyWebkitHyphenateCharacter:
1984 if (style->hyphenationString().isNull())
1985 return cssValuePool().createIdentifierValue(CSSValueAuto);
1986 return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
1987 case CSSPropertyWebkitHyphenateLimitAfter:
1988 if (style->hyphenationLimitAfter() < 0)
1989 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1990 return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
1991 case CSSPropertyWebkitHyphenateLimitBefore:
1992 if (style->hyphenationLimitBefore() < 0)
1993 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1994 return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
1995 case CSSPropertyWebkitHyphenateLimitLines:
1996 if (style->hyphenationLimitLines() < 0)
1997 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
1998 return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
1999 case CSSPropertyWebkitBorderFit:
2000 if (style->borderFit() == BorderFitBorder)
2001 return cssValuePool().createIdentifierValue(CSSValueBorder);
2002 return cssValuePool().createIdentifierValue(CSSValueLines);
2003 case CSSPropertyImageRendering:
2004 return CSSPrimitiveValue::create(style->imageRendering());
2005 case CSSPropertyLeft:
2006 return getPositionOffsetValue(style.get(), CSSPropertyLeft, renderer, m_node->document()->renderView());
2007 case CSSPropertyLetterSpacing:
2008 if (!style->letterSpacing())
2009 return cssValuePool().createIdentifierValue(CSSValueNormal);
2010 return zoomAdjustedPixelValue(style->letterSpacing(), style.get());
2011 case CSSPropertyWebkitLineClamp:
2012 if (style->lineClamp().isNone())
2013 return cssValuePool().createIdentifierValue(CSSValueNone);
2014 return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2015 case CSSPropertyLineHeight:
2016 return lineHeightFromStyle(style.get(), m_node->document()->renderView());
2017 case CSSPropertyListStyleImage:
2018 if (style->listStyleImage())
2019 return style->listStyleImage()->cssValue();
2020 return cssValuePool().createIdentifierValue(CSSValueNone);
2021 case CSSPropertyListStylePosition:
2022 return cssValuePool().createValue(style->listStylePosition());
2023 case CSSPropertyListStyleType:
2024 return cssValuePool().createValue(style->listStyleType());
2025 case CSSPropertyWebkitLocale:
2026 if (style->locale().isNull())
2027 return cssValuePool().createIdentifierValue(CSSValueAuto);
2028 return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2029 case CSSPropertyMarginTop: {
2030 Length marginTop = style->marginTop();
2031 if (marginTop.isFixed() || !renderer || !renderer->isBox())
2032 return zoomAdjustedPixelValueForLength(marginTop, style.get());
2033 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginTop(), style.get());
2034 }
2035 case CSSPropertyMarginRight: {
2036 Length marginRight = style->marginRight();
2037 if (marginRight.isFixed() || !renderer || !renderer->isBox())
2038 return zoomAdjustedPixelValueForLength(marginRight, style.get());
2039 float value;
2040 if (marginRight.isPercent() || marginRight.isViewportPercentage())
2041 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2042 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2043 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2044 value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document()->renderView());
2045 else
2046 value = toRenderBox(renderer)->marginRight();
2047 return zoomAdjustedPixelValue(value, style.get());
2048 }
2049 case CSSPropertyMarginBottom: {
2050 Length marginBottom = style->marginBottom();
2051 if (marginBottom.isFixed() || !renderer || !renderer->isBox())
2052 return zoomAdjustedPixelValueForLength(marginBottom, style.get());
2053 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginBottom(), style.get());
2054 }
2055 case CSSPropertyMarginLeft: {
2056 Length marginLeft = style->marginLeft();
2057 if (marginLeft.isFixed() || !renderer || !renderer->isBox())
2058 return zoomAdjustedPixelValueForLength(marginLeft, style.get());
2059 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginLeft(), style.get());
2060 }
2061 case CSSPropertyWebkitMarqueeDirection:
2062 return cssValuePool().createValue(style->marqueeDirection());
2063 case CSSPropertyWebkitMarqueeIncrement:
2064 return cssValuePool().createValue(style->marqueeIncrement());
2065 case CSSPropertyWebkitMarqueeRepetition:
2066 if (style->marqueeLoopCount() < 0)
2067 return cssValuePool().createIdentifierValue(CSSValueInfinite);
2068 return cssValuePool().createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
2069 case CSSPropertyWebkitMarqueeStyle:
2070 return cssValuePool().createValue(style->marqueeBehavior());
2071 case CSSPropertyWebkitUserModify:
2072 return cssValuePool().createValue(style->userModify());
2073 case CSSPropertyMaxHeight: {
2074 const Length& maxHeight = style->maxHeight();
2075 if (maxHeight.isUndefined())
2076 return cssValuePool().createIdentifierValue(CSSValueNone);
2077 return zoomAdjustedPixelValueForLength(maxHeight, style.get());
2078 }
2079 case CSSPropertyMaxWidth: {
2080 const Length& maxWidth = style->maxWidth();
2081 if (maxWidth.isUndefined())
2082 return cssValuePool().createIdentifierValue(CSSValueNone);
2083 return zoomAdjustedPixelValueForLength(maxWidth, style.get());
2084 }
2085 case CSSPropertyMinHeight:
2086 // FIXME: For flex-items, min-height:auto should compute to min-content.
2087 if (style->minHeight().isAuto())
2088 return zoomAdjustedPixelValue(0, style.get());
2089 return zoomAdjustedPixelValueForLength(style->minHeight(), style.get());
2090 case CSSPropertyMinWidth:
2091 // FIXME: For flex-items, min-width:auto should compute to min-content.
2092 if (style->minWidth().isAuto())
2093 return zoomAdjustedPixelValue(0, style.get());
2094 return zoomAdjustedPixelValueForLength(style->minWidth(), style.get());
2095 case CSSPropertyOpacity:
2096 return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
2097 case CSSPropertyOrphans:
2098 if (style->hasAutoOrphans())
2099 return cssValuePool().createIdentifierValue(CSSValueAuto);
2100 return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
2101 case CSSPropertyOutlineColor:
2102 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
2103 case CSSPropertyOutlineOffset:
2104 return zoomAdjustedPixelValue(style->outlineOffset(), style.get());
2105 case CSSPropertyOutlineStyle:
2106 if (style->outlineStyleIsAuto())
2107 return cssValuePool().createIdentifierValue(CSSValueAuto);
2108 return cssValuePool().createValue(style->outlineStyle());
2109 case CSSPropertyOutlineWidth:
2110 return zoomAdjustedPixelValue(style->outlineWidth(), style.get());
2111 case CSSPropertyOverflow:
2112 return cssValuePool().createValue(max(style->overflowX(), style->overflowY()));
2113 case CSSPropertyOverflowWrap:
2114 return cssValuePool().createValue(style->overflowWrap());
2115 case CSSPropertyOverflowX:
2116 return cssValuePool().createValue(style->overflowX());
2117 case CSSPropertyOverflowY:
2118 return cssValuePool().createValue(style->overflowY());
Ben Murdoch591b9582013-07-10 11:41:44 +01002119 case CSSPropertyPaddingTop: {
2120 Length paddingTop = style->paddingTop();
2121 if (paddingTop.isFixed() || !renderer || !renderer->isBox())
2122 return zoomAdjustedPixelValueForLength(paddingTop, style.get());
2123 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingTop(), style.get());
2124 }
2125 case CSSPropertyPaddingRight: {
2126 Length paddingRight = style->paddingRight();
2127 if (paddingRight.isFixed() || !renderer || !renderer->isBox())
2128 return zoomAdjustedPixelValueForLength(paddingRight, style.get());
2129 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingRight(), style.get());
2130 }
2131 case CSSPropertyPaddingBottom: {
2132 Length paddingBottom = style->paddingBottom();
2133 if (paddingBottom.isFixed() || !renderer || !renderer->isBox())
2134 return zoomAdjustedPixelValueForLength(paddingBottom, style.get());
2135 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingBottom(), style.get());
2136 }
2137 case CSSPropertyPaddingLeft: {
2138 Length paddingLeft = style->paddingLeft();
2139 if (paddingLeft.isFixed() || !renderer || !renderer->isBox())
2140 return zoomAdjustedPixelValueForLength(paddingLeft, style.get());
2141 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingLeft(), style.get());
2142 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002143 case CSSPropertyPageBreakAfter:
2144 return cssValuePool().createValue(style->pageBreakAfter());
2145 case CSSPropertyPageBreakBefore:
2146 return cssValuePool().createValue(style->pageBreakBefore());
2147 case CSSPropertyPageBreakInside: {
2148 EPageBreak pageBreak = style->pageBreakInside();
2149 ASSERT(pageBreak != PBALWAYS);
2150 if (pageBreak == PBALWAYS)
2151 return 0;
2152 return cssValuePool().createValue(style->pageBreakInside());
2153 }
2154 case CSSPropertyPosition:
2155 return cssValuePool().createValue(style->position());
2156 case CSSPropertyRight:
2157 return getPositionOffsetValue(style.get(), CSSPropertyRight, renderer, m_node->document()->renderView());
2158 case CSSPropertyWebkitRubyPosition:
2159 return cssValuePool().createValue(style->rubyPosition());
2160 case CSSPropertyTableLayout:
2161 return cssValuePool().createValue(style->tableLayout());
2162 case CSSPropertyTextAlign:
2163 return cssValuePool().createValue(style->textAlign());
Ben Murdoche69819b2013-07-17 14:56:49 +01002164 case CSSPropertyTextAlignLast:
2165 return cssValuePool().createValue(style->textAlignLast());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002166 case CSSPropertyTextDecoration:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002167 case CSSPropertyTextDecorationLine:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002168 return renderTextDecorationFlagsToCSSValue(style->textDecoration());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002169 case CSSPropertyTextDecorationStyle:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002170 return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002171 case CSSPropertyTextDecorationColor:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002172 return currentColorOrValidColor(style.get(), style->textDecorationColor());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002173#if ENABLE(CSS3_TEXT)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002174 case CSSPropertyWebkitTextUnderlinePosition:
2175 return cssValuePool().createValue(style->textUnderlinePosition());
2176#endif // CSS3_TEXT
2177 case CSSPropertyWebkitTextDecorationsInEffect:
2178 return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
2179 case CSSPropertyWebkitTextFillColor:
2180 return currentColorOrValidColor(style.get(), style->textFillColor());
2181 case CSSPropertyWebkitTextEmphasisColor:
2182 return currentColorOrValidColor(style.get(), style->textEmphasisColor());
2183 case CSSPropertyWebkitTextEmphasisPosition:
2184 return cssValuePool().createValue(style->textEmphasisPosition());
2185 case CSSPropertyWebkitTextEmphasisStyle:
2186 switch (style->textEmphasisMark()) {
2187 case TextEmphasisMarkNone:
2188 return cssValuePool().createIdentifierValue(CSSValueNone);
2189 case TextEmphasisMarkCustom:
2190 return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
2191 case TextEmphasisMarkAuto:
2192 ASSERT_NOT_REACHED();
2193 // Fall through
2194 case TextEmphasisMarkDot:
2195 case TextEmphasisMarkCircle:
2196 case TextEmphasisMarkDoubleCircle:
2197 case TextEmphasisMarkTriangle:
2198 case TextEmphasisMarkSesame: {
2199 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2200 list->append(cssValuePool().createValue(style->textEmphasisFill()));
2201 list->append(cssValuePool().createValue(style->textEmphasisMark()));
2202 return list.release();
2203 }
2204 }
2205 case CSSPropertyTextIndent: {
2206 RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), style.get());
2207#if ENABLE(CSS3_TEXT)
2208 if (style->textIndentLine() == TextIndentEachLine) {
2209 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2210 list->append(textIndent.release());
2211 list->append(cssValuePool().createIdentifierValue(CSSValueWebkitEachLine));
2212 return list.release();
2213 }
2214#endif
2215 return textIndent.release();
2216 }
2217 case CSSPropertyTextShadow:
2218 return valueForShadow(style->textShadow(), propertyID, style.get());
2219 case CSSPropertyTextRendering:
2220 return cssValuePool().createValue(style->fontDescription().textRenderingMode());
2221 case CSSPropertyTextOverflow:
2222 if (style->textOverflow())
2223 return cssValuePool().createIdentifierValue(CSSValueEllipsis);
2224 return cssValuePool().createIdentifierValue(CSSValueClip);
2225 case CSSPropertyWebkitTextSecurity:
2226 return cssValuePool().createValue(style->textSecurity());
2227 case CSSPropertyWebkitTextStrokeColor:
2228 return currentColorOrValidColor(style.get(), style->textStrokeColor());
2229 case CSSPropertyWebkitTextStrokeWidth:
2230 return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get());
2231 case CSSPropertyTextTransform:
2232 return cssValuePool().createValue(style->textTransform());
2233 case CSSPropertyTop:
2234 return getPositionOffsetValue(style.get(), CSSPropertyTop, renderer, m_node->document()->renderView());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002235 case CSSPropertyTouchAction:
2236 return cssValuePool().createValue(style->touchAction());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002237 case CSSPropertyUnicodeBidi:
2238 return cssValuePool().createValue(style->unicodeBidi());
2239 case CSSPropertyVerticalAlign:
2240 switch (style->verticalAlign()) {
2241 case BASELINE:
2242 return cssValuePool().createIdentifierValue(CSSValueBaseline);
2243 case MIDDLE:
2244 return cssValuePool().createIdentifierValue(CSSValueMiddle);
2245 case SUB:
2246 return cssValuePool().createIdentifierValue(CSSValueSub);
2247 case SUPER:
2248 return cssValuePool().createIdentifierValue(CSSValueSuper);
2249 case TEXT_TOP:
2250 return cssValuePool().createIdentifierValue(CSSValueTextTop);
2251 case TEXT_BOTTOM:
2252 return cssValuePool().createIdentifierValue(CSSValueTextBottom);
2253 case TOP:
2254 return cssValuePool().createIdentifierValue(CSSValueTop);
2255 case BOTTOM:
2256 return cssValuePool().createIdentifierValue(CSSValueBottom);
2257 case BASELINE_MIDDLE:
2258 return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
2259 case LENGTH:
2260 return cssValuePool().createValue(style->verticalAlignLength());
2261 }
2262 ASSERT_NOT_REACHED();
2263 return 0;
2264 case CSSPropertyVisibility:
2265 return cssValuePool().createValue(style->visibility());
2266 case CSSPropertyWhiteSpace:
2267 return cssValuePool().createValue(style->whiteSpace());
2268 case CSSPropertyWidows:
2269 if (style->hasAutoWidows())
2270 return cssValuePool().createIdentifierValue(CSSValueAuto);
2271 return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
2272 case CSSPropertyWidth:
2273 if (renderer) {
2274 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
2275 // the "width" property does not apply for non-replaced inline elements.
2276 if (!renderer->isReplaced() && renderer->isInline())
2277 return cssValuePool().createIdentifierValue(CSSValueAuto);
2278 return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get());
2279 }
2280 return zoomAdjustedPixelValueForLength(style->width(), style.get());
2281 case CSSPropertyWordBreak:
2282 return cssValuePool().createValue(style->wordBreak());
2283 case CSSPropertyWordSpacing:
2284 return zoomAdjustedPixelValue(style->wordSpacing(), style.get());
2285 case CSSPropertyWordWrap:
2286 return cssValuePool().createValue(style->overflowWrap());
2287 case CSSPropertyWebkitLineBreak:
2288 return cssValuePool().createValue(style->lineBreak());
2289 case CSSPropertyResize:
2290 return cssValuePool().createValue(style->resize());
2291 case CSSPropertyWebkitFontKerning:
2292 return cssValuePool().createValue(style->fontDescription().kerning());
2293 case CSSPropertyWebkitFontSmoothing:
2294 return cssValuePool().createValue(style->fontDescription().fontSmoothing());
2295 case CSSPropertyWebkitFontVariantLigatures: {
2296 FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
2297 FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
2298 FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
2299 if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
2300 && historicalLigaturesState == FontDescription::NormalLigaturesState)
2301 return cssValuePool().createIdentifierValue(CSSValueNormal);
2302
2303 RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
2304 if (commonLigaturesState != FontDescription::NormalLigaturesState)
2305 valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
2306 if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
2307 valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
2308 if (historicalLigaturesState != FontDescription::NormalLigaturesState)
2309 valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
2310 return valueList;
2311 }
2312 case CSSPropertyZIndex:
2313 if (style->hasAutoZIndex())
2314 return cssValuePool().createIdentifierValue(CSSValueAuto);
2315 return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
2316 case CSSPropertyZoom:
2317 return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
2318 case CSSPropertyBoxSizing:
2319 if (style->boxSizing() == CONTENT_BOX)
2320 return cssValuePool().createIdentifierValue(CSSValueContentBox);
2321 return cssValuePool().createIdentifierValue(CSSValueBorderBox);
2322 case CSSPropertyWebkitAppRegion:
2323 return cssValuePool().createIdentifierValue(style->getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag);
2324 case CSSPropertyWebkitAnimationDelay:
2325 return getDelayValue(style->animations());
2326 case CSSPropertyWebkitAnimationDirection: {
2327 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2328 const CSSAnimationDataList* t = style->animations();
2329 if (t) {
2330 for (size_t i = 0; i < t->size(); ++i) {
2331 if (t->animation(i)->direction())
2332 list->append(cssValuePool().createIdentifierValue(CSSValueAlternate));
2333 else
2334 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2335 }
2336 } else
2337 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2338 return list.release();
2339 }
2340 case CSSPropertyWebkitAnimationDuration:
2341 return getDurationValue(style->animations());
2342 case CSSPropertyWebkitAnimationFillMode: {
2343 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2344 const CSSAnimationDataList* t = style->animations();
2345 if (t) {
2346 for (size_t i = 0; i < t->size(); ++i) {
2347 switch (t->animation(i)->fillMode()) {
2348 case AnimationFillModeNone:
2349 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2350 break;
2351 case AnimationFillModeForwards:
2352 list->append(cssValuePool().createIdentifierValue(CSSValueForwards));
2353 break;
2354 case AnimationFillModeBackwards:
2355 list->append(cssValuePool().createIdentifierValue(CSSValueBackwards));
2356 break;
2357 case AnimationFillModeBoth:
2358 list->append(cssValuePool().createIdentifierValue(CSSValueBoth));
2359 break;
2360 }
2361 }
2362 } else
2363 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2364 return list.release();
2365 }
2366 case CSSPropertyWebkitAnimationIterationCount: {
2367 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2368 const CSSAnimationDataList* t = style->animations();
2369 if (t) {
2370 for (size_t i = 0; i < t->size(); ++i) {
2371 double iterationCount = t->animation(i)->iterationCount();
2372 if (iterationCount == CSSAnimationData::IterationCountInfinite)
2373 list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
2374 else
2375 list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
2376 }
2377 } else
2378 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2379 return list.release();
2380 }
2381 case CSSPropertyWebkitAnimationName: {
2382 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2383 const CSSAnimationDataList* t = style->animations();
2384 if (t) {
2385 for (size_t i = 0; i < t->size(); ++i)
2386 list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
2387 } else
2388 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2389 return list.release();
2390 }
2391 case CSSPropertyWebkitAnimationPlayState: {
2392 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2393 const CSSAnimationDataList* t = style->animations();
2394 if (t) {
2395 for (size_t i = 0; i < t->size(); ++i) {
2396 int prop = t->animation(i)->playState();
2397 if (prop == AnimPlayStatePlaying)
2398 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2399 else
2400 list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
2401 }
2402 } else
2403 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2404 return list.release();
2405 }
2406 case CSSPropertyWebkitAnimationTimingFunction:
2407 return getTimingFunctionValue(style->animations());
2408 case CSSPropertyWebkitAppearance:
2409 return cssValuePool().createValue(style->appearance());
2410 case CSSPropertyWebkitAspectRatio:
2411 if (!style->hasAspectRatio())
2412 return cssValuePool().createIdentifierValue(CSSValueNone);
2413 return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
2414 case CSSPropertyWebkitBackfaceVisibility:
2415 return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
2416 case CSSPropertyWebkitBorderImage:
2417 return valueForNinePieceImage(style->borderImage());
2418 case CSSPropertyBorderImageOutset:
2419 return valueForNinePieceImageQuad(style->borderImage().outset());
2420 case CSSPropertyBorderImageRepeat:
2421 return valueForNinePieceImageRepeat(style->borderImage());
2422 case CSSPropertyBorderImageSlice:
2423 return valueForNinePieceImageSlice(style->borderImage());
2424 case CSSPropertyBorderImageWidth:
2425 return valueForNinePieceImageQuad(style->borderImage().borderSlices());
2426 case CSSPropertyWebkitMaskBoxImage:
2427 return valueForNinePieceImage(style->maskBoxImage());
2428 case CSSPropertyWebkitMaskBoxImageOutset:
2429 return valueForNinePieceImageQuad(style->maskBoxImage().outset());
2430 case CSSPropertyWebkitMaskBoxImageRepeat:
2431 return valueForNinePieceImageRepeat(style->maskBoxImage());
2432 case CSSPropertyWebkitMaskBoxImageSlice:
2433 return valueForNinePieceImageSlice(style->maskBoxImage());
2434 case CSSPropertyWebkitMaskBoxImageWidth:
2435 return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
2436 case CSSPropertyWebkitMaskBoxImageSource:
2437 if (style->maskBoxImageSource())
2438 return style->maskBoxImageSource()->cssValue();
2439 return cssValuePool().createIdentifierValue(CSSValueNone);
2440 case CSSPropertyWebkitFontSizeDelta:
2441 // Not a real style property -- used by the editing engine -- so has no computed value.
2442 break;
2443 case CSSPropertyWebkitMarginBottomCollapse:
2444 case CSSPropertyWebkitMarginAfterCollapse:
2445 return cssValuePool().createValue(style->marginAfterCollapse());
2446 case CSSPropertyWebkitMarginTopCollapse:
2447 case CSSPropertyWebkitMarginBeforeCollapse:
2448 return cssValuePool().createValue(style->marginBeforeCollapse());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002449 case CSSPropertyWebkitPerspective:
2450 if (!style->hasPerspective())
2451 return cssValuePool().createIdentifierValue(CSSValueNone);
2452 return zoomAdjustedPixelValue(style->perspective(), style.get());
2453 case CSSPropertyWebkitPerspectiveOrigin: {
2454 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2455 if (renderer) {
2456 LayoutRect box;
2457 if (renderer->isBox())
2458 box = toRenderBox(renderer)->borderBoxRect();
2459
2460 RenderView* renderView = m_node->document()->renderView();
2461 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), style.get()));
2462 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), style.get()));
2463 }
2464 else {
2465 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get()));
2466 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get()));
2467
2468 }
2469 return list.release();
2470 }
2471 case CSSPropertyWebkitRtlOrdering:
2472 return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
2473 case CSSPropertyWebkitTapHighlightColor:
2474 return currentColorOrValidColor(style.get(), style->tapHighlightColor());
2475 case CSSPropertyWebkitUserDrag:
2476 return cssValuePool().createValue(style->userDrag());
2477 case CSSPropertyWebkitUserSelect:
2478 return cssValuePool().createValue(style->userSelect());
2479 case CSSPropertyBorderBottomLeftRadius:
2480 return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), m_node->document()->renderView());
2481 case CSSPropertyBorderBottomRightRadius:
2482 return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), m_node->document()->renderView());
2483 case CSSPropertyBorderTopLeftRadius:
2484 return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), m_node->document()->renderView());
2485 case CSSPropertyBorderTopRightRadius:
2486 return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), m_node->document()->renderView());
2487 case CSSPropertyClip: {
2488 if (!style->hasClip())
2489 return cssValuePool().createIdentifierValue(CSSValueAuto);
2490 RefPtr<Rect> rect = Rect::create();
2491 rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get()));
2492 rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get()));
2493 rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get()));
2494 rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get()));
2495 return cssValuePool().createValue(rect.release());
2496 }
2497 case CSSPropertySpeak:
2498 return cssValuePool().createValue(style->speak());
2499 case CSSPropertyWebkitTransform:
2500 return computedTransform(renderer, style.get());
2501 case CSSPropertyWebkitTransformOrigin: {
2502 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2503 if (renderer) {
2504 LayoutRect box;
2505 if (renderer->isBox())
2506 box = toRenderBox(renderer)->borderBoxRect();
2507
2508 RenderView* renderView = m_node->document()->renderView();
2509 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), style.get()));
2510 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), style.get()));
2511 if (style->transformOriginZ() != 0)
2512 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2513 } else {
2514 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get()));
2515 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get()));
2516 if (style->transformOriginZ() != 0)
2517 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2518 }
2519 return list.release();
2520 }
2521 case CSSPropertyWebkitTransformStyle:
2522 return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
2523 case CSSPropertyTransitionDelay:
2524 case CSSPropertyWebkitTransitionDelay:
2525 return getDelayValue(style->transitions());
2526 case CSSPropertyTransitionDuration:
2527 case CSSPropertyWebkitTransitionDuration:
2528 return getDurationValue(style->transitions());
2529 case CSSPropertyTransitionProperty:
2530 case CSSPropertyWebkitTransitionProperty:
2531 return getTransitionPropertyValue(style->transitions());
2532 case CSSPropertyTransitionTimingFunction:
2533 case CSSPropertyWebkitTransitionTimingFunction:
2534 return getTimingFunctionValue(style->transitions());
2535 case CSSPropertyTransition:
2536 case CSSPropertyWebkitTransition: {
2537 const CSSAnimationDataList* animList = style->transitions();
2538 if (animList) {
2539 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
2540 for (size_t i = 0; i < animList->size(); ++i) {
2541 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2542 const CSSAnimationData* animation = animList->animation(i);
2543 list->append(createTransitionPropertyValue(animation));
2544 list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
2545 list->append(createTimingFunctionValue(animation->timingFunction().get()));
2546 list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
2547 transitionsList->append(list);
2548 }
2549 return transitionsList.release();
2550 }
2551
2552 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2553 // transition-property default value.
2554 list->append(cssValuePool().createIdentifierValue(CSSValueAll));
2555 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
2556 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
2557 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
2558 return list.release();
2559 }
2560 case CSSPropertyPointerEvents:
2561 return cssValuePool().createValue(style->pointerEvents());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002562 case CSSPropertyWebkitLineGrid:
2563 if (style->lineGrid().isNull())
2564 return cssValuePool().createIdentifierValue(CSSValueNone);
2565 return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
2566 case CSSPropertyWebkitLineSnap:
2567 return CSSPrimitiveValue::create(style->lineSnap());
2568 case CSSPropertyWebkitLineAlign:
2569 return CSSPrimitiveValue::create(style->lineAlign());
2570 case CSSPropertyWebkitWritingMode:
2571 return cssValuePool().createValue(style->writingMode());
2572 case CSSPropertyWebkitTextCombine:
2573 return cssValuePool().createValue(style->textCombine());
2574 case CSSPropertyWebkitTextOrientation:
2575 return CSSPrimitiveValue::create(style->textOrientation());
2576 case CSSPropertyWebkitLineBoxContain:
2577 return createLineBoxContainValue(style->lineBoxContain());
2578 case CSSPropertyContent:
2579 return contentToCSSValue(style.get());
2580 case CSSPropertyCounterIncrement:
2581 return counterToCSSValue(style.get(), propertyID);
2582 case CSSPropertyCounterReset:
2583 return counterToCSSValue(style.get(), propertyID);
2584 case CSSPropertyWebkitClipPath:
2585 if (ClipPathOperation* operation = style->clipPath()) {
2586 if (operation->getOperationType() == ClipPathOperation::SHAPE)
2587 return valueForBasicShape(static_cast<ShapeClipPathOperation*>(operation)->basicShape());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002588 if (operation->getOperationType() == ClipPathOperation::REFERENCE) {
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002589 ReferenceClipPathOperation* referenceOperation = static_cast<ReferenceClipPathOperation*>(operation);
2590 return CSSPrimitiveValue::create(referenceOperation->url(), CSSPrimitiveValue::CSS_URI);
2591 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002592 }
2593 return cssValuePool().createIdentifierValue(CSSValueNone);
2594 case CSSPropertyWebkitFlowInto:
2595 if (style->flowThread().isNull())
2596 return cssValuePool().createIdentifierValue(CSSValueNone);
2597 return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
2598 case CSSPropertyWebkitFlowFrom:
2599 if (style->regionThread().isNull())
2600 return cssValuePool().createIdentifierValue(CSSValueNone);
2601 return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01002602 case CSSPropertyWebkitRegionFragment:
2603 return cssValuePool().createValue(style->regionFragment());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002604 case CSSPropertyWebkitWrapFlow:
2605 return cssValuePool().createValue(style->wrapFlow());
2606 case CSSPropertyWebkitShapeMargin:
2607 return cssValuePool().createValue(style->shapeMargin());
2608 case CSSPropertyWebkitShapePadding:
2609 return cssValuePool().createValue(style->shapePadding());
2610 case CSSPropertyWebkitShapeInside:
2611 if (!style->shapeInside())
2612 return cssValuePool().createIdentifierValue(CSSValueAuto);
Ben Murdoch591b9582013-07-10 11:41:44 +01002613 if (style->shapeInside()->type() == ShapeValue::Outside)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002614 return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
Ben Murdoch591b9582013-07-10 11:41:44 +01002615 if (style->shapeInside()->type() == ShapeValue::Image) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002616 if (style->shapeInside()->image())
2617 return style->shapeInside()->image()->cssValue();
2618 return cssValuePool().createIdentifierValue(CSSValueNone);
2619 }
Ben Murdoch591b9582013-07-10 11:41:44 +01002620 ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002621 return valueForBasicShape(style->shapeInside()->shape());
2622 case CSSPropertyWebkitShapeOutside:
2623 if (!style->shapeOutside())
2624 return cssValuePool().createIdentifierValue(CSSValueAuto);
Ben Murdoch591b9582013-07-10 11:41:44 +01002625 if (style->shapeOutside()->type() == ShapeValue::Image) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002626 if (style->shapeOutside()->image())
2627 return style->shapeOutside()->image()->cssValue();
2628 return cssValuePool().createIdentifierValue(CSSValueNone);
2629 }
Ben Murdoch591b9582013-07-10 11:41:44 +01002630 ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002631 return valueForBasicShape(style->shapeOutside()->shape());
2632 case CSSPropertyWebkitWrapThrough:
2633 return cssValuePool().createValue(style->wrapThrough());
2634 case CSSPropertyWebkitFilter:
2635 return valueForFilter(renderer, style.get());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002636 case CSSPropertyMixBlendMode:
2637 return cssValuePool().createValue(style->blendMode());
2638
2639 case CSSPropertyBackgroundBlendMode: {
2640 const FillLayer* layers = style->backgroundLayers();
2641 if (!layers->next())
2642 return cssValuePool().createValue(layers->blendMode());
2643
2644 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2645 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2646 list->append(cssValuePool().createValue(currLayer->blendMode()));
2647
2648 return list.release();
2649 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002650 case CSSPropertyBackground:
2651 return getBackgroundShorthandValue();
2652 case CSSPropertyBorder: {
2653 RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
2654 const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
2655 CSSPropertyBorderLeft };
2656 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
2657 if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
2658 return 0;
2659 }
2660 return value.release();
2661 }
2662 case CSSPropertyBorderBottom:
2663 return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand());
2664 case CSSPropertyBorderColor:
2665 return getCSSPropertyValuesForSidesShorthand(borderColorShorthand());
2666 case CSSPropertyBorderLeft:
2667 return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand());
2668 case CSSPropertyBorderImage:
2669 return valueForNinePieceImage(style->borderImage());
2670 case CSSPropertyBorderRadius:
2671 return getBorderRadiusShorthandValue(style.get(), m_node->document()->renderView());
2672 case CSSPropertyBorderRight:
2673 return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
2674 case CSSPropertyBorderStyle:
2675 return getCSSPropertyValuesForSidesShorthand(borderStyleShorthand());
2676 case CSSPropertyBorderTop:
2677 return getCSSPropertyValuesForShorthandProperties(borderTopShorthand());
2678 case CSSPropertyBorderWidth:
2679 return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand());
2680 case CSSPropertyWebkitColumnRule:
2681 return getCSSPropertyValuesForShorthandProperties(webkitColumnRuleShorthand());
2682 case CSSPropertyWebkitColumns:
2683 return getCSSPropertyValuesForShorthandProperties(webkitColumnsShorthand());
2684 case CSSPropertyListStyle:
2685 return getCSSPropertyValuesForShorthandProperties(listStyleShorthand());
2686 case CSSPropertyMargin:
2687 return getCSSPropertyValuesForSidesShorthand(marginShorthand());
2688 case CSSPropertyOutline:
2689 return getCSSPropertyValuesForShorthandProperties(outlineShorthand());
2690 case CSSPropertyPadding:
2691 return getCSSPropertyValuesForSidesShorthand(paddingShorthand());
2692 /* Individual properties not part of the spec */
2693 case CSSPropertyBackgroundRepeatX:
2694 case CSSPropertyBackgroundRepeatY:
2695 break;
2696
2697 /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
2698 case CSSPropertyWebkitTextEmphasis:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002699 case CSSPropertyTextLineThroughColor:
2700 case CSSPropertyTextLineThroughMode:
2701 case CSSPropertyTextLineThroughStyle:
2702 case CSSPropertyTextLineThroughWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002703 case CSSPropertyTextOverlineColor:
2704 case CSSPropertyTextOverlineMode:
2705 case CSSPropertyTextOverlineStyle:
2706 case CSSPropertyTextOverlineWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002707 case CSSPropertyTextUnderlineColor:
2708 case CSSPropertyTextUnderlineMode:
2709 case CSSPropertyTextUnderlineStyle:
2710 case CSSPropertyTextUnderlineWidth:
2711 break;
2712
2713 /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
2714 case CSSPropertyWebkitBorderEnd:
2715 case CSSPropertyWebkitBorderEndColor:
2716 case CSSPropertyWebkitBorderEndStyle:
2717 case CSSPropertyWebkitBorderEndWidth:
2718 case CSSPropertyWebkitBorderStart:
2719 case CSSPropertyWebkitBorderStartColor:
2720 case CSSPropertyWebkitBorderStartStyle:
2721 case CSSPropertyWebkitBorderStartWidth:
2722 case CSSPropertyWebkitBorderAfter:
2723 case CSSPropertyWebkitBorderAfterColor:
2724 case CSSPropertyWebkitBorderAfterStyle:
2725 case CSSPropertyWebkitBorderAfterWidth:
2726 case CSSPropertyWebkitBorderBefore:
2727 case CSSPropertyWebkitBorderBeforeColor:
2728 case CSSPropertyWebkitBorderBeforeStyle:
2729 case CSSPropertyWebkitBorderBeforeWidth:
2730 case CSSPropertyWebkitMarginEnd:
2731 case CSSPropertyWebkitMarginStart:
2732 case CSSPropertyWebkitMarginAfter:
2733 case CSSPropertyWebkitMarginBefore:
2734 case CSSPropertyWebkitPaddingEnd:
2735 case CSSPropertyWebkitPaddingStart:
2736 case CSSPropertyWebkitPaddingAfter:
2737 case CSSPropertyWebkitPaddingBefore:
2738 case CSSPropertyWebkitLogicalWidth:
2739 case CSSPropertyWebkitLogicalHeight:
2740 case CSSPropertyWebkitMinLogicalWidth:
2741 case CSSPropertyWebkitMinLogicalHeight:
2742 case CSSPropertyWebkitMaxLogicalWidth:
2743 case CSSPropertyWebkitMaxLogicalHeight:
2744 ASSERT_NOT_REACHED();
2745 break;
2746
2747 /* Unimplemented @font-face properties */
2748 case CSSPropertyFontStretch:
2749 case CSSPropertySrc:
2750 case CSSPropertyUnicodeRange:
2751 break;
2752
2753 /* Other unimplemented properties */
2754 case CSSPropertyPage: // for @page
2755 case CSSPropertyQuotes: // FIXME: needs implementation
2756 case CSSPropertySize: // for @page
2757 break;
2758
2759 /* Unimplemented -webkit- properties */
2760 case CSSPropertyWebkitAnimation:
2761 case CSSPropertyWebkitBorderRadius:
2762 case CSSPropertyWebkitMarginCollapse:
2763 case CSSPropertyWebkitMarquee:
2764 case CSSPropertyWebkitMarqueeSpeed:
2765 case CSSPropertyWebkitMask:
2766 case CSSPropertyWebkitMaskRepeatX:
2767 case CSSPropertyWebkitMaskRepeatY:
2768 case CSSPropertyWebkitPerspectiveOriginX:
2769 case CSSPropertyWebkitPerspectiveOriginY:
2770 case CSSPropertyWebkitTextStroke:
2771 case CSSPropertyWebkitTransformOriginX:
2772 case CSSPropertyWebkitTransformOriginY:
2773 case CSSPropertyWebkitTransformOriginZ:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002774 break;
2775
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01002776 /* @viewport rule properties */
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002777 case CSSPropertyMaxZoom:
2778 case CSSPropertyMinZoom:
2779 case CSSPropertyOrientation:
2780 case CSSPropertyUserZoom:
2781 break;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002782
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002783 case CSSPropertyBufferedRendering:
2784 case CSSPropertyClipPath:
2785 case CSSPropertyClipRule:
2786 case CSSPropertyMask:
2787 case CSSPropertyEnableBackground:
2788 case CSSPropertyFilter:
2789 case CSSPropertyFloodColor:
2790 case CSSPropertyFloodOpacity:
2791 case CSSPropertyLightingColor:
2792 case CSSPropertyStopColor:
2793 case CSSPropertyStopOpacity:
2794 case CSSPropertyColorInterpolation:
2795 case CSSPropertyColorInterpolationFilters:
2796 case CSSPropertyColorProfile:
2797 case CSSPropertyColorRendering:
2798 case CSSPropertyFill:
2799 case CSSPropertyFillOpacity:
2800 case CSSPropertyFillRule:
2801 case CSSPropertyMarker:
2802 case CSSPropertyMarkerEnd:
2803 case CSSPropertyMarkerMid:
2804 case CSSPropertyMarkerStart:
2805 case CSSPropertyMaskType:
2806 case CSSPropertyShapeRendering:
2807 case CSSPropertyStroke:
2808 case CSSPropertyStrokeDasharray:
2809 case CSSPropertyStrokeDashoffset:
2810 case CSSPropertyStrokeLinecap:
2811 case CSSPropertyStrokeLinejoin:
2812 case CSSPropertyStrokeMiterlimit:
2813 case CSSPropertyStrokeOpacity:
2814 case CSSPropertyStrokeWidth:
2815 case CSSPropertyAlignmentBaseline:
2816 case CSSPropertyBaselineShift:
2817 case CSSPropertyDominantBaseline:
2818 case CSSPropertyGlyphOrientationHorizontal:
2819 case CSSPropertyGlyphOrientationVertical:
2820 case CSSPropertyKerning:
2821 case CSSPropertyTextAnchor:
2822 case CSSPropertyVectorEffect:
2823 case CSSPropertyWritingMode:
2824 case CSSPropertyWebkitSvgShadow:
2825 return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002826 }
2827
2828 logUnimplementedPropertyID(propertyID);
2829 return 0;
2830}
2831
2832String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
2833{
2834 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2835 if (value)
2836 return value->cssText();
2837 return "";
2838}
2839
2840
2841unsigned CSSComputedStyleDeclaration::length() const
2842{
2843 Node* node = m_node.get();
2844 if (!node)
2845 return 0;
2846
2847 RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
2848 if (!style)
2849 return 0;
2850
2851 return computableProperties().size();
2852}
2853
2854String CSSComputedStyleDeclaration::item(unsigned i) const
2855{
2856 if (i >= length())
2857 return "";
2858
2859 return getPropertyNameString(computableProperties()[i]);
2860}
2861
2862bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
2863{
2864 if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() && m_node) {
2865 m_node->document()->updateLayoutIgnorePendingStylesheets();
2866 RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
2867 if (style && style->fontDescription().keywordSize()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002868 CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
Torne (Richard Coles)e5249552013-05-15 11:35:13 +01002869 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(propertyValue);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002870 if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002871 return true;
2872 }
2873 }
2874 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2875 return value && propertyValue && value->equals(*propertyValue);
2876}
2877
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002878PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002879{
2880 return copyPropertiesInSet(computableProperties());
2881}
2882
2883PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) const
2884{
2885 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2886 for (size_t i = 0; i < shorthand.length(); ++i) {
2887 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
2888 list->append(value);
2889 }
2890 return list.release();
2891}
2892
2893PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand& shorthand) const
2894{
2895 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2896 // Assume the properties are in the usual order top, right, bottom, left.
2897 RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
2898 RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
2899 RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
2900 RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
2901
2902 // All 4 properties must be specified.
2903 if (!topValue || !rightValue || !bottomValue || !leftValue)
2904 return 0;
2905
2906 bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
2907 bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
2908 bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;
2909
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002910 list->append(topValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002911 if (showRight)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002912 list->append(rightValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002913 if (showBottom)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002914 list->append(bottomValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002915 if (showLeft)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002916 list->append(leftValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002917
2918 return list.release();
2919}
2920
2921PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) const
2922{
2923 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
2924 for (size_t i = 0; i < shorthand.length(); ++i) {
2925 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002926 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002927 }
2928 return list.release();
2929}
2930
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002931PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002932{
2933 Vector<CSSProperty, 256> list;
2934 list.reserveInitialCapacity(properties.size());
2935 for (unsigned i = 0; i < properties.size(); ++i) {
2936 RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
2937 if (value)
2938 list.append(CSSProperty(properties[i], value.release(), false));
2939 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002940 return MutableStylePropertySet::create(list.data(), list.size());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002941}
2942
2943void CSSComputedStyleDeclaration::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
2944{
2945 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
2946 info.addMember(m_node, "node");
2947}
2948
2949CSSRule* CSSComputedStyleDeclaration::parentRule() const
2950{
2951 return 0;
2952}
2953
2954PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
2955{
2956 CSSPropertyID propertyID = cssPropertyID(propertyName);
2957 if (!propertyID)
2958 return 0;
2959 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2960 return value ? value->cloneForCSSOM() : 0;
2961}
2962
2963String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
2964{
2965 CSSPropertyID propertyID = cssPropertyID(propertyName);
2966 if (!propertyID)
2967 return String();
2968 return getPropertyValue(propertyID);
2969}
2970
2971String CSSComputedStyleDeclaration::getPropertyPriority(const String&)
2972{
2973 // All computed styles have a priority of not "important".
2974 return "";
2975}
2976
2977String CSSComputedStyleDeclaration::getPropertyShorthand(const String&)
2978{
2979 return "";
2980}
2981
2982bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
2983{
2984 return false;
2985}
2986
2987void CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&, ExceptionCode& ec)
2988{
Ben Murdoche69819b2013-07-17 14:56:49 +01002989 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002990}
2991
2992String CSSComputedStyleDeclaration::removeProperty(const String&, ExceptionCode& ec)
2993{
Ben Murdoche69819b2013-07-17 14:56:49 +01002994 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002995 return String();
2996}
2997
2998PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
2999{
3000 return getPropertyCSSValue(propertyID);
3001}
3002
3003String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
3004{
3005 return getPropertyValue(propertyID);
3006}
3007
3008void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool, ExceptionCode& ec)
3009{
Ben Murdoche69819b2013-07-17 14:56:49 +01003010 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003011}
3012
3013PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getBackgroundShorthandValue() const
3014{
3015 static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage,
3016 CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment,
3017 CSSPropertyBackgroundPosition };
3018 static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin,
3019 CSSPropertyBackgroundClip };
3020
3021 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01003022 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator))));
3023 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator))));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003024 return list.release();
3025}
3026
3027} // namespace WebCore