
META-INF.resources.page_editor.app.contexts.GlobalContext.tsx Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.layout.content.page.editor.web
Show all versions of com.liferay.layout.content.page.editor.web
Liferay Layout Content Page Editor Web
The newest version!
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
import ClayLoadingIndicator from '@clayui/loading-indicator';
import {ReactPortal, useIsMounted} from '@liferay/frontend-js-react-web';
import PropTypes from 'prop-types';
import React, {useContext, useEffect, useMemo, useState} from 'react';
import RawDOM from '../../common/components/RawDOM';
import {config} from '../config/index';
type GlobalContextValueType = {
document: Document;
iframe?: HTMLIFrameElement;
window: Window;
};
type GlobalContextType = [
GlobalContextValueType,
(value: GlobalContextValueType) => void,
];
const DEFAULT_GLOBAL_CONTEXT: GlobalContextValueType = {document, window};
const GlobalContext = React.createContext([
DEFAULT_GLOBAL_CONTEXT,
() => {},
]);
export function GlobalContextFrame({
children,
useIframe,
}: {
children: React.ReactNode;
useIframe: boolean;
}) {
const [baseElement, setBaseElement] = useState(null);
const [iframeContext, setIframeContext] =
useState(null);
const [iframeElement, setIframeElement] =
useState(null);
const isMounted = useIsMounted();
const [loadIframe, setLoadIframe] = useState(false);
const localContext = useMemo(() => ({document, window}), []);
const [, setGlobalContext] = useContext(GlobalContext);
useEffect(() => {
if (useIframe && !loadIframe) {
setLoadIframe(true);
}
}, [useIframe, loadIframe]);
useEffect(() => {
let timeoutId: NodeJS.Timeout | null = null;
const handleIframeLoaded = () => {
if (
!isMounted() ||
!iframeElement ||
!iframeElement.contentDocument
) {
return;
}
const pageEditorStylesLinkId = `${config.portletNamespace}pageEditorStylesLink`;
if (
!iframeElement.contentDocument?.getElementById(
pageEditorStylesLinkId
)
) {
const pageEditorStylesLink =
iframeElement.contentDocument.createElement('link');
pageEditorStylesLink.id = pageEditorStylesLinkId;
pageEditorStylesLink.rel = 'stylesheet';
pageEditorStylesLink.href = config.getIframeContentCssURL;
iframeElement.contentDocument.head.appendChild(
pageEditorStylesLink
);
}
const element =
iframeElement.contentDocument &&
(iframeElement.contentDocument.getElementById('content') ||
iframeElement.contentDocument.getElementById(
'main-content'
));
if (element) {
// False positive - react-compiler/react-compiler
// eslint-disable-next-line react-compiler/react-compiler
element.innerHTML = '';
iframeElement.contentWindow?.requestAnimationFrame(() => {
setBaseElement(element);
setIframeContext({
document: iframeElement.contentDocument!,
iframe: iframeElement,
window: iframeElement.contentWindow!,
});
});
}
else {
timeoutId = setTimeout(handleIframeLoaded, 100);
}
};
if (iframeElement) {
iframeElement.addEventListener('load', handleIframeLoaded);
iframeElement.src = config.getIframeContentURL;
}
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
if (iframeElement) {
iframeElement.removeEventListener('load', handleIframeLoaded);
}
if (isMounted()) {
setBaseElement(null);
setIframeContext(DEFAULT_GLOBAL_CONTEXT);
}
};
}, [iframeElement, isMounted]);
let context: GlobalContextValueType | null = null;
let content;
if (useIframe && baseElement && iframeContext) {
content = {children} ;
context = iframeContext;
iframeElement?.classList.remove(
'page-editor__global-context-iframe--hidden',
'page-editor__global-context-iframe--loading'
);
}
else if (!useIframe) {
content = <>{children}>;
context = localContext;
if (iframeElement) {
iframeElement.classList.add(
'page-editor__global-context-iframe--hidden'
);
}
}
else {
content = ;
context = localContext;
}
useEffect(() => {
setGlobalContext(context!);
}, [context, setGlobalContext]);
return (
<>
{content}
{loadIframe ? (
{
if (element) {
element.classList.add(
'page-editor__global-context-iframe',
'page-editor__global-context-iframe--loading'
);
}
setIframeElement(element as HTMLIFrameElement);
}}
/>
) : null}
>
);
}
GlobalContextFrame.propTypes = {
useIframe: PropTypes.bool,
};
export function GlobalContextProvider({children}: {children: React.ReactNode}) {
return (
{children}
);
}
export function useGlobalContext() {
const [globalContext] = useContext(GlobalContext);
return globalContext;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy