From 497ead37bcc959a9325aa22b0a233e302b071229 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 4 Sep 2022 16:56:15 +0200 Subject: [PATCH] LibWeb: Make DOMException GC-allocated --- .../LibWeb/WrapperGenerator/IDLGenerators.cpp | 2 + .../CrossOriginAbstractOperations.cpp | 7 +- .../LibWeb/Bindings/ExceptionOrUtils.h | 5 +- .../LibWeb/Bindings/LocationObject.cpp | 9 +-- .../Libraries/LibWeb/Bindings/WindowProxy.cpp | 11 +-- .../Libraries/LibWeb/Bindings/WindowProxy.h | 4 +- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp | 6 +- .../Libraries/LibWeb/CSS/CSSStyleSheet.cpp | 2 +- .../CSS/ResolvedCSSStyleDeclaration.cpp | 4 +- Userland/Libraries/LibWeb/Crypto/Crypto.cpp | 6 +- .../Libraries/LibWeb/Crypto/SubtleCrypto.cpp | 7 +- Userland/Libraries/LibWeb/DOM/AbortSignal.cpp | 4 +- .../Libraries/LibWeb/DOM/CharacterData.cpp | 4 +- .../Libraries/LibWeb/DOM/DOMException.cpp | 34 +++++++++ Userland/Libraries/LibWeb/DOM/DOMException.h | 75 ++++++++++--------- .../LibWeb/DOM/DOMImplementation.cpp | 2 +- .../Libraries/LibWeb/DOM/DOMTokenList.cpp | 4 +- Userland/Libraries/LibWeb/DOM/Document.cpp | 46 ++++++------ Userland/Libraries/LibWeb/DOM/Document.h | 2 +- Userland/Libraries/LibWeb/DOM/Element.cpp | 22 +++--- Userland/Libraries/LibWeb/DOM/Element.h | 2 +- Userland/Libraries/LibWeb/DOM/EventTarget.cpp | 4 +- Userland/Libraries/LibWeb/DOM/ExceptionOr.h | 14 ++-- .../Libraries/LibWeb/DOM/NamedNodeMap.cpp | 4 +- Userland/Libraries/LibWeb/DOM/Node.cpp | 36 ++++----- Userland/Libraries/LibWeb/DOM/NodeFilter.cpp | 1 + .../Libraries/LibWeb/DOM/NodeIterator.cpp | 3 +- Userland/Libraries/LibWeb/DOM/ParentNode.cpp | 5 +- Userland/Libraries/LibWeb/DOM/Range.cpp | 40 +++++----- Userland/Libraries/LibWeb/DOM/StaticRange.cpp | 8 +- Userland/Libraries/LibWeb/DOM/Text.cpp | 2 +- Userland/Libraries/LibWeb/DOM/TreeWalker.cpp | 4 +- .../LibWeb/DOMParsing/XMLSerializer.cpp | 32 ++++---- .../Libraries/LibWeb/Encoding/TextDecoder.cpp | 2 +- Userland/Libraries/LibWeb/Fetch/Headers.cpp | 37 ++++----- .../LibWeb/Fetch/Infrastructure/HTTP/Bodies.h | 1 + Userland/Libraries/LibWeb/FileAPI/Blob.cpp | 5 +- Userland/Libraries/LibWeb/FileAPI/File.cpp | 2 +- Userland/Libraries/LibWeb/Forward.h | 1 - .../LibWeb/HTML/Canvas/CanvasPath.cpp | 7 +- .../Libraries/LibWeb/HTML/Canvas/CanvasPath.h | 6 +- .../Libraries/LibWeb/HTML/CanvasGradient.cpp | 4 +- .../LibWeb/HTML/CanvasRenderingContext2D.cpp | 7 +- .../Libraries/LibWeb/HTML/DOMStringMap.cpp | 2 +- .../Libraries/LibWeb/HTML/HTMLElement.cpp | 2 +- .../LibWeb/HTML/HTMLOptionsCollection.cpp | 4 +- .../LibWeb/HTML/HTMLTableElement.cpp | 8 +- .../LibWeb/HTML/HTMLTableSectionElement.cpp | 4 +- Userland/Libraries/LibWeb/HTML/History.cpp | 2 +- Userland/Libraries/LibWeb/HTML/Path2D.cpp | 1 + .../LibWeb/HTML/Scripting/ClassicScript.cpp | 9 ++- Userland/Libraries/LibWeb/HTML/Window.cpp | 7 +- Userland/Libraries/LibWeb/HTML/Worker.cpp | 2 +- .../LibWeb/HTML/WorkerGlobalScope.cpp | 5 +- .../Libraries/LibWeb/WebSockets/WebSocket.cpp | 12 +-- .../Libraries/LibWeb/XHR/XMLHttpRequest.cpp | 41 +++++----- Userland/Libraries/LibWeb/idl_files.cmake | 2 +- 58 files changed, 307 insertions(+), 278 deletions(-) create mode 100644 Userland/Libraries/LibWeb/DOM/DOMException.cpp diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp index cc9daf4352..52ca3ac56f 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp @@ -167,6 +167,8 @@ static bool impl_is_wrapper(Type const& type) return true; if (type.name == "URLSearchParams"sv) return true; + if (type.name == "DOMException"sv) + return true; return false; } diff --git a/Userland/Libraries/LibWeb/Bindings/CrossOriginAbstractOperations.cpp b/Userland/Libraries/LibWeb/Bindings/CrossOriginAbstractOperations.cpp index 6a1210a9c5..ab1b1512d8 100644 --- a/Userland/Libraries/LibWeb/Bindings/CrossOriginAbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/Bindings/CrossOriginAbstractOperations.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -79,7 +78,7 @@ JS::ThrowCompletionOr cross_origin_property_fallback(JS: return JS::PropertyDescriptor { .value = JS::js_undefined(), .writable = false, .enumerable = false, .configurable = true }; // 2. Throw a "SecurityError" DOMException. - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't access property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(vm.current_realm()->global_object(), String::formatted("Can't access property '{}' on cross-origin object", property_key))); } // 7.2.3.3 IsPlatformObjectSameOrigin ( O ), https://html.spec.whatwg.org/multipage/browsers.html#isplatformobjectsameorigin-(-o-) @@ -197,7 +196,7 @@ JS::ThrowCompletionOr cross_origin_get(JS::VM& vm, JS::Object const& // 6. If getter is undefined, then throw a "SecurityError" DOMException. if (!getter.has_value()) - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't get property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(vm.current_realm()->global_object(), String::formatted("Can't get property '{}' on cross-origin object", property_key))); // 7. Return ? Call(getter, Receiver). return JS::call(vm, *getter, receiver); @@ -223,7 +222,7 @@ JS::ThrowCompletionOr cross_origin_set(JS::VM& vm, JS::Object& object, JS: } // 4. Throw a "SecurityError" DOMException. - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't set property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(vm.current_realm()->global_object(), String::formatted("Can't set property '{}' on cross-origin object", property_key))); } // 7.2.3.7 CrossOriginOwnPropertyKeys ( O ), https://html.spec.whatwg.org/multipage/browsers.html#crossoriginownpropertykeys-(-o-) diff --git a/Userland/Libraries/LibWeb/Bindings/ExceptionOrUtils.h b/Userland/Libraries/LibWeb/Bindings/ExceptionOrUtils.h index 52f93a550d..3a44f87da8 100644 --- a/Userland/Libraries/LibWeb/Bindings/ExceptionOrUtils.h +++ b/Userland/Libraries/LibWeb/Bindings/ExceptionOrUtils.h @@ -9,7 +9,6 @@ #include #include #include -#include #include namespace Web::Bindings { @@ -74,8 +73,8 @@ ALWAYS_INLINE JS::Completion dom_exception_to_throw_completion(auto&& vm, auto&& VERIFY_NOT_REACHED(); } }, - [&](NonnullRefPtr exception) { - return vm.template throw_completion(move(exception)); + [&](JS::NonnullGCPtr const& exception) { + return throw_completion(exception); }); } diff --git a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp index 37d388e2cf..04a86908b0 100644 --- a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -308,8 +307,6 @@ JS::ThrowCompletionOr> LocationObject::internal // 7.10.5.6 [[DefineOwnProperty]] ( P, Desc ), https://html.spec.whatwg.org/multipage/history.html#location-defineownproperty JS::ThrowCompletionOr LocationObject::internal_define_own_property(JS::PropertyKey const& property_key, JS::PropertyDescriptor const& descriptor) { - auto& vm = this->vm(); - // 1. If IsPlatformObjectSameOrigin(this) is true, then: if (is_platform_object_same_origin(*this)) { // 1. If the value of the [[DefaultProperties]] internal slot of this contains P, then return false. @@ -318,7 +315,7 @@ JS::ThrowCompletionOr LocationObject::internal_define_own_property(JS::Pro } // 2. Throw a "SecurityError" DOMException. - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't define property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(global_object(), String::formatted("Can't define property '{}' on cross-origin object", property_key))); } // 7.10.5.7 [[Get]] ( P, Receiver ), https://html.spec.whatwg.org/multipage/history.html#location-get @@ -350,14 +347,12 @@ JS::ThrowCompletionOr LocationObject::internal_set(JS::PropertyKey const& // 7.10.5.9 [[Delete]] ( P ), https://html.spec.whatwg.org/multipage/history.html#location-delete JS::ThrowCompletionOr LocationObject::internal_delete(JS::PropertyKey const& property_key) { - auto& vm = this->vm(); - // 1. If IsPlatformObjectSameOrigin(this) is true, then return ? OrdinaryDelete(this, P). if (is_platform_object_same_origin(*this)) return JS::Object::internal_delete(property_key); // 2. Throw a "SecurityError" DOMException. - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't delete property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(global_object(), String::formatted("Can't delete property '{}' on cross-origin object", property_key))); } // 7.10.5.10 [[OwnPropertyKeys]] ( ), https://html.spec.whatwg.org/multipage/history.html#location-ownpropertykeys diff --git a/Userland/Libraries/LibWeb/Bindings/WindowProxy.cpp b/Userland/Libraries/LibWeb/Bindings/WindowProxy.cpp index f943bef8b1..c93bb37cbf 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowProxy.cpp +++ b/Userland/Libraries/LibWeb/Bindings/WindowProxy.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -91,7 +90,7 @@ JS::ThrowCompletionOr> WindowProxy::internal_ge return Optional {}; // 2. Throw a "SecurityError" DOMException. - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't access property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(window(), String::formatted("Can't access property '{}' on cross-origin object", property_key))); } // 6. Return PropertyDescriptor{ [[Value]]: value, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true }. @@ -127,8 +126,6 @@ JS::ThrowCompletionOr> WindowProxy::internal_ge // 7.4.6 [[DefineOwnProperty]] ( P, Desc ), https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-defineownproperty JS::ThrowCompletionOr WindowProxy::internal_define_own_property(JS::PropertyKey const& property_key, JS::PropertyDescriptor const& descriptor) { - auto& vm = this->vm(); - // 1. Let W be the value of the [[Window]] internal slot of this. // 2. If IsPlatformObjectSameOrigin(W) is true, then: @@ -143,7 +140,7 @@ JS::ThrowCompletionOr WindowProxy::internal_define_own_property(JS::Proper } // 3. Throw a "SecurityError" DOMException. - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't define property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(window(), String::formatted("Can't define property '{}' on cross-origin object", property_key))); } // 7.4.7 [[Get]] ( P, Receiver ), https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-get @@ -194,8 +191,6 @@ JS::ThrowCompletionOr WindowProxy::internal_set(JS::PropertyKey const& pro // 7.4.9 [[Delete]] ( P ), https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-delete JS::ThrowCompletionOr WindowProxy::internal_delete(JS::PropertyKey const& property_key) { - auto& vm = this->vm(); - // 1. Let W be the value of the [[Window]] internal slot of this. // 2. If IsPlatformObjectSameOrigin(W) is true, then: @@ -218,7 +213,7 @@ JS::ThrowCompletionOr WindowProxy::internal_delete(JS::PropertyKey const& } // 3. Throw a "SecurityError" DOMException. - return vm.throw_completion(DOM::SecurityError::create(String::formatted("Can't delete property '{}' on cross-origin object", property_key))); + return throw_completion(DOM::SecurityError::create(window(), String::formatted("Can't delete property '{}' on cross-origin object", property_key))); } // 7.4.10 [[OwnPropertyKeys]] ( ), https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-ownpropertykeys diff --git a/Userland/Libraries/LibWeb/Bindings/WindowProxy.h b/Userland/Libraries/LibWeb/Bindings/WindowProxy.h index 880fe3dead..11d696d332 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowProxy.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowProxy.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -30,8 +31,7 @@ public: virtual JS::ThrowCompletionOr internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr> internal_own_property_keys() const override; - HTML::Window& window() { return *m_window; } - HTML::Window const& window() const { return *m_window; } + HTML::Window& window() const { return const_cast(*m_window); } // NOTE: Someone will have to replace the wrapped window object as well: // "When the browsing context is navigated, the Window object wrapped by the browsing context's associated WindowProxy object is changed." diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 700ae2a68c..255a972d5f 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -82,6 +82,7 @@ set(SOURCES DOM/Comment.cpp DOM/CustomEvent.cpp DOM/DOMEventListener.cpp + DOM/DOMException.cpp DOM/DOMImplementation.cpp DOM/DOMTokenList.cpp DOM/DOMTokenList.idl diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index b3fdde9a8d..bbd5f35b59 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -55,7 +55,7 @@ DOM::ExceptionOr CSSRuleList::insert_a_css_rule(Variant length) - return DOM::IndexSizeError::create("CSS rule index out of bounds."); + return DOM::IndexSizeError::create(global_object(), "CSS rule index out of bounds."); // 3. Set new rule to the results of performing parse a CSS rule on argument rule. // NOTE: The insert-a-css-rule spec expects `rule` to be a string, but the CSSStyleSheet.insertRule() @@ -72,7 +72,7 @@ DOM::ExceptionOr CSSRuleList::insert_a_css_rule(Variant CSSRuleList::remove_a_css_rule(u32 index) // 2. If index is greater than or equal to length, then throw an IndexSizeError exception. if (index >= length) - return DOM::IndexSizeError::create("CSS rule index out of bounds."); + return DOM::IndexSizeError::create(global_object(), "CSS rule index out of bounds."); // 3. Set old rule to the indexth item in list. CSSRule& old_rule = m_rules[index]; diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 50e87ea2c1..3ba873d5e5 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -50,7 +50,7 @@ DOM::ExceptionOr CSSStyleSheet::insert_rule(StringView rule, unsigned // 4. If parsed rule is a syntax error, return parsed rule. if (!parsed_rule) - return DOM::SyntaxError::create("Unable to parse CSS rule."); + return DOM::SyntaxError::create(global_object(), "Unable to parse CSS rule."); // FIXME: 5. If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException. diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index d52749ce0c..9aeb584da4 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp @@ -520,14 +520,14 @@ Optional ResolvedCSSStyleDeclaration::property(PropertyID propert DOM::ExceptionOr ResolvedCSSStyleDeclaration::set_property(PropertyID, StringView, StringView) { // 1. If the computed flag is set, then throw a NoModificationAllowedError exception. - return DOM::NoModificationAllowedError::create("Cannot modify properties in result of getComputedStyle()"); + return DOM::NoModificationAllowedError::create(global_object(), "Cannot modify properties in result of getComputedStyle()"); } // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty DOM::ExceptionOr ResolvedCSSStyleDeclaration::remove_property(PropertyID) { // 1. If the computed flag is set, then throw a NoModificationAllowedError exception. - return DOM::NoModificationAllowedError::create("Cannot remove properties from result of getComputedStyle()"); + return DOM::NoModificationAllowedError::create(global_object(), "Cannot remove properties from result of getComputedStyle()"); } String ResolvedCSSStyleDeclaration::serialized() const diff --git a/Userland/Libraries/LibWeb/Crypto/Crypto.cpp b/Userland/Libraries/LibWeb/Crypto/Crypto.cpp index 414b92a5f9..f9f1a3b2a2 100644 --- a/Userland/Libraries/LibWeb/Crypto/Crypto.cpp +++ b/Userland/Libraries/LibWeb/Crypto/Crypto.cpp @@ -43,16 +43,16 @@ DOM::ExceptionOr Crypto::get_random_values(JS::Value array) const { // 1. If array is not an Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array, then throw a TypeMismatchError and terminate the algorithm. if (!array.is_object() || !(is(array.as_object()) || is(array.as_object()) || is(array.as_object()) || is(array.as_object()) || is(array.as_object()) || is(array.as_object()) || is(array.as_object()) || is(array.as_object()) || is(array.as_object()))) - return DOM::TypeMismatchError::create("array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array"); + return DOM::TypeMismatchError::create(global_object(), "array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array"); auto& typed_array = static_cast(array.as_object()); // 2. If the byteLength of array is greater than 65536, throw a QuotaExceededError and terminate the algorithm. if (typed_array.byte_length() > 65536) - return DOM::QuotaExceededError::create("array's byteLength may not be greater than 65536"); + return DOM::QuotaExceededError::create(global_object(), "array's byteLength may not be greater than 65536"); // IMPLEMENTATION DEFINED: If the viewed array buffer is detached, throw a InvalidStateError and terminate the algorithm. if (typed_array.viewed_array_buffer()->is_detached()) - return DOM::InvalidStateError::create("array is detached"); + return DOM::InvalidStateError::create(global_object(), "array is detached"); // FIXME: Handle SharedArrayBuffers // 3. Overwrite all elements of array with cryptographically strong random values of the appropriate type. diff --git a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp index bcad3cf09d..575339a254 100644 --- a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp +++ b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +37,7 @@ JS::Promise* SubtleCrypto::digest(String const& algorithm, JS::Handlereject(error); return promise; @@ -59,7 +58,7 @@ JS::Promise* SubtleCrypto::digest(String const& algorithm, JS::Handlereject(error); return promise; @@ -80,7 +79,7 @@ JS::Promise* SubtleCrypto::digest(String const& algorithm, JS::Handlereject(error); return promise; } diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp index a4cf9b4269..f65291129d 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp +++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp @@ -4,8 +4,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include -#include #include #include #include @@ -45,7 +43,7 @@ void AbortSignal::signal_abort(JS::Value reason) if (!reason.is_undefined()) m_abort_reason = reason; else - m_abort_reason = wrap(realm(), AbortError::create("Aborted without reason")); + m_abort_reason = wrap(realm(), AbortError::create(global_object(), "Aborted without reason")); // 3. For each algorithm in signal’s abort algorithms: run algorithm. for (auto& algorithm : m_abort_algorithms) diff --git a/Userland/Libraries/LibWeb/DOM/CharacterData.cpp b/Userland/Libraries/LibWeb/DOM/CharacterData.cpp index f13c28189d..95a40568de 100644 --- a/Userland/Libraries/LibWeb/DOM/CharacterData.cpp +++ b/Userland/Libraries/LibWeb/DOM/CharacterData.cpp @@ -38,7 +38,7 @@ ExceptionOr CharacterData::substring_data(size_t offset, size_t count) c // 2. If offset is greater than length, then throw an "IndexSizeError" DOMException. if (offset > length) - return DOM::IndexSizeError::create("Substring offset out of range."); + return DOM::IndexSizeError::create(global_object(), "Substring offset out of range."); // 3. If offset plus count is greater than length, return a string whose value is the code units from the offsetth code unit // to the end of node’s data, and then return. @@ -57,7 +57,7 @@ ExceptionOr CharacterData::replace_data(size_t offset, size_t count, Strin // 2. If offset is greater than length, then throw an "IndexSizeError" DOMException. if (offset > length) - return DOM::IndexSizeError::create("Replacement offset out of range."); + return DOM::IndexSizeError::create(global_object(), "Replacement offset out of range."); // 3. If offset plus count is greater than length, then set count to length minus offset. if (offset + count > length) diff --git a/Userland/Libraries/LibWeb/DOM/DOMException.cpp b/Userland/Libraries/LibWeb/DOM/DOMException.cpp new file mode 100644 index 0000000000..a4c9d3ae73 --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/DOMException.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::DOM { + +JS::NonnullGCPtr DOMException::create(JS::Object& global_object, FlyString const& name, FlyString const& message) +{ + auto& window = verify_cast(global_object); + return *window.heap().allocate(window.realm(), window, name, message); +} + +JS::NonnullGCPtr DOMException::create_with_global_object(JS::Object& global_object, FlyString const& message, FlyString const& name) +{ + auto& window = verify_cast(global_object); + return *window.heap().allocate(window.realm(), window, name, message); +} + +DOMException::DOMException(HTML::Window& window, FlyString const& name, FlyString const& message) + : PlatformObject(window.realm()) + , m_name(name) + , m_message(message) +{ + set_prototype(&window.cached_web_prototype("DOMException")); +} + +DOMException::~DOMException() = default; + +} diff --git a/Userland/Libraries/LibWeb/DOM/DOMException.h b/Userland/Libraries/LibWeb/DOM/DOMException.h index 8240a300a9..a8f8f5c2de 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMException.h +++ b/Userland/Libraries/LibWeb/DOM/DOMException.h @@ -7,20 +7,19 @@ #pragma once #include -#include -#include -#include +#include +#include namespace Web::DOM { -#define TRY_OR_RETURN_OOM(expression) \ - ({ \ - auto _temporary_result = (expression); \ - if (_temporary_result.is_error()) { \ - VERIFY(_temporary_result.error().code() == ENOMEM); \ - return DOM::UnknownError::create("Out of memory."sv); \ - } \ - _temporary_result.release_value(); \ +#define TRY_OR_RETURN_OOM(global_object, expression) \ + ({ \ + auto _temporary_result = (expression); \ + if (_temporary_result.is_error()) { \ + VERIFY(_temporary_result.error().code() == ENOMEM); \ + return DOM::UnknownError::create(global_object, "Out of memory."sv); \ + } \ + _temporary_result.release_value(); \ }) // The following have a legacy code value but *don't* produce it as @@ -99,48 +98,52 @@ static u16 get_legacy_code_for_name(FlyString const& name) } // https://webidl.spec.whatwg.org/#idl-DOMException -class DOMException final - : public RefCounted - , public Bindings::Wrappable { -public: - using WrapperType = Bindings::DOMExceptionWrapper; +class DOMException final : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(DOMException, Bindings::PlatformObject); - static NonnullRefPtr create(FlyString const& name, FlyString const& message) - { - return adopt_ref(*new DOMException(name, message)); - } +public: + static JS::NonnullGCPtr create(JS::Object& global_object, FlyString const& name, FlyString const& message); // JS constructor has message first, name second - static NonnullRefPtr create_with_global_object(HTML::Window&, FlyString const& message, FlyString const& name) - { - return adopt_ref(*new DOMException(name, message)); - } + // FIXME: This is a completely pointless footgun, let's use the same order for both factories. + static JS::NonnullGCPtr create_with_global_object(JS::Object& global_object, FlyString const& message, FlyString const& name); + + static JS::NonnullGCPtr create(JS::Realm& realm, FlyString const& message); + + virtual ~DOMException() override; FlyString const& name() const { return m_name; } FlyString const& message() const { return m_message; } u16 code() const { return get_legacy_code_for_name(m_name); } protected: - DOMException(FlyString const& name, FlyString const& message) - : m_name(name) - , m_message(message) - { - } + DOMException(HTML::Window&, FlyString const& name, FlyString const& message); private: FlyString m_name; FlyString m_message; }; -#define __ENUMERATE(ErrorName) \ - class ErrorName final { \ - public: \ - static NonnullRefPtr create(FlyString const& message) \ - { \ - return DOMException::create(#ErrorName, message); \ - } \ +#define __ENUMERATE(ErrorName) \ + class ErrorName final { \ + public: \ + static JS::NonnullGCPtr create(JS::Object& global_object, FlyString const& message) \ + { \ + return DOMException::create(global_object, #ErrorName, message); \ + } \ }; ENUMERATE_DOM_EXCEPTION_ERROR_NAMES #undef __ENUMERATE } + +WRAPPER_HACK(DOMException, Web::DOM) + +namespace Web { + +inline JS::Completion throw_completion(JS::NonnullGCPtr exception) +{ + return JS::throw_completion(JS::Value(static_cast(exception.ptr()))); +} + +} diff --git a/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp b/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp index 1b0be32d48..d1cb97ff5e 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp +++ b/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp @@ -105,7 +105,7 @@ JS::NonnullGCPtr DOMImplementation::create_html_document(String const& // https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype ExceptionOr> DOMImplementation::create_document_type(String const& qualified_name, String const& public_id, String const& system_id) { - TRY(Document::validate_qualified_name(qualified_name)); + TRY(Document::validate_qualified_name(global_object(), qualified_name)); auto document_type = DocumentType::create(document()); document_type->set_name(qualified_name); document_type->set_public_id(public_id); diff --git a/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp b/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp index 2934ead8cc..82ef51ed99 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp +++ b/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp @@ -234,9 +234,9 @@ void DOMTokenList::set_value(String value) ExceptionOr DOMTokenList::validate_token(StringView token) const { if (token.is_empty()) - return SyntaxError::create("Non-empty DOM tokens are not allowed"); + return SyntaxError::create(global_object(), "Non-empty DOM tokens are not allowed"); if (any_of(token, is_ascii_space)) - return InvalidCharacterError::create("DOM tokens containing ASCII whitespace are not allowed"); + return InvalidCharacterError::create(global_object(), "DOM tokens containing ASCII whitespace are not allowed"); return {}; } diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 46e978e0da..43a88e19ed 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -349,11 +349,11 @@ ExceptionOr Document::run_the_document_write_steps(String input) { // 1. If document is an XML document, then throw an "InvalidStateError" DOMException. if (m_type == Type::XML) - return DOM::InvalidStateError::create("write() called on XML document."); + return DOM::InvalidStateError::create(global_object(), "write() called on XML document."); // 2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException. if (m_throw_on_dynamic_markup_insertion_counter > 0) - return DOM::InvalidStateError::create("throw-on-dynamic-markup-insertion-counter greater than zero."); + return DOM::InvalidStateError::create(global_object(), "throw-on-dynamic-markup-insertion-counter greater than zero."); // 3. If document's active parser was aborted is true, then return. if (m_active_parser_was_aborted) @@ -384,18 +384,18 @@ ExceptionOr Document::open(String const&, String const&) { // 1. If document is an XML document, then throw an "InvalidStateError" DOMException exception. if (m_type == Type::XML) - return DOM::InvalidStateError::create("open() called on XML document."); + return DOM::InvalidStateError::create(global_object(), "open() called on XML document."); // 2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException. if (m_throw_on_dynamic_markup_insertion_counter > 0) - return DOM::InvalidStateError::create("throw-on-dynamic-markup-insertion-counter greater than zero."); + return DOM::InvalidStateError::create(global_object(), "throw-on-dynamic-markup-insertion-counter greater than zero."); // FIXME: 3. Let entryDocument be the entry global object's associated Document. auto& entry_document = *this; // 4. If document's origin is not same origin to entryDocument's origin, then throw a "SecurityError" DOMException. if (origin() != entry_document.origin()) - return DOM::SecurityError::create("Document.origin() not the same as entryDocument's."); + return DOM::SecurityError::create(global_object(), "Document.origin() not the same as entryDocument's."); // 5. If document has an active parser whose script nesting level is greater than 0, then return document. if (m_parser && m_parser->script_nesting_level() > 0) @@ -455,11 +455,11 @@ ExceptionOr Document::close() { // 1. If document is an XML document, then throw an "InvalidStateError" DOMException exception. if (m_type == Type::XML) - return DOM::InvalidStateError::create("close() called on XML document."); + return DOM::InvalidStateError::create(global_object(), "close() called on XML document."); // 2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException. if (m_throw_on_dynamic_markup_insertion_counter > 0) - return DOM::InvalidStateError::create("throw-on-dynamic-markup-insertion-counter greater than zero."); + return DOM::InvalidStateError::create(global_object(), "throw-on-dynamic-markup-insertion-counter greater than zero."); // 3. If there is no script-created parser associated with the document, then return. if (!m_parser) @@ -563,7 +563,7 @@ HTML::HTMLElement* Document::body() ExceptionOr Document::set_body(HTML::HTMLElement* new_body) { if (!is(new_body) && !is(new_body)) - return DOM::HierarchyRequestError::create("Invalid document body element, must be 'body' or 'frameset'"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid document body element, must be 'body' or 'frameset'"); auto* existing_body = body(); if (existing_body) { @@ -573,7 +573,7 @@ ExceptionOr Document::set_body(HTML::HTMLElement* new_body) auto* document_element = this->document_element(); if (!document_element) - return DOM::HierarchyRequestError::create("Missing document element"); + return DOM::HierarchyRequestError::create(global_object(), "Missing document element"); (void)TRY(document_element->append_child(*new_body)); return {}; @@ -1073,7 +1073,7 @@ JS::Value Document::run_javascript(StringView source, StringView filename) DOM::ExceptionOr> Document::create_element(String const& tag_name) { if (!is_valid_name(tag_name)) - return DOM::InvalidCharacterError::create("Invalid character in tag name."); + return DOM::InvalidCharacterError::create(global_object(), "Invalid character in tag name."); // FIXME: Let namespace be the HTML namespace, if this is an HTML document or this’s content type is "application/xhtml+xml", and null otherwise. return DOM::create_element(*this, tag_name, Namespace::HTML); @@ -1085,7 +1085,7 @@ DOM::ExceptionOr> Document::create_element(String cons DOM::ExceptionOr> Document::create_element_ns(String const& namespace_, String const& qualified_name) { // 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract. - auto extracted_qualified_name = TRY(validate_and_extract(namespace_, qualified_name)); + auto extracted_qualified_name = TRY(validate_and_extract(global_object(), namespace_, qualified_name)); // FIXME: 2. Let is be null. // FIXME: 3. If options is a dictionary and options["is"] exists, then set is to it. @@ -1166,7 +1166,7 @@ DOM::ExceptionOr> Document::create_event(String const& i // 3. If constructor is null, then throw a "NotSupportedError" DOMException. if (!event) { - return DOM::NotSupportedError::create("No constructor for interface found"); + return DOM::NotSupportedError::create(global_object(), "No constructor for interface found"); } // FIXME: 4. If the interface indicated by constructor is not exposed on the relevant global object of this, then throw a "NotSupportedError" DOMException. @@ -1226,7 +1226,7 @@ ExceptionOr> Document::import_node(JS::NonnullGCPtr { // 1. If node is a document or shadow root, then throw a "NotSupportedError" DOMException. if (is(*node) || is(*node)) - return DOM::NotSupportedError::create("Cannot import a document or shadow root."); + return DOM::NotSupportedError::create(global_object(), "Cannot import a document or shadow root."); // 2. Return a clone of node, with this and the clone children flag set if deep is true. return node->clone_node(this, deep); @@ -1273,10 +1273,10 @@ void Document::adopt_node(Node& node) ExceptionOr> Document::adopt_node_binding(JS::NonnullGCPtr node) { if (is(*node)) - return DOM::NotSupportedError::create("Cannot adopt a document into a document"); + return DOM::NotSupportedError::create(global_object(), "Cannot adopt a document into a document"); if (is(*node)) - return DOM::HierarchyRequestError::create("Cannot adopt a shadow root into a document"); + return DOM::HierarchyRequestError::create(global_object(), "Cannot adopt a shadow root into a document"); if (is(*node) && verify_cast(*node).host()) return node; @@ -1665,14 +1665,14 @@ bool Document::is_valid_name(String const& name) } // https://dom.spec.whatwg.org/#validate -ExceptionOr Document::validate_qualified_name(String const& qualified_name) +ExceptionOr Document::validate_qualified_name(JS::Object& global_object, String const& qualified_name) { if (qualified_name.is_empty()) - return InvalidCharacterError::create("Empty string is not a valid qualified name."); + return InvalidCharacterError::create(global_object, "Empty string is not a valid qualified name."); Utf8View utf8view { qualified_name }; if (!utf8view.validate()) - return InvalidCharacterError::create("Invalid qualified name."); + return InvalidCharacterError::create(global_object, "Invalid qualified name."); Optional colon_offset; @@ -1682,19 +1682,19 @@ ExceptionOr Document::validate_qualified_name(String auto code_point = *it; if (code_point == ':') { if (colon_offset.has_value()) - return InvalidCharacterError::create("More than one colon (:) in qualified name."); + return InvalidCharacterError::create(global_object, "More than one colon (:) in qualified name."); colon_offset = utf8view.byte_offset_of(it); at_start_of_name = true; continue; } if (at_start_of_name) { if (!is_valid_name_start_character(code_point)) - return InvalidCharacterError::create("Invalid start of qualified name."); + return InvalidCharacterError::create(global_object, "Invalid start of qualified name."); at_start_of_name = false; continue; } if (!is_valid_name_character(code_point)) - return InvalidCharacterError::create("Invalid character in qualified name."); + return InvalidCharacterError::create(global_object, "Invalid character in qualified name."); } if (!colon_offset.has_value()) @@ -1704,10 +1704,10 @@ ExceptionOr Document::validate_qualified_name(String }; if (*colon_offset == 0) - return InvalidCharacterError::create("Qualified name can't start with colon (:)."); + return InvalidCharacterError::create(global_object, "Qualified name can't start with colon (:)."); if (*colon_offset >= (qualified_name.length() - 1)) - return InvalidCharacterError::create("Qualified name can't end with colon (:)."); + return InvalidCharacterError::create(global_object, "Qualified name can't end with colon (:)."); return Document::PrefixAndTagName { .prefix = qualified_name.substring_view(0, *colon_offset), diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 6f86126f15..894e9011d9 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -328,7 +328,7 @@ public: FlyString prefix; FlyString tag_name; }; - static ExceptionOr validate_qualified_name(String const& qualified_name); + static ExceptionOr validate_qualified_name(JS::Object& global_object, String const& qualified_name); JS::NonnullGCPtr create_node_iterator(Node& root, unsigned what_to_show, JS::GCPtr); JS::NonnullGCPtr create_tree_walker(Node& root, unsigned what_to_show, JS::GCPtr); diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 18e3cb7884..1d0b715c1e 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -87,7 +87,7 @@ ExceptionOr Element::set_attribute(FlyString const& name, String const& va // 1. If qualifiedName does not match the Name production in XML, then throw an "InvalidCharacterError" DOMException. // FIXME: Proper name validation if (name.is_empty()) - return InvalidCharacterError::create("Attribute name must not be empty"); + return InvalidCharacterError::create(global_object(), "Attribute name must not be empty"); // 2. If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase. // FIXME: Handle the second condition, assume it is an HTML document for now. @@ -118,14 +118,14 @@ ExceptionOr Element::set_attribute(FlyString const& name, String const& va } // https://dom.spec.whatwg.org/#validate-and-extract -ExceptionOr validate_and_extract(FlyString namespace_, FlyString qualified_name) +ExceptionOr validate_and_extract(JS::Object& global_object, FlyString namespace_, FlyString qualified_name) { // 1. If namespace is the empty string, then set it to null. if (namespace_.is_empty()) namespace_ = {}; // 2. Validate qualifiedName. - TRY(Document::validate_qualified_name(qualified_name)); + TRY(Document::validate_qualified_name(global_object, qualified_name)); // 3. Let prefix be null. FlyString prefix = {}; @@ -142,19 +142,19 @@ ExceptionOr validate_and_extract(FlyString namespace_, FlyString // 6. If prefix is non-null and namespace is null, then throw a "NamespaceError" DOMException. if (!prefix.is_null() && namespace_.is_null()) - return NamespaceError::create("Prefix is non-null and namespace is null."); + return NamespaceError::create(global_object, "Prefix is non-null and namespace is null."); // 7. If prefix is "xml" and namespace is not the XML namespace, then throw a "NamespaceError" DOMException. if (prefix == "xml"sv && namespace_ != Namespace::XML) - return NamespaceError::create("Prefix is 'xml' and namespace is not the XML namespace."); + return NamespaceError::create(global_object, "Prefix is 'xml' and namespace is not the XML namespace."); // 8. If either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace, then throw a "NamespaceError" DOMException. if ((qualified_name == "xmlns"sv || prefix == "xmlns"sv) && namespace_ != Namespace::XMLNS) - return NamespaceError::create("Either qualifiedName or prefix is 'xmlns' and namespace is not the XMLNS namespace."); + return NamespaceError::create(global_object, "Either qualifiedName or prefix is 'xmlns' and namespace is not the XMLNS namespace."); // 9. If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns", then throw a "NamespaceError" DOMException. if (namespace_ == Namespace::XMLNS && !(qualified_name == "xmlns"sv || prefix == "xmlns"sv)) - return NamespaceError::create("Namespace is the XMLNS namespace and neither qualifiedName nor prefix is 'xmlns'."); + return NamespaceError::create(global_object, "Namespace is the XMLNS namespace and neither qualifiedName nor prefix is 'xmlns'."); // 10. Return namespace, prefix, and localName. return QualifiedName { local_name, prefix, namespace_ }; @@ -164,7 +164,7 @@ ExceptionOr validate_and_extract(FlyString namespace_, FlyString ExceptionOr Element::set_attribute_ns(FlyString const& namespace_, FlyString const& qualified_name, String const& value) { // 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract. - auto extracted_qualified_name = TRY(validate_and_extract(namespace_, qualified_name)); + auto extracted_qualified_name = TRY(validate_and_extract(global_object(), namespace_, qualified_name)); // FIXME: 2. Set an attribute value for this using localName, value, and also prefix and namespace. @@ -195,7 +195,7 @@ DOM::ExceptionOr Element::toggle_attribute(FlyString const& name, Optional // 1. If qualifiedName does not match the Name production in XML, then throw an "InvalidCharacterError" DOMException. // FIXME: Proper name validation if (name.is_empty()) - return InvalidCharacterError::create("Attribute name must not be empty"); + return InvalidCharacterError::create(global_object(), "Attribute name must not be empty"); // 2. If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase. // FIXME: Handle the second condition, assume it is an HTML document for now. @@ -439,7 +439,7 @@ DOM::ExceptionOr Element::matches(StringView selectors) const { auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(static_cast(const_cast(*this))), selectors); if (!maybe_selectors.has_value()) - return DOM::SyntaxError::create("Failed to parse selector"); + return DOM::SyntaxError::create(global_object(), "Failed to parse selector"); auto sel = maybe_selectors.value(); for (auto& s : sel) { @@ -454,7 +454,7 @@ DOM::ExceptionOr Element::closest(StringView selectors) con { auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(static_cast(const_cast(*this))), selectors); if (!maybe_selectors.has_value()) - return DOM::SyntaxError::create("Failed to parse selector"); + return DOM::SyntaxError::create(global_object(), "Failed to parse selector"); auto matches_selectors = [](CSS::SelectorList const& selector_list, Element const* element) { for (auto& selector : selector_list) { diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index f1f51311c4..ab4ffce2f7 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -170,7 +170,7 @@ private: template<> inline bool Node::fast_is() const { return is_element(); } -ExceptionOr validate_and_extract(FlyString namespace_, FlyString qualified_name); +ExceptionOr validate_and_extract(JS::Object& global_object, FlyString namespace_, FlyString qualified_name); } diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp index 58eb036cce..f94161eb5f 100644 --- a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp +++ b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp @@ -228,10 +228,10 @@ ExceptionOr EventTarget::dispatch_event_binding(Event& event) { // 1. If event’s dispatch flag is set, or if its initialized flag is not set, then throw an "InvalidStateError" DOMException. if (event.dispatched()) - return DOM::InvalidStateError::create("The event is already being dispatched."); + return DOM::InvalidStateError::create(global_object(), "The event is already being dispatched."); if (!event.initialized()) - return DOM::InvalidStateError::create("Cannot dispatch an uninitialized event."); + return DOM::InvalidStateError::create(global_object(), "Cannot dispatch an uninitialized event."); // 2. Initialize event’s isTrusted attribute to false. event.set_is_trusted(false); diff --git a/Userland/Libraries/LibWeb/DOM/ExceptionOr.h b/Userland/Libraries/LibWeb/DOM/ExceptionOr.h index bef730ff68..8e99b6adaf 100644 --- a/Userland/Libraries/LibWeb/DOM/ExceptionOr.h +++ b/Userland/Libraries/LibWeb/DOM/ExceptionOr.h @@ -49,7 +49,7 @@ public: { } - ExceptionOr(NonnullRefPtr exception) + ExceptionOr(JS::NonnullGCPtr exception) : m_exception(move(exception)) { } @@ -59,8 +59,8 @@ public: { } - ExceptionOr(Variant> exception) - : m_exception(move(exception).template downcast>()) + ExceptionOr(Variant> exception) + : m_exception(move(exception).template downcast>()) { } @@ -78,9 +78,9 @@ public: return m_result.release_value(); } - Variant> exception() const + Variant> exception() const { - return m_exception.template downcast>(); + return m_exception.template downcast>(); } bool is_exception() const @@ -90,12 +90,12 @@ public: // These are for compatibility with the TRY() macro in AK. [[nodiscard]] bool is_error() const { return is_exception(); } - Variant> release_error() { return exception(); } + Variant> release_error() { return exception(); } private: Optional m_result; // https://webidl.spec.whatwg.org/#idl-exceptions - Variant> m_exception {}; + Variant> m_exception {}; }; template<> diff --git a/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp b/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp index fddcf1906e..42c8b3d3fa 100644 --- a/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp +++ b/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp @@ -93,7 +93,7 @@ ExceptionOr NamedNodeMap::remove_named_item(StringView qualifi // 2. If attr is null, then throw a "NotFoundError" DOMException. if (!attribute) - return NotFoundError::create(String::formatted("Attribute with name '{}' not found", qualified_name)); + return NotFoundError::create(global_object(), String::formatted("Attribute with name '{}' not found", qualified_name)); // 3. Return attr. return nullptr; @@ -137,7 +137,7 @@ ExceptionOr NamedNodeMap::set_attribute(Attribute& attribute) { // 1. If attr’s element is neither null nor element, throw an "InUseAttributeError" DOMException. if ((attribute.owner_element() != nullptr) && (attribute.owner_element() != &associated_element())) - return InUseAttributeError::create("Attribute must not already be in use"sv); + return InUseAttributeError::create(global_object(), "Attribute must not already be in use"sv); // 2. Let oldAttr be the result of getting an attribute given attr’s namespace, attr’s local name, and element. // FIXME: When getNamedItemNS is implemented, use that instead. diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index 1feab011fc..c68efd6e21 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -310,24 +310,24 @@ ExceptionOr Node::ensure_pre_insertion_validity(JS::NonnullGCPtr nod { // 1. If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. if (!is(this) && !is(this) && !is(this)) - return DOM::HierarchyRequestError::create("Can only insert into a document, document fragment or element"); + return DOM::HierarchyRequestError::create(global_object(), "Can only insert into a document, document fragment or element"); // 2. If node is a host-including inclusive ancestor of parent, then throw a "HierarchyRequestError" DOMException. if (node->is_host_including_inclusive_ancestor_of(*this)) - return DOM::HierarchyRequestError::create("New node is an ancestor of this node"); + return DOM::HierarchyRequestError::create(global_object(), "New node is an ancestor of this node"); // 3. If child is non-null and its parent is not parent, then throw a "NotFoundError" DOMException. if (child && child->parent() != this) - return DOM::NotFoundError::create("This node is not the parent of the given child"); + return DOM::NotFoundError::create(global_object(), "This node is not the parent of the given child"); // FIXME: All the following "Invalid node type for insertion" messages could be more descriptive. // 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. if (!is(*node) && !is(*node) && !is(*node) && !is(*node) && !is(*node) && !is(*node)) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); // 5. If either node is a Text node and parent is a document, or node is a doctype and parent is not a document, then throw a "HierarchyRequestError" DOMException. if ((is(*node) && is(this)) || (is(*node) && !is(this))) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); // 6. If parent is a document, and any of the statements below, switched on the interface node implements, are true, then throw a "HierarchyRequestError" DOMException. if (is(this)) { @@ -338,18 +338,18 @@ ExceptionOr Node::ensure_pre_insertion_validity(JS::NonnullGCPtr nod auto node_element_child_count = verify_cast(*node).child_element_count(); if ((node_element_child_count > 1 || node->has_child_of_type()) || (node_element_child_count == 1 && (has_child_of_type() || is(child.ptr()) || (child && child->has_following_node_of_type_in_tree_order())))) { - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); } } else if (is(*node)) { // Element // If parent has an element child, child is a doctype, or child is non-null and a doctype is following child. if (has_child_of_type() || is(child.ptr()) || (child && child->has_following_node_of_type_in_tree_order())) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); } else if (is(*node)) { // DocumentType // parent has a doctype child, child is non-null and an element is preceding child, or child is null and parent has an element child. if (has_child_of_type() || (child && child->has_preceding_node_of_type_in_tree_order()) || (!child && has_child_of_type())) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); } } @@ -482,7 +482,7 @@ ExceptionOr> Node::pre_remove(JS::NonnullGCPtr chil { // 1. If child’s parent is not parent, then throw a "NotFoundError" DOMException. if (child->parent() != this) - return DOM::NotFoundError::create("Child does not belong to this node"); + return DOM::NotFoundError::create(global_object(), "Child does not belong to this node"); // 2. Remove child. child->remove(); @@ -607,25 +607,25 @@ ExceptionOr> Node::replace_child(JS::NonnullGCPtr n { // If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. if (!is(this) && !is(this) && !is(this)) - return DOM::HierarchyRequestError::create("Can only insert into a document, document fragment or element"); + return DOM::HierarchyRequestError::create(global_object(), "Can only insert into a document, document fragment or element"); // 2. If node is a host-including inclusive ancestor of parent, then throw a "HierarchyRequestError" DOMException. if (node->is_host_including_inclusive_ancestor_of(*this)) - return DOM::HierarchyRequestError::create("New node is an ancestor of this node"); + return DOM::HierarchyRequestError::create(global_object(), "New node is an ancestor of this node"); // 3. If child’s parent is not parent, then throw a "NotFoundError" DOMException. if (child->parent() != this) - return DOM::NotFoundError::create("This node is not the parent of the given child"); + return DOM::NotFoundError::create(global_object(), "This node is not the parent of the given child"); // FIXME: All the following "Invalid node type for insertion" messages could be more descriptive. // 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. if (!is(*node) && !is(*node) && !is(*node) && !is(*node) && !is(*node) && !is(*node)) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); // 5. If either node is a Text node and parent is a document, or node is a doctype and parent is not a document, then throw a "HierarchyRequestError" DOMException. if ((is(*node) && is(this)) || (is(*node) && !is(this))) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); // If parent is a document, and any of the statements below, switched on the interface node implements, are true, then throw a "HierarchyRequestError" DOMException. if (is(this)) { @@ -636,18 +636,18 @@ ExceptionOr> Node::replace_child(JS::NonnullGCPtr n auto node_element_child_count = verify_cast(*node).child_element_count(); if ((node_element_child_count > 1 || node->has_child_of_type()) || (node_element_child_count == 1 && (first_child_of_type() != child || child->has_following_node_of_type_in_tree_order()))) { - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); } } else if (is(*node)) { // Element // parent has an element child that is not child or a doctype is following child. if (first_child_of_type() != child || child->has_following_node_of_type_in_tree_order()) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); } else if (is(*node)) { // DocumentType // parent has a doctype child that is not child, or an element is preceding child. if (first_child_of_type() != node || child->has_preceding_node_of_type_in_tree_order()) - return DOM::HierarchyRequestError::create("Invalid node type for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Invalid node type for insertion"); } } @@ -791,7 +791,7 @@ ExceptionOr> Node::clone_node_binding(bool deep) { // 1. If this is a shadow root, then throw a "NotSupportedError" DOMException. if (is(*this)) - return NotSupportedError::create("Cannot clone shadow root"); + return NotSupportedError::create(global_object(), "Cannot clone shadow root"); // 2. Return a clone of this, with the clone children flag set if deep is true. return clone_node(nullptr, deep); diff --git a/Userland/Libraries/LibWeb/DOM/NodeFilter.cpp b/Userland/Libraries/LibWeb/DOM/NodeFilter.cpp index 5f02bb1cb5..8c018a73ab 100644 --- a/Userland/Libraries/LibWeb/DOM/NodeFilter.cpp +++ b/Userland/Libraries/LibWeb/DOM/NodeFilter.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include diff --git a/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp b/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp index 923f66be67..6c9d3bacc2 100644 --- a/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp +++ b/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp @@ -4,7 +4,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include #include @@ -131,7 +130,7 @@ JS::ThrowCompletionOr NodeIterator::filter(Node& node) { // 1. If traverser’s active flag is set, then throw an "InvalidStateError" DOMException. if (m_active) - return JS::throw_completion(wrap(shape().realm(), InvalidStateError::create("NodeIterator is already active"))); + return JS::throw_completion(wrap(shape().realm(), InvalidStateError::create(global_object(), "NodeIterator is already active"))); // 2. Let n be node’s nodeType attribute value − 1. auto n = node.node_type() - 1; diff --git a/Userland/Libraries/LibWeb/DOM/ParentNode.cpp b/Userland/Libraries/LibWeb/DOM/ParentNode.cpp index efbcfbffe9..a472e356c3 100644 --- a/Userland/Libraries/LibWeb/DOM/ParentNode.cpp +++ b/Userland/Libraries/LibWeb/DOM/ParentNode.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace Web::DOM { @@ -19,7 +20,7 @@ ExceptionOr> ParentNode::query_selector(StringView selector_t { auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(*this), selector_text); if (!maybe_selectors.has_value()) - return DOM::SyntaxError::create("Failed to parse selector"); + return DOM::SyntaxError::create(global_object(), "Failed to parse selector"); auto selectors = maybe_selectors.value(); @@ -42,7 +43,7 @@ ExceptionOr> ParentNode::query_selector_all(StringVie { auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(*this), selector_text); if (!maybe_selectors.has_value()) - return DOM::SyntaxError::create("Failed to parse selector"); + return DOM::SyntaxError::create(global_object(), "Failed to parse selector"); auto selectors = maybe_selectors.value(); diff --git a/Userland/Libraries/LibWeb/DOM/Range.cpp b/Userland/Libraries/LibWeb/DOM/Range.cpp index cfe2709016..ccb99cd301 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.cpp +++ b/Userland/Libraries/LibWeb/DOM/Range.cpp @@ -137,11 +137,11 @@ ExceptionOr Range::set_start_or_end(Node& node, u32 offset, StartOrEnd sta // 1. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. if (is(node)) - return InvalidNodeTypeError::create("Node cannot be a DocumentType."); + return InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType."); // 2. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException. if (offset > node.length()) - return IndexSizeError::create(String::formatted("Node does not contain a child at offset {}", offset)); + return IndexSizeError::create(global_object(), String::formatted("Node does not contain a child at offset {}", offset)); // 3. Let bp be the boundary point (node, offset). @@ -196,7 +196,7 @@ ExceptionOr Range::set_start_before(Node& node) // 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. if (!parent) - return InvalidNodeTypeError::create("Given node has no parent."); + return InvalidNodeTypeError::create(global_object(), "Given node has no parent."); // 3. Set the start of this to boundary point (parent, node’s index). return set_start_or_end(*parent, node.index(), StartOrEnd::Start); @@ -210,7 +210,7 @@ ExceptionOr Range::set_start_after(Node& node) // 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. if (!parent) - return InvalidNodeTypeError::create("Given node has no parent."); + return InvalidNodeTypeError::create(global_object(), "Given node has no parent."); // 3. Set the start of this to boundary point (parent, node’s index plus 1). return set_start_or_end(*parent, node.index() + 1, StartOrEnd::Start); @@ -224,7 +224,7 @@ ExceptionOr Range::set_end_before(Node& node) // 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. if (!parent) - return InvalidNodeTypeError::create("Given node has no parent."); + return InvalidNodeTypeError::create(global_object(), "Given node has no parent."); // 3. Set the end of this to boundary point (parent, node’s index). return set_start_or_end(*parent, node.index(), StartOrEnd::End); @@ -238,7 +238,7 @@ ExceptionOr Range::set_end_after(Node& node) // 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. if (!parent) - return InvalidNodeTypeError::create("Given node has no parent."); + return InvalidNodeTypeError::create(global_object(), "Given node has no parent."); // 3. Set the end of this to boundary point (parent, node’s index plus 1). return set_start_or_end(*parent, node.index() + 1, StartOrEnd::End); @@ -254,11 +254,11 @@ ExceptionOr Range::compare_boundary_points(u16 how, Range const& source_ran // - END_TO_START, // then throw a "NotSupportedError" DOMException. if (how != HowToCompareBoundaryPoints::START_TO_START && how != HowToCompareBoundaryPoints::START_TO_END && how != HowToCompareBoundaryPoints::END_TO_END && how != HowToCompareBoundaryPoints::END_TO_START) - return NotSupportedError::create(String::formatted("Expected 'how' to be one of START_TO_START (0), START_TO_END (1), END_TO_END (2) or END_TO_START (3), got {}", how)); + return NotSupportedError::create(global_object(), String::formatted("Expected 'how' to be one of START_TO_START (0), START_TO_END (1), END_TO_END (2) or END_TO_START (3), got {}", how)); // 2. If this’s root is not the same as sourceRange’s root, then throw a "WrongDocumentError" DOMException. if (&root() != &source_range.root()) - return WrongDocumentError::create("This range is not in the same tree as the source range."); + return WrongDocumentError::create(global_object(), "This range is not in the same tree as the source range."); JS::GCPtr this_point_node; u32 this_point_offset = 0; @@ -339,7 +339,7 @@ ExceptionOr Range::select(Node& node) // 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. if (!parent) - return InvalidNodeTypeError::create("Given node has no parent."); + return InvalidNodeTypeError::create(global_object(), "Given node has no parent."); // 3. Let index be node’s index. auto index = node.index(); @@ -381,7 +381,7 @@ ExceptionOr Range::select_node_contents(Node const& node) { // 1. If node is a doctype, throw an "InvalidNodeTypeError" DOMException. if (is(node)) - return InvalidNodeTypeError::create("Node cannot be a DocumentType."); + return InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType."); // 2. Let length be the length of node. auto length = node.length(); @@ -474,11 +474,11 @@ ExceptionOr Range::is_point_in_range(Node const& node, u32 offset) const // 2. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. if (is(node)) - return InvalidNodeTypeError::create("Node cannot be a DocumentType."); + return InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType."); // 3. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException. if (offset > node.length()) - return IndexSizeError::create(String::formatted("Node does not contain a child at offset {}", offset)); + return IndexSizeError::create(global_object(), String::formatted("Node does not contain a child at offset {}", offset)); // 4. If (node, offset) is before start or after end, return false. auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset); @@ -495,15 +495,15 @@ ExceptionOr Range::compare_point(Node const& node, u32 offset) const { // 1. If node’s root is different from this’s root, then throw a "WrongDocumentError" DOMException. if (&node.root() != &root()) - return WrongDocumentError::create("Given node is not in the same document as the range."); + return WrongDocumentError::create(global_object(), "Given node is not in the same document as the range."); // 2. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. if (is(node)) - return InvalidNodeTypeError::create("Node cannot be a DocumentType."); + return InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType."); // 3. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException. if (offset > node.length()) - return IndexSizeError::create(String::formatted("Node does not contain a child at offset {}", offset)); + return IndexSizeError::create(global_object(), String::formatted("Node does not contain a child at offset {}", offset)); // 4. If (node, offset) is before start, return −1. auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset); @@ -636,7 +636,7 @@ ExceptionOr> Range::extract() // 12. If any member of contained children is a doctype, then throw a "HierarchyRequestError" DOMException. for (auto const& child : contained_children) { if (is(*child)) - return DOM::HierarchyRequestError::create("Contained child is a DocumentType"); + return DOM::HierarchyRequestError::create(global_object(), "Contained child is a DocumentType"); } JS::GCPtr new_node; @@ -783,7 +783,7 @@ ExceptionOr Range::insert(JS::NonnullGCPtr node) if ((is(*m_start_container) || is(*m_start_container)) || (is(*m_start_container) && !m_start_container->parent_node()) || m_start_container.ptr() == node.ptr()) { - return DOM::HierarchyRequestError::create("Range has inappropriate start node for insertion"); + return DOM::HierarchyRequestError::create(global_object(), "Range has inappropriate start node for insertion"); } // 2. Let referenceNode be null. @@ -854,11 +854,11 @@ ExceptionOr Range::surround_contents(JS::NonnullGCPtr new_parent) if (is(*end_non_text_node)) end_non_text_node = end_non_text_node->parent_node(); if (start_non_text_node != end_non_text_node) - return InvalidStateError::create("Non-Text node is partially contained in range."); + return InvalidStateError::create(global_object(), "Non-Text node is partially contained in range."); // 2. If newParent is a Document, DocumentType, or DocumentFragment node, then throw an "InvalidNodeTypeError" DOMException. if (is(*new_parent) || is(*new_parent) || is(*new_parent)) - return InvalidNodeTypeError::create("Invalid parent node type"); + return InvalidNodeTypeError::create(global_object(), "Invalid parent node type"); // 3. Let fragment be the result of extracting this. auto fragment = TRY(extract()); @@ -962,7 +962,7 @@ ExceptionOr> Range::clone_the_contents() // 12. If any member of contained children is a doctype, then throw a "HierarchyRequestError" DOMException. for (auto const& child : contained_children) { if (is(*child)) - return DOM::HierarchyRequestError::create("Contained child is a DocumentType"); + return DOM::HierarchyRequestError::create(global_object(), "Contained child is a DocumentType"); } // 13. If first partially contained child is a CharacterData node, then: diff --git a/Userland/Libraries/LibWeb/DOM/StaticRange.cpp b/Userland/Libraries/LibWeb/DOM/StaticRange.cpp index 3396d1aeb3..287856db7a 100644 --- a/Userland/Libraries/LibWeb/DOM/StaticRange.cpp +++ b/Userland/Libraries/LibWeb/DOM/StaticRange.cpp @@ -23,17 +23,17 @@ StaticRange::StaticRange(Node& start_container, u32 start_offset, Node& end_cont StaticRange::~StaticRange() = default; // https://dom.spec.whatwg.org/#dom-staticrange-staticrange -ExceptionOr StaticRange::create_with_global_object(HTML::Window& window_object, StaticRangeInit& init) +ExceptionOr StaticRange::create_with_global_object(HTML::Window& window, StaticRangeInit& init) { // 1. If init["startContainer"] or init["endContainer"] is a DocumentType or Attr node, then throw an "InvalidNodeTypeError" DOMException. if (is(*init.start_container) || is(*init.start_container)) - return DOM::InvalidNodeTypeError::create("startContainer cannot be a DocumentType or Attribute node."); + return DOM::InvalidNodeTypeError::create(window, "startContainer cannot be a DocumentType or Attribute node."); if (is(*init.end_container) || is(*init.end_container)) - return DOM::InvalidNodeTypeError::create("endContainer cannot be a DocumentType or Attribute node."); + return DOM::InvalidNodeTypeError::create(window, "endContainer cannot be a DocumentType or Attribute node."); // 2. Set this’s start to (init["startContainer"], init["startOffset"]) and end to (init["endContainer"], init["endOffset"]). - return window_object.heap().allocate(window_object.realm(), *init.start_container, init.start_offset, *init.end_container, init.end_offset); + return window.heap().allocate(window.realm(), *init.start_container, init.start_offset, *init.end_container, init.end_offset); } } diff --git a/Userland/Libraries/LibWeb/DOM/Text.cpp b/Userland/Libraries/LibWeb/DOM/Text.cpp index c6a4d0ad66..57398559e1 100644 --- a/Userland/Libraries/LibWeb/DOM/Text.cpp +++ b/Userland/Libraries/LibWeb/DOM/Text.cpp @@ -50,7 +50,7 @@ ExceptionOr> Text::split_text(size_t offset) // 2. If offset is greater than length, then throw an "IndexSizeError" DOMException. if (offset > length) - return DOM::IndexSizeError::create("Split offset is greater than length"); + return DOM::IndexSizeError::create(global_object(), "Split offset is greater than length"); // 3. Let count be length minus offset. auto count = length - offset; diff --git a/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp b/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp index c07b2ba666..2a496c27e9 100644 --- a/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp +++ b/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp @@ -4,9 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include -#include #include #include #include @@ -233,7 +231,7 @@ JS::ThrowCompletionOr TreeWalker::filter(Node& node) { // 1. If traverser’s active flag is set, then throw an "InvalidStateError" DOMException. if (m_active) - return JS::throw_completion(wrap(shape().realm(), InvalidStateError::create("NodeIterator is already active"))); + return JS::throw_completion(wrap(shape().realm(), InvalidStateError::create(global_object(), "NodeIterator is already active"))); // 2. Let n be node’s nodeType attribute value − 1. auto n = node.node_type() - 1; diff --git a/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp b/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp index 6a7f99121d..95cf5150cb 100644 --- a/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp +++ b/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp @@ -308,6 +308,8 @@ struct LocalNameSetEntry { // https://w3c.github.io/DOM-Parsing/#dfn-xml-serialization-of-the-attributes static DOM::ExceptionOr serialize_element_attributes(DOM::Element const& element, HashMap>& namespace_prefix_map, u64& prefix_index, HashMap const& local_prefixes_map, bool ignore_namespace_definition_attribute, RequireWellFormed require_well_formed) { + auto& global_object = element.global_object(); + // 1. Let result be the empty string. StringBuilder result; @@ -329,7 +331,7 @@ static DOM::ExceptionOr serialize_element_attributes(DOM::Element const& }); if (local_name_set_iterator != local_name_set.end()) - return DOM::InvalidStateError::create("Element contains two attributes with identical namespaces and local names"); + return DOM::InvalidStateError::create(global_object, "Element contains two attributes with identical namespaces and local names"); } // 2. Create a new tuple consisting of attr's namespaceURI attribute and localName attribute, and add it to the localname set. @@ -382,12 +384,12 @@ static DOM::ExceptionOr serialize_element_attributes(DOM::Element const& // 2. If the require well-formed flag is set (its value is true), and the value of attr's value attribute matches the XMLNS namespace, // then throw an exception; the serialization of this attribute would produce invalid XML because the XMLNS namespace is reserved and cannot be applied as an element's namespace via XML parsing. if (require_well_formed == RequireWellFormed::Yes && attribute->value() == Namespace::XMLNS) - return DOM::InvalidStateError::create("The XMLNS namespace cannot be used as an element's namespace"); + return DOM::InvalidStateError::create(global_object, "The XMLNS namespace cannot be used as an element's namespace"); // 3. If the require well-formed flag is set (its value is true), and the value of attr's value attribute is the empty string, // then throw an exception; namespace prefix declarations cannot be used to undeclare a namespace (use a default namespace declaration instead). if (require_well_formed == RequireWellFormed::Yes && attribute->value().is_empty()) - return DOM::InvalidStateError::create("Attribute's value is empty"); + return DOM::InvalidStateError::create(global_object, "Attribute's value is empty"); // 4. [If] the attr's prefix matches the string "xmlns", then let candidate prefix be the string "xmlns". if (attribute->prefix() == "xmlns"sv) @@ -430,12 +432,12 @@ static DOM::ExceptionOr serialize_element_attributes(DOM::Element const& // or does not match the XML Name production or equals "xmlns" and attribute namespace is null, then throw an exception; the serialization of this attr would not be a well-formed attribute. if (require_well_formed == RequireWellFormed::Yes) { if (attribute->local_name().view().contains(':')) - return DOM::InvalidStateError::create("Attribute's local name contains a colon"); + return DOM::InvalidStateError::create(global_object, "Attribute's local name contains a colon"); // FIXME: Check attribute's local name against the XML Name production. if (attribute->local_name() == "xmlns"sv && attribute_namespace.is_null()) - return DOM::InvalidStateError::create("Attribute's local name is 'xmlns' and the attribute has no namespace"); + return DOM::InvalidStateError::create(global_object, "Attribute's local name is 'xmlns' and the attribute has no namespace"); } // 9. Append the following strings to result, in the order listed: @@ -459,11 +461,13 @@ static DOM::ExceptionOr serialize_element_attributes(DOM::Element const& // https://w3c.github.io/DOM-Parsing/#xml-serializing-an-element-node static DOM::ExceptionOr serialize_element(DOM::Element const& element, Optional& namespace_, HashMap>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed) { + auto& global_object = element.global_object(); + // 1. If the require well-formed flag is set (its value is true), and this node's localName attribute contains the character ":" (U+003A COLON) or does not match the XML Name production, // then throw an exception; the serialization of this node would not be a well-formed element. if (require_well_formed == RequireWellFormed::Yes) { if (element.local_name().view().contains(':')) - return DOM::InvalidStateError::create("Element's local name contains a colon"); + return DOM::InvalidStateError::create(global_object, "Element's local name contains a colon"); // FIXME: Check element's local name against the XML Char production. } @@ -535,7 +539,7 @@ static DOM::ExceptionOr serialize_element(DOM::Element const& element, O if (prefix == "xmlns"sv) { // 1. If the require well-formed flag is set, then throw an error. An Element with prefix "xmlns" will not legally round-trip in a conforming XML parser. if (require_well_formed == RequireWellFormed::Yes) - return DOM::InvalidStateError::create("Elements prefix is 'xmlns'"); + return DOM::InvalidStateError::create(global_object, "Elements prefix is 'xmlns'"); // 2. Let candidate prefix be the value of prefix. candidate_prefix = prefix; @@ -702,7 +706,7 @@ static DOM::ExceptionOr serialize_document(DOM::Document const& document // If the require well-formed flag is set (its value is true), and this node has no documentElement (the documentElement attribute's value is null), // then throw an exception; the serialization of this node would not be a well-formed document. if (require_well_formed == RequireWellFormed::Yes && !document.document_element()) - return DOM::InvalidStateError::create("Document has no document element"); + return DOM::InvalidStateError::create(document.global_object(), "Document has no document element"); // Otherwise, run the following steps: // 1. Let serialized document be an empty string. @@ -726,10 +730,10 @@ static DOM::ExceptionOr serialize_comment(DOM::Comment const& comment, R // FIXME: Check comment's data against the XML Char production. if (comment.data().contains("--"sv)) - return DOM::InvalidStateError::create("Comment data contains two adjacent hyphens"); + return DOM::InvalidStateError::create(comment.global_object(), "Comment data contains two adjacent hyphens"); if (comment.data().ends_with('-')) - return DOM::InvalidStateError::create("Comment data ends with a hyphen"); + return DOM::InvalidStateError::create(comment.global_object(), "Comment data ends with a hyphen"); } // Otherwise, return the concatenation of "". @@ -784,7 +788,7 @@ static DOM::ExceptionOr serialize_document_type(DOM::DocumentType const& // both a """ (U+0022 QUOTATION MARK) and a "'" (U+0027 APOSTROPHE), then throw an exception; the serialization of this node would not be a well-formed document type declaration. // FIXME: Check systemId against the XML Char production. if (document_type.system_id().contains('"') && document_type.system_id().contains('\'')) - return DOM::InvalidStateError::create("Document type system ID contains both a quotation mark and an apostrophe"); + return DOM::InvalidStateError::create(document_type.global_object(), "Document type system ID contains both a quotation mark and an apostrophe"); } // 3. Let markup be an empty string. @@ -846,16 +850,16 @@ static DOM::ExceptionOr serialize_processing_instruction(DOM::Processing // 1. If the require well-formed flag is set (its value is true), and node's target contains a ":" (U+003A COLON) character // or is an ASCII case-insensitive match for the string "xml", then throw an exception; the serialization of this node's target would not be well-formed. if (processing_instruction.target().contains(':')) - return DOM::InvalidStateError::create("Processing instruction target contains a colon"); + return DOM::InvalidStateError::create(processing_instruction.global_object(), "Processing instruction target contains a colon"); if (processing_instruction.target().equals_ignoring_case("xml"sv)) - return DOM::InvalidStateError::create("Processing instruction target is equal to 'xml'"); + return DOM::InvalidStateError::create(processing_instruction.global_object(), "Processing instruction target is equal to 'xml'"); // 2. If the require well-formed flag is set (its value is true), and node's data contains characters that are not matched by the XML Char production or contains // the string "?>" (U+003F QUESTION MARK, U+003E GREATER-THAN SIGN), then throw an exception; the serialization of this node's data would not be well-formed. // FIXME: Check data against the XML Char production. if (processing_instruction.data().contains("?>"sv)) - return DOM::InvalidStateError::create("Processing instruction data contains a terminator"); + return DOM::InvalidStateError::create(processing_instruction.global_object(), "Processing instruction data contains a terminator"); } // 3. Let markup be the concatenation of the following, in the order listed: diff --git a/Userland/Libraries/LibWeb/Encoding/TextDecoder.cpp b/Userland/Libraries/LibWeb/Encoding/TextDecoder.cpp index 4895ce1b62..9da49e92ba 100644 --- a/Userland/Libraries/LibWeb/Encoding/TextDecoder.cpp +++ b/Userland/Libraries/LibWeb/Encoding/TextDecoder.cpp @@ -41,7 +41,7 @@ DOM::ExceptionOr TextDecoder::decode(JS::Handle const& input auto data_buffer_or_error = Bindings::IDL::get_buffer_source_copy(*input.cell()); if (data_buffer_or_error.is_error()) - return DOM::OperationError::create("Failed to copy bytes from ArrayBuffer"); + return DOM::OperationError::create(global_object(), "Failed to copy bytes from ArrayBuffer"); auto& data_buffer = data_buffer_or_error.value(); return m_decoder.to_utf8({ data_buffer.data(), data_buffer.size() }); } diff --git a/Userland/Libraries/LibWeb/Fetch/Headers.cpp b/Userland/Libraries/LibWeb/Fetch/Headers.cpp index 1b2e0d7d1f..a254be9b45 100644 --- a/Userland/Libraries/LibWeb/Fetch/Headers.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Headers.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include @@ -38,8 +39,8 @@ DOM::ExceptionOr Headers::append(String const& name_string, String const& { // The append(name, value) method steps are to append (name, value) to this. auto header = Infrastructure::Header { - .name = TRY_OR_RETURN_OOM(ByteBuffer::copy(name_string.bytes())), - .value = TRY_OR_RETURN_OOM(ByteBuffer::copy(value_string.bytes())), + .name = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(name_string.bytes())), + .value = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(value_string.bytes())), }; TRY(append(move(header))); return {}; @@ -96,7 +97,7 @@ DOM::ExceptionOr Headers::get(String const& name_string) return DOM::SimpleException { DOM::SimpleExceptionType::TypeError, "Invalid header name" }; // 2. Return the result of getting name from this’s header list. - auto byte_buffer = TRY_OR_RETURN_OOM(m_header_list.get(name)); + auto byte_buffer = TRY_OR_RETURN_OOM(global_object(), m_header_list.get(name)); // FIXME: Teach WrapperGenerator about Optional return byte_buffer.has_value() ? String { byte_buffer->span() } : String {}; } @@ -123,10 +124,10 @@ DOM::ExceptionOr Headers::set(String const& name_string, String const& val auto value = value_string.bytes(); // 1. Normalize value. - auto normalized_value = TRY_OR_RETURN_OOM(Infrastructure::normalize_header_value(value)); + auto normalized_value = TRY_OR_RETURN_OOM(global_object(), Infrastructure::normalize_header_value(value)); auto header = Infrastructure::Header { - .name = TRY_OR_RETURN_OOM(ByteBuffer::copy(name)), + .name = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(name)), .value = move(normalized_value), }; @@ -153,7 +154,7 @@ DOM::ExceptionOr Headers::set(String const& name_string, String const& val return {}; // 7. Set (name, value) in this’s header list. - TRY_OR_RETURN_OOM(m_header_list.set(move(header))); + TRY_OR_RETURN_OOM(global_object(), m_header_list.set(move(header))); // 8. If this’s guard is "request-no-cors", then remove privileged no-CORS request headers from this. if (m_guard == Guard::RequestNoCORS) @@ -206,7 +207,7 @@ DOM::ExceptionOr Headers::append(Infrastructure::Header header) auto& [name, value] = header; // 1. Normalize value. - value = TRY_OR_RETURN_OOM(Infrastructure::normalize_header_value(value)); + value = TRY_OR_RETURN_OOM(global_object(), Infrastructure::normalize_header_value(value)); // 2. If name is not a header name or value is not a header value, then throw a TypeError. if (!Infrastructure::is_header_name(name)) @@ -225,21 +226,21 @@ DOM::ExceptionOr Headers::append(Infrastructure::Header header) // 5. Otherwise, if headers’s guard is "request-no-cors": if (m_guard == Guard::RequestNoCORS) { // 1. Let temporaryValue be the result of getting name from headers’s header list. - auto temporary_value = TRY_OR_RETURN_OOM(m_header_list.get(name)); + auto temporary_value = TRY_OR_RETURN_OOM(global_object(), m_header_list.get(name)); // 2. If temporaryValue is null, then set temporaryValue to value. if (!temporary_value.has_value()) { - temporary_value = TRY_OR_RETURN_OOM(ByteBuffer::copy(value)); + temporary_value = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(value)); } // 3. Otherwise, set temporaryValue to temporaryValue, followed by 0x2C 0x20, followed by value. else { - TRY_OR_RETURN_OOM(temporary_value->try_append(0x2c)); - TRY_OR_RETURN_OOM(temporary_value->try_append(0x20)); - TRY_OR_RETURN_OOM(temporary_value->try_append(value)); + TRY_OR_RETURN_OOM(global_object(), temporary_value->try_append(0x2c)); + TRY_OR_RETURN_OOM(global_object(), temporary_value->try_append(0x20)); + TRY_OR_RETURN_OOM(global_object(), temporary_value->try_append(value)); } auto temporary_header = Infrastructure::Header { - .name = TRY_OR_RETURN_OOM(ByteBuffer::copy(name)), + .name = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(name)), .value = temporary_value.release_value(), }; @@ -253,7 +254,7 @@ DOM::ExceptionOr Headers::append(Infrastructure::Header header) return {}; // 7. Append (name, value) to headers’s header list. - TRY_OR_RETURN_OOM(m_header_list.append(move(header))); + TRY_OR_RETURN_OOM(global_object(), m_header_list.append(move(header))); // 8. If headers’s guard is "request-no-cors", then remove privileged no-CORS request headers from headers. if (m_guard == Guard::RequestNoCORS) @@ -276,8 +277,8 @@ DOM::ExceptionOr Headers::fill(HeadersInit const& object) // 2. Append (header’s first item, header’s second item) to headers. auto header = Fetch::Infrastructure::Header { - .name = TRY_OR_RETURN_OOM(ByteBuffer::copy(entry[0].bytes())), - .value = TRY_OR_RETURN_OOM(ByteBuffer::copy(entry[1].bytes())), + .name = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(entry[0].bytes())), + .value = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(entry[1].bytes())), }; TRY(append(move(header))); } @@ -287,8 +288,8 @@ DOM::ExceptionOr Headers::fill(HeadersInit const& object) [this](OrderedHashMap const& object) -> DOM::ExceptionOr { for (auto const& entry : object) { auto header = Fetch::Infrastructure::Header { - .name = TRY_OR_RETURN_OOM(ByteBuffer::copy(entry.key.bytes())), - .value = TRY_OR_RETURN_OOM(ByteBuffer::copy(entry.value.bytes())), + .name = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(entry.key.bytes())), + .value = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(entry.value.bytes())), }; TRY(append(move(header))); } diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.h index f487874fa0..8f4dfcad4e 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.h +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.h @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace Web::Fetch::Infrastructure { diff --git a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp index f839062ef4..bc41d26aeb 100644 --- a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -145,7 +144,7 @@ DOM::ExceptionOr> Blob::create(HTML::Window& window, Opti ByteBuffer byte_buffer {}; // 2. Let bytes be the result of processing blob parts given blobParts and options. if (blob_parts.has_value()) { - byte_buffer = TRY_OR_RETURN_OOM(process_blob_parts(blob_parts.value(), options)); + byte_buffer = TRY_OR_RETURN_OOM(window, process_blob_parts(blob_parts.value(), options)); } auto type = String::empty(); @@ -233,7 +232,7 @@ DOM::ExceptionOr> Blob::slice(Optional start, Option // a. S refers to span consecutive bytes from this, beginning with the byte at byte-order position relativeStart. // b. S.size = span. // c. S.type = relativeContentType. - auto byte_buffer = TRY_OR_RETURN_OOM(m_byte_buffer.slice(relative_start, span)); + auto byte_buffer = TRY_OR_RETURN_OOM(global_object(), m_byte_buffer.slice(relative_start, span)); return JS::NonnullGCPtr(*heap().allocate(realm(), global_object(), move(byte_buffer), move(relative_content_type))); } diff --git a/Userland/Libraries/LibWeb/FileAPI/File.cpp b/Userland/Libraries/LibWeb/FileAPI/File.cpp index af004640d9..f431134bca 100644 --- a/Userland/Libraries/LibWeb/FileAPI/File.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/File.cpp @@ -23,7 +23,7 @@ File::~File() = default; DOM::ExceptionOr> File::create(HTML::Window& window, Vector const& file_bits, String const& file_name, Optional const& options) { // 1. Let bytes be the result of processing blob parts given fileBits and options. - auto bytes = TRY_OR_RETURN_OOM(process_blob_parts(file_bits, static_cast const&>(*options))); + auto bytes = TRY_OR_RETURN_OOM(window, process_blob_parts(file_bits, static_cast const&>(*options))); // 2. Let n be the fileName argument to the constructor. // NOTE: Underlying OS filesystems use differing conventions for file name; with constructed files, mandating UTF-16 lessens ambiquity when file names are converted to byte sequences. diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 35dbb89550..1c7718b722 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -448,7 +448,6 @@ class URLSearchParamsIterator; } namespace Web::Bindings { -class DOMExceptionWrapper; class LocationObject; class OptionConstructor; class RangePrototype; diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp index d87f9cbe9a..2091832fa7 100644 --- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace Web::HTML { @@ -38,17 +39,17 @@ void CanvasPath::bezier_curve_to(double cp1x, double cp1y, double cp2x, double c DOM::ExceptionOr CanvasPath::arc(float x, float y, float radius, float start_angle, float end_angle, bool counter_clockwise) { if (radius < 0) - return DOM::IndexSizeError::create(String::formatted("The radius provided ({}) is negative.", radius)); + return DOM::IndexSizeError::create(m_self.global_object(), String::formatted("The radius provided ({}) is negative.", radius)); return ellipse(x, y, radius, radius, 0, start_angle, end_angle, counter_clockwise); } DOM::ExceptionOr CanvasPath::ellipse(float x, float y, float radius_x, float radius_y, float rotation, float start_angle, float end_angle, bool counter_clockwise) { if (radius_x < 0) - return DOM::IndexSizeError::create(String::formatted("The major-axis radius provided ({}) is negative.", radius_x)); + return DOM::IndexSizeError::create(m_self.global_object(), String::formatted("The major-axis radius provided ({}) is negative.", radius_x)); if (radius_y < 0) - return DOM::IndexSizeError::create(String::formatted("The minor-axis radius provided ({}) is negative.", radius_y)); + return DOM::IndexSizeError::create(m_self.global_object(), String::formatted("The minor-axis radius provided ({}) is negative.", radius_y)); if (constexpr float tau = M_TAU; (!counter_clockwise && (end_angle - start_angle) >= tau) || (counter_clockwise && (start_angle - end_angle) >= tau)) { diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.h b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.h index 0fb4e1fd42..4d9a0ecd2f 100644 --- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.h +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.h @@ -30,9 +30,13 @@ public: Gfx::Path const& path() const { return m_path; } protected: - CanvasPath() = default; + explicit CanvasPath(Bindings::PlatformObject& self) + : m_self(self) + { + } private: + Bindings::PlatformObject& m_self; Gfx::Path m_path; }; diff --git a/Userland/Libraries/LibWeb/HTML/CanvasGradient.cpp b/Userland/Libraries/LibWeb/HTML/CanvasGradient.cpp index 56e0971d4e..213d301e81 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasGradient.cpp +++ b/Userland/Libraries/LibWeb/HTML/CanvasGradient.cpp @@ -53,14 +53,14 @@ DOM::ExceptionOr CanvasGradient::add_color_stop(double offset, String cons { // 1. If the offset is less than 0 or greater than 1, then throw an "IndexSizeError" DOMException. if (offset < 0 || offset > 1) - return DOM::IndexSizeError::create("CanvasGradient color stop offset out of bounds"); + return DOM::IndexSizeError::create(global_object(), "CanvasGradient color stop offset out of bounds"); // 2. Let parsed color be the result of parsing color. auto parsed_color = Color::from_string(color); // 3. If parsed color is failure, throw a "SyntaxError" DOMException. if (!parsed_color.has_value()) - return DOM::SyntaxError::create("Could not parse color for CanvasGradient"); + return DOM::SyntaxError::create(global_object(), "Could not parse color for CanvasGradient"); // 4. Place a new stop on the gradient, at offset offset relative to the whole gradient, and with the color parsed color. m_color_stops.append(ColorStop { offset, parsed_color.value() }); diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 287e03e5d9..8e9fc7a126 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -29,6 +29,7 @@ JS::NonnullGCPtr CanvasRenderingContext2D::create(HTML CanvasRenderingContext2D::CanvasRenderingContext2D(HTML::Window& window, HTMLCanvasElement& element) : PlatformObject(window.realm()) + , CanvasPath(static_cast(*this)) , m_element(element) { set_prototype(&window.cached_web_prototype("CanvasRenderingContext2D")); @@ -326,11 +327,11 @@ DOM::ExceptionOr> CanvasRenderingContext2D::get_image_data( { // 1. If either the sw or sh arguments are zero, then throw an "IndexSizeError" DOMException. if (width == 0 || height == 0) - return DOM::IndexSizeError::create("Width and height must not be zero"); + return DOM::IndexSizeError::create(global_object(), "Width and height must not be zero"); // 2. If the CanvasRenderingContext2D's origin-clean flag is set to false, then throw a "SecurityError" DOMException. if (!m_origin_clean) - return DOM::SecurityError::create("CanvasRenderingContext2D is not origin-clean"); + return DOM::SecurityError::create(global_object(), "CanvasRenderingContext2D is not origin-clean"); // 3. Let imageData be a new ImageData object. // 4. Initialize imageData given sw, sh, settings set to settings, and defaultColorSpace set to this's color space. @@ -548,7 +549,7 @@ DOM::ExceptionOr check_usability_of_image(CanvasImag [](JS::Handle const& canvas_element) -> DOM::ExceptionOr> { // If image has either a horizontal dimension or a vertical dimension equal to zero, then throw an "InvalidStateError" DOMException. if (canvas_element->width() == 0 || canvas_element->height() == 0) - return DOM::InvalidStateError::create("Canvas width or height is zero"); + return DOM::InvalidStateError::create(canvas_element->global_object(), "Canvas width or height is zero"); return Optional {}; })); if (usability.has_value()) diff --git a/Userland/Libraries/LibWeb/HTML/DOMStringMap.cpp b/Userland/Libraries/LibWeb/HTML/DOMStringMap.cpp index 8909953dcb..2db4c8512d 100644 --- a/Userland/Libraries/LibWeb/HTML/DOMStringMap.cpp +++ b/Userland/Libraries/LibWeb/HTML/DOMStringMap.cpp @@ -126,7 +126,7 @@ DOM::ExceptionOr DOMStringMap::set_value_of_new_named_property(String cons if (current_character == '-' && character_index + 1 < name.length()) { auto next_character = name[character_index + 1]; if (is_ascii_lower_alpha(next_character)) - return DOM::SyntaxError::create("Name cannot contain a '-' followed by a lowercase character."); + return DOM::SyntaxError::create(global_object(), "Name cannot contain a '-' followed by a lowercase character."); } // 2. For each ASCII upper alpha in name, insert a U+002D HYPHEN-MINUS character (-) before the character and replace the character with the same character converted to ASCII lowercase. diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp index e2660a8f02..097e16cda2 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -104,7 +104,7 @@ DOM::ExceptionOr HTMLElement::set_content_editable(String const& content_e set_attribute(HTML::AttributeNames::contenteditable, "false"); return {}; } - return DOM::SyntaxError::create("Invalid contentEditable value, must be 'true', 'false', or 'inherit'"); + return DOM::SyntaxError::create(global_object(), "Invalid contentEditable value, must be 'true', 'false', or 'inherit'"); } void HTMLElement::set_inner_text(StringView text) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOptionsCollection.cpp b/Userland/Libraries/LibWeb/HTML/HTMLOptionsCollection.cpp index dc1a8109cc..ac7add85e2 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLOptionsCollection.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLOptionsCollection.cpp @@ -40,11 +40,11 @@ DOM::ExceptionOr HTMLOptionsCollection::add(HTMLOptionOrOptGroupElement el // 1. If element is an ancestor of the select element on which the HTMLOptionsCollection is rooted, then throw a "HierarchyRequestError" DOMException. if (resolved_element->is_ancestor_of(root())) - return DOM::HierarchyRequestError::create("The provided element is an ancestor of the root select element."); + return DOM::HierarchyRequestError::create(global_object(), "The provided element is an ancestor of the root select element."); // 2. If before is an element, but that element isn't a descendant of the select element on which the HTMLOptionsCollection is rooted, then throw a "NotFoundError" DOMException. if (before_element && !before_element->is_descendant_of(root())) - return DOM::NotFoundError::create("The 'before' element is not a descendant of the root select element."); + return DOM::NotFoundError::create(global_object(), "The 'before' element is not a descendant of the root select element."); // 3. If element and before are the same element, then return. if (before_element && (resolved_element.ptr() == before_element.ptr())) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp index 8e9566e0dd..aacc49517b 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp @@ -103,7 +103,7 @@ DOM::ExceptionOr HTMLTableElement::set_t_head(HTMLTableSectionElement* the VERIFY(thead); if (thead->local_name() != TagNames::thead) - return DOM::HierarchyRequestError::create("Element is not thead"); + return DOM::HierarchyRequestError::create(global_object(), "Element is not thead"); // FIXME: The spec requires deleting the current thead if thead is null // Currently the wrapper generator doesn't send us a nullable value @@ -190,7 +190,7 @@ DOM::ExceptionOr HTMLTableElement::set_t_foot(HTMLTableSectionElement* tfo VERIFY(tfoot); if (tfoot->local_name() != TagNames::tfoot) - return DOM::HierarchyRequestError::create("Element is not tfoot"); + return DOM::HierarchyRequestError::create(global_object(), "Element is not tfoot"); // FIXME: The spec requires deleting the current tfoot if tfoot is null // Currently the wrapper generator doesn't send us a nullable value @@ -286,7 +286,7 @@ DOM::ExceptionOr> HTMLTableElement::insert auto rows_length = rows->length(); if (index < -1 || index > (long)rows_length) { - return DOM::IndexSizeError::create("Index is negative or greater than the number of rows"); + return DOM::IndexSizeError::create(global_object(), "Index is negative or greater than the number of rows"); } auto& tr = static_cast(*DOM::create_element(document(), TagNames::tr, Namespace::HTML)); if (rows_length == 0 && !has_child_of_type()) { @@ -313,7 +313,7 @@ DOM::ExceptionOr HTMLTableElement::delete_row(long index) // 1. If index is less than −1 or greater than or equal to the number of elements in the rows collection, then throw an "IndexSizeError" DOMException. if (index < -1 || index >= (long)rows_length) - return DOM::IndexSizeError::create("Index is negative or greater than or equal to the number of rows"); + return DOM::IndexSizeError::create(global_object(), "Index is negative or greater than or equal to the number of rows"); // 2. If index is −1, then remove the last element in the rows collection from its parent, or do nothing if the rows collection is empty. if (index == -1) { diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp index a4aa621237..d0f4f04d22 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp @@ -43,7 +43,7 @@ DOM::ExceptionOr> HTMLTableSectionElement: // 1. If index is less than −1 or greater than the number of elements in the rows collection, throw an "IndexSizeError" DOMException. if (index < -1 || index > rows_collection_size) - return DOM::IndexSizeError::create("Index is negative or greater than the number of rows"); + return DOM::IndexSizeError::create(global_object(), "Index is negative or greater than the number of rows"); // 2. Let table row be the result of creating an element given this element's node document, tr, and the HTML namespace. auto& table_row = static_cast(*DOM::create_element(document(), TagNames::tr, Namespace::HTML)); @@ -67,7 +67,7 @@ DOM::ExceptionOr HTMLTableSectionElement::delete_row(long index) // 1. If index is less than −1 or greater than or equal to the number of elements in the rows collection, then throw an "IndexSizeError" DOMException. if (index < -1 || index >= rows_collection_size) - return DOM::IndexSizeError::create("Index is negative or greater than or equal to the number of rows"); + return DOM::IndexSizeError::create(global_object(), "Index is negative or greater than or equal to the number of rows"); // 2. If index is −1, then remove the last element in the rows collection from this element, or do nothing if the rows collection is empty. if (index == -1) { diff --git a/Userland/Libraries/LibWeb/HTML/History.cpp b/Userland/Libraries/LibWeb/HTML/History.cpp index 4dce0e22ad..e46b713f65 100644 --- a/Userland/Libraries/LibWeb/HTML/History.cpp +++ b/Userland/Libraries/LibWeb/HTML/History.cpp @@ -50,7 +50,7 @@ DOM::ExceptionOr History::shared_history_push_replace_state(JS::Value, Str // 2. If document is not fully active, then throw a "SecurityError" DOMException. if (!m_associated_document->is_fully_active()) - return DOM::SecurityError::create("Cannot perform pushState or replaceState on a document that isn't fully active."); + return DOM::SecurityError::create(global_object(), "Cannot perform pushState or replaceState on a document that isn't fully active."); // 3. Optionally, return. (For example, the user agent might disallow calls to these methods that are invoked on a timer, // or from event listeners that are not triggered in response to a clear user action, or that are invoked in rapid succession.) diff --git a/Userland/Libraries/LibWeb/HTML/Path2D.cpp b/Userland/Libraries/LibWeb/HTML/Path2D.cpp index 69ac6e1871..54e140dbb2 100644 --- a/Userland/Libraries/LibWeb/HTML/Path2D.cpp +++ b/Userland/Libraries/LibWeb/HTML/Path2D.cpp @@ -17,6 +17,7 @@ JS::NonnullGCPtr Path2D::create_with_global_object(HTML::Window& window, // https://html.spec.whatwg.org/multipage/canvas.html#dom-path2d Path2D::Path2D(HTML::Window& window, Optional, String>> const& path) : PlatformObject(window.realm()) + , CanvasPath(static_cast(*this)) { set_prototype(&window.cached_web_prototype("Path2D")); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp index 9fad10b186..d3d1aa7022 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp @@ -109,6 +109,7 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) // 1. Clean up after running script with settings. settings.clean_up_after_running_script(); + dbgln("rethrow"); // 2. Rethrow evaluationStatus.[[Value]]. return JS::throw_completion(*evaluation_status.value()); } @@ -118,15 +119,17 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) // 1. Clean up after running script with settings. settings.clean_up_after_running_script(); + dbgln("network error"); + // 2. Throw a "NetworkError" DOMException. - return Bindings::throw_dom_exception_if_needed(vm, [] { - return DOM::NetworkError::create("Script error."); - }).release_error(); + return throw_completion(DOM::NetworkError::create(settings.global_object(), "Script error.")); } // 3. Otherwise, rethrow errors is false. Perform the following steps: VERIFY(rethrow_errors == RethrowErrors::No); + dbgln("no rethrow, stat: {}", evaluation_status.value().value().to_string_without_side_effects()); + // 1. Report the exception given by evaluationStatus.[[Value]] for script. report_exception(evaluation_status); diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index aa5c471d57..8a50160ee6 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -1067,11 +1067,8 @@ JS_DEFINE_NATIVE_FUNCTION(Window::btoa) Vector byte_string; byte_string.ensure_capacity(string.length()); for (u32 code_point : Utf8View(string)) { - if (code_point > 0xff) { - return Bindings::throw_dom_exception_if_needed(vm, [] { - return DOM::InvalidCharacterError::create("Data contains characters outside the range U+0000 and U+00FF"); - }).release_error(); - } + if (code_point > 0xff) + return throw_completion(DOM::InvalidCharacterError::create(vm.current_realm()->global_object(), "Data contains characters outside the range U+0000 and U+00FF")); byte_string.append(code_point); } diff --git a/Userland/Libraries/LibWeb/HTML/Worker.cpp b/Userland/Libraries/LibWeb/HTML/Worker.cpp index 8051bd6332..74abb3d1ea 100644 --- a/Userland/Libraries/LibWeb/HTML/Worker.cpp +++ b/Userland/Libraries/LibWeb/HTML/Worker.cpp @@ -65,7 +65,7 @@ DOM::ExceptionOr> Worker::create(FlyString const& scrip // 4. If this fails, throw a "SyntaxError" DOMException. if (!url.is_valid()) { dbgln_if(WEB_WORKER_DEBUG, "WebWorker: Invalid URL loaded '{}'.", script_url); - return DOM::SyntaxError::create("url is not valid"); + return DOM::SyntaxError::create(document.global_object(), "url is not valid"); } // 5. Let worker URL be the resulting URL record. diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp index 74280f5647..7a452bbaa5 100644 --- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp +++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -129,7 +130,7 @@ DOM::ExceptionOr WorkerGlobalScope::btoa(String const& data) const byte_string.ensure_capacity(data.length()); for (u32 code_point : Utf8View(data)) { if (code_point > 0xff) - return DOM::InvalidCharacterError::create("Data contains characters outside the range U+0000 and U+00FF"); + return DOM::InvalidCharacterError::create(global_object(), "Data contains characters outside the range U+0000 and U+00FF"); byte_string.append(code_point); } @@ -149,7 +150,7 @@ DOM::ExceptionOr WorkerGlobalScope::atob(String const& data) const // 2. If decodedData is failure, then throw an "InvalidCharacterError" DOMException. if (decoded_data.is_error()) - return DOM::InvalidCharacterError::create("Input string is not valid base64 data"); + return DOM::InvalidCharacterError::create(global_object(), "Input string is not valid base64 data"); // 3. Return decodedData. // decode_base64() returns a byte string. LibJS uses UTF-8 for strings. Use Latin1Decoder to convert bytes 128-255 to UTF-8. diff --git a/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp b/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp index e8380d7157..f17346da06 100644 --- a/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp +++ b/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp @@ -51,11 +51,11 @@ DOM::ExceptionOr> WebSocket::create_with_global_obje { AK::URL url_record(url); if (!url_record.is_valid()) - return DOM::SyntaxError::create("Invalid URL"); + return DOM::SyntaxError::create(window, "Invalid URL"); if (!url_record.protocol().is_one_of("ws", "wss")) - return DOM::SyntaxError::create("Invalid protocol"); + return DOM::SyntaxError::create(window, "Invalid protocol"); if (!url_record.fragment().is_empty()) - return DOM::SyntaxError::create("Presence of URL fragment is invalid"); + return DOM::SyntaxError::create(window, "Presence of URL fragment is invalid"); // 5. If `protocols` is a string, set `protocols` to a sequence consisting of just that string // 6. If any of the values in `protocols` occur more than once or otherwise fail to match the requirements, throw SyntaxError return JS::NonnullGCPtr(*window.heap().allocate(window.realm(), window.impl(), url_record)); @@ -137,13 +137,13 @@ DOM::ExceptionOr WebSocket::close(Optional code, Optional rea { // 1. If code is present, but is neither an integer equal to 1000 nor an integer in the range 3000 to 4999, inclusive, throw an "InvalidAccessError" DOMException. if (code.has_value() && *code != 1000 && (*code < 3000 || *code > 4099)) - return DOM::InvalidAccessError::create("The close error code is invalid"); + return DOM::InvalidAccessError::create(global_object(), "The close error code is invalid"); // 2. If reason is present, then run these substeps: if (reason.has_value()) { // 1. Let reasonBytes be the result of encoding reason. // 2. If reasonBytes is longer than 123 bytes, then throw a "SyntaxError" DOMException. if (reason->bytes().size() > 123) - return DOM::SyntaxError::create("The close reason is longer than 123 bytes"); + return DOM::SyntaxError::create(global_object(), "The close reason is longer than 123 bytes"); } // 3. Run the first matching steps from the following list: auto state = ready_state(); @@ -164,7 +164,7 @@ DOM::ExceptionOr WebSocket::send(String const& data) { auto state = ready_state(); if (state == WebSocket::ReadyState::Connecting) - return DOM::InvalidStateError::create("Websocket is still CONNECTING"); + return DOM::InvalidStateError::create(global_object(), "Websocket is still CONNECTING"); if (state == WebSocket::ReadyState::Open) { m_websocket->send(data); // TODO : If the data cannot be sent, e.g. because it would need to be buffered but the buffer is full, the user agent must flag the WebSocket as full and then close the WebSocket connection. diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp index 2f50023426..2772d7b7ce 100644 --- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp +++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp @@ -84,7 +84,7 @@ DOM::ExceptionOr XMLHttpRequest::response_text() const { // 1. If this’s response type is not the empty string or "text", then throw an "InvalidStateError" DOMException. if (m_response_type != Bindings::XMLHttpRequestResponseType::Empty && m_response_type != Bindings::XMLHttpRequestResponseType::Text) - return DOM::InvalidStateError::create("XHR responseText can only be used for responseType \"\" or \"text\""); + return DOM::InvalidStateError::create(global_object(), "XHR responseText can only be used for responseType \"\" or \"text\""); // 2. If this’s state is not loading or done, then return the empty string. if (m_ready_state != ReadyState::Loading && m_ready_state != ReadyState::Done) @@ -334,20 +334,20 @@ DOM::ExceptionOr XMLHttpRequest::set_request_header(String const& name_str // 1. If this’s state is not opened, then throw an "InvalidStateError" DOMException. if (m_ready_state != ReadyState::Opened) - return DOM::InvalidStateError::create("XHR readyState is not OPENED"); + return DOM::InvalidStateError::create(global_object(), "XHR readyState is not OPENED"); // 2. If this’s send() flag is set, then throw an "InvalidStateError" DOMException. if (m_send) - return DOM::InvalidStateError::create("XHR send() flag is already set"); + return DOM::InvalidStateError::create(global_object(), "XHR send() flag is already set"); // 3. Normalize value. value = MUST(Fetch::Infrastructure::normalize_header_value(value)); // 4. If name is not a header name or value is not a header value, then throw a "SyntaxError" DOMException. if (!Fetch::Infrastructure::is_header_name(name)) - return DOM::SyntaxError::create("Header name contains invalid characters."); + return DOM::SyntaxError::create(global_object(), "Header name contains invalid characters."); if (!Fetch::Infrastructure::is_header_value(value)) - return DOM::SyntaxError::create("Header value contains invalid characters."); + return DOM::SyntaxError::create(global_object(), "Header value contains invalid characters."); // 5. If name is a forbidden header name, then return. if (Fetch::Infrastructure::is_forbidden_header_name(name)) @@ -385,15 +385,15 @@ DOM::ExceptionOr XMLHttpRequest::open(String const& method_string, String // 2. If settingsObject has a responsible document and it is not fully active, then throw an "InvalidStateError" DOMException. if (settings_object.responsible_document() && !settings_object.responsible_document()->is_active()) - return DOM::InvalidStateError::create("Invalid state: Responsible document is not fully active."); + return DOM::InvalidStateError::create(global_object(), "Invalid state: Responsible document is not fully active."); // 3. If method is not a method, then throw a "SyntaxError" DOMException. if (!Fetch::Infrastructure::is_method(method)) - return DOM::SyntaxError::create("An invalid or illegal string was specified."); + return DOM::SyntaxError::create(global_object(), "An invalid or illegal string was specified."); // 4. If method is a forbidden method, then throw a "SecurityError" DOMException. if (Fetch::Infrastructure::is_forbidden_method(method)) - return DOM::SecurityError::create("Forbidden method, must not be 'CONNECT', 'TRACE', or 'TRACK'"); + return DOM::SecurityError::create(global_object(), "Forbidden method, must not be 'CONNECT', 'TRACE', or 'TRACK'"); // 5. Normalize method. method = MUST(Fetch::Infrastructure::normalize_method(method)); @@ -403,7 +403,7 @@ DOM::ExceptionOr XMLHttpRequest::open(String const& method_string, String // 7. If parsedURL is failure, then throw a "SyntaxError" DOMException. if (!parsed_url.is_valid()) - return DOM::SyntaxError::create("Invalid URL"); + return DOM::SyntaxError::create(global_object(), "Invalid URL"); // 8. If the async argument is omitted, set async to true, and set username and password to null. // NOTE: This is handled in the overload lacking the async argument. @@ -456,16 +456,16 @@ DOM::ExceptionOr XMLHttpRequest::open(String const& method_string, String DOM::ExceptionOr XMLHttpRequest::send(Optional body) { if (m_ready_state != ReadyState::Opened) - return DOM::InvalidStateError::create("XHR readyState is not OPENED"); + return DOM::InvalidStateError::create(global_object(), "XHR readyState is not OPENED"); if (m_send) - return DOM::InvalidStateError::create("XHR send() flag is already set"); + return DOM::InvalidStateError::create(global_object(), "XHR send() flag is already set"); // If this’s request method is `GET` or `HEAD`, then set body to null. if (m_method.is_one_of("GET"sv, "HEAD"sv)) body = {}; - auto body_with_type = body.has_value() ? TRY_OR_RETURN_OOM(extract_body(body.value())) : Optional {}; + auto body_with_type = body.has_value() ? TRY_OR_RETURN_OOM(global_object(), extract_body(body.value())) : Optional {}; AK::URL request_url = m_window->associated_document().parse_url(m_url.to_string()); dbgln("XHR send from {} to {}", m_window->associated_document().url(), request_url); @@ -487,19 +487,12 @@ DOM::ExceptionOr XMLHttpRequest::send(Optional bod auto request = LoadRequest::create_for_url_on_page(request_url, m_window->page()); request.set_method(m_method); if (body_with_type.has_value()) { - TRY_OR_RETURN_OOM(body_with_type->body.source().visit( - [&](ByteBuffer const& buffer) -> ErrorOr { + TRY_OR_RETURN_OOM(global_object(), body_with_type->body.source().visit([&](ByteBuffer const& buffer) -> ErrorOr { request.set_body(buffer); - return {}; - }, - [&](JS::Handle const& blob) -> ErrorOr { + return {}; }, [&](JS::Handle const& blob) -> ErrorOr { auto byte_buffer = TRY(ByteBuffer::copy(blob->bytes())); request.set_body(byte_buffer); - return {}; - }, - [](auto&) -> ErrorOr { - return {}; - })); + return {}; }, [](auto&) -> ErrorOr { return {}; })); if (body_with_type->type.has_value()) request.set_header("Content-Type", String { body_with_type->type->span() }); } @@ -611,7 +604,7 @@ DOM::ExceptionOr XMLHttpRequest::override_mime_type(String const& mime) { // 1. If this’s state is loading or done, then throw an "InvalidStateError" DOMException. if (m_ready_state == ReadyState::Loading || m_ready_state == ReadyState::Done) - return DOM::InvalidStateError::create("Cannot override MIME type when state is Loading or Done."); + return DOM::InvalidStateError::create(global_object(), "Cannot override MIME type when state is Loading or Done."); // 2. Set this’s override MIME type to the result of parsing mime. m_override_mime_type = MimeSniff::MimeType::from_string(mime); @@ -629,7 +622,7 @@ DOM::ExceptionOr XMLHttpRequest::set_timeout(u32 timeout) // 1. If the current global object is a Window object and this’s synchronous flag is set, // then throw an "InvalidAccessError" DOMException. if (is(HTML::current_global_object()) && m_synchronous) - return DOM::InvalidAccessError::create("Use of XMLHttpRequest's timeout attribute is not supported in the synchronous mode in window context."); + return DOM::InvalidAccessError::create(global_object(), "Use of XMLHttpRequest's timeout attribute is not supported in the synchronous mode in window context."); // 2. Set this’s timeout to the given value. m_timeout = timeout; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index b7c01b01dc..7708d8d2c2 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -31,7 +31,7 @@ libweb_js_wrapper(DOM/CustomEvent NO_INSTANCE) libweb_js_wrapper(DOM/Document NO_INSTANCE) libweb_js_wrapper(DOM/DocumentFragment NO_INSTANCE) libweb_js_wrapper(DOM/DocumentType NO_INSTANCE) -libweb_js_wrapper(DOM/DOMException) +libweb_js_wrapper(DOM/DOMException NO_INSTANCE) libweb_js_wrapper(DOM/DOMImplementation NO_INSTANCE) libweb_js_wrapper(DOM/DOMTokenList NO_INSTANCE) libweb_js_wrapper(DOM/Element NO_INSTANCE)