@@ -33,6 +33,7 @@ const MediaQueryList = @import("media_query_list.zig").MediaQueryList;
3333const Performance = @import ("../dom/performance.zig" ).Performance ;
3434const CSSStyleDeclaration = @import ("../cssom/CSSStyleDeclaration.zig" );
3535const Screen = @import ("screen.zig" ).Screen ;
36+ const domcss = @import ("../dom/css.zig" );
3637const Css = @import ("../css/css.zig" ).Css ;
3738
3839const Function = Env .Function ;
@@ -126,7 +127,43 @@ pub const Window = struct {
126127 return self ;
127128 }
128129
129- // TODO: frames
130+ // frames return the window itself, but accessing it via a pseudo
131+ // array returns the Window object corresponding to the given frame or
132+ // iframe.
133+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/frames
134+ pub fn get_frames (self : * Window ) * Window {
135+ return self ;
136+ }
137+
138+ pub fn indexed_get (self : * Window , index : u32 , has_value : * bool , page : * Page ) ! * Window {
139+ const frames = try domcss .querySelectorAll (
140+ page .call_arena ,
141+ parser .documentHTMLToNode (self .document ),
142+ "iframe" ,
143+ );
144+
145+ if (index >= frames .nodes .items .len ) {
146+ has_value .* = false ;
147+ return undefined ;
148+ }
149+
150+ has_value .* = true ;
151+ // TODO return the correct frame's window
152+ // frames.nodes.items[indexed]
153+ return error .TODO ;
154+ }
155+
156+ // Retrieve the numbre of frames/iframes from the DOM dynamically.
157+ pub fn get_length (self : * const Window , page : * Page ) ! u32 {
158+ const frames = try domcss .querySelectorAll (
159+ page .call_arena ,
160+ parser .documentHTMLToNode (self .document ),
161+ "iframe" ,
162+ );
163+
164+ return frames .get_length ();
165+ }
166+
130167 pub fn get_top (self : * Window ) * Window {
131168 return self ;
132169 }
@@ -493,6 +530,14 @@ test "Browser.HTML.Window" {
493530 .{ "scrollend" , "true" },
494531 }, .{});
495532
533+ try runner .testCases (&.{
534+ .{ "window == window.self" , "true" },
535+ .{ "window == window.parent" , "true" },
536+ .{ "window == window.top" , "true" },
537+ .{ "window == window.frames" , "true" },
538+ .{ "window.frames.length" , "0" },
539+ }, .{});
540+
496541 try runner .testCases (&.{
497542 .{ "var qm = false; window.queueMicrotask(() => {qm = true });" , null },
498543 .{ "qm" , "true" },
@@ -515,3 +560,26 @@ test "Browser.HTML.Window" {
515560 }, .{});
516561 }
517562}
563+
564+ test "Browser.HTML.Window.frames" {
565+ var runner = try testing .jsRunner (testing .tracking_allocator , .{ .html =
566+ \\<body>
567+ \\ <iframe
568+ \\ src="https://httpbin.io/html"
569+ \\ title="iframea">
570+ \\ </iframe>
571+ \\ <iframe
572+ \\ src="https://httpbin.io/html"
573+ \\ title="iframeb">
574+ \\ </iframe>
575+ \\</body>
576+ });
577+
578+ defer runner .deinit ();
579+
580+ try runner .testCases (&.{
581+ .{ "frames.length" , "2" },
582+ .{ "try { frames[1] } catch (e) { e }" , "Error: TODO" }, // TODO fixme
583+ .{ "frames[3]" , "undefined" },
584+ }, .{});
585+ }
0 commit comments