Repository: wagtail/wagtail
File: client/src/entrypoints/admin/telepath/widgets.js (JavaScript)

Code before:

  render(
    placeholder,
    name,
    id,
    initialState,
    parentCapabilities,
    options = {},
  ) {
    const html = this.html.replace(/__NAME__/g, name).replace(/__ID__/g, id);
    const idForLabel = this.idPattern.replace(/__ID__/g, id);

    /* write the HTML into a temp container to parse it into an element */
    const tempContainer = document.createElement('div');
    tempContainer.innerHTML = html.trim();
    const dom = tempContainer.firstChild;

    /* replace the placeholder with the new element */
    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);
    });

    // Add any extra attributes we received to the HTML of the widget
    if (typeof options?.attributes === 'object') {
      Object.entries(options.attributes).forEach(([key, value]) => {
        dom.setAttribute(key, value);
      });
    }

    // eslint-disable-next-line new-cap
    return new this.boundWidgetClass(
      dom,
      name,
      idForLabel,
      initialState,
      parentCapabilities,
      options,
    );
  }
}
window.telepath.register('wagtail.widgets.Widget', Widget);

class BoundCheckboxInput extends BoundWidget {
  getValue() {
    return this.input.checked;
  }

Review comment (suggestion):
Note that this would only execute inline scripts, and scripts with `src`s will be replaced with empty scripts (as the attributes are not carried over).

I did something similar for the `TeleportController`, but only targeted scripts without `src` and without an explicit `type`, and retain any attributes from the original script element:

https://github.com/wagtail/wagtail/blob/e653a4afbb7f61e0e27e74e60a96981ca1d27f60/client/src/controllers/TeleportController.ts#L104-L113

Code after:
  boundWidgetClass = BoundWidget;

  render(
    placeholder,
    name,
    id,
    initialState,
    parentCapabilities,
    options = {},
  ) {
    const html = this.html.replace(/__NAME__/g, name).replace(/__ID__/g, id);
    const idForLabel = this.idPattern.replace(/__ID__/g, id);

    /* write the HTML into a temp container to parse it into an element */
    const tempContainer = document.createElement('div');
    tempContainer.innerHTML = html.trim();
    const dom = tempContainer.firstChild;

    /* replace the placeholder with the new element */
    placeholder.replaceWith(dom);

    /* execute any scripts in the new element */
    runInlineScripts(dom);

    // Add any extra attributes we received to the HTML of the widget
    if (typeof options?.attributes === 'object') {
      Object.entries(options.attributes).forEach(([key, value]) => {
        dom.setAttribute(key, value);
      });
    }

    // eslint-disable-next-line new-cap
    return new this.boundWidgetClass(
      dom,
      name,
      idForLabel,
      initialState,
      parentCapabilities,
      options,
    );
  }
}
window.telepath.register('wagtail.widgets.Widget', Widget);

class BoundCheckboxInput extends BoundWidget {
  getValue() {
    return this.input.checked;
  }

  getState() {
    return this.input.checked;