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:

JSDoc do Objeto Extension
Copy CopyRun External Link
1
2/**
3 * O objeto de extensão do FastCommentsUI. Usado para carregar componentes de forma lazy. Por exemplo, o sistema de avaliações não é
4 * usado por todos os clientes, então só carregamos essa extensão quando a queremos.
5 *
6 * @typedef {Object} FastCommentsUIExtension
7 * @property {string} id
8 * @property {Element} scriptNode
9 * @property {Element} root - O nó DOM raiz do widget.
10 * @property {string} [css]
11 * @property {Object} config - O objeto de configuração do FastComments.
12 * @property {Object} commentsById - Uma referência a um objeto com todos os comentários por id, que é mantido atualizado.
13 * @property {Object} translations - Uma referência a todas as traduções.
14 * @property {Function} reRenderComment - Uma referência a uma função que pode ser invocada para re-renderizar um comentário.
15 * @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.
16 * @property {Function} newBroadcastId - Uma referência a uma função que pode ser invocada para criar um novo broadcast id e adicioná-lo à lista local de broadcast ids a serem ignorados.
17 * @property {Function} [withSessionId] - Chame com uma URL de requisição e um callback. Invoca o callback com a URL mais o session id do visualizador anexado quando cookies de terceiros são bloqueados (o mesmo caminho que as requisições de comentário e voto usam), ou com a URL inalterada caso contrário. Quando não há session id disponível dessa forma, anexa o session id anônimo fornecido por último para rememberAnonSessionId, se houver. Não usado para SSO.
18 * @property {Function} [rememberAnonSessionId] - Chame com o anonSessionId que uma resposta retornou. O servidor só retorna um para um convidado cuja requisição não tinha cookie de sessão, e nunca para uma sessão autenticada. Ele é mantido no localStorage (ou na memória quando o armazenamento não está disponível) para que withSessionId o envie em requisições posteriores e o convidado mantenha uma única identidade.
19 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
20 * @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).
21 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
22 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filtra o HTML da área de comentários.
23 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filtra o HTML de todo o widget na renderização.
24 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filtra o HTML de cada comentário antes da renderização.
25 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filtra o HTML do menu de cada comentário antes da renderização.
26 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filtra o HTML de todo o widget na renderização.
27 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (LEGADO) Retorna HTML a ser adicionado ao topo da área de resposta.
28 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (LEGADO) Retorna HTML a ser adicionado ao topo do widget.
29 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (LEGADO) Retorna HTML a ser adicionado ao topo do elemento do comentário.
30 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (LEGADO) Retorna HTML a ser adicionado ao rodapé do elemento do comentário.
31 * @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).
32 * @property {Function} [replyAreaInputBottom] - Retorna HTML a ser adicionado dentro do quadro de entrada de comentários, abaixo do campo de texto (usado por enquetes para o editor de enquete no local). Recebe o id do comentário pai, ou null para a caixa de resposta raiz.
33 * @property {Function} [onPollUpdate] - Chamado com o evento ao vivo quando a contagem de votos de uma enquete na página muda.
34 * @property {Function} isSiteAdmin - Retorna se o visualizador é um administrador ou moderador do tenant. Conhecido após a primeira busca.
35 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGADO) Retorna HTML a ser adicionado ao rodapé do elemento de menu de cada comentário.
36 * @property {FastCommentsUIExtensionRenderCallback} [onRender]
37 * @property {FastCommentsUIExtensionConnectionStatusCallback} [onLiveConnectionStatusUpdate]
38 * @property {FastCommentsUIExtensionInitialRenderCallback} [onInitialRenderComplete]
39 * @property {FastCommentsUIExtensionPresenceUpdateCallback} [onPresenceUpdate]
40 */
41
42/**
43 * @callback FastCommentsUIExtensionSetupEventHandlers
44 * @param {Element} element - O elemento raiz.
45 * @param {Object.<string, Function>} clickListeners - Os manipuladores de eventos de clique, por nome de classe, que podem ser modificados por referência.
46 * @returns void
47 */
48
49/**
50 * @callback FastCommentsUIExtensionWidgetTopCallback
51 * @param {Object} moduleData
52 * @returns {string}
53 */
54
55/**
56 * @callback FastCommentsUIExtensionWidgetFilter
57 * @param {Object} moduleData
58 * @param {Object} html
59 * @returns {string}
60 */
61
62/**
63 * @callback FastCommentsUIExtensionCommentTopCallback
64 * @param {Object} comment
65 * @returns {string}
66 */
67
68/**
69 * @callback FastCommentsUIExtensionCommentTopFilter
70 * @param {Object} comment
71 * @param {string} html
72 * @returns {string}
73 */
74
75/**
76 * @callback FastCommentsUIExtensionCommentBottomCallback
77 * @param {Object} comment
78 * @returns {string}
79 */
80
81/**
82 * @callback FastCommentsUIExtensionMenuBottomCallback
83 * @param {Object} comment
84 * @returns {string}
85 */
86
87/**
88 * @callback FastCommentsUIExtensionMenuFilter
89 * @param {Object} comment
90 * @param {string} html
91 * @returns {string}
92 */
93
94/**
95 * @callback FastCommentsUIExtensionRenderCallback
96 * @returns {string}
97 */
98
99/**
100 * @callback FastCommentsUIExtensionConnectionStatusCallback
101 * @param {boolean} isConnected
102 * @returns {void}
103 */
104
105/**
106 * @callback FastCommentsUIExtensionInitialRenderCallback
107 * @returns {void}
108 */
109
110/**
111 * @callback FastCommentsUIExtensionReplyAreaTop
112 * @param {Object|null} currentUser
113 * @param {boolean} isSaving
114 * @param {boolean} isReplyOpen
115 * @param {string|null} parentId
116 * @returns {string}
117 */
118
119/**
120 * @callback FastCommentsUIExtensionReplyAreaFilter
121 * @param {Object|null} currentUser
122 * @param {boolean} isSaving
123 * @param {boolean} isReplyOpen
124 * @param {string|null} parentId
125 * @param {string|null} html
126 * @returns {string}
127 */
128
129/**
130 * @callback FastCommentsUIExtensionPrepareCommentForSavingCallback
131 * @param {Object} comment
132 * @param {string} parentId
133 */
134
135/**
136 * @callback FastCommentsUIExtensionNewCommentCallback
137 * @param {Object} comment
138 */
139
140/**
141 * @callback FastCommentsUIExtensionPresenceUpdateCallback
142 * @param {Object} update
143 */
144

A API da Extensão Internal Link

Interagir com a Extension é simples, pois apenas definimos referências para as funções que queremos que sejam invocadas.

Para continuar o exemplo anterior, digamos que queremos adicionar HTML ao topo de cada comentário:

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

Sempre que você retornar HTML como este, ele será mesclado na UI por meio de um algoritmo de dom-diffing.

Acionando manualmente a re-renderização de um comentário

Podemos aguardar o carregamento inicial da página e re-renderizar manualmente um comentário invocando 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); // o timeout não é obrigatório, é apenas um exemplo.
20 }
21})();
22