PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const { switch (classType()) { case PrimitiveClass: return toCSSPrimitiveValue(this)->cloneForCSSOM(); case ValueListClass: return toCSSValueList(this)->cloneForCSSOM(); case ImageClass: case CursorImageClass: return toCSSImageValue(this)->cloneForCSSOM(); #if ENABLE(CSS_FILTERS) case WebKitCSSFilterClass: return toWebKitCSSFilterValue(this)->cloneForCSSOM(); #endif case WebKitCSSTransformClass: return toWebKitCSSTransformValue(this)->cloneForCSSOM(); #if ENABLE(CSS_IMAGE_SET) case ImageSetClass: return toCSSImageSetValue(this)->cloneForCSSOM(); #endif #if ENABLE(SVG) case SVGColorClass: return toSVGColor(this)->cloneForCSSOM(); case SVGPaintClass: return toSVGPaint(this)->cloneForCSSOM(); #endif default: ASSERT(!isSubtypeExposedToCSSOM()); return TextCloneCSSValue::create(classType(), cssText()); } }
void StyleResolver::applySVGProperty(CSSPropertyID id, CSSValue* value) { ASSERT(value); CSSPrimitiveValue* primitiveValue = 0; if (value->isPrimitiveValue()) primitiveValue = toCSSPrimitiveValue(value); const State& state = m_state; SVGRenderStyle& svgStyle = state.style()->accessSVGStyle(); bool isInherit = state.parentNode() && value->isInheritedValue(); bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue()); // What follows is a list that maps the CSS properties into their // corresponding front-end RenderStyle values. Shorthands(e.g. border, // background) occur in this list as well and are only hit when mapping // "inherit" or "initial" into front-end values. switch (id) { // ident only properties case CSSPropertyAlignmentBaseline: { HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline) if (!primitiveValue) break; svgStyle.setAlignmentBaseline(*primitiveValue); break; } case CSSPropertyBaselineShift: { HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift); if (!primitiveValue) break; if (primitiveValue->getValueID()) { switch (primitiveValue->getValueID()) { case CSSValueBaseline: svgStyle.setBaselineShift(BS_BASELINE); break; case CSSValueSub: svgStyle.setBaselineShift(BS_SUB); break; case CSSValueSuper: svgStyle.setBaselineShift(BS_SUPER); break; default: break; } } else { svgStyle.setBaselineShift(BS_LENGTH); svgStyle.setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue)); } break; } case CSSPropertyKerning: { HANDLE_INHERIT_AND_INITIAL(kerning, Kerning); if (primitiveValue) svgStyle.setKerning(SVGLength::fromCSSPrimitiveValue(primitiveValue)); break; } case CSSPropertyDominantBaseline: { HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline) if (primitiveValue) svgStyle.setDominantBaseline(*primitiveValue); break; } case CSSPropertyColorInterpolation: { HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation) if (primitiveValue) svgStyle.setColorInterpolation(*primitiveValue); break; } case CSSPropertyColorInterpolationFilters: { HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters) if (primitiveValue) svgStyle.setColorInterpolationFilters(*primitiveValue); break; } case CSSPropertyColorProfile: { // Not implemented. break; } case CSSPropertyColorRendering: { HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering) if (primitiveValue) svgStyle.setColorRendering(*primitiveValue); break; } case CSSPropertyClipRule: { HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule) if (primitiveValue) svgStyle.setClipRule(*primitiveValue); break; } case CSSPropertyFillRule: { HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule) if (primitiveValue) svgStyle.setFillRule(*primitiveValue); break; } case CSSPropertyStrokeLinejoin: { HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle) if (primitiveValue) svgStyle.setJoinStyle(*primitiveValue); break; } case CSSPropertyShapeRendering: { HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering) if (primitiveValue) svgStyle.setShapeRendering(*primitiveValue); break; } // end of ident only properties case CSSPropertyFill: { if (isInherit) { const SVGRenderStyle& svgParentStyle = state.parentStyle()->svgStyle(); svgStyle.setFillPaint(svgParentStyle.fillPaintType(), svgParentStyle.fillPaintColor(), svgParentStyle.fillPaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (isInitial) { svgStyle.setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (value->isSVGPaint()) { SVGPaint* svgPaint = toSVGPaint(value); svgStyle.setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); } break; } case CSSPropertyStroke: { if (isInherit) { const SVGRenderStyle& svgParentStyle = state.parentStyle()->svgStyle(); svgStyle.setStrokePaint(svgParentStyle.strokePaintType(), svgParentStyle.strokePaintColor(), svgParentStyle.strokePaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (isInitial) { svgStyle.setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (value->isSVGPaint()) { SVGPaint* svgPaint = toSVGPaint(value); svgStyle.setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); } break; } case CSSPropertyStrokeWidth: { HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth) if (primitiveValue) svgStyle.setStrokeWidth(SVGLength::fromCSSPrimitiveValue(primitiveValue)); break; } case CSSPropertyStrokeDasharray: { HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray) if (!value->isValueList()) { svgStyle.setStrokeDashArray(SVGRenderStyle::initialStrokeDashArray()); break; } CSSValueList* dashes = toCSSValueList(value); Vector<SVGLength> array; size_t length = dashes->length(); for (size_t i = 0; i < length; ++i) { CSSValue* currValue = dashes->itemWithoutBoundsCheck(i); if (!currValue->isPrimitiveValue()) continue; CSSPrimitiveValue* dash = toCSSPrimitiveValue(dashes->itemWithoutBoundsCheck(i)); array.append(SVGLength::fromCSSPrimitiveValue(dash)); } svgStyle.setStrokeDashArray(array); break; } case CSSPropertyStrokeDashoffset: { HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset) if (primitiveValue) svgStyle.setStrokeDashOffset(SVGLength::fromCSSPrimitiveValue(primitiveValue)); break; } case CSSPropertyFillOpacity: { HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgStyle.setFillOpacity(f); break; } case CSSPropertyStrokeOpacity: { HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgStyle.setStrokeOpacity(f); break; } case CSSPropertyStopOpacity: { HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgStyle.setStopOpacity(f); break; } case CSSPropertyMarkerStart: { HANDLE_INHERIT_AND_INITIAL(markerStartResource, MarkerStartResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgStyle.setMarkerStartResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyMarkerMid: { HANDLE_INHERIT_AND_INITIAL(markerMidResource, MarkerMidResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgStyle.setMarkerMidResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyMarkerEnd: { HANDLE_INHERIT_AND_INITIAL(markerEndResource, MarkerEndResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgStyle.setMarkerEndResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyStrokeLinecap: { HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle) if (primitiveValue) svgStyle.setCapStyle(*primitiveValue); break; } case CSSPropertyStrokeMiterlimit: { HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgStyle.setStrokeMiterLimit(f); break; } case CSSPropertyFilter: { HANDLE_INHERIT_AND_INITIAL(filterResource, FilterResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgStyle.setFilterResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyMask: { HANDLE_INHERIT_AND_INITIAL(maskerResource, MaskerResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgStyle.setMaskerResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyClipPath: { HANDLE_INHERIT_AND_INITIAL(clipperResource, ClipperResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgStyle.setClipperResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyTextAnchor: { HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor) if (primitiveValue) svgStyle.setTextAnchor(*primitiveValue); break; } case CSSPropertyWritingMode: { HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode) if (primitiveValue) svgStyle.setWritingMode(*primitiveValue); break; } case CSSPropertyStopColor: { HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor); if (value->isSVGColor()) svgStyle.setStopColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color())); break; } case CSSPropertyLightingColor: { HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor); if (value->isSVGColor()) svgStyle.setLightingColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color())); break; } case CSSPropertyFloodOpacity: { HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgStyle.setFloodOpacity(f); break; } case CSSPropertyFloodColor: { HANDLE_INHERIT_AND_INITIAL(floodColor, FloodColor); if (value->isSVGColor()) svgStyle.setFloodColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color())); break; } case CSSPropertyGlyphOrientationHorizontal: { HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal) if (!primitiveValue) return; if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) { int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue()); ASSERT(orientation != -1); svgStyle.setGlyphOrientationHorizontal((EGlyphOrientation) orientation); } break; } case CSSPropertyGlyphOrientationVertical: { HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical) if (!primitiveValue) return; if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) { int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue()); ASSERT(orientation != -1); svgStyle.setGlyphOrientationVertical((EGlyphOrientation) orientation); } else if (primitiveValue->getValueID() == CSSValueAuto) svgStyle.setGlyphOrientationVertical(GO_AUTO); break; } case CSSPropertyEnableBackground: // Silently ignoring this property for now // http://bugs.webkit.org/show_bug.cgi?id=6022 break; case CSSPropertyWebkitSvgShadow: { if (isInherit) return svgStyle.setShadow(state.parentStyle()->svgStyle().shadow() ? std::make_unique<ShadowData>(*state.parentStyle()->svgStyle().shadow()) : nullptr); if (isInitial || primitiveValue) // initial | none return svgStyle.setShadow(nullptr); if (!value->isValueList()) return; CSSValueList* list = toCSSValueList(value); if (!list->length()) return; CSSValue* firstValue = list->itemWithoutBoundsCheck(0); if (!firstValue->isShadowValue()) return; CSSShadowValue* item = toCSSShadowValue(firstValue); IntPoint location(item->x->computeLength<int>(state.style(), state.rootElementStyle()), item->y->computeLength<int>(state.style(), state.rootElementStyle())); int blur = item->blur ? item->blur->computeLength<int>(state.style(), state.rootElementStyle()) : 0; Color color; if (item->color) color = colorFromPrimitiveValue(item->color.get()); // -webkit-svg-shadow does should not have a spread or style ASSERT(!item->spread); ASSERT(!item->style); auto shadowData = std::make_unique<ShadowData>(location, blur, 0, Normal, false, color.isValid() ? color : Color::transparent); svgStyle.setShadow(std::move(shadowData)); return; } case CSSPropertyVectorEffect: { HANDLE_INHERIT_AND_INITIAL(vectorEffect, VectorEffect) if (!primitiveValue) break; svgStyle.setVectorEffect(*primitiveValue); break; } case CSSPropertyBufferedRendering: { HANDLE_INHERIT_AND_INITIAL(bufferedRendering, BufferedRendering) if (!primitiveValue) break; svgStyle.setBufferedRendering(*primitiveValue); break; } case CSSPropertyMaskType: { HANDLE_INHERIT_AND_INITIAL(maskType, MaskType) if (!primitiveValue) break; svgStyle.setMaskType(*primitiveValue); break; } default: // If you crash here, it's because you added a css property and are not handling it // in either this switch statement or the one in StyleResolver::applyProperty ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id); return; } }
void CSSValue::destroy() { if (m_isTextClone) { ASSERT(isCSSOMSafe()); delete static_cast<TextCloneCSSValue*>(this); return; } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: delete toCSSAspectRatioValue(this); return; case BorderImageSliceClass: delete toCSSBorderImageSliceValue(this); return; case CanvasClass: delete toCSSCanvasValue(this); return; case CursorImageClass: delete toCSSCursorImageValue(this); return; case FontClass: delete toCSSFontValue(this); return; case FontFaceSrcClass: delete toCSSFontFaceSrcValue(this); return; case FontFeatureClass: delete toCSSFontFeatureValue(this); return; case FunctionClass: delete toCSSFunctionValue(this); return; case LinearGradientClass: delete toCSSLinearGradientValue(this); return; case RadialGradientClass: delete toCSSRadialGradientValue(this); return; case CrossfadeClass: delete toCSSCrossfadeValue(this); return; case ImageClass: delete toCSSImageValue(this); return; case InheritedClass: delete toCSSInheritedValue(this); return; case InitialClass: delete toCSSInitialValue(this); return; case GridTemplateClass: delete toCSSGridTemplateValue(this); return; case PrimitiveClass: delete toCSSPrimitiveValue(this); return; case ReflectClass: delete toCSSReflectValue(this); return; case ShadowClass: delete toCSSShadowValue(this); return; case CubicBezierTimingFunctionClass: delete toCSSCubicBezierTimingFunctionValue(this); return; case StepsTimingFunctionClass: delete toCSSStepsTimingFunctionValue(this); return; case UnicodeRangeClass: delete toCSSUnicodeRangeValue(this); return; case ValueListClass: delete toCSSValueList(this); return; case WebKitCSSTransformClass: delete toWebKitCSSTransformValue(this); return; case LineBoxContainClass: delete toCSSLineBoxContainValue(this); return; case CalculationClass: delete toCSSCalcValue(this); return; #if ENABLE(CSS_IMAGE_SET) case ImageSetClass: delete toCSSImageSetValue(this); return; #endif #if ENABLE(CSS_FILTERS) case FilterImageClass: delete toCSSFilterImageValue(this); return; case WebKitCSSFilterClass: delete toWebKitCSSFilterValue(this); return; #if ENABLE(CSS_SHADERS) case WebKitCSSArrayFunctionValueClass: delete toWebKitCSSArrayFunctionValue(this); return; case WebKitCSSMatFunctionValueClass: delete toWebKitCSSMatFunctionValue(this); return; case WebKitCSSMixFunctionValueClass: delete toWebKitCSSMixFunctionValue(this); return; case WebKitCSSShaderClass: delete toWebKitCSSShaderValue(this); return; #endif #endif #if ENABLE(SVG) case SVGColorClass: delete toSVGColor(this); return; case SVGPaintClass: delete toSVGPaint(this); return; case WebKitCSSSVGDocumentClass: delete toWebKitCSSSVGDocumentValue(this); return; #endif } ASSERT_NOT_REACHED(); }
String CSSValue::cssText() const { if (m_isTextClone) { ASSERT(isCSSOMSafe()); return static_cast<const TextCloneCSSValue*>(this)->cssText(); } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: return toCSSAspectRatioValue(this)->customCSSText(); case BorderImageSliceClass: return toCSSBorderImageSliceValue(this)->customCSSText(); case CanvasClass: return toCSSCanvasValue(this)->customCSSText(); case CursorImageClass: return toCSSCursorImageValue(this)->customCSSText(); #if ENABLE(CSS_FILTERS) case FilterImageClass: return toCSSFilterImageValue(this)->customCSSText(); #endif case FontClass: return toCSSFontValue(this)->customCSSText(); case FontFaceSrcClass: return toCSSFontFaceSrcValue(this)->customCSSText(); case FontFeatureClass: return toCSSFontFeatureValue(this)->customCSSText(); case FunctionClass: return toCSSFunctionValue(this)->customCSSText(); case LinearGradientClass: return toCSSLinearGradientValue(this)->customCSSText(); case RadialGradientClass: return toCSSRadialGradientValue(this)->customCSSText(); case CrossfadeClass: return toCSSCrossfadeValue(this)->customCSSText(); case ImageClass: return toCSSImageValue(this)->customCSSText(); case InheritedClass: return toCSSInheritedValue(this)->customCSSText(); case InitialClass: return toCSSInitialValue(this)->customCSSText(); #if ENABLE(CSS_GRID_LAYOUT) case GridLineNamesClass: return toCSSGridLineNamesValue(this)->customCSSText(); case GridTemplateAreasClass: return toCSSGridTemplateAreasValue(this)->customCSSText(); #endif case PrimitiveClass: return toCSSPrimitiveValue(this)->customCSSText(); case ReflectClass: return toCSSReflectValue(this)->customCSSText(); case ShadowClass: return toCSSShadowValue(this)->customCSSText(); case CubicBezierTimingFunctionClass: return toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); case StepsTimingFunctionClass: return toCSSStepsTimingFunctionValue(this)->customCSSText(); case UnicodeRangeClass: return toCSSUnicodeRangeValue(this)->customCSSText(); case ValueListClass: return toCSSValueList(this)->customCSSText(); case WebKitCSSTransformClass: return toWebKitCSSTransformValue(this)->customCSSText(); case LineBoxContainClass: return toCSSLineBoxContainValue(this)->customCSSText(); case CalculationClass: return toCSSCalcValue(this)->customCSSText(); #if ENABLE(CSS_IMAGE_SET) case ImageSetClass: return toCSSImageSetValue(this)->customCSSText(); #endif #if ENABLE(CSS_FILTERS) case WebKitCSSFilterClass: return toWebKitCSSFilterValue(this)->customCSSText(); #endif case SVGColorClass: return toSVGColor(this)->customCSSText(); case SVGPaintClass: return toSVGPaint(this)->customCSSText(); } ASSERT_NOT_REACHED(); return String(); }