Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Intégration de l'éditeur

Cette page vient d'être traduite, mais elle a besoin d'un relecteur différent du traducteur. Pensez également à toujours vérifier le contenu avec sa toute dernière version en anglais.

Introduction

Ce document présente les possibilités actuelles d'intégration d'un éditeur, les problèmes causés par l'intégration existante, quelques scénarios d'intégration possibles pour s'en sortir, et une solution d'intégration pour les réaliser. Pour finir, la solution retenue sera décrite étape par étape.

Mises en œuvre possibles de l'intégration

Ici sont décrits des scénarios d'intégration nécessaires pour faire fonctionner un éditeur. Notez que j'utilise le terme de « Compositeur » pour désigner une interface de composition au format HTML qui fait de l'édition de texte enrichi et « Éditeur » pour un éditeur en texte brut (aussi bien que pour la technologie sous-jacente du compositeur). <htmlarea> est vu comme une formule pour désigner un objet texte contenant du texte enrichi, cela ne veut pas dire pour autant que cette balise sera supportée dans les versions suivantes de Mozilla.

Compositeur intégré dans une application XUL

Les développeurs ont besoin d'intégrer des compositeurs dans leurs applications XUL en utilisant la balise <editor>, comme cela se fait aujourd'hui. Ils devraient avoir le moins possible de travail à faire pour obtenir les fonctions basiques d'édition, avoir autant d'<editor>s par fenêtre qu'ils le souhaitent et pouvoir contrôler si ces <editor>s sont en mode HTML ou en mode texte.

Compositeur intégré dans une application native

