diff --git a/packages/quill/src/core/editor.ts b/packages/quill/src/core/editor.ts
index b6391a7cd4..9b08ba1dbe 100644
--- a/packages/quill/src/core/editor.ts
+++ b/packages/quill/src/core/editor.ts
@@ -337,10 +337,17 @@ function convertListHTML(
}
const [{ child, offset, length, indent, type }, ...rest] = items;
const [tag, attribute] = getListType(type);
+ const classes =
+ child.domNode instanceof Element
+ ? Array.from(child.domNode.classList)
+ .filter((className) => !className.startsWith('ql-indent-'))
+ .join(' ')
+ : '';
+ const classAttribute = classes ? ` class="${escapeText(classes)}"` : '';
if (indent > lastIndent) {
types.push(type);
if (indent === lastIndent + 1) {
- return `<${tag}>
${convertHTML(
+ return `<${tag}>${convertHTML(
child,
offset,
length,
@@ -350,7 +357,7 @@ function convertListHTML(
}
const previousType = types[types.length - 1];
if (indent === lastIndent && type === previousType) {
- return `${convertHTML(
+ return `${convertHTML(
child,
offset,
length,
diff --git a/packages/quill/test/unit/core/editor.spec.ts b/packages/quill/test/unit/core/editor.spec.ts
index 2d47a1dec9..b0abf8a240 100644
--- a/packages/quill/test/unit/core/editor.spec.ts
+++ b/packages/quill/test/unit/core/editor.spec.ts
@@ -17,6 +17,7 @@ import { FontClass } from '../../../src/formats/font.js';
import Header from '../../../src/formats/header.js';
import Italic from '../../../src/formats/italic.js';
import { AlignClass } from '../../../src/formats/align.js';
+import { DirectionClass } from '../../../src/formats/direction.js';
import Video from '../../../src/formats/video.js';
import Strike from '../../../src/formats/strike.js';
import Underline from '../../../src/formats/underline.js';
@@ -47,6 +48,7 @@ const createEditor = (htmlOrContents: string | Delta) => {
Header,
Italic,
AlignClass,
+ DirectionClass,
Video,
Strike,
Underline,
@@ -1242,6 +1244,122 @@ describe('Editor', () => {
expect(editor.getHTML(0, 5)).toEqual('');
});
+ test('aligned bullet list', () => {
+ const editor = createEditor(
+ `
+
+ - One
+ - Two
+ - Three
+
+ `,
+ );
+ expect(editor.getHTML(0, 14)).toEqualHTML(`
+
+ `);
+ });
+
+ test('aligned ordered list', () => {
+ const editor = createEditor(
+ `
+
+ - One
+ - Two
+
+ `,
+ );
+ expect(editor.getHTML(0, 8)).toEqualHTML(`
+
+ - One
+ - Two
+
+ `);
+ });
+
+ test('aligned checklist', () => {
+ const editor = createEditor(
+ `
+
+ - One
+ - Two
+
+ `,
+ );
+ expect(editor.getHTML(0, 8)).toEqualHTML(`
+
+
+ `);
+ });
+
+ test('aligned nested list with skipped indent', () => {
+ const editor = createEditor(
+ `
+
+ - One
+ - Two
+
+ `,
+ );
+ expect(editor.getHTML(0, 8)).toEqualHTML(`
+
+ `);
+ });
+
+ test('indent-only list item', () => {
+ const editor = createEditor(
+ `
+
+ - One
+
+ `,
+ );
+ expect(editor.getHTML(0, 4)).toEqualHTML(`
+
+ `);
+ });
+
+ test('list item direction and custom classes', () => {
+ const editor = createEditor(
+ '- One
',
+ );
+ editor.scroll.domNode.querySelector('li')!.classList.add('custom');
+ expect(editor.getHTML(0, 4)).toEqualHTML(`
+
+ `);
+ });
+
+ test('escape list item class attribute', () => {
+ const editor = createEditor('- One
');
+ editor.scroll.domNode.querySelector('li')!.classList.add('custom"&<>');
+ expect(editor.getHTML(0, 4)).toEqual(
+ '',
+ );
+ });
+
test('across lines', () => {
const editor = createEditor(
'Header
Text
Quote
',