mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-30 12:49:19 +00:00
LibWeb: Treat execCommand
command names as case insensitive
This commit is contained in:
parent
26ea5335c7
commit
dccb374876
Notes:
github-actions[bot]
2025-02-08 12:31:22 +00:00
Author: https://github.com/tcl3
Commit: dccb374876
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3470
3 changed files with 46 additions and 8 deletions
|
@ -45,8 +45,11 @@ WebIDL::ExceptionOr<bool> Document::exec_command(FlyString const& command, [[may
|
||||||
// classified with the miscellaneous events, we'd have to stop firing events for consistency's sake.
|
// classified with the miscellaneous events, we'd have to stop firing events for consistency's sake.
|
||||||
//
|
//
|
||||||
// AD-HOC: The defaultParagraphSeparator command is also in the Miscellaneous commands section
|
// AD-HOC: The defaultParagraphSeparator command is also in the Miscellaneous commands section
|
||||||
|
auto optional_command = Editing::find_command_definition(command);
|
||||||
|
VERIFY(optional_command.has_value());
|
||||||
|
auto const& command_definition = optional_command.release_value();
|
||||||
GC::Ptr<Node> affected_editing_host;
|
GC::Ptr<Node> affected_editing_host;
|
||||||
if (!command.is_one_of(Editing::CommandNames::copy, Editing::CommandNames::cut,
|
if (!command_definition.command.is_one_of(Editing::CommandNames::copy, Editing::CommandNames::cut,
|
||||||
Editing::CommandNames::defaultParagraphSeparator, Editing::CommandNames::paste, Editing::CommandNames::redo,
|
Editing::CommandNames::defaultParagraphSeparator, Editing::CommandNames::paste, Editing::CommandNames::redo,
|
||||||
Editing::CommandNames::selectAll, Editing::CommandNames::styleWithCSS, Editing::CommandNames::undo,
|
Editing::CommandNames::selectAll, Editing::CommandNames::styleWithCSS, Editing::CommandNames::undo,
|
||||||
Editing::CommandNames::useCSS)) {
|
Editing::CommandNames::useCSS)) {
|
||||||
|
@ -89,9 +92,6 @@ WebIDL::ExceptionOr<bool> Document::exec_command(FlyString const& command, [[may
|
||||||
|
|
||||||
// https://w3c.github.io/editing/docs/execCommand/#preserves-overrides
|
// https://w3c.github.io/editing/docs/execCommand/#preserves-overrides
|
||||||
// If a command preserves overrides, then before taking its action, the user agent must record current overrides.
|
// If a command preserves overrides, then before taking its action, the user agent must record current overrides.
|
||||||
auto optional_command = Editing::find_command_definition(command);
|
|
||||||
VERIFY(optional_command.has_value());
|
|
||||||
auto const& command_definition = optional_command.release_value();
|
|
||||||
Vector<Editing::RecordedOverride> overrides;
|
Vector<Editing::RecordedOverride> overrides;
|
||||||
if (command_definition.preserves_overrides)
|
if (command_definition.preserves_overrides)
|
||||||
overrides = Editing::record_current_overrides(*this);
|
overrides = Editing::record_current_overrides(*this);
|
||||||
|
@ -146,7 +146,7 @@ WebIDL::ExceptionOr<bool> Document::query_command_enabled(FlyString const& comma
|
||||||
// Among commands defined in this specification, those listed in Miscellaneous commands are always enabled, except
|
// Among commands defined in this specification, those listed in Miscellaneous commands are always enabled, except
|
||||||
// for the cut command and the paste command.
|
// for the cut command and the paste command.
|
||||||
// NOTE: cut and paste are actually in the Clipboard commands section
|
// NOTE: cut and paste are actually in the Clipboard commands section
|
||||||
if (command.is_one_of(
|
if (command.is_one_of_ignoring_ascii_case(
|
||||||
Editing::CommandNames::defaultParagraphSeparator,
|
Editing::CommandNames::defaultParagraphSeparator,
|
||||||
Editing::CommandNames::redo,
|
Editing::CommandNames::redo,
|
||||||
Editing::CommandNames::styleWithCSS,
|
Editing::CommandNames::styleWithCSS,
|
||||||
|
@ -155,7 +155,7 @@ WebIDL::ExceptionOr<bool> Document::query_command_enabled(FlyString const& comma
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// AD-HOC: selectAll requires a selection object to exist.
|
// AD-HOC: selectAll requires a selection object to exist.
|
||||||
if (command == Editing::CommandNames::selectAll)
|
if (command.equals_ignoring_ascii_case(Editing::CommandNames::selectAll))
|
||||||
return get_selection() != nullptr;
|
return get_selection() != nullptr;
|
||||||
|
|
||||||
// The other commands defined here are enabled if the active range is not null,
|
// The other commands defined here are enabled if the active range is not null,
|
||||||
|
@ -195,7 +195,7 @@ WebIDL::ExceptionOr<bool> Document::query_command_enabled(FlyString const& comma
|
||||||
// the spec is that certain commands must not be enabled if the editing host is in the plaintext-only state.
|
// the spec is that certain commands must not be enabled if the editing host is in the plaintext-only state.
|
||||||
if (auto const* html_element = as_if<HTML::HTMLElement>(inclusive_ancestor_editing_host.ptr()); html_element
|
if (auto const* html_element = as_if<HTML::HTMLElement>(inclusive_ancestor_editing_host.ptr()); html_element
|
||||||
&& html_element->content_editable_state() == HTML::ContentEditableState::PlaintextOnly
|
&& html_element->content_editable_state() == HTML::ContentEditableState::PlaintextOnly
|
||||||
&& command.is_one_of(
|
&& command.is_one_of_ignoring_ascii_case(
|
||||||
Editing::CommandNames::backColor,
|
Editing::CommandNames::backColor,
|
||||||
Editing::CommandNames::bold,
|
Editing::CommandNames::bold,
|
||||||
Editing::CommandNames::createLink,
|
Editing::CommandNames::createLink,
|
||||||
|
@ -242,7 +242,7 @@ WebIDL::ExceptionOr<bool> Document::query_command_indeterm(FlyString const& comm
|
||||||
// https://w3c.github.io/editing/docs/execCommand/#inline-command-activated-values
|
// https://w3c.github.io/editing/docs/execCommand/#inline-command-activated-values
|
||||||
// If a command is a standard inline value command, it is indeterminate if among formattable nodes that are
|
// If a command is a standard inline value command, it is indeterminate if among formattable nodes that are
|
||||||
// effectively contained in the active range, there are two that have distinct effective command values.
|
// effectively contained in the active range, there are two that have distinct effective command values.
|
||||||
if (command.is_one_of(Editing::CommandNames::backColor, Editing::CommandNames::fontName,
|
if (command_definition.command.is_one_of(Editing::CommandNames::backColor, Editing::CommandNames::fontName,
|
||||||
Editing::CommandNames::foreColor, Editing::CommandNames::hiliteColor)) {
|
Editing::CommandNames::foreColor, Editing::CommandNames::hiliteColor)) {
|
||||||
Optional<String> first_node_value;
|
Optional<String> first_node_value;
|
||||||
auto range = Editing::active_range(*this);
|
auto range = Editing::active_range(*this);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
queryCommandSupported("selectall"): true
|
||||||
|
queryCommandEnabled("selectall"): true
|
||||||
|
execCommand("selectall"): PASS
|
||||||
|
queryCommandSupported("SELECTALL"): true
|
||||||
|
queryCommandEnabled("SELECTALL"): true
|
||||||
|
execCommand("SELECTALL"): PASS
|
||||||
|
queryCommandSupported("SeLeCtAlL"): true
|
||||||
|
queryCommandEnabled("SeLeCtAlL"): true
|
||||||
|
execCommand("SeLeCtAlL"): PASS
|
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<body></body>
|
||||||
|
<script>
|
||||||
|
function execCommandCaseInsensitivityTest(command) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const iframe = document.createElement("iframe");
|
||||||
|
iframe.srcdoc = `<div>PASS</div>`;
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
iframe.onload = () => {
|
||||||
|
const iframeDocument = iframe.contentDocument;
|
||||||
|
iframeDocument.execCommand(command);
|
||||||
|
|
||||||
|
const selection = iframeDocument.getSelection();
|
||||||
|
println(`queryCommandSupported("${command}"): ${iframeDocument.queryCommandSupported(command)}`);
|
||||||
|
println(`queryCommandEnabled("${command}"): ${iframeDocument.queryCommandEnabled(command)}`);
|
||||||
|
println(`execCommand("${command}"): ${selection.toString()}`);
|
||||||
|
iframe.remove();
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
asyncTest(async done => {
|
||||||
|
for (command of ["selectall", "SELECTALL", "SeLeCtAlL"]) {
|
||||||
|
await execCommandCaseInsensitivityTest(command);
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue