Documents sur Internet
Le document applicatif interne
S'exercer au brouillon
ATTENTION : ce document étant assez technique, il s'adresse plutôt à un lecteur déjà habitué à concevoir des documents en HTML + CSS et connaissant assez bien le langage Javascript.
La notion d'ILO (Interface Linguistique Opérationnelle) est esquissée dans le document de référence d'AlgoDok, dans la dernière partie. Le présent document a pour vocation d'en montrer les principes et les motivations, dans les détails, afin de pouvoir en guider la mise au point.
Avant d'entrer dans le vif du sujet, commençons par rappeler certaines instructions
d'AlgoDok permettant de facilement construire ou manipuler des éléments d'un document
applicatif
, désigné par la suite par le néologisme docapp
.
Sur un élément variable, on peut spécifier un attribut onchange contenant une instruction qui s'exécutera après chaque modification de cette variable par l'utilisateur. On peut donc filtrer la valeur saisie.
On peut modifier l'apparence de la valeur d'une variable numérique, avec l'instruction présenter (nom de variable) .selon (format) où le format de donnée est une chaîne de caractères contenant +v+ pour désigner la valeur de la variable dans la chaîne affichée, ou encore une fonction qui retourne un chaîne de caractères.
Avec la variable
V_sphère = sqrt(9,8696) on peut
Il s'agit bien d'un format de données au sens classique du terme,
pas d'un source HTML ; il suffit d'essayer avec
Comme avec AlgoDok tout élément est potentiellement variable, on utilise souvent insérer, écrire ou mettre.à.jour un contenu, sans passer par un élément var. Cette notion de variable n'est donc qu'une commodité de mise en place d'éléments variables surtout destinée au concepteur de docapp qui ne connaît pas la programmation ou qui veut rapidement faire une maquette du produit final.
Les fonctions insérer et écrire sont particulièrement adaptées aux développeurs de docapps, qui s'en servent alors pour compléter dynamiquement un docapp sur action de l'utilisateur, avec au moins un minimum de connaissances en programmation.
La fonction insérer insère des éléments à partir
d'un source HTML comme on le ferait à la main dans le source originel.
Par exemple, on peut
Cette démarche d'initialisation est générale pour des composants définis par
une balise spécifique. On retrouve cette même logique avec les x-tag, mais sans les contraintes d'un shadow DOM
qui reste encore très
problématique, d'autant plus qu'il est conceptuellement inutile : c'est finalement une simple astuce
pour masquer un contenu lors de l'inspection d'un élément via le navigateur.
La fonction écrire opère comme insérer mais crée un élément skribo
(un écrit
, en espéranto) contenant les éléments définis par le source HTML fourni,
sauf lorsqu'on écrit dans un élément vide, car on écrit a priori pour compléter un écrit déjà
existant dans le source du docapp. Cette modalité permet
une sélection a posteriori des écrits dynamiques via le nom de balise (skribo),
afin de pouvoir traiter tout ce qui a été ajouté par programmation.
On le voit bien sur cet exemple, en deux instructions :
pour (k = 1 ; k < 10 ; k++) { insérer(k + "*") .dans ("le brouillon") ;
écrire(k + "*") .en("color:red") .sur ("le brouillon") } ;
Dans les deux cas, par exemple avec
Le fait de
On rappelle que si on a écrit dans un élément initialement vide seule la première écriture n'est pas encapsulée dans un élément skribo et donc n'est pas supprimée avec une instruction de suppression comme la précédente.
La fonction mettre.à.jour est particulièrement adaptée à
la modification complète du contenu d'un élément ; par exemple
AlgoDok traite touts les composants du document de la même manière, tant les
Elements, que les TEXTAREAs ou un simple Text : il les considère
comme comme des boîtes
qu'on peut remplir avec du texte, interprété comme un source HTML ou non.
Par exemple on peut
la différence
!
Tout Text, c'est à dire tout composant structurel ultime du document, est considéré par AlgoDok
comme ayant aussi un tagName, afin de donner une sémantique primitive similaire
à celle des éléments : STRING. On peut s'en rendre compte facilement,
avec
Tout conteneur d'un composant structurel du document est forcément un Element !
Les instructions décrites dans cette section supposent que les éléments existent ! Elles permettent aussi d'en créer de nouveaux puisque tout source HTML ajouté au document est analysé par le navigateur qui modifie le DOM en conséquence. Cependant, pour des raisons d'efficacité, un développeur de modules aura intérêt à en créer de nouveaux directement dans le DOM.
Pour construire directement un élément du DOM on utilise l'instruction nouvel.élément (balise, classe) qui retourne un objet héritant de Element. On peut aussi utiliser nouveau et nouvelle à la place de nouvel.élément.
Ces fonctions très simples et primitives sont surtout définies pour amorcer des constructeurs d'objets variés via une ILO de module, c'est à dire une Interface Linguistique Opérationnelle.
Si l'on exploite un module avec ILO (voir infra) il est naturel d'utiliser des instructions de création d'éléments structurés, comme nouveau.commutateur .pour ("le préliminaire"). Pour tester l'exemple précédent il faut importer le module Komutilo.
Ce principe de création devient donc insuffisant lorsqu'on veut créer un élément avec un contenu et une classe, en une seule instruction.
On peut utiliser l'instruction créer (id) .un .élément (balise, classe) .contenant (texte) .dans (élément), sachant que l'identifiant, la classe et le contenu sont facultatifs.
Par exemple :
grosparagraphe.") .dans ('le brouillon')
Pour supprimer le style ajouté il suffit alors
d'
On note alors que l'exécution répétée d'une même instruction peut entraîner une alerte, car un identifiant est unique, et qu'on crée un objet identique à chaque fois. On dit que l'on a créé des clones. AlgoDok permet de cloner facilement tout élément du document, mais sans conflit d'identifiants.
Avec l'instruction cloner (un élément) .dans (un autre élément) on duplique le premier pour le mettre dans le second (on peut remplacer dans par avant, après ou au.début.de).
Le clonage d'un TEMPLATE ne clone pas le template lui-même mais l'instance intensionnelle qu'il représente. On préfèrera donc utiliser le synonyme instancier, plus parlant. De toute façon les templates n'ont un intérêt marginal lorsqu'on utilise AlgoDok.
On peut ainsi cloner (le .conteneur (ceci)) .dans ('le brouillon') ou encore
Tous les éléments clonés possédant un identifiant acquièrent aussi un identifiant, obtenu par
un suffixe donnant le numéro du clone ; par exemple en clonant trois fois un élément
d'identifiant Toto, les clones obtenus auront —dans l'ordre de création— les identifiants
Toto.1, Toto.2 et Toto.3 ; la numérotation est spécifique à chaque élément
cloné. Ce principe est appliqué à tout élément contenu dans l'élément cloné, mais le suffixe
est alors le même pour tous.
On peut le mettre en évidence sur les clones créés ici avec l'instruction suivante :
La fonction de déplacement à la souris de tout élément déplaçable
est reprise lors d'un clonage, et donc si par exemple
on clone la mémoire à instructions, le clone sera lui aussi déplaçable via sa poignée.
Ce principe est valable pour toute poignée
de traction d'un élément déplaçable.
Avec les instructions précédentes il convient d'offrir le moyen de voir l'équivalent en source HTML de ce qu'on a créé, comme le ferait un développeur de docapps, au moins pour le debug.
Pour un élément du DOM on peut utiliser source.HTML (un élément) qui retourne une
chaîne de caractères équivalente au source HTML de l'élément.
Par exemple :
Pour un objet Javascript on peut utiliser source.JSON (un élément) qui retourne une
chaîne de caractères correspondant à un source JS donnant les propriétés de l'objet.
Ceci peut être néanmoins assez sommaire dans le cas d'un élément du DOM, et de toute façon ne
permet pas d'être exhaustif (toute propriété n'est pas forcément énumérable).
Par exemple, sans saut de ligne :
On peut utiliser directement l'objet JSON pour obtenir un source avec des sauts de ligne et
des indentations, par exemple, pour avoir une indentation en multiple de 4 espaces :
La section suivante, charnière dans l'approche de développement sans ou avec ILO, complète le rappel de ces instructions.
Les instructions précédentes et, d'une manière générale, la programmation de modules avec ILO
n'interdisent à aucun développeur d'utiliser toutes ses connaissances en HTML, CSS et Javascript
pour faire son travail.
La notion d'ILO
est particulière en ce sens où à la fois elle
est très rigoureuse pour ce qui doit apparaître aux yeux de tous, et très tolérante pour
tout ce qui doit n'apparaître qu'aux yeux du développeur.
Ici le mot développeur
est pris en un sens général :
ce peut être une personne physique comme une personne morale, mais il s'agit bien
évidemment de développement en Javascript.
Il va de soi que toute entreprise a besoin d'obtenir des codes sources
compréhensibles par tout une communauté de ses développeurs, à des fins
de maintenance, adaptative, évolutive ou corrective. C'est alors l'avantage d'une ILO car elle n'impose
aucune méthode du côté du développement algorithmique et qu'on peut plaquer a posteriori
sur des modules existants, pour en offir la portée aux concepteurs de documents applicatifs,
a priori non développeurs en Javascript mais qui peuvent avoir besoin d'instructions
pour piloter le document, c'est à dire sur apporter une dynamique visuelle adaptative au gré des actions
du lecteur/utilisateur.
La notion d'ILO induit une nouvelle approche du développement
de modules en Javascript, réellement orientée utilisateur/lecteur puisque
toute fonction ou objet exploitable de l'extérieur d'un module
doit être compréhensible par un béotien,
afin que ce dernier puisse l'utiliser dans des instructions cliquables lors de la mise
au point de ses documents applicatifs.
Dans les développements informatiques usuels pour le Web,
on est très loin de ce souci de lecture, avec un usage de
fonctions et d'objets dont l'accès est réservé à une communauté de développeurs avertis.
Ces derniers parlent d'ailleurs d'API (Application Programming Interface) : il s'agit bien pour eux de développer des logiciels,
pas d'exécuter des commandes à la volée
, de façon inopinée, comme on peut le faire avec
AlgoDok dans un document applicatif, via la mémoire à instructions
.
Même avec HTML 5 et les Web-components, même si l'approche sémantique du Web est affirmée comme la meilleure pour élaborer un Web 3.0 dont personne ne sait pourtant encore bien définir les contours, même si l'algorithmique est désormais mise à l'ordre du jour dans plusieurs sytèmes éducatifs, on en est toujours à considérer que d'un côté il y a ceux qui utilisent des IHM produites par les autres, ceux qui savent manipuler des langages abscons, à la syntaxe hermétique.
C'est ainsi que le MIT a développé Scratch comme mise en IHM de Logo l'ancêtre constructionniste, avec un environnement destiné aux écoliers. On a imaginé se débarrasser ainsi d'une syntaxe postulée rebutante, par simple généralisation de l'existant (Logo, Pascal, FORTRAN, Lisp, Ada, C, C++, SmallTalk, etc…). Pourtant tout écolier européen ou américain sait dès la troisème année de l'école primaire qu'une phrase commence par une majuscule et se termine par un point : c'est une règle syntaxique qui a justement été mise au point, avant l'imprimerie, pour faciliter la lecture des phrases ! Pourtant n'importe quel écolier peut comprendre un langage écrit avec une syntaxe : le sien. D'ailleurs l'utilisateur de Scratch voit bien un texte, mais qui ne respecte de toute façon pas la syntaxe usuelle en français, comme sur cet exemple simple qu'il est pourtant difficile de comprendre à la simple lecture.
C'est d'ailleurs pourquoi avec AlgoDok on peut exploiter son propre langage, adapté aux besoins d'une classe d'utilisateurs. On a par exemple imaginé un langage, Scribe, avec une syntaxe très proche du langage naturel, dont le but est d'appréhender différemment l'algorithmique, comme on rédigerait des recettes de cuisine, avec une syntaxe usuelle en français.
Ainsi la notion d'ILO est une technique novatrice de communication d'une pensée spécifique
et algorithmique exprimée avec un langage endosubjectif (celui du développeur en Javascript),
via un langage intersubjectif (de tous ceux qui ne connaîssent rien à Javascript),
et le mot interface
n'est ici que le reflet de cette adaptation linguistique,
sans commune mesure avec les interfaces de la programmation contractuelle.
Donc une ILO est d'une part une Interface Linguistique, c'est à dire un moyen de communiquer, non seulement avec des développeurs chevronés mais aussi, et principalement, avec le commun des mortels. D'autre part elle est Opérationnelle car c'est le seul moyen de rendre… opérationnel un module offrant des instructions linguistiques ! C'est ce qui fait la différence essentielle entre les modules avec ILO de ceux qui n'en ont pas, et qu'on va développer dans les sections suivantes.
Un module qui ne propose pas d'instruction linguistique est simplement au service d'autres modules : il n'aura donc pas d'ILO mais seulement une API. Les deux sont approches sont exclusives mais complémentaires.
La compréhension technique de la notion de module avec ILO
en opposition à celle
de module
traditionnel, donc sans ILO,
nécessite au préalable de poser une problématique rarement perçue, mais pourtant fondamentale
dans une approche du développement d'instructions compréhensibles par un béotien, qui
de surcroit ne parle pas forcément anglais.
La notion de module, assez générale en programmation,
conduit souvent les développeurs en Javascript (JS)
à confiner leurs applications dans des objets appelés namespaces
,
avec un accès nécessitant aux autres développeurs de référencer systématiquement
l'objet en question pour accéder aux objets du module (des fonctions principalement, mais
aussi des structures d'objets imbriqués).
L'approche par namespace est justifiée par la construction d'ontologies qui autorisent les développeurs à exploiter un vocabulaire pouvant être commun à plusieurs environnements de travail. Cette approche serait honorable si elle résultait d'un dialogue avec les utilisateurs potentiels, ou au moins des utilisateurs représentatifs, pour s'adapter à eux. C'est loin d'être le cas car en plus on pert le pouvoir d'expression linguistique des langages à objets. Elle permet surtout aux développeurs de ne pas se préoccuper de ce que font les autres développeurs et de concevoir une sémiotique de façon assez débridée, pour ensuite l'imposer aux autres développeurs, ce qui est à la rigueur acceptable mais très contraignant, mais aussi aux utilisateurs, ce qui l'est nettement moins…
Elle a aussi un inconvénient majeur, celui de reposer sur des réseaux sémantques et des taxonomies, mais le développement de ce point sort largement du cadre de ce document. Le lecteur intéressé par l'approche philosophique du sujet pourra consulter un document significatif.
L'approche avec AlgoDok/ILO réserve l'usage de namespace soit implicitement dans le principe même de la
programmation par objets en JS (donc à usage privé), soit pour donner aux développeurs
un moyen de paraméter un module.
Ainsi
C'est d'ailleurs pourquoi, avec AlgoDok, toutes les fonctions mathématiques usuelles ayant un
nom relativement international sont accessibles
sans passer par l'objet Math, tout comme les nombres π et E ; par exemple :
Javascript est un langage à objets qui pousse le raffinement jusqu'à confiner les fonctions mathématiques usuelles dans un objet Math qui leur sert donc de namespace. Ainsi, par exemple, pour calculer l'exponentielle de sin(x) + cos(x), on doit a priori utiliser une expression comme y = Math.exp(Math.sin(x) + Math.cos(x)) ou encore with(Math) { y = exp(sin(x) + cos(x)) }. Écrire de cette manière des expressions algébriques n'est quand même pas bien naturel pour qui exploite couramment les fonctions mathématiques usuelles. En outre, comme ces noms de fonction sont devenus internationaux, tout développeur digne de ce nom devrait a priori les connaître et donc veiller à éviter l'usage de variables globale éponymes.
L'inconvénient de ne pas travailler systématiquement sous la protection d'un namespace est de prendre
le risque qu'un module écrase une variable globale.
Ce risque est en fait mineur si les variables globales utilisées
le sont par la volonté du développeur, avec un nom pertinent par rapport au module et
(re)connu dans l'interface. Il s'agit donc de développer de façon durable
, en évitant
un vocabulaire trop vague et en adoptant une sémantique pertinente.
De toute façon, on peut détecter dans un script une tentative d'écrasement d'une telle variable
en passant en mode strict, en le commençant donc par "use strict"; .
On peut cependant redéfinir ces fonctions dans un module,
par exemple pour un calcul de fonctions avec des nombres complexes.
Il suffit de procéder à une reconfiguration
de ces fonctions globales, par exemple :
D'où l'intérêt des namespaces pour les variables à caractère privé, en particulier pour étendre des fonctionnalités d'un module sans pour autant en changer l'interface linguistique.
La raison souvent évoquée pour promouvoir l'usage de namespace est d'éviter au maximum les variables globales, considérées comme le fléau des programmeurs. Ceci est tout à fait vrai si on ne voit que les langages d'une manière… globale, comme des langages qui ne sont pas à objets, c'est à dire avec une vision un peu datée. En effet cette notion de variable globale perd de sa force dans un contexte de programmation à objets puisqu'une variable d'objet x porte la référence de l'objet en question et donc ce dernier peut (et c'est même le cas général !) varier tandis que le contenu de x ne varie pas.
C'est d'ailleurs ce qui rend le test d'égalité d'objets
problématique,
puisque la seule égalité immédiatement compréhensible est celle des références. Pour y voir
plus clair, il faudrait plutôt parler d'égalité structurelle, ou d'égalité de modèles,
mais ceci sort du cadre de notre propos.
Le cas de Javascript est assez particulier car non seulement c'est un langage à objets, ce
qui n'a rien d'extraordinaire en soi, mais tout constructeur d'objets est en fait une
propriété d'un objet unique, appelé… Global
en ECMAScript, donc est une variable globale.
Les fameux namespaces
n'échappent pas à cette règle : ce sont des variables globales.
On ne peut donc finalement rien construire en Javascript sans utiliser des variables globales ;
au mieux peut-on en limiter le nombre.
En fait dans l'environnement d'un navigateur, l'objet Global
est window ; donc si vg est une variable globale, c'est aussi
window.vg ; on le constate par exemple avec
l'instruction cliquable suivante :
Donc si on n'échappe pas aux variables globales en JS, il est important de savoir comment on peut s'en servir raisonnablement et habilement.
Ainsi, limiter au maximum les variables globales restreint la portée de Javascript en le réservant aux initiés, ceux qui savent programmer avec une notion informatique d'objet incontournable.
Ce n'est pas le cas avec AlgoDok qui permet l'inverse : tout concepteur de documents, pour peu qu'il connaisse les bases de HTML et sache lire un texte dans sa langue peut comprendre toute instruction linguistique, la copier et l'utiliser à bon escient, sans beaucoup de risque de se tromper. C'est le fondement même du document applicatif : la partie applicative non modulaire est modifiable par un concepteur de documents, sans connaissance spécifique en Javascript.
Le langage Scribe déjà évoqué n'est que le cas particulier d'un langage qui servira de compagnon privilégié pour tout concepteur de document voulant lui apporter de la dynamique, tout en étant réticent à l'usage d'une syntaxe particulière. On ne peut pas être effrayé par celle de sa langue maternelle ! C'est en particulier essentiel pour qui veut développer des documents pédagogiques interactifs en y mettant le plus de créativité personnelle possible.
On pourrait alors penser que la notion d'instruction linguistique est un inconvénient majeur, puisque le source d'un script étant toujours visible entièrement par le lecteur d'un document qui en contient, tout lecteur pourrait comprendre le code source d'un module et donc un développeur en peine de source à intégrer dans ses applications.
En fait ces instructions linguistiques représentent le seul moyen d'accéder aux ressources
fonctionnelles des modules, puisqu'à la mise en service du module
le code sera brouillé
(au sens de brouiller les pistes, donc obscurci
) rendant
inintelligible la partie algorithmique.
La mise au point de ces instructions revient alors à définir une
Interface Linguistique Opérationnelle (ILO) permettant au développeur de
s'exprimer dans la langue des utilisateurs, avec leur vocabulaire et
avec leur syntaxe, tout en ayant mis au point son module à sa façon,
c'est à dire avec son propre vocabulaire et les structures de données qui lui conviennent,
namespaces compris.
Le brouillage du code n'est donc à faire que si l'on veut préserver le source du développeur,
indépendamment de la mise au point de l'ILO, dont le but est de rendre intelligible son accès,
en langage naturel, mais complété par une syntaxe acceptable en Javascript. Donc
brouiller n'est pas offusquer
, au sens informatique usuel du terme.
offusquer
Pour préserver les droits d'auteur, les développeurs de modules
masquent en général la sémantique de leur code originel en le passant dans un offuscateur
,
qui souvent fait aussi office de minifieur
car il réduit sensiblement le source à charger
par le navigateur (en divisant couramment par deux ou trois la taille du source).
La notion d'instruction linguistique entraînant celle d'ILO,
la préservation des droits d'auteur nécessite de ne pas tout offusquer
puisque
justement une partie doit être préservée, celle exploitable par un
non-informaticien. Comme à un même code originel peut
correspondre autant d'ILO que de langues naturelles, voire même de jargons,
les outils habituels d'offuscation sont inadaptés. Et c'est là un point
essentiel puisque le développeur d'un module avec ILO doit s'adapter à la syntaxe et à la sémantique
de l'utilisateur.
Avec AlgoDok on utilise un outil spécifique développé en Python, appelé brouilleur,
intimement lié à la notion d'ILO. On doit commencer par en comprendre les principes,
en particulier celui de l'exploitation systématique de variables globales, pour bien saisir
la différence entre brouiller
et offusquer
.
La notion de document applicatif décrite ici est consubstantielle de celle d'instruction linguistique. Elle impose que la lecture des instructions soit conforme à un langage naturel et exprimable en plusieurs langages : le développement de modules en Javascript est pourtant possible en laissant une grande liberté d'expression algorithmique au développeur, à condition d'exploiter la notion de module avec ILO, c'est à dire avec une Interface Linguistique Opérationnelle dont les principes et motivations sont détaillés ci-dessous.
Comme on l'a expliqué précédemment, la notion de namespace
souvent utilisée avec le principe d'encapsuler
tous les objets d'un module dans un seul objet, n'a pas le même sens avec le
principe des instructions linguistiques, puisqu'il est constitutif de la notion de document applicatif
tel qu'il est décrit ici. On favorise plutôt l'usage
de variables globales, mais avec une technique de conception qui élimine quasiment le risque de collision
entre les noms des variables définies dans plusieurs modules.
Pour ce faire, les instructions linguistiques d'un module sont définies dans un source Javascript appelée ILO (Interface Linguistique Opérationnelle), indispensable pour accéder aux variables globales d'un module mis en service, puisque potentiellement définies par un brouilleur, avec d'une part le souci du respect du droit d'auteur, et d'autre part celui de la lisiblilité par un néophyte, dans sa langue maternelle, donc dans une langue vernaculaire.
Un développeur peut très bien décider d'utiliser un namespace pour stocker toutes les
informations privées
dont il a besoin, du moment qu'il n'impose pas de l'utiliser
dans l'interface linguistique.
Le mot ILO
signifie outil
en espéranto,
langue dans laquelle les noms communs n'ont pas de genre. Le code brouillé d'une fonction
reste encore compréhensible pour son concepteur, puisqu'aucun nom de variable locale n'est changé
et que le concepteur dispose du source originel !
Ainsi, dans le contexte d'AlgoDok, une ILO est la seule partie sémantiquement exploitable d'un module, tant pour les concepteurs de documents applicatifs que pour les développeurs de modules : elle utilise donc les variables globales comme un moyen de s'exprimer avec le moins d'ambiguïté possible.
Néanmoins, comme pour le reste du module, cette partie est la propriété de son concepteur. Elle n'est donc pas destinée à être lue par un autre développeur, mais à servir de traduction bidirectionnelle entre langage endosubjectif, celui du développeur, et un langage intersubjectif, celui des concepteurs de documents applicatifs, developpeurs de modules ou non, qui exploitent des instructions linguistiques.
Une telle interface peut exister en plusieurs langues et doit être décrite dans un document à part, comme celui-ci (contenant ces lignes !) ou comme celui-là (Formulo). Toute ILO est définie par le développeur du module qu'elle interface, et passe en même temps que le reste du module dans un brouilleur qui permet de conserver la partie linguistique (intersubjective, de l'utilisateur) tout en expurgeant le module de toute la sémantique (endosubjective, du développeur).
Pour mettre au point un module avec ILO, appelé génériquement ici CeModule, on utilise plusieurs sources et plusieurs langages informatiques (HTML, CSS et Javascript), définis ci-dessous dans l'ordre chronologique du développement :
RAPPEL :
ici développeur
désigne une personne physique ou une personne morale.
neuve; le module brouillé (livré) sera alors appelé CeModule.js.
Tant qu'un module n'est décliné qu'en une seule langue, on peut éviter de suffixer les noms avec le code ISO 639-1 de la langue, et l'ILO peut être incluse dans CeModule-new.js.
On peut aussi développer des modules de portée assez faible, avec ou sans ILO mais sans documentation explicite, qu'on appelle micro-modules s'ils font moins de 1 Kio de source (éventuellement brouillé) ou mini-modules s'ils font entre 1 et 2 Kio de source (éventuellement brouillé). Pour en savoir plus à ce sujet, le mieux est d'étudier des exemples.
En fait la mise en service d'un module dont on veut garder le source originel entraîne la création d'autres sources javascript, via un brouilleur.
Une longue pratique de la programmation et des mathématiques d'une part, et d'une recherche sur la modélisation des connaissances d'autre part, a conduit le développeur d'AlgoDok à affirmer qu'il est plus efficace d'utiliser des fonctions en grand nombre, mais au source réduit, avec un usage d'abréviations pour les variables locales (pour l'aspect algorithmique), mais bien commentées (pour l'aspect sémantique), que de manipuler des noms à rallonge dans le but de garantir a priori une meilleure lisibilité du code, comme il est souvent conseillé aux débutants en programmation.
Conçu ainsi, le source d'un module ne nécessite pas qu'une offuscation soit sophistiquée
pour être efficace : il suffit déjà d'enlever tous les commentaires et tous les espacements inutiles,
en particulier les sauts de ligne, et la compréhension en devient impossible, même avec
beaucoup d'attention, à la seule condition d'enlever aussi la sémantique des fonctions.
Mieux, si l'offuscation garde les noms des variables locales,
elle rend quand même possible des modifications circonstanciées (patches
),
d'adaptation à une nécessité contingente, puisque le développeur peut facilement faire le lien
avec le source originel.
Ce qui n'est pas le cas des outils usuels d'offuscation
qui ne gardent pas les noms originels des variables locales,
les programmes étant alors réduits à un aspect purement algorithmique
,
vidé de toute sémantique, empêchant même le concepteur de s'y retrouver.
Avec AlgoDok on utilise un logiciel spécifique développé en Python, appelé brouilleur
et intimement lié à la notion d'ILO :
Le brouilleur remplace toutes les occurences des noms de variables du module commençant par le $ caractéristique, par des noms commençant eux aussi par $, sans aucune sémantique. Comme un concepteur de documents applicatifs n'a évidemment aucune raison d'utiliser de telles variables, ce principe assure la disjonction entre l'ensemble des variables utilisées par les développeurs et l'ensemble de celles définies par les utilisateurs de modules, développeurs de modules ou non.
Ainsi la seule contrainte pour le développeur d'un module avec ILO est de préfixer toutes les variables globales qu'il utilise par un $, et il peut même n'en garder qu'une avec ta technique du namespace (mais ses propriétés ne seront pas brouillées, par principe). Ce qu'il peut même facilement faire a posteriori et qui ne surprendra pas de nombreux développeurs ayant aussi l'habitude du PHP. Le brouilleur garantit ainsi que la sémantique de ces — ses — variables sera évacuée et que plusieurs modules pourront cohabiter dans un même document applicatif, même avec des noms originels identiques, sans risque de collision ni entre les variables des différents modules, ni entre celles définies au sein du document applicatif.
C'est pourquoi le développeur peut très bien se passer d'un namespace de module pour éviter des conflits éventuels en cas de vocabulaire polysémique, permettant ainsi l'expression de réelles instructions linguistiques :
Le code originel du développeur est :
Le code brouillé correspondant est :
On note que tous les noms des variables locales
(de un à trois caractères) sont conservés, conservant ainsi l'aspect algorithmique
du module défini implicitement par une telle fonction.
Dans l'ILO, brouillée en même temps que le reste, on trouve alors :
Dans la documentation de référence (non fournie ici, car la mettre au point fait partie d'un processus de formation), on peut alors trouver :
L'instruction identifier (élément) .par (identifiant)
permet de donner un identifiant à un objet qui n'en a pas. Par exemple on peut
Une alerte est émise lorsqu'on cherche à identifier un élément déjà identifié, comme
avec identifier .directement (le .successeur .de (ceci)) (ici, une petite boîte insignifiante) .
Dans la conception d'un module avec ILO, seule cette dernière permet de le rendre exploitable, qu'il y ait brouillage ou non. Elle doit donc faire l'objet d'exemples et être décrite par un document applicatif spécifique comme celui que le lecteur est en train d'étudier, pour AlgoDok. Ainsi aucun utilisateur du module n'a besoin d'étudier le source de l'ILO pour l'exploiter : c'est au manuel de référence d'expliciter les instructions linguistiques et leur usage.
Néanmoins, tout développeur doit pouvoir agir en fonction de la présence de certains modules, donc de certaines instructions linguistiques. D'où une fonction spécifique : module (nom du module) qui retourne un objet contenant certaines informations pertinentes et laissant l'opportunité de paramétrer le fonctionnement du module. Dans un contexte pluri-linguistique, cet objet permet en particulier de savoir quelles langues sont utilisées ; ainsi, par exemple, avec module('IDoni').fr on peut tester la présence du module IDoni avec une ILO française.
Connaître la présence d'AlgoDok, ou de tout autre module, est indispensable dans le cas où l'on développe un module pouvant aussi bien être utilisé avec lui que sans lui, mais on doit aussi pouvoir paramétrer certains modules, surtout les signifiants utilisés et les messages d'alerte. Donc certains objets ou éléments sont présents mais sans une présence visuelle, ou bien ont une signification particulière qu'il est préférable de connaître avant de développer un module.
C'est pourquoi le nom du module sert de namespace
:
chaque module avec ILO doit définir un objet éponyme
qui peut fournir un moyen de le paramétrer, ou au moins
d'en paramétrer les signifiants (indispensable dans un contexte pluri-linguistique).
Alors le lecteur peut modifier les affectations précédentes puis en tester l'effet
avec les instructions suivantes :
Tout module avec ILO présentera donc des éléments linguistiques potentiellement variables dont les plus importants seront mentionnés dans la documentation de référence, comme dans le cas d'AlgoDok, rappelés ci-dessous car il est l'archétype du module avec ILO.
Cette partie donne des possibilités de test d'état et de configuration du module AlgoDok, l'incontournable premier module des documents applicatifs, au sens développé ici. Elle permet de comprendre l'ensemble des propriétés de l'objet AlgoDok, en particulier celles définissant son paramétrage sémantique, et fournit donc un exemple riche pour savoir comment élaborer des modules avec ILO.
Le booléen AlgoDok.chargé est mis à vrai après le chargement complet
d'AlgoDok, donc après l'exécution de toutes ses initialisations.
Donc il est souvent préférable d'utiliser une instructions du genre
On dispose aussi de AlgoDok.sxargxita pour l'espéranto et AlgoDok.loaded pour l'anglais. Pour les événements du DOM, on peut étudier une documentation spécifique.
On peut fournir des informations aux modules d'un document applicatif (modules avec ou sans ILO) en les inscrivant après son URL. Alors AlgoDok se contente de mémoriser dans AlgoDok.param cet éventuel paramétrage du document applicatif, situé en fin d'URL après un point d'interrogation séparateur.
A priori un module ne modifie pas cette chaîne de caractères, mais on laisse la liberté de
la modifier, soit pour masquer les informations adressées à module particulier (on en consomme
alors une partie), soit pour qu'un module puisse en paramétrer un autre.
On pourrait préférer imposer un format JSON au paramétrage, avec des namespaces pour chacun des modules, mais il est préférable de privilégier le point de vue du lecteur : il doit comprendre facilement ce qui est écrit dans l'URL (sauf évidemment si elle est construite dynamiquement et à son insu). C'est conforme à l'objectif premier d'AlgoDok et des autres modules avec ILO : faciliter la lecture d'un document applicatif, quel qu'il soit, en réservant l'aspect purement algorithmique à des modules externes, uniquement écrit en Javascript.
On passe le paramètre ceci est un paramètre à un document applicatif d'URL http://XXX ··· XXX.html sous la forme : <a href="http://XXX ··· XXX.html?ceci est un paramètre"> Exemple de passage de paramètre </a>. Exemple : http://www.algodok.com/Algorithmique/Algorithmique en Algo.html?On gèle ici. .
Comme il faut pouvoir s'adapter aux contraintes de présentation des utilisateurs, on
peut charger des feuilles de style particulières, pour compléter ou changer complètement
la feuille de style de base, dont le nom est consigné dans AlgoDok.css, dont
le nom par défaut est canonique :
Par exemple on peut
SOURIS
La fonction position(e) retourne un objet { x : ···, y : ··· }
où l'unité des coordonnées est a priori implicite : un pixel.
Exemple :
La position par rapport au document est dite absolute
dans le
langage des CSS, tandis que celle par rapport à la fenêtre de visualisation est dite fixed
.
Si la première est a priori la plus naturelle pour positionner des objets dans le document,
comme la notion de position est surtout destinée à placer des objets au bon endroit
fixed
.
Exemple :
Pour une CSS, la notion de position dépend de la nature du positionnement de l'objet : position:absolute ou position:fixed. Si l'on ne fait pas défiler le document par rapport à la fenêtre de visualisation, les coordonnées d'un point sont les mêmes dans les deux repères.
La mémoire à instructions
, le nom du document
et les éléments déplaçables (à la souris)
sont en position fixed
: leur position par rapport à la fenêtre est plus naturelle que
celle par rapport au document.
Ainsi l'ordonnée absolue
y est déterminée par rapport au coin supérieur gauche du document,
et donc peut être négative ou largement supérieure à la hauteur de l'écran.
Il en va de même avec l'abscisse. Ce positionnnement en nombres relatifs est aussi valable
pour le positionnement par rapport à la fenêtre de visualisation. Exemple :
Lorsqu'on déterminer des déplacements, peu importe le repère puisqu'on
calcule alors des différences d'ordonnées ! On peut aussi utiliser les synonymes
pageXOffset et pageYOffset. Ces variables étant en lecture seule,
on utilise les instructions scrollTo et scrollBy pour faire défiler le document ;
par exemple
Le nom AlgoDok.musnomo désigne une variable contenant le nom de la souris dans la langue utilisée
(
Tout développeur peut s'entraîner à modifier les valeurs suivantes et en voir l'effe. On doit noter cependant que seules les items écrits sur fond blanc traitent des paramètres modifiables une fois le document chargé. Les autres servant à paramétrer AlgoDok, elles doivent être affectées dans un module qui le suit dans l'élément HEAD, afin de pouvoir travailler convenablement, en particulier pour définir une autre ILO.
undefined.
caché(i.e invisible).
Il existe d'autres propriétés d'AlgoDok définies dans l'ILO, mais plutôt spécifiques aux développements des ILO d'AlgoDok, donc exploitables presque exclusivement par le développeur d'AlgoDok.
Ainsi le développeur d'un module avec ILO peut le gérer en fonction d'un contexte linguistique variable, avec une réelle efficacité. En particulier il peut facilement étendre les instructions linguistiques des autres modules avec ILO, avec une simple connaissance de la structure systématique des instructions linguistiques, puisque toute fonction en Javascript est un objet et que tout objet est un tableau associatif.
On appelle souvent dictionnaires
ces structures associatives qui, en Python comme dans la plupart des langages à objets, sont des objets d'une classe particulière.
Mais
Bien entendu, pour des raisons d'optimisation à l'exécution, ces derniers ne sont pas directement modifiables en tant qu'objets, sauf si on les définit via leur constructeur, comme on peut le comprendre sur l'exemple suivant, en utilisant la notation pointée :
Tout objet en Javascript est ainsi vu comme un tableau associatif.
Une instruction de la forme j_e = JEDI.prénom.toLowerCase(), en notation pointée
,
équivaut à j_e = JEDI['prénom'] .toLowerCase () ou même à
j_e = JEDI['prénom']['toLowerCase']().
La forme en notation pointée n'est valable que pour des noms de variable
acceptables en Javascript, tandis que
Cette souplesse permet de pouvoir compléter des objets existants, en particulier pour définir ou étendre la syntaxe d'instructions linguistiques déjà définies.
On peut affiner la définition de toute propriété d'un objet, mais on doit alors utiliser la propriété defineProperty de la classe Object. Les explications sortent du cadre de ce document, mais le lecteur intéressé peut consulter une documentation précise sur le sujet.
Il est fondamental de comprendre que toute fonction en Javascript est un objet, donc que toute instruction linguistique est un objet, qu'on peut donc éventuellement compléter pour enrichir, via de nouvelles propriétés, un corpus d'expressions linguistiques déjà définies.
Il faut néanmoins prendre quelques précautions pour éviter
d'écraser les propriétés existantes (ce qui peut aussi être volontaire et habile !).
On peut facilement lister les propriétés — énumérables — d'un objet ; par exemple :
Par exemple, après l'affectation
Mais il faut faire attention car une propriété peut ne pas être (ré)affectable
voire ne pas être énumérable tout en étant (ré)affectable (voir un exemple).
La compréhension de ces subtilités est en général inutile pour développer des modules
en Javascrit (pour les détails : étudier la documentation spécifique).
Avant de penser à modifier de telles instructions, il vaut mieux commencer par en définir soi-même, par exemple en étudiant celles, nombreuses, d'AlgoDok.
La liste exhaustive des instructions de l'ILO-fr d'AlgoDok peut-être étudiée avec profit afin de s'imprégner du principe de définition des instructions linguistiques, qui, pour mériter ce vocable, doivent simplement pouvoir être comprises à leur simple lecture par un béotien.