From 99229513ba5ec6f668951bbbfe6e5e0217087235 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Sat, 10 May 2025 17:00:57 +0200 Subject: [PATCH] implement TextEncoder --- src/browser/encoding/text_encoder.zig | 64 +++++++++++++++++++++++++++ src/browser/env.zig | 1 + 2 files changed, 65 insertions(+) create mode 100644 src/browser/encoding/text_encoder.zig diff --git a/src/browser/encoding/text_encoder.zig b/src/browser/encoding/text_encoder.zig new file mode 100644 index 00000000..5bf9b7d7 --- /dev/null +++ b/src/browser/encoding/text_encoder.zig @@ -0,0 +1,64 @@ +// Copyright (C) 2023-2024 Lightpanda (Selecy SAS) +// +// Francis Bouvier +// Pierre Tachoire +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +const std = @import("std"); + +const Env = @import("../env.zig").Env; + +pub const Interfaces = .{ + TextEncoder, +}; + +// https://encoding.spec.whatwg.org/#interface-textencoder +pub const TextEncoder = struct { + pub fn constructor() !TextEncoder { + return .{}; + } + + pub fn get_encoding(_: *const TextEncoder) []const u8 { + return "utf-8"; + } + + pub fn _encode(_: *const TextEncoder, v: []const u8) !Env.TypedArray(u8) { + // Ensure the input is a valid utf-8 + // It seems chrome accepts invalid utf-8 sequence. + // + if (!std.unicode.utf8ValidateSlice(v)) { + return error.InvalidUtf8; + } + + return .{ .values = v }; + } +}; + +const testing = @import("../../testing.zig"); +test "Browser.Encoding.TextEncoder" { + var runner = try testing.jsRunner(testing.tracking_allocator, .{}); + defer runner.deinit(); + + try runner.testCases(&.{ + .{ "var encoder = new TextEncoder();", "undefined" }, + .{ "encoder.encoding;", "utf-8" }, + .{ "encoder.encode('€');", "226,130,172" }, + + // Invalid utf-8 sequence. + // Result with chrome: + // .{ "encoder.encode(new Uint8Array([0xE2,0x28,0xA1]))", "50,50,54,44,52,48,44,49,54,49" }, + .{ "try {encoder.encode(new Uint8Array([0xE2,0x28,0xA1])) } catch (e) { e };", "Error: InvalidUtf8" }, + }, .{}); +} diff --git a/src/browser/env.zig b/src/browser/env.zig index 3f04ff09..8d3e253b 100644 --- a/src/browser/env.zig +++ b/src/browser/env.zig @@ -28,6 +28,7 @@ const WebApis = struct { @import("crypto/crypto.zig").Crypto, @import("console/console.zig").Console, @import("dom/dom.zig").Interfaces, + @import("encoding/text_encoder.zig").Interfaces, @import("events/event.zig").Interfaces, @import("html/html.zig").Interfaces, @import("iterator/iterator.zig").Interfaces,