Sommaire
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.
Les différents points abordés dans cette section ne concernent que les agents utilisateurs qui supportent les scripts.
<!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
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.
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.
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.
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>
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é.
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>"
Définition des attributs
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.
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 """ ou encore """ '&' devra être inscrit en tant que "&" ou encore "&"
Ainsi, par exemple, on pourrait écrire :
<INPUT name="num" value="0" onChange="if (compare(this.value, "help")) {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"'
Le modèle de modification dynamique du document peut être exprimé ainsi :
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>
<!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>
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.