⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cssparser.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if( !parseValue( properties[3], important ) ) return false;
	return true;
    }
    default:
        return false;
    }
}

// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
// in CSS 2.1 this got somewhat reduced:
// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
bool CSSParser::parseContent( int propId, bool important )
{
    CSSValueListImpl* values = new CSSValueListImpl();

    Value *val;
    CSSValueImpl *parsedValue = 0;
    while ( (val = valueList->current()) ) {
        if ( val->unit == CSSPrimitiveValue::CSS_URI ) {
            // url
	    DOMString value = khtml::parseURL(domString(val->string));
            parsedValue = new CSSImageValueImpl(
		DOMString(KURL( styleElement->baseURL().string(), value.string()).url() ), styleElement );
#ifdef CSS_DEBUG
	    kdDebug( 6080 ) << "content, url=" << value.string() << " base=" << styleElement->baseURL().string() << endl;
#endif
        } else if ( val->unit == Value::Function ) {
	    // attr( X )
            ValueList *args = val->function->args;
            QString fname = qString( val->function->name ).lower();
            if ( fname != "attr(" || !args )
                return false;
            if ( args->numValues != 1)
                return false;
            Value *a = args->current();
            parsedValue = new CSSPrimitiveValueImpl(domString(a->string), CSSPrimitiveValue::CSS_ATTR);
        } else if ( val->unit == CSSPrimitiveValue::CSS_IDENT ) {
            // open-quote
            // close-quote
            // no-open-quote
            // no-close-quote
        } else if ( val->unit == CSSPrimitiveValue::CSS_STRING ) {
            parsedValue = new CSSPrimitiveValueImpl(domString(val->string), CSSPrimitiveValue::CSS_STRING);
        }
        if (parsedValue)
            values->append(parsedValue);
	else
	    break;
	valueList->next();
    }
    if ( values->length() ) {
	addProperty( propId, values, important );
	valueList->next();
	return true;
    }
    delete values;
    return false;
}

CSSValueImpl* CSSParser::parseBackgroundColor()
{
    int id = valueList->current()->id;
    if (id == CSS_VAL__KHTML_TEXT || (id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) || id == CSS_VAL_MENU ||
        (id >= CSS_VAL_GREY && id < CSS_VAL__KHTML_TEXT && !strict))
       return new CSSPrimitiveValueImpl(id);
    return parseColor();
}

CSSValueImpl* CSSParser::parseBackgroundImage()
{
    if (valueList->current()->id == CSS_VAL_NONE)
        return new CSSImageValueImpl();
    if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
        DOMString uri = khtml::parseURL(domString(valueList->current()->string));
        if (!uri.isEmpty())
            return new CSSImageValueImpl(DOMString(KURL(styleElement->baseURL().string(), uri.string()).url()),
                                         styleElement);
    }
    return 0;
}

