FastComments.com

Écrire des extensions

Développement d'extensions

Contexte

FastComments offre la possibilité d'étendre notre fonctionnalité principale via des scripts que nous appelons Extensions.

Une Extension peut ajouter du balisage supplémentaire au widget de commentaires, ajouter des écouteurs d'événements et exécuter du code arbitraire.

Ici vous trouverez des exemples d'extensions que nous utilisons en production, ainsi que la documentation sur la manière d'écrire des extensions.


Le cycle de vie d'une extension Internal Link

Le script pour chaque extension est récupéré et invoqué avant que le widget de commentaires ne commence à récupérer le premier jeu de commentaires et à rendre l'interface utilisateur.

Au chargement initial, les données suivantes seront ajoutées à l'objet extension :

  • config - Une référence à l'objet config.
  • translations - Une référence à l'objet translations.
  • commentsById - Une référence à tous les commentaires par id.
  • root - Une référence au nœud DOM racine.

Les extensions doivent redéfinir les fonctions souhaitées, que le widget de commentaires invoquera aux moments appropriés.

Définir une extension Internal Link

La plus petite extension possible serait :

Une extension simple
Copy CopyRun External Link
1
2(function () {
3 const extension = FastCommentsUI.extensions.find((extension) => {
4 return extension.id === 'my-extension';
5 });
6})();
7

Pour cet exemple, enregistrez ceci sous my-extension.js, et mettez-le à disposition à https://example.com/my-extension.min.js.

Cette extension ne fait rien ; au chargement, elle récupère simplement l'objet Extension créé par la bibliothèque principale de commentaires.

Cet objet Extension est un singleton et n'est pas partagé avec d'autres extensions.

Ensuite, pour charger notre extension, nous devons en informer le widget de commentaires. Par exemple :

Utilisation d'une extension personnalisée
Copy CopyRun External Link
1
2<script async src="https://cdn.fastcomments.com/js/embed-v2-async.min.js"></script>
3<div id="fastcomments-widget"></div>
4<script>
5window.fcConfigs = [{
6 "tenantId": "demo",
7 "extensions": [
8 {
9 "id": "my-extension",
10 "path": "https://example.com/my-extension.min.js"
11 }
12 ]
13}];
14</script>
15

Pour des exemples fonctionnels, voir la section suivante.


L'objet d'extension Internal Link

L'objet d'extension se compose de la définition suivante :

