FastComments.com

Erweiterungen schreiben

Entwicklung von Erweiterungen

Kontext

FastComments bietet die Möglichkeit, unsere Kernfunktionalität durch Skripte zu erweitern, die wir Extensions nennen.

Eine Extension kann dem Kommentar-Widget zusätzliches Markup hinzufügen, Event-Listener registrieren und beliebigen Code ausführen.

Hier finden Sie Beispiele für Extensions, die wir in der Produktion einsetzen, sowie Dokumentation dazu, wie man Extensions schreibt.


Lebenszyklus einer Erweiterung Internal Link

Das Skript für jede Erweiterung wird abgerufen und aufgerufen, bevor das Kommentar-Widget beginnt, das erste Set von Kommentaren abzurufen und die Benutzeroberfläche zu rendern.

Beim ersten Laden werden die folgenden Daten dem Erweiterungsobjekt angehängt:

  • config - Eine Referenz auf das config-Objekt.
  • translations - Eine Referenz auf das translations-Objekt.
  • commentsById - Eine Referenz auf alle Kommentare nach ID.
  • root - Eine Referenz auf den Root-DOM-Knoten.

Erweiterungen sollten die gewünschten Funktionen überschreiben, die das Kommentar-Widget zu den entsprechenden Zeitpunkten aufrufen wird.

Definieren einer Erweiterung Internal Link

Die kleinstmögliche Erweiterung wäre:

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

For the sake of this example, save this as my-extension.js, and make it available at https://example.com/my-extension.min.js.

This extension does not do anything, except on load it fetches the extension object created by the core comment library.

This Extension object is a singleton and is not shared with any other extensions.

Next, to load our extension, we have to tell the comment widget about it. For example:

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

For functional examples, see the next section.

Das Erweiterungsobjekt Internal Link

The extension object consists of the following definition:

