もう2020年です。飢えた人間は単純なテキストでは満足できなくなり、さまざまなスタイルの派手なテキストが登場しています。しかし、テキストがあるだけでは十分ではありません。私たちが発信するソフト記事がより美しくなるように、ユーザーが編集時にさまざまなカスタムメッセージタイプを挿入できるようにする必要があります。そのため、この記事を書いています。 序文 Quill エディターに付属するリッチ テキスト フィルタリング (ほとんどの主流エディターはリッチ テキストをフィルタリングします) が原因で、開発者はカスタム HTML テンプレートを構成するときに多くの問題に遭遇します。 1. クイルレンダリングロジック分析 Quill で HTML ブロック コンテンツをカスタマイズするには、まず Quill の内部レンダリング プロセスを理解する必要があります。理解すべき重要な概念をいくつか示します。 1. デルタ Delta は Quill 内で定義されたデータ形式で、ドキュメントの内容やドキュメントの変更操作を表すために使用されます。読みやすく、シンプルな形式です。ドキュメントの内容は Delta 形式で保持されます。HTML の内容と Delta は相互に変換できます。 例えば: このようなリッチテキストは次の形式で表されます。 { 「オプス」:[ {"挿入":"これは単純なテキストです。\\nただし、"}, {"attributes":{"bold":true},"insert":"それは "}, {"挿入":"太字ではありません。\\n試してみます"}, {"attributes":{"italic":true},"insert":"italic "}, {"挿入":"ははは\\n"}、{"属性": {"italic":true,"bold":true},"insert":"両方"}, {"挿入":" ?\\n"} ] }" 通常のテキストは挿入アクションとして定義され、各項目はテキスト コンテンツの説明であるデルタを表します。 同様に、変更または削除が発生した場合、対応するデルタが生成され、新しく生成された変更デルタが元のデルタとマージされて新しいデルタが生成されます。 (デルタには、挿入、削除、保持の 3 つの操作が含まれます) 最初の 10 文字を保持し、次の 20 文字を太字にします。差分は次のとおりです。 { 「オプス」: [ { "保持": }、 { "保持": 、 "属性": { "太字": } } ] } 最初の 10 文字を保持し、次の 20 文字を削除します。 { 「オプス」: [ { "保持": }、 { "消去": } ] } 2. 羊皮紙 Parchment は、Blots を管理する抽象的なドキュメント モデルです。 Parchment が完全な DOM ツリー構造として理解される場合、Blot はその中の単一のノードです。 Quill のデフォルトの機能に加えて、Blot ではカスタマイズも可能で、拡張の余地が広がります。 3. ブロット Blot は Parchment ドキュメントのコンポーネントであり、DOM ノード タイプの抽象化に相当します。ただし、特定の Blot インスタンスには他のノード情報も含まれています。 グローバル ルート ノード Blot は、Quill によってカスタマイズされたスクロール タイプの Blot であり、その下のすべての Blot を管理します。 Blot の実装定義については、こちらを参照してください: https://github.com/quilljs/parchment#blots Quill における Blot のデフォルトの定義は次のとおりです。 一般的なものには、TextBlot (1 行内の通常のテキスト)、Inline (1 行内のスタイル付き通常のテキスト)、Block (ブロック レベルの行、通常は段落 p 内)、Break (改行)、Image (画像 IMG 挿入)、Bold (太字テキスト) などがあります。 HTML の一部はどのようにしてブロットを構築するのでしょうか? Quill は、ノード タイプに基づいてテキスト ノードを除外する優先順位を決定します。要素ノードの場合は、ノードの ClassName に基づいて再度判断されます。一致する BlotName が見つからない場合は、デフォルトで次のマッピング関係が一致し、対応する BlotClass が検索されます。 4. デルタの実際的意義 コンテンツ構造を表す Blot はすでにあるのに、なぜ Delta が必要なのでしょうか? Delta 自体はコンテンツ データのメンテナンスにすぎません。つまり、ユーザー入力であれ API 操作であれ、HTML の更新はすべて Delta に同期して更新されます。Delta が HTML のデータ ソースとして使用されていない場合、Delta データのコピーを維持する意味は何でしょうか。 HTML => Delta であるが、Delta=> HTML が存在しない場合は、デルタを常に維持する意味は何でしょうか? 1. Delta から HTML を生成することは実際に存在しますが、その適用シナリオはドキュメントの初期化に限定されています。Quill は、受信した初期化 HTML 文字列を解析し、対応する Delta を生成します。次に、Delta を適用して DOM ノードを生成し、ページに表示します。 2. これでもまだ満足できないかもしれません。なぜこのプロセスを実行する必要があるのでしょうか。初期化中に文字列 document.getElementById('container').innerHTML = val を使用すればよいのではないでしょうか。はい、できますが、Delta の存在により、ユーザーのドキュメントはより細分化され、保守しやすく、追跡しやすくなります。 A と B が同時にドキュメントを編集していて、A が 2 行目の 10 文字を削除した場合、ドキュメントのコンテンツ全体を更新する必要はありません。代わりに、A は自分の動作を同期するアクションを送信するだけで済み、B は競合を解決してマージするだけで済みます。 Delta メンテナンスによりロジックはより複雑になりますが、Delta が存在することでドキュメント拡張の可能性も広がります。 5. エディターのレンダリングと更新プロセス コンテンツを変更するには、次の 3 つの方法があります。 1. エディターのコンテンツを初期化します。quill.pasteHTML への呼び出しを初期化し、HTML のフィルタリングと解析を行った後、編集ボックスにエコーします。 2. 入力イベント: ユーザーの入力と編集操作は MutationObserver によって監視および処理され、デルタが更新されます。 3. API 呼び出し: 内部的に提供されている API を、modify メソッドを通じて呼び出し、次にグローバル Scroll インスタンスのメソッドを呼び出して変更します。 2. カスタムHTMLブロックを挿入する 記事の内容が多様化するにつれ、記事内に地図や音楽プレーヤー、広告パネルなどを挿入する必要が生じ、リッチテキストエディタをより多くの機能に拡張する必要が生じています。しかし同時に、XSS 保護攻撃も適切に行う必要があります。 最初の部分によると、カスタム HTML ブロックを挿入する必要があり、Quill がそれを認識できる必要があります。お気づきかと思いますが、Blot をカスタマイズする必要があります。 Blot メソッドを定義することで、Quill は初期化中に HTML ブロックの表示を認識できるようになり、また、HTML ブロックを挿入するときに Quill がダーティ HTML をフィルタリングするのを防ぐこともできます。 登録ブロット方式は以下のとおりです。 デフォルト関数をエクスポートする(Quill){ // ソースコードからBlockEmbedをインポートする const BlockEmbed = Quill.import('blots/block/embed'); // 新しいブロットタイプクラスを定義する AppPanelEmbed extends BlockEmbed { 静的作成(値) { 定数ノード = super.create(値); ノードの属性を設定します('contenteditable', 'false'); ノード.setAttribute('幅', '100%'); // カスタム HTML を設定する node.innerHTML = this.transformValue(値) ノードを返します。 } 静的変換値(値) { handleArr = value.split('\n') とします。 handleArr = handleArr.map(e => e.replace(/^[\s]+/, '') .replace(/[\s]+$/, '')) handleArr.join('') を返します } // 操作を元に戻すためのノード自体の値を返す static value(node) { node.innerHTML を返す } } // ブロット名 AppPanelEmbed.blotName = 'AppPanelEmbed'; // クラス名はブロット名と一致するために使用されます AppPanelEmbed.className = 'embed-innerApp'; // タグ タイプをカスタマイズします AppPanelEmbed.tagName = 'div'; Quill.register(AppPanelEmbed, true); } 次に、カスタム HTML ブロックをエディターに挿入するには、次のように呼び出す必要があります。 quill.insertEmbed(quill.getSelection().index || 0, 'AppPanelEmbed', ` <div class="app_card_header"> カスタムパネルタイトル</div> <div class="app_card_content"> パネルのコンテンツをカスタマイズする</div> <div class="app_card_footer"> フッター </div> `); パラメータ形式の要件は次のとおりです。 insertEmbed(インデックス: Number, タイプ: String, 値: any, ソース: String \= 'api'): Delta これは単なる簡単な例です。カスタム Blot の機能を充実させたい場合は、https://github.com/quilljs/parchment#blots を参照してください。 contenteditable 属性が解放されているため、XSS 攻撃を防ぐために、この属性に対して特別なフィルタリングを実行する必要があります。ここでは、XSS モジュール処理を例に挙げます。 ハンドルWithXss(コンテンツ) { 定数オプション = { ホワイトリスト: { ... div: ['class', 'style', 'data-id', 'contenteditable'], ... }, css: { ホワイトリスト: { 色: 真、 '背景色': true、 '最大幅': true、 }, }, タグを無視: true, onTagAttr: (タグ、名前、値、isWhiteAttr) => { // div の contenteditable を処理します if (isWhiteAttr && tag === 'div' && name === 'contenteditable') { 'contenteditable="false"' を返します。 } }, } // カスタムルール const myxss = new xss.FilterXSS(options) myxss.process(コンテンツ) を返す } Quill エディターでカスタム HTML レコードを挿入する方法に関するこの記事はこれで終わりです。Quill エディターのカスタム HTML コンテンツの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。 |
<<: クロスオリジン画像リソース権限(CORS 対応画像)
>>: ブルートフォース攻撃を防ぐためのシェルスクリプト設定
1. CentOS 7 仮想マシンを開きます。 2. 仮想マシンにログインし、リストにないユーザー名...
目次1. はじめに2. 行き詰まった問題の分析3. 解決策(理論) 4. ソリューション(コード) ...
コンピュータ サイエンスで最も一般的に使用され、議論されているデータ構造の 1 つは、二分探索木です...
この記事では、参考までに、簡単なメモ帳機能を実装するためのVueの具体的なコードを紹介します。具体的...
目次序文yumソース、epelソースを設定するCephソースの設定Cephとそのコンポーネントをイン...
SQL (Structured Query Language) ステートメント、つまり構造化クエリ言...
目次概要機能性と読みやすさ空白括弧セミコロンインデント身元大文字と小文字を区別予約キーワード概要すべ...
Vue では、一般的にフロントエンドとバックエンドを分離したプロジェクトがあり、データ操作を実装する...
この記事の例では、テーブルを追加および削除するためのjsの具体的なコードを参考までに共有しています。...
一般的に使用される Oracle10g パーティションは、範囲 (範囲パーティション)、リスト (リ...
目次1. はじめに2. 本文2.1 Where句の位置2.2 演算子2.3 NULL値1. はじめに...
序文通常のビジネスニーズ: 写真、Excel などをアップロードします。結局のところ、数 MB のサ...
データの挿入テーブル名(列名1、列名2、列名3)の値(値1、値2、値3)に挿入します。ユーザーに(u...
たとえば、昨日新規登録されたユーザーを照会するには、次の 2 つの書き方があります。 説明する ch...
I. はじめにDockerテクノロジーは現在非常に人気があります。コンテナを介してプロジェクト環境を...