blob: 5cce9ab2ffd5944d1af41caf55e0c6c0a33320e2 [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
650PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
651{
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
658static PassRefPtr<CSSValueList> getBorderRadiusCornerValues(LengthSize radius, const RenderStyle* style, RenderView* renderView)
659{
660 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
661 if (radius.width().type() == Percent)
662 list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
663 else
664 list->append(zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style));
665 if (radius.height().type() == Percent)
666 list->append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
667 else
668 list->append(zoomAdjustedPixelValue(valueForLength(radius.height(), 0, renderView), style));
669 return list.release();
670}
671
672static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, RenderView* renderView)
673{
674 if (radius.width() == radius.height()) {
675 if (radius.width().type() == Percent)
676 return cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
677 return zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style);
678 }
679 return getBorderRadiusCornerValues(radius, style, renderView);
680}
681
682static PassRefPtr<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* style, RenderView* renderView)
683{
684 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
685 bool showHorizontalBottomLeft = style->borderTopRightRadius().width() != style->borderBottomLeftRadius().width();
686 bool showHorizontalBottomRight = style->borderBottomRightRadius().width() != style->borderTopLeftRadius().width();
687 bool showHorizontalTopRight = style->borderTopRightRadius().width() != style->borderTopLeftRadius().width();
688
689 bool showVerticalBottomLeft = style->borderTopRightRadius().height() != style->borderBottomLeftRadius().height();
690 bool showVerticalBottomRight = (style->borderBottomRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomLeft;
691 bool showVerticalTopRight = (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomRight;
692 bool showVerticalTopLeft = (style->borderTopLeftRadius().width() != style->borderTopLeftRadius().height());
693
694 RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style->borderTopLeftRadius(), style, renderView);
695 RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style->borderTopRightRadius(), style, renderView);
696 RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style->borderBottomRightRadius(), style, renderView);
697 RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style->borderBottomLeftRadius(), style, renderView);
698
699 RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
700 horizontalRadii->append(topLeftRadius->item(0));
701 if (showHorizontalTopRight)
702 horizontalRadii->append(topRightRadius->item(0));
703 if (showHorizontalBottomRight)
704 horizontalRadii->append(bottomRightRadius->item(0));
705 if (showHorizontalBottomLeft)
706 horizontalRadii->append(bottomLeftRadius->item(0));
707
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100708 list->append(horizontalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100709
710 if (showVerticalTopLeft) {
711 RefPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated();
712 verticalRadii->append(topLeftRadius->item(1));
713 if (showVerticalTopRight)
714 verticalRadii->append(topRightRadius->item(1));
715 if (showVerticalBottomRight)
716 verticalRadii->append(bottomRightRadius->item(1));
717 if (showVerticalBottomLeft)
718 verticalRadii->append(bottomLeftRadius->item(1));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100719 list->append(verticalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100720 }
721 return list.release();
722}
723
724static LayoutRect sizingBox(RenderObject* renderer)
725{
726 if (!renderer->isBox())
727 return LayoutRect();
728
729 RenderBox* box = toRenderBox(renderer);
730 return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect();
731}
732
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100733static PassRefPtr<CSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle* style)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100734{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100735 RefPtr<CSSTransformValue> transformValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100736 if (transform.isAffine()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100737 transformValue = CSSTransformValue::create(CSSTransformValue::MatrixTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100738
739 transformValue->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
740 transformValue->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
741 transformValue->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
742 transformValue->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
743 transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
744 transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
745 } else {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100746 transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100747
748 transformValue->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
749 transformValue->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
750 transformValue->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
751 transformValue->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
752
753 transformValue->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
754 transformValue->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
755 transformValue->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
756 transformValue->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
757
758 transformValue->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
759 transformValue->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
760 transformValue->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
761 transformValue->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
762
763 transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
764 transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
765 transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
766 transformValue->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
767 }
768
769 return transformValue.release();
770}
771
772static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style)
773{
774 if (!renderer || !renderer->hasTransform() || !style->hasTransform())
775 return cssValuePool().createIdentifierValue(CSSValueNone);
776
777 IntRect box;
778 if (renderer->isBox())
779 box = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect());
780
781 TransformationMatrix transform;
782 style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
783
784 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
785 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
786 list->append(matrixTransformValue(transform, style));
787
788 return list.release();
789}
790
791static PassRefPtr<CSSValue> valueForCustomFilterArrayParameter(const CustomFilterArrayParameter* arrayParameter)
792{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100793 RefPtr<CSSArrayFunctionValue> arrayParameterValue = CSSArrayFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100794 for (unsigned i = 0, size = arrayParameter->size(); i < size; ++i)
795 arrayParameterValue->append(cssValuePool().createValue(arrayParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
796 return arrayParameterValue.release();
797}
798
799static PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter)
800{
801 RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated();
802 for (unsigned i = 0; i < numberParameter->size(); ++i)
803 numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
804 return numberParameterValue.release();
805}
806
807static PassRefPtr<CSSValue> valueForCustomFilterTransformParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterTransformParameter* transformParameter)
808{
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100809 IntSize size;
810 if (renderer && renderer->isBox())
811 size = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()).size();
812
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100813 TransformationMatrix transform;
814 transformParameter->applyTransform(transform, size);
815 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
816 return matrixTransformValue(transform, style);
817}
818
819static PassRefPtr<CSSValue> valueForCustomFilterParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterParameter* parameter)
820{
821 // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture.
822 ASSERT(parameter);
823 switch (parameter->parameterType()) {
824 case CustomFilterParameter::ARRAY:
825 return valueForCustomFilterArrayParameter(static_cast<const CustomFilterArrayParameter*>(parameter));
826 case CustomFilterParameter::NUMBER:
827 return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter));
828 case CustomFilterParameter::TRANSFORM:
829 return valueForCustomFilterTransformParameter(renderer, style, static_cast<const CustomFilterTransformParameter*>(parameter));
830 }
831
832 ASSERT_NOT_REACHED();
833 return 0;
834}
835
836PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle* style) const
837{
838 if (style->filter().operations().isEmpty())
839 return cssValuePool().createIdentifierValue(CSSValueNone);
840
841 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
842
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100843 RefPtr<CSSFilterValue> filterValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100844
845 Vector<RefPtr<FilterOperation> >::const_iterator end = style->filter().operations().end();
846 for (Vector<RefPtr<FilterOperation> >::const_iterator it = style->filter().operations().begin(); it != end; ++it) {
847 FilterOperation* filterOperation = (*it).get();
848 switch (filterOperation->getOperationType()) {
849 case FilterOperation::REFERENCE: {
850 ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100851 filterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100852 filterValue->append(cssValuePool().createValue(referenceOperation->url(), CSSPrimitiveValue::CSS_STRING));
853 break;
854 }
855 case FilterOperation::GRAYSCALE: {
856 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100857 filterValue = CSSFilterValue::create(CSSFilterValue::GrayscaleFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100858 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
859 break;
860 }
861 case FilterOperation::SEPIA: {
862 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100863 filterValue = CSSFilterValue::create(CSSFilterValue::SepiaFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100864 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
865 break;
866 }
867 case FilterOperation::SATURATE: {
868 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100869 filterValue = CSSFilterValue::create(CSSFilterValue::SaturateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100870 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
871 break;
872 }
873 case FilterOperation::HUE_ROTATE: {
874 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100875 filterValue = CSSFilterValue::create(CSSFilterValue::HueRotateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100876 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_DEG));
877 break;
878 }
879 case FilterOperation::INVERT: {
880 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100881 filterValue = CSSFilterValue::create(CSSFilterValue::InvertFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100882 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
883 break;
884 }
885 case FilterOperation::OPACITY: {
886 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100887 filterValue = CSSFilterValue::create(CSSFilterValue::OpacityFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100888 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
889 break;
890 }
891 case FilterOperation::BRIGHTNESS: {
892 BasicComponentTransferFilterOperation* brightnessOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100893 filterValue = CSSFilterValue::create(CSSFilterValue::BrightnessFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100894 filterValue->append(cssValuePool().createValue(brightnessOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
895 break;
896 }
897 case FilterOperation::CONTRAST: {
898 BasicComponentTransferFilterOperation* contrastOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100899 filterValue = CSSFilterValue::create(CSSFilterValue::ContrastFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100900 filterValue->append(cssValuePool().createValue(contrastOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
901 break;
902 }
903 case FilterOperation::BLUR: {
904 BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100905 filterValue = CSSFilterValue::create(CSSFilterValue::BlurFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100906 filterValue->append(zoomAdjustedPixelValue(blurOperation->stdDeviation().value(), style));
907 break;
908 }
909 case FilterOperation::DROP_SHADOW: {
910 DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100911 filterValue = CSSFilterValue::create(CSSFilterValue::DropShadowFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100912 // 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 +0100913 OwnPtr<ShadowData> shadow = ShadowData::create(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, dropShadowOperation->color());
914 filterValue->append(valueForShadow(shadow.get(), CSSPropertyTextShadow, style));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100915 break;
916 }
917 case FilterOperation::VALIDATED_CUSTOM:
918 // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
919 ASSERT_NOT_REACHED();
920 break;
921 case FilterOperation::CUSTOM: {
922 CustomFilterOperation* customOperation = static_cast<CustomFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100923 filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100924
925 // The output should be verbose, even if the values are the default ones.
926
927 ASSERT(customOperation->program());
928 StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program());
929
930 RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
931 if (program->vertexShader())
932 shadersList->append(program->vertexShader()->cssValue());
933 else
934 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
935
936 const CustomFilterProgramMixSettings mixSettings = program->mixSettings();
937 if (program->fragmentShader()) {
938 if (program->programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100939 RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100940 mixFunction->append(program->fragmentShader()->cssValue());
941 mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
942 mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
943 shadersList->append(mixFunction.release());
944 } else
945 shadersList->append(program->fragmentShader()->cssValue());
946 }
947 else
948 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
949
950 filterValue->append(shadersList.release());
951
952 RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated();
953 meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER));
954 meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
955
956 // FIXME: The specification doesn't have any "attached" identifier. Should we add one?
957 // https://bugs.webkit.org/show_bug.cgi?id=72700
958 if (customOperation->meshType() == MeshTypeDetached)
959 meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached));
960
961 filterValue->append(meshParameters.release());
962
963 const CustomFilterParameterList& parameters = customOperation->parameters();
964 size_t parametersSize = parameters.size();
965 if (!parametersSize)
966 break;
967 RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated();
968 for (size_t i = 0; i < parametersSize; ++i) {
969 const CustomFilterParameter* parameter = parameters.at(i).get();
970 RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated();
971 parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING));
972 parameterCSSNameAndValue->append(valueForCustomFilterParameter(renderer, style, parameter));
973 parametersCSSValue->append(parameterCSSNameAndValue.release());
974 }
975
976 filterValue->append(parametersCSSValue.release());
977 break;
978 }
979 default:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100980 filterValue = CSSFilterValue::create(CSSFilterValue::UnknownFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100981 break;
982 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100983 list->append(filterValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100984 }
985
986 return list.release();
987}
988
989static PassRefPtr<CSSValue> valueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle* style, RenderView* renderView)
990{
991 if (!trackBreadth.isLength()) {
992 String flex = String::number(trackBreadth.flex());
993 flex.append("fr");
994 return cssValuePool().createValue(flex, CSSPrimitiveValue::CSS_DIMENSION);
995 }
996
997 const Length& trackBreadthLength = trackBreadth.length();
998 if (trackBreadthLength.isAuto())
999 return cssValuePool().createIdentifierValue(CSSValueAuto);
1000 if (trackBreadthLength.isViewportPercentage())
1001 return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style);
1002 return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
1003}
1004
1005static PassRefPtr<CSSValue> valueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle* style, RenderView* renderView)
1006{
1007 switch (trackSize.type()) {
1008 case LengthTrackSizing:
1009 return valueForGridTrackBreadth(trackSize.length(), style, renderView);
1010 case MinMaxTrackSizing:
1011 RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1012 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView));
1013 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView));
1014 return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
1015 }
1016 ASSERT_NOT_REACHED();
1017 return 0;
1018}
1019
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001020static void addValuesForNamedGridLinesAtIndex(const NamedGridLinesMap& namedGridLines, size_t i, CSSValueList& list)
1021{
1022 // Note that this won't return the results in the order specified in the style sheet,
1023 // which is probably fine as we stil *do* return all the expected values.
1024 NamedGridLinesMap::const_iterator it = namedGridLines.begin();
1025 NamedGridLinesMap::const_iterator end = namedGridLines.end();
1026 for (; it != end; ++it) {
1027 const Vector<size_t>& linesIndexes = it->value;
1028 for (size_t j = 0; j < linesIndexes.size(); ++j) {
1029 if (linesIndexes[j] != i)
1030 continue;
1031
1032 list.append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1033 break;
1034 }
1035 }
1036}
1037
1038static PassRefPtr<CSSValue> valueForGridTrackList(const Vector<GridTrackSize>& trackSizes, const NamedGridLinesMap& namedGridLines, const RenderStyle* style, RenderView* renderView)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001039{
1040 // Handle the 'none' case here.
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001041 if (!trackSizes.size()) {
1042 ASSERT(namedGridLines.isEmpty());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001043 return cssValuePool().createIdentifierValue(CSSValueNone);
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001044 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001045
1046 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001047 for (size_t i = 0; i < trackSizes.size(); ++i) {
1048 addValuesForNamedGridLinesAtIndex(namedGridLines, i, *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001049 list->append(valueForGridTrackSize(trackSizes[i], style, renderView));
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001050 }
1051 // Those are the trailing <string>* allowed in the syntax.
1052 addValuesForNamedGridLinesAtIndex(namedGridLines, trackSizes.size(), *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001053 return list.release();
1054}
1055
1056static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
1057{
1058 if (position.isAuto())
1059 return cssValuePool().createIdentifierValue(CSSValueAuto);
1060
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001061 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001062 if (position.isSpan()) {
1063 list->append(cssValuePool().createIdentifierValue(CSSValueSpan));
1064 list->append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1065 } else
1066 list->append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1067
1068 if (!position.namedGridLine().isNull())
1069 list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001070 return list;
1071}
1072static PassRefPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation)
1073{
1074 RefPtr<CSSValue> propertyValue;
1075 if (animation->animationMode() == CSSAnimationData::AnimateNone)
1076 propertyValue = cssValuePool().createIdentifierValue(CSSValueNone);
1077 else if (animation->animationMode() == CSSAnimationData::AnimateAll)
1078 propertyValue = cssValuePool().createIdentifierValue(CSSValueAll);
1079 else
1080 propertyValue = cssValuePool().createValue(getPropertyNameString(animation->property()), CSSPrimitiveValue::CSS_STRING);
1081 return propertyValue.release();
1082}
1083static PassRefPtr<CSSValue> getTransitionPropertyValue(const CSSAnimationDataList* animList)
1084{
1085 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1086 if (animList) {
1087 for (size_t i = 0; i < animList->size(); ++i)
1088 list->append(createTransitionPropertyValue(animList->animation(i)));
1089 } else
1090 list->append(cssValuePool().createIdentifierValue(CSSValueAll));
1091 return list.release();
1092}
1093
1094static PassRefPtr<CSSValue> getDelayValue(const CSSAnimationDataList* animList)
1095{
1096 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1097 if (animList) {
1098 for (size_t i = 0; i < animList->size(); ++i)
1099 list->append(cssValuePool().createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
1100 } else {
1101 // Note that initialAnimationDelay() is used for both transitions and animations
1102 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
1103 }
1104 return list.release();
1105}
1106
1107static PassRefPtr<CSSValue> getDurationValue(const CSSAnimationDataList* animList)
1108{
1109 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1110 if (animList) {
1111 for (size_t i = 0; i < animList->size(); ++i)
1112 list->append(cssValuePool().createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
1113 } else {
1114 // Note that initialAnimationDuration() is used for both transitions and animations
1115 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
1116 }
1117 return list.release();
1118}
1119
1120static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1121{
1122 if (timingFunction->isCubicBezierTimingFunction()) {
1123 const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
1124 if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1125 CSSValueID valueId = CSSValueInvalid;
1126 switch (bezierTimingFunction->timingFunctionPreset()) {
1127 case CubicBezierTimingFunction::Ease:
1128 valueId = CSSValueEase;
1129 break;
1130 case CubicBezierTimingFunction::EaseIn:
1131 valueId = CSSValueEaseIn;
1132 break;
1133 case CubicBezierTimingFunction::EaseOut:
1134 valueId = CSSValueEaseOut;
1135 break;
1136 case CubicBezierTimingFunction::EaseInOut:
1137 valueId = CSSValueEaseInOut;
1138 break;
1139 default:
1140 ASSERT_NOT_REACHED();
1141 return 0;
1142 }
1143 return cssValuePool().createIdentifierValue(valueId);
1144 }
1145 return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
1146 }
1147
1148 if (timingFunction->isStepsTimingFunction()) {
1149 const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
1150 return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
1151 }
1152
1153 return CSSLinearTimingFunctionValue::create();
1154}
1155
1156static PassRefPtr<CSSValue> getTimingFunctionValue(const CSSAnimationDataList* animList)
1157{
1158 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1159 if (animList) {
1160 for (size_t i = 0; i < animList->size(); ++i)
1161 list->append(createTimingFunctionValue(animList->animation(i)->timingFunction().get()));
1162 } else
1163 // Note that initialAnimationTimingFunction() is used for both transitions and animations
1164 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
1165 return list.release();
1166}
1167
1168static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1169{
1170 if (!lineBoxContain)
1171 return cssValuePool().createIdentifierValue(CSSValueNone);
1172 return CSSLineBoxContainValue::create(lineBoxContain);
1173}
1174
1175CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1176 : m_node(n)
1177 , m_allowVisitedStyle(allowVisitedStyle)
1178 , m_refCount(1)
1179{
1180 unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1181 m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
1182 AtomicString(pseudoElementName.substring(nameWithoutColonsStart))));
1183}
1184
1185CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1186{
1187}
1188
1189void CSSComputedStyleDeclaration::ref()
1190{
1191 ++m_refCount;
1192}
1193
1194void CSSComputedStyleDeclaration::deref()
1195{
1196 ASSERT(m_refCount);
1197 if (!--m_refCount)
1198 delete this;
1199}
1200
1201String CSSComputedStyleDeclaration::cssText() const
1202{
1203 StringBuilder result;
1204 const Vector<CSSPropertyID>& properties = computableProperties();
1205
1206 for (unsigned i = 0; i < properties.size(); i++) {
1207 if (i)
1208 result.append(' ');
1209 result.append(getPropertyName(properties[i]));
1210 result.append(": ", 2);
1211 result.append(getPropertyValue(properties[i]));
1212 result.append(';');
1213 }
1214
1215 return result.toString();
1216}
1217
1218void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
1219{
Ben Murdoche69819b2013-07-17 14:56:49 +01001220 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001221}
1222
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001223static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001224{
1225 ASSERT_ARG(keywordSize, keywordSize);
1226 ASSERT_ARG(keywordSize, keywordSize <= 8);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001227 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001228}
1229
1230PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
1231{
1232 if (!m_node)
1233 return 0;
1234
1235 m_node->document()->updateLayoutIgnorePendingStylesheets();
1236
1237 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1238 if (!style)
1239 return 0;
1240
1241 if (int keywordSize = style->fontDescription().keywordSize())
1242 return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
1243
1244
1245 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get());
1246}
1247
1248bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
1249{
1250 if (!m_node)
1251 return false;
1252
1253 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1254 if (!style)
1255 return false;
1256
1257 return style->fontDescription().useFixedDefaultSize();
1258}
1259
1260PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle* style) const
1261{
1262 if (!shadow)
1263 return cssValuePool().createIdentifierValue(CSSValueNone);
1264
1265 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1266 for (const ShadowData* s = shadow; s; s = s->next()) {
1267 RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style);
1268 RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style);
1269 RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style);
1270 RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : zoomAdjustedPixelValue(s->spread(), style);
1271 RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset);
1272 RefPtr<CSSPrimitiveValue> color = cssValuePool().createColorValue(s->color().rgb());
1273 list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
1274 }
1275 return list.release();
1276}
1277
1278PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const
1279{
1280 return getPropertyCSSValue(propertyID, UpdateLayout);
1281}
1282
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001283static CSSValueID identifierForFamily(const AtomicString& family)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001284{
1285 if (family == cursiveFamily)
1286 return CSSValueCursive;
1287 if (family == fantasyFamily)
1288 return CSSValueFantasy;
1289 if (family == monospaceFamily)
1290 return CSSValueMonospace;
1291 if (family == pictographFamily)
1292 return CSSValueWebkitPictograph;
1293 if (family == sansSerifFamily)
1294 return CSSValueSansSerif;
1295 if (family == serifFamily)
1296 return CSSValueSerif;
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001297 return CSSValueInvalid;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001298}
1299
1300static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1301{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001302 if (CSSValueID familyIdentifier = identifierForFamily(family))
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001303 return cssValuePool().createIdentifierValue(familyIdentifier);
1304 return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
1305}
1306
1307static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1308{
1309 // Blink value is ignored.
1310 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001311 if (textDecoration & TextDecorationUnderline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001312 list->append(cssValuePool().createIdentifierValue(CSSValueUnderline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001313 if (textDecoration & TextDecorationOverline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001314 list->append(cssValuePool().createIdentifierValue(CSSValueOverline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001315 if (textDecoration & TextDecorationLineThrough)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001316 list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough));
1317
1318 if (!list->length())
1319 return cssValuePool().createIdentifierValue(CSSValueNone);
Ben Murdoch591b9582013-07-10 11:41:44 +01001320 return list.release();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001321}
1322
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001323static PassRefPtr<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1324{
1325 switch (textDecorationStyle) {
1326 case TextDecorationStyleSolid:
1327 return cssValuePool().createIdentifierValue(CSSValueSolid);
1328 case TextDecorationStyleDouble:
1329 return cssValuePool().createIdentifierValue(CSSValueDouble);
1330 case TextDecorationStyleDotted:
1331 return cssValuePool().createIdentifierValue(CSSValueDotted);
1332 case TextDecorationStyleDashed:
1333 return cssValuePool().createIdentifierValue(CSSValueDashed);
1334 case TextDecorationStyleWavy:
1335 return cssValuePool().createIdentifierValue(CSSValueWavy);
1336 }
1337
1338 ASSERT_NOT_REACHED();
1339 return cssValuePool().createExplicitInitialValue();
1340}
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001341
1342static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1343{
1344 // For backwards compatibility, if both values are equal, just return one of them. And
1345 // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1346 if (xRepeat == yRepeat)
1347 return cssValuePool().createValue(xRepeat);
1348 if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1349 return cssValuePool().createIdentifierValue(CSSValueRepeatX);
1350 if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1351 return cssValuePool().createIdentifierValue(CSSValueRepeatY);
1352
1353 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1354 list->append(cssValuePool().createValue(xRepeat));
1355 list->append(cssValuePool().createValue(yRepeat));
1356 return list.release();
1357}
1358
1359static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style)
1360{
1361 if (fillSize.type == Contain)
1362 return cssValuePool().createIdentifierValue(CSSValueContain);
1363
1364 if (fillSize.type == Cover)
1365 return cssValuePool().createIdentifierValue(CSSValueCover);
1366
1367 if (fillSize.size.height().isAuto())
1368 return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1369
1370 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1371 list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1372 list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1373 return list.release();
1374}
1375
1376static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style)
1377{
1378 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1379 for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1380 if (contentData->isCounter()) {
1381 const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter();
1382 ASSERT(counter);
1383 list->append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1384 } else if (contentData->isImage()) {
1385 const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image();
1386 ASSERT(image);
1387 list->append(image->cssValue());
1388 } else if (contentData->isText())
1389 list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING));
1390 }
1391 if (!style->regionThread().isNull())
1392 list->append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1393 return list.release();
1394}
1395
1396static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1397{
1398 const CounterDirectiveMap* map = style->counterDirectives();
1399 if (!map)
1400 return 0;
1401
1402 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1403 for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1404 list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1405 short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1406 list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1407 }
1408 return list.release();
1409}
1410
1411static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1412{
1413 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ());
1414 if (!propertyIDSet.add(propertyID).isNewEntry)
1415 return;
1416
1417 LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1418}
1419
1420static PassRefPtr<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
1421{
1422 const FontFamily& firstFamily = style->fontDescription().family();
1423 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1424 for (const FontFamily* family = &firstFamily; family; family = family->next())
1425 list->append(valueForFamily(family->family()));
1426 return list.release();
1427}
1428
1429static PassRefPtr<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style, RenderView* renderView)
1430{
1431 Length length = style->lineHeight();
1432 if (length.isNegative())
1433 return cssValuePool().createIdentifierValue(CSSValueNormal);
1434 if (length.isPercent())
1435 // This is imperfect, because it doesn't include the zoom factor and the real computation
1436 // for how high to be in pixels does include things like minimum font size and the zoom factor.
1437 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1438 // that here either.
1439 return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style);
1440 return zoomAdjustedPixelValue(valueForLength(length, 0, renderView), style);
1441}
1442
1443static PassRefPtr<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style)
1444{
1445 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style);
1446}
1447
1448static PassRefPtr<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
1449{
1450 if (style->fontDescription().italic())
1451 return cssValuePool().createIdentifierValue(CSSValueItalic);
1452 return cssValuePool().createIdentifierValue(CSSValueNormal);
1453}
1454
1455static PassRefPtr<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style)
1456{
1457 if (style->fontDescription().smallCaps())
1458 return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
1459 return cssValuePool().createIdentifierValue(CSSValueNormal);
1460}
1461
1462static PassRefPtr<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
1463{
1464 switch (style->fontDescription().weight()) {
1465 case FontWeight100:
1466 return cssValuePool().createIdentifierValue(CSSValue100);
1467 case FontWeight200:
1468 return cssValuePool().createIdentifierValue(CSSValue200);
1469 case FontWeight300:
1470 return cssValuePool().createIdentifierValue(CSSValue300);
1471 case FontWeightNormal:
1472 return cssValuePool().createIdentifierValue(CSSValueNormal);
1473 case FontWeight500:
1474 return cssValuePool().createIdentifierValue(CSSValue500);
1475 case FontWeight600:
1476 return cssValuePool().createIdentifierValue(CSSValue600);
1477 case FontWeightBold:
1478 return cssValuePool().createIdentifierValue(CSSValueBold);
1479 case FontWeight800:
1480 return cssValuePool().createIdentifierValue(CSSValue800);
1481 case FontWeight900:
1482 return cssValuePool().createIdentifierValue(CSSValue900);
1483 }
1484 ASSERT_NOT_REACHED();
1485 return cssValuePool().createIdentifierValue(CSSValueNormal);
1486}
1487
Ben Murdoch591b9582013-07-10 11:41:44 +01001488static bool isLayoutDependent(CSSPropertyID propertyID, PassRefPtr<RenderStyle> style, RenderObject* renderer)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001489{
Ben Murdoch591b9582013-07-10 11:41:44 +01001490 // Some properties only depend on layout in certain conditions which
1491 // are specified in the main switch statement below. So we can avoid
1492 // forcing layout in those conditions. The conditions in this switch
1493 // statement must remain in sync with the conditions in the main switch.
1494 // FIXME: Some of these cases could be narrowed down or optimized better.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001495 switch (propertyID) {
1496 case CSSPropertyBottom:
1497 case CSSPropertyHeight:
1498 case CSSPropertyLeft:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001499 case CSSPropertyRight:
1500 case CSSPropertyTop:
1501 case CSSPropertyWebkitPerspectiveOrigin:
1502 case CSSPropertyWebkitTransform:
1503 case CSSPropertyWebkitTransformOrigin:
1504 case CSSPropertyWidth:
1505 case CSSPropertyWebkitFilter:
1506 return true;
Ben Murdoch591b9582013-07-10 11:41:44 +01001507 case CSSPropertyMargin:
1508 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed() || !style->marginTop().isFixed() || !style->marginLeft().isFixed() || !style->marginRight().isFixed());
1509 case CSSPropertyMarginLeft:
1510 return renderer && renderer->isBox() && (!style || !style->marginLeft().isFixed());
1511 case CSSPropertyMarginRight:
1512 return renderer && renderer->isBox() && (!style || !style->marginRight().isFixed());
1513 case CSSPropertyMarginTop:
1514 return renderer && renderer->isBox() && (!style || !style->marginTop().isFixed());
1515 case CSSPropertyMarginBottom:
1516 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed());
1517 case CSSPropertyPadding:
1518 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed() || !style->paddingTop().isFixed() || !style->paddingLeft().isFixed() || !style->paddingRight().isFixed());
1519 case CSSPropertyPaddingBottom:
1520 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed());
1521 case CSSPropertyPaddingLeft:
1522 return renderer && renderer->isBox() && (!style || !style->paddingLeft().isFixed());
1523 case CSSPropertyPaddingRight:
1524 return renderer && renderer->isBox() && (!style || !style->paddingRight().isFixed());
1525 case CSSPropertyPaddingTop:
1526 return renderer && renderer->isBox() && (!style || !style->paddingTop().isFixed());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001527 default:
1528 return false;
1529 }
1530}
1531
Ben Murdoch591b9582013-07-10 11:41:44 +01001532PassRefPtr<RenderStyle> CSSComputedStyleDeclaration::computeRenderStyle(CSSPropertyID propertyID) const
1533{
1534 Node* styledNode = this->styledNode();
1535 ASSERT(styledNode);
1536 RenderObject* renderer = styledNode->renderer();
Ben Murdoche69819b2013-07-17 14:56:49 +01001537 if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID) && !RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
Ben Murdoch591b9582013-07-10 11:41:44 +01001538 AnimationUpdateBlock animationUpdateBlock(renderer->animation());
1539 if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) {
1540 // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
1541 return renderer->animation()->getAnimatedStyleForRenderer(renderer)->getCachedPseudoStyle(m_pseudoElementSpecifier);
1542 }
1543 return renderer->animation()->getAnimatedStyleForRenderer(renderer);
1544 }
1545 return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
1546}
1547
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001548Node* CSSComputedStyleDeclaration::styledNode() const
1549{
1550 if (!m_node)
1551 return 0;
1552 if (m_node->isElementNode()) {
1553 if (PseudoElement* element = toElement(m_node.get())->pseudoElement(m_pseudoElementSpecifier))
1554 return element;
1555 }
1556 return m_node.get();
1557}
1558
1559PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1560{
1561 Node* styledNode = this->styledNode();
1562 if (!styledNode)
1563 return 0;
Ben Murdoch591b9582013-07-10 11:41:44 +01001564 RenderObject* renderer = styledNode->renderer();
1565 RefPtr<RenderStyle> style;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001566
1567 if (updateLayout) {
1568 Document* document = styledNode->document();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001569
Ben Murdoch591b9582013-07-10 11:41:44 +01001570 document->updateStyleForNodeIfNeeded(styledNode);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001571
1572 // The style recalc could have caused the styled node to be discarded or replaced
1573 // if it was a PseudoElement so we need to update it.
1574 styledNode = this->styledNode();
Ben Murdoch591b9582013-07-10 11:41:44 +01001575 renderer = styledNode->renderer();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001576
Ben Murdoch591b9582013-07-10 11:41:44 +01001577 style = computeRenderStyle(propertyID);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001578
Ben Murdoch591b9582013-07-10 11:41:44 +01001579 bool forceFullLayout = isLayoutDependent(propertyID, style, renderer)
1580 || styledNode->isInShadowTree()
1581 || (document->styleResolverIfExists() && document->styleResolverIfExists()->hasViewportDependentMediaQueries() && document->ownerElement())
1582 || document->seamlessParentIFrame();
1583
1584 if (forceFullLayout) {
1585 document->updateLayoutIgnorePendingStylesheets();
1586 styledNode = this->styledNode();
1587 style = computeRenderStyle(propertyID);
1588 renderer = styledNode->renderer();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001589 }
Ben Murdoch591b9582013-07-10 11:41:44 +01001590 } else {
1591 style = computeRenderStyle(propertyID);
1592 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001593
1594 if (!style)
1595 return 0;
1596
1597 propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
1598
1599 switch (propertyID) {
1600 case CSSPropertyInvalid:
1601 case CSSPropertyVariable:
1602 break;
1603
1604 case CSSPropertyBackgroundColor:
1605 return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
1606 case CSSPropertyBackgroundImage:
1607 case CSSPropertyWebkitMaskImage: {
1608 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
1609 if (!layers)
1610 return cssValuePool().createIdentifierValue(CSSValueNone);
1611
1612 if (!layers->next()) {
1613 if (layers->image())
1614 return layers->image()->cssValue();
1615
1616 return cssValuePool().createIdentifierValue(CSSValueNone);
1617 }
1618
1619 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1620 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1621 if (currLayer->image())
1622 list->append(currLayer->image()->cssValue());
1623 else
1624 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1625 }
1626 return list.release();
1627 }
1628 case CSSPropertyBackgroundSize:
1629 case CSSPropertyWebkitBackgroundSize:
1630 case CSSPropertyWebkitMaskSize: {
1631 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
1632 if (!layers->next())
1633 return fillSizeToCSSValue(layers->size(), style.get());
1634
1635 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1636 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1637 list->append(fillSizeToCSSValue(currLayer->size(), style.get()));
1638
1639 return list.release();
1640 }
1641 case CSSPropertyBackgroundRepeat:
1642 case CSSPropertyWebkitMaskRepeat: {
1643 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
1644 if (!layers->next())
1645 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
1646
1647 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1648 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1649 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
1650
1651 return list.release();
1652 }
1653 case CSSPropertyWebkitBackgroundComposite:
1654 case CSSPropertyWebkitMaskComposite: {
1655 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
1656 if (!layers->next())
1657 return cssValuePool().createValue(layers->composite());
1658
1659 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1660 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1661 list->append(cssValuePool().createValue(currLayer->composite()));
1662
1663 return list.release();
1664 }
1665 case CSSPropertyBackgroundAttachment: {
1666 const FillLayer* layers = style->backgroundLayers();
1667 if (!layers->next())
1668 return cssValuePool().createValue(layers->attachment());
1669
1670 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1671 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1672 list->append(cssValuePool().createValue(currLayer->attachment()));
1673
1674 return list.release();
1675 }
1676 case CSSPropertyBackgroundClip:
1677 case CSSPropertyBackgroundOrigin:
1678 case CSSPropertyWebkitBackgroundClip:
1679 case CSSPropertyWebkitBackgroundOrigin:
1680 case CSSPropertyWebkitMaskClip:
1681 case CSSPropertyWebkitMaskOrigin: {
1682 const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
1683 bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
1684 if (!layers->next()) {
1685 EFillBox box = isClip ? layers->clip() : layers->origin();
1686 return cssValuePool().createValue(box);
1687 }
1688
1689 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1690 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1691 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
1692 list->append(cssValuePool().createValue(box));
1693 }
1694
1695 return list.release();
1696 }
1697 case CSSPropertyBackgroundPosition:
1698 case CSSPropertyWebkitMaskPosition: {
1699 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
1700 if (!layers->next())
1701 return createPositionListForLayer(propertyID, layers, style.get());
1702
1703 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1704 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1705 list->append(createPositionListForLayer(propertyID, currLayer, style.get()));
1706 return list.release();
1707 }
1708 case CSSPropertyBackgroundPositionX:
1709 case CSSPropertyWebkitMaskPositionX: {
1710 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
1711 if (!layers->next())
1712 return cssValuePool().createValue(layers->xPosition());
1713
1714 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1715 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1716 list->append(cssValuePool().createValue(currLayer->xPosition()));
1717
1718 return list.release();
1719 }
1720 case CSSPropertyBackgroundPositionY:
1721 case CSSPropertyWebkitMaskPositionY: {
1722 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
1723 if (!layers->next())
1724 return cssValuePool().createValue(layers->yPosition());
1725
1726 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1727 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1728 list->append(cssValuePool().createValue(currLayer->yPosition()));
1729
1730 return list.release();
1731 }
1732 case CSSPropertyBorderCollapse:
1733 if (style->borderCollapse())
1734 return cssValuePool().createIdentifierValue(CSSValueCollapse);
1735 return cssValuePool().createIdentifierValue(CSSValueSeparate);
1736 case CSSPropertyBorderSpacing: {
1737 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1738 list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()));
1739 list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()));
1740 return list.release();
1741 }
1742 case CSSPropertyWebkitBorderHorizontalSpacing:
1743 return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get());
1744 case CSSPropertyWebkitBorderVerticalSpacing:
1745 return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get());
1746 case CSSPropertyBorderImageSource:
1747 if (style->borderImageSource())
1748 return style->borderImageSource()->cssValue();
1749 return cssValuePool().createIdentifierValue(CSSValueNone);
1750 case CSSPropertyBorderTopColor:
1751 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
1752 case CSSPropertyBorderRightColor:
1753 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
1754 case CSSPropertyBorderBottomColor:
1755 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
1756 case CSSPropertyBorderLeftColor:
1757 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
1758 case CSSPropertyBorderTopStyle:
1759 return cssValuePool().createValue(style->borderTopStyle());
1760 case CSSPropertyBorderRightStyle:
1761 return cssValuePool().createValue(style->borderRightStyle());
1762 case CSSPropertyBorderBottomStyle:
1763 return cssValuePool().createValue(style->borderBottomStyle());
1764 case CSSPropertyBorderLeftStyle:
1765 return cssValuePool().createValue(style->borderLeftStyle());
1766 case CSSPropertyBorderTopWidth:
1767 return zoomAdjustedPixelValue(style->borderTopWidth(), style.get());
1768 case CSSPropertyBorderRightWidth:
1769 return zoomAdjustedPixelValue(style->borderRightWidth(), style.get());
1770 case CSSPropertyBorderBottomWidth:
1771 return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get());
1772 case CSSPropertyBorderLeftWidth:
1773 return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get());
1774 case CSSPropertyBottom:
1775 return getPositionOffsetValue(style.get(), CSSPropertyBottom, renderer, m_node->document()->renderView());
1776 case CSSPropertyWebkitBoxAlign:
1777 return cssValuePool().createValue(style->boxAlign());
1778 case CSSPropertyWebkitBoxDecorationBreak:
1779 if (style->boxDecorationBreak() == DSLICE)
1780 return cssValuePool().createIdentifierValue(CSSValueSlice);
1781 return cssValuePool().createIdentifierValue(CSSValueClone);
1782 case CSSPropertyWebkitBoxDirection:
1783 return cssValuePool().createValue(style->boxDirection());
1784 case CSSPropertyWebkitBoxFlex:
1785 return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
1786 case CSSPropertyWebkitBoxFlexGroup:
1787 return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
1788 case CSSPropertyWebkitBoxLines:
1789 return cssValuePool().createValue(style->boxLines());
1790 case CSSPropertyWebkitBoxOrdinalGroup:
1791 return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
1792 case CSSPropertyWebkitBoxOrient:
1793 return cssValuePool().createValue(style->boxOrient());
1794 case CSSPropertyWebkitBoxPack:
1795 return cssValuePool().createValue(style->boxPack());
1796 case CSSPropertyWebkitBoxReflect:
1797 return valueForReflection(style->boxReflect(), style.get());
1798 case CSSPropertyBoxShadow:
1799 case CSSPropertyWebkitBoxShadow:
1800 return valueForShadow(style->boxShadow(), propertyID, style.get());
1801 case CSSPropertyCaptionSide:
1802 return cssValuePool().createValue(style->captionSide());
1803 case CSSPropertyClear:
1804 return cssValuePool().createValue(style->clear());
1805 case CSSPropertyColor:
1806 return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
1807 case CSSPropertyWebkitPrintColorAdjust:
1808 return cssValuePool().createValue(style->printColorAdjust());
1809 case CSSPropertyWebkitColumnAxis:
1810 return cssValuePool().createValue(style->columnAxis());
1811 case CSSPropertyWebkitColumnCount:
1812 if (style->hasAutoColumnCount())
1813 return cssValuePool().createIdentifierValue(CSSValueAuto);
1814 return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
1815 case CSSPropertyWebkitColumnGap:
1816 if (style->hasNormalColumnGap())
1817 return cssValuePool().createIdentifierValue(CSSValueNormal);
1818 return zoomAdjustedPixelValue(style->columnGap(), style.get());
1819 case CSSPropertyWebkitColumnProgression:
1820 return cssValuePool().createValue(style->columnProgression());
1821 case CSSPropertyWebkitColumnRuleColor:
1822 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
1823 case CSSPropertyWebkitColumnRuleStyle:
1824 return cssValuePool().createValue(style->columnRuleStyle());
1825 case CSSPropertyWebkitColumnRuleWidth:
1826 return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get());
1827 case CSSPropertyWebkitColumnSpan:
1828 return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
1829 case CSSPropertyWebkitColumnBreakAfter:
1830 return cssValuePool().createValue(style->columnBreakAfter());
1831 case CSSPropertyWebkitColumnBreakBefore:
1832 return cssValuePool().createValue(style->columnBreakBefore());
1833 case CSSPropertyWebkitColumnBreakInside:
1834 return cssValuePool().createValue(style->columnBreakInside());
1835 case CSSPropertyWebkitColumnWidth:
1836 if (style->hasAutoColumnWidth())
1837 return cssValuePool().createIdentifierValue(CSSValueAuto);
1838 return zoomAdjustedPixelValue(style->columnWidth(), style.get());
1839 case CSSPropertyTabSize:
1840 return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
1841 case CSSPropertyWebkitRegionBreakAfter:
1842 return cssValuePool().createValue(style->regionBreakAfter());
1843 case CSSPropertyWebkitRegionBreakBefore:
1844 return cssValuePool().createValue(style->regionBreakBefore());
1845 case CSSPropertyWebkitRegionBreakInside:
1846 return cssValuePool().createValue(style->regionBreakInside());
1847 case CSSPropertyCursor: {
1848 RefPtr<CSSValueList> list;
1849 CursorList* cursors = style->cursors();
1850 if (cursors && cursors->size() > 0) {
1851 list = CSSValueList::createCommaSeparated();
1852 for (unsigned i = 0; i < cursors->size(); ++i)
1853 if (StyleImage* image = cursors->at(i).image())
1854 list->append(image->cssValue());
1855 }
1856 RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
1857 if (list) {
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001858 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001859 return list.release();
1860 }
1861 return value.release();
1862 }
1863 case CSSPropertyDirection:
1864 return cssValuePool().createValue(style->direction());
1865 case CSSPropertyDisplay:
1866 return cssValuePool().createValue(style->display());
1867 case CSSPropertyEmptyCells:
1868 return cssValuePool().createValue(style->emptyCells());
Ben Murdoch591b9582013-07-10 11:41:44 +01001869 case CSSPropertyAlignContent:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001870 return cssValuePool().createValue(style->alignContent());
Ben Murdoch591b9582013-07-10 11:41:44 +01001871 case CSSPropertyAlignItems:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001872 return cssValuePool().createValue(style->alignItems());
Ben Murdoch591b9582013-07-10 11:41:44 +01001873 case CSSPropertyAlignSelf:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001874 if (style->alignSelf() == AlignAuto) {
1875 Node* parent = styledNode->parentNode();
1876 if (parent && parent->computedStyle())
1877 return cssValuePool().createValue(parent->computedStyle()->alignItems());
1878 return cssValuePool().createValue(AlignStretch);
1879 }
1880 return cssValuePool().createValue(style->alignSelf());
Ben Murdoch591b9582013-07-10 11:41:44 +01001881 case CSSPropertyFlex:
1882 return getCSSPropertyValuesForShorthandProperties(flexShorthand());
1883 case CSSPropertyFlexBasis:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001884 return cssValuePool().createValue(style->flexBasis());
Ben Murdoch591b9582013-07-10 11:41:44 +01001885 case CSSPropertyFlexDirection:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001886 return cssValuePool().createValue(style->flexDirection());
Ben Murdoch591b9582013-07-10 11:41:44 +01001887 case CSSPropertyFlexFlow:
1888 return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
1889 case CSSPropertyFlexGrow:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001890 return cssValuePool().createValue(style->flexGrow());
Ben Murdoch591b9582013-07-10 11:41:44 +01001891 case CSSPropertyFlexShrink:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001892 return cssValuePool().createValue(style->flexShrink());
Ben Murdoch591b9582013-07-10 11:41:44 +01001893 case CSSPropertyFlexWrap:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001894 return cssValuePool().createValue(style->flexWrap());
Ben Murdoch591b9582013-07-10 11:41:44 +01001895 case CSSPropertyJustifyContent:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001896 return cssValuePool().createValue(style->justifyContent());
Ben Murdoch591b9582013-07-10 11:41:44 +01001897 case CSSPropertyOrder:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001898 return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
1899 case CSSPropertyFloat:
1900 if (style->display() != NONE && style->hasOutOfFlowPosition())
1901 return cssValuePool().createIdentifierValue(CSSValueNone);
1902 return cssValuePool().createValue(style->floating());
1903 case CSSPropertyFont: {
1904 RefPtr<FontValue> computedFont = FontValue::create();
1905 computedFont->style = fontStyleFromStyle(style.get());
1906 computedFont->variant = fontVariantFromStyle(style.get());
1907 computedFont->weight = fontWeightFromStyle(style.get());
1908 computedFont->size = fontSizeFromStyle(style.get());
1909 computedFont->lineHeight = lineHeightFromStyle(style.get(), m_node->document()->renderView());
1910 computedFont->family = fontFamilyFromStyle(style.get());
1911 return computedFont.release();
1912 }
1913 case CSSPropertyFontFamily: {
1914 RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get());
1915 // If there's only a single family, return that as a CSSPrimitiveValue.
1916 // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
1917 if (fontFamilyList->length() == 1)
1918 return fontFamilyList->item(0);
1919 return fontFamilyList.release();
1920 }
1921 case CSSPropertyFontSize:
1922 return fontSizeFromStyle(style.get());
1923 case CSSPropertyFontStyle:
1924 return fontStyleFromStyle(style.get());
1925 case CSSPropertyFontVariant:
1926 return fontVariantFromStyle(style.get());
1927 case CSSPropertyFontWeight:
1928 return fontWeightFromStyle(style.get());
1929 case CSSPropertyWebkitFontFeatureSettings: {
1930 const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings();
1931 if (!featureSettings || !featureSettings->size())
1932 return cssValuePool().createIdentifierValue(CSSValueNormal);
1933 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1934 for (unsigned i = 0; i < featureSettings->size(); ++i) {
1935 const FontFeature& feature = featureSettings->at(i);
1936 RefPtr<FontFeatureValue> featureValue = FontFeatureValue::create(feature.tag(), feature.value());
1937 list->append(featureValue.release());
1938 }
1939 return list.release();
1940 }
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001941 case CSSPropertyGridAutoColumns:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001942 return valueForGridTrackSize(style->gridAutoColumns(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001943 case CSSPropertyGridAutoFlow:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001944 return cssValuePool().createValue(style->gridAutoFlow());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001945 case CSSPropertyGridAutoRows:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001946 return valueForGridTrackSize(style->gridAutoRows(), style.get(), m_node->document()->renderView());
Ben Murdoch591b9582013-07-10 11:41:44 +01001947 case CSSPropertyGridDefinitionColumns:
1948 return valueForGridTrackList(style->gridDefinitionColumns(), style->namedGridColumnLines(), style.get(), m_node->document()->renderView());
1949 case CSSPropertyGridDefinitionRows:
1950 return valueForGridTrackList(style->gridDefinitionRows(), style->namedGridRowLines(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001951
Ben Murdoch591b9582013-07-10 11:41:44 +01001952 case CSSPropertyGridColumnStart:
1953 return valueForGridPosition(style->gridColumnStart());
1954 case CSSPropertyGridColumnEnd:
1955 return valueForGridPosition(style->gridColumnEnd());
1956 case CSSPropertyGridRowStart:
1957 return valueForGridPosition(style->gridRowStart());
1958 case CSSPropertyGridRowEnd:
1959 return valueForGridPosition(style->gridRowEnd());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001960 case CSSPropertyGridColumn:
1961 return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
1962 case CSSPropertyGridRow:
1963 return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
1964 case CSSPropertyGridArea:
1965 return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001966
1967 case CSSPropertyHeight:
1968 if (renderer) {
1969 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
1970 // the "height" property does not apply for non-replaced inline elements.
1971 if (!renderer->isReplaced() && renderer->isInline())
1972 return cssValuePool().createIdentifierValue(CSSValueAuto);
1973 return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get());
1974 }
1975 return zoomAdjustedPixelValueForLength(style->height(), style.get());
1976 case CSSPropertyWebkitHighlight:
1977 if (style->highlight() == nullAtom)
1978 return cssValuePool().createIdentifierValue(CSSValueNone);
1979 return cssValuePool().createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
1980 case CSSPropertyWebkitHyphens:
1981 return cssValuePool().createValue(style->hyphens());
1982 case CSSPropertyWebkitHyphenateCharacter:
1983 if (style->hyphenationString().isNull())
1984 return cssValuePool().createIdentifierValue(CSSValueAuto);
1985 return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
1986 case CSSPropertyWebkitHyphenateLimitAfter:
1987 if (style->hyphenationLimitAfter() < 0)
1988 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1989 return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
1990 case CSSPropertyWebkitHyphenateLimitBefore:
1991 if (style->hyphenationLimitBefore() < 0)
1992 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1993 return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
1994 case CSSPropertyWebkitHyphenateLimitLines:
1995 if (style->hyphenationLimitLines() < 0)
1996 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
1997 return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
1998 case CSSPropertyWebkitBorderFit:
1999 if (style->borderFit() == BorderFitBorder)
2000 return cssValuePool().createIdentifierValue(CSSValueBorder);
2001 return cssValuePool().createIdentifierValue(CSSValueLines);
2002 case CSSPropertyImageRendering:
2003 return CSSPrimitiveValue::create(style->imageRendering());
2004 case CSSPropertyLeft:
2005 return getPositionOffsetValue(style.get(), CSSPropertyLeft, renderer, m_node->document()->renderView());
2006 case CSSPropertyLetterSpacing:
2007 if (!style->letterSpacing())
2008 return cssValuePool().createIdentifierValue(CSSValueNormal);
2009 return zoomAdjustedPixelValue(style->letterSpacing(), style.get());
2010 case CSSPropertyWebkitLineClamp:
2011 if (style->lineClamp().isNone())
2012 return cssValuePool().createIdentifierValue(CSSValueNone);
2013 return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2014 case CSSPropertyLineHeight:
2015 return lineHeightFromStyle(style.get(), m_node->document()->renderView());
2016 case CSSPropertyListStyleImage:
2017 if (style->listStyleImage())
2018 return style->listStyleImage()->cssValue();
2019 return cssValuePool().createIdentifierValue(CSSValueNone);
2020 case CSSPropertyListStylePosition:
2021 return cssValuePool().createValue(style->listStylePosition());
2022 case CSSPropertyListStyleType:
2023 return cssValuePool().createValue(style->listStyleType());
2024 case CSSPropertyWebkitLocale:
2025 if (style->locale().isNull())
2026 return cssValuePool().createIdentifierValue(CSSValueAuto);
2027 return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2028 case CSSPropertyMarginTop: {
2029 Length marginTop = style->marginTop();
2030 if (marginTop.isFixed() || !renderer || !renderer->isBox())
2031 return zoomAdjustedPixelValueForLength(marginTop, style.get());
2032 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginTop(), style.get());
2033 }
2034 case CSSPropertyMarginRight: {
2035 Length marginRight = style->marginRight();
2036 if (marginRight.isFixed() || !renderer || !renderer->isBox())
2037 return zoomAdjustedPixelValueForLength(marginRight, style.get());
2038 float value;
2039 if (marginRight.isPercent() || marginRight.isViewportPercentage())
2040 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2041 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2042 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2043 value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document()->renderView());
2044 else
2045 value = toRenderBox(renderer)->marginRight();
2046 return zoomAdjustedPixelValue(value, style.get());
2047 }
2048 case CSSPropertyMarginBottom: {
2049 Length marginBottom = style->marginBottom();
2050 if (marginBottom.isFixed() || !renderer || !renderer->isBox())
2051 return zoomAdjustedPixelValueForLength(marginBottom, style.get());
2052 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginBottom(), style.get());
2053 }
2054 case CSSPropertyMarginLeft: {
2055 Length marginLeft = style->marginLeft();
2056 if (marginLeft.isFixed() || !renderer || !renderer->isBox())
2057 return zoomAdjustedPixelValueForLength(marginLeft, style.get());
2058 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginLeft(), style.get());
2059 }
2060 case CSSPropertyWebkitMarqueeDirection:
2061 return cssValuePool().createValue(style->marqueeDirection());
2062 case CSSPropertyWebkitMarqueeIncrement:
2063 return cssValuePool().createValue(style->marqueeIncrement());
2064 case CSSPropertyWebkitMarqueeRepetition:
2065 if (style->marqueeLoopCount() < 0)
2066 return cssValuePool().createIdentifierValue(CSSValueInfinite);
2067 return cssValuePool().createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
2068 case CSSPropertyWebkitMarqueeStyle:
2069 return cssValuePool().createValue(style->marqueeBehavior());
2070 case CSSPropertyWebkitUserModify:
2071 return cssValuePool().createValue(style->userModify());
2072 case CSSPropertyMaxHeight: {
2073 const Length& maxHeight = style->maxHeight();
2074 if (maxHeight.isUndefined())
2075 return cssValuePool().createIdentifierValue(CSSValueNone);
2076 return zoomAdjustedPixelValueForLength(maxHeight, style.get());
2077 }
2078 case CSSPropertyMaxWidth: {
2079 const Length& maxWidth = style->maxWidth();
2080 if (maxWidth.isUndefined())
2081 return cssValuePool().createIdentifierValue(CSSValueNone);
2082 return zoomAdjustedPixelValueForLength(maxWidth, style.get());
2083 }
2084 case CSSPropertyMinHeight:
2085 // FIXME: For flex-items, min-height:auto should compute to min-content.
2086 if (style->minHeight().isAuto())
2087 return zoomAdjustedPixelValue(0, style.get());
2088 return zoomAdjustedPixelValueForLength(style->minHeight(), style.get());
2089 case CSSPropertyMinWidth:
2090 // FIXME: For flex-items, min-width:auto should compute to min-content.
2091 if (style->minWidth().isAuto())
2092 return zoomAdjustedPixelValue(0, style.get());
2093 return zoomAdjustedPixelValueForLength(style->minWidth(), style.get());
2094 case CSSPropertyOpacity:
2095 return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
2096 case CSSPropertyOrphans:
2097 if (style->hasAutoOrphans())
2098 return cssValuePool().createIdentifierValue(CSSValueAuto);
2099 return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
2100 case CSSPropertyOutlineColor:
2101 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
2102 case CSSPropertyOutlineOffset:
2103 return zoomAdjustedPixelValue(style->outlineOffset(), style.get());
2104 case CSSPropertyOutlineStyle:
2105 if (style->outlineStyleIsAuto())
2106 return cssValuePool().createIdentifierValue(CSSValueAuto);
2107 return cssValuePool().createValue(style->outlineStyle());
2108 case CSSPropertyOutlineWidth:
2109 return zoomAdjustedPixelValue(style->outlineWidth(), style.get());
2110 case CSSPropertyOverflow:
2111 return cssValuePool().createValue(max(style->overflowX(), style->overflowY()));
2112 case CSSPropertyOverflowWrap:
2113 return cssValuePool().createValue(style->overflowWrap());
2114 case CSSPropertyOverflowX:
2115 return cssValuePool().createValue(style->overflowX());
2116 case CSSPropertyOverflowY:
2117 return cssValuePool().createValue(style->overflowY());
Ben Murdoch591b9582013-07-10 11:41:44 +01002118 case CSSPropertyPaddingTop: {
2119 Length paddingTop = style->paddingTop();
2120 if (paddingTop.isFixed() || !renderer || !renderer->isBox())
2121 return zoomAdjustedPixelValueForLength(paddingTop, style.get());
2122 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingTop(), style.get());
2123 }
2124 case CSSPropertyPaddingRight: {
2125 Length paddingRight = style->paddingRight();
2126 if (paddingRight.isFixed() || !renderer || !renderer->isBox())
2127 return zoomAdjustedPixelValueForLength(paddingRight, style.get());
2128 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingRight(), style.get());
2129 }
2130 case CSSPropertyPaddingBottom: {
2131 Length paddingBottom = style->paddingBottom();
2132 if (paddingBottom.isFixed() || !renderer || !renderer->isBox())
2133 return zoomAdjustedPixelValueForLength(paddingBottom, style.get());
2134 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingBottom(), style.get());
2135 }
2136 case CSSPropertyPaddingLeft: {
2137 Length paddingLeft = style->paddingLeft();
2138 if (paddingLeft.isFixed() || !renderer || !renderer->isBox())
2139 return zoomAdjustedPixelValueForLength(paddingLeft, style.get());
2140 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingLeft(), style.get());
2141 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002142 case CSSPropertyPageBreakAfter:
2143 return cssValuePool().createValue(style->pageBreakAfter());
2144 case CSSPropertyPageBreakBefore:
2145 return cssValuePool().createValue(style->pageBreakBefore());
2146 case CSSPropertyPageBreakInside: {
2147 EPageBreak pageBreak = style->pageBreakInside();
2148 ASSERT(pageBreak != PBALWAYS);
2149 if (pageBreak == PBALWAYS)
2150 return 0;
2151 return cssValuePool().createValue(style->pageBreakInside());
2152 }
2153 case CSSPropertyPosition:
2154 return cssValuePool().createValue(style->position());
2155 case CSSPropertyRight:
2156 return getPositionOffsetValue(style.get(), CSSPropertyRight, renderer, m_node->document()->renderView());
2157 case CSSPropertyWebkitRubyPosition:
2158 return cssValuePool().createValue(style->rubyPosition());
2159 case CSSPropertyTableLayout:
2160 return cssValuePool().createValue(style->tableLayout());
2161 case CSSPropertyTextAlign:
2162 return cssValuePool().createValue(style->textAlign());
Ben Murdoche69819b2013-07-17 14:56:49 +01002163 case CSSPropertyTextAlignLast:
2164 return cssValuePool().createValue(style->textAlignLast());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002165 case CSSPropertyTextDecoration:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002166 case CSSPropertyTextDecorationLine:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002167 return renderTextDecorationFlagsToCSSValue(style->textDecoration());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002168 case CSSPropertyTextDecorationStyle:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002169 return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002170 case CSSPropertyTextDecorationColor:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002171 return currentColorOrValidColor(style.get(), style->textDecorationColor());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002172#if ENABLE(CSS3_TEXT)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002173 case CSSPropertyWebkitTextUnderlinePosition:
2174 return cssValuePool().createValue(style->textUnderlinePosition());
2175#endif // CSS3_TEXT
2176 case CSSPropertyWebkitTextDecorationsInEffect:
2177 return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
2178 case CSSPropertyWebkitTextFillColor:
2179 return currentColorOrValidColor(style.get(), style->textFillColor());
2180 case CSSPropertyWebkitTextEmphasisColor:
2181 return currentColorOrValidColor(style.get(), style->textEmphasisColor());
2182 case CSSPropertyWebkitTextEmphasisPosition:
2183 return cssValuePool().createValue(style->textEmphasisPosition());
2184 case CSSPropertyWebkitTextEmphasisStyle:
2185 switch (style->textEmphasisMark()) {
2186 case TextEmphasisMarkNone:
2187 return cssValuePool().createIdentifierValue(CSSValueNone);
2188 case TextEmphasisMarkCustom:
2189 return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
2190 case TextEmphasisMarkAuto:
2191 ASSERT_NOT_REACHED();
2192 // Fall through
2193 case TextEmphasisMarkDot:
2194 case TextEmphasisMarkCircle:
2195 case TextEmphasisMarkDoubleCircle:
2196 case TextEmphasisMarkTriangle:
2197 case TextEmphasisMarkSesame: {
2198 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2199 list->append(cssValuePool().createValue(style->textEmphasisFill()));
2200 list->append(cssValuePool().createValue(style->textEmphasisMark()));
2201 return list.release();
2202 }
2203 }
2204 case CSSPropertyTextIndent: {
2205 RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), style.get());
2206#if ENABLE(CSS3_TEXT)
2207 if (style->textIndentLine() == TextIndentEachLine) {
2208 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2209 list->append(textIndent.release());
2210 list->append(cssValuePool().createIdentifierValue(CSSValueWebkitEachLine));
2211 return list.release();
2212 }
2213#endif
2214 return textIndent.release();
2215 }
2216 case CSSPropertyTextShadow:
2217 return valueForShadow(style->textShadow(), propertyID, style.get());
2218 case CSSPropertyTextRendering:
2219 return cssValuePool().createValue(style->fontDescription().textRenderingMode());
2220 case CSSPropertyTextOverflow:
2221 if (style->textOverflow())
2222 return cssValuePool().createIdentifierValue(CSSValueEllipsis);
2223 return cssValuePool().createIdentifierValue(CSSValueClip);
2224 case CSSPropertyWebkitTextSecurity:
2225 return cssValuePool().createValue(style->textSecurity());
2226 case CSSPropertyWebkitTextStrokeColor:
2227 return currentColorOrValidColor(style.get(), style->textStrokeColor());
2228 case CSSPropertyWebkitTextStrokeWidth:
2229 return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get());
2230 case CSSPropertyTextTransform:
2231 return cssValuePool().createValue(style->textTransform());
2232 case CSSPropertyTop:
2233 return getPositionOffsetValue(style.get(), CSSPropertyTop, renderer, m_node->document()->renderView());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002234 case CSSPropertyTouchAction:
2235 return cssValuePool().createValue(style->touchAction());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002236 case CSSPropertyUnicodeBidi:
2237 return cssValuePool().createValue(style->unicodeBidi());
2238 case CSSPropertyVerticalAlign:
2239 switch (style->verticalAlign()) {
2240 case BASELINE:
2241 return cssValuePool().createIdentifierValue(CSSValueBaseline);
2242 case MIDDLE:
2243 return cssValuePool().createIdentifierValue(CSSValueMiddle);
2244 case SUB:
2245 return cssValuePool().createIdentifierValue(CSSValueSub);
2246 case SUPER:
2247 return cssValuePool().createIdentifierValue(CSSValueSuper);
2248 case TEXT_TOP:
2249 return cssValuePool().createIdentifierValue(CSSValueTextTop);
2250 case TEXT_BOTTOM:
2251 return cssValuePool().createIdentifierValue(CSSValueTextBottom);
2252 case TOP:
2253 return cssValuePool().createIdentifierValue(CSSValueTop);
2254 case BOTTOM:
2255 return cssValuePool().createIdentifierValue(CSSValueBottom);
2256 case BASELINE_MIDDLE:
2257 return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
2258 case LENGTH:
2259 return cssValuePool().createValue(style->verticalAlignLength());
2260 }
2261 ASSERT_NOT_REACHED();
2262 return 0;
2263 case CSSPropertyVisibility:
2264 return cssValuePool().createValue(style->visibility());
2265 case CSSPropertyWhiteSpace:
2266 return cssValuePool().createValue(style->whiteSpace());
2267 case CSSPropertyWidows:
2268 if (style->hasAutoWidows())
2269 return cssValuePool().createIdentifierValue(CSSValueAuto);
2270 return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
2271 case CSSPropertyWidth:
2272 if (renderer) {
2273 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
2274 // the "width" property does not apply for non-replaced inline elements.
2275 if (!renderer->isReplaced() && renderer->isInline())
2276 return cssValuePool().createIdentifierValue(CSSValueAuto);
2277 return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get());
2278 }
2279 return zoomAdjustedPixelValueForLength(style->width(), style.get());
2280 case CSSPropertyWordBreak:
2281 return cssValuePool().createValue(style->wordBreak());
2282 case CSSPropertyWordSpacing:
2283 return zoomAdjustedPixelValue(style->wordSpacing(), style.get());
2284 case CSSPropertyWordWrap:
2285 return cssValuePool().createValue(style->overflowWrap());
2286 case CSSPropertyWebkitLineBreak:
2287 return cssValuePool().createValue(style->lineBreak());
2288 case CSSPropertyResize:
2289 return cssValuePool().createValue(style->resize());
2290 case CSSPropertyWebkitFontKerning:
2291 return cssValuePool().createValue(style->fontDescription().kerning());
2292 case CSSPropertyWebkitFontSmoothing:
2293 return cssValuePool().createValue(style->fontDescription().fontSmoothing());
2294 case CSSPropertyWebkitFontVariantLigatures: {
2295 FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
2296 FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
2297 FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
2298 if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
2299 && historicalLigaturesState == FontDescription::NormalLigaturesState)
2300 return cssValuePool().createIdentifierValue(CSSValueNormal);
2301
2302 RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
2303 if (commonLigaturesState != FontDescription::NormalLigaturesState)
2304 valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
2305 if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
2306 valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
2307 if (historicalLigaturesState != FontDescription::NormalLigaturesState)
2308 valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
2309 return valueList;
2310 }
2311 case CSSPropertyZIndex:
2312 if (style->hasAutoZIndex())
2313 return cssValuePool().createIdentifierValue(CSSValueAuto);
2314 return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
2315 case CSSPropertyZoom:
2316 return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
2317 case CSSPropertyBoxSizing:
2318 if (style->boxSizing() == CONTENT_BOX)
2319 return cssValuePool().createIdentifierValue(CSSValueContentBox);
2320 return cssValuePool().createIdentifierValue(CSSValueBorderBox);
2321 case CSSPropertyWebkitAppRegion:
2322 return cssValuePool().createIdentifierValue(style->getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag);
2323 case CSSPropertyWebkitAnimationDelay:
2324 return getDelayValue(style->animations());
2325 case CSSPropertyWebkitAnimationDirection: {
2326 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2327 const CSSAnimationDataList* t = style->animations();
2328 if (t) {
2329 for (size_t i = 0; i < t->size(); ++i) {
2330 if (t->animation(i)->direction())
2331 list->append(cssValuePool().createIdentifierValue(CSSValueAlternate));
2332 else
2333 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2334 }
2335 } else
2336 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2337 return list.release();
2338 }
2339 case CSSPropertyWebkitAnimationDuration:
2340 return getDurationValue(style->animations());
2341 case CSSPropertyWebkitAnimationFillMode: {
2342 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2343 const CSSAnimationDataList* t = style->animations();
2344 if (t) {
2345 for (size_t i = 0; i < t->size(); ++i) {
2346 switch (t->animation(i)->fillMode()) {
2347 case AnimationFillModeNone:
2348 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2349 break;
2350 case AnimationFillModeForwards:
2351 list->append(cssValuePool().createIdentifierValue(CSSValueForwards));
2352 break;
2353 case AnimationFillModeBackwards:
2354 list->append(cssValuePool().createIdentifierValue(CSSValueBackwards));
2355 break;
2356 case AnimationFillModeBoth:
2357 list->append(cssValuePool().createIdentifierValue(CSSValueBoth));
2358 break;
2359 }
2360 }
2361 } else
2362 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2363 return list.release();
2364 }
2365 case CSSPropertyWebkitAnimationIterationCount: {
2366 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2367 const CSSAnimationDataList* t = style->animations();
2368 if (t) {
2369 for (size_t i = 0; i < t->size(); ++i) {
2370 double iterationCount = t->animation(i)->iterationCount();
2371 if (iterationCount == CSSAnimationData::IterationCountInfinite)
2372 list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
2373 else
2374 list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
2375 }
2376 } else
2377 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2378 return list.release();
2379 }
2380 case CSSPropertyWebkitAnimationName: {
2381 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2382 const CSSAnimationDataList* t = style->animations();
2383 if (t) {
2384 for (size_t i = 0; i < t->size(); ++i)
2385 list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
2386 } else
2387 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2388 return list.release();
2389 }
2390 case CSSPropertyWebkitAnimationPlayState: {
2391 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2392 const CSSAnimationDataList* t = style->animations();
2393 if (t) {
2394 for (size_t i = 0; i < t->size(); ++i) {
2395 int prop = t->animation(i)->playState();
2396 if (prop == AnimPlayStatePlaying)
2397 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2398 else
2399 list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
2400 }
2401 } else
2402 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2403 return list.release();
2404 }
2405 case CSSPropertyWebkitAnimationTimingFunction:
2406 return getTimingFunctionValue(style->animations());
2407 case CSSPropertyWebkitAppearance:
2408 return cssValuePool().createValue(style->appearance());
2409 case CSSPropertyWebkitAspectRatio:
2410 if (!style->hasAspectRatio())
2411 return cssValuePool().createIdentifierValue(CSSValueNone);
2412 return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
2413 case CSSPropertyWebkitBackfaceVisibility:
2414 return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
2415 case CSSPropertyWebkitBorderImage:
2416 return valueForNinePieceImage(style->borderImage());
2417 case CSSPropertyBorderImageOutset:
2418 return valueForNinePieceImageQuad(style->borderImage().outset());
2419 case CSSPropertyBorderImageRepeat:
2420 return valueForNinePieceImageRepeat(style->borderImage());
2421 case CSSPropertyBorderImageSlice:
2422 return valueForNinePieceImageSlice(style->borderImage());
2423 case CSSPropertyBorderImageWidth:
2424 return valueForNinePieceImageQuad(style->borderImage().borderSlices());
2425 case CSSPropertyWebkitMaskBoxImage:
2426 return valueForNinePieceImage(style->maskBoxImage());
2427 case CSSPropertyWebkitMaskBoxImageOutset:
2428 return valueForNinePieceImageQuad(style->maskBoxImage().outset());
2429 case CSSPropertyWebkitMaskBoxImageRepeat:
2430 return valueForNinePieceImageRepeat(style->maskBoxImage());
2431 case CSSPropertyWebkitMaskBoxImageSlice:
2432 return valueForNinePieceImageSlice(style->maskBoxImage());
2433 case CSSPropertyWebkitMaskBoxImageWidth:
2434 return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
2435 case CSSPropertyWebkitMaskBoxImageSource:
2436 if (style->maskBoxImageSource())
2437 return style->maskBoxImageSource()->cssValue();
2438 return cssValuePool().createIdentifierValue(CSSValueNone);
2439 case CSSPropertyWebkitFontSizeDelta:
2440 // Not a real style property -- used by the editing engine -- so has no computed value.
2441 break;
2442 case CSSPropertyWebkitMarginBottomCollapse:
2443 case CSSPropertyWebkitMarginAfterCollapse:
2444 return cssValuePool().createValue(style->marginAfterCollapse());
2445 case CSSPropertyWebkitMarginTopCollapse:
2446 case CSSPropertyWebkitMarginBeforeCollapse:
2447 return cssValuePool().createValue(style->marginBeforeCollapse());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002448 case CSSPropertyWebkitPerspective:
2449 if (!style->hasPerspective())
2450 return cssValuePool().createIdentifierValue(CSSValueNone);
2451 return zoomAdjustedPixelValue(style->perspective(), style.get());
2452 case CSSPropertyWebkitPerspectiveOrigin: {
2453 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2454 if (renderer) {
2455 LayoutRect box;
2456 if (renderer->isBox())
2457 box = toRenderBox(renderer)->borderBoxRect();
2458
2459 RenderView* renderView = m_node->document()->renderView();
2460 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), style.get()));
2461 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), style.get()));
2462 }
2463 else {
2464 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get()));
2465 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get()));
2466
2467 }
2468 return list.release();
2469 }
2470 case CSSPropertyWebkitRtlOrdering:
2471 return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
2472 case CSSPropertyWebkitTapHighlightColor:
2473 return currentColorOrValidColor(style.get(), style->tapHighlightColor());
2474 case CSSPropertyWebkitUserDrag:
2475 return cssValuePool().createValue(style->userDrag());
2476 case CSSPropertyWebkitUserSelect:
2477 return cssValuePool().createValue(style->userSelect());
2478 case CSSPropertyBorderBottomLeftRadius:
2479 return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), m_node->document()->renderView());
2480 case CSSPropertyBorderBottomRightRadius:
2481 return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), m_node->document()->renderView());
2482 case CSSPropertyBorderTopLeftRadius:
2483 return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), m_node->document()->renderView());
2484 case CSSPropertyBorderTopRightRadius:
2485 return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), m_node->document()->renderView());
2486 case CSSPropertyClip: {
2487 if (!style->hasClip())
2488 return cssValuePool().createIdentifierValue(CSSValueAuto);
2489 RefPtr<Rect> rect = Rect::create();
2490 rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get()));
2491 rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get()));
2492 rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get()));
2493 rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get()));
2494 return cssValuePool().createValue(rect.release());
2495 }
2496 case CSSPropertySpeak:
2497 return cssValuePool().createValue(style->speak());
2498 case CSSPropertyWebkitTransform:
2499 return computedTransform(renderer, style.get());
2500 case CSSPropertyWebkitTransformOrigin: {
2501 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2502 if (renderer) {
2503 LayoutRect box;
2504 if (renderer->isBox())
2505 box = toRenderBox(renderer)->borderBoxRect();
2506
2507 RenderView* renderView = m_node->document()->renderView();
2508 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), style.get()));
2509 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), style.get()));
2510 if (style->transformOriginZ() != 0)
2511 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2512 } else {
2513 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get()));
2514 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get()));
2515 if (style->transformOriginZ() != 0)
2516 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2517 }
2518 return list.release();
2519 }
2520 case CSSPropertyWebkitTransformStyle:
2521 return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
2522 case CSSPropertyTransitionDelay:
2523 case CSSPropertyWebkitTransitionDelay:
2524 return getDelayValue(style->transitions());
2525 case CSSPropertyTransitionDuration:
2526 case CSSPropertyWebkitTransitionDuration:
2527 return getDurationValue(style->transitions());
2528 case CSSPropertyTransitionProperty:
2529 case CSSPropertyWebkitTransitionProperty:
2530 return getTransitionPropertyValue(style->transitions());
2531 case CSSPropertyTransitionTimingFunction:
2532 case CSSPropertyWebkitTransitionTimingFunction:
2533 return getTimingFunctionValue(style->transitions());
2534 case CSSPropertyTransition:
2535 case CSSPropertyWebkitTransition: {
2536 const CSSAnimationDataList* animList = style->transitions();
2537 if (animList) {
2538 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
2539 for (size_t i = 0; i < animList->size(); ++i) {
2540 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2541 const CSSAnimationData* animation = animList->animation(i);
2542 list->append(createTransitionPropertyValue(animation));
2543 list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
2544 list->append(createTimingFunctionValue(animation->timingFunction().get()));
2545 list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
2546 transitionsList->append(list);
2547 }
2548 return transitionsList.release();
2549 }
2550
2551 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2552 // transition-property default value.
2553 list->append(cssValuePool().createIdentifierValue(CSSValueAll));
2554 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
2555 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
2556 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
2557 return list.release();
2558 }
2559 case CSSPropertyPointerEvents:
2560 return cssValuePool().createValue(style->pointerEvents());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002561 case CSSPropertyWebkitLineGrid:
2562 if (style->lineGrid().isNull())
2563 return cssValuePool().createIdentifierValue(CSSValueNone);
2564 return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
2565 case CSSPropertyWebkitLineSnap:
2566 return CSSPrimitiveValue::create(style->lineSnap());
2567 case CSSPropertyWebkitLineAlign:
2568 return CSSPrimitiveValue::create(style->lineAlign());
2569 case CSSPropertyWebkitWritingMode:
2570 return cssValuePool().createValue(style->writingMode());
2571 case CSSPropertyWebkitTextCombine:
2572 return cssValuePool().createValue(style->textCombine());
2573 case CSSPropertyWebkitTextOrientation:
2574 return CSSPrimitiveValue::create(style->textOrientation());
2575 case CSSPropertyWebkitLineBoxContain:
2576 return createLineBoxContainValue(style->lineBoxContain());
2577 case CSSPropertyContent:
2578 return contentToCSSValue(style.get());
2579 case CSSPropertyCounterIncrement:
2580 return counterToCSSValue(style.get(), propertyID);
2581 case CSSPropertyCounterReset:
2582 return counterToCSSValue(style.get(), propertyID);
2583 case CSSPropertyWebkitClipPath:
2584 if (ClipPathOperation* operation = style->clipPath()) {
2585 if (operation->getOperationType() == ClipPathOperation::SHAPE)
2586 return valueForBasicShape(static_cast<ShapeClipPathOperation*>(operation)->basicShape());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002587 if (operation->getOperationType() == ClipPathOperation::REFERENCE) {
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002588 ReferenceClipPathOperation* referenceOperation = static_cast<ReferenceClipPathOperation*>(operation);
2589 return CSSPrimitiveValue::create(referenceOperation->url(), CSSPrimitiveValue::CSS_URI);
2590 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002591 }
2592 return cssValuePool().createIdentifierValue(CSSValueNone);
2593 case CSSPropertyWebkitFlowInto:
2594 if (style->flowThread().isNull())
2595 return cssValuePool().createIdentifierValue(CSSValueNone);
2596 return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
2597 case CSSPropertyWebkitFlowFrom:
2598 if (style->regionThread().isNull())
2599 return cssValuePool().createIdentifierValue(CSSValueNone);
2600 return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01002601 case CSSPropertyWebkitRegionFragment:
2602 return cssValuePool().createValue(style->regionFragment());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002603 case CSSPropertyWebkitWrapFlow:
2604 return cssValuePool().createValue(style->wrapFlow());
2605 case CSSPropertyWebkitShapeMargin:
2606 return cssValuePool().createValue(style->shapeMargin());
2607 case CSSPropertyWebkitShapePadding:
2608 return cssValuePool().createValue(style->shapePadding());
2609 case CSSPropertyWebkitShapeInside:
2610 if (!style->shapeInside())
2611 return cssValuePool().createIdentifierValue(CSSValueAuto);
Ben Murdoch591b9582013-07-10 11:41:44 +01002612 if (style->shapeInside()->type() == ShapeValue::Outside)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002613 return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
Ben Murdoch591b9582013-07-10 11:41:44 +01002614 if (style->shapeInside()->type() == ShapeValue::Image) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002615 if (style->shapeInside()->image())
2616 return style->shapeInside()->image()->cssValue();
2617 return cssValuePool().createIdentifierValue(CSSValueNone);
2618 }
Ben Murdoch591b9582013-07-10 11:41:44 +01002619 ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002620 return valueForBasicShape(style->shapeInside()->shape());
2621 case CSSPropertyWebkitShapeOutside:
2622 if (!style->shapeOutside())
2623 return cssValuePool().createIdentifierValue(CSSValueAuto);
Ben Murdoch591b9582013-07-10 11:41:44 +01002624 if (style->shapeOutside()->type() == ShapeValue::Image) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002625 if (style->shapeOutside()->image())
2626 return style->shapeOutside()->image()->cssValue();
2627 return cssValuePool().createIdentifierValue(CSSValueNone);
2628 }
Ben Murdoch591b9582013-07-10 11:41:44 +01002629 ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002630 return valueForBasicShape(style->shapeOutside()->shape());
2631 case CSSPropertyWebkitWrapThrough:
2632 return cssValuePool().createValue(style->wrapThrough());
2633 case CSSPropertyWebkitFilter:
2634 return valueForFilter(renderer, style.get());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002635 case CSSPropertyMixBlendMode:
2636 return cssValuePool().createValue(style->blendMode());
2637
2638 case CSSPropertyBackgroundBlendMode: {
2639 const FillLayer* layers = style->backgroundLayers();
2640 if (!layers->next())
2641 return cssValuePool().createValue(layers->blendMode());
2642
2643 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2644 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2645 list->append(cssValuePool().createValue(currLayer->blendMode()));
2646
2647 return list.release();
2648 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002649 case CSSPropertyBackground:
2650 return getBackgroundShorthandValue();
2651 case CSSPropertyBorder: {
2652 RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
2653 const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
2654 CSSPropertyBorderLeft };
2655 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
2656 if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
2657 return 0;
2658 }
2659 return value.release();
2660 }
2661 case CSSPropertyBorderBottom:
2662 return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand());
2663 case CSSPropertyBorderColor:
2664 return getCSSPropertyValuesForSidesShorthand(borderColorShorthand());
2665 case CSSPropertyBorderLeft:
2666 return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand());
2667 case CSSPropertyBorderImage:
2668 return valueForNinePieceImage(style->borderImage());
2669 case CSSPropertyBorderRadius:
2670 return getBorderRadiusShorthandValue(style.get(), m_node->document()->renderView());
2671 case CSSPropertyBorderRight:
2672 return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
2673 case CSSPropertyBorderStyle:
2674 return getCSSPropertyValuesForSidesShorthand(borderStyleShorthand());
2675 case CSSPropertyBorderTop:
2676 return getCSSPropertyValuesForShorthandProperties(borderTopShorthand());
2677 case CSSPropertyBorderWidth:
2678 return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand());
2679 case CSSPropertyWebkitColumnRule:
2680 return getCSSPropertyValuesForShorthandProperties(webkitColumnRuleShorthand());
2681 case CSSPropertyWebkitColumns:
2682 return getCSSPropertyValuesForShorthandProperties(webkitColumnsShorthand());
2683 case CSSPropertyListStyle:
2684 return getCSSPropertyValuesForShorthandProperties(listStyleShorthand());
2685 case CSSPropertyMargin:
2686 return getCSSPropertyValuesForSidesShorthand(marginShorthand());
2687 case CSSPropertyOutline:
2688 return getCSSPropertyValuesForShorthandProperties(outlineShorthand());
2689 case CSSPropertyPadding:
2690 return getCSSPropertyValuesForSidesShorthand(paddingShorthand());
2691 /* Individual properties not part of the spec */
2692 case CSSPropertyBackgroundRepeatX:
2693 case CSSPropertyBackgroundRepeatY:
2694 break;
2695
2696 /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
2697 case CSSPropertyWebkitTextEmphasis:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002698 case CSSPropertyTextLineThroughColor:
2699 case CSSPropertyTextLineThroughMode:
2700 case CSSPropertyTextLineThroughStyle:
2701 case CSSPropertyTextLineThroughWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002702 case CSSPropertyTextOverlineColor:
2703 case CSSPropertyTextOverlineMode:
2704 case CSSPropertyTextOverlineStyle:
2705 case CSSPropertyTextOverlineWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002706 case CSSPropertyTextUnderlineColor:
2707 case CSSPropertyTextUnderlineMode:
2708 case CSSPropertyTextUnderlineStyle:
2709 case CSSPropertyTextUnderlineWidth:
2710 break;
2711
2712 /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
2713 case CSSPropertyWebkitBorderEnd:
2714 case CSSPropertyWebkitBorderEndColor:
2715 case CSSPropertyWebkitBorderEndStyle:
2716 case CSSPropertyWebkitBorderEndWidth:
2717 case CSSPropertyWebkitBorderStart:
2718 case CSSPropertyWebkitBorderStartColor:
2719 case CSSPropertyWebkitBorderStartStyle:
2720 case CSSPropertyWebkitBorderStartWidth:
2721 case CSSPropertyWebkitBorderAfter:
2722 case CSSPropertyWebkitBorderAfterColor:
2723 case CSSPropertyWebkitBorderAfterStyle:
2724 case CSSPropertyWebkitBorderAfterWidth:
2725 case CSSPropertyWebkitBorderBefore:
2726 case CSSPropertyWebkitBorderBeforeColor:
2727 case CSSPropertyWebkitBorderBeforeStyle:
2728 case CSSPropertyWebkitBorderBeforeWidth:
2729 case CSSPropertyWebkitMarginEnd:
2730 case CSSPropertyWebkitMarginStart:
2731 case CSSPropertyWebkitMarginAfter:
2732 case CSSPropertyWebkitMarginBefore:
2733 case CSSPropertyWebkitPaddingEnd:
2734 case CSSPropertyWebkitPaddingStart:
2735 case CSSPropertyWebkitPaddingAfter:
2736 case CSSPropertyWebkitPaddingBefore:
2737 case CSSPropertyWebkitLogicalWidth:
2738 case CSSPropertyWebkitLogicalHeight:
2739 case CSSPropertyWebkitMinLogicalWidth:
2740 case CSSPropertyWebkitMinLogicalHeight:
2741 case CSSPropertyWebkitMaxLogicalWidth:
2742 case CSSPropertyWebkitMaxLogicalHeight:
2743 ASSERT_NOT_REACHED();
2744 break;
2745
2746 /* Unimplemented @font-face properties */
2747 case CSSPropertyFontStretch:
2748 case CSSPropertySrc:
2749 case CSSPropertyUnicodeRange:
2750 break;
2751
2752 /* Other unimplemented properties */
2753 case CSSPropertyPage: // for @page
2754 case CSSPropertyQuotes: // FIXME: needs implementation
2755 case CSSPropertySize: // for @page
2756 break;
2757
2758 /* Unimplemented -webkit- properties */
2759 case CSSPropertyWebkitAnimation:
2760 case CSSPropertyWebkitBorderRadius:
2761 case CSSPropertyWebkitMarginCollapse:
2762 case CSSPropertyWebkitMarquee:
2763 case CSSPropertyWebkitMarqueeSpeed:
2764 case CSSPropertyWebkitMask:
2765 case CSSPropertyWebkitMaskRepeatX:
2766 case CSSPropertyWebkitMaskRepeatY:
2767 case CSSPropertyWebkitPerspectiveOriginX:
2768 case CSSPropertyWebkitPerspectiveOriginY:
2769 case CSSPropertyWebkitTextStroke:
2770 case CSSPropertyWebkitTransformOriginX:
2771 case CSSPropertyWebkitTransformOriginY:
2772 case CSSPropertyWebkitTransformOriginZ:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002773 break;
2774
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01002775 /* @viewport rule properties */
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002776 case CSSPropertyMaxZoom:
2777 case CSSPropertyMinZoom:
2778 case CSSPropertyOrientation:
2779 case CSSPropertyUserZoom:
2780 break;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002781
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002782 case CSSPropertyBufferedRendering:
2783 case CSSPropertyClipPath:
2784 case CSSPropertyClipRule:
2785 case CSSPropertyMask:
2786 case CSSPropertyEnableBackground:
2787 case CSSPropertyFilter:
2788 case CSSPropertyFloodColor:
2789 case CSSPropertyFloodOpacity:
2790 case CSSPropertyLightingColor:
2791 case CSSPropertyStopColor:
2792 case CSSPropertyStopOpacity:
2793 case CSSPropertyColorInterpolation:
2794 case CSSPropertyColorInterpolationFilters:
2795 case CSSPropertyColorProfile:
2796 case CSSPropertyColorRendering:
2797 case CSSPropertyFill:
2798 case CSSPropertyFillOpacity:
2799 case CSSPropertyFillRule:
2800 case CSSPropertyMarker:
2801 case CSSPropertyMarkerEnd:
2802 case CSSPropertyMarkerMid:
2803 case CSSPropertyMarkerStart:
2804 case CSSPropertyMaskType:
2805 case CSSPropertyShapeRendering:
2806 case CSSPropertyStroke:
2807 case CSSPropertyStrokeDasharray:
2808 case CSSPropertyStrokeDashoffset:
2809 case CSSPropertyStrokeLinecap:
2810 case CSSPropertyStrokeLinejoin:
2811 case CSSPropertyStrokeMiterlimit:
2812 case CSSPropertyStrokeOpacity:
2813 case CSSPropertyStrokeWidth:
2814 case CSSPropertyAlignmentBaseline:
2815 case CSSPropertyBaselineShift:
2816 case CSSPropertyDominantBaseline:
2817 case CSSPropertyGlyphOrientationHorizontal:
2818 case CSSPropertyGlyphOrientationVertical:
2819 case CSSPropertyKerning:
2820 case CSSPropertyTextAnchor:
2821 case CSSPropertyVectorEffect:
2822 case CSSPropertyWritingMode:
2823 case CSSPropertyWebkitSvgShadow:
2824 return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002825 }
2826
2827 logUnimplementedPropertyID(propertyID);
2828 return 0;
2829}
2830
2831String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
2832{
2833 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2834 if (value)
2835 return value->cssText();
2836 return "";
2837}
2838
2839
2840unsigned CSSComputedStyleDeclaration::length() const
2841{
2842 Node* node = m_node.get();
2843 if (!node)
2844 return 0;
2845
2846 RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
2847 if (!style)
2848 return 0;
2849
2850 return computableProperties().size();
2851}
2852
2853String CSSComputedStyleDeclaration::item(unsigned i) const
2854{
2855 if (i >= length())
2856 return "";
2857
2858 return getPropertyNameString(computableProperties()[i]);
2859}
2860
2861bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
2862{
2863 if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() && m_node) {
2864 m_node->document()->updateLayoutIgnorePendingStylesheets();
2865 RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
2866 if (style && style->fontDescription().keywordSize()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002867 CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
Torne (Richard Coles)e5249552013-05-15 11:35:13 +01002868 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(propertyValue);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002869 if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002870 return true;
2871 }
2872 }
2873 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2874 return value && propertyValue && value->equals(*propertyValue);
2875}
2876
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002877PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002878{
2879 return copyPropertiesInSet(computableProperties());
2880}
2881
2882PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) const
2883{
2884 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2885 for (size_t i = 0; i < shorthand.length(); ++i) {
2886 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
2887 list->append(value);
2888 }
2889 return list.release();
2890}
2891
2892PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand& shorthand) const
2893{
2894 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2895 // Assume the properties are in the usual order top, right, bottom, left.
2896 RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
2897 RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
2898 RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
2899 RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
2900
2901 // All 4 properties must be specified.
2902 if (!topValue || !rightValue || !bottomValue || !leftValue)
2903 return 0;
2904
2905 bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
2906 bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
2907 bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;
2908
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002909 list->append(topValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002910 if (showRight)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002911 list->append(rightValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002912 if (showBottom)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002913 list->append(bottomValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002914 if (showLeft)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002915 list->append(leftValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002916
2917 return list.release();
2918}
2919
2920PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) const
2921{
2922 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
2923 for (size_t i = 0; i < shorthand.length(); ++i) {
2924 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002925 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002926 }
2927 return list.release();
2928}
2929
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002930PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002931{
2932 Vector<CSSProperty, 256> list;
2933 list.reserveInitialCapacity(properties.size());
2934 for (unsigned i = 0; i < properties.size(); ++i) {
2935 RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
2936 if (value)
2937 list.append(CSSProperty(properties[i], value.release(), false));
2938 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002939 return MutableStylePropertySet::create(list.data(), list.size());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002940}
2941
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002942CSSRule* CSSComputedStyleDeclaration::parentRule() const
2943{
2944 return 0;
2945}
2946
2947PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
2948{
2949 CSSPropertyID propertyID = cssPropertyID(propertyName);
2950 if (!propertyID)
2951 return 0;
2952 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2953 return value ? value->cloneForCSSOM() : 0;
2954}
2955
2956String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
2957{
2958 CSSPropertyID propertyID = cssPropertyID(propertyName);
2959 if (!propertyID)
2960 return String();
2961 return getPropertyValue(propertyID);
2962}
2963
2964String CSSComputedStyleDeclaration::getPropertyPriority(const String&)
2965{
2966 // All computed styles have a priority of not "important".
2967 return "";
2968}
2969
2970String CSSComputedStyleDeclaration::getPropertyShorthand(const String&)
2971{
2972 return "";
2973}
2974
2975bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
2976{
2977 return false;
2978}
2979
2980void CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&, ExceptionCode& ec)
2981{
Ben Murdoche69819b2013-07-17 14:56:49 +01002982 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002983}
2984
2985String CSSComputedStyleDeclaration::removeProperty(const String&, ExceptionCode& ec)
2986{
Ben Murdoche69819b2013-07-17 14:56:49 +01002987 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002988 return String();
2989}
2990
2991PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
2992{
2993 return getPropertyCSSValue(propertyID);
2994}
2995
2996String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
2997{
2998 return getPropertyValue(propertyID);
2999}
3000
3001void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool, ExceptionCode& ec)
3002{
Ben Murdoche69819b2013-07-17 14:56:49 +01003003 ec = NoModificationAllowedError;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003004}
3005
Ben Murdoch7757ec22013-07-23 11:17:36 +01003006const HashMap<AtomicString, String>* CSSComputedStyleDeclaration::variableMap() const
3007{
3008 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3009 Node* styledNode = this->styledNode();
3010 if (!styledNode)
3011 return 0;
3012 RefPtr<RenderStyle> style = styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
3013 if (!style)
3014 return 0;
3015 return style->variables();
3016}
3017
3018unsigned CSSComputedStyleDeclaration::variableCount() const
3019{
3020 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3021 const HashMap<AtomicString, String>* variables = variableMap();
3022 if (!variables)
3023 return 0;
3024 return variables->size();
3025}
3026
3027String CSSComputedStyleDeclaration::variableValue(const AtomicString& name) const
3028{
3029 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3030 const HashMap<AtomicString, String>* variables = variableMap();
3031 if (!variables)
3032 return emptyString();
3033 HashMap<AtomicString, String>::const_iterator it = variables->find(name);
3034 if (it == variables->end())
3035 return emptyString();
3036 return it->value;
3037}
3038
3039void CSSComputedStyleDeclaration::setVariableValue(const AtomicString&, const String&, ExceptionCode& ec)
3040{
3041 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3042 ec = NoModificationAllowedError;
3043}
3044
3045bool CSSComputedStyleDeclaration::removeVariable(const AtomicString&)
3046{
3047 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3048 return false;
3049}
3050
3051void CSSComputedStyleDeclaration::clearVariables(ExceptionCode& ec)
3052{
3053 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3054 ec = NoModificationAllowedError;
3055}
3056
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003057PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getBackgroundShorthandValue() const
3058{
3059 static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage,
3060 CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment,
3061 CSSPropertyBackgroundPosition };
3062 static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin,
3063 CSSPropertyBackgroundClip };
3064
3065 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +01003066 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator))));
3067 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator))));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003068 return list.release();
3069}
3070
3071} // namespace WebCore