diff --git a/Libraries/LibWeb/Editing/CommandNames.h b/Libraries/LibWeb/Editing/CommandNames.h
index d4fcdb6c1f3..84d9f7e5fce 100644
--- a/Libraries/LibWeb/Editing/CommandNames.h
+++ b/Libraries/LibWeb/Editing/CommandNames.h
@@ -40,6 +40,7 @@ namespace Web::Editing::CommandNames {
__ENUMERATE_COMMAND_NAME(justifyRight, "justifyRight") \
__ENUMERATE_COMMAND_NAME(outdent, "outdent") \
__ENUMERATE_COMMAND_NAME(paste, "paste") \
+ __ENUMERATE_COMMAND_NAME(preserveWhitespace, "preserveWhitespace") \
__ENUMERATE_COMMAND_NAME(redo, "redo") \
__ENUMERATE_COMMAND_NAME(removeFormat, "removeFormat") \
__ENUMERATE_COMMAND_NAME(selectAll, "selectAll") \
diff --git a/Libraries/LibWeb/Editing/Commands.cpp b/Libraries/LibWeb/Editing/Commands.cpp
index c6d9ed6a4e3..300b26bdb9f 100644
--- a/Libraries/LibWeb/Editing/Commands.cpp
+++ b/Libraries/LibWeb/Editing/Commands.cpp
@@ -2657,6 +2657,15 @@ static Array const commands {
.preserves_overrides = true,
.mapped_value = "formatOutdent"_fly_string,
},
+ // AD-HOC: This is a Ladybird-specific formatting command that is not part of the spec. It has no action and as
+ // such, it's not supported in userland (yet). The relevant CSS property `white-space` is used to indicate
+ // that if this style value is found during editing commands, it is recorded and restored where necessary.
+ // This is used to keep things like
..
intact when a selection is
+ // deleted, for example.
+ CommandDefinition {
+ .command = CommandNames::preserveWhitespace,
+ .relevant_css_property = CSS::PropertyID::WhiteSpace,
+ },
// https://w3c.github.io/editing/docs/execCommand/#the-removeformat-command
CommandDefinition {
.command = CommandNames::removeFormat,
diff --git a/Libraries/LibWeb/Editing/ExecCommand.cpp b/Libraries/LibWeb/Editing/ExecCommand.cpp
index 9d31239de63..89eead0af36 100644
--- a/Libraries/LibWeb/Editing/ExecCommand.cpp
+++ b/Libraries/LibWeb/Editing/ExecCommand.cpp
@@ -360,10 +360,11 @@ WebIDL::ExceptionOr Document::query_command_supported(FlyString const& com
if (!is_html_document())
return WebIDL::InvalidStateError::create(realm(), "queryCommandSupported is only supported on HTML documents"_string);
- // When the queryCommandSupported(command) method on the Document interface is invoked, the
- // user agent must return true if command is supported and available within the current script
- // on the current site, and false otherwise.
- return Editing::find_command_definition(command).has_value();
+ // When the queryCommandSupported(command) method on the Document interface is invoked, the user agent must return
+ // true if command is supported and available within the current script on the current site, and false otherwise.
+ // AD-HOC: Supported commands should have an action defined. Currently, ::preserveWhitespace does not have one.
+ auto command_definition = Editing::find_command_definition(command);
+ return command_definition.has_value() && command_definition->action;
}
// https://w3c.github.io/editing/docs/execCommand/#querycommandvalue()
diff --git a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp
index 48abcb2d721..ce8f04e5453 100644
--- a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp
+++ b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp
@@ -3333,9 +3333,10 @@ Vector record_the_values_of_nodes(Vector>
// 2. For each node in node list, for each command in the list "subscript", "bold", "fontName",
// "fontSize", "foreColor", "hiliteColor", "italic", "strikethrough", and "underline" in that
// order:
+ // AD-HOC: We include "preserveWhitespace" as well.
Array const commands = { CommandNames::subscript, CommandNames::bold, CommandNames::fontName,
CommandNames::fontSize, CommandNames::foreColor, CommandNames::hiliteColor, CommandNames::italic,
- CommandNames::strikethrough, CommandNames::underline };
+ CommandNames::strikethrough, CommandNames::underline, CommandNames::preserveWhitespace };
for (auto node : node_list) {
for (auto command : commands) {
// 1. Let ancestor equal node.
diff --git a/Tests/LibWeb/Text/expected/Editing/execCommand-preserveWhitespace.txt b/Tests/LibWeb/Text/expected/Editing/execCommand-preserveWhitespace.txt
new file mode 100644
index 00000000000..b6db7c81e10
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/Editing/execCommand-preserveWhitespace.txt
@@ -0,0 +1,2 @@
+Before: foobar
+After: foobar
diff --git a/Tests/LibWeb/Text/input/Editing/execCommand-preserveWhitespace.html b/Tests/LibWeb/Text/input/Editing/execCommand-preserveWhitespace.html
new file mode 100644
index 00000000000..46900f3769e
--- /dev/null
+++ b/Tests/LibWeb/Text/input/Editing/execCommand-preserveWhitespace.html
@@ -0,0 +1,19 @@
+
+
+
+