@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
JavaScript
;
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;