プロパティはどのようにbgcolor
計算されますか?
次のhtmlコードを使用すると...
<body bgcolor="#Deine Mutter hat eine Farbe und die ist grün."></body>
...私が得るのは次の色です。
ところで: CSS で使用しようとすると、機能せず、標準の色が適用されます。
body{
color: #IchwillGOLD;
}
なんで?
プロパティはどのようにbgcolor
計算されますか?
次のhtmlコードを使用すると...
<body bgcolor="#Deine Mutter hat eine Farbe und die ist grün."></body>
...私が得るのは次の色です。
ところで: CSS で使用しようとすると、機能せず、標準の色が適用されます。
body{
color: #IchwillGOLD;
}
なんで?
これに対する私の最初の試みは、エラーに関する小さな試行であり、システムのいくつかの興味深い特性を見つけましたが、答えを形成するには十分ではありませんでした. 次に注目したのはスタンダード。これが標準であると私が信じた理由は、3 つの異なるブラウザーでテストしたところ、実際にはすべて同じことをしたからです。標準を使用して、何が起こるかを知りました:
De
00FA00
このようにして、あなたはあなたが得るのを見るでしょうDeine Mutter hat eine Farbe und die ist grün.
html5 標準ではプロセスがより正確に説明されており、実際にはここでさらにいくつかのケースが説明されています。
コメントで述べたように、HTMLParserはそれをCSSプロパティとして追加し、Jasperによってすでに回答されているように、それは仕様によるものです。
実装
WebkitはHTMLParser.cppのhtmlを解析し、パーサーが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)。
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);
}