@@ -201,49 +201,69 @@ pub const Search = struct {
201201// (For now, we only support direct children)
202202
203203pub const Writer = struct {
204- opts : Opts ,
205- node : * const Node ,
204+ depth : i32 ,
205+ exclude_root : bool ,
206+ root : * const Node ,
206207 registry : * Registry ,
207208
208- pub const Opts = struct {};
209+ pub const Opts = struct {
210+ depth : i32 = 0 ,
211+ exclude_root : bool = false ,
212+ };
209213
210214 pub fn jsonStringify (self : * const Writer , w : anytype ) ! void {
211- self .toJSON (w ) catch | err | {
212- // The only error our jsonStringify method can return is
213- // @TypeOf(w).Error. In other words, our code can't return its own
214- // error, we can only return a writer error. Kinda sucks.
215- log .err (.cdp , "json stringify" , .{ .err = err });
216- return error .OutOfMemory ;
217- };
215+ if (self .exclude_root ) {
216+ _ = self .writeChildren (self .root , 1 , w ) catch | err | {
217+ log .err (.cdp , "node writeChildren" , .{ .err = err });
218+ return error .OutOfMemory ;
219+ };
220+ } else {
221+ self .toJSON (self .root , 0 , w ) catch | err | {
222+ // The only error our jsonStringify method can return is
223+ // @TypeOf(w).Error. In other words, our code can't return its own
224+ // error, we can only return a writer error. Kinda sucks.
225+ log .err (.cdp , "node toJSON stringify" , .{ .err = err });
226+ return error .OutOfMemory ;
227+ };
228+ }
218229 }
219230
220- fn toJSON (self : * const Writer , w : anytype ) ! void {
231+ fn toJSON (self : * const Writer , node : * const Node , depth : usize , w : anytype ) ! void {
221232 try w .beginObject ();
222- try self .writeCommon (self . node , false , w );
233+ try self .writeCommon (node , false , w );
223234
224- {
225- var registry = self .registry ;
226- const child_nodes = try parser . nodeGetChildNodes ( self . node . _node );
227- const child_count = try parser . nodeListLength ( child_nodes );
235+ try w . objectField ( "children" );
236+ const child_count = try self .writeChildren ( node , depth , w ) ;
237+ try w . objectField ( "childNodeCount" );
238+ try w . write ( child_count );
228239
229- var i : usize = 0 ;
230- try w .objectField ("children" );
231- try w .beginArray ();
232- for (0.. child_count ) | _ | {
233- const child = (try parser .nodeListItem (child_nodes , @intCast (i ))) orelse break ;
234- const child_node = try registry .register (child );
240+ try w .endObject ();
241+ }
242+
243+ fn writeChildren (self : * const Writer , node : * const Node , depth : usize , w : anytype ) anyerror ! usize {
244+ var registry = self .registry ;
245+ const child_nodes = try parser .nodeGetChildNodes (node ._node );
246+ const child_count = try parser .nodeListLength (child_nodes );
247+ const full_child = self .depth < 0 or self .depth < depth ;
248+
249+ var i : usize = 0 ;
250+ try w .beginArray ();
251+ for (0.. child_count ) | _ | {
252+ const child = (try parser .nodeListItem (child_nodes , @intCast (i ))) orelse break ;
253+ const child_node = try registry .register (child );
254+ if (full_child ) {
255+ try self .toJSON (child_node , depth + 1 , w );
256+ } else {
235257 try w .beginObject ();
236258 try self .writeCommon (child_node , true , w );
237259 try w .endObject ();
238- i += 1 ;
239260 }
240- try w .endArray ();
241261
242- try w .objectField ("childNodeCount" );
243- try w .write (i );
262+ i += 1 ;
244263 }
264+ try w .endArray ();
245265
246- try w . endObject () ;
266+ return i ;
247267 }
248268
249269 fn writeCommon (self : * const Writer , node : * const Node , include_child_count : bool , w : anytype ) ! void {
@@ -400,14 +420,15 @@ test "cdp Node: Writer" {
400420 var registry = Registry .init (testing .allocator );
401421 defer registry .deinit ();
402422
403- var doc = try testing .Document .init ("<a id=a1></a><a id=a2></a>" );
423+ var doc = try testing .Document .init ("<a id=a1></a><div id=d2>< a id=a2></a></div >" );
404424 defer doc .deinit ();
405425
406426 {
407427 const node = try registry .register (doc .asNode ());
408428 const json = try std .json .stringifyAlloc (testing .allocator , Writer {
409- .node = node ,
410- .opts = .{},
429+ .root = node ,
430+ .depth = 0 ,
431+ .exclude_root = false ,
411432 .registry = & registry ,
412433 }, .{});
413434 defer testing .allocator .free (json );
@@ -445,8 +466,9 @@ test "cdp Node: Writer" {
445466 {
446467 const node = registry .lookup_by_id .get (1 ).? ;
447468 const json = try std .json .stringifyAlloc (testing .allocator , Writer {
448- .node = node ,
449- .opts = .{},
469+ .root = node ,
470+ .depth = 1 ,
471+ .exclude_root = false ,
450472 .registry = & registry ,
451473 }, .{});
452474 defer testing .allocator .free (json );
@@ -495,4 +517,61 @@ test "cdp Node: Writer" {
495517 } },
496518 }, json );
497519 }
520+
521+ {
522+ const node = registry .lookup_by_id .get (1 ).? ;
523+ const json = try std .json .stringifyAlloc (testing .allocator , Writer {
524+ .root = node ,
525+ .depth = -1 ,
526+ .exclude_root = true ,
527+ .registry = & registry ,
528+ }, .{});
529+ defer testing .allocator .free (json );
530+
531+ try testing .expectJson (&.{ .{
532+ .nodeId = 2 ,
533+ .backendNodeId = 2 ,
534+ .nodeType = 1 ,
535+ .nodeName = "HEAD" ,
536+ .localName = "head" ,
537+ .nodeValue = "" ,
538+ .childNodeCount = 0 ,
539+ .documentURL = null ,
540+ .baseURL = null ,
541+ .xmlVersion = "" ,
542+ .compatibilityMode = "NoQuirksMode" ,
543+ .isScrollable = false ,
544+ .parentId = 1 ,
545+ }, .{
546+ .nodeId = 3 ,
547+ .backendNodeId = 3 ,
548+ .nodeType = 1 ,
549+ .nodeName = "BODY" ,
550+ .localName = "body" ,
551+ .nodeValue = "" ,
552+ .childNodeCount = 2 ,
553+ .documentURL = null ,
554+ .baseURL = null ,
555+ .xmlVersion = "" ,
556+ .compatibilityMode = "NoQuirksMode" ,
557+ .isScrollable = false ,
558+ .children = &.{ .{
559+ .nodeId = 4 ,
560+ .localName = "a" ,
561+ .childNodeCount = 0 ,
562+ .parentId = 3 ,
563+ }, .{
564+ .nodeId = 5 ,
565+ .localName = "div" ,
566+ .childNodeCount = 1 ,
567+ .parentId = 3 ,
568+ .children = &.{ .{
569+ .nodeId = 6 ,
570+ .localName = "a" ,
571+ .childNodeCount = 0 ,
572+ .parentId = 5 ,
573+ }}
574+ }
575+ } } }, json );
576+ }
498577}
0 commit comments