From 5fa13625a1ca0ea1a3a1c5bb86d0880dcfac349f Mon Sep 17 00:00:00 2001 From: Dylan Conway <35280289+dylan-conway@users.noreply.github.com> Date: Wed, 21 Jun 2023 23:38:18 -0700 Subject: upgrade zig to `v0.11.0-dev.3737+9eb008717` (#3374) * progress * finish `@memset/@memcpy` update * Update build.zig * change `@enumToInt` to `@intFromEnum` and friends * update zig versions * it was 1 * add link to issue * add `compileError` reminder * fix merge * format * upgrade to llvm 16 * Revert "upgrade to llvm 16" This reverts commit cc930ceb1c5b4db9614a7638596948f704544ab8. --------- Co-authored-by: Jarred Sumner Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- src/deps/lol-html.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/deps/lol-html.zig') diff --git a/src/deps/lol-html.zig b/src/deps/lol-html.zig index 975aac2b3..1d71e6aa6 100644 --- a/src/deps/lol-html.zig +++ b/src/deps/lol-html.zig @@ -727,11 +727,11 @@ pub fn DirectiveHandler(comptime Container: type, comptime UserDataType: type, c return struct { pub fn callback(this: *Container, user_data: ?*anyopaque) callconv(.C) Directive { auto_disable(); - return @intToEnum( + return @enumFromInt( Directive, @as( c_uint, - @boolToInt( + @intFromBool( Callback( @ptrCast( *UserDataType, -- cgit v1.2.3 From 662335d81aa39dc53b83f2759312ff0ff3a93af2 Mon Sep 17 00:00:00 2001 From: Brúnó Salomon <35275408+bru02@users.noreply.github.com> Date: Mon, 26 Jun 2023 01:48:03 +0200 Subject: chore: update lol-html version (#3356) * chore: update lol-html version * add tests --------- Co-authored-by: Jarred Sumner --- src/bun.js/api/html_rewriter.zig | 7 +++++++ src/deps/lol-html | 2 +- src/deps/lol-html.zig | 8 ++++++-- src/generated_versions_list.zig | 2 +- test/js/workerd/html-rewriter.test.js | 15 +++++++++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src/deps/lol-html.zig') diff --git a/src/bun.js/api/html_rewriter.zig b/src/bun.js/api/html_rewriter.zig index 93a41b095..d09c14e42 100644 --- a/src/bun.js/api/html_rewriter.zig +++ b/src/bun.js/api/html_rewriter.zig @@ -1016,6 +1016,9 @@ pub const TextChunk = struct { .removed = .{ .get = getterWrap(TextChunk, "removed"), }, + .lastInTextNode = .{ + .get = getterWrap(TextChunk, "lastInTextNode"), + }, .text = .{ .get = getterWrap(TextChunk, "getText"), }, @@ -1084,6 +1087,10 @@ pub const TextChunk = struct { return JSC.JSValue.jsBoolean(this.text_chunk.?.isRemoved()); } + pub fn lastInTextNode(this: *TextChunk, _: *JSGlobalObject) JSValue { + return JSC.JSValue.jsBoolean(this.text_chunk.?.isLastInTextNode()); + } + pub fn finalize(this: *TextChunk) void { this.text_chunk = null; bun.default_allocator.destroy(this); diff --git a/src/deps/lol-html b/src/deps/lol-html index 2eed349dc..2681dcf0b 160000 --- a/src/deps/lol-html +++ b/src/deps/lol-html @@ -1 +1 @@ -Subproject commit 2eed349dcdfa4ff5c19fe7c6e501cfd687601033 +Subproject commit 2681dcf0b3e6907111565199df8c43cc9aab7fe8 diff --git a/src/deps/lol-html.zig b/src/deps/lol-html.zig index 1d71e6aa6..9c5345046 100644 --- a/src/deps/lol-html.zig +++ b/src/deps/lol-html.zig @@ -393,7 +393,8 @@ pub const Element = opaque { extern fn lol_html_element_is_removed(element: *const Element) bool; extern fn lol_html_element_user_data_set(element: *const Element, user_data: ?*anyopaque) void; extern fn lol_html_element_user_data_get(element: *const Element) ?*anyopaque; - extern fn lol_html_element_on_end_tag(element: *Element, end_tag_handler: lol_html_end_tag_handler_t, user_data: ?*anyopaque) c_int; + extern fn lol_html_element_add_end_tag_handler(element: *Element, end_tag_handler: lol_html_end_tag_handler_t, user_data: ?*anyopaque) c_int; + extern fn lol_html_element_clear_end_tag_handlers(element: *Element) void; pub fn getAttribute(element: *const Element, name: []const u8) HTMLString { auto_disable(); @@ -502,7 +503,10 @@ pub const Element = opaque { } pub fn onEndTag(element: *Element, end_tag_handler: lol_html_end_tag_handler_t, user_data: ?*anyopaque) Error!void { auto_disable(); - return switch (lol_html_element_on_end_tag(element, end_tag_handler, user_data)) { + + lol_html_element_clear_end_tag_handlers(element); + + return switch (lol_html_element_add_end_tag_handler(element, end_tag_handler, user_data)) { 0 => {}, -1 => error.Fail, else => unreachable, diff --git a/src/generated_versions_list.zig b/src/generated_versions_list.zig index 90bee0b8c..c27f47c83 100644 --- a/src/generated_versions_list.zig +++ b/src/generated_versions_list.zig @@ -9,6 +9,6 @@ pub const webkit = "60d11703a533fd694cd1d6ddda04813eecb5d69f"; pub const zig = @import("std").fmt.comptimePrint("{}", .{@import("builtin").zig_version}); pub const zlib = "885674026394870b7e7a05b7bf1ec5eb7bd8a9c0"; pub const tinycc = "2d3ad9e0d32194ad7fd867b66ebe218dcc8cb5cd"; -pub const lolhtml = "2eed349dcdfa4ff5c19fe7c6e501cfd687601033"; +pub const lolhtml = "2681dcf0b3e6907111565199df8c43cc9aab7fe8"; pub const c_ares = "0e7a5dee0fbb04080750cf6eabbe89d8bae87faa"; pub const usockets = "fafc241e8664243fc0c51d69684d5d02b9805134"; diff --git a/test/js/workerd/html-rewriter.test.js b/test/js/workerd/html-rewriter.test.js index 1ca92a567..b6131a09f 100644 --- a/test/js/workerd/html-rewriter.test.js +++ b/test/js/workerd/html-rewriter.test.js @@ -300,4 +300,19 @@ describe("HTMLRewriter", () => { .text(), ).toEqual("
"); }); + + it("it supports lastInTextNode", async () => { + let lastInTextNode; + + await new HTMLRewriter() + .on("p", { + text(text) { + lastInTextNode ??= text.lastInTextNode; + }, + }) + .transform(new Response("

Lorem ipsum!

")) + .text(); + + expect(lastInTextNode).toBeBoolean(); + }); }); -- cgit v1.2.3 From b05879e9e2e9d52359eb91a1305c1e694169c030 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Sun, 2 Jul 2023 01:06:40 -0700 Subject: Fixes #3489 (#3490) Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- src/bun.js/api/html_rewriter.zig | 35 ++++++++--------------------------- src/deps/lol-html.zig | 22 +++++++++++++++++++++- test/js/workerd/html-rewriter.test.js | 28 ++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 28 deletions(-) (limited to 'src/deps/lol-html.zig') diff --git a/src/bun.js/api/html_rewriter.zig b/src/bun.js/api/html_rewriter.zig index 5e14d5503..532e0ae1e 100644 --- a/src/bun.js/api/html_rewriter.zig +++ b/src/bun.js/api/html_rewriter.zig @@ -996,26 +996,14 @@ const getterWrap = JSC.getterWrap; const setterWrap = JSC.setterWrap; const wrap = JSC.wrapSync; -pub fn free_html_writer_string(_: ?*anyopaque, ptr: ?*anyopaque, len: usize) callconv(.C) void { - var str = LOLHTML.HTMLString{ .ptr = bun.cast([*]const u8, ptr.?), .len = len }; - str.deinit(); -} - fn throwLOLHTMLError(global: *JSGlobalObject) JSValue { - var err = LOLHTML.HTMLString.lastError(); - return ZigString.init(err.slice()).toErrorInstance(global); + const err = LOLHTML.HTMLString.lastError(); + defer err.deinit(); + return ZigString.fromUTF8(err.slice()).toErrorInstance(global); } fn htmlStringValue(input: LOLHTML.HTMLString, globalObject: *JSGlobalObject) JSValue { - var str = ZigString.init( - input.slice(), - ); - str.detectEncoding(); - - return str.toExternalValueWithCallback( - globalObject, - free_html_writer_string, - ); + return input.toJS(globalObject); } pub const TextChunk = struct { @@ -1328,7 +1316,7 @@ pub const Comment = struct { pub fn getText(this: *Comment, global: *JSGlobalObject) JSValue { if (this.comment == null) return JSValue.jsNull(); - return ZigString.init(this.comment.?.getText().slice()).withEncoding().toValueGC(global); + return this.comment.?.getText().toJS(global); } pub fn setText( @@ -1458,7 +1446,7 @@ pub const EndTag = struct { if (this.end_tag == null) return JSC.JSValue.jsUndefined(); - return ZigString.init(this.end_tag.?.getName().slice()).withEncoding().toValueGC(global); + return this.end_tag.?.getName().toJS(global); } pub fn setName( @@ -1696,19 +1684,12 @@ pub const Element = struct { var slice = name.toSlice(bun.default_allocator); defer slice.deinit(); - var attr = this.element.?.getAttribute(slice.slice()).slice(); + var attr = this.element.?.getAttribute(slice.slice()); if (attr.len == 0) return JSC.JSValue.jsNull(); - var str = ZigString.init( - attr, - ); - - return str.toExternalValueWithCallback( - globalObject, - free_html_writer_string, - ); + return attr.toJS(globalObject); } /// Returns a boolean indicating whether an attribute exists on the element. diff --git a/src/deps/lol-html.zig b/src/deps/lol-html.zig index 9c5345046..50dab9592 100644 --- a/src/deps/lol-html.zig +++ b/src/deps/lol-html.zig @@ -1,6 +1,6 @@ pub const Error = error{Fail}; const std = @import("std"); - +const bun = @import("root").bun; pub const MemorySettings = extern struct { preallocated_parsing_buffer_size: usize, max_allowed_memory_usage: usize, @@ -563,6 +563,26 @@ pub const HTMLString = extern struct { @setRuntimeSafety(false); return this.ptr[0..this.len]; } + + fn deinit_external(ctx: *anyopaque, ptr: *anyopaque, len: u32) callconv(.C) void { + _ = ctx; + auto_disable(); + lol_html_str_free(.{ .ptr = @ptrCast([*]const u8, ptr), .len = len }); + } + + pub fn toJS(this: HTMLString, globalThis: *bun.JSC.JSGlobalObject) bun.JSC.JSValue { + const bytes = this.slice(); + if (bun.strings.isAllASCII(bytes)) { + var external = bun.String.createExternal(bytes, true, @constCast(bytes.ptr), &deinit_external); + defer external.deref(); + return external.toJS(globalThis); + } + defer this.deinit(); + + var str = bun.String.create(bytes); + defer str.deref(); + return str.toJS(globalThis); + } }; pub const EndTag = opaque { diff --git a/test/js/workerd/html-rewriter.test.js b/test/js/workerd/html-rewriter.test.js index 3f7b7493d..aaf912aff 100644 --- a/test/js/workerd/html-rewriter.test.js +++ b/test/js/workerd/html-rewriter.test.js @@ -337,3 +337,31 @@ it("#3334 regression", async () => { } Bun.gc(true); }); + +it("#3489", async () => { + var el; + await new HTMLRewriter() + .on("p", { + element(element) { + el = element.getAttribute("id"); + }, + }) + .transform(new Response('

')) + .text(); + expect(el).toEqual("Šžõäöü"); +}); + +it("get attribute - ascii", async () => { + for (let i = 0; i < 10; i++) { + var el; + await new HTMLRewriter() + .on("p", { + element(element) { + el = element.getAttribute("id"); + }, + }) + .transform(new Response(`

`)) + .text(); + expect(el).toEqual("asciii"); + } +}); -- cgit v1.2.3 From a7f5a91cfbf93a31cc53974a6c27185e57a57f64 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 5 Jul 2023 00:08:59 -0700 Subject: Fixes #3520 (#3522) * Fixes #3520 * Update html_rewriter.zig --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- src/bun.js/api/html_rewriter.zig | 26 ++++++++------------------ src/deps/lol-html.zig | 11 ++++++----- test/js/workerd/html-rewriter.test.js | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 23 deletions(-) (limited to 'src/deps/lol-html.zig') diff --git a/src/bun.js/api/html_rewriter.zig b/src/bun.js/api/html_rewriter.zig index 532e0ae1e..b309e07d7 100644 --- a/src/bun.js/api/html_rewriter.zig +++ b/src/bun.js/api/html_rewriter.zig @@ -1558,27 +1558,16 @@ pub const AttributeIterator = struct { return JSC.JSValue.jsNull(); }; - // TODO: don't clone here const value = attribute.value(); const name = attribute.name(); - defer name.deinit(); - defer value.deinit(); - var strs = [2]ZigString{ - ZigString.init(name.slice()), - ZigString.init(value.slice()), - }; - - var valid_strs: []ZigString = strs[0..2]; - - var array = JSC.JSValue.createStringArray( + return bun.String.toJSArray( globalObject, - valid_strs.ptr, - valid_strs.len, - true, + &[_]bun.String{ + name.toString(), + value.toString(), + }, ); - - return array; } }; pub const Element = struct { @@ -1864,8 +1853,9 @@ pub const Element = struct { pub fn getNamespaceURI(this: *Element, globalObject: *JSGlobalObject) JSValue { if (this.element == null) return JSValue.jsUndefined(); - - return ZigString.init(std.mem.span(this.element.?.namespaceURI())).toValueGC(globalObject); + var str = bun.String.create(std.mem.span(this.element.?.namespaceURI())); + defer str.deref(); + return str.toJS(globalObject); } pub fn getAttributes(this: *Element, globalObject: *JSGlobalObject) JSValue { diff --git a/src/deps/lol-html.zig b/src/deps/lol-html.zig index 50dab9592..bac422fb0 100644 --- a/src/deps/lol-html.zig +++ b/src/deps/lol-html.zig @@ -570,16 +570,17 @@ pub const HTMLString = extern struct { lol_html_str_free(.{ .ptr = @ptrCast([*]const u8, ptr), .len = len }); } - pub fn toJS(this: HTMLString, globalThis: *bun.JSC.JSGlobalObject) bun.JSC.JSValue { + pub fn toString(this: HTMLString) bun.String { const bytes = this.slice(); if (bun.strings.isAllASCII(bytes)) { - var external = bun.String.createExternal(bytes, true, @constCast(bytes.ptr), &deinit_external); - defer external.deref(); - return external.toJS(globalThis); + return bun.String.createExternal(bytes, true, @constCast(bytes.ptr), &deinit_external); } defer this.deinit(); + return bun.String.create(bytes); + } - var str = bun.String.create(bytes); + pub fn toJS(this: HTMLString, globalThis: *bun.JSC.JSGlobalObject) bun.JSC.JSValue { + var str = this.toString(); defer str.deref(); return str.toJS(globalThis); } diff --git a/test/js/workerd/html-rewriter.test.js b/test/js/workerd/html-rewriter.test.js index aaf912aff..44961df3b 100644 --- a/test/js/workerd/html-rewriter.test.js +++ b/test/js/workerd/html-rewriter.test.js @@ -365,3 +365,26 @@ it("get attribute - ascii", async () => { expect(el).toEqual("asciii"); } }); + +it("#3520", async () => { + const pairs = []; + + await new HTMLRewriter() + .on("p", { + element(element) { + for (const pair of element.attributes) { + pairs.push(pair); + } + }, + }) + .transform(new Response('

')) + .text(); + + expect(pairs).toEqual([ + ["šž", "Õäöü"], + ["ab", "Õäöü"], + ["šž", "Õäöü"], + ["šž", "dc"], + ["šž", "🕵🏻"], + ]); +}); -- cgit v1.2.3