app/javascript/blacklight/modal.js in blacklight-8.1.0 vs app/javascript/blacklight/modal.js in blacklight-8.2.0
- old
+ new
@@ -50,11 +50,11 @@
One additional feature. If the content returned from the AJAX form submission
can be a turbo-stream that defines some HTML fragementsand where on the page to put them:
https://turbo.hotwired.dev/handbook/streams
*/
-import ModalForm from 'blacklight/modalForm'
+import ModalForm from './modalForm.js'
const Modal = (() => {
const modal = {}
// a Bootstrap modal div that should be already on the page hidden
@@ -95,24 +95,38 @@
modal.show();
}
// Add the passed in contents to the modal and display it.
+ // We have specific handling so that scripts returned from the ajax call are executed.
+ // This enables adding a script like recaptcha to prevent bots from sending emails.
modal.receiveAjax = function (contents) {
- const domparser = new DOMParser();
- const dom = domparser.parseFromString(contents, "text/html")
- // If there is a containerSelector on the document, use its children.
- let elements = dom.querySelectorAll(`${modal.containerSelector} > *`)
- if (elements.length == 0) {
- // If the containerSelector wasn't found, use the whole document
- elements = dom.body.childNodes
- }
+ const domparser = new DOMParser();
+ const dom = domparser.parseFromString(contents, "text/html")
+ // If there is a containerSelector on the document, use its children.
+ let elements = dom.querySelectorAll(`${modal.containerSelector} > *`)
+ const frag = document.createDocumentFragment()
+ if (elements.length == 0) {
+ // If the containerSelector wasn't found, use the whole document
+ elements = dom.body.childNodes
+ }
+ elements.forEach((el) => frag.appendChild(el))
+ modal.activateScripts(frag)
+
+ document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(frag)
- document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(...elements)
-
- modal.show();
+ modal.show();
};
+ // DOMParser doesn't allow scripts to be executed. This fixes that.
+ modal.activateScripts = function (frag) {
+ frag.querySelectorAll('script').forEach((script) => {
+ const fixedScript = document.createElement('script')
+ fixedScript.src = script.src
+ fixedScript.async = false
+ script.parentNode.replaceChild(fixedScript, script)
+ })
+ }
modal.modalAjaxLinkClick = function(e) {
e.preventDefault();
const href = e.target.getAttribute('href')
fetch(href)