@@ -451,6 +451,12 @@ pub const Page = struct {
451451 // if no src is present, we evaluate the text source.
452452 // https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model
453453 fn tryEvalScript (self : * Page , script : * const Script ) ! void {
454+ if (try script .alreadyProcessed ()) {
455+ return ;
456+ }
457+
458+ try script .markAsProcessed ();
459+
454460 const html_doc = self .window .document ;
455461 try parser .documentHTMLSetCurrentScript (html_doc , @ptrCast (script .element ));
456462
@@ -998,6 +1004,21 @@ const Script = struct {
9981004 return null ;
9991005 }
10001006
1007+ // If a script tag gets dynamically created and added to the dom:
1008+ // document.getElementsByTagName('head')[0].appendChild(script)
1009+ // that script tag will immediately get executed by our scriptAddedCallback.
1010+ // However, if the location where the script tag is inserted happens to be
1011+ // below where processHTMLDoc curently is, then we'll re-run that same script
1012+ // again in processHTMLDoc. This flag is used to let us know if a specific
1013+ // <script> has already been processed.
1014+ fn alreadyProcessed (self : * const Script ) ! bool {
1015+ return parser .scriptGetProcessed (@ptrCast (self .element ));
1016+ }
1017+
1018+ fn markAsProcessed (self : * const Script ) ! void {
1019+ return parser .scriptSetProcessed (@ptrCast (self .element ), true );
1020+ }
1021+
10011022 fn eval (self : * const Script , page : * Page , body : []const u8 ) ! void {
10021023 var try_catch : Env.TryCatch = undefined ;
10031024 try_catch .init (page .main_context );
0 commit comments