mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-15 15:58:57 +00:00
Fix typos
Encode unicode nonbreaking space
This commit is contained in:
@@ -486,7 +486,7 @@ pub const Client = struct {
|
||||
}
|
||||
|
||||
// called by CDP
|
||||
// Websocket frames have a variable lenght header. For server-client,
|
||||
// Websocket frames have a variable length header. For server-client,
|
||||
// it could be anywhere from 2 to 10 bytes. Our IO.Loop doesn't have
|
||||
// writev, so we need to get creative. We'll JSON serialize to a
|
||||
// buffer, where the first 10 bytes are reserved. We can then backfill
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2023-2025 Lightpanda (Selecy SAS)
|
||||
// Copyright (C) 2023-2025 Lightpanda (Selecy SAS)
|
||||
//
|
||||
// Francis Bouvier <francis@lightpanda.io>
|
||||
// Pierre Tachoire <pierre@lightpanda.io>
|
||||
@@ -74,7 +74,11 @@ fn _deep(node: *Node, opts: Opts, comptime force_slot: bool, writer: *std.Io.Wri
|
||||
try writer.writeAll(cd.getData());
|
||||
try writer.writeAll("-->");
|
||||
} else {
|
||||
try writeEscapedText(cd.getData(), writer);
|
||||
if (shouldEscapeText(node._parent)) {
|
||||
try writeEscapedText(cd.getData(), writer);
|
||||
} else {
|
||||
try writer.writeAll(cd.getData());
|
||||
}
|
||||
}
|
||||
},
|
||||
.element => |el| {
|
||||
@@ -245,34 +249,46 @@ fn shouldStripElement(el: *const Node.Element, opts: Opts) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
fn shouldEscapeText(node_: ?*Node) bool {
|
||||
const node = node_ orelse return true;
|
||||
if (node.is(Node.Element.Html.Script) != null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
fn writeEscapedText(text: []const u8, writer: *std.Io.Writer) !void {
|
||||
// Fast path: if no special characters, write directly
|
||||
const first_special = std.mem.indexOfAny(u8, text, "&<>") orelse {
|
||||
const first_special = std.mem.indexOfAnyPos(u8, text, 0, &.{ '&', '<', '>', 194 }) orelse {
|
||||
return writer.writeAll(text);
|
||||
};
|
||||
|
||||
try writer.writeAll(text[0..first_special]);
|
||||
try writer.writeAll(switch (text[first_special]) {
|
||||
'&' => "&",
|
||||
'<' => "<",
|
||||
'>' => ">",
|
||||
else => unreachable,
|
||||
});
|
||||
var remaining = try writeEscapedByte(text, first_special, writer);
|
||||
|
||||
// Process remaining text
|
||||
var remaining = text[first_special + 1 ..];
|
||||
while (std.mem.indexOfAny(u8, remaining, "&<>")) |offset| {
|
||||
while (std.mem.indexOfAnyPos(u8, remaining, 0, &.{ '&', '<', '>', 194 })) |offset| {
|
||||
try writer.writeAll(remaining[0..offset]);
|
||||
try writer.writeAll(switch (remaining[offset]) {
|
||||
'&' => "&",
|
||||
'<' => "<",
|
||||
'>' => ">",
|
||||
else => unreachable,
|
||||
});
|
||||
remaining = remaining[offset + 1 ..];
|
||||
remaining = try writeEscapedByte(remaining, offset, writer);
|
||||
}
|
||||
|
||||
if (remaining.len > 0) {
|
||||
try writer.writeAll(remaining);
|
||||
}
|
||||
}
|
||||
|
||||
fn writeEscapedByte(input: []const u8, index: usize, writer: *std.Io.Writer) ![]const u8 {
|
||||
switch (input[index]) {
|
||||
'&' => try writer.writeAll("&"),
|
||||
'<' => try writer.writeAll("<"),
|
||||
'>' => try writer.writeAll(">"),
|
||||
194 => {
|
||||
// non breaking space
|
||||
if (input.len > index + 1 and input[index + 1] == 160) {
|
||||
try writer.writeAll(" ");
|
||||
return input [index + 2 ..];
|
||||
}
|
||||
try writer.writeByte(194);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
return input[index + 1..];
|
||||
}
|
||||
|
||||
@@ -164,7 +164,17 @@
|
||||
if (observed_ids[script_id] === 'fail') {
|
||||
return;
|
||||
}
|
||||
|
||||
observed_ids[script_id] = status;
|
||||
|
||||
if (document.currentScript != null) {
|
||||
if (document.currentScript.onerror === null) {
|
||||
document.currentScript.onerror = function() {
|
||||
observed_ids[document.currentScript.id] = 'fail';
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _currentScriptId() {
|
||||
@@ -201,17 +211,15 @@
|
||||
return `array: \n${value.map(_displayValue).join('\n')}\n`;
|
||||
}
|
||||
|
||||
// Quickjs can deal with cyclical objects, but browsers can't. We
|
||||
// serialize with a custom replacer so that the tests can be run in browsers.
|
||||
const seen = [];
|
||||
return JSON.stringify(value, function(key, val) {
|
||||
if (val != null && typeof val == "object") {
|
||||
if (seen.indexOf(val) >= 0) {
|
||||
return;
|
||||
}
|
||||
seen.push(val);
|
||||
}
|
||||
return val;
|
||||
});
|
||||
if (val != null && typeof val == "object") {
|
||||
if (seen.indexOf(val) >= 0) {
|
||||
return;
|
||||
}
|
||||
seen.push(val);
|
||||
}
|
||||
return val;
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -336,13 +336,16 @@ pub fn setAttributeSafe(self: *Element, name: []const u8, value: []const u8, pag
|
||||
_ = try attributes.putSafe(name, value, self, page);
|
||||
}
|
||||
|
||||
fn getOrCreateAttributeList(self: *Element, page: *Page) !*Attribute.List {
|
||||
return self._attributes orelse {
|
||||
const a = try page.arena.create(Attribute.List);
|
||||
a.* = .{};
|
||||
self._attributes = a;
|
||||
return a;
|
||||
};
|
||||
pub fn getOrCreateAttributeList(self: *Element, page: *Page) !*Attribute.List {
|
||||
return self._attributes orelse return self.createAttributeList(page);
|
||||
}
|
||||
|
||||
pub fn createAttributeList(self: *Element, page: *Page) !*Attribute.List {
|
||||
std.debug.assert(self._attributes == null);
|
||||
const a = try page.arena.create(Attribute.List);
|
||||
a.* = .{.normalize = self._namespace == .html};
|
||||
self._attributes = a;
|
||||
return a;
|
||||
}
|
||||
|
||||
pub fn getShadowRoot(self: *Element, page: *Page) ?*ShadowRoot {
|
||||
@@ -370,12 +373,7 @@ pub fn setAttributeNode(self: *Element, attr: *Attribute, page: *Page) !?*Attrib
|
||||
_ = try el.removeAttributeNode(attr, page);
|
||||
}
|
||||
|
||||
const attributes = self._attributes orelse blk: {
|
||||
const a = try page.arena.create(Attribute.List);
|
||||
a.* = .{};
|
||||
self._attributes = a;
|
||||
break :blk a;
|
||||
};
|
||||
const attributes = try self.getOrCreateAttributeList(page);
|
||||
return attributes.putAttribute(attr, self, page);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ pub const JsApi = struct {
|
||||
pub const src = bridge.accessor(Script.getSrc, Script.setSrc, .{});
|
||||
pub const @"type" = bridge.accessor(Script.getType, Script.setType, .{});
|
||||
pub const onload = bridge.accessor(Script.getOnLoad, Script.setOnLoad, .{});
|
||||
pub const onerorr = bridge.accessor(Script.getOnError, Script.setOnError, .{});
|
||||
pub const onerror = bridge.accessor(Script.getOnError, Script.setOnError, .{});
|
||||
pub const noModule = bridge.accessor(Script.getNoModule, null, .{});
|
||||
};
|
||||
|
||||
|
||||
@@ -724,7 +724,7 @@ const IsolatedWorld = struct {
|
||||
// The isolate world must share at least some of the state with the related page, specifically the DocumentHTML
|
||||
// (assuming grantUniveralAccess will be set to True!).
|
||||
// We just created the world and the page. The page's state lives in the session, but is update on navigation.
|
||||
// This also means this pointer becomes invalid after removePage untill a new page is created.
|
||||
// This also means this pointer becomes invalid after removePage until a new page is created.
|
||||
// Currently we have only 1 page/frame and thus also only 1 state in the isolate world.
|
||||
pub fn createContext(self: *IsolatedWorld, page: *Page) !void {
|
||||
// if (self.executor.context != null) return error.Only1IsolatedContextSupported;
|
||||
|
||||
@@ -821,7 +821,7 @@ pub const Transfer = struct {
|
||||
self.deinit();
|
||||
}
|
||||
|
||||
// abortAuthChallenge is called when an auth chanllenge interception is
|
||||
// abortAuthChallenge is called when an auth challenge interception is
|
||||
// abort. We don't call self.client.endTransfer here b/c it has been done
|
||||
// before interception process.
|
||||
pub fn abortAuthChallenge(self: *Transfer) void {
|
||||
|
||||
Reference in New Issue
Block a user