如何计算bgcolor属性? [重复]

时间:2022-09-06 20:25:08

Possible Duplicate:
Why does HTML think “chucknorris” is a color?

可能重复:为什么HTML认为“chucknorris”是一种颜色?

How is the bgcolor property calculated?

如何计算bgcolor属性?

When i use the following html code...

当我使用以下HTML代码时......

<body bgcolor="#Deine Mutter hat eine Farbe und die ist grün."></body>

...what I get is the following color.

...我得到的是以下颜色。

如何计算bgcolor属性? [重复]

By the way: When I try to use it in CSS it won´t work and will apply the standard color:

顺便说一句:当我尝试在CSS中使用它时它不会工作并将应用标准颜色:

body{
    color: #IchwillGOLD;
}

Why?

为什么?

2 个解决方案

#1


17  

My first try on this was a little trial on error and while I found some interesting properties of the system, it wasn't quite enough to form an answer. Next, I turned my attention to the standard. The reason that I believed this to be in the standard was that I tested it on three different browsers and they actually all did the same thing. Using the standard I found out what happens:

我第一次尝试这是一个关于错误的小试验,虽然我发现了一些有趣的系统属性,但还不足以形成答案。接下来,我把注意力转向标准。我认为这是标准的原因是我在三种不同的浏览器上测试它们实际上都做了同样的事情。使用标准我发现了会发生什么:

  1. All characters that aren't hexadecimal are replaced by zeroes (so only zeroes, 1-9 and a-e remain)
  2. 所有非十六进制的字符都被零替换(因此只有零,1-9和a-e保留)
  3. The string is zero padded at the end to be a multiple of three
  4. 该字符串在末尾为零填充为三的倍数
  5. The string is then divided up in three equal parts, each representing a color
  6. 然后将该字符串分成三个相等的部分,每个部分代表一种颜色
  7. If the resulting strings are longer than 8 characters, take the last 8 characters of each string
  8. 如果结果字符串超过8个字符,请取每个字符串的最后8个字符
  9. As long as each of the strings starts with a zero, the first character is removed from each string (not happening for this particular string since it starts with De
  10. 只要每个字符串以零开头,就会从每个字符串中删除第一个字符(因为它以De开头,因此不会发生此特定字符串
  11. The first two characters are taken from each of those strings and converted to a number for use as one of the components of the color
  12. 前两个字符取自每个字符串并转换为数字,用作颜色的一个组成部分

This way you'll see you get 00FA00 for Deine Mutter hat eine Farbe und die ist grün.

通过这种方式,你会看到你获得00FA00的Deine Mutter帽子eine Farbe和dieistgrün。

The html5 standard describes the process more precisely and actually describes a couple more cases here: http://www.w3.org/TR/html5/common-microsyntaxes.html#colors under the "rules for parsing a legacy color value"

html5标准更准确地描述了这个过程,实际上在这里描述了几个案例:http://www.w3.org/TR/html5/common-microsyntaxes.html#colors在“解析遗留颜色值的规则”下

#2


8  

As i stated in the Comments, the HTMLParser adds it as a CSS Property, and as already answered by Jasper, it is by Specification.

正如我在评论中所说,HTMLParser将其添加为CSS属性,并且已经由Jasper回答,它是由规范。

Implementation

履行

Webkit parses the html in HTMLParser.cpp and if the Parser is inBody it adds the bgColor Attribute as CssColor in HTMLBodyElement.cpp

Webkit解析HTMLParser.cpp中的html,如果Parser是inBody,它会在HTMLBodyElement.cpp中将bgColor属性添加为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()));
}

You have good chances to end in this method:

你有很好的机会以这种方式结束:

static RGBA32 parseColorStringWithCrazyLegacyRules(const String& colorString)

I think it is to support legacy Colors like this : body bgcolor=ff0000 ( Mozilla Gecko Test ).

我认为这是支持传统的颜色:body bgcolor = ff0000(Mozilla Gecko Test)。

  1. Skip a leading #
  2. 跳过领先#
  3. Grab the first 128 characters, replacing non-hex characters with 0. 1120
  4. 抓取前128个字符,用0. 1120替换非十六进制字符
  5. Non-BMP characters are replaced with "00" due to them appearing as two "characters" in the String.
  6. 非BMP字符替换为“00”,因为它们在字符串中显示为两个“字符”。
  7. If no digits return Color black
  8. 如果没有数字返回颜色黑色
  9. Split the digits into three components, then search the last 8 digits of each component.
  10. 将数字拆分为三个组件,然后搜索每个组件的最后8位数。

