今天看 Quill Editor 的 Model 技術文件介紹,根據文件的描述,語意版本控制(Semantic Versioning)不適用於實驗性 API,意思是 Model 的 API 目前仍然處於實驗性階段,代表未來可能會出現一些重大的改動而影響到 API 的穩定性,但可以先看過一遍並嘗試玩看看,未來有機會正式發布後,再考慮應用到正式的專案上。
透過 Model API 找到的 Blot 物件是 LinkedList
的資料結構:
find
這是一個靜態方法,可以代入 DOM 節點並回傳 Quill 或 Blot Instance。在後者的情況下,對 bubble
參數傳入 true 會向上尋找目標 DOM 的祖先,直到找到相應的 Blot。
方法:
Quill.find(domNode: Node, bubble: boolean = false): Blot | Quill
範例:
find(quill: Quill, container: HTMLElement) {
// 帶入 container 尋找並取得 quill instance
const target = Quill.find(container);
console.log('target is quill instance', target === quill);
// 編輯器輸入連結文字並嘗試取得 link node
quill.insertText(0, 'Hello, World!', 'link', 'https://google.com');
const linkNode = container.querySelector('a');
const findLinkNode = Quill.find(linkNode!);
console.log('linkNode', findLinkNode);
}
getIndex
回傳從文件開頭到帶入的 blot 之間的距離長度。
方法:
getIndex(blot: Blot): Number
範例:
// 預先輸入文字並取得第 10 個字元的 blot
quill.insertText(0, 'Hello, World!');
const [line, offset] = quill.getLine(10);
console.log('line', line);
// 帶入 blot 取得 index
const index = quill.getIndex(line); // index + offset should == 10
console.log('index', index);
console.log('offset', offset);
getLeaf
回傳文件中指定索引處的葉節點。leaf
通常指的是資料結構中的末端節點。
方法:
getLeaf(index: Number): Blot
範例:
quill.setText('Hello Good World!');
quill.formatText(6, 4, 'bold', true);
const [leaf, offset] = quill.getLeaf(7);
// leaf 會是帶有值為 "Good" 的葉節點
// offset 應為 1,因為回傳的葉節點在索引 6 開始
console.log('leaf', leaf);
console.log('offset', offset);
getLine
回傳帶入的索引值指定位置的行 blot 。
方法:
getLine(index: Number): [Blot, Number]
範例:
quill.setText('Hello\nWorld!');
const [line, offset] = quill.getLine(7);
// line 應為代表第二個 "World!" 行的 Block Blot
console.log('line', line);
// offset 為 1,因為 index 7 是在第二行 "World!" 的第二個字元
console.log('offset', offset);
getLines
回傳指定位置的行中所包含的 blot。
方法:
getLines(index: Number = 0, length: Number = remaining): Blot[]
getLines(range: Range): Blot[]
範例:
quill.setText('Hello\nGood\nWorld!');
quill.formatLine(1, 1, 'list', 'bullet');
const lines = quill.getLines(2, 5);
// 帶有 ListItem 與 Block Blot 的陣列
// 代表是前面的兩行
console.log('lines', lines);
// 帶入 range 物件
const linesByRange = quill.getLines({ index: 8, length: 5 });
console.log('linesByRange', linesByRange);
小結
今天看了 Model 提供的 API,這些 API 主要是用於尋找 Blot 的相關應用,對於未來要自訂編輯器模組的功能實現時,可以利用這些 API 來找到正確的 Blot 並進一步處理文本內容,並且 Blot 提供的是 linkedList
的資料結構,因此對於節點的尋找來說,未來編輯內容量大的時候,可以研究看看linkedList
訪問節點的技巧來實現較有效率的搜尋處理。
Quill 的觀念基本上不難,較有挑戰的地方在於未來要滿足各種特殊需求時,要建立自訂的 Blot 必須要很清楚底層的生命週期與處理過程,這樣才能打造出高效且實用的自訂功能。找時間再繼續研究使用一些第三方套件,並嘗試了解這些套件是如何實現的,對於自訂功能的實現與優化應該會有所幫助。
再整理一下今天嘗試的 API:
find
:透過 DOM 節點找到 Quill 或 Blot 實例。getIndex
:回傳文件開頭到指定 blot 之間的距離。getLeaf
:回傳指定索引處的葉節點。getLine
:回傳指定索引位置的行 blot。getLines
:回傳指定位置內的所有行 blot。
雜記
今天突然意識到,這星期上完班之後,又是一個連續假期,這次的假期是要回宜蘭帶朋友四處走走,雖然住在宜蘭很久了,但還是有不少地方沒去過,趁這個機會去走走看。不過 11 月就完全沒有連假了,週末期望能好好的學習,並嘗試一些新玩意兒,還有買了一些書,要好好的閱讀一番。
Reference
文章同步發表於2023 iThome 鐵人賽