FastComments.com

Разработване на разширения

Контекст

FastComments предоставя възможност за разширяване на основната ни функционалност чрез скриптове, които наричаме Extensions.

Един Extension може да добави допълнителна маркировка към коментарния уиджет, да добави слушатели на събития и да изпълнява произволен код.

Тук ще намерите примери за разширения, които имаме в продукция, както и документация за това как да пишете разширения.

Жизнен цикъл на разширението Internal Link


Скриптът за всяко разширение се изтегля и извиква преди компонентът за коментари да започне да извлича първия набор от коментари и да рендерира потребителския интерфейс.

При първоначално зареждане следните данни ще бъдат добавени към обекта на разширението:

  • config - Препратка към обекта config.
  • translations - Препратка към обекта translations.
  • commentsById - Препратка към всички коментари по id.
  • 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 обект е единствен екземпляр и не се споделя с други разширения.

След това, за да заредим нашето разширение, трябва да уведомим коментарния уиджет за него. Например:

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 на обекта Extension
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 - Коренният 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 {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
18 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving]
19 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
20 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Филтър за HTML на областта за коментари.
21 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Филтър за HTML на целия уиджет при рендиране.
22 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Филтър за HTML за всеки коментар преди рендиране.
23 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Филтър за HTML за всяко меню на коментар преди рендиране.
24 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Филтър за HTML на целия уиджет при рендиране.
25 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (LEGACY) Връща HTML за добавяне в горната част на зоната за отговори.
26 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (LEGACY) Връща HTML за добавяне в горната част на уиджета.
27 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (LEGACY) Връща HTML за добавяне в горната част на елемента на коментара.
28 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (LEGACY) Връща HTML за добавяне в долната част на елемента на коментара.
29 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGACY) Връща HTML за добавяне в долната част на елемента на менюто за всеки коментар.
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 - Коренният елемент.
39 * @param {Object.<string, Function>} clickListeners - Обработчиците на събития за кликове, индексирани по име на клас, които могат да бъдат модифицирани чрез референция.
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 * @param {string} parentId
127 */
128
129/**
130 * @callback FastCommentsUIExtensionNewCommentCallback
131 * @param {Object} comment
132 */
133
134/**
135 * @callback FastCommentsUIExtensionPresenceUpdateCallback
136 * @param {Object} update
137 */
138

API за разширения Internal Link

Взаимодействието с Extension е просто, тъй като просто дефинираме референции към функции, които искаме да бъдат извикани.

За да надградим предишния пример, да кажем, че искаме да добавим HTML в горната част на всеки коментар:

Просто разширение - Продължение
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); // таймаутът не е необходим, просто пример.
20 }
21})();
22