Skip to content

Commit 890d4b0

Browse files
authored
button xprops for app switch support (#2455)
1 parent f0b5eeb commit 890d4b0

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

Diff for: src/ui/buttons/props.js

+9
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,15 @@ export type PrerenderDetails = {|
497497
export type GetPrerenderDetails = () => PrerenderDetails | void;
498498

499499
export type ButtonProps = {|
500+
// app switch properties
501+
appSwitchWhenAvailable: string,
502+
listenForHashChanges: () => void,
503+
removeListenerForHashChanges: () => void,
504+
// Not passed to child iframe
505+
// change any to HashChangeEvent when we move to typescript
506+
// eslint-disable-next-line flowtype/no-weak-types
507+
hashChangeHandler: (event: any) => void,
508+
500509
fundingSource?: ?$Values<typeof FUNDING>,
501510
intent: $Values<typeof INTENT>,
502511
createOrder: CreateOrder,

Diff for: src/zoid/buttons/component.jsx

+59
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
} from "@paypal/funding-components/src";
5151
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
5252
import { create, EVENT, type ZoidComponent } from "@krakenjs/zoid/src";
53+
import { send as postRobotSend } from "@krakenjs/post-robot/src";
5354
import {
5455
uniqueID,
5556
memoize,
@@ -99,6 +100,7 @@ export type ButtonsComponent = ZoidComponent<ButtonProps>;
99100

100101
export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
101102
const queriedEligibleFunding = [];
103+
102104
return create({
103105
tag: "paypal-buttons",
104106
url: () => `${getPayPalDomain()}${__PAYPAL_CHECKOUT__.__URI__.__BUTTONS__}`,
@@ -246,6 +248,63 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
246248
},
247249

248250
props: {
251+
// App Switch Properties
252+
appSwitchWhenAvailable: {
253+
// this value is a string for now while we test the app switch
254+
// feature. Before we give this to a real merchant, we should
255+
// change this to a boolean - Shane 11 Dec 2024
256+
type: "string",
257+
required: false,
258+
},
259+
260+
hashChangeHandler: {
261+
type: "function",
262+
sendToChild: false,
263+
queryParam: false,
264+
required: false,
265+
value: () => (event) => {
266+
const iframes = document.querySelectorAll("iframe");
267+
268+
// I don't understand why but trying to make iframes which is a NodeList
269+
// into an Iterable (so we could do a for..of loop or .forEach) is not
270+
// working. It ends up iterating over itself so instead of looping over the contents
271+
// of the NodeList you loop over the NodeList itself which is extremely unexpected
272+
// for..in works though :shrug: - Shane 11 Dec 2024
273+
for (let i = 0; i < iframes.length; i++) {
274+
if (iframes[i].name.includes("zoid__paypal_buttons")) {
275+
postRobotSend(
276+
iframes[i].contentWindow,
277+
"paypal-hashchange",
278+
{
279+
url: event.newURL,
280+
},
281+
{ domain: getPayPalDomain() }
282+
);
283+
}
284+
}
285+
},
286+
},
287+
288+
listenForHashChanges: {
289+
type: "function",
290+
queryParam: false,
291+
value:
292+
({ props }) =>
293+
() => {
294+
window.addEventListener("hashchange", props.hashChangeHandler);
295+
},
296+
},
297+
298+
removeListenerForHashChanges: {
299+
type: "function",
300+
queryParam: false,
301+
value:
302+
({ props }) =>
303+
() => {
304+
window.removeEventListener("hashchange", props.hashChangeHandler);
305+
},
306+
},
307+
249308
// allowBillingPayments prop is used by Honey Extension to render the one-click button
250309
// with payment methods & to use the payment methods instead of the Billing Agreement
251310
allowBillingPayments: {

0 commit comments

Comments
 (0)