Bilan provisoire

Nous avons jusqu’ici développé une mécanique maison qui réalise déjà quelques petites choses pas inintéressantes :

  • Une page dédiée au réglage des valeurs par défaut, accessible tout à la fois depuis la page des extensions et le menu Réglages de WordPress.
  • L’ajout dans la barre d’outils de l’éditeur d’un bouton qui ne s’active que lorsque notre extension est applicable.
  • Une fenêtre de paramétrage permettant au rédacteur d’ajuster tout à loisir les caractéristiques de l’image mais aussi d’élargir ou de réduire la portion de texte impliquée dans l’alignement.

Les esprits chagrins ne manqueront cependant pas de souligner qu’il nous reste encore beaucoup à faire :

  • En premier lieu, nous débrouiller pour que notre fenêtre de paramétrage n’affecte pas comme elle le fait actuellement la visibilité sur le contenu de l’article. Il s’agira de la positionner dans le coin supérieur droit, de diminuer l’opacité du cadre modal qui l’entoure et d’autoriser par la ruse le scroll sur l’article de façon à délivrer un meilleur aperçu du texte sélectionné.
  • À l’ouverture du pop-up :
    • s’il s’agit d’une première application de notre extension, assurer la sélection du premier bloc de texte qui suit l’image.
    • s’il s’agit d’un update, sélectionner tous les blocs de texte impliqués dans l’alignement.
  • Gérer au mieux l’état des boutons + et en fonction du texte susceptible d’être impliqué dans l’alignement.
  • Mettre enfin en place la mécanique qui permettra d’assurer une visualisation de l’alignement dans l’éditeur tout en gérant les éventuelles modifications des paramètres y compris la suppression de l’effet.
  • Assurer une transition sans encombre du mode Visuel au mode Texte de l’éditeur.
  • Surveiller les modifications apportées par le rédacteur au contenu affecté par notre extension (déplacement ou suppression de l’image, modification du texte, etc.) et rectifier la structure en conséquence.
Donner de la visibilité au contenu

Voilà qui sonne comme le slogan d’un professionnel du référencement. Mais il s’agit en l’occurrence de tout autre chose : en l’état, notre pop-up de paramétrage apparaît au centre de la fenêtre du navigateur sur un fond sombre qui dissimule en grande partie le corps de l’article. L’aspect modal n’est certes pas dépourvu d’intérêt en ce sens qu’il limite les interventions de l’utilisateur à notre fenêtre et à elle seule et prévient donc toute modification intempestive du contenu durant l’édition des paramètres. Néanmoins, il restreint drastiquement la vision d’ensemble d’autant plus qu’il interdit de scroller au sein de l’article pour garder un œil sur les portions de texte sélectionnées.

Pour régler cet épineux problème, nous nous appuyons sur l’événement onOpen de notre fenêtre ainsi que sur quelques petits bouts de jQuery auquel nous sommes contraints de recourir pour palier les insuffisances de la classe DomQuery de tinyMCE qui n’implémente pas la gestion des dimensions.

Que voici donc un aperçu de la chose :


 

Les mains dans le cambouis

Pour la gestion des blocs de texte, nous allons recourir à deux tableaux : selectedTextArray qui contiendra les blocs de texte impliqués dans l’alignement et availableTextArray qui recensera tous les blocs de textes susceptibles de participer à l’alignement. Ceux qui gardent envers et contre tout quelques souvenirs de la théorie des ensembles étudiée dans leurs jeunes années conviendront sans peine que le premier est inclus dans le second. La comparaison entre ces deux tableaux nous permettra par ailleurs de gérer l’état des boutons + et de notre pop-up.

Pour opérer toute la petite cuisine autour de l’image, nous nous appuierons sur un objet Tfi construit sur mesure à partir de l’image qu’il reçoit en paramètre.

Cet objet va disposer des propriétés suivantes :

  • id : identifiant unique stocké dans l’attribut data-text_floating_image porté par l’image (ainsi que par les blocs de texte qui lui sont apparentés).
  • texts : tableau des blocs de texte lié à l’image.
  • first : référence au premier de ces blocs de texte.
  • last : référence au dernier de ces blocs de texte.

Et des méthodes que voici-voilà :

  • suppress : assure le nettoyage en cas de suppression de l’effet.
  • clean : lors de la sauvegarde de l’article, débarrasse le code des différents éléments et autres ajustements stylistiques introduits pour assurer la prévisualisation et assure ainsi l’enregistrement d’une structure html dénuée de toute scorie inutile.
  • preUpdate : effectue un reset de la structure avant de procéder à l’update d’une image déjà traitée dont on modifie les paramètres.
  • update : construit la structure nécessaire en introduisant les div preElastik et elastik avant le bloc container de l’image et en rajoutant au dernier des blocs de texte une classe dont on reparle dans quelques lignes.
  • resize : réalise la mise en place effective des éléments les uns par rapport aux autres en fonction de leurs dimensions respectives.

