diff --git a/src/browser/tests/element/html/script/dynamic.html b/src/browser/tests/element/html/script/dynamic.html index a6a0179c1..d67b1ef2e 100644 --- a/src/browser/tests/element/html/script/dynamic.html +++ b/src/browser/tests/element/html/script/dynamic.html @@ -42,3 +42,19 @@ testing.expectEqual(2, loaded2); }); + + diff --git a/src/browser/tests/element/html/script/dynamic_attribute.js b/src/browser/tests/element/html/script/dynamic_attribute.js new file mode 100644 index 000000000..fb2bbac5a --- /dev/null +++ b/src/browser/tests/element/html/script/dynamic_attribute.js @@ -0,0 +1 @@ +loadedByAttribute += 1; diff --git a/src/browser/webapi/element/html/Script.zig b/src/browser/webapi/element/html/Script.zig index 72ca44a38..7c3c9864f 100644 --- a/src/browser/webapi/element/html/Script.zig +++ b/src/browser/webapi/element/html/Script.zig @@ -16,6 +16,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . const std = @import("std"); +const lp = @import("lightpanda"); const js = @import("../../../js/js.zig"); const Frame = @import("../../../Frame.zig"); @@ -24,6 +25,7 @@ const Node = @import("../../Node.zig"); const Element = @import("../../Element.zig"); const HtmlElement = @import("../Html.zig"); +const String = lp.String; const Script = @This(); _proto: *HtmlElement, @@ -50,12 +52,7 @@ pub fn getSrc(self: *Script, frame: *Frame) ![]const u8 { } pub fn setSrc(self: *Script, src: []const u8, frame: *Frame) !void { - const element = self.asElement(); - try element.setAttributeSafe(comptime .wrap("src"), .wrap(src), frame); - self._src = element.getAttributeSafe(comptime .wrap("src")) orelse unreachable; - if (element.asNode().isConnected()) { - try frame.scriptAddedCallback(false, self); - } + try self.asElement().setAttributeSafe(comptime .wrap("src"), .wrap(src), frame); } pub fn getType(self: *const Script) []const u8 { @@ -164,6 +161,24 @@ pub const Build = struct { self._src = element.getAttributeSafe(comptime .wrap("src")) orelse ""; } + pub fn attributeChange(element: *Element, name: String, _: String, frame: *Frame) !void { + if (!name.eql(comptime .wrap("src"))) { + return; + } + + const self = element.as(Script); + self._src = element.getAttributeSafe(comptime .wrap("src")) orelse ""; + if (element.asNode().isConnected()) { + try frame.scriptAddedCallback(false, self); + } + } + + pub fn attributeRemove(element: *Element, name: String, _: *Frame) !void { + if (name.eql(comptime .wrap("src"))) { + element.as(Script)._src = ""; + } + } + // Per the HTML spec, the "already started" flag must be propagated to the // clone so that re-inserting a cloned