LibWeb: Pass Utf16String around directly in Editing APIs
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

Noticed while working adjacent to these APIs that we take a Utf16String
and pass it around as a Utf16View, only to re-allocate the Utf16String
in many commands. Let's just pass the string itself around.
This commit is contained in:
Timothy Flynn 2025-07-25 16:09:44 -04:00 committed by Jelle Raaijmakers
commit 3a072f66e3
Notes: github-actions[bot] 2025-07-25 22:41:28 +00:00
4 changed files with 105 additions and 113 deletions

View file

@ -27,10 +27,10 @@
namespace Web::Editing {
// https://w3c.github.io/editing/docs/execCommand/#the-backcolor-command
bool command_back_color_action(DOM::Document& document, Utf16View const& value)
bool command_back_color_action(DOM::Document& document, Utf16String const& value)
{
// 1. If value is not a valid CSS color, prepend "#" to it.
auto resulting_value = Utf16String::from_utf16_without_validation(value);
auto resulting_value = value;
if (!Color::from_utf16_string(resulting_value).has_value()) {
resulting_value = Utf16String::formatted("#{}", resulting_value);
@ -43,23 +43,23 @@ bool command_back_color_action(DOM::Document& document, Utf16View const& value)
}
// 3. Set the selection's value to value.
set_the_selections_value(document, CommandNames::backColor, resulting_value.utf16_view());
set_the_selections_value(document, CommandNames::backColor, resulting_value);
// 4. Return true.
return true;
}
// https://w3c.github.io/editing/docs/execCommand/#the-bold-command
bool command_bold_action(DOM::Document& document, Utf16View const&)
bool command_bold_action(DOM::Document& document, Utf16String const&)
{
// If queryCommandState("bold") returns true, set the selection's value to "normal".
if (MUST(document.query_command_state(CommandNames::bold))) {
set_the_selections_value(document, CommandNames::bold, u"normal"sv);
set_the_selections_value(document, CommandNames::bold, "normal"_utf16);
}
// Otherwise set the selection's value to "bold".
else {
set_the_selections_value(document, CommandNames::bold, u"bold"sv);
set_the_selections_value(document, CommandNames::bold, "bold"_utf16);
}
// Either way, return true.
@ -67,7 +67,7 @@ bool command_bold_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-createlink-command
bool command_create_link_action(DOM::Document& document, Utf16View const& value)
bool command_create_link_action(DOM::Document& document, Utf16String const& value)
{
// 1. If value is the empty string, return false.
if (value.is_empty())
@ -100,7 +100,7 @@ bool command_create_link_action(DOM::Document& document, Utf16View const& value)
}
// https://w3c.github.io/editing/docs/execCommand/#the-defaultparagraphseparator-command
bool command_default_paragraph_separator_action(DOM::Document& document, Utf16View const& input_value)
bool command_default_paragraph_separator_action(DOM::Document& document, Utf16String const& input_value)
{
// Let value be converted to ASCII lowercase.
auto value = input_value.to_ascii_lowercase();
@ -128,7 +128,7 @@ Utf16String command_default_paragraph_separator_value(DOM::Document const& docum
}
// https://w3c.github.io/editing/docs/execCommand/#the-delete-command
bool command_delete_action(DOM::Document& document, Utf16View const&)
bool command_delete_action(DOM::Document& document, Utf16String const&)
{
// 1. If the active range is not collapsed, delete the selection and return true.
auto& selection = *document.get_selection();
@ -495,7 +495,7 @@ bool command_delete_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-fontname-command
bool command_font_name_action(DOM::Document& document, Utf16View const& value)
bool command_font_name_action(DOM::Document& document, Utf16String const& value)
{
// Set the selection's value to value, then return true.
set_the_selections_value(document, CommandNames::fontName, value);
@ -509,10 +509,10 @@ enum class FontSizeMode : u8 {
};
// https://w3c.github.io/editing/docs/execCommand/#the-fontsize-command
bool command_font_size_action(DOM::Document& document, Utf16View const& value)
bool command_font_size_action(DOM::Document& document, Utf16String const& value)
{
// 1. Strip leading and trailing whitespace from value.
auto resulting_value = value.trim_ascii_whitespace();
auto resulting_value = value.utf16_view().trim_ascii_whitespace();
// 2. If value is not a valid floating point number, and would not be a valid floating point number if a single
// leading "+" character were stripped, return false.
@ -567,7 +567,7 @@ bool command_font_size_action(DOM::Document& document, Utf16View const& value)
resulting_value = font_sizes[number - 1];
// 12. Set the selection's value to value.
set_the_selections_value(document, CommandNames::fontSize, resulting_value);
set_the_selections_value(document, CommandNames::fontSize, Utf16String::from_utf16_without_validation(resulting_value));
// 13. Return true.
return true;
@ -595,7 +595,7 @@ Utf16String command_font_size_value(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-forecolor-command
bool command_fore_color_action(DOM::Document& document, Utf16View const& value)
bool command_fore_color_action(DOM::Document& document, Utf16String const& value)
{
// 1. If value is not a valid CSS color, prepend "#" to it.
auto resulting_value = value;
@ -618,7 +618,7 @@ bool command_fore_color_action(DOM::Document& document, Utf16View const& value)
}
// https://w3c.github.io/editing/docs/execCommand/#the-formatblock-command
bool command_format_block_action(DOM::Document& document, Utf16View const& value)
bool command_format_block_action(DOM::Document& document, Utf16String const& value)
{
// 1. If value begins with a "<" character and ends with a ">" character, remove the first and last characters from
// it.
@ -871,7 +871,7 @@ Utf16String command_format_block_value(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-forwarddelete-command
bool command_forward_delete_action(DOM::Document& document, Utf16View const&)
bool command_forward_delete_action(DOM::Document& document, Utf16String const&)
{
// 1. If the active range is not collapsed, delete the selection and return true.
auto& selection = *document.get_selection();
@ -1062,7 +1062,7 @@ bool command_forward_delete_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-indent-command
bool command_indent_action(DOM::Document& document, Utf16View const&)
bool command_indent_action(DOM::Document& document, Utf16String const&)
{
// 1. Let items be a list of all lis that are inclusive ancestors of the active range's start and/or end node.
Vector<GC::Ref<DOM::Node>> items;
@ -1137,7 +1137,7 @@ bool command_indent_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-inserthorizontalrule-command
bool command_insert_horizontal_rule_action(DOM::Document& document, Utf16View const&)
bool command_insert_horizontal_rule_action(DOM::Document& document, Utf16String const&)
{
// 1. Let start node, start offset, end node, and end offset be the active range's start and end nodes and offsets.
auto range = active_range(document);
@ -1206,7 +1206,7 @@ bool command_insert_horizontal_rule_action(DOM::Document& document, Utf16View co
}
// https://w3c.github.io/editing/docs/execCommand/#the-inserthtml-command
bool command_insert_html_action(DOM::Document& document, Utf16View const& value)
bool command_insert_html_action(DOM::Document& document, Utf16String const& value)
{
// FIXME: 1. Set value to the result of invoking get trusted types compliant string with TrustedHTML, this's relevant
// global object, value, "Document execCommand", and "script".
@ -1278,7 +1278,7 @@ bool command_insert_html_action(DOM::Document& document, Utf16View const& value)
}
// https://w3c.github.io/editing/docs/execCommand/#the-insertimage-command
bool command_insert_image_action(DOM::Document& document, Utf16View const& value)
bool command_insert_image_action(DOM::Document& document, Utf16String const& value)
{
// 1. If value is the empty string, return false.
if (value.is_empty())
@ -1323,7 +1323,7 @@ bool command_insert_image_action(DOM::Document& document, Utf16View const& value
}
// https://w3c.github.io/editing/docs/execCommand/#the-insertlinebreak-command
bool command_insert_linebreak_action(DOM::Document& document, Utf16View const&)
bool command_insert_linebreak_action(DOM::Document& document, Utf16String const&)
{
// 1. Delete the selection, with strip wrappers false.
auto& selection = *document.get_selection();
@ -1397,7 +1397,7 @@ bool command_insert_linebreak_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-insertorderedlist-command
bool command_insert_ordered_list_action(DOM::Document& document, Utf16View const&)
bool command_insert_ordered_list_action(DOM::Document& document, Utf16String const&)
{
// Toggle lists with tag name "ol", then return true.
toggle_lists(document, HTML::TagNames::ol);
@ -1419,7 +1419,7 @@ bool command_insert_ordered_list_state(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-insertparagraph-command
bool command_insert_paragraph_action(DOM::Document& document, Utf16View const&)
bool command_insert_paragraph_action(DOM::Document& document, Utf16String const&)
{
// 1. Delete the selection.
auto& selection = *document.get_selection();
@ -1730,7 +1730,7 @@ bool command_insert_paragraph_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-inserttext-command
bool command_insert_text_action(DOM::Document& document, Utf16View const& value)
bool command_insert_text_action(DOM::Document& document, Utf16String const& value)
{
// 1. Delete the selection, with strip wrappers false.
auto& selection = *document.get_selection();
@ -1744,8 +1744,10 @@ bool command_insert_text_action(DOM::Document& document, Utf16View const& value)
// 3. If value's length is greater than one:
if (value.length_in_code_units() > 1) {
// 1. For each code unit el in value, take the action for the insertText command, with value equal to el.
for (size_t i = 0; i < value.length_in_code_units(); ++i)
take_the_action_for_command(document, CommandNames::insertText, value.substring_view(i, 1));
for (size_t i = 0; i < value.length_in_code_units(); ++i) {
auto code_unit = value.code_unit_at(i);
take_the_action_for_command(document, CommandNames::insertText, Utf16String::from_code_point(code_unit));
}
// 2. Return true.
return true;
@ -1812,7 +1814,7 @@ bool command_insert_text_action(DOM::Document& document, Utf16View const& value)
node->first_child()->remove();
// 2. Let text be the result of calling createTextNode(value) on the context object.
auto text = document.create_text_node(Utf16String::from_utf16_without_validation(value));
auto text = document.create_text_node(value);
// 3. Call insertNode(text) on the active range.
MUST(active_range(document)->insert_node(text));
@ -1845,7 +1847,7 @@ bool command_insert_text_action(DOM::Document& document, Utf16View const& value)
}
// https://w3c.github.io/editing/docs/execCommand/#the-insertunorderedlist-command
bool command_insert_unordered_list_action(DOM::Document& document, Utf16View const&)
bool command_insert_unordered_list_action(DOM::Document& document, Utf16String const&)
{
// Toggle lists with tag name "ul", then return true.
toggle_lists(document, HTML::TagNames::ul);
@ -1867,16 +1869,16 @@ bool command_insert_unordered_list_state(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-italic-command
bool command_italic_action(DOM::Document& document, Utf16View const&)
bool command_italic_action(DOM::Document& document, Utf16String const&)
{
// If queryCommandState("italic") returns true, set the selection's value to "normal".
if (MUST(document.query_command_state(CommandNames::italic))) {
set_the_selections_value(document, CommandNames::italic, u"normal"sv);
set_the_selections_value(document, CommandNames::italic, "normal"_utf16);
}
// Otherwise set the selection's value to "italic".
else {
set_the_selections_value(document, CommandNames::italic, u"italic"sv);
set_the_selections_value(document, CommandNames::italic, "italic"_utf16);
}
// Either way, return true.
@ -1962,7 +1964,7 @@ static Utf16String justify_value(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-justifycenter-command
bool command_justify_center_action(DOM::Document& document, Utf16View const&)
bool command_justify_center_action(DOM::Document& document, Utf16String const&)
{
// Justify the selection with alignment "center", then return true.
justify_the_selection(document, JustifyAlignment::Center);
@ -1988,7 +1990,7 @@ Utf16String command_justify_center_value(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-justifyfull-command
bool command_justify_full_action(DOM::Document& document, Utf16View const&)
bool command_justify_full_action(DOM::Document& document, Utf16String const&)
{
// Justify the selection with alignment "justify", then return true.
justify_the_selection(document, JustifyAlignment::Justify);
@ -2014,7 +2016,7 @@ Utf16String command_justify_full_value(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-justifyleft-command
bool command_justify_left_action(DOM::Document& document, Utf16View const&)
bool command_justify_left_action(DOM::Document& document, Utf16String const&)
{
// Justify the selection with alignment "left", then return true.
justify_the_selection(document, JustifyAlignment::Left);
@ -2040,7 +2042,7 @@ Utf16String command_justify_left_value(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-justifyright-command
bool command_justify_right_action(DOM::Document& document, Utf16View const&)
bool command_justify_right_action(DOM::Document& document, Utf16String const&)
{
// Justify the selection with alignment "right", then return true.
justify_the_selection(document, JustifyAlignment::Right);
@ -2066,7 +2068,7 @@ Utf16String command_justify_right_value(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-outdent-command
bool command_outdent_action(DOM::Document& document, Utf16View const&)
bool command_outdent_action(DOM::Document& document, Utf16String const&)
{
// 1. Let items be a list of all lis that are inclusive ancestors of the active range's start and/or end node.
Vector<GC::Ref<DOM::Node>> items;
@ -2157,7 +2159,7 @@ bool command_outdent_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-removeformat-command
bool command_remove_format_action(DOM::Document& document, Utf16View const&)
bool command_remove_format_action(DOM::Document& document, Utf16String const&)
{
// 1. Let elements to remove be a list of every removeFormat candidate effectively contained in the active range.
Vector<GC::Ref<DOM::Element>> elements_to_remove;
@ -2232,7 +2234,7 @@ bool command_remove_format_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-selectall-command
bool command_select_all_action(DOM::Document& document, Utf16View const&)
bool command_select_all_action(DOM::Document& document, Utf16String const&)
{
// NOTE: The spec mentions "This is totally broken". So fair warning :^)
@ -2259,7 +2261,7 @@ bool command_select_all_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-strikethrough-command
bool command_strikethrough_action(DOM::Document& document, Utf16View const&)
bool command_strikethrough_action(DOM::Document& document, Utf16String const&)
{
// If queryCommandState("strikethrough") returns true, set the selection's value to null.
if (MUST(document.query_command_state(CommandNames::strikethrough))) {
@ -2268,7 +2270,7 @@ bool command_strikethrough_action(DOM::Document& document, Utf16View const&)
// Otherwise set the selection's value to "line-through".
else {
set_the_selections_value(document, CommandNames::strikethrough, u"line-through"sv);
set_the_selections_value(document, CommandNames::strikethrough, "line-through"_utf16);
}
// Either way, return true.
@ -2276,7 +2278,7 @@ bool command_strikethrough_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-stylewithcss-command
bool command_style_with_css_action(DOM::Document& document, Utf16View const& value)
bool command_style_with_css_action(DOM::Document& document, Utf16String const& value)
{
// If value is an ASCII case-insensitive match for the string "false", set the CSS styling flag to false.
// Otherwise, set the CSS styling flag to true.
@ -2294,7 +2296,7 @@ bool command_style_with_css_state(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-subscript-command
bool command_subscript_action(DOM::Document& document, Utf16View const&)
bool command_subscript_action(DOM::Document& document, Utf16String const&)
{
// 1. Call queryCommandState("subscript"), and let state be the result.
auto state = MUST(document.query_command_state(CommandNames::subscript));
@ -2304,7 +2306,7 @@ bool command_subscript_action(DOM::Document& document, Utf16View const&)
// 3. If state is false, set the selection's value to "subscript".
if (!state)
set_the_selections_value(document, CommandNames::subscript, u"subscript"sv);
set_the_selections_value(document, CommandNames::subscript, "subscript"_utf16);
// 4. Return true.
return true;
@ -2347,7 +2349,7 @@ bool command_subscript_indeterminate(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-superscript-command
bool command_superscript_action(DOM::Document& document, Utf16View const&)
bool command_superscript_action(DOM::Document& document, Utf16String const&)
{
// 1. Call queryCommandState("superscript"), and let state be the result.
auto state = MUST(document.query_command_state(CommandNames::superscript));
@ -2357,7 +2359,7 @@ bool command_superscript_action(DOM::Document& document, Utf16View const&)
// 3. If state is false, set the selection's value to "superscript".
if (!state)
set_the_selections_value(document, CommandNames::superscript, u"superscript"sv);
set_the_selections_value(document, CommandNames::superscript, "superscript"_utf16);
// 4. Return true.
return true;
@ -2400,7 +2402,7 @@ bool command_superscript_indeterminate(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#the-underline-command
bool command_underline_action(DOM::Document& document, Utf16View const&)
bool command_underline_action(DOM::Document& document, Utf16String const&)
{
// If queryCommandState("underline") returns true, set the selection's value to null.
if (MUST(document.query_command_state(CommandNames::underline))) {
@ -2409,7 +2411,7 @@ bool command_underline_action(DOM::Document& document, Utf16View const&)
// Otherwise set the selection's value to "underline".
else {
set_the_selections_value(document, CommandNames::underline, u"underline"sv);
set_the_selections_value(document, CommandNames::underline, "underline"_utf16);
}
// Either way, return true.
@ -2417,7 +2419,7 @@ bool command_underline_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-unlink-command
bool command_unlink_action(DOM::Document& document, Utf16View const&)
bool command_unlink_action(DOM::Document& document, Utf16String const&)
{
// 1. Let hyperlinks be a list of every a element that has an href attribute and is contained in the active range or
// is an ancestor of one of its boundary points.
@ -2452,7 +2454,7 @@ bool command_unlink_action(DOM::Document& document, Utf16View const&)
}
// https://w3c.github.io/editing/docs/execCommand/#the-usecss-command
bool command_use_css_action(DOM::Document& document, Utf16View const& value)
bool command_use_css_action(DOM::Document& document, Utf16String const& value)
{
// If value is an ASCII case-insensitive match for the string "false", set the CSS styling flag to true.
// Otherwise, set the CSS styling flag to false.

View file

@ -16,7 +16,7 @@ namespace Web::Editing {
// https://w3c.github.io/editing/docs/execCommand/#properties-of-commands
struct CommandDefinition {
FlyString const& command;
Function<bool(DOM::Document&, Utf16View const&)> action {};
Function<bool(DOM::Document&, Utf16String const&)> action {};
Function<bool(DOM::Document const&)> indeterminate {};
Function<bool(DOM::Document const&)> state {};
Function<Utf16String(DOM::Document const&)> value {};
@ -35,62 +35,62 @@ struct CommandDefinition {
Optional<CommandDefinition const&> find_command_definition(FlyString const&);
// Command implementations
bool command_back_color_action(DOM::Document&, Utf16View const&);
bool command_bold_action(DOM::Document&, Utf16View const&);
bool command_create_link_action(DOM::Document&, Utf16View const&);
bool command_default_paragraph_separator_action(DOM::Document&, Utf16View const&);
bool command_back_color_action(DOM::Document&, Utf16String const&);
bool command_bold_action(DOM::Document&, Utf16String const&);
bool command_create_link_action(DOM::Document&, Utf16String const&);
bool command_default_paragraph_separator_action(DOM::Document&, Utf16String const&);
Utf16String command_default_paragraph_separator_value(DOM::Document const&);
bool command_delete_action(DOM::Document&, Utf16View const&);
bool command_font_name_action(DOM::Document&, Utf16View const&);
bool command_font_size_action(DOM::Document&, Utf16View const&);
bool command_delete_action(DOM::Document&, Utf16String const&);
bool command_font_name_action(DOM::Document&, Utf16String const&);
bool command_font_size_action(DOM::Document&, Utf16String const&);
Utf16String command_font_size_value(DOM::Document const&);
bool command_fore_color_action(DOM::Document&, Utf16View const&);
bool command_format_block_action(DOM::Document&, Utf16View const&);
bool command_fore_color_action(DOM::Document&, Utf16String const&);
bool command_format_block_action(DOM::Document&, Utf16String const&);
bool command_format_block_indeterminate(DOM::Document const&);
Utf16String command_format_block_value(DOM::Document const&);
bool command_forward_delete_action(DOM::Document&, Utf16View const&);
bool command_indent_action(DOM::Document&, Utf16View const&);
bool command_insert_horizontal_rule_action(DOM::Document&, Utf16View const&);
bool command_insert_html_action(DOM::Document&, Utf16View const&);
bool command_insert_image_action(DOM::Document&, Utf16View const&);
bool command_insert_linebreak_action(DOM::Document&, Utf16View const&);
bool command_insert_ordered_list_action(DOM::Document&, Utf16View const&);
bool command_forward_delete_action(DOM::Document&, Utf16String const&);
bool command_indent_action(DOM::Document&, Utf16String const&);
bool command_insert_horizontal_rule_action(DOM::Document&, Utf16String const&);
bool command_insert_html_action(DOM::Document&, Utf16String const&);
bool command_insert_image_action(DOM::Document&, Utf16String const&);
bool command_insert_linebreak_action(DOM::Document&, Utf16String const&);
bool command_insert_ordered_list_action(DOM::Document&, Utf16String const&);
bool command_insert_ordered_list_indeterminate(DOM::Document const&);
bool command_insert_ordered_list_state(DOM::Document const&);
bool command_insert_paragraph_action(DOM::Document&, Utf16View const&);
bool command_insert_text_action(DOM::Document&, Utf16View const&);
bool command_insert_unordered_list_action(DOM::Document&, Utf16View const&);
bool command_insert_paragraph_action(DOM::Document&, Utf16String const&);
bool command_insert_text_action(DOM::Document&, Utf16String const&);
bool command_insert_unordered_list_action(DOM::Document&, Utf16String const&);
bool command_insert_unordered_list_indeterminate(DOM::Document const&);
bool command_insert_unordered_list_state(DOM::Document const&);
bool command_italic_action(DOM::Document&, Utf16View const&);
bool command_justify_center_action(DOM::Document&, Utf16View const&);
bool command_italic_action(DOM::Document&, Utf16String const&);
bool command_justify_center_action(DOM::Document&, Utf16String const&);
bool command_justify_center_indeterminate(DOM::Document const&);
bool command_justify_center_state(DOM::Document const&);
Utf16String command_justify_center_value(DOM::Document const&);
bool command_justify_full_action(DOM::Document&, Utf16View const&);
bool command_justify_full_action(DOM::Document&, Utf16String const&);
bool command_justify_full_indeterminate(DOM::Document const&);
bool command_justify_full_state(DOM::Document const&);
Utf16String command_justify_full_value(DOM::Document const&);
bool command_justify_left_action(DOM::Document&, Utf16View const&);
bool command_justify_left_action(DOM::Document&, Utf16String const&);
bool command_justify_left_indeterminate(DOM::Document const&);
bool command_justify_left_state(DOM::Document const&);
Utf16String command_justify_left_value(DOM::Document const&);
bool command_justify_right_action(DOM::Document&, Utf16View const&);
bool command_justify_right_action(DOM::Document&, Utf16String const&);
bool command_justify_right_indeterminate(DOM::Document const&);
bool command_justify_right_state(DOM::Document const&);
Utf16String command_justify_right_value(DOM::Document const&);
bool command_outdent_action(DOM::Document&, Utf16View const&);
bool command_remove_format_action(DOM::Document&, Utf16View const&);
bool command_select_all_action(DOM::Document&, Utf16View const&);
bool command_strikethrough_action(DOM::Document&, Utf16View const&);
bool command_style_with_css_action(DOM::Document&, Utf16View const&);
bool command_outdent_action(DOM::Document&, Utf16String const&);
bool command_remove_format_action(DOM::Document&, Utf16String const&);
bool command_select_all_action(DOM::Document&, Utf16String const&);
bool command_strikethrough_action(DOM::Document&, Utf16String const&);
bool command_style_with_css_action(DOM::Document&, Utf16String const&);
bool command_style_with_css_state(DOM::Document const&);
bool command_subscript_action(DOM::Document&, Utf16View const&);
bool command_subscript_action(DOM::Document&, Utf16String const&);
bool command_subscript_indeterminate(DOM::Document const&);
bool command_superscript_action(DOM::Document&, Utf16View const&);
bool command_superscript_action(DOM::Document&, Utf16String const&);
bool command_superscript_indeterminate(DOM::Document const&);
bool command_underline_action(DOM::Document&, Utf16View const&);
bool command_unlink_action(DOM::Document&, Utf16View const&);
bool command_use_css_action(DOM::Document&, Utf16View const&);
bool command_underline_action(DOM::Document&, Utf16String const&);
bool command_unlink_action(DOM::Document&, Utf16String const&);
bool command_use_css_action(DOM::Document&, Utf16String const&);
}

View file

@ -1389,7 +1389,7 @@ bool follows_a_line_break(GC::Ref<DOM::Node> node)
}
// https://w3c.github.io/editing/docs/execCommand/#force-the-value
void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional<Utf16View const&> new_value)
void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional<Utf16String const&> new_value)
{
// 1. Let command be the current command.
@ -1402,17 +1402,14 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
return;
// 4. If node is an allowed child of "span":
auto new_value_string = new_value.map([](Utf16View const& view) {
return Utf16String::from_utf16_without_validation(view);
});
if (is_allowed_child_of_node(node, HTML::TagNames::span)) {
// 1. Reorder modifiable descendants of node's previousSibling.
if (node->previous_sibling())
reorder_modifiable_descendants(*node->previous_sibling(), command, new_value_string);
reorder_modifiable_descendants(*node->previous_sibling(), command, new_value);
// 2. Reorder modifiable descendants of node's nextSibling.
if (node->next_sibling())
reorder_modifiable_descendants(*node->next_sibling(), command, new_value_string);
reorder_modifiable_descendants(*node->next_sibling(), command, new_value);
// 3. Wrap the one-node list consisting of node, with sibling criteria returning true for a simple modifiable
// element whose specified command value is equivalent to new value and whose effective command value is
@ -1422,7 +1419,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
[&](GC::Ref<DOM::Node> sibling) {
return is_simple_modifiable_element(sibling)
&& specified_command_value(static_cast<DOM::Element&>(*sibling), command) == new_value
&& values_are_loosely_equivalent(command, effective_command_value(sibling, command), new_value_string);
&& values_are_loosely_equivalent(command, effective_command_value(sibling, command), new_value);
},
[] -> GC::Ptr<DOM::Node> { return {}; });
}
@ -1432,7 +1429,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
return;
// 6. If the effective command value of command is loosely equivalent to new value on node, abort this algorithm.
if (values_are_loosely_equivalent(command, effective_command_value(node, command), new_value_string))
if (values_are_loosely_equivalent(command, effective_command_value(node, command), new_value))
return;
// 7. If node is not an allowed child of "span":
@ -1443,7 +1440,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
node->for_each_child([&](GC::Ref<DOM::Node> child) {
if (is<DOM::Element>(*child)) {
auto const child_specified_value = specified_command_value(static_cast<DOM::Element&>(*child), command);
if (child_specified_value.has_value() && !values_are_equivalent(command, child_specified_value.value(), new_value_string))
if (child_specified_value.has_value() && !values_are_equivalent(command, child_specified_value.value(), new_value))
return IterationDecision::Continue;
}
@ -1461,7 +1458,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
}
// 8. If the effective command value of command is loosely equivalent to new value on node, abort this algorithm.
if (values_are_loosely_equivalent(command, effective_command_value(node, command), new_value_string))
if (values_are_loosely_equivalent(command, effective_command_value(node, command), new_value))
return;
// 9. Let new parent be null.
@ -1575,7 +1572,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
// 17. If the effective command value of command for new parent is not loosely equivalent to new value, and the
// relevant CSS property for command is not null, set that CSS property of new parent to new value (if the new
// value would be valid).
if (!values_are_loosely_equivalent(command, effective_command_value(new_parent, command), new_value_string)) {
if (!values_are_loosely_equivalent(command, effective_command_value(new_parent, command), new_value)) {
auto const& command_definition = find_command_definition(command);
if (command_definition->relevant_css_property.has_value()) {
auto inline_style = new_parent->style_for_bindings();
@ -1606,7 +1603,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
// 21. If node is an Element and the effective command value of command for node is not loosely equivalent to new
// value:
if (is<DOM::Element>(*node)
&& !values_are_loosely_equivalent(command, effective_command_value(node, command), new_value_string)) {
&& !values_are_loosely_equivalent(command, effective_command_value(node, command), new_value)) {
// 1. Insert node into the parent of new parent before new parent, preserving ranges.
move_node_preserving_ranges(node, *new_parent->parent(), new_parent->index());
@ -1619,7 +1616,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
node->for_each_child([&](GC::Ref<DOM::Node> child) {
if (is<DOM::Element>(*child)) {
auto child_value = specified_command_value(static_cast<DOM::Element&>(*child), command);
if (child_value.has_value() && !values_are_equivalent(command, child_value.value(), new_value_string))
if (child_value.has_value() && !values_are_equivalent(command, child_value.value(), new_value))
return IterationDecision::Continue;
}
@ -3239,10 +3236,7 @@ void push_down_values(FlyString const& command, GC::Ref<DOM::Node> node, Optiona
continue;
// 4. Force the value of child, with command as in this algorithm and new value equal to propagated value.
force_the_value(
*child,
command,
propagated_value.map([](Utf16String const& string) { return string.utf16_view(); }));
force_the_value(*child, command, propagated_value);
}
}
}
@ -3590,7 +3584,7 @@ void restore_the_values_of_nodes(Vector<RecordedNodeValue> const& values)
// node.
else if ((is<DOM::Element>(ancestor.ptr()) && specified_command_value(static_cast<DOM::Element&>(*ancestor), command) != value)
|| (!is<DOM::Element>(ancestor.ptr()) && value.has_value())) {
force_the_value(node, command, value->utf16_view());
force_the_value(node, command, value);
}
}
}
@ -3711,12 +3705,8 @@ SelectionsListState selections_list_state(DOM::Document const& document)
}
// https://w3c.github.io/editing/docs/execCommand/#set-the-selection's-value
void set_the_selections_value(DOM::Document& document, FlyString const& command, Optional<Utf16View const&> new_value)
void set_the_selections_value(DOM::Document& document, FlyString const& command, Optional<Utf16String const&> new_value)
{
auto new_value_string = new_value.map([](Utf16View const& view) {
return Utf16String::from_utf16_without_validation(view);
});
// 1. Let command be the current command.
// 2. If there is no formattable node effectively contained in the active range:
@ -3752,7 +3742,7 @@ void set_the_selections_value(DOM::Document& document, FlyString const& command,
// 5. Otherwise, if command is "createLink" or it has a value specified, set the value override to new value.
else if (command == CommandNames::createLink || !MUST(document.query_command_value(CommandNames::createLink)).is_empty()) {
document.set_command_value_override(command, *new_value_string);
document.set_command_value_override(command, *new_value);
}
// 6. Abort these steps.
@ -3798,7 +3788,7 @@ void set_the_selections_value(DOM::Document& document, FlyString const& command,
// 8. For each node in node list:
for (auto node : node_list) {
// 1. Push down values on node.
push_down_values(command, node, new_value_string);
push_down_values(command, node, new_value);
// 2. If node is an allowed child of "span", force the value of node.
if (is_allowed_child_of_node(node, HTML::TagNames::span))
@ -4756,7 +4746,7 @@ Optional<NonnullRefPtr<CSS::CSSStyleValue const>> resolved_value(GC::Ref<DOM::No
return optional_style_property.value().value;
}
void take_the_action_for_command(DOM::Document& document, FlyString const& command, Utf16View const& value)
void take_the_action_for_command(DOM::Document& document, FlyString const& command, Utf16String const& value)
{
auto const& command_definition = find_command_definition(command);
command_definition->action(document, value);

View file

@ -64,7 +64,7 @@ Optional<Utf16String> effective_command_value(GC::Ptr<DOM::Node>, FlyString cons
DOM::BoundaryPoint first_equivalent_point(DOM::BoundaryPoint);
void fix_disallowed_ancestors_of_node(GC::Ref<DOM::Node>);
bool follows_a_line_break(GC::Ref<DOM::Node>);
void force_the_value(GC::Ref<DOM::Node>, FlyString const&, Optional<Utf16View const&>);
void force_the_value(GC::Ref<DOM::Node>, FlyString const&, Optional<Utf16String const&>);
void indent(Vector<GC::Ref<DOM::Node>>);
bool is_allowed_child_of_node(Variant<GC::Ref<DOM::Node>, FlyString> child, Variant<GC::Ref<DOM::Node>, FlyString> parent);
bool is_block_boundary_point(DOM::BoundaryPoint);
@ -115,7 +115,7 @@ void reorder_modifiable_descendants(GC::Ref<DOM::Node>, FlyString const&, Option
void restore_states_and_values(DOM::Document&, Vector<RecordedOverride> const&);
void restore_the_values_of_nodes(Vector<RecordedNodeValue> const&);
SelectionsListState selections_list_state(DOM::Document const&);
void set_the_selections_value(DOM::Document&, FlyString const&, Optional<Utf16View const&>);
void set_the_selections_value(DOM::Document&, FlyString const&, Optional<Utf16String const&>);
GC::Ref<DOM::Element> set_the_tag_name(GC::Ref<DOM::Element>, FlyString const&);
Optional<Utf16String> specified_command_value(GC::Ref<DOM::Element>, FlyString const& command);
void split_the_parent_of_nodes(Vector<GC::Ref<DOM::Node>> const&);
@ -137,7 +137,7 @@ Optional<NonnullRefPtr<CSS::CSSStyleValue const>> property_in_style_attribute(GC
Optional<CSS::Display> resolved_display(GC::Ref<DOM::Node>);
Optional<CSS::Keyword> resolved_keyword(GC::Ref<DOM::Node>, CSS::PropertyID);
Optional<NonnullRefPtr<CSS::CSSStyleValue const>> resolved_value(GC::Ref<DOM::Node>, CSS::PropertyID);
void take_the_action_for_command(DOM::Document&, FlyString const&, Utf16View const&);
void take_the_action_for_command(DOM::Document&, FlyString const&, Utf16String const&);
bool value_contains_keyword(CSS::CSSStyleValue const&, CSS::Keyword);
}