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