Подтвердить что ты не робот

Как вычисляется свойство bgcolor?

Возможный дубликат:
Почему HTML считает, что "chucknorris" - это цвет?

Как вычисляется свойство bgcolor?

Когда я использую следующий код html...

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

... я получаю следующий цвет.

#Deine Mutter hat eine Farbe und die ist grün.

Кстати: когда я пытаюсь использовать его в CSS, он не будет работать и будет применять стандартный цвет:

body{
    color: #IchwillGOLD;
}

Почему?

4b9b3361

Ответ 1

Моя первая попытка в этом была небольшим испытанием по ошибке, и, хотя я нашел некоторые интересные свойства системы, было недостаточно, чтобы сформировать ответ. Затем я обратил внимание на стандарт. Причина, по которой я полагал, что это стандарт, заключалась в том, что я тестировал ее на трех разных браузерах, и на самом деле все они делали то же самое. Используя стандарт, я узнал, что происходит:

  • Все символы, которые не являются шестнадцатеричными, заменяются нулями (поэтому остаются только нули, 1-9 и a-e)
  • Строка нулевая, заполненная в конце, кратна трем
  • Затем строка делится на три равные части, каждая из которых представляет цвет
  • Если результирующие строки длиннее 8 символов, возьмите последние 8 символов каждой строки
  • Пока каждая из строк начинается с нуля, первый символ удаляется из каждой строки (не происходит для этой конкретной строки, так как она начинается с De
  • Первые два символа берутся из каждой из этих строк и преобразуются в число для использования в качестве одного из компонентов цвета

Таким образом вы увидите, что вы получаете 00FA00 для Deine Mutter hat eine Farbe und die ist grün.

Стандарт html5 описывает процесс более точно и фактически описывает еще пару случаев: http://www.w3.org/TR/html5/common-microsyntaxes.html#colors в разделе "правила для анализа наследия цветное значение"

Ответ 2

Как указано в комментариях, HTMLParser добавляет его как свойство CSS, и, как уже ответил Джаспер, это по спецификации.

Реализация

Webkit анализирует html в HTMLParser.cpp, и если Parser inBody, он добавляет атрибут bgColor как CssColor в HTMLBodyElement.cpp

// Color parsing that matches HTML "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).

  • Пропустить ведущую #
  • Возьмите первые 128 символов, заменив шестнадцатеричные символы на 0. 1120
  • Символы, отличные от BMP, заменяются символом "00" из-за их появления в строке "два символа".
  • Если цифры не возвращаются Цвет черный
  • Разделите цифры на три компонента, затем найдите последние 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);
}