Scripts 

Sommaire

  1. Conception de documents à destination des agents utilisateurs supportant les scripts
    1. L'élément SCRIPT
    2. Spécification du langage de script
    3. Syntaxe du contenu du script
    4. Evénements intrinsèques
    5. Modification dynamique des documents
  2. Conception de documents ne supportant pas les scripts
    1. L'élément NOSCRIPT
    2. Passer les scripts en commentaires
Un script client est un programme qui peut accompagner un document HTML ou y être directement inséré. Le programme s'exécute sur la machine cliente au moment où le document se charge, ou à d'autres moments particuliers, par exemple lorsqu'un lien est activé. Le support des scripts par HTML est indépendant du langage utilisé pour l'écriture de ces derniers.

Les scripts offrent aux auteurs de documents électroniques une méthode pour étendre considérablement les possibilités du HTML en lui ajoutant une interactivité et une dynamisation importante. Par exemple :

Un auteur pourra attacher deux types de scripts à un document HTML :

Note : Cette spécification donnera des informations plus détaillées sur les scripts dans les sections traitant des macros.

Conception de documents pour les agents utilisateurs supportant les scripts 

Les différents points abordés dans cette section ne concernent que les agents utilisateurs qui supportent les scripts.

L'élément SCRIPT 

    
<!ELEMENT SCRIPT - - CDATA      -- instructions de script -->
<!ATTLIST SCRIPT
  type        CDATA      #IMPLIED  -- type MIME pour le langage de script --
  language    CDATA      #IMPLIED  -- nom de langage de script prédéfini --
  src         %URL       #IMPLIED  -- URL d'un script externe --
  >

Balise de début : requise, Balise de fin : requise

Définition des attributs

type = cdata
Cet attribut spécifie le langage de script dans lequel est écrit le contenu de cet élément. Cette valeur doitêtre un type de contenu Internet. Cet attribut n'a pas de valeur par défaut.
language = cdata
Obsolète. Cet attribut spécifie le langage de script dans lequel est écrit le contenu de cet élément. Sa valeur représente un identificateur conventionnel du langage utilisé, mais comme ces identificateurs ne sont pas standard, cet attribut est aujourd'hui obsolète au profit de l'attribut type.
src = url
Cet attribut spécifie la localisation d'un script défini en externe.

L'élément SCRIPT introduit un script dans un document. Cet élément peut apparaître autant de fois que nécessaire dans une section HEAD ou BODY d'un document HTML.

Le code du script sera écrit comme le contenu de cet élément SCRIPT ou éventuellement dans un fichier externe. Si l'attribut src est absent, les agents utilisateurs devront interpréter le contenu de l'élément comme le source du script. S'il indique une URL, les agents utilisateurs ignoreront le contenu de l'élément pour récupérer en lieu et place le contenu de la resource désignée par l'URL.

Les scripts seront évalués par un moteur de script qui doit être fourni par l'agent utilisateur.

Spécification du langage de script 

Comme le HTML ne se base sur aucun langage de script particulier, les concepteurs de documents HTML devront indiquer explicitement à l'agent utilisateur le langage utilisé pour chaque script. Ceci pourra être fait de façon globale par une déclaration de "défaut" ou plus localement par une déclaration explicite.

Les documents qui n'affichent aucune définition de langage, ni implicite par défaut, ni locale associée à un élément SCRIPT ne sont pas corrects au vu du HTML. Les agents utilisateurs pourront cependant essayer d'interpréter le script, mais n'en ont nullement l'obligation.

Langage de script par défaut 

Pour spécifier quel est le langage par défaut attribuable à tous les scripts d'un document HTML, on incluera la déclaration META suivante dans la section HEAD du document :

<META http-equiv="Content-Script-Type" content="type">

dans laquelle "type" est le type MIME (Cf. [MIMETYPES]) nommant le langage. On pourra trouver par exemple des déclarations pour du "text/tcl", "text/javascript", "text/vbscript". Vous trouverez dans le document [MIMETYPES] une liste complète des types de langages valides.

En l'absence de toute déclaration META, le langage par défaut pourra toujours être précisé par un champ d'en-tête HTTP optionnel "Content-Script-Type".

    Content-Script-Type: type

dans lequel "type" est à nouveau le type MIME associé au langage de script.

