void StyleBuilderFunctions::applyInheritCSSPropertyWillChange(StyleResolverState& state) { state.style()->setWillChangeContents(state.parentStyle()->willChangeContents()); state.style()->setWillChangeScrollPosition(state.parentStyle()->willChangeScrollPosition()); state.style()->setWillChangeProperties(state.parentStyle()->willChangeProperties()); state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents()); }
void StyleBuilderFunctions::applyInheritCSSPropertyMotionPath(StyleResolverState& state) { if (state.parentStyle()->motionPath()) state.style()->setMotionPath(state.parentStyle()->motionPath()); else state.style()->resetMotionPath(); }
void StyleBuilderFunctions::applyInheritCSSPropertyVerticalAlign(StyleResolverState& state) { EVerticalAlign verticalAlign = state.parentStyle()->verticalAlign(); state.style()->setVerticalAlign(verticalAlign); if (verticalAlign == LENGTH) state.style()->setVerticalAlignLength(state.parentStyle()->verticalAlignLength()); }
void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value) { ASSERT_WITH_MESSAGE(!isShorthandProperty(id), "Shorthand property id = %d wasn't expanded at parsing time", id); bool isInherit = state.parentNode() && value->isInheritedValue(); bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue()); ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle()) if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) { // Limit the properties that can be applied to only the ones honored by :visited. return; } if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSPropertyMetadata::isInheritedProperty(id)) { state.parentStyle()->setHasExplicitlyInheritedProperties(); } else if (value->isUnsetValue()) { ASSERT(!isInherit && !isInitial); if (CSSPropertyMetadata::isInheritedProperty(id)) isInherit = true; else isInitial = true; } StyleBuilder::applyProperty(id, state, value, isInitial, isInherit); }
void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAspectRatio(StyleResolverState& state) { if (!state.parentStyle()->hasAspectRatio()) return; state.style()->setHasAspectRatio(true); state.style()->setAspectRatioDenominator(state.parentStyle()->aspectRatioDenominator()); state.style()->setAspectRatioNumerator(state.parentStyle()->aspectRatioNumerator()); }
InterpolationValue CSSClipInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { ClipAutos parentAutos = getClipAutos(*state.parentStyle()); conversionCheckers.append(ParentAutosChecker::create(parentAutos)); if (parentAutos.isAuto) return nullptr; return createClipValue(state.parentStyle()->clip(), state.parentStyle()->effectiveZoom()); }
PassOwnPtr<InterpolationValue> CSSShadowListInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (!state.parentStyle()) return nullptr; const ShadowList* parentShadowList = ShadowListPropertyFunctions::getShadowList(cssProperty(), *state.parentStyle()); conversionCheckers.append(ParentShadowListChecker::create(*this, cssProperty(), const_cast<ShadowList*>(parentShadowList))); // Take ref. return convertShadowList(parentShadowList, state.parentStyle()->effectiveZoom()); }
InterpolationValue CSSLengthListInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { Vector<Length> inheritedLengthList; bool success = LengthListPropertyFunctions::getLengthList(cssProperty(), *state.parentStyle(), inheritedLengthList); conversionCheckers.append(ParentLengthListChecker::create(cssProperty(), inheritedLengthList)); if (!success) return nullptr; return maybeConvertLengthList(inheritedLengthList, state.parentStyle()->effectiveZoom()); }
PassOwnPtr<InterpolationValue> CSSImageListInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (!state.parentStyle()) return nullptr; StyleImageList inheritedImageList; ImageListPropertyFunctions::getImageList(cssProperty(), *state.parentStyle(), inheritedImageList); conversionCheckers.append(ParentImageListChecker::create(*this, cssProperty(), inheritedImageList)); return maybeConvertStyleImageList(inheritedImageList); }
InterpolationValue CSSNumberInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (!state.parentStyle()) return nullptr; double inheritedNumber; if (!NumberPropertyFunctions::getNumber(cssProperty(), *state.parentStyle(), inheritedNumber)) return nullptr; conversionCheckers.append(ParentNumberChecker::create(cssProperty(), inheritedNumber)); return createNumberValue(inheritedNumber); }
PassOwnPtr<InterpolationValue> CSSLengthInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (!state.parentStyle()) return nullptr; Length inheritedLength; if (!LengthPropertyFunctions::getLength(cssProperty(), *state.parentStyle(), inheritedLength)) return nullptr; conversionCheckers.append(ParentLengthChecker::create(*this, cssProperty(), inheritedLength)); return maybeConvertLength(inheritedLength, effectiveZoom(*state.parentStyle())); }
InterpolationValue CSSBasicShapeInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { const BasicShape* shape = BasicShapePropertyFunctions::getBasicShape( cssProperty(), *state.parentStyle()); // const_cast to take a ref. conversionCheckers.push_back(InheritedShapeChecker::create( cssProperty(), const_cast<BasicShape*>(shape))); return BasicShapeInterpolationFunctions::maybeConvertBasicShape( shape, state.parentStyle()->effectiveZoom()); }
InterpolationValue CSSImageSliceInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { const ImageSlice& inheritedImageSlice = ImageSlicePropertyFunctions::getImageSlice(cssProperty(), *state.parentStyle()); conversionCheckers.push_back(InheritedSliceTypesChecker::create( cssProperty(), SliceTypes(inheritedImageSlice))); return convertImageSlice(inheritedImageSlice, state.parentStyle()->effectiveZoom()); }
void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent) state.style()->setTextAlign(*primitiveValue); else if (state.parentStyle()->textAlign() == TASTART) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT); else if (state.parentStyle()->textAlign() == TAEND) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT); else state.style()->setTextAlign(state.parentStyle()->textAlign()); }
InterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { const BorderImageLengthBox& inherited = BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox( cssProperty(), *state.parentStyle()); conversionCheckers.append(InheritedSideNumbersChecker::create( cssProperty(), SideNumbers(inherited))); return convertBorderImageLengthBox(inherited, state.parentStyle()->effectiveZoom()); }
InterpolationValue CSSPaintInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (!state.parentStyle()) return nullptr; StyleColor parentColor; if (!PaintPropertyFunctions::getColor(cssProperty(), *state.parentStyle(), parentColor)) { conversionCheckers.append(ParentPaintChecker::create(cssProperty())); return nullptr; } conversionCheckers.append(ParentPaintChecker::create(cssProperty(), parentColor)); return InterpolationValue(CSSColorInterpolationType::createInterpolableColor(parentColor)); }
void StyleResolver::applyMatchedProperties(StyleResolverState& state, const MatchResult& matchResult) { const Element* element = state.element(); ASSERT(element); INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyApply); unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0; bool applyInheritedOnly = false; const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_matchedPropertiesCache.find(cacheHash, state, matchResult) : 0; if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) { INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit); // We can build up the style by copying non-inherited properties from an earlier style object built using the same exact // style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the // element context. This is fast and saves memory by reusing the style data structures. state.style()->copyNonInheritedFrom(cachedMatchedProperties->renderStyle.get()); if (state.parentStyle()->inheritedDataShared(cachedMatchedProperties->parentRenderStyle.get()) && (state.style()->userModify() == READ_ONLY)) { INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheInheritedHit); // If the cache item parent style has identical inherited properties to the current parent style then the // resulting style will be identical too. We copy the inherited properties over from the cache and are done. state.style()->inheritFrom(cachedMatchedProperties->renderStyle.get()); return; } applyInheritedOnly = true; } state.setLineHeightValue(0); applyMatchedProperties<HighPriorityProperties>(state, matchResult, applyInheritedOnly); // If our font got dirtied, go ahead and update it now. updateFont(state); // Line-height is set when we are sure we decided on the font-size. if (state.lineHeightValue()) StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue()); // Many properties depend on the font. If it changes we just apply all properties. if (cachedMatchedProperties && cachedMatchedProperties->renderStyle->fontDescription() != state.style()->fontDescription()) applyInheritedOnly = false; applyMatchedProperties<LowPriorityProperties>(state, matchResult, applyInheritedOnly); if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) { INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded); m_matchedPropertiesCache.add(state.style(), state.parentStyle(), cacheHash, matchResult); } ASSERT(!state.fontBuilder().fontDirty()); }
FontWeight StyleBuilderConverter::convertFontWeight(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); switch (primitiveValue->getValueID()) { case CSSValueBolder: return FontDescription::bolderWeight(state.parentStyle()->fontDescription().weight()); case CSSValueLighter: return FontDescription::lighterWeight(state.parentStyle()->fontDescription().weight()); default: return *primitiveValue; } }
InterpolationValue CSSImageInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (!state.parentStyle()) return nullptr; const StyleImage* inheritedImage = ImagePropertyFunctions::getStyleImage( cssProperty(), *state.parentStyle()); StyleImage* refableImage = const_cast<StyleImage*>(inheritedImage); conversionCheckers.append( InheritedImageChecker::create(cssProperty(), refableImage)); return maybeConvertStyleImage(inheritedImage, true); }
void StyleBuilderFunctions::applyInitialCSSPropertyWillChange(StyleResolverState& state) { state.style()->setWillChangeContents(false); state.style()->setWillChangeScrollPosition(false); state.style()->setWillChangeProperties(Vector<CSSPropertyID>()); state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents()); }
InterpolationValue CSSScaleInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { Scale parentScale(state.parentStyle()->scale()); conversionCheckers.append(ParentScaleChecker::create(parentScale)); return InterpolationValue(parentScale.createInterpolableValue()); }
InterpolationValue CSSRotateInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { Rotation inheritedRotation = getRotation(*state.parentStyle()); conversionCheckers.push_back( InheritedRotationChecker::create(inheritedRotation)); return convertRotation(inheritedRotation); }
void StyleBuilderFunctions::applyInheritCSSPropertyColor(StyleResolverState& state) { Color color = state.parentStyle()->color(); if (state.applyPropertyToRegularStyle()) state.style()->setColor(color); if (state.applyPropertyToVisitedLinkStyle()) state.style()->setVisitedLinkColor(color); }
void StyleBuilderFunctions::applyInheritCSSPropertyBaselineShift(StyleResolverState& state) { const SVGComputedStyle& parentSvgStyle = state.parentStyle()->svgStyle(); EBaselineShift baselineShift = parentSvgStyle.baselineShift(); SVGComputedStyle& svgStyle = state.style()->accessSVGStyle(); svgStyle.setBaselineShift(baselineShift); if (baselineShift == BS_LENGTH) svgStyle.setBaselineShiftValue(parentSvgStyle.baselineShiftValue()); }
InterpolationValue CSSTransformInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { const TransformOperations& inheritedTransform = state.parentStyle()->transform(); conversionCheckers.append( InheritedTransformChecker::create(inheritedTransform)); return convertTransform(inheritedTransform); }
InterpolationValue CSSColorInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (!state.parentStyle()) return nullptr; // Visited color can never explicitly inherit from parent visited color so only use the unvisited color. const StyleColor inheritedColor = ColorPropertyFunctions::getUnvisitedColor(cssProperty(), *state.parentStyle()); conversionCheckers.append(ParentColorChecker::create(cssProperty(), inheritedColor)); return convertStyleColorPair(inheritedColor, inheritedColor); }
void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value) { ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id); bool isInherit = state.parentNode() && value->isInheritedValue(); bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue()); ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle()) CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0; if (primitiveValue && primitiveValue->getValueID() == CSSValueCurrentcolor) state.style()->setHasCurrentColor(); if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSPropertyMetadata::isInheritedProperty(id)) state.parentStyle()->setHasExplicitlyInheritedProperties(); StyleBuilder::applyProperty(id, state, value, isInitial, isInherit); }
void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); // FIXME : Per http://www.w3.org/TR/css3-text/#text-align0 can now take <string> but this is not implemented in the // rendering code. if (primitiveValue->isString()) return; if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent) state.style()->setTextAlign(*primitiveValue); else if (state.parentStyle()->textAlign() == TASTART) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT); else if (state.parentStyle()->textAlign() == TAEND) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT); else state.style()->setTextAlign(state.parentStyle()->textAlign()); }
InterpolationValue CSSFilterListInterpolationType::maybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { const FilterOperations& inheritedFilterOperations = FilterListPropertyFunctions::getFilterList(cssProperty(), *state.parentStyle()); conversionCheckers.push_back(InheritedFilterListChecker::create( cssProperty(), inheritedFilterOperations)); return convertFilterList(inheritedFilterOperations, state.style()->effectiveZoom()); }
void StyleBuilderFunctions::applyValueCSSPropertyWillChange(StyleResolverState& state, CSSValue* value) { ASSERT(value->isValueList()); bool willChangeContents = false; bool willChangeScrollPosition = false; Vector<CSSPropertyID> willChangeProperties; for (CSSValueListIterator i(value); i.hasMore(); i.advance()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value()); if (CSSPropertyID propertyID = primitiveValue->getPropertyID()) willChangeProperties.append(propertyID); else if (primitiveValue->getValueID() == CSSValueContents) willChangeContents = true; else if (primitiveValue->getValueID() == CSSValueScrollPosition) willChangeScrollPosition = true; else ASSERT_NOT_REACHED(); } state.style()->setWillChangeContents(willChangeContents); state.style()->setWillChangeScrollPosition(willChangeScrollPosition); state.style()->setWillChangeProperties(willChangeProperties); state.style()->setSubtreeWillChangeContents(willChangeContents || state.parentStyle()->subtreeWillChangeContents()); }