Browse Source

LibWeb: Add XMLHttpRequest.readyState and constants

Linus Groh 5 years ago
parent
commit
602a36970f

+ 6 - 0
Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp

@@ -39,6 +39,12 @@ XMLHttpRequestConstructor::XMLHttpRequestConstructor()
     : NativeFunction(*interpreter().global_object().function_prototype())
     : NativeFunction(*interpreter().global_object().function_prototype())
 {
 {
     put("length", JS::Value(1));
     put("length", JS::Value(1));
+
+    put("UNSENT", JS::Value((i32)XMLHttpRequest::ReadyState::Unsent));
+    put("OPENED", JS::Value((i32)XMLHttpRequest::ReadyState::Opened));
+    put("HEADERS_RECEIVED", JS::Value((i32)XMLHttpRequest::ReadyState::HeadersReceived));
+    put("LOADING", JS::Value((i32)XMLHttpRequest::ReadyState::Loading));
+    put("DONE", JS::Value((i32)XMLHttpRequest::ReadyState::Done));
 }
 }
 
 
 XMLHttpRequestConstructor::~XMLHttpRequestConstructor()
 XMLHttpRequestConstructor::~XMLHttpRequestConstructor()

+ 15 - 0
Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp

@@ -40,7 +40,14 @@ XMLHttpRequestPrototype::XMLHttpRequestPrototype()
 {
 {
     put_native_function("open", open, 2);
     put_native_function("open", open, 2);
     put_native_function("send", send, 0);
     put_native_function("send", send, 0);
+    put_native_property("readyState", ready_state_getter, nullptr);
     put_native_property("responseText", response_text_getter, nullptr);
     put_native_property("responseText", response_text_getter, nullptr);
+
+    put("UNSENT", JS::Value((i32)XMLHttpRequest::ReadyState::Unsent));
+    put("OPENED", JS::Value((i32)XMLHttpRequest::ReadyState::Opened));
+    put("HEADERS_RECEIVED", JS::Value((i32)XMLHttpRequest::ReadyState::HeadersReceived));
+    put("LOADING", JS::Value((i32)XMLHttpRequest::ReadyState::Loading));
+    put("DONE", JS::Value((i32)XMLHttpRequest::ReadyState::Done));
 }
 }
 
 
 XMLHttpRequestPrototype::~XMLHttpRequestPrototype()
 XMLHttpRequestPrototype::~XMLHttpRequestPrototype()
@@ -77,6 +84,14 @@ JS::Value XMLHttpRequestPrototype::send(JS::Interpreter& interpreter)
     return JS::js_undefined();
     return JS::js_undefined();
 }
 }
 
 
+JS::Value XMLHttpRequestPrototype::ready_state_getter(JS::Interpreter& interpreter)
+{
+    auto* impl = impl_from(interpreter);
+    if (!impl)
+        return {};
+    return JS::Value((i32)impl->ready_state());
+}
+
 JS::Value XMLHttpRequestPrototype::response_text_getter(JS::Interpreter& interpreter)
 JS::Value XMLHttpRequestPrototype::response_text_getter(JS::Interpreter& interpreter)
 {
 {
     auto* impl = impl_from(interpreter);
     auto* impl = impl_from(interpreter);

+ 1 - 0
Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.h

@@ -42,6 +42,7 @@ private:
     static JS::Value open(JS::Interpreter&);
     static JS::Value open(JS::Interpreter&);
     static JS::Value send(JS::Interpreter&);
     static JS::Value send(JS::Interpreter&);
 
 
+    static JS::Value ready_state_getter(JS::Interpreter&);
     static JS::Value response_text_getter(JS::Interpreter&);
     static JS::Value response_text_getter(JS::Interpreter&);
 };
 };
 
 

+ 11 - 0
Libraries/LibWeb/DOM/XMLHttpRequest.cpp

@@ -46,6 +46,12 @@ XMLHttpRequest::~XMLHttpRequest()
 {
 {
 }
 }
 
 
