mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-08-01 18:26:06 -04:00
webapi: documents report the navigation response's content type
Fixes 9 failing files under /dom/nodes/Document-contentType/contentType/ (bmp, css, gif, jpg, mimeheader_01, png, txt, xml, and keeps the rest green): a document created from a non-HTML response (the synthesized image/text/raw documents) reported the text/html default from document.contentType instead of the response's MIME type. The frame records the response's MIME essence (type/subtype, lowercased, parameters stripped) when the first chunk arrives, and applies it to the new document's _content_type override once the navigation commits. text/html responses keep the default. The remaining file in the directory (contenttype_javascripturi) needs iframes to navigate to javascript: URLs and document their string result, which is a different mechanism. Coverage: /dom/nodes/Document-contentType/: 14/15 files passing (9 newly passing, 1 subtest each). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
committed by
Karl Seguin
parent
888d6fd52f
commit
bf56adeb16
@@ -236,6 +236,10 @@ _factory: *Factory,
|
||||
|
||||
_load_state: LoadState = .waiting,
|
||||
|
||||
// The navigation response's MIME essence, recorded when the first chunk
|
||||
// arrives and applied to the new document (document.contentType) once the
|
||||
// navigation commits. null means the text/html default.
|
||||
_pending_content_type: ?[]const u8 = null,
|
||||
_parse_state: ParseState = .pre,
|
||||
|
||||
/// `frameErrorCallback` swallows the failure into a placeholder page;
|
||||
@@ -1427,6 +1431,19 @@ fn frameDataCallback(transfer: *HttpClient.Transfer, data: []const u8) !void {
|
||||
});
|
||||
}
|
||||
|
||||
// Record the response's MIME essence so the resulting document
|
||||
// reports it (document.contentType); text/html stays the default.
|
||||
self._pending_content_type = null;
|
||||
if (transfer.contentType()) |ct| {
|
||||
const end = std.mem.indexOfScalar(u8, ct, ';') orelse ct.len;
|
||||
const essence = std.mem.trim(u8, ct[0..end], " \t");
|
||||
if (essence.len > 0 and !std.ascii.eqlIgnoreCase(essence, "text/html")) {
|
||||
const lower = try self.arena.dupe(u8, essence);
|
||||
_ = std.ascii.lowerString(lower, essence);
|
||||
self._pending_content_type = lower;
|
||||
}
|
||||
}
|
||||
|
||||
switch (mime.content_type) {
|
||||
.text_html => {
|
||||
// Normalize and store the charset using encoding_rs canonical names
|
||||
@@ -1501,6 +1518,11 @@ fn frameDoneCallback(ctx: *anyopaque) !void {
|
||||
//We need to handle different navigation types differently.
|
||||
try self._session.navigation.commitNavigation(self);
|
||||
|
||||
if (self._pending_content_type) |content_type| {
|
||||
self.document._content_type = content_type;
|
||||
self._pending_content_type = null;
|
||||
}
|
||||
|
||||
defer if (comptime IS_DEBUG) {
|
||||
log.debug(.frame, "frame load complete", .{
|
||||
.url = self.url,
|
||||
|
||||
Reference in New Issue
Block a user