PRInt32 found = ParseChoice(aErrorCode, values, aPropIDs, numProps);
4117 PRInt32 CSSParserImpl::ParseChoice(nsresult aErrorCode, nsCSSValue aValues[],
4118 const nsCSSProperty aPropIDs[], PRInt32 aNumIDs)
4119 {
4120 PRInt32 found = 0;
4121 nsAutoParseCompoundProperty compound(this);
4122
4123 PRInt32 loop;
4124 for (loop = 0; loop &< aNumIDs; loop++) {
4125 // Try each property parser in order
4126 PRInt32 hadFound = found;
4127 PRInt32 index;
4128 for (index = 0; index &< aNumIDs; index++) {
4129 PRInt32 bit = 1 &<&< index;
4130 if ((found bit) == 0) {
4131 if (ParseSingleValueProperty(aErrorCode, aValues[index], aPropIDs[index])) {
4132 found |= bit;
4133 }
4134 }
4135 }
4136 if (found == hadFound) { // found nothing new
4137 break;
4138 }
4139 }
事到如今很明顯了,就是遍歷每種可能值的類型(比如 border 的情況就是依次嘗試 width、style、color),嘗試匹配讀到的每一個值(看到兩個 for loop 是不是有種微醺的感覺哈哈哈哈)。
我們再看看 ParseSingleValueProperty 的實現:
4637 case eCSSProperty_border_bottom_color:
4638 case eCSSProperty_border_end_color_value: // for internal use
4639 case eCSSProperty_border_left_color_value: // for internal use
4640 case eCSSProperty_border_right_color_value: // for internal use
4641 case eCSSProperty_border_start_color_value: // for internal use
4642 case eCSSProperty_border_top_color:
4643 return ParseVariant(aErrorCode, aValue, VARIANT_HCK,
4644 nsCSSProps::kBorderColorKTable);
4645 case eCSSProperty_border_bottom_style:
4646 case eCSSProperty_border_end_style_value: // for internal use
4647 case eCSSProperty_border_left_style_value: // for internal use
4648 case eCSSProperty_border_right_style_value: // for internal use
4649 case eCSSProperty_border_start_style_value: // for internal use
4650 case eCSSProperty_border_top_style:
4651 return ParseVariant(aErrorCode, aValue, VARIANT_HOK,
4652 nsCSSProps::kBorderStyleKTable);
4653 case eCSSProperty_border_bottom_width:
4654 case eCSSProperty_border_end_width_value: // for internal use
4655 case eCSSProperty_border_left_width_value: // for internal use
4656 case eCSSProperty_border_right_width_value: // for internal use
4657 case eCSSProperty_border_start_width_value: // for internal use
4658 case eCSSProperty_border_top_width:
4659 return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HKL,
4660 nsCSSProps::kBorderWidthKTable);
Note that order is important within each animation definition: the first value in each & that can be parsed as a & is assigned to the animation-duration, and the second value in each & that can be parsed as a & is assigned to animation-delay.