1+ import React from "react" ;
2+ import { isWithinIframe } from "../utils/iframe.js" ;
3+
4+ // This is a wrapper component that works with https://www.npmjs.com/package/iframe-resizer
5+ // to allow the components detect that they are within an iframe who's parent is running iframeresizer
6+ // so they can change styles and act differently
7+
8+ export default class IframeResizerInParent extends React . Component {
9+ // iframe-resizer will create window.iFrameResizer
10+ // this code adds additional properties to that
11+
12+ static inParent ( ) { // true if component is running in an iframe and the parent is running iframe-resizer
13+ return window . iFrameResizer ?. inParent ;
14+ }
15+
16+ static onInParent ( cb ) { // when iframe-resizer is started by the parent, execute the call back so the component can rerender or something
17+ // iframe-resizer will create window.iFrameResize when it runs, but it may not exist yet
18+ if ( ! window . iFrameResizer ) window . iFrameResizer = { } ;
19+ if ( ! window . iFrameResizer . onInParent ) window . iFrameResizer . onInParent = [ ] ;
20+ window . iFrameResizer . onInParent . push ( cb ) ;
21+ }
22+
23+ static _detected ( ...args ) {
24+ // we are running in an iframe, and the parent has just started iframe-resizer
25+ if ( ! args [ 0 ] . data . includes ( '[iFrameSizer]' ) ) return ;
26+ if ( ! window . iFrameResizer ) window . iFrameResizer = { } ;
27+ window . iFrameResizer . inParent = true ;
28+ /*There could be multiple components needing to be re-rendered after iframe resizer starts, each will add a callback
29+ * to the array: onInParent.
30+ * Components may need to rerender after iframeresizer starts because their style needs to change if rendering
31+ * in an iframe that resizes v. rendering in an iframe that doesn't resize.
32+ */
33+ let func ;
34+ while ( ( func = window . iFrameResizer . onInParent ?. shift ( ) ) )
35+ func ( ) ;
36+ window . removeEventListener ( 'message' , IframeResizerInParent . _detected ) ;
37+ }
38+
39+ componentDidMount ( ) {
40+ // if page is not running within an iframe, this component is just a pass through
41+ if ( window && document && isWithinIframe ( ) ) {
42+ // we are running within an iframe
43+ // allow parent frame to determine background color
44+ document . getElementsByTagName ( 'body' ) [ 0 ] . style . backgroundColor = 'transparent' ;
45+ // be prepared to detect IframeResizer has been run in parent window
46+ window . addEventListener ( 'message' , IframeResizerInParent . _detected ) ;
47+ // add the child side (in the iframe) javascript code to this page -- it's only relevant if running within an iframe
48+ const script = document . createElement ( 'script' ) ;
49+ const body = document . getElementsByTagName ( 'body' ) [ 0 ] ;
50+ script . src = '/static/iframeResizer.contentWindow.min.js' ;
51+ body . appendChild ( script ) ;
52+ }
53+ }
54+ render ( ) : Array < React$Node > {
55+ return this . props . children ;
56+ }
57+ }
0 commit comments