diff options
author | Andreas Kling <kling@serenityos.org> | 2020-04-08 21:11:51 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-08 21:46:43 +0200 |
commit | 4ffac713b961e3e96f271877ae4d65f6d2d48680 (patch) | |
tree | 4769f98db2fa1d90107efe44135d30b3120400b0 /Libraries/LibWeb | |
parent | b3c62d0bc86c01846ff67ba3f1d667334153b376 (diff) | |
download | serenity-4ffac713b961e3e96f271877ae4d65f6d2d48680.zip |
LibWeb: Add XMLHttpRequest object :^)
This patch adds very basic XMLHttpRequest support to LibWeb. Here's an
example that currently works:
var callback = function() { alert(this.responseText); }
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", callback);
xhr.open("GET", "http://serenityos.org/~kling/test/example.txt");
xhr.send();
There are many limitations and bugs, but it's pretty dang awesome that
we have XHR. :^)
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r-- | Libraries/LibWeb/Bindings/WindowObject.cpp | 14 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/WindowObject.h | 9 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp | 57 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.h | 48 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp | 87 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.h | 49 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.cpp | 65 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.h | 49 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/XMLHttpRequest.cpp | 89 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/XMLHttpRequest.h | 69 | ||||
-rw-r--r-- | Libraries/LibWeb/Forward.h | 5 | ||||
-rw-r--r-- | Libraries/LibWeb/Makefile | 4 |
12 files changed, 543 insertions, 2 deletions
diff --git a/Libraries/LibWeb/Bindings/WindowObject.cpp b/Libraries/LibWeb/Bindings/WindowObject.cpp index aab2489376..bc47d02bf6 100644 --- a/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -32,6 +32,8 @@ #include <LibWeb/Bindings/DocumentWrapper.h> #include <LibWeb/Bindings/NavigatorObject.h> #include <LibWeb/Bindings/WindowObject.h> +#include <LibWeb/Bindings/XMLHttpRequestConstructor.h> +#include <LibWeb/Bindings/XMLHttpRequestPrototype.h> #include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Window.h> @@ -50,12 +52,24 @@ WindowObject::WindowObject(Window& impl) put_native_function("cancelAnimationFrame", cancel_animation_frame, 1); put("navigator", heap().allocate<NavigatorObject>()); + + m_xhr_prototype = heap().allocate<XMLHttpRequestPrototype>(); + m_xhr_constructor = heap().allocate<XMLHttpRequestConstructor>(); + m_xhr_constructor->put("prototype", m_xhr_prototype); + put("XMLHttpRequest", m_xhr_constructor); } WindowObject::~WindowObject() { } +void WindowObject::visit_children(Visitor& visitor) +{ + GlobalObject::visit_children(visitor); + visitor.visit(m_xhr_constructor); + visitor.visit(m_xhr_prototype); +} + static Window* impl_from(JS::Interpreter& interpreter) { auto* this_object = interpreter.this_value().to_object(interpreter.heap()); diff --git a/Libraries/LibWeb/Bindings/WindowObject.h b/Libraries/LibWeb/Bindings/WindowObject.h index 9f9f4e3256..c3605ae7c9 100644 --- a/Libraries/LibWeb/Bindings/WindowObject.h +++ b/Libraries/LibWeb/Bindings/WindowObject.h @@ -32,7 +32,7 @@ namespace Web { namespace Bindings { -class WindowObject : public JS::GlobalObject { +class WindowObject final : public JS::GlobalObject { public: explicit WindowObject(Window&); virtual ~WindowObject() override; @@ -40,8 +40,12 @@ public: Window& impl() { return *m_impl; } const Window& impl() const { return *m_impl; } + XMLHttpRequestPrototype* xhr_prototype() { return m_xhr_prototype; } + XMLHttpRequestConstructor* xhr_constructor() { return m_xhr_constructor; } + private: virtual const char* class_name() const override { return "WindowObject"; } + virtual void visit_children(Visitor&) override; static JS::Value document_getter(JS::Interpreter&); static void document_setter(JS::Interpreter&, JS::Value); @@ -53,6 +57,9 @@ private: static JS::Value cancel_animation_frame(JS::Interpreter&); NonnullRefPtr<Window> m_impl; + + XMLHttpRequestConstructor* m_xhr_constructor { nullptr }; + XMLHttpRequestPrototype* m_xhr_prototype { nullptr }; }; } diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp b/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp new file mode 100644 index 0000000000..e4d7b9238b --- /dev/null +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibJS/Heap/Heap.h> +#include <LibJS/Interpreter.h> +#include <LibWeb/Bindings/WindowObject.h> +#include <LibWeb/Bindings/XMLHttpRequestConstructor.h> +#include <LibWeb/Bindings/XMLHttpRequestWrapper.h> +#include <LibWeb/DOM/XMLHttpRequest.h> + +namespace Web { +namespace Bindings { + +XMLHttpRequestConstructor::XMLHttpRequestConstructor() +{ + put("length", JS::Value(1)); +} + +XMLHttpRequestConstructor::~XMLHttpRequestConstructor() +{ +} + +JS::Value XMLHttpRequestConstructor::call(JS::Interpreter& interpreter) +{ + return construct(interpreter); +} + +JS::Value XMLHttpRequestConstructor::construct(JS::Interpreter& interpreter) +{ + return interpreter.heap().allocate<XMLHttpRequestWrapper>(XMLHttpRequest::create()); +} + +} +} diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.h b/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.h new file mode 100644 index 0000000000..a0089b9049 --- /dev/null +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestConstructor.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibJS/Runtime/NativeFunction.h> + +namespace Web { +namespace Bindings { + +class XMLHttpRequestConstructor final : public JS::NativeFunction { +public: + XMLHttpRequestConstructor(); + virtual ~XMLHttpRequestConstructor() override; + + virtual JS::Value call(JS::Interpreter&) override; + virtual JS::Value construct(JS::Interpreter&) override; + +private: + virtual bool has_constructor() const override { return true; } + virtual const char* class_name() const override { return "XMLHttpRequestConstructor"; } +}; + +} +} diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp b/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp new file mode 100644 index 0000000000..58d4ce9ac0 --- /dev/null +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/Function.h> +#include <LibJS/Interpreter.h> +#include <LibJS/Runtime/Error.h> +#include <LibWeb/Bindings/XMLHttpRequestPrototype.h> +#include <LibWeb/Bindings/XMLHttpRequestWrapper.h> +#include <LibWeb/DOM/XMLHttpRequest.h> + +namespace Web { +namespace Bindings { + +XMLHttpRequestPrototype::XMLHttpRequestPrototype() +{ + put_native_function("open", open, 2); + put_native_function("send", send, 0); + put_native_property("responseText", response_text_getter, nullptr); +} + +XMLHttpRequestPrototype::~XMLHttpRequestPrototype() +{ +} + +static XMLHttpRequest* impl_from(JS::Interpreter& interpreter) +{ + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return nullptr; + if (StringView("XMLHttpRequestWrapper") != this_object->class_name()) { + interpreter.throw_exception<JS::Error>("TypeError", "This is not an XMLHttpRequest object"); + return nullptr; + } + return &static_cast<XMLHttpRequestWrapper*>(this_object)->impl(); +} + +JS::Value XMLHttpRequestPrototype::open(JS::Interpreter& interpreter) +{ + auto* impl = impl_from(interpreter); + if (!impl) + return {}; + impl->open(interpreter.argument(0).to_string(), interpreter.argument(1).to_string()); + return JS::js_undefined(); +} + +JS::Value XMLHttpRequestPrototype::send(JS::Interpreter& interpreter) +{ + auto* impl = impl_from(interpreter); + if (!impl) + return {}; + impl->send(); + return JS::js_undefined(); +} + +JS::Value XMLHttpRequestPrototype::response_text_getter(JS::Interpreter& interpreter) +{ + auto* impl = impl_from(interpreter); + if (!impl) + return {}; + return JS::js_string(interpreter, impl->response_text()); +} + +} +} diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.h b/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.h new file mode 100644 index 0000000000..3f76025054 --- /dev/null +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestPrototype.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibJS/Runtime/Object.h> + +namespace Web { +namespace Bindings { + +class XMLHttpRequestPrototype final : public JS::Object { +public: + XMLHttpRequestPrototype(); + virtual ~XMLHttpRequestPrototype() override; + +private: + virtual const char* class_name() const override { return "XMLHttpRequestPrototype"; } + + static JS::Value open(JS::Interpreter&); + static JS::Value send(JS::Interpreter&); + + static JS::Value response_text_getter(JS::Interpreter&); +}; + +} +} diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.cpp b/Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.cpp new file mode 100644 index 0000000000..cfc3f9ebaa --- /dev/null +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/FlyString.h> +#include <LibJS/Interpreter.h> +#include <LibJS/Runtime/GlobalObject.h> +#include <LibJS/Runtime/Value.h> +#include <LibWeb/Bindings/WindowObject.h> +#include <LibWeb/Bindings/XMLHttpRequestPrototype.h> +#include <LibWeb/Bindings/XMLHttpRequestWrapper.h> +#include <LibWeb/DOM/XMLHttpRequest.h> + +namespace Web { +namespace Bindings { + +XMLHttpRequestWrapper* wrap(JS::Heap& heap, XMLHttpRequest& impl) +{ + return static_cast<XMLHttpRequestWrapper*>(wrap_impl(heap, impl)); +} + +XMLHttpRequestWrapper::XMLHttpRequestWrapper(XMLHttpRequest& impl) + : EventTargetWrapper(impl) +{ + set_prototype(static_cast<WindowObject&>(interpreter().global_object()).xhr_prototype()); +} + +XMLHttpRequestWrapper::~XMLHttpRequestWrapper() +{ +} + +XMLHttpRequest& XMLHttpRequestWrapper::impl() +{ + return static_cast<XMLHttpRequest&>(EventTargetWrapper::impl()); +} + +const XMLHttpRequest& XMLHttpRequestWrapper::impl() const +{ + return static_cast<const XMLHttpRequest&>(EventTargetWrapper::impl()); +} + +} +} diff --git a/Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.h b/Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.h new file mode 100644 index 0000000000..fe1a6f0bd3 --- /dev/null +++ b/Libraries/LibWeb/Bindings/XMLHttpRequestWrapper.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/Bindings/EventTargetWrapper.h> + +namespace Web { +namespace Bindings { + +class XMLHttpRequestWrapper final : public EventTargetWrapper { +public: + explicit XMLHttpRequestWrapper(XMLHttpRequest&); + virtual ~XMLHttpRequestWrapper() override; + + XMLHttpRequest& impl(); + const XMLHttpRequest& impl() const; + +private: + virtual const char* class_name() const override { return "XMLHttpRequestWrapper"; } +}; + +XMLHttpRequestWrapper* wrap(JS::Heap&, XMLHttpRequest&); + +} +} diff --git a/Libraries/LibWeb/DOM/XMLHttpRequest.cpp b/Libraries/LibWeb/DOM/XMLHttpRequest.cpp new file mode 100644 index 0000000000..d28ad8935d --- /dev/null +++ b/Libraries/LibWeb/DOM/XMLHttpRequest.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibJS/Interpreter.h> +#include <LibJS/Runtime/Function.h> +#include <LibWeb/Bindings/EventWrapper.h> +#include <LibWeb/Bindings/XMLHttpRequestWrapper.h> +#include <LibWeb/DOM/Event.h> +#include <LibWeb/DOM/EventListener.h> +#include <LibWeb/DOM/XMLHttpRequest.h> +#include <LibWeb/ResourceLoader.h> + +namespace Web { + +XMLHttpRequest::XMLHttpRequest() +{ +} + +XMLHttpRequest::~XMLHttpRequest() +{ +} + +String XMLHttpRequest::response_text() const +{ + if (m_response.is_null()) + return {}; + return String::copy(m_response); +} + +void XMLHttpRequest::open(const String& method, const String& url) +{ + m_method = method; + m_url = url; +} + +void XMLHttpRequest::send() +{ + ResourceLoader::the().load( + URL(m_url), + [weak_this = make_weak_ptr()](auto& data) { + if (!weak_this) + return; + const_cast<XMLHttpRequest&>(*weak_this).m_response = data; + const_cast<XMLHttpRequest&>(*weak_this).dispatch_event(Event::create("load")); + }, + [weak_this = make_weak_ptr()](auto& error) { + if (!weak_this) + return; + dbg() << "XHR failed to load: " << error; + const_cast<XMLHttpRequest&>(*weak_this).dispatch_event(Event::create("error")); + }); +} + +void XMLHttpRequest::dispatch_event(NonnullRefPtr<Event> event) +{ + for (auto& listener : listeners()) { + if (listener.event_name == event->name()) { + auto* function = const_cast<EventListener&>(*listener.listener).function(); + auto* this_value = wrap(function->heap(), *this); + auto* event_wrapper = wrap(function->heap(), *event); + function->interpreter().call(function, this_value, { event_wrapper }); + } + } +} + +} diff --git a/Libraries/LibWeb/DOM/XMLHttpRequest.h b/Libraries/LibWeb/DOM/XMLHttpRequest.h new file mode 100644 index 0000000000..f2924977aa --- /dev/null +++ b/Libraries/LibWeb/DOM/XMLHttpRequest.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/ByteBuffer.h> +#include <AK/RefCounted.h> +#include <AK/Weakable.h> +#include <LibWeb/Bindings/Wrappable.h> +#include <LibWeb/DOM/EventTarget.h> + +namespace Web { + +class XMLHttpRequest final + : public RefCounted<XMLHttpRequest> + , public Weakable<XMLHttpRequest> + , public EventTarget + , public Bindings::Wrappable { +public: + using WrapperType = Bindings::XMLHttpRequestWrapper; + + static NonnullRefPtr<XMLHttpRequest> create() { return adopt(*new XMLHttpRequest); } + + virtual ~XMLHttpRequest() override; + + using RefCounted::ref; + using RefCounted::unref; + + String response_text() const; + void open(const String& method, const String& url); + void send(); + +private: + virtual void ref_event_target() override { ref(); } + virtual void unref_event_target() override { unref(); } + virtual void dispatch_event(NonnullRefPtr<Event>) override; + + XMLHttpRequest(); + + String m_method; + String m_url; + + ByteBuffer m_response; +}; + +} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 8322c32b85..6c82e1f345 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -51,6 +51,7 @@ class StyleResolver; class StyleRule; class StyleSheet; class Window; +class XMLHttpRequest; namespace Bindings { @@ -66,8 +67,10 @@ class NodeWrapper; class WindowObject; class Wrappable; class Wrapper; +class XMLHttpRequestConstructor; +class XMLHttpRequestPrototype; +class XMLHttpRequestWrapper; } - } diff --git a/Libraries/LibWeb/Makefile b/Libraries/LibWeb/Makefile index 700452655c..13d7a6c8ea 100644 --- a/Libraries/LibWeb/Makefile +++ b/Libraries/LibWeb/Makefile @@ -11,6 +11,9 @@ LIBWEB_OBJS = \ Bindings/NodeWrapper.o \ Bindings/WindowObject.o \ Bindings/Wrappable.o \ + Bindings/XMLHttpRequestConstructor.o \ + Bindings/XMLHttpRequestPrototype.o \ + Bindings/XMLHttpRequestWrapper.o \ CSS/DefaultStyleSheetSource.o \ CSS/PropertyID.o \ CSS/Selector.o \ @@ -54,6 +57,7 @@ LIBWEB_OBJS = \ DOM/ParentNode.o \ DOM/Text.o \ DOM/Window.o \ + DOM/XMLHttpRequest.o \ StylePropertiesModel.o \ DOMTreeModel.o \ Dump.o \ |