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