From 24a4164f5ebbe96b897e99616cfcb79e7b8e0bef Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 11 Oct 2023 16:49:12 +0200 Subject: [PATCH 1/5] dom: add missing tags according with https://wpt.live/dom/nodes/Node-cloneNode.html test --- src/html/elements.zig | 46 +++++++++++++++++++++++++++++++-- src/netsurf.zig | 60 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/html/elements.zig b/src/html/elements.zig index 17df069a..0d93c3d6 100644 --- a/src/html/elements.zig +++ b/src/html/elements.zig @@ -5,6 +5,7 @@ const Element = @import("../dom/element.zig").Element; // HTMLElement interfaces pub const Interfaces = .{ + HTMLElement, HTMLUnknownElement, HTMLAnchorElement, HTMLAreaElement, @@ -16,11 +17,15 @@ pub const Interfaces = .{ HTMLCanvasElement, HTMLDListElement, HTMLDataElement, + HTMLDataListElement, HTMLDialogElement, + HTMLDirectoryElement, HTMLDivElement, HTMLEmbedElement, HTMLFieldSetElement, + HTMLFontElement, HTMLFormElement, + HTMLFrameElement, HTMLFrameSetElement, HTMLHRElement, HTMLHeadElement, @@ -43,6 +48,7 @@ pub const Interfaces = .{ HTMLOptionElement, HTMLOutputElement, HTMLParagraphElement, + HTMLParamElement, HTMLPictureElement, HTMLPreElement, HTMLProgressElement, @@ -161,12 +167,24 @@ pub const HTMLDataElement = struct { pub const mem_guarantied = true; }; +pub const HTMLDataListElement = struct { + pub const Self = parser.DataList; + pub const prototype = *HTMLElement; + pub const mem_guarantied = true; +}; + pub const HTMLDialogElement = struct { pub const Self = parser.Dialog; pub const prototype = *HTMLElement; pub const mem_guarantied = true; }; +pub const HTMLDirectoryElement = struct { + pub const Self = parser.Directory; + pub const prototype = *HTMLElement; + pub const mem_guarantied = true; +}; + pub const HTMLDivElement = struct { pub const Self = parser.Div; pub const prototype = *HTMLElement; @@ -185,12 +203,24 @@ pub const HTMLFieldSetElement = struct { pub const mem_guarantied = true; }; +pub const HTMLFontElement = struct { + pub const Self = parser.Font; + pub const prototype = *HTMLElement; + pub const mem_guarantied = true; +}; + pub const HTMLFormElement = struct { pub const Self = parser.Form; pub const prototype = *HTMLElement; pub const mem_guarantied = true; }; +pub const HTMLFrameElement = struct { + pub const Self = parser.Frame; + pub const prototype = *HTMLElement; + pub const mem_guarantied = true; +}; + pub const HTMLFrameSetElement = struct { pub const Self = parser.FrameSet; pub const prototype = *HTMLElement; @@ -323,6 +353,12 @@ pub const HTMLParagraphElement = struct { pub const mem_guarantied = true; }; +pub const HTMLParamElement = struct { + pub const Self = parser.Param; + pub const prototype = *HTMLElement; + pub const mem_guarantied = true; +}; + pub const HTMLPictureElement = struct { pub const Self = parser.Picture; pub const prototype = *HTMLElement; @@ -459,21 +495,26 @@ pub fn toInterface(comptime T: type, e: *parser.Element) T { const elem: *align(@alignOf(*parser.Element)) parser.Element = @alignCast(e); const tag = parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem))); return switch (tag) { + .abbr, .acronym, .address, .article, .aside, .b, .bdi, .bdo, .bgsound, .big, .center, .cite, .code, .dd, .details, .dfn, .dt, .figcaption, .figure, .footer, .header, .hgroup, .i, .isindex, .kbd, .main, .mark, .marquee, .nav, .nobr, .noframes, .noscript, .rp, .rt, .ruby, .s, .samp, .section, .small, .spacer, .strike, .sub, .summary, .sup, .tt, .u, .wbr, ._var => .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(elem)) }, .a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(elem)) }, .area => .{ .HTMLAreaElement = @as(*parser.Area, @ptrCast(elem)) }, .audio => .{ .HTMLAudioElement = @as(*parser.Audio, @ptrCast(elem)) }, - .br => .{ .HTMLBRElement = @as(*parser.BR, @ptrCast(elem)) }, .base => .{ .HTMLBaseElement = @as(*parser.Base, @ptrCast(elem)) }, .body => .{ .HTMLBodyElement = @as(*parser.Body, @ptrCast(elem)) }, + .br => .{ .HTMLBRElement = @as(*parser.BR, @ptrCast(elem)) }, .button => .{ .HTMLButtonElement = @as(*parser.Button, @ptrCast(elem)) }, .canvas => .{ .HTMLCanvasElement = @as(*parser.Canvas, @ptrCast(elem)) }, .dl => .{ .HTMLDListElement = @as(*parser.DList, @ptrCast(elem)) }, .data => .{ .HTMLDataElement = @as(*parser.Data, @ptrCast(elem)) }, + .datalist => .{ .HTMLDataListElement = @as(*parser.DataList, @ptrCast(elem)) }, .dialog => .{ .HTMLDialogElement = @as(*parser.Dialog, @ptrCast(elem)) }, + .dir => .{ .HTMLDirectoryElement = @as(*parser.Directory, @ptrCast(elem)) }, .div => .{ .HTMLDivElement = @as(*parser.Div, @ptrCast(elem)) }, .embed => .{ .HTMLEmbedElement = @as(*parser.Embed, @ptrCast(elem)) }, .fieldset => .{ .HTMLFieldSetElement = @as(*parser.FieldSet, @ptrCast(elem)) }, + .font => .{ .HTMLFontElement = @as(*parser.Font, @ptrCast(elem)) }, .form => .{ .HTMLFormElement = @as(*parser.Form, @ptrCast(elem)) }, + .frame => .{ .HTMLFrameElement = @as(*parser.Frame, @ptrCast(elem)) }, .frameset => .{ .HTMLFrameSetElement = @as(*parser.FrameSet, @ptrCast(elem)) }, .hr => .{ .HTMLHRElement = @as(*parser.HR, @ptrCast(elem)) }, .head => .{ .HTMLHeadElement = @as(*parser.Head, @ptrCast(elem)) }, @@ -496,6 +537,7 @@ pub fn toInterface(comptime T: type, e: *parser.Element) T { .option => .{ .HTMLOptionElement = @as(*parser.Option, @ptrCast(elem)) }, .output => .{ .HTMLOutputElement = @as(*parser.Output, @ptrCast(elem)) }, .p => .{ .HTMLParagraphElement = @as(*parser.Paragraph, @ptrCast(elem)) }, + .param => .{ .HTMLParamElement = @as(*parser.Param, @ptrCast(elem)) }, .picture => .{ .HTMLPictureElement = @as(*parser.Picture, @ptrCast(elem)) }, .pre => .{ .HTMLPreElement = @as(*parser.Pre, @ptrCast(elem)) }, .progress => .{ .HTMLProgressElement = @as(*parser.Progress, @ptrCast(elem)) }, @@ -508,7 +550,7 @@ pub fn toInterface(comptime T: type, e: *parser.Element) T { .table => .{ .HTMLTableElement = @as(*parser.Table, @ptrCast(elem)) }, .caption => .{ .HTMLTableCaptionElement = @as(*parser.TableCaption, @ptrCast(elem)) }, .th, .td => .{ .HTMLTableCellElement = @as(*parser.TableCell, @ptrCast(elem)) }, - .col => .{ .HTMLTableColElement = @as(*parser.TableCol, @ptrCast(elem)) }, + .col, .colgroup => .{ .HTMLTableColElement = @as(*parser.TableCol, @ptrCast(elem)) }, .tr => .{ .HTMLTableRowElement = @as(*parser.TableRow, @ptrCast(elem)) }, .thead, .tbody, .tfoot => .{ .HTMLTableSectionElement = @as(*parser.TableSection, @ptrCast(elem)) }, .template => .{ .HTMLTemplateElement = @as(*parser.Template, @ptrCast(elem)) }, diff --git a/src/netsurf.zig b/src/netsurf.zig index 03b2efb0..b114a298 100644 --- a/src/netsurf.zig +++ b/src/netsurf.zig @@ -68,41 +68,81 @@ inline fn stringFromData(data: []const u8) *String { // Tag pub const Tag = enum(u8) { + acronym = 123, // TODO c.DOM_HTML_ELEMENT_TYPE_ACRONYM, + bgsound = 124, // TODO c.DOM_HTML_ELEMENT_TYPE_BGSOUND, + big = 125, // TODO c.DOM_HTML_ELEMENT_TYPE_BIG, + marquee = 127, // TODO c.DOM_HTML_ELEMENT_TYPE_MARQUEE, + nobr = 128, // TODO c.DOM_HTML_ELEMENT_TYPE_NOBR, + noframes = 129, // TODO c.DOM_HTML_ELEMENT_TYPE_NOFRAMES, + spacer = 130, // TODO c.DOM_HTML_ELEMENT_TYPE_SPACER, + strike = 131, // TODO c.DOM_HTML_ELEMENT_TYPE_STRIKE, + tt = 132, // TODO c.DOM_HTML_ELEMENT_TYPE_TT, + a = c.DOM_HTML_ELEMENT_TYPE_A, + abbr = c.DOM_HTML_ELEMENT_TYPE_ABBR, + address = c.DOM_HTML_ELEMENT_TYPE_ADDRESS, + article = c.DOM_HTML_ELEMENT_TYPE_ARTICLE, + aside = c.DOM_HTML_ELEMENT_TYPE_ASIDE, area = c.DOM_HTML_ELEMENT_TYPE_AREA, audio = c.DOM_HTML_ELEMENT_TYPE_AUDIO, + b = c.DOM_HTML_ELEMENT_TYPE_B, + bdi = c.DOM_HTML_ELEMENT_TYPE_BDI, + bdo = c.DOM_HTML_ELEMENT_TYPE_BDO, br = c.DOM_HTML_ELEMENT_TYPE_BR, base = c.DOM_HTML_ELEMENT_TYPE_BASE, body = c.DOM_HTML_ELEMENT_TYPE_BODY, button = c.DOM_HTML_ELEMENT_TYPE_BUTTON, canvas = c.DOM_HTML_ELEMENT_TYPE_CANVAS, + center = c.DOM_HTML_ELEMENT_TYPE_CENTER, + cite = c.DOM_HTML_ELEMENT_TYPE_CITE, + code = c.DOM_HTML_ELEMENT_TYPE_CODE, + dd = c.DOM_HTML_ELEMENT_TYPE_DD, + details = c.DOM_HTML_ELEMENT_TYPE_DETAILS, + dfn = c.DOM_HTML_ELEMENT_TYPE_DFN, + dt = c.DOM_HTML_ELEMENT_TYPE_DT, dl = c.DOM_HTML_ELEMENT_TYPE_DL, dialog = c.DOM_HTML_ELEMENT_TYPE_DIALOG, data = c.DOM_HTML_ELEMENT_TYPE_DATA, + datalist = c.DOM_HTML_ELEMENT_TYPE_DATALIST, + dir = c.DOM_HTML_ELEMENT_TYPE_DIR, div = c.DOM_HTML_ELEMENT_TYPE_DIV, embed = c.DOM_HTML_ELEMENT_TYPE_EMBED, + figcaption = c.DOM_HTML_ELEMENT_TYPE_FIGCAPTION, + figure = c.DOM_HTML_ELEMENT_TYPE_FIGURE, fieldset = c.DOM_HTML_ELEMENT_TYPE_FIELDSET, + footer = c.DOM_HTML_ELEMENT_TYPE_FOOTER, + font = c.DOM_HTML_ELEMENT_TYPE_FONT, form = c.DOM_HTML_ELEMENT_TYPE_FORM, + frame = c.DOM_HTML_ELEMENT_TYPE_FRAME, frameset = c.DOM_HTML_ELEMENT_TYPE_FRAMESET, hr = c.DOM_HTML_ELEMENT_TYPE_HR, head = c.DOM_HTML_ELEMENT_TYPE_HEAD, + header = c.DOM_HTML_ELEMENT_TYPE_HEADER, h1 = c.DOM_HTML_ELEMENT_TYPE_H1, h2 = c.DOM_HTML_ELEMENT_TYPE_H2, h3 = c.DOM_HTML_ELEMENT_TYPE_H3, h4 = c.DOM_HTML_ELEMENT_TYPE_H4, h5 = c.DOM_HTML_ELEMENT_TYPE_H5, h6 = c.DOM_HTML_ELEMENT_TYPE_H6, + hgroup = c.DOM_HTML_ELEMENT_TYPE_HGROUP, html = c.DOM_HTML_ELEMENT_TYPE_HTML, + i = c.DOM_HTML_ELEMENT_TYPE_I, + isindex = c.DOM_HTML_ELEMENT_TYPE_ISINDEX, iframe = c.DOM_HTML_ELEMENT_TYPE_IFRAME, img = c.DOM_HTML_ELEMENT_TYPE_IMG, input = c.DOM_HTML_ELEMENT_TYPE_INPUT, + kbd = c.DOM_HTML_ELEMENT_TYPE_KBD, li = c.DOM_HTML_ELEMENT_TYPE_LI, label = c.DOM_HTML_ELEMENT_TYPE_LABEL, legend = c.DOM_HTML_ELEMENT_TYPE_LEGEND, link = c.DOM_HTML_ELEMENT_TYPE_LINK, + main = c.DOM_HTML_ELEMENT_TYPE_MAIN, map = c.DOM_HTML_ELEMENT_TYPE_MAP, + mark = c.DOM_HTML_ELEMENT_TYPE_MARK, meta = c.DOM_HTML_ELEMENT_TYPE_META, meter = c.DOM_HTML_ELEMENT_TYPE_METER, + nav = c.DOM_HTML_ELEMENT_TYPE_NAV, + noscript = c.DOM_HTML_ELEMENT_TYPE_NOSCRIPT, ins = c.DOM_HTML_ELEMENT_TYPE_INS, del = c.DOM_HTML_ELEMENT_TYPE_DEL, ol = c.DOM_HTML_ELEMENT_TYPE_OL, @@ -111,11 +151,22 @@ pub const Tag = enum(u8) { option = c.DOM_HTML_ELEMENT_TYPE_OPTION, output = c.DOM_HTML_ELEMENT_TYPE_OUTPUT, p = c.DOM_HTML_ELEMENT_TYPE_P, + param = c.DOM_HTML_ELEMENT_TYPE_PARAM, picture = c.DOM_HTML_ELEMENT_TYPE_PICTURE, pre = c.DOM_HTML_ELEMENT_TYPE_PRE, progress = c.DOM_HTML_ELEMENT_TYPE_PROGRESS, blockquote = c.DOM_HTML_ELEMENT_TYPE_BLOCKQUOTE, q = c.DOM_HTML_ELEMENT_TYPE_Q, + rp = c.DOM_HTML_ELEMENT_TYPE_RP, + rt = c.DOM_HTML_ELEMENT_TYPE_RT, + ruby = c.DOM_HTML_ELEMENT_TYPE_RUBY, + s = c.DOM_HTML_ELEMENT_TYPE_S, + samp = c.DOM_HTML_ELEMENT_TYPE_SAMP, + section = c.DOM_HTML_ELEMENT_TYPE_SECTION, + small = c.DOM_HTML_ELEMENT_TYPE_SMALL, + sub = c.DOM_HTML_ELEMENT_TYPE_SUB, + summary = c.DOM_HTML_ELEMENT_TYPE_SUMMARY, + sup = c.DOM_HTML_ELEMENT_TYPE_SUP, script = c.DOM_HTML_ELEMENT_TYPE_SCRIPT, select = c.DOM_HTML_ELEMENT_TYPE_SELECT, source = c.DOM_HTML_ELEMENT_TYPE_SOURCE, @@ -126,6 +177,7 @@ pub const Tag = enum(u8) { th = c.DOM_HTML_ELEMENT_TYPE_TH, td = c.DOM_HTML_ELEMENT_TYPE_TD, col = c.DOM_HTML_ELEMENT_TYPE_COL, + colgroup = c.DOM_HTML_ELEMENT_TYPE_COLGROUP, tr = c.DOM_HTML_ELEMENT_TYPE_TR, thead = c.DOM_HTML_ELEMENT_TYPE_THEAD, tbody = c.DOM_HTML_ELEMENT_TYPE_TBODY, @@ -135,8 +187,11 @@ pub const Tag = enum(u8) { time = c.DOM_HTML_ELEMENT_TYPE_TIME, title = c.DOM_HTML_ELEMENT_TYPE_TITLE, track = c.DOM_HTML_ELEMENT_TYPE_TRACK, + u = c.DOM_HTML_ELEMENT_TYPE_U, ul = c.DOM_HTML_ELEMENT_TYPE_UL, + _var = c.DOM_HTML_ELEMENT_TYPE_VAR, video = c.DOM_HTML_ELEMENT_TYPE_VIDEO, + wbr = c.DOM_HTML_ELEMENT_TYPE_WBR, undef = c.DOM_HTML_ELEMENT_TYPE__UNKNOWN, pub fn all() []Tag { @@ -583,11 +638,15 @@ pub const Button = c.dom_html_button_element; pub const Canvas = c.dom_html_canvas_element; pub const DList = c.dom_html_dlist_element; pub const Data = struct { base: *c.dom_html_element }; +pub const DataList = struct { base: *c.dom_html_element }; pub const Dialog = struct { base: *c.dom_html_element }; +pub const Directory = struct { base: *c.dom_html_element }; pub const Div = c.dom_html_div_element; pub const Embed = struct { base: *c.dom_html_element }; pub const FieldSet = c.dom_html_field_set_element; pub const Form = c.dom_html_form_element; +pub const Font = c.dom_html_font_element; +pub const Frame = c.dom_html_frame_element; pub const FrameSet = c.dom_html_frame_set_element; pub const HR = c.dom_html_hr_element; pub const Head = c.dom_html_head_element; @@ -610,6 +669,7 @@ pub const OptGroup = c.dom_html_opt_group_element; pub const Option = c.dom_html_option_element; pub const Output = struct { base: *c.dom_html_element }; pub const Paragraph = c.dom_html_paragraph_element; +pub const Param = c.dom_html_param_element; pub const Picture = struct { base: *c.dom_html_element }; pub const Pre = c.dom_html_pre_element; pub const Progress = struct { base: *c.dom_html_element }; From 18b4c2c0027d92cc06f6d7f14c77dbe6284725d5 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 18 Oct 2023 15:23:33 +0200 Subject: [PATCH 2/5] vendor: use libdom fork --- .gitmodules | 2 +- vendor/netsurf/libdom | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 46314c3a..e6ff1e85 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://source.netsurf-browser.org/libparserutils.git [submodule "vendor/netsurf/libdom"] path = vendor/netsurf/libdom - url = https://source.netsurf-browser.org/libdom.git + url = git@github.com:Browsercore/libdom.git [submodule "vendor/netsurf/share/netsurf-buildsystem"] path = vendor/netsurf/share/netsurf-buildsystem url = https://source.netsurf-browser.org/buildsystem.git diff --git a/vendor/netsurf/libdom b/vendor/netsurf/libdom index 176bab60..eb25a0d9 160000 --- a/vendor/netsurf/libdom +++ b/vendor/netsurf/libdom @@ -1 +1 @@ -Subproject commit 176bab60eb10beb68fbbb1a6185c68eeda2a6e95 +Subproject commit eb25a0d90fe6979ec43b7dca72cbd83630fb2b06 From 091a7fec9a3b0ee35c2f5582adc579d52ec05f76 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 18 Oct 2023 15:24:12 +0200 Subject: [PATCH 3/5] netsurf: use the missing tags from libdom --- src/netsurf.zig | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/netsurf.zig b/src/netsurf.zig index b114a298..5e368d98 100644 --- a/src/netsurf.zig +++ b/src/netsurf.zig @@ -68,16 +68,15 @@ inline fn stringFromData(data: []const u8) *String { // Tag pub const Tag = enum(u8) { - acronym = 123, // TODO c.DOM_HTML_ELEMENT_TYPE_ACRONYM, - bgsound = 124, // TODO c.DOM_HTML_ELEMENT_TYPE_BGSOUND, - big = 125, // TODO c.DOM_HTML_ELEMENT_TYPE_BIG, - marquee = 127, // TODO c.DOM_HTML_ELEMENT_TYPE_MARQUEE, - nobr = 128, // TODO c.DOM_HTML_ELEMENT_TYPE_NOBR, - noframes = 129, // TODO c.DOM_HTML_ELEMENT_TYPE_NOFRAMES, - spacer = 130, // TODO c.DOM_HTML_ELEMENT_TYPE_SPACER, - strike = 131, // TODO c.DOM_HTML_ELEMENT_TYPE_STRIKE, - tt = 132, // TODO c.DOM_HTML_ELEMENT_TYPE_TT, - + acronym = c.DOM_HTML_ELEMENT_TYPE_ACRONYM, + bgsound = c.DOM_HTML_ELEMENT_TYPE_BGSOUND, + big = c.DOM_HTML_ELEMENT_TYPE_BIG, + marquee = c.DOM_HTML_ELEMENT_TYPE_MARQUEE, + nobr = c.DOM_HTML_ELEMENT_TYPE_NOBR, + noframes = c.DOM_HTML_ELEMENT_TYPE_NOFRAMES, + spacer = c.DOM_HTML_ELEMENT_TYPE_SPACER, + strike = c.DOM_HTML_ELEMENT_TYPE_STRIKE, + tt = c.DOM_HTML_ELEMENT_TYPE_TT, a = c.DOM_HTML_ELEMENT_TYPE_A, abbr = c.DOM_HTML_ELEMENT_TYPE_ABBR, address = c.DOM_HTML_ELEMENT_TYPE_ADDRESS, From cff27ecbd2cbc27522a6893380dbec455b71f1aa Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 18 Oct 2023 15:24:47 +0200 Subject: [PATCH 4/5] document: remove constructor comparison from test Now the tag's constructor can be HTMLElement, so previous basic test is invalid. --- src/dom/document.zig | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/dom/document.zig b/src/dom/document.zig index 55f73dc9..7e2ac989 100644 --- a/src/dom/document.zig +++ b/src/dom/document.zig @@ -59,22 +59,14 @@ pub fn testExecFn( try checkCases(js_env, &getElementById); const tags = comptime parser.Tag.all(); - const elements = comptime parser.Tag.allElements(); - comptime var createElements: [(tags.len) * 3]Case = undefined; - inline for (tags, elements, 0..) |tag, element_name, i| { - // if (tag == .undef) { - // continue; - // } + comptime var createElements: [(tags.len) * 2]Case = undefined; + inline for (tags, 0..) |tag, i| { const tag_name = @tagName(tag); - createElements[i * 3] = Case{ + createElements[i * 2] = Case{ .src = "var " ++ tag_name ++ "Elem = document.createElement('" ++ tag_name ++ "')", .ex = "undefined", }; - createElements[(i * 3) + 1] = Case{ - .src = tag_name ++ "Elem.constructor.name", - .ex = "HTML" ++ element_name ++ "Element", - }; - createElements[(i * 3) + 2] = Case{ + createElements[(i * 2) + 1] = Case{ .src = tag_name ++ "Elem.localName", .ex = tag_name, }; From d15ad1e5d8d7693edb383f54ff993e53549d4347 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Thu, 19 Oct 2023 15:17:18 +0200 Subject: [PATCH 5/5] vendor: update netsurf/libdom@master --- vendor/netsurf/libdom | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/netsurf/libdom b/vendor/netsurf/libdom index eb25a0d9..74a553b0 160000 --- a/vendor/netsurf/libdom +++ b/vendor/netsurf/libdom @@ -1 +1 @@ -Subproject commit eb25a0d90fe6979ec43b7dca72cbd83630fb2b06 +Subproject commit 74a553b093550e34d63fb61fc310546a9b511b4c