diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp | 314 |
1 files changed, 298 insertions, 16 deletions
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp index d3ffb158dce..fe94e10930e 100644 --- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp +++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp @@ -27,26 +27,210 @@ #include "config.h" #include "core/css/resolver/StyleBuilderConverter.h" +#include "core/css/CSSFunctionValue.h" +#include "core/css/CSSGridLineNamesValue.h" #include "core/css/CSSPrimitiveValueMappings.h" +#include "core/css/CSSReflectValue.h" #include "core/css/CSSShadowValue.h" #include "core/css/Pair.h" #include "core/svg/SVGURIReference.h" namespace WebCore { -String StyleBuilderConverter::convertFragmentIdentifier(StyleResolverState& state, CSSValue* value) +namespace { + +static GridLength convertGridTrackBreadth(const StyleResolverState& state, CSSPrimitiveValue* primitiveValue) +{ + if (primitiveValue->getValueID() == CSSValueMinContent) + return Length(MinContent); + + if (primitiveValue->getValueID() == CSSValueMaxContent) + return Length(MaxContent); + + // Fractional unit. + if (primitiveValue->isFlex()) + return GridLength(primitiveValue->getDoubleValue()); + + return primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData()); +} + +} // namespace + +PassRefPtr<StyleReflection> StyleBuilderConverter::convertBoxReflect(StyleResolverState& state, CSSValue* value) +{ + if (value->isPrimitiveValue()) { + ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); + return RenderStyle::initialBoxReflect(); + } + + CSSReflectValue* reflectValue = toCSSReflectValue(value); + RefPtr<StyleReflection> reflection = StyleReflection::create(); + reflection->setDirection(*reflectValue->direction()); + if (reflectValue->offset()) + reflection->setOffset(reflectValue->offset()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData())); + NinePieceImage mask; + mask.setMaskDefaults(); + state.styleMap().mapNinePieceImage(state.style(), CSSPropertyWebkitBoxReflect, reflectValue->mask(), mask); + reflection->setMask(mask); + + return reflection.release(); +} + +AtomicString StyleBuilderConverter::convertFragmentIdentifier(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isURI()) - return SVGURIReference::fragmentIdentifierFromIRIString(primitiveValue->getStringValue(), state.document()); - return String(); + return SVGURIReference::fragmentIdentifierFromIRIString(primitiveValue->getStringValue(), state.element()->treeScope()); + return nullAtom; +} + +EGlyphOrientation StyleBuilderConverter::convertGlyphOrientation(StyleResolverState&, CSSValue* value) +{ + if (!value->isPrimitiveValue()) + return GO_0DEG; + + CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); + if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_DEG) + return GO_0DEG; + + float angle = fabsf(fmodf(primitiveValue->getFloatValue(), 360.0f)); + + if (angle <= 45.0f || angle > 315.0f) + return GO_0DEG; + if (angle > 45.0f && angle <= 135.0f) + return GO_90DEG; + if (angle > 135.0f && angle <= 225.0f) + return GO_180DEG; + return GO_270DEG; +} + +GridPosition StyleBuilderConverter::convertGridPosition(StyleResolverState&, CSSValue* value) +{ + // We accept the specification's grammar: + // 'auto' | [ <integer> || <custom-ident> ] | [ span && [ <integer> || <custom-ident> ] ] | <custom-ident> + + GridPosition position; + + if (value->isPrimitiveValue()) { + CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); + // We translate <custom-ident> to <string> during parsing as it + // makes handling it more simple. + if (primitiveValue->isString()) { + position.setNamedGridArea(primitiveValue->getStringValue()); + return position; + } + + ASSERT(primitiveValue->getValueID() == CSSValueAuto); + return position; + } + + CSSValueList* values = toCSSValueList(value); + ASSERT(values->length()); + + bool isSpanPosition = false; + // The specification makes the <integer> optional, in which case it default to '1'. + int gridLineNumber = 1; + String gridLineName; + + CSSValueListIterator it = values; + CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value()); + if (currentValue->getValueID() == CSSValueSpan) { + isSpanPosition = true; + it.advance(); + currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0; + } + + if (currentValue && currentValue->isNumber()) { + gridLineNumber = currentValue->getIntValue(); + it.advance(); + currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0; + } + + if (currentValue && currentValue->isString()) { + gridLineName = currentValue->getStringValue(); + it.advance(); + } + + ASSERT(!it.hasMore()); + if (isSpanPosition) + position.setSpanPosition(gridLineNumber, gridLineName); + else + position.setExplicitPosition(gridLineNumber, gridLineName); + + return position; +} + +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->itemWithoutBoundsCheck(0)))); + GridLength maxTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(1)))); + return GridTrackSize(minTrackBreadth, maxTrackBreadth); +} + +bool StyleBuilderConverter::convertGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, StyleResolverState& state) +{ + // Handle 'none'. + if (value->isPrimitiveValue()) { + CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); + return primitiveValue->getValueID() == CSSValueNone; + } + + if (!value->isValueList()) + return false; + + size_t currentNamedGridLine = 0; + for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { + CSSValue* currValue = i.value(); + if (currValue->isGridLineNamesValue()) { + CSSGridLineNamesValue* lineNamesValue = toCSSGridLineNamesValue(currValue); + for (CSSValueListIterator j = lineNamesValue; j.hasMore(); j.advance()) { + String namedGridLine = toCSSPrimitiveValue(j.value())->getStringValue(); + NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>()); + result.storedValue->value.append(currentNamedGridLine); + OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>()); + orderedInsertionResult.storedValue->value.append(namedGridLine); + } + continue; + } + + ++currentNamedGridLine; + trackSizes.append(convertGridTrackSize(state, currValue)); + } + + // The parser should have rejected any <track-list> without any <track-size> as + // this is not conformant to the syntax. + ASSERT(!trackSizes.isEmpty()); + return true; +} + +void StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(const NamedGridAreaMap& namedGridAreas, NamedGridLinesMap& namedGridLines, GridTrackSizingDirection direction) +{ + NamedGridAreaMap::const_iterator end = namedGridAreas.end(); + for (NamedGridAreaMap::const_iterator it = namedGridAreas.begin(); it != end; ++it) { + GridSpan areaSpan = direction == ForRows ? it->value.rows : it->value.columns; + { + NamedGridLinesMap::AddResult startResult = namedGridLines.add(it->key + "-start", Vector<size_t>()); + startResult.storedValue->value.append(areaSpan.resolvedInitialPosition.toInt()); + std::sort(startResult.storedValue->value.begin(), startResult.storedValue->value.end()); + } + { + NamedGridLinesMap::AddResult endResult = namedGridLines.add(it->key + "-end", Vector<size_t>()); + endResult.storedValue->value.append(areaSpan.resolvedFinalPosition.toInt() + 1); + std::sort(endResult.storedValue->value.begin(), endResult.storedValue->value.end()); + } + } } Length StyleBuilderConverter::convertLength(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); - ASSERT(!result.isUndefined()); result.setQuirk(primitiveValue->isQuirkValue()); return result; } @@ -55,7 +239,6 @@ Length StyleBuilderConverter::convertLengthOrAuto(StyleResolverState& state, CSS { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData()); - ASSERT(!result.isUndefined()); result.setQuirk(primitiveValue->isQuirkValue()); return result; } @@ -103,6 +286,16 @@ LengthPoint StyleBuilderConverter::convertLengthPoint(StyleResolverState& state, return LengthPoint(x, y); } +LineBoxContain StyleBuilderConverter::convertLineBoxContain(StyleResolverState&, CSSValue* value) +{ + if (value->isPrimitiveValue()) { + ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); + return LineBoxContainNone; + } + + return toCSSLineBoxContainValue(value)->value(); +} + float StyleBuilderConverter::convertNumberOrPercentage(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); @@ -112,6 +305,59 @@ float StyleBuilderConverter::convertNumberOrPercentage(StyleResolverState& state return primitiveValue->getFloatValue() / 100.0f; } +EPaintOrder StyleBuilderConverter::convertPaintOrder(StyleResolverState&, CSSValue* cssPaintOrder) +{ + if (cssPaintOrder->isValueList()) { + int paintOrder = 0; + CSSValueListInspector iter(cssPaintOrder); + for (size_t i = 0; i < iter.length(); i++) { + CSSPrimitiveValue* value = toCSSPrimitiveValue(iter.item(i)); + + EPaintOrderType paintOrderType = PT_NONE; + switch (value->getValueID()) { + case CSSValueFill: + paintOrderType = PT_FILL; + break; + case CSSValueStroke: + paintOrderType = PT_STROKE; + break; + case CSSValueMarkers: + paintOrderType = PT_MARKERS; + break; + default: + ASSERT_NOT_REACHED(); + break; + } + + paintOrder |= (paintOrderType << kPaintOrderBitwidth*i); + } + return (EPaintOrder)paintOrder; + } + + return PO_NORMAL; +} + +PassRefPtr<QuotesData> StyleBuilderConverter::convertQuotes(StyleResolverState&, CSSValue* value) +{ + if (value->isValueList()) { + CSSValueList* list = toCSSValueList(value); + RefPtr<QuotesData> quotes = QuotesData::create(); + for (size_t i = 0; i < list->length(); i += 2) { + CSSValue* first = list->itemWithoutBoundsCheck(i); + // item() returns null if out of bounds so this is safe. + CSSValue* second = list->item(i + 1); + if (!second) + continue; + String startQuote = toCSSPrimitiveValue(first)->getStringValue(); + String endQuote = toCSSPrimitiveValue(second)->getStringValue(); + quotes->addPair(std::make_pair(startQuote, endQuote)); + } + return quotes.release(); + } + // FIXME: We should assert we're a primitive value with valueID = CSSValueNone + return QuotesData::create(); +} + LengthSize StyleBuilderConverter::convertRadius(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); @@ -138,20 +384,17 @@ PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState& ShadowDataVector shadows; for (size_t i = 0; i < shadowCount; ++i) { const CSSShadowValue* item = toCSSShadowValue(valueList->item(i)); - int x = item->x->computeLength<int>(state.cssToLengthConversionData()); - int y = item->y->computeLength<int>(state.cssToLengthConversionData()); - int blur = item->blur ? item->blur->computeLength<int>(state.cssToLengthConversionData()) : 0; - int spread = item->spread ? item->spread->computeLength<int>(state.cssToLengthConversionData()) : 0; + 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 = state.document().textLinkColors().colorFromPrimitiveValue(item->color.get(), state.style()->color()); else color = state.style()->color(); - - if (!color.isValid()) - color = Color::transparent; - shadows.append(ShadowData(IntPoint(x, y), blur, spread, shadowStyle, color)); + shadows.append(ShadowData(FloatPoint(x, y), blur, spread, shadowStyle, color)); } return ShadowList::adopt(shadows); } @@ -161,14 +404,53 @@ float StyleBuilderConverter::convertSpacing(StyleResolverState& state, CSSValue* CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueNormal) return 0; - if (state.useSVGZoomRules()) - return primitiveValue->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1)); return primitiveValue->computeLength<float>(state.cssToLengthConversionData()); } -SVGLength StyleBuilderConverter::convertSVGLength(StyleResolverState&, CSSValue* value) +PassRefPtr<SVGLengthList> StyleBuilderConverter::convertStrokeDasharray(StyleResolverState&, CSSValue* value) +{ + if (!value->isValueList()) { + return SVGRenderStyle::initialStrokeDashArray(); + } + + CSSValueList* dashes = toCSSValueList(value); + + RefPtr<SVGLengthList> array = SVGLengthList::create(); + 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)); + } + + return array.release(); +} + +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(); +} + +PassRefPtr<SVGLength> StyleBuilderConverter::convertSVGLength(StyleResolverState&, CSSValue* value) { return SVGLength::fromCSSPrimitiveValue(toCSSPrimitiveValue(value)); } +float StyleBuilderConverter::convertTextStrokeWidth(StyleResolverState& state, CSSValue* value) +{ + CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); + if (primitiveValue->getValueID()) { + float multiplier = convertLineWidth<float>(state, value); + return CSSPrimitiveValue::create(multiplier / 48, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.cssToLengthConversionData()); + } + return primitiveValue->computeLength<float>(state.cssToLengthConversionData()); +} + } // namespace WebCore |