Lorsque plusieurs champs d'en-tête HTTP et des déclarations META se cotnrarient, c'est la dernière qui remporte. Pour les besoins de cette règle, il est établi que tout champ d'en-tête HTTP est supposé être intervenu avant toute déclaration de la section HEAD.

Déclaration locale de langage de script 

Il est également possible de spécifier le langage de script pour chacun des éléments SCRIPT, via l'attribut type. En l'absence de toute déclaration de langage par défaut, cet attribut devra être définit pour chaque élément SCRIPT. Si un langage de script par défaut a été défini, il pourra être contrarié par l'attribut type.

Dans l'exemple qui suit, nous attribuons au langage de script par défaut la valeur "text/tcl". nous définissons un élément SCRIPT dans l'en-tête, qui fait référence à un source écrit dans un fichier externe en "text/vbscript". Nous incluerons de plus un SCRIPT dans le corps de document, contenant un script en "text/javascript".

<HTML>
<HEAD>
<META http-equiv="Content-Script-Type" content="text/tcl">
<SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc">
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
...du Javascript...
</SCRIPT>
</BODY>
</HTML>

Références aux éléments HTML à partir d'un script 

Chaque langage de script dispose de ses propres conventions pour référencer les instances d'éléments HTML à partir du script. Cette spécification ne propose aucun mécanisme particulier pour effectuer ce référencement.

Malgré tout, il serait préférable que les les scripts se réfèrent aux éléments selon leur nom d'instance. Les moteurs de scripts devraient suivre ces règles de précédence dans la prise en compte de ces noms : un attribut name aura la précédence sur un attribut id si les deux sont définis. Autrement, l'attribut défini pourra être utilisé.

Syntaxe du contenu du script 

Le contenu d'un élément SCRIPT est le code source d'un script, et en tant que tel, ne devra pas être considéré par l'agent utilisateur comme un fragment de HTML. L'agent utilisateur passera directement ce source à un moteur de script.

Les interpréteurs HTML doivent reconnaitre le début du script immédiatement après la fermeture de la balise de début, et une fin de script juste avant un délimiteur ETAGO ("</") suivi du premier caractère d'un token ([a-zA-Z]). Le source du script peut de ce fait ne pas être achevé par une balise </SCRIPT>, mais peut s'arrêter sur toute balise commençant par "</" suivi d'un caractère alphabétique.

