Преглед изворни кода

LibWeb/HTML: Make Window::m{location,navigator} lazily allocated

This now matches the other window-owned objects, which already do this:
m_crypto, m_performance, m_screen.
Linus Groh пре 2 година
родитељ
комит
4da68384e6

+ 2 - 2
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -1673,7 +1673,7 @@ bool Document::is_active() const
 }
 }
 
 
 // https://html.spec.whatwg.org/multipage/history.html#dom-document-location
 // https://html.spec.whatwg.org/multipage/history.html#dom-document-location
-HTML::Location* Document::location()
+WebIDL::ExceptionOr<JS::GCPtr<HTML::Location>> Document::location()
 {
 {
     // The Document object's location attribute's getter must return this Document object's relevant global object's Location object,
     // The Document object's location attribute's getter must return this Document object's relevant global object's Location object,
     // if this Document object is fully active, and null otherwise.
     // if this Document object is fully active, and null otherwise.
@@ -1681,7 +1681,7 @@ HTML::Location* Document::location()
     if (!is_fully_active())
     if (!is_fully_active())
         return nullptr;
         return nullptr;
 
 
-    return window().location();
+    return TRY(window().location());
 }
 }
 
 
 // https://html.spec.whatwg.org/multipage/interaction.html#dom-document-hidden
 // https://html.spec.whatwg.org/multipage/interaction.html#dom-document-hidden

+ 1 - 1
Userland/Libraries/LibWeb/DOM/Document.h

@@ -343,7 +343,7 @@ public:
     JS::NonnullGCPtr<HTML::History> history();
     JS::NonnullGCPtr<HTML::History> history();
     JS::NonnullGCPtr<HTML::History> history() const;
     JS::NonnullGCPtr<HTML::History> history() const;
 
 
-    HTML::Location* location();
+    WebIDL::ExceptionOr<JS::GCPtr<HTML::Location>> location();
 
 
     size_t number_of_things_delaying_the_load_event() { return m_number_of_things_delaying_the_load_event; }
     size_t number_of_things_delaying_the_load_event() { return m_number_of_things_delaying_the_load_event; }
     void increment_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>);
     void increment_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>);

+ 17 - 9
Userland/Libraries/LibWeb/HTML/Window.cpp

@@ -858,9 +858,6 @@ WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironm
 
 
     Object::set_prototype(&Bindings::ensure_web_prototype<Bindings::WindowPrototype>(realm, "Window"));
     Object::set_prototype(&Bindings::ensure_web_prototype<Bindings::WindowPrototype>(realm, "Window"));
 
 
-    m_location = MUST_OR_THROW_OOM(heap().allocate<Location>(realm, realm));
-    m_navigator = MUST_OR_THROW_OOM(heap().allocate<Navigator>(realm, realm));
-
     MUST_OR_THROW_OOM(Bindings::WindowGlobalMixin::initialize(realm, *this));
     MUST_OR_THROW_OOM(Bindings::WindowGlobalMixin::initialize(realm, *this));
 
 
     // FIXME: These should be native accessors, not properties
     // FIXME: These should be native accessors, not properties
@@ -959,10 +956,14 @@ void Window::set_name(String const& name)
 }
 }
 
 
 // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-location
 // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-location
-JS::NonnullGCPtr<Location> Window::location() const
+WebIDL::ExceptionOr<JS::NonnullGCPtr<Location>> Window::location()
 {
 {
+    auto& realm = this->realm();
+
     // The Window object's location getter steps are to return this's Location object.
     // The Window object's location getter steps are to return this's Location object.
-    return *m_location;
+    if (!m_location)
+        m_location = MUST_OR_THROW_OOM(heap().allocate<Location>(realm, realm));
+    return JS::NonnullGCPtr { *m_location };
 }
 }
 
 
 // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-history
 // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-history
@@ -1068,10 +1069,14 @@ WebIDL::ExceptionOr<JS::GCPtr<HTML::WindowProxy>> Window::open(Optional<String>
 }
 }
 
 
 // https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator
 // https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator
-JS::NonnullGCPtr<Navigator> Window::navigator() const
+WebIDL::ExceptionOr<JS::NonnullGCPtr<Navigator>> Window::navigator()
 {
 {
+    auto& realm = this->realm();
+
     // The navigator and clientInformation getter steps are to return this's associated Navigator.
     // The navigator and clientInformation getter steps are to return this's associated Navigator.
-    return *m_navigator;
+    if (!m_navigator)
+        m_navigator = MUST_OR_THROW_OOM(heap().allocate<Navigator>(realm, realm));
+    return JS::NonnullGCPtr { *m_navigator };
 }
 }
 
 
 // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-alert
 // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-alert
@@ -1470,8 +1475,10 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<HighResolutionTime::Performance>> Window::p
 // https://w3c.github.io/webcrypto/#dom-windoworworkerglobalscope-crypto
 // https://w3c.github.io/webcrypto/#dom-windoworworkerglobalscope-crypto
 WebIDL::ExceptionOr<JS::NonnullGCPtr<Crypto::Crypto>> Window::crypto()
 WebIDL::ExceptionOr<JS::NonnullGCPtr<Crypto::Crypto>> Window::crypto()
 {
 {
+    auto& realm = this->realm();
+
     if (!m_crypto)
     if (!m_crypto)
-        m_crypto = MUST_OR_THROW_OOM(heap().allocate<Crypto::Crypto>(realm(), realm()));
+        m_crypto = MUST_OR_THROW_OOM(heap().allocate<Crypto::Crypto>(realm, realm));
     return JS::NonnullGCPtr { *m_crypto };
     return JS::NonnullGCPtr { *m_crypto };
 }
 }
 
 
@@ -1567,7 +1574,8 @@ size_t Window::document_tree_child_browsing_context_count() const
 JS_DEFINE_NATIVE_FUNCTION(Window::location_setter)
 JS_DEFINE_NATIVE_FUNCTION(Window::location_setter)
 {
 {
     auto* impl = TRY(impl_from(vm));
     auto* impl = TRY(impl_from(vm));
-    TRY(impl->m_location->set(JS::PropertyKey("href"), vm.argument(0), JS::Object::ShouldThrowExceptions::Yes));
+    auto location = TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return impl->location(); }));
+    TRY(location->set(JS::PropertyKey("href"), vm.argument(0), JS::Object::ShouldThrowExceptions::Yes));
     return JS::js_undefined();
     return JS::js_undefined();
 }
 }
 
 

+ 2 - 2
Userland/Libraries/LibWeb/HTML/Window.h

@@ -139,7 +139,7 @@ public:
     JS::NonnullGCPtr<DOM::Document const> document() const;
     JS::NonnullGCPtr<DOM::Document const> document() const;
     String name() const;
     String name() const;
     void set_name(String const&);
     void set_name(String const&);
-    JS::NonnullGCPtr<Location> location() const;
+    WebIDL::ExceptionOr<JS::NonnullGCPtr<Location>> location();
     JS::NonnullGCPtr<History> history() const;
     JS::NonnullGCPtr<History> history() const;
     void focus();
     void focus();
 
 
@@ -150,7 +150,7 @@ public:
     JS::GCPtr<DOM::Element const> frame_element() const;
     JS::GCPtr<DOM::Element const> frame_element() const;
     WebIDL::ExceptionOr<JS::GCPtr<HTML::WindowProxy>> open(Optional<String> const& url, Optional<String> const& target, Optional<String> const& features);
     WebIDL::ExceptionOr<JS::GCPtr<HTML::WindowProxy>> open(Optional<String> const& url, Optional<String> const& target, Optional<String> const& features);
 
 
-    JS::NonnullGCPtr<Navigator> navigator() const;
+    WebIDL::ExceptionOr<JS::NonnullGCPtr<Navigator>> navigator();
 
 
     void alert(String const& message = {});
     void alert(String const& message = {});
     bool confirm(Optional<String> const& message);
     bool confirm(Optional<String> const& message);