7. Osadzanie JavaScriptu i CSS

Współczesne strony internetowe dużo korzystają z usług JavaScriptu i CSS. Dlatego system szablonów oparty na XML-u musi zapewniać odpowiednie narzędzia, które gwarantują poprawne osadzenie ich w kodzie szablonu. Podstawą naszych dalszych prac będą XML-owe sekcje CDATA. Standard XML-a mówi, że sekcja CDATA to specjalny blok tekstu traktowany jednolicie i niepodlegający dalszemu parsowaniu. Możemy swobodnie umieszczać w nim znaczniki bez obaw, że zostaną one przetworzone, komentarze i inne rzeczy. OPT zachowuje semantykę sekcji CDATA i nie parsuje ich zawartości. Jest ona przepisywana na wyjście razem z ogranicznikami CDATA, dzięki czemu przeglądarka także powinna teoretycznie ignorować jej strukturę.

Niestety sama sekcja CDATA to nie wszystko. Rozważmy następujący przykład, gdzie chcemy umieścić kod JavaScript, który jest generowany dynamicznie, ze zmienną wstawianą przez szablon ze skryptu:

<script type="text/javascript">
<![CDATA[
    document.write('Test: {$zmienna} czy ]]>{$zmienna}<![CDATA[?');
]]>
</script>

Po przetworzeniu takiego szablonu otrzymalibyśmy:

<script type="text/javascript">
<![CDATA[
    document.write('Test: {$zmienna} czy ]]>wartość zmiennej<![CDATA[?');
]]>
</script>

Nie jest to do końca to, co chcielibyśmy uzyskać. Kompilator musiał przerwać sekcję CDATA, by wstawić wartość zmiennej, a później rozpocząć ją ponownie, co nie dość, że nie wygląda ładnie, stwarza pytanie czy to na pewno wszędzie poprawnie zadziała. Rozwiązaniem jest wspomożenie się dodatkową instrukcją opt:literal, która pozwala kontrolować zachowanie się sekcji CDATA:

<script type="text/javascript">
<opt:literal type="comment_cdata">
<![CDATA[
    document.write('Test: {$zmienna} czy ]]>{$zmienna}<![CDATA[?');
]]>
</opt:literal>
</script>

opt:literal sprawia, że znaczniki CDATA umieszczone w treści instrukcji są dalej przetwarzane, a ich treść wyświetlana, jednak już bez samych znaczników początku i końca. Ponadto instrukcja pozwala opakować swoją zawartość wybranym rodzajem ograniczników ustawianym poprzez atrybut type:

  • cdata - opakowuje treść znacznikami <![CDATA[ oraz ]]>.
  • comment_cdata - opakowuje treść znacznikami /* <![CDATA[ */ oraz /* ]]> */.
  • comment - opakowuje treść znacznikami <!-- oraz --> (dynamiczne generowanie komentarzy).
  • transparent - nie opakowuje treści niczym, po prostu nie wyświetla znajdujących się wewnątrz <![CDATA[ i ]]>.

Zatem rezultatem naszych działań będzie:

<script type="text/javascript">
/* <![CDATA[ */
    document.write('Test: {$zmienna} czy wartość zmiennej?');
/* ]]> */
</script>

Zawartość znaczników <![CDATA[ dalej nie jest przetwarzana, ale same znaczniki się już nie wyświetlają. Ponadto opakowaliśmy kod JavaScript ogranicznikami, które gwarantują jego poprawną interpretację zarówno przez starsze, jak i nowsze przeglądarki.

Identyczną sztuczkę można wykorzystać do utworzenia komentarzy warunkowych dla przeglądarki Internet Explorer. Pozostawiamy to jako ćwiczenie.