mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-16 08:18:59 +00:00
Fix typos
Encode unicode nonbreaking space
This commit is contained in:
@@ -486,7 +486,7 @@ pub const Client = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// called by CDP
|
// 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
|
// 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
|
// 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
|
// 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>
|
// Francis Bouvier <francis@lightpanda.io>
|
||||||
// Pierre Tachoire <pierre@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(cd.getData());
|
||||||
try writer.writeAll("-->");
|
try writer.writeAll("-->");
|
||||||
} else {
|
} else {
|
||||||
try writeEscapedText(cd.getData(), writer);
|
if (shouldEscapeText(node._parent)) {
|
||||||
|
try writeEscapedText(cd.getData(), writer);
|
||||||
|
} else {
|
||||||
|
try writer.writeAll(cd.getData());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.element => |el| {
|
.element => |el| {
|
||||||
@@ -245,34 +249,46 @@ fn shouldStripElement(el: *const Node.Element, opts: Opts) bool {
|
|||||||
return false;
|
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 {
|
fn writeEscapedText(text: []const u8, writer: *std.Io.Writer) !void {
|
||||||
// Fast path: if no special characters, write directly
|
// 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);
|
return writer.writeAll(text);
|
||||||
};
|
};
|
||||||
|
|
||||||
try writer.writeAll(text[0..first_special]);
|
try writer.writeAll(text[0..first_special]);
|
||||||
try writer.writeAll(switch (text[first_special]) {
|
var remaining = try writeEscapedByte(text, first_special, writer);
|
||||||
'&' => "&",
|
|
||||||
'<' => "<",
|
|
||||||
'>' => ">",
|
|
||||||
else => unreachable,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Process remaining text
|
while (std.mem.indexOfAnyPos(u8, remaining, 0, &.{ '&', '<', '>', 194 })) |offset| {
|
||||||
var remaining = text[first_special + 1 ..];
|
|
||||||
while (std.mem.indexOfAny(u8, remaining, "&<>")) |offset| {
|
|
||||||
try writer.writeAll(remaining[0..offset]);
|
try writer.writeAll(remaining[0..offset]);
|
||||||
try writer.writeAll(switch (remaining[offset]) {
|
remaining = try writeEscapedByte(remaining, offset, writer);
|
||||||
'&' => "&",
|
|
||||||
'<' => "<",
|
|
||||||
'>' => ">",
|
|
||||||
else => unreachable,
|
|
||||||
});
|
|
||||||
remaining = remaining[offset + 1 ..];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remaining.len > 0) {
|
if (remaining.len > 0) {
|
||||||
try writer.writeAll(remaining);
|
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') {
|
if (observed_ids[script_id] === 'fail') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
observed_ids[script_id] = status;
|
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() {
|
function _currentScriptId() {
|
||||||
@@ -201,17 +211,15 @@
|
|||||||
return `array: \n${value.map(_displayValue).join('\n')}\n`;
|
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 = [];
|
const seen = [];
|
||||||
return JSON.stringify(value, function(key, val) {
|
return JSON.stringify(value, function(key, val) {
|
||||||
if (val != null && typeof val == "object") {
|
if (val != null && typeof val == "object") {
|
||||||
if (seen.indexOf(val) >= 0) {
|
if (seen.indexOf(val) >= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
seen.push(val);
|
seen.push(val);
|
||||||
}
|
}
|
||||||
return 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);
|
_ = try attributes.putSafe(name, value, self, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getOrCreateAttributeList(self: *Element, page: *Page) !*Attribute.List {
|
pub fn getOrCreateAttributeList(self: *Element, page: *Page) !*Attribute.List {
|
||||||
return self._attributes orelse {
|
return self._attributes orelse return self.createAttributeList(page);
|
||||||
const a = try page.arena.create(Attribute.List);
|
}
|
||||||
a.* = .{};
|
|
||||||
self._attributes = a;
|
pub fn createAttributeList(self: *Element, page: *Page) !*Attribute.List {
|
||||||
return a;
|
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 {
|
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);
|
_ = try el.removeAttributeNode(attr, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
const attributes = self._attributes orelse blk: {
|
const attributes = try self.getOrCreateAttributeList(page);
|
||||||
const a = try page.arena.create(Attribute.List);
|
|
||||||
a.* = .{};
|
|
||||||
self._attributes = a;
|
|
||||||
break :blk a;
|
|
||||||
};
|
|
||||||
return attributes.putAttribute(attr, self, 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 src = bridge.accessor(Script.getSrc, Script.setSrc, .{});
|
||||||
pub const @"type" = bridge.accessor(Script.getType, Script.setType, .{});
|
pub const @"type" = bridge.accessor(Script.getType, Script.setType, .{});
|
||||||
pub const onload = bridge.accessor(Script.getOnLoad, Script.setOnLoad, .{});
|
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, .{});
|
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
|
// 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!).
|
// (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.
|
// 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.
|
// 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 {
|
pub fn createContext(self: *IsolatedWorld, page: *Page) !void {
|
||||||
// if (self.executor.context != null) return error.Only1IsolatedContextSupported;
|
// if (self.executor.context != null) return error.Only1IsolatedContextSupported;
|
||||||
|
|||||||
@@ -821,7 +821,7 @@ pub const Transfer = struct {
|
|||||||
self.deinit();
|
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
|
// abort. We don't call self.client.endTransfer here b/c it has been done
|
||||||
// before interception process.
|
// before interception process.
|
||||||
pub fn abortAuthChallenge(self: *Transfer) void {
|
pub fn abortAuthChallenge(self: *Transfer) void {
|
||||||
|
|||||||
Reference in New Issue
Block a user