1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15- import { Component } from '@angular/core' ;
15+ import { Component , OnDestroy } from '@angular/core' ;
1616import { ViewController , NavParams } from 'ionic-angular' ;
1717
1818/**
@@ -22,13 +22,19 @@ import { ViewController, NavParams } from 'ionic-angular';
2222 selector : 'core-recaptcha-modal' ,
2323 templateUrl : 'core-recaptchamodal.html'
2424} )
25- export class CoreRecaptchaModalComponent {
25+ export class CoreRecaptchaModalComponent implements OnDestroy {
2626 expired = false ;
2727 value = '' ;
2828 src : string ;
2929
30+ protected messageListenerFunction : ( event : MessageEvent ) => Promise < void > ;
31+
3032 constructor ( protected viewCtrl : ViewController , params : NavParams ) {
3133 this . src = params . get ( 'src' ) ;
34+
35+ // Listen for messages from the iframe.
36+ this . messageListenerFunction = this . onIframeMessage . bind ( this ) ;
37+ window . addEventListener ( 'message' , this . messageListenerFunction ) ;
3238 }
3339
3440 /**
@@ -51,18 +57,63 @@ export class CoreRecaptchaModalComponent {
5157 const contentWindow = iframe && iframe . contentWindow ;
5258
5359 if ( contentWindow ) {
54- // Set the callbacks we're interested in.
55- contentWindow [ 'recaptchacallback' ] = ( value ) : void => {
56- this . expired = false ;
57- this . value = value ;
58- this . closeModal ( ) ;
59- } ;
60+ try {
61+ // Set the callbacks we're interested in.
62+ contentWindow [ 'recaptchacallback' ] = this . onRecaptchaCallback . bind ( this ) ;
63+ contentWindow [ 'recaptchaexpiredcallback' ] = this . onRecaptchaExpiredCallback . bind ( this ) ;
64+ } catch ( error ) {
65+ // Cannot access the window.
66+ }
67+ }
68+ }
69+
70+ /**
71+ * Treat an iframe message event.
72+ *
73+ * @param event Event.
74+ * @return Promise resolved when done.
75+ */
76+ protected async onIframeMessage ( event : MessageEvent ) : Promise < void > {
77+ if ( ! event . data || event . data . environment != 'moodleapp' || event . data . context != 'recaptcha' ) {
78+ return ;
79+ }
6080
61- contentWindow [ 'recaptchaexpiredcallback' ] = ( ) : void => {
62- // Verification expired. Check the checkbox again.
63- this . expired = true ;
64- this . value = '' ;
65- } ;
81+ switch ( event . data . action ) {
82+ case 'callback' :
83+ this . onRecaptchaCallback ( event . data . value ) ;
84+ break ;
85+ case 'expired' :
86+ this . onRecaptchaExpiredCallback ( ) ;
87+ break ;
88+
89+ default :
90+ break ;
6691 }
6792 }
93+
94+ /**
95+ * Recapcha callback called.
96+ *
97+ * @param value Value received.
98+ */
99+ protected onRecaptchaCallback ( value : any ) : void {
100+ this . expired = false ;
101+ this . value = value ;
102+ this . closeModal ( ) ;
103+ }
104+
105+ /**
106+ * Recapcha expired callback called.
107+ */
108+ protected onRecaptchaExpiredCallback ( ) : void {
109+ this . expired = true ;
110+ this . value = '' ;
111+ }
112+
113+ /**
114+ * Component destroyed.
115+ */
116+ ngOnDestroy ( ) : void {
117+ window . removeEventListener ( 'message' , this . messageListenerFunction ) ;
118+ }
68119}
0 commit comments