blob: 48da4edd3b8cda17c355b68f0fba2eec4ef51f18 [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
2 * Copyright (C) 2004 Zack Rusin <zack@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6 * Copyright (C) 2011 Sencha, Inc. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24#include "config.h"
25#include "core/css/CSSComputedStyleDeclaration.h"
26
27#include "CSSPropertyNames.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010028#include "FontFamilyNames.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010029#include "core/css/BasicShapeFunctions.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010030#include "core/css/CSSArrayFunctionValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010031#include "core/css/CSSAspectRatioValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010032#include "core/css/CSSBorderImage.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010033#include "core/css/CSSFilterValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010034#include "core/css/CSSFunctionValue.h"
35#include "core/css/CSSLineBoxContainValue.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010036#include "core/css/CSSMixFunctionValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010037#include "core/css/CSSParser.h"
38#include "core/css/CSSPrimitiveValue.h"
39#include "core/css/CSSPrimitiveValueMappings.h"
40#include "core/css/CSSReflectValue.h"
41#include "core/css/CSSSelector.h"
42#include "core/css/CSSTimingFunctionValue.h"
Torne (Richard Coles)5267f702013-06-11 10:57:24 +010043#include "core/css/CSSTransformValue.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010044#include "core/css/CSSValueList.h"
45#include "core/css/CSSValuePool.h"
46#include "core/css/FontFeatureValue.h"
47#include "core/css/FontValue.h"
48#include "core/css/Pair.h"
49#include "core/css/Rect.h"
50#include "core/css/ShadowValue.h"
51#include "core/css/StylePropertySet.h"
52#include "core/css/StylePropertyShorthand.h"
Torne (Richard Coles)81a51572013-05-13 16:52:28 +010053#include "core/css/resolver/StyleResolver.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010054#include "core/dom/Document.h"
55#include "core/dom/ExceptionCode.h"
56#include "core/dom/PseudoElement.h"
57#include "core/dom/WebCoreMemoryInstrumentation.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010058#include "core/page/RuntimeCSSEnabled.h"
59#include "core/page/animation/AnimationController.h"
60#include "core/platform/graphics/FontFeatureSettings.h"
61#include "core/rendering/RenderBox.h"
62#include "core/rendering/RenderView.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010063#include "core/rendering/style/ContentData.h"
64#include "core/rendering/style/CounterContent.h"
65#include "core/rendering/style/CursorList.h"
66#include "core/rendering/style/ExclusionShapeValue.h"
67#include "core/rendering/style/RenderStyle.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010068#include <wtf/text/StringBuilder.h>
69
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010070#include "core/platform/graphics/filters/custom/CustomFilterArrayParameter.h"
71#include "core/platform/graphics/filters/custom/CustomFilterNumberParameter.h"
72#include "core/platform/graphics/filters/custom/CustomFilterOperation.h"
73#include "core/platform/graphics/filters/custom/CustomFilterParameter.h"
74#include "core/platform/graphics/filters/custom/CustomFilterTransformParameter.h"
75
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010076#include "core/rendering/style/StyleCustomFilterProgram.h"
77
78namespace WebCore {
79
80// List of all properties we know how to compute, omitting shorthands.
81// NOTE: Do not use this list, use computableProperties() instead
82// to respect runtime enabling of CSS properties.
83static const CSSPropertyID staticComputableProperties[] = {
84 CSSPropertyBackgroundAttachment,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010085 CSSPropertyBackgroundBlendMode,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010086 CSSPropertyBackgroundClip,
87 CSSPropertyBackgroundColor,
88 CSSPropertyBackgroundImage,
89 CSSPropertyBackgroundOrigin,
90 CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
91 CSSPropertyBackgroundRepeat,
92 CSSPropertyBackgroundSize,
93 CSSPropertyBorderBottomColor,
94 CSSPropertyBorderBottomLeftRadius,
95 CSSPropertyBorderBottomRightRadius,
96 CSSPropertyBorderBottomStyle,
97 CSSPropertyBorderBottomWidth,
98 CSSPropertyBorderCollapse,
99 CSSPropertyBorderImageOutset,
100 CSSPropertyBorderImageRepeat,
101 CSSPropertyBorderImageSlice,
102 CSSPropertyBorderImageSource,
103 CSSPropertyBorderImageWidth,
104 CSSPropertyBorderLeftColor,
105 CSSPropertyBorderLeftStyle,
106 CSSPropertyBorderLeftWidth,
107 CSSPropertyBorderRightColor,
108 CSSPropertyBorderRightStyle,
109 CSSPropertyBorderRightWidth,
110 CSSPropertyBorderTopColor,
111 CSSPropertyBorderTopLeftRadius,
112 CSSPropertyBorderTopRightRadius,
113 CSSPropertyBorderTopStyle,
114 CSSPropertyBorderTopWidth,
115 CSSPropertyBottom,
116 CSSPropertyBoxShadow,
117 CSSPropertyBoxSizing,
118 CSSPropertyCaptionSide,
119 CSSPropertyClear,
120 CSSPropertyClip,
121 CSSPropertyColor,
122 CSSPropertyCursor,
123 CSSPropertyDirection,
124 CSSPropertyDisplay,
125 CSSPropertyEmptyCells,
126 CSSPropertyFloat,
127 CSSPropertyFontFamily,
128 CSSPropertyFontSize,
129 CSSPropertyFontStyle,
130 CSSPropertyFontVariant,
131 CSSPropertyFontWeight,
132 CSSPropertyHeight,
133 CSSPropertyImageRendering,
134 CSSPropertyLeft,
135 CSSPropertyLetterSpacing,
136 CSSPropertyLineHeight,
137 CSSPropertyListStyleImage,
138 CSSPropertyListStylePosition,
139 CSSPropertyListStyleType,
140 CSSPropertyMarginBottom,
141 CSSPropertyMarginLeft,
142 CSSPropertyMarginRight,
143 CSSPropertyMarginTop,
144 CSSPropertyMaxHeight,
145 CSSPropertyMaxWidth,
146 CSSPropertyMinHeight,
147 CSSPropertyMinWidth,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100148 CSSPropertyMixBlendMode,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100149 CSSPropertyOpacity,
150 CSSPropertyOrphans,
151 CSSPropertyOutlineColor,
152 CSSPropertyOutlineOffset,
153 CSSPropertyOutlineStyle,
154 CSSPropertyOutlineWidth,
155 CSSPropertyOverflowWrap,
156 CSSPropertyOverflowX,
157 CSSPropertyOverflowY,
158 CSSPropertyPaddingBottom,
159 CSSPropertyPaddingLeft,
160 CSSPropertyPaddingRight,
161 CSSPropertyPaddingTop,
162 CSSPropertyPageBreakAfter,
163 CSSPropertyPageBreakBefore,
164 CSSPropertyPageBreakInside,
165 CSSPropertyPointerEvents,
166 CSSPropertyPosition,
167 CSSPropertyResize,
168 CSSPropertyRight,
169 CSSPropertySpeak,
170 CSSPropertyTableLayout,
171 CSSPropertyTabSize,
172 CSSPropertyTextAlign,
173 CSSPropertyTextDecoration,
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100174 CSSPropertyTextDecorationLine,
175 CSSPropertyTextDecorationStyle,
176 CSSPropertyTextDecorationColor,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100177#if ENABLE(CSS3_TEXT)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100178 CSSPropertyWebkitTextAlignLast,
179 CSSPropertyWebkitTextUnderlinePosition,
180#endif // CSS3_TEXT
181 CSSPropertyTextIndent,
182 CSSPropertyTextRendering,
183 CSSPropertyTextShadow,
184 CSSPropertyTextOverflow,
185 CSSPropertyTextTransform,
186 CSSPropertyTop,
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100187 CSSPropertyTouchAction,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100188 CSSPropertyTransitionDelay,
189 CSSPropertyTransitionDuration,
190 CSSPropertyTransitionProperty,
191 CSSPropertyTransitionTimingFunction,
192 CSSPropertyUnicodeBidi,
193 CSSPropertyVerticalAlign,
194 CSSPropertyVisibility,
195 CSSPropertyWhiteSpace,
196 CSSPropertyWidows,
197 CSSPropertyWidth,
198 CSSPropertyWordBreak,
199 CSSPropertyWordSpacing,
200 CSSPropertyWordWrap,
201 CSSPropertyZIndex,
202 CSSPropertyZoom,
203
204 CSSPropertyWebkitAnimationDelay,
205 CSSPropertyWebkitAnimationDirection,
206 CSSPropertyWebkitAnimationDuration,
207 CSSPropertyWebkitAnimationFillMode,
208 CSSPropertyWebkitAnimationIterationCount,
209 CSSPropertyWebkitAnimationName,
210 CSSPropertyWebkitAnimationPlayState,
211 CSSPropertyWebkitAnimationTimingFunction,
212 CSSPropertyWebkitAppearance,
213 CSSPropertyWebkitBackfaceVisibility,
214 CSSPropertyWebkitBackgroundClip,
215 CSSPropertyWebkitBackgroundComposite,
216 CSSPropertyWebkitBackgroundOrigin,
217 CSSPropertyWebkitBackgroundSize,
218 CSSPropertyWebkitBorderFit,
219 CSSPropertyWebkitBorderHorizontalSpacing,
220 CSSPropertyWebkitBorderImage,
221 CSSPropertyWebkitBorderVerticalSpacing,
222 CSSPropertyWebkitBoxAlign,
223 CSSPropertyWebkitBoxDecorationBreak,
224 CSSPropertyWebkitBoxDirection,
225 CSSPropertyWebkitBoxFlex,
226 CSSPropertyWebkitBoxFlexGroup,
227 CSSPropertyWebkitBoxLines,
228 CSSPropertyWebkitBoxOrdinalGroup,
229 CSSPropertyWebkitBoxOrient,
230 CSSPropertyWebkitBoxPack,
231 CSSPropertyWebkitBoxReflect,
232 CSSPropertyWebkitBoxShadow,
233 CSSPropertyWebkitClipPath,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100234 CSSPropertyWebkitColumnBreakAfter,
235 CSSPropertyWebkitColumnBreakBefore,
236 CSSPropertyWebkitColumnBreakInside,
237 CSSPropertyWebkitColumnAxis,
238 CSSPropertyWebkitColumnCount,
239 CSSPropertyWebkitColumnGap,
240 CSSPropertyWebkitColumnProgression,
241 CSSPropertyWebkitColumnRuleColor,
242 CSSPropertyWebkitColumnRuleStyle,
243 CSSPropertyWebkitColumnRuleWidth,
244 CSSPropertyWebkitColumnSpan,
245 CSSPropertyWebkitColumnWidth,
246 CSSPropertyWebkitFilter,
247 CSSPropertyWebkitAlignContent,
248 CSSPropertyWebkitAlignItems,
249 CSSPropertyWebkitAlignSelf,
250 CSSPropertyWebkitFlexBasis,
251 CSSPropertyWebkitFlexGrow,
252 CSSPropertyWebkitFlexShrink,
253 CSSPropertyWebkitFlexDirection,
254 CSSPropertyWebkitFlexWrap,
255 CSSPropertyWebkitJustifyContent,
256 CSSPropertyWebkitFontKerning,
257 CSSPropertyWebkitFontSmoothing,
258 CSSPropertyWebkitFontVariantLigatures,
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100259 CSSPropertyGridAutoColumns,
260 CSSPropertyGridAutoFlow,
261 CSSPropertyGridAutoRows,
262 CSSPropertyGridColumns,
263 CSSPropertyGridRows,
264 CSSPropertyGridStart,
265 CSSPropertyGridEnd,
266 CSSPropertyGridBefore,
267 CSSPropertyGridAfter,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100268 CSSPropertyWebkitHighlight,
269 CSSPropertyWebkitHyphenateCharacter,
270 CSSPropertyWebkitHyphenateLimitAfter,
271 CSSPropertyWebkitHyphenateLimitBefore,
272 CSSPropertyWebkitHyphenateLimitLines,
273 CSSPropertyWebkitHyphens,
274 CSSPropertyWebkitLineAlign,
275 CSSPropertyWebkitLineBoxContain,
276 CSSPropertyWebkitLineBreak,
277 CSSPropertyWebkitLineClamp,
278 CSSPropertyWebkitLineGrid,
279 CSSPropertyWebkitLineSnap,
280 CSSPropertyWebkitLocale,
281 CSSPropertyWebkitMarginBeforeCollapse,
282 CSSPropertyWebkitMarginAfterCollapse,
283 CSSPropertyWebkitMarqueeDirection,
284 CSSPropertyWebkitMarqueeIncrement,
285 CSSPropertyWebkitMarqueeRepetition,
286 CSSPropertyWebkitMarqueeStyle,
287 CSSPropertyWebkitMaskBoxImage,
288 CSSPropertyWebkitMaskBoxImageOutset,
289 CSSPropertyWebkitMaskBoxImageRepeat,
290 CSSPropertyWebkitMaskBoxImageSlice,
291 CSSPropertyWebkitMaskBoxImageSource,
292 CSSPropertyWebkitMaskBoxImageWidth,
293 CSSPropertyWebkitMaskClip,
294 CSSPropertyWebkitMaskComposite,
295 CSSPropertyWebkitMaskImage,
296 CSSPropertyWebkitMaskOrigin,
297 CSSPropertyWebkitMaskPosition,
298 CSSPropertyWebkitMaskRepeat,
299 CSSPropertyWebkitMaskSize,
300 CSSPropertyWebkitOrder,
301#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
302 CSSPropertyWebkitOverflowScrolling,
303#endif
304 CSSPropertyWebkitPerspective,
305 CSSPropertyWebkitPerspectiveOrigin,
306 CSSPropertyWebkitPrintColorAdjust,
307 CSSPropertyWebkitRtlOrdering,
308 CSSPropertyWebkitShapeInside,
309 CSSPropertyWebkitShapeOutside,
310 CSSPropertyWebkitTapHighlightColor,
311 CSSPropertyWebkitTextCombine,
312 CSSPropertyWebkitTextDecorationsInEffect,
313 CSSPropertyWebkitTextEmphasisColor,
314 CSSPropertyWebkitTextEmphasisPosition,
315 CSSPropertyWebkitTextEmphasisStyle,
316 CSSPropertyWebkitTextFillColor,
317 CSSPropertyWebkitTextOrientation,
318 CSSPropertyWebkitTextSecurity,
319 CSSPropertyWebkitTextStrokeColor,
320 CSSPropertyWebkitTextStrokeWidth,
321 CSSPropertyWebkitTransform,
322 CSSPropertyWebkitTransformOrigin,
323 CSSPropertyWebkitTransformStyle,
324 CSSPropertyWebkitTransitionDelay,
325 CSSPropertyWebkitTransitionDuration,
326 CSSPropertyWebkitTransitionProperty,
327 CSSPropertyWebkitTransitionTimingFunction,
328 CSSPropertyWebkitUserDrag,
329 CSSPropertyWebkitUserModify,
330 CSSPropertyWebkitUserSelect,
331 CSSPropertyWebkitWritingMode,
332 CSSPropertyWebkitFlowInto,
333 CSSPropertyWebkitFlowFrom,
334 CSSPropertyWebkitRegionOverflow,
335 CSSPropertyWebkitRegionBreakAfter,
336 CSSPropertyWebkitRegionBreakBefore,
337 CSSPropertyWebkitRegionBreakInside,
338 CSSPropertyWebkitAppRegion,
339 CSSPropertyWebkitWrapFlow,
340 CSSPropertyWebkitShapeMargin,
341 CSSPropertyWebkitShapePadding,
342 CSSPropertyWebkitWrapThrough,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100343 CSSPropertyBufferedRendering,
344 CSSPropertyClipPath,
345 CSSPropertyClipRule,
346 CSSPropertyMask,
347 CSSPropertyFilter,
348 CSSPropertyFloodColor,
349 CSSPropertyFloodOpacity,
350 CSSPropertyLightingColor,
351 CSSPropertyStopColor,
352 CSSPropertyStopOpacity,
353 CSSPropertyColorInterpolation,
354 CSSPropertyColorInterpolationFilters,
355 CSSPropertyColorRendering,
356 CSSPropertyFill,
357 CSSPropertyFillOpacity,
358 CSSPropertyFillRule,
359 CSSPropertyMarkerEnd,
360 CSSPropertyMarkerMid,
361 CSSPropertyMarkerStart,
362 CSSPropertyMaskType,
363 CSSPropertyShapeRendering,
364 CSSPropertyStroke,
365 CSSPropertyStrokeDasharray,
366 CSSPropertyStrokeDashoffset,
367 CSSPropertyStrokeLinecap,
368 CSSPropertyStrokeLinejoin,
369 CSSPropertyStrokeMiterlimit,
370 CSSPropertyStrokeOpacity,
371 CSSPropertyStrokeWidth,
372 CSSPropertyAlignmentBaseline,
373 CSSPropertyBaselineShift,
374 CSSPropertyDominantBaseline,
375 CSSPropertyKerning,
376 CSSPropertyTextAnchor,
377 CSSPropertyWritingMode,
378 CSSPropertyGlyphOrientationHorizontal,
379 CSSPropertyGlyphOrientationVertical,
380 CSSPropertyWebkitSvgShadow,
381 CSSPropertyVectorEffect
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100382};
383
384static const Vector<CSSPropertyID>& computableProperties()
385{
386 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
387 if (properties.isEmpty())
388 RuntimeCSSEnabled::filterEnabledCSSPropertiesIntoVector(staticComputableProperties, WTF_ARRAY_LENGTH(staticComputableProperties), properties);
389 return properties;
390}
391
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100392static CSSValueID valueForRepeatRule(int rule)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100393{
394 switch (rule) {
395 case RepeatImageRule:
396 return CSSValueRepeat;
397 case RoundImageRule:
398 return CSSValueRound;
399 case SpaceImageRule:
400 return CSSValueSpace;
401 default:
402 return CSSValueStretch;
403 }
404}
405
406static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
407{
408 // Create the slices.
409 RefPtr<CSSPrimitiveValue> top;
410 RefPtr<CSSPrimitiveValue> right;
411 RefPtr<CSSPrimitiveValue> bottom;
412 RefPtr<CSSPrimitiveValue> left;
413
414 if (image.imageSlices().top().isPercent())
415 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
416 else
417 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
418
419 if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top()
420 && image.imageSlices().left() == image.imageSlices().top()) {
421 right = top;
422 bottom = top;
423 left = top;
424 } else {
425 if (image.imageSlices().right().isPercent())
426 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
427 else
428 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
429
430 if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) {
431 bottom = top;
432 left = right;
433 } else {
434 if (image.imageSlices().bottom().isPercent())
435 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
436 else
437 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
438
439 if (image.imageSlices().left() == image.imageSlices().right())
440 left = right;
441 else {
442 if (image.imageSlices().left().isPercent())
443 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
444 else
445 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
446 }
447 }
448 }
449
450 RefPtr<Quad> quad = Quad::create();
451 quad->setTop(top);
452 quad->setRight(right);
453 quad->setBottom(bottom);
454 quad->setLeft(left);
455
456 return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill());
457}
458
459static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
460{
461 // Create the slices.
462 RefPtr<CSSPrimitiveValue> top;
463 RefPtr<CSSPrimitiveValue> right;
464 RefPtr<CSSPrimitiveValue> bottom;
465 RefPtr<CSSPrimitiveValue> left;
466
467 if (box.top().isRelative())
468 top = cssValuePool().createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER);
469 else
470 top = cssValuePool().createValue(box.top());
471
472 if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
473 right = top;
474 bottom = top;
475 left = top;
476 } else {
477 if (box.right().isRelative())
478 right = cssValuePool().createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER);
479 else
480 right = cssValuePool().createValue(box.right());
481
482 if (box.bottom() == box.top() && box.right() == box.left()) {
483 bottom = top;
484 left = right;
485 } else {
486 if (box.bottom().isRelative())
487 bottom = cssValuePool().createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
488 else
489 bottom = cssValuePool().createValue(box.bottom());
490
491 if (box.left() == box.right())
492 left = right;
493 else {
494 if (box.left().isRelative())
495 left = cssValuePool().createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER);
496 else
497 left = cssValuePool().createValue(box.left());
498 }
499 }
500 }
501
502 RefPtr<Quad> quad = Quad::create();
503 quad->setTop(top);
504 quad->setRight(right);
505 quad->setBottom(bottom);
506 quad->setLeft(left);
507
508 return cssValuePool().createValue(quad.release());
509}
510
511static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
512{
513 RefPtr<CSSPrimitiveValue> horizontalRepeat;
514 RefPtr<CSSPrimitiveValue> verticalRepeat;
515
516 horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
517 if (image.horizontalRule() == image.verticalRule())
518 verticalRepeat = horizontalRepeat;
519 else
520 verticalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.verticalRule()));
521 return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release()));
522}
523
524static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
525{
526 if (!image.hasImage())
527 return cssValuePool().createIdentifierValue(CSSValueNone);
528
529 // Image first.
530 RefPtr<CSSValue> imageValue;
531 if (image.image())
532 imageValue = image.image()->cssValue();
533
534 // Create the image slice.
535 RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
536
537 // Create the border area slices.
538 RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices());
539
540 // Create the border outset.
541 RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset());
542
543 // Create the repeat rules.
544 RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
545
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100546 return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100547}
548
549inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle* style)
550{
551 return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
552}
553
554inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style)
555{
556 return cssValuePool().createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
557}
558
559static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style)
560{
561 if (length.isFixed())
562 return zoomAdjustedPixelValue(length.value(), style);
563 return cssValuePool().createValue(length);
564}
565
566static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style)
567{
568 if (!reflection)
569 return cssValuePool().createIdentifierValue(CSSValueNone);
570
571 RefPtr<CSSPrimitiveValue> offset;
572 if (reflection->offset().isPercent())
573 offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
574 else
575 offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
576
577 RefPtr<CSSPrimitiveValue> direction;
578 switch (reflection->direction()) {
579 case ReflectionBelow:
580 direction = cssValuePool().createIdentifierValue(CSSValueBelow);
581 break;
582 case ReflectionAbove:
583 direction = cssValuePool().createIdentifierValue(CSSValueAbove);
584 break;
585 case ReflectionLeft:
586 direction = cssValuePool().createIdentifierValue(CSSValueLeft);
587 break;
588 case ReflectionRight:
589 direction = cssValuePool().createIdentifierValue(CSSValueRight);
590 break;
591 }
592
593 return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask()));
594}
595
596static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle* style)
597{
598 RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
599 if (layer->isBackgroundOriginSet()) {
600 ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
601 positionList->append(cssValuePool().createValue(layer->backgroundXOrigin()));
602 }
603 positionList->append(zoomAdjustedPixelValueForLength(layer->xPosition(), style));
604 if (layer->isBackgroundOriginSet()) {
605 ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
606 positionList->append(cssValuePool().createValue(layer->backgroundYOrigin()));
607 }
608 positionList->append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
609 return positionList.release();
610}
611
612static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView)
613{
614 if (!style)
615 return 0;
616
617 Length l;
618 switch (propertyID) {
619 case CSSPropertyLeft:
620 l = style->left();
621 break;
622 case CSSPropertyRight:
623 l = style->right();
624 break;
625 case CSSPropertyTop:
626 l = style->top();
627 break;
628 case CSSPropertyBottom:
629 l = style->bottom();
630 break;
631 default:
632 return 0;
633 }
634
635 if (l.isPercent() && renderer && renderer->isBox()) {
636 LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
637 toRenderBox(renderer)->containingBlockLogicalWidthForContent() :
638 toRenderBox(renderer)->containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
639 return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize, 0), style);
640 } if (l.isViewportPercentage())
641 return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style);
642 if (l.isAuto()) {
643 // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
644 // In other words if left is auto and right is not auto, then left's computed value is negative right().
645 // So we should get the opposite length unit and see if it is auto.
646 return cssValuePool().createValue(l);
647 }
648
649 return zoomAdjustedPixelValueForLength(l, style);
650}
651
652PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
653{
654 // This function does NOT look at visited information, so that computed style doesn't expose that.
655 if (!color.isValid())
656 return cssValuePool().createColorValue(style->color().rgb());
657 return cssValuePool().createColorValue(color.rgb());
658}
659
660static PassRefPtr<CSSValueList> getBorderRadiusCornerValues(LengthSize radius, const RenderStyle* style, RenderView* renderView)
661{
662 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
663 if (radius.width().type() == Percent)
664 list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
665 else
666 list->append(zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style));
667 if (radius.height().type() == Percent)
668 list->append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
669 else
670 list->append(zoomAdjustedPixelValue(valueForLength(radius.height(), 0, renderView), style));
671 return list.release();
672}
673
674static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, RenderView* renderView)
675{
676 if (radius.width() == radius.height()) {
677 if (radius.width().type() == Percent)
678 return cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
679 return zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style);
680 }
681 return getBorderRadiusCornerValues(radius, style, renderView);
682}
683
684static PassRefPtr<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* style, RenderView* renderView)
685{
686 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
687 bool showHorizontalBottomLeft = style->borderTopRightRadius().width() != style->borderBottomLeftRadius().width();
688 bool showHorizontalBottomRight = style->borderBottomRightRadius().width() != style->borderTopLeftRadius().width();
689 bool showHorizontalTopRight = style->borderTopRightRadius().width() != style->borderTopLeftRadius().width();
690
691 bool showVerticalBottomLeft = style->borderTopRightRadius().height() != style->borderBottomLeftRadius().height();
692 bool showVerticalBottomRight = (style->borderBottomRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomLeft;
693 bool showVerticalTopRight = (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomRight;
694 bool showVerticalTopLeft = (style->borderTopLeftRadius().width() != style->borderTopLeftRadius().height());
695
696 RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style->borderTopLeftRadius(), style, renderView);
697 RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style->borderTopRightRadius(), style, renderView);
698 RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style->borderBottomRightRadius(), style, renderView);
699 RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style->borderBottomLeftRadius(), style, renderView);
700
701 RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
702 horizontalRadii->append(topLeftRadius->item(0));
703 if (showHorizontalTopRight)
704 horizontalRadii->append(topRightRadius->item(0));
705 if (showHorizontalBottomRight)
706 horizontalRadii->append(bottomRightRadius->item(0));
707 if (showHorizontalBottomLeft)
708 horizontalRadii->append(bottomLeftRadius->item(0));
709
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100710 list->append(horizontalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100711
712 if (showVerticalTopLeft) {
713 RefPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated();
714 verticalRadii->append(topLeftRadius->item(1));
715 if (showVerticalTopRight)
716 verticalRadii->append(topRightRadius->item(1));
717 if (showVerticalBottomRight)
718 verticalRadii->append(bottomRightRadius->item(1));
719 if (showVerticalBottomLeft)
720 verticalRadii->append(bottomLeftRadius->item(1));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100721 list->append(verticalRadii.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100722 }
723 return list.release();
724}
725
726static LayoutRect sizingBox(RenderObject* renderer)
727{
728 if (!renderer->isBox())
729 return LayoutRect();
730
731 RenderBox* box = toRenderBox(renderer);
732 return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect();
733}
734
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100735static PassRefPtr<CSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle* style)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100736{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100737 RefPtr<CSSTransformValue> transformValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100738 if (transform.isAffine()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100739 transformValue = CSSTransformValue::create(CSSTransformValue::MatrixTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100740
741 transformValue->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
742 transformValue->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
743 transformValue->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
744 transformValue->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
745 transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
746 transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
747 } else {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100748 transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100749
750 transformValue->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
751 transformValue->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
752 transformValue->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
753 transformValue->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
754
755 transformValue->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
756 transformValue->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
757 transformValue->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
758 transformValue->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
759
760 transformValue->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
761 transformValue->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
762 transformValue->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
763 transformValue->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
764
765 transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
766 transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
767 transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
768 transformValue->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
769 }
770
771 return transformValue.release();
772}
773
774static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style)
775{
776 if (!renderer || !renderer->hasTransform() || !style->hasTransform())
777 return cssValuePool().createIdentifierValue(CSSValueNone);
778
779 IntRect box;
780 if (renderer->isBox())
781 box = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect());
782
783 TransformationMatrix transform;
784 style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
785
786 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
787 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
788 list->append(matrixTransformValue(transform, style));
789
790 return list.release();
791}
792
793static PassRefPtr<CSSValue> valueForCustomFilterArrayParameter(const CustomFilterArrayParameter* arrayParameter)
794{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100795 RefPtr<CSSArrayFunctionValue> arrayParameterValue = CSSArrayFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100796 for (unsigned i = 0, size = arrayParameter->size(); i < size; ++i)
797 arrayParameterValue->append(cssValuePool().createValue(arrayParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
798 return arrayParameterValue.release();
799}
800
801static PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter)
802{
803 RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated();
804 for (unsigned i = 0; i < numberParameter->size(); ++i)
805 numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
806 return numberParameterValue.release();
807}
808
809static PassRefPtr<CSSValue> valueForCustomFilterTransformParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterTransformParameter* transformParameter)
810{
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100811 IntSize size;
812 if (renderer && renderer->isBox())
813 size = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()).size();
814
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100815 TransformationMatrix transform;
816 transformParameter->applyTransform(transform, size);
817 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
818 return matrixTransformValue(transform, style);
819}
820
821static PassRefPtr<CSSValue> valueForCustomFilterParameter(const RenderObject* renderer, const RenderStyle* style, const CustomFilterParameter* parameter)
822{
823 // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture.
824 ASSERT(parameter);
825 switch (parameter->parameterType()) {
826 case CustomFilterParameter::ARRAY:
827 return valueForCustomFilterArrayParameter(static_cast<const CustomFilterArrayParameter*>(parameter));
828 case CustomFilterParameter::NUMBER:
829 return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter));
830 case CustomFilterParameter::TRANSFORM:
831 return valueForCustomFilterTransformParameter(renderer, style, static_cast<const CustomFilterTransformParameter*>(parameter));
832 }
833
834 ASSERT_NOT_REACHED();
835 return 0;
836}
837
838PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle* style) const
839{
840 if (style->filter().operations().isEmpty())
841 return cssValuePool().createIdentifierValue(CSSValueNone);
842
843 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
844
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100845 RefPtr<CSSFilterValue> filterValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100846
847 Vector<RefPtr<FilterOperation> >::const_iterator end = style->filter().operations().end();
848 for (Vector<RefPtr<FilterOperation> >::const_iterator it = style->filter().operations().begin(); it != end; ++it) {
849 FilterOperation* filterOperation = (*it).get();
850 switch (filterOperation->getOperationType()) {
851 case FilterOperation::REFERENCE: {
852 ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100853 filterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100854 filterValue->append(cssValuePool().createValue(referenceOperation->url(), CSSPrimitiveValue::CSS_STRING));
855 break;
856 }
857 case FilterOperation::GRAYSCALE: {
858 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100859 filterValue = CSSFilterValue::create(CSSFilterValue::GrayscaleFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100860 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
861 break;
862 }
863 case FilterOperation::SEPIA: {
864 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100865 filterValue = CSSFilterValue::create(CSSFilterValue::SepiaFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100866 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
867 break;
868 }
869 case FilterOperation::SATURATE: {
870 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100871 filterValue = CSSFilterValue::create(CSSFilterValue::SaturateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100872 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
873 break;
874 }
875 case FilterOperation::HUE_ROTATE: {
876 BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100877 filterValue = CSSFilterValue::create(CSSFilterValue::HueRotateFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100878 filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_DEG));
879 break;
880 }
881 case FilterOperation::INVERT: {
882 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100883 filterValue = CSSFilterValue::create(CSSFilterValue::InvertFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100884 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
885 break;
886 }
887 case FilterOperation::OPACITY: {
888 BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100889 filterValue = CSSFilterValue::create(CSSFilterValue::OpacityFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100890 filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
891 break;
892 }
893 case FilterOperation::BRIGHTNESS: {
894 BasicComponentTransferFilterOperation* brightnessOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100895 filterValue = CSSFilterValue::create(CSSFilterValue::BrightnessFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100896 filterValue->append(cssValuePool().createValue(brightnessOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
897 break;
898 }
899 case FilterOperation::CONTRAST: {
900 BasicComponentTransferFilterOperation* contrastOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100901 filterValue = CSSFilterValue::create(CSSFilterValue::ContrastFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100902 filterValue->append(cssValuePool().createValue(contrastOperation->amount(), CSSPrimitiveValue::CSS_NUMBER));
903 break;
904 }
905 case FilterOperation::BLUR: {
906 BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100907 filterValue = CSSFilterValue::create(CSSFilterValue::BlurFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100908 filterValue->append(zoomAdjustedPixelValue(blurOperation->stdDeviation().value(), style));
909 break;
910 }
911 case FilterOperation::DROP_SHADOW: {
912 DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100913 filterValue = CSSFilterValue::create(CSSFilterValue::DropShadowFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100914 // 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 +0100915 ShadowData shadowData = ShadowData(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, dropShadowOperation->color());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100916 filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style));
917 break;
918 }
919 case FilterOperation::VALIDATED_CUSTOM:
920 // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
921 ASSERT_NOT_REACHED();
922 break;
923 case FilterOperation::CUSTOM: {
924 CustomFilterOperation* customOperation = static_cast<CustomFilterOperation*>(filterOperation);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100925 filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100926
927 // The output should be verbose, even if the values are the default ones.
928
929 ASSERT(customOperation->program());
930 StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program());
931
932 RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
933 if (program->vertexShader())
934 shadersList->append(program->vertexShader()->cssValue());
935 else
936 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
937
938 const CustomFilterProgramMixSettings mixSettings = program->mixSettings();
939 if (program->fragmentShader()) {
940 if (program->programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100941 RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100942 mixFunction->append(program->fragmentShader()->cssValue());
943 mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
944 mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
945 shadersList->append(mixFunction.release());
946 } else
947 shadersList->append(program->fragmentShader()->cssValue());
948 }
949 else
950 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
951
952 filterValue->append(shadersList.release());
953
954 RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated();
955 meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER));
956 meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
957
958 // FIXME: The specification doesn't have any "attached" identifier. Should we add one?
959 // https://bugs.webkit.org/show_bug.cgi?id=72700
960 if (customOperation->meshType() == MeshTypeDetached)
961 meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached));
962
963 filterValue->append(meshParameters.release());
964
965 const CustomFilterParameterList& parameters = customOperation->parameters();
966 size_t parametersSize = parameters.size();
967 if (!parametersSize)
968 break;
969 RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated();
970 for (size_t i = 0; i < parametersSize; ++i) {
971 const CustomFilterParameter* parameter = parameters.at(i).get();
972 RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated();
973 parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING));
974 parameterCSSNameAndValue->append(valueForCustomFilterParameter(renderer, style, parameter));
975 parametersCSSValue->append(parameterCSSNameAndValue.release());
976 }
977
978 filterValue->append(parametersCSSValue.release());
979 break;
980 }
981 default:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100982 filterValue = CSSFilterValue::create(CSSFilterValue::UnknownFilterOperation);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100983 break;
984 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100985 list->append(filterValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100986 }
987
988 return list.release();
989}
990
991static PassRefPtr<CSSValue> valueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle* style, RenderView* renderView)
992{
993 if (!trackBreadth.isLength()) {
994 String flex = String::number(trackBreadth.flex());
995 flex.append("fr");
996 return cssValuePool().createValue(flex, CSSPrimitiveValue::CSS_DIMENSION);
997 }
998
999 const Length& trackBreadthLength = trackBreadth.length();
1000 if (trackBreadthLength.isAuto())
1001 return cssValuePool().createIdentifierValue(CSSValueAuto);
1002 if (trackBreadthLength.isViewportPercentage())
1003 return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style);
1004 return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
1005}
1006
1007static PassRefPtr<CSSValue> valueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle* style, RenderView* renderView)
1008{
1009 switch (trackSize.type()) {
1010 case LengthTrackSizing:
1011 return valueForGridTrackBreadth(trackSize.length(), style, renderView);
1012 case MinMaxTrackSizing:
1013 RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1014 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView));
1015 minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView));
1016 return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
1017 }
1018 ASSERT_NOT_REACHED();
1019 return 0;
1020}
1021
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001022static void addValuesForNamedGridLinesAtIndex(const NamedGridLinesMap& namedGridLines, size_t i, CSSValueList& list)
1023{
1024 // Note that this won't return the results in the order specified in the style sheet,
1025 // which is probably fine as we stil *do* return all the expected values.
1026 NamedGridLinesMap::const_iterator it = namedGridLines.begin();
1027 NamedGridLinesMap::const_iterator end = namedGridLines.end();
1028 for (; it != end; ++it) {
1029 const Vector<size_t>& linesIndexes = it->value;
1030 for (size_t j = 0; j < linesIndexes.size(); ++j) {
1031 if (linesIndexes[j] != i)
1032 continue;
1033
1034 list.append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1035 break;
1036 }
1037 }
1038}
1039
1040static PassRefPtr<CSSValue> valueForGridTrackList(const Vector<GridTrackSize>& trackSizes, const NamedGridLinesMap& namedGridLines, const RenderStyle* style, RenderView* renderView)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001041{
1042 // Handle the 'none' case here.
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001043 if (!trackSizes.size()) {
1044 ASSERT(namedGridLines.isEmpty());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001045 return cssValuePool().createIdentifierValue(CSSValueNone);
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001046 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001047
1048 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001049 for (size_t i = 0; i < trackSizes.size(); ++i) {
1050 addValuesForNamedGridLinesAtIndex(namedGridLines, i, *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001051 list->append(valueForGridTrackSize(trackSizes[i], style, renderView));
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001052 }
1053 // Those are the trailing <string>* allowed in the syntax.
1054 addValuesForNamedGridLinesAtIndex(namedGridLines, trackSizes.size(), *list);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001055 return list.release();
1056}
1057
1058static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
1059{
1060 if (position.isAuto())
1061 return cssValuePool().createIdentifierValue(CSSValueAuto);
1062
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001063 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001064 if (position.isSpan()) {
1065 list->append(cssValuePool().createIdentifierValue(CSSValueSpan));
1066 list->append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1067 } else
1068 list->append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1069
1070 if (!position.namedGridLine().isNull())
1071 list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001072 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
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001225static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001226{
1227 ASSERT_ARG(keywordSize, keywordSize);
1228 ASSERT_ARG(keywordSize, keywordSize <= 8);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001229 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001230}
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
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001285static CSSValueID identifierForFamily(const AtomicString& family)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001286{
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;
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001299 return CSSValueInvalid;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001300}
1301
1302static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1303{
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001304 if (CSSValueID familyIdentifier = identifierForFamily(family))
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001305 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();
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001313 if (textDecoration & TextDecorationUnderline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001314 list->append(cssValuePool().createIdentifierValue(CSSValueUnderline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001315 if (textDecoration & TextDecorationOverline)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001316 list->append(cssValuePool().createIdentifierValue(CSSValueOverline));
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001317 if (textDecoration & TextDecorationLineThrough)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001318 list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough));
1319
1320 if (!list->length())
1321 return cssValuePool().createIdentifierValue(CSSValueNone);
1322 return list;
1323}
1324
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001325static PassRefPtr<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1326{
1327 switch (textDecorationStyle) {
1328 case TextDecorationStyleSolid:
1329 return cssValuePool().createIdentifierValue(CSSValueSolid);
1330 case TextDecorationStyleDouble:
1331 return cssValuePool().createIdentifierValue(CSSValueDouble);
1332 case TextDecorationStyleDotted:
1333 return cssValuePool().createIdentifierValue(CSSValueDotted);
1334 case TextDecorationStyleDashed:
1335 return cssValuePool().createIdentifierValue(CSSValueDashed);
1336 case TextDecorationStyleWavy:
1337 return cssValuePool().createIdentifierValue(CSSValueWavy);
1338 }
1339
1340 ASSERT_NOT_REACHED();
1341 return cssValuePool().createExplicitInitialValue();
1342}
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001343
1344static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1345{
1346 // For backwards compatibility, if both values are equal, just return one of them. And
1347 // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1348 if (xRepeat == yRepeat)
1349 return cssValuePool().createValue(xRepeat);
1350 if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1351 return cssValuePool().createIdentifierValue(CSSValueRepeatX);
1352 if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1353 return cssValuePool().createIdentifierValue(CSSValueRepeatY);
1354
1355 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1356 list->append(cssValuePool().createValue(xRepeat));
1357 list->append(cssValuePool().createValue(yRepeat));
1358 return list.release();
1359}
1360
1361static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style)
1362{
1363 if (fillSize.type == Contain)
1364 return cssValuePool().createIdentifierValue(CSSValueContain);
1365
1366 if (fillSize.type == Cover)
1367 return cssValuePool().createIdentifierValue(CSSValueCover);
1368
1369 if (fillSize.size.height().isAuto())
1370 return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1371
1372 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1373 list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1374 list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1375 return list.release();
1376}
1377
1378static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style)
1379{
1380 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1381 for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1382 if (contentData->isCounter()) {
1383 const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter();
1384 ASSERT(counter);
1385 list->append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1386 } else if (contentData->isImage()) {
1387 const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image();
1388 ASSERT(image);
1389 list->append(image->cssValue());
1390 } else if (contentData->isText())
1391 list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING));
1392 }
1393 if (!style->regionThread().isNull())
1394 list->append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1395 return list.release();
1396}
1397
1398static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1399{
1400 const CounterDirectiveMap* map = style->counterDirectives();
1401 if (!map)
1402 return 0;
1403
1404 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1405 for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1406 list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1407 short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1408 list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1409 }
1410 return list.release();
1411}
1412
1413static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1414{
1415 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ());
1416 if (!propertyIDSet.add(propertyID).isNewEntry)
1417 return;
1418
1419 LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1420}
1421
1422static PassRefPtr<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
1423{
1424 const FontFamily& firstFamily = style->fontDescription().family();
1425 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1426 for (const FontFamily* family = &firstFamily; family; family = family->next())
1427 list->append(valueForFamily(family->family()));
1428 return list.release();
1429}
1430
1431static PassRefPtr<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style, RenderView* renderView)
1432{
1433 Length length = style->lineHeight();
1434 if (length.isNegative())
1435 return cssValuePool().createIdentifierValue(CSSValueNormal);
1436 if (length.isPercent())
1437 // This is imperfect, because it doesn't include the zoom factor and the real computation
1438 // for how high to be in pixels does include things like minimum font size and the zoom factor.
1439 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1440 // that here either.
1441 return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style);
1442 return zoomAdjustedPixelValue(valueForLength(length, 0, renderView), style);
1443}
1444
1445static PassRefPtr<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style)
1446{
1447 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style);
1448}
1449
1450static PassRefPtr<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
1451{
1452 if (style->fontDescription().italic())
1453 return cssValuePool().createIdentifierValue(CSSValueItalic);
1454 return cssValuePool().createIdentifierValue(CSSValueNormal);
1455}
1456
1457static PassRefPtr<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style)
1458{
1459 if (style->fontDescription().smallCaps())
1460 return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
1461 return cssValuePool().createIdentifierValue(CSSValueNormal);
1462}
1463
1464static PassRefPtr<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
1465{
1466 switch (style->fontDescription().weight()) {
1467 case FontWeight100:
1468 return cssValuePool().createIdentifierValue(CSSValue100);
1469 case FontWeight200:
1470 return cssValuePool().createIdentifierValue(CSSValue200);
1471 case FontWeight300:
1472 return cssValuePool().createIdentifierValue(CSSValue300);
1473 case FontWeightNormal:
1474 return cssValuePool().createIdentifierValue(CSSValueNormal);
1475 case FontWeight500:
1476 return cssValuePool().createIdentifierValue(CSSValue500);
1477 case FontWeight600:
1478 return cssValuePool().createIdentifierValue(CSSValue600);
1479 case FontWeightBold:
1480 return cssValuePool().createIdentifierValue(CSSValueBold);
1481 case FontWeight800:
1482 return cssValuePool().createIdentifierValue(CSSValue800);
1483 case FontWeight900:
1484 return cssValuePool().createIdentifierValue(CSSValue900);
1485 }
1486 ASSERT_NOT_REACHED();
1487 return cssValuePool().createIdentifierValue(CSSValueNormal);
1488}
1489
1490static bool isLayoutDependentProperty(CSSPropertyID propertyID)
1491{
1492 switch (propertyID) {
1493 case CSSPropertyBottom:
1494 case CSSPropertyHeight:
1495 case CSSPropertyLeft:
1496 case CSSPropertyMargin:
1497 case CSSPropertyMarginBottom:
1498 case CSSPropertyMarginLeft:
1499 case CSSPropertyMarginRight:
1500 case CSSPropertyMarginTop:
1501 case CSSPropertyPadding:
1502 case CSSPropertyPaddingBottom:
1503 case CSSPropertyPaddingLeft:
1504 case CSSPropertyPaddingRight:
1505 case CSSPropertyPaddingTop:
1506 case CSSPropertyRight:
1507 case CSSPropertyTop:
1508 case CSSPropertyWebkitPerspectiveOrigin:
1509 case CSSPropertyWebkitTransform:
1510 case CSSPropertyWebkitTransformOrigin:
1511 case CSSPropertyWidth:
1512 case CSSPropertyWebkitFilter:
1513 return true;
1514 default:
1515 return false;
1516 }
1517}
1518
1519Node* CSSComputedStyleDeclaration::styledNode() const
1520{
1521 if (!m_node)
1522 return 0;
1523 if (m_node->isElementNode()) {
1524 if (PseudoElement* element = toElement(m_node.get())->pseudoElement(m_pseudoElementSpecifier))
1525 return element;
1526 }
1527 return m_node.get();
1528}
1529
1530PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1531{
1532 Node* styledNode = this->styledNode();
1533 if (!styledNode)
1534 return 0;
1535
1536 if (updateLayout) {
1537 Document* document = styledNode->document();
1538 // FIXME: Some of these cases could be narrowed down or optimized better.
1539 bool forceFullLayout = isLayoutDependentProperty(propertyID)
1540 || styledNode->isInShadowTree()
1541 || (document->styleResolverIfExists() && document->styleResolverIfExists()->hasViewportDependentMediaQueries() && document->ownerElement())
1542 || document->seamlessParentIFrame();
1543
1544 if (forceFullLayout)
1545 document->updateLayoutIgnorePendingStylesheets();
1546 else {
1547 bool needsStyleRecalc = document->hasPendingForcedStyleRecalc();
1548 for (Node* n = styledNode; n && !needsStyleRecalc; n = n->parentNode())
1549 needsStyleRecalc = n->needsStyleRecalc();
1550 if (needsStyleRecalc)
1551 document->updateStyleIfNeeded();
1552 }
1553
1554 // The style recalc could have caused the styled node to be discarded or replaced
1555 // if it was a PseudoElement so we need to update it.
1556 styledNode = this->styledNode();
1557 }
1558
1559 RenderObject* renderer = styledNode->renderer();
1560
1561 RefPtr<RenderStyle> style;
1562 if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
1563 AnimationUpdateBlock animationUpdateBlock(renderer->animation());
1564 style = renderer->animation()->getAnimatedStyleForRenderer(renderer);
1565 if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) {
1566 // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
1567 style = style->getCachedPseudoStyle(m_pseudoElementSpecifier);
1568 }
1569 } else
1570 style = styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
1571
1572 if (!style)
1573 return 0;
1574
1575 propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
1576
1577 switch (propertyID) {
1578 case CSSPropertyInvalid:
1579 case CSSPropertyVariable:
1580 break;
1581
1582 case CSSPropertyBackgroundColor:
1583 return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
1584 case CSSPropertyBackgroundImage:
1585 case CSSPropertyWebkitMaskImage: {
1586 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
1587 if (!layers)
1588 return cssValuePool().createIdentifierValue(CSSValueNone);
1589
1590 if (!layers->next()) {
1591 if (layers->image())
1592 return layers->image()->cssValue();
1593
1594 return cssValuePool().createIdentifierValue(CSSValueNone);
1595 }
1596
1597 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1598 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1599 if (currLayer->image())
1600 list->append(currLayer->image()->cssValue());
1601 else
1602 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1603 }
1604 return list.release();
1605 }
1606 case CSSPropertyBackgroundSize:
1607 case CSSPropertyWebkitBackgroundSize:
1608 case CSSPropertyWebkitMaskSize: {
1609 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
1610 if (!layers->next())
1611 return fillSizeToCSSValue(layers->size(), style.get());
1612
1613 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1614 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1615 list->append(fillSizeToCSSValue(currLayer->size(), style.get()));
1616
1617 return list.release();
1618 }
1619 case CSSPropertyBackgroundRepeat:
1620 case CSSPropertyWebkitMaskRepeat: {
1621 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
1622 if (!layers->next())
1623 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
1624
1625 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1626 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1627 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
1628
1629 return list.release();
1630 }
1631 case CSSPropertyWebkitBackgroundComposite:
1632 case CSSPropertyWebkitMaskComposite: {
1633 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
1634 if (!layers->next())
1635 return cssValuePool().createValue(layers->composite());
1636
1637 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1638 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1639 list->append(cssValuePool().createValue(currLayer->composite()));
1640
1641 return list.release();
1642 }
1643 case CSSPropertyBackgroundAttachment: {
1644 const FillLayer* layers = style->backgroundLayers();
1645 if (!layers->next())
1646 return cssValuePool().createValue(layers->attachment());
1647
1648 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1649 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1650 list->append(cssValuePool().createValue(currLayer->attachment()));
1651
1652 return list.release();
1653 }
1654 case CSSPropertyBackgroundClip:
1655 case CSSPropertyBackgroundOrigin:
1656 case CSSPropertyWebkitBackgroundClip:
1657 case CSSPropertyWebkitBackgroundOrigin:
1658 case CSSPropertyWebkitMaskClip:
1659 case CSSPropertyWebkitMaskOrigin: {
1660 const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
1661 bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
1662 if (!layers->next()) {
1663 EFillBox box = isClip ? layers->clip() : layers->origin();
1664 return cssValuePool().createValue(box);
1665 }
1666
1667 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1668 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1669 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
1670 list->append(cssValuePool().createValue(box));
1671 }
1672
1673 return list.release();
1674 }
1675 case CSSPropertyBackgroundPosition:
1676 case CSSPropertyWebkitMaskPosition: {
1677 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
1678 if (!layers->next())
1679 return createPositionListForLayer(propertyID, layers, style.get());
1680
1681 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1682 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1683 list->append(createPositionListForLayer(propertyID, currLayer, style.get()));
1684 return list.release();
1685 }
1686 case CSSPropertyBackgroundPositionX:
1687 case CSSPropertyWebkitMaskPositionX: {
1688 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
1689 if (!layers->next())
1690 return cssValuePool().createValue(layers->xPosition());
1691
1692 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1693 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1694 list->append(cssValuePool().createValue(currLayer->xPosition()));
1695
1696 return list.release();
1697 }
1698 case CSSPropertyBackgroundPositionY:
1699 case CSSPropertyWebkitMaskPositionY: {
1700 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
1701 if (!layers->next())
1702 return cssValuePool().createValue(layers->yPosition());
1703
1704 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1705 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1706 list->append(cssValuePool().createValue(currLayer->yPosition()));
1707
1708 return list.release();
1709 }
1710 case CSSPropertyBorderCollapse:
1711 if (style->borderCollapse())
1712 return cssValuePool().createIdentifierValue(CSSValueCollapse);
1713 return cssValuePool().createIdentifierValue(CSSValueSeparate);
1714 case CSSPropertyBorderSpacing: {
1715 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1716 list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()));
1717 list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()));
1718 return list.release();
1719 }
1720 case CSSPropertyWebkitBorderHorizontalSpacing:
1721 return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get());
1722 case CSSPropertyWebkitBorderVerticalSpacing:
1723 return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get());
1724 case CSSPropertyBorderImageSource:
1725 if (style->borderImageSource())
1726 return style->borderImageSource()->cssValue();
1727 return cssValuePool().createIdentifierValue(CSSValueNone);
1728 case CSSPropertyBorderTopColor:
1729 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
1730 case CSSPropertyBorderRightColor:
1731 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
1732 case CSSPropertyBorderBottomColor:
1733 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
1734 case CSSPropertyBorderLeftColor:
1735 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
1736 case CSSPropertyBorderTopStyle:
1737 return cssValuePool().createValue(style->borderTopStyle());
1738 case CSSPropertyBorderRightStyle:
1739 return cssValuePool().createValue(style->borderRightStyle());
1740 case CSSPropertyBorderBottomStyle:
1741 return cssValuePool().createValue(style->borderBottomStyle());
1742 case CSSPropertyBorderLeftStyle:
1743 return cssValuePool().createValue(style->borderLeftStyle());
1744 case CSSPropertyBorderTopWidth:
1745 return zoomAdjustedPixelValue(style->borderTopWidth(), style.get());
1746 case CSSPropertyBorderRightWidth:
1747 return zoomAdjustedPixelValue(style->borderRightWidth(), style.get());
1748 case CSSPropertyBorderBottomWidth:
1749 return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get());
1750 case CSSPropertyBorderLeftWidth:
1751 return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get());
1752 case CSSPropertyBottom:
1753 return getPositionOffsetValue(style.get(), CSSPropertyBottom, renderer, m_node->document()->renderView());
1754 case CSSPropertyWebkitBoxAlign:
1755 return cssValuePool().createValue(style->boxAlign());
1756 case CSSPropertyWebkitBoxDecorationBreak:
1757 if (style->boxDecorationBreak() == DSLICE)
1758 return cssValuePool().createIdentifierValue(CSSValueSlice);
1759 return cssValuePool().createIdentifierValue(CSSValueClone);
1760 case CSSPropertyWebkitBoxDirection:
1761 return cssValuePool().createValue(style->boxDirection());
1762 case CSSPropertyWebkitBoxFlex:
1763 return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
1764 case CSSPropertyWebkitBoxFlexGroup:
1765 return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
1766 case CSSPropertyWebkitBoxLines:
1767 return cssValuePool().createValue(style->boxLines());
1768 case CSSPropertyWebkitBoxOrdinalGroup:
1769 return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
1770 case CSSPropertyWebkitBoxOrient:
1771 return cssValuePool().createValue(style->boxOrient());
1772 case CSSPropertyWebkitBoxPack:
1773 return cssValuePool().createValue(style->boxPack());
1774 case CSSPropertyWebkitBoxReflect:
1775 return valueForReflection(style->boxReflect(), style.get());
1776 case CSSPropertyBoxShadow:
1777 case CSSPropertyWebkitBoxShadow:
1778 return valueForShadow(style->boxShadow(), propertyID, style.get());
1779 case CSSPropertyCaptionSide:
1780 return cssValuePool().createValue(style->captionSide());
1781 case CSSPropertyClear:
1782 return cssValuePool().createValue(style->clear());
1783 case CSSPropertyColor:
1784 return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
1785 case CSSPropertyWebkitPrintColorAdjust:
1786 return cssValuePool().createValue(style->printColorAdjust());
1787 case CSSPropertyWebkitColumnAxis:
1788 return cssValuePool().createValue(style->columnAxis());
1789 case CSSPropertyWebkitColumnCount:
1790 if (style->hasAutoColumnCount())
1791 return cssValuePool().createIdentifierValue(CSSValueAuto);
1792 return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
1793 case CSSPropertyWebkitColumnGap:
1794 if (style->hasNormalColumnGap())
1795 return cssValuePool().createIdentifierValue(CSSValueNormal);
1796 return zoomAdjustedPixelValue(style->columnGap(), style.get());
1797 case CSSPropertyWebkitColumnProgression:
1798 return cssValuePool().createValue(style->columnProgression());
1799 case CSSPropertyWebkitColumnRuleColor:
1800 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
1801 case CSSPropertyWebkitColumnRuleStyle:
1802 return cssValuePool().createValue(style->columnRuleStyle());
1803 case CSSPropertyWebkitColumnRuleWidth:
1804 return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get());
1805 case CSSPropertyWebkitColumnSpan:
1806 return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
1807 case CSSPropertyWebkitColumnBreakAfter:
1808 return cssValuePool().createValue(style->columnBreakAfter());
1809 case CSSPropertyWebkitColumnBreakBefore:
1810 return cssValuePool().createValue(style->columnBreakBefore());
1811 case CSSPropertyWebkitColumnBreakInside:
1812 return cssValuePool().createValue(style->columnBreakInside());
1813 case CSSPropertyWebkitColumnWidth:
1814 if (style->hasAutoColumnWidth())
1815 return cssValuePool().createIdentifierValue(CSSValueAuto);
1816 return zoomAdjustedPixelValue(style->columnWidth(), style.get());
1817 case CSSPropertyTabSize:
1818 return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
1819 case CSSPropertyWebkitRegionBreakAfter:
1820 return cssValuePool().createValue(style->regionBreakAfter());
1821 case CSSPropertyWebkitRegionBreakBefore:
1822 return cssValuePool().createValue(style->regionBreakBefore());
1823 case CSSPropertyWebkitRegionBreakInside:
1824 return cssValuePool().createValue(style->regionBreakInside());
1825 case CSSPropertyCursor: {
1826 RefPtr<CSSValueList> list;
1827 CursorList* cursors = style->cursors();
1828 if (cursors && cursors->size() > 0) {
1829 list = CSSValueList::createCommaSeparated();
1830 for (unsigned i = 0; i < cursors->size(); ++i)
1831 if (StyleImage* image = cursors->at(i).image())
1832 list->append(image->cssValue());
1833 }
1834 RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
1835 if (list) {
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01001836 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001837 return list.release();
1838 }
1839 return value.release();
1840 }
1841 case CSSPropertyDirection:
1842 return cssValuePool().createValue(style->direction());
1843 case CSSPropertyDisplay:
1844 return cssValuePool().createValue(style->display());
1845 case CSSPropertyEmptyCells:
1846 return cssValuePool().createValue(style->emptyCells());
1847 case CSSPropertyWebkitAlignContent:
1848 return cssValuePool().createValue(style->alignContent());
1849 case CSSPropertyWebkitAlignItems:
1850 return cssValuePool().createValue(style->alignItems());
1851 case CSSPropertyWebkitAlignSelf:
1852 if (style->alignSelf() == AlignAuto) {
1853 Node* parent = styledNode->parentNode();
1854 if (parent && parent->computedStyle())
1855 return cssValuePool().createValue(parent->computedStyle()->alignItems());
1856 return cssValuePool().createValue(AlignStretch);
1857 }
1858 return cssValuePool().createValue(style->alignSelf());
1859 case CSSPropertyWebkitFlex:
1860 return getCSSPropertyValuesForShorthandProperties(webkitFlexShorthand());
1861 case CSSPropertyWebkitFlexBasis:
1862 return cssValuePool().createValue(style->flexBasis());
1863 case CSSPropertyWebkitFlexDirection:
1864 return cssValuePool().createValue(style->flexDirection());
1865 case CSSPropertyWebkitFlexFlow:
1866 return getCSSPropertyValuesForShorthandProperties(webkitFlexFlowShorthand());
1867 case CSSPropertyWebkitFlexGrow:
1868 return cssValuePool().createValue(style->flexGrow());
1869 case CSSPropertyWebkitFlexShrink:
1870 return cssValuePool().createValue(style->flexShrink());
1871 case CSSPropertyWebkitFlexWrap:
1872 return cssValuePool().createValue(style->flexWrap());
1873 case CSSPropertyWebkitJustifyContent:
1874 return cssValuePool().createValue(style->justifyContent());
1875 case CSSPropertyWebkitOrder:
1876 return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
1877 case CSSPropertyFloat:
1878 if (style->display() != NONE && style->hasOutOfFlowPosition())
1879 return cssValuePool().createIdentifierValue(CSSValueNone);
1880 return cssValuePool().createValue(style->floating());
1881 case CSSPropertyFont: {
1882 RefPtr<FontValue> computedFont = FontValue::create();
1883 computedFont->style = fontStyleFromStyle(style.get());
1884 computedFont->variant = fontVariantFromStyle(style.get());
1885 computedFont->weight = fontWeightFromStyle(style.get());
1886 computedFont->size = fontSizeFromStyle(style.get());
1887 computedFont->lineHeight = lineHeightFromStyle(style.get(), m_node->document()->renderView());
1888 computedFont->family = fontFamilyFromStyle(style.get());
1889 return computedFont.release();
1890 }
1891 case CSSPropertyFontFamily: {
1892 RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get());
1893 // If there's only a single family, return that as a CSSPrimitiveValue.
1894 // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
1895 if (fontFamilyList->length() == 1)
1896 return fontFamilyList->item(0);
1897 return fontFamilyList.release();
1898 }
1899 case CSSPropertyFontSize:
1900 return fontSizeFromStyle(style.get());
1901 case CSSPropertyFontStyle:
1902 return fontStyleFromStyle(style.get());
1903 case CSSPropertyFontVariant:
1904 return fontVariantFromStyle(style.get());
1905 case CSSPropertyFontWeight:
1906 return fontWeightFromStyle(style.get());
1907 case CSSPropertyWebkitFontFeatureSettings: {
1908 const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings();
1909 if (!featureSettings || !featureSettings->size())
1910 return cssValuePool().createIdentifierValue(CSSValueNormal);
1911 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1912 for (unsigned i = 0; i < featureSettings->size(); ++i) {
1913 const FontFeature& feature = featureSettings->at(i);
1914 RefPtr<FontFeatureValue> featureValue = FontFeatureValue::create(feature.tag(), feature.value());
1915 list->append(featureValue.release());
1916 }
1917 return list.release();
1918 }
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001919 case CSSPropertyGridAutoColumns:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001920 return valueForGridTrackSize(style->gridAutoColumns(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001921 case CSSPropertyGridAutoFlow:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001922 return cssValuePool().createValue(style->gridAutoFlow());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001923 case CSSPropertyGridAutoRows:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001924 return valueForGridTrackSize(style->gridAutoRows(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001925 case CSSPropertyGridColumns:
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001926 return valueForGridTrackList(style->gridColumns(), style->namedGridColumnLines(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001927 case CSSPropertyGridRows:
Torne (Richard Coles)81a51572013-05-13 16:52:28 +01001928 return valueForGridTrackList(style->gridRows(), style->namedGridRowLines(), style.get(), m_node->document()->renderView());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001929
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001930 case CSSPropertyGridStart:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001931 return valueForGridPosition(style->gridStart());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001932 case CSSPropertyGridEnd:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001933 return valueForGridPosition(style->gridEnd());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001934 case CSSPropertyGridBefore:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001935 return valueForGridPosition(style->gridBefore());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001936 case CSSPropertyGridAfter:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001937 return valueForGridPosition(style->gridAfter());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01001938 case CSSPropertyGridColumn:
1939 return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
1940 case CSSPropertyGridRow:
1941 return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
1942 case CSSPropertyGridArea:
1943 return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001944
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:
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002134 case CSSPropertyTextDecorationLine:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002135 return renderTextDecorationFlagsToCSSValue(style->textDecoration());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002136 case CSSPropertyTextDecorationStyle:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002137 return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002138 case CSSPropertyTextDecorationColor:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002139 return currentColorOrValidColor(style.get(), style->textDecorationColor());
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002140#if ENABLE(CSS3_TEXT)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002141 case CSSPropertyWebkitTextAlignLast:
2142 return cssValuePool().createValue(style->textAlignLast());
2143 case CSSPropertyWebkitTextUnderlinePosition:
2144 return cssValuePool().createValue(style->textUnderlinePosition());
2145#endif // CSS3_TEXT
2146 case CSSPropertyWebkitTextDecorationsInEffect:
2147 return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
2148 case CSSPropertyWebkitTextFillColor:
2149 return currentColorOrValidColor(style.get(), style->textFillColor());
2150 case CSSPropertyWebkitTextEmphasisColor:
2151 return currentColorOrValidColor(style.get(), style->textEmphasisColor());
2152 case CSSPropertyWebkitTextEmphasisPosition:
2153 return cssValuePool().createValue(style->textEmphasisPosition());
2154 case CSSPropertyWebkitTextEmphasisStyle:
2155 switch (style->textEmphasisMark()) {
2156 case TextEmphasisMarkNone:
2157 return cssValuePool().createIdentifierValue(CSSValueNone);
2158 case TextEmphasisMarkCustom:
2159 return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
2160 case TextEmphasisMarkAuto:
2161 ASSERT_NOT_REACHED();
2162 // Fall through
2163 case TextEmphasisMarkDot:
2164 case TextEmphasisMarkCircle:
2165 case TextEmphasisMarkDoubleCircle:
2166 case TextEmphasisMarkTriangle:
2167 case TextEmphasisMarkSesame: {
2168 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2169 list->append(cssValuePool().createValue(style->textEmphasisFill()));
2170 list->append(cssValuePool().createValue(style->textEmphasisMark()));
2171 return list.release();
2172 }
2173 }
2174 case CSSPropertyTextIndent: {
2175 RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), style.get());
2176#if ENABLE(CSS3_TEXT)
2177 if (style->textIndentLine() == TextIndentEachLine) {
2178 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2179 list->append(textIndent.release());
2180 list->append(cssValuePool().createIdentifierValue(CSSValueWebkitEachLine));
2181 return list.release();
2182 }
2183#endif
2184 return textIndent.release();
2185 }
2186 case CSSPropertyTextShadow:
2187 return valueForShadow(style->textShadow(), propertyID, style.get());
2188 case CSSPropertyTextRendering:
2189 return cssValuePool().createValue(style->fontDescription().textRenderingMode());
2190 case CSSPropertyTextOverflow:
2191 if (style->textOverflow())
2192 return cssValuePool().createIdentifierValue(CSSValueEllipsis);
2193 return cssValuePool().createIdentifierValue(CSSValueClip);
2194 case CSSPropertyWebkitTextSecurity:
2195 return cssValuePool().createValue(style->textSecurity());
2196 case CSSPropertyWebkitTextStrokeColor:
2197 return currentColorOrValidColor(style.get(), style->textStrokeColor());
2198 case CSSPropertyWebkitTextStrokeWidth:
2199 return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get());
2200 case CSSPropertyTextTransform:
2201 return cssValuePool().createValue(style->textTransform());
2202 case CSSPropertyTop:
2203 return getPositionOffsetValue(style.get(), CSSPropertyTop, renderer, m_node->document()->renderView());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002204 case CSSPropertyTouchAction:
2205 return cssValuePool().createValue(style->touchAction());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002206 case CSSPropertyUnicodeBidi:
2207 return cssValuePool().createValue(style->unicodeBidi());
2208 case CSSPropertyVerticalAlign:
2209 switch (style->verticalAlign()) {
2210 case BASELINE:
2211 return cssValuePool().createIdentifierValue(CSSValueBaseline);
2212 case MIDDLE:
2213 return cssValuePool().createIdentifierValue(CSSValueMiddle);
2214 case SUB:
2215 return cssValuePool().createIdentifierValue(CSSValueSub);
2216 case SUPER:
2217 return cssValuePool().createIdentifierValue(CSSValueSuper);
2218 case TEXT_TOP:
2219 return cssValuePool().createIdentifierValue(CSSValueTextTop);
2220 case TEXT_BOTTOM:
2221 return cssValuePool().createIdentifierValue(CSSValueTextBottom);
2222 case TOP:
2223 return cssValuePool().createIdentifierValue(CSSValueTop);
2224 case BOTTOM:
2225 return cssValuePool().createIdentifierValue(CSSValueBottom);
2226 case BASELINE_MIDDLE:
2227 return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
2228 case LENGTH:
2229 return cssValuePool().createValue(style->verticalAlignLength());
2230 }
2231 ASSERT_NOT_REACHED();
2232 return 0;
2233 case CSSPropertyVisibility:
2234 return cssValuePool().createValue(style->visibility());
2235 case CSSPropertyWhiteSpace:
2236 return cssValuePool().createValue(style->whiteSpace());
2237 case CSSPropertyWidows:
2238 if (style->hasAutoWidows())
2239 return cssValuePool().createIdentifierValue(CSSValueAuto);
2240 return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
2241 case CSSPropertyWidth:
2242 if (renderer) {
2243 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
2244 // the "width" property does not apply for non-replaced inline elements.
2245 if (!renderer->isReplaced() && renderer->isInline())
2246 return cssValuePool().createIdentifierValue(CSSValueAuto);
2247 return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get());
2248 }
2249 return zoomAdjustedPixelValueForLength(style->width(), style.get());
2250 case CSSPropertyWordBreak:
2251 return cssValuePool().createValue(style->wordBreak());
2252 case CSSPropertyWordSpacing:
2253 return zoomAdjustedPixelValue(style->wordSpacing(), style.get());
2254 case CSSPropertyWordWrap:
2255 return cssValuePool().createValue(style->overflowWrap());
2256 case CSSPropertyWebkitLineBreak:
2257 return cssValuePool().createValue(style->lineBreak());
2258 case CSSPropertyResize:
2259 return cssValuePool().createValue(style->resize());
2260 case CSSPropertyWebkitFontKerning:
2261 return cssValuePool().createValue(style->fontDescription().kerning());
2262 case CSSPropertyWebkitFontSmoothing:
2263 return cssValuePool().createValue(style->fontDescription().fontSmoothing());
2264 case CSSPropertyWebkitFontVariantLigatures: {
2265 FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
2266 FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
2267 FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
2268 if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
2269 && historicalLigaturesState == FontDescription::NormalLigaturesState)
2270 return cssValuePool().createIdentifierValue(CSSValueNormal);
2271
2272 RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
2273 if (commonLigaturesState != FontDescription::NormalLigaturesState)
2274 valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
2275 if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
2276 valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
2277 if (historicalLigaturesState != FontDescription::NormalLigaturesState)
2278 valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
2279 return valueList;
2280 }
2281 case CSSPropertyZIndex:
2282 if (style->hasAutoZIndex())
2283 return cssValuePool().createIdentifierValue(CSSValueAuto);
2284 return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
2285 case CSSPropertyZoom:
2286 return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
2287 case CSSPropertyBoxSizing:
2288 if (style->boxSizing() == CONTENT_BOX)
2289 return cssValuePool().createIdentifierValue(CSSValueContentBox);
2290 return cssValuePool().createIdentifierValue(CSSValueBorderBox);
2291 case CSSPropertyWebkitAppRegion:
2292 return cssValuePool().createIdentifierValue(style->getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag);
2293 case CSSPropertyWebkitAnimationDelay:
2294 return getDelayValue(style->animations());
2295 case CSSPropertyWebkitAnimationDirection: {
2296 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2297 const CSSAnimationDataList* t = style->animations();
2298 if (t) {
2299 for (size_t i = 0; i < t->size(); ++i) {
2300 if (t->animation(i)->direction())
2301 list->append(cssValuePool().createIdentifierValue(CSSValueAlternate));
2302 else
2303 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2304 }
2305 } else
2306 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2307 return list.release();
2308 }
2309 case CSSPropertyWebkitAnimationDuration:
2310 return getDurationValue(style->animations());
2311 case CSSPropertyWebkitAnimationFillMode: {
2312 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2313 const CSSAnimationDataList* t = style->animations();
2314 if (t) {
2315 for (size_t i = 0; i < t->size(); ++i) {
2316 switch (t->animation(i)->fillMode()) {
2317 case AnimationFillModeNone:
2318 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2319 break;
2320 case AnimationFillModeForwards:
2321 list->append(cssValuePool().createIdentifierValue(CSSValueForwards));
2322 break;
2323 case AnimationFillModeBackwards:
2324 list->append(cssValuePool().createIdentifierValue(CSSValueBackwards));
2325 break;
2326 case AnimationFillModeBoth:
2327 list->append(cssValuePool().createIdentifierValue(CSSValueBoth));
2328 break;
2329 }
2330 }
2331 } else
2332 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2333 return list.release();
2334 }
2335 case CSSPropertyWebkitAnimationIterationCount: {
2336 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2337 const CSSAnimationDataList* t = style->animations();
2338 if (t) {
2339 for (size_t i = 0; i < t->size(); ++i) {
2340 double iterationCount = t->animation(i)->iterationCount();
2341 if (iterationCount == CSSAnimationData::IterationCountInfinite)
2342 list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
2343 else
2344 list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
2345 }
2346 } else
2347 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2348 return list.release();
2349 }
2350 case CSSPropertyWebkitAnimationName: {
2351 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2352 const CSSAnimationDataList* t = style->animations();
2353 if (t) {
2354 for (size_t i = 0; i < t->size(); ++i)
2355 list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
2356 } else
2357 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2358 return list.release();
2359 }
2360 case CSSPropertyWebkitAnimationPlayState: {
2361 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2362 const CSSAnimationDataList* t = style->animations();
2363 if (t) {
2364 for (size_t i = 0; i < t->size(); ++i) {
2365 int prop = t->animation(i)->playState();
2366 if (prop == AnimPlayStatePlaying)
2367 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2368 else
2369 list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
2370 }
2371 } else
2372 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2373 return list.release();
2374 }
2375 case CSSPropertyWebkitAnimationTimingFunction:
2376 return getTimingFunctionValue(style->animations());
2377 case CSSPropertyWebkitAppearance:
2378 return cssValuePool().createValue(style->appearance());
2379 case CSSPropertyWebkitAspectRatio:
2380 if (!style->hasAspectRatio())
2381 return cssValuePool().createIdentifierValue(CSSValueNone);
2382 return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
2383 case CSSPropertyWebkitBackfaceVisibility:
2384 return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
2385 case CSSPropertyWebkitBorderImage:
2386 return valueForNinePieceImage(style->borderImage());
2387 case CSSPropertyBorderImageOutset:
2388 return valueForNinePieceImageQuad(style->borderImage().outset());
2389 case CSSPropertyBorderImageRepeat:
2390 return valueForNinePieceImageRepeat(style->borderImage());
2391 case CSSPropertyBorderImageSlice:
2392 return valueForNinePieceImageSlice(style->borderImage());
2393 case CSSPropertyBorderImageWidth:
2394 return valueForNinePieceImageQuad(style->borderImage().borderSlices());
2395 case CSSPropertyWebkitMaskBoxImage:
2396 return valueForNinePieceImage(style->maskBoxImage());
2397 case CSSPropertyWebkitMaskBoxImageOutset:
2398 return valueForNinePieceImageQuad(style->maskBoxImage().outset());
2399 case CSSPropertyWebkitMaskBoxImageRepeat:
2400 return valueForNinePieceImageRepeat(style->maskBoxImage());
2401 case CSSPropertyWebkitMaskBoxImageSlice:
2402 return valueForNinePieceImageSlice(style->maskBoxImage());
2403 case CSSPropertyWebkitMaskBoxImageWidth:
2404 return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
2405 case CSSPropertyWebkitMaskBoxImageSource:
2406 if (style->maskBoxImageSource())
2407 return style->maskBoxImageSource()->cssValue();
2408 return cssValuePool().createIdentifierValue(CSSValueNone);
2409 case CSSPropertyWebkitFontSizeDelta:
2410 // Not a real style property -- used by the editing engine -- so has no computed value.
2411 break;
2412 case CSSPropertyWebkitMarginBottomCollapse:
2413 case CSSPropertyWebkitMarginAfterCollapse:
2414 return cssValuePool().createValue(style->marginAfterCollapse());
2415 case CSSPropertyWebkitMarginTopCollapse:
2416 case CSSPropertyWebkitMarginBeforeCollapse:
2417 return cssValuePool().createValue(style->marginBeforeCollapse());
2418#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2419 case CSSPropertyWebkitOverflowScrolling:
2420 if (!style->useTouchOverflowScrolling())
2421 return cssValuePool().createIdentifierValue(CSSValueAuto);
2422 return cssValuePool().createIdentifierValue(CSSValueTouch);
2423#endif
2424 case CSSPropertyWebkitPerspective:
2425 if (!style->hasPerspective())
2426 return cssValuePool().createIdentifierValue(CSSValueNone);
2427 return zoomAdjustedPixelValue(style->perspective(), style.get());
2428 case CSSPropertyWebkitPerspectiveOrigin: {
2429 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2430 if (renderer) {
2431 LayoutRect box;
2432 if (renderer->isBox())
2433 box = toRenderBox(renderer)->borderBoxRect();
2434
2435 RenderView* renderView = m_node->document()->renderView();
2436 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), style.get()));
2437 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), style.get()));
2438 }
2439 else {
2440 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get()));
2441 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get()));
2442
2443 }
2444 return list.release();
2445 }
2446 case CSSPropertyWebkitRtlOrdering:
2447 return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
2448 case CSSPropertyWebkitTapHighlightColor:
2449 return currentColorOrValidColor(style.get(), style->tapHighlightColor());
2450 case CSSPropertyWebkitUserDrag:
2451 return cssValuePool().createValue(style->userDrag());
2452 case CSSPropertyWebkitUserSelect:
2453 return cssValuePool().createValue(style->userSelect());
2454 case CSSPropertyBorderBottomLeftRadius:
2455 return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), m_node->document()->renderView());
2456 case CSSPropertyBorderBottomRightRadius:
2457 return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), m_node->document()->renderView());
2458 case CSSPropertyBorderTopLeftRadius:
2459 return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), m_node->document()->renderView());
2460 case CSSPropertyBorderTopRightRadius:
2461 return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), m_node->document()->renderView());
2462 case CSSPropertyClip: {
2463 if (!style->hasClip())
2464 return cssValuePool().createIdentifierValue(CSSValueAuto);
2465 RefPtr<Rect> rect = Rect::create();
2466 rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get()));
2467 rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get()));
2468 rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get()));
2469 rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get()));
2470 return cssValuePool().createValue(rect.release());
2471 }
2472 case CSSPropertySpeak:
2473 return cssValuePool().createValue(style->speak());
2474 case CSSPropertyWebkitTransform:
2475 return computedTransform(renderer, style.get());
2476 case CSSPropertyWebkitTransformOrigin: {
2477 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2478 if (renderer) {
2479 LayoutRect box;
2480 if (renderer->isBox())
2481 box = toRenderBox(renderer)->borderBoxRect();
2482
2483 RenderView* renderView = m_node->document()->renderView();
2484 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), style.get()));
2485 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), style.get()));
2486 if (style->transformOriginZ() != 0)
2487 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2488 } else {
2489 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get()));
2490 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get()));
2491 if (style->transformOriginZ() != 0)
2492 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2493 }
2494 return list.release();
2495 }
2496 case CSSPropertyWebkitTransformStyle:
2497 return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
2498 case CSSPropertyTransitionDelay:
2499 case CSSPropertyWebkitTransitionDelay:
2500 return getDelayValue(style->transitions());
2501 case CSSPropertyTransitionDuration:
2502 case CSSPropertyWebkitTransitionDuration:
2503 return getDurationValue(style->transitions());
2504 case CSSPropertyTransitionProperty:
2505 case CSSPropertyWebkitTransitionProperty:
2506 return getTransitionPropertyValue(style->transitions());
2507 case CSSPropertyTransitionTimingFunction:
2508 case CSSPropertyWebkitTransitionTimingFunction:
2509 return getTimingFunctionValue(style->transitions());
2510 case CSSPropertyTransition:
2511 case CSSPropertyWebkitTransition: {
2512 const CSSAnimationDataList* animList = style->transitions();
2513 if (animList) {
2514 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
2515 for (size_t i = 0; i < animList->size(); ++i) {
2516 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2517 const CSSAnimationData* animation = animList->animation(i);
2518 list->append(createTransitionPropertyValue(animation));
2519 list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
2520 list->append(createTimingFunctionValue(animation->timingFunction().get()));
2521 list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
2522 transitionsList->append(list);
2523 }
2524 return transitionsList.release();
2525 }
2526
2527 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2528 // transition-property default value.
2529 list->append(cssValuePool().createIdentifierValue(CSSValueAll));
2530 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
2531 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
2532 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
2533 return list.release();
2534 }
2535 case CSSPropertyPointerEvents:
2536 return cssValuePool().createValue(style->pointerEvents());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002537 case CSSPropertyWebkitLineGrid:
2538 if (style->lineGrid().isNull())
2539 return cssValuePool().createIdentifierValue(CSSValueNone);
2540 return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
2541 case CSSPropertyWebkitLineSnap:
2542 return CSSPrimitiveValue::create(style->lineSnap());
2543 case CSSPropertyWebkitLineAlign:
2544 return CSSPrimitiveValue::create(style->lineAlign());
2545 case CSSPropertyWebkitWritingMode:
2546 return cssValuePool().createValue(style->writingMode());
2547 case CSSPropertyWebkitTextCombine:
2548 return cssValuePool().createValue(style->textCombine());
2549 case CSSPropertyWebkitTextOrientation:
2550 return CSSPrimitiveValue::create(style->textOrientation());
2551 case CSSPropertyWebkitLineBoxContain:
2552 return createLineBoxContainValue(style->lineBoxContain());
2553 case CSSPropertyContent:
2554 return contentToCSSValue(style.get());
2555 case CSSPropertyCounterIncrement:
2556 return counterToCSSValue(style.get(), propertyID);
2557 case CSSPropertyCounterReset:
2558 return counterToCSSValue(style.get(), propertyID);
2559 case CSSPropertyWebkitClipPath:
2560 if (ClipPathOperation* operation = style->clipPath()) {
2561 if (operation->getOperationType() == ClipPathOperation::SHAPE)
2562 return valueForBasicShape(static_cast<ShapeClipPathOperation*>(operation)->basicShape());
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002563 if (operation->getOperationType() == ClipPathOperation::REFERENCE) {
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002564 ReferenceClipPathOperation* referenceOperation = static_cast<ReferenceClipPathOperation*>(operation);
2565 return CSSPrimitiveValue::create(referenceOperation->url(), CSSPrimitiveValue::CSS_URI);
2566 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002567 }
2568 return cssValuePool().createIdentifierValue(CSSValueNone);
2569 case CSSPropertyWebkitFlowInto:
2570 if (style->flowThread().isNull())
2571 return cssValuePool().createIdentifierValue(CSSValueNone);
2572 return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
2573 case CSSPropertyWebkitFlowFrom:
2574 if (style->regionThread().isNull())
2575 return cssValuePool().createIdentifierValue(CSSValueNone);
2576 return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
2577 case CSSPropertyWebkitRegionOverflow:
2578 return cssValuePool().createValue(style->regionOverflow());
2579 case CSSPropertyWebkitWrapFlow:
2580 return cssValuePool().createValue(style->wrapFlow());
2581 case CSSPropertyWebkitShapeMargin:
2582 return cssValuePool().createValue(style->shapeMargin());
2583 case CSSPropertyWebkitShapePadding:
2584 return cssValuePool().createValue(style->shapePadding());
2585 case CSSPropertyWebkitShapeInside:
2586 if (!style->shapeInside())
2587 return cssValuePool().createIdentifierValue(CSSValueAuto);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002588 if (style->shapeInside()->type() == ExclusionShapeValue::Outside)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002589 return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002590 if (style->shapeInside()->type() == ExclusionShapeValue::Image) {
2591 if (style->shapeInside()->image())
2592 return style->shapeInside()->image()->cssValue();
2593 return cssValuePool().createIdentifierValue(CSSValueNone);
2594 }
2595 ASSERT(style->shapeInside()->type() == ExclusionShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002596 return valueForBasicShape(style->shapeInside()->shape());
2597 case CSSPropertyWebkitShapeOutside:
2598 if (!style->shapeOutside())
2599 return cssValuePool().createIdentifierValue(CSSValueAuto);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002600 if (style->shapeOutside()->type() == ExclusionShapeValue::Image) {
2601 if (style->shapeOutside()->image())
2602 return style->shapeOutside()->image()->cssValue();
2603 return cssValuePool().createIdentifierValue(CSSValueNone);
2604 }
2605 ASSERT(style->shapeOutside()->type() == ExclusionShapeValue::Shape);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002606 return valueForBasicShape(style->shapeOutside()->shape());
2607 case CSSPropertyWebkitWrapThrough:
2608 return cssValuePool().createValue(style->wrapThrough());
2609 case CSSPropertyWebkitFilter:
2610 return valueForFilter(renderer, style.get());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002611 case CSSPropertyMixBlendMode:
2612 return cssValuePool().createValue(style->blendMode());
2613
2614 case CSSPropertyBackgroundBlendMode: {
2615 const FillLayer* layers = style->backgroundLayers();
2616 if (!layers->next())
2617 return cssValuePool().createValue(layers->blendMode());
2618
2619 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2620 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2621 list->append(cssValuePool().createValue(currLayer->blendMode()));
2622
2623 return list.release();
2624 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002625 case CSSPropertyBackground:
2626 return getBackgroundShorthandValue();
2627 case CSSPropertyBorder: {
2628 RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
2629 const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
2630 CSSPropertyBorderLeft };
2631 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
2632 if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
2633 return 0;
2634 }
2635 return value.release();
2636 }
2637 case CSSPropertyBorderBottom:
2638 return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand());
2639 case CSSPropertyBorderColor:
2640 return getCSSPropertyValuesForSidesShorthand(borderColorShorthand());
2641 case CSSPropertyBorderLeft:
2642 return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand());
2643 case CSSPropertyBorderImage:
2644 return valueForNinePieceImage(style->borderImage());
2645 case CSSPropertyBorderRadius:
2646 return getBorderRadiusShorthandValue(style.get(), m_node->document()->renderView());
2647 case CSSPropertyBorderRight:
2648 return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
2649 case CSSPropertyBorderStyle:
2650 return getCSSPropertyValuesForSidesShorthand(borderStyleShorthand());
2651 case CSSPropertyBorderTop:
2652 return getCSSPropertyValuesForShorthandProperties(borderTopShorthand());
2653 case CSSPropertyBorderWidth:
2654 return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand());
2655 case CSSPropertyWebkitColumnRule:
2656 return getCSSPropertyValuesForShorthandProperties(webkitColumnRuleShorthand());
2657 case CSSPropertyWebkitColumns:
2658 return getCSSPropertyValuesForShorthandProperties(webkitColumnsShorthand());
2659 case CSSPropertyListStyle:
2660 return getCSSPropertyValuesForShorthandProperties(listStyleShorthand());
2661 case CSSPropertyMargin:
2662 return getCSSPropertyValuesForSidesShorthand(marginShorthand());
2663 case CSSPropertyOutline:
2664 return getCSSPropertyValuesForShorthandProperties(outlineShorthand());
2665 case CSSPropertyPadding:
2666 return getCSSPropertyValuesForSidesShorthand(paddingShorthand());
2667 /* Individual properties not part of the spec */
2668 case CSSPropertyBackgroundRepeatX:
2669 case CSSPropertyBackgroundRepeatY:
2670 break;
2671
2672 /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
2673 case CSSPropertyWebkitTextEmphasis:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002674 case CSSPropertyTextLineThroughColor:
2675 case CSSPropertyTextLineThroughMode:
2676 case CSSPropertyTextLineThroughStyle:
2677 case CSSPropertyTextLineThroughWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002678 case CSSPropertyTextOverlineColor:
2679 case CSSPropertyTextOverlineMode:
2680 case CSSPropertyTextOverlineStyle:
2681 case CSSPropertyTextOverlineWidth:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002682 case CSSPropertyTextUnderlineColor:
2683 case CSSPropertyTextUnderlineMode:
2684 case CSSPropertyTextUnderlineStyle:
2685 case CSSPropertyTextUnderlineWidth:
2686 break;
2687
2688 /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
2689 case CSSPropertyWebkitBorderEnd:
2690 case CSSPropertyWebkitBorderEndColor:
2691 case CSSPropertyWebkitBorderEndStyle:
2692 case CSSPropertyWebkitBorderEndWidth:
2693 case CSSPropertyWebkitBorderStart:
2694 case CSSPropertyWebkitBorderStartColor:
2695 case CSSPropertyWebkitBorderStartStyle:
2696 case CSSPropertyWebkitBorderStartWidth:
2697 case CSSPropertyWebkitBorderAfter:
2698 case CSSPropertyWebkitBorderAfterColor:
2699 case CSSPropertyWebkitBorderAfterStyle:
2700 case CSSPropertyWebkitBorderAfterWidth:
2701 case CSSPropertyWebkitBorderBefore:
2702 case CSSPropertyWebkitBorderBeforeColor:
2703 case CSSPropertyWebkitBorderBeforeStyle:
2704 case CSSPropertyWebkitBorderBeforeWidth:
2705 case CSSPropertyWebkitMarginEnd:
2706 case CSSPropertyWebkitMarginStart:
2707 case CSSPropertyWebkitMarginAfter:
2708 case CSSPropertyWebkitMarginBefore:
2709 case CSSPropertyWebkitPaddingEnd:
2710 case CSSPropertyWebkitPaddingStart:
2711 case CSSPropertyWebkitPaddingAfter:
2712 case CSSPropertyWebkitPaddingBefore:
2713 case CSSPropertyWebkitLogicalWidth:
2714 case CSSPropertyWebkitLogicalHeight:
2715 case CSSPropertyWebkitMinLogicalWidth:
2716 case CSSPropertyWebkitMinLogicalHeight:
2717 case CSSPropertyWebkitMaxLogicalWidth:
2718 case CSSPropertyWebkitMaxLogicalHeight:
2719 ASSERT_NOT_REACHED();
2720 break;
2721
2722 /* Unimplemented @font-face properties */
2723 case CSSPropertyFontStretch:
2724 case CSSPropertySrc:
2725 case CSSPropertyUnicodeRange:
2726 break;
2727
2728 /* Other unimplemented properties */
2729 case CSSPropertyPage: // for @page
2730 case CSSPropertyQuotes: // FIXME: needs implementation
2731 case CSSPropertySize: // for @page
2732 break;
2733
2734 /* Unimplemented -webkit- properties */
2735 case CSSPropertyWebkitAnimation:
2736 case CSSPropertyWebkitBorderRadius:
2737 case CSSPropertyWebkitMarginCollapse:
2738 case CSSPropertyWebkitMarquee:
2739 case CSSPropertyWebkitMarqueeSpeed:
2740 case CSSPropertyWebkitMask:
2741 case CSSPropertyWebkitMaskRepeatX:
2742 case CSSPropertyWebkitMaskRepeatY:
2743 case CSSPropertyWebkitPerspectiveOriginX:
2744 case CSSPropertyWebkitPerspectiveOriginY:
2745 case CSSPropertyWebkitTextStroke:
2746 case CSSPropertyWebkitTransformOriginX:
2747 case CSSPropertyWebkitTransformOriginY:
2748 case CSSPropertyWebkitTransformOriginZ:
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002749 break;
2750
2751#if ENABLE(CSS_DEVICE_ADAPTATION)
2752 case CSSPropertyMaxZoom:
2753 case CSSPropertyMinZoom:
2754 case CSSPropertyOrientation:
2755 case CSSPropertyUserZoom:
2756 break;
2757#endif
2758
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002759 case CSSPropertyBufferedRendering:
2760 case CSSPropertyClipPath:
2761 case CSSPropertyClipRule:
2762 case CSSPropertyMask:
2763 case CSSPropertyEnableBackground:
2764 case CSSPropertyFilter:
2765 case CSSPropertyFloodColor:
2766 case CSSPropertyFloodOpacity:
2767 case CSSPropertyLightingColor:
2768 case CSSPropertyStopColor:
2769 case CSSPropertyStopOpacity:
2770 case CSSPropertyColorInterpolation:
2771 case CSSPropertyColorInterpolationFilters:
2772 case CSSPropertyColorProfile:
2773 case CSSPropertyColorRendering:
2774 case CSSPropertyFill:
2775 case CSSPropertyFillOpacity:
2776 case CSSPropertyFillRule:
2777 case CSSPropertyMarker:
2778 case CSSPropertyMarkerEnd:
2779 case CSSPropertyMarkerMid:
2780 case CSSPropertyMarkerStart:
2781 case CSSPropertyMaskType:
2782 case CSSPropertyShapeRendering:
2783 case CSSPropertyStroke:
2784 case CSSPropertyStrokeDasharray:
2785 case CSSPropertyStrokeDashoffset:
2786 case CSSPropertyStrokeLinecap:
2787 case CSSPropertyStrokeLinejoin:
2788 case CSSPropertyStrokeMiterlimit:
2789 case CSSPropertyStrokeOpacity:
2790 case CSSPropertyStrokeWidth:
2791 case CSSPropertyAlignmentBaseline:
2792 case CSSPropertyBaselineShift:
2793 case CSSPropertyDominantBaseline:
2794 case CSSPropertyGlyphOrientationHorizontal:
2795 case CSSPropertyGlyphOrientationVertical:
2796 case CSSPropertyKerning:
2797 case CSSPropertyTextAnchor:
2798 case CSSPropertyVectorEffect:
2799 case CSSPropertyWritingMode:
2800 case CSSPropertyWebkitSvgShadow:
2801 return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002802 }
2803
2804 logUnimplementedPropertyID(propertyID);
2805 return 0;
2806}
2807
2808String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
2809{
2810 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2811 if (value)
2812 return value->cssText();
2813 return "";
2814}
2815
2816
2817unsigned CSSComputedStyleDeclaration::length() const
2818{
2819 Node* node = m_node.get();
2820 if (!node)
2821 return 0;
2822
2823 RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
2824 if (!style)
2825 return 0;
2826
2827 return computableProperties().size();
2828}
2829
2830String CSSComputedStyleDeclaration::item(unsigned i) const
2831{
2832 if (i >= length())
2833 return "";
2834
2835 return getPropertyNameString(computableProperties()[i]);
2836}
2837
2838bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
2839{
2840 if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() && m_node) {
2841 m_node->document()->updateLayoutIgnorePendingStylesheets();
2842 RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
2843 if (style && style->fontDescription().keywordSize()) {
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002844 CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
Torne (Richard Coles)e5249552013-05-15 11:35:13 +01002845 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(propertyValue);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +01002846 if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002847 return true;
2848 }
2849 }
2850 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2851 return value && propertyValue && value->equals(*propertyValue);
2852}
2853
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002854PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002855{
2856 return copyPropertiesInSet(computableProperties());
2857}
2858
2859PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) const
2860{
2861 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2862 for (size_t i = 0; i < shorthand.length(); ++i) {
2863 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
2864 list->append(value);
2865 }
2866 return list.release();
2867}
2868
2869PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand& shorthand) const
2870{
2871 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2872 // Assume the properties are in the usual order top, right, bottom, left.
2873 RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
2874 RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
2875 RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
2876 RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
2877
2878 // All 4 properties must be specified.
2879 if (!topValue || !rightValue || !bottomValue || !leftValue)
2880 return 0;
2881
2882 bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
2883 bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
2884 bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;
2885
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002886 list->append(topValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002887 if (showRight)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002888 list->append(rightValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002889 if (showBottom)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002890 list->append(bottomValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002891 if (showLeft)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002892 list->append(leftValue.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002893
2894 return list.release();
2895}
2896
2897PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) const
2898{
2899 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
2900 for (size_t i = 0; i < shorthand.length(); ++i) {
2901 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002902 list->append(value.release());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002903 }
2904 return list.release();
2905}
2906
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002907PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002908{
2909 Vector<CSSProperty, 256> list;
2910 list.reserveInitialCapacity(properties.size());
2911 for (unsigned i = 0; i < properties.size(); ++i) {
2912 RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
2913 if (value)
2914 list.append(CSSProperty(properties[i], value.release(), false));
2915 }
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +01002916 return MutableStylePropertySet::create(list.data(), list.size());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01002917}
2918
2919void CSSComputedStyleDeclaration::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
2920{
2921 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
2922 info.addMember(m_node, "node");
2923}
2924
2925CSSRule* CSSComputedStyleDeclaration::parentRule() const
2926{
2927 return 0;
2928}
2929
2930PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
2931{
2932 CSSPropertyID propertyID = cssPropertyID(propertyName);
2933 if (!propertyID)
2934 return 0;
2935 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2936 return value ? value->cloneForCSSOM() : 0;
2937}
2938
2939String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
2940{
2941 CSSPropertyID propertyID = cssPropertyID(propertyName);
2942 if (!propertyID)
2943 return String();
2944 return getPropertyValue(propertyID);
2945}
2946
2947String CSSComputedStyleDeclaration::getPropertyPriority(const String&)
2948{
2949 // All computed styles have a priority of not "important".
2950 return "";
2951}
2952
2953String CSSComputedStyleDeclaration::getPropertyShorthand(const String&)
2954{
2955 return "";
2956}
2957
2958bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
2959{
2960 return false;
2961}
2962
2963void CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&, ExceptionCode& ec)
2964{
2965 ec = NO_MODIFICATION_ALLOWED_ERR;
2966}
2967
2968String CSSComputedStyleDeclaration::removeProperty(const String&, ExceptionCode& ec)
2969{
2970 ec = NO_MODIFICATION_ALLOWED_ERR;
2971 return String();
2972}
2973
2974PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
2975{
2976 return getPropertyCSSValue(propertyID);
2977}
2978
2979String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
2980{
2981 return getPropertyValue(propertyID);
2982}
2983
2984void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool, ExceptionCode& ec)
2985{
2986 ec = NO_MODIFICATION_ALLOWED_ERR;
2987}
2988
2989PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getBackgroundShorthandValue() const
2990{
2991 static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage,
2992 CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment,
2993 CSSPropertyBackgroundPosition };
2994 static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin,
2995 CSSPropertyBackgroundClip };
2996
2997 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
2998 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator))));
2999 list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator))));
3000 return list.release();
3001}
3002
3003} // namespace WebCore