void StyleBuilderFunctions::applyInheritCSSPropertyMotionPath(StyleResolverState& state) { if (state.parentStyle()->motionPath()) state.style()->setMotionPath(state.parentStyle()->motionPath()); else state.style()->resetMotionPath(); }
void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state, CSSValue* value) { if (value->isValueList()) { CSSValueList* list = toCSSValueList(value); ASSERT(list->length() == 2); for (unsigned i = 0; i < 2; ++i) { CSSPrimitiveValue* value = toCSSPrimitiveValue(list->item(i)); if (value->getValueID() == CSSValueFilled || value->getValueID() == CSSValueOpen) state.style()->setTextEmphasisFill(*value); else state.style()->setTextEmphasisMark(*value); } state.style()->setTextEmphasisCustomMark(nullAtom); return; } CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isString()) { state.style()->setTextEmphasisFill(TextEmphasisFillFilled); state.style()->setTextEmphasisMark(TextEmphasisMarkCustom); state.style()->setTextEmphasisCustomMark(AtomicString(primitiveValue->getStringValue())); return; } state.style()->setTextEmphasisCustomMark(nullAtom); if (primitiveValue->getValueID() == CSSValueFilled || primitiveValue->getValueID() == CSSValueOpen) { state.style()->setTextEmphasisFill(*primitiveValue); state.style()->setTextEmphasisMark(TextEmphasisMarkAuto); } else { state.style()->setTextEmphasisFill(TextEmphasisFillFilled); state.style()->setTextEmphasisMark(*primitiveValue); } }
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::applyInitialCSSPropertyWillChange(StyleResolverState& state) { state.style()->setWillChangeContents(false); state.style()->setWillChangeScrollPosition(false); state.style()->setWillChangeProperties(Vector<CSSPropertyID>()); state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents()); }
void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value) { if (!value->isValueList()) return; Length lengthOrPercentageValue; TextIndentLine textIndentLineValue = RenderStyle::initialTextIndentLine(); TextIndentType textIndentTypeValue = RenderStyle::initialTextIndentType(); for (CSSValueListIterator i(value); i.hasMore(); i.advance()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value()); if (!primitiveValue->getValueID()) lengthOrPercentageValue = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); else if (primitiveValue->getValueID() == CSSValueEachLine) textIndentLineValue = TextIndentEachLine; else if (primitiveValue->getValueID() == CSSValueHanging) textIndentTypeValue = TextIndentHanging; else ASSERT_NOT_REACHED(); } state.style()->setTextIndent(lengthOrPercentageValue); state.style()->setTextIndentLine(textIndentLineValue); state.style()->setTextIndentType(textIndentTypeValue); }
void StyleBuilderFunctions::applyValueCSSPropertyGlyphOrientationVertical(StyleResolverState& state, CSSValue* value) { if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueAuto) state.style()->accessSVGStyle().setGlyphOrientationVertical(GO_AUTO); else state.style()->accessSVGStyle().setGlyphOrientationVertical(StyleBuilderConverter::convertGlyphOrientation(state, value)); }
void StyleBuilderFunctions::applyInheritCSSPropertyVerticalAlign(StyleResolverState& state) { EVerticalAlign verticalAlign = state.parentStyle()->verticalAlign(); state.style()->setVerticalAlign(verticalAlign); if (verticalAlign == LENGTH) state.style()->setVerticalAlignLength(state.parentStyle()->verticalAlignLength()); }
void StyleBuilderFunctions::applyValueCSSPropertyMotionRotation(StyleResolverState& state, CSSValue* value) { float rotation = 0; MotionRotationType rotationType = MotionRotationFixed; ASSERT(value->isValueList()); CSSValueList* list = toCSSValueList(value); int len = list->length(); for (int i = 0; i < len; i++) { CSSValue* item = list->item(i); ASSERT(item->isPrimitiveValue()); CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item); if (primitiveValue->getValueID() == CSSValueAuto) { rotationType = MotionRotationAuto; } else if (primitiveValue->getValueID() == CSSValueReverse) { rotationType = MotionRotationAuto; rotation += 180; } else { rotation += primitiveValue->computeDegrees(); } } state.style()->setMotionRotation(rotation); state.style()->setMotionRotationType(rotationType); }
void CSSToStyleMap::mapNinePieceImage(StyleResolverState& state, CSSPropertyID property, CSSValue* value, NinePieceImage& image) { // If we're not a value list, then we are "none" and don't need to alter the empty image at all. if (!value || !value->isValueList()) return; // Retrieve the border image value. CSSValueList* borderImage = toCSSValueList(value); // Set the image (this kicks off the load). CSSPropertyID imageProperty; if (property == CSSPropertyWebkitBorderImage) imageProperty = CSSPropertyBorderImageSource; else if (property == CSSPropertyWebkitMaskBoxImage) imageProperty = CSSPropertyWebkitMaskBoxImageSource; else imageProperty = property; for (unsigned i = 0 ; i < borderImage->length() ; ++i) { CSSValue* current = borderImage->item(i); if (current->isImageValue() || current->isImageGeneratorValue() || current->isImageSetValue()) image.setImage(state.styleImage(imageProperty, current)); else if (current->isBorderImageSliceValue()) mapNinePieceImageSlice(state, current, image); else if (current->isValueList()) { CSSValueList* slashList = toCSSValueList(current); size_t length = slashList->length(); // Map in the image slices. if (length && slashList->item(0)->isBorderImageSliceValue()) mapNinePieceImageSlice(state, slashList->item(0), image); // Map in the border slices. if (length > 1) image.setBorderSlices(mapNinePieceImageQuad(state, slashList->item(1))); // Map in the outset. if (length > 2) image.setOutset(mapNinePieceImageQuad(state, slashList->item(2))); } else if (current->isPrimitiveValue()) { // Set the appropriate rules for stretch/round/repeat of the slices. mapNinePieceImageRepeat(state, current, image); } } if (property == CSSPropertyWebkitBorderImage) { // We have to preserve the legacy behavior of -webkit-border-image and make the border slices // also set the border widths. We don't need to worry about percentages, since we don't even support // those on real borders yet. if (image.borderSlices().top().isLength() && image.borderSlices().top().length().isFixed()) state.style()->setBorderTopWidth(image.borderSlices().top().length().value()); if (image.borderSlices().right().isLength() && image.borderSlices().right().length().isFixed()) state.style()->setBorderRightWidth(image.borderSlices().right().length().value()); if (image.borderSlices().bottom().isLength() && image.borderSlices().bottom().length().isFixed()) state.style()->setBorderBottomWidth(image.borderSlices().bottom().length().value()); if (image.borderSlices().left().isLength() && image.borderSlices().left().length().isFixed()) state.style()->setBorderLeftWidth(image.borderSlices().left().length().value()); } }
void StyleBuilderFunctions::applyInitialCSSPropertyColor(StyleResolverState& state) { Color color = ComputedStyle::initialColor(); if (state.applyPropertyToRegularStyle()) state.style()->setColor(color); if (state.applyPropertyToVisitedLinkStyle()) state.style()->setVisitedLinkColor(color); }
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::applyInheritCSSPropertyWebkitAspectRatio(StyleResolverState& state) { if (!state.parentStyle()->hasAspectRatio()) return; state.style()->setHasAspectRatio(true); state.style()->setAspectRatioDenominator(state.parentStyle()->aspectRatioDenominator()); state.style()->setAspectRatioNumerator(state.parentStyle()->aspectRatioNumerator()); }
void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID()) state.style()->setVerticalAlign(*primitiveValue); else state.style()->setVerticalAlignLength(primitiveValue->convertToLength(state.cssToLengthConversionData())); }
void StyleBuilderFunctions::applyValueCSSPropertyWebkitAspectRatio(StyleResolverState& state, CSSValue* value) { if (!value->isAspectRatioValue()) { state.style()->setHasAspectRatio(false); return; } CSSAspectRatioValue* aspectRatioValue = toCSSAspectRatioValue(value); state.style()->setHasAspectRatio(true); state.style()->setAspectRatioDenominator(aspectRatioValue->denominatorValue()); state.style()->setAspectRatioNumerator(aspectRatioValue->numeratorValue()); }
void StyleBuilderFunctions::applyValueCSSPropertyWebkitClipPath(StyleResolverState& state, CSSValue* value) { if (value->isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueNone) { state.style()->setClipPath(nullptr); } else if (primitiveValue->isShape()) { state.style()->setClipPath(ShapeClipPathOperation::create(basicShapeForValue(state, primitiveValue->getShapeValue()))); } } }
void StyleBuilderFunctions::applyValueCSSPropertyWebkitLocale(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueAuto) state.style()->setLocale(nullAtom); else state.style()->setLocale(AtomicString(primitiveValue->getStringValue())); state.fontBuilder().setScript(state.style()->locale()); }
void StyleBuilderFunctions::applyValueCSSPropertyMotionPath(StyleResolverState& state, CSSValue* value) { if (value->isPathValue()) { const String& pathString = toCSSPathValue(value)->pathString(); state.style()->setMotionPath(PathStyleMotionPath::create(pathString)); return; } ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); state.style()->resetMotionPath(); }
void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value) { state.style()->resetPageSizeType(); FloatSize size; PageSizeType pageSizeType = PAGE_SIZE_AUTO; CSSValueList* list = toCSSValueList(value); if (list->length() == 2) { // <length>{2} | <page-size> <orientation> CSSPrimitiveValue* first = toCSSPrimitiveValue(list->item(0)); CSSPrimitiveValue* second = toCSSPrimitiveValue(list->item(1)); if (first->isLength()) { // <length>{2} size = FloatSize(first->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)), second->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0))); } else { // <page-size> <orientation> size = getPageSizeFromName(first); ASSERT(second->getValueID() == CSSValueLandscape || second->getValueID() == CSSValuePortrait); if (second->getValueID() == CSSValueLandscape) size = size.transposedSize(); } pageSizeType = PAGE_SIZE_RESOLVED; } else { ASSERT(list->length() == 1); // <length> | auto | <page-size> | [ portrait | landscape] CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0)); if (primitiveValue->isLength()) { // <length> pageSizeType = PAGE_SIZE_RESOLVED; float width = primitiveValue->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)); size = FloatSize(width, width); } else { switch (primitiveValue->getValueID()) { case CSSValueAuto: pageSizeType = PAGE_SIZE_AUTO; break; case CSSValuePortrait: pageSizeType = PAGE_SIZE_AUTO_PORTRAIT; break; case CSSValueLandscape: pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE; break; default: // <page-size> pageSizeType = PAGE_SIZE_RESOLVED; size = getPageSizeFromName(primitiveValue); } } } state.style()->setPageSizeType(pageSizeType); state.style()->setPageSize(size); }
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()); }
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()); }
void StyleBuilderFunctions::applyValueCSSPropertyColor(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); // As per the spec, 'color: currentColor' is treated as 'color: inherit' if (primitiveValue->getValueID() == CSSValueCurrentcolor) { applyInheritCSSPropertyColor(state); return; } if (state.applyPropertyToRegularStyle()) state.style()->setColor(StyleBuilderConverter::convertColor(state, value)); if (state.applyPropertyToVisitedLinkStyle()) state.style()->setVisitedLinkColor(StyleBuilderConverter::convertColor(state, value, true)); }
void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID()) { state.style()->setVerticalAlign(*primitiveValue); return; } state.style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData())); }
void StyleBuilderFunctions::applyValueCSSPropertyDirection(StyleResolverState& state, CSSValue* value) { state.style()->setDirection(*toCSSPrimitiveValue(value)); Element* element = state.element(); if (element && element == element->document().documentElement()) element->document().setDirectionSetOnDocumentElement(true); }
PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState& state, CSSValue* value) { if (value->isPrimitiveValue()) { ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); return PassRefPtr<ShadowList>(); } const CSSValueList* valueList = toCSSValueList(value); size_t shadowCount = valueList->length(); ShadowDataVector shadows; for (size_t i = 0; i < shadowCount; ++i) { const CSSShadowValue* item = toCSSShadowValue(valueList->item(i)); float x = item->x->computeLength<float>(state.cssToLengthConversionData()); float y = item->y->computeLength<float>(state.cssToLengthConversionData()); float blur = item->blur ? item->blur->computeLength<float>(state.cssToLengthConversionData()) : 0; float spread = item->spread ? item->spread->computeLength<float>(state.cssToLengthConversionData()) : 0; ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal; Color color; if (item->color) color = convertColor(state, item->color.get()); else color = state.style()->color(); shadows.append(ShadowData(FloatPoint(x, y), blur, spread, shadowStyle, color)); } return ShadowList::adopt(shadows); }
void CSSVariableResolver::resolveAndApplyVariableReferences(StyleResolverState& state, CSSPropertyID id, const CSSVariableReferenceValue& value) { CSSVariableResolver resolver(state.style()->variables()); Vector<CSSParserToken> tokens; if (resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens)) { CSSParserContext context(HTMLStandardMode, 0); HeapVector<CSSProperty, 256> parsedProperties; // TODO: Non-shorthands should just call CSSPropertyParser::parseSingleValue if (CSSPropertyParser::parseValue(id, false, CSSParserTokenRange(tokens), context, parsedProperties, StyleRule::RuleType::Style)) { unsigned parsedPropertiesCount = parsedProperties.size(); for (unsigned i = 0; i < parsedPropertiesCount; ++i) StyleBuilder::applyProperty(parsedProperties[i].id(), state, parsedProperties[i].value()); return; } } RawPtr<CSSUnsetValue> unset = cssValuePool().createUnsetValue(); if (isShorthandProperty(id)) { StylePropertyShorthand shorthand = shorthandForProperty(id); for (unsigned i = 0; i < shorthand.length(); i++) StyleBuilder::applyProperty(shorthand.properties()[i], state, unset.get()); return; } StyleBuilder::applyProperty(id, state, unset.get()); }
void StyleBuilderFunctions::applyValueCSSPropertyPerspective(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueNone) { state.style()->setPerspective(0); return; } if (!primitiveValue->isLength()) return; float perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData()); if (perspectiveValue >= 0.0f) state.style()->setPerspective(perspectiveValue); }
void StyleBuilderFunctions::applyValueCSSPropertyTransform(StyleResolverState& state, CSSValue* value) { // FIXME: We should just make this a converter TransformOperations operations; TransformBuilder::createTransformOperations(*value, state.cssToLengthConversionData(), operations); state.style()->setTransform(operations); }
void StyleBuilderFunctions::applyValueCSSPropertyBackdropFilter(StyleResolverState& state, CSSValue* value) { // FIXME: We should just make this a converter FilterOperations operations; FilterOperationResolver::createFilterOperations(*value, state.cssToLengthConversionData(), operations, state); state.style()->setBackdropFilter(operations); }
Color StyleBuilderConverter::convertSVGColor(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isRGBColor()) return primitiveValue->getRGBA32Value(); ASSERT(primitiveValue->getValueID() == CSSValueCurrentcolor); return state.style()->color(); }
static PassRefPtr<CustomFilterParameter> parseCustomFilterTransformParameter(const String& name, CSSValueList* values, StyleResolverState& state) { RefPtr<CustomFilterTransformParameter> transformParameter = CustomFilterTransformParameter::create(name); TransformOperations operations; TransformBuilder::createTransformOperations(values, state.style(), state.rootElementStyle(), operations); transformParameter->setOperations(operations); return transformParameter.release(); }