@@ -29,39 +29,107 @@ License: BSD 3-Clause License
2929 */
3030 onRender : function ( component , event , helper ) {
3131
32- let initialized = component . get ( 'v.penpalInitialized ' ) ;
32+ const isPenpalFrameCreated = component . get ( 'v.penpalFrameCreated ' ) ;
3333
34+ // For Penpal to operate correctly, you must ensure that `connectToChild`
35+ // is called before the iframe has called `connectToParent`.
3436 // Since the iframe source is calculated asynchronously,
3537 // we listen to the component's render events and each time
36- // check if the iframe is ready, and if so, then we initialize
38+ // check if the iframe source is ready, and if so, then we initialize
3739 // penpal to connect this component to the iframe.
3840 // Since we only want to do this once, we also set the initialized flag.
39- if ( ! initialized ) {
41+ if ( ! isPenpalFrameCreated ) {
4042
41- let iframeElmt = component . find ( 'penpalFrame' ) . getElement ( ) ;
43+ const container = component . find ( 'penpalFrameContainer' ) ;
44+ const iframeSrc = component . get ( 'v.iframeSrc' ) ;
4245
43- if ( ! $A . util . isEmpty ( iframeElmt . src ) ) {
46+ // Ensure the container element has rendered otherwise we can't
47+ // append child elements to it. And wait for the iframe source to
48+ // be available otherwise no reason to create the iframe element.
49+ if ( ! $A . util . isEmpty ( container ) && ! $A . util . isEmpty ( iframeSrc ) ) {
4450
45- component . set ( 'v.penpalInitialized' , true ) ;
51+ $A . createComponent (
52+ "aura:html" ,
53+ {
54+ "aura:id" : "penpalFrame" ,
55+ "tag" : "iframe" ,
56+ "HTMLAttributes" : {
57+ "src" : iframeSrc
58+ }
59+ } ,
60+ function ( iframeCmp , status , errorMessage ) {
61+
62+ // This callback happened asynchronously, so make one
63+ // more check on whether the penpal frame has been initialized or not
64+ // in the off chance a separate render cycle got here before this one.
65+ const isPenpalFrameCreated = component . get ( 'v.penpalFrameCreated' ) ;
66+
67+ if ( isPenpalFrameCreated ) {
68+
69+ console . log ( 'LC_API: iframe is already initialized' ) ;
70+
71+ } else if ( status === 'SUCCESS' ) {
72+
73+ // At this point, the iframe component has been constructed
74+ // but not yet been rendered, so we don't have access to the
75+ // HTML iframe element yet. We need to wait for another render cycle,
76+ // that is, we need to wait for the render() method to be called again
77+ // after we append the new iframe component to the body of its container.
78+ // Once we're able to find the 'penpalFrame' on the page then
79+ // we can proceed with the rest of the penpal initialization.
80+
81+ component . set ( 'v.penpalFrameCreated' , true ) ;
82+
83+ container . set ( 'v.body' , [ iframeCmp ] ) ;
84+
85+ console . info ( 'LC_API: iframe initialized' ) ;
86+
87+ } else if ( status === 'INCOMPLETE' ) {
88+
89+ console . warn ( 'LC_API: No response from server or client is offline' ) ;
90+
91+ } else if ( status === 'ERROR' ) {
92+
93+ console . error ( 'LC_API: Error creating iframe: ' + errorMessage ) ;
94+
95+ }
96+
97+ }
98+ ) ;
99+
100+ } // else, iframe source is empty, keep waiting
101+
102+ } else {
103+
104+ const isPenpalFrameConnected = component . get ( 'v.penpalFrameConnected' ) ;
105+ const iframeCmp = component . find ( 'penpalFrame' ) ;
106+
107+ if ( ! $A . util . isEmpty ( iframeCmp ) && ! isPenpalFrameConnected ) {
46108
47109 const connection = Penpal . connectToChild ( {
48110 // The iframe to which a connection should be made
49- iframe : iframeElmt
111+ iframe : iframeCmp . getElement ( )
50112 } ) ;
51113
52114 helper . _penpal . connection = connection ;
53115
54116 connection . promise . then ( $A . getCallback ( function ( child ) {
117+
55118 // Cache a reference to the child so that we can
56119 // use it in the restRequest/fetchRequest methods,
57120 // as well as be able to destroy it when this component unrenders.
58121 helper . _penpal . child = child ;
122+ console . info ( 'LC_API: connected to iframe ' + iframeCmp . getGlobalId ( ) ) ;
123+ component . set ( 'v.penpalFrameConnected' , true ) ;
124+
59125 } ) ) . catch ( $A . getCallback ( function ( err ) {
60- console . error ( 'LC_API: Error establishing connection to iframe' , err ) ;
61- component . set ( 'v.penpalInitialized' , false ) ;
126+
127+ console . error ( 'LC_API: Error establishing connection to iframe ' + iframeCmp . getGlobalId ( ) , err ) ;
128+ component . set ( 'v.penpalFrameConnected' , false ) ;
129+
62130 } ) ) ;
63131
64- } // else, iframe source is empty, keep waiting
132+ }
65133
66134 }
67135
0 commit comments