FastComments.com

Pisanje ekstenzija

Razvoj ekstenzija

Kontekst

FastComments omogućava mogućnost proširenja naše osnovne funkcionalnosti putem skripti koje nazivamo ekstenzijama.

An Extension može dodati dodatni markup u widget za komentare, slušaoce događaja, i izvršavati proizvoljan kod.

Ovde ćete naći primere ekstenzija koje imamo u produkciji, kao i dokumentaciju o tome kako pisati ekstenzije.

Životni ciklus ekstenzije Internal Link

Skript za svaku ekstenziju se preuzima i poziva pre nego što vidžet komentara počne da preuzima prvi skup komentara i prikazuje korisnički interfejs.

Pri početnom učitavanju, sledeći podaci biće prikačeni na objekat ekstenzije:

  • config - Referenca na objekat config.
  • translations - Referenca na objekat translations.
  • commentsById - Referenca na sve komentare po id.
  • root - Referenca na root DOM čvor.

Ekstenzije bi trebalo da prepišu željene funkcije, koje će vidžet komentara pozivati u odgovarajućim trenucima.

Definisanje ekstenzije Internal Link

Najmanje moguće proširenje bi bilo:

Jednostavno proširenje
Copy CopyRun External Link
1
2(function () {
3 const extension = FastCommentsUI.extensions.find((extension) => {
4 return extension.id === 'my-extension';
5 });
6})();
7

Za potrebe ovog primera, sačuvajte ovo kao my-extension.js, i postavite ga na https://example.com/my-extension.min.js.

Ovo proširenje ništa ne radi, osim što pri učitavanju preuzima Extension objekat koji je kreirala osnovna biblioteka za komentare.

Ovaj Extension objekat je singleton i nije deljen sa nijednim drugim proširenjima.

Dalje, da bismo učitali naše proširenje, moramo obavestiti widget za komentare o njemu. Na primer:

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

Za funkcionalne primere, pogledajte sledeći odeljak.

Objekat ekstenzije Internal Link

Objekat proširenja (extension) se sastoji iz sledeće definicije:

JSDoc dokumentacija objekta Extension
Copy CopyRun External Link
1
2/**
3 * Objekat proširenja FastCommentsUI. Koristi se za lazy-loading određenih komponenti. Na primer, sistem recenzija ne
4 * koriste svi korisnici, pa taj extension učitavamo samo kada nam treba.
5 *
6 * @typedef {Object} FastCommentsUIExtension
7 * @property {string} id
8 * @property {Element} scriptNode
9 * @property {Element} root - Root DOM čvor vidžeta.
10 * @property {string} [css]
11 * @property {Object} config - FastComments config objekat.
12 * @property {Object} commentsById - Referenca na objekat sa svim komentarima po id-u, koji se održava ažurnim.
13 * @property {Object} translations - Referenca na sve prevode.
14 * @property {Function} reRenderComment - Referenca na funkciju koja se može pozvati da ponovo renderuje komentar.
15 * @property {Function} removeCommentAndReRender - Referenca na funkciju koja se može pozvati da ukloni komentar iz memorije i ponovo renderuje odgovarajući deo DOM-a.
16 * @property {Function} newBroadcastId - Referenca na funkciju koja se može pozvati da kreira novi broadcast id i doda ga u lokalnu listu broadcast id-jeva koje treba ignorisati.
17 * @property {Function} [withSessionId] - Poziva se sa URL-om zahteva i callback-om. Poziva callback sa URL-om plus session id-jem gledaoca kada su third-party kolačići blokirani (isti put koji koriste zahtevi za komentare i glasanje), ili sa nepromenjenim URL-om u suprotnom. Kada session id nije dostupan na taj način, dodaje poslednji anonimni session id dat funkciji rememberAnonSessionId, ako postoji. Ne koristi se za SSO.
18 * @property {Function} [rememberAnonSessionId] - Poziva se sa anonSessionId koji je odgovor vratio. Server ga vraća samo gostu čiji zahtev nije imao session kolačić, i nikada za ulogovanu sesiju. Čuva se u localStorage-u (ili u memoriji kada skladište nije dostupno) tako da withSessionId šalje id u kasnijim zahtevima i gost zadržava jedan identitet.
19 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
20 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving] - Poziva se sa komentarom koji će biti objavljen. Vratite false da otkažete slanje (na primer kada je priložena anketa nepotpuna).
21 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
22 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filtrira HTML za oblast komentara.
23 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filtrira HTML za ceo vidžet pri renderovanju.
24 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filtrira HTML za svaki komentar pre renderovanja.
25 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filtrira HTML za meni svakog komentara pre renderovanja.
26 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filtrira HTML za ceo vidžet pri renderovanju.
27 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (LEGACY) Vraća HTML koji se dodaje na vrh oblasti za odgovore.
28 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (LEGACY) Vraća HTML koji se dodaje na vrh vidžeta.
29 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (LEGACY) Vraća HTML koji se dodaje na vrh elementa komentara.
30 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (LEGACY) Vraća HTML koji se dodaje na dno elementa komentara.
31 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentContentBottom] - Vraća HTML koji se dodaje posle teksta komentara, unutar elementa sadržaja komentara (koriste se ankete).
32 * @property {Function} [replyAreaInputBottom] - Vraća HTML koji se dodaje unutar okvira za unos komentara, ispod polja za tekst (koriste se ankete za editor ankete na licu mesta). Prima id roditeljskog komentara, ili null za glavni okvir za odgovore.
33 * @property {Function} [onPollUpdate] - Poziva se sa live eventom kada se promene brojaci glasova ankete na stranici.
34 * @property {Function} isSiteAdmin - Vraća da li je gledalac admin ili moderator tenanta. Postaje poznato posle prvog preuzimanja.
35 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGACY) Vraća HTML koji se dodaje na dno elementa menija za svaki komentar.
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 - Root element.
45 * @param {Object.<string, Function>} clickListeners - Handler-i događaja za klikove, po imenu klase, koje je moguće menjati po referenci.
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

API ekstenzije Internal Link

Interakcija sa Extension je jednostavna, jer jednostavno definišemo reference na funkcije koje želimo da budu pozvane.

Da bismo nadogradili raniji primer, pretpostavimo da želimo da dodamo HTML na vrh svakog komentara:

Jednostavno proširenje - Nastavak
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

Kad god vratite HTML kao ovaj, on će biti uklopljen u UI putem algoritma za dom-diffing.

Ručno pokretanje ponovnog renderovanja komentara

Možemo sačekati inicijalno učitavanje stranice i ručno ponovo renderovati komentar pozivanjem reRenderComment:

Ponovno renderovanje komentara
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