À chaque fois qu’une image se voit appliquer notre extension, nous générons une instance de l’objet Tfi et l’ajoutons à un tableau tfiArray destiné à recenser toutes les instances ainsi créées. À chaque image traitée correspond donc une instance tfi ayant comme propriété id la même valeur que l’attribut data-text_floating_image de l’image en question. Ainsi n’est-il donc pas franchement sorcier, en parcourant le tableau tfiArray, de retrouver l’instance tfi correspondant à une image à partir de la valeur enregistrée dans l’attribut data-text_floating_image de celle-ci.

Plutôt que d’introduire un élément stylé avec clear:both après le dernier bloc de texte pour mettre fin à l’effet flottant et courir subséquemment le risque conséquent que celui-ci soit inopinément supprimé ensuite par le rédacteur, il m’a semblé plus judicieux de recourir à un pseudo élément ::after apposé sur ce dernier bloc lui-même. La hauteur de ce pseudo élément correspondra à la valeur entrée pour le champ Espace après de notre pop-up. Le problème majeur de cette élégante option est que le langage javascript ne nous permet pas d’accéder aux pseudo-éléments. Pour contourner l’obstacle, nous développerons une solution similaire à celle exposée ici : on inscrit dans l’en-tête de l’éditeur de tinyMCE un élément <style> déclarant une classe répondant à nos besoins. Il ne nous reste plus alors qu’à attribuer cette classe au bloc que nous souhaitons traiter.

Changement du mode d’édition

Le passage du mode Visuel au mode Texte est détecté par un écouteur posé sur l’événement click du bouton Texte de l’éditeur. Cet écouteur déclenche la fonction clean des instances de l’objet Tfi, fonction qui est justement chargée d’éliminer toutes les traces de nos petites bidouilles destinées à la prévisualisation de l’effet.

Le retour au mode visuel est détecté par un écouteur posé sur l’événement show de l’éditeur. Il nous suffit alors de recréer une instance de Tfi pour chaque image portant l’attribut data-text_floating_image.

La NSA n’a pas le monopole de la surveillance

Une fois notre extension appliquée à une image, nous devons nous assurer que le rédacteur ne va pas bousiller notre grand oeuvre en éditant comme un cochon. En même temps, on ne peut pas l’en empêcher… Mais, on peut en retour prendre quelques mesures, au besoin radicales…

Ainsi donc, j’ai décidé en tant que moi-même qu’un déplacement de l’image provoquerait la suppression immédiate de l’effet. De même si l’on constate l’insertion d’une image au sein d’un des blocs impliqués dans l’alignement. Itou s’il s’avère qu’il ne reste qu’un bloc aligné et que ce bloc est dépourvu de texte. Et toc !

Bien évidemment, nous devons tout autant nettoyer la structure dès lors que notre utilisateur choisit de supprimer l’image seule ou un ensemble comportant l’image.

Enfin, il nous faut prendre en compte le cas où notre utilisateur choisit de rédiger un nouveau paragraphe au sein même des blocs de texte participant à l’alignement.

Pour mettre en place cette surveillance, nous nous reposerons sur la nouvelle API javascript MutationObserver dont nous exploiterons sans vergogne la puissance.

Cependant, il demeure un paramètre sur lequel notre utilisateur est encore libre d’intervenir pour foutre la pagaille : ce fourbe peut tenter de redimensionner l’image. Sauf que tinyMCE a la judicieuse idée d’offrir dans sa phase d’initialisation une option permettant de spécifier les éléments disposant des poignées de redimensionnement. Nous n’allons bien évidemment pas nous priver du malin plaisir de bloquer cette possibilité sur les images portant l’attribut data-text_floating_image. Et ce pas plus tard que maintenant, d’autant que la phase d’initialisation de tinyMCE est aussi celle où l’on peut définir certains éléments de style que l’on veut voir s’appliquer au sein de l’éditeur. Nous en profiterons donc pour établir une largeur de 100% sur nos images afin de nous assurer que, quoiqu’il arrive, elles occupent toujours toute la largeur mise à leur disposition par leur paragraphe container (que les inquiets se rassurent : le style height:auto nécessaire par ailleurs pour éviter toute déformation de l’image est prévu par WordPress dans sa feuille wp-content.css).

Un petit saut dans la classe admin/class-text-floating-image-admin.php :


Et un autre dans includes/class-text-floating-image.php :


Vite fait, bien fait !

Un gros pavé

Ne me reste donc plus (pour l’instant !) qu’à vous délivrer le contenu total révisé commenté vérifié contrôlé mais faut pas rêver comportant certainement son lot de bugs encore à déceler :


Félicitations à celles et ceux qui sont parvenus jusqu’ici tout en ayant méticuleusement décortiqué les près de 1000 lignes de code qui précédent. Je compte sur eux pour expliquer en détail tout le pourquoi du comment à ceux qui auront abandonné en route. Et qu’ils n’hésitent surtout pas à me taper sur les doigts pour chacune des erreurs-incohérences-aberrations (rayer les mentions inutiles et, le cas échéant, en rajouter d’autres) que leur vigilance aguerrie n’aura pas manqué de relever.

Reste qu’il est grand temps désormais de nous attaquer à la mise en place de notre effet côté front-end, ce que nous allons nous attacher à faire dans le chapitre suivant.