Skip to content
Open
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions packages/quill/src/modules/toolbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ class Toolbar extends Module<ToolbarProps> {
debug.warn('ignoring attaching to nonexistent format', format, input);
return;
}
if (input.tagName === 'BUTTON') {
input.addEventListener('mousedown', (event) => {
// Keep the editor selection when a button is clicked inside a modal dialog.
if (event.button === 0) event.preventDefault();
});
}
const eventName = input.tagName === 'SELECT' ? 'change' : 'click';
input.addEventListener(eventName, (e) => {
let value;
Expand Down
49 changes: 49 additions & 0 deletions packages/quill/test/e2e/toolbar.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { expect } from '@playwright/test';
import { test } from './fixtures/index.js';

for (const modal of [false, true]) {
test(`toolbar preserves a selected range in a ${modal ? 'modal' : 'non-modal'} dialog`, async ({
page,
editorPage,
}) => {
await editorPage.open();
await page.evaluate((isModal) => {
const dialog = document.createElement('dialog');
dialog.appendChild(document.querySelector('#standalone-container')!);
document.body.appendChild(dialog);
if (isModal) dialog.showModal();
else dialog.show();
}, modal);
await editorPage.root.fill('Hello world');
await editorPage.selectText('Hello');

const bold = page.locator('.ql-bold');
for (const formatted of [true, false]) {
await bold.hover();
await page.mouse.down();
// Hold the button as in a slow click, allowing selectionchange to run.
await page.waitForTimeout(150);
expect(
await page.evaluate(() => document.getSelection()?.toString()),
).toBe('Hello');
await page.mouse.up();

await expect(editorPage.root).toHaveJSProperty(
'innerHTML',
formatted
? '<p><strong>Hello</strong> world</p>'
: '<p>Hello world</p>',
);
expect(await editorPage.getSelection()).toEqual({ index: 0, length: 5 });
}

await bold.focus();
await page.keyboard.press('Enter');
await expect(editorPage.root).toHaveJSProperty(
'innerHTML',
'<p><strong>Hello</strong> world</p>',
);
await expect(editorPage.root).toBeFocused();
expect(await editorPage.getSelection()).toEqual({ index: 0, length: 5 });
});
}