@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,143 @@
1
+ import { ENGrid } from "./engrid";
2
+ export class DigitalWallets {
3
+ constructor() {
4
+ //digital wallets not enabled.
5
+ if (!document.getElementById("en__digitalWallet")) {
6
+ ENGrid.setBodyData("payment-type-option-apple-pay", "false");
7
+ ENGrid.setBodyData("payment-type-option-google-pay", "false");
8
+ ENGrid.setBodyData("payment-type-option-paypal-one-touch", "false");
9
+ ENGrid.setBodyData("payment-type-option-venmo", "false");
10
+ ENGrid.setBodyData("payment-type-option-daf", "false");
11
+ return;
12
+ }
13
+ // Add giveBySelect classes to the separate wallet containers
14
+ // and hide them on load.
15
+ const stripeButtons = document.getElementById("en__digitalWallet__stripeButtons__container");
16
+ if (stripeButtons) {
17
+ stripeButtons.classList.add("giveBySelect-stripedigitalwallet");
18
+ stripeButtons.classList.add("showif-stripedigitalwallet-selected");
19
+ // stripeButtons.style.display = "none";
20
+ }
21
+ const paypalTouchButtons = document.getElementById("en__digitalWallet__paypalTouch__container");
22
+ if (paypalTouchButtons) {
23
+ paypalTouchButtons.classList.add("giveBySelect-paypaltouch");
24
+ paypalTouchButtons.classList.add("showif-paypaltouch-selected");
25
+ // paypalTouchButtons.style.display = "none";
26
+ }
27
+ const donorAdvisedFundButtonContainer = document.getElementById("en__digitalWallet__chariot__container");
28
+ if (donorAdvisedFundButtonContainer) {
29
+ donorAdvisedFundButtonContainer.classList.add("giveBySelect-daf");
30
+ donorAdvisedFundButtonContainer.classList.add("showif-daf-selected");
31
+ }
32
+ /**
33
+ * Check for presence of elements that indicated Stripe digital wallets
34
+ * (Google Pay, Apple Pay) have loaded, and add functionality for them.
35
+ * If they haven't yet loaded, set up a Mutation Observer to check for
36
+ * when they do.
37
+ */
38
+ if (document.querySelector("#en__digitalWallet__stripeButtons__container > *")) {
39
+ this.addStripeDigitalWallets();
40
+ }
41
+ else {
42
+ ENGrid.setBodyData("payment-type-option-apple-pay", "false");
43
+ ENGrid.setBodyData("payment-type-option-google-pay", "false");
44
+ const stripeContainer = document.getElementById("en__digitalWallet__stripeButtons__container");
45
+ if (stripeContainer) {
46
+ this.checkForWalletsBeingAdded(stripeContainer, "stripe");
47
+ }
48
+ // If the default payment type is Stripe Digital Wallet and the page doesnt support it, set the payment type to Card
49
+ const paymentType = ENGrid.getPaymentType();
50
+ if (paymentType.toLowerCase() === "stripedigitalwallet") {
51
+ ENGrid.setPaymentType("card");
52
+ }
53
+ }
54
+ /**
55
+ * Check for presence of elements that indicated Paypal digital wallets
56
+ * (Paypal One Touch, Venmo, Etc) have loaded, and add functionality for them.
57
+ * If they haven't yet loaded, set up a Mutation Observer to check for
58
+ * when they do.
59
+ */
60
+ if (document.querySelector("#en__digitalWallet__paypalTouch__container > *")) {
61
+ this.addPaypalTouchDigitalWallets();
62
+ }
63
+ else {
64
+ ENGrid.setBodyData("payment-type-option-paypal-one-touch", "false");
65
+ ENGrid.setBodyData("payment-type-option-venmo", "false");
66
+ const paypalContainer = document.getElementById("en__digitalWallet__paypalTouch__container");
67
+ if (paypalContainer) {
68
+ this.checkForWalletsBeingAdded(paypalContainer, "paypalTouch");
69
+ }
70
+ }
71
+ /**
72
+ * Check for presence of elements that indicate DAF is present, and add functionality for it.
73
+ * If it hasn't loaded yet, set up a Mutation Observer to check for when it does.
74
+ */
75
+ if (document.querySelector("#en__digitalWallet__chariot__container > *")) {
76
+ this.addDAF();
77
+ }
78
+ else {
79
+ ENGrid.setBodyData("payment-type-option-daf", "false");
80
+ const donorAdvisedFundButtonContainer = document.getElementById("en__digitalWallet__chariot__container");
81
+ if (donorAdvisedFundButtonContainer) {
82
+ this.checkForWalletsBeingAdded(donorAdvisedFundButtonContainer, "daf");
83
+ }
84
+ }
85
+ }
86
+ addStripeDigitalWallets() {
87
+ this.addOptionToPaymentTypeField("stripedigitalwallet", "GooglePay / ApplePay");
88
+ ENGrid.setBodyData("payment-type-option-apple-pay", "true");
89
+ ENGrid.setBodyData("payment-type-option-google-pay", "true");
90
+ }
91
+ addPaypalTouchDigitalWallets() {
92
+ this.addOptionToPaymentTypeField("paypaltouch", "Paypal / Venmo");
93
+ ENGrid.setBodyData("payment-type-option-paypal-one-touch", "true");
94
+ ENGrid.setBodyData("payment-type-option-venmo", "true");
95
+ }
96
+ addDAF() {
97
+ this.addOptionToPaymentTypeField("daf", "Donor Advised Fund");
98
+ ENGrid.setBodyData("payment-type-option-daf", "true");
99
+ }
100
+ addOptionToPaymentTypeField(value, label) {
101
+ const paymentTypeField = document.querySelector('[name="transaction.paymenttype"]');
102
+ if (paymentTypeField &&
103
+ !paymentTypeField.querySelector(`[value=${value}]`)) {
104
+ const walletOption = document.createElement("option");
105
+ walletOption.value = value;
106
+ walletOption.innerText = label;
107
+ paymentTypeField.appendChild(walletOption);
108
+ }
109
+ // If this payment type is set as the default on GiveBySelect, set the payment type to this value
110
+ // We need to do this here because the digital wallets are sometimes slow to load
111
+ const giveBySelect = document.querySelector('input[name="transaction.giveBySelect"][value="' + value + '"]');
112
+ if (giveBySelect && giveBySelect.dataset.default === "true") {
113
+ giveBySelect.checked = true;
114
+ const event = new Event("change", {
115
+ bubbles: true,
116
+ cancelable: true,
117
+ });
118
+ giveBySelect.dispatchEvent(event);
119
+ }
120
+ }
121
+ checkForWalletsBeingAdded(node, walletType) {
122
+ const callback = (mutationList, observer) => {
123
+ for (const mutation of mutationList) {
124
+ //Once a child node has been added, set up the appropriate digital wallet
125
+ if (mutation.type === "childList" && mutation.addedNodes.length) {
126
+ if (walletType === "stripe") {
127
+ this.addStripeDigitalWallets();
128
+ }
129
+ else if (walletType === "paypalTouch") {
130
+ this.addPaypalTouchDigitalWallets();
131
+ }
132
+ else if (walletType === "daf") {
133
+ this.addDAF();
134
+ }
135
+ //Disconnect observer to prevent multiple additions
136
+ observer.disconnect();
137
+ }
138
+ }
139
+ };
140
+ const observer = new MutationObserver(callback);
141
+ observer.observe(node, { childList: true, subtree: true });
142
+ }
143
+ }
@@ -0,0 +1,11 @@
1
+ export declare class EcardToTarget {
2
+ private readonly options;
3
+ private logger;
4
+ private _form;
5
+ private supporterNameAddedToMessage;
6
+ constructor();
7
+ private shouldRun;
8
+ private setTarget;
9
+ private hideElements;
10
+ private addSupporterNameToMessage;
11
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * This component adjusts an ecard form to target a specific recipient,
3
+ * defined in a code block
4
+ */
5
+ import { EcardToTargetOptionsDefaults, } from "./interfaces/ecard-to-target-options";
6
+ import { EngridLogger } from "./logger";
7
+ import { ENGrid } from "./engrid";
8
+ import { EnForm } from "./events";
9
+ export class EcardToTarget {
10
+ constructor() {
11
+ this.options = EcardToTargetOptionsDefaults;
12
+ this.logger = new EngridLogger("EcardToTarget", "DarkBlue", "Azure", "📧");
13
+ this._form = EnForm.getInstance();
14
+ this.supporterNameAddedToMessage = false;
15
+ if (!this.shouldRun())
16
+ return;
17
+ this.options = Object.assign(Object.assign({}, this.options), window.EngridEcardToTarget);
18
+ this.logger.log("EcardToTarget running. Options:", this.options);
19
+ this.setTarget();
20
+ this.hideElements();
21
+ this.addSupporterNameToMessage();
22
+ }
23
+ shouldRun() {
24
+ return (window.hasOwnProperty("EngridEcardToTarget") &&
25
+ typeof window.EngridEcardToTarget === "object" &&
26
+ window.EngridEcardToTarget.hasOwnProperty("targetName") &&
27
+ window.EngridEcardToTarget.hasOwnProperty("targetEmail"));
28
+ }
29
+ setTarget() {
30
+ const targetNameField = document.querySelector(".en__ecardrecipients__name input");
31
+ const targetEmailField = document.querySelector(".en__ecardrecipients__email input");
32
+ const addRecipientButton = document.querySelector(".en__ecarditems__addrecipient");
33
+ if (!targetNameField || !targetEmailField || !addRecipientButton) {
34
+ this.logger.error("Could not add recipient. Required elements not found.");
35
+ return;
36
+ }
37
+ targetNameField.value = this.options.targetName;
38
+ targetEmailField.value = this.options.targetEmail;
39
+ addRecipientButton === null || addRecipientButton === void 0 ? void 0 : addRecipientButton.click();
40
+ this.logger.log("Added recipient", this.options.targetName, this.options.targetEmail);
41
+ }
42
+ hideElements() {
43
+ const messageBlock = document.querySelector(".en__ecardmessage");
44
+ const sendDateBlock = document.querySelector(".en__ecardrecipients__futureDelivery");
45
+ const targetBlock = document.querySelector(".en__ecardrecipients");
46
+ if (this.options.hideMessage && messageBlock) {
47
+ messageBlock.classList.add("hide");
48
+ }
49
+ if (this.options.hideSendDate && sendDateBlock) {
50
+ sendDateBlock.classList.add("hide");
51
+ }
52
+ if (this.options.hideTarget && targetBlock) {
53
+ targetBlock.classList.add("hide");
54
+ }
55
+ }
56
+ addSupporterNameToMessage() {
57
+ if (!this.options.addSupporterNameToMessage)
58
+ return;
59
+ this._form.onSubmit.subscribe(() => {
60
+ if (!this._form.submit)
61
+ return;
62
+ if (!this.supporterNameAddedToMessage) {
63
+ this.supporterNameAddedToMessage = true;
64
+ const supporterName = `${ENGrid.getFieldValue("supporter.firstName")} ${ENGrid.getFieldValue("supporter.lastName")}`;
65
+ const messageField = document.querySelector("[name='transaction.comments']");
66
+ if (!messageField)
67
+ return;
68
+ messageField.value = `${messageField.value}\n${supporterName}`;
69
+ this.logger.log("Added supporter name to personalized message", supporterName);
70
+ }
71
+ });
72
+ }
73
+ }
@@ -0,0 +1,8 @@
1
+ import { EnForm } from ".";
2
+ export declare class Ecard {
3
+ _form: EnForm;
4
+ private logger;
5
+ constructor();
6
+ private shouldRun;
7
+ private checkRecipientFields;
8
+ }
package/dist/ecard.js ADDED
@@ -0,0 +1,61 @@
1
+ import { ENGrid, EnForm, EngridLogger } from ".";
2
+ export class Ecard {
3
+ constructor() {
4
+ this._form = EnForm.getInstance();
5
+ this.logger = new EngridLogger("Ecard", "red", "#f5f5f5", "🪪");
6
+ if (!this.shouldRun())
7
+ return;
8
+ this._form.onValidate.subscribe(() => this.checkRecipientFields());
9
+ const schedule = ENGrid.getUrlParameter("engrid_ecard.schedule");
10
+ const scheduleField = ENGrid.getField("ecard.schedule");
11
+ const name = ENGrid.getUrlParameter("engrid_ecard.name");
12
+ const nameField = document.querySelector(".en__ecardrecipients__name input");
13
+ const email = ENGrid.getUrlParameter("engrid_ecard.email");
14
+ const emailField = document.querySelector(".en__ecardrecipients__email input");
15
+ if (schedule && scheduleField) {
16
+ // Check if chedule date is in the past
17
+ const scheduleDate = new Date(schedule.toString());
18
+ const today = new Date();
19
+ if (scheduleDate.setHours(0, 0, 0, 0) < today.setHours(0, 0, 0, 0)) {
20
+ // If it is, set the schedule to today
21
+ scheduleField.value = ENGrid.formatDate(today, "YYYY-MM-DD");
22
+ }
23
+ else {
24
+ // Otherwise, set the schedule to the date provided
25
+ scheduleField.value = schedule.toString();
26
+ }
27
+ this.logger.log("Schedule set to " + scheduleField.value);
28
+ }
29
+ if (name && nameField) {
30
+ nameField.value = name.toString();
31
+ this.logger.log("Name set to " + nameField.value);
32
+ }
33
+ if (email && emailField) {
34
+ emailField.value = email.toString();
35
+ this.logger.log("Email set to " + emailField.value);
36
+ }
37
+ // Replace the Future Delivery Label with a H2
38
+ const futureDeliveryLabel = document.querySelector(".en__ecardrecipients__futureDelivery label");
39
+ if (futureDeliveryLabel) {
40
+ const futureDeliveryH2 = document.createElement("h2");
41
+ futureDeliveryH2.innerText = futureDeliveryLabel.innerText;
42
+ futureDeliveryLabel.replaceWith(futureDeliveryH2);
43
+ }
44
+ if (emailField) {
45
+ emailField.setAttribute("type", "email");
46
+ emailField.setAttribute("autocomplete", "off");
47
+ }
48
+ }
49
+ shouldRun() {
50
+ return ENGrid.getPageType() === "ECARD";
51
+ }
52
+ checkRecipientFields() {
53
+ const addRecipientButton = document.querySelector(".en__ecarditems__addrecipient");
54
+ // If we find the "+" button and there's no hidden recipient field, click on the button
55
+ if (addRecipientButton &&
56
+ !document.querySelector(".ecardrecipient__email")) {
57
+ addRecipientButton.click();
58
+ }
59
+ return true;
60
+ }
61
+ }
@@ -0,0 +1,18 @@
1
+ export declare class EmbeddedEcard {
2
+ private logger;
3
+ private readonly options;
4
+ private _form;
5
+ isSubmitting: boolean;
6
+ constructor();
7
+ private onHostPage;
8
+ private onEmbeddedEcardPage;
9
+ private onPostActionPage;
10
+ private embedEcard;
11
+ private createIframe;
12
+ private addEventListeners;
13
+ private setEmbeddedEcardSessionData;
14
+ private getEcardRecipients;
15
+ private setupEmbeddedPage;
16
+ private submitEcard;
17
+ private sendPostMessage;
18
+ }
@@ -0,0 +1,267 @@
1
+ /**
2
+ * This class handles adding a checkbox to a form that, when checked, will display an embedded ecard form.
3
+ * The embedded ecard form is hosted on a separate page and is displayed in an iframe.
4
+ * The form data is saved in session storage and is submitted when the thank you page is loaded.
5
+ * Options can set on the page via window.EngridEmbeddedEcard.
6
+ */
7
+ import { EnForm, ENGrid, EngridLogger } from ".";
8
+ import { EmbeddedEcardOptionsDefaults, } from "./interfaces/embedded-ecard-options";
9
+ export class EmbeddedEcard {
10
+ constructor() {
11
+ this.logger = new EngridLogger("Embedded Ecard", "#D95D39", "#0E1428", "📧");
12
+ this.options = EmbeddedEcardOptionsDefaults;
13
+ this._form = EnForm.getInstance();
14
+ this.isSubmitting = false;
15
+ // For the page hosting the embedded ecard
16
+ if (this.onHostPage()) {
17
+ // Clean up session variables if the page is reloaded, and it isn't a submission failure
18
+ const submissionFailed = !!(ENGrid.checkNested(window.EngagingNetworks, "require", "_defined", "enjs", "checkSubmissionFailed") &&
19
+ window.EngagingNetworks.require._defined.enjs.checkSubmissionFailed());
20
+ if (!submissionFailed) {
21
+ sessionStorage.removeItem("engrid-embedded-ecard");
22
+ sessionStorage.removeItem("engrid-send-embedded-ecard");
23
+ }
24
+ this.options = Object.assign(Object.assign({}, EmbeddedEcardOptionsDefaults), window.EngridEmbeddedEcard);
25
+ const pageUrl = new URL(this.options.pageUrl);
26
+ pageUrl.searchParams.append("data-engrid-embedded-ecard", "true");
27
+ this.options.pageUrl = pageUrl.href;
28
+ this.logger.log("Running Embedded Ecard component", this.options);
29
+ this.embedEcard();
30
+ this.addEventListeners();
31
+ }
32
+ // For the thank you page - after the host page form has been submitted
33
+ // Only runs if eCard was selected on the main page
34
+ if (this.onPostActionPage()) {
35
+ ENGrid.setBodyData("embedded-ecard-sent", "true");
36
+ this.submitEcard();
37
+ }
38
+ // For the page that is embedded
39
+ if (this.onEmbeddedEcardPage()) {
40
+ this.setupEmbeddedPage();
41
+ }
42
+ }
43
+ onHostPage() {
44
+ return (window.hasOwnProperty("EngridEmbeddedEcard") &&
45
+ typeof window.EngridEmbeddedEcard === "object" &&
46
+ window.EngridEmbeddedEcard.hasOwnProperty("pageUrl") &&
47
+ window.EngridEmbeddedEcard.pageUrl !== "");
48
+ }
49
+ onEmbeddedEcardPage() {
50
+ return ENGrid.getPageType() === "ECARD" && ENGrid.hasBodyData("embedded");
51
+ }
52
+ onPostActionPage() {
53
+ return (sessionStorage.getItem("engrid-embedded-ecard") !== null &&
54
+ sessionStorage.getItem("engrid-send-embedded-ecard") !== null &&
55
+ !this.onHostPage() &&
56
+ !this.onEmbeddedEcardPage());
57
+ }
58
+ embedEcard() {
59
+ var _a;
60
+ const container = document.createElement("div");
61
+ container.classList.add("engrid--embedded-ecard");
62
+ const heading = document.createElement("h3");
63
+ heading.textContent = this.options.headerText;
64
+ heading.classList.add("engrid--embedded-ecard-heading");
65
+ container.appendChild(heading);
66
+ const checkbox = document.createElement("div");
67
+ checkbox.classList.add("pseudo-en-field", "en__field", "en__field--checkbox", "en__field--000000", "en__field--embedded-ecard");
68
+ checkbox.innerHTML = `
69
+ <div class="en__field__element en__field__element--checkbox">
70
+ <div class="en__field__item">
71
+ <input class="en__field__input en__field__input--checkbox" id="en__field_embedded-ecard" name="engrid.embedded-ecard" type="checkbox" value="Y">
72
+ <label class="en__field__label en__field__label--item" for="en__field_embedded-ecard">${this.options.checkboxText}</label>
73
+ </div>
74
+ </div>`;
75
+ container.appendChild(checkbox);
76
+ container.appendChild(this.createIframe(this.options.pageUrl));
77
+ (_a = document
78
+ .querySelector(this.options.anchor)) === null || _a === void 0 ? void 0 : _a.insertAdjacentElement(this.options.placement, container);
79
+ }
80
+ createIframe(url) {
81
+ const iframe = document.createElement("iframe");
82
+ iframe.src = url;
83
+ iframe.setAttribute("src", url);
84
+ iframe.setAttribute("width", "100%");
85
+ iframe.setAttribute("scrolling", "no");
86
+ iframe.setAttribute("frameborder", "0");
87
+ iframe.classList.add("engrid-iframe", "engrid-iframe--embedded-ecard");
88
+ iframe.style.display = "none";
89
+ return iframe;
90
+ }
91
+ addEventListeners() {
92
+ const iframe = document.querySelector(".engrid-iframe--embedded-ecard");
93
+ const sendEcardCheckbox = document.getElementById("en__field_embedded-ecard");
94
+ // Initialize based on checkbox's default state
95
+ if (sendEcardCheckbox === null || sendEcardCheckbox === void 0 ? void 0 : sendEcardCheckbox.checked) {
96
+ iframe === null || iframe === void 0 ? void 0 : iframe.setAttribute("style", "display: block");
97
+ sessionStorage.setItem("engrid-send-embedded-ecard", "true");
98
+ }
99
+ else {
100
+ iframe === null || iframe === void 0 ? void 0 : iframe.setAttribute("style", "display: none");
101
+ sessionStorage.removeItem("engrid-send-embedded-ecard");
102
+ }
103
+ sendEcardCheckbox === null || sendEcardCheckbox === void 0 ? void 0 : sendEcardCheckbox.addEventListener("change", (e) => {
104
+ const checkbox = e.target;
105
+ if (checkbox === null || checkbox === void 0 ? void 0 : checkbox.checked) {
106
+ iframe === null || iframe === void 0 ? void 0 : iframe.setAttribute("style", "display: block");
107
+ sessionStorage.setItem("engrid-send-embedded-ecard", "true");
108
+ }
109
+ else {
110
+ iframe === null || iframe === void 0 ? void 0 : iframe.setAttribute("style", "display: none");
111
+ sessionStorage.removeItem("engrid-send-embedded-ecard");
112
+ }
113
+ });
114
+ }
115
+ setEmbeddedEcardSessionData() {
116
+ let ecardVariant = document.querySelector("[name='friend.ecard']");
117
+ let ecardSendDate = document.querySelector("[name='ecard.schedule']");
118
+ let ecardMessage = document.querySelector("[name='transaction.comments']");
119
+ //add "chain" param to window.location.href if it doesnt have it
120
+ const pageUrl = new URL(window.location.href);
121
+ if (!pageUrl.searchParams.has("chain")) {
122
+ pageUrl.searchParams.append("chain", "");
123
+ }
124
+ const embeddedEcardData = {
125
+ pageUrl: pageUrl.href,
126
+ formData: {
127
+ ecardVariant: (ecardVariant === null || ecardVariant === void 0 ? void 0 : ecardVariant.value) || "",
128
+ ecardSendDate: (ecardSendDate === null || ecardSendDate === void 0 ? void 0 : ecardSendDate.value) || "",
129
+ ecardMessage: (ecardMessage === null || ecardMessage === void 0 ? void 0 : ecardMessage.value) || "",
130
+ recipients: this.getEcardRecipients(),
131
+ },
132
+ };
133
+ sessionStorage.setItem("engrid-embedded-ecard", JSON.stringify(embeddedEcardData));
134
+ }
135
+ getEcardRecipients() {
136
+ const recipients = [];
137
+ const addRecipientButton = document.querySelector(".en__ecarditems__addrecipient");
138
+ //Single recipient form where the "add recipient" button is hidden, and we use the recipient name and email fields
139
+ const isSingleRecipientForm = !addRecipientButton || addRecipientButton.offsetHeight === 0;
140
+ if (isSingleRecipientForm) {
141
+ // When it is a single recipient form, we only need to get the recipient name and email from the input fields
142
+ let recipientName = document.querySelector(".en__ecardrecipients__name > input");
143
+ let recipientEmail = document.querySelector(".en__ecardrecipients__email > input");
144
+ if (recipientName && recipientEmail) {
145
+ recipients.push({
146
+ name: recipientName.value,
147
+ email: recipientEmail.value,
148
+ });
149
+ }
150
+ return recipients;
151
+ }
152
+ // For multiple recipient forms, we need to get the recipient name and email from each recipient in the recipient list
153
+ const recipientList = document.querySelector(".en__ecardrecipients__list");
154
+ recipientList === null || recipientList === void 0 ? void 0 : recipientList.querySelectorAll(".en__ecardrecipients__recipient").forEach((el) => {
155
+ const recipientName = el.querySelector(".ecardrecipient__name");
156
+ const recipientEmail = el.querySelector(".ecardrecipient__email");
157
+ if (recipientName && recipientEmail) {
158
+ recipients.push({
159
+ name: recipientName.value,
160
+ email: recipientEmail.value,
161
+ });
162
+ }
163
+ });
164
+ return recipients;
165
+ }
166
+ setupEmbeddedPage() {
167
+ let ecardVariant = document.querySelector("[name='friend.ecard']");
168
+ let ecardSendDate = document.querySelector("[name='ecard.schedule']");
169
+ let ecardMessage = document.querySelector("[name='transaction.comments']");
170
+ let recipientName = document.querySelector(".en__ecardrecipients__name > input");
171
+ let recipientEmail = document.querySelector(".en__ecardrecipients__email > input");
172
+ [
173
+ ecardVariant,
174
+ ecardSendDate,
175
+ ecardMessage,
176
+ recipientName,
177
+ recipientEmail,
178
+ ].forEach((el) => {
179
+ el.addEventListener("input", () => {
180
+ if (this.isSubmitting)
181
+ return;
182
+ this.setEmbeddedEcardSessionData();
183
+ });
184
+ });
185
+ // MutationObserver to detect changes in the recipient list and update the session data
186
+ const observer = new MutationObserver((mutationsList) => {
187
+ for (let mutation of mutationsList) {
188
+ if (mutation.type === "childList") {
189
+ if (this.isSubmitting)
190
+ return;
191
+ this.setEmbeddedEcardSessionData();
192
+ }
193
+ }
194
+ });
195
+ const recipientList = document.querySelector(".en__ecardrecipients__list");
196
+ if (recipientList) {
197
+ observer.observe(recipientList, { childList: true });
198
+ }
199
+ document.querySelectorAll(".en__ecarditems__thumb").forEach((el) => {
200
+ // Making sure the session value is changed when this is clicked
201
+ el.addEventListener("click", () => {
202
+ ecardVariant.dispatchEvent(new Event("input"));
203
+ });
204
+ });
205
+ window.addEventListener("message", (e) => {
206
+ if (e.origin !== location.origin || !e.data.action)
207
+ return;
208
+ this.logger.log("Received post message", e.data);
209
+ switch (e.data.action) {
210
+ case "submit_form":
211
+ this.isSubmitting = true;
212
+ let embeddedEcardData = JSON.parse(sessionStorage.getItem("engrid-embedded-ecard") || "{}");
213
+ if (ecardVariant) {
214
+ ecardVariant.value = embeddedEcardData.formData["ecardVariant"];
215
+ }
216
+ if (ecardSendDate) {
217
+ ecardSendDate.value = embeddedEcardData.formData["ecardSendDate"];
218
+ }
219
+ if (ecardMessage) {
220
+ ecardMessage.value = embeddedEcardData.formData["ecardMessage"];
221
+ }
222
+ const addRecipientButton = document.querySelector(".en__ecarditems__addrecipient");
223
+ embeddedEcardData.formData.recipients.forEach((recipient) => {
224
+ recipientName.value = recipient.name;
225
+ recipientEmail.value = recipient.email;
226
+ addRecipientButton === null || addRecipientButton === void 0 ? void 0 : addRecipientButton.click();
227
+ });
228
+ const form = EnForm.getInstance();
229
+ form.submitForm();
230
+ sessionStorage.removeItem("engrid-embedded-ecard");
231
+ sessionStorage.removeItem("engrid-send-embedded-ecard");
232
+ break;
233
+ case "set_recipient":
234
+ recipientName.value = e.data.name;
235
+ recipientEmail.value = e.data.email;
236
+ recipientName.dispatchEvent(new Event("input"));
237
+ recipientEmail.dispatchEvent(new Event("input"));
238
+ break;
239
+ }
240
+ });
241
+ this.sendPostMessage("parent", "ecard_form_ready");
242
+ }
243
+ submitEcard() {
244
+ var _a;
245
+ const embeddedEcardData = JSON.parse(sessionStorage.getItem("engrid-embedded-ecard") || "{}");
246
+ this.logger.log("Submitting ecard", embeddedEcardData);
247
+ const iframe = this.createIframe(embeddedEcardData.pageUrl);
248
+ (_a = document.querySelector(".body-main")) === null || _a === void 0 ? void 0 : _a.appendChild(iframe);
249
+ window.addEventListener("message", (e) => {
250
+ if (e.origin !== location.origin || !e.data.action)
251
+ return;
252
+ if (e.data.action === "ecard_form_ready") {
253
+ this.sendPostMessage(iframe, "submit_form");
254
+ }
255
+ });
256
+ }
257
+ sendPostMessage(target, action, data = {}) {
258
+ var _a;
259
+ const message = Object.assign({ action }, data);
260
+ if (target === "parent") {
261
+ window.parent.postMessage(message, location.origin);
262
+ }
263
+ else {
264
+ (_a = target.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage(message, location.origin);
265
+ }
266
+ }
267
+ }
@@ -0,0 +1,10 @@
1
+ export declare class ENValidators {
2
+ private _form;
3
+ private _enElements;
4
+ private logger;
5
+ constructor();
6
+ loadValidators(): boolean;
7
+ shouldRun(): boolean | null | undefined;
8
+ enOnValidate(): void;
9
+ liveValidate(container: HTMLDivElement, field: Element, regex: string, message: string): boolean;
10
+ }