summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/HTML
diff options
context:
space:
mode:
authorLuke Wilde <lukew@serenityos.org>2022-06-19 16:02:48 +0100
committerLinus Groh <mail@linusgroh.de>2022-06-19 16:35:43 +0100
commit1f820f8840ebf83ada1ea552f3686dce23a66346 (patch)
treed5cc1467d3251dd01aae69c689df12d56d31372c /Userland/Libraries/LibWeb/HTML
parentb3d87f8e3747aa40d2f72c5d91a25d38e505501b (diff)
downloadserenity-1f820f8840ebf83ada1ea552f3686dce23a66346.zip
LibWeb: Add support for the <base> element changing the base URL
Used by Google seemingly almost all around account sign in and management. The modern sign in page has this near the beginning: ```html <base href="https://accounts.google.com"> ``` All of the XHRs performed by sign in are relative URLs to this base URL. Previously we ignored this and did it relative to the current URL, causing the XHRs to 404 and sign in to fall apart. I presume they do this because you can access the sign in page from multiple endpoints, such as `/ServiceLogin` and `/o/oauth2/auth/identifier`
Diffstat (limited to 'Userland/Libraries/LibWeb/HTML')
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLBaseElement.cpp49
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLBaseElement.h12
-rw-r--r--Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp5
3 files changed, 63 insertions, 3 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.cpp
index 19a73dfe84..b5008f41e6 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.cpp
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLBaseElement.h>
namespace Web::HTML {
@@ -14,4 +15,52 @@ HTMLBaseElement::HTMLBaseElement(DOM::Document& document, DOM::QualifiedName qua
}
HTMLBaseElement::~HTMLBaseElement() = default;
+
+void HTMLBaseElement::inserted()
+{
+ HTMLElement::inserted();
+
+ // The frozen base URL must be immediately set for an element whenever any of the following situations occur:
+ // - The base element becomes the first base element in tree order with an href content attribute in its Document.
+
+ // NOTE: inserted() is called after this element has been inserted into the document.
+ auto first_base_element_with_href_in_document = document().first_base_element_with_href_in_tree_order();
+ if (first_base_element_with_href_in_document == this)
+ set_the_frozen_base_url();
+}
+
+void HTMLBaseElement::parse_attribute(FlyString const& name, String const& value)
+{
+ HTMLElement::parse_attribute(name, value);
+
+ // The frozen base URL must be immediately set for an element whenever any of the following situations occur:
+ // - The base element is the first base element in tree order with an href content attribute in its Document, and its href content attribute is changed.
+ if (name != AttributeNames::href)
+ return;
+
+ auto first_base_element_with_href_in_document = document().first_base_element_with_href_in_tree_order();
+ if (first_base_element_with_href_in_document == this)
+ set_the_frozen_base_url();
+}
+
+// https://html.spec.whatwg.org/multipage/semantics.html#set-the-frozen-base-url
+void HTMLBaseElement::set_the_frozen_base_url()
+{
+ // 1. Let document be element's node document.
+ auto& document = this->document();
+
+ // 2. Let urlRecord be the result of parsing the value of element's href content attribute with document's fallback base URL, and document's character encoding. (Thus, the base element isn't affected by itself.)
+ auto href = attribute(AttributeNames::href);
+ auto url_record = document.fallback_base_url().complete_url(href);
+
+ // 3. Set element's frozen base URL to document's fallback base URL, if urlRecord is failure or running Is base allowed for Document? on the resulting URL record and document returns "Blocked", and to urlRecord otherwise.
+ // FIXME: Apply "Is base allowed for Document?" CSP
+ if (!url_record.is_valid()) {
+ m_frozen_base_url = document.fallback_base_url();
+ return;
+ }
+
+ m_frozen_base_url = move(url_record);
+}
+
}
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.h b/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.h
index de620b86a9..40d7bd3525 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLBaseElement.h
@@ -16,6 +16,18 @@ public:
HTMLBaseElement(DOM::Document&, DOM::QualifiedName);
virtual ~HTMLBaseElement() override;
+
+ AK::URL const& frozen_base_url() const { return m_frozen_base_url; }
+
+ virtual void inserted() override;
+ virtual void parse_attribute(FlyString const& name, String const& value) override;
+
+private:
+ // https://html.spec.whatwg.org/multipage/semantics.html#frozen-base-url
+ // A base element that is the first base element with an href content attribute in a document tree has a frozen base URL.
+ AK::URL m_frozen_base_url;
+
+ void set_the_frozen_base_url();
};
}
diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp
index 14a541e6bb..bc5183fce2 100644
--- a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp
@@ -62,9 +62,8 @@ String WindowEnvironmentSettingsObject::api_url_character_encoding()
// https://html.spec.whatwg.org/multipage/window-object.html#script-settings-for-window-objects:api-base-url
AK::URL WindowEnvironmentSettingsObject::api_base_url()
{
- // FIXME: Return the current base URL of window's associated Document.
- // (This currently just returns the current document URL, not accounting for <base> elements and such)
- return m_window->associated_document().url();
+ // Return the current base URL of window's associated Document.
+ return m_window->associated_document().base_url();
}
// https://html.spec.whatwg.org/multipage/window-object.html#script-settings-for-window-objects:concept-settings-object-origin