@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 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
- new ApplePay();
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
@@ -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
- const pageform = document.querySelector("form.en__component--page");
36
- if (!this.applePay || !window.hasOwnProperty("ApplePaySession")) {
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
- if (ENGrid.debug)
41
- console.log("Apple Pay DISABLED");
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
- yield promise.then((canMakePayments) => {
47
- applePayEnabled = canMakePayments;
48
- if (canMakePayments) {
49
- let input = document.createElement("input");
50
- input.setAttribute("type", "hidden");
51
- input.setAttribute("name", "PkPaymentToken");
52
- input.setAttribute("id", "applePayToken");
53
- pageform.appendChild(input);
54
- this._form.onSubmit.subscribe(() => this.onPayClicked());
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
- else {
65
- // Hide Apple Pay Wrapper
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,5 +1,6 @@
1
1
  export interface Options {
2
2
  backgroundImage?: string | string[];
3
+ UseBodyBannerImageAsBackground?: boolean;
3
4
  MediaAttribution?: boolean;
4
5
  applePay?: boolean;
5
6
  CapitalizeFields?: boolean;
@@ -54,4 +54,5 @@ export const OptionsDefaults = {
54
54
  "rightright1col",
55
55
  "none",
56
56
  ],
57
+ UseBodyBannerImageAsBackground: false,
57
58
  };
@@ -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
  */
@@ -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 (!this.pageBackground) {
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
- if (!this.pageBackground)
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
- const pageBackgroundImg = this.pageBackground.querySelector("img");
24
- if (!pageBackgroundImg) {
25
- 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");
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
- const dataSrc = pageBackgroundImg.getAttribute("data-src");
29
- const src = pageBackgroundImg.src;
30
- if (dataSrc) {
31
- this.setBackgroundImageUrl(dataSrc, "data-src");
43
+ this.setBackgroundImageUrl(imageSource.url, imageSource.sourceType);
44
+ }
45
+ getBackgroundImage() {
46
+ if (!this.pageBackground) {
47
+ return null;
32
48
  }
33
- else if (src) {
34
- this.setBackgroundImageUrl(src, "src");
49
+ const existingImage = this.pageBackground.querySelector("img");
50
+ if (existingImage) {
51
+ return existingImage;
35
52
  }
36
- else {
37
- this.logger.log("A background image set in the page was found but without a data-src or src value, no action taken", pageBackgroundImg);
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.25.12";
1
+ export declare const AppVersion = "0.26.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const AppVersion = "0.25.12";
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.25.12",
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": "79a43bee4e541f226dd438124f7a0d14f3169586",
28
+ "gitHead": "c87a860f3a1f50d089c6219377dbaf87311a6914",
29
29
  "devDependencies": {
30
30
  "nodemon": "^2.0.20"
31
31
  }