11/* global Android */
22import { isAndroidWebview , isIosWebview , getPerformance } from '@krakenjs/belter/src' ;
33import { getOrCreateDeviceID , logger } from '../../../../utils' ;
4- import { isIframe } from './utils' ;
4+ import { validateProps , isIframe } from './utils' ;
5+ import { sendEvent , createPostMessengerEvent , POSTMESSENGER_EVENT_NAMES } from './postMessage' ;
56
67const IOS_INTERFACE_NAME = 'paypalMessageModalCallbackHandler' ;
78const ANDROID_INTERFACE_NAME = 'paypalMessageModalCallbackHandler' ;
89
10+ function updateProps ( newProps , propListeners ) {
11+ Array . from ( propListeners . values ( ) ) . forEach ( listener => {
12+ listener ( { ...window . xprops , ...newProps } ) ;
13+ } ) ;
14+ Object . assign ( window . xprops , newProps ) ;
15+ }
16+
17+ export function handlePropsUpdateEvent ( propListeners , updatedPropsEvent ) {
18+ const {
19+ data : { eventPayload : newProps }
20+ } = updatedPropsEvent ;
21+ if ( newProps && typeof newProps === 'object' ) {
22+ const validProps = validateProps ( newProps ) ;
23+ updateProps ( validProps , propListeners ) ;
24+ }
25+ }
26+
27+ export function logModalClose ( linkName ) {
28+ logger . track ( {
29+ index : '1' ,
30+ et : 'CLICK' ,
31+ event_type : 'modal_close' ,
32+ page_view_link_name : linkName
33+ } ) ;
34+ }
35+
36+ export function handleBrowserEvents ( clientOrigin , propListeners , event ) {
37+ const {
38+ origin : eventOrigin ,
39+ data : { eventName, id }
40+ } = event ;
41+ if ( eventOrigin !== clientOrigin ) {
42+ return ;
43+ }
44+ if ( eventName === 'PROPS_UPDATE' ) {
45+ handlePropsUpdateEvent ( propListeners , event ) ;
46+ }
47+ if ( eventName === 'MODAL_CLOSED' ) {
48+ logModalClose ( event . data . eventPayload . linkName ) ;
49+ }
50+ // send event ack with original event id so PostMessenger will stop reposting event
51+ sendEvent ( createPostMessengerEvent ( 'ack' , id ) , clientOrigin ) ;
52+ }
53+
954const getAccount = ( merchantId , clientId , payerId ) => {
1055 if ( merchantId ) {
1156 return merchantId ;
@@ -20,9 +65,23 @@ const getAccount = (merchantId, clientId, payerId) => {
2065} ;
2166
2267const setupBrowser = props => {
68+ const propListeners = new Set ( ) ;
69+
70+ let trustedOrigin = decodeURIComponent ( props . origin || '' ) ;
71+ if ( isIframe && document . referrer && ! process . env . NODE_ENV === 'test' ) {
72+ trustedOrigin = new window . URL ( document . referrer ) . origin ;
73+ }
74+
75+ window . addEventListener (
76+ 'message' ,
77+ event => {
78+ handleBrowserEvents ( trustedOrigin , propListeners , event ) ;
79+ } ,
80+ false
81+ ) ;
82+
2383 window . xprops = {
24- // We will never recieve new props via this integration style
25- onProps : ( ) => { } ,
84+ onProps : listener => propListeners . add ( listener ) ,
2685 // TODO: Verify these callbacks are instrumented correctly
2786 onReady : ( { products, meta } ) => {
2887 const { clientId, payerId, merchantId, offer, partnerAttributionId } = props ;
@@ -79,6 +138,7 @@ const setupBrowser = props => {
79138 } ) ;
80139 } ,
81140 onCalculate : ( { value } ) => {
141+ sendEvent ( createPostMessengerEvent ( 'message' , POSTMESSENGER_EVENT_NAMES . CALCULATE ) , trustedOrigin ) ;
82142 logger . track ( {
83143 index : '1' ,
84144 et : 'CLICK' ,
@@ -89,6 +149,7 @@ const setupBrowser = props => {
89149 } ) ;
90150 } ,
91151 onShow : ( ) => {
152+ sendEvent ( createPostMessengerEvent ( 'message' , POSTMESSENGER_EVENT_NAMES . SHOW ) , trustedOrigin ) ;
92153 logger . track ( {
93154 index : '1' ,
94155 et : 'CLIENT_IMPRESSION' ,
@@ -97,16 +158,15 @@ const setupBrowser = props => {
97158 } ) ;
98159 } ,
99160 onClose : ( { linkName } ) => {
100- if ( isIframe && document . referrer ) {
101- const targetOrigin = new window . URL ( document . referrer ) . origin ;
102- window . parent . postMessage ( 'paypal-messages-modal-close' , targetOrigin ) ;
103- }
104- logger . track ( {
105- index : '1' ,
106- et : 'CLICK' ,
107- event_type : 'modal_close' ,
108- page_view_link_name : linkName
109- } ) ;
161+ const eventPayload = {
162+ linkName
163+ // for data security, also add new params to createSafePayload in ./postMessage.js
164+ } ;
165+ sendEvent (
166+ createPostMessengerEvent ( 'message' , POSTMESSENGER_EVENT_NAMES . CLOSE , eventPayload ) ,
167+ trustedOrigin
168+ ) ;
169+ logModalClose ( linkName ) ;
110170 } ,
111171 // Overridable defaults
112172 integrationType : __MESSAGES__ . __TARGET__ ,
@@ -139,11 +199,7 @@ const setupWebview = props => {
139199 window . actions = {
140200 updateProps : newProps => {
141201 if ( newProps && typeof newProps === 'object' ) {
142- Array . from ( propListeners . values ( ) ) . forEach ( listener => {
143- listener ( { ...window . xprops , ...newProps } ) ;
144- } ) ;
145-
146- Object . assign ( window . xprops , newProps ) ;
202+ updateProps ( newProps , propListeners ) ;
147203 }
148204 }
149205 } ;
0 commit comments