diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 05d7137f5ae..762536d664f 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -739,24 +739,32 @@ void invoke_custom_element_reactions(Vector>& element_que // 1. Remove the first element of reactions, and let reaction be that element. Switch on reaction's type: auto reaction = reactions->take_first(); - auto maybe_exception = reaction.visit( - [&](DOM::CustomElementUpgradeReaction const& custom_element_upgrade_reaction) -> JS::ThrowCompletionOr { + reaction.visit( + [&](DOM::CustomElementUpgradeReaction const& custom_element_upgrade_reaction) -> void { // -> upgrade reaction // Upgrade element using reaction's custom element definition. - return element->upgrade_element(*custom_element_upgrade_reaction.custom_element_definition); + auto maybe_exception = element->upgrade_element(*custom_element_upgrade_reaction.custom_element_definition); + // If this throws an exception, catch it, and report it for reaction's custom element definition's constructor's corresponding JavaScript object's associated realm's global object. + if (maybe_exception.is_error()) { + // FIXME: Should it be easier to get to report an exception from an IDL callback? + auto& callback = custom_element_upgrade_reaction.custom_element_definition->constructor(); + auto& realm = callback.callback->shape().realm(); + auto& global = realm.global_object(); + + auto* window_or_worker = dynamic_cast(&global); + VERIFY(window_or_worker); + window_or_worker->report_an_exception(maybe_exception.error_value()); + } }, - [&](DOM::CustomElementCallbackReaction& custom_element_callback_reaction) -> JS::ThrowCompletionOr { + [&](DOM::CustomElementCallbackReaction& custom_element_callback_reaction) -> void { // -> callback reaction // Invoke reaction's callback function with reaction's arguments, and with element as the callback this value. auto result = WebIDL::invoke_callback(*custom_element_callback_reaction.callback, element.ptr(), custom_element_callback_reaction.arguments); + // FIXME: The error from CustomElementCallbackReaction is supposed + // to use the new steps for IDL callback error reporting if (result.is_abrupt()) - return result.release_error(); - return {}; + HTML::report_exception(result, element->realm()); }); - - // If this throws an exception, catch it, and report the exception. - if (maybe_exception.is_throw_completion()) - HTML::report_exception(maybe_exception, element->realm()); } } } diff --git a/Tests/LibWeb/Text/expected/HTML/custom-elements-throw-in-constructor.txt b/Tests/LibWeb/Text/expected/HTML/custom-elements-throw-in-constructor.txt index 56cb91d69ec..45ccb2b1c21 100644 --- a/Tests/LibWeb/Text/expected/HTML/custom-elements-throw-in-constructor.txt +++ b/Tests/LibWeb/Text/expected/HTML/custom-elements-throw-in-constructor.txt @@ -1,2 +1,3 @@ Entered TestElement constructor, throwing. +Uncaught exception: test PASS! (Didn't crash) diff --git a/Tests/LibWeb/Text/expected/wpt-import/custom-elements/upgrading.txt b/Tests/LibWeb/Text/expected/wpt-import/custom-elements/upgrading.txt new file mode 100644 index 00000000000..46634c20732 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/custom-elements/upgrading.txt @@ -0,0 +1,39 @@ +Summary + +Harness status: OK + +Rerun + +Found 28 tests + +25 Pass +3 Fail +Details +Result Test Name MessagePass Creating an element in the document of the template elements must not enqueue a custom element upgrade reaction because the document does not have a browsing context +Pass Creating an element in the document of the template elements and inserting into the document must not enqueue a custom element upgrade reaction +Pass Creating an element in the document of the template elements and adopting back to a document with browsing context must enqueue a custom element upgrade reaction +Pass Creating an element in a new document must not enqueue a custom element upgrade reaction because the document does not have a browsing context +Pass Creating an element in a new document and inserting into the document must not enqueue a custom element upgrade reaction +Pass Creating an element in a new document and adopting back to a document with browsing context must enqueue a custom element upgrade reaction +Pass Creating an element in a cloned document must not enqueue a custom element upgrade reaction because the document does not have a browsing context +Pass Creating an element in a cloned document and inserting into the document must not enqueue a custom element upgrade reaction +Pass Creating an element in a cloned document and adopting back to a document with browsing context must enqueue a custom element upgrade reaction +Pass Creating an element in a document created by createHTMLDocument must not enqueue a custom element upgrade reaction because the document does not have a browsing context +Pass Creating an element in a document created by createHTMLDocument and inserting into the document must not enqueue a custom element upgrade reaction +Pass Creating an element in a document created by createHTMLDocument and adopting back to a document with browsing context must enqueue a custom element upgrade reaction +Pass Creating an element in an HTML document created by createDocument must not enqueue a custom element upgrade reaction because the document does not have a browsing context +Pass Creating an element in an HTML document created by createDocument and inserting into the document must not enqueue a custom element upgrade reaction +Pass Creating an element in an HTML document created by createDocument and adopting back to a document with browsing context must enqueue a custom element upgrade reaction +Fail Creating an element in an HTML document fetched by XHR must not enqueue a custom element upgrade reaction because the document does not have a browsing context +Fail Creating an element in an HTML document fetched by XHR and inserting into the document must not enqueue a custom element upgrade reaction +Fail Creating an element in an HTML document fetched by XHR and adopting back to a document with browsing context must enqueue a custom element upgrade reaction +Pass Creating an element in the document of an iframe must not enqueue a custom element upgrade reaction if there is no matching definition +Pass Creating an element in the document of an iframe must enqueue a custom element upgrade reaction if there is a matching definition +Pass "define" in the document of an iframe must not enqueue a custom element upgrade reaction on a disconnected unresolved custom element +Pass Inserting an unresolved custom element into the document of an iframe must enqueue a custom element upgrade reaction +Pass "define" in the document of an iframe must enqueue a custom element upgrade reaction on a connected unresolved custom element +Pass Adopting (and leaving disconnceted) an unresolved custom element into the document of an iframe must not enqueue a custom element upgrade reaction +Pass Adopting and inserting an unresolved custom element into the document of an iframe must enqueue a custom element upgrade reaction +Pass If definition's disable shadow is true and element's shadow root is non-null, then throw a "NotSupportedError" DOMException. +Pass Infinite constructor recursion with upgrade(this) should not be possible +Pass Infinite constructor recursion with appendChild should not be possible \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/HTML/custom-elements-throw-in-constructor.html b/Tests/LibWeb/Text/input/HTML/custom-elements-throw-in-constructor.html index 39481e5093e..b32c1bffbc1 100644 --- a/Tests/LibWeb/Text/input/HTML/custom-elements-throw-in-constructor.html +++ b/Tests/LibWeb/Text/input/HTML/custom-elements-throw-in-constructor.html @@ -2,6 +2,8 @@ + + + + + + + +
+ + +