@4site/engrid-scripts 0.25.12 → 0.26.0
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/dist/app.js +3 -3
- package/dist/apple-pay.d.ts +18 -3
- package/dist/apple-pay.js +290 -96
- package/dist/engrid.js +1 -1
- package/dist/interfaces/options.d.ts +1 -0
- package/dist/interfaces/options.js +1 -0
- package/dist/page-background.d.ts +7 -1
- package/dist/page-background.js +57 -14
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/app.js
CHANGED
|
@@ -180,12 +180,14 @@ export class App extends ENGrid {
|
|
|
180
180
|
new CustomCurrency();
|
|
181
181
|
// Auto Country Select
|
|
182
182
|
new AutoCountrySelect();
|
|
183
|
+
// Page Background
|
|
184
|
+
new PageBackground(this.options.UseBodyBannerImageAsBackground);
|
|
183
185
|
// Add Image Attribution
|
|
184
186
|
if (this.options.MediaAttribution)
|
|
185
187
|
new MediaAttribution();
|
|
186
188
|
// Apple Pay
|
|
187
189
|
if (this.options.applePay)
|
|
188
|
-
|
|
190
|
+
ApplePay.getInstance();
|
|
189
191
|
// Capitalize Fields
|
|
190
192
|
if (this.options.CapitalizeFields)
|
|
191
193
|
new CapitalizeFields();
|
|
@@ -230,8 +232,6 @@ export class App extends ENGrid {
|
|
|
230
232
|
new A11y();
|
|
231
233
|
new AddNameToMessage();
|
|
232
234
|
new ExpandRegionName();
|
|
233
|
-
// Page Background
|
|
234
|
-
new PageBackground();
|
|
235
235
|
// Url Params to Form Fields
|
|
236
236
|
new UrlToForm();
|
|
237
237
|
// Required if Visible Fields
|
package/dist/apple-pay.d.ts
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { EnForm, DonationAmount, ProcessingFees } from ".";
|
|
2
2
|
export declare class ApplePay {
|
|
3
|
+
private logger;
|
|
3
4
|
applePay: HTMLInputElement;
|
|
4
5
|
_amount: DonationAmount;
|
|
5
6
|
_fees: ProcessingFees;
|
|
6
7
|
_form: EnForm;
|
|
8
|
+
beforeSession: (() => boolean) | null;
|
|
9
|
+
private walletFields;
|
|
10
|
+
private errorFields;
|
|
11
|
+
private static instance;
|
|
7
12
|
constructor();
|
|
13
|
+
static getInstance(): ApplePay;
|
|
14
|
+
private hasApplePayOption;
|
|
8
15
|
private checkApplePay;
|
|
16
|
+
private writeButtonContainer;
|
|
17
|
+
private onSubmitFallback;
|
|
18
|
+
onPayClicked(): void;
|
|
19
|
+
private preflight;
|
|
20
|
+
private scrollToError;
|
|
21
|
+
private clearErrors;
|
|
22
|
+
private missingMandatoryFields;
|
|
23
|
+
private openSession;
|
|
24
|
+
private onPaymentAuthorized;
|
|
25
|
+
private setField;
|
|
26
|
+
private setRegion;
|
|
9
27
|
performValidation(url: string): Promise<unknown>;
|
|
10
|
-
private log;
|
|
11
|
-
sendPaymentToken(token: any): Promise<unknown>;
|
|
12
|
-
private onPayClicked;
|
|
13
28
|
}
|
package/dist/apple-pay.js
CHANGED
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { EnForm, DonationAmount, ENGrid, ProcessingFees } from ".";
|
|
10
|
+
import { EnForm, DonationAmount, ENGrid, ProcessingFees, EngridLogger, } from ".";
|
|
11
11
|
/*global window */
|
|
12
12
|
const ApplePaySession = window.ApplePaySession;
|
|
13
13
|
const merchantIdentifier = window.merchantIdentifier;
|
|
@@ -24,50 +24,313 @@ const merchantCapabilities = window.merchantCapabilities;
|
|
|
24
24
|
const merchantTotalLabel = window.merchantTotalLabel;
|
|
25
25
|
export class ApplePay {
|
|
26
26
|
constructor() {
|
|
27
|
+
this.logger = new EngridLogger("ApplePay", "#000000", "#a6f3a6", "🍎");
|
|
27
28
|
this.applePay = document.querySelector('.en__field__input.en__field__input--radio[value="applepay"]');
|
|
28
29
|
this._amount = DonationAmount.getInstance();
|
|
29
30
|
this._fees = ProcessingFees.getInstance();
|
|
30
31
|
this._form = EnForm.getInstance();
|
|
32
|
+
// Client hook: runs after the built-in pre-flight, right before the Apple
|
|
33
|
+
// Pay sheet opens. Return false to abort. The hook shows its own errors
|
|
34
|
+
// with ENGrid.setError; the donation amount field error is cleared before
|
|
35
|
+
// every attempt.
|
|
36
|
+
this.beforeSession = null;
|
|
37
|
+
// Fields the wallet supplies via requiredBillingContactFields, so they are
|
|
38
|
+
// excluded from the mandatory-field pre-flight.
|
|
39
|
+
this.walletFields = [
|
|
40
|
+
"supporter.address1",
|
|
41
|
+
"supporter.address2",
|
|
42
|
+
"supporter.city",
|
|
43
|
+
"supporter.region",
|
|
44
|
+
"supporter.postcode",
|
|
45
|
+
"supporter.country",
|
|
46
|
+
"supporter.phoneNumber",
|
|
47
|
+
];
|
|
48
|
+
// Field containers this component flagged with ENGrid.setError, so they can
|
|
49
|
+
// be cleared on the next attempt.
|
|
50
|
+
this.errorFields = [];
|
|
51
|
+
ApplePay.instance = this;
|
|
31
52
|
this.checkApplePay();
|
|
32
53
|
}
|
|
54
|
+
static getInstance() {
|
|
55
|
+
if (!ApplePay.instance) {
|
|
56
|
+
ApplePay.instance = new ApplePay();
|
|
57
|
+
}
|
|
58
|
+
return ApplePay.instance;
|
|
59
|
+
}
|
|
60
|
+
// True when the page offers Apple Pay, either as a giveBySelect radio tile
|
|
61
|
+
// or as an option of the payment type select.
|
|
62
|
+
hasApplePayOption() {
|
|
63
|
+
if (this.applePay)
|
|
64
|
+
return true;
|
|
65
|
+
const paymentTypeField = ENGrid.getField("transaction.paymenttype");
|
|
66
|
+
if (!paymentTypeField || !paymentTypeField.options)
|
|
67
|
+
return false;
|
|
68
|
+
return Array.from(paymentTypeField.options).some((option) => option.value.toLowerCase() === "applepay");
|
|
69
|
+
}
|
|
33
70
|
checkApplePay() {
|
|
34
71
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
-
|
|
36
|
-
|
|
72
|
+
if (!this.hasApplePayOption() ||
|
|
73
|
+
!window.hasOwnProperty("ApplePaySession")) {
|
|
37
74
|
const applePayContainer = document.querySelector(".en__field__item.applepay");
|
|
38
75
|
if (applePayContainer)
|
|
39
76
|
applePayContainer.remove();
|
|
40
|
-
|
|
41
|
-
|
|
77
|
+
ENGrid.setBodyData("apple-pay-available", "false");
|
|
78
|
+
this.logger.log("DISABLED: not supported by this browser or page");
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
if (!merchantIdentifier) {
|
|
82
|
+
ENGrid.setBodyData("apple-pay-available", "false");
|
|
83
|
+
this.logger.log("DISABLED: window.merchantIdentifier is not defined");
|
|
42
84
|
return false;
|
|
43
85
|
}
|
|
44
|
-
const promise = ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);
|
|
45
86
|
let applePayEnabled = false;
|
|
46
|
-
|
|
47
|
-
applePayEnabled =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
87
|
+
try {
|
|
88
|
+
applePayEnabled = yield ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
applePayEnabled = false;
|
|
92
|
+
}
|
|
93
|
+
ENGrid.setBodyData("apple-pay-available", applePayEnabled ? "true" : "false");
|
|
94
|
+
if (!applePayEnabled) {
|
|
95
|
+
this.logger.log("DISABLED: no provisioned card");
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
// Hidden field that carries the wallet token to EN. Only create it if it
|
|
99
|
+
// doesn't exist yet, so we never post a duplicate PkPaymentToken.
|
|
100
|
+
if (!ENGrid.getField("PkPaymentToken")) {
|
|
101
|
+
ENGrid.createHiddenInput("PkPaymentToken").setAttribute("id", "applePayToken");
|
|
102
|
+
}
|
|
103
|
+
this.writeButtonContainer();
|
|
104
|
+
// Fallback trigger: an implicit submit (e.g. Enter key) while Apple Pay
|
|
105
|
+
// is selected and no token exists yet opens the sheet instead of
|
|
106
|
+
// submitting. After authorization the token is set and the submit
|
|
107
|
+
// passes through.
|
|
108
|
+
this._form.onSubmit.subscribe(() => this.onSubmitFallback());
|
|
109
|
+
this.logger.log("ENABLED");
|
|
110
|
+
return true;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// Writes the native Apple Pay button container right before the submit
|
|
114
|
+
// button. CSS swaps it with the submit button while the applepay payment
|
|
115
|
+
// type is selected (data-engrid-payment-type="applepay").
|
|
116
|
+
writeButtonContainer() {
|
|
117
|
+
if (document.querySelector(".apple-pay-container"))
|
|
118
|
+
return;
|
|
119
|
+
if (!document.querySelector(".en__submit"))
|
|
120
|
+
return;
|
|
121
|
+
// The -apple-pay-button-* properties are set inline because cssnano's
|
|
122
|
+
// colormin rewrites the keyword "black" to #000 in built stylesheets,
|
|
123
|
+
// which is not a valid value for -apple-pay-button-style, so Safari
|
|
124
|
+
// drops it and falls back to white-outline.
|
|
125
|
+
ENGrid.addHtml('<div class="apple-pay-container showif-applepay-selected">' +
|
|
126
|
+
'<div class="apple-pay-button" role="button" tabindex="0" aria-label="Donate with Apple Pay" ' +
|
|
127
|
+
'style="-apple-pay-button-type: donate; -apple-pay-button-style: black;"></div>' +
|
|
128
|
+
"</div>", ".en__submit", "before");
|
|
129
|
+
const button = document.querySelector(".apple-pay-container .apple-pay-button");
|
|
130
|
+
if (!button)
|
|
131
|
+
return;
|
|
132
|
+
button.addEventListener("click", () => this.onPayClicked());
|
|
133
|
+
button.addEventListener("keydown", (event) => {
|
|
134
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
this.onPayClicked();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
onSubmitFallback() {
|
|
141
|
+
const applePayToken = document.getElementById("applePayToken");
|
|
142
|
+
if (ENGrid.getPaymentType().toLowerCase() !== "applepay" ||
|
|
143
|
+
(applePayToken && applePayToken.value !== "")) {
|
|
144
|
+
return; // Not Apple Pay, or already authorized: let the submit proceed
|
|
145
|
+
}
|
|
146
|
+
if (!this._form.submit)
|
|
147
|
+
return; // Another component vetoed this submit
|
|
148
|
+
this._form.submit = false; // Veto the submit and open the sheet instead
|
|
149
|
+
this.onPayClicked();
|
|
150
|
+
}
|
|
151
|
+
onPayClicked() {
|
|
152
|
+
if (!this.preflight())
|
|
153
|
+
return;
|
|
154
|
+
this.openSession();
|
|
155
|
+
}
|
|
156
|
+
preflight() {
|
|
157
|
+
this.clearErrors();
|
|
158
|
+
// The wallet supplies billing address and phone, but nothing else. Flag
|
|
159
|
+
// empty mandatory fields before the sheet opens so a donor never
|
|
160
|
+
// authorizes a payment EN will bounce for a missing mandatory field.
|
|
161
|
+
const missing = this.missingMandatoryFields();
|
|
162
|
+
missing.forEach((field) => {
|
|
163
|
+
ENGrid.setError(field, "This field is required");
|
|
164
|
+
this.errorFields.push(field);
|
|
165
|
+
});
|
|
166
|
+
if (missing.length) {
|
|
167
|
+
this.scrollToError();
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
const amount = this._amount.amount;
|
|
171
|
+
if (!amount || amount <= 0) {
|
|
172
|
+
ENGrid.setError(".en__field--donationAmt", "Please select a gift amount.");
|
|
173
|
+
this.scrollToError();
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
// The client hook owns the donation amount field error from here on
|
|
177
|
+
ENGrid.removeError(".en__field--donationAmt");
|
|
178
|
+
if (this.beforeSession && this.beforeSession() === false) {
|
|
179
|
+
this.scrollToError();
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
// Scrolls to the first field flagged with a validation error so the donor
|
|
185
|
+
// sees what needs fixing; without this the button looks unresponsive.
|
|
186
|
+
scrollToError() {
|
|
187
|
+
const errorField = (this.errorFields[0] ||
|
|
188
|
+
document.querySelector(".en__field--validationFailed"));
|
|
189
|
+
if (errorField) {
|
|
190
|
+
errorField.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
clearErrors() {
|
|
194
|
+
this.errorFields.forEach((field) => ENGrid.removeError(field));
|
|
195
|
+
this.errorFields = [];
|
|
196
|
+
ENGrid.removeError(".en__field--donationAmt");
|
|
197
|
+
}
|
|
198
|
+
// Every visible mandatory field container that is empty and that the
|
|
199
|
+
// wallet cannot fill.
|
|
200
|
+
missingMandatoryFields() {
|
|
201
|
+
const missing = [];
|
|
202
|
+
document
|
|
203
|
+
.querySelectorAll(".en__field.en__mandatory")
|
|
204
|
+
.forEach((field) => {
|
|
205
|
+
const fieldElement = field;
|
|
206
|
+
if (!ENGrid.isVisible(fieldElement))
|
|
207
|
+
return;
|
|
208
|
+
const input = fieldElement.querySelector("input, select, textarea");
|
|
209
|
+
if (!input || !input.name)
|
|
210
|
+
return;
|
|
211
|
+
if (this.walletFields.indexOf(input.name) !== -1)
|
|
212
|
+
return;
|
|
213
|
+
if (input.type === "radio" || input.type === "checkbox") {
|
|
214
|
+
if (!fieldElement.querySelector("input:checked")) {
|
|
215
|
+
missing.push(fieldElement);
|
|
55
216
|
}
|
|
56
|
-
|
|
57
|
-
if (ENGrid.debug)
|
|
58
|
-
console.log("applePayEnabled", applePayEnabled);
|
|
59
|
-
let applePayWrapper = this.applePay.closest(".en__field__item");
|
|
60
|
-
if (applePayEnabled) {
|
|
61
|
-
// Set Apple Pay Class
|
|
62
|
-
applePayWrapper === null || applePayWrapper === void 0 ? void 0 : applePayWrapper.classList.add("applePayWrapper");
|
|
217
|
+
return;
|
|
63
218
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (applePayWrapper)
|
|
67
|
-
applePayWrapper.style.display = "none";
|
|
219
|
+
if (input.value.trim() === "") {
|
|
220
|
+
missing.push(fieldElement);
|
|
68
221
|
}
|
|
69
|
-
return applePayEnabled;
|
|
70
222
|
});
|
|
223
|
+
return missing;
|
|
224
|
+
}
|
|
225
|
+
openSession() {
|
|
226
|
+
// ProcessingFees mirrors EN's own fee cover calculation, so the sheet
|
|
227
|
+
// total matches what EN will actually charge.
|
|
228
|
+
const donationAmount = (this._amount.amount + this._fees.fee).toFixed(2);
|
|
229
|
+
const request = {
|
|
230
|
+
supportedNetworks: merchantSupportedNetworks,
|
|
231
|
+
merchantCapabilities: merchantCapabilities,
|
|
232
|
+
countryCode: merchantCountryCode,
|
|
233
|
+
currencyCode: merchantCurrencyCode,
|
|
234
|
+
requiredBillingContactFields: ["postalAddress", "phone"],
|
|
235
|
+
total: {
|
|
236
|
+
label: merchantTotalLabel || merchantDisplayName || "Donation",
|
|
237
|
+
amount: donationAmount,
|
|
238
|
+
type: "final",
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
let session;
|
|
242
|
+
try {
|
|
243
|
+
session = new ApplePaySession(3, request);
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
const errorTarget = (document.querySelector(".apple-pay-container") || document.querySelector(".en__submit"));
|
|
247
|
+
if (errorTarget) {
|
|
248
|
+
ENGrid.setError(errorTarget, "Apple Pay error: '" + e.message + "'");
|
|
249
|
+
}
|
|
250
|
+
this._form.dispatchError();
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const thisClass = this;
|
|
254
|
+
session.onvalidatemerchant = function (event) {
|
|
255
|
+
thisClass
|
|
256
|
+
.performValidation(event.validationURL)
|
|
257
|
+
.then(function (merchantSession) {
|
|
258
|
+
if (ENGrid.debug)
|
|
259
|
+
console.log("Apple Pay merchantSession", merchantSession);
|
|
260
|
+
session.completeMerchantValidation(merchantSession);
|
|
261
|
+
})
|
|
262
|
+
.catch(function () {
|
|
263
|
+
session.abort();
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
session.onpaymentauthorized = function (event) {
|
|
267
|
+
thisClass.onPaymentAuthorized(session, event);
|
|
268
|
+
};
|
|
269
|
+
session.oncancel = function () {
|
|
270
|
+
// Donor closed the sheet; return them to the form quietly.
|
|
271
|
+
thisClass.logger.log("Sheet cancelled by the donor");
|
|
272
|
+
};
|
|
273
|
+
session.begin();
|
|
274
|
+
}
|
|
275
|
+
onPaymentAuthorized(session, event) {
|
|
276
|
+
if (ENGrid.debug)
|
|
277
|
+
console.log("Apple Pay Token", event.payment.token);
|
|
278
|
+
// Pass the billing info from Apple Pay back into the EN billing fields -
|
|
279
|
+
// this won't happen automatically with Vantiv Apple Pay.
|
|
280
|
+
const billing = event.payment.billingContact || {};
|
|
281
|
+
const addressLines = billing.addressLines || [];
|
|
282
|
+
// Country goes first, dispatching change: EN swaps country-dependent
|
|
283
|
+
// fields (supporter.region is a select for some countries and a text
|
|
284
|
+
// input for others) when the country changes, so the region field must
|
|
285
|
+
// already be in its final shape when we fill it below.
|
|
286
|
+
this.setField("supporter.country", billing.countryCode, true);
|
|
287
|
+
this.setField("supporter.address1", addressLines[0]);
|
|
288
|
+
this.setField("supporter.address2", addressLines[1]);
|
|
289
|
+
this.setField("supporter.city", billing.locality);
|
|
290
|
+
if (billing.administrativeArea) {
|
|
291
|
+
this.setRegion(billing.administrativeArea);
|
|
292
|
+
}
|
|
293
|
+
this.setField("supporter.postcode", billing.postalCode);
|
|
294
|
+
this.setField("supporter.phoneNumber", billing.phone);
|
|
295
|
+
// Apple Pay gifts are one-time on this setup; make sure recurrpay isn't
|
|
296
|
+
// submitted blank when we bypass the EN submit button.
|
|
297
|
+
const recurrpay = ENGrid.getField("transaction.recurrpay");
|
|
298
|
+
if (recurrpay && !recurrpay.value)
|
|
299
|
+
recurrpay.value = "N";
|
|
300
|
+
const applePayToken = document.getElementById("applePayToken");
|
|
301
|
+
if (applePayToken) {
|
|
302
|
+
applePayToken.value = JSON.stringify(event.payment.token);
|
|
303
|
+
}
|
|
304
|
+
session.completePayment(ApplePaySession.STATUS_SUCCESS);
|
|
305
|
+
this._form.submitForm();
|
|
306
|
+
}
|
|
307
|
+
setField(name, value, dispatchEvents = false) {
|
|
308
|
+
if (value == null || value === "")
|
|
309
|
+
return;
|
|
310
|
+
if (!ENGrid.getField(name))
|
|
311
|
+
return;
|
|
312
|
+
ENGrid.setFieldValue(name, value, true, dispatchEvents);
|
|
313
|
+
}
|
|
314
|
+
// The region field is a select for countries EN has subdivisions for and a
|
|
315
|
+
// text input for the rest. On a select, the wallet value must match an
|
|
316
|
+
// option or the write is silently dropped, so match case-insensitively by
|
|
317
|
+
// option value or label (Apple returns subdivision codes for some
|
|
318
|
+
// countries and full names for others).
|
|
319
|
+
setRegion(value) {
|
|
320
|
+
const field = ENGrid.getField("supporter.region");
|
|
321
|
+
if (!field)
|
|
322
|
+
return;
|
|
323
|
+
if (field instanceof HTMLSelectElement) {
|
|
324
|
+
const option = Array.from(field.options).find((o) => o.value.toLowerCase() === value.toLowerCase() ||
|
|
325
|
+
o.text.toLowerCase() === value.toLowerCase());
|
|
326
|
+
if (!option) {
|
|
327
|
+
this.logger.log(`Region "${value}" doesn't match any region select option`);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
ENGrid.setFieldValue("supporter.region", option.value);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
ENGrid.setFieldValue("supporter.region", value);
|
|
71
334
|
}
|
|
72
335
|
performValidation(url) {
|
|
73
336
|
return new Promise(function (resolve, reject) {
|
|
@@ -97,73 +360,4 @@ export class ApplePay {
|
|
|
97
360
|
xhr.send();
|
|
98
361
|
});
|
|
99
362
|
}
|
|
100
|
-
log(name, msg) {
|
|
101
|
-
var xhr = new XMLHttpRequest();
|
|
102
|
-
xhr.open("GET", "/ea-dataservice/rest/applepay/log?name=" + name + "&msg=" + msg);
|
|
103
|
-
xhr.send();
|
|
104
|
-
}
|
|
105
|
-
sendPaymentToken(token) {
|
|
106
|
-
return new Promise(function (resolve, reject) {
|
|
107
|
-
resolve(true);
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
onPayClicked() {
|
|
111
|
-
if (!this._form.submit)
|
|
112
|
-
return;
|
|
113
|
-
const enFieldPaymentType = document.querySelector("#en__field_transaction_paymenttype");
|
|
114
|
-
const applePayToken = document.getElementById("applePayToken");
|
|
115
|
-
const formClass = this._form;
|
|
116
|
-
// Only work if Payment Type is Apple Pay
|
|
117
|
-
if (enFieldPaymentType.value == "applepay" && applePayToken.value == "") {
|
|
118
|
-
try {
|
|
119
|
-
let donationAmount = this._amount.amount + this._fees.fee;
|
|
120
|
-
var request = {
|
|
121
|
-
supportedNetworks: merchantSupportedNetworks,
|
|
122
|
-
merchantCapabilities: merchantCapabilities,
|
|
123
|
-
countryCode: merchantCountryCode,
|
|
124
|
-
currencyCode: merchantCurrencyCode,
|
|
125
|
-
total: {
|
|
126
|
-
label: merchantTotalLabel,
|
|
127
|
-
amount: donationAmount,
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
var session = new ApplePaySession(1, request);
|
|
131
|
-
var thisClass = this;
|
|
132
|
-
session.onvalidatemerchant = function (event) {
|
|
133
|
-
thisClass
|
|
134
|
-
.performValidation(event.validationURL)
|
|
135
|
-
.then(function (merchantSession) {
|
|
136
|
-
if (ENGrid.debug)
|
|
137
|
-
console.log("Apple Pay merchantSession", merchantSession);
|
|
138
|
-
session.completeMerchantValidation(merchantSession);
|
|
139
|
-
});
|
|
140
|
-
};
|
|
141
|
-
session.onpaymentauthorized = function (event) {
|
|
142
|
-
thisClass
|
|
143
|
-
.sendPaymentToken(event.payment.token)
|
|
144
|
-
.then(function (success) {
|
|
145
|
-
if (ENGrid.debug)
|
|
146
|
-
console.log("Apple Pay Token", event.payment.token);
|
|
147
|
-
document.getElementById("applePayToken").value = JSON.stringify(event.payment.token);
|
|
148
|
-
formClass.submitForm();
|
|
149
|
-
});
|
|
150
|
-
};
|
|
151
|
-
session.oncancel = function (event) {
|
|
152
|
-
if (ENGrid.debug)
|
|
153
|
-
console.log("Cancelled", event);
|
|
154
|
-
alert("You cancelled. Sorry it didn't work out.");
|
|
155
|
-
formClass.dispatchError();
|
|
156
|
-
};
|
|
157
|
-
session.begin();
|
|
158
|
-
this._form.submit = false;
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
catch (e) {
|
|
162
|
-
alert("Developer mistake: '" + e.message + "'");
|
|
163
|
-
formClass.dispatchError();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
this._form.submit = true;
|
|
167
|
-
return true;
|
|
168
|
-
}
|
|
169
363
|
}
|
package/dist/engrid.js
CHANGED
|
@@ -171,7 +171,7 @@ export class ENGrid {
|
|
|
171
171
|
return null;
|
|
172
172
|
}
|
|
173
173
|
static isThankYouPage() {
|
|
174
|
-
return this.getPageNumber() === this.getPageCount();
|
|
174
|
+
return (this.getPageNumber() === this.getPageCount() && this.getPageCount() > 1);
|
|
175
175
|
}
|
|
176
176
|
// Return the current page ID
|
|
177
177
|
static getPageID() {
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
export declare class PageBackground {
|
|
2
2
|
private pageBackground;
|
|
3
|
+
private bodyBanner;
|
|
4
|
+
private bodyBannerImage;
|
|
3
5
|
private mutationObserver;
|
|
4
6
|
private logger;
|
|
5
|
-
constructor();
|
|
7
|
+
constructor(useBodyBannerImage?: boolean);
|
|
8
|
+
private findBodyBannerImage;
|
|
6
9
|
/**
|
|
7
10
|
* Initialize background image by finding and setting CSS custom property
|
|
8
11
|
*/
|
|
9
12
|
private initializeBackgroundImage;
|
|
13
|
+
private getBackgroundImage;
|
|
14
|
+
private useBodyBannerAsBackground;
|
|
15
|
+
private getImageSource;
|
|
10
16
|
/**
|
|
11
17
|
* Set the background image URL as a CSS custom property
|
|
12
18
|
*/
|
package/dist/page-background.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { ENGrid, EngridLogger } from ".";
|
|
2
2
|
export class PageBackground {
|
|
3
|
-
constructor() {
|
|
3
|
+
constructor(useBodyBannerImage = false) {
|
|
4
4
|
// @TODO: Change page-backgroundImage to page-background
|
|
5
5
|
this.pageBackground = document.querySelector(".page-backgroundImage");
|
|
6
|
+
this.bodyBanner = document.querySelector(".body-banner");
|
|
7
|
+
this.bodyBannerImage = null;
|
|
6
8
|
this.mutationObserver = null;
|
|
7
9
|
this.logger = new EngridLogger("PageBackground", "lightblue", "darkblue", "🖼️");
|
|
8
|
-
if (
|
|
10
|
+
if (useBodyBannerImage) {
|
|
11
|
+
this.bodyBannerImage = this.findBodyBannerImage();
|
|
12
|
+
}
|
|
13
|
+
if (!this.pageBackground && !this.bodyBannerImage) {
|
|
9
14
|
this.logger.log("A background image set in the page was not found, any default image set in the theme on --engrid__page-backgroundImage_url will be used");
|
|
10
15
|
return;
|
|
11
16
|
}
|
|
@@ -14,28 +19,66 @@ export class PageBackground {
|
|
|
14
19
|
this.processAttributionPositioning();
|
|
15
20
|
this.setupMutationObserver();
|
|
16
21
|
}
|
|
22
|
+
findBodyBannerImage() {
|
|
23
|
+
var _a;
|
|
24
|
+
if (!this.bodyBanner) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return ((_a = this.bodyBanner.querySelector("img.preferred-image")) !== null && _a !== void 0 ? _a : this.bodyBanner.querySelector("img"));
|
|
28
|
+
}
|
|
17
29
|
/**
|
|
18
30
|
* Initialize background image by finding and setting CSS custom property
|
|
19
31
|
*/
|
|
20
32
|
initializeBackgroundImage() {
|
|
21
|
-
|
|
33
|
+
const backgroundImg = this.getBackgroundImage();
|
|
34
|
+
if (!backgroundImg) {
|
|
35
|
+
this.logger.log("No image found in page background and no body banner image found (or pageBackground is already occupied), any default image set in the theme on --engrid__page-backgroundImage_url will be used");
|
|
22
36
|
return;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
}
|
|
38
|
+
const imageSource = this.getImageSource(backgroundImg);
|
|
39
|
+
if (!imageSource) {
|
|
40
|
+
this.logger.log("A background image set in the page was found but without a data-src or src value, no action taken", backgroundImg);
|
|
26
41
|
return;
|
|
27
42
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
this.setBackgroundImageUrl(imageSource.url, imageSource.sourceType);
|
|
44
|
+
}
|
|
45
|
+
getBackgroundImage() {
|
|
46
|
+
if (!this.pageBackground) {
|
|
47
|
+
return null;
|
|
32
48
|
}
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
const existingImage = this.pageBackground.querySelector("img");
|
|
50
|
+
if (existingImage) {
|
|
51
|
+
return existingImage;
|
|
35
52
|
}
|
|
36
|
-
|
|
37
|
-
this.
|
|
53
|
+
if (this.bodyBannerImage && this.pageBackground.children.length === 0) {
|
|
54
|
+
return this.useBodyBannerAsBackground();
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
useBodyBannerAsBackground() {
|
|
59
|
+
var _a;
|
|
60
|
+
if (!this.pageBackground || !this.bodyBanner) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
this.logger.log("No image found in page background, using body banner image as background image instead");
|
|
64
|
+
const clonedBodyBanner = this.bodyBanner.cloneNode(true);
|
|
65
|
+
while (clonedBodyBanner.firstChild) {
|
|
66
|
+
this.pageBackground.appendChild(clonedBodyBanner.firstChild);
|
|
67
|
+
}
|
|
68
|
+
document.body.removeAttribute("data-engrid-no-page-backgroundImage");
|
|
69
|
+
ENGrid.setBodyData("use-body-banner-background", "");
|
|
70
|
+
return ((_a = this.pageBackground.querySelector("img.preferred-image")) !== null && _a !== void 0 ? _a : this.pageBackground.querySelector("img"));
|
|
71
|
+
}
|
|
72
|
+
getImageSource(backgroundImg) {
|
|
73
|
+
const dataSrc = backgroundImg.getAttribute("data-src");
|
|
74
|
+
if (dataSrc) {
|
|
75
|
+
return { sourceType: "data-src", url: dataSrc };
|
|
76
|
+
}
|
|
77
|
+
const src = backgroundImg.src;
|
|
78
|
+
if (src) {
|
|
79
|
+
return { sourceType: "src", url: src };
|
|
38
80
|
}
|
|
81
|
+
return null;
|
|
39
82
|
}
|
|
40
83
|
/**
|
|
41
84
|
* Set the background image URL as a CSS custom property
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AppVersion = "0.
|
|
1
|
+
export declare const AppVersion = "0.26.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AppVersion = "0.
|
|
1
|
+
export const AppVersion = "0.26.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4site/engrid-scripts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Scripts for the ENGRID Project",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"strongly-typed-events": "^2.0.9"
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/4site-interactive-studios/engrid#readme",
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "c87a860f3a1f50d089c6219377dbaf87311a6914",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"nodemon": "^2.0.20"
|
|
31
31
|
}
|