blob: 9007ea3fcf2486b08bf4a6f9c98ecd52e85d4297 [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"
Ben Murdoch7757ec22013-07-23 11:17:36 +010030#include "StylePropertyShorthand.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010031#include "core/css/BasicShapeFunctions.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010032#include "core/css/CSSArrayFunctionValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010033#include "core/css/CSSAspectRatioValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010034#include "core/css/CSSBorderImage.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010035#include "core/css/CSSFilterValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010036#include "core/css/CSSFunctionValue.h"
37#include "core/css/CSSLineBoxContainValue.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010038#include "core/css/CSSMixFunctionValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010039#include "core/css/CSSParser.h"
40#include "core/css/CSSPrimitiveValue.h"
41#include "core/css/CSSPrimitiveValueMappings.h"
42#include "core/css/CSSReflectValue.h"
43#include "core/css/CSSSelector.h"
44#include "core/css/CSSTimingFunctionValue.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010045#include "core/css/CSSTransformValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010046#include "core/css/CSSValueList.h"
47#include "core/css/CSSValuePool.h"
48#include "core/css/FontFeatureValue.h"
49#include "core/css/FontValue.h"
50#include "core/css/Pair.h"
51#include "core/css/Rect.h"
52#include "core/css/ShadowValue.h"
53#include "core/css/StylePropertySet.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"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010058#include "core/page/RuntimeCSSEnabled.h"
59#include "core/page/animation/AnimationController.h"
60#include "core/platform/graphics/FontFeatureSettings.h"
61#include "core/rendering/RenderBox.h"
62#include "core/rendering/RenderView.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010063#include "core/rendering/style/ContentData.h"
64#include "core/rendering/style/CounterContent.h"
65#include "core/rendering/style/CursorList.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010066#include "core/rendering/style/RenderStyle.h"
Ben Murdoch591b9582013-07-10 11:41:44 +010067#include "core/rendering/style/ShapeValue.h"
68#include "wtf/text/StringBuilder.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010069
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010070#include "core/platform/graphics/filters/custom/CustomFilterArrayParameter.h"
71#include "core/platform/graphics/filters/custom/CustomFilterNumberParameter.h"
72#include "core/platform/graphics/filters/custom/CustomFilterOperation.h"
73#include "core/platform/graphics/filters/custom/CustomFilterParameter.h"
74#include "core/platform/graphics/filters/custom/CustomFilterTransformParameter.h"
75
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010076#include "core/rendering/style/StyleCustomFilterProgram.h"
77
78namespace WebCore {
79
80// List of all properties we know how to compute, omitting shorthands.
81// NOTE: Do not use this list, use computableProperties() instead
82// to respect runtime enabling of CSS properties.
83static const CSSPropertyID staticComputableProperties[] = {
84 CSSPropertyBackgroundAttachment,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010085 CSSPropertyBackgroundBlendMode,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010086 CSSPropertyBackgroundClip,
87 CSSPropertyBackgroundColor,
88 CSSPropertyBackgroundImage,
89 CSSPropertyBackgroundOrigin,
90 CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
91 CSSPropertyBackgroundRepeat,
92 CSSPropertyBackgroundSize,
93 CSSPropertyBorderBottomColor,
94 CSSPropertyBorderBottomLeftRadius,
95 CSSPropertyBorderBottomRightRadius,
96 CSSPropertyBorderBottomStyle,
97 CSSPropertyBorderBottomWidth,
98 CSSPropertyBorderCollapse,
99 CSSPropertyBorderImageOutset,
100 CSSPropertyBorderImageRepeat,
101 CSSPropertyBorderImageSlice,
102 CSSPropertyBorderImageSource,
103 CSSPropertyBorderImageWidth,
104 CSSPropertyBorderLeftColor,
105 CSSPropertyBorderLeftStyle,
106 CSSPropertyBorderLeftWidth,
107 CSSPropertyBorderRightColor,
108 CSSPropertyBorderRightStyle,
109 CSSPropertyBorderRightWidth,
110 CSSPropertyBorderTopColor,
111 CSSPropertyBorderTopLeftRadius,
112 CSSPropertyBorderTopRightRadius,
113 CSSPropertyBorderTopStyle,
114 CSSPropertyBorderTopWidth,
115 CSSPropertyBottom,
116 CSSPropertyBoxShadow,
117 CSSPropertyBoxSizing,
118 CSSPropertyCaptionSide,
119 CSSPropertyClear,
120 CSSPropertyClip,
121 CSSPropertyColor,
122 CSSPropertyCursor,
123 CSSPropertyDirection,
124 CSSPropertyDisplay,
125 CSSPropertyEmptyCells,
126 CSSPropertyFloat,
127 CSSPropertyFontFamily,
128 CSSPropertyFontSize,
129 CSSPropertyFontStyle,
130 CSSPropertyFontVariant,
131 CSSPropertyFontWeight,
132 CSSPropertyHeight,
133 CSSPropertyImageRendering,
134 CSSPropertyLeft,
135 CSSPropertyLetterSpacing,
136 CSSPropertyLineHeight,
137 CSSPropertyListStyleImage,
138 CSSPropertyListStylePosition,
139 CSSPropertyListStyleType,
140 CSSPropertyMarginBottom,
141 CSSPropertyMarginLeft,
142 CSSPropertyMarginRight,
143 CSSPropertyMarginTop,
144 CSSPropertyMaxHeight,
145 CSSPropertyMaxWidth,
146 CSSPropertyMinHeight,
147 CSSPropertyMinWidth,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100148 CSSPropertyMixBlendMode,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100149 CSSPropertyOpacity,
150 CSSPropertyOrphans,
151 CSSPropertyOutlineColor,
152 CSSPropertyOutlineOffset,
153 CSSPropertyOutlineStyle,
154 CSSPropertyOutlineWidth,
155 CSSPropertyOverflowWrap,
156 CSSPropertyOverflowX,
157 CSSPropertyOverflowY,
158 CSSPropertyPaddingBottom,
159 CSSPropertyPaddingLeft,
160 CSSPropertyPaddingRight,
161 CSSPropertyPaddingTop,
162 CSSPropertyPageBreakAfter,
163 CSSPropertyPageBreakBefore,
164 CSSPropertyPageBreakInside,
165 CSSPropertyPointerEvents,
166 CSSPropertyPosition,
167 CSSPropertyResize,
168 CSSPropertyRight,
169 CSSPropertySpeak,
170 CSSPropertyTableLayout,
171 CSSPropertyTabSize,
172 CSSPropertyTextAlign,
Ben Murdoche69819b2013-07-17 14:56:49 +0100173 CSSPropertyTextAlignLast,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100174 CSSPropertyTextDecoration,
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100175 CSSPropertyTextDecorationLine,
176 CSSPropertyTextDecorationStyle,
177 CSSPropertyTextDecorationColor,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100178#if ENABLE(CSS3_TEXT)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100179 CSSPropertyWebkitTextUnderlinePosition,
180#endif // CSS3_TEXT
181 CSSPropertyTextIndent,
182 CSSPropertyTextRendering,
183 CSSPropertyTextShadow,
184 CSSPropertyTextOverflow,
185 CSSPropertyTextTransform,
186 CSSPropertyTop,
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100187 CSSPropertyTouchAction,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100188 CSSPropertyTransitionDelay,
189 CSSPropertyTransitionDuration,
190 CSSPropertyTransitionProperty,
191 CSSPropertyTransitionTimingFunction,
192 CSSPropertyUnicodeBidi,
193 CSSPropertyVerticalAlign,
194 CSSPropertyVisibility,
195 CSSPropertyWhiteSpace,
196 CSSPropertyWidows,
197 CSSPropertyWidth,
198 CSSPropertyWordBreak,
199 CSSPropertyWordSpacing,
200 CSSPropertyWordWrap,
201 CSSPropertyZIndex,
202 CSSPropertyZoom,
203
204 CSSPropertyWebkitAnimationDelay,
205 CSSPropertyWebkitAnimationDirection,
206 CSSPropertyWebkitAnimationDuration,
207 CSSPropertyWebkitAnimationFillMode,
208 CSSPropertyWebkitAnimationIterationCount,
209 CSSPropertyWebkitAnimationName,
210 CSSPropertyWebkitAnimationPlayState,
211 CSSPropertyWebkitAnimationTimingFunction,
212 CSSPropertyWebkitAppearance,
213 CSSPropertyWebkitBackfaceVisibility,
214 CSSPropertyWebkitBackgroundClip,
215 CSSPropertyWebkitBackgroundComposite,
216 CSSPropertyWebkitBackgroundOrigin,
217 CSSPropertyWebkitBackgroundSize,
218 CSSPropertyWebkitBorderFit,
219 CSSPropertyWebkitBorderHorizontalSpacing,
220 CSSPropertyWebkitBorderImage,
221 CSSPropertyWebkitBorderVerticalSpacing,
222 CSSPropertyWebkitBoxAlign,
223 CSSPropertyWebkitBoxDecorationBreak,
224 CSSPropertyWebkitBoxDirection,
225 CSSPropertyWebkitBoxFlex,
226 CSSPropertyWebkitBoxFlexGroup,
227 CSSPropertyWebkitBoxLines,
228 CSSPropertyWebkitBoxOrdinalGroup,
229 CSSPropertyWebkitBoxOrient,
230 CSSPropertyWebkitBoxPack,
231 CSSPropertyWebkitBoxReflect,
232 CSSPropertyWebkitBoxShadow,
233 CSSPropertyWebkitClipPath,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100234 CSSPropertyWebkitColumnBreakAfter,
235 CSSPropertyWebkitColumnBreakBefore,
236 CSSPropertyWebkitColumnBreakInside,
237 CSSPropertyWebkitColumnAxis,
238 CSSPropertyWebkitColumnCount,
239 CSSPropertyWebkitColumnGap,
240 CSSPropertyWebkitColumnProgression,
241 CSSPropertyWebkitColumnRuleColor,
242 CSSPropertyWebkitColumnRuleStyle,
243 CSSPropertyWebkitColumnRuleWidth,
244 CSSPropertyWebkitColumnSpan,
245 CSSPropertyWebkitColumnWidth,
246 CSSPropertyWebkitFilter,
Ben Murdoch591b9582013-07-10 11:41:44 +0100247 CSSPropertyAlignContent,
248 CSSPropertyAlignItems,
249 CSSPropertyAlignSelf,
250 CSSPropertyFlexBasis,
251 CSSPropertyFlexGrow,
252 CSSPropertyFlexShrink,
253 CSSPropertyFlexDirection,
254 CSSPropertyFlexWrap,
255 CSSPropertyJustifyContent,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100256 CSSPropertyWebkitFontKerning,
257 CSSPropertyWebkitFontSmoothing,
258 CSSPropertyWebkitFontVariantLigatures,
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100259 CSSPropertyGridAutoColumns,
260 CSSPropertyGridAutoFlow,
261 CSSPropertyGridAutoRows,
Ben Murdoch591b9582013-07-10 11:41:44 +0100262 CSSPropertyGridColumnEnd,
263 CSSPropertyGridColumnStart,
264 CSSPropertyGridDefinitionColumns,
265 CSSPropertyGridDefinitionRows,
266 CSSPropertyGridRowEnd,
267 CSSPropertyGridRowStart,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100268 CSSPropertyWebkitHighlight,
269 CSSPropertyWebkitHyphenateCharacter,
270 CSSPropertyWebkitHyphenateLimitAfter,
271 CSSPropertyWebkitHyphenateLimitBefore,
272 CSSPropertyWebkitHyphenateLimitLines,
273 CSSPropertyWebkitHyphens,
274 CSSPropertyWebkitLineAlign,
275 CSSPropertyWebkitLineBoxContain,
276 CSSPropertyWebkitLineBreak,
277 CSSPropertyWebkitLineClamp,
278 CSSPropertyWebkitLineGrid,
279 CSSPropertyWebkitLineSnap,
280 CSSPropertyWebkitLocale,
281 CSSPropertyWebkitMarginBeforeCollapse,
282 CSSPropertyWebkitMarginAfterCollapse,
283 CSSPropertyWebkitMarqueeDirection,
284 CSSPropertyWebkitMarqueeIncrement,
285 CSSPropertyWebkitMarqueeRepetition,
286 CSSPropertyWebkitMarqueeStyle,
287 CSSPropertyWebkitMaskBoxImage,
288 CSSPropertyWebkitMaskBoxImageOutset,
289 CSSPropertyWebkitMaskBoxImageRepeat,
290 CSSPropertyWebkitMaskBoxImageSlice,
291 CSSPropertyWebkitMaskBoxImageSource,
292 CSSPropertyWebkitMaskBoxImageWidth,
293 CSSPropertyWebkitMaskClip,
294 CSSPropertyWebkitMaskComposite,
295 CSSPropertyWebkitMaskImage,
296 CSSPropertyWebkitMaskOrigin,
297 CSSPropertyWebkitMaskPosition,
298 CSSPropertyWebkitMaskRepeat,
299 CSSPropertyWebkitMaskSize,
Ben Murdoch591b9582013-07-10 11:41:44 +0100300 CSSPropertyOrder,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100301 CSSPropertyWebkitPerspective,
302 CSSPropertyWebkitPerspectiveOrigin,
303 CSSPropertyWebkitPrintColorAdjust,
304 CSSPropertyWebkitRtlOrdering,
305 CSSPropertyWebkitShapeInside,
306 CSSPropertyWebkitShapeOutside,
307 CSSPropertyWebkitTapHighlightColor,
308 CSSPropertyWebkitTextCombine,
309 CSSPropertyWebkitTextDecorationsInEffect,
310 CSSPropertyWebkitTextEmphasisColor,
311 CSSPropertyWebkitTextEmphasisPosition,
312 CSSPropertyWebkitTextEmphasisStyle,
313 CSSPropertyWebkitTextFillColor,
314 CSSPropertyWebkitTextOrientation,
315 CSSPropertyWebkitTextSecurity,
316 CSSPropertyWebkitTextStrokeColor,
317 CSSPropertyWebkitTextStrokeWidth,
318 CSSPropertyWebkitTransform,
319 CSSPropertyWebkitTransformOrigin,
320 CSSPropertyWebkitTransformStyle,
321 CSSPropertyWebkitTransitionDelay,
322 CSSPropertyWebkitTransitionDuration,
323 CSSPropertyWebkitTransitionProperty,
324 CSSPropertyWebkitTransitionTimingFunction,
325 CSSPropertyWebkitUserDrag,
326 CSSPropertyWebkitUserModify,
327 CSSPropertyWebkitUserSelect,
328 CSSPropertyWebkitWritingMode,
329 CSSPropertyWebkitFlowInto,
330 CSSPropertyWebkitFlowFrom,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100331 CSSPropertyWebkitRegionBreakAfter,
332 CSSPropertyWebkitRegionBreakBefore,
333 CSSPropertyWebkitRegionBreakInside,
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100334 CSSPropertyWebkitRegionFragment,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100335 CSSPropertyWebkitAppRegion,
336 CSSPropertyWebkitWrapFlow,
337 CSSPropertyWebkitShapeMargin,
338 CSSPropertyWebkitShapePadding,
339 CSSPropertyWebkitWrapThrough,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100340 CSSPropertyBufferedRendering,
341 CSSPropertyClipPath,
342 CSSPropertyClipRule,
343 CSSPropertyMask,
344 CSSPropertyFilter,
345 CSSPropertyFloodColor,
346 CSSPropertyFloodOpacity,
347 CSSPropertyLightingColor,
348 CSSPropertyStopColor,
349 CSSPropertyStopOpacity,
350 CSSPropertyColorInterpolation,
351 CSSPropertyColorInterpolationFilters,
352 CSSPropertyColorRendering,
353 CSSPropertyFill,
354 CSSPropertyFillOpacity,
355 CSSPropertyFillRule,
356 CSSPropertyMarkerEnd,
357 CSSPropertyMarkerMid,
358 CSSPropertyMarkerStart,
359 CSSPropertyMaskType,
360 CSSPropertyShapeRendering,
361 CSSPropertyStroke,
362 CSSPropertyStrokeDasharray,
363 CSSPropertyStrokeDashoffset,
364 CSSPropertyStrokeLinecap,
365 CSSPropertyStrokeLinejoin,
366 CSSPropertyStrokeMiterlimit,
367 CSSPropertyStrokeOpacity,
368 CSSPropertyStrokeWidth,
369 CSSPropertyAlignmentBaseline,
370 CSSPropertyBaselineShift,
371 CSSPropertyDominantBaseline,
372 CSSPropertyKerning,
373 CSSPropertyTextAnchor,
374 CSSPropertyWritingMode,
375 CSSPropertyGlyphOrientationHorizontal,
376 CSSPropertyGlyphOrientationVertical,
377 CSSPropertyWebkitSvgShadow,
378 CSSPropertyVectorEffect
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100379};
380
381static const Vector<CSSPropertyID>& computableProperties()
382{
383 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
384 if (properties.isEmpty())
385 RuntimeCSSEnabled::filterEnabledCSSPropertiesIntoVector(staticComputableProperties, WTF_ARRAY_LENGTH(staticComputableProperties), properties);
386 return properties;
387}
388
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100389static CSSValueID valueForRepeatRule(int rule)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100390{
391 switch (rule) {
392 case RepeatImageRule:
393 return CSSValueRepeat;
394 case RoundImageRule:
395 return CSSValueRound;
396 case SpaceImageRule:
397 return CSSValueSpace;
398 default:
399 return CSSValueStretch;
400 }
401}
402
403static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
404{
405 // Create the slices.
406 RefPtr<CSSPrimitiveValue> top;
407 RefPtr<CSSPrimitiveValue> right;
408 RefPtr<CSSPrimitiveValue> bottom;
409 RefPtr<CSSPrimitiveValue> left;
410
411 if (image.imageSlices().top().isPercent())
412 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
413 else
414 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
415
416 if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top()
417 && image.imageSlices().left() == image.imageSlices().top()) {
418 right = top;
419 bottom = top;
420 left = top;
421 } else {
422 if (image.imageSlices().right().isPercent())
423 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
424 else
425 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
426
427 if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) {
428 bottom = top;
429 left = right;
430 } else {
431 if (image.imageSlices().bottom().isPercent())
432 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
433 else
434 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
435
436 if (image.imageSlices().left() == image.imageSlices().right())
437 left = right;
438 else {
439 if (image.imageSlices().left().isPercent())
440 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
441 else
442 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
443 }
444 }
445 }
446
447 RefPtr<Quad> quad = Quad::create();
448 quad->setTop(top);
449 quad->setRight(right);
450 quad->setBottom(bottom);
451 quad->setLeft(left);
452
453 return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill());
454}
455
456static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
457{
458 // Create the slices.
459 RefPtr<CSSPrimitiveValue> top;
460 RefPtr<CSSPrimitiveValue> right;
461 RefPtr<CSSPrimitiveValue> bottom;
462 RefPtr<CSSPrimitiveValue> left;
463
464 if (box.top().isRelative())
465 top = cssValuePool().createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER);
466 else
467 top = cssValuePool().createValue(box.top());
468
469 if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
470 right = top;
471 bottom = top;
472 left = top;
473 } else {
474 if (box.right().isRelative())
475 right = cssValuePool().createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER);
476 else
477 right = cssValuePool().createValue(box.right());
478
479 if (box.bottom() == box.top() && box.right() == box.left()) {
480 bottom = top;
481 left = right;
482 } else {
483 if (box.bottom().isRelative())
484 bottom = cssValuePool().createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
485 else
486 bottom = cssValuePool().createValue(box.bottom());
487
488 if (box.left() == box.right())
489 left = right;
490 else {
491 if (box.left().isRelative())
492 left = cssValuePool().createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER);
493 else
494 left = cssValuePool().createValue(box.left());
495 }
496 }
497 }
498
499 RefPtr<Quad> quad = Quad::create();
500 quad->setTop(top);
501 quad->setRight(right);
502 quad->setBottom(bottom);
503 quad->setLeft(left);
504
505 return cssValuePool().createValue(quad.release());
506}
507
508static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
509{
510 RefPtr<CSSPrimitiveValue> horizontalRepeat;
511 RefPtr<CSSPrimitiveValue> verticalRepeat;
512
513 horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
514 if (image.horizontalRule() == image.verticalRule())
515 verticalRepeat = horizontalRepeat;
516 else
517 verticalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.verticalRule()));
518 return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release()));
519}
520
521static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
522{
523 if (!image.hasImage())
524 return cssValuePool().createIdentifierValue(CSSValueNone);
525
526 // Image first.
527 RefPtr<CSSValue> imageValue;
528 if (image.image())
529 imageValue = image.image()->cssValue();
530
531 // Create the image slice.
532 RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
533
534 // Create the border area slices.
535 RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices());
536
537 // Create the border outset.
538 RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset());
539
540 // Create the repeat rules.
541 RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
542
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100543 return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100544}
545
546inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle* style)
547{
548 return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
549}
550
551inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style)
552{
553 return cssValuePool().createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
554}
555
556static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style)
557{
558 if (length.isFixed())
559 return zoomAdjustedPixelValue(length.value(), style);
560 return cssValuePool().createValue(length);
561}
562
563static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style)
564{
565 if (!reflection)
566 return cssValuePool().createIdentifierValue(CSSValueNone);
567
568 RefPtr<CSSPrimitiveValue> offset;
569 if (reflection->offset().isPercent())
570 offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
571 else
572 offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
573
574 RefPtr<CSSPrimitiveValue> direction;
575 switch (reflection->direction()) {
576 case ReflectionBelow:
577 direction = cssValuePool().createIdentifierValue(CSSValueBelow);
578 break;
579 case ReflectionAbove:
580 direction = cssValuePool().createIdentifierValue(CSSValueAbove);
581 break;
582 case ReflectionLeft:
583 direction = cssValuePool().createIdentifierValue(CSSValueLeft);
584 break;
585 case ReflectionRight:
586 direction = cssValuePool().createIdentifierValue(CSSValueRight);
587 break;
588 }
589
590 return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask()));
591}
592
593static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle* style)
594{
595 RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
596 if (layer->isBackgroundOriginSet()) {
597 ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
598 positionList->append(cssValuePool().createValue(layer->backgroundXOrigin()));
599 }
600 positionList->append(zoomAdjustedPixelValueForLength(layer->xPosition(), style));
601 if (layer->isBackgroundOriginSet()) {
602 ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
603 positionList->append(cssValuePool().createValue(layer->backgroundYOrigin()));
604 }
605 positionList->append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
606 return positionList.release();
607}
608
609static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView)
610{
611 if (!style)
612 return 0;
613
614 Length l;
615 switch (propertyID) {
616 case CSSPropertyLeft:
617 l = style->left();
618 break;
619 case CSSPropertyRight:
620 l = style->right();
621 break;
622 case CSSPropertyTop:
623 l = style->top();
624 break;
625 case CSSPropertyBottom:
626 l = style->bottom();
627 break;
628 default:
629 return 0;
630 }
631
632 if (l.isPercent() && renderer && renderer->isBox()) {
633 LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
634 toRenderBox(renderer)->containingBlockLogicalWidthForContent() :
635 toRenderBox(renderer)->containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
636 return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize, 0), style);
Ben Murdoch591b9582013-07-10 11:41:44 +0100637 }
638 if (l.isViewportPercentage())
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100639 return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style);
640 if (l.isAuto()) {
641 // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
642 // In other words if left is auto and right is not auto, then left's computed value is negative right().
643 // So we should get the opposite length unit and see if it is auto.
644 return cssValuePool().createValue(l);
645 }
646
647 return zoomAdjustedPixelValueForLength(l, style);
648}
649
Ben Murdoch83750172013-07-24 10:36:59 +0100650PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const StyleColor& color) const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100651{
652 // This function does NOT look at visited information, so that computed style doesn't expose that.
653 if (!color.isValid())
654 return cssValuePool().createColorValue(style->color().rgb());
655 return cssValuePool().createColorValue(color.rgb());
656}
657
Ben Murdoch83750172013-07-24 10:36:59 +0100658PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(const RenderObject* renderer, const RenderStyle* style, int colorProperty) const
659{
660 Color color;
661 if (renderer) {
662 if (m_allowVisitedStyle)
663 color = renderer->resolveColor(colorProperty);
664 else
665 color = renderer->resolveColor(style->colorIncludingFallback(colorProperty, false /* visited */));
666 } else {
667 if (m_allowVisitedStyle)
668 color = style->visitedDependentColor(colorProperty).color();
669 else
670 color = style->colorIncludingFallback(colorProperty, false /* visited */).color();
671 }
672 return cssValuePool().createColorValue(color.rgb());
673}
674
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100675static PassRefPtr<CSSValueList> getBorderRadiusCornerValues(LengthSize radius, const RenderStyle* style, RenderView* renderView)
676{
677 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
678 if (radius.width().type() == Percent)
679 list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
680 else
681 list->append(zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style));
682 if (radius.height().type() == Percent)
683 list->append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
684 else
685 list->append(zoomAdjustedPixelValue(valueForLength(radius.height(), 0, renderView), style));
686 return list.release();
687}
688
689static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, RenderView* renderView)
690{
691 if (radius.width() == radius.height()) {
692 if (radius.width().type() == Percent)
693 return cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
694 return zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style);
695 }
696 return getBorderRadiusCornerValues(radius, style, renderView);
697}
698
699static PassRefPtr<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* style, RenderView* renderView)
700{
701 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
702 bool showHorizontalBottomLeft = style->borderTopRightRadius().width() != style->borderBottomLeftRadius().width();
703 bool showHorizontalBottomRight = style->borderBottomRightRadius().width() != style->borderTopLeftRadius().width();
704 bool showHorizontalTopRight = style->borderTopRightRadius().width() != style->borderTopLeftRadius().width();
705
706 bool showVerticalBottomLeft = style->borderTopRightRadius().height() != style->borderBottomLeftRadius().height();
707 bool showVerticalBottomRight = (style->borderBottomRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomLeft;
708 bool showVerticalTopRight = (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomRight;
709 bool showVerticalTopLeft = (style->borderTopLeftRadius().width() != style->borderTopLeftRadius().height());
710
711 RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style->borderTopLeftRadius(), style, renderView);
712 RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style->borderTopRightRadius(), style, renderView);
713 RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style->borderBottomRightRadius(), style, renderView);
714 RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style->borderBottomLeftRadius(), style, renderView);
715
716 RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
717 horizontalRadii->append(topLeftRadius->item(0));
718 if (showHorizontalTopRight)
719 horizontalRadii->append(topRightRadius->item(0));
720 if (showHorizontalBottomRight)
721 horizontalRadii->append(bottomRightRadius->item(0));
722 if (showHorizontalBottomLeft)
723 horizontalRadii->append(bottomLeftRadius->item(0));
724
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100725 list->append(horizontalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100726
727 if (showVerticalTopLeft) {
728 RefPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated();
729 verticalRadii->append(topLeftRadius->item(1));
730 if (showVerticalTopRight)
731 verticalRadii->append(topRightRadius->item(1));
732 if (showVerticalBottomRight)
733 verticalRadii->append(bottomRightRadius->item(1));
734 if (showVerticalBottomLeft)
735 verticalRadii->append(bottomLeftRadius->item(1));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100736 list->append(verticalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100737 }
738 return list.release();
739}
740
741static LayoutRect sizingBox(RenderObject* renderer)
742{
743 if (!renderer->isBox())
744 return LayoutRect();
745
746 RenderBox* box = toRenderBox(renderer);
747 return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect();
748}
749
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100750static PassRefPtr<CSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle* style)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100751{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100752 RefPtr<CSSTransformValue> transformValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100753 if (transform.isAffine()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100754 transformValue = CSSTransformValue::create(CSSTransformValue::MatrixTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100755
756 transformValue->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
757 transformValue->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
758 transformValue->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
759 transformValue->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
760 transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
761 transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
762 } else {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100763 transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100764
765 transformValue->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
766 transformValue->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
767 transformValue->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
768 transformValue->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
769
770 transformValue->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
771 transformValue->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
772 transformValue->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
773 transformValue->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
774
775 transformValue->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
776 transformValue->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
777 transformValue->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
778 transformValue->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
779
780 transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
781 transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
782 transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
783 transformValue->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
784 }
785
786 return transformValue.release();
787}
788
789static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style)
790{
791 if (!renderer || !renderer->hasTransform() || !style->hasTransform())
792 return cssValuePool().createIdentifierValue(CSSValueNone);
793
794 IntRect box;
795 if (renderer->isBox())
796 box = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect());
797
798 TransformationMatrix transform;
799 style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
800
801 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
802 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
803 list->append(matrixTransformValue(transform, style));
804
805 return list.release();
806}
807
808static PassRefPtr<CSSValue> valueForCustomFilterArrayParameter(const CustomFilterArrayParameter* arrayParameter)
809{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100810 RefPtr<CSSArrayFunctionValue> arrayParameterValue = CSSArrayFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100811 for (unsigned i = 0, size = arrayParameter->size(); i < size; ++i)
812 arrayParameterValue->append(cssValuePool().createValue(arrayParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
813 return arrayParameterValue.release();
814}
815
816static PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter)
817{
818 RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated();
819 for (unsigned i = 0; i < numberParameter->size(); ++i)
820 numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
821 return numberParameterValue.release();
822}
823
824static PassRefPtr<CSSValue> valueForCustomFilterTransformParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterTransformParameter* transformParameter)
825{
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100826 IntSize size;
827 if (renderer && renderer->isBox())
828 size = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()).size();
829
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100830 TransformationMatrix transform;
831 transformParameter->applyTransform(transform, size);
832 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
833 return matrixTransformValue(transform, style);
834}
835
836static PassRefPtr<CSSValue> valueForCustomFilterParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterParameter* parameter)
837{
838 // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture.
839 ASSERT(parameter);
840 switch (parameter->parameterType()) {
841 case CustomFilterParameter::ARRAY:
842 return valueForCustomFilterArrayParameter(static_cast<const CustomFilterArrayParameter*>(parameter));
843 case CustomFilterParameter::NUMBER:
844 return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter));
845 case CustomFilterParameter::TRANSFORM:
846 return valueForCustomFilterTransformParameter(renderer, style, static_cast<const CustomFilterTransformParameter*>(parameter));
847 }
848
849 ASSERT_NOT_REACHED();
850 return 0;
851}
852
853PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle* style) const
854{
855 if (style->filter().operations().isEmpty())
856 return cssValuePool().createIdentifierValue(CSSValueNone);
857
858 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
859
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100860 RefPtr<CSSFilterValue> filterValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100861
862 Vector<RefPtr<FilterOperation> >::const_iterator end = style->filter().operations().end();
863 for (Vector<RefPtr<FilterOperation> >::const_iterator it = style->filter().operations().begin(); it != end; ++it) {
864 FilterOperation* filterOperation = (*it).get();
865 switch (filterOperation->getOperationType()) {
866 case FilterOperation::REFERENCE: {
867 ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100868 filterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100869 filterValue->append(cssValuePool().createValue(referenceOperation->url(), CSSPrimitiveValue::CSS_STRING));
870 break;
871 }
872 case FilterOperation::GRAYSCALE: {
873 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100874 filterValue = CSSFilterValue::create(CSSFilterValue::GrayscaleFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100875 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
876 break;
877 }
878 case FilterOperation::SEPIA: {
879 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100880 filterValue = CSSFilterValue::create(CSSFilterValue::SepiaFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100881 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
882 break;
883 }
884 case FilterOperation::SATURATE: {
885 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100886 filterValue = CSSFilterValue::create(CSSFilterValue::SaturateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100887 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
888 break;
889 }
890 case FilterOperation::HUE_ROTATE: {
891 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100892 filterValue = CSSFilterValue::create(CSSFilterValue::HueRotateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100893 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_DEG));
894 break;
895 }
896 case FilterOperation::INVERT: {
897 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100898 filterValue = CSSFilterValue::create(CSSFilterValue::InvertFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100899 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
900 break;
901 }
902 case FilterOperation::OPACITY: {
903 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100904 filterValue = CSSFilterValue::create(CSSFilterValue::OpacityFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100905 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
906 break;
907 }
908 case FilterOperation::BRIGHTNESS: {
909 BasicComponentTransferFilterOperation* brightnessOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100910 filterValue = CSSFilterValue::create(CSSFilterValue::BrightnessFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100911 filterValue->append(cssValuePool().createValue(brightnessOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
912 break;
913 }
914 case FilterOperation::CONTRAST: {
915 BasicComponentTransferFilterOperation* contrastOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100916 filterValue = CSSFilterValue::create(CSSFilterValue::ContrastFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100917 filterValue->append(cssValuePool().createValue(contrastOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
918 break;
919 }
920 case FilterOperation::BLUR: {
921 BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100922 filterValue = CSSFilterValue::create(CSSFilterValue::BlurFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100923 filterValue->append(zoomAdjustedPixelValue(blurOperation->stdDeviation().value(), style));
924 break;
925 }
926 case FilterOperation::DROP_SHADOW: {
927 DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100928 filterValue = CSSFilterValue::create(CSSFilterValue::DropShadowFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100929 // 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 +0100930 OwnPtr<ShadowData> shadow = ShadowData::create(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, dropShadowOperation->color());
Ben Murdoch83750172013-07-24 10:36:59 +0100931 filterValue->append(valueForShadow(renderer, shadow.get(), CSSPropertyTextShadow, style));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100932 break;
933 }
934 case FilterOperation::VALIDATED_CUSTOM:
935 // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
936 ASSERT_NOT_REACHED();
937 break;
938 case FilterOperation::CUSTOM: {
939 CustomFilterOperation* customOperation = static_cast<CustomFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100940 filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100941
942 // The output should be verbose, even if the values are the default ones.
943
944 ASSERT(customOperation->program());
945 StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program());
946
947 RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
948 if (program->vertexShader())
949 shadersList->append(program->vertexShader()->cssValue());
950 else
951 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
952
953 const CustomFilterProgramMixSettings mixSettings = program->mixSettings();
954 if (program->fragmentShader()) {
955 if (program->programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100956 RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100957 mixFunction->append(program->fragmentShader()->cssValue());
958 mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
959 mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
960 shadersList->append(mixFunction.release());
961 } else
962 shadersList->append(program->fragmentShader()->cssValue());
963 }
964 else
965 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
966
967 filterValue->append(shadersList.release());
968
969 RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated();
970 meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER));
971 meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
972
973 // FIXME: The specification doesn't have any "attached" identifier. Should we add one?
974 // https://bugs.webkit.org/show_bug.cgi?id=72700
975 if (customOperation->meshType() == MeshTypeDetached)
976 meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached));
977
978 filterValue->append(meshParameters.release());
979
980 const CustomFilterParameterList& parameters = customOperation->parameters();
981 size_t parametersSize = parameters.size();
982 if (!parametersSize)
983 break;
984 RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated();
985 for (size_t i = 0; i < parametersSize; ++i) {
986 const CustomFilterParameter* parameter = parameters.at(i).get();
987 RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated();
988 parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING));
989 parameterCSSNameAndValue->append(valueForCustomFilterParameter(renderer, style, parameter));
990 parametersCSSValue->append(parameterCSSNameAndValue.release());
991 }
992
993 filterValue->append(parametersCSSValue.release());
994 break;
995 }
996 default:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100997 filterValue = CSSFilterValue::create(CSSFilterValue::UnknownFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100998 break;
999 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001000 list->append(filterValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001001 }
1002
1003 return list.release();
1004}
1005
1006static PassRefPtr<CSSValue> valueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle* style, RenderView* renderView)
1007{
1008 if (!trackBreadth.isLength()) {
1009 String flex = String::number(trackBreadth.flex());
1010 flex.append("fr");
1011 return cssValuePool().createValue(flex, CSSPrimitiveValue::CSS_DIMENSION);
1012 }
1013
1014 const Length& trackBreadthLength = trackBreadth.length();
1015 if (trackBreadthLength.isAuto())
1016 return cssValuePool().createIdentifierValue(CSSValueAuto);
1017 if (trackBreadthLength.isViewportPercentage())
1018 return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style);
1019 return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
1020}
1021
1022static PassRefPtr<CSSValue> valueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle* style, RenderView* renderView)
1023{
1024 switch (trackSize.type()) {
1025 case LengthTrackSizing:
1026 return valueForGridTrackBreadth(trackSize.length(), style, renderView);
1027 case MinMaxTrackSizing:
1028 RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1029 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView));
1030 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView));
1031 return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
1032 }
1033 ASSERT_NOT_REACHED();
1034 return 0;
1035}
1036
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001037static void addValuesForNamedGridLinesAtIndex(const NamedGridLinesMap& namedGridLines, size_t i, CSSValueList& list)
1038{
1039 // Note that this won't return the results in the order specified in the style sheet,
1040 // which is probably fine as we stil *do* return all the expected values.
1041 NamedGridLinesMap::const_iterator it = namedGridLines.begin();
1042 NamedGridLinesMap::const_iterator end = namedGridLines.end();
1043 for (; it != end; ++it) {
1044 const Vector<size_t>& linesIndexes = it->value;
1045 for (size_t j = 0; j < linesIndexes.size(); ++j) {
1046 if (linesIndexes[j] != i)
1047 continue;
1048
1049 list.append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1050 break;
1051 }
1052 }
1053}
1054
1055static PassRefPtr<CSSValue> valueForGridTrackList(const Vector<GridTrackSize>& trackSizes, const NamedGridLinesMap& namedGridLines, const RenderStyle* style, RenderView* renderView)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001056{
1057 // Handle the 'none' case here.
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001058 if (!trackSizes.size()) {
1059 ASSERT(namedGridLines.isEmpty());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001060 return cssValuePool().createIdentifierValue(CSSValueNone);
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001061 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001062
1063 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001064 for (size_t i = 0; i < trackSizes.size(); ++i) {
1065 addValuesForNamedGridLinesAtIndex(namedGridLines, i, *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001066 list->append(valueForGridTrackSize(trackSizes[i], style, renderView));
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001067 }
1068 // Those are the trailing <string>* allowed in the syntax.
1069 addValuesForNamedGridLinesAtIndex(namedGridLines, trackSizes.size(), *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001070 return list.release();
1071}
1072
1073static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
1074{
1075 if (position.isAuto())
1076 return cssValuePool().createIdentifierValue(CSSValueAuto);
1077
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001078 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001079 if (position.isSpan()) {
1080 list->append(cssValuePool().createIdentifierValue(CSSValueSpan));
1081 list->append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1082 } else
1083 list->append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1084
1085 if (!position.namedGridLine().isNull())
1086 list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001087 return list;
1088}
1089static PassRefPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation)
1090{
1091 RefPtr<CSSValue> propertyValue;
1092 if (animation->animationMode() == CSSAnimationData::AnimateNone)
1093 propertyValue = cssValuePool().createIdentifierValue(CSSValueNone);
1094 else if (animation->animationMode() == CSSAnimationData::AnimateAll)
1095 propertyValue = cssValuePool().createIdentifierValue(CSSValueAll);
1096 else
1097 propertyValue = cssValuePool().createValue(getPropertyNameString(animation->property()), CSSPrimitiveValue::CSS_STRING);
1098 return propertyValue.release();
1099}
1100static PassRefPtr<CSSValue> getTransitionPropertyValue(const CSSAnimationDataList* animList)
1101{
1102 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1103 if (animList) {
1104 for (size_t i = 0; i < animList->size(); ++i)
1105 list->append(createTransitionPropertyValue(animList->animation(i)));
1106 } else
1107 list->append(cssValuePool().createIdentifierValue(CSSValueAll));
1108 return list.release();
1109}
1110
1111static PassRefPtr<CSSValue> getDelayValue(const CSSAnimationDataList* animList)
1112{
1113 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1114 if (animList) {
1115 for (size_t i = 0; i < animList->size(); ++i)
1116 list->append(cssValuePool().createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
1117 } else {
1118 // Note that initialAnimationDelay() is used for both transitions and animations
1119 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
1120 }
1121 return list.release();
1122}
1123
1124static PassRefPtr<CSSValue> getDurationValue(const CSSAnimationDataList* animList)
1125{
1126 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1127 if (animList) {
1128 for (size_t i = 0; i < animList->size(); ++i)
1129 list->append(cssValuePool().createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
1130 } else {
1131 // Note that initialAnimationDuration() is used for both transitions and animations
1132 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
1133 }
1134 return list.release();
1135}
1136
1137static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1138{
1139 if (timingFunction->isCubicBezierTimingFunction()) {
1140 const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
1141 if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1142 CSSValueID valueId = CSSValueInvalid;
1143 switch (bezierTimingFunction->timingFunctionPreset()) {
1144 case CubicBezierTimingFunction::Ease:
1145 valueId = CSSValueEase;
1146 break;
1147 case CubicBezierTimingFunction::EaseIn:
1148 valueId = CSSValueEaseIn;
1149 break;
1150 case CubicBezierTimingFunction::EaseOut:
1151 valueId = CSSValueEaseOut;
1152 break;
1153 case CubicBezierTimingFunction::EaseInOut:
1154 valueId = CSSValueEaseInOut;
1155 break;
1156 default:
1157 ASSERT_NOT_REACHED();
1158 return 0;
1159 }
1160 return cssValuePool().createIdentifierValue(valueId);
1161 }
1162 return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
1163 }
1164
1165 if (timingFunction->isStepsTimingFunction()) {
1166 const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
1167 return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
1168 }
1169
1170 return CSSLinearTimingFunctionValue::create();
1171}
1172
1173static PassRefPtr<CSSValue> getTimingFunctionValue(const CSSAnimationDataList* animList)
1174{
1175 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1176 if (animList) {
1177 for (size_t i = 0; i < animList->size(); ++i)
1178 list->append(createTimingFunctionValue(animList->animation(i)->timingFunction().get()));
1179 } else
1180 // Note that initialAnimationTimingFunction() is used for both transitions and animations
1181 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
1182 return list.release();
1183}
1184
1185static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1186{
1187 if (!lineBoxContain)
1188 return cssValuePool().createIdentifierValue(CSSValueNone);
1189 return CSSLineBoxContainValue::create(lineBoxContain);
1190}
1191
1192CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1193 : m_node(n)
1194 , m_allowVisitedStyle(allowVisitedStyle)
1195 , m_refCount(1)
1196{
1197 unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1198 m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
1199 AtomicString(pseudoElementName.substring(nameWithoutColonsStart))));
1200}
1201
1202CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1203{
1204}
1205
1206void CSSComputedStyleDeclaration::ref()
1207{
1208 ++m_refCount;
1209}
1210
1211void CSSComputedStyleDeclaration::deref()
1212{
1213 ASSERT(m_refCount);
1214 if (!--m_refCount)
1215 delete this;
1216}
1217
1218String CSSComputedStyleDeclaration::cssText() const
1219{
1220 StringBuilder result;
1221 const Vector<CSSPropertyID>& properties = computableProperties();
1222
1223 for (unsigned i = 0; i < properties.size(); i++) {
1224 if (i)
1225 result.append(' ');
1226 result.append(getPropertyName(properties[i]));
1227 result.append(": ", 2);
1228 result.append(getPropertyValue(properties[i]));
1229 result.append(';');
1230 }
1231
1232 return result.toString();
1233}
1234
1235void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
1236{
Ben Murdoche69819b2013-07-17 14:56:49 +01001237 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001238}
1239
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001240static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001241{
1242 ASSERT_ARG(keywordSize, keywordSize);
1243 ASSERT_ARG(keywordSize, keywordSize <= 8);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001244 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001245}
1246
1247PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
1248{
1249 if (!m_node)
1250 return 0;
1251
1252 m_node->document()->updateLayoutIgnorePendingStylesheets();
1253
1254 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1255 if (!style)
1256 return 0;
1257
1258 if (int keywordSize = style->fontDescription().keywordSize())
1259 return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
1260
1261
1262 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get());
1263}
1264
1265bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
1266{
1267 if (!m_node)
1268 return false;
1269
1270 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1271 if (!style)
1272 return false;
1273
1274 return style->fontDescription().useFixedDefaultSize();
1275}
1276
Ben Murdoch83750172013-07-24 10:36:59 +01001277PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const RenderObject* renderer, const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle* style) const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001278{
1279 if (!shadow)
1280 return cssValuePool().createIdentifierValue(CSSValueNone);
1281
1282 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1283 for (const ShadowData* s = shadow; s; s = s->next()) {
1284 RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style);
1285 RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style);
1286 RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style);
1287 RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : zoomAdjustedPixelValue(s->spread(), style);
1288 RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset);
Ben Murdoch83750172013-07-24 10:36:59 +01001289 RefPtr<CSSPrimitiveValue> color = cssValuePool().createColorValue(renderer ? renderer->resolveColor(s->color()).rgb() : s->color().rgb());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001290 list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
1291 }
1292 return list.release();
1293}
1294
1295PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const
1296{
1297 return getPropertyCSSValue(propertyID, UpdateLayout);
1298}
1299
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001300static CSSValueID identifierForFamily(const AtomicString& family)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001301{
1302 if (family == cursiveFamily)
1303 return CSSValueCursive;
1304 if (family == fantasyFamily)
1305 return CSSValueFantasy;
1306 if (family == monospaceFamily)
1307 return CSSValueMonospace;
1308 if (family == pictographFamily)
1309 return CSSValueWebkitPictograph;
1310 if (family == sansSerifFamily)
1311 return CSSValueSansSerif;
1312 if (family == serifFamily)
1313 return CSSValueSerif;
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001314 return CSSValueInvalid;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001315}
1316
1317static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1318{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001319 if (CSSValueID familyIdentifier = identifierForFamily(family))
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001320 return cssValuePool().createIdentifierValue(familyIdentifier);
1321 return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
1322}
1323
1324static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1325{
1326 // Blink value is ignored.
1327 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001328 if (textDecoration & TextDecorationUnderline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001329 list->append(cssValuePool().createIdentifierValue(CSSValueUnderline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001330 if (textDecoration & TextDecorationOverline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001331 list->append(cssValuePool().createIdentifierValue(CSSValueOverline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001332 if (textDecoration & TextDecorationLineThrough)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001333 list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough));
1334
1335 if (!list->length())
1336 return cssValuePool().createIdentifierValue(CSSValueNone);
Ben Murdoch591b9582013-07-10 11:41:44 +01001337 return list.release();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001338}
1339
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001340static PassRefPtr<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1341{
1342 switch (textDecorationStyle) {
1343 case TextDecorationStyleSolid:
1344 return cssValuePool().createIdentifierValue(CSSValueSolid);
1345 case TextDecorationStyleDouble:
1346 return cssValuePool().createIdentifierValue(CSSValueDouble);
1347 case TextDecorationStyleDotted:
1348 return cssValuePool().createIdentifierValue(CSSValueDotted);
1349 case TextDecorationStyleDashed:
1350 return cssValuePool().createIdentifierValue(CSSValueDashed);
1351 case TextDecorationStyleWavy:
1352 return cssValuePool().createIdentifierValue(CSSValueWavy);
1353 }
1354
1355 ASSERT_NOT_REACHED();
1356 return cssValuePool().createExplicitInitialValue();
1357}
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001358
1359static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1360{
1361 // For backwards compatibility, if both values are equal, just return one of them. And
1362 // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1363 if (xRepeat == yRepeat)
1364 return cssValuePool().createValue(xRepeat);
1365 if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1366 return cssValuePool().createIdentifierValue(CSSValueRepeatX);
1367 if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1368 return cssValuePool().createIdentifierValue(CSSValueRepeatY);
1369
1370 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1371 list->append(cssValuePool().createValue(xRepeat));
1372 list->append(cssValuePool().createValue(yRepeat));
1373 return list.release();
1374}
1375
1376static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style)
1377{
1378 if (fillSize.type == Contain)
1379 return cssValuePool().createIdentifierValue(CSSValueContain);
1380
1381 if (fillSize.type == Cover)
1382 return cssValuePool().createIdentifierValue(CSSValueCover);
1383
1384 if (fillSize.size.height().isAuto())
1385 return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1386
1387 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1388 list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1389 list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1390 return list.release();
1391}
1392
1393static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style)
1394{
1395 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1396 for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1397 if (contentData->isCounter()) {
1398 const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter();
1399 ASSERT(counter);
1400 list->append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1401 } else if (contentData->isImage()) {
1402 const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image();
1403 ASSERT(image);
1404 list->append(image->cssValue());
1405 } else if (contentData->isText())
1406 list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING));
1407 }
1408 if (!style->regionThread().isNull())
1409 list->append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1410 return list.release();
1411}
1412
1413static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1414{
1415 const CounterDirectiveMap* map = style->counterDirectives();
1416 if (!map)
1417 return 0;
1418
1419 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1420 for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1421 list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1422 short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1423 list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1424 }
1425 return list.release();
1426}
1427
1428static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1429{
1430 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ());
1431 if (!propertyIDSet.add(propertyID).isNewEntry)
1432 return;
1433
1434 LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1435}
1436
1437static PassRefPtr<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
1438{
1439 const FontFamily& firstFamily = style->fontDescription().family();
1440 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1441 for (const FontFamily* family = &firstFamily; family; family = family->next())
1442 list->append(valueForFamily(family->family()));
1443 return list.release();
1444}
1445
1446static PassRefPtr<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style, RenderView* renderView)
1447{
1448 Length length = style->lineHeight();
1449 if (length.isNegative())
1450 return cssValuePool().createIdentifierValue(CSSValueNormal);
1451 if (length.isPercent())
1452 // This is imperfect, because it doesn't include the zoom factor and the real computation
1453 // for how high to be in pixels does include things like minimum font size and the zoom factor.
1454 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1455 // that here either.
1456 return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style);
1457 return zoomAdjustedPixelValue(valueForLength(length, 0, renderView), style);
1458}
1459
1460static PassRefPtr<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style)
1461{
1462 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style);
1463}
1464
1465static PassRefPtr<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
1466{
1467 if (style->fontDescription().italic())
1468 return cssValuePool().createIdentifierValue(CSSValueItalic);
1469 return cssValuePool().createIdentifierValue(CSSValueNormal);
1470}
1471
1472static PassRefPtr<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style)
1473{
1474 if (style->fontDescription().smallCaps())
1475 return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
1476 return cssValuePool().createIdentifierValue(CSSValueNormal);
1477}
1478
1479static PassRefPtr<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
1480{
1481 switch (style->fontDescription().weight()) {
1482 case FontWeight100:
1483 return cssValuePool().createIdentifierValue(CSSValue100);
1484 case FontWeight200:
1485 return cssValuePool().createIdentifierValue(CSSValue200);
1486 case FontWeight300:
1487 return cssValuePool().createIdentifierValue(CSSValue300);
1488 case FontWeightNormal:
1489 return cssValuePool().createIdentifierValue(CSSValueNormal);
1490 case FontWeight500:
1491 return cssValuePool().createIdentifierValue(CSSValue500);
1492 case FontWeight600:
1493 return cssValuePool().createIdentifierValue(CSSValue600);
1494 case FontWeightBold:
1495 return cssValuePool().createIdentifierValue(CSSValueBold);
1496 case FontWeight800:
1497 return cssValuePool().createIdentifierValue(CSSValue800);
1498 case FontWeight900:
1499 return cssValuePool().createIdentifierValue(CSSValue900);
1500 }
1501 ASSERT_NOT_REACHED();
1502 return cssValuePool().createIdentifierValue(CSSValueNormal);
1503}
1504
Ben Murdoch591b9582013-07-10 11:41:44 +01001505static bool isLayoutDependent(CSSPropertyID propertyID, PassRefPtr<RenderStyle> style, RenderObject* renderer)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001506{
Ben Murdoch591b9582013-07-10 11:41:44 +01001507 // Some properties only depend on layout in certain conditions which
1508 // are specified in the main switch statement below. So we can avoid
1509 // forcing layout in those conditions. The conditions in this switch
1510 // statement must remain in sync with the conditions in the main switch.
1511 // FIXME: Some of these cases could be narrowed down or optimized better.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001512 switch (propertyID) {
1513 case CSSPropertyBottom:
1514 case CSSPropertyHeight:
1515 case CSSPropertyLeft:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001516 case CSSPropertyRight:
1517 case CSSPropertyTop:
1518 case CSSPropertyWebkitPerspectiveOrigin:
1519 case CSSPropertyWebkitTransform:
1520 case CSSPropertyWebkitTransformOrigin:
1521 case CSSPropertyWidth:
1522 case CSSPropertyWebkitFilter:
1523 return true;
Ben Murdoch591b9582013-07-10 11:41:44 +01001524 case CSSPropertyMargin:
1525 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed() || !style->marginTop().isFixed() || !style->marginLeft().isFixed() || !style->marginRight().isFixed());
1526 case CSSPropertyMarginLeft:
1527 return renderer && renderer->isBox() && (!style || !style->marginLeft().isFixed());
1528 case CSSPropertyMarginRight:
1529 return renderer && renderer->isBox() && (!style || !style->marginRight().isFixed());
1530 case CSSPropertyMarginTop:
1531 return renderer && renderer->isBox() && (!style || !style->marginTop().isFixed());
1532 case CSSPropertyMarginBottom:
1533 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed());
1534 case CSSPropertyPadding:
1535 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed() || !style->paddingTop().isFixed() || !style->paddingLeft().isFixed() || !style->paddingRight().isFixed());
1536 case CSSPropertyPaddingBottom:
1537 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed());
1538 case CSSPropertyPaddingLeft:
1539 return renderer && renderer->isBox() && (!style || !style->paddingLeft().isFixed());
1540 case CSSPropertyPaddingRight:
1541 return renderer && renderer->isBox() && (!style || !style->paddingRight().isFixed());
1542 case CSSPropertyPaddingTop:
1543 return renderer && renderer->isBox() && (!style || !style->paddingTop().isFixed());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001544 default:
1545 return false;
1546 }
1547}
1548
Ben Murdoch591b9582013-07-10 11:41:44 +01001549PassRefPtr<RenderStyle> CSSComputedStyleDeclaration::computeRenderStyle(CSSPropertyID propertyID) const
1550{
1551 Node* styledNode = this->styledNode();
1552 ASSERT(styledNode);
1553 RenderObject* renderer = styledNode->renderer();
Ben Murdoche69819b2013-07-17 14:56:49 +01001554 if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID) && !RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
Ben Murdoch591b9582013-07-10 11:41:44 +01001555 AnimationUpdateBlock animationUpdateBlock(renderer->animation());
1556 if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) {
1557 // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
1558 return renderer->animation()->getAnimatedStyleForRenderer(renderer)->getCachedPseudoStyle(m_pseudoElementSpecifier);
1559 }
1560 return renderer->animation()->getAnimatedStyleForRenderer(renderer);
1561 }
1562 return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
1563}
1564
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001565Node* CSSComputedStyleDeclaration::styledNode() const
1566{
1567 if (!m_node)
1568 return 0;
1569 if (m_node->isElementNode()) {
1570 if (PseudoElement* element = toElement(m_node.get())->pseudoElement(m_pseudoElementSpecifier))
1571 return element;
1572 }
1573 return m_node.get();
1574}
1575
1576PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1577{
1578 Node* styledNode = this->styledNode();
1579 if (!styledNode)
1580 return 0;
Ben Murdoch591b9582013-07-10 11:41:44 +01001581 RenderObject* renderer = styledNode->renderer();
1582 RefPtr<RenderStyle> style;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001583
1584 if (updateLayout) {
1585 Document* document = styledNode->document();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001586
Ben Murdoch591b9582013-07-10 11:41:44 +01001587 document->updateStyleForNodeIfNeeded(styledNode);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001588
1589 // The style recalc could have caused the styled node to be discarded or replaced
1590 // if it was a PseudoElement so we need to update it.
1591 styledNode = this->styledNode();
Ben Murdoch591b9582013-07-10 11:41:44 +01001592 renderer = styledNode->renderer();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001593
Ben Murdoch591b9582013-07-10 11:41:44 +01001594 style = computeRenderStyle(propertyID);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001595
Ben Murdoch591b9582013-07-10 11:41:44 +01001596 bool forceFullLayout = isLayoutDependent(propertyID, style, renderer)
1597 || styledNode->isInShadowTree()
1598 || (document->styleResolverIfExists() && document->styleResolverIfExists()->hasViewportDependentMediaQueries() && document->ownerElement())
1599 || document->seamlessParentIFrame();
1600
1601 if (forceFullLayout) {
1602 document->updateLayoutIgnorePendingStylesheets();
1603 styledNode = this->styledNode();
1604 style = computeRenderStyle(propertyID);
1605 renderer = styledNode->renderer();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001606 }
Ben Murdoch591b9582013-07-10 11:41:44 +01001607 } else {
1608 style = computeRenderStyle(propertyID);
1609 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001610
1611 if (!style)
1612 return 0;
1613
1614 propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
1615
1616 switch (propertyID) {
1617 case CSSPropertyInvalid:
1618 case CSSPropertyVariable:
1619 break;
1620
1621 case CSSPropertyBackgroundColor:
Ben Murdoch83750172013-07-24 10:36:59 +01001622 return cssValuePool().createColorValue(renderer->resolveColor(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor()).rgb());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001623 case CSSPropertyBackgroundImage:
1624 case CSSPropertyWebkitMaskImage: {
1625 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
1626 if (!layers)
1627 return cssValuePool().createIdentifierValue(CSSValueNone);
1628
1629 if (!layers->next()) {
1630 if (layers->image())
1631 return layers->image()->cssValue();
1632
1633 return cssValuePool().createIdentifierValue(CSSValueNone);
1634 }
1635
1636 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1637 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1638 if (currLayer->image())
1639 list->append(currLayer->image()->cssValue());
1640 else
1641 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1642 }
1643 return list.release();
1644 }
1645 case CSSPropertyBackgroundSize:
1646 case CSSPropertyWebkitBackgroundSize:
1647 case CSSPropertyWebkitMaskSize: {
1648 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
1649 if (!layers->next())
1650 return fillSizeToCSSValue(layers->size(), style.get());
1651
1652 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1653 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1654 list->append(fillSizeToCSSValue(currLayer->size(), style.get()));
1655
1656 return list.release();
1657 }
1658 case CSSPropertyBackgroundRepeat:
1659 case CSSPropertyWebkitMaskRepeat: {
1660 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
1661 if (!layers->next())
1662 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
1663
1664 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1665 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1666 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
1667
1668 return list.release();
1669 }
1670 case CSSPropertyWebkitBackgroundComposite:
1671 case CSSPropertyWebkitMaskComposite: {
1672 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
1673 if (!layers->next())
1674 return cssValuePool().createValue(layers->composite());
1675
1676 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1677 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1678 list->append(cssValuePool().createValue(currLayer->composite()));
1679
1680 return list.release();
1681 }
1682 case CSSPropertyBackgroundAttachment: {
1683 const FillLayer* layers = style->backgroundLayers();
1684 if (!layers->next())
1685 return cssValuePool().createValue(layers->attachment());
1686
1687 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1688 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1689 list->append(cssValuePool().createValue(currLayer->attachment()));
1690
1691 return list.release();
1692 }
1693 case CSSPropertyBackgroundClip:
1694 case CSSPropertyBackgroundOrigin:
1695 case CSSPropertyWebkitBackgroundClip:
1696 case CSSPropertyWebkitBackgroundOrigin:
1697 case CSSPropertyWebkitMaskClip:
1698 case CSSPropertyWebkitMaskOrigin: {
1699 const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
1700 bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
1701 if (!layers->next()) {
1702 EFillBox box = isClip ? layers->clip() : layers->origin();
1703 return cssValuePool().createValue(box);
1704 }
1705
1706 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1707 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1708 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
1709 list->append(cssValuePool().createValue(box));
1710 }
1711
1712 return list.release();
1713 }
1714 case CSSPropertyBackgroundPosition:
1715 case CSSPropertyWebkitMaskPosition: {
1716 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
1717 if (!layers->next())
1718 return createPositionListForLayer(propertyID, layers, style.get());
1719
1720 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1721 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1722 list->append(createPositionListForLayer(propertyID, currLayer, style.get()));
1723 return list.release();
1724 }
1725 case CSSPropertyBackgroundPositionX:
1726 case CSSPropertyWebkitMaskPositionX: {
1727 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
1728 if (!layers->next())
1729 return cssValuePool().createValue(layers->xPosition());
1730
1731 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1732 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1733 list->append(cssValuePool().createValue(currLayer->xPosition()));
1734
1735 return list.release();
1736 }
1737 case CSSPropertyBackgroundPositionY:
1738 case CSSPropertyWebkitMaskPositionY: {
1739 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
1740 if (!layers->next())
1741 return cssValuePool().createValue(layers->yPosition());
1742
1743 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1744 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1745 list->append(cssValuePool().createValue(currLayer->yPosition()));
1746
1747 return list.release();
1748 }
1749 case CSSPropertyBorderCollapse:
1750 if (style->borderCollapse())
1751 return cssValuePool().createIdentifierValue(CSSValueCollapse);
1752 return cssValuePool().createIdentifierValue(CSSValueSeparate);
1753 case CSSPropertyBorderSpacing: {
1754 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1755 list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()));
1756 list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()));
1757 return list.release();
1758 }
1759 case CSSPropertyWebkitBorderHorizontalSpacing:
1760 return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get());
1761 case CSSPropertyWebkitBorderVerticalSpacing:
1762 return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get());
1763 case CSSPropertyBorderImageSource:
1764 if (style->borderImageSource())
1765 return style->borderImageSource()->cssValue();
1766 return cssValuePool().createIdentifierValue(CSSValueNone);
1767 case CSSPropertyBorderTopColor:
Ben Murdoch83750172013-07-24 10:36:59 +01001768 return currentColorOrValidColor(renderer, style.get(), CSSPropertyBorderTopColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001769 case CSSPropertyBorderRightColor:
Ben Murdoch83750172013-07-24 10:36:59 +01001770 return currentColorOrValidColor(renderer, style.get(), CSSPropertyBorderRightColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001771 case CSSPropertyBorderBottomColor:
Ben Murdoch83750172013-07-24 10:36:59 +01001772 return currentColorOrValidColor(renderer, style.get(), CSSPropertyBorderBottomColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001773 case CSSPropertyBorderLeftColor:
Ben Murdoch83750172013-07-24 10:36:59 +01001774 return currentColorOrValidColor(renderer, style.get(), CSSPropertyBorderLeftColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001775 case CSSPropertyBorderTopStyle:
1776 return cssValuePool().createValue(style->borderTopStyle());
1777 case CSSPropertyBorderRightStyle:
1778 return cssValuePool().createValue(style->borderRightStyle());
1779 case CSSPropertyBorderBottomStyle:
1780 return cssValuePool().createValue(style->borderBottomStyle());
1781 case CSSPropertyBorderLeftStyle:
1782 return cssValuePool().createValue(style->borderLeftStyle());
1783 case CSSPropertyBorderTopWidth:
1784 return zoomAdjustedPixelValue(style->borderTopWidth(), style.get());
1785 case CSSPropertyBorderRightWidth:
1786 return zoomAdjustedPixelValue(style->borderRightWidth(), style.get());
1787 case CSSPropertyBorderBottomWidth:
1788 return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get());
1789 case CSSPropertyBorderLeftWidth:
1790 return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get());
1791 case CSSPropertyBottom:
1792 return getPositionOffsetValue(style.get(), CSSPropertyBottom, renderer, m_node->document()->renderView());
1793 case CSSPropertyWebkitBoxAlign:
1794 return cssValuePool().createValue(style->boxAlign());
1795 case CSSPropertyWebkitBoxDecorationBreak:
1796 if (style->boxDecorationBreak() == DSLICE)
1797 return cssValuePool().createIdentifierValue(CSSValueSlice);
1798 return cssValuePool().createIdentifierValue(CSSValueClone);
1799 case CSSPropertyWebkitBoxDirection:
1800 return cssValuePool().createValue(style->boxDirection());
1801 case CSSPropertyWebkitBoxFlex:
1802 return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
1803 case CSSPropertyWebkitBoxFlexGroup:
1804 return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
1805 case CSSPropertyWebkitBoxLines:
1806 return cssValuePool().createValue(style->boxLines());
1807 case CSSPropertyWebkitBoxOrdinalGroup:
1808 return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
1809 case CSSPropertyWebkitBoxOrient:
1810 return cssValuePool().createValue(style->boxOrient());
1811 case CSSPropertyWebkitBoxPack:
1812 return cssValuePool().createValue(style->boxPack());
1813 case CSSPropertyWebkitBoxReflect:
1814 return valueForReflection(style->boxReflect(), style.get());
1815 case CSSPropertyBoxShadow:
1816 case CSSPropertyWebkitBoxShadow:
Ben Murdoch83750172013-07-24 10:36:59 +01001817 return valueForShadow(renderer, style->boxShadow(), propertyID, style.get());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001818 case CSSPropertyCaptionSide:
1819 return cssValuePool().createValue(style->captionSide());
1820 case CSSPropertyClear:
1821 return cssValuePool().createValue(style->clear());
1822 case CSSPropertyColor:
1823 return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
1824 case CSSPropertyWebkitPrintColorAdjust:
1825 return cssValuePool().createValue(style->printColorAdjust());
1826 case CSSPropertyWebkitColumnAxis:
1827 return cssValuePool().createValue(style->columnAxis());
1828 case CSSPropertyWebkitColumnCount:
1829 if (style->hasAutoColumnCount())
1830 return cssValuePool().createIdentifierValue(CSSValueAuto);
1831 return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
1832 case CSSPropertyWebkitColumnGap:
1833 if (style->hasNormalColumnGap())
1834 return cssValuePool().createIdentifierValue(CSSValueNormal);
1835 return zoomAdjustedPixelValue(style->columnGap(), style.get());
1836 case CSSPropertyWebkitColumnProgression:
1837 return cssValuePool().createValue(style->columnProgression());
1838 case CSSPropertyWebkitColumnRuleColor:
Ben Murdoch83750172013-07-24 10:36:59 +01001839 return currentColorOrValidColor(renderer, style.get(), CSSPropertyWebkitColumnRuleColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001840 case CSSPropertyWebkitColumnRuleStyle:
1841 return cssValuePool().createValue(style->columnRuleStyle());
1842 case CSSPropertyWebkitColumnRuleWidth:
1843 return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get());
1844 case CSSPropertyWebkitColumnSpan:
1845 return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
1846 case CSSPropertyWebkitColumnBreakAfter:
1847 return cssValuePool().createValue(style->columnBreakAfter());
1848 case CSSPropertyWebkitColumnBreakBefore:
1849 return cssValuePool().createValue(style->columnBreakBefore());
1850 case CSSPropertyWebkitColumnBreakInside:
1851 return cssValuePool().createValue(style->columnBreakInside());
1852 case CSSPropertyWebkitColumnWidth:
1853 if (style->hasAutoColumnWidth())
1854 return cssValuePool().createIdentifierValue(CSSValueAuto);
1855 return zoomAdjustedPixelValue(style->columnWidth(), style.get());
1856 case CSSPropertyTabSize:
1857 return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
1858 case CSSPropertyWebkitRegionBreakAfter:
1859 return cssValuePool().createValue(style->regionBreakAfter());
1860 case CSSPropertyWebkitRegionBreakBefore:
1861 return cssValuePool().createValue(style->regionBreakBefore());
1862 case CSSPropertyWebkitRegionBreakInside:
1863 return cssValuePool().createValue(style->regionBreakInside());
1864 case CSSPropertyCursor: {
1865 RefPtr<CSSValueList> list;
1866 CursorList* cursors = style->cursors();
1867 if (cursors && cursors->size() > 0) {
1868 list = CSSValueList::createCommaSeparated();
1869 for (unsigned i = 0; i < cursors->size(); ++i)
1870 if (StyleImage* image = cursors->at(i).image())
1871 list->append(image->cssValue());
1872 }
1873 RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
1874 if (list) {
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001875 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001876 return list.release();
1877 }
1878 return value.release();
1879 }
1880 case CSSPropertyDirection:
1881 return cssValuePool().createValue(style->direction());
1882 case CSSPropertyDisplay:
1883 return cssValuePool().createValue(style->display());
1884 case CSSPropertyEmptyCells:
1885 return cssValuePool().createValue(style->emptyCells());
Ben Murdoch591b9582013-07-10 11:41:44 +01001886 case CSSPropertyAlignContent:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001887 return cssValuePool().createValue(style->alignContent());
Ben Murdoch591b9582013-07-10 11:41:44 +01001888 case CSSPropertyAlignItems:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001889 return cssValuePool().createValue(style->alignItems());
Ben Murdoch591b9582013-07-10 11:41:44 +01001890 case CSSPropertyAlignSelf:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001891 if (style->alignSelf() == AlignAuto) {
1892 Node* parent = styledNode->parentNode();
1893 if (parent && parent->computedStyle())
1894 return cssValuePool().createValue(parent->computedStyle()->alignItems());
1895 return cssValuePool().createValue(AlignStretch);
1896 }
1897 return cssValuePool().createValue(style->alignSelf());
Ben Murdoch591b9582013-07-10 11:41:44 +01001898 case CSSPropertyFlex:
1899 return getCSSPropertyValuesForShorthandProperties(flexShorthand());
1900 case CSSPropertyFlexBasis:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001901 return cssValuePool().createValue(style->flexBasis());
Ben Murdoch591b9582013-07-10 11:41:44 +01001902 case CSSPropertyFlexDirection:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001903 return cssValuePool().createValue(style->flexDirection());
Ben Murdoch591b9582013-07-10 11:41:44 +01001904 case CSSPropertyFlexFlow:
1905 return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
1906 case CSSPropertyFlexGrow:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001907 return cssValuePool().createValue(style->flexGrow());
Ben Murdoch591b9582013-07-10 11:41:44 +01001908 case CSSPropertyFlexShrink:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001909 return cssValuePool().createValue(style->flexShrink());
Ben Murdoch591b9582013-07-10 11:41:44 +01001910 case CSSPropertyFlexWrap:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001911 return cssValuePool().createValue(style->flexWrap());
Ben Murdoch591b9582013-07-10 11:41:44 +01001912 case CSSPropertyJustifyContent:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001913 return cssValuePool().createValue(style->justifyContent());
Ben Murdoch591b9582013-07-10 11:41:44 +01001914 case CSSPropertyOrder:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001915 return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
1916 case CSSPropertyFloat:
1917 if (style->display() != NONE && style->hasOutOfFlowPosition())
1918 return cssValuePool().createIdentifierValue(CSSValueNone);
1919 return cssValuePool().createValue(style->floating());
1920 case CSSPropertyFont: {
1921 RefPtr<FontValue> computedFont = FontValue::create();
1922 computedFont->style = fontStyleFromStyle(style.get());
1923 computedFont->variant = fontVariantFromStyle(style.get());
1924 computedFont->weight = fontWeightFromStyle(style.get());
1925 computedFont->size = fontSizeFromStyle(style.get());
1926 computedFont->lineHeight = lineHeightFromStyle(style.get(), m_node->document()->renderView());
1927 computedFont->family = fontFamilyFromStyle(style.get());
1928 return computedFont.release();
1929 }
1930 case CSSPropertyFontFamily: {
1931 RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get());
1932 // If there's only a single family, return that as a CSSPrimitiveValue.
1933 // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
1934 if (fontFamilyList->length() == 1)
1935 return fontFamilyList->item(0);
1936 return fontFamilyList.release();
1937 }
1938 case CSSPropertyFontSize:
1939 return fontSizeFromStyle(style.get());
1940 case CSSPropertyFontStyle:
1941 return fontStyleFromStyle(style.get());
1942 case CSSPropertyFontVariant:
1943 return fontVariantFromStyle(style.get());
1944 case CSSPropertyFontWeight:
1945 return fontWeightFromStyle(style.get());
1946 case CSSPropertyWebkitFontFeatureSettings: {
1947 const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings();
1948 if (!featureSettings || !featureSettings->size())
1949 return cssValuePool().createIdentifierValue(CSSValueNormal);
1950 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1951 for (unsigned i = 0; i < featureSettings->size(); ++i) {
1952 const FontFeature& feature = featureSettings->at(i);
1953 RefPtr<FontFeatureValue> featureValue = FontFeatureValue::create(feature.tag(), feature.value());
1954 list->append(featureValue.release());
1955 }
1956 return list.release();
1957 }
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001958 case CSSPropertyGridAutoColumns:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001959 return valueForGridTrackSize(style->gridAutoColumns(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001960 case CSSPropertyGridAutoFlow:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001961 return cssValuePool().createValue(style->gridAutoFlow());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001962 case CSSPropertyGridAutoRows:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001963 return valueForGridTrackSize(style->gridAutoRows(), style.get(), m_node->document()->renderView());
Ben Murdoch591b9582013-07-10 11:41:44 +01001964 case CSSPropertyGridDefinitionColumns:
1965 return valueForGridTrackList(style->gridDefinitionColumns(), style->namedGridColumnLines(), style.get(), m_node->document()->renderView());
1966 case CSSPropertyGridDefinitionRows:
1967 return valueForGridTrackList(style->gridDefinitionRows(), style->namedGridRowLines(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001968
Ben Murdoch591b9582013-07-10 11:41:44 +01001969 case CSSPropertyGridColumnStart:
1970 return valueForGridPosition(style->gridColumnStart());
1971 case CSSPropertyGridColumnEnd:
1972 return valueForGridPosition(style->gridColumnEnd());
1973 case CSSPropertyGridRowStart:
1974 return valueForGridPosition(style->gridRowStart());
1975 case CSSPropertyGridRowEnd:
1976 return valueForGridPosition(style->gridRowEnd());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001977 case CSSPropertyGridColumn:
1978 return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
1979 case CSSPropertyGridRow:
1980 return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
1981 case CSSPropertyGridArea:
1982 return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001983
1984 case CSSPropertyHeight:
1985 if (renderer) {
1986 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
1987 // the "height" property does not apply for non-replaced inline elements.
1988 if (!renderer->isReplaced() && renderer->isInline())
1989 return cssValuePool().createIdentifierValue(CSSValueAuto);
1990 return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get());
1991 }
1992 return zoomAdjustedPixelValueForLength(style->height(), style.get());
1993 case CSSPropertyWebkitHighlight:
1994 if (style->highlight() == nullAtom)
1995 return cssValuePool().createIdentifierValue(CSSValueNone);
1996 return cssValuePool().createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
1997 case CSSPropertyWebkitHyphens:
1998 return cssValuePool().createValue(style->hyphens());
1999 case CSSPropertyWebkitHyphenateCharacter:
2000 if (style->hyphenationString().isNull())
2001 return cssValuePool().createIdentifierValue(CSSValueAuto);
2002 return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
2003 case CSSPropertyWebkitHyphenateLimitAfter:
2004 if (style->hyphenationLimitAfter() < 0)
2005 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2006 return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
2007 case CSSPropertyWebkitHyphenateLimitBefore:
2008 if (style->hyphenationLimitBefore() < 0)
2009 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2010 return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
2011 case CSSPropertyWebkitHyphenateLimitLines:
2012 if (style->hyphenationLimitLines() < 0)
2013 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
2014 return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
2015 case CSSPropertyWebkitBorderFit:
2016 if (style->borderFit() == BorderFitBorder)
2017 return cssValuePool().createIdentifierValue(CSSValueBorder);
2018 return cssValuePool().createIdentifierValue(CSSValueLines);
2019 case CSSPropertyImageRendering:
2020 return CSSPrimitiveValue::create(style->imageRendering());
2021 case CSSPropertyLeft:
2022 return getPositionOffsetValue(style.get(), CSSPropertyLeft, renderer, m_node->document()->renderView());
2023 case CSSPropertyLetterSpacing:
2024 if (!style->letterSpacing())
2025 return cssValuePool().createIdentifierValue(CSSValueNormal);
2026 return zoomAdjustedPixelValue(style->letterSpacing(), style.get());
2027 case CSSPropertyWebkitLineClamp:
2028 if (style->lineClamp().isNone())
2029 return cssValuePool().createIdentifierValue(CSSValueNone);
2030 return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2031 case CSSPropertyLineHeight:
2032 return lineHeightFromStyle(style.get(), m_node->document()->renderView());
2033 case CSSPropertyListStyleImage:
2034 if (style->listStyleImage())
2035 return style->listStyleImage()->cssValue();
2036 return cssValuePool().createIdentifierValue(CSSValueNone);
2037 case CSSPropertyListStylePosition:
2038 return cssValuePool().createValue(style->listStylePosition());
2039 case CSSPropertyListStyleType:
2040 return cssValuePool().createValue(style->listStyleType());
2041 case CSSPropertyWebkitLocale:
2042 if (style->locale().isNull())
2043 return cssValuePool().createIdentifierValue(CSSValueAuto);
2044 return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2045 case CSSPropertyMarginTop: {
2046 Length marginTop = style->marginTop();
2047 if (marginTop.isFixed() || !renderer || !renderer->isBox())
2048 return zoomAdjustedPixelValueForLength(marginTop, style.get());
2049 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginTop(), style.get());
2050 }
2051 case CSSPropertyMarginRight: {
2052 Length marginRight = style->marginRight();
2053 if (marginRight.isFixed() || !renderer || !renderer->isBox())
2054 return zoomAdjustedPixelValueForLength(marginRight, style.get());
2055 float value;
2056 if (marginRight.isPercent() || marginRight.isViewportPercentage())
2057 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2058 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2059 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2060 value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document()->renderView());
2061 else
2062 value = toRenderBox(renderer)->marginRight();
2063 return zoomAdjustedPixelValue(value, style.get());
2064 }
2065 case CSSPropertyMarginBottom: {
2066 Length marginBottom = style->marginBottom();
2067 if (marginBottom.isFixed() || !renderer || !renderer->isBox())
2068 return zoomAdjustedPixelValueForLength(marginBottom, style.get());
2069 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginBottom(), style.get());
2070 }
2071 case CSSPropertyMarginLeft: {
2072 Length marginLeft = style->marginLeft();
2073 if (marginLeft.isFixed() || !renderer || !renderer->isBox())
2074 return zoomAdjustedPixelValueForLength(marginLeft, style.get());
2075 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginLeft(), style.get());
2076 }
2077 case CSSPropertyWebkitMarqueeDirection:
2078 return cssValuePool().createValue(style->marqueeDirection());
2079 case CSSPropertyWebkitMarqueeIncrement:
2080 return cssValuePool().createValue(style->marqueeIncrement());
2081 case CSSPropertyWebkitMarqueeRepetition:
2082 if (style->marqueeLoopCount() < 0)
2083 return cssValuePool().createIdentifierValue(CSSValueInfinite);
2084 return cssValuePool().createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
2085 case CSSPropertyWebkitMarqueeStyle:
2086 return cssValuePool().createValue(style->marqueeBehavior());
2087 case CSSPropertyWebkitUserModify:
2088 return cssValuePool().createValue(style->userModify());
2089 case CSSPropertyMaxHeight: {
2090 const Length& maxHeight = style->maxHeight();
2091 if (maxHeight.isUndefined())
2092 return cssValuePool().createIdentifierValue(CSSValueNone);
2093 return zoomAdjustedPixelValueForLength(maxHeight, style.get());
2094 }
2095 case CSSPropertyMaxWidth: {
2096 const Length& maxWidth = style->maxWidth();
2097 if (maxWidth.isUndefined())
2098 return cssValuePool().createIdentifierValue(CSSValueNone);
2099 return zoomAdjustedPixelValueForLength(maxWidth, style.get());
2100 }
2101 case CSSPropertyMinHeight:
2102 // FIXME: For flex-items, min-height:auto should compute to min-content.
2103 if (style->minHeight().isAuto())
2104 return zoomAdjustedPixelValue(0, style.get());
2105 return zoomAdjustedPixelValueForLength(style->minHeight(), style.get());
2106 case CSSPropertyMinWidth:
2107 // FIXME: For flex-items, min-width:auto should compute to min-content.
2108 if (style->minWidth().isAuto())
2109 return zoomAdjustedPixelValue(0, style.get());
2110 return zoomAdjustedPixelValueForLength(style->minWidth(), style.get());
2111 case CSSPropertyOpacity:
2112 return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
2113 case CSSPropertyOrphans:
2114 if (style->hasAutoOrphans())
2115 return cssValuePool().createIdentifierValue(CSSValueAuto);
2116 return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
2117 case CSSPropertyOutlineColor:
Ben Murdoch83750172013-07-24 10:36:59 +01002118 return currentColorOrValidColor(renderer, style.get(), CSSPropertyOutlineColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002119 case CSSPropertyOutlineOffset:
2120 return zoomAdjustedPixelValue(style->outlineOffset(), style.get());
2121 case CSSPropertyOutlineStyle:
2122 if (style->outlineStyleIsAuto())
2123 return cssValuePool().createIdentifierValue(CSSValueAuto);
2124 return cssValuePool().createValue(style->outlineStyle());
2125 case CSSPropertyOutlineWidth:
2126 return zoomAdjustedPixelValue(style->outlineWidth(), style.get());
2127 case CSSPropertyOverflow:
2128 return cssValuePool().createValue(max(style->overflowX(), style->overflowY()));
2129 case CSSPropertyOverflowWrap:
2130 return cssValuePool().createValue(style->overflowWrap());
2131 case CSSPropertyOverflowX:
2132 return cssValuePool().createValue(style->overflowX());
2133 case CSSPropertyOverflowY:
2134 return cssValuePool().createValue(style->overflowY());
Ben Murdoch591b9582013-07-10 11:41:44 +01002135 case CSSPropertyPaddingTop: {
2136 Length paddingTop = style->paddingTop();
2137 if (paddingTop.isFixed() || !renderer || !renderer->isBox())
2138 return zoomAdjustedPixelValueForLength(paddingTop, style.get());
2139 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingTop(), style.get());
2140 }
2141 case CSSPropertyPaddingRight: {
2142 Length paddingRight = style->paddingRight();
2143 if (paddingRight.isFixed() || !renderer || !renderer->isBox())
2144 return zoomAdjustedPixelValueForLength(paddingRight, style.get());
2145 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingRight(), style.get());
2146 }
2147 case CSSPropertyPaddingBottom: {
2148 Length paddingBottom = style->paddingBottom();
2149 if (paddingBottom.isFixed() || !renderer || !renderer->isBox())
2150 return zoomAdjustedPixelValueForLength(paddingBottom, style.get());
2151 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingBottom(), style.get());
2152 }
2153 case CSSPropertyPaddingLeft: {
2154 Length paddingLeft = style->paddingLeft();
2155 if (paddingLeft.isFixed() || !renderer || !renderer->isBox())
2156 return zoomAdjustedPixelValueForLength(paddingLeft, style.get());
2157 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingLeft(), style.get());
2158 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002159 case CSSPropertyPageBreakAfter:
2160 return cssValuePool().createValue(style->pageBreakAfter());
2161 case CSSPropertyPageBreakBefore:
2162 return cssValuePool().createValue(style->pageBreakBefore());
2163 case CSSPropertyPageBreakInside: {
2164 EPageBreak pageBreak = style->pageBreakInside();
2165 ASSERT(pageBreak != PBALWAYS);
2166 if (pageBreak == PBALWAYS)
2167 return 0;
2168 return cssValuePool().createValue(style->pageBreakInside());
2169 }
2170 case CSSPropertyPosition:
2171 return cssValuePool().createValue(style->position());
2172 case CSSPropertyRight:
2173 return getPositionOffsetValue(style.get(), CSSPropertyRight, renderer, m_node->document()->renderView());
2174 case CSSPropertyWebkitRubyPosition:
2175 return cssValuePool().createValue(style->rubyPosition());
2176 case CSSPropertyTableLayout:
2177 return cssValuePool().createValue(style->tableLayout());
2178 case CSSPropertyTextAlign:
2179 return cssValuePool().createValue(style->textAlign());
Ben Murdoche69819b2013-07-17 14:56:49 +01002180 case CSSPropertyTextAlignLast:
2181 return cssValuePool().createValue(style->textAlignLast());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002182 case CSSPropertyTextDecoration:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002183 case CSSPropertyTextDecorationLine:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002184 return renderTextDecorationFlagsToCSSValue(style->textDecoration());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002185 case CSSPropertyTextDecorationStyle:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002186 return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002187 case CSSPropertyTextDecorationColor:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002188 return currentColorOrValidColor(style.get(), style->textDecorationColor());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002189#if ENABLE(CSS3_TEXT)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002190 case CSSPropertyWebkitTextUnderlinePosition:
2191 return cssValuePool().createValue(style->textUnderlinePosition());
2192#endif // CSS3_TEXT
2193 case CSSPropertyWebkitTextDecorationsInEffect:
2194 return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
2195 case CSSPropertyWebkitTextFillColor:
Ben Murdoch83750172013-07-24 10:36:59 +01002196 return currentColorOrValidColor(renderer, style.get(), CSSPropertyWebkitTextFillColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002197 case CSSPropertyWebkitTextEmphasisColor:
Ben Murdoch83750172013-07-24 10:36:59 +01002198 return currentColorOrValidColor(renderer, style.get(), CSSPropertyWebkitTextEmphasisColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002199 case CSSPropertyWebkitTextEmphasisPosition:
2200 return cssValuePool().createValue(style->textEmphasisPosition());
2201 case CSSPropertyWebkitTextEmphasisStyle:
2202 switch (style->textEmphasisMark()) {
2203 case TextEmphasisMarkNone:
2204 return cssValuePool().createIdentifierValue(CSSValueNone);
2205 case TextEmphasisMarkCustom:
2206 return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
2207 case TextEmphasisMarkAuto:
2208 ASSERT_NOT_REACHED();
2209 // Fall through
2210 case TextEmphasisMarkDot:
2211 case TextEmphasisMarkCircle:
2212 case TextEmphasisMarkDoubleCircle:
2213 case TextEmphasisMarkTriangle:
2214 case TextEmphasisMarkSesame: {
2215 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2216 list->append(cssValuePool().createValue(style->textEmphasisFill()));
2217 list->append(cssValuePool().createValue(style->textEmphasisMark()));
2218 return list.release();
2219 }
2220 }
2221 case CSSPropertyTextIndent: {
2222 RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), style.get());
2223#if ENABLE(CSS3_TEXT)
2224 if (style->textIndentLine() == TextIndentEachLine) {
2225 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2226 list->append(textIndent.release());
2227 list->append(cssValuePool().createIdentifierValue(CSSValueWebkitEachLine));
2228 return list.release();
2229 }
2230#endif
2231 return textIndent.release();
2232 }
2233 case CSSPropertyTextShadow:
Ben Murdoch83750172013-07-24 10:36:59 +01002234 return valueForShadow(renderer, style->textShadow(), propertyID, style.get());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002235 case CSSPropertyTextRendering:
2236 return cssValuePool().createValue(style->fontDescription().textRenderingMode());
2237 case CSSPropertyTextOverflow:
2238 if (style->textOverflow())
2239 return cssValuePool().createIdentifierValue(CSSValueEllipsis);
2240 return cssValuePool().createIdentifierValue(CSSValueClip);
2241 case CSSPropertyWebkitTextSecurity:
2242 return cssValuePool().createValue(style->textSecurity());
2243 case CSSPropertyWebkitTextStrokeColor:
Ben Murdoch83750172013-07-24 10:36:59 +01002244 return currentColorOrValidColor(renderer, style.get(), CSSPropertyWebkitTextStrokeColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002245 case CSSPropertyWebkitTextStrokeWidth:
2246 return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get());
2247 case CSSPropertyTextTransform:
2248 return cssValuePool().createValue(style->textTransform());
2249 case CSSPropertyTop:
2250 return getPositionOffsetValue(style.get(), CSSPropertyTop, renderer, m_node->document()->renderView());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002251 case CSSPropertyTouchAction:
2252 return cssValuePool().createValue(style->touchAction());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002253 case CSSPropertyUnicodeBidi:
2254 return cssValuePool().createValue(style->unicodeBidi());
2255 case CSSPropertyVerticalAlign:
2256 switch (style->verticalAlign()) {
2257 case BASELINE:
2258 return cssValuePool().createIdentifierValue(CSSValueBaseline);
2259 case MIDDLE:
2260 return cssValuePool().createIdentifierValue(CSSValueMiddle);
2261 case SUB:
2262 return cssValuePool().createIdentifierValue(CSSValueSub);
2263 case SUPER:
2264 return cssValuePool().createIdentifierValue(CSSValueSuper);
2265 case TEXT_TOP:
2266 return cssValuePool().createIdentifierValue(CSSValueTextTop);
2267 case TEXT_BOTTOM:
2268 return cssValuePool().createIdentifierValue(CSSValueTextBottom);
2269 case TOP:
2270 return cssValuePool().createIdentifierValue(CSSValueTop);
2271 case BOTTOM:
2272 return cssValuePool().createIdentifierValue(CSSValueBottom);
2273 case BASELINE_MIDDLE:
2274 return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
2275 case LENGTH:
2276 return cssValuePool().createValue(style->verticalAlignLength());
2277 }
2278 ASSERT_NOT_REACHED();
2279 return 0;
2280 case CSSPropertyVisibility:
2281 return cssValuePool().createValue(style->visibility());
2282 case CSSPropertyWhiteSpace:
2283 return cssValuePool().createValue(style->whiteSpace());
2284 case CSSPropertyWidows:
2285 if (style->hasAutoWidows())
2286 return cssValuePool().createIdentifierValue(CSSValueAuto);
2287 return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
2288 case CSSPropertyWidth:
2289 if (renderer) {
2290 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
2291 // the "width" property does not apply for non-replaced inline elements.
2292 if (!renderer->isReplaced() && renderer->isInline())
2293 return cssValuePool().createIdentifierValue(CSSValueAuto);
2294 return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get());
2295 }
2296 return zoomAdjustedPixelValueForLength(style->width(), style.get());
2297 case CSSPropertyWordBreak:
2298 return cssValuePool().createValue(style->wordBreak());
2299 case CSSPropertyWordSpacing:
2300 return zoomAdjustedPixelValue(style->wordSpacing(), style.get());
2301 case CSSPropertyWordWrap:
2302 return cssValuePool().createValue(style->overflowWrap());
2303 case CSSPropertyWebkitLineBreak:
2304 return cssValuePool().createValue(style->lineBreak());
2305 case CSSPropertyResize:
2306 return cssValuePool().createValue(style->resize());
2307 case CSSPropertyWebkitFontKerning:
2308 return cssValuePool().createValue(style->fontDescription().kerning());
2309 case CSSPropertyWebkitFontSmoothing:
2310 return cssValuePool().createValue(style->fontDescription().fontSmoothing());
2311 case CSSPropertyWebkitFontVariantLigatures: {
2312 FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
2313 FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
2314 FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
2315 if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
2316 && historicalLigaturesState == FontDescription::NormalLigaturesState)
2317 return cssValuePool().createIdentifierValue(CSSValueNormal);
2318
2319 RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
2320 if (commonLigaturesState != FontDescription::NormalLigaturesState)
2321 valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
2322 if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
2323 valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
2324 if (historicalLigaturesState != FontDescription::NormalLigaturesState)
2325 valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
2326 return valueList;
2327 }
2328 case CSSPropertyZIndex:
2329 if (style->hasAutoZIndex())
2330 return cssValuePool().createIdentifierValue(CSSValueAuto);
2331 return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
2332 case CSSPropertyZoom:
2333 return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
2334 case CSSPropertyBoxSizing:
2335 if (style->boxSizing() == CONTENT_BOX)
2336 return cssValuePool().createIdentifierValue(CSSValueContentBox);
2337 return cssValuePool().createIdentifierValue(CSSValueBorderBox);
2338 case CSSPropertyWebkitAppRegion:
2339 return cssValuePool().createIdentifierValue(style->getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag);
2340 case CSSPropertyWebkitAnimationDelay:
2341 return getDelayValue(style->animations());
2342 case CSSPropertyWebkitAnimationDirection: {
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 if (t->animation(i)->direction())
2348 list->append(cssValuePool().createIdentifierValue(CSSValueAlternate));
2349 else
2350 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2351 }
2352 } else
2353 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2354 return list.release();
2355 }
2356 case CSSPropertyWebkitAnimationDuration:
2357 return getDurationValue(style->animations());
2358 case CSSPropertyWebkitAnimationFillMode: {
2359 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2360 const CSSAnimationDataList* t = style->animations();
2361 if (t) {
2362 for (size_t i = 0; i < t->size(); ++i) {
2363 switch (t->animation(i)->fillMode()) {
2364 case AnimationFillModeNone:
2365 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2366 break;
2367 case AnimationFillModeForwards:
2368 list->append(cssValuePool().createIdentifierValue(CSSValueForwards));
2369 break;
2370 case AnimationFillModeBackwards:
2371 list->append(cssValuePool().createIdentifierValue(CSSValueBackwards));
2372 break;
2373 case AnimationFillModeBoth:
2374 list->append(cssValuePool().createIdentifierValue(CSSValueBoth));
2375 break;
2376 }
2377 }
2378 } else
2379 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2380 return list.release();
2381 }
2382 case CSSPropertyWebkitAnimationIterationCount: {
2383 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2384 const CSSAnimationDataList* t = style->animations();
2385 if (t) {
2386 for (size_t i = 0; i < t->size(); ++i) {
2387 double iterationCount = t->animation(i)->iterationCount();
2388 if (iterationCount == CSSAnimationData::IterationCountInfinite)
2389 list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
2390 else
2391 list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
2392 }
2393 } else
2394 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2395 return list.release();
2396 }
2397 case CSSPropertyWebkitAnimationName: {
2398 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2399 const CSSAnimationDataList* t = style->animations();
2400 if (t) {
2401 for (size_t i = 0; i < t->size(); ++i)
2402 list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
2403 } else
2404 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2405 return list.release();
2406 }
2407 case CSSPropertyWebkitAnimationPlayState: {
2408 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2409 const CSSAnimationDataList* t = style->animations();
2410 if (t) {
2411 for (size_t i = 0; i < t->size(); ++i) {
2412 int prop = t->animation(i)->playState();
2413 if (prop == AnimPlayStatePlaying)
2414 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2415 else
2416 list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
2417 }
2418 } else
2419 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2420 return list.release();
2421 }
2422 case CSSPropertyWebkitAnimationTimingFunction:
2423 return getTimingFunctionValue(style->animations());
2424 case CSSPropertyWebkitAppearance:
2425 return cssValuePool().createValue(style->appearance());
2426 case CSSPropertyWebkitAspectRatio:
2427 if (!style->hasAspectRatio())
2428 return cssValuePool().createIdentifierValue(CSSValueNone);
2429 return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
2430 case CSSPropertyWebkitBackfaceVisibility:
2431 return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
2432 case CSSPropertyWebkitBorderImage:
2433 return valueForNinePieceImage(style->borderImage());
2434 case CSSPropertyBorderImageOutset:
2435 return valueForNinePieceImageQuad(style->borderImage().outset());
2436 case CSSPropertyBorderImageRepeat:
2437 return valueForNinePieceImageRepeat(style->borderImage());
2438 case CSSPropertyBorderImageSlice:
2439 return valueForNinePieceImageSlice(style->borderImage());
2440 case CSSPropertyBorderImageWidth:
2441 return valueForNinePieceImageQuad(style->borderImage().borderSlices());
2442 case CSSPropertyWebkitMaskBoxImage:
2443 return valueForNinePieceImage(style->maskBoxImage());
2444 case CSSPropertyWebkitMaskBoxImageOutset:
2445 return valueForNinePieceImageQuad(style->maskBoxImage().outset());
2446 case CSSPropertyWebkitMaskBoxImageRepeat:
2447 return valueForNinePieceImageRepeat(style->maskBoxImage());
2448 case CSSPropertyWebkitMaskBoxImageSlice:
2449 return valueForNinePieceImageSlice(style->maskBoxImage());
2450 case CSSPropertyWebkitMaskBoxImageWidth:
2451 return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
2452 case CSSPropertyWebkitMaskBoxImageSource:
2453 if (style->maskBoxImageSource())
2454 return style->maskBoxImageSource()->cssValue();
2455 return cssValuePool().createIdentifierValue(CSSValueNone);
2456 case CSSPropertyWebkitFontSizeDelta:
2457 // Not a real style property -- used by the editing engine -- so has no computed value.
2458 break;
2459 case CSSPropertyWebkitMarginBottomCollapse:
2460 case CSSPropertyWebkitMarginAfterCollapse:
2461 return cssValuePool().createValue(style->marginAfterCollapse());
2462 case CSSPropertyWebkitMarginTopCollapse:
2463 case CSSPropertyWebkitMarginBeforeCollapse:
2464 return cssValuePool().createValue(style->marginBeforeCollapse());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002465 case CSSPropertyWebkitPerspective:
2466 if (!style->hasPerspective())
2467 return cssValuePool().createIdentifierValue(CSSValueNone);
2468 return zoomAdjustedPixelValue(style->perspective(), style.get());
2469 case CSSPropertyWebkitPerspectiveOrigin: {
2470 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2471 if (renderer) {
2472 LayoutRect box;
2473 if (renderer->isBox())
2474 box = toRenderBox(renderer)->borderBoxRect();
2475
2476 RenderView* renderView = m_node->document()->renderView();
2477 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), style.get()));
2478 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), style.get()));
2479 }
2480 else {
2481 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get()));
2482 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get()));
2483
2484 }
2485 return list.release();
2486 }
2487 case CSSPropertyWebkitRtlOrdering:
2488 return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
2489 case CSSPropertyWebkitTapHighlightColor:
Ben Murdoch83750172013-07-24 10:36:59 +01002490 return currentColorOrValidColor(renderer, style.get(), CSSPropertyWebkitTapHighlightColor);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002491 case CSSPropertyWebkitUserDrag:
2492 return cssValuePool().createValue(style->userDrag());
2493 case CSSPropertyWebkitUserSelect:
2494 return cssValuePool().createValue(style->userSelect());
2495 case CSSPropertyBorderBottomLeftRadius:
2496 return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), m_node->document()->renderView());
2497 case CSSPropertyBorderBottomRightRadius:
2498 return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), m_node->document()->renderView());
2499 case CSSPropertyBorderTopLeftRadius:
2500 return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), m_node->document()->renderView());
2501 case CSSPropertyBorderTopRightRadius:
2502 return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), m_node->document()->renderView());
2503 case CSSPropertyClip: {
2504 if (!style->hasClip())
2505 return cssValuePool().createIdentifierValue(CSSValueAuto);
2506 RefPtr<Rect> rect = Rect::create();
2507 rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get()));
2508 rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get()));
2509 rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get()));
2510 rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get()));
2511 return cssValuePool().createValue(rect.release());
2512 }
2513 case CSSPropertySpeak:
2514 return cssValuePool().createValue(style->speak());
2515 case CSSPropertyWebkitTransform:
2516 return computedTransform(renderer, style.get());
2517 case CSSPropertyWebkitTransformOrigin: {
2518 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2519 if (renderer) {
2520 LayoutRect box;
2521 if (renderer->isBox())
2522 box = toRenderBox(renderer)->borderBoxRect();
2523
2524 RenderView* renderView = m_node->document()->renderView();
2525 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), style.get()));
2526 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), style.get()));
2527 if (style->transformOriginZ() != 0)
2528 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2529 } else {
2530 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get()));
2531 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get()));
2532 if (style->transformOriginZ() != 0)
2533 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2534 }
2535 return list.release();
2536 }
2537 case CSSPropertyWebkitTransformStyle:
2538 return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
2539 case CSSPropertyTransitionDelay:
2540 case CSSPropertyWebkitTransitionDelay:
2541 return getDelayValue(style->transitions());
2542 case CSSPropertyTransitionDuration:
2543 case CSSPropertyWebkitTransitionDuration:
2544 return getDurationValue(style->transitions());
2545 case CSSPropertyTransitionProperty:
2546 case CSSPropertyWebkitTransitionProperty:
2547 return getTransitionPropertyValue(style->transitions());
2548 case CSSPropertyTransitionTimingFunction:
2549 case CSSPropertyWebkitTransitionTimingFunction:
2550 return getTimingFunctionValue(style->transitions());
2551 case CSSPropertyTransition:
2552 case CSSPropertyWebkitTransition: {
2553 const CSSAnimationDataList* animList = style->transitions();
2554 if (animList) {
2555 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
2556 for (size_t i = 0; i < animList->size(); ++i) {
2557 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2558 const CSSAnimationData* animation = animList->animation(i);
2559 list->append(createTransitionPropertyValue(animation));
2560 list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
2561 list->append(createTimingFunctionValue(animation->timingFunction().get()));
2562 list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
2563 transitionsList->append(list);
2564 }
2565 return transitionsList.release();
2566 }
2567
2568 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2569 // transition-property default value.
2570 list->append(cssValuePool().createIdentifierValue(CSSValueAll));
2571 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
2572 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
2573 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
2574 return list.release();
2575 }
2576 case CSSPropertyPointerEvents:
2577 return cssValuePool().createValue(style->pointerEvents());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002578 case CSSPropertyWebkitLineGrid:
2579 if (style->lineGrid().isNull())
2580 return cssValuePool().createIdentifierValue(CSSValueNone);
2581 return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
2582 case CSSPropertyWebkitLineSnap:
2583 return CSSPrimitiveValue::create(style->lineSnap());
2584 case CSSPropertyWebkitLineAlign:
2585 return CSSPrimitiveValue::create(style->lineAlign());
2586 case CSSPropertyWebkitWritingMode:
2587 return cssValuePool().createValue(style->writingMode());
2588 case CSSPropertyWebkitTextCombine:
2589 return cssValuePool().createValue(style->textCombine());
2590 case CSSPropertyWebkitTextOrientation:
2591 return CSSPrimitiveValue::create(style->textOrientation());
2592 case CSSPropertyWebkitLineBoxContain:
2593 return createLineBoxContainValue(style->lineBoxContain());
2594 case CSSPropertyContent:
2595 return contentToCSSValue(style.get());
2596 case CSSPropertyCounterIncrement:
2597 return counterToCSSValue(style.get(), propertyID);
2598 case CSSPropertyCounterReset:
2599 return counterToCSSValue(style.get(), propertyID);
2600 case CSSPropertyWebkitClipPath:
2601 if (ClipPathOperation* operation = style->clipPath()) {
2602 if (operation->getOperationType() == ClipPathOperation::SHAPE)
2603 return valueForBasicShape(static_cast<ShapeClipPathOperation*>(operation)->basicShape());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002604 if (operation->getOperationType() == ClipPathOperation::REFERENCE) {
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002605 ReferenceClipPathOperation* referenceOperation = static_cast<ReferenceClipPathOperation*>(operation);
2606 return CSSPrimitiveValue::create(referenceOperation->url(), CSSPrimitiveValue::CSS_URI);
2607 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002608 }
2609 return cssValuePool().createIdentifierValue(CSSValueNone);
2610 case CSSPropertyWebkitFlowInto:
2611 if (style->flowThread().isNull())
2612 return cssValuePool().createIdentifierValue(CSSValueNone);
2613 return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
2614 case CSSPropertyWebkitFlowFrom:
2615 if (style->regionThread().isNull())
2616 return cssValuePool().createIdentifierValue(CSSValueNone);
2617 return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01002618 case CSSPropertyWebkitRegionFragment:
2619 return cssValuePool().createValue(style->regionFragment());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002620 case CSSPropertyWebkitWrapFlow:
2621 return cssValuePool().createValue(style->wrapFlow());
2622 case CSSPropertyWebkitShapeMargin:
2623 return cssValuePool().createValue(style->shapeMargin());
2624 case CSSPropertyWebkitShapePadding:
2625 return cssValuePool().createValue(style->shapePadding());
2626 case CSSPropertyWebkitShapeInside:
2627 if (!style->shapeInside())
2628 return cssValuePool().createIdentifierValue(CSSValueAuto);
Ben Murdoch591b9582013-07-10 11:41:44 +01002629 if (style->shapeInside()->type() == ShapeValue::Outside)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002630 return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
Ben Murdoch591b9582013-07-10 11:41:44 +01002631 if (style->shapeInside()->type() == ShapeValue::Image) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002632 if (style->shapeInside()->image())
2633 return style->shapeInside()->image()->cssValue();
2634 return cssValuePool().createIdentifierValue(CSSValueNone);
2635 }
Ben Murdoch591b9582013-07-10 11:41:44 +01002636 ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002637 return valueForBasicShape(style->shapeInside()->shape());
2638 case CSSPropertyWebkitShapeOutside:
2639 if (!style->shapeOutside())
2640 return cssValuePool().createIdentifierValue(CSSValueAuto);
Ben Murdoch591b9582013-07-10 11:41:44 +01002641 if (style->shapeOutside()->type() == ShapeValue::Image) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002642 if (style->shapeOutside()->image())
2643 return style->shapeOutside()->image()->cssValue();
2644 return cssValuePool().createIdentifierValue(CSSValueNone);
2645 }
Ben Murdoch591b9582013-07-10 11:41:44 +01002646 ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002647 return valueForBasicShape(style->shapeOutside()->shape());
2648 case CSSPropertyWebkitWrapThrough:
2649 return cssValuePool().createValue(style->wrapThrough());
2650 case CSSPropertyWebkitFilter:
2651 return valueForFilter(renderer, style.get());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002652 case CSSPropertyMixBlendMode:
2653 return cssValuePool().createValue(style->blendMode());
2654
2655 case CSSPropertyBackgroundBlendMode: {
2656 const FillLayer* layers = style->backgroundLayers();
2657 if (!layers->next())
2658 return cssValuePool().createValue(layers->blendMode());
2659
2660 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2661 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2662 list->append(cssValuePool().createValue(currLayer->blendMode()));
2663
2664 return list.release();
2665 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002666 case CSSPropertyBackground:
2667 return getBackgroundShorthandValue();
2668 case CSSPropertyBorder: {
2669 RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
2670 const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
2671 CSSPropertyBorderLeft };
2672 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
2673 if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
2674 return 0;
2675 }
2676 return value.release();
2677 }
2678 case CSSPropertyBorderBottom:
2679 return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand());
2680 case CSSPropertyBorderColor:
2681 return getCSSPropertyValuesForSidesShorthand(borderColorShorthand());
2682 case CSSPropertyBorderLeft:
2683 return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand());
2684 case CSSPropertyBorderImage:
2685 return valueForNinePieceImage(style->borderImage());
2686 case CSSPropertyBorderRadius:
2687 return getBorderRadiusShorthandValue(style.get(), m_node->document()->renderView());
2688 case CSSPropertyBorderRight:
2689 return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
2690 case CSSPropertyBorderStyle:
2691 return getCSSPropertyValuesForSidesShorthand(borderStyleShorthand());
2692 case CSSPropertyBorderTop:
2693 return getCSSPropertyValuesForShorthandProperties(borderTopShorthand());
2694 case CSSPropertyBorderWidth:
2695 return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand());
2696 case CSSPropertyWebkitColumnRule:
2697 return getCSSPropertyValuesForShorthandProperties(webkitColumnRuleShorthand());
2698 case CSSPropertyWebkitColumns:
2699 return getCSSPropertyValuesForShorthandProperties(webkitColumnsShorthand());
2700 case CSSPropertyListStyle:
2701 return getCSSPropertyValuesForShorthandProperties(listStyleShorthand());
2702 case CSSPropertyMargin:
2703 return getCSSPropertyValuesForSidesShorthand(marginShorthand());
2704 case CSSPropertyOutline:
2705 return getCSSPropertyValuesForShorthandProperties(outlineShorthand());
2706 case CSSPropertyPadding:
2707 return getCSSPropertyValuesForSidesShorthand(paddingShorthand());
2708 /* Individual properties not part of the spec */
2709 case CSSPropertyBackgroundRepeatX:
2710 case CSSPropertyBackgroundRepeatY:
2711 break;
2712
2713 /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
2714 case CSSPropertyWebkitTextEmphasis:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002715 case CSSPropertyTextLineThroughColor:
2716 case CSSPropertyTextLineThroughMode:
2717 case CSSPropertyTextLineThroughStyle:
2718 case CSSPropertyTextLineThroughWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002719 case CSSPropertyTextOverlineColor:
2720 case CSSPropertyTextOverlineMode:
2721 case CSSPropertyTextOverlineStyle:
2722 case CSSPropertyTextOverlineWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002723 case CSSPropertyTextUnderlineColor:
2724 case CSSPropertyTextUnderlineMode:
2725 case CSSPropertyTextUnderlineStyle:
2726 case CSSPropertyTextUnderlineWidth:
2727 break;
2728
2729 /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
2730 case CSSPropertyWebkitBorderEnd:
2731 case CSSPropertyWebkitBorderEndColor:
2732 case CSSPropertyWebkitBorderEndStyle:
2733 case CSSPropertyWebkitBorderEndWidth:
2734 case CSSPropertyWebkitBorderStart:
2735 case CSSPropertyWebkitBorderStartColor:
2736 case CSSPropertyWebkitBorderStartStyle:
2737 case CSSPropertyWebkitBorderStartWidth:
2738 case CSSPropertyWebkitBorderAfter:
2739 case CSSPropertyWebkitBorderAfterColor:
2740 case CSSPropertyWebkitBorderAfterStyle:
2741 case CSSPropertyWebkitBorderAfterWidth:
2742 case CSSPropertyWebkitBorderBefore:
2743 case CSSPropertyWebkitBorderBeforeColor:
2744 case CSSPropertyWebkitBorderBeforeStyle:
2745 case CSSPropertyWebkitBorderBeforeWidth:
2746 case CSSPropertyWebkitMarginEnd:
2747 case CSSPropertyWebkitMarginStart:
2748 case CSSPropertyWebkitMarginAfter:
2749 case CSSPropertyWebkitMarginBefore:
2750 case CSSPropertyWebkitPaddingEnd:
2751 case CSSPropertyWebkitPaddingStart:
2752 case CSSPropertyWebkitPaddingAfter:
2753 case CSSPropertyWebkitPaddingBefore:
2754 case CSSPropertyWebkitLogicalWidth:
2755 case CSSPropertyWebkitLogicalHeight:
2756 case CSSPropertyWebkitMinLogicalWidth:
2757 case CSSPropertyWebkitMinLogicalHeight:
2758 case CSSPropertyWebkitMaxLogicalWidth:
2759 case CSSPropertyWebkitMaxLogicalHeight:
2760 ASSERT_NOT_REACHED();
2761 break;
2762
2763 /* Unimplemented @font-face properties */
2764 case CSSPropertyFontStretch:
2765 case CSSPropertySrc:
2766 case CSSPropertyUnicodeRange:
2767 break;
2768
2769 /* Other unimplemented properties */
2770 case CSSPropertyPage: // for @page
2771 case CSSPropertyQuotes: // FIXME: needs implementation
2772 case CSSPropertySize: // for @page
2773 break;
2774
2775 /* Unimplemented -webkit- properties */
2776 case CSSPropertyWebkitAnimation:
2777 case CSSPropertyWebkitBorderRadius:
2778 case CSSPropertyWebkitMarginCollapse:
2779 case CSSPropertyWebkitMarquee:
2780 case CSSPropertyWebkitMarqueeSpeed:
2781 case CSSPropertyWebkitMask:
2782 case CSSPropertyWebkitMaskRepeatX:
2783 case CSSPropertyWebkitMaskRepeatY:
2784 case CSSPropertyWebkitPerspectiveOriginX:
2785 case CSSPropertyWebkitPerspectiveOriginY:
2786 case CSSPropertyWebkitTextStroke:
2787 case CSSPropertyWebkitTransformOriginX:
2788 case CSSPropertyWebkitTransformOriginY:
2789 case CSSPropertyWebkitTransformOriginZ:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002790 break;
2791
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01002792 /* @viewport rule properties */
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002793 case CSSPropertyMaxZoom:
2794 case CSSPropertyMinZoom:
2795 case CSSPropertyOrientation:
2796 case CSSPropertyUserZoom:
2797 break;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002798
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002799 case CSSPropertyBufferedRendering:
2800 case CSSPropertyClipPath:
2801 case CSSPropertyClipRule:
2802 case CSSPropertyMask:
2803 case CSSPropertyEnableBackground:
2804 case CSSPropertyFilter:
2805 case CSSPropertyFloodColor:
2806 case CSSPropertyFloodOpacity:
2807 case CSSPropertyLightingColor:
2808 case CSSPropertyStopColor:
2809 case CSSPropertyStopOpacity:
2810 case CSSPropertyColorInterpolation:
2811 case CSSPropertyColorInterpolationFilters:
2812 case CSSPropertyColorProfile:
2813 case CSSPropertyColorRendering:
2814 case CSSPropertyFill:
2815 case CSSPropertyFillOpacity:
2816 case CSSPropertyFillRule:
2817 case CSSPropertyMarker:
2818 case CSSPropertyMarkerEnd:
2819 case CSSPropertyMarkerMid:
2820 case CSSPropertyMarkerStart:
2821 case CSSPropertyMaskType:
2822 case CSSPropertyShapeRendering:
2823 case CSSPropertyStroke:
2824 case CSSPropertyStrokeDasharray:
2825 case CSSPropertyStrokeDashoffset:
2826 case CSSPropertyStrokeLinecap:
2827 case CSSPropertyStrokeLinejoin:
2828 case CSSPropertyStrokeMiterlimit:
2829 case CSSPropertyStrokeOpacity:
2830 case CSSPropertyStrokeWidth:
2831 case CSSPropertyAlignmentBaseline:
2832 case CSSPropertyBaselineShift:
2833 case CSSPropertyDominantBaseline:
2834 case CSSPropertyGlyphOrientationHorizontal:
2835 case CSSPropertyGlyphOrientationVertical:
2836 case CSSPropertyKerning:
2837 case CSSPropertyTextAnchor:
2838 case CSSPropertyVectorEffect:
2839 case CSSPropertyWritingMode:
2840 case CSSPropertyWebkitSvgShadow:
2841 return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002842 }
2843
2844 logUnimplementedPropertyID(propertyID);
2845 return 0;
2846}
2847
2848String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
2849{
2850 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2851 if (value)
2852 return value->cssText();
2853 return "";
2854}
2855
2856
2857unsigned CSSComputedStyleDeclaration::length() const
2858{
2859 Node* node = m_node.get();
2860 if (!node)
2861 return 0;
2862
2863 RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
2864 if (!style)
2865 return 0;
2866
2867 return computableProperties().size();
2868}
2869
2870String CSSComputedStyleDeclaration::item(unsigned i) const
2871{
2872 if (i >= length())
2873 return "";
2874
2875 return getPropertyNameString(computableProperties()[i]);
2876}
2877
2878bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
2879{
2880 if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() && m_node) {
2881 m_node->document()->updateLayoutIgnorePendingStylesheets();
2882 RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
2883 if (style && style->fontDescription().keywordSize()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002884 CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
Torne (Richard Coles)e5249552013-05-15 11:35:13 +01002885 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(propertyValue);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002886 if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002887 return true;
2888 }
2889 }
2890 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2891 return value && propertyValue && value->equals(*propertyValue);
2892}
2893
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002894PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002895{
2896 return copyPropertiesInSet(computableProperties());
2897}
2898
2899PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) const
2900{
2901 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2902 for (size_t i = 0; i < shorthand.length(); ++i) {
2903 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
2904 list->append(value);
2905 }
2906 return list.release();
2907}
2908
2909PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand& shorthand) const
2910{
2911 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2912 // Assume the properties are in the usual order top, right, bottom, left.
2913 RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
2914 RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
2915 RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
2916 RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
2917
2918 // All 4 properties must be specified.
2919 if (!topValue || !rightValue || !bottomValue || !leftValue)
2920 return 0;
2921
2922 bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
2923 bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
2924 bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;
2925
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002926 list->append(topValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002927 if (showRight)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002928 list->append(rightValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002929 if (showBottom)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002930 list->append(bottomValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002931 if (showLeft)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002932 list->append(leftValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002933
2934 return list.release();
2935}
2936
2937PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) const
2938{
2939 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
2940 for (size_t i = 0; i < shorthand.length(); ++i) {
2941 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002942 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002943 }
2944 return list.release();
2945}
2946
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002947PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002948{
2949 Vector<CSSProperty, 256> list;
2950 list.reserveInitialCapacity(properties.size());
2951 for (unsigned i = 0; i < properties.size(); ++i) {
2952 RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
2953 if (value)
2954 list.append(CSSProperty(properties[i], value.release(), false));
2955 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002956 return MutableStylePropertySet::create(list.data(), list.size());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002957}
2958
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002959CSSRule* CSSComputedStyleDeclaration::parentRule() const
2960{
2961 return 0;
2962}
2963
2964PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
2965{
2966 CSSPropertyID propertyID = cssPropertyID(propertyName);
2967 if (!propertyID)
2968 return 0;
2969 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2970 return value ? value->cloneForCSSOM() : 0;
2971}
2972
2973String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
2974{
2975 CSSPropertyID propertyID = cssPropertyID(propertyName);
2976 if (!propertyID)
2977 return String();
2978 return getPropertyValue(propertyID);
2979}
2980
2981String CSSComputedStyleDeclaration::getPropertyPriority(const String&)
2982{
2983 // All computed styles have a priority of not "important".
2984 return "";
2985}
2986
2987String CSSComputedStyleDeclaration::getPropertyShorthand(const String&)
2988{
2989 return "";
2990}
2991
2992bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
2993{
2994 return false;
2995}
2996
2997void CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&, ExceptionCode& ec)
2998{
Ben Murdoche69819b2013-07-17 14:56:49 +01002999 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003000}
3001
3002String CSSComputedStyleDeclaration::removeProperty(const String&, ExceptionCode& ec)
3003{
Ben Murdoche69819b2013-07-17 14:56:49 +01003004 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003005 return String();
3006}
3007
3008PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
3009{
3010 return getPropertyCSSValue(propertyID);
3011}
3012
3013String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
3014{
3015 return getPropertyValue(propertyID);
3016}
3017
3018void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool, ExceptionCode& ec)
3019{
Ben Murdoche69819b2013-07-17 14:56:49 +01003020 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003021}
3022
Ben Murdoch7757ec22013-07-23 11:17:36 +01003023const HashMap<AtomicString, String>* CSSComputedStyleDeclaration::variableMap() const
3024{
3025 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3026 Node* styledNode = this->styledNode();
3027 if (!styledNode)
3028 return 0;
3029 RefPtr<RenderStyle> style = styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
3030 if (!style)
3031 return 0;
3032 return style->variables();
3033}
3034
3035unsigned CSSComputedStyleDeclaration::variableCount() const
3036{
3037 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3038 const HashMap<AtomicString, String>* variables = variableMap();
3039 if (!variables)
3040 return 0;
3041 return variables->size();
3042}
3043
3044String CSSComputedStyleDeclaration::variableValue(const AtomicString& name) const
3045{
3046 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3047 const HashMap<AtomicString, String>* variables = variableMap();
3048 if (!variables)
3049 return emptyString();
3050 HashMap<AtomicString, String>::const_iterator it = variables->find(name);
3051 if (it == variables->end())
3052 return emptyString();
3053 return it->value;
3054}
3055
3056void CSSComputedStyleDeclaration::setVariableValue(const AtomicString&, const String&, ExceptionCode& ec)
3057{
3058 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3059 ec = NoModificationAllowedError;
3060}
3061
3062bool CSSComputedStyleDeclaration::removeVariable(const AtomicString&)
3063{
3064 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3065 return false;
3066}
3067
3068void CSSComputedStyleDeclaration::clearVariables(ExceptionCode& ec)
3069{
3070 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3071 ec = NoModificationAllowedError;
3072}
3073
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003074PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getBackgroundShorthandValue() const
3075{
3076 static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage,
3077 CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment,
3078 CSSPropertyBackgroundPosition };
3079 static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin,
3080 CSSPropertyBackgroundClip };
3081
3082 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01003083 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator))));
3084 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator))));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003085 return list.release();
3086}
3087
3088} // namespace WebCore