1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:34:59 +00:00

LibWeb: Implement the window.opener attribute

This returns a reference to the window that opened the current window.
This commit is contained in:
Tim Ledbetter 2024-03-12 23:39:59 +00:00 committed by Sam Atkins
parent 5713c2ffdd
commit fc1f037cd1
5 changed files with 63 additions and 0 deletions

View file

@ -0,0 +1,5 @@
window.opener initial value: null
window.opener after setting to "test": test
iframe contentWindow.opener initial value is the current window object: true
iframe contentWindow.opener after setting to null: null
iframe contentWindow.opener after setting to "test": test

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<script src="../include.js"></script>
<iframe name="testFrame"></iframe>
<script>
asyncTest(done => {
println(`window.opener initial value: ${window.opener}`);
window.opener = "test";
println(`window.opener after setting to "test": ${window.opener}`);
const frame = document.querySelector("iframe");
frame.onload = () => {
println(`iframe contentWindow.opener initial value is the current window object: ${frame.contentWindow.opener === window}`);
frame.contentWindow.opener = null;
println(`iframe contentWindow.opener after setting to null: ${frame.contentWindow.opener}`);
frame.contentWindow.opener = "test";
println(`iframe contentWindow.opener after setting to "test": ${frame.contentWindow.opener}`);
done();
}
window.open("about:srcdoc", "testFrame");
});
</script>

View file

@ -946,6 +946,41 @@ JS::GCPtr<WindowProxy const> Window::top() const
return navigable->top_level_traversable()->active_window_proxy();
}
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-opener
JS::GCPtr<WindowProxy const> Window::opener() const
{
// 1. Let current be this's browsing context.
auto const* current = browsing_context();
// 2. If current is null, then return null.
if (!current)
return {};
// 3. If current's opener browsing context is null, then return null.
auto opener_browsing_context = current->opener_browsing_context();
if (!opener_browsing_context)
return {};
// 4. Return current's opener browsing context's WindowProxy object.
return opener_browsing_context->window_proxy();
}
WebIDL::ExceptionOr<void> Window::set_opener(JS::Value value)
{
// 1. If the given value is null and this's browsing context is non-null, then set this's browsing context's opener browsing context to null.
auto* browsing_context = this->browsing_context();
if (value.is_null() && browsing_context)
browsing_context->set_opener_browsing_context(nullptr);
// 2. If the given value is non-null, then perform ? DefinePropertyOrThrow(this, "opener", { [[Value]]: the given value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }).
if (!value.is_null()) {
static JS::PropertyKey opener_property_key { "opener", JS::PropertyKey::StringMayBeNumber::No };
TRY(define_property_or_throw(opener_property_key, { .value = value, .writable = true, .enumerable = true, .configurable = true }));
}
return {};
}
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-parent
JS::GCPtr<WindowProxy const> Window::parent() const
{

View file

@ -144,6 +144,8 @@ public:
JS::NonnullGCPtr<WindowProxy> frames() const;
u32 length();
JS::GCPtr<WindowProxy const> top() const;
JS::GCPtr<WindowProxy const> opener() const;
WebIDL::ExceptionOr<void> set_opener(JS::Value);
JS::GCPtr<WindowProxy const> parent() const;
JS::GCPtr<DOM::Element const> frame_element() const;
WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> open(Optional<String> const& url, Optional<String> const& target, Optional<String> const& features);

View file

@ -35,6 +35,7 @@ interface Window : EventTarget {
[Replaceable] readonly attribute WindowProxy frames;
[Replaceable] readonly attribute unsigned long length;
[LegacyUnforgeable] readonly attribute WindowProxy? top;
attribute any opener;
[Replaceable] readonly attribute WindowProxy? parent;
readonly attribute Element? frameElement;
WindowProxy? open(optional USVString url = "", optional DOMString target = "_blank", optional [LegacyNullToEmptyString] DOMString features = "");