Erweiterungsobjekt JSDoc
Copy CopyRun External Link
1
2/**
3 * Das FastCommentsUI-Erweiterungsobjekt. Wird zum Lazy-Loading bestimmter Komponenten verwendet. Zum Beispiel wird das Bewertungssystem nicht von allen Kunden genutzt, sodass wir diese Erweiterung nur laden, wenn wir sie benötigen.
4 *
5 * @typedef {Object} FastCommentsUIExtension
6 * @property {string} id
7 * @property {Element} scriptNode
8 * @property {Element} root - Der Wurzel-DOM-Knoten des Widgets.
9 * @property {string} [css]
10 * @property {Object} config - Das FastComments-Konfigurationsobjekt.
11 * @property {Object} commentsById - Ein Verweis auf ein Objekt mit allen Kommentaren nach ID, das stets aktuell gehalten wird.
12 * @property {Object} translations - Ein Verweis auf alle Übersetzungen.
13 * @property {Function} reRenderComment - Ein Verweis auf eine Funktion, die aufgerufen werden kann, um einen Kommentar neu zu rendern.
14 * @property {Function} removeCommentAndReRender - Ein Verweis auf eine Funktion, die aufgerufen werden kann, um einen Kommentar aus dem Speicher zu entfernen und den entsprechenden Teil des DOM neu zu rendern.
15 * @property {Function} newBroadcastId - Ein Verweis auf eine Funktion, die aufgerufen werden kann, um eine neue Broadcast-ID zu erstellen und sie zur lokalen Liste der zu ignorierenden Broadcast-IDs hinzuzufügen.
16 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
17 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving] - Wird mit dem Kommentar aufgerufen, der gepostet werden soll. Gibt false zurück, um das Absenden abzubrechen (z. B. wenn eine angehängte Umfrage unvollständig ist).
18 * @property {FastCommentsUIExtensionNewCommentCallback} [newComment]
19 * @property {FastCommentsUIExtensionReplyAreaFilter} [replyAreaFilter] - Filtert HTML für den Kommentarbereich.
20 * @property {FastCommentsUIExtensionWidgetFilter} [widgetFilter] - Filtert HTML für das gesamte Widget beim Rendern.
21 * @property {FastCommentsUIExtensionCommentTopFilter} [commentFilter] - Filtert HTML für jeden Kommentar vor dem Rendern.
22 * @property {FastCommentsUIExtensionReplyAreaFilter} [commentMenuFilter] - Filtert HTML für jedes Kommentarmenü vor dem Rendern.
23 * @property {FastCommentsUIExtensionMenuFilter} [menuFilter] - Filtert HTML für das gesamte Widget beim Rendern.
24 * @property {FastCommentsUIExtensionReplyAreaTop} [replyAreaTop] - (VERALTET) Gibt HTML zurück, das oben im Antwortbereich hinzugefügt wird.
25 * @property {FastCommentsUIExtensionWidgetTopCallback} [widgetTop] - (VERALTET) Gibt HTML zurück, das oben im Widget hinzugefügt wird.
26 * @property {FastCommentsUIExtensionCommentTopCallback} [commentTop] - (VERALTET) Gibt HTML zurück, das oben im Kommentar-Element hinzugefügt wird.
27 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentBottom] - (VERALTET) Gibt HTML zurück, das unten im Kommentar-Element hinzugefügt wird.
28 * @property {FastCommentsUIExtensionCommentBottomCallback} [commentContentBottom] - Gibt HTML zurück, das nach dem Kommentartext im Kommentar-Inhaltselement hinzugefügt wird (verwendet von Umfragen).
29 * @property {Function} [replyAreaInputBottom] - Gibt HTML zurück, das im Kommentar-Eingabefeld unterhalb des Texteingabefeldes hinzugefügt wird (verwendet von Umfragen für den In-Place-Umfrage-Editor). Erhält die übergeordnete Kommentar-ID oder null für das Hauptantwortfeld.
30 * @property {Function} [onPollUpdate] - Wird mit dem Live-Event aufgerufen, wenn sich die Stimmenzahlen einer Umfrage auf der Seite ändern.
31 * @property {Function} isSiteAdmin - Gibt zurück, ob der Betrachter ein Administrator oder Moderator des Mandanten ist. Bekannt nach dem ersten Abruf.
32 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (VERALTET) Gibt HTML zurück, das unten im Menü-Element für jeden Kommentar hinzugefügt wird.
33 * @property {FastCommentsUIExtensionRenderCallback} [onRender]
34 * @property {FastCommentsUIExtensionConnectionStatusCallback} [onLiveConnectionStatusUpdate]
35 * @property {FastCommentsUIExtensionInitialRenderCallback} [onInitialRenderComplete]
36 * @property {FastCommentsUIExtensionPresenceUpdateCallback} [onPresenceUpdate]
37 */
38
39/**
40 * @callback FastCommentsUIExtensionSetupEventHandlers
41 * @param {Element} element - Das Wurzelelement.
42 * @param {Object.<string, Function>} clickListeners - Die Ereignis-Handler für Klicks, nach Klassenname, die per Referenz modifiziert werden können.
43 * @returns void
44 */
45
46/**
47 * @callback FastCommentsUIExtensionWidgetTopCallback
48 * @param {Object} moduleData
49 * @returns {string}
50 */
51
52/**
53 * @callback FastCommentsUIExtensionWidgetFilter
54 * @param {Object} moduleData
55 * @param {Object} html
56 * @returns {string}
57 */
58
59/**
60 * @callback FastCommentsUIExtensionCommentTopCallback
61 * @param {Object} comment
62 * @returns {string}
63 */
64
65/**
66 * @callback FastCommentsUIExtensionCommentTopFilter
67 * @param {Object} comment
68 * @param {string} html
69 * @returns {string}
70 */
71
72/**
73 * @callback FastCommentsUIExtensionCommentBottomCallback
74 * @param {Object} comment
75 * @returns {string}
76 */
77
78/**
79 * @callback FastCommentsUIExtensionMenuBottomCallback
80 * @param {Object} comment
81 * @returns {string}
82 */
83
84/**
85 * @callback FastCommentsUIExtensionMenuFilter
86 * @param {Object} comment
87 * @param {string} html
88 * @returns {string}
89 */
90
91/**
92 * @callback FastCommentsUIExtensionRenderCallback
93 * @returns {string}
94 */
95
96/**
97 * @callback FastCommentsUIExtensionConnectionStatusCallback
98 * @param {boolean} isConnected
99 * @returns {void}
100 */
101
102/**
103 * @callback FastCommentsUIExtensionInitialRenderCallback
104 * @returns {void}
105 */
106
107/**
108 * @callback FastCommentsUIExtensionReplyAreaTop
109 * @param {Object|null} currentUser
110 * @param {boolean} isSaving
111 * @param {boolean} isReplyOpen
112 * @param {string|null} parentId
113 * @returns {string}
114 */
115
116/**
117 * @callback FastCommentsUIExtensionReplyAreaFilter
118 * @param {Object|null} currentUser
119 * @param {boolean} isSaving
120 * @param {boolean} isReplyOpen
121 * @param {string|null} parentId
122 * @param {string|null} html
123 * @returns {string}
124 */
125
126/**
127 * @callback FastCommentsUIExtensionPrepareCommentForSavingCallback
128 * @param {Object} comment
129 * @param {string} parentId
130 */
131
132/**
133 * @callback FastCommentsUIExtensionNewCommentCallback
134 * @param {Object} comment
135 */
136
137/**
138 * @callback FastCommentsUIExtensionPresenceUpdateCallback
139 * @param {Object} update
140 */
141

Die Erweiterungs-API Internal Link

Die Interaktion mit der Extension ist einfach, da wir lediglich Verweise auf Funktionen definieren, die aufgerufen werden sollen.

Um am vorherigen Beispiel anzuknüpfen, nehmen wir an, wir möchten HTML am Anfang jedes Kommentars hinzufügen:

Eine einfache Erweiterung - Fortsetzung
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

Wann immer Sie auf diese Weise HTML zurückgeben, wird es mittels eines DOM-Diffing-Algorithmus in die UI integriert.

Manuelles Auslösen des erneuten Renderns eines Kommentars

Wir können auf das initiale Laden der Seite warten und einen Kommentar manuell neu rendern, indem wir reRenderComment aufrufen:

Einen Kommentar neu rendern
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 nicht erforderlich, nur ein Beispiel.
20 }
21})();
22