如何计算bgcolor属性?
可能重复:
为什么HTML认为“chucknorris”是一种颜色?
如何计算bgcolor
属性?
当我使用下面的HTML代码…
<body bgcolor="#Deine Mutter hat eine Farbe und die ist grün."></body>
…我得到的是以下颜色。
顺便说一句:当我尝试在CSS中使用它,它不会工作,并将应用标准的颜色:
body{ color: #IchwillGOLD; }
为什么?
我的第一个尝试是错误的一个小试验,虽然我发现系统有一些有趣的属性,但还不足以形成答案。 接下来,我把注意力转向标准。 我相信这是标准的原因是我testing了三个不同的浏览器,他们实际上都做了同样的事情。 使用标准我发现了什么发生:
- 所有不是hex的字符都被replace为零(因此只有零,1-9和ae保留)
- 该string在零末尾填充为三的倍数
- string然后分成三个相等的部分,每个代表一种颜色
- 如果结果string长度超过8个字符,则取每个string的最后8个字符
- 只要每个string从零开始,第一个字符将从每个string中移除(对于此特定的string不会发生,因为它始于
De
- 前两个字符取自每个string,并转换为一个数字以用作颜色的组成部分之一
这样,你会看到你得到00FA00
Deine Mutter hat eine Farbe und die ist grün.
00FA00
Deine Mutter hat eine Farbe und die ist grün.
00FA00
Deine Mutter hat eine Farbe und die ist grün.
html5标准更准确地描述了这个过程,实际上在这里描述了更多的情况: http : //www.w3.org/TR/html5/common-microsyntax.html#colors “parsing遗留颜色值的规则”
正如我在评论中所述,HTMLParser将其添加为一个CSS属性,并已由Jasper回答,它是由规范。
履行
Webkit分析HTMLParser.cpp中的html,如果parsing器是inBody,则它将bgColor属性添加为HTMLBodyElement.cpp中的CssColor
// 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())); }
你有很好的机会结束这个方法:
static RGBA32 parseColorStringWithCrazyLegacyRules(const String& colorString)
我认为这是支持像这样的传统颜色:body bgcolor = ff0000( Mozilla Gecko Test )。
- 跳过领先#
- 抓住前128个字符,用0.1120replace非hex字符
- 非BMP字符被replace为“00”,因为它们在string中显示为两个“字符”。
- 如果没有数字返回颜色黑色
- 将数字拆分为三个组件,然后search每个组件的最后8位数字。
Webkit / HTMLElement.cpp的代码:parseColorStringWithCrazyLegacyRules :
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); }