FastComments.com

Escrevendo Extensões

Desenvolvendo Extensões

Contexto

FastComments fornece a capacidade de estender nossa funcionalidade principal por meio de scripts que chamamos de Extensions.

Um Extension pode adicionar marcação adicional ao widget de comentários, ouvintes de eventos e executar código arbitrário.

Aqui você encontrará exemplos de extensões que estão em produção, bem como documentação sobre como escrever extensões.

O Ciclo de Vida da Extensão Internal Link

O script para cada extensão é buscado e invocado antes que o widget de comentários comece a buscar o primeiro conjunto de comentários e renderizar a UI.

No carregamento inicial, os seguintes dados serão anexados ao objeto da extensão:

  • config - Uma referência ao objeto config.
  • translations - Uma referência ao objeto translations.
  • commentsById - Uma referência a todos os comentários por id.
  • root - Uma referência ao nó DOM raiz.

As extensões devem sobrescrever as funções desejadas, que o widget de comentários chamará nos momentos apropriados.

Definindo uma Extensão Internal Link

A menor extensão possível seria:

Uma Extensão Simples
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 exemplo, salve isto como my-extension.js, e torne-o disponível em https://example.com/my-extension.min.js.

Esta extensão não faz nada; ao ser carregada, ela busca o objeto de extensão criado pela biblioteca principal de comentários.

Este objeto Extension é um singleton e não é compartilhado com outras extensões.

A seguir, para carregar nossa extensão, precisamos informar o widget de comentários sobre ela. Por exemplo:

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 exemplos funcionais, veja a próxima seção.

O Objeto da Extensão Internal Link

O objeto de extensão consiste na seguinte definição:

Objeto de Extensão JSDoc
Copy CopyRun External Link
1
2/**
3 * O objeto de extensão FastCommentsUI. Usado para carregamento preguiçoso (lazy-loading) de certos componentes. Por exemplo, o sistema de avaliações não é usado por todos os clientes, então carregamos essa extensão apenas quando precisamos dela.
4 *
5 * @typedef {Object} FastCommentsUIExtension
6 * @property {string} id
7 * @property {Element} scriptNode
8 * @property {Element} root - O nó DOM raiz do widget.
9 * @property {string} [css]
10 * @property {Object} config - O objeto de configuração do FastComments.
11 * @property {Object} commentsById - Uma referência a um objeto com todos os comentários por id, mantido atualizado.
12 * @property {Object} translations - Uma referência a todas as traduções.
13 * @property {Function} reRenderComment - Uma referência a uma função que pode ser invocada para re-renderizar um comentário.
14 * @property {Function} removeCommentAndReRender - Uma referência a uma função que pode ser invocada para remover um comentário da memória e re-renderizar a parte apropriada do DOM.
15 * @property {Function} newBroadcastId - Uma referência a uma função que pode ser invocada para criar um novo ID de broadcast e adicioná-lo à lista local de IDs de broadcast a serem ignorados.
16 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
17 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving] - Chamado com o comentário que está prestes a ser postado. Retorne false para cancelar o envio (por exemplo, quando uma enquete anexada está incompleta).
18 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
19 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filtra o HTML para a área de comentário.
20 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filtra o HTML para todo o widget na renderização.
21 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filtra o HTML para cada comentário antes da renderização.
22 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filtra o HTML para cada menu de comentário antes da renderização.
23 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filtra o HTML para todo o widget na renderização.
24 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (LEGADO) Retorna HTML a ser adicionado ao topo da área de resposta.
25 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (LEGADO) Retorna HTML a ser adicionado ao topo do widget.
26 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (LEGADO) Retorna HTML a ser adicionado ao topo do elemento de comentário.
27 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (LEGADO) Retorna HTML a ser adicionado ao fundo do elemento de comentário.
28 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentContentBottom] - Retorna HTML a ser adicionado após o texto do comentário, dentro do elemento de conteúdo do comentário (usado por enquetes).
29 * @property {Function} [replyAreaInputBottom] - Retorna HTML a ser adicionado dentro da caixa de entrada de comentário, abaixo da entrada de texto (usado por enquetes para o editor de enquete in-place). Recebe o ID do comentário pai, ou null para a caixa de resposta raiz.
30 * @property {Function} [onPollUpdate] - Chamado com o evento ao vivo quando a contagem de votos de uma enquete na página mudar.
31 * @property {Function} isSiteAdmin - Retorna se o visualizador é um administrador ou moderador do tenant. Conhecido após a primeira busca.
32 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGADO) Retorna HTML a ser adicionado ao fundo do elemento de menu para cada comentário.
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 - O elemento raiz.
42 * @param {Object.<string, Function>} clickListeners - Os manipuladores de eventos para cliques, por nome de classe, que podem ser modificados por referência.
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

A API da Extensão Internal Link

Interacting with the Extension is simple, as we simply define references to functions we want invoked.

To build off the example earlier, let's say we want to add HTML to the top of each comment:

Uma Extensão Simples - Continuação
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

Whenever you return HTML like this, it will get merged into the UI via a dom-diffing algorithm.

Manually triggering the re-render of a comment

We can wait for the initial page load and manually re-render a comment by invoking reRenderComment:

Re-renderizando um Comentário
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 não é necessário, apenas um exemplo.
20 }
21})();
22