Kodėl HTML mano, kad "chucknorris" yra spalva?

Kaip tam tikros atsitiktinės eilutės sukuria spalvas, kai įvestos kaip HTML fono spalvos? Pavyzdžiui:

<body bgcolor="chucknorris"> test </body>

...sukuria dokumentą su raudonu fonu visose naršyklėse ir platformose.

Įdomu tai, kad chucknorri taip pat sukuria raudoną foną, o chucknorr - geltoną.

Kas čia vyksta?

Sprendimas

Tai "Netscape" laikų atgyvena:

Trūkstami skaitmenys laikomi 0[...]. Neteisingas skaitmuo paprasčiausiai interpretuojamas kaip 0. Pavyzdžiui, reikšmės #F0F0F0F0, F0F0F0F0, F0F0F0F, #FxFxFx ir FxFxFx yra vienodos.

Jis paimtas iš tinklaraščio įrašo A little rant about Microsoft Internet Explorer's color parsing, kuriame apie tai rašoma labai išsamiai, įskaitant skirtingus spalvų reikšmių ilgius ir t. t.

Jei paeiliui taikysime tinklaraščio įraše pateiktas taisykles, gausime šiuos rezultatus:

  1. Pakeiskite visus netinkamus šešioliktainius simbolius 0's

    chucknorris tampa c00c0000000
  2. Padidinkite iki kito bendro ženklų skaičiaus, kuris dalijasi iš 3 (11 -> 12)

    c00c 0000 0000 0000
  3. Suskirstykite į tris lygias grupes, kurių kiekvienas komponentas atitinka atitinkamą RGB spalvos komponentą:

    RGB (c00c, 0000, 0000, 0000)
  4. Kiekvieną argumentą iš dešinės sutrumpinkite iki dviejų ženklų

Gaunamas toks rezultatas:

RGB (c0, 00, 00) = #C00000 or RGB(192, 0, 0)

Štai pavyzdys, kuriame demonstruojamas bgcolor atributo veikimas, siekiant sukurti šį "nuostabų" spalvų pavyzdį:

<table>
  <tr>
    <td bgcolor="chucknorris" cellpadding="8" width="100" align="center">chuck norris</td>
    <td bgcolor="mrt"         cellpadding="8" width="100" align="center" style="color:#ffffff">Mr T</td>
    <td bgcolor="ninjaturtle" cellpadding="8" width="100" align="center" style="color:#ffffff">ninjaturtle</td>
  </tr>
  <tr>
    <td bgcolor="sick"  cellpadding="8" width="100" align="center">sick</td>
    <td bgcolor="crap"  cellpadding="8" width="100" align="center">crap</td>
    <td bgcolor="grass" cellpadding="8" width="100" align="center">grass</td>
  </tr>
</table>

Tai taip pat atsako į kitą klausimo dalį; kodėl bgcolor="chucknorr" sukuria geltoną spalvą? Na, jei taikysime taisykles, eilutė yra:

c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]

Tai suteikia šviesiai geltoną aukso spalvą. Kadangi eilutė prasideda nuo 9 simbolių, šį kartą paliekame antrąją raidę C, todėl ji patenka į galutinę spalvos reikšmę.

Iš pradžių su tuo susidūriau, kai kažkas atkreipė dėmesį, kad galima atlikti color="crap" ir, na, išeina ruda spalva.

Komentarai (15)

Dauguma naršyklių paprasčiausiai ignoruos bet kokias spalvinėje eilutėje esančias NEhex reikšmes, o nehex skaitmenis pakeis nuliais.

ChuCknorris verčiama į c00c0000000. Šiuo metu naršyklė padalys eilutę į tris lygias dalis, nurodydama Raudoną, Žalią ir Mėlyną reikšmes: c00c 0000 0000. Į papildomus kiekvienos sekcijos bitus nebus atsižvelgiama, todėl galutinis rezultatas bus #c00000, t. y. rausva spalva.

Atkreipkite dėmesį, kad tai netaikoma CSS spalvų analizei, kuri atitinka CSS standartą.

<p>Redish</p>
<p>Same as above</p>
<p><span style="color: chucknorris">Black</span></p>
Komentarai (4)

WHATWG HTML specifikacijoje pateikiamas tikslus senosios spalvos vertės analizės algoritmas: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

Kodas, kurį "Netscape Classic" naudojo spalvų eilutėms analizuoti, yra atviro kodo: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

Pavyzdžiui, atkreipkite dėmesį, kad kiekvienas simbolis analizuojamas kaip šešioliktainis skaitmuo ir tada perkeliamas į 32 bitų sveikąjį skaičių netikrinant, ar nėra perpildymo. Tik aštuoni šešiaženkliai skaitmenys telpa į 32 bitų sveikąjį skaičių, todėl atsižvelgiama tik į 8 paskutinius simbolius. Po šešiaženklių skaitmenų išskaidymo į 32 bitų sveikuosius skaičius jie sutrumpinami į 8 bitų sveikuosius skaičius, dalijant juos iš 16, kol jie telpa į 8 bitus, todėl pradiniai nuliai ignoruojami.

Atnaujinimas: šis kodas ne visai atitinka specifikacijoje apibrėžtą kodą, tačiau skiriasi tik kelios kodo eilutės. Manau, kad būtent šios eilutės buvo pridėtos (į "Netscape 4"):

if (bytes_per_val > 4)
{
      bytes_per_val = 4;
}
Komentarai (0)