Objet d'extension JSDoc
Copy CopyRun External Link
1
2/**
3 * L'objet d'extension FastCommentsUI. Utilisé pour le chargement différé de certains composants. Par exemple, le système d'évaluation n'est pas utilisé par tous les clients, nous ne chargeons donc cette extension que lorsque nous en avons besoin.
4 *
5 * @typedef {Object} FastCommentsUIExtension
6 * @property {string} id
7 * @property {Element} scriptNode
8 * @property {Element} root - Le nœud DOM racine du widget.
9 * @property {string} [css]
10 * @property {Object} config - L'objet de configuration FastComments.
11 * @property {Object} commentsById - Une référence à un objet contenant tous les commentaires par id, maintenu à jour.
12 * @property {Object} translations - Une référence à toutes les traductions.
13 * @property {Function} reRenderComment - Une référence à une fonction pouvant être invoquée pour re‑rendre un commentaire.
14 * @property {Function} removeCommentAndReRender - Une référence à une fonction pouvant être invoquée pour supprimer un commentaire de la mémoire et re‑rendre la partie appropriée du DOM.
15 * @property {Function} newBroadcastId - Une référence à une fonction pouvant être invoquée pour créer un nouvel ID de diffusion et l'ajouter à la liste locale des IDs de diffusion à ignorer.
16 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
17 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving] - Appelé avec le commentaire sur le point d'être publié. Retourne false pour annuler la soumission (par exemple lorsqu'un sondage joint est incomplet).
18 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
19 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filtrer le HTML pour la zone de commentaire.
20 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filtrer le HTML pour l'ensemble du widget lors du rendu.
21 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filtrer le HTML pour chaque commentaire avant le rendu.
22 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filtrer le HTML pour chaque menu de commentaire avant le rendu.
23 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filtrer le HTML pour l'ensemble du widget lors du rendu.
24 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (HÉRITAGE) Retourner du HTML à ajouter en haut de la zone de réponse.
25 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (HÉRITAGE) Retourner du HTML à ajouter en haut du widget.
26 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (HÉRITAGE) Retourner du HTML à ajouter en haut de l'élément de commentaire.
27 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (HÉRITAGE) Retourner du HTML à ajouter en bas de l'élément de commentaire.
28 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentContentBottom] - Retourner du HTML à ajouter après le texte du commentaire, à l'intérieur de l'élément de contenu du commentaire (utilisé par les sondages).
29 * @property {Function} [replyAreaInputBottom] - Retourner du HTML à ajouter à l'intérieur du cadre de saisie du commentaire, sous le champ texte (utilisé par les sondages pour l'éditeur de sondage intégré). Reçoit l'ID du commentaire parent, ou null pour la boîte de réponse racine.
30 * @property {Function} [onPollUpdate] - Appelé avec l'événement en direct lorsque le nombre de votes d'un sondage sur la page change.
31 * @property {Function} isSiteAdmin - Renvoie si le visiteur est un administrateur ou modérateur du locataire. Connu après le premier fetch.
32 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (HÉRITAGE) Retourner du HTML à ajouter en bas de l'élément de menu pour chaque commentaire.
33 * @property {FastCommentsUIExtensionRenderCallback} [onRender]
34 * @property {FastCommentsUIExtensionConnectionStatusCallback} [onLiveConnectionStatusUpdate]
35 * @property {FastCommentsUIExtensionInitialRenderCallback} [onInitialRenderComplete]
36 * @property {FastCommentsUIExtensionPresenceUpdateCallback} [onPresenceUpdate]
37 */
38
39/**
40 * @callback FastCommentsUIExtensionSetupEventHandlers
41 * @param {Element} element - L'élément racine.
42 * @param {Object.<string, Function>} clickListeners - Les gestionnaires d'événements pour les clics, par nom de classe, qui peuvent être modifiés par référence.
43 * @returns void
44 */
45
46/**
47 * @callback FastCommentsUIExtensionWidgetTopCallback
48 * @param {Object} moduleData
49 * @returns {string}
50 */
51
52/**
53 * @callback FastCommentsUIExtensionWidgetFilter
54 * @param {Object} moduleData
55 * @param {Object} html
56 * @returns {string}
57 */
58
59/**
60 * @callback FastCommentsUIExtensionCommentTopCallback
61 * @param {Object} comment
62 * @returns {string}
63 */
64
65/**
66 * @callback FastCommentsUIExtensionCommentTopFilter
67 * @param {Object} comment
68 * @param {string} html
69 * @returns {string}
70 */
71
72/**
73 * @callback FastCommentsUIExtensionCommentBottomCallback
74 * @param {Object} comment
75 * @returns {string}
76 */
77
78/**
79 * @callback FastCommentsUIExtensionMenuBottomCallback
80 * @param {Object} comment
81 * @returns {string}
82 */
83
84/**
85 * @callback FastCommentsUIExtensionMenuFilter
86 * @param {Object} comment
87 * @param {string} html
88 * @returns {string}
89 */
90
91/**
92 * @callback FastCommentsUIExtensionRenderCallback
93 * @returns {string}
94 */
95
96/**
97 * @callback FastCommentsUIExtensionConnectionStatusCallback
98 * @param {boolean} isConnected
99 * @returns {void}
100 */
101
102/**
103 * @callback FastCommentsUIExtensionInitialRenderCallback
104 * @returns {void}
105 */
106
107/**
108 * @callback FastCommentsUIExtensionReplyAreaTop
109 * @param {Object|null} currentUser
110 * @param {boolean} isSaving
111 * @param {boolean} isReplyOpen
112 * @param {string|null} parentId
113 * @returns {string}
114 */
115
116/**
117 * @callback FastCommentsUIExtensionReplyAreaFilter
118 * @param {Object|null} currentUser
119 * @param {boolean} isSaving
120 * @param {boolean} isReplyOpen
121 * @param {string|null} parentId
122 * @param {string|null} html
123 * @returns {string}
124 */
125
126/**
127 * @callback FastCommentsUIExtensionPrepareCommentForSavingCallback
128 * @param {Object} comment
129 * @param {string} parentId
130 */
131
132/**
133 * @callback FastCommentsUIExtensionNewCommentCallback
134 * @param {Object} comment
135 */
136
137/**
138 * @callback FastCommentsUIExtensionPresenceUpdateCallback
139 * @param {Object} update
140 */
141

L'API de l'extension Internal Link

Interagir avec l'Extension est simple, car nous définissons simplement des références aux fonctions que nous voulons invoquer.

Pour prolonger l'exemple précédent, disons que nous voulons ajouter du HTML en haut de chaque commentaire :

Une extension simple - Suite
Copy CopyRun External Link
1
2(function () {
3 const extension = FastCommentsUI.extensions.find((extension) => {
4 return extension.id === 'my-extension';
5 });
6
7 extension.commentFilter = function(comment, html) {
8 return `<h3>The user's name is ${comment.commenterName}!</h3>` + html;
9 }
10})();
11

Chaque fois que vous renvoyez du HTML de cette manière, il sera fusionné dans l'interface via un algorithme de diff du DOM.

Déclencher manuellement le re-rendu d'un commentaire

Nous pouvons attendre le chargement initial de la page et re-rendre manuellement un commentaire en appelant reRenderComment :

Re-rendu d'un commentaire
Copy CopyRun External Link
1
2(function () {
3 const extension = FastCommentsUI.extensions.find((extension) => {
4 return extension.id === 'my-extension';
5 });
6
7 let renderCount = 0;
8
9 extension.commentFilter = function(comment, html) {
10 renderCount++;
11 return `<h3>The render count is ${renderCount}!</h3>` + html;
12 }
13
14 extension.onInitialRenderComplete = function() {
15 setInterval(function() {
16 extension.reRenderComment(extension.commentsById[Object.keys(extension.commentsById)[0]], function renderDone() {
17 console.log('Comment re-render done.');
18 });
19 }, 2000); // timeout not required, just an example.
20 }
21})();
22