L'objet Range identifie une étendue de contenu dans un objet Document, DocumentFragment ou Attr.
Elle est contiguë au sens où on peut la caractériser comme sélectionnant tout le contenu entre un couple de points limites.
Remarque : Dans un éditeur de texte ou un traitement de texte, l'utilisateur peut effectuer une sélection en pressant le bouton de la souris à un point du document puis en la déplaçant jusqu'à un autre point et enfin en relâchant le bouton de la souris. La sélection résultante est contiguë et se compose du contenu entre les deux points.
Le terme « sélection » ne signifie pas que toute étendue Range correspond à une sélection par l'utilisateur
d'une interface graphique (GUI) ; par contre, une telle sélection
pourra être retournée à un utilisateur DOM comme étendue Range.
Remarque : Dans une écriture bidirectionnelle (arabe, hébreu), une étendue peut correspondre à une sélection logique qui n'est pas forcément contiguë à l'affichage. Une sélection visuelle contiguë, utilisée dans certains cas également, ne correspondra peut-être pas à une seule sélection logique et pourra donc être représentée par plusieurs étendues.
L'interface Range fournit des méthodes permettant d'accéder et de manipuler l'arbre du document à un niveau supérieur
à celui des méthodes similaires de l'interface Node. Chaque méthode fournie par l'interface Range pour
insérer, supprimer et copier un contenu est censée correspondre directement à une série d'opérations d'édition via l'interface Node
du module DOM Core. Dans cette optique, on peut considérer les opérations de l'interface Range
comme des méthodes commodes qui permettent aussi à la mise en œuvre d'optimiser des motifs d'édition courants.
Ce chapitre décrit l'interface Range, dont des méthodes pour créer et déplacer une étendue Range
et des méthodes pour manipuler un contenu avec des étendues Range.
Les interfaces trouvées dans cette section ne sont pas obligatoires. Une application DOM peut employer la méthode
hasFeature(feature, version) de l'interface DOMImplementation,
respectivement avec les valeurs de paramètre "Range" et "2.0", pour déterminer si ce module est reconnu ou non par la mise en œuvre.
Pour la gestion complète de ce module, une mise en œuvre doit également gérer la fonctionnalité "Core",
définie dans la spécification DOM niveau 2 Core [DOM niveau 2 Core].
Consulter la section à propos de la
conformité →vf
dans la spécification DOM niveau 2 Core [DOM niveau 2 Core]
pour d'autres renseignements.
Cette section renvoie à deux représentations différentes d'un document : la forme textuelle, ou source, qui comprend le balisage du document, et la forme en arbre similaire à celle décrite en introduction du DOM niveau 2 Core [DOM niveau 2 Core].
L'étendue Range se compose de deux points limites
correspondant au début et à la fin de l'étendue.
On peut caractériser la position d'un point de limite,
dans l'arbre d'un nœud Document ou DocumentFragment, par un nœud et un décalage.
On appelle ce nœud le conteneur du point limite et de sa position.
Le conteneur et ses ancêtres sont les conteneurs ancêtres
du point limite et de sa position.
Le décalage à l'intérieur du nœud est appelé le décalage
du point limite et de sa position. Si le conteneur est un nœud Attr, Document, DocumentFragment,
Element ou EntityReference, le décalage se trouve entre ses nœuds enfants
Si le conteneur est un nœud CharacterData, Comment ou ProcessingInstruction,
le décalage se trouve entre les unités de 16 bits de la chaîne de caractères
codée en UTF-16 contenu par le nœud.
Les points limites d'une étendue Range doivent avoir un
conteneur ancêtre commun de type Document,
DocumentFragment ou Attr. C'est-à-dire que le contenu d'une étendue Range
doit se trouver entièrement dans le sous-arbre prenant racine dans un seul nœud Document, DocumentFragment
ou Attr.
Ce conteneur ancêtre commun est appelé le conteneur racine
de l'étendue Range. L'arbre enraciné dans le
conteneur racine s'appelle l'arbre de contexte de l'étendue Range.
Le conteneur d'un point limite
d'une étendue Range doit être un nœud de type
Element, Comment, ProcessingInstruction, EntityReference, CDATASection,
Document, DocumentFragment, Attr ou Text.
Aucun conteneur ancêtre d'un
point limite de l'étendue Range ne peut être un nœud de type
DocumentType, Entity ou Notation.
En ce qui concerne la représentation textuelle d'un document, les points limites
de l'étendue Range peuvent se trouver seulement aux frontières d'un atome. C'est-à-dire qu'un
point limite d'une étendue de texte ne peut pas se trouver
au milieu de la balise ouvrante ou fermante d'un élément, ou encore dans le nom d'une entité ou d'un appel de caractère.
L'étendue Range repère une portion contiguë de contenu du modèle de structure.
Les relations entre les positions dans la représentation textuelle d'un document et l'interface arborescente à nœuds Node
du DOM sont illustrées dans le diagramme suivant :
Dans ce diagramme, on montre quatre étendues différentes. Les points limites
de chaque étendue Range sont repérés par « dX » (le début de l'étendue) et par
« fX » (la fin de l'étendue), où « X » est le numéro de l'étendue. Pour l'étendue 2, elle débute dans l'élément BODY,
immédiatement après l'élément H1 et immédiatement avant l'élément P, et sa position est donc entre les enfants H1 et P de BODY.
Le décalage d'un point limite
dont le conteneur n'est pas un nœud CharacterData est de 0, si le point se trouve
avant le premier enfant, de 1, s'il se trouve entre le premier et le deuxième enfant, et ainsi de suite. Donc, pour le début de l'étendue 2,
le conteneur est BODY et le décalage est de 1.
Le décalage d'un point limite dont le
conteneur est un nœud CharacterData se détermine de façon similaire,
cette fois en utilisant la position des unités de 16 bits. Par exemple,
le point limite repéré par « d1 » de l'étendue 1 a pour
conteneur un nœud Text (celui qui contient "Titre") et a un
décalage de 2, puisqu'il se trouve entre la deuxième et la troisième
unité de 16 bits.
Remarquer que les points limites des étendues 3 et 4 correspondent
au même emplacement dans la représentation textuelle. Un aspect essentiel des étendues est que le
point limite d'une étendue Range peut représenter sans ambiguïté
n'importe quelle position dans l'arbre du document.
On peut déterminer les conteneurs et les décalages
des points limites grâce aux attributs suivants (en lecture seule)
de l'étendue Range :
readonly attribute Node startContainer; readonly attribute long startOffset; readonly attribute Node endContainer; readonly attribute long endOffset;
Si les points limites
d'une étendue Range ont les mêmes conteneurs et
décalages, on dit de l'étendue qu'elle
se rétracte. (Dans un agent utilisateur, cela renvoie souvent
au point d'insertion).
Un nœud, ou une unité de 16 bits,
est dit sélectionné par une étendue Range s'il se trouve entre les deux
points limites de cette étendue Range, c'est-à-dire si la
position immédiatement avant le nœud, ou l'unité de 16 bits, est située avant la fin de l'étendue
et si la position immédiatement après le nœud, ou l'unité de 16 bits, est située après le début de l'étendue.
Par exemple, dans une représentation textuelle d'un document, un élément sera sélectionné
par une étendue Range si sa balise ouvrante correspondante est située après le début de l'étendue et sa balise fermante
située avant la fin de l'étendue. Dans les exemples du diagramme précédent, l'étendue 2 sélectionne
le nœud P et l'étendue 3 le nœud de texte contenant le texte "Blah xyz."
On dit qu'un nœud est partiellement sélectionné
par une étendue Range si c'est un conteneur ancêtre
pour exactement un seul point limite de l'étendue. Par exemple,
prenons l'étendue 1 du diagramme précédent. L'élément H1 est partiellement sélectionné
par cette étendue Range car le début de l'étendue se trouve dans l'un de ses enfants.
Plusieurs exemples de ce chapitre sont illustrés en s'inspirant d'une représentation textuelle du document.
Les points limites d'une étendue Range sont signalés
par un affichage des caractères (qu'il s'agisse de balisage ou de données textuelles) entre les deux
points limites dans une graisse plus forte comme suit :
<TRUC>ABC<MUCHE>DEF</MUCHE></TRUC>
Quand les deux points limites sont à la même position, ils sont signalés par un caractère signe d'insertion « ^ » dans une graisse plus forte comme suit :
<TRUC>A^BC<MUCHE>DEF</MUCHE></TRUC>
On crée une étendue Range en appelant la méthode createRange() de l'interface
DocumentRange. On peut obtenir cette interface à partir de
l'objet qui met en œuvre l'interface Document en utilisant les
méthodes prépondérantes spécifiques de la liaison.
interface DocumentRange {
Range createRange();
}
L'état initial de l'étendue Range retournée par cette méthode est tel que les deux
points limites sont positionnés au début du
nœud Document correspondant, avant tout contenu. En d'autres termes, le
conteneur de chaque point limite
est le nœud Document et le décalage dans ce nœud est de 0.
Comme pour certains objets créés en utilisant les méthodes de l'interface Document (tels que les
nœuds Node et DocumentFragment), les étendues Range créées via une instance de document particulière
peuvent seulement sélectionner un contenu associé à ce nœud Document, ou bien aux objets
DocumentFragment et Attr dont l'attribut ownerDocument désigne le nœud Document
en question. On ne peut donc pas utiliser ces étendues Range avec d'autres instances de l'objet Document.
On peut définir la position d'une étendue Range en paramétrant le
conteneur et le décalage
de chaque point limite à l'aide des méthodes setStart() et setEnd().
void setStart(in Node parent, in long offset)
raises(RangeException);
void setEnd(in Node parent, in long offset)
raises(RangeException);
Si l'un des points limites d'une étendue Range est fixé avec un
autre conteneur racine que le conteneur actuel de l'étendue Range,
l'étendue se rétracte à cette nouvelle position. Cela pour respecter la restriction
selon laquelle les deux points limites d'une étendue Range doivent avoir le même
conteneur racine.
La position de début d'une étendue Range est assurée de ne jamais se trouver après sa position de fin.
Pour respecter cette restriction, si on fixe le début à une position après celle de fin, alors l'étendue Range
se rétracte à cette nouvelle position. Et inversement, si on fixe la fin à une position
avant celle de début, l'étendue se rétracte à la nouvelle position.
On peut également fixer la position de l'étendue Range par rapport aux nœuds dans l'arbre :
void setStartBefore(in Node node);
raises(RangeException);
void setStartAfter(in Node node);
raises(RangeException);
void setEndBefore(in Node node);
raises(RangeException);
void setEndAfter(in Node node);
raises(RangeException);
Le parent du nœud devient le conteneur
du point limite et l'étendue Range est soumise aux mêmes restrictions
que celles indiquées dans la description des méthodes setStart() et setEnd().
L'étendue Range peut se rétracter à l'un ou l'autre point limite :
void collapse(in boolean toStart);
La valeur true du paramètre toStart entraînera la rétractation
de l'étendue Range à sa position de début, et une valeur false à celle de fin.
On peut tester si une étendue Range s'est rétractée en examinant la valeur
de l'attribut collapsed :
readonly attribute boolean collapsed;
Les méthodes suivantes peuvent servir pour qu'une étendue Range sélectionne le contenu d'un nœud ou le nœud même.
void selectNode(in Node n); void selectNodeContents(in Node n);
Les exemples suivants illustrent l'action des méthodes selectNode() et selectNodeContents() :
Avant : ^<MUCHE><TRUC>A<CHOSE>B</CHOSE>C</TRUC></MUCHE> Après Range.selectNodeContents(TRUC) : <MUCHE><TRUC>A<CHOSE>B</CHOSE>C</TRUC></MUCHE> (Dans ce cas, TRUC est le parent des deux points limites) Après Range.selectNode(TRUC) : <MUCHE><TRUC>A<CHOSE>B</CHOSE>C</TRUC></MUCHE>
On peut comparer deux étendues Range en comparant leurs points limites :
short compareBoundaryPoints(in CompareHow how, in Range sourceRange) raises(RangeException);
Où le paramètre CompareHow prend l'une de quatres valeurs : START_TO_START,
START_TO_END, END_TO_END et END_TO_START. La valeur retournée est -1, 0 ou 1,
selon que le point limite correspondant de l'étendue Range se trouve avant, est égal ou se trouve après le point limite
correspondant de l'étendue Range désignée par l'attribut sourceRange. Une exception est soulevée
si les deux étendues Range ont des conteneurs racines différents.
Le résultat de la comparaison de deux points limites (ou de deux positions) est précisé ci-dessous. Une définition informelle mais parfois inexacte est qu'un point limite se trouvera avant, sera égal ou se trouvera après un autre point limite s'il correspond, dans la représentation textuelle, à une position avant, égale ou après la position correspondante de l'autre point limite.
Soit deux points limites (ou positions) A et B. L'une des propositions suivantes sera alors vérifiée : A est avant B, A est égal à B, ou A est après B. On détermine celle qui est vérifiée en examinant les quatre cas suivants :
Premier cas : les points limites ont le même conteneur. A est avant B si son décalage est inférieur à celui de B ; A est égal à B si son décalage est égal à celui de B A est après B si son décalage est supérieur à celui de B.
Deuxième cas : un nœud enfant C du conteneur de A est un conteneur ancêtre de B. Auquel cas, A est avant B si le décalage de A est inférieur ou égal à l'index du nœud enfant C ; sinon A est après B.
Troisième cas : un nœud enfant C du conteneur de B est un conteneur ancêtre de A. Auquel cas, A est avant B si l'index du nœud enfant C est inférieur au décalage de B ; sinon A est après B.
Quatrième cas : aucun des trois autres cas n'est vérifié et les conteneurs de A et B sont
frères ou des descendants
de nœuds frères. Auquel cas, A est avant B si le conteneur
de A est avant celui de B dans une traversée préordonnée de l'arbre de contexte
des étendues Range ; sinonA est après B.
Remarquer que, puisqu'une même position dans la représentation textuelle du document peut correspondre à deux positions distinctes dans l'arbre DOM, il est possible que la comparaison de deux points limites ne corresponde pas à une égalité, quoiqu'elle le puisse dans la représentation textuelle. La définition informelle qui précède est donc parfois inexacte pour cette raison.
On peut supprimer le contenu sélectionné par une étendue Range :
void deleteContents();
La méthode deleteContents() supprime tous les nœuds et caractères sélectionnés par l'étendue Range.
Tous les autres nœuds et caractères restent dans l'arbre de contexte
de l'étendue Range. Voici quelques exemples de suppression :
(1) <TRUC>AB<CHOSE>CD</CHOSE>CD</TRUC> --> <TRUC>A^CD</TRUC>
(2) <TRUC>A<CHOSE>BC</CHOSE>DE</TRUC> --> <TRUC>A<CHOSE>B</CHOSE>^E</TRUC>
(3) <TRUC>XY<MUCHE>ZW</MUCHE>Q</TRUC> --> <TRUC>X^<MUCHE>W</MUCHE>Q</TRUC>
(4) <TRUC><MUCHE1>AB</MUCHE1><MUCHE2/><MUCHE3>CD</MUCHE3></TRUC> --> <TRUC><MUCHE1>A</MUCHE1>^<MUCHE3>D</MUCHE3>
Après l'invocation de la méthode deleteContents() sur une étendue Range, celle-ci
se rétracte.
Si aucun nœud n'est partiellement sélectionné
par l'étendue Range, alors l'étendue se rétracte à son point de début original,
comme dans l'exemple (1). Si un nœud est partiellement sélectionné
par l'étendue Range, et que ce nœud est un conteneur ancêtre
du début de l'étendue Range, et qu'aucun ancêtre de ce nœud
ne satisfasse aux deux premières conditions, alors l'étendue Range se rétracte à la position immédiatement après le nœud,
comme dans les exemples (2) et (4). Si un nœud est partiellement sélectionné
par l'étendue Range, et que ce nœud est un conteneur ancêtre
de la fin de l'étendue Range, et qu'aucun ancêtre du nœud ne satisfasse à ces deux conditions,
alors l'étendue Range se rétracte à la position immédiatement avant le nœud, comme dans les exemples (3) et (4).
Remarquer que si la suppression d'une étendue laisse des nœuds Text adjacents, ils ne fusionnent pas automatiquement
et les nœuds vides ne sont pas retirés non plus. Deux nœuds Text devraient seulement être joints si chacun
est le conteneur de l'un des points limites d'une étendue Range dont le contenu est supprimé. Pour fusionner des
nœuds Text adjacents, ou retirer des nœuds Text vides, on devrait employer
la méthode normalize() de l'interface Node.
Si on doit extraire le contenu d'une étendue Range au lieu de le supprimer, on peut utiliser la méthode suivante :
DocumentFragment extractContents();
La méthode extractContents() retire les nœuds de
l'arbre de contexte de l'étendue Range de façon similaire à
la méthode deleteContents(). En outre, elle range le contenu supprimé dans un nouvel objet DocumentFragment.
Les exemples suivants montrent le contenu de l'objet DocumentFragment retourné :
(1) <TRUC>AB<CHOSE>CD</CHOSE>CD</TRUC> --> B<CHOSE>CD</CHOSE>
(2) <TRUC>A<CHOSE>BC</CHOSE>DE</TRUC> --> <CHOSE>C<CHOSE>D
(3) <TRUC>XY<MUCHE>ZW</MUCHE>Q</TRUC> --> Y<MUCHE>Z</MUCHE>
(4) <TRUC><MUCHE1>AB</MUCHE1><MUCHE2/><MUCHE3>CD</MUCHE3></TRUC> --> <MUCHE1>B</MUCHE1><MUCHE2/><MUCHE3>C</MUCHE3>
Il importe de remarquer que les nœuds partiellement sélectionnés
par l'étendue Range sont clonés. Puisqu'une partie du contenu de ce nœud doit rester dans
l'arbre de contexte de l'étendue Range et qu'une partie du contenu doit
être déplacée dans le nouvel objet DocumentFragment, un clone du nœud
partiellement sélectionné est inclus au nouvel objet DocumentFragment.
Remarquer que le clonage n'intervient pas sur les éléments sélectionnés ;
ces nœuds sont déplacés sur le nouvel objet DocumentFragment.
On peut dupliquer le contenu d'une étendue Range en utilisant la méthode suivante :
DocumentFragment cloneContents();
Cette méthode retourne un objet DocumentFragment similaire à celui retourné par la
méthode extractContents(). Dans ce cas, par contre, les nœuds et
données textuelles d'origine dans l'étendue Range ne sont pas retirés
de son arbre de contexte. Plutôt, tous les nœuds et le contenu textuel de
l'objet DocumentFragment retourné sont clonés.
On peut insérer un nœud dans une étendue Range en utilisant la méthode suivante :
void insertNode(in Node n) raises(RangeException);
La méthode insertNode() insère le nœud indiqué dans l'arbre de contexte
de l'étendue Range. Le nœud est inséré au point limite de début
de l'étendue Range sans le modifier.
Si le point limite de début de l'étendue Range se trouve dans un nœud Text, la méthode insertNode
scinde le nœud Text au point limite. Si le nœud à insérer est également un nœud Text,
les nœuds Text adjacents qui en résultent ne sont pas automatiquement normalisés ; cette opération est laissée
à l'application.
Le nœud passé à cette méthode peut être un objet DocumentFragment. Auquel cas, son contenu est inséré
au point limite de début de l'étendue Range
mais pas le nœud DocumentFragment en question. Remarquer que si le nœud représente la racine d'un sous-arbre,
le sous-arbre entier est inséré.
Les mêmes règles applicables à la méthode insertBefore() de l'interface Node s'applique ici.
Notamment, le nœud Node passé, s'il a déjà un parent, sera retiré de sa position existante.
On peut insérer un seul nœud afin d'incorporer le contenu sélectionné par une étendue Range :
void surroundContents(in Node newParent);
La méthode surroundContents() entraîne l'enracinement de tout le contenu sélectionné
par l'étendue Range sur le nœud indiqué. Ce nœud ne peut pas être du type Attr,
Entity, DocumentType, Notation, Document ou DocumentFragment.
L'appel de la méthode surroundContents() avec le nœud TRUC de type Element produit le résultat suivant :
Avant :
<MUCHE>AB<CHOSE>C</CHOSE>DE</MUCHE>
Après surroundContents(TRUC) :
<MUCHE>A<TRUC>B<CHOSE>C</CHOSE>D</TRUC>E</MUCHE>
On peut décrire autrement l'effet de cette méthode sur l'arbre de contexte
de l'étendue Range en le décomposant en d'autres opérations :
Range par un appel de la méthode extractContents() ;newParent là où l'étendue Range se rétracte
(après l'extraction) avec la méthode insertNode() ;DocumentFragment extrait dans le nœud indiqué par
newParent. Notamment, invoquer la méthode appendChild() sur le nœud newParent
en lui passant l'objet DocumentFragment extrait, retourné en résultat de l'appel de la méthode extractContents() ;newParent et tout son contenu avec la méthode selectNode().La méthode surroundContents() soulève une exception si l'étendue Range
sélectionne partiellement un nœud d'un autre type que Text.
Voici un exemple d'étendue Range pour lequel la méthode surroundContents() soulève une exception :
<TRUC>AB<MUCHE>CD</MUCHE>E</TRUC>
Si le nœud indiqué par l'attribut newParent a des enfants, ces derniers sont retirés avant l'insertion du nœud.
Également, si le nœud newParent a déjà un parent, il est retiré de la liste originale décrite
par l'attribut childNodes du parent.
On peut cloner une étendue Range :
Range cloneRange();
Cette méthode crée une nouvelle étendue Range sélectionnant exactement le même contenu que celui de
l'étendue Range sur laquelle est invoquée la méthode cloneRange. Le contenu n'est pas affecté par cette opération.
Comme les points limites d'une étendue Range n'ont pas forcément les mêmes conteneurs,
utiliser :
readonly attribute Node commonAncestorContainer;
Pour obtenir le conteneur ancêtre des deux points limites le plus éloigné
en descendant le conteneur racine de l'étendue Range.
On peut obtenir une copie de toutes les données textuelles sélectionnées ou partiellement sélectionnées par une étendue Range :
DOMString toString();
L'effet est une simple concaténation de toutes les données textuelles sélectionnées par l'étendue Range.
Cela concerne les données textuelles des nœuds Text et CDATASection.
Lors de la modification d'un document, les étendues Range du document doivent être mises à jour. Par exemple,
si un point limite d'une étendue Range se trouve dans un nœud retiré du document, l'étendue Range
sera invalide à moins de la réparer d'une façon ou d'une autre. Cette section décrit comment les étendues Range
sont modifiées au cours des mutations du document afin de rester valides.
Deux principes généraux s'appliquent aux étendues Range en cas de mutation du document : premièrement, que
toutes les étenduee Range dans le document resteront valide après une opération de mutation et, deuxièmement, que toutes les
étendues Range sélectionneront, autant que possible, la même portion du document après sa mutation.
On peut assimiler la mutation de l'arbre du document, qui affecte les étendues Range, à une combinaison de suppressions
et d'insertions élémentaires. En fait, il peut être commode de considérer ces opérations comme réalisées en se servant des méthodes
deleteContents() et insertNode() de l'étendue Range et, dans le cas des mutations de texte,
des méthodes splitText() et normalize().
Une insertion a lieu en un seul point dans le document : le point d'insertion. Considérer chaque point limite pour toute
étendue Range dans l'arbre du document. Le seul cas où le point limite changera après l'insertion est celui dans lequel
le point limite et le point d'insertion ont le même conteneur et dans lequel le
décalage du point d'insertion est strictement inférieur à celui du point limite
de l'étendue Range. Auquel cas, le décalage du point limite de
l'étendue Range augmentera de façon à se trouver entre les mêmes nœuds, ou les mêmes caractères, où le point limite
était avant l'insertion.
Remarquer que, à l'insertion d'un contenu à un point limite, le repositionnement du point de délimitation si sa position relative devait être conservée est ambigu. Il y a deux possibilités : au début ou à la fin du contenu nouvellement inséré. Nous avons décidé que ni le conteneur ni le décalage du point limite ne changeront dans ce cas. En conséquence, le point limite se positionnera au début du contenu inséré.
Exemples
Supposons que l'étendue Range fasse la sélection suivante :
<P>Abcd efgh XY blah ijkl</P>
Examinons l'insertion du texte texte inséré
aux positions suivantes :
1. Avant le 'X' : <P>Abcd efgh texte inséréXY blah ijkl</P> 2. Après le 'X' : <P>Abcd efgh Xtexte inséréY blah ijkl</P> 3. Après le 'Y' : <P>Abcd efgh XYtexte inséré blah ijkl</P> 4. Après le 'h' de "Y blah" : <P>Abcd efgh XY blahtexte inséré ijkl</P>
On peut assimiler toute suppression dans l'arbre du document à une succession d'opérations deleteContents()
appliquées à un ensemble minimal d'étendues Range disjointes. Pour définir comment une étendue Range
est modifiée pendant des suppressions, on a seulement besoin d'étudier ce qui arrive à une étendue Range
au cours d'une seule opération deleteContents() exercée par une autre étendue Range.
Et, en réalité, on a uniquement besoin d'examiner ce qui arrive à un seul point limite de l'étendue Range puisque
les points limites sont modifiés d'après le même algorithme.
Si un point limite de l'étendue Range initiale se trouve dans le contenu à supprimer, il sera alors, après la suppression,
à la même position que le point limite final de l'étendue Range (désormais rétractée)
qui a servi à supprimer le contenu.
Si un point limite se trouve après le contenu à supprimer, alors il n'est pas affecté par la suppression,
à moins que son conteneur ne soit aussi celui de l'un des points limites
de l'étendue Range à supprimer. En présence d'un tel conteneur commun,
l'index du point limite est modifié de façon à ce que le point limite conserve sa position relativement
au contenu du conteneur.
Si un point limite se trouve avant le contenu à supprimer, alors il n'est pas du tout affecté par la suppression.
Exemples
Dans ces exemples, l'étendue Range sur laquelle on invoque la méthode deleteContents()
est signalée par un trait souligné.
Exemple 1.
Avant :
<P>Abcd efgh The Range ijkl</P>
Après :
<P>Abcd Range ijkl</P>
Exemple 2.
Avant :
<p>Abcd efgh The Range ijkl</p>
Après :
<p>Abcd ^kl</p>
Exemple 3.
Avant :
<P>ABCD efgh The <EM>Range</EM> ijkl</P>
Après :
<P>ABCD <EM>ange</EM> ijkl</P>
Pour cet exemple, le conteneur du point limite de début après suppression est le nœud de type Text
contenant la chaîne "ange".
Exemple 4.
Avant :
<P>Abcd efgh The Range ijkl</P>
Après :
<P>Abcd he Range ijkl</P>
Exemple 5.
Avant :
<P>Abcd <EM>efgh The Range ij</EM>kl</P>
Après :
<P>Abcd ^kl</P>
En résumé, on donne ci-dessous la description formelle complète de l'interface
Range :
// Introduite dans DOM niveau 2 :
interface Range {
readonly attribute Node startContainer;
// soulève une exception DOMException en retour
readonly attribute long startOffset;
// soulève une exception DOMException en retour
readonly attribute Node endContainer;
// soulève une exception DOMException en retour
readonly attribute long endOffset;
// soulève une exception DOMException en retour
readonly attribute boolean collapsed;
// soulève une exception DOMException en retour
readonly attribute Node commonAncestorContainer;
// soulève une exception DOMException en retour
void setStart(in Node refNode,
in long offset)
raises(RangeException,
DOMException);
void setEnd(in Node refNode,
in long offset)
raises(RangeException,
DOMException);
void setStartBefore(in Node refNode)
raises(RangeException,
DOMException);
void setStartAfter(in Node refNode)
raises(RangeException,
DOMException);
void setEndBefore(in Node refNode)
raises(RangeException,
DOMException);
void setEndAfter(in Node refNode)
raises(RangeException,
DOMException);
void collapse(in boolean toStart)
raises(DOMException);
void selectNode(in Node refNode)
raises(RangeException,
DOMException);
void selectNodeContents(in Node refNode)
raises(RangeException,
DOMException);
// Paramètre compareHow
const unsigned short START_TO_START = 0;
const unsigned short START_TO_END = 1;
const unsigned short END_TO_END = 2;
const unsigned short END_TO_START = 3;
short compareBoundaryPoints(in unsigned short how,
in Range sourceRange)
raises(DOMException);
void deleteContents()
raises(DOMException);
DocumentFragment extractContents()
raises(DOMException);
DocumentFragment cloneContents()
raises(DOMException);
void insertNode(in Node newNode)
raises(DOMException,
RangeException);
void surroundContents(in Node newParent)
raises(DOMException,
RangeException);
Range cloneRange()
raises(DOMException);
DOMString toString()
raises(DOMException);
void detach()
raises(DOMException);
};
Passé comme paramètre à la méthode compareBoundaryPoints.
END_TO_ENDsourceRange au point limite de fin
de l'étendue Range sur laquelle la méthode compareBoundaryPoints est invoquée.END_TO_STARTsourceRange au point limite de début
de l'étendue Range sur laquelle la méthode compareBoundaryPoints est invoquée.START_TO_ENDsourceRange au point limite de fin
de l'étendue Range sur laquelle la méthode compareBoundaryPoints est invoquée.START_TO_STARTsourceRange au point limite de début
de l'étendue Range sur laquelle la méthode compareBoundaryPoints est invoquée.collapsed de type boolean, en lecture seuletrue si l'étendue Range est rétractée.|
|
INVALID_STATE_ERR : Soulevée si la méthode |
commonAncestorContainer de type Node, en lecture seuleRange.|
|
INVALID_STATE_ERR : Soulevée si la méthode |
endContainer de type Node, en lecture seuleRange.|
|
INVALID_STATE_ERR : Soulevée si la méthode |
endOffset de type long, en lecture seuleRange.|
|
INVALID_STATE_ERR : Soulevée si la méthode |
startContainer de type Node, en lecture seuleRange.|
|
INVALID_STATE_ERR : Soulevée si la méthode |
startOffset de type long, en lecture seuleRange.|
|
INVALID_STATE_ERR : Soulevée si la méthode |
cloneContentsRange.
|
|
Un objet |
|
|
HIERARCHY_REQUEST_ERR : Soulevée si un nœud INVALID_STATE_ERR : Soulevée si la méthode |
cloneRangeRange dont les points limites sont identiques
à ceux de l'étendue Range initiale.
|
L'étendue |
|
|
INVALID_STATE_ERR : Soulevée si la méthode |
collapseRange à l'un de ses points limites.
toStart de type booleantrue, rétracte l'étendue Range sur son début ; pour false,
rétracte l'étendue Range sur sa fin.|
|
INVALID_STATE_ERR : Soulevée si la méthode |
compareBoundaryPointsRange dans un document.
how de type unsigned shortsourceRange de type RangeRange à laquelle l'étendue Range courante est comparée.|
|
La valeur -1, 0 ou 1, selon que le point limite de l'étendue |
|
|
WRONG_DOCUMENT_ERR : Soulevée si les deux étendues INVALID_STATE_ERR : Soulevée si la méthode |
deleteContentsRange du document, ou du fragment de document, qui le contient,
sans retourner de référence au contenu retiré.
|
|
NO_MODIFICATION_ALLOWED_ERR : Soulevée si une portion du contenu de l'étendue INVALID_STATE_ERR : Soulevée si la méthode |
detachRange ne sert plus, et la mise en œuvre peut
renoncer aux ressources associées à cette étendue Range. Les appels suivants d'une méthode ou d'un attribut de
cette étendue Range soulèveront une exception DOMException de code d'erreur INVALID_STATE_ERR.
|
|
INVALID_STATE_ERR : Soulevée si la méthode |
extractContentsRange du document, ou du fragment de document, qui le contient vers un
nouvel objet DocumentFragment.
|
|
Un objet |
|
|
NO_MODIFICATION_ALLOWED_ERR : Soulevée si une portion du contenu de l'étendue HIERARCHY_REQUEST_ERR : Soulevée si un nœud INVALID_STATE_ERR : Soulevée si la méthode |
insertNodeDocument, ou DocumentFragment,
au début de l'étendue Range. Si le conteneur est un nœud Text, il sera scindé au début de
l'étendue Range (comme si la méthode splitText du type Text opérait au point d'insertion)
et l'insertion interviendra entre les deux nœuds Text résultants. Les nœuds Text adjacents
ne fusionneront pas automatiquement. Si le nœud à insérer est du type DocumentFragment,
les enfants seront insérés au lieu du nœud DocumentFragment en question.
newNode de type NodeRange.|
|
NO_MODIFICATION_ALLOWED_ERR : Soulevée si un conteneur ancêtre
du début de l'étendue WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par HIERARCHY_REQUEST_ERR : Soulevée si le conteneur du début de l'étendue INVALID_STATE_ERR : Soulevée si la méthode |
|
INVALID_NODE_TYPE_ERR : Soulevée si le nœud indiqué par |
selectNoderefNode de type Node|
INVALID_NODE_TYPE_ERR : Soulevée si un ancêtre du nœud indiqué par |
|
|
|
INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
selectNodeContentsrefNode de type Node|
INVALID_NODE_TYPE_ERR : Soulevée si le nœud indiqué par |
|
|
|
INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
setEndRange.
refNode de type NoderefNode. Ce paramètre doit être différent de la valeur null.offset de type longendOffset.|
INVALID_NODE_TYPE_ERR : Soulevée si le nœud indiqué par |
|
|
|
INDEX_SIZE_ERR : Soulevée si le paramètre INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
setEndAfterRange afin qu'elle soit après un nœud.
refNode de type NodeRange finit après le nœud indiqué par refNode.|
INVALID_NODE_TYPE_ERR : Soulevée si le conteneur racine du nōud indiqué par |
|
|
|
INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
setEndBeforeRange afin qu'elle soit avant un nœud.
refNode de type NodeRange finit avant le nœud indiqué par refNode|
INVALID_NODE_TYPE_ERR : Soulevée si le conteneur racine du œud indiqué par |
|
|
|
INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
setStartRange.
refNode de type NoderefNode. Ce paramètre doit avoir une valeur différente de null.offset de type longstartOffset.|
INVALID_NODE_TYPE_ERR : Soulevée si le nœud indiqué par |
|
|
|
INDEX_SIZE_ERR : Soulevée si le paramètre INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
setStartAfterRange afin qu'elle soit après un nœud.
refNode de type NodeRange débute après le nœud indiqué par refNode|
INVALID_NODE_TYPE_ERR : Soulevée si le conteneur racine du nœud indiqué par |
|
|
|
INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
setStartBeforerefNode de type NodeRange débute avant le nœud indiqué par refNode.|
INVALID_NODE_TYPE_ERR : Soulevée si le conteneur racine du nœud indiqué par |
|
|
|
INVALID_STATE_ERR : Soulevée si la méthode WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par |
surroundContentsRange et s'insère
à la position de début de l'étendue Range.
newParent de type Node|
|
NO_MODIFICATION_ALLOWED_ERR : Soulevée si un conteneur ancêtre
de l'un ou l'autre point limite de l'étendue WRONG_DOCUMENT_ERR : Soulevée si le nœud indiqué par HIERARCHY_REQUEST_ERR : Soulevée si le container du début de l'étendue INVALID_STATE_ERR : Soulevée si la méthode |
|
BAD_BOUNDARYPOINTS_ERR : Soulevée si l'étendue INVALID_NODE_TYPE_ERR : Soulevée si c'est un nœud de type |
toStringRange sous forme d'une chaîne. Cette chaîne ne contient que des
données textuelles sans balisage.
|
|
Le contenu de l'étendue |
|
|
INVALID_STATE_ERR : Soulevée si la méthode |
// Introduite dans DOM niveau 2 :
interface DocumentRange {
Range createRange();
};
createRangeDocument
en utilisant les méthodes prépondérantes spécifiques de la liaison.
|
L'état initial de l'étendue |
Les opérations sur les étendues Range peuvent soulever des
exceptions RangeException comme défini dans la description de leurs méthodes.
// Introduite dans DOM niveau 2 :
exception RangeException {
unsigned short code;
};
// RangeExceptionCode
const unsigned short BAD_BOUNDARYPOINTS_ERR = 1;
const unsigned short INVALID_NODE_TYPE_ERR = 2;
Un entier indiquant le type d'erreur généré.
BAD_BOUNDARYPOINTS_ERRRange ne satisfont pas aux obligations spécifiques.INVALID_NODE_TYPE_ERRRange
un nœud d'un type invalide, ou dont un ancêtre est d'un type invalide.