From 4fa003668722c8dc5caf057cd5a96f6992d58804 Mon Sep 17 00:00:00 2001 From: "rudraswamy.c" Date: Fri, 2 Aug 2024 12:43:20 +0530 Subject: [PATCH] inline_script: inline script code to excute in PWA APP --- .../pagebuilder/lib/ContentTypes/Html/html.js | 6 +- .../peregrine/lib/hooks/useExecuteScripts.js | 65 +++++++++++++++++++ packages/peregrine/lib/index.js | 3 +- packages/peregrine/lib/util/nonceGenerator.js | 6 ++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 packages/peregrine/lib/hooks/useExecuteScripts.js create mode 100644 packages/peregrine/lib/util/nonceGenerator.js diff --git a/packages/pagebuilder/lib/ContentTypes/Html/html.js b/packages/pagebuilder/lib/ContentTypes/Html/html.js index 70670541ea..70ab84aec7 100644 --- a/packages/pagebuilder/lib/ContentTypes/Html/html.js +++ b/packages/pagebuilder/lib/ContentTypes/Html/html.js @@ -4,6 +4,7 @@ import { useStyle } from '@magento/venia-ui/lib/classify'; import { arrayOf, shape, string } from 'prop-types'; import { useHistory } from 'react-router-dom'; import handleHtmlContentClick from '../../handleHtmlContentClick'; +import {useExecuteScripts} from '@magento/peregrine/lib/hooks/useExecuteScripts' const toHTML = str => ({ __html: str }); @@ -60,12 +61,13 @@ const Html = props => { const clickHandler = event => { handleHtmlContentClick(history, event); }; - + const setRef = useExecuteScripts(html); return (
{ + return html.replace(//g, ''); +}; + +export const useExecuteScripts = htmlContent => { + const containerRef = useRef(null); + const lastScriptTagRef = useRef(null); + const originalDocumentWrite = document.write; + + useEffect(() => { + if (containerRef.current) { + /** + * Overriding the document.write function to make sure + * Javascript is writing the content in a place they intent to + * write instead of replacing the whole document. + * + */ + + document.write = function(content) { + console.log(lastScriptTagRef.current); + if (lastScriptTagRef.current) { + const span = document.createElement('span'); + const scriptNode = lastScriptTagRef.current; + span.innerHTML = content; + console.log(scriptNode); + if (scriptNode) scriptNode.after(span); + } else { + originalDocumentWrite.call(document, content); + } + }; + + // Remove HTML comments + const contentWithoutComments = removeHtmlComments(htmlContent); + containerRef.current.innerHTML = contentWithoutComments; + + const scriptTags = containerRef.current.querySelectorAll('script'); + + scriptTags.forEach(scriptTag => { + const newScript = document.createElement('script'); + const nonce = nonceGenerator(24); + newScript.type = scriptTag.type || 'text/javascript'; + newScript.setAttribute('nonce', nonce); + + if (scriptTag.src) { + newScript.src = scriptTag.src; + } else { + newScript.textContent = scriptTag.innerHTML; + } + + lastScriptTagRef.current = newScript; + + scriptTag.replaceWith(newScript); + }); + } + + return () => { + document.write = originalDocumentWrite; + }; + }, [htmlContent]); + + return containerRef; +}; diff --git a/packages/peregrine/lib/index.js b/packages/peregrine/lib/index.js index 13a2150fe0..27baa74152 100644 --- a/packages/peregrine/lib/index.js +++ b/packages/peregrine/lib/index.js @@ -1,3 +1,4 @@ +import { from } from '@apollo/client'; import * as RestApi from './RestApi'; import * as Util from './util'; @@ -12,7 +13,7 @@ export { useScrollLock } from './hooks/useScrollLock'; export { useSearchParam } from './hooks/useSearchParam'; export { useSort } from './hooks/useSort'; export { useTypePolicies } from './hooks/useTypePolicies'; - +export { useExecuteScripts } from './hooks/useExecuteScripts' export { WindowSizeContextProvider, useWindowSize diff --git a/packages/peregrine/lib/util/nonceGenerator.js b/packages/peregrine/lib/util/nonceGenerator.js new file mode 100644 index 0000000000..a7726d3497 --- /dev/null +++ b/packages/peregrine/lib/util/nonceGenerator.js @@ -0,0 +1,6 @@ +// Function to generate a random nonce +export const nonceGenerator = length => { + const array = new Uint8Array(length); + window.crypto.getRandomValues(array); + return btoa(String.fromCharCode.apply(null, array)).slice(0, length); +}; \ No newline at end of file