Skip to content

Commit

Permalink
#4602: Add NONCE to inline style
Browse files Browse the repository at this point in the history
  • Loading branch information
melloware committed Jul 12, 2023
1 parent 27a9654 commit b54d021
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 29 deletions.
43 changes: 23 additions & 20 deletions components/lib/hooks/useStyle.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
import { useEffect, useRef, useState } from 'react';
import { DomHandler, ObjectUtils } from '../utils/Utils';
import PrimeReact, { PrimeReactContext } from '../api/Api';
import { DomHandler } from '../utils/Utils';

let _id = 0;

export const useStyle = (css = {}, options = {}) => {
export const useStyle = (css, options = {}) => {
const [isLoaded, setIsLoaded] = useState(false);
const styleRef = useRef(null);
const context = React.useContext(PrimeReactContext);

const cssRef = useRef(null);
const defaultDocument = DomHandler.isClient() ? window.document : undefined;
const { document = defaultDocument, immediate = true, manual = false, name = `primereact_style_${++_id}`, media } = options;
const { document = defaultDocument, immediate = true, manual = false, name = `style_${++_id}`, id = undefined, media = undefined } = options;

useEffect(() => {
cssRef.current = css;
}, [css]);
const update = (newCSS) => {
isLoaded && css !== newCSS && (styleRef.current.textContent = newCSS);
};

const load = () => {
if (!document) return;

const el = document.querySelector(`[data-pc-name="${name}"]`) || document.createElement('style');
styleRef.current = document.querySelector(`style[data-primereact-style-id="${name}"]`) || document.getElementById(id) || document.createElement('style');

if (ObjectUtils.isNotEmpty(el) || !el.isConnected) {
el.type = 'text/css';
el.setAttribute('data-pc-name', name);
if (media) el.media = media;
document.head.appendChild(el);
if (!styleRef.current.isConnected) {
styleRef.current.type = 'text/css';
id && (styleRef.current.id = id);
media && (styleRef.current.media = media);
DomHandler.addNonce(styleRef.current, (context && context.nonce) || PrimeReact.nonce);
document.head.appendChild(styleRef.current);
name && styleRef.current.setAttribute('data-primereact-style-id', name);
}

if (isLoaded) return;

el.textContent = cssRef.current;
styleRef.current.textContent = css;

setIsLoaded(true);
};

const unload = () => {
if (!document || !isLoaded) return;
const node = document.querySelector(`[data-pc-name="${name}"]`);

if (node && node.isConnected) {
document.head.removeChild(node);
setIsLoaded(false);
}
DomHandler.removeInlineStyle(styleRef.current);
setIsLoaded(false);
};

useEffect(() => {
Expand All @@ -50,8 +52,9 @@ export const useStyle = (css = {}, options = {}) => {
}, [immediate, manual]);

return {
id,
name,
css: cssRef,
update,
unload,
load,
isLoaded
Expand Down
22 changes: 13 additions & 9 deletions components/lib/utils/DomHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -981,15 +981,7 @@ export default class DomHandler {
static createInlineStyle(nonce) {
let styleElement = document.createElement('style');

try {
if (!nonce) {
nonce = process.env.REACT_APP_CSS_NONCE;
}
} catch (error) {
// NOOP
}

nonce && styleElement.setAttribute('nonce', nonce);
DomHandler.addNonce(styleElement, nonce);
document.head.appendChild(styleElement);

return styleElement;
Expand All @@ -1009,6 +1001,18 @@ export default class DomHandler {
return styleElement;
}

static addNonce(styleElement, nonce) {
try {
if (!nonce) {
nonce = process.env.REACT_APP_CSS_NONCE;
}
} catch (error) {
// NOOP
}

nonce && styleElement.setAttribute('nonce', nonce);
}

static getTargetElement(target) {
if (!target) return null;

Expand Down

0 comments on commit b54d021

Please sign in to comment.