En conséquence, toute balise HTML qui est sensée être envoyée telle que à un moteur de script (lequel en fera ce qu'il en veut) doit être "échappée" de façon à ne pas provoquer de confusion d'interprétation au niveau du HTML. Les concepteurs de langages de script devront proposer des solutions internes à la définition de langage pour traiter ce problème.

EXEMPLE ILLEGAL :
Le code suivant est invalide du fait de la présence de la séquence de caractères "</EM>" dans l'élément SCRIPT :

    <SCRIPT type="text/javascript">
      document.write ("<EM>Ceci ne marchera pas</EM>")
    </SCRIPT>

Un interpréteur conforme devra traiter ce "</EM>" comme la fin du source du script, ce qui est en contradiction totale avec la volonté affichée du concepteur.

En JavaScript, ce code pourra être exprimé de façon licite pour peu que l'on s'assure que le délimiteur ETAGO n'apparaisse pas immédiatement avant un caractère d'un nom SGML :

    <SCRIPT type="text/javascript">
      document.write ("<EM>Ceci fonctionnera<\/EM>")
    </SCRIPT>

En Tcl, on pourrait écrire de même :

    <SCRIPT type="text/tcl">
      document write "<EM>Ceci fonctionnera<\/EM>"
    </SCRIPT>

En VBScript, le problème pourrait être circonvenu par l'usage de la fonction Chr() :

    
    "<EM>Ceci fonctionnera<\" & Chr(47) + "EM>"

Evénements intrinsèques 

Définition des attributs

onload = script
L'événement onload intervient lorsque l'agent utilisateur vient de finir le chargement de la fenêtre, ou de tous les cadres d'un FRAMESET. Cet attribut peut être utilisé dans des éléments BODY et FRAMESET.
onunload = script
L'événement onunload intervient lorsque l'agent utilisateur décharge la fenêtre ou un cadre. Cet attribut peut être utilisé dans des éléments BODY et FRAMESET.
onclick = script
L'événement onclick intervient lorsque le bouton de l'organe de pointage est pressé puis relâché alors que ce dernier est situé sur l'objet. Cet attribut est reconnu par la plupart des éléments.
ondblclick = script
L'événement ondblclick intervient lorsque le bouton de l'organe de pointage est pressé deux fois répétitivement puis relâché alors que ce dernier est situé sur l'objet. Cet attribut est reconnu par la plupart des éléments.
onmousedown = script
L'événement onmousedown intervient lorsque le bouton de l'organe de pointage est enfoncé alors que ce dernier est positionné sur l'objet (mais n'est pas immédiatement relâché). Cet attribut est reconnu par la plupart des éléments.
onmouseup = script
L'événement onmouseup intervient lorsque le bouton de l'organe de pointage est relâché alors que ce dernier est positionné sur l'objet (on suppose qu'il avait été enfoncé au préalable). Cet attribut est reconnu par la plupart des éléments.
onmouseover = script
L'événement onmouseover intervient lorsque le pointeur est déplacé et entre sur la zone occupée par l'objet. Cet attribut est reconnu par la plupart des éléments.
onmousemove = script
L'événement onmousemove intervient lorsque le pointeur est déplacé alors que ce dernier est positionné sur l'objet. Cet attribut est reconnu par la plupart des éléments.
onmouseout = script
L'événement onmouseout intervient lorsque le pointeur est déplacé et sort de la zone occupée par l'objet. Cet attribut est reconnu par la plupart des éléments.
onfocus = script
L'événement onfocus lorsque l'élément reçoit le "focus" soit par action de l'organe de pointage, soit par la navigation tabulée. Cet attribut est reconnu par les éléments suivants : LABEL, INPUT, SELECT, TEXTAREA, et BUTTON.
onblur = script
L'événement onblur intervient lorsque l'élément perd le "focus", soit suite à une action de l'organe de pointage, soit par navigation tabulée. Il sera utilisable sur les mêmes éléments que l'événement onfocus.
onkeypress = script
L'événement onkeypress intervient lorsqu'une touche du clavier est enfoncée puis relâchée immédiatemment alors que l'élément a le "focus". Cet attribut est reconnu par la plupart des éléments.
onkeydown = script
L'événement onkeydown intervient lorsqu'une touche du clavier est enfoncée puis alors que l'élément a le "focus". Cet attribut est reconnu par la plupart des éléments.
onkeyup = script
L'événement onkeyup intervient lorsqu'une touche du clavier est relâchée alors que l'élément a le "focus". This attribute may be used with most elements.
onsubmit = script
L'événement onsubmit intervient lorsque le formulaire est soumis. Il n'est applicable que dans le contexte d'un élément FORM.
onreset = script
L'événement onreset intervient lorsqu'un formulaire est réinitialisé. Il n'est applicable que dans le contexte d'un élément FORM.
onselect = script
L'événement onselect intervient lorsque l'utilisateur sélectionne du texte dans un champ de texte. Cet attribut est exploitable pour des éléments INPUT et TEXTAREA.
onchange = script
L'événement onchange lorsque l'élément perd le "focus" ET sa valeur a été modifiée depuis le dernier instant où il a été activé. Cet attribut est applicable aux éléments suivants : INPUT, SELECT, et TEXTAREA.

Il est possible d'associer une action à un certain nombre d'événements issus de l'interaction d'un utilisateur et de l'agent utilisateur. Chacun des "événements intrinsèques" cité ci-dessus accepte un script comme valeur. Ce script est exécuté dès que l'événement considéré intervient pour l'élément spécifié.

Des contrôles tels que INPUT, SELECT, BUTTON, TEXTAREA, et LABEL répondent chacun à certains éléments. Lorsque ces éléments sont utilisés en dehors d'un contexte de formulaire, ils seront utilisés pour améliorer l'interface utilisateur du document.

Par exemple, certains concepteurs souhaiteront implanter des boutons qui ne soumettent aucun formulaire, mais continueront à communiquer avec un serveur lorsqu'ils sont pressés.

Les exemples suivants montrent des utilisations possibles de contrôles et de comportement d'interface utilisateur basé sur les événements intrinsèques.

Dans l'exemple qui suit, NomUtilisateur est un champ de texte requis. Lorsqu'un utilisateur tente de sortir de ce champ, l'événement OnBlur appelle une fonction JavaScript pour confirmer que NomUtilisateur est renseigné de façon convenable.

