String CSSPrimitiveValue::customCSSText() const
{
    if (m_hasCachedCSSText) {
        ASSERT(cssTextCache().contains(this));
        return cssTextCache().get(this);
    }

    String text;
    switch (type()) {
    case UnitType::Unknown:
        // FIXME
        break;
    case UnitType::Integer:
        text = String::format("%d", getIntValue());
        break;
    case UnitType::Number:
    case UnitType::Percentage:
    case UnitType::Ems:
    case UnitType::Exs:
    case UnitType::Rems:
    case UnitType::Chs:
    case UnitType::Pixels:
    case UnitType::Centimeters:
    case UnitType::DotsPerPixel:
    case UnitType::DotsPerInch:
    case UnitType::DotsPerCentimeter:
    case UnitType::Millimeters:
    case UnitType::Inches:
    case UnitType::Points:
    case UnitType::Picas:
    case UnitType::Degrees:
    case UnitType::Radians:
    case UnitType::Gradians:
    case UnitType::Milliseconds:
    case UnitType::Seconds:
    case UnitType::Hertz:
    case UnitType::Kilohertz:
    case UnitType::Turns:
    case UnitType::Fraction:
    case UnitType::ViewportWidth:
    case UnitType::ViewportHeight:
    case UnitType::ViewportMin:
    case UnitType::ViewportMax:
        text = formatNumber(m_value.num, unitTypeToString(type()));
        break;
    case UnitType::CustomIdentifier:
        text = quoteCSSStringIfNeeded(m_value.string);
        break;
    case UnitType::String: {
        text = serializeString(m_value.string);
        break;
    }
    case UnitType::URI:
        text = "url(" + quoteCSSURLIfNeeded(m_value.string) + ")";
        break;
    case UnitType::ValueID:
        text = valueName(m_value.valueID);
        break;
    case UnitType::PropertyID:
        text = propertyName(m_value.propertyID);
        break;
    case UnitType::Attribute: {
        StringBuilder result;
        result.reserveCapacity(6 + m_value.string->length());
        result.appendLiteral("attr(");
        result.append(m_value.string);
        result.append(')');

        text = result.toString();
        break;
    }
    case UnitType::Counter: {
        StringBuilder result;
        String separator = m_value.counter->separator();
        if (separator.isEmpty())
            result.appendLiteral("counter(");
        else
            result.appendLiteral("counters(");

        result.append(m_value.counter->identifier());
        if (!separator.isEmpty()) {
            result.appendLiteral(", ");
            result.append(serializeString(separator));
        }
        String listStyle = m_value.counter->listStyle();
        bool isDefaultListStyle = m_value.counter->listStyleIdent() == CSSValueDecimal;
        if (!listStyle.isEmpty() && !isDefaultListStyle) {
            result.appendLiteral(", ");
            result.append(listStyle);
        }
        result.append(')');

        text = result.toString();
        break;
    }
    case UnitType::Rect:
        text = getRectValue()->cssText();
        break;
    case UnitType::Quad:
        text = getQuadValue()->cssText();
        break;
    case UnitType::RGBColor: {
        text = Color(m_value.rgbcolor).serializedAsCSSComponentValue();
        break;
    }
    case UnitType::Pair:
        text = getPairValue()->cssText();
        break;
    case UnitType::Calc:
        text = m_value.calc->customCSSText();
        break;
    case UnitType::Shape:
        text = m_value.shape->cssText();
        break;
    case UnitType::CalcPercentageWithNumber:
    case UnitType::CalcPercentageWithLength:
    case UnitType::QuirkyEms:
        ASSERT_NOT_REACHED();
        break;
    }

    ASSERT(!cssTextCache().contains(this));
    cssTextCache().set(this, text);
    m_hasCachedCSSText = true;
    return text;
}
示例#2
0
ALWAYS_INLINE String CSSPrimitiveValue::formatNumberForcustomCSSText() const
{
    switch (m_primitiveUnitType) {
    case CSS_UNKNOWN:
        return String();
    case CSS_NUMBER:
    case CSS_PARSER_INTEGER:
        return formatNumberValue("");
    case CSS_PERCENTAGE:
        return formatNumberValue("%");
    case CSS_EMS:
        return formatNumberValue("em");
    case CSS_EXS:
        return formatNumberValue("ex");
    case CSS_REMS:
        return formatNumberValue("rem");
    case CSS_CHS:
        return formatNumberValue("ch");
    case CSS_PX:
        return formatNumberValue("px");
    case CSS_CM:
        return formatNumberValue("cm");
#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
    case CSS_DPPX:
        return formatNumberValue("dppx");
    case CSS_DPI:
        return formatNumberValue("dpi");
    case CSS_DPCM:
        return formatNumberValue("dpcm");
#endif
    case CSS_MM:
        return formatNumberValue("mm");
    case CSS_IN:
        return formatNumberValue("in");
    case CSS_PT:
        return formatNumberValue("pt");
    case CSS_PC:
        return formatNumberValue("pc");
    case CSS_DEG:
        return formatNumberValue("deg");
    case CSS_RAD:
        return formatNumberValue("rad");
    case CSS_GRAD:
        return formatNumberValue("grad");
    case CSS_MS:
        return formatNumberValue("ms");
    case CSS_S:
        return formatNumberValue("s");
    case CSS_HZ:
        return formatNumberValue("hz");
    case CSS_KHZ:
        return formatNumberValue("khz");
    case CSS_TURN:
        return formatNumberValue("turn");
    case CSS_FR:
        return formatNumberValue("fr");
    case CSS_DIMENSION:
        // FIXME: We currently don't handle CSS_DIMENSION properly as we don't store
        // the actual dimension, just the numeric value as a string.
    case CSS_STRING:
        return quoteCSSStringIfNeeded(m_value.string);
    case CSS_URI:
        return "url(" + quoteCSSURLIfNeeded(m_value.string) + ')';
    case CSS_VALUE_ID:
        return valueName(m_value.valueID);
    case CSS_PROPERTY_ID:
        return propertyName(m_value.propertyID);
    case CSS_ATTR: {
        StringBuilder result;
        result.reserveCapacity(6 + m_value.string->length());
        result.appendLiteral("attr(");
        result.append(m_value.string);
        result.append(')');

        return result.toString();
    }
    case CSS_COUNTER_NAME:
        return "counter(" + String(m_value.string) + ')';
    case CSS_COUNTER: {
        StringBuilder result;
        String separator = m_value.counter->separator();
        if (separator.isEmpty())
            result.appendLiteral("counter(");
        else
            result.appendLiteral("counters(");

        result.append(m_value.counter->identifier());
        if (!separator.isEmpty()) {
            result.appendLiteral(", ");
            result.append(quoteCSSStringIfNeeded(separator));
        }
        String listStyle = m_value.counter->listStyle();
        if (!listStyle.isEmpty()) {
            result.appendLiteral(", ");
            result.append(listStyle);
        }
        result.append(')');

        return result.toString();
    }
    case CSS_RECT:
        return getRectValue()->cssText();
    case CSS_QUAD:
        return getQuadValue()->cssText();
    case CSS_RGBCOLOR:
    case CSS_PARSER_HEXCOLOR: {
        RGBA32 rgbColor = m_value.rgbcolor;
        if (m_primitiveUnitType == CSS_PARSER_HEXCOLOR)
            Color::parseHexColor(m_value.string, rgbColor);
        Color color(rgbColor);

        Vector<LChar> result;
        result.reserveInitialCapacity(32);
        bool colorHasAlpha = color.hasAlpha();
        if (colorHasAlpha)
            result.append("rgba(", 5);
        else
            result.append("rgb(", 4);

        appendNumber(result, static_cast<unsigned char>(color.red()));
        result.append(", ", 2);

        appendNumber(result, static_cast<unsigned char>(color.green()));
        result.append(", ", 2);

        appendNumber(result, static_cast<unsigned char>(color.blue()));
        if (colorHasAlpha) {
            result.append(", ", 2);

            NumberToStringBuffer buffer;
            const char* alphaString = numberToFixedPrecisionString(color.alpha() / 255.0f, 6, buffer, true);
            result.append(alphaString, strlen(alphaString));
        }

        result.append(')');
        return String::adopt(result);
    }
    case CSS_PAIR:
        return getPairValue()->cssText();
#if ENABLE(DASHBOARD_SUPPORT)
    case CSS_DASHBOARD_REGION: {
        StringBuilder result;
        for (DashboardRegion* region = getDashboardRegionValue(); region; region = region->m_next.get()) {
            if (!result.isEmpty())
                result.append(' ');
            result.appendLiteral("dashboard-region(");
            result.append(region->m_label);
            if (region->m_isCircle)
                result.appendLiteral(" circle");
            else if (region->m_isRectangle)
                result.appendLiteral(" rectangle");
            else
                break;
            if (region->top()->m_primitiveUnitType == CSS_VALUE_ID && region->top()->getValueID() == CSSValueInvalid) {
                ASSERT(region->right()->m_primitiveUnitType == CSS_VALUE_ID);
                ASSERT(region->bottom()->m_primitiveUnitType == CSS_VALUE_ID);
                ASSERT(region->left()->m_primitiveUnitType == CSS_VALUE_ID);
                ASSERT(region->right()->getValueID() == CSSValueInvalid);
                ASSERT(region->bottom()->getValueID() == CSSValueInvalid);
                ASSERT(region->left()->getValueID() == CSSValueInvalid);
            } else {
                result.append(' ');
                result.append(region->top()->cssText());
                result.append(' ');
                result.append(region->right()->cssText());
                result.append(' ');
                result.append(region->bottom()->cssText());
                result.append(' ');
                result.append(region->left()->cssText());
            }
            result.append(')');
        }
        return result.toString();
    }
#endif
    case CSS_PARSER_OPERATOR: {
        char c = static_cast<char>(m_value.parserOperator);
        return String(&c, 1U);
    }
    case CSS_PARSER_IDENTIFIER:
        return quoteCSSStringIfNeeded(m_value.string);
    case CSS_CALC:
        return m_value.calc->cssText();
    case CSS_SHAPE:
        return m_value.shape->cssText();
    case CSS_VW:
        return formatNumberValue("vw");
    case CSS_VH:
        return formatNumberValue("vh");
    case CSS_VMIN:
        return formatNumberValue("vmin");
    case CSS_VMAX:
        return formatNumberValue("vmax");
    }
    return String();
}