FastComments.com

Писање екстензија

Развој проширења

Контекст

FastComments пружа могућност проширења наше основне функционалности путем скрипти које зовемо проширења.

Један Extension може додати додатни маркап у видгет за коментаре, слушаоце догађаја и извршавати произвољни код.

Овде ћете пронаћи примере проширења која имамо у продукцији, као и документацију о томе како написати проширења.

Животни циклус екстензије Internal Link

Скрипт за свако проширење се преузима и извршава пре него што виџет коментара почне да преузима први скуп коментара и да приказује кориснички интерфејс.

При првом учитавању, следећи подаци ће бити додати на објекат проширења:

  • config - Референца на објекат config.
  • translations - Референца на објекат translations.
  • commentsById - Референца на све коментаре по id.
  • root - Референца на root DOM чвор.

Проширења треба да замене жељене функције, које ће виџет коментара позивати у одговарајућим тренуцима.

Дефинисање екстензије Internal Link

Најмање могуће проширење изгледало би овако:

Једноставно проширење
Copy CopyRun External Link
1
2(function () {
3 const extension = FastCommentsUI.extensions.find((extension) => {
4 return extension.id === 'my-extension';
5 });
6})();
7

Заради овог примера, сачувајте ово као my-extension.js, и учините га доступним на https://example.com/my-extension.min.js.

Ово проширење не ради ништа посебно, осим што при учитавању преузима објекат проширења који креира основна библиотека коментара.

Овај објекат Extension је јединичан (singleton) и није дељен са другим проширењима.

Даље, да бисмо учитали наше проширење, морамо обавестити видгет за коментаре о њему. На пример:

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

За функционалне примере, погледајте следећи одељак.

Објекат екстензије Internal Link

Објекат проширења се састоји од следеће дефиниције:

JSDoc документација објекта проширења
Copy CopyRun External Link
1
2/**
3 * Објекат проширења FastCommentsUI. Користи се за лењо учитавање одређених компоненти. На пример, систем рецензија не
4 * користе сви корисници, па учитавамо то проширење само када нам затреба.
5 *
6 * @typedef {Object} FastCommentsUIExtension
7 * @property {string} id
8 * @property {Element} scriptNode
9 * @property {Element} root - Коренски DOM чвор виџета.
10 * @property {string} [css]
11 * @property {Object} config - Конфигурациони објекат FastComments.
12 * @property {Object} commentsById - Референца на објекат са свим коментарима по id, који се стално ажурира.
13 * @property {Object} translations - Референца на све преводе.
14 * @property {Function} reRenderComment - Референца на функцију која се може позвати да поново прикаже коментар.
15 * @property {Function} removeCommentAndReRender - Референца на функцију која се може позвати да уклони коментар из меморије и поново прикаже одговарајући део DOM-а.
16 * @property {Function} newBroadcastId - Референца на функцију која се може позвати да креира нови broadcast id и дода га у локалну листу broadcast id-јева за игнорисање.
17 * @property {Function} [withSessionId] - Позива се са URL-ом захтева и callback функцијом. Позива callback са URL-ом коме је додат session id гледаоца када су third-party колачићи блокирани (исти пут који користе захтеви за коментаре и гласање), или са непромењеним URL-ом у супротном. Када session id није доступан на тај начин, додаје анонимни session id последњи прослеђен функцији rememberAnonSessionId, ако постоји. Не користи се за SSO.
18 * @property {Function} [rememberAnonSessionId] - Позива се са anonSessionId који је вратио одговор. Сервер га враћа само госту чији захтев није имао колачић сесије, и никада за пријављену сесију. Чува се у localStorage (или у меморији када складиште није доступно) тако да withSessionId шаље у каснијим захтевима и да гост задржи један идентитет.
19 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
20 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving] - Позива се са коментаром који ће бити објављен. Вратите false да бисте отказали слање (на пример када је приложена анкета непотпуна).
21 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
22 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Филтрира HTML за област коментара.
23 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Филтрира HTML за цео виџет при приказу.
24 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Филтрира HTML за сваки коментар пре приказа.
25 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Филтрира HTML за мени сваког коментара пре приказа.
26 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Филтрира HTML за цео виџет при приказу.
27 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (ЗАСТАРЕЛО) Враћа HTML који се додаје на врх области за одговор.
28 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (ЗАСТАРЕЛО) Враћа HTML који се додаје на врх виџета.
29 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (ЗАСТАРЕЛО) Враћа HTML који се додаје на врх елемента коментара.
30 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (ЗАСТАРЕЛО) Враћа HTML који се додаје на дно елемента коментара.
31 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentContentBottom] - Враћа HTML који се додаје после текста коментара, унутар елемента садржаја коментара (користе анкете).
32 * @property {Function} [replyAreaInputBottom] - Враћа HTML који се додаје унутар оквира за унос коментара, испод поља за текст (користе анкете за уређивач анкете на месту). Прима id родитељског коментара, или null за коренско поље за одговор.
33 * @property {Function} [onPollUpdate] - Позива се са live догађајем када се промене бројачи гласова анкете на страници.
34 * @property {Function} isSiteAdmin - Враћа да ли је гледалац администратор или модератор тенанта. Постаје познато после првог дохвата.
35 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (ЗАСТАРЕЛО) Враћа HTML који се додаје на дно елемента менија за сваки коментар.
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 - Коренски елемент.
45 * @param {Object.<string, Function>} clickListeners - Обрађивачи догађаја за кликове, по називу класе, који се могу мењати по референци.
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 екстензије Internal Link

Интеракција са Extension је једноставна, јер само дефинишемо референце на функције које желимо да буду позване.

Да наставимо са претходним примером, рецимо да желимо да додамо HTML на врх сваког коментара:

Једноставан Extension - наставак
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

Кад год вратите HTML овако, он ће бити спојен у кориснички интерфејс помоћу алгоритма за dom-diffing.

Ручно покретање поновног приказивања коментара

Можемо сачекати почетно учитавање странице и ручно поново приказати коментар позивањем reRenderComment:

Поновно приказивање коментара
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 није обавезан, само пример.
20 }
21})();
22