mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1728 from lightpanda-io/about_blank
Some checks failed
e2e-test / zig build release (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / zig build release (push) Has been cancelled
wpt / build wpt runner (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
Some checks failed
e2e-test / zig build release (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / zig build release (push) Has been cancelled
wpt / build wpt runner (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
Optimize about:blank loading in general and for frames specifically
This commit is contained in:
@@ -477,12 +477,10 @@ pub fn navigate(self: *Page, request_url: [:0]const u8, opts: NavigateOpts) !voi
|
|||||||
// It's important to force a reset during the following navigation.
|
// It's important to force a reset during the following navigation.
|
||||||
self._parse_state = .complete;
|
self._parse_state = .complete;
|
||||||
|
|
||||||
{
|
self.document.injectBlank(self) catch |err| {
|
||||||
const parse_arena = try self.getArena(.{ .debug = "about:blank parse" });
|
log.err(.browser, "inject blank", .{ .err = err });
|
||||||
defer self.releaseArena(parse_arena);
|
return error.InjectBlankFailed;
|
||||||
var parser = Parser.init(parse_arena, self.document.asNode(), self);
|
};
|
||||||
parser.parse("<html><head></head><body></body></html>");
|
|
||||||
}
|
|
||||||
self.documentIsComplete();
|
self.documentIsComplete();
|
||||||
|
|
||||||
session.notification.dispatch(.page_navigate, &.{
|
session.notification.dispatch(.page_navigate, &.{
|
||||||
@@ -1035,9 +1033,9 @@ pub fn iframeAddedCallback(self: *Page, iframe: *IFrame) !void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const src = iframe.asElement().getAttributeSafe(comptime .wrap("src")) orelse return;
|
var src = iframe.asElement().getAttributeSafe(comptime .wrap("src")) orelse "";
|
||||||
if (src.len == 0) {
|
if (src.len == 0) {
|
||||||
return;
|
src = "about:blank";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iframe._window != null) {
|
if (iframe._window != null) {
|
||||||
@@ -2920,11 +2918,6 @@ fn nodeIsReady(self: *Page, comptime from_parser: bool, node: *Node) !void {
|
|||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
} else if (node.is(IFrame)) |iframe| {
|
} else if (node.is(IFrame)) |iframe| {
|
||||||
if ((comptime from_parser == false) and iframe._src.len == 0) {
|
|
||||||
// iframe was added via JavaScript, but without a src
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.iframeAddedCallback(iframe) catch |err| {
|
self.iframeAddedCallback(iframe) catch |err| {
|
||||||
log.err(.page, "page.nodeIsReady", .{ .err = err, .element = "iframe", .type = self._type, .url = self.url });
|
log.err(.page, "page.nodeIsReady", .{ .err = err, .element = "iframe", .type = self._type, .url = self.url });
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -7,46 +7,59 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<iframe id=f1 onload="frame1Onload" src="support/sub 1.html"></iframe>
|
<iframe id=f0></iframe>
|
||||||
|
<iframe id=f1 onload="frame1Onload()" src="support/sub 1.html"></iframe>
|
||||||
<iframe id=f2 src="support/sub2.html"></iframe>
|
<iframe id=f2 src="support/sub2.html"></iframe>
|
||||||
|
|
||||||
|
<script id=empty>
|
||||||
|
{
|
||||||
|
const blank = document.createElement('iframe');
|
||||||
|
testing.expectEqual(null, blank.contentDocument);
|
||||||
|
document.documentElement.appendChild(blank);
|
||||||
|
testing.expectEqual('<html><head></head><body></body></html>', blank.contentDocument.documentElement.outerHTML);
|
||||||
|
|
||||||
|
const f0 = $('#f0')
|
||||||
|
testing.expectEqual('<html><head></head><body></body></html>', f0.contentDocument.documentElement.outerHTML);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script id="basic">
|
<script id="basic">
|
||||||
// reload it
|
// reload it
|
||||||
$('#f2').src = 'support/sub2.html';
|
$('#f2').src = 'support/sub2.html';
|
||||||
testing.expectEqual(true, true);
|
testing.expectEqual(true, true);
|
||||||
|
|
||||||
testing.eventually(() => {
|
testing.eventually(() => {
|
||||||
testing.expectEqual(undefined, window[10]);
|
testing.expectEqual(undefined, window[20]);
|
||||||
|
|
||||||
testing.expectEqual(window, window[0].top);
|
|
||||||
testing.expectEqual(window, window[0].parent);
|
|
||||||
testing.expectEqual(false, window === window[0]);
|
|
||||||
|
|
||||||
testing.expectEqual(window, window[1].top);
|
testing.expectEqual(window, window[1].top);
|
||||||
testing.expectEqual(window, window[1].parent);
|
testing.expectEqual(window, window[1].parent);
|
||||||
testing.expectEqual(false, window === window[1]);
|
testing.expectEqual(false, window === window[1]);
|
||||||
testing.expectEqual(false, window[0] === window[1]);
|
|
||||||
|
testing.expectEqual(window, window[2].top);
|
||||||
|
testing.expectEqual(window, window[2].parent);
|
||||||
|
testing.expectEqual(false, window === window[2]);
|
||||||
|
testing.expectEqual(false, window[1] === window[2]);
|
||||||
|
|
||||||
testing.expectEqual(0, $('#f1').childNodes.length);
|
testing.expectEqual(0, $('#f1').childNodes.length);
|
||||||
|
|
||||||
testing.expectEqual(testing.BASE_URL + 'frames/support/sub%201.html', $('#f1').src);
|
testing.expectEqual(testing.BASE_URL + 'frames/support/sub%201.html', $('#f1').src);
|
||||||
testing.expectEqual(window[0], $('#f1').contentWindow);
|
testing.expectEqual(window[1], $('#f1').contentWindow);
|
||||||
testing.expectEqual(window[1], $('#f2').contentWindow);
|
testing.expectEqual(window[2], $('#f2').contentWindow);
|
||||||
|
|
||||||
testing.expectEqual(window[0].document, $('#f1').contentDocument);
|
testing.expectEqual(window[1].document, $('#f1').contentDocument);
|
||||||
testing.expectEqual(window[1].document, $('#f2').contentDocument);
|
testing.expectEqual(window[2].document, $('#f2').contentDocument);
|
||||||
|
|
||||||
// sibling frames share the same top
|
// sibling frames share the same top
|
||||||
testing.expectEqual(window[0].top, window[1].top);
|
testing.expectEqual(window[1].top, window[2].top);
|
||||||
|
|
||||||
// child frames have no sub-frames
|
// child frames have no sub-frames
|
||||||
testing.expectEqual(0, window[0].length);
|
|
||||||
testing.expectEqual(0, window[1].length);
|
testing.expectEqual(0, window[1].length);
|
||||||
|
testing.expectEqual(0, window[2].length);
|
||||||
|
|
||||||
// self and window are self-referential on child frames
|
// self and window are self-referential on child frames
|
||||||
testing.expectEqual(window[0], window[0].self);
|
|
||||||
testing.expectEqual(window[0], window[0].window);
|
|
||||||
testing.expectEqual(window[1], window[1].self);
|
testing.expectEqual(window[1], window[1].self);
|
||||||
|
testing.expectEqual(window[1], window[1].window);
|
||||||
|
testing.expectEqual(window[2], window[2].self);
|
||||||
|
|
||||||
// child frame's top.parent is itself (root has no parent)
|
// child frame's top.parent is itself (root has no parent)
|
||||||
testing.expectEqual(window, window[0].top.parent);
|
testing.expectEqual(window, window[0].top.parent);
|
||||||
@@ -127,6 +140,6 @@
|
|||||||
|
|
||||||
<script id=count>
|
<script id=count>
|
||||||
testing.eventually(() => {
|
testing.eventually(() => {
|
||||||
testing.expectEqual(6, window.length);
|
testing.expectEqual(8, window.length);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ const Selection = @import("Selection.zig");
|
|||||||
pub const XMLDocument = @import("XMLDocument.zig");
|
pub const XMLDocument = @import("XMLDocument.zig");
|
||||||
pub const HTMLDocument = @import("HTMLDocument.zig");
|
pub const HTMLDocument = @import("HTMLDocument.zig");
|
||||||
|
|
||||||
|
const IS_DEBUG = @import("builtin").mode == .Debug;
|
||||||
|
|
||||||
const Document = @This();
|
const Document = @This();
|
||||||
|
|
||||||
_type: Type,
|
_type: Type,
|
||||||
@@ -937,6 +939,32 @@ fn validateElementName(name: []const u8) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When a page or frame's URL is about:blank, or as soon as a frame is
|
||||||
|
// programmatically created, it has this default "blank" content
|
||||||
|
pub fn injectBlank(self: *Document, page: *Page) error{InjectBlankError}!void {
|
||||||
|
self._injectBlank(page) catch |err| {
|
||||||
|
// we wrap _injectBlank like this so that injectBlank can only return an
|
||||||
|
// InjectBlankError. injectBlank is used in when nodes are inserted
|
||||||
|
// as since it inserts node itself, Zig can't infer the error set.
|
||||||
|
log.err(.browser, "inject blank", .{ .err = err });
|
||||||
|
return error.InjectBlankError;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _injectBlank(self: *Document, page: *Page) !void {
|
||||||
|
if (comptime IS_DEBUG) {
|
||||||
|
// should only be called on an empty document
|
||||||
|
std.debug.assert(self.asNode()._children == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
const html = try page.createElementNS(.html, "html", null);
|
||||||
|
const head = try page.createElementNS(.html, "head", null);
|
||||||
|
const body = try page.createElementNS(.html, "body", null);
|
||||||
|
try page.appendNode(html, head, .{});
|
||||||
|
try page.appendNode(html, body, .{});
|
||||||
|
try page.appendNode(self.asNode(), html, .{});
|
||||||
|
}
|
||||||
|
|
||||||
const ReadyState = enum {
|
const ReadyState = enum {
|
||||||
loading,
|
loading,
|
||||||
interactive,
|
interactive,
|
||||||
|
|||||||
Reference in New Issue
Block a user