@@ -226,6 +226,23 @@ pub const HTMLDocument = struct {
226226 return "" ;
227227 }
228228
229+ pub fn _elementFromPoint (_ : * parser.DocumentHTML , x : f32 , y : f32 , state : * SessionState ) ! ? * parser.Element {
230+ const ix : i32 = @intFromFloat (@floor (x ));
231+ const iy : i32 = @intFromFloat (@floor (y ));
232+ return state .renderer .getElementAtPosition (ix , iy ) orelse return null ;
233+ }
234+
235+ pub fn _elementsFromPoint (_ : * parser.DocumentHTML , x : f32 , y : f32 , state : * SessionState ) ! []* parser.Element { // empty array or optional array?
236+ const ix : i32 = @intFromFloat (@floor (x ));
237+ const iy : i32 = @intFromFloat (@floor (y ));
238+ const element = state .renderer .getElementAtPosition (ix , iy ) orelse return &.{}; // Or should we return the window element instead of empty -> parser.documentGetDocumentElement(self);
239+ // We need to return either 0 or 1 item, so we cannot fix the size to [1]*parser.Element
240+ // Converting the pointer to a slice []parser.Element is not supported by our framework.
241+ // So instead we just need to allocate the pointer to create a slice of 1.
242+ const heap_ptr = try state .arena .create (@TypeOf (element ));
243+ return heap_ptr [0.. 1];
244+ }
245+
229246 pub fn documentIsLoaded (html_doc : * parser.DocumentHTML , state : * SessionState ) ! void {
230247 const self = try state .getNodeWrapper (HTMLDocument , @ptrCast (html_doc ));
231248 self .ready_state = .interactive ;
@@ -295,6 +312,16 @@ test "Browser.HTML.Document" {
295312 .{ "document.cookie" , "name=Oeschger; favorite_food=tripe" },
296313 }, .{});
297314
315+ try runner .testCases (&.{
316+ .{ "document.elementFromPoint(0.5, 0.5)" , "null" },
317+ .{ "document.elementsFromPoint(0.5, 0.5)" , "" },
318+ .{ "document.createElement('div').getClientRects()" , "[object Object]" },
319+ .{ "document.elementFromPoint(0.5, 0.5)" , "[object HTMLDivElement]" },
320+ .{ "let elems = document.elementsFromPoint(0.5, 0.5)" , "undefined" },
321+ .{ "elems.length" , "1" },
322+ .{ "elems[0]" , "[object Element]" }, // TBD why is this not: HTMLDivElement?
323+ }, .{});
324+
298325 try runner .testCases (&.{
299326 .{ "!document.all" , "true" },
300327 .{ "!!document.all" , "false" },
@@ -310,12 +337,12 @@ test "Browser.HTML.Document" {
310337 .{ "document.readyState" , "loading" },
311338 }, .{});
312339
313- try HTMLDocument .documentIsLoaded (runner .state .document .? , & runner .state );
340+ try HTMLDocument .documentIsLoaded (runner .state .window . document .? , & runner .state );
314341 try runner .testCases (&.{
315342 .{ "document.readyState" , "interactive" },
316343 }, .{});
317344
318- try HTMLDocument .documentIsComplete (runner .state .document .? , & runner .state );
345+ try HTMLDocument .documentIsComplete (runner .state .window . document .? , & runner .state );
319346 try runner .testCases (&.{
320347 .{ "document.readyState" , "complete" },
321348 }, .{});
0 commit comments