diff --git a/Tests/LibWeb/Text/expected/DOM/Document-defaultView.txt b/Tests/LibWeb/Text/expected/DOM/Document-defaultView.txt
new file mode 100644
index 00000000000..aa721174eec
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/DOM/Document-defaultView.txt
@@ -0,0 +1 @@
+document.defaultView === window: true
diff --git a/Tests/LibWeb/Text/input/DOM/Document-defaultView.html b/Tests/LibWeb/Text/input/DOM/Document-defaultView.html
new file mode 100644
index 00000000000..5bf173fd6af
--- /dev/null
+++ b/Tests/LibWeb/Text/input/DOM/Document-defaultView.html
@@ -0,0 +1,7 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index ac32dbb467a..c5bac24f370 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Document.cpp
@@ -698,6 +698,22 @@ WebIDL::ExceptionOr Document::close()
return {};
}
+// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-document-defaultview
+JS::GCPtr Document::default_view()
+{
+ // If this's browsing context is null, then return null.
+ if (!browsing_context())
+ return {};
+
+ // 2. Return this's browsing context's WindowProxy object.
+ return browsing_context()->window_proxy();
+}
+
+JS::GCPtr Document::default_view() const
+{
+ return const_cast(this)->default_view();
+}
+
HTML::Origin Document::origin() const
{
return m_origin;
diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h
index 39b181a0d83..28e04800e42 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.h
+++ b/Userland/Libraries/LibWeb/DOM/Document.h
@@ -370,8 +370,8 @@ public:
WebIDL::ExceptionOr> open(StringView url, StringView name, StringView features);
WebIDL::ExceptionOr close();
- HTML::Window* default_view() { return m_window.ptr(); }
- HTML::Window const* default_view() const { return m_window.ptr(); }
+ JS::GCPtr default_view() const;
+ JS::GCPtr default_view();
String const& content_type() const { return m_content_type; }
void set_content_type(String content_type) { m_content_type = move(content_type); }
diff --git a/Userland/Libraries/LibWeb/DOM/Document.idl b/Userland/Libraries/LibWeb/DOM/Document.idl
index 3ee2e8aa4ea..859e91329e2 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.idl
+++ b/Userland/Libraries/LibWeb/DOM/Document.idl
@@ -48,7 +48,7 @@ interface Document : Node {
readonly attribute DOMString inputEncoding;
readonly attribute DOMString contentType;
- readonly attribute Window? defaultView;
+ readonly attribute WindowProxy? defaultView;
[CEReactions] Document open(optional DOMString unused1, optional DOMString unused2);
WindowProxy? open(USVString url, DOMString name, DOMString features);
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index e1214498d97..5a3c265ea33 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -1246,7 +1246,8 @@ double Element::scroll_top() const
return 0.0;
// 3. Let window be the value of document’s defaultView attribute.
- auto* window = document.default_view();
+ // FIXME: The specification expects defaultView to be a Window object, but defaultView actually returns a WindowProxy object.
+ auto window = document.window();
// 4. If window is null, return zero and terminate these steps.
if (!window)
@@ -1276,6 +1277,7 @@ double Element::scroll_top() const
return paintable_box()->scroll_offset().y().to_double();
}
+// https://drafts.csswg.org/cssom-view/#dom-element-scrollleft
double Element::scroll_left() const
{
// 1. Let document be the element’s node document.
@@ -1286,7 +1288,8 @@ double Element::scroll_left() const
return 0.0;
// 3. Let window be the value of document’s defaultView attribute.
- auto* window = document.default_view();
+ // FIXME: The specification expects defaultView to be a Window object, but defaultView actually returns a WindowProxy object.
+ auto window = document.window();
// 4. If window is null, return zero and terminate these steps.
if (!window)
@@ -1332,7 +1335,8 @@ void Element::set_scroll_left(double x)
return;
// 5. Let window be the value of document’s defaultView attribute.
- auto* window = document.default_view();
+ // FIXME: The specification expects defaultView to be a Window object, but defaultView actually returns a WindowProxy object.
+ auto window = document.window();
// 6. If window is null, terminate these steps.
if (!window)
@@ -1388,7 +1392,8 @@ void Element::set_scroll_top(double y)
return;
// 5. Let window be the value of document’s defaultView attribute.
- auto* window = document.default_view();
+ // FIXME: The specification expects defaultView to be a Window object, but defaultView actually returns a WindowProxy object.
+ auto window = document.window();
// 6. If window is null, terminate these steps.
if (!window)
@@ -2347,7 +2352,8 @@ void Element::scroll(double x, double y)
return;
// 5. Let window be the value of document’s defaultView attribute.
- auto* window = document.default_view();
+ // FIXME: The specification expects defaultView to be a Window object, but defaultView actually returns a WindowProxy object.
+ auto window = document.window();
// 6. If window is null, terminate these steps.
if (!window)