mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-09-20 19:49:27 -04:00
webapi: DOMParser capture owning frame for correct URL
The URL assigned to a document parsed via DOMParser should come from the Frame which created the DOMParser.
This commit is contained in:
3 files changed
+61
-9
No files matched your search
@@ -535,3 +535,15 @@
|
||||
testing.expectEqual('svg', svg.documentElement.localName);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=invalidType>
|
||||
{
|
||||
let err = null;
|
||||
try {
|
||||
new DOMParser().parseFromString('', 'text/foo');
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
testing.expectEqual(true, err instanceof TypeError);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script src="../testing.js"></script>
|
||||
|
||||
<!--
|
||||
The document DOMParser.parseFromString produces takes its URL from the
|
||||
DOMParser's own realm (the frame it was constructed in), not from the realm
|
||||
whose parseFromString is invoked.
|
||||
-->
|
||||
|
||||
<iframe id=if_dp src="support/cross_realm_collection.html"></iframe>
|
||||
|
||||
<script id=document_url_follows_the_parser_realm>
|
||||
testing.onload(() => {
|
||||
const iwin = document.getElementById('if_dp').contentWindow;
|
||||
const child_url = iwin.document.URL;
|
||||
testing.expectEqual(true, child_url !== document.URL);
|
||||
|
||||
for (const type of ['text/html', 'text/xml']) {
|
||||
const local = new DOMParser();
|
||||
const remote = new iwin.DOMParser();
|
||||
|
||||
let doc = local.parseFromString('<a/>', type);
|
||||
testing.expectEqual(document.URL, doc.URL);
|
||||
testing.expectEqual(document.URL, doc.baseURI);
|
||||
|
||||
doc = remote.parseFromString('<a/>', type);
|
||||
testing.expectEqual(child_url, doc.URL);
|
||||
testing.expectEqual(child_url, doc.documentURI);
|
||||
testing.expectEqual(child_url, doc.baseURI);
|
||||
|
||||
// method from the other realm, parser from this one (and vice versa)
|
||||
doc = iwin.DOMParser.prototype.parseFromString.call(local, '<a/>', type);
|
||||
testing.expectEqual(document.URL, doc.URL);
|
||||
doc = DOMParser.prototype.parseFromString.call(remote, '<a/>', type);
|
||||
testing.expectEqual(child_url, doc.URL);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -24,25 +24,24 @@ const Frame = @import("../Frame.zig");
|
||||
const Parser = @import("../parser/Parser.zig");
|
||||
|
||||
const Node = @import("Node.zig");
|
||||
const HTMLDocument = @import("HTMLDocument.zig");
|
||||
const Document = @import("Document.zig");
|
||||
const HTMLDocument = @import("HTMLDocument.zig");
|
||||
|
||||
const DOMParser = @This();
|
||||
|
||||
// Padding to avoid zero-size struct, which causes identity_map pointer collisions.
|
||||
_pad: bool = false,
|
||||
_frame: *Frame,
|
||||
|
||||
pub fn init() DOMParser {
|
||||
return .{};
|
||||
pub fn init(frame: *Frame) !*DOMParser {
|
||||
return frame._factory.create(DOMParser{ ._frame = frame });
|
||||
}
|
||||
|
||||
pub fn parseFromString(
|
||||
_: *const DOMParser,
|
||||
self: *const DOMParser,
|
||||
html: []const u8,
|
||||
mime_type: []const u8,
|
||||
frame: *Frame,
|
||||
) !*Document {
|
||||
const target_mime = std.meta.stringToEnum(SupportedType, mime_type) orelse return error.NotSupported;
|
||||
const frame = self._frame;
|
||||
const target_mime = std.meta.stringToEnum(SupportedType, mime_type) orelse return error.TypeError;
|
||||
|
||||
switch (target_mime) {
|
||||
.@"text/html" => {
|
||||
@@ -64,6 +63,7 @@ pub fn parseFromString(
|
||||
const doc = try frame._factory.document(HTMLDocument{
|
||||
._proto = undefined,
|
||||
});
|
||||
doc.asDocument()._url = frame.url;
|
||||
|
||||
var normalized = std.mem.trim(u8, html, &std.ascii.whitespace);
|
||||
if (normalized.len == 0) {
|
||||
@@ -86,6 +86,7 @@ pub fn parseFromString(
|
||||
else => {
|
||||
const xml_doc = (try Frame.parse.xmlDocument(frame, html)) orelse try parserErrorDocument(frame);
|
||||
const doc = xml_doc.asDocument();
|
||||
doc._url = frame.url;
|
||||
doc._content_type = @tagName(target_mime);
|
||||
return doc;
|
||||
},
|
||||
@@ -121,7 +122,6 @@ pub const JsApi = struct {
|
||||
pub const name = "DOMParser";
|
||||
pub const prototype_chain = bridge.prototypeChain();
|
||||
pub var class_id: bridge.ClassId = undefined;
|
||||
pub const empty_with_no_proto = true;
|
||||
};
|
||||
|
||||
pub const constructor = bridge.constructor(DOMParser.init, .{});
|
||||
|
||||
Reference in new issue
Block a user