Skip to content
Merged
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
2 changes: 1 addition & 1 deletion lib/lexxy/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Engine < ::Rails::Engine
ActionText::ContentHelper.allowed_tags = default_allowed_tags + %w[ video audio source embed table tbody tr th td ]

default_allowed_attributes = Class.new.include(ActionText::ContentHelper).new.sanitizer_allowed_attributes
ActionText::ContentHelper.allowed_attributes = default_allowed_attributes + %w[ controls poster data-language style ]
ActionText::ContentHelper.allowed_attributes = default_allowed_attributes + %w[ controls poster data-language style value ]

Loofah::HTML5::SafeList::ALLOWED_CSS_FUNCTIONS << "var"
end
Expand Down
4 changes: 4 additions & 0 deletions src/extensions/format_escape_extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export class FormatEscapeExtension extends LexxyExtension {
return this.editorElement.supportsRichText
}

get allowedElements() {
return [ { tag: "li", attributes: [ "value" ] } ]
}
Comment thread
zoltanhosszu marked this conversation as resolved.

get lexicalExtension() {
return defineExtension({
name: "lexxy/format-escape",
Expand Down
28 changes: 19 additions & 9 deletions test/browser/tests/formatting/block_formatting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ test.describe("Block formatting", () => {
await editor.setValue(HELLO_EVERYONE)
await editor.select("everyone")
await page.getByRole("button", { name: "Bullet list" }).click()
await assertEditorHtml(editor, "<ul><li>Hello everyone</li></ul>")
await assertEditorHtml(editor, '<ul><li value="1">Hello everyone</li></ul>')
})

test("toggle bullet list off", async ({ page, editor }) => {
await editor.setValue(HELLO_EVERYONE)
await editor.select("everyone")
await page.getByRole("button", { name: "Bullet list" }).click()
await assertEditorHtml(editor, "<ul><li>Hello everyone</li></ul>")
await assertEditorHtml(editor, '<ul><li value="1">Hello everyone</li></ul>')

await editor.select("everyone")
await page.getByRole("button", { name: "Bullet list" }).click()
Expand All @@ -52,7 +52,7 @@ test.describe("Block formatting", () => {
await editor.setValue("<p>Alpha</p><p>Bravo</p><p>Charlie</p>")
await editor.selectAll()
await page.getByRole("button", { name: "Bullet list" }).click()
await assertEditorHtml(editor, "<ul><li>Alpha</li><li>Bravo</li><li>Charlie</li></ul>")
await assertEditorHtml(editor, '<ul><li value="1">Alpha</li><li value="2">Bravo</li><li value="3">Charlie</li></ul>')

await editor.selectAll()
await page.getByRole("button", { name: "Bullet list" }).click()
Expand All @@ -70,14 +70,14 @@ test.describe("Block formatting", () => {
await editor.setValue(HELLO_EVERYONE)
await editor.select("everyone")
await page.getByRole("button", { name: "Numbered list" }).click()
await assertEditorHtml(editor, "<ol><li>Hello everyone</li></ol>")
await assertEditorHtml(editor, '<ol><li value="1">Hello everyone</li></ol>')
})

test("toggle numbered list off", async ({ page, editor }) => {
await editor.setValue(HELLO_EVERYONE)
await editor.select("everyone")
await page.getByRole("button", { name: "Numbered list" }).click()
await assertEditorHtml(editor, "<ol><li>Hello everyone</li></ol>")
await assertEditorHtml(editor, '<ol><li value="1">Hello everyone</li></ol>')

await editor.select("everyone")
await page.getByRole("button", { name: "Numbered list" }).click()
Expand All @@ -88,13 +88,23 @@ test.describe("Block formatting", () => {
await editor.setValue("<p>Alpha</p><p>Bravo</p><p>Charlie</p>")
await editor.selectAll()
await page.getByRole("button", { name: "Numbered list" }).click()
await assertEditorHtml(editor, "<ol><li>Alpha</li><li>Bravo</li><li>Charlie</li></ol>")
await assertEditorHtml(editor, '<ol><li value="1">Alpha</li><li value="2">Bravo</li><li value="3">Charlie</li></ol>')

await editor.selectAll()
await page.getByRole("button", { name: "Numbered list" }).click()
await assertEditorHtml(editor, "<p>Alpha</p><p>Bravo</p><p>Charlie</p>")
})

test("ordered list exports li value attribute", async ({ editor }) => {
await editor.setValue("<ol><li>First</li><li>Second</li></ol>")
await assertEditorHtml(editor, '<ol><li value="1">First</li><li value="2">Second</li></ol>')
})

Comment thread
zoltanhosszu marked this conversation as resolved.
test("nested ordered list numbering is calculated correctly", async ({ editor }) => {
await editor.setValue('<ol><li>First</li><li><ol><li>Nested</li></ol></li><li>Second</li></ol>')
await assertEditorHtml(editor, '<ol><li value="1">First</li><li value="2" class="lexxy-nested-listitem"><ol><li value="1">Nested</li></ol></li><li value="2">Second</li></ol>')
})

test("insert quote without selection", async ({ page, editor }) => {
await editor.setValue(HELLO_EVERYONE)
await page.getByRole("button", { name: "Quote" }).click()
Expand Down Expand Up @@ -225,7 +235,7 @@ test.describe("Block formatting", () => {

await assertEditorHtml(
editor,
"<p>First line</p><ul><li>Second line</li></ul><p>Third line</p>",
'<p>First line</p><ul><li value="1">Second line</li></ul><p>Third line</p>',
)
})

Expand All @@ -240,7 +250,7 @@ test.describe("Block formatting", () => {

await assertEditorHtml(
editor,
"<p>First line</p><ol><li>Second line</li></ol><p>Third line</p>",
'<p>First line</p><ol><li value="1">Second line</li></ol><p>Third line</p>',
)
})

Expand All @@ -255,7 +265,7 @@ test.describe("Block formatting", () => {

await assertEditorHtml(
editor,
"<ul><li>First item<br>continuation</li></ul>",
'<ul><li value="1">First item<br>continuation</li></ul>',
)
})

Expand Down
14 changes: 7 additions & 7 deletions test/browser/tests/formatting/escape_format.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ test.describe("Escape format", () => {
await editor.selectAll()

await page.getByRole("button", { name: "Bullet list" }).click()
await assertEditorHtml(editor, "<ul><li>First line</li></ul>")
await assertEditorHtml(editor, "<ul><li value=\"1\">First line</li></ul>")

await clickToolbarButton(page, "insertQuoteBlock")
await assertEditorHtml(
editor,
"<blockquote><ul><li>First line</li></ul></blockquote>",
"<blockquote><ul><li value=\"1\">First line</li></ul></blockquote>",
)

await editor.send("ArrowRight")
Expand All @@ -30,7 +30,7 @@ test.describe("Escape format", () => {

await assertEditorHtml(
editor,
"<blockquote><ul><li>First line</li></ul></blockquote><p>Outside quote</p>",
"<blockquote><ul><li value=\"1\">First line</li></ul></blockquote><p>Outside quote</p>",
)
})

Expand Down Expand Up @@ -74,7 +74,7 @@ test.describe("Escape format", () => {
await clickToolbarButton(page, "insertQuoteBlock")
await assertEditorHtml(
editor,
"<blockquote><ul><li>Item one</li><li>Item two</li><li>Item three</li></ul></blockquote>",
"<blockquote><ul><li value=\"1\">Item one</li><li value=\"2\">Item two</li><li value=\"3\">Item three</li></ul></blockquote>",
)

await editor.select("Item two")
Expand All @@ -86,7 +86,7 @@ test.describe("Escape format", () => {

await assertEditorHtml(
editor,
"<blockquote><ul><li>Item one</li><li>Item two</li></ul></blockquote><p>Middle text</p><blockquote><ul><li>Item three</li></ul></blockquote>",
"<blockquote><ul><li value=\"1\">Item one</li><li value=\"2\">Item two</li></ul></blockquote><p>Middle text</p><blockquote><ul><li value=\"1\">Item three</li></ul></blockquote>",
)
})

Expand All @@ -101,7 +101,7 @@ test.describe("Escape format", () => {
await clickToolbarButton(page, "insertQuoteBlock")
await assertEditorHtml(
editor,
"<blockquote><ul><li>Item one</li></ul></blockquote>",
"<blockquote><ul><li value=\"1\">Item one</li></ul></blockquote>",
)

await editor.send("ArrowRight")
Expand All @@ -111,7 +111,7 @@ test.describe("Escape format", () => {

await assertEditorHtml(
editor,
"<blockquote><ul><li>Item one</li></ul></blockquote><p>After escape</p>",
"<blockquote><ul><li value=\"1\">Item one</li></ul></blockquote><p>After escape</p>",
)
})

Expand Down
2 changes: 1 addition & 1 deletion test/browser/tests/formatting/inline_code_escape.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test.describe("Inline code escape with arrow keys", () => {
await editor.send("ArrowRight")
await editor.send(" more")

await assertEditorHtml(editor, "<ul><li>item <code>code</code> more</li></ul>")
await assertEditorHtml(editor, '<ul><li value="1">item <code>code</code> more</li></ul>')
})

test("right arrow escapes inline code when code is only content in paragraph", async ({ page, editor }) => {
Expand Down
12 changes: 6 additions & 6 deletions test/browser/tests/formatting/list_indentation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test.describe("List indentation", () => {

await assertEditorHtml(
editor,
'<ul><li>First item</li><li class="lexxy-nested-listitem"><ul><li>Second item</li></ul></li></ul>',
'<ul><li value="1">First item</li><li value="2" class="lexxy-nested-listitem"><ul><li value="1">Second item</li></ul></li></ul>',
)
})

Expand All @@ -31,7 +31,7 @@ test.describe("List indentation", () => {

await assertEditorHtml(
editor,
'<ul><li>First</li><li class="lexxy-nested-listitem"><ul><li class="lexxy-nested-listitem"><ul><li>Second</li></ul></li></ul></li></ul>',
'<ul><li value="1">First</li><li value="2" class="lexxy-nested-listitem"><ul><li value="1" class="lexxy-nested-listitem"><ul><li value="1">Second</li></ul></li></ul></li></ul>',
)
})

Expand All @@ -47,7 +47,7 @@ test.describe("List indentation", () => {

await assertEditorHtml(
editor,
'<ul><li>First</li><li class="lexxy-nested-listitem"><ul><li>Second</li></ul></li></ul>',
'<ul><li value="1">First</li><li value="2" class="lexxy-nested-listitem"><ul><li value="1">Second</li></ul></li></ul>',
)
})

Expand All @@ -61,7 +61,7 @@ test.describe("List indentation", () => {

await assertEditorHtml(
editor,
"<ul><li>First item</li><li>Nested item</li></ul>",
'<ul><li value="1">First item</li><li value="2">Nested item</li></ul>',
)
})

Expand All @@ -74,7 +74,7 @@ test.describe("List indentation", () => {

await assertEditorHtml(
editor,
'<ol><li>First item</li><li class="lexxy-nested-listitem"><ol><li>Second item</li></ol></li></ol>',
'<ol><li value="1">First item</li><li value="2" class="lexxy-nested-listitem"><ol><li value="1">Second item</li></ol></li></ol>',
)
})

Expand All @@ -88,7 +88,7 @@ test.describe("List indentation", () => {

await assertEditorHtml(
editor,
"<ol><li>First item</li><li>Nested item</li></ol>",
'<ol><li value="1">First item</li><li value="2">Nested item</li></ol>',
)
})

Expand Down
16 changes: 8 additions & 8 deletions test/browser/tests/formatting/list_item_deletion.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ test.describe("List item deletion cursor position", () => {
editor,
}) => {
// Set up a bullet list with one item
await editor.setValue("<ul><li>Some text</li></ul>")
await editor.setValue("<ul><li value=\"1\">Some text</li></ul>")
await editor.flush()

// Place cursor at the very start of "Some text"
Expand All @@ -33,22 +33,22 @@ test.describe("List item deletion cursor position", () => {
await editor.send("Backspace")
await editor.flush()

await assertEditorHtml(editor, "<p><br></p><ul><li>Some text</li></ul>")
await assertEditorHtml(editor, "<p><br></p><ul><li value=\"1\">Some text</li></ul>")

// Type a marker character to verify cursor position.
// Cursor should be in the new paragraph, so marker appears there.
await editor.send("X")
await editor.flush()

await assertEditorHtml(editor, "<p>X</p><ul><li>Some text</li></ul>")
await assertEditorHtml(editor, "<p>X</p><ul><li value=\"1\">Some text</li></ul>")
})

test("backspace on empty first list item with paragraph above converts to paragraph", async ({
editor,
}) => {
// Set up content before the list, then a list
await editor.setValue(
"<p>Paragraph above</p><ul><li>List item text</li></ul>",
"<p>Paragraph above</p><ul><li value=\"1\">List item text</li></ul>",
)
await editor.flush()

Expand Down Expand Up @@ -76,7 +76,7 @@ test.describe("List item deletion cursor position", () => {

await assertEditorHtml(
editor,
"<p>Paragraph above</p><p>X</p><ul><li>List item text</li></ul>",
"<p>Paragraph above</p><p>X</p><ul><li value=\"1\">List item text</li></ul>",
)
})

Expand All @@ -85,7 +85,7 @@ test.describe("List item deletion cursor position", () => {
}) => {
// Set up a bullet list with two items
await editor.setValue(
"<ul><li>First item</li><li>Second item</li></ul>",
"<ul><li value=\"1\">First item</li><li value=\"2\">Second item</li></ul>",
)
await editor.flush()

Expand All @@ -109,7 +109,7 @@ test.describe("List item deletion cursor position", () => {

await assertEditorHtml(
editor,
"<ul><li>First item</li><li>Second item</li></ul>",
"<ul><li value=\"1\">First item</li><li value=\"2\">Second item</li></ul>",
)

// Type a marker to verify cursor is at the end of "First item"
Expand All @@ -118,7 +118,7 @@ test.describe("List item deletion cursor position", () => {

await assertEditorHtml(
editor,
"<ul><li>First itemX</li><li>Second item</li></ul>",
"<ul><li value=\"1\">First itemX</li><li value=\"2\">Second item</li></ul>",
)
})
})
Loading