fix dynamic script src attribute loading

This commit is contained in:
NaR82n
2026-07-29 19:30:14 +08:00
parent 5bbec625d0
commit d2d1efd703
3 changed files with 38 additions and 6 deletions

View File

@@ -42,3 +42,19 @@
testing.expectEqual(2, loaded2);
});
</script>
<script id=set_attribute_src>
loadedByAttribute = 0;
const attributeBeforeAppend = document.createElement('script');
attributeBeforeAppend.setAttribute('src', 'dynamic_attribute.js');
document.getElementsByTagName('head')[0].appendChild(attributeBeforeAppend);
const attributeAfterAppend = document.createElement('script');
document.getElementsByTagName('head')[0].appendChild(attributeAfterAppend);
attributeAfterAppend.setAttribute('src', 'dynamic_attribute.js');
testing.onload(() => {
testing.expectEqual(2, loadedByAttribute);
});
</script>

View File

@@ -0,0 +1 @@
loadedByAttribute += 1;

View File

@@ -16,6 +16,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
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 <script> doesn't run it again.
pub fn cloned(source_element: *Element, cloned_element: *Element, deep: bool, _: *Frame) !void {