CSSValueImpl* CSSParser::parseBackgroundPositionXY(bool& xFound, bool& yFound)
{
    int id = valueList->current()->id;
    if (id == CSS_VAL_LEFT || id == CSS_VAL_TOP || id == CSS_VAL_RIGHT || id == CSS_VAL_BOTTOM || id == CSS_VAL_CENTER) {
        int percent = 0;
        if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT) {
            if (xFound)
                return 0;
            xFound = true;
            if (id == CSS_VAL_RIGHT)
                percent = 100;
        }
        else if (id == CSS_VAL_TOP || id == CSS_VAL_BOTTOM) {
            if (yFound)
                return 0;
            yFound = true;
            if (id == CSS_VAL_BOTTOM)
                percent = 100;
        }
        else if (id == CSS_VAL_CENTER)
            // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
            percent = 50;
        return new CSSPrimitiveValueImpl(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
    }
    if (validUnit(valueList->current(), FPercent|FLength, strict))
        return new CSSPrimitiveValueImpl(valueList->current()->fValue,
                                         (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);

    return 0;
}

void CSSParser::parseBackgroundPosition(CSSValueImpl*& value1, CSSValueImpl*& value2)
{
    value1 = value2 = 0;
    Value* value = valueList->current();

    // Parse the first value.  We're just making sure that it is one of the valid keywords or a percentage/length.
    bool value1IsX = false, value1IsY = false;
    value1 = parseBackgroundPositionXY(value1IsX, value1IsY);
    if (!value1)
        return;

    // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
    // can assume that any other values belong to the rest of the shorthand).  If we're not parsing a shorthand, though, the
    // value was explicitly specified for our property.
    value = valueList->next();

    // First check for the comma.  If so, we are finished parsing this value or value pair.
    if (value && value->unit == Value::Operator && value->iValue == ',')
        value = 0;

    bool value2IsX = false, value2IsY = false;
    if (value) {
        value2 = parseBackgroundPositionXY(value2IsX, value2IsY);
        if (value2)
            valueList->next();
        else {
            if (!inParseShortHand) {
                delete value1;
                value1 = 0;
                return;
            }
        }
    }

    if (!value2)
        // Only one value was specified.  If that value was not a keyword, then it sets the x position, and the y position
        // is simply 50%.  This is our default.
        // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
        // For left/right/center, the default of 50% in the y is still correct.
        value2 = new CSSPrimitiveValueImpl(50, CSSPrimitiveValue::CSS_PERCENTAGE);

    if (value1IsY || value2IsX) {
        // Swap our two values.
        CSSValueImpl* val = value2;
        value2 = value1;
        value1 = val;
    }
}

bool CSSParser::parseBackgroundProperty(int propId, int& propId1, int& propId2,
                                        CSSValueImpl*& retValue1, CSSValueImpl*& retValue2)
{
    CSSValueListImpl *values = 0, *values2 = 0;
    Value* val;
    CSSValueImpl *value = 0, *value2 = 0;
    bool allowComma = false;

    retValue1 = retValue2 = 0;
    propId1 = propId;
    propId2 = propId;
    if (propId == CSS_PROP_BACKGROUND_POSITION) {
        propId1 = CSS_PROP_BACKGROUND_POSITION_X;
        propId2 = CSS_PROP_BACKGROUND_POSITION_Y;
    }

    while ((val = valueList->current())) {
        CSSValueImpl *currValue = 0, *currValue2 = 0;
        if (allowComma) {
            if (val->unit != Value::Operator || val->iValue != ',')
                goto failed;
            valueList->next();
            allowComma = false;
        }
        else {
            switch (propId) {
                case CSS_PROP_BACKGROUND_ATTACHMENT:
                    if (val->id == CSS_VAL_SCROLL || val->id == CSS_VAL_FIXED) {
                        currValue = new CSSPrimitiveValueImpl(val->id);
                        valueList->next();
                    }
                    break;
                case CSS_PROP_BACKGROUND_COLOR:
                    currValue = parseBackgroundColor();
                    if (currValue)
                        valueList->next();
                    break;
                case CSS_PROP_BACKGROUND_IMAGE:
                    currValue = parseBackgroundImage();
                    if (currValue)
                        valueList->next();
                    break;
                case CSS_PROP_BACKGROUND_POSITION:
                    parseBackgroundPosition(currValue, currValue2);
                    // unlike the other functions, parseBackgroundPosition advances the valueList pointer
                    break;
                case CSS_PROP_BACKGROUND_POSITION_X: {
                    bool xFound = false, yFound = true;
                    currValue = parseBackgroundPositionXY(xFound, yFound);
                    if (currValue)
                        valueList->next();
                    break;
                }
                case CSS_PROP_BACKGROUND_POSITION_Y: {
                    bool xFound = true, yFound = false;
                    currValue = parseBackgroundPositionXY(xFound, yFound);
                    if (currValue)
                        valueList->next();
                    break;
                }
                case CSS_PROP_BACKGROUND_REPEAT:
                    if (val->id >= CSS_VAL_REPEAT && val->id <= CSS_VAL_NO_REPEAT) {
                        currValue = new CSSPrimitiveValueImpl(val->id);
                        valueList->next();
                    }
                    break;
            }

            if (!currValue)
                goto failed;

            if (value && !values) {
                values = new CSSValueListImpl();
                values->append(value);
                value = 0;
            }

            if (value2 && !values2) {
                values2 = new CSSValueListImpl();
                values2->append(value2);
                value2 = 0;
            }

            if (values)
                values->append(currValue);
            else
                value = currValue;
            if (currValue2) {
                if (values2)
                    values2->append(currValue2);
                else
                    value2 = currValue2;
            }
            allowComma = true;
        }

        // When parsing the 'background' shorthand property, we let it handle building up the lists for all
        // properties.
        if (inParseShortHand)
            break;
    }

    if (values && values->length()) {
        retValue1 = values;
        if (values2 && values2->length())
            retValue2 = values2;
        return true;
    }
    if (value) {
        retValue1 = value;
        retValue2 = value2;
        return true;
    }

failed:
    delete values; delete values2;
    delete value; delete value2;
    return false;
}

#define DASHBOARD_REGION_NUM_PARAMETERS  6
#define DASHBOARD_REGION_SHORT_NUM_PARAMETERS  2

static Value *skipCommaInDashboardRegion (ValueList *args)
{
    if ( args->numValues == (DASHBOARD_REGION_NUM_PARAMETERS*2-1) ||
         args->numValues == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
        Value *current = args->current();
        if (current->unit == Value::Operator && current->iValue == ',' )
            return args->next();
    }
    return args->current();
}

#if APPLE_CHANGES
bool CSSParser::parseDashboardRegions( int propId, bool important )
{
    bool valid = true;

    Value *value = valueList->current();

    if (value->id == CSS_VAL_NONE) {
        addProperty( propId, new CSSPrimitiveValueImpl( value->id ), important );
        return valid;
    }

    DashboardRegionImpl *firstRegion = new DashboardRegionImpl(), *region = 0;

    while (value) {
        if (region == 0) {
            region = firstRegion;
        }
        else {
            DashboardRegionImpl *nextRegion = new DashboardRegionImpl();
            region->setNext (nextRegion);
            region = nextRegion;
        }

        if ( value->unit != Value::Function) {
            valid = false;
            break;
        }

        // Commas count as values, so allow:
        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
        // also allow
        // dashboard-region(label, type) or dashboard-region(label type)
        // dashboard-region(label, type) or dashboard-region(label type)
        ValueList *args = value->function->args;
        int numArgs = value->function->args->numValues;
        if ((numArgs != DASHBOARD_REGION_NUM_PARAMETERS && numArgs != (DASHBOARD_REGION_NUM_PARAMETERS*2-1)) &&
            (numArgs != DASHBOARD_REGION_SHORT_NUM_PARAMETERS && numArgs != (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1))){
            valid = false;
            break;
        }

        QString fname = qString( value->function->name ).lower();
        if (fname != "dashboard-region(" ) {
            valid = false;
            break;
        }

        // First arg is a label.
        Value *arg = args->current();
        if (arg->unit != CSSPrimitiveValue::CSS_IDENT) {
            valid = false;
            break;
        }

        region->m_label = qString(arg->string);

        // Second arg is a type.
        arg = args->next();
        arg = skipCommaInDashboardRegion (args);
        if (arg->unit != CSSPrimitiveValue::CSS_IDENT) {
            valid = false;
            break;
        }

        QString geometryType = qString(arg->string).lower();
        if (geometryType == "circle")
      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -