diff --git a/src/browser/Page.zig b/src/browser/Page.zig index e61bee90..1e8fddeb 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -1460,6 +1460,8 @@ pub fn adoptNodeTree(self: *Page, node: *Node, new_owner: *Document) !void { } pub fn createElementNS(self: *Page, namespace: Element.Namespace, name: []const u8, attribute_iterator: anytype) !*Node { + const from_parser = @TypeOf(attribute_iterator) == Parser.AttributeIterator; + switch (namespace) { .html => { switch (name.len) { @@ -2130,6 +2132,15 @@ pub fn createElementNS(self: *Page, namespace: Element.Namespace, name: []const self.js.localScope(&ls); defer ls.deinit(); + if (from_parser) { + // There are some things custom elements aren't allowed to do + // when we're parsing. + self.document._throw_on_dynamic_markup_insertion_counter += 1; + } + defer if (from_parser) { + self.document._throw_on_dynamic_markup_insertion_counter -= 1; + }; + var caught: JS.TryCatch.Caught = undefined; _ = ls.toLocal(def.constructor).newInstance(&caught) catch |err| { log.warn(.js, "custom element constructor", .{ .name = name, .err = err, .caught = caught, .type = self._type, .url = self.url }); diff --git a/src/browser/parser/Parser.zig b/src/browser/parser/Parser.zig index 08adfb47..f259bdd5 100644 --- a/src/browser/parser/Parser.zig +++ b/src/browser/parser/Parser.zig @@ -23,6 +23,9 @@ const h5e = @import("html5ever.zig"); const Page = @import("../Page.zig"); const Node = @import("../webapi/Node.zig"); const Element = @import("../webapi/Element.zig"); + +pub const AttributeIterator = h5e.AttributeIterator; + const Allocator = std.mem.Allocator; const IS_DEBUG = @import("builtin").mode == .Debug; diff --git a/src/browser/tests/custom_elements/throw_on_dynamic_markup_insertion.html b/src/browser/tests/custom_elements/throw_on_dynamic_markup_insertion.html new file mode 100644 index 00000000..06739297 --- /dev/null +++ b/src/browser/tests/custom_elements/throw_on_dynamic_markup_insertion.html @@ -0,0 +1,66 @@ + +
+ + + + + +