Dans ce cas de figure, l'<iframe> dans laquelle fonctionne l'éditeur est directement intégrée dans l'application native. Cela revient à intégrer un navigateur via nsIWebBrowser, mais en obtenant, à la place, un document éditable. L'interface du compositeur (barres d'outils, etc.) doit être implémentée à partir des éléments d'interface graphique présents dans le conteneur ou en utilisant du XUL. Cette interface doit être configurable, avec notamment des barres d'outils flottantes déplaçables (dockable ?), une même barre d'outils pour plusieurs objets compositeur, ou une pour chaque.

Ce type d'intégration requiert que le code du compositeur fonctionne quelle que soit l'interface utilisateur (IU). La communication entre le noyau de l'éditeur et l'interface utilisateur doit pouvoir passer par une ou plusieurs interfaces qui isolent l'éditeur de l'application hôte. (L'nsEditorShell existant fait des suppositions sur l'hébergement de document XUL, qui doivent être contredites.)

Compositeur intégré dans une page web (<htmlarea>)

IE 5 supporte l'élément <HTMLArea> ; si Mozilla travaille à supporter quelque chose de similaire, l'éditeur devra être intégrable dans la mesure du possible. Il est probable qu'on utilise XBL pour implémenter ce type d'objet, comme c'est prévu pour d'autres types de contrôles.

Dans le cas de l'intégration du compositeur dans une application native, il est donc ici nécessaire de rendre l'interface utilisateur configurable, de façon que l'on puisse aussi bien l'afficher comme une barre d'outils au dessus de <htmlarea>, comme une fenêtre flottante, ou comme une barre d'outil de haut-niveau (top-level).

Problèmes connus

L'architecture du compositeur existant a été créée alors que d'autres parties de Mozilla étaient encore en cours de développement. Il en résulte de nombreux points faibles et anachronismes. Cette section décrit ses défauts majeurs.

Problème d'appartenance de l'éditeur

L'éditeur d'une fenêtre compositrice appartient au nsEditorShell, qui à son tour est créé, dirigé et détruit par nsEditorBoxObject. L'objet box est une structure de présentation qui appartient aux noeuds de contenu et survit à la destruction/reconstitution de la frame. L'objet box a également une référence vers le docShell de la frame éditrice. XBL créé un nsEditorBoxObject pour chaque balise <editor>, et permet à Javascript d'accéder aux propriétés de cet objet box (tel que le nsIEditorShell). La balise <editor> est tout simplement une <iframe> dans laquelle l'éditeur est créé. Dans les autres aspects, il se comporte comme une <iframe> XUL.

Le problème avec ce modèle d'appartenance est qu'il ne peut y avoir qu'un éditeur par balise <editor>, alors que le document chargé dans l'<iframe> peut très bien contenir de multiples <iframe>s (dans le cas d'un document frameset ou dans un document contenant lui-même un <html:iframe>). Aujourd'hui, le compositeur ne fonctionne pas très bien avec ce types de document.

Limitation d'un éditeur par fenêtre

Le compositeur construit sur une architecture XUL/C++ s'est développé sur le présupposé qu'une seule balise <editor> par fenêtre suffirait. Lors de la construction de la fenêtre, nous prenons l'editorShell de l'élément <editor> que l'on met dans window.editorShell. A partir de là, beaucoup de Javascript dans editor.js, ComposerCommands.js et les différents fichiés JS de dialogue s'assurent de pouvoir atteindre le seul bon éditeur via window.editorShell. Ce présupposé manquait de clairevoyance et doit être corrigé.

L'éditeur suppose une structure de document XUL

Du code C++ et JS présent dans l'éditeur suppose que celui-ci se trouve dans un document XUL et qu'il y ait des nœuds du document XUL en dehors, dont les attributs peuvent être récupérés pour changer l'état de l'interface utilisateur (par exemple le style des boutons). Cela doit être changé pour permettre aux conteneurs d'utiliser leurs propres apparences, probablement natives. L'éditeur doit pouvoir faire des appels à travers une ou plusieurs interfaces quand il communique avec l'interface utilisateur.

Objectifs de l'intégration

L'éditeur requiert des changements de conception de façon à ce que les applications intégrées soient fonctionnelles. Ces changements doivent nécessairement prendre en compte les problèmes existants. Brièvement, les objectifs de l'intégration sont :

  • <editor> devrait vous offrir un éditeur fonctionnel dans une application XUL
  • possibilité d'avoir plusieurs <editor>s par fenêtre XUL
  • possibilité d'intégrer une frame éditable dans une application native
  • Les conteneurs devraient être capables de fournir leur propre interface (barre d'outils, etc).

Atteindre ces objectifs doit également permettre de résoudre les problèmes suivants, liés au compositeur :

  • il doit pouvoir traiter les documents de type frameset
  • il doit pouvoir traiter les documents contenant des <iframe>s
  • il ne doit pas dépendre d'une structure de document XUL donnée

Solutions proposées

Régler les problèmes d'appartenance de l'éditeur

Comme décrit plus haut, les liens d'appartenance (racines) de l'éditeur doivent être changés de façon à ce qu'un éditeur se trouve au plus haut niveau du nsDocShell, plutôt que d'être accroché à l'objet nsEditorBoxObject. Il doit y avoir un docShell par <iframe> éditable. Cela implique :

  • Faire une nouvelle interface : nsIEditorFrame qui est exécutée par nsDocShell ou une classe liée. On doit pouvoir faire appel à l'une d'entres elle à partir de nsIDocShell, si l'appel réussit, il indique que la frame est éditable. nsIEditorFrame doit contenir des méthodes pour obtenir la session d'édition et faire certains traitements génériques liés à l'éditeur (probablement commun à l'édition HTML et texte brut). Une partie de nsIEditorShell devraient probablement passer dans cette interface. (Cela devrait être analogue à l'interface [https://lxr.mozilla.org/seamonkey/sou...Navigation.idl nsIWebNavigation utilisée par le navigateur.)
  • Quand on aura un éditeur par docShell, charger un document frameset ou une page avec une iframe dans le compositeur instanciera plus d'un éditeur de bas-niveau. Nous avons besoin d'un concept de "session d'édition" - pour avoir un seul document de haut-niveau éditable qui puisse incorporer plusieurs éditeurs. Cette interface s'appellerait nsI????. L'IU de haut-niveau et le code intégré doivent communiquer avec cette interface de session d'édition sans connaitre les éditeurs sous-jacents. La session d'édition enverra les commandes aux éditeurs individuels en fonction du focus et gérera l' annuler/rétablir entre eux.
  • La solution alternative  : Plutôt que d'avoir de multiples éditeurs, dans ce scénario on pourrait avoir un seul éditeur capable d'enregistrer et de restorer un état, de sorte qu'il puisse être transmis entre les différents sous-documents édités. Cette état doit inclure le document, la pile d'actions 'annuler' et l'état de la saisie (? typing state). La mise en place de la session d'édition permettra la permutation de l'état de l'éditeur en fonction du changement de focus ect.

Plus d'un éditeur par fenêtre

Les clients compositeurs basés sur Mozilla supposent tous qu'il n'y a qu'une balise <editor> par fenêtre. Ils ont tous besoin de fonctionner avec plusieurs éditeurs. Corriger cela nécessite des modifications JS de cette ordre :

  • Standardiser la façon dont les clients obtiennent l'editorShell (ou son remplacant, travail post-intégration) à partir de la fenêtre.
  • S'assurer que les changements de focus entre éditeurs mettent bien à jour la notion de session courante de la fenêtre. Si on continue à utiliser window.editorShell, il doit être mis à jour pour supporter les changements de focus.
  • S'assurer que chaque éditeur est correctement construit lors de la création de la fenêtre et supprimé lors de destruction de la fenêtre.
  • S'assurer que les tests de fermeture de fenêtre (par exemple appelé window.tryToClose) consultent convenablement l'état de chaques éditeurs.

Isoler l'éditeur de l'interface

Le compositeur doit ne rien connaitre de l'IU qui le contrôle. Le plan est d'isoler le compositeur de l'IU via une nouvelle interface que le conteneur implémente. N'importe quel IU qui est aujourd'hui créée par le compositeur doit passer par cette interface.

  • Utiliser une nouvelle interface, nsIEditorUserInterface pour diffuser la communication entre l'éditeur et l'IU. Un conteneur pourrait avoir besoin de l'implémenter pour avoir des menus et barres d'outils natives. Dans le compositeur, on aurait une implémentation en JS qui communique avec les commandes existantes et met à jour les noeuds XUL.
  • Corriger le code JS et C++ qui s'adresse explicitement à des éléments dans le document XUL pour passer par nsIEditorUserInterface.

Les étapes de l'intégration

Cette section tente de préparer un plan d'implémentation, dans le but de garder tout en état de marche étape après étape (? as the various steps are taken). Certaines de ces tâches peuvent être faite simultanément.

  1. Décider comment implémenter le support d'une session édition muti-éditeur
  2. Éliminer les interdépendances spécifiques entre le compositeur et le document XUL, via nsIEditorUserInterface
  3. Créer un goulet d'étranglement pour communiquer avec l'éditeur qui a le focus; s'assurer que les changements de focus mettent bien à jour l'état
  4. Faire du docShell,le propriétaire de l'éditeur, créant nsIEditorFrame
  5. Créer l'API de la session d'édition qui s'occupera des collections d'éditeurs (ou rendre l'éditeur refocusable)

Questions ouvertes

Ou doit se trouver la logique d'ouverture et enregistrement de fichier ?

Il semble que certains conteneurs voudront composer leur logique d'ouverture et enregistrement de fichier, d'autres non. Ou devrait se trouver cette logique ? Peut-elle être en JavaScript ? Bien sur, un conteneur doit pouvoir utiliser ses propres boîtes de dialogue Ouvrir et Enregistrer et communiquer avec le compositeur pour coordonner le processus d'ouverture et enregistrement.

Réponse possible

Le conteneur fournit les boîtes de dialogue Ouvrir et Enregistrer s'il le veut. Dans le compositeur, on peut adopter (? pose) ces boîtes de dialogue à partir de JS (? certains problèmes liés à nsIFile ont été résolu - once some nsIFile problems have been solved).

Toute l'IU du compositeur doit-elle être remplaçable ?

Une immense partie de l'IU du compositeur se trouve dans les différentes boîtes de dialogue pour l'édition des tableaux, liens, images etc. Doit-on donner la possibilité à un conteneur de remplacer tout cela par une IU native ?

Réponse possible

Les boîtes de dialogue utilisent les API de l'éditeur disponible pour obtenir et affecter les données, donc elles peuvent faire tout leur travail en passant par les API existantes. Si un intégrateur veut une IU entièrement native, il aura à coder ses propres boîtes de dialogue et logiques associées, mais les API devraient toujours leurs être accessibles. Il semble que ce ne soit pas une bonne solution.

Informations sur le document d'origine

Étiquettes et contributeurs liés au document

Étiquettes : 
 Contributeurs à cette page : teoli, Jeremie, CedricP, BenoitL, Worms, Kyodev, Bellerophon
 Dernière mise à jour par : teoli,