FastComments.com

Escribir extensiones

Desarrollo de Extensiones

Contexto

FastComments proporciona la capacidad de ampliar nuestra funcionalidad principal mediante scripts que llamamos Extensions.

Un Extension puede añadir marcado adicional al widget de comentarios, registrar manejadores de eventos y ejecutar código arbitrario.

Aquí encontrará ejemplos de extensiones que tenemos en producción, así como documentación sobre cómo escribir extensiones.


El ciclo de vida de la extensión Internal Link

El script de cada extensión se obtiene e invoca antes de que el widget de comentarios comience a obtener el primer conjunto de comentarios y a renderizar la interfaz de usuario.

En la carga inicial, los siguientes datos se anexarán al objeto de la extensión:

  • config - A reference to the config object.
  • translations - A reference to the translations object.
  • commentsById - A reference to all comments by id.
  • root - A reference to the root DOM node.

Las extensiones deben sobrescribir las funciones deseadas, que el widget de comentarios invocará en los momentos apropiados.

Definir una extensión Internal Link

La extensión más pequeña posible sería:

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

Para este ejemplo, guárdalo como my-extension.js, y ponlo disponible en https://example.com/my-extension.min.js.

Esta extensión no hace nada; excepto que al cargarse recupera el objeto de extensión creado por la biblioteca principal de comentarios.

Este objeto Extension es una instancia única y no se comparte con ninguna otra extensión.

A continuación, para cargar nuestra extensión, tenemos que informar al widget de comentarios sobre ella. Por ejemplo:

Using a Custom Extension
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

Para ejemplos funcionales, vea la siguiente sección.


El objeto de la extensión Internal Link

El objeto de extensión consta de la siguiente definición:

