FastComments.com

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 :

JSDoc de l'objet d'extension
Copy CopyRun External Link
1
2/**
3 * The FastCommentsUI extension object. Used for lazy-loading certain components. For example, the review system is not
4 * used by all customers, so we only load that extension when we want it.
5 *
6 * @typedef {Object} FastCommentsUIExtension
7 * @property {string} id
8 * @property {Element} scriptNode
9 * @property {Element} root - The widget root dom node.
10 * @property {string} [css]
11 * @property {Object} config - The FastComments config object.
12 * @property {Object} commentsById - A reference to an object with all comments by id, which is kept up to date.
13 * @property {Object} translations - A reference to all translations.
14 * @property {Function} reRenderComment - A reference to a function that can be invoked to re-render a comment.
15 * @property {Function} removeCommentAndReRender - A reference to a function that can be invoked to remove a comment from memory and re-render the appropriate part of the DOM.
16 * @property {Function} newBroadcastId - A reference to a function that can be invoked create a new broadcast id and add it to the local list of broadcast ids to ignore.
17 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
18 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving]
19 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
20 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filter HTML for the comment area.
21 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filter HTML for the whole widget on render.
22 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filter HTML for each comment before render.
23 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filter HTML for each comment menu before render.
24 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filter HTML for the whole widget on render.
25 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (LEGACY) Return HTML to add to the top of the reply area.
26 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (LEGACY) Return HTML to add to the top of the widget.
27 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (LEGACY) Return HTML to add to the top of the comment element.
28 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (LEGACY) Return HTML to add to the bottom of the comment element.
29 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGACY) Return HTML to add to the bottom of the menu element for each comment.
30 * @property {FastCommentsUIExtensionRenderCallback} [onRender]
31 * @property {FastCommentsUIExtensionConnectionStatusCallback} [onLiveConnectionStatusUpdate]
32 * @property {FastCommentsUIExtensionInitialRenderCallback} [onInitialRenderComplete]
33 * @property {FastCommentsUIExtensionPresenceUpdateCallback} [onPresenceUpdate]
34 */
35
36/**
37 * @callback FastCommentsUIExtensionSetupEventHandlers
38 * @param {Element} element - The root element.
39 * @param {Object.<string, Function>} clickListeners - The event handlers for clicks, by class name, which can be modified by reference.
40 * @returns void
41 */
42
43/**
44 * @callback FastCommentsUIExtensionWidgetTopCallback
45 * @param {Object} moduleData
46 * @returns {string}
47 */
48
49/**
50 * @callback FastCommentsUIExtensionWidgetFilter
51 * @param {Object} moduleData
52 * @param {Object} html
53 * @returns {string}
54 */
55
56/**
57 * @callback FastCommentsUIExtensionCommentTopCallback
58 * @param {Object} comment
59 * @returns {string}
60 */
61
62/**
63 * @callback FastCommentsUIExtensionCommentTopFilter
64 * @param {Object} comment
65 * @param {string} html
66 * @returns {string}
67 */
68
69/**
70 * @callback FastCommentsUIExtensionCommentBottomCallback
71 * @param {Object} comment
72 * @returns {string}
73 */
74
75/**
76 * @callback FastCommentsUIExtensionMenuBottomCallback
77 * @param {Object} comment
78 * @returns {string}
79 */
80
81/**
82 * @callback FastCommentsUIExtensionMenuFilter
83 * @param {Object} comment
84 * @param {string} html
85 * @returns {string}
86 */
87
88/**
89 * @callback FastCommentsUIExtensionRenderCallback
90 * @returns {string}
91 */
92
93/**
94 * @callback FastCommentsUIExtensionConnectionStatusCallback
95 * @param {boolean} isConnected
96 * @returns {void}
97 */
98
99/**
100 * @callback FastCommentsUIExtensionInitialRenderCallback
101 * @returns {void}
102 */
103
104/**
105 * @callback FastCommentsUIExtensionReplyAreaTop
106 * @param {Object|null} currentUser
107 * @param {boolean} isSaving
108 * @param {boolean} isReplyOpen
109 * @param {string|null} parentId
110 * @returns {string}
111 */
112
113/**
114 * @callback FastCommentsUIExtensionReplyAreaFilter
115 * @param {Object|null} currentUser
116 * @param {boolean} isSaving
117 * @param {boolean} isReplyOpen
118 * @param {string|null} parentId
119 * @param {string|null} html
120 * @returns {string}
121 */
122
123/**
124 * @callback FastCommentsUIExtensionPrepareCommentForSavingCallback
125 * @param {Object} comment
126 * @param {string} parentId
127 */
128
129/**
130 * @callback FastCommentsUIExtensionNewCommentCallback
131 * @param {Object} comment
132 */
133
134/**
135 * @callback FastCommentsUIExtensionPresenceUpdateCallback
136 * @param {Object} update
137 */
138

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