summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb
diff options
context:
space:
mode:
authorLuke <luke.wilde@live.co.uk>2020-11-21 21:53:18 +0000
committerAndreas Kling <kling@serenityos.org>2020-11-22 18:20:56 +0100
commit773df8826dddeb4fced0af6377233d79fc5ad74c (patch)
tree67ad5f80cd2024ff0ef57ad542ff5a2080c7c6eb /Libraries/LibWeb
parent99502708087031172bca0e0dc423b28d82517ea8 (diff)
downloadserenity-773df8826dddeb4fced0af6377233d79fc5ad74c.zip
LibWeb: Add the submit event to HTMLFormElement
Also adds the ability to submit from JavaScript.
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r--Libraries/LibWeb/CMakeLists.txt1
-rw-r--r--Libraries/LibWeb/Forward.h1
-rw-r--r--Libraries/LibWeb/HTML/HTMLElement.cpp7
-rw-r--r--Libraries/LibWeb/HTML/HTMLElement.h2
-rw-r--r--Libraries/LibWeb/HTML/HTMLFormElement.cpp41
-rw-r--r--Libraries/LibWeb/HTML/HTMLFormElement.h8
-rw-r--r--Libraries/LibWeb/HTML/HTMLFormElement.idl2
-rw-r--r--Libraries/LibWeb/HTML/HTMLInputElement.cpp3
-rw-r--r--Libraries/LibWeb/HTML/SubmitEvent.h54
-rw-r--r--Libraries/LibWeb/HTML/SubmitEvent.idl5
10 files changed, 120 insertions, 4 deletions
diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt
index d552e8b04f..5d0ee2b27e 100644
--- a/Libraries/LibWeb/CMakeLists.txt
+++ b/Libraries/LibWeb/CMakeLists.txt
@@ -318,6 +318,7 @@ libweb_js_wrapper(HTML/HTMLUListElement)
libweb_js_wrapper(HTML/HTMLUnknownElement)
libweb_js_wrapper(HTML/HTMLVideoElement)
libweb_js_wrapper(HTML/ImageData)
+libweb_js_wrapper(HTML/SubmitEvent)
libweb_js_wrapper(HighResolutionTime/Performance)
libweb_js_wrapper(SVG/SVGElement)
libweb_js_wrapper(SVG/SVGGeometryElement)
diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h
index 741752a4d0..3b0c20d156 100644
--- a/Libraries/LibWeb/Forward.h
+++ b/Libraries/LibWeb/Forward.h
@@ -270,6 +270,7 @@ class MouseEventWrapper;
class NodeWrapper;
class PerformanceWrapper;
class ScriptExecutionContext;
+class SubmitEventWrapper;
class SVGElementWrapper;
class SVGGeometryElementWrapper;
class SVGGraphicsElementWrapper;
diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp
index bb364a19a3..3ed31c7211 100644
--- a/Libraries/LibWeb/HTML/HTMLElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLElement.cpp
@@ -26,6 +26,7 @@
#include <AK/StringBuilder.h>
#include <LibWeb/DOM/Document.h>
+#include <LibWeb/HTML/HTMLAnchorElement.h>
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/Layout/TextNode.h>
@@ -131,4 +132,10 @@ String HTMLElement::inner_text()
return builder.to_string();
}
+bool HTMLElement::cannot_navigate() const
+{
+ // FIXME: Return true if element's node document is not fully active
+ return !is<HTML::HTMLAnchorElement>(this) && !is_connected();
+}
+
}
diff --git a/Libraries/LibWeb/HTML/HTMLElement.h b/Libraries/LibWeb/HTML/HTMLElement.h
index 9e0e38a467..7d1dd4fd10 100644
--- a/Libraries/LibWeb/HTML/HTMLElement.h
+++ b/Libraries/LibWeb/HTML/HTMLElement.h
@@ -46,6 +46,8 @@ public:
String inner_text();
void set_inner_text(StringView);
+ bool cannot_navigate() const;
+
private:
virtual bool is_html_element() const final { return true; }
diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Libraries/LibWeb/HTML/HTMLFormElement.cpp
index b709538cff..b05ebdce0f 100644
--- a/Libraries/LibWeb/HTML/HTMLFormElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLFormElement.cpp
@@ -25,8 +25,10 @@
*/
#include <AK/StringBuilder.h>
+#include <LibWeb/HTML/EventNames.h>
#include <LibWeb/HTML/HTMLFormElement.h>
#include <LibWeb/HTML/HTMLInputElement.h>
+#include <LibWeb/HTML/SubmitEvent.h>
#include <LibWeb/InProcessWebView.h>
#include <LibWeb/Page/Frame.h>
#include <LibWeb/URLEncoder.h>
@@ -42,8 +44,11 @@ HTMLFormElement::~HTMLFormElement()
{
}
-void HTMLFormElement::submit(RefPtr<HTMLInputElement> submitter)
+void HTMLFormElement::submit_form(RefPtr<HTMLElement> submitter, bool from_submit_binding)
{
+ if (cannot_navigate())
+ return;
+
if (action().is_null()) {
dbg() << "Unsupported form action ''";
return;
@@ -60,6 +65,35 @@ void HTMLFormElement::submit(RefPtr<HTMLInputElement> submitter)
effective_method = "get";
}
+ if (!from_submit_binding) {
+ if (m_firing_submission_events)
+ return;
+
+ m_firing_submission_events = true;
+
+ // FIXME: If the submitter element's no-validate state is false...
+
+ RefPtr<HTMLElement> submitter_button;
+
+ if (submitter != this)
+ submitter_button = submitter;
+
+ auto submit_event = SubmitEvent::create(EventNames::submit, submitter_button);
+ submit_event->set_bubbles(true);
+ submit_event->set_cancelable(true);
+ bool continue_ = dispatch_event(submit_event);
+
+ m_firing_submission_events = false;
+
+ if (!continue_)
+ return;
+
+ // This is checked again because arbitrary JS may have run when handling submit,
+ // which may have changed the result.
+ if (cannot_navigate())
+ return;
+ }
+
URL url(document().complete_url(action()));
if (!url.is_valid()) {
@@ -109,4 +143,9 @@ void HTMLFormElement::submit(RefPtr<HTMLInputElement> submitter)
page->load(request);
}
+void HTMLFormElement::submit()
+{
+ submit_form(this, true);
+}
+
}
diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.h b/Libraries/LibWeb/HTML/HTMLFormElement.h
index 67c1cb4817..cc0a275998 100644
--- a/Libraries/LibWeb/HTML/HTMLFormElement.h
+++ b/Libraries/LibWeb/HTML/HTMLFormElement.h
@@ -41,7 +41,13 @@ public:
String action() const { return attribute(HTML::AttributeNames::action); }
String method() const { return attribute(HTML::AttributeNames::method); }
- void submit(RefPtr<HTMLInputElement> submitter);
+ void submit_form(RefPtr<HTMLElement> submitter, bool from_submit_binding = false);
+
+ // NOTE: This is for the JS bindings. Use submit_form instead.
+ void submit();
+
+private:
+ bool m_firing_submission_events { false };
};
}
diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.idl b/Libraries/LibWeb/HTML/HTMLFormElement.idl
index 833910914d..fcc358eceb 100644
--- a/Libraries/LibWeb/HTML/HTMLFormElement.idl
+++ b/Libraries/LibWeb/HTML/HTMLFormElement.idl
@@ -5,4 +5,6 @@ interface HTMLFormElement : HTMLElement {
[Reflect=accept-charset] attribute DOMString acceptCharset;
[Reflect=novalidate] attribute boolean noValidate;
+ void submit();
+
}
diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp
index 6a63e23435..2d48fdc49c 100644
--- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp
@@ -55,8 +55,7 @@ void HTMLInputElement::did_click_button(Badge<Layout::ButtonBox>)
if (type().equals_ignoring_case("submit")) {
if (auto* form = first_ancestor_of_type<HTMLFormElement>()) {
- // FIXME: Remove this const_cast once we have a non-const first_ancestor_of_type.
- form->submit(this);
+ form->submit_form(this);
}
return;
}
diff --git a/Libraries/LibWeb/HTML/SubmitEvent.h b/Libraries/LibWeb/HTML/SubmitEvent.h
new file mode 100644
index 0000000000..06c4b6fb0b
--- /dev/null
+++ b/Libraries/LibWeb/HTML/SubmitEvent.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ * 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/DOM/Event.h>
+
+namespace Web::HTML {
+
+class SubmitEvent final : public DOM::Event {
+public:
+ using WrapperType = Bindings::SubmitEventWrapper;
+
+ static NonnullRefPtr<SubmitEvent> create(const FlyString& event_name, RefPtr<HTMLElement> submitter)
+ {
+ return adopt(*new SubmitEvent(event_name, submitter));
+ }
+
+ const RefPtr<HTMLElement> submitter() const { return m_submitter; }
+
+private:
+ SubmitEvent(const FlyString& event_name, RefPtr<HTMLElement> submitter)
+ : DOM::Event(event_name)
+ , m_submitter(submitter)
+ {
+ }
+
+ RefPtr<HTMLElement> m_submitter;
+};
+
+}
diff --git a/Libraries/LibWeb/HTML/SubmitEvent.idl b/Libraries/LibWeb/HTML/SubmitEvent.idl
new file mode 100644
index 0000000000..fd6dd9a73c
--- /dev/null
+++ b/Libraries/LibWeb/HTML/SubmitEvent.idl
@@ -0,0 +1,5 @@
+interface SubmitEvent : Event {
+
+ readonly attribute HTMLElement? submitter;
+
+}