<INPUT NAME="NomUtilisateur" onBlur="NomValide(this.value)">

Voici un autre exemple de script :

<INPUT NAME="num"
    onChange="if (!checkNum(this.value, 1, 10)) 
        {this.focus();this.select();} else {thanks()}"
    VALUE="0">

Voici un exemple de script VBScript d'un gestionnaire d'événement pour champ de texte :

    <INPUT name="edit1" size="50">    
    <SCRIPT type="text/vbscript">
      Sub edit1_changed()
        If edit1.value = "abc" Then
          button1.enabled = True
        Else
          button1.enabled = False
        End If
      End Sub
    </SCRIPT>

Et le même exemple écrit en Tcl :

    <INPUT name="edit1" size="50">
    <SCRIPT type="text/tcl">
      proc edit1_changed {} {
        if {[edit value] == abc} {
          button1 enable 1
        } else {
          button1 enable 0
        }
      }
      edit1 onChange edit1_changed
    </SCRIPT>

Voici un exemple Javascript qui permet d'affecter un gestionnaire à un élément par programme. Tout d'abord, voici un premier gestionnaire :

    
<BUTTON type="button" name="mybutton" value="10">
<SCRIPT type="text/javascript">
      function my_onclick() {
         . . .
      }
    document.form.mybutton.onclick = my_onclick
 </SCRIPT>
 </BUTTON>

Voici un gestionnaire de fenêtre plus élaboré :

    
<SCRIPT type="text/javascript">
      function my_onload() {
         . . .
      }

      var win = window.open("some/other/URL")
      if (win) win.onload = my_onload
</SCRIPT>

En Tcl, cela ressemblerait à :

 <SCRIPT type="text/tcl">
     proc my_onload {} {
       . . .
     }
     set win [window open "some/other/URL"]
     if {$win != ""} {
         $win onload my_onload
     }
 </SCRIPT>

Notez que "document.write" ou toute instruction équivalente dans les gestionnaires d'événements intrinsèques crée et écrivent dans un nouveau document, plutôt que dans le document courant.

Interprétation des gestionnaires d'événements intrinsèques 

