0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-29 01:22:07 +01:00

Split out a reusable runInlineScripts utility function and handle attributes correctly

This commit is contained in:
Matt Westcott 2024-04-16 14:13:53 +01:00 committed by Sage Abdullah
parent 57d407d0eb
commit bb3e58abd0
No known key found for this signature in database
GPG Key ID: EB1A33CC51CC0217
3 changed files with 24 additions and 15 deletions

View File

@ -1,4 +1,5 @@
import { Controller } from '@hotwired/stimulus';
import { runInlineScripts } from '../utils/runInlineScripts';
/**
* Allows the controlled element's content to be copied and appended
@ -101,16 +102,7 @@ export class TeleportController extends Controller<HTMLTemplateElement> {
// and copy the attributes and innerHTML over. This is necessary when we're
// teleporting a template that contains legacy init code, e.g. initDateChooser.
// Only do this for inline scripts, as that's what we're expecting.
templateFragment
.querySelectorAll('script:not([src], [type])')
.forEach((script) => {
const newScript = document.createElement('script');
Array.from(script.attributes).forEach((key) =>
newScript.setAttribute(key.nodeName, key.nodeValue || ''),
);
newScript.innerHTML = script.innerHTML;
script.replaceWith(newScript);
});
runInlineScripts(templateFragment);
return templateFragment;
}

View File

@ -1,4 +1,5 @@
import { gettext } from '../../../utils/gettext';
import { runInlineScripts } from '../../../utils/runInlineScripts';
class BoundWidget {
constructor(
@ -79,11 +80,7 @@ class Widget {
placeholder.replaceWith(dom);
/* execute any scripts in the new element */
dom.querySelectorAll('script').forEach((script) => {
const newScript = document.createElement('script');
newScript.text = script.text;
script.replaceWith(newScript);
});
runInlineScripts(dom);
// Add any extra attributes we received to the HTML of the widget
if (typeof options?.attributes === 'object') {

View File

@ -0,0 +1,20 @@
/**
* Runs any inline scripts contained within the given DOM element or fragment.
*/
const runInlineScripts = (element: HTMLElement | DocumentFragment) => {
const scripts = element.querySelectorAll(
'script:not([src])',
) as NodeListOf<HTMLScriptElement>;
scripts.forEach((script) => {
if (!script.type || script.type === 'application/javascript') {
const newScript = document.createElement('script');
Array.from(script.attributes).forEach((key) =>
newScript.setAttribute(key.nodeName, key.nodeValue || ''),
);
newScript.text = script.text;
script.replaceWith(newScript);
}
});
};
export { runInlineScripts };