FastComments.com

拡張機能の作成

Extensions の開発

コンテキスト

FastComments は、Extensions と呼ぶスクリプトを介してコア機能を拡張する機能を提供します。

An Extension はコメントウィジェットに追加のマークアップを加えたり、イベントリスナーを設定したり、任意のコードを実行したりできます。

ここでは、本番で使用している Extensions の例と、Extensions の書き方に関するドキュメントを紹介します。


拡張機能のライフサイクル Internal Link

各拡張機能のスクリプトは、コメントウィジェットが最初のコメントセットの取得とUIのレンダリングを開始する前にフェッチされ、実行されます。

初回読み込み時に、次のデータが extension オブジェクトに付与されます:

  • 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
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 - 新しいブロードキャスト ID を作成し、無視するローカルリストに追加できる関数への参照。
17 * @property {FastCommentsUIExtensionSetupEventHandlers} [setupEventHandlers]
18 * @property {FastCommentsUIExtensionPrepareCommentForSavingCallback} [prepareCommentForSaving] - 投稿される直前のコメントが渡されます。false を返すと送信がキャンセルされます(例:添付された投票が未完了の場合)。
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 {FastCommentsUIExtensionCommentBottomCallback} [commentContentBottom] - コメントテキストの後、コメントコンテンツ要素内に追加する HTML を返します(投票で使用)。
30 * @property {Function} [replyAreaInputBottom] - テキスト入力の下に、コメント入力フレーム内に追加する HTML を返します(インライン投票エディタで使用)。親コメント ID、またはルート返信ボックスの場合は null が渡されます。
31 * @property {Function} [onPollUpdate] - ページ上の投票の票数が変化したときにライブイベントとして呼び出されます。
32 * @property {Function} isSiteAdmin - ビューアがテナントの管理者またはモデレーターかどうかを返します。最初の取得後に判明します。
33 * @property {FastCommentsUIExtensionMenuBottomCallback} [menuBottom] - (LEGACY) 各コメントのメニュー要素の下部に追加する HTML を返します。
34 * @property {FastCommentsUIExtensionRenderCallback} [onRender]
35 * @property {FastCommentsUIExtensionConnectionStatusCallback} [onLiveConnectionStatusUpdate]
36 * @property {FastCommentsUIExtensionInitialRenderCallback} [onInitialRenderComplete]
37 * @property {FastCommentsUIExtensionPresenceUpdateCallback} [onPresenceUpdate]
38 */
39
40/**
41 * @callback FastCommentsUIExtensionSetupEventHandlers
42 * @param {Element} element - ルート要素。
43 * @param {Object.<string, Function>} clickListeners - クラス名ごとのクリックイベントハンドラで、参照によって変更可能です。
44 * @returns void
45 */
46
47/**
48 * @callback FastCommentsUIExtensionWidgetTopCallback
49 * @param {Object} moduleData
50 * @returns {string}
51 */
52
53/**
54 * @callback FastCommentsUIExtensionWidgetFilter
55 * @param {Object} moduleData
56 * @param {Object} html
57 * @returns {string}
58 */
59
60/**
61 * @callback FastCommentsUIExtensionCommentTopCallback
62 * @param {Object} comment
63 * @returns {string}
64 */
65
66/**
67 * @callback FastCommentsUIExtensionCommentTopFilter
68 * @param {Object} comment
69 * @param {string} html
70 * @returns {string}
71 */
72
73/**
74 * @callback FastCommentsUIExtensionCommentBottomCallback
75 * @param {Object} comment
76 * @returns {string}
77 */
78
79/**
80 * @callback FastCommentsUIExtensionMenuBottomCallback
81 * @param {Object} comment
82 * @returns {string}
83 */
84
85/**
86 * @callback FastCommentsUIExtensionMenuFilter
87 * @param {Object} comment
88 * @param {string} html
89 * @returns {string}
90 */
91
92/**
93 * @callback FastCommentsUIExtensionRenderCallback
94 * @returns {string}
95 */
96
97/**
98 * @callback FastCommentsUIExtensionConnectionStatusCallback
99 * @param {boolean} isConnected
100 * @returns {void}
101 */
102
103/**
104 * @callback FastCommentsUIExtensionInitialRenderCallback
105 * @returns {void}
106 */
107
108/**
109 * @callback FastCommentsUIExtensionReplyAreaTop
110 * @param {Object|null} currentUser
111 * @param {boolean} isSaving
112 * @param {boolean} isReplyOpen
113 * @param {string|null} parentId
114 * @returns {string}
115 */
116
117/**
118 * @callback FastCommentsUIExtensionReplyAreaFilter
119 * @param {Object|null} currentUser
120 * @param {boolean} isSaving
121 * @param {boolean} isReplyOpen
122 * @param {string|null} parentId
123 * @param {string|null} html
124 * @returns {string}
125 */
126
127/**
128 * @callback FastCommentsUIExtensionPrepareCommentForSavingCallback
129 * @param {Object} comment
130 * @param {string} parentId
131 */
132
133/**
134 * @callback FastCommentsUIExtensionNewCommentCallback
135 * @param {Object} comment
136 */
137
138/**
139 * @callback FastCommentsUIExtensionPresenceUpdateCallback
140 * @param {Object} update
141 */
142

拡張機能のAPI Internal Link

Interacting with the Extension is simple, as we simply define references to functions we want invoked.

To build off the example earlier, let's say we want to add HTML to the top of each comment:

シンプルな拡張機能 - 続き
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

Whenever you return HTML like this, it will get merged into the UI via a dom-diffing algorithm.

コメントの再レンダリングを手動でトリガーする

We can wait for the initial page load and manually re-render a comment by invoking 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