Les attributs scripts pour les événements intrinséques sont définis comme étant des CDATA. Le traitement SGML des valeurs d'attribut de type CDATA impose que (1) les remplacements d'entités ne se font qu'à l'intérieur de la valeur délimitée et que (2) cette valeur d'attribut doit être délimitée par des paires de guillemets (") ou d'apostrophes (').

Etant donné ces restrictions syntaxiques, les délimiteurs ('), ("), "&", et "&#" ne peuvent pas apparaître tels que dans la valeur d'un attribut de script. Pour résoudre ce problème, nous recommandons que les valeurs de ces attributs d'événements soient écrits entre guillemets (") et que les occurences de guillemets (") et de "&" à l'intérieur d'un script soient écrites comme suit :

    '"'  devra être inscrit en tant que "&quot;" ou encore "&#34;"
    '&'  devra être inscrit en tant que "&amp;"  ou encore "&#38;"

Ainsi, par exemple, on pourrait écrire :

 <INPUT name="num" value="0"
 onChange="if (compare(this.value, &quot;help&quot;)) {gethelp()}">

Le SGML permet à des apostrophes (') de figurer dans des chaînes limitées par des guillemets ("), et vice versa. Les deux écritures qui suivent sont de ce fait correctes :

"Tout est 'OK'" and 'C'est "cela"'

Modification dynamique des documents 

Les scripts exécutés lors du chargement du document peuvent inscrire dans ce dernier du contenu dynamiquement. Cette faculté dépendra souvent du langage de script (ex., l'instruction "document.write" du modèle HTML objet supporté par quelques produits du marché).

Le modèle de modification dynamique du document peut être exprimé ainsi :

  1. Chaque élément SCRIPT est évalué dans l'ordre ou il est inscrit dans le document.
  2. Toutes les constructions de langage incluses dans un élément SCRIPT qui générent des CDATA du SGML sont évaluées. Le texte généré par ces instructions sont insérées dans le document en remplacement de l'éléùment SCRIPT par lequel il a été créé.
  3. Les CDATA générés sont alors réévalués.

Les documents HTML doivent nécessairement se conformer à la DTD HTML à la fois avant et après le traitement des éléments SCRIPT.

L'exemple suivant montre comment un document peut être dynamiquement modifié par un script. Le script suivant :

 <TITLE>Document Test</TITLE>
 <SCRIPT type="text/javascript">
     document.write("<p><b>Hello World!<\/b>")
 </SCRIPT>

a le même effet que le texte HTML suivant :

 <TITLE>Document Test</TITLE>
 <P><B>Hello World!</B>

Conception de documents pour des agents utilisateurs ne supportant pas les scripts 

La section qui suit traite des considérations à prendre en termes d'absence de support des scripts. Le"s documents HTML "idéaux" devront prendre en compte cette possibilité et prévoir un comportement alternatif dans ce cas.

L'élément NOSCRIPT 

<!ELEMENT NOSCRIPT - - (%block)>

Balise de début : requise, Balise de fin : requise

L'élément NOSCRIPT permet aux auteurs de définir une alternative de comportement lorsque les scripts ne sont pas exécutés. Le contenu d'un élément NOSCRIPT ne sera affiché par un agent utilisateur supportant les scripts :

Les agents utilisateurs qui ne peuvent réagir au scripts afficheront le contenu de cet élément.

Dans l'exemple qui suit, un agent utilisateur supportant les éléments SCRIPT vont inclure du texte généré dynamiquement dans le document. Si l'agent utilisateur ne supporte pas les scripts, l'utilisateur pourra tout de même récupérer les données via un hyperlien.

<SCRIPT type="text/tcl">
 ...du script Tcl qui inclue des données...
</SCRIPT>
<NOSCRIPT>
 <P>Pour accéder aux données, cliquer <A href="http://someplace.com/data">ici.</A>
</NOSCRIPT>

Passer les scripts en commentaires 

Les agents utilisateur qui ne reconnaissent pas l'élément SCRIPT sera tenté d'afficher son contenu au même titre que du texte normal. Certains moteurs de script, comprenant ceux pour du JavaScript, VBScript, et Tcl autorisent que les instructions de scripts soient inclus sous forme d'un commentaire SGML. Les agents utilisateurs ne reconnaissant pas l'élément SCRIPT ignoreront de ce fait totalement le script, tandis que les agents utilisateurs avisés extrairont le script et l'exécuteront.

Une autre solution à ce problème est de déporter les scripts dans des documents externes et de s'y référer par des attributs src.

Commenter les scripts en JavaScript
L'interpréteur JavaScript autorise l'usage d'une séquence "<!--" au début du contenu d'un élément SCRIPT, et ignorera tous les caractères qui suivent jusqu'à la fin de la ligne. Le JavaScript interprète quant à lui la séquence "//" comme le début d'un commentaire Javascript courant jusqu'à la fin de la ligne. Il sera utile d'utiliser cette possibilité pour masquer la séquence "-->" indiquant la fin du commentaire SGML aux yeux de l'interpréteur Javascript.

<SCRIPT type="text/javascript">
<!--  pour cacher le scipt des anciens navigateurs
  function square(i) {
    document.write("The call passed ", i ," to the function.","<BR>")
    return i * i
  }
  document.write("The function returned ",square(5),".")
// commente la marque de fin de commentaire SGML -->
</SCRIPT>

Commenter les scripts en VBScript
En VBScript, une simple apostrophe débute un commentaire Visual Basic qui court jusqu'à la fin de la ligne. Elle pourra être utilisée pour masquer la séquence "-->" de l'interpréteur VBScript, par exemple :

   <SCRIPT type="text/vbscript">
     <!--
       Sub foo()
        ...
       End Sub
     ' commente la marque de fin de commentaire SGML  -->
    </SCRIPT>

Commenter les scripts en TCL
En Tcl, le caractère "#" initie un commentaire jusqu'à la fin de la ligne :

<SCRIPT type="text/tcl">
<!--  pour cacher le script des anciens navigateurs
  proc square {i} {
    document write "L'appel passe $i à la fonction.<BR>"
    return [expr $i * $i]
  }
  document write "The function returned [square 5]."
# commente la marque de fin de commentaire SGML -->
</SCRIPT>

Note : certains navigateurs reconnaissent une fin de commentaire sur le premier caractère ">". Pour se prémunir contre une mauvaise interprétation, vous pourrez transposer les opérateurs de comparaison et de décalage pour éviter la confusion (ex., écrivez "y < x" lorsque vous souhaitez écrire "x > y") ou utilisez les séquences d'échappement prévues par le langage.