📄 cssparser.cpp
字号:
FFrequency = 0x0040,
FRelative = 0x0100,
FNonNeg = 0x0200
};
static bool validUnit( Value *value, int unitflags, bool strict )
{
if ( unitflags & FNonNeg && value->fValue < 0 )
return false;
bool b = false;
switch( value->unit ) {
case CSSPrimitiveValue::CSS_NUMBER:
b = (unitflags & FNumber);
if ( !b && ( (unitflags & FLength) && (value->fValue == 0 || !strict ) ) ) {
value->unit = CSSPrimitiveValue::CSS_PX;
b = true;
}
if ( !b && ( unitflags & FInteger ) &&
(value->fValue - (int)value->fValue) < 0.001 )
b = true;
break;
case CSSPrimitiveValue::CSS_PERCENTAGE:
b = (unitflags & FPercent);
break;
case Value::Q_EMS:
case CSSPrimitiveValue::CSS_EMS:
case CSSPrimitiveValue::CSS_EXS:
case CSSPrimitiveValue::CSS_PX:
case CSSPrimitiveValue::CSS_CM:
case CSSPrimitiveValue::CSS_MM:
case CSSPrimitiveValue::CSS_IN:
case CSSPrimitiveValue::CSS_PT:
case CSSPrimitiveValue::CSS_PC:
b = (unitflags & FLength);
break;
case CSSPrimitiveValue::CSS_MS:
case CSSPrimitiveValue::CSS_S:
b = (unitflags & FTime);
break;
case CSSPrimitiveValue::CSS_DEG:
case CSSPrimitiveValue::CSS_RAD:
case CSSPrimitiveValue::CSS_GRAD:
case CSSPrimitiveValue::CSS_HZ:
case CSSPrimitiveValue::CSS_KHZ:
case CSSPrimitiveValue::CSS_DIMENSION:
default:
break;
}
return b;
}
bool CSSParser::parseValue( int propId, bool important )
{
if ( !valueList ) return false;
Value *value = valueList->current();
if ( !value )
return false;
int id = 0;
id = value->id;
if (id == CSS_VAL_INHERIT) {
addProperty(propId, new CSSInheritedValueImpl(), important);
return true;
}
else if (id == CSS_VAL_INITIAL) {
addProperty(propId, new CSSInitialValueImpl(), important);
return true;
}
bool valid_primitive = false;
CSSValueImpl *parsedValue = 0;
switch(propId) {
/* The comment to the left defines all valid value of this properties as defined
* in CSS 2, Appendix F. Property index
*/
/* All the CSS properties are not supported by the renderer at the moment.
* Note that all the CSS2 Aural properties are only checked, if CSS_AURAL is defined
* (see parseAuralValues). As we don't support them at all this seems reasonable.
*/
case CSS_PROP_SIZE: // <length>{1,2} | auto | portrait | landscape | inherit
case CSS_PROP_QUOTES: // [<string> <string>]+ | none | inherit
// case CSS_PROP_PAGE: // <identifier> | auto // ### CHECK
// ### To be done
if (id)
valid_primitive = true;
break;
case CSS_PROP_UNICODE_BIDI: // normal | embed | bidi-override | inherit
if ( id == CSS_VAL_NORMAL ||
id == CSS_VAL_EMBED ||
id == CSS_VAL_BIDI_OVERRIDE )
valid_primitive = true;
break;
case CSS_PROP_POSITION: // static | relative | absolute | fixed | inherit
if ( id == CSS_VAL_STATIC ||
id == CSS_VAL_RELATIVE ||
id == CSS_VAL_ABSOLUTE ||
id == CSS_VAL_FIXED )
valid_primitive = true;
break;
case CSS_PROP_PAGE_BREAK_AFTER: // auto | always | avoid | left | right | inherit
case CSS_PROP_PAGE_BREAK_BEFORE: // auto | always | avoid | left | right | inherit
if ( id == CSS_VAL_AUTO ||
id == CSS_VAL_ALWAYS ||
id == CSS_VAL_AVOID ||
id == CSS_VAL_LEFT ||
id == CSS_VAL_RIGHT )
valid_primitive = true;
break;
case CSS_PROP_PAGE_BREAK_INSIDE: // avoid | auto | inherit
if ( id == CSS_VAL_AUTO ||
id == CSS_VAL_AVOID )
valid_primitive = true;
break;
case CSS_PROP_EMPTY_CELLS: // show | hide | inherit
if ( id == CSS_VAL_SHOW ||
id == CSS_VAL_HIDE )
valid_primitive = true;
break;
case CSS_PROP_CONTENT: // [ <string> | <uri> | <counter> | attr(X) | open-quote |
// close-quote | no-open-quote | no-close-quote ]+ | inherit
return parseContent( propId, important );
break;
case CSS_PROP_WHITE_SPACE: // normal | pre | nowrap | inherit
if ( id == CSS_VAL_NORMAL ||
id == CSS_VAL_PRE ||
id == CSS_VAL_NOWRAP )
valid_primitive = true;
break;
case CSS_PROP_CLIP: // <shape> | auto | inherit
if ( id == CSS_VAL_AUTO )
valid_primitive = true;
else if ( value->unit == Value::Function )
return parseShape( propId, important );
break;
#if APPLE_CHANGES
case CSS_PROP__APPLE_DASHBOARD_REGION: // <dashboard-region> | <dashboard-region>
if ( value->unit == Value::Function || id == CSS_VAL_NONE)
return parseDashboardRegions( propId, important );
break;
#endif
/* Start of supported CSS properties with validation. This is needed for parseShortHand to work
* correctly and allows optimization in khtml::applyRule(..)
*/
case CSS_PROP_CAPTION_SIDE: // top | bottom | left | right | inherit
if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT ||
id == CSS_VAL_TOP || id == CSS_VAL_BOTTOM)
valid_primitive = true;
break;
case CSS_PROP_BORDER_COLLAPSE: // collapse | separate | inherit
if ( id == CSS_VAL_COLLAPSE || id == CSS_VAL_SEPARATE )
valid_primitive = true;
break;
case CSS_PROP_VISIBILITY: // visible | hidden | collapse | inherit
if (id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_COLLAPSE)
valid_primitive = true;
break;
case CSS_PROP_OVERFLOW: // visible | hidden | scroll | auto | marquee | overlay | inherit
if (id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_SCROLL || id == CSS_VAL_AUTO ||
id == CSS_VAL_MARQUEE || id == CSS_VAL_OVERLAY)
valid_primitive = true;
break;
case CSS_PROP_LIST_STYLE_POSITION: // inside | outside | inherit
if ( id == CSS_VAL_INSIDE || id == CSS_VAL_OUTSIDE )
valid_primitive = true;
break;
case CSS_PROP_LIST_STYLE_TYPE:
// disc | circle | square | decimal | decimal-leading-zero | lower-roman |
// upper-roman | lower-greek | lower-alpha | lower-latin | upper-alpha |
// upper-latin | hebrew | armenian | georgian | cjk-ideographic | hiragana |
// katakana | hiragana-iroha | katakana-iroha | none | inherit
if ((id >= CSS_VAL_DISC && id <= CSS_VAL_KATAKANA_IROHA) || id == CSS_VAL_NONE)
valid_primitive = true;
break;
case CSS_PROP_DISPLAY:
// inline | block | list-item | run-in | inline-block | table |
// inline-table | table-row-group | table-header-group | table-footer-group | table-row |
// table-column-group | table-column | table-cell | table-caption | box | inline-box | none | inherit
if ((id >= CSS_VAL_INLINE && id <= CSS_VAL__KHTML_INLINE_BOX) || id == CSS_VAL_NONE)
valid_primitive = true;
break;
case CSS_PROP_DIRECTION: // ltr | rtl | inherit
if ( id == CSS_VAL_LTR || id == CSS_VAL_RTL )
valid_primitive = true;
break;
case CSS_PROP_TEXT_TRANSFORM: // capitalize | uppercase | lowercase | none | inherit
if ((id >= CSS_VAL_CAPITALIZE && id <= CSS_VAL_LOWERCASE) || id == CSS_VAL_NONE)
valid_primitive = true;
break;
case CSS_PROP_FLOAT: // left | right | none | inherit + center for buggy CSS
if ( id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT ||
id == CSS_VAL_NONE || id == CSS_VAL_CENTER)
valid_primitive = true;
break;
case CSS_PROP_CLEAR: // none | left | right | both | inherit
if ( id == CSS_VAL_NONE || id == CSS_VAL_LEFT ||
id == CSS_VAL_RIGHT|| id == CSS_VAL_BOTH)
valid_primitive = true;
break;
case CSS_PROP_TEXT_ALIGN:
// left | right | center | justify | khtml_left | khtml_right | khtml_center | <string> | inherit
if ( ( id >= CSS_VAL__KHTML_AUTO && id <= CSS_VAL__KHTML_CENTER ) ||
value->unit == CSSPrimitiveValue::CSS_STRING )
valid_primitive = true;
break;
case CSS_PROP_OUTLINE_STYLE: // <border-style> | auto | inherit
if (id == CSS_VAL_AUTO) {
valid_primitive = true;
break;
} // Fall through!
case CSS_PROP_BORDER_TOP_STYLE: //// <border-style> | inherit
case CSS_PROP_BORDER_RIGHT_STYLE: // Defined as: none | hidden | dotted | dashed |
case CSS_PROP_BORDER_BOTTOM_STYLE: // solid | double | groove | ridge | inset | outset
case CSS_PROP_BORDER_LEFT_STYLE: ////
if (id >= CSS_VAL_NONE && id <= CSS_VAL_DOUBLE)
valid_primitive = true;
break;
case CSS_PROP_FONT_WEIGHT: // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 |
// 500 | 600 | 700 | 800 | 900 | inherit
if (id >= CSS_VAL_NORMAL && id <= CSS_VAL_900) {
// Allready correct id
valid_primitive = true;
} else if ( validUnit( value, FInteger|FNonNeg, false ) ) {
int weight = (int)value->fValue;
if ( (weight % 100) )
break;
weight /= 100;
if ( weight >= 1 && weight <= 9 ) {
id = CSS_VAL_100 + weight - 1;
valid_primitive = true;
}
}
break;
case CSS_PROP_BORDER_SPACING: {
const int properties[2] = { CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING,
CSS_PROP__KHTML_BORDER_VERTICAL_SPACING };
int num = valueList->numValues;
if (num == 1) {
if (!parseValue(properties[0], important)) return false;
CSSValueImpl* value = parsedProperties[numParsedProperties-1]->value();
addProperty(properties[1], value, important);
return true;
}
else if (num == 2) {
if (!parseValue(properties[0], important)) return false;
if (!parseValue(properties[1], important)) return false;
return true;
}
return false;
}
case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING:
case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING:
valid_primitive = validUnit(value, FLength|FNonNeg, strict);
break;
case CSS_PROP_SCROLLBAR_FACE_COLOR: // IE5.5
case CSS_PROP_SCROLLBAR_SHADOW_COLOR: // IE5.5
case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR: // IE5.5
case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR: // IE5.5
case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR: // IE5.5
case CSS_PROP_SCROLLBAR_TRACK_COLOR: // IE5.5
case CSS_PROP_SCROLLBAR_ARROW_COLOR: // IE5.5
if ( strict )
break;
/* nobreak */
case CSS_PROP_OUTLINE_COLOR: // <color> | invert | inherit
// outline has "invert" as additional keyword.
if ( propId == CSS_PROP_OUTLINE_COLOR && id == CSS_VAL_INVERT ) {
valid_primitive = true;
break;
}
/* nobreak */
case CSS_PROP_BACKGROUND_COLOR: // <color> | inherit
case CSS_PROP_BORDER_TOP_COLOR: // <color> | inherit
case CSS_PROP_BORDER_RIGHT_COLOR: // <color> | inherit
case CSS_PROP_BORDER_BOTTOM_COLOR: // <color> | inherit
case CSS_PROP_BORDER_LEFT_COLOR: // <color> | inherit
case CSS_PROP_COLOR: // <color> | inherit
case CSS_PROP_TEXT_LINE_THROUGH_COLOR: // CSS3 text decoration colors
case CSS_PROP_TEXT_UNDERLINE_COLOR:
case CSS_PROP_TEXT_OVERLINE_COLOR:
if (id == CSS_VAL__KHTML_TEXT)
valid_primitive = true; // Always allow this, even when strict parsing is on,
// since we use this in our UA sheets.
else if ( id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT || id == CSS_VAL_MENU ||
(id >= CSS_VAL_GREY && id < CSS_VAL__KHTML_TEXT && !strict) ) {
valid_primitive = true;
} else {
parsedValue = parseColor();
if ( parsedValue )
valueList->next();
}
break;
case CSS_PROP_CURSOR:
// [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
// nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | text |
// wait | help ] ] | inherit
// MSIE 5 compatibility :/
if ( !strict && id == CSS_VAL_HAND ) {
id = CSS_VAL_POINTER;
valid_primitive = true;
} else if ( id >= CSS_VAL_AUTO && id <= CSS_VAL_HELP )
valid_primitive = true;
break;
case CSS_PROP_BACKGROUND_ATTACHMENT:
case CSS_PROP_BACKGROUND_IMAGE:
case CSS_PROP_BACKGROUND_POSITION:
case CSS_PROP_BACKGROUND_POSITION_X:
case CSS_PROP_BACKGROUND_POSITION_Y:
case CSS_PROP_BACKGROUND_REPEAT: {
CSSValueImpl *val1 = 0, *val2 = 0;
int propId1, propId2;
if (parseBackgroundProperty(propId, propId1, propId2, val1, val2)) {
addProperty(propId1, val1, important);
if (val2)
addProperty(propId2, val2, important);
return true;
}
return false;
}
case CSS_PROP_LIST_STYLE_IMAGE: // <uri> | none | inherit
if (id == CSS_VAL_NONE) {
parsedValue = new CSSImageValueImpl();
valueList->next();
}
else if (value->unit == CSSPrimitiveValue::CSS_URI) {
// ### allow string in non strict mode?
DOMString uri = khtml::parseURL( domString( value->string ) );
if (!uri.isEmpty()) {
parsedValue = new CSSImageValueImpl(
DOMString(KURL( styleElement->baseURL().string(), uri.string()).url()),
styleElement);
valueList->next();
}
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -