mirror of
				https://github.com/lightpanda-io/browser.git
				synced 2025-10-29 15:13:28 +00:00 
			
		
		
		
	Merge pull request #1043 from lightpanda-io/html_slot_assigned_elements
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				e2e-test / zig build release (push) Has been cancelled
				
			
		
			
				
	
				zig-test / zig build dev (push) Has been cancelled
				
			
		
			
				
	
				zig-test / zig test (push) Has been cancelled
				
			
		
			
				
	
				e2e-test / demo-scripts (push) Has been cancelled
				
			
		
			
				
	
				e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
				
			
		
			
				
	
				e2e-test / perf-fmt (push) Has been cancelled
				
			
		
			
				
	
				zig-test / browser fetch (push) Has been cancelled
				
			
		
			
				
	
				zig-test / perf-fmt (push) Has been cancelled
				
			
		
			
				
	
				nightly build / build-linux-x86_64 (push) Has been cancelled
				
			
		
			
				
	
				nightly build / build-linux-aarch64 (push) Has been cancelled
				
			
		
			
				
	
				nightly build / build-macos-aarch64 (push) Has been cancelled
				
			
		
			
				
	
				nightly build / build-macos-x86_64 (push) Has been cancelled
				
			
		
			
				
	
				wpt / web platform tests json output (push) Has been cancelled
				
			
		
			
				
	
				wpt / perf-fmt (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	e2e-test / zig build release (push) Has been cancelled
				
			zig-test / zig build dev (push) Has been cancelled
				
			zig-test / zig test (push) Has been cancelled
				
			e2e-test / demo-scripts (push) Has been cancelled
				
			e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
				
			e2e-test / perf-fmt (push) Has been cancelled
				
			zig-test / browser fetch (push) Has been cancelled
				
			zig-test / perf-fmt (push) Has been cancelled
				
			nightly build / build-linux-x86_64 (push) Has been cancelled
				
			nightly build / build-linux-aarch64 (push) Has been cancelled
				
			nightly build / build-macos-aarch64 (push) Has been cancelled
				
			nightly build / build-macos-x86_64 (push) Has been cancelled
				
			wpt / web platform tests json output (push) Has been cancelled
				
			wpt / perf-fmt (push) Has been cancelled
				
			add assignedElements to HTMLSlotElement
This commit is contained in:
		| @@ -1042,68 +1042,84 @@ pub const HTMLSlotElement = struct { | ||||
|         flatten: bool = false, | ||||
|     }; | ||||
|     pub fn _assignedNodes(self: *parser.Slot, opts_: ?AssignedNodesOpts, page: *Page) ![]NodeUnion { | ||||
|         const opts = opts_ orelse AssignedNodesOpts{ .flatten = false }; | ||||
|  | ||||
|         if (try findAssignedSlotNodes(self, opts, page)) |nodes| { | ||||
|             return nodes; | ||||
|         } | ||||
|  | ||||
|         if (!opts.flatten) { | ||||
|             return &.{}; | ||||
|         } | ||||
|  | ||||
|         const node: *parser.Node = @ptrCast(@alignCast(self)); | ||||
|         const nl = try parser.nodeGetChildNodes(node); | ||||
|         const len = try parser.nodeListLength(nl); | ||||
|         if (len == 0) { | ||||
|             return &.{}; | ||||
|         } | ||||
|  | ||||
|         var assigned = try page.call_arena.alloc(NodeUnion, len); | ||||
|         var i: usize = 0; | ||||
|         while (true) : (i += 1) { | ||||
|             const child = try parser.nodeListItem(nl, @intCast(i)) orelse break; | ||||
|             assigned[i] = try Node.toInterface(child); | ||||
|         } | ||||
|         return assigned[0..i]; | ||||
|         return findAssignedSlotNodes(self, opts_, false, page); | ||||
|     } | ||||
|  | ||||
|     fn findAssignedSlotNodes(self: *parser.Slot, opts: AssignedNodesOpts, page: *Page) !?[]NodeUnion { | ||||
|     // This should return Union, instead of NodeUnion, but we want to re-use | ||||
|     // findAssignedSlotNodes. Returning NodeUnion is fine, as long as every element | ||||
|     // within is an Element. This could be more efficient | ||||
|     pub fn _assignedElements(self: *parser.Slot, opts_: ?AssignedNodesOpts, page: *Page) ![]NodeUnion { | ||||
|         return findAssignedSlotNodes(self, opts_, true, page); | ||||
|     } | ||||
|  | ||||
|     fn findAssignedSlotNodes(self: *parser.Slot, opts_: ?AssignedNodesOpts, element_only: bool, page: *Page) ![]NodeUnion { | ||||
|         const opts = opts_ orelse AssignedNodesOpts{ .flatten = false }; | ||||
|  | ||||
|         if (opts.flatten) { | ||||
|             log.debug(.web_api, "not implemented", .{ .feature = "HTMLSlotElement flatten assignedNodes" }); | ||||
|         } | ||||
|  | ||||
|         const slot_name = try parser.elementGetAttribute(@ptrCast(@alignCast(self)), "name"); | ||||
|         const node: *parser.Node = @ptrCast(@alignCast(self)); | ||||
|         var root = try parser.nodeGetRootNode(node); | ||||
|         if (page.getNodeState(root)) |state| { | ||||
|             if (state.shadow_root) |sr| { | ||||
|                 root = @ptrCast(@alignCast(sr.host)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         var arr: std.ArrayList(NodeUnion) = .empty; | ||||
|         const w = @import("../dom/walker.zig").WalkerChildren{}; | ||||
|         var next: ?*parser.Node = null; | ||||
|         while (true) { | ||||
|             next = try w.get_next(root, next) orelse break; | ||||
|             if (try parser.nodeType(next.?) != .element) { | ||||
|                 if (slot_name == null) { | ||||
|                     // default slot (with no name), takes everything | ||||
|                     try arr.append(page.call_arena, try Node.toInterface(next.?)); | ||||
|         // First we look for any explicitly assigned nodes (via the slot attribute) | ||||
|         { | ||||
|             const slot_name = try parser.elementGetAttribute(@ptrCast(@alignCast(self)), "name"); | ||||
|             var root = try parser.nodeGetRootNode(node); | ||||
|             if (page.getNodeState(root)) |state| { | ||||
|                 if (state.shadow_root) |sr| { | ||||
|                     root = @ptrCast(@alignCast(sr.host)); | ||||
|                 } | ||||
|                 continue; | ||||
|             } | ||||
|             const el: *parser.Element = @ptrCast(@alignCast(next.?)); | ||||
|             const element_slot = try parser.elementGetAttribute(el, "slot"); | ||||
|  | ||||
|             if (nullableStringsAreEqual(slot_name, element_slot)) { | ||||
|                 // either they're the same string or they are both null | ||||
|                 try arr.append(page.call_arena, try Node.toInterface(next.?)); | ||||
|                 continue; | ||||
|             var arr: std.ArrayList(NodeUnion) = .empty; | ||||
|             const w = @import("../dom/walker.zig").WalkerChildren{}; | ||||
|             var next: ?*parser.Node = null; | ||||
|             while (true) { | ||||
|                 next = try w.get_next(root, next) orelse break; | ||||
|                 if (try parser.nodeType(next.?) != .element) { | ||||
|                     if (slot_name == null and !element_only) { | ||||
|                         // default slot (with no name), takes everything | ||||
|                         try arr.append(page.call_arena, try Node.toInterface(next.?)); | ||||
|                     } | ||||
|                     continue; | ||||
|                 } | ||||
|                 const el: *parser.Element = @ptrCast(@alignCast(next.?)); | ||||
|                 const element_slot = try parser.elementGetAttribute(el, "slot"); | ||||
|  | ||||
|                 if (nullableStringsAreEqual(slot_name, element_slot)) { | ||||
|                     // either they're the same string or they are both null | ||||
|                     try arr.append(page.call_arena, try Node.toInterface(next.?)); | ||||
|                     continue; | ||||
|                 } | ||||
|             } | ||||
|             if (arr.items.len > 0) { | ||||
|                 return arr.items; | ||||
|             } | ||||
|  | ||||
|             if (!opts.flatten) { | ||||
|                 return &.{}; | ||||
|             } | ||||
|         } | ||||
|         return if (arr.items.len == 0) null else arr.items; | ||||
|  | ||||
|         // Since, we have no explicitly assigned nodes and flatten == false, | ||||
|         // we'll collect the children of the slot - the defaults. | ||||
|         { | ||||
|             const nl = try parser.nodeGetChildNodes(node); | ||||
|             const len = try parser.nodeListLength(nl); | ||||
|             if (len == 0) { | ||||
|                 return &.{}; | ||||
|             } | ||||
|  | ||||
|             var assigned = try page.call_arena.alloc(NodeUnion, len); | ||||
|             var i: usize = 0; | ||||
|             while (true) : (i += 1) { | ||||
|                 const child = try parser.nodeListItem(nl, @intCast(i)) orelse break; | ||||
|                 if (!element_only or try parser.nodeType(child) == .element) { | ||||
|                     assigned[i] = try Node.toInterface(child); | ||||
|                 } | ||||
|             } | ||||
|             return assigned[0..i]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn nullableStringsAreEqual(a: ?[]const u8, b: ?[]const u8) bool { | ||||
|   | ||||
| @@ -63,4 +63,9 @@ | ||||
|   assertNodes(['default2'], s6[0].assignedNodes({flatten: true})); | ||||
|   assertNodes(['More ', ' ', '!!'], s6[1].assignedNodes({})); | ||||
|   assertNodes(['More ', ' ', '!!'], s6[1].assignedNodes({flatten: true})); | ||||
|  | ||||
|   assertNodes(['default2'], s6[0].assignedElements({})); | ||||
|   assertNodes(['default2'], s6[0].assignedElements({flatten: true})); | ||||
|   assertNodes(['!!'], s6[1].assignedElements({})); | ||||
|   assertNodes(['!!'], s6[1].assignedElements({flatten: true})); | ||||
| </script> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Karl Seguin
					Karl Seguin