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

The extension object consists of the following definition:

JSDoc объекта расширения
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 подобным образом, он будет объединён с UI с помощью алгоритма сравнения DOM.

Ручной запуск повторного рендеринга комментария

Мы можем дождаться начальной загрузки страницы и вручную перерендерить комментарий, вызвав 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