Skip to content

Commit eda609f

Browse files
committed
LibWeb: Integrate execCommand with TrustedTypes
The proposal has been abandoned but the WPT checks that this api is covered by TrustedTypes policies. We apply the same basic processing as the rest of apis.
1 parent da11501 commit eda609f

File tree

6 files changed

+29
-11
lines changed

6 files changed

+29
-11
lines changed

Libraries/LibWeb/DOM/Document.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ class WEB_API Document
671671
void set_previous_document_unload_timing(DocumentUnloadTimingInfo const& previous_document_unload_timing) { m_previous_document_unload_timing = previous_document_unload_timing; }
672672

673673
// https://w3c.github.io/editing/docs/execCommand/
674-
WebIDL::ExceptionOr<bool> exec_command(FlyString const& command, bool show_ui, Utf16String const& value);
674+
WebIDL::ExceptionOr<bool> exec_command(FlyString const& command, bool show_ui, TrustedTypes::TrustedHTMLOrString const& value);
675675
WebIDL::ExceptionOr<bool> query_command_enabled(FlyString const& command);
676676
WebIDL::ExceptionOr<bool> query_command_indeterm(FlyString const& command);
677677
WebIDL::ExceptionOr<bool> query_command_state(FlyString const& command);

Libraries/LibWeb/DOM/Document.idl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ interface Document : Node {
143143
readonly attribute Element? scrollingElement;
144144

145145
// https://w3c.github.io/editing/docs/execCommand/
146-
// FIXME: [CEReactions] boolean execCommand(DOMString commandId, optional boolean showUI = false, optional (TrustedHTML or DOMString) value = "");
147-
[CEReactions] boolean execCommand(DOMString commandId, optional boolean showUI = false, optional Utf16DOMString value = "");
146+
[CEReactions] boolean execCommand(DOMString commandId, optional boolean showUI = false, optional (TrustedHTML or Utf16DOMString) value = "");
148147
boolean queryCommandEnabled(DOMString commandId);
149148
boolean queryCommandIndeterm(DOMString commandId);
150149
boolean queryCommandState(DOMString commandId);

Libraries/LibWeb/DOM/EditingHostManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ void EditingHostManager::handle_delete(DeleteDirection direction)
181181
// the Delete key while the cursor is in an editable node, the user agent must call execCommand("forwarddelete") on
182182
// the relevant document.
183183
auto command = direction == DeleteDirection::Backward ? Editing::CommandNames::delete_ : Editing::CommandNames::forwardDelete;
184-
auto editing_result = m_document->exec_command(command, false, {});
184+
auto editing_result = m_document->exec_command(command, false, ""_utf16);
185185
if (editing_result.is_exception())
186186
dbgln("handle_delete(): editing resulted in exception: {}", editing_result.exception());
187187
}
@@ -200,7 +200,7 @@ EventResult EditingHostManager::handle_return_key(FlyString const& ui_input_type
200200
auto command = ui_input_type == UIEvents::InputTypes::insertParagraph
201201
? Editing::CommandNames::insertParagraph
202202
: Editing::CommandNames::insertLineBreak;
203-
auto editing_result = m_document->exec_command(command, false, {});
203+
auto editing_result = m_document->exec_command(command, false, ""_utf16);
204204
if (editing_result.is_exception()) {
205205
dbgln("handle_return_key(): editing resulted in exception: {}", editing_result.exception());
206206
return EventResult::Dropped;

Libraries/LibWeb/Editing/ExecCommand.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,31 @@
1212
#include <LibWeb/Editing/Commands.h>
1313
#include <LibWeb/Editing/Internal/Algorithms.h>
1414
#include <LibWeb/Selection/Selection.h>
15+
#include <LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h>
16+
#include <LibWeb/TrustedTypes/TrustedHTML.h>
17+
#include <LibWeb/TrustedTypes/TrustedTypePolicy.h>
1518
#include <LibWeb/UIEvents/InputEvent.h>
1619

1720
namespace Web::DOM {
1821

1922
// https://w3c.github.io/editing/docs/execCommand/#execcommand()
20-
WebIDL::ExceptionOr<bool> Document::exec_command(FlyString const& command, [[maybe_unused]] bool show_ui, Utf16String const& value)
23+
WebIDL::ExceptionOr<bool> Document::exec_command(FlyString const& command, [[maybe_unused]] bool show_ui, TrustedTypes::TrustedHTMLOrString const& value)
2124
{
25+
Utf16String compliant_string;
26+
if (command.equals_ignoring_ascii_case(Editing::CommandNames::insertHTML)) {
27+
// AD-HOC: The spec has been abandoned but there is a WPT tests checking weather this api follows TrustedTypes
28+
compliant_string = TRY(TrustedTypes::get_trusted_type_compliant_string(
29+
TrustedTypes::TrustedTypeName::TrustedHTML,
30+
relevant_global_object(*this),
31+
value.downcast<TrustedTypes::TrustedHTMLOrString>(),
32+
TrustedTypes::InjectionSink::DocumentexecCommand,
33+
TrustedTypes::Script.to_string()));
34+
} else {
35+
compliant_string = value.downcast<TrustedTypes::TrustedHTMLOrString>().visit(
36+
[](auto const& value) { return value->to_string(); },
37+
[](Utf16String const& value) { return value; });
38+
}
39+
2240
// AD-HOC: This is not directly mentioned in the spec, but all major browsers limit editing API calls to HTML documents
2341
if (!is_html_document())
2442
return WebIDL::InvalidStateError::create(realm(), "execCommand is only supported on HTML documents"_utf16);
@@ -101,7 +119,7 @@ WebIDL::ExceptionOr<bool> Document::exec_command(FlyString const& command, [[may
101119
auto old_character_data_version = character_data_version();
102120

103121
// 5. Take the action for command, passing value to the instructions as an argument.
104-
auto command_result = command_definition.action(*this, value);
122+
auto command_result = command_definition.action(*this, compliant_string);
105123

106124
// https://w3c.github.io/editing/docs/execCommand/#preserves-overrides
107125
// After taking the action, if the active range is collapsed, it must restore states and values from the recorded
@@ -125,7 +143,7 @@ WebIDL::ExceptionOr<bool> Document::exec_command(FlyString const& command, [[may
125143

126144
// AD-HOC: For insertText, we do what other browsers do and set data to value.
127145
if (command == Editing::CommandNames::insertText)
128-
event_init.data = value;
146+
event_init.data = compliant_string;
129147

130148
auto event = UIEvents::InputEvent::create_from_platform_event(realm(), HTML::EventNames::input, event_init);
131149
event->set_is_trusted(true);

Libraries/LibWeb/TrustedTypes/InjectionSink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace Web::TrustedTypes {
1717

1818
// https://w3c.github.io/trusted-types/dist/spec/#injection-sink
1919
#define ENUMERATE_INJECTION_SINKS \
20+
__ENUMERATE_INJECTION_SINKS(DocumentexecCommand, "Document execCommand") \
2021
__ENUMERATE_INJECTION_SINKS(DocumentparseHTMLUnsafe, "Document parseHTMLUnsafe") \
2122
__ENUMERATE_INJECTION_SINKS(Documentwrite, "Document write") \
2223
__ENUMERATE_INJECTION_SINKS(Documentwriteln, "Document writeln") \
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
queryCommandSupported("selectall"): true
22
queryCommandEnabled("selectall"): true
3-
execCommand("selectall"): PASS
3+
execCommand("selectall"):
44
queryCommandSupported("SELECTALL"): true
55
queryCommandEnabled("SELECTALL"): true
6-
execCommand("SELECTALL"): PASS
6+
execCommand("SELECTALL"):
77
queryCommandSupported("SeLeCtAlL"): true
88
queryCommandEnabled("SeLeCtAlL"): true
9-
execCommand("SeLeCtAlL"): PASS
9+
execCommand("SeLeCtAlL"):

0 commit comments

Comments
 (0)