@4site/engrid-scripts 0.19.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.
Files changed (189) hide show
  1. package/.prettierrc.js +226 -0
  2. package/LICENSE +24 -0
  3. package/dist/a11y.d.ts +6 -0
  4. package/dist/a11y.js +46 -0
  5. package/dist/add-name-to-message.d.ts +5 -0
  6. package/dist/add-name-to-message.js +49 -0
  7. package/dist/advocacy.d.ts +7 -0
  8. package/dist/advocacy.js +34 -0
  9. package/dist/amount-label.d.ts +6 -0
  10. package/dist/amount-label.js +29 -0
  11. package/dist/app.d.ts +19 -0
  12. package/dist/app.js +340 -0
  13. package/dist/apple-pay.d.ts +13 -0
  14. package/dist/apple-pay.js +169 -0
  15. package/dist/auto-country-select.d.ts +10 -0
  16. package/dist/auto-country-select.js +63 -0
  17. package/dist/auto-year.d.ts +7 -0
  18. package/dist/auto-year.js +35 -0
  19. package/dist/autocomplete.d.ts +5 -0
  20. package/dist/autocomplete.js +38 -0
  21. package/dist/autosubmit.d.ts +5 -0
  22. package/dist/autosubmit.js +14 -0
  23. package/dist/branding-html.d.ts +14 -0
  24. package/dist/branding-html.js +70 -0
  25. package/dist/capitalize-fields.d.ts +7 -0
  26. package/dist/capitalize-fields.js +22 -0
  27. package/dist/click-to-expand.d.ts +4 -0
  28. package/dist/click-to-expand.js +39 -0
  29. package/dist/cookie.d.ts +53 -0
  30. package/dist/cookie.js +76 -0
  31. package/dist/country-disable.d.ts +4 -0
  32. package/dist/country-disable.js +22 -0
  33. package/dist/country-redirect.d.ts +7 -0
  34. package/dist/country-redirect.js +61 -0
  35. package/dist/custom-currency.d.ts +9 -0
  36. package/dist/custom-currency.js +112 -0
  37. package/dist/data-attributes.d.ts +5 -0
  38. package/dist/data-attributes.js +122 -0
  39. package/dist/data-hide.d.ts +15 -0
  40. package/dist/data-hide.js +66 -0
  41. package/dist/data-layer.d.ts +23 -0
  42. package/dist/data-layer.js +312 -0
  43. package/dist/data-replace.d.ts +26 -0
  44. package/dist/data-replace.js +76 -0
  45. package/dist/debug-hidden-fields.d.ts +4 -0
  46. package/dist/debug-hidden-fields.js +42 -0
  47. package/dist/debug-panel.d.ts +27 -0
  48. package/dist/debug-panel.js +508 -0
  49. package/dist/deprecated.d.ts +5 -0
  50. package/dist/deprecated.js +40 -0
  51. package/dist/digital-wallets.d.ts +8 -0
  52. package/dist/digital-wallets.js +143 -0
  53. package/dist/ecard-to-target.d.ts +11 -0
  54. package/dist/ecard-to-target.js +73 -0
  55. package/dist/ecard.d.ts +8 -0
  56. package/dist/ecard.js +61 -0
  57. package/dist/embedded-ecard.d.ts +18 -0
  58. package/dist/embedded-ecard.js +267 -0
  59. package/dist/en-validators.d.ts +10 -0
  60. package/dist/en-validators.js +89 -0
  61. package/dist/engrid.d.ts +49 -0
  62. package/dist/engrid.js +547 -0
  63. package/dist/event-tickets.d.ts +3 -0
  64. package/dist/event-tickets.js +24 -0
  65. package/dist/events/country.d.ts +12 -0
  66. package/dist/events/country.js +42 -0
  67. package/dist/events/donation-amount.d.ts +16 -0
  68. package/dist/events/donation-amount.js +119 -0
  69. package/dist/events/donation-frequency.d.ts +17 -0
  70. package/dist/events/donation-frequency.js +115 -0
  71. package/dist/events/en-form.d.ts +20 -0
  72. package/dist/events/en-form.js +52 -0
  73. package/dist/events/index.d.ts +6 -0
  74. package/dist/events/index.js +6 -0
  75. package/dist/events/processing-fees.d.ts +20 -0
  76. package/dist/events/processing-fees.js +92 -0
  77. package/dist/events/remember-me-events.d.ts +18 -0
  78. package/dist/events/remember-me-events.js +36 -0
  79. package/dist/exit-intent-lightbox.d.ts +14 -0
  80. package/dist/exit-intent-lightbox.js +145 -0
  81. package/dist/expand-region-name.d.ts +7 -0
  82. package/dist/expand-region-name.js +44 -0
  83. package/dist/fast-form-fill.d.ts +8 -0
  84. package/dist/fast-form-fill.js +75 -0
  85. package/dist/freshaddress.d.ts +18 -0
  86. package/dist/freshaddress.js +204 -0
  87. package/dist/give-by-select.d.ts +9 -0
  88. package/dist/give-by-select.js +82 -0
  89. package/dist/iframe.d.ts +16 -0
  90. package/dist/iframe.js +217 -0
  91. package/dist/index.d.ts +82 -0
  92. package/dist/index.js +84 -0
  93. package/dist/input-has-value-and-focus.d.ts +9 -0
  94. package/dist/input-has-value-and-focus.js +50 -0
  95. package/dist/input-placeholders.d.ts +7 -0
  96. package/dist/input-placeholders.js +82 -0
  97. package/dist/interfaces/ecard-to-target-options.d.ts +9 -0
  98. package/dist/interfaces/ecard-to-target-options.js +8 -0
  99. package/dist/interfaces/embedded-ecard-options.d.ts +8 -0
  100. package/dist/interfaces/embedded-ecard-options.js +7 -0
  101. package/dist/interfaces/exit-intent-options.d.ts +13 -0
  102. package/dist/interfaces/exit-intent-options.js +13 -0
  103. package/dist/interfaces/options.d.ts +147 -0
  104. package/dist/interfaces/options.js +50 -0
  105. package/dist/interfaces/translate-options.d.ts +7 -0
  106. package/dist/interfaces/translate-options.js +42 -0
  107. package/dist/interfaces/upsell-options.d.ts +24 -0
  108. package/dist/interfaces/upsell-options.js +33 -0
  109. package/dist/live-currency.d.ts +15 -0
  110. package/dist/live-currency.js +140 -0
  111. package/dist/live-frequency.d.ts +13 -0
  112. package/dist/live-frequency.js +109 -0
  113. package/dist/live-variables.d.ts +21 -0
  114. package/dist/live-variables.js +147 -0
  115. package/dist/loader.d.ts +10 -0
  116. package/dist/loader.js +175 -0
  117. package/dist/logger.d.ts +16 -0
  118. package/dist/logger.js +84 -0
  119. package/dist/media-attribution.d.ts +4 -0
  120. package/dist/media-attribution.js +66 -0
  121. package/dist/menu.d.ts +0 -0
  122. package/dist/menu.js +1 -0
  123. package/dist/min-max-amount.d.ts +13 -0
  124. package/dist/min-max-amount.js +71 -0
  125. package/dist/mobile-cta.d.ts +9 -0
  126. package/dist/mobile-cta.js +71 -0
  127. package/dist/modal.d.ts +19 -0
  128. package/dist/modal.js +129 -0
  129. package/dist/neverbounce.d.ts +23 -0
  130. package/dist/neverbounce.js +244 -0
  131. package/dist/other-amount.d.ts +6 -0
  132. package/dist/other-amount.js +70 -0
  133. package/dist/page-background.d.ts +7 -0
  134. package/dist/page-background.js +55 -0
  135. package/dist/plaid.d.ts +6 -0
  136. package/dist/plaid.js +49 -0
  137. package/dist/postal-code-validator.d.ts +20 -0
  138. package/dist/postal-code-validator.js +118 -0
  139. package/dist/premium-gift.d.ts +10 -0
  140. package/dist/premium-gift.js +115 -0
  141. package/dist/progress-bar.d.ts +3 -0
  142. package/dist/progress-bar.js +40 -0
  143. package/dist/remember-me.d.ts +61 -0
  144. package/dist/remember-me.js +358 -0
  145. package/dist/required-if-visible.d.ts +8 -0
  146. package/dist/required-if-visible.js +60 -0
  147. package/dist/set-attr.d.ts +4 -0
  148. package/dist/set-attr.js +31 -0
  149. package/dist/set-recurr-freq.d.ts +7 -0
  150. package/dist/set-recurr-freq.js +70 -0
  151. package/dist/show-hide-radio-checkboxes.d.ts +13 -0
  152. package/dist/show-hide-radio-checkboxes.js +161 -0
  153. package/dist/show-if-amount.d.ts +15 -0
  154. package/dist/show-if-amount.js +117 -0
  155. package/dist/show-if-present.d.ts +7 -0
  156. package/dist/show-if-present.js +79 -0
  157. package/dist/skip-link.d.ts +4 -0
  158. package/dist/skip-link.js +36 -0
  159. package/dist/src-defer.d.ts +6 -0
  160. package/dist/src-defer.js +70 -0
  161. package/dist/supporter-hub.d.ts +9 -0
  162. package/dist/supporter-hub.js +75 -0
  163. package/dist/swap-amounts.d.ts +45 -0
  164. package/dist/swap-amounts.js +81 -0
  165. package/dist/thank-you-page-conditional-content.d.ts +8 -0
  166. package/dist/thank-you-page-conditional-content.js +46 -0
  167. package/dist/ticker.d.ts +11 -0
  168. package/dist/ticker.js +66 -0
  169. package/dist/tidycontact.d.ts +46 -0
  170. package/dist/tidycontact.js +1202 -0
  171. package/dist/translate-fields.d.ts +12 -0
  172. package/dist/translate-fields.js +548 -0
  173. package/dist/universal-opt-in.d.ts +7 -0
  174. package/dist/universal-opt-in.js +91 -0
  175. package/dist/upsell-lightbox.d.ts +31 -0
  176. package/dist/upsell-lightbox.js +363 -0
  177. package/dist/url-params-to-body-attrs.d.ts +5 -0
  178. package/dist/url-params-to-body-attrs.js +14 -0
  179. package/dist/url-to-form.d.ts +7 -0
  180. package/dist/url-to-form.js +32 -0
  181. package/dist/us-only-form.d.ts +4 -0
  182. package/dist/us-only-form.js +30 -0
  183. package/dist/version.d.ts +1 -0
  184. package/dist/version.js +1 -0
  185. package/dist/vgs.d.ts +16 -0
  186. package/dist/vgs.js +250 -0
  187. package/dist/welcome-back.d.ts +10 -0
  188. package/dist/welcome-back.js +112 -0
  189. package/package.json +32 -0