Objeto de Extensión JSDoc
Copy CopyRun External Link
1
2/**
3 * El objeto de extensión FastCommentsUI. Utilizado para cargar perezosamente ciertos componentes. Por ejemplo, el sistema de reseñas no
4 * es usado por todos los clientes, por lo que solo cargamos esa extensión cuando la necesitamos.
5 *
6 * @typedef {Object} FastCommentsUIExtension
7 * @property {string} id
8 * @property {Element} scriptNode
9 * @property {Element} root - El nodo DOM raíz del widget.
10 * @property {string} [css]
11 * @property {Object} config - El objeto de configuración de FastComments.
12 * @property {Object} commentsById - Una referencia a un objeto con todos los comentarios por id, que se mantiene actualizado.
13 * @property {Object} translations - Una referencia a todas las traducciones.
14 * @property {Function} reRenderComment - Una referencia a una función que puede invocarse para volver a renderizar un comentario.
15 * @property {Function} removeCommentAndReRender - Una referencia a una función que puede invocarse para eliminar un comentario de la memoria y volver a renderizar la parte apropiada del DOM.
16 * @property {Function} newBroadcastId - Una referencia a una función que puede invocarse para crear un nuevo id de difusión y añadirlo a la lista local de ids de difusión a ignorar.
17 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
18 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving] - Se llama con el comentario que está a punto de publicarse. Devuelve false para cancelar el envío (por ejemplo, cuando una encuesta adjunta está incompleta).
19 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
20 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filtra HTML para el área de comentarios.
21 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filtra HTML para todo el widget al renderizar.
22 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filtra HTML para cada comentario antes de renderizar.
23 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filtra HTML para cada menú de comentario antes de renderizar.
24 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filtra HTML para todo el widget al renderizar.
25 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (LEGADO) Devuelve HTML para añadir a la parte superior del área de respuesta.
26 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (LEGADO) Devuelve HTML para añadir a la parte superior del widget.
27 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (LEGADO) Devuelve HTML para añadir a la parte superior del elemento de comentario.
28 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (LEGADO) Devuelve HTML para añadir a la parte inferior del elemento de comentario.
29 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentContentBottom] - Devuelve HTML para añadir después del texto del comentario, dentro del elemento de contenido del comentario (usado por encuestas).
30 * @property {Function} [replyAreaInputBottom] - Devuelve HTML para añadir dentro del marco de entrada del comentario, bajo la entrada de texto (usado por encuestas para el editor de encuestas in situ). Recibe el id del comentario padre, o null para el cuadro de respuesta raíz.
31 * @property {Function} [onPollUpdate] - Se llama con el evento en vivo cuando cambian los recuentos de votos de una encuesta en la página.
32 * @property {Function} isSiteAdmin - Devuelve si el visor es un administrador o moderador del inquilino. Conocido después de la primera obtención.
33 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGADO) Devuelve HTML para añadir a la parte inferior del elemento de menú para cada comentario.
34 * @property {FastCommentsUIExtensionRenderCallback} [onRender]
35 * @property {FastCommentsUIExtensionConnectionStatusCallback} [onLiveConnectionStatusUpdate]
36 * @property {FastCommentsUIExtensionInitialRenderCallback} [onInitialRenderComplete]
37 * @property {FastCommentsUIExtensionPresenceUpdateCallback} [onPresenceUpdate]
38 */
39
40/**
41 * @callback FastCommentsUIExtensionSetupEventHandlers
42 * @param {Element} element - El elemento raíz.
43 * @param {Object.<string, Function>} clickListeners - Los manejadores de eventos para clics, por nombre de clase, que pueden modificarse por referencia.
44 * @returns void
45 */
46
47/**
48 * @callback FastCommentsUIExtensionWidgetTopCallback
49 * @param {Object} moduleData
50 * @returns {string}
51 */
52
53/**
54 * @callback FastCommentsUIExtensionWidgetFilter
55 * @param {Object} moduleData
56 * @param {Object} html
57 * @returns {string}
58 */
59
60/**
61 * @callback FastCommentsUIExtensionCommentTopCallback
62 * @param {Object} comment
63 * @returns {string}
64 */
65
66/**
67 * @callback FastCommentsUIExtensionCommentTopFilter
68 * @param {Object} comment
69 * @param {string} html
70 * @returns {string}
71 */
72
73/**
74 * @callback FastCommentsUIExtensionCommentBottomCallback
75 * @param {Object} comment
76 * @returns {string}
77 */
78
79/**
80 * @callback FastCommentsUIExtensionMenuBottomCallback
81 * @param {Object} comment
82 * @returns {string}
83 */
84
85/**
86 * @callback FastCommentsUIExtensionMenuFilter
87 * @param {Object} comment
88 * @param {string} html
89 * @returns {string}
90 */
91
92/**
93 * @callback FastCommentsUIExtensionRenderCallback
94 * @returns {string}
95 */
96
97/**
98 * @callback FastCommentsUIExtensionConnectionStatusCallback
99 * @param {boolean} isConnected
100 * @returns {void}
101 */
102
103/**
104 * @callback FastCommentsUIExtensionInitialRenderCallback
105 * @returns {void}
106 */
107
108/**
109 * @callback FastCommentsUIExtensionReplyAreaTop
110 * @param {Object|null} currentUser
111 * @param {boolean} isSaving
112 * @param {boolean} isReplyOpen
113 * @param {string|null} parentId
114 * @returns {string}
115 */
116
117/**
118 * @callback FastCommentsUIExtensionReplyAreaFilter
119 * @param {Object|null} currentUser
120 * @param {boolean} isSaving
121 * @param {boolean} isReplyOpen
122 * @param {string|null} parentId
123 * @param {string|null} html
124 * @returns {string}
125 */
126
127/**
128 * @callback FastCommentsUIExtensionPrepareCommentForSavingCallback
129 * @param {Object} comment
130 * @param {string} parentId
131 */
132
133/**
134 * @callback FastCommentsUIExtensionNewCommentCallback
135 * @param {Object} comment
136 */
137
138/**
139 * @callback FastCommentsUIExtensionPresenceUpdateCallback
140 * @param {Object} update
141 */
142

La API de la extensión Internal Link

Interactuar con la Extension es sencillo, ya que simplemente definimos referencias a las funciones que queremos invocar.

Para basarnos en el ejemplo anterior, digamos que queremos añadir HTML al principio de cada comentario:

Una extensión simple - Continuación
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

Cada vez que devuelvas HTML así, se fusionará en la interfaz mediante un algoritmo de dom-diffing.

Volver a renderizar un comentario manualmente

Podemos esperar a la carga inicial de la página y volver a renderizar manualmente un comentario invocando reRenderComment:

Volver a renderizar un comentario
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); // el timeout no es necesario, solo un ejemplo.
20 }
21})();
22