UNPKG

@uiw/react-iframe

Version:

This component allows you to wrap your entire React application or each component in an iFrame.

131 lines (130 loc) 4.98 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "FrameContext", { enumerable: true, get: function get() { return _Context.FrameContext; } }); exports["default"] = void 0; Object.defineProperty(exports, "useFrame", { enumerable: true, get: function get() { return _Context.useFrame; } }); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = require("react"); var _reactDom = require("react-dom"); var _Context = require("./Context"); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["children", "head", "initialContent", "src", "mountTarget"]; var IFrame = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) { var children = _ref.children, head = _ref.head, initialContent = _ref.initialContent, src = _ref.src, mountTarget = _ref.mountTarget, other = (0, _objectWithoutProperties2["default"])(_ref, _excluded); var _useState = (0, _react.useState)(false), _useState2 = (0, _slicedToArray2["default"])(_useState, 2), iframeLoaded = _useState2[0], setIframeLoaded = _useState2[1]; var _useState3 = (0, _react.useState)(), _useState4 = (0, _slicedToArray2["default"])(_useState3, 2), mountNode = _useState4[0], setMountNode = _useState4[1]; var refContent = function refContent(node) { if (node) { setMountNode(node); } }; (0, _react.useImperativeHandle)(ref, function () { return mountNode; }, [mountNode]); var html = initialContent || "<!DOCTYPE html><html><head></head><body></body></html>"; var getDoc = function getDoc() { return mountNode ? mountNode.contentDocument : null; }; var getMountTarget = function getMountTarget() { var doc = getDoc(); if (mountTarget) { return doc === null || doc === void 0 ? void 0 : doc.querySelector(mountTarget); } return doc === null || doc === void 0 ? void 0 : doc.body; }; var evnRef = (0, _react.useRef)(); var handleLoad = (0, _react.useCallback)(function (evn) { evnRef.current = evn; /** * In certain situations on a cold cache DOMContentLoaded never gets called * fallback to an interval to check if that's the case */ var loadCheck = function loadCheck() { return setInterval(function () { return handleLoad(evn); }, 500); }; clearInterval(loadCheck()); // Bail update as some browsers will trigger on both DOMContentLoaded & onLoad ala firefox if (!iframeLoaded) { setIframeLoaded(true); } }, [iframeLoaded]); (0, _react.useMemo)(function () { if (!src && other.onLoad && iframeLoaded) { other.onLoad(evnRef.current); } }, [iframeLoaded]); (0, _react.useEffect)(function () { if (mountNode && !src) { var _mountNode$contentWin; (_mountNode$contentWin = mountNode.contentWindow) === null || _mountNode$contentWin === void 0 || _mountNode$contentWin.addEventListener('DOMContentLoaded', handleLoad); } return function () { if (mountNode && !src) { var _mountNode$contentWin2; (_mountNode$contentWin2 = mountNode.contentWindow) === null || _mountNode$contentWin2 === void 0 || _mountNode$contentWin2.removeEventListener('DOMContentLoaded', handleLoad); } }; }, [mountNode, handleLoad]); var renderFrameContents = function renderFrameContents() { var _getDoc; var doc = getDoc(); var header = (_getDoc = getDoc()) === null || _getDoc === void 0 ? void 0 : _getDoc.head; var mountTarget = getMountTarget(); // @ts-ignore var win = (doc === null || doc === void 0 ? void 0 : doc.defaultView) || (doc === null || doc === void 0 ? void 0 : doc.parentView); var contents = /*#__PURE__*/(0, _jsxRuntime.jsx)(_Context.FrameContext.Provider, { value: { document: doc, window: win }, children: children }); return [header && head && /*#__PURE__*/(0, _reactDom.createPortal)(head, header), mountNode && mountTarget && /*#__PURE__*/(0, _reactDom.createPortal)(contents, mountTarget)]; }; var reProps = {}; if (src) { delete reProps.srcDoc; reProps.src = src; reProps.onLoad = other.onLoad; } else { reProps.srcDoc = html; } return /*#__PURE__*/(0, _jsxRuntime.jsx)("iframe", (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({ title: other.title, ref: refContent }, other), {}, { onLoad: handleLoad }, reProps), {}, { children: iframeLoaded && renderFrameContents() })); }); IFrame.displayName = 'IFrame'; var _default = exports["default"] = IFrame;