Serenity Operating System
at master 139 lines 6.1 kB view raw
1/* 2 * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/DeprecatedFlyString.h> 10#include <AK/Diagnostics.h> 11#include <LibJS/Runtime/VM.h> 12#include <LibWeb/Bindings/PlatformObject.h> 13#include <LibWeb/HTML/Scripting/Environments.h> 14 15namespace Web::WebIDL { 16 17// The following have a legacy code value but *don't* produce it as 18// DOMException.code value when used as name (and are therefore omitted here): 19// - DOMStringSizeError (DOMSTRING_SIZE_ERR = 2) 20// - NoDataAllowedError (NO_DATA_ALLOWED_ERR = 6) 21// - ValidationError (VALIDATION_ERR = 16) 22#define ENUMERATE_DOM_EXCEPTION_LEGACY_CODES \ 23 __ENUMERATE(IndexSizeError, 1) \ 24 __ENUMERATE(HierarchyRequestError, 3) \ 25 __ENUMERATE(WrongDocumentError, 4) \ 26 __ENUMERATE(InvalidCharacterError, 5) \ 27 __ENUMERATE(NoModificationAllowedError, 7) \ 28 __ENUMERATE(NotFoundError, 8) \ 29 __ENUMERATE(NotSupportedError, 9) \ 30 __ENUMERATE(InUseAttributeError, 10) \ 31 __ENUMERATE(InvalidStateError, 11) \ 32 __ENUMERATE(SyntaxError, 12) \ 33 __ENUMERATE(InvalidModificationError, 13) \ 34 __ENUMERATE(NamespaceError, 14) \ 35 __ENUMERATE(InvalidAccessError, 15) \ 36 __ENUMERATE(TypeMismatchError, 17) \ 37 __ENUMERATE(SecurityError, 18) \ 38 __ENUMERATE(NetworkError, 19) \ 39 __ENUMERATE(AbortError, 20) \ 40 __ENUMERATE(URLMismatchError, 21) \ 41 __ENUMERATE(QuotaExceededError, 22) \ 42 __ENUMERATE(TimeoutError, 23) \ 43 __ENUMERATE(InvalidNodeTypeError, 24) \ 44 __ENUMERATE(DataCloneError, 25) 45 46// https://webidl.spec.whatwg.org/#idl-DOMException-error-names 47// Same order as in the spec document, also matches the legacy codes order above. 48#define ENUMERATE_DOM_EXCEPTION_ERROR_NAMES \ 49 __ENUMERATE(IndexSizeError) /* Deprecated */ \ 50 __ENUMERATE(HierarchyRequestError) \ 51 __ENUMERATE(WrongDocumentError) \ 52 __ENUMERATE(InvalidCharacterError) \ 53 __ENUMERATE(NoModificationAllowedError) \ 54 __ENUMERATE(NotFoundError) \ 55 __ENUMERATE(NotSupportedError) \ 56 __ENUMERATE(InUseAttributeError) \ 57 __ENUMERATE(InvalidStateError) \ 58 __ENUMERATE(SyntaxError) \ 59 __ENUMERATE(InvalidModificationError) \ 60 __ENUMERATE(NamespaceError) \ 61 __ENUMERATE(InvalidAccessError) /* Deprecated */ \ 62 __ENUMERATE(TypeMismatchError) /* Deprecated */ \ 63 __ENUMERATE(SecurityError) \ 64 __ENUMERATE(NetworkError) \ 65 __ENUMERATE(AbortError) \ 66 __ENUMERATE(URLMismatchError) \ 67 __ENUMERATE(QuotaExceededError) \ 68 __ENUMERATE(TimeoutError) \ 69 __ENUMERATE(InvalidNodeTypeError) \ 70 __ENUMERATE(DataCloneError) \ 71 __ENUMERATE(EncodingError) \ 72 __ENUMERATE(NotReadableError) \ 73 __ENUMERATE(UnknownError) \ 74 __ENUMERATE(ConstraintError) \ 75 __ENUMERATE(DataError) \ 76 __ENUMERATE(TransactionInactiveError) \ 77 __ENUMERATE(ReadOnlyError) \ 78 __ENUMERATE(VersionError) \ 79 __ENUMERATE(OperationError) \ 80 __ENUMERATE(NotAllowedError) 81 82static u16 get_legacy_code_for_name(DeprecatedFlyString const& name) 83{ 84#define __ENUMERATE(ErrorName, code) \ 85 if (name == #ErrorName) \ 86 return code; 87 ENUMERATE_DOM_EXCEPTION_LEGACY_CODES 88#undef __ENUMERATE 89 return 0; 90} 91 92// https://webidl.spec.whatwg.org/#idl-DOMException 93class DOMException final : public Bindings::PlatformObject { 94 WEB_PLATFORM_OBJECT(DOMException, Bindings::PlatformObject); 95 96public: 97 static JS::NonnullGCPtr<DOMException> create(JS::Realm& realm, DeprecatedFlyString const& name, DeprecatedFlyString const& message); 98 99 // JS constructor has message first, name second 100 // FIXME: This is a completely pointless footgun, let's use the same order for both factories. 101 static JS::NonnullGCPtr<DOMException> construct_impl(JS::Realm& realm, DeprecatedFlyString const& message, DeprecatedFlyString const& name); 102 103 virtual ~DOMException() override; 104 105 DeprecatedFlyString const& name() const { return m_name; } 106 DeprecatedFlyString const& message() const { return m_message; } 107 u16 code() const { return get_legacy_code_for_name(m_name); } 108 109protected: 110 DOMException(JS::Realm&, DeprecatedFlyString const& name, DeprecatedFlyString const& message); 111 112 virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; 113 114private: 115 DeprecatedFlyString m_name; 116 DeprecatedFlyString m_message; 117}; 118 119#define __ENUMERATE(ErrorName) \ 120 class ErrorName final { \ 121 public: \ 122 static JS::NonnullGCPtr<DOMException> create(JS::Realm& realm, DeprecatedFlyString const& message) \ 123 { \ 124 return DOMException::create(realm, #ErrorName, message); \ 125 } \ 126 }; 127ENUMERATE_DOM_EXCEPTION_ERROR_NAMES 128#undef __ENUMERATE 129 130} 131 132namespace Web { 133 134inline JS::Completion throw_completion(JS::NonnullGCPtr<WebIDL::DOMException> exception) 135{ 136 return JS::throw_completion(JS::Value(static_cast<JS::Object*>(exception.ptr()))); 137} 138 139}