@@ -0,0 +1,71 @@
1
+ // This component adds a floating CTA button to the page, which can be used to scroll to the top of the form
2
+ import { ENGrid } from ".";
3
+ export class MobileCTA {
4
+ constructor() {
5
+ var _a, _b, _c;
6
+ // Initialize options with the MobileCTA value or false
7
+ this.options = (_a = ENGrid.getOption("MobileCTA")) !== null && _a !== void 0 ? _a : false;
8
+ this.buttonLabel = "";
9
+ // Return early if the options object is falsy or the current page type is not in the options.pages array
10
+ if (!this.options ||
11
+ !((_b = this.options.pages) === null || _b === void 0 ? void 0 : _b.includes(ENGrid.getPageType())) ||
12
+ ENGrid.getPageNumber() !== 1)
13
+ return;
14
+ // Set the button label using the options.label or the default value "Take Action"
15
+ this.buttonLabel = (_c = this.options.label) !== null && _c !== void 0 ? _c : "Take Action";
16
+ this.renderButton();
17
+ this.addEventListeners();
18
+ }
19
+ renderButton() {
20
+ const engridDiv = document.querySelector("#engrid");
21
+ const formBlock = document.querySelector(".body-main .en__component--widgetblock:first-child, .en__component--formblock");
22
+ // Return early if engridDiv or formBlock are not found
23
+ if (!engridDiv || !formBlock)
24
+ return;
25
+ const buttonContainer = document.createElement("div");
26
+ const button = document.createElement("button");
27
+ // Add necessary classes and set the initial display style for the button container
28
+ buttonContainer.classList.add("engrid-mobile-cta-container");
29
+ buttonContainer.style.display = "none";
30
+ button.classList.add("primary");
31
+ // Set the button's innerHTML and add a click event listener
32
+ button.innerHTML = this.buttonLabel;
33
+ button.addEventListener("click", () => {
34
+ formBlock.scrollIntoView({ behavior: "smooth" });
35
+ });
36
+ // Append the button to the button container and the container to engridDiv
37
+ buttonContainer.appendChild(button);
38
+ engridDiv.appendChild(buttonContainer);
39
+ }
40
+ addEventListeners() {
41
+ const bodyMain = document.querySelector(".body-main");
42
+ // Return early if formBlock is not found
43
+ if (!bodyMain)
44
+ return;
45
+ // Define a function to toggle the button visibility based on the bodyMain position
46
+ const toggleButton = () => {
47
+ if (bodyMain.getBoundingClientRect().top <= window.innerHeight - 100) {
48
+ this.hideButton();
49
+ }
50
+ else {
51
+ this.showButton();
52
+ }
53
+ };
54
+ // Add event listeners for load, resize, and scroll events to toggle the button visibility
55
+ window.addEventListener("load", toggleButton);
56
+ window.addEventListener("resize", toggleButton);
57
+ window.addEventListener("scroll", toggleButton);
58
+ }
59
+ // Hide the button by setting the container's display style to "none"
60
+ hideButton() {
61
+ const buttonContainer = document.querySelector(".engrid-mobile-cta-container");
62
+ if (buttonContainer)
63
+ buttonContainer.style.display = "none";
64
+ }
65
+ // Show the button by setting the container's display style to "block"
66
+ showButton() {
67
+ const buttonContainer = document.querySelector(".engrid-mobile-cta-container");
68
+ if (buttonContainer)
69
+ buttonContainer.style.display = "block";
70
+ }
71
+ }
@@ -0,0 +1,19 @@
1
+ interface ModalOptions {
2
+ onClickOutside: "close" | "bounce";
3
+ addCloseButton: boolean;
4
+ closeButtonLabel: string;
5
+ }
6
+ export declare abstract class Modal {
7
+ modalContent: NodeListOf<Element> | HTMLElement | String;
8
+ private modal;
9
+ private defaultOptions;
10
+ private options;
11
+ protected constructor(options: ModalOptions);
12
+ private createModal;
13
+ private addEventListeners;
14
+ private focusTrapHandler;
15
+ open(): void;
16
+ close(): void;
17
+ getModalContent(): NodeListOf<Element> | HTMLElement | String;
18
+ }
19
+ export {};
package/dist/modal.js ADDED
@@ -0,0 +1,129 @@
1
+ import { ENGrid } from "./engrid";
2
+ export class Modal {
3
+ constructor(options) {
4
+ this.modal = null;
5
+ this.defaultOptions = {
6
+ onClickOutside: "close",
7
+ addCloseButton: false,
8
+ closeButtonLabel: "Okay!",
9
+ };
10
+ this.focusTrapHandler = (e) => {
11
+ const modalElement = this.modal;
12
+ const focusableElements = [
13
+ ...modalElement.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'),
14
+ ];
15
+ const firstFocusable = focusableElements[0];
16
+ const lastFocusable = focusableElements[focusableElements.length - 1];
17
+ const isTabPressed = e.key === "Tab";
18
+ if (!isTabPressed) {
19
+ return;
20
+ }
21
+ if (e.shiftKey) {
22
+ if (document.activeElement === firstFocusable) {
23
+ e.preventDefault();
24
+ lastFocusable.focus();
25
+ }
26
+ }
27
+ else {
28
+ if (document.activeElement === lastFocusable) {
29
+ e.preventDefault();
30
+ firstFocusable.focus();
31
+ }
32
+ }
33
+ };
34
+ this.options = Object.assign(Object.assign({}, this.defaultOptions), options);
35
+ this.modalContent = this.getModalContent();
36
+ this.createModal();
37
+ }
38
+ createModal() {
39
+ var _a;
40
+ this.modal = document.createElement("div");
41
+ this.modal.classList.add("engrid-modal", "modal--hidden");
42
+ this.modal.setAttribute("aria-hidden", "true");
43
+ this.modal.setAttribute("role", "dialog");
44
+ this.modal.setAttribute("aria-modal", "true");
45
+ this.modal.setAttribute("tabindex", "-1");
46
+ this.modal.innerHTML = `
47
+ <div class="engrid-modal__overlay" tabindex="-1">
48
+ <div class="engrid-modal__container" tabindex="0">
49
+ <div class="engrid-modal__close" role="button" tabindex="0" aria-label="Close">
50
+ X
51
+ </div>
52
+ <div class="engrid-modal__body"></div>
53
+ </div>
54
+ </div>
55
+ `;
56
+ (_a = document.getElementById("engrid")) === null || _a === void 0 ? void 0 : _a.appendChild(this.modal);
57
+ const modalBody = this.modal.querySelector(".engrid-modal__body");
58
+ if (this.modalContent instanceof NodeList) {
59
+ this.modalContent.forEach((content) => {
60
+ modalBody === null || modalBody === void 0 ? void 0 : modalBody.appendChild(content);
61
+ });
62
+ }
63
+ else if (typeof this.modalContent === "string") {
64
+ modalBody === null || modalBody === void 0 ? void 0 : modalBody.insertAdjacentHTML("beforeend", this.modalContent);
65
+ }
66
+ else {
67
+ modalBody === null || modalBody === void 0 ? void 0 : modalBody.appendChild(this.modalContent);
68
+ }
69
+ if (this.options.addCloseButton) {
70
+ const button = document.createElement("button");
71
+ button.classList.add("engrid-modal__button");
72
+ button.textContent = this.options.closeButtonLabel;
73
+ button.addEventListener("click", () => {
74
+ this.close();
75
+ });
76
+ modalBody === null || modalBody === void 0 ? void 0 : modalBody.appendChild(button);
77
+ }
78
+ this.addEventListeners();
79
+ }
80
+ addEventListeners() {
81
+ var _a, _b, _c, _d, _e;
82
+ // Close event on top X
83
+ (_b = (_a = this.modal) === null || _a === void 0 ? void 0 : _a.querySelector(".engrid-modal__close")) === null || _b === void 0 ? void 0 : _b.addEventListener("click", () => {
84
+ this.close();
85
+ });
86
+ // Bounce scale when clicking outside of modal
87
+ (_d = (_c = this.modal) === null || _c === void 0 ? void 0 : _c.querySelector(".engrid-modal__overlay")) === null || _d === void 0 ? void 0 : _d.addEventListener("click", (event) => {
88
+ if (event.target === event.currentTarget) {
89
+ if (this.options.onClickOutside === "close") {
90
+ this.close();
91
+ }
92
+ else if (this.options.onClickOutside === "bounce") {
93
+ const modal = document.querySelector(".engrid-modal");
94
+ if (modal) {
95
+ modal.classList.remove("engrid-modal--scale");
96
+ void modal.clientWidth;
97
+ modal.classList.add("engrid-modal--scale");
98
+ }
99
+ }
100
+ }
101
+ });
102
+ // Close on "modal__close" click
103
+ const closeEls = (_e = this.modal) === null || _e === void 0 ? void 0 : _e.querySelectorAll(".modal__close");
104
+ closeEls === null || closeEls === void 0 ? void 0 : closeEls.forEach((el) => {
105
+ el.addEventListener("click", () => {
106
+ this.close();
107
+ });
108
+ });
109
+ }
110
+ open() {
111
+ var _a, _b, _c, _d;
112
+ ENGrid.setBodyData("has-lightbox", "true");
113
+ (_a = this.modal) === null || _a === void 0 ? void 0 : _a.classList.remove("modal--hidden");
114
+ (_b = this.modal) === null || _b === void 0 ? void 0 : _b.removeAttribute("aria-hidden");
115
+ const container = (_c = this.modal) === null || _c === void 0 ? void 0 : _c.querySelector(".engrid-modal__container");
116
+ container === null || container === void 0 ? void 0 : container.focus({ preventScroll: true });
117
+ (_d = this.modal) === null || _d === void 0 ? void 0 : _d.addEventListener("keydown", this.focusTrapHandler);
118
+ }
119
+ close() {
120
+ var _a, _b, _c;
121
+ ENGrid.setBodyData("has-lightbox", false);
122
+ (_a = this.modal) === null || _a === void 0 ? void 0 : _a.classList.add("modal--hidden");
123
+ (_b = this.modal) === null || _b === void 0 ? void 0 : _b.setAttribute("aria-hidden", "true");
124
+ (_c = this.modal) === null || _c === void 0 ? void 0 : _c.removeEventListener("keydown", this.focusTrapHandler);
125
+ }
126
+ getModalContent() {
127
+ return "<h1>Default Modal Content</h1>";
128
+ }
129
+ }
@@ -0,0 +1,23 @@
1
+ import { EnForm } from "./events";
2
+ export declare class NeverBounce {
3
+ private apiKey;
4
+ dateField: string | null;
5
+ statusField: string | null;
6
+ dateFormat: string | undefined;
7
+ form: EnForm;
8
+ emailField: HTMLInputElement | null;
9
+ emailWrapper: HTMLDivElement;
10
+ nbDate: HTMLInputElement | null;
11
+ nbStatus: HTMLInputElement | null;
12
+ private logger;
13
+ private shouldRun;
14
+ private nbLoaded;
15
+ constructor(apiKey: string, dateField: string | null, statusField: string | null, dateFormat: string | undefined);
16
+ private init;
17
+ private clearStatus;
18
+ private deleteENFieldError;
19
+ private setEmailStatus;
20
+ private insertAfter;
21
+ private wrap;
22
+ private validate;
23
+ }
@@ -0,0 +1,244 @@
1
+ import { ENGrid, EngridLogger } from ".";
2
+ import { EnForm } from "./events";
3
+ export class NeverBounce {
4
+ constructor(apiKey, dateField = null, statusField = null, dateFormat) {
5
+ this.apiKey = apiKey;
6
+ this.dateField = dateField;
7
+ this.statusField = statusField;
8
+ this.dateFormat = dateFormat;
9
+ this.form = EnForm.getInstance();
10
+ this.emailField = null;
11
+ this.emailWrapper = document.querySelector(".en__field--emailAddress");
12
+ this.nbDate = null;
13
+ this.nbStatus = null;
14
+ this.logger = new EngridLogger("NeverBounce", "#039bc4", "#dfdfdf", "📧");
15
+ this.shouldRun = true;
16
+ this.nbLoaded = false;
17
+ this.emailField = document.getElementById("en__field_supporter_emailAddress");
18
+ window._NBSettings = {
19
+ apiKey: this.apiKey,
20
+ autoFieldHookup: false,
21
+ inputLatency: 1500,
22
+ displayPoweredBy: false,
23
+ loadingMessage: "Validating...",
24
+ softRejectMessage: "Invalid email",
25
+ acceptedMessage: "Email validated!",
26
+ feedback: false,
27
+ };
28
+ ENGrid.loadJS("https://cdn.neverbounce.com/widget/dist/NeverBounce.js");
29
+ if (this.emailField) {
30
+ if (this.emailField.value) {
31
+ this.logger.log("E-mail Field Found");
32
+ this.shouldRun = false;
33
+ }
34
+ this.emailField.addEventListener("change", (e) => {
35
+ var _a;
36
+ if (!this.nbLoaded) {
37
+ this.shouldRun = true;
38
+ this.init();
39
+ if ((_a = this.emailField) === null || _a === void 0 ? void 0 : _a.value) {
40
+ setTimeout(function () {
41
+ window._nb.fields
42
+ .get(document.querySelector("[data-nb-id]"))[0]
43
+ .forceUpdate();
44
+ }, 100);
45
+ }
46
+ }
47
+ });
48
+ window.setTimeout(() => {
49
+ if (this.emailField && this.emailField.value) {
50
+ this.logger.log("E-mail Filled Programatically");
51
+ this.shouldRun = false;
52
+ }
53
+ this.init();
54
+ }, 1000);
55
+ }
56
+ this.form.onValidate.subscribe(this.validate.bind(this));
57
+ }
58
+ init() {
59
+ if (!this.shouldRun) {
60
+ this.logger.log("Should Not Run");
61
+ return;
62
+ }
63
+ if (this.nbLoaded) {
64
+ this.logger.log("Already Loaded");
65
+ return;
66
+ }
67
+ this.logger.log("Init Function");
68
+ if (this.dateField && document.getElementsByName(this.dateField).length)
69
+ this.nbDate = document.querySelector("[name='" + this.dateField + "']");
70
+ if (this.statusField && document.getElementsByName(this.statusField).length)
71
+ this.nbStatus = document.querySelector("[name='" + this.statusField + "']");
72
+ if (!this.emailField) {
73
+ this.logger.log("E-mail Field Not Found");
74
+ return;
75
+ }
76
+ this.wrap(this.emailField, document.createElement("div"));
77
+ const parentNode = this.emailField.parentNode;
78
+ parentNode.id = "nb-wrapper";
79
+ // Define HTML structure for a Custom NB Message and insert it after Email field
80
+ const nbCustomMessageHTML = document.createElement("div");
81
+ nbCustomMessageHTML.innerHTML =
82
+ '<div id="nb-feedback" class="en__field__error nb-hidden">Enter a valid email.</div>';
83
+ this.insertAfter(nbCustomMessageHTML, this.emailField);
84
+ const NBClass = this;
85
+ document.body.addEventListener("nb:registered", function (event) {
86
+ const field = document.querySelector('[data-nb-id="' + event.detail.id + '"]');
87
+ field.addEventListener("nb:loading", function (e) {
88
+ ENGrid.disableSubmit("Validating Your Email");
89
+ });
90
+ // Never Bounce: Do work when input changes or when API responds with an error
91
+ field.addEventListener("nb:clear", function (e) {
92
+ NBClass.setEmailStatus("clear");
93
+ ENGrid.enableSubmit();
94
+ if (NBClass.nbDate)
95
+ NBClass.nbDate.value = "";
96
+ if (NBClass.nbStatus)
97
+ NBClass.nbStatus.value = "";
98
+ });
99
+ // Never Bounce: Do work when results have an input that does not look like an email (i.e. missing @ or no .com/.net/etc...)
100
+ field.addEventListener("nb:soft-result", function (e) {
101
+ NBClass.setEmailStatus("soft-result");
102
+ if (NBClass.nbDate)
103
+ NBClass.nbDate.value = "";
104
+ if (NBClass.nbStatus)
105
+ NBClass.nbStatus.value = "";
106
+ ENGrid.enableSubmit();
107
+ });
108
+ // Never Bounce: When results have been received
109
+ field.addEventListener("nb:result", function (e) {
110
+ if (e.detail.result.is(window._nb.settings.getAcceptedStatusCodes())) {
111
+ NBClass.setEmailStatus("valid");
112
+ if (NBClass.nbDate)
113
+ NBClass.nbDate.value = ENGrid.formatDate(new Date(), NBClass.dateFormat);
114
+ if (NBClass.nbStatus)
115
+ NBClass.nbStatus.value = (e).detail.result.response.result;
116
+ }
117
+ else {
118
+ NBClass.setEmailStatus("invalid");
119
+ if (NBClass.nbDate)
120
+ NBClass.nbDate.value = "";
121
+ if (NBClass.nbStatus)
122
+ NBClass.nbStatus.value = "";
123
+ }
124
+ ENGrid.enableSubmit();
125
+ });
126
+ });
127
+ // Never Bounce: Register field with the widget and broadcast nb:registration event
128
+ window._nb.fields.registerListener(NBClass.emailField, true);
129
+ this.nbLoaded = true;
130
+ }
131
+ clearStatus() {
132
+ if (!this.emailField) {
133
+ this.logger.log("E-mail Field Not Found");
134
+ return;
135
+ }
136
+ this.emailField.classList.remove("rm-error");
137
+ // Search page for the NB Wrapper div and set as variable
138
+ const nb_email_field_wrapper = (document.getElementById("nb-wrapper"));
139
+ // Search page for the NB Feedback div and set as variable
140
+ const nb_email_feedback_field = (document.getElementById("nb-feedback"));
141
+ nb_email_field_wrapper.className = "";
142
+ nb_email_feedback_field.className = "en__field__error nb-hidden";
143
+ nb_email_feedback_field.innerHTML = "";
144
+ this.emailWrapper.classList.remove("en__field--validationFailed");
145
+ }
146
+ deleteENFieldError() {
147
+ const errorField = (document.querySelector(".en__field--emailAddress>div.en__field__error"));
148
+ if (errorField)
149
+ errorField.remove();
150
+ }
151
+ setEmailStatus(status) {
152
+ this.logger.log("Status:", status);
153
+ if (!this.emailField) {
154
+ this.logger.log("E-mail Field Not Found");
155
+ return;
156
+ }
157
+ // Search page for the NB Wrapper div and set as variable
158
+ const nb_email_field_wrapper = (document.getElementById("nb-wrapper"));
159
+ // Search page for the NB Feedback div and set as variable
160
+ let nb_email_feedback_field = (document.getElementById("nb-feedback"));
161
+ // classes to add or remove based on neverbounce results
162
+ const nb_email_field_wrapper_success = "nb-success";
163
+ const nb_email_field_wrapper_error = "nb-error";
164
+ const nb_email_feedback_hidden = "nb-hidden";
165
+ const nb_email_feedback_loading = "nb-loading";
166
+ const nb_email_field_error = "rm-error";
167
+ if (!nb_email_feedback_field) {
168
+ const nbWrapperDiv = nb_email_field_wrapper.querySelector("div");
169
+ if (nbWrapperDiv)
170
+ nbWrapperDiv.innerHTML =
171
+ '<div id="nb-feedback" class="en__field__error nb-hidden">Enter a valid email.</div>';
172
+ nb_email_feedback_field = (document.getElementById("nb-feedback"));
173
+ }
174
+ if (status == "valid") {
175
+ this.clearStatus();
176
+ }
177
+ else {
178
+ nb_email_field_wrapper.classList.remove(nb_email_field_wrapper_success);
179
+ nb_email_field_wrapper.classList.add(nb_email_field_wrapper_error);
180
+ switch (status) {
181
+ case "required": // special case status that we added ourselves -- doesn't come from NB
182
+ this.deleteENFieldError();
183
+ nb_email_feedback_field.innerHTML = "A valid email is required";
184
+ nb_email_feedback_field.classList.remove(nb_email_feedback_loading);
185
+ nb_email_feedback_field.classList.remove(nb_email_feedback_hidden);
186
+ this.emailField.classList.add(nb_email_field_error);
187
+ break;
188
+ case "soft-result":
189
+ if (this.emailField.value) {
190
+ this.deleteENFieldError();
191
+ nb_email_feedback_field.innerHTML = "Invalid email";
192
+ nb_email_feedback_field.classList.remove(nb_email_feedback_hidden);
193
+ this.emailField.classList.add(nb_email_field_error);
194
+ }
195
+ else {
196
+ this.clearStatus();
197
+ }
198
+ break;
199
+ case "invalid":
200
+ this.deleteENFieldError();
201
+ nb_email_feedback_field.innerHTML = "Invalid email";
202
+ nb_email_feedback_field.classList.remove(nb_email_feedback_loading);
203
+ nb_email_feedback_field.classList.remove(nb_email_feedback_hidden);
204
+ this.emailField.classList.add(nb_email_field_error);
205
+ break;
206
+ case "loading":
207
+ case "clear":
208
+ default:
209
+ this.clearStatus();
210
+ break;
211
+ }
212
+ }
213
+ }
214
+ // Function to insert HTML after a DIV
215
+ insertAfter(el, referenceNode) {
216
+ var _a;
217
+ (_a = referenceNode === null || referenceNode === void 0 ? void 0 : referenceNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(el, referenceNode.nextSibling);
218
+ }
219
+ // to Wrap HTML around a DIV
220
+ wrap(el, wrapper) {
221
+ var _a;
222
+ (_a = el.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(wrapper, el);
223
+ wrapper.appendChild(el);
224
+ }
225
+ validate() {
226
+ var _a;
227
+ if (!this.form.validate)
228
+ return;
229
+ const nbResult = ENGrid.getFieldValue("nb-result");
230
+ if (!this.emailField || !this.shouldRun || !this.nbLoaded || !nbResult) {
231
+ this.logger.log("validate(): Should Not Run. Returning true.");
232
+ return;
233
+ }
234
+ if (this.nbStatus) {
235
+ this.nbStatus.value = nbResult;
236
+ }
237
+ if (!["catchall", "unknown", "valid"].includes(nbResult)) {
238
+ this.setEmailStatus("required");
239
+ (_a = this.emailField) === null || _a === void 0 ? void 0 : _a.focus();
240
+ this.logger.log("NB-Result:", ENGrid.getFieldValue("nb-result"));
241
+ this.form.validate = false;
242
+ }
243
+ }
244
+ }
@@ -0,0 +1,6 @@
1
+ export declare class OtherAmount {
2
+ private logger;
3
+ private _amount;
4
+ constructor();
5
+ private setRadioInput;
6
+ }
@@ -0,0 +1,70 @@
1
+ // This class automatically select other radio input when an amount is entered into it.
2
+ import { EngridLogger, ENGrid, DonationAmount } from ".";
3
+ export class OtherAmount {
4
+ constructor() {
5
+ this.logger = new EngridLogger("OtherAmount", "green", "black", "💰");
6
+ this._amount = DonationAmount.getInstance();
7
+ "focusin input".split(" ").forEach((e) => {
8
+ var _a;
9
+ // We're attaching this event to the body because sometimes the other amount input is not in the DOM yet and comes via AJAX.
10
+ (_a = document.querySelector("body")) === null || _a === void 0 ? void 0 : _a.addEventListener(e, (event) => {
11
+ const target = event.target;
12
+ if (target.classList.contains("en__field__input--other")) {
13
+ this.logger.log("Other Amount Field Focused");
14
+ this.setRadioInput();
15
+ }
16
+ });
17
+ });
18
+ const otherAmountField = document.querySelector("[name='transaction.donationAmt.other'");
19
+ if (otherAmountField) {
20
+ otherAmountField.setAttribute("inputmode", "decimal");
21
+ // ADD THE MISSING LABEL FOR IMPROVED ACCESSABILITY
22
+ otherAmountField.setAttribute("aria-label", "Enter your custom donation amount");
23
+ otherAmountField.setAttribute("autocomplete", "off");
24
+ otherAmountField.setAttribute("data-lpignore", "true");
25
+ otherAmountField.addEventListener("change", (e) => {
26
+ const target = e.target;
27
+ const amount = target.value;
28
+ const cleanAmount = ENGrid.cleanAmount(amount);
29
+ if (amount !== cleanAmount.toString()) {
30
+ this.logger.log(`Other Amount Field Changed: ${amount} => ${cleanAmount}`);
31
+ if ("dataLayer" in window) {
32
+ window.dataLayer.push({
33
+ event: "otherAmountTransformed",
34
+ otherAmountTransformation: `${amount} => ${cleanAmount}`,
35
+ });
36
+ }
37
+ target.value =
38
+ cleanAmount % 1 != 0
39
+ ? cleanAmount.toFixed(2)
40
+ : cleanAmount.toString();
41
+ }
42
+ });
43
+ // On blur, if the amount is 0, select the previous amount
44
+ otherAmountField.addEventListener("blur", (e) => {
45
+ const target = e.target;
46
+ const amount = target.value;
47
+ const cleanAmount = ENGrid.cleanAmount(amount);
48
+ if (cleanAmount === 0) {
49
+ this.logger.log("Other Amount Field Blurred with 0 amount");
50
+ // Get Live Amount
51
+ const liveAmount = this._amount.amount;
52
+ if (liveAmount > 0) {
53
+ this._amount.setAmount(liveAmount, false);
54
+ }
55
+ }
56
+ });
57
+ }
58
+ }
59
+ setRadioInput() {
60
+ const target = document.querySelector(".en__field--donationAmt .en__field__input--other");
61
+ if (target && target.parentNode && target.parentNode.parentNode) {
62
+ const targetWrapper = target.parentNode;
63
+ targetWrapper.classList.remove("en__field__item--hidden");
64
+ if (targetWrapper.parentNode) {
65
+ const lastRadioInput = targetWrapper.parentNode.querySelector(".en__field__item:nth-last-child(2) input");
66
+ lastRadioInput.checked = !0;
67
+ }
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,7 @@
1
+ export declare class PageBackground {
2
+ private pageBackground;
3
+ constructor();
4
+ private setDataAttributes;
5
+ private hasVideoBackground;
6
+ private hasImageBackground;
7
+ }
@@ -0,0 +1,55 @@
1
+ import { ENGrid } from "./engrid";
2
+ export class PageBackground {
3
+ constructor() {
4
+ // @TODO: Change page-backgroundImage to page-background
5
+ this.pageBackground = document.querySelector(".page-backgroundImage");
6
+ // Finds any <img> added to the "backgroundImage" ENGRid section and sets it as the "--engrid__page-backgroundImage_url" CSS Custom Property
7
+ if (this.pageBackground) {
8
+ const pageBackgroundImg = this.pageBackground.querySelector("img");
9
+ let pageBackgroundImgDataSrc = pageBackgroundImg === null || pageBackgroundImg === void 0 ? void 0 : pageBackgroundImg.getAttribute("data-src");
10
+ let pageBackgroundImgSrc = pageBackgroundImg === null || pageBackgroundImg === void 0 ? void 0 : pageBackgroundImg.src;
11
+ if (this.pageBackground && pageBackgroundImgDataSrc) {
12
+ if (ENGrid.debug)
13
+ console.log("A background image set in the page was found with a data-src value, setting it as --engrid__page-backgroundImage_url", pageBackgroundImgDataSrc);
14
+ pageBackgroundImgDataSrc = "url('" + pageBackgroundImgDataSrc + "')";
15
+ this.pageBackground.style.setProperty("--engrid__page-backgroundImage_url", pageBackgroundImgDataSrc);
16
+ }
17
+ else if (this.pageBackground && pageBackgroundImgSrc) {
18
+ if (ENGrid.debug)
19
+ console.log("A background image set in the page was found with a src value, setting it as --engrid__page-backgroundImage_url", pageBackgroundImgSrc);
20
+ pageBackgroundImgSrc = "url('" + pageBackgroundImgSrc + "')";
21
+ this.pageBackground.style.setProperty("--engrid__page-backgroundImage_url", pageBackgroundImgSrc);
22
+ }
23
+ else if (pageBackgroundImg) {
24
+ if (ENGrid.debug)
25
+ console.log("A background image set in the page was found but without a data-src or src value, no action taken", pageBackgroundImg);
26
+ }
27
+ else {
28
+ if (ENGrid.debug)
29
+ console.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");
30
+ }
31
+ }
32
+ else {
33
+ if (ENGrid.debug)
34
+ console.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");
35
+ }
36
+ this.setDataAttributes();
37
+ }
38
+ setDataAttributes() {
39
+ if (this.hasVideoBackground())
40
+ return ENGrid.setBodyData("page-background", "video");
41
+ if (this.hasImageBackground())
42
+ return ENGrid.setBodyData("page-background", "image");
43
+ return ENGrid.setBodyData("page-background", "empty");
44
+ }
45
+ hasVideoBackground() {
46
+ if (this.pageBackground) {
47
+ return !!this.pageBackground.querySelector("video");
48
+ }
49
+ }
50
+ hasImageBackground() {
51
+ if (this.pageBackground) {
52
+ return (!this.hasVideoBackground() && !!this.pageBackground.querySelector("img"));
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,6 @@
1
+ export declare class Plaid {
2
+ private logger;
3
+ private _form;
4
+ constructor();
5
+ submit(): void;
6
+ }