How is the bgcolor property being calculated?
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
Why does HTML think"chucknorris" is a color?
如何计算
当我使用以下HTML代码时…
1 | <body bgcolor="#Deine Mutter hat eine Farbe und die ist grün."></body> |
…我得到的是以下颜色。
顺便说一下:当我尝试在CSS中使用它时,它将不起作用,将应用标准颜色:
1 2 3 | body{ color: #IchwillGOLD; } |
为什么?
我的第一次尝试是一个关于错误的小尝试,虽然我发现了一些有趣的系统属性,但还不足以形成一个答案。接下来,我把注意力转向了标准。我之所以相信这个标准是因为我在三个不同的浏览器上测试了它,实际上它们都做了相同的事情。根据标准,我发现会发生什么:
这样,你会看到你得到了
HTML5标准更准确地描述了这个过程,并在这里实际描述了更多的几个案例:http://www.w3.org/tr/html5/common microsyntaxes.html colors under the"Rules for Parsing a Legacy Color Value"
正如我在注释中所说,htmlparser将它作为一个css属性添加,正如Jasper已经回答过的那样,它是按规格划分的。
实施
webkit解析html parser.cpp中的HTML,如果解析器是inbody,则在htmlbodyelement.cpp中将bgcolor属性添加为csscolor。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Color parsing that matches HTML's"rules for parsing a legacy color value" void HTMLElement::addHTMLColorToStyle(StylePropertySet* style, CSSPropertyID propertyID, const String& attributeValue) { // An empty string doesn't apply a color. (One containing only whitespace does, which is why this check occurs before stripping.) if (attributeValue.isEmpty()) return; String colorString = attributeValue.stripWhiteSpace(); //"transparent" doesn't apply a color either. if (equalIgnoringCase(colorString,"transparent")) return; // If the string is a named CSS color or a 3/6-digit hex color, use that. Color parsedColor(colorString); if (!parsedColor.isValid()) parsedColor.setRGB(parseColorStringWithCrazyLegacyRules(colorString)); style->setProperty(propertyID, cssValuePool().createColorValue(parsedColor.rgb())); } |
你很有可能以这种方法结束:
1 | static RGBA32 parseColorStringWithCrazyLegacyRules(const String& colorString) |
我认为它支持这样的传统颜色:body bgcolor=ff0000(mozilla gecko测试)。
webkit/htmlelement.cpp的代码:parseColorStringWithCrazylegacyRules:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | static RGBA32 parseColorStringWithCrazyLegacyRules(const String& colorString) { // Per spec, only look at the first 128 digits of the string. const size_t maxColorLength = 128; // We'll pad the buffer with two extra 0s later, so reserve two more than the max. Vector<char, maxColorLength+2> digitBuffer; size_t i = 0; // Skip a leading #. if (colorString[0] == '#') i = 1; // Grab the first 128 characters, replacing non-hex characters with 0. // Non-BMP characters are replaced with"00" due to them appearing as two"characters" in the String. for (; i < colorString.length() && digitBuffer.size() < maxColorLength; i++) { if (!isASCIIHexDigit(colorString[i])) digitBuffer.append('0'); else digitBuffer.append(colorString[i]); } if (!digitBuffer.size()) return Color::black; // Pad the buffer out to at least the next multiple of three in size. digitBuffer.append('0'); digitBuffer.append('0'); if (digitBuffer.size() < 6) return makeRGB(toASCIIHexValue(digitBuffer[0]), toASCIIHexValue(digitBuffer[1]), toASCIIHexValue(digitBuffer[2])); // Split the digits into three components, then search the last 8 digits of each component. ASSERT(digitBuffer.size() >= 6); size_t componentLength = digitBuffer.size() / 3; size_t componentSearchWindowLength = min<size_t>(componentLength, 8); size_t redIndex = componentLength - componentSearchWindowLength; size_t greenIndex = componentLength * 2 - componentSearchWindowLength; size_t blueIndex = componentLength * 3 - componentSearchWindowLength; // Skip digits until one of them is non-zero, // or we've only got two digits left in the component. while (digitBuffer[redIndex] == '0' && digitBuffer[greenIndex] == '0' && digitBuffer[blueIndex] == '0' && (componentLength - redIndex) > 2) { redIndex++; greenIndex++; blueIndex++; } ASSERT(redIndex + 1 < componentLength); ASSERT(greenIndex >= componentLength); ASSERT(greenIndex + 1 < componentLength * 2); ASSERT(blueIndex >= componentLength * 2); ASSERT(blueIndex + 1 < digitBuffer.size()); int redValue = toASCIIHexValue(digitBuffer[redIndex], digitBuffer[redIndex + 1]); int greenValue = toASCIIHexValue(digitBuffer[greenIndex], digitBuffer[greenIndex + 1]); int blueValue = toASCIIHexValue(digitBuffer[blueIndex], digitBuffer[blueIndex + 1]); return makeRGB(redValue, greenValue, blueValue); } |