連假第三天,終於來到最後的兩個章節,Clipboard & Syntax Highlighter Module。因為篇幅比較沒有那麼多,所以就放在一起看了。

剪貼簿 ( Clipboard Module ),負責處理 Quill Editor 與外部 App 之間的複製、剪下與貼上的操作。Clipboard module 提供了一組預設的判斷邏輯處理貼上的內容,並且我們能進一步通過加入自定義的匹配器(matcher)來調整或擴充這些預設行為。例如:我們可以讓特定的 HTML 標籤或文字段落在貼上時有特殊的格式或行為。

剪貼簿會通過後序遍歷(post-order)相應的 DOM 樹來處理貼上的 HTML,從而建構所有子樹的 Delta 表示形式。在每個子節點,matcher 函數會被呼叫,並傳入 DOM 節點和到目前為止的 Delta 處理,這樣可以讓 matcher 回傳一個修改過的 Delta。要能操作好 matcher,就需要熟悉和理解 Delta。

可用的 API

addMatcher

將自定義 matcher 新增到 clipboard module。使用 nodeType 的 matcher 會先被呼叫,按照它們被加入的順序,另一個是使用 CSS selector 的 matcher,也是按照被加入的順序。nodeType 可能是 Node.ELEMENT_NODENode.TEXT_NODE

方法:

addMatcher(selector: String, (node: Node, delta: Delta) => Delta)
addMatcher(nodeType: Number, (node: Node, delta: Delta) => Delta)

範例:

quill.clipboard.addMatcher(Node.TEXT_NODE, function(node, delta) {
  return new Delta().insert(node.data);
});

// Interpret a <b> tag as bold
quill.clipboard.addMatcher('B', function(node, delta) {
  return delta.compose(new Delta().retain(delta.length(), { bold: true }));
});

dangerouslyPasteHTML

在指定的索引位置將由 HTML 片段表示的內容插入到編輯器中。該片段會被剪貼簿的匹配器解釋,這可能不會產生完全相同的輸入 HTML。如果沒有提供插入索引,則會覆蓋整個編輯器的內容。來源可能是 “user”、”api” 或 “silent”。

不正確的處理 HTML 可能會導致跨站腳本攻擊(XSS),而未能正確清理 (sanitize) 則是引發網站漏洞的主要原因之一。明確的命名這個方法,以確保我們能注意到使用這個方法可能涉及的風險。這個命名方式也遵循了 React 框架的例子,React 也有類似的概念,如 dangerouslySetInnerHTML 用來提醒開發者必須謹慎操作。

方法:

dangerouslyPasteHTML(html: String, source: String = 'api')
dangerouslyPasteHTML(index: Number, html: String, source: String = 'api')

範例:

quill.setText('Hello!');
quill.clipboard.dangerouslyPasteHTML(5, ' <b>World</b>');
// 編輯器的 HTML 文本內容會是 '<p>Hello <strong>World</strong>!</p>';

Clipboard 配置設定

matchers

可以將 matcher 陣列傳遞到剪貼簿的配置選項中。這些將附加在 Quill 內建的 matcher 之後。

var quill = new Quill('#editor', {
  modules: {
    clipboard: {
      matchers: [
        ['B', customMatcherA],
        [Node.TEXT_NODE, customMatcherB]
      ]
    }
  }
});

Syntax Highlighter Module

語法高亮模組(Syntax Highlighter Module)在 Quill Editor 中用於增強程式碼區塊內容(Code Block)格式。它會自動檢測並套用語法高亮效果,且依賴於 highlight.js 函式庫來解析和標記程式碼區塊。

我們可以根據需求來配置 highlight.js。不過,Quill 要求 useBR 的選項必須設為 false。

範例:

<!-- 引入 highlight.js 樣式表 -->
<link href="highlight.js/monokai-sublime.min.css" rel="stylesheet">


<!-- 引入 highlight.js 函式庫 -->
<script href="highlight.js"></script>

  

<script>
hljs.configure({   // optionally configure hljs
  languages: ['javascript', 'ruby', 'python']
});

var quill = new Quill('#editor', {
  modules: {
    syntax: true,              // Include syntax module
    toolbar: [['code-block']]  // Include button in toolbar
  },
  theme: 'snow'
});
</script>

小結

剪貼簿(Clipboard)模組在 Quill Editor 中負責處理與外部應用間的複製、剪下和貼上操作。它提供了一套預設行為來解析貼上的內容,並允許開發者透過自定義 matcher 來進一步調整這些行為。這些 matcher 可以按照它們被加入的順序來進行呼叫,而在貼上 HTML 時,剪貼簿會後序遍歷對應的 DOM 樹來創建一個 Delta 表示形式。

基於安全性考慮,提供了一個 dangerouslyPasteHTML 的API,用在確認安全的操作情境下插入 HTML。剪貼簿模組不僅提供了彈性的自訂方式,也考慮到貼上內容的安全處理,使 Quill 更靈活實用。

雜記

儘管昨日發現前一晚停車時刮到了輪拱板金,心情受到一些影響之外,整體的行程還不錯,在金車威士忌酒廠待了一整天,雖然之前也去過幾次,但都沒有導覽員,這次趁著人多時,有導覽員的服務,也學到不少威士忌的一些觀念,今天出發前就發了這篇文章,預計會去傳統藝術中心,今天天氣看起來很不錯,要多喝水避免被太陽曬昏頭了 XD

Reference

文章同步發表於2023 iThome 鐵人賽