Code of Webkit/HTMLElement.cpp:parseColorStringWithCrazyLegacyRules:

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);
}

#1


17  

My first try on this was a little trial on error and while I found some interesting properties of the system, it wasn't quite enough to form an answer. Next, I turned my attention to the standard. The reason that I believed this to be in the standard was that I tested it on three different browsers and they actually all did the same thing. Using the standard I found out what happens:

我第一次尝试这是一个关于错误的小试验,虽然我发现了一些有趣的系统属性,但还不足以形成答案。接下来,我把注意力转向标准。我认为这是标准的原因是我在三种不同的浏览器上测试它们实际上都做了同样的事情。使用标准我发现了会发生什么:

  1. All characters that aren't hexadecimal are replaced by zeroes (so only zeroes, 1-9 and a-e remain)
  2. 所有非十六进制的字符都被零替换(因此只有零,1-9和a-e保留)
  3. The string is zero padded at the end to be a multiple of three
  4. 该字符串在末尾为零填充为三的倍数
  5. The string is then divided up in three equal parts, each representing a color
  6. 然后将该字符串分成三个相等的部分,每个部分代表一种颜色
  7. If the resulting strings are longer than 8 characters, take the last 8 characters of each string
  8. 如果结果字符串超过8个字符,请取每个字符串的最后8个字符
  9. As long as each of the strings starts with a zero, the first character is removed from each string (not happening for this particular string since it starts with De
  10. 只要每个字符串以零开头,就会从每个字符串中删除第一个字符(因为它以De开头,因此不会发生此特定字符串
  11. The first two characters are taken from each of those strings and converted to a number for use as one of the components of the color
  12. 前两个字符取自每个字符串并转换为数字,用作颜色的一个组成部分

This way you'll see you get 00FA00 for Deine Mutter hat eine Farbe und die ist grün.

通过这种方式,你会看到你获得00FA00的Deine Mutter帽子eine Farbe和dieistgrün。

The html5 standard describes the process more precisely and actually describes a couple more cases here: http://www.w3.org/TR/html5/common-microsyntaxes.html#colors under the "rules for parsing a legacy color value"

html5标准更准确地描述了这个过程,实际上在这里描述了几个案例:http://www.w3.org/TR/html5/common-microsyntaxes.html#colors在“解析遗留颜色值的规则”下

#2


8  

As i stated in the Comments, the HTMLParser adds it as a CSS Property, and as already answered by Jasper, it is by Specification.

正如我在评论中所说,HTMLParser将其添加为CSS属性,并且已经由Jasper回答,它是由规范。

Implementation

履行

Webkit parses the html in HTMLParser.cpp and if the Parser is inBody it adds the bgColor Attribute as CssColor in HTMLBodyElement.cpp

Webkit解析HTMLParser.cpp中的html,如果Parser是inBody,它会在HTMLBodyElement.cpp中将bgColor属性添加为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()));
}

You have good chances to end in this method:

你有很好的机会以这种方式结束:

static RGBA32 parseColorStringWithCrazyLegacyRules(const String& colorString)

I think it is to support legacy Colors like this : body bgcolor=ff0000 ( Mozilla Gecko Test ).

我认为这是支持传统的颜色:body bgcolor = ff0000(Mozilla Gecko Test)。

  1. Skip a leading #
  2. 跳过领先#
  3. Grab the first 128 characters, replacing non-hex characters with 0. 1120
  4. 抓取前128个字符,用0. 1120替换非十六进制字符
  5. Non-BMP characters are replaced with "00" due to them appearing as two "characters" in the String.
  6. 非BMP字符替换为“00”,因为它们在字符串中显示为两个“字符”。
  7. If no digits return Color black
  8. 如果没有数字返回颜色黑色
  9. Split the digits into three components, then search the last 8 digits of each component.
  10. 将数字拆分为三个组件,然后搜索每个组件的最后8位数。

Code of Webkit/HTMLElement.cpp:parseColorStringWithCrazyLegacyRules:

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);
}