@automattic/newspack-blocks 2.6.2 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cache/babel/135eb7c6e583be53418b26a29fcc4d81.json.gz +0 -0
- package/.cache/babel/2bec24377bb9890c2268bcd4c8f3953c.json.gz +0 -0
- package/.cache/babel/9ba57ee86df44178ceb255eaf0e770e3.json.gz +0 -0
- package/.cache/babel/a804bf1963e56137e59e37a567cb5e2e.json.gz +0 -0
- package/.cache/babel/b94e6dc0852876a37bd23ec88c5b2583.json.gz +0 -0
- package/.cache/babel/c04d2af94bb0f10f408a15534301cc86.json.gz +0 -0
- package/.cache/babel/c8d4b9ae4be3002e8507d71f1136ebc6.json.gz +0 -0
- package/.cache/babel/d21f5515648ce2a2349b0ee5cc787fce.json.gz +0 -0
- package/.cache/babel/d3eee0c40fc44bc734dee21a645a4f7d.json.gz +0 -0
- package/.cache/babel/d661309b03e38954105e706a32ef09f6.json.gz +0 -0
- package/.cache/babel/e2dd36051554e75a2bf087b85c11e43d.json.gz +0 -0
- package/.hooks/pre-push +2 -2
- package/CHANGELOG.md +21 -0
- package/composer.lock +38 -36
- package/dist/donate/view.asset.php +1 -1
- package/dist/donate/view.css +1 -1
- package/dist/donate/view.rtl.css +1 -1
- package/dist/editor.asset.php +1 -1
- package/dist/editor.css +1 -1
- package/dist/editor.js +11 -11
- package/dist/editor.rtl.css +1 -1
- package/dist/frequencyBased.asset.php +1 -1
- package/dist/frequencyBased.css +1 -1
- package/dist/frequencyBased.rtl.css +1 -1
- package/dist/modalCheckout.asset.php +1 -1
- package/dist/modalCheckout.css +1 -1
- package/dist/modalCheckout.rtl.css +1 -1
- package/dist/tiersBased.asset.php +1 -1
- package/dist/tiersBased.css +1 -1
- package/dist/tiersBased.js +1 -1
- package/dist/tiersBased.rtl.css +1 -1
- package/includes/class-modal-checkout.php +11 -14
- package/includes/class-newspack-blocks.php +87 -43
- package/languages/newspack-blocks-de_DE.po +0 -40
- package/languages/newspack-blocks-es_ES.po +0 -40
- package/languages/newspack-blocks-fr_BE.po +0 -40
- package/languages/newspack-blocks-pt_PT.po +0 -40
- package/languages/newspack-blocks.pot +0 -38
- package/newspack-blocks.php +2 -14
- package/package.json +7 -8
- package/src/blocks/checkout-button/edit.js +5 -1
- package/src/blocks/donate/block.json +0 -12
- package/src/blocks/donate/edit/FrequencyBasedLayout.tsx +61 -106
- package/src/blocks/donate/edit/TierBasedLayout.tsx +7 -26
- package/src/blocks/donate/edit/components/index.tsx +0 -1
- package/src/blocks/donate/edit/index.tsx +157 -152
- package/src/blocks/donate/frequency-based/style.scss +5 -0
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer-base.php +33 -147
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer-frequency-based.php +21 -10
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer-tiers-based.php +3 -50
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer.php +1 -14
- package/src/blocks/donate/styles/editor.scss +6 -28
- package/src/blocks/donate/styles/style-variations.scss +17 -8
- package/src/blocks/donate/styles/view.scss +9 -0
- package/src/blocks/donate/tiers-based/style.scss +0 -11
- package/src/blocks/donate/tiers-based/utils.test.js +38 -0
- package/src/blocks/donate/tiers-based/utils.ts +1 -2
- package/src/blocks/donate/tiers-based/view.ts +0 -33
- package/src/blocks/donate/types.ts +0 -16
- package/src/blocks/donate/utils.ts +31 -0
- package/src/blocks/homepage-articles/block.json +18 -0
- package/src/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php +1 -1
- package/src/blocks/homepage-articles/edit.js +3 -0
- package/src/blocks/homepage-articles/utils.ts +4 -0
- package/src/blocks/homepage-articles/view.php +4 -4
- package/src/components/query-controls.js +41 -8
- package/src/modal-checkout/checkout.scss +4 -5
- package/src/types/index.d.ts +4 -3
- package/vendor/autoload.php +1 -1
- package/vendor/composer/autoload_real.php +4 -4
- package/vendor/composer/autoload_static.php +2 -2
- package/vendor/composer/installed.php +2 -2
- package/webpack.config.js +0 -1
- package/.cache/babel/18dda1142078f066419138e7284f03bf.json.gz +0 -0
- package/.cache/babel/1f43960564787ebde7c6d44957cddf0e.json.gz +0 -0
- package/.cache/babel/225618337c609eed2be110274ff82be1.json.gz +0 -0
- package/.cache/babel/29d960d2fc51492a4bea1f4f165810fb.json.gz +0 -0
- package/.cache/babel/2f22325668b5763f8f2c9557833af36f.json.gz +0 -0
- package/.cache/babel/39bcc541624feefe54d1493493ae1ce8.json.gz +0 -0
- package/.cache/babel/4d450b37d365154f05b17cbf6a009255.json.gz +0 -0
- package/.cache/babel/87e2dc4a961b25b0de8d1a8ac88eea13.json.gz +0 -0
- package/.cache/babel/91884d41523f3790da70ea305ee187f2.json.gz +0 -0
- package/.cache/babel/b1ac90699e641ff99e1449b5d7b686e5.json.gz +0 -0
- package/.cache/babel/c5a441fdf7d90d45d2cbeb89967c61fe.json.gz +0 -0
- package/.cache/babel/c7cfb8590e887722a3e715c72ee99bac.json.gz +0 -0
- package/.cache/babel/e1d8932bb19afa36f476f107dbc6ca39.json.gz +0 -0
- package/.cache/babel/f60f8c23ec2b4448cb2815d79207d8c0.json.gz +0 -0
- package/dist/donateStreamlined.asset.php +0 -1
- package/dist/donateStreamlined.css +0 -1
- package/dist/donateStreamlined.js +0 -1
- package/dist/donateStreamlined.rtl.css +0 -1
- package/src/blocks/donate/class-wp-rest-newspack-donate-controller.php +0 -206
- package/src/blocks/donate/edit/components/AdditionalFields.tsx +0 -282
- package/src/blocks/donate/streamlined/index.test.js +0 -132
- package/src/blocks/donate/streamlined/index.ts +0 -356
- package/src/blocks/donate/streamlined/style.scss +0 -306
- package/src/blocks/donate/streamlined/utils.test.js +0 -18
- package/src/blocks/donate/streamlined/utils.ts +0 -217
- package/src/blocks/donate/tiers-based/view.test.js +0 -209
|
@@ -1,356 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { __ } from '@wordpress/i18n';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* External dependencies
|
|
8
|
-
*/
|
|
9
|
-
import { loadStripe } from '@stripe/stripe-js/pure';
|
|
10
|
-
import type * as Stripe from '@stripe/stripe-js/types';
|
|
11
|
-
import 'regenerator-runtime'; // Required in WP >=5.8.
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Internal dependencies
|
|
15
|
-
*/
|
|
16
|
-
import * as utils from './utils';
|
|
17
|
-
import './style.scss';
|
|
18
|
-
|
|
19
|
-
const getAdditionalFieldsValues = ( formElement: HTMLFormElement ) => {
|
|
20
|
-
const fields = [
|
|
21
|
-
...formElement.querySelectorAll( 'input[data-is-additional-field]' ),
|
|
22
|
-
] as HTMLInputElement[];
|
|
23
|
-
return fields.map( field => ( { name: field.name, value: field.value } ) );
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const processStreamlinedElements = ( parentElement = document ) =>
|
|
27
|
-
[ ...parentElement.querySelectorAll( '.stripe-payment' ) ].forEach( async el => {
|
|
28
|
-
let stripe: Stripe.Stripe | null,
|
|
29
|
-
cardElement: Stripe.StripeCardElement,
|
|
30
|
-
paymentRequest: Stripe.PaymentRequest,
|
|
31
|
-
paymentRequestToken: Stripe.Token,
|
|
32
|
-
isCardUIVisible = false;
|
|
33
|
-
|
|
34
|
-
const formElement: HTMLFormElement | null = el.closest( 'form' );
|
|
35
|
-
const messagesEl: HTMLDivElement | null = el.querySelector( '.stripe-payment__messages' );
|
|
36
|
-
if ( ! formElement || ! messagesEl ) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const blockWrapperElement = el.closest( '.wpbnbd' );
|
|
41
|
-
const paymentFlowCompleteEventName = `newspackPaymentFlowComplete-${
|
|
42
|
-
blockWrapperElement?.id || ''
|
|
43
|
-
}`;
|
|
44
|
-
|
|
45
|
-
const settings = utils.getSettings( formElement );
|
|
46
|
-
|
|
47
|
-
const disableForm = () => el.classList.add( 'stripe-payment--disabled' );
|
|
48
|
-
const enableForm = () => el.classList.remove( 'stripe-payment--disabled' );
|
|
49
|
-
enableForm();
|
|
50
|
-
|
|
51
|
-
// Display CC UI.
|
|
52
|
-
const displayCardUI = () => {
|
|
53
|
-
if ( isCardUIVisible ) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const inputsHiddenEl = el.querySelector( '.stripe-payment__inputs.stripe-payment--hidden' );
|
|
57
|
-
if ( inputsHiddenEl ) {
|
|
58
|
-
inputsHiddenEl.classList.remove( 'stripe-payment--hidden' );
|
|
59
|
-
isCardUIVisible = true;
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const getCaptchaToken = async ( captchaSiteKey: string ) => {
|
|
64
|
-
return new Promise( ( res, rej ) => {
|
|
65
|
-
const { grecaptcha } = window;
|
|
66
|
-
if ( ! grecaptcha ) {
|
|
67
|
-
return res( '' );
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if ( ! grecaptcha?.ready || ! captchaSiteKey ) {
|
|
71
|
-
rej( __( 'Error loading the reCaptcha library.', 'newspack-blocks' ) );
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
grecaptcha.ready( async () => {
|
|
75
|
-
try {
|
|
76
|
-
const token = await grecaptcha.execute( captchaSiteKey, { action: 'submit' } );
|
|
77
|
-
return res( token );
|
|
78
|
-
} catch ( e ) {
|
|
79
|
-
rej( e );
|
|
80
|
-
}
|
|
81
|
-
} );
|
|
82
|
-
} );
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// Universal payment handling, for both card and payment request button flows.
|
|
86
|
-
// In card flow, this will happen after user submits their card data in the HTML form.
|
|
87
|
-
// In payment request flow, this will happen after the user validates the payment in
|
|
88
|
-
// the browser/OS UI.
|
|
89
|
-
const payWithSource = async (
|
|
90
|
-
source: Stripe.Source,
|
|
91
|
-
token: Stripe.Token | undefined = undefined,
|
|
92
|
-
/**
|
|
93
|
-
* Overrides for sent donation data. In a card flow the data is
|
|
94
|
-
* provided explicitly by the user (via the form), but in payment request flow
|
|
95
|
-
* the data is from the payment request event.
|
|
96
|
-
*/
|
|
97
|
-
requestPayloadOverrides = {}
|
|
98
|
-
) => {
|
|
99
|
-
if ( ! stripe ) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Add reCaptcha challenge to form submission, if available.
|
|
104
|
-
const captchaSiteKey = settings?.captchaSiteKey;
|
|
105
|
-
let captchaToken;
|
|
106
|
-
if ( captchaSiteKey ) {
|
|
107
|
-
try {
|
|
108
|
-
captchaToken = await getCaptchaToken( captchaSiteKey );
|
|
109
|
-
} catch ( e ) {
|
|
110
|
-
const errorMessage =
|
|
111
|
-
e instanceof Error
|
|
112
|
-
? e.message
|
|
113
|
-
: __( 'Error processing captcha request.', 'newspack-blocks' );
|
|
114
|
-
utils.renderMessages( [ errorMessage ], messagesEl );
|
|
115
|
-
return { error: true };
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
const formValues = utils.getDonationFormValues( formElement );
|
|
119
|
-
|
|
120
|
-
const additionalFields: { name: string; value: string }[] =
|
|
121
|
-
getAdditionalFieldsValues( formElement );
|
|
122
|
-
|
|
123
|
-
const apiRequestPayload = {
|
|
124
|
-
captchaToken,
|
|
125
|
-
stripe_tokenization_method: token ? token.card?.tokenization_method : 'card',
|
|
126
|
-
stripe_source_id: source.id,
|
|
127
|
-
amount: utils.getTotalAmount( formElement ),
|
|
128
|
-
email: formValues.email,
|
|
129
|
-
full_name: formValues.full_name,
|
|
130
|
-
frequency: formValues.donation_frequency,
|
|
131
|
-
newsletter_opt_in: Boolean( formValues.newsletter_opt_in ),
|
|
132
|
-
newspack_popup_id: formValues.newspack_popup_id,
|
|
133
|
-
_wp_http_referer: formValues._wp_http_referer,
|
|
134
|
-
clientId: formValues.cid,
|
|
135
|
-
additional_fields: additionalFields,
|
|
136
|
-
...requestPayloadOverrides,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
const chargeResultData = await utils.sendAPIRequest( '/donate', apiRequestPayload );
|
|
140
|
-
|
|
141
|
-
// Error handling.
|
|
142
|
-
if ( chargeResultData.data?.status !== 200 && chargeResultData.message ) {
|
|
143
|
-
utils.renderMessages( [ chargeResultData.message ], messagesEl );
|
|
144
|
-
return { error: true };
|
|
145
|
-
}
|
|
146
|
-
if ( chargeResultData.error ) {
|
|
147
|
-
utils.renderMessages( [ chargeResultData.error ], messagesEl );
|
|
148
|
-
return { error: true };
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const exitWithError = ( errorMessage: Stripe.StripeError[ 'message' ] ) => {
|
|
152
|
-
utils.renderMessages( [ errorMessage ], messagesEl );
|
|
153
|
-
enableForm();
|
|
154
|
-
window.dispatchEvent( new Event( paymentFlowCompleteEventName ) );
|
|
155
|
-
return { error: true };
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
// Additional steps handling.
|
|
159
|
-
if ( chargeResultData.client_secret ) {
|
|
160
|
-
const confirmationResult = await stripe.confirmCardPayment(
|
|
161
|
-
chargeResultData.client_secret
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
if ( confirmationResult.error ) {
|
|
165
|
-
return exitWithError( confirmationResult.error.message );
|
|
166
|
-
} else if ( confirmationResult.paymentIntent.status === 'succeeded' ) {
|
|
167
|
-
utils.renderSuccessMessageWithEmail( apiRequestPayload.email, messagesEl );
|
|
168
|
-
} else if ( confirmationResult.paymentIntent.status === 'requires_action' ) {
|
|
169
|
-
// Could not test this flow (with 3D Secure test cards), but it's listed in the docs:
|
|
170
|
-
// https://stripe.com/docs/stripe-js/elements/payment-request-button#html-js-complete-payment
|
|
171
|
-
const { error: confirmationError } = await stripe.confirmCardPayment(
|
|
172
|
-
chargeResultData.client_secret
|
|
173
|
-
);
|
|
174
|
-
if ( confirmationError ) {
|
|
175
|
-
return exitWithError( confirmationError.message );
|
|
176
|
-
}
|
|
177
|
-
utils.renderSuccessMessageWithEmail( apiRequestPayload.email, messagesEl );
|
|
178
|
-
} else {
|
|
179
|
-
return exitWithError(
|
|
180
|
-
__(
|
|
181
|
-
'Something went wrong with the payment. Please try again later.',
|
|
182
|
-
'newspack-blocks'
|
|
183
|
-
)
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if ( chargeResultData.status === 'success' ) {
|
|
189
|
-
utils.renderSuccessMessageWithEmail( apiRequestPayload.email, messagesEl );
|
|
190
|
-
}
|
|
191
|
-
window.dispatchEvent( new Event( paymentFlowCompleteEventName ) );
|
|
192
|
-
return {};
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const initStripe = async () => {
|
|
196
|
-
stripe = await loadStripe( settings.stripePublishableKey );
|
|
197
|
-
if ( ! stripe ) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
const cardElementContainer: HTMLElement | null = el.querySelector( '.stripe-payment__card' );
|
|
201
|
-
if ( ! cardElementContainer ) {
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
const elements = stripe.elements();
|
|
205
|
-
|
|
206
|
-
// Handle card element.
|
|
207
|
-
cardElement = elements.create( 'card' );
|
|
208
|
-
cardElement.mount( cardElementContainer );
|
|
209
|
-
|
|
210
|
-
// Handle payment request button (Apple/Google Pay). This has to be initialised to see if
|
|
211
|
-
// such payments are available in the browser (canMakePayment method).
|
|
212
|
-
paymentRequest = stripe.paymentRequest( {
|
|
213
|
-
country: settings.countryCode,
|
|
214
|
-
currency: settings.currency,
|
|
215
|
-
total: utils.getPaymentRequestTotal( formElement ),
|
|
216
|
-
// Docs: Use the requestPayerName parameter to collect the payer’s billing address for Apple Pay.
|
|
217
|
-
requestPayerName: true,
|
|
218
|
-
requestPayerEmail: true,
|
|
219
|
-
} );
|
|
220
|
-
|
|
221
|
-
const rendersPaymentRequestButton = await paymentRequest.canMakePayment();
|
|
222
|
-
if ( rendersPaymentRequestButton ) {
|
|
223
|
-
paymentRequest.on( 'source', async event => {
|
|
224
|
-
const result = await payWithSource( event.source, paymentRequestToken, {
|
|
225
|
-
email: event.payerEmail,
|
|
226
|
-
full_name: event.payerName,
|
|
227
|
-
} );
|
|
228
|
-
// The UI messages are handled in payWithSource, this event listener only
|
|
229
|
-
// has to notify the browser that the payment is done.
|
|
230
|
-
event.complete( result?.error ? 'fail' : 'success' );
|
|
231
|
-
} );
|
|
232
|
-
paymentRequest.on( 'token', async event => {
|
|
233
|
-
paymentRequestToken = event.token;
|
|
234
|
-
} );
|
|
235
|
-
// Update payment request when the form values are updated.
|
|
236
|
-
formElement.addEventListener( 'change', () => {
|
|
237
|
-
paymentRequest.update( {
|
|
238
|
-
total: utils.getPaymentRequestTotal( formElement ),
|
|
239
|
-
} );
|
|
240
|
-
} );
|
|
241
|
-
// Create and mount the payment request button.
|
|
242
|
-
const prButton = elements.create( 'paymentRequestButton', {
|
|
243
|
-
paymentRequest,
|
|
244
|
-
style: {
|
|
245
|
-
paymentRequestButton: {
|
|
246
|
-
type: settings.paymentRequestType,
|
|
247
|
-
height: '46px',
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
} );
|
|
251
|
-
const prButtonElement: HTMLButtonElement | null = el.querySelector(
|
|
252
|
-
'.stripe-payment__request-button'
|
|
253
|
-
);
|
|
254
|
-
if ( ! prButtonElement ) {
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
prButton.mount( prButtonElement );
|
|
258
|
-
prButtonElement.classList.remove( 'stripe-payment--hidden' );
|
|
259
|
-
setTimeout( () => {
|
|
260
|
-
prButtonElement.classList.remove( 'stripe-payment__request-button--invisible' );
|
|
261
|
-
}, 0 );
|
|
262
|
-
} else {
|
|
263
|
-
displayCardUI();
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
el.classList.remove( 'stripe-payment--invisible' );
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
// Initialise Stripe once the element is visible.
|
|
270
|
-
const observer = new IntersectionObserver( entries => {
|
|
271
|
-
if ( entries[ 0 ].isIntersecting ) {
|
|
272
|
-
initStripe();
|
|
273
|
-
}
|
|
274
|
-
} );
|
|
275
|
-
observer.observe( el );
|
|
276
|
-
|
|
277
|
-
// Card form unravelling.
|
|
278
|
-
const submitButtonEl: HTMLButtonElement | null = el.querySelector( 'button[type="submit"]' );
|
|
279
|
-
if ( submitButtonEl ) {
|
|
280
|
-
submitButtonEl.onclick = e => {
|
|
281
|
-
if ( ! isCardUIVisible ) {
|
|
282
|
-
e.preventDefault();
|
|
283
|
-
displayCardUI();
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const updateFeesAmount = () => {
|
|
289
|
-
const feesAmountEl = el.querySelector( '#stripe-fees-amount' );
|
|
290
|
-
if ( feesAmountEl ) {
|
|
291
|
-
const formValues = Object.fromEntries( new FormData( formElement ) );
|
|
292
|
-
const feeAmount = utils.getFeeAmount( formElement );
|
|
293
|
-
if ( feeAmount === 0 ) {
|
|
294
|
-
const feesAmountContainerEl: HTMLElement | null = el.querySelector(
|
|
295
|
-
'#stripe-fees-amount-container'
|
|
296
|
-
);
|
|
297
|
-
if ( feesAmountContainerEl ) {
|
|
298
|
-
feesAmountContainerEl.style.display = 'none';
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
if ( typeof formValues.donation_frequency === 'string' ) {
|
|
302
|
-
feesAmountEl.innerHTML = `(${ settings.currencySymbol }${ feeAmount.toFixed(
|
|
303
|
-
2
|
|
304
|
-
) } ${ settings.frequencies[ formValues.donation_frequency ].toLowerCase() })`;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
updateFeesAmount();
|
|
310
|
-
formElement.addEventListener( 'change', updateFeesAmount );
|
|
311
|
-
|
|
312
|
-
// Card payment flow – on form submission.
|
|
313
|
-
formElement.addEventListener( 'submit', async e => {
|
|
314
|
-
if ( ! stripe ) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
e.preventDefault();
|
|
318
|
-
disableForm();
|
|
319
|
-
utils.renderMessages(
|
|
320
|
-
[ __( 'Processing payment…', 'newspack-blocks' ) ],
|
|
321
|
-
messagesEl,
|
|
322
|
-
'info'
|
|
323
|
-
);
|
|
324
|
-
|
|
325
|
-
const formValues = utils.getDonationFormValues( formElement );
|
|
326
|
-
const validationErrors = Object.values( utils.validateFormData( formValues, settings ) );
|
|
327
|
-
if ( validationErrors.length > 0 ) {
|
|
328
|
-
utils.renderMessages( validationErrors, messagesEl );
|
|
329
|
-
enableForm();
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const handleStripeSDKError = ( error: Stripe.StripeError ) => {
|
|
334
|
-
if ( error.message ) {
|
|
335
|
-
validationErrors.push( error.message );
|
|
336
|
-
}
|
|
337
|
-
utils.renderMessages( validationErrors, messagesEl );
|
|
338
|
-
enableForm();
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
const sourceCreationResult = await stripe.createSource( cardElement, {
|
|
342
|
-
type: 'card',
|
|
343
|
-
owner: { name: formValues.full_name, email: formValues.email },
|
|
344
|
-
} );
|
|
345
|
-
if ( sourceCreationResult.error ) {
|
|
346
|
-
handleStripeSDKError( sourceCreationResult.error );
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
await payWithSource( sourceCreationResult.source );
|
|
350
|
-
if ( window.newspackReaderActivation?.refreshAuthentication ) {
|
|
351
|
-
window.newspackReaderActivation.refreshAuthentication();
|
|
352
|
-
}
|
|
353
|
-
} );
|
|
354
|
-
} );
|
|
355
|
-
|
|
356
|
-
processStreamlinedElements();
|
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
@use '../../../shared/sass/colors';
|
|
2
|
-
@use '../../../shared/sass/mixins';
|
|
3
|
-
@use '../../../shared/sass/variables';
|
|
4
|
-
|
|
5
|
-
@keyframes loader {
|
|
6
|
-
0% {
|
|
7
|
-
background-position: 0% 50%;
|
|
8
|
-
}
|
|
9
|
-
50% {
|
|
10
|
-
background-position: 100% 50%;
|
|
11
|
-
}
|
|
12
|
-
100% {
|
|
13
|
-
background-position: 0% 50%;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.wp-block-newspack-blocks-donate {
|
|
18
|
-
.stripe-payment {
|
|
19
|
-
// For the initial unravelling animation.
|
|
20
|
-
position: relative;
|
|
21
|
-
&,
|
|
22
|
-
&--transition,
|
|
23
|
-
&::after {
|
|
24
|
-
transition: all 300ms ease-out;
|
|
25
|
-
}
|
|
26
|
-
&::after {
|
|
27
|
-
content: '';
|
|
28
|
-
opacity: 0;
|
|
29
|
-
pointer-events: none;
|
|
30
|
-
position: absolute;
|
|
31
|
-
top: 0;
|
|
32
|
-
left: 0;
|
|
33
|
-
width: 100%;
|
|
34
|
-
height: 100%;
|
|
35
|
-
background: linear-gradient( 318deg, #d5d5d5, #fff );
|
|
36
|
-
background-size: 400% 400%;
|
|
37
|
-
animation: loader 3s ease infinite;
|
|
38
|
-
border-radius: 5px;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
&__card {
|
|
42
|
-
padding: 0.34rem 0.66rem;
|
|
43
|
-
min-height: 32px;
|
|
44
|
-
}
|
|
45
|
-
input[type='text'],
|
|
46
|
-
input[type='email'],
|
|
47
|
-
&__card {
|
|
48
|
-
border: 1px solid variables.$color__border;
|
|
49
|
-
border-radius: 3px;
|
|
50
|
-
}
|
|
51
|
-
input[type='text'],
|
|
52
|
-
input[type='email'],
|
|
53
|
-
&__checkbox,
|
|
54
|
-
button,
|
|
55
|
-
.submit-button {
|
|
56
|
-
font-size: 0.7em;
|
|
57
|
-
}
|
|
58
|
-
input[type='text'],
|
|
59
|
-
input[type='email'],
|
|
60
|
-
&__messages {
|
|
61
|
-
width: 100%;
|
|
62
|
-
}
|
|
63
|
-
input[type='text'],
|
|
64
|
-
input[type='email'] {
|
|
65
|
-
border-radius: 3px;
|
|
66
|
-
font-family: sans-serif;
|
|
67
|
-
|
|
68
|
-
@include mixins.media( tablet ) {
|
|
69
|
-
font-size: 14px;
|
|
70
|
-
line-height: 1.2;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
&--invisible {
|
|
75
|
-
> * {
|
|
76
|
-
opacity: 0;
|
|
77
|
-
}
|
|
78
|
-
&::after {
|
|
79
|
-
opacity: 1;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
&--hidden {
|
|
83
|
-
display: none;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
&__checkbox {
|
|
87
|
-
align-items: center;
|
|
88
|
-
display: inline-flex;
|
|
89
|
-
cursor: pointer;
|
|
90
|
-
|
|
91
|
-
input {
|
|
92
|
-
height: 1em;
|
|
93
|
-
width: 1em;
|
|
94
|
-
margin-right: 0.5em;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
&__messages {
|
|
99
|
-
margin-bottom: 10px;
|
|
100
|
-
> div {
|
|
101
|
-
border: 0 solid colors.$color__info;
|
|
102
|
-
border-left-width: 4px;
|
|
103
|
-
font-size: variables.$font__size-sm;
|
|
104
|
-
margin-top: 0.76rem;
|
|
105
|
-
padding: 0.38rem 0.76rem;
|
|
106
|
-
&:empty {
|
|
107
|
-
border: 0;
|
|
108
|
-
margin: 0;
|
|
109
|
-
padding: 0;
|
|
110
|
-
}
|
|
111
|
-
&.type-error {
|
|
112
|
-
background-color: rgba( colors.$color__error, 0.075 );
|
|
113
|
-
border-color: colors.$color__error;
|
|
114
|
-
}
|
|
115
|
-
&.type-success {
|
|
116
|
-
background-color: rgba( colors.$color__success, 0.075 );
|
|
117
|
-
border-color: colors.$color__success;
|
|
118
|
-
margin: 1.12rem;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
&--disabled {
|
|
124
|
-
button,
|
|
125
|
-
input {
|
|
126
|
-
pointer-events: none;
|
|
127
|
-
opacity: 0.4;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
&__element {
|
|
132
|
-
margin-bottom: 0.4rem;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
&__row {
|
|
136
|
-
margin-bottom: 0.5rem;
|
|
137
|
-
&--small {
|
|
138
|
-
margin-bottom: 5px;
|
|
139
|
-
line-height: 1.2;
|
|
140
|
-
}
|
|
141
|
-
&--flex {
|
|
142
|
-
display: flex;
|
|
143
|
-
align-items: flex-end;
|
|
144
|
-
justify-content: space-between;
|
|
145
|
-
flex-wrap: wrap;
|
|
146
|
-
@include mixins.media( tablet ) {
|
|
147
|
-
flex-wrap: nowrap;
|
|
148
|
-
}
|
|
149
|
-
input {
|
|
150
|
-
margin-bottom: 0.5rem;
|
|
151
|
-
@include mixins.media( tablet ) {
|
|
152
|
-
margin-bottom: 0;
|
|
153
|
-
width: 50%;
|
|
154
|
-
+ input {
|
|
155
|
-
margin-left: 0.5rem;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
&--additional-fields {
|
|
161
|
-
display: flex;
|
|
162
|
-
flex-wrap: wrap;
|
|
163
|
-
margin-left: -0.25rem;
|
|
164
|
-
margin-right: -0.25rem;
|
|
165
|
-
> input {
|
|
166
|
-
margin-bottom: 0.5rem;
|
|
167
|
-
margin-left: 0.25rem;
|
|
168
|
-
margin-right: 0.25rem;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
&__info {
|
|
174
|
-
color: colors.$color__text-light;
|
|
175
|
-
font-size: 0.7em;
|
|
176
|
-
font-style: italic;
|
|
177
|
-
padding-left: 1.5em;
|
|
178
|
-
display: none;
|
|
179
|
-
@include mixins.media( mobile ) {
|
|
180
|
-
display: block;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
&__footer {
|
|
185
|
-
align-items: flex-end;
|
|
186
|
-
margin-bottom: 1.32rem;
|
|
187
|
-
margin-left: -10px;
|
|
188
|
-
margin-right: -10px;
|
|
189
|
-
> * {
|
|
190
|
-
padding-left: 10px;
|
|
191
|
-
padding-right: 10px;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
&__methods {
|
|
196
|
-
display: flex;
|
|
197
|
-
flex-wrap: wrap;
|
|
198
|
-
width: 100%;
|
|
199
|
-
@include mixins.media( mobile ) {
|
|
200
|
-
width: auto;
|
|
201
|
-
}
|
|
202
|
-
button,
|
|
203
|
-
.submit-button {
|
|
204
|
-
margin-left: 0;
|
|
205
|
-
margin-right: 0;
|
|
206
|
-
margin-bottom: 0;
|
|
207
|
-
height: 46px;
|
|
208
|
-
}
|
|
209
|
-
> * {
|
|
210
|
-
&:not( :last-child ) {
|
|
211
|
-
margin-bottom: 10px;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
width: 100%;
|
|
215
|
-
@include mixins.media( mobile ) {
|
|
216
|
-
width: auto;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
&__request-button {
|
|
222
|
-
min-width: 190px;
|
|
223
|
-
@include mixins.media( mobile ) {
|
|
224
|
-
margin-right: 1em;
|
|
225
|
-
}
|
|
226
|
-
&--invisible {
|
|
227
|
-
opacity: 0;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
&__stripe {
|
|
233
|
-
margin: 0.38rem 0.76rem 0.76rem;
|
|
234
|
-
|
|
235
|
-
@include mixins.media( tablet ) {
|
|
236
|
-
margin-left: 1.5rem;
|
|
237
|
-
margin-right: 1.5rem;
|
|
238
|
-
}
|
|
239
|
-
&--editor {
|
|
240
|
-
input:first-child {
|
|
241
|
-
margin-top: 0;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
#stripe-fees-amount {
|
|
248
|
-
padding-left: 3px;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/* Alternate Style */
|
|
252
|
-
|
|
253
|
-
.wpbnbd.is-style-alternate {
|
|
254
|
-
.wp-block-newspack-blocks-donate__stripe {
|
|
255
|
-
margin: 1.12rem 1.12rem 0;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
.stripe-payment {
|
|
259
|
-
&__row {
|
|
260
|
-
margin-bottom: 0.56rem;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
&__footer {
|
|
264
|
-
margin: 0 0 1.12rem;
|
|
265
|
-
|
|
266
|
-
> * {
|
|
267
|
-
padding: 0;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
button,
|
|
271
|
-
.submit-button {
|
|
272
|
-
border-top-left-radius: 5px;
|
|
273
|
-
border-top-right-radius: 5px;
|
|
274
|
-
margin: 0;
|
|
275
|
-
width: auto;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/* Minimal Style */
|
|
282
|
-
|
|
283
|
-
.wpbnbd.is-style-minimal {
|
|
284
|
-
.wp-block-newspack-blocks-donate__stripe {
|
|
285
|
-
margin: 0;
|
|
286
|
-
text-align: left;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
.stripe-payment {
|
|
290
|
-
&__row {
|
|
291
|
-
margin-bottom: 0.56rem;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
&__inputs {
|
|
295
|
-
margin-bottom: 1.12rem;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
&__footer {
|
|
299
|
-
margin: 0 0 1.12rem;
|
|
300
|
-
|
|
301
|
-
> * {
|
|
302
|
-
padding: 0;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import 'regenerator-runtime';
|
|
2
|
-
|
|
3
|
-
import { computeFeeAmount } from './utils';
|
|
4
|
-
|
|
5
|
-
describe( 'Fee computation', () => {
|
|
6
|
-
it( 'computes fee with default values', () => {
|
|
7
|
-
expect( computeFeeAmount( 1, 2.9, 0.3 ) ).toBe( 0.34 );
|
|
8
|
-
expect( computeFeeAmount( 15, 2.9, 0.3 ) ).toBe( 0.76 );
|
|
9
|
-
expect( computeFeeAmount( 100, 2.9, 0.3 ) ).toBe( 3.3 );
|
|
10
|
-
} );
|
|
11
|
-
it( 'computes fee with other values', () => {
|
|
12
|
-
expect( computeFeeAmount( 15, 0, 0 ) ).toBe( 0 );
|
|
13
|
-
expect( computeFeeAmount( 15, 2.3, 0.3 ) ).toBe( 0.66 );
|
|
14
|
-
expect( computeFeeAmount( 15, 2.3, 0 ) ).toBe( 0.35 );
|
|
15
|
-
expect( computeFeeAmount( 15, 50, 0 ) ).toBe( 15 );
|
|
16
|
-
expect( computeFeeAmount( 15, 50, 10 ) ).toBe( 35 );
|
|
17
|
-
} );
|
|
18
|
-
} );
|