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