Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/fluent-editor/src/modules/custom-clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ const Delta = Quill.import('delta')
export class CustomClipboard extends Clipboard {
declare quill: FluentEditor

constructor(public quill: FluentEditor) {
super(quill)
Comment on lines 23 to +26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Quill clipboard module constructor signature options parameter

💡 Result:

In Quill v2, the Clipboard module constructor is:

constructor(quill: Quill, options: Partial<ClipboardOptions>)

where:

interface ClipboardOptions {
  matchers: [Selector, Matcher][];
}

type Selector = string | Node['TEXT_NODE'] | Node['ELEMENT_NODE'];
type Matcher = (node: Node, delta: Delta, scroll: ScrollBlot) => Delta;

So the only documented/typed option is matchers, an array of [selectorOrNodeType, matcherFn] entries. These configured matchers are appended after Quill’s default clipboard matchers (e.g., via modules: { clipboard: { matchers: [...] } }). [1], [2]


🏁 Script executed:

cat -n packages/fluent-editor/src/modules/custom-clipboard.ts | head -50

Repository: opentiny/tiny-editor

Length of output: 1996


Constructor signature mismatch with Quill module system.

Quill v2's Clipboard module constructor expects (quill: Quill, options: Partial<ClipboardOptions>) where options.matchers allows users to configure custom clipboard matchers. This constructor only accepts quill, which means:

  1. Any options passed by Quill are silently dropped
  2. User-configured clipboard matchers will be lost
  3. The super(quill) call doesn't forward options to the parent Clipboard class

Additionally, the declare quill: FluentEditor on line 23 is redundant and should be removed since it's redeclared as public on line 25.

The event listener added on line 28 is never cleaned up, creating a potential memory leak if the editor instance is destroyed or recreated.

🔧 Proposed fix to accept and forward options
 export class CustomClipboard extends Clipboard {
-  declare quill: FluentEditor
 
-  constructor(public quill: FluentEditor) {
-    super(quill)
+  constructor(quill: FluentEditor, options?: Record<string, unknown>) {
+    super(quill, options)
+    this.quill = quill

Also consider storing the listener reference and removing it on cleanup to prevent memory leaks:

+  private inputListener = () => {
+    if (this.quill.root.innerText !== '\n' && this.quill.root.classList.contains('ql-blank')) {
+      this.quill.root.classList.toggle('ql-blank', false)
+    }
+    else {
+      this.quill.options.placeholder = this.quill.getLangText('editor-placeholder')
+    }
+  }
+
   constructor(quill: FluentEditor, options?: Record<string, unknown>) {
     super(quill, options)
     this.quill = quill
-    this.quill.root.addEventListener('input', () => { ... })
+    this.quill.root.addEventListener('input', this.inputListener)
+  }
+
+  destroy() {
+    this.quill.root.removeEventListener('input', this.inputListener)
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
declare quill: FluentEditor
constructor(public quill: FluentEditor) {
super(quill)
constructor(quill: FluentEditor, options?: Record<string, unknown>) {
super(quill, options)
this.quill = quill
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/fluent-editor/src/modules/custom-clipboard.ts` around lines 23 - 26,
The constructor for your custom Clipboard module is incorrect: remove the
redundant "declare quill: FluentEditor" and change the constructor signature to
accept both (quill: FluentEditor, options?: Partial<ClipboardOptions>) and
forward options to the parent by calling super(quill, options) so Quill-provided
matchers and options aren't dropped; also capture the event listener handler you
add (store the reference) and remove it during cleanup/destroy (e.g., on module
teardown or override a destroy method) to avoid the memory leak.

// 解决 quill 组件在中文输入法的情景下开始输入placeholder不消失的问题
this.quill.root.addEventListener('input', () => {
if (this.quill.root.innerText !== '\\n' && this.quill.root.classList.contains('ql-blank')) {
this.quill.root.classList.toggle('ql-blank', false)
}
else {
this.quill.options.placeholder = this.quill.getLangText('editor-placeholder')
}
})
}

prepareMatching(container: HTMLElement, nodeMatches) {
const elementMatchers = []
const textMatchers = []
Expand Down
Loading