Autor Zpráva
Jan Tvrdík
Profil
Demonstrační kód (posílaný s mime type application/xhtml+xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs">
	<head><title>Titulek</title></head>
	<body>
		<p>
			<textarea id="box" rows="10" cols="50">&copy;</textarea>
		</p>
		<script type="text/javascript">
		<![CDATA[
		var box = document.getElementById("box");
		var entity = new Array('amp','nbsp','gt','lt','copy','scaron');
		var entita;
		var funkcni = new Array();
		var nefunkcni = new Array();
		
		for(var i = 0; i < entity.length; i++)
		{
			try
			{
				entita = "&" + entity[i] + ";";
				box.innerHTML = entita;
				funkcni.push(entita);
			}
			catch(e)
			{
				nefunkcni.push(entita);
			}
		}
		
		box.innerHTML = "";
		box.appendChild(document.createTextNode("Funkční entity: \n" + funkcni.join(' ') + "\n\nNefunkční entity: \n" + nefunkcni.join(' ')));

		]]>
		</script>
	</body>
</html>


Proč ve firefoxu velká část entit nefunguje? Jak je zapsat, aby fungovali? Pokud jsou zapsány přímo do textarei, tak fungují všechny.


Pozn.: Na problém jsem narazil, když jsem se pokusi integrovat Texylu do webu, který používá "skutečné XHTML".
Chamurappi
Profil
Reaguji na Jana Tvrdíka:
Vskutku krásný problém.

XML definuje jen pět základních entit: „amp“, „lt“, „gt“, „quot“ a „apos“. Ostatní mohou být definovány v DTD.

XML parser není povinen číst externí DTD. Pokud se dokument odvolává na externí DTD, není použití nedefinované entity fatální chybou a měla by být interpretována jako prostý text. Pokud se dokument neodvolává na externí DTD, je použití nedefinované entity fatální chybou. Od prohlížečů se očekává, že nebudou externí DTD číst a oni ji většinou skutečně nečtou. Když interpretují v XHTML entity „nbsp“ a spol., tak de facto podvádí a utváří okolo entit v XML nehezký mýtus. Entity (a celý formát DTD) jsou v XML jazycích nespolehlivý přežitek, který přináší více problémů než užitku. Budoucí verze XHTML (ať už 2 nebo 5) je pravděpodobně zruší.

Nastavení vlastnosti innerHTML by dle mého názoru mělo vyvolat výjimku jen tehdy, pokud by dosazovaný XML kód vyvolal fatální chybu. Teď koukám, že definice v návrhu HTML 5 je výstižnější. Říká, že prohlížeč musí vyrobit nový XML parser a částečně zapomenout kontext => zapomene i na přítomnost externí DTD a pak považuje výskyt entity za fatální chybu.

Jak je zapsat, aby fungovaly?
Podobný problém už jsem tu viděl, tenkrát jsem zjistil, že prohlížeče v HTML nepodporují metodu document.createEntityReference, která je pro tento účel stvořená. Teď jsem zjistil, že ji nepodporují ani v XML.

když jsem se pokusi integrovat Texylu
Jestli ty entity plive Texyla (či Texy), nešlo by ji nějak ukecat, aby je neplivala? Nebo aby raději plivala znakové entity? (Jako třeba &#160; — ty běží vždy.)
Kdyžtak sem přivolej krteczka, autora Texyly.
Jan Tvrdík
Profil
Chamurappi
aby raději plivala znakové entity
Problém jsem zatím skutečně vyřešil tak, že jsem všechny entity převedl na číselné.
Mě nejvíc zarazilo, že když se ty entity do dokumentu napíšou přímo, tak fungují, ale když je tam dává JS, tak nefungují.
Chamurappi
Profil
Reaguji na Jana Tvrdíka:
když se ty entity do dokumentu napíšou přímo, tak fungují
Stěžuj si výrobcům prohlížečů, fungovat by neměly. Pro innerHTML jsou přísnější pravidla.

Bez načítání DTD by mimochodem neměla fungovat ani metoda document.getElementById, protože to, který atribut je typu ID, se parser může dozvědět jen z DTD (typu ID může být i jiný atribut než „id“).
Jan Tvrdík
Profil
Mnou použitý postup k zprovoznění Texyly při mime typu application/xhtml+xml

1. Přidat následující funkci (kdyby někdo věděl, jak ji napsat lépe, tak ať napíše) na konec texyla.php:
function convertEntitiesToNumeric($string)
{
	preg_match_all("~\&[a-z]+\;~i", $string, $entity);
	$entity = array_unique($entity[0]);
	
	foreach($entity as $entita)
	{
		$char = html_entity_decode($entita,ENT_COMPAT,'UTF-8');
		
		$charCode = unpack("N", mb_convert_encoding($char, 'UCS-4BE', 'UTF-8'));
		$charCode = $charCode[1];

		$replaceTable[$entita] = "&#$charCode;";
	}
	
	return strtr($string, $replaceTable);
}


2. Upravit zpracování FSHL bloku (to on je zdrojem problému) – řádek asi 340
(...)
$content = $parser->highlightString($lang, $content);
$content = convertEntitiesToNumeric($content);
$content = $texy->protect($content, Texy::CONTENT_BLOCK);
(...)


3. Ve složce cfg upravit v potřebném souboru výstup z Texy (řádek asi 18):
$texy->setOutputMode(Texy::XHTML1_STRICT);
Jan Tvrdík
Profil
Stěžuj si výrobcům prohlížečů
Těším se na dobu, kdy budou prohlížeče pravidla skutečně respektovat. Poslední dobou se to začíná hodně lepšit (např. IE 8 by konečně mělo dodržovat specifikace), ale cesta bude ještě dlouhá...
Chamurappi
Profil
Reaguji na Jana Tvrdíka:
Brzdi s tím optimismem. Na věrném dodržování současných specifikací nic moc pozitivního nevidím a doufám, že je Explorer 8 nebude dodržovat do puntíku.

ale cesta bude ještě dlouhá...
Ta cesta je nekonečná, pokud specifikace nepůjdou prohlížečům naproti. Souhlasím s tím, že by v ideálním případě mezi standardem a prohlížeči neměl existovat žádný rozpor, ale to ještě automaticky neznamená, že jsou autoři standardů schopnější patlalové než autoři prohlížečů.

Ještě mě napadá:
$replaceTable[$entita] = "&#$charCode;";
Proč nevypíšeš rovnou ten znak? Jestli je výsledný dokument v Unicodu, tak jsou entity zbytečné.
Jan Tvrdík
Profil
Chamurappi
Proč nevypíšeš rovnou ten znak?
Protože ampresand (možná i jiné znaky) musí (aby je zpracoval firefox) být v entitách. Problém je, že nevím, které všechny entity jsou takto problematické. Pro ampresand by to šlo vyřešit takto:
function convertEntitiesToNumeric($string)
{
	preg_match_all("~\&[a-z]+\;~i", $string, $entity);
	$entity = array_unique($entity[0]);
	
	foreach($entity as $entita)
	{
		$char = html_entity_decode($entita,ENT_COMPAT,'UTF-8');
		if($char != "&")
			$replaceTable[$entita] = $char;
		else
			$replaceTable[$entita] = "&amp;";
	}
	
	return strtr($string, $replaceTable);
}
Chamurappi
Profil
Reaguji na Jana Tvrdíka:
Problematická může být v určitých situacích jen ta předdefinovaná pětice z XML 1.0. Takže „&“, „<“, „>“, „"“ a „'“.
Jan Tvrdík
Profil
Zatím to teda vypadá takto, snad to bude fungovat.
function convertEntitiesToNumeric($string)
{
	preg_match_all("~\&[a-z]+\;~i", $string, $entity);
	$entity = array_unique($entity[0]);
		
	$unconvertedEntities = array('&amp;','&lt;','&gt;','&quot;');
	foreach($entity as $entita)
	{
		if(in_array($entita, $unconvertedEntities)) continue;
		$char = html_entity_decode($entita,ENT_COMPAT,'UTF-8');
		$replaceTable[$entita] = $char;
	}
	
	return strtr($string, $replaceTable);
}

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: