bool FilterStyleInterpolation::canCreateFrom(const CSSValue& start, const CSSValue& end) { // Discrete interpolation occurs when url or distinct function types occur. // http://dev.w3.org/fxtf/filters/#animation-of-filters // FIXME: Drop shadow interpolation has not been implemented. CSSValueID startFunctionType = toCSSFunctionValue(start).functionType(); return startFunctionType == toCSSFunctionValue(end).functionType() && startFunctionType != CSSValueUrl && startFunctionType != CSSValueDropShadow; }
PassOwnPtr<InterpolableValue> FilterStyleInterpolation::toInterpolableValue(const CSSValue& value, CSSValueID& functionType) { const CSSFunctionValue& filterValue = toCSSFunctionValue(value); functionType = filterValue.functionType(); size_t length = filterValue.length(); OwnPtr<InterpolableList> result = InterpolableList::create(length); for (size_t i = 0; i < length; ++i) { switch (functionType) { case CSSValueHueRotate: result->set(i, InterpolableNumber::create(toCSSPrimitiveValue(filterValue.item(i))->computeDegrees())); break; case CSSValueBlur: result->set(i, LengthStyleInterpolation::toInterpolableValue(*filterValue.item(i), CSSPropertyWebkitFilter)); break; case CSSValueGrayscale: case CSSValueInvert: case CSSValueSepia: case CSSValueBrightness: case CSSValueContrast: case CSSValueOpacity: case CSSValueSaturate: result->set(i, InterpolableNumber::create(toCSSPrimitiveValue(filterValue.item(i))->getDoubleValue())); break; case CSSValueDropShadow: case CSSValueUrl: default: ASSERT_NOT_REACHED(); } } return result.release(); }
InterpolationValue CSSTransformInterpolationType::maybeConvertValue( const CSSValue& value, const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (value.isValueList()) { CSSLengthArray lengthArray; for (const CSSValue* item : toCSSValueList(value)) { const CSSFunctionValue& transformFunction = toCSSFunctionValue(*item); if (transformFunction.functionType() == CSSValueMatrix || transformFunction.functionType() == CSSValueMatrix3d) { lengthArray.typeFlags.set(CSSPrimitiveValue::UnitTypePixels); continue; } for (const CSSValue* argument : transformFunction) { const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(*argument); if (!primitiveValue.isLength()) continue; primitiveValue.accumulateLengthArray(lengthArray); } } std::unique_ptr<InterpolationType::ConversionChecker> lengthUnitsChecker = LengthUnitsChecker::maybeCreate(std::move(lengthArray), state); if (lengthUnitsChecker) conversionCheckers.append(std::move(lengthUnitsChecker)); } TransformOperations transform; TransformBuilder::createTransformOperations( value, state.cssToLengthConversionData(), transform); return convertTransform(std::move(transform)); }
String CSSValue::cssText() const { if (m_isTextClone) { ASSERT(isCSSOMSafe()); return toTextCloneCSSValue(this)->cssText(); } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: return toCSSAspectRatioValue(this)->customCSSText(); case BorderImageSliceClass: return toCSSBorderImageSliceValue(this)->customCSSText(); 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(); case PrimitiveClass: return toCSSPrimitiveValue(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 CSSTransformClass: return toCSSTransformValue(this)->customCSSText(); case LineBoxContainClass: return toCSSLineBoxContainValue(this)->customCSSText(); case CalculationClass: return toCSSCalcValue(this)->customCSSText(); case ImageSetClass: return toCSSImageSetValue(this)->customCSSText(); case CSSFilterClass: return toCSSFilterValue(this)->customCSSText(); } ASSERT_NOT_REACHED(); return String(); }
GridTrackSize StyleBuilderConverter::convertGridTrackSize(StyleResolverState& state, CSSValue* value) { if (value->isPrimitiveValue()) return GridTrackSize(convertGridTrackBreadth(state, toCSSPrimitiveValue(value))); CSSFunctionValue* minmaxFunction = toCSSFunctionValue(value); CSSValueList* arguments = minmaxFunction->arguments(); ASSERT_WITH_SECURITY_IMPLICATION(arguments->length() == 2); GridLength minTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->item(0)))); GridLength maxTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->item(1)))); return GridTrackSize(minTrackBreadth, maxTrackBreadth); }
bool TransformBuilder::hasRelativeLengths(const CSSValueList& valueList) { for (auto& value : valueList) { const CSSFunctionValue* transformValue = toCSSFunctionValue(value.get()); for (const CSSValue* item : *transformValue) { const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(*item); // TODO(hs1217.lee) : to prevent relative unit like calc(10px + 1em). // but when calc() not take parameter of ralative unit like calc(1px +1 // px), // shoud be return false; if (primitiveValue.isCalculated()) { return true; } if (CSSPrimitiveValue::isRelativeUnit( primitiveValue.typeWithCalcResolved())) { return true; } } } return false; }
void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& ruleData) { const StylePropertySet& propertySet = ruleData.rule()->properties(); int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); if (propertyIndex == -1) return; StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt(propertyIndex); CSSValue* contentValue = contentProperty.value(); if (!contentValue->isValueList()) return; for (auto& item : toCSSValueList(*contentValue)) { if (!item->isFunctionValue()) continue; CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); if (functionValue->functionType() != CSSValueAttr) continue; ensureAttributeInvalidationSet(AtomicString(toCSSPrimitiveValue(functionValue->item(0))->getStringValue())).setInvalidatesSelf(); } }
TransformOperations TransformBuilder::createTransformOperations( const CSSValue& inValue, const CSSToLengthConversionData& conversionData) { TransformOperations operations; if (!inValue.isValueList()) { DCHECK_EQ(toCSSIdentifierValue(inValue).getValueID(), CSSValueNone); return operations; } float zoomFactor = conversionData.zoom(); for (auto& value : toCSSValueList(inValue)) { const CSSFunctionValue* transformValue = toCSSFunctionValue(value.get()); TransformOperation::OperationType transformType = getTransformOperationType(transformValue->functionType()); const CSSPrimitiveValue& firstValue = toCSSPrimitiveValue(transformValue->item(0)); switch (transformType) { case TransformOperation::Scale: case TransformOperation::ScaleX: case TransformOperation::ScaleY: { double sx = 1.0; double sy = 1.0; if (transformType == TransformOperation::ScaleY) { sy = firstValue.getDoubleValue(); } else { sx = firstValue.getDoubleValue(); if (transformType != TransformOperation::ScaleX) { if (transformValue->length() > 1) { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); sy = secondValue.getDoubleValue(); } else { sy = sx; } } } operations.operations().append( ScaleTransformOperation::create(sx, sy, 1.0, transformType)); break; } case TransformOperation::ScaleZ: case TransformOperation::Scale3D: { double sx = 1.0; double sy = 1.0; double sz = 1.0; if (transformType == TransformOperation::ScaleZ) { sz = firstValue.getDoubleValue(); } else { sx = firstValue.getDoubleValue(); sy = toCSSPrimitiveValue(transformValue->item(1)).getDoubleValue(); sz = toCSSPrimitiveValue(transformValue->item(2)).getDoubleValue(); } operations.operations().append( ScaleTransformOperation::create(sx, sy, sz, transformType)); break; } case TransformOperation::Translate: case TransformOperation::TranslateX: case TransformOperation::TranslateY: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); if (transformType == TransformOperation::TranslateY) ty = convertToFloatLength(firstValue, conversionData); else { tx = convertToFloatLength(firstValue, conversionData); if (transformType != TransformOperation::TranslateX) { if (transformValue->length() > 1) { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); ty = convertToFloatLength(secondValue, conversionData); } } } operations.operations().append( TranslateTransformOperation::create(tx, ty, 0, transformType)); break; } case TransformOperation::TranslateZ: case TransformOperation::Translate3D: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); double tz = 0; if (transformType == TransformOperation::TranslateZ) { tz = firstValue.computeLength<double>(conversionData); } else { tx = convertToFloatLength(firstValue, conversionData); ty = convertToFloatLength( toCSSPrimitiveValue(transformValue->item(1)), conversionData); tz = toCSSPrimitiveValue(transformValue->item(2)) .computeLength<double>(conversionData); } operations.operations().append( TranslateTransformOperation::create(tx, ty, tz, transformType)); break; } case TransformOperation::RotateX: case TransformOperation::RotateY: case TransformOperation::RotateZ: { double angle = firstValue.computeDegrees(); if (transformValue->length() == 1) { double x = transformType == TransformOperation::RotateX; double y = transformType == TransformOperation::RotateY; double z = transformType == TransformOperation::RotateZ; operations.operations().append( RotateTransformOperation::create(x, y, z, angle, transformType)); } else { // For SVG 'transform' attributes we generate 3-argument rotate() // functions. DCHECK_EQ(transformValue->length(), 3u); const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); const CSSPrimitiveValue& thirdValue = toCSSPrimitiveValue(transformValue->item(2)); operations.operations().append( RotateAroundOriginTransformOperation::create( angle, secondValue.computeLength<double>(conversionData), thirdValue.computeLength<double>(conversionData))); } break; } case TransformOperation::Rotate3D: { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); const CSSPrimitiveValue& thirdValue = toCSSPrimitiveValue(transformValue->item(2)); const CSSPrimitiveValue& fourthValue = toCSSPrimitiveValue(transformValue->item(3)); double x = firstValue.getDoubleValue(); double y = secondValue.getDoubleValue(); double z = thirdValue.getDoubleValue(); double angle = fourthValue.computeDegrees(); operations.operations().append( RotateTransformOperation::create(x, y, z, angle, transformType)); break; } case TransformOperation::Skew: case TransformOperation::SkewX: case TransformOperation::SkewY: { double angleX = 0; double angleY = 0; double angle = firstValue.computeDegrees(); if (transformType == TransformOperation::SkewY) angleY = angle; else { angleX = angle; if (transformType == TransformOperation::Skew) { if (transformValue->length() > 1) { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); angleY = secondValue.computeDegrees(); } } } operations.operations().append( SkewTransformOperation::create(angleX, angleY, transformType)); break; } case TransformOperation::Matrix: { double a = firstValue.getDoubleValue(); double b = toCSSPrimitiveValue(transformValue->item(1)).getDoubleValue(); double c = toCSSPrimitiveValue(transformValue->item(2)).getDoubleValue(); double d = toCSSPrimitiveValue(transformValue->item(3)).getDoubleValue(); double e = zoomFactor * toCSSPrimitiveValue(transformValue->item(4)).getDoubleValue(); double f = zoomFactor * toCSSPrimitiveValue(transformValue->item(5)).getDoubleValue(); operations.operations().append( MatrixTransformOperation::create(a, b, c, d, e, f)); break; } case TransformOperation::Matrix3D: { TransformationMatrix matrix( toCSSPrimitiveValue(transformValue->item(0)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(1)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(2)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(3)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(4)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(5)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(6)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(7)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(8)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(9)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(10)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(11)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(12)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(13)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(14)).getDoubleValue(), toCSSPrimitiveValue(transformValue->item(15)).getDoubleValue()); matrix.zoom(zoomFactor); operations.operations().append( Matrix3DTransformOperation::create(matrix)); break; } case TransformOperation::Perspective: { double p = firstValue.computeLength<double>(conversionData); ASSERT(p >= 0); operations.operations().append( PerspectiveTransformOperation::create(p)); break; } default: ASSERT_NOT_REACHED(); break; } } return operations; }
void CSSValue::finalizeGarbageCollectedObject() { switch (getClassType()) { case BasicShapeCircleClass: toCSSBasicShapeCircleValue(this)->~CSSBasicShapeCircleValue(); return; case BasicShapeEllipseClass: toCSSBasicShapeEllipseValue(this)->~CSSBasicShapeEllipseValue(); return; case BasicShapePolygonClass: toCSSBasicShapePolygonValue(this)->~CSSBasicShapePolygonValue(); return; case BasicShapeInsetClass: toCSSBasicShapeInsetValue(this)->~CSSBasicShapeInsetValue(); return; case BorderImageSliceClass: toCSSBorderImageSliceValue(this)->~CSSBorderImageSliceValue(); return; case ColorClass: toCSSColorValue(this)->~CSSColorValue(); return; case CounterClass: toCSSCounterValue(this)->~CSSCounterValue(); return; case CursorImageClass: toCSSCursorImageValue(this)->~CSSCursorImageValue(); return; case FontFaceSrcClass: toCSSFontFaceSrcValue(this)->~CSSFontFaceSrcValue(); return; case FontFamilyClass: toCSSFontFamilyValue(this)->~CSSFontFamilyValue(); return; case FontFeatureClass: toCSSFontFeatureValue(this)->~CSSFontFeatureValue(); return; case FunctionClass: toCSSFunctionValue(this)->~CSSFunctionValue(); return; case LinearGradientClass: toCSSLinearGradientValue(this)->~CSSLinearGradientValue(); return; case RadialGradientClass: toCSSRadialGradientValue(this)->~CSSRadialGradientValue(); return; case CrossfadeClass: toCSSCrossfadeValue(this)->~CSSCrossfadeValue(); return; case PaintClass: toCSSPaintValue(this)->~CSSPaintValue(); return; case CustomIdentClass: toCSSCustomIdentValue(this)->~CSSCustomIdentValue(); return; case ImageClass: toCSSImageValue(this)->~CSSImageValue(); return; case InheritedClass: toCSSInheritedValue(this)->~CSSInheritedValue(); return; case InitialClass: toCSSInitialValue(this)->~CSSInitialValue(); return; case UnsetClass: toCSSUnsetValue(this)->~CSSUnsetValue(); return; case GridAutoRepeatClass: toCSSGridAutoRepeatValue(this)->~CSSGridAutoRepeatValue(); return; case GridLineNamesClass: toCSSGridLineNamesValue(this)->~CSSGridLineNamesValue(); return; case GridTemplateAreasClass: toCSSGridTemplateAreasValue(this)->~CSSGridTemplateAreasValue(); return; case PathClass: toCSSPathValue(this)->~CSSPathValue(); return; case PrimitiveClass: toCSSPrimitiveValue(this)->~CSSPrimitiveValue(); return; case IdentifierClass: toCSSIdentifierValue(this)->~CSSIdentifierValue(); return; case QuadClass: toCSSQuadValue(this)->~CSSQuadValue(); return; case ReflectClass: toCSSReflectValue(this)->~CSSReflectValue(); return; case ShadowClass: toCSSShadowValue(this)->~CSSShadowValue(); return; case StringClass: toCSSStringValue(this)->~CSSStringValue(); return; case CubicBezierTimingFunctionClass: toCSSCubicBezierTimingFunctionValue(this) ->~CSSCubicBezierTimingFunctionValue(); return; case StepsTimingFunctionClass: toCSSStepsTimingFunctionValue(this)->~CSSStepsTimingFunctionValue(); return; case UnicodeRangeClass: toCSSUnicodeRangeValue(this)->~CSSUnicodeRangeValue(); return; case URIClass: toCSSURIValue(this)->~CSSURIValue(); return; case ValueListClass: toCSSValueList(this)->~CSSValueList(); return; case ValuePairClass: toCSSValuePair(this)->~CSSValuePair(); return; case ImageSetClass: toCSSImageSetValue(this)->~CSSImageSetValue(); return; case CSSContentDistributionClass: toCSSContentDistributionValue(this)->~CSSContentDistributionValue(); return; case VariableReferenceClass: toCSSVariableReferenceValue(this)->~CSSVariableReferenceValue(); return; case CustomPropertyDeclarationClass: toCSSCustomPropertyDeclaration(this)->~CSSCustomPropertyDeclaration(); return; case PendingSubstitutionValueClass: toCSSPendingSubstitutionValue(this)->~CSSPendingSubstitutionValue(); return; } ASSERT_NOT_REACHED(); }
InterpolationValue FilterInterpolationFunctions::maybeConvertCSSFilter(const CSSValue& value) { const CSSFunctionValue& filter = toCSSFunctionValue(value); ASSERT(filter.length() <= 1); FilterOperation::OperationType type = FilterOperationResolver::filterOperationForType(filter.functionType()); InterpolationValue result = nullptr; switch (type) { case FilterOperation::BRIGHTNESS: case FilterOperation::CONTRAST: case FilterOperation::GRAYSCALE: case FilterOperation::INVERT: case FilterOperation::OPACITY: case FilterOperation::SATURATE: case FilterOperation::SEPIA: { double amount = defaultParameter(type); if (filter.length() == 1) { const CSSPrimitiveValue& firstValue = toCSSPrimitiveValue(*filter.item(0)); amount = firstValue.getDoubleValue(); if (firstValue.isPercentage()) amount /= 100; } result.interpolableValue = InterpolableNumber::create(amount); break; } case FilterOperation::HUE_ROTATE: { double angle = defaultParameter(type); if (filter.length() == 1) angle = toCSSPrimitiveValue(*filter.item(0)).computeDegrees(); result.interpolableValue = InterpolableNumber::create(angle); break; } case FilterOperation::BLUR: { if (filter.length() == 0) result.interpolableValue = CSSLengthInterpolationType::createNeutralInterpolableValue(); else result = CSSLengthInterpolationType::maybeConvertCSSValue(*filter.item(0)); break; } case FilterOperation::DROP_SHADOW: { result = ShadowInterpolationFunctions::maybeConvertCSSValue(*filter.item(0)); break; } case FilterOperation::REFERENCE: return nullptr; default: ASSERT_NOT_REACHED(); return nullptr; } if (!result) return nullptr; result.nonInterpolableValue = FilterNonInterpolableValue::create(type, result.nonInterpolableValue.release()); return result; }
void CSSValue::finalizeGarbageCollectedObject() { switch (classType()) { case BorderImageSliceClass: toCSSBorderImageSliceValue(this)->~CSSBorderImageSliceValue(); return; case CanvasClass: toCSSCanvasValue(this)->~CSSCanvasValue(); return; case CounterClass: toCSSCounterValue(this)->~CSSCounterValue(); return; case CursorImageClass: toCSSCursorImageValue(this)->~CSSCursorImageValue(); return; case FontFaceSrcClass: toCSSFontFaceSrcValue(this)->~CSSFontFaceSrcValue(); return; case FontFeatureClass: toCSSFontFeatureValue(this)->~CSSFontFeatureValue(); return; case FunctionClass: toCSSFunctionValue(this)->~CSSFunctionValue(); return; case LinearGradientClass: toCSSLinearGradientValue(this)->~CSSLinearGradientValue(); return; case RadialGradientClass: toCSSRadialGradientValue(this)->~CSSRadialGradientValue(); return; case CrossfadeClass: toCSSCrossfadeValue(this)->~CSSCrossfadeValue(); return; case ImageClass: toCSSImageValue(this)->~CSSImageValue(); return; case InheritedClass: toCSSInheritedValue(this)->~CSSInheritedValue(); return; case InitialClass: toCSSInitialValue(this)->~CSSInitialValue(); return; case UnsetClass: toCSSUnsetValue(this)->~CSSUnsetValue(); return; case GridLineNamesClass: toCSSGridLineNamesValue(this)->~CSSGridLineNamesValue(); return; case GridTemplateAreasClass: toCSSGridTemplateAreasValue(this)->~CSSGridTemplateAreasValue(); return; case PathClass: toCSSPathValue(this)->~CSSPathValue(); return; case PrimitiveClass: toCSSPrimitiveValue(this)->~CSSPrimitiveValue(); return; case QuadClass: toCSSQuadValue(this)->~CSSQuadValue(); return; case ReflectClass: toCSSReflectValue(this)->~CSSReflectValue(); return; case ShadowClass: toCSSShadowValue(this)->~CSSShadowValue(); return; case CubicBezierTimingFunctionClass: toCSSCubicBezierTimingFunctionValue(this)->~CSSCubicBezierTimingFunctionValue(); return; case StepsTimingFunctionClass: toCSSStepsTimingFunctionValue(this)->~CSSStepsTimingFunctionValue(); return; case UnicodeRangeClass: toCSSUnicodeRangeValue(this)->~CSSUnicodeRangeValue(); return; case ValueListClass: toCSSValueList(this)->~CSSValueList(); return; case ValuePairClass: toCSSValuePair(this)->~CSSValuePair(); return; case ImageSetClass: toCSSImageSetValue(this)->~CSSImageSetValue(); return; case CSSSVGDocumentClass: toCSSSVGDocumentValue(this)->~CSSSVGDocumentValue(); return; case CSSContentDistributionClass: toCSSContentDistributionValue(this)->~CSSContentDistributionValue(); return; } ASSERT_NOT_REACHED(); }
FilterOperations FilterOperationResolver::createFilterOperations(StyleResolverState& state, const CSSValue& inValue) { FilterOperations operations; if (inValue.isPrimitiveValue()) { ASSERT(toCSSPrimitiveValue(inValue).getValueID() == CSSValueNone); return operations; } const CSSToLengthConversionData& conversionData = state.cssToLengthConversionData(); for (auto& currValue : toCSSValueList(inValue)) { const CSSFunctionValue* filterValue = toCSSFunctionValue(currValue.get()); FilterOperation::OperationType operationType = filterOperationForType(filterValue->functionType()); countFilterUse(operationType, state.document()); ASSERT(filterValue->length() <= 1); if (operationType == FilterOperation::REFERENCE) { const CSSSVGDocumentValue& svgDocumentValue = toCSSSVGDocumentValue(filterValue->item(0)); KURL url = state.document().completeURL(svgDocumentValue.url()); ReferenceFilterOperation* operation = ReferenceFilterOperation::create(svgDocumentValue.url(), AtomicString(url.fragmentIdentifier())); if (SVGURIReference::isExternalURIReference(svgDocumentValue.url(), state.document())) { if (!svgDocumentValue.loadRequested()) state.elementStyleResources().addPendingSVGDocument(operation, &svgDocumentValue); else if (svgDocumentValue.cachedSVGDocument()) ReferenceFilterBuilder::setDocumentResourceReference(operation, new DocumentResourceReference(svgDocumentValue.cachedSVGDocument())); } operations.operations().append(operation); continue; } const CSSPrimitiveValue* firstValue = filterValue->length() && filterValue->item(0).isPrimitiveValue() ? &toCSSPrimitiveValue(filterValue->item(0)) : nullptr; switch (filterValue->functionType()) { case CSSValueGrayscale: case CSSValueSepia: case CSSValueSaturate: { double amount = 1; if (filterValue->length() == 1) { amount = firstValue->getDoubleValue(); if (firstValue->isPercentage()) amount /= 100; } operations.operations().append(BasicColorMatrixFilterOperation::create(amount, operationType)); break; } case CSSValueHueRotate: { double angle = 0; if (filterValue->length() == 1) angle = firstValue->computeDegrees(); operations.operations().append(BasicColorMatrixFilterOperation::create(angle, operationType)); break; } case CSSValueInvert: case CSSValueBrightness: case CSSValueContrast: case CSSValueOpacity: { double amount = (filterValue->functionType() == CSSValueBrightness) ? 0 : 1; if (filterValue->length() == 1) { amount = firstValue->getDoubleValue(); if (firstValue->isPercentage()) amount /= 100; } operations.operations().append(BasicComponentTransferFilterOperation::create(amount, operationType)); break; } case CSSValueBlur: { Length stdDeviation = Length(0, Fixed); if (filterValue->length() >= 1) stdDeviation = firstValue->convertToLength(conversionData); operations.operations().append(BlurFilterOperation::create(stdDeviation)); break; } case CSSValueDropShadow: { const CSSShadowValue& item = toCSSShadowValue(filterValue->item(0)); IntPoint location(item.x->computeLength<int>(conversionData), item.y->computeLength<int>(conversionData)); int blur = item.blur ? item.blur->computeLength<int>(conversionData) : 0; Color shadowColor = Color::black; if (item.color) shadowColor = state.document().textLinkColors().colorFromCSSValue(*item.color, state.style()->color()); operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor)); break; } default: ASSERT_NOT_REACHED(); break; } } return operations; }
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(); }
void CSSValue::trace(Visitor* visitor) { if (m_isTextClone) { ASSERT(isCSSOMSafe()); toTextCloneCSSValue(this)->traceAfterDispatch(visitor); return; } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: toCSSAspectRatioValue(this)->traceAfterDispatch(visitor); return; case BorderImageSliceClass: toCSSBorderImageSliceValue(this)->traceAfterDispatch(visitor); return; case CanvasClass: toCSSCanvasValue(this)->traceAfterDispatch(visitor); return; case CursorImageClass: toCSSCursorImageValue(this)->traceAfterDispatch(visitor); return; case FontClass: toCSSFontValue(this)->traceAfterDispatch(visitor); return; case FontFaceSrcClass: toCSSFontFaceSrcValue(this)->traceAfterDispatch(visitor); return; case FontFeatureClass: toCSSFontFeatureValue(this)->traceAfterDispatch(visitor); return; case FunctionClass: toCSSFunctionValue(this)->traceAfterDispatch(visitor); return; case LinearGradientClass: toCSSLinearGradientValue(this)->traceAfterDispatch(visitor); return; case RadialGradientClass: toCSSRadialGradientValue(this)->traceAfterDispatch(visitor); return; case CrossfadeClass: toCSSCrossfadeValue(this)->traceAfterDispatch(visitor); return; case ImageClass: toCSSImageValue(this)->traceAfterDispatch(visitor); return; case InheritedClass: toCSSInheritedValue(this)->traceAfterDispatch(visitor); return; case InitialClass: toCSSInitialValue(this)->traceAfterDispatch(visitor); return; case GridLineNamesClass: toCSSGridLineNamesValue(this)->traceAfterDispatch(visitor); return; case GridTemplateAreasClass: toCSSGridTemplateAreasValue(this)->traceAfterDispatch(visitor); return; case PrimitiveClass: toCSSPrimitiveValue(this)->traceAfterDispatch(visitor); return; case ShadowClass: toCSSShadowValue(this)->traceAfterDispatch(visitor); return; case CubicBezierTimingFunctionClass: toCSSCubicBezierTimingFunctionValue(this)->traceAfterDispatch(visitor); return; case StepsTimingFunctionClass: toCSSStepsTimingFunctionValue(this)->traceAfterDispatch(visitor); return; case UnicodeRangeClass: toCSSUnicodeRangeValue(this)->traceAfterDispatch(visitor); return; case ValueListClass: toCSSValueList(this)->traceAfterDispatch(visitor); return; case CSSTransformClass: toCSSTransformValue(this)->traceAfterDispatch(visitor); return; case LineBoxContainClass: toCSSLineBoxContainValue(this)->traceAfterDispatch(visitor); return; case CalculationClass: toCSSCalcValue(this)->traceAfterDispatch(visitor); return; case ImageSetClass: toCSSImageSetValue(this)->traceAfterDispatch(visitor); return; case CSSFilterClass: toCSSFilterValue(this)->traceAfterDispatch(visitor); return; } ASSERT_NOT_REACHED(); }
void StyleBuilderFunctions::applyValueCSSPropertyContent(StyleResolverState& state, CSSValue* value) { // list of string, uri, counter, attr, i bool didSet = false; for (auto& item : toCSSValueList(*value)) { if (item->isImageGeneratorValue()) { state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item.get())), didSet); didSet = true; } else if (item->isImageSetValue()) { state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item.get())), didSet); didSet = true; } if (item->isImageValue()) { state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(state.document(), CSSPropertyContent, toCSSImageValue(item.get())), didSet); didSet = true; continue; } if (item->isCounterValue()) { CSSCounterValue* counterValue = toCSSCounterValue(item.get()); EListStyleType listStyleType = NoneListStyle; CSSValueID listStyleIdent = counterValue->listStyle(); if (listStyleIdent != CSSValueNone) listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc); OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(AtomicString(counterValue->identifier()), listStyleType, AtomicString(counterValue->separator()))); state.style()->setContent(counter.release(), didSet); didSet = true; } if (item->isFunctionValue()) { CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); ASSERT(functionValue->functionType() == CSSValueAttr); // FIXME: Can a namespace be specified for an attr(foo)? if (state.style()->styleType() == NOPSEUDO) state.style()->setUnique(); else state.parentStyle()->setUnique(); QualifiedName attr(nullAtom, AtomicString(toCSSPrimitiveValue(functionValue->item(0))->getStringValue()), nullAtom); const AtomicString& value = state.element()->getAttribute(attr); state.style()->setContent(value.isNull() ? emptyString() : value.string(), didSet); didSet = true; } if (!item->isPrimitiveValue()) continue; CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item.get()); if (contentValue->isString()) { state.style()->setContent(contentValue->getStringValue().impl(), didSet); didSet = true; } else { switch (contentValue->getValueID()) { case CSSValueOpenQuote: state.style()->setContent(OPEN_QUOTE, didSet); didSet = true; break; case CSSValueCloseQuote: state.style()->setContent(CLOSE_QUOTE, didSet); didSet = true; break; case CSSValueNoOpenQuote: state.style()->setContent(NO_OPEN_QUOTE, didSet); didSet = true; break; case CSSValueNoCloseQuote: state.style()->setContent(NO_CLOSE_QUOTE, didSet); didSet = true; break; default: // normal and none do not have any effect. { } } } } if (!didSet) state.style()->clearContent(); }