From 9f6766f700dfc98ffefb244c081437a66466382c Mon Sep 17 00:00:00 2001 From: Justin Coyne Date: Fri, 19 Jan 2024 14:58:05 -0600 Subject: [PATCH] Patch Blacklight.modal.receiveAjax to execute recaptcha --- app/javascript/application.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/app/javascript/application.js b/app/javascript/application.js index 71ea15f90..c7068b292 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -52,6 +52,39 @@ import "./tooltip"; import "./truncate"; import "./update-hidden-inputs-by-checkbox"; + +// TODO: Remove this whole method when we upgrade to Blacklight 8, provided that +// https://github.com/projectblacklight/blacklight/pull/3133 is merged +// +// 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. +Blacklight.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(`${Blacklight.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)) + + // DOMParser doesn't allow scripts to be executed. This fixes that. + frag.querySelectorAll('script').forEach((script) => { + const fixedScript = document.createElement('script') + fixedScript.src = script.src + fixedScript.async = false + script.parentNode.replaceChild(fixedScript, script) + }) + + document.querySelector(`${Blacklight.modal.modalSelector} .modal-content`).replaceChildren(frag) + + Blacklight.modal.show(); +}; + + // Prevent the back-button from trying to add a second instance of recaptcha // See https://github.com/ambethia/recaptcha/issues/217#issuecomment-615221808 document.addEventListener("turbo:before-cache", function () {