+void XMLHttpRequest::set_ready_state(ReadyState ready_state)
+{
+    // FIXME: call onreadystatechange once we have that
+    m_ready_state = ready_state;
+}
+
 String XMLHttpRequest::response_text() const
 String XMLHttpRequest::response_text() const
 {
 {
     if (m_response.is_null())
     if (m_response.is_null())
@@ -57,22 +63,27 @@ void XMLHttpRequest::open(const String& method, const String& url)
 {
 {
     m_method = method;
     m_method = method;
     m_url = url;
     m_url = url;
+    set_ready_state(ReadyState::Opened);
 }
 }
 
 
 void XMLHttpRequest::send()
 void XMLHttpRequest::send()
 {
 {
+    // FIXME: in order to properly set ReadyState::HeadersReceived and ReadyState::Loading,
+    // we need to make ResourceLoader give us more detailed updates than just "done" and "error".
     ResourceLoader::the().load(
     ResourceLoader::the().load(
         m_window->document().complete_url(m_url),
         m_window->document().complete_url(m_url),
         [weak_this = make_weak_ptr()](auto& data) {
         [weak_this = make_weak_ptr()](auto& data) {
             if (!weak_this)
             if (!weak_this)
                 return;
                 return;
             const_cast<XMLHttpRequest&>(*weak_this).m_response = data;
             const_cast<XMLHttpRequest&>(*weak_this).m_response = data;
+            const_cast<XMLHttpRequest&>(*weak_this).set_ready_state(ReadyState::Done);
             const_cast<XMLHttpRequest&>(*weak_this).dispatch_event(Event::create("load"));
             const_cast<XMLHttpRequest&>(*weak_this).dispatch_event(Event::create("load"));
         },
         },
         [weak_this = make_weak_ptr()](auto& error) {
         [weak_this = make_weak_ptr()](auto& error) {
             if (!weak_this)
             if (!weak_this)
                 return;
                 return;
             dbg() << "XHR failed to load: " << error;
             dbg() << "XHR failed to load: " << error;
+            const_cast<XMLHttpRequest&>(*weak_this).set_ready_state(ReadyState::Done);
             const_cast<XMLHttpRequest&>(*weak_this).dispatch_event(Event::create("error"));
             const_cast<XMLHttpRequest&>(*weak_this).dispatch_event(Event::create("error"));
         });
         });
 }
 }

+ 13 - 0
Libraries/LibWeb/DOM/XMLHttpRequest.h

@@ -40,6 +40,14 @@ class XMLHttpRequest final
     , public EventTarget
     , public EventTarget
     , public Bindings::Wrappable {
     , public Bindings::Wrappable {
 public:
 public:
+    enum class ReadyState {
+        Unsent,
+        Opened,
+        HeadersReceived,
+        Loading,
+        Done,
+    };
+
     using WrapperType = Bindings::XMLHttpRequestWrapper;
     using WrapperType = Bindings::XMLHttpRequestWrapper;
 
 
     static NonnullRefPtr<XMLHttpRequest> create(Window& window) { return adopt(*new XMLHttpRequest(window)); }
     static NonnullRefPtr<XMLHttpRequest> create(Window& window) { return adopt(*new XMLHttpRequest(window)); }
@@ -49,6 +57,7 @@ public:
     using RefCounted::ref;
     using RefCounted::ref;
     using RefCounted::unref;
     using RefCounted::unref;
 
 
+    ReadyState ready_state() const { return m_ready_state; };
     String response_text() const;
     String response_text() const;
     void open(const String& method, const String& url);
     void open(const String& method, const String& url);
     void send();
     void send();
@@ -58,10 +67,14 @@ private:
     virtual void unref_event_target() override { unref(); }
     virtual void unref_event_target() override { unref(); }
     virtual void dispatch_event(NonnullRefPtr<Event>) override;
     virtual void dispatch_event(NonnullRefPtr<Event>) override;
 
 
+    void set_ready_state(ReadyState);
+
     explicit XMLHttpRequest(Window&);
     explicit XMLHttpRequest(Window&);
 
 
     NonnullRefPtr<Window> m_window;
     NonnullRefPtr<Window> m_window;
 
 
+    ReadyState m_ready_state { ReadyState::Unsent };
+
     String m_method;
     String m_method;
     String m_url;
     String m_url;