FastComments.com

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 de Extensão
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 - O nó raiz do DOM 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 é mantida atualizada.
13 * @property {Object} translations - Uma referência para todas as traduções.
14 * @property {Function} reRenderComment - Uma referência para uma função que pode ser invocada para re-renderizar um comentário.
15 * @property {Function} removeCommentAndReRender - Uma referência para 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 para 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 {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
18 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving]
19 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
20 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filtrar o HTML da área de resposta.
21 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filtrar o HTML de todo o widget ao renderizar.
22 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filtrar o HTML de cada comentário antes de renderizar.
23 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filtrar o HTML de cada menu de comentário antes de renderizar.
24 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filtrar o HTML de todo o widget ao renderizar.
25 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (LEGADO) Retorna HTML para adicionar ao topo da área de resposta.
26 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (LEGADO) Retorna HTML para adicionar ao topo do widget.
27 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (LEGADO) Retorna HTML para adicionar ao topo do elemento de comentário.
28 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (LEGADO) Retorna HTML para adicionar ao final do elemento de comentário.
29 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGADO) Retorna HTML para adicionar ao final do elemento de menu para cada comentário.
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 - O elemento raiz.
39 * @param {Object.<string, Function>} clickListeners - Os manipuladores de evento para cliques, por nome de classe, que podem ser modificados por referência.
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 */
127
128/**
129 * @callback FastCommentsUIExtensionNewCommentCallback
130 * @param {Object} comment
131 */
132
133/**
134 * @callback FastCommentsUIExtensionPresenceUpdateCallback
135 * @param {Object} update
136 */
137

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