@4site/engrid-scripts 0.28.5 → 0.28.7
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 +5 -1
- package/dist/iframe.d.ts +12 -0
- package/dist/iframe.js +37 -9
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interfaces/options.d.ts +11 -0
- package/dist/interfaces/options.js +1 -0
- package/dist/tidycontact-email.d.ts +7 -0
- package/dist/tidycontact-email.js +83 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DonationAmount, DonationFrequency, EnForm, ProcessingFees, Country, } from "./events";
|
|
2
|
-
import { AmountLabel, Loader, ProgressBar, UpsellLightbox, ENGrid, OptionsDefaults, setRecurrFreq, PageBackground, MediaAttribution, ApplePay, A11y, CapitalizeFields, Ecard, ClickToExpand, Advocacy, DataAttributes, LiveVariables, iFrame, InputPlaceholders, InputHasValueAndFocus, ShowHideRadioCheckboxes, AutoCountrySelect, SkipToMainContentLink, SrcDefer, NeverBounce, AutoYear, Autocomplete, RememberMe, TranslateFields, ShowIfAmount, EngridLogger, OtherAmount, MinMaxAmount, Ticker, DataReplace, DataHide, AddNameToMessage, ExpandRegionName, AppVersion, UrlToForm, RequiredIfVisible, TidyContact, DataLayer, LiveCurrency, Autosubmit, EventTickets, SwapAmounts, DebugPanel, DebugHiddenFields, FreshAddress, BrandingHtml, CountryDisable, PremiumGift, DigitalWallets, MobileCTA, LiveFrequency, UniversalOptIn, StripeFinancialConnections, GiveBySelect, UrlParamsToBodyAttrs, ExitIntentLightbox, SupporterHub, FastFormFill, SetAttr, ShowIfPresent, ENValidators, CustomCurrency, VGS, PostalCodeValidator, CountryRedirect, WelcomeBack, EcardToTarget, UsOnlyForm, ThankYouPageConditionalContent, EmbeddedEcard, CheckboxLabel, UpsellCheckbox, PostDonationEmbed, FrequencyUpsell, CustomPremium, StickyNSG, StickyPrepopulation, PreferredPaymentMethod, } from ".";
|
|
2
|
+
import { AmountLabel, Loader, ProgressBar, UpsellLightbox, ENGrid, OptionsDefaults, setRecurrFreq, PageBackground, MediaAttribution, ApplePay, A11y, CapitalizeFields, Ecard, ClickToExpand, Advocacy, DataAttributes, LiveVariables, iFrame, InputPlaceholders, InputHasValueAndFocus, ShowHideRadioCheckboxes, AutoCountrySelect, SkipToMainContentLink, SrcDefer, NeverBounce, AutoYear, Autocomplete, RememberMe, TranslateFields, ShowIfAmount, EngridLogger, OtherAmount, MinMaxAmount, Ticker, DataReplace, DataHide, AddNameToMessage, ExpandRegionName, AppVersion, UrlToForm, RequiredIfVisible, TidyContact, DataLayer, LiveCurrency, Autosubmit, EventTickets, SwapAmounts, DebugPanel, DebugHiddenFields, FreshAddress, BrandingHtml, CountryDisable, PremiumGift, DigitalWallets, MobileCTA, LiveFrequency, UniversalOptIn, StripeFinancialConnections, GiveBySelect, UrlParamsToBodyAttrs, ExitIntentLightbox, SupporterHub, FastFormFill, SetAttr, ShowIfPresent, ENValidators, CustomCurrency, VGS, PostalCodeValidator, CountryRedirect, WelcomeBack, EcardToTarget, UsOnlyForm, ThankYouPageConditionalContent, EmbeddedEcard, CheckboxLabel, UpsellCheckbox, PostDonationEmbed, FrequencyUpsell, CustomPremium, StickyNSG, StickyPrepopulation, PreferredPaymentMethod, TidyContactEmail, } from ".";
|
|
3
3
|
export class App extends ENGrid {
|
|
4
4
|
constructor(options) {
|
|
5
5
|
super();
|
|
@@ -225,6 +225,10 @@ export class App extends ENGrid {
|
|
|
225
225
|
// FreshAddress
|
|
226
226
|
if (this.options.FreshAddress)
|
|
227
227
|
new FreshAddress();
|
|
228
|
+
// TidyContact Email. Must stay below the window.enOnValidate assignment,
|
|
229
|
+
// so the TC Email bundle wraps ENgrid's hook instead of being overwritten by it.
|
|
230
|
+
if (this.options.TidyContactEmail)
|
|
231
|
+
new TidyContactEmail();
|
|
228
232
|
new ShowIfAmount();
|
|
229
233
|
new OtherAmount();
|
|
230
234
|
new MinMaxAmount();
|
package/dist/iframe.d.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { EnForm } from "./events";
|
|
2
2
|
export declare class iFrame {
|
|
3
3
|
_form: EnForm;
|
|
4
|
+
private resizeObserver;
|
|
4
5
|
private logger;
|
|
5
6
|
constructor();
|
|
6
7
|
private onLoaded;
|
|
8
|
+
/**
|
|
9
|
+
* Observes document.body for size changes (DOM mutations, font/image
|
|
10
|
+
* loads, CSS transitions) and re-sends the iframe height to the parent.
|
|
11
|
+
*
|
|
12
|
+
* Uses a leading + trailing throttle via debounceWithImmediate: the
|
|
13
|
+
* first change is sent immediately, and the settled height is always
|
|
14
|
+
* re-sent once changes stop for 120ms. Animated transitions therefore
|
|
15
|
+
* don't flood the parent page with one message per frame, but the
|
|
16
|
+
* parent always ends up matching the final resolved height.
|
|
17
|
+
*/
|
|
18
|
+
private observeHeightChanges;
|
|
7
19
|
/**
|
|
8
20
|
* Posts a `engrid-iframe-queue:thank-you` message to the parent window
|
|
9
21
|
* when the embedded EN page reaches its Thank You page (the last page
|
package/dist/iframe.js
CHANGED
|
@@ -3,6 +3,7 @@ import { EnForm } from "./events";
|
|
|
3
3
|
export class iFrame {
|
|
4
4
|
constructor() {
|
|
5
5
|
this._form = EnForm.getInstance();
|
|
6
|
+
this.resizeObserver = null;
|
|
6
7
|
this.logger = new EngridLogger("iFrame", "brown", "gray", "📡");
|
|
7
8
|
if (this.inIframe()) {
|
|
8
9
|
// Add the data-engrid-embedded attribute when inside an iFrame if it wasn't already added by a script in the Page Template
|
|
@@ -95,6 +96,7 @@ export class iFrame {
|
|
|
95
96
|
if (iframe) {
|
|
96
97
|
if (event.data.hasOwnProperty("frameHeight")) {
|
|
97
98
|
iframe.style.height = event.data.frameHeight + "px";
|
|
99
|
+
this.logger.log(`iFrame Event - Resized iframe element to ${event.data.frameHeight}px`);
|
|
98
100
|
if (event.data.frameHeight > 0) {
|
|
99
101
|
iframe.classList.add("loaded");
|
|
100
102
|
}
|
|
@@ -134,6 +136,8 @@ export class iFrame {
|
|
|
134
136
|
// Scroll to top of iFrame
|
|
135
137
|
this.logger.log("iFrame Event - window.onload");
|
|
136
138
|
this.sendIframeHeight();
|
|
139
|
+
// Continuously re-send the height whenever the body size changes
|
|
140
|
+
this.observeHeightChanges();
|
|
137
141
|
window.parent.postMessage({
|
|
138
142
|
scroll: this.shouldScroll(),
|
|
139
143
|
}, "*");
|
|
@@ -142,16 +146,40 @@ export class iFrame {
|
|
|
142
146
|
// matches it by Page ID to advance to the next queued iframe. Fires
|
|
143
147
|
// exactly once per Thank-You-page load. See iframe-queue.ts.
|
|
144
148
|
this.sendIframeQueueThankYouPing();
|
|
145
|
-
// On click fire the resize event
|
|
146
|
-
document.addEventListener("click", (e) => {
|
|
147
|
-
this.logger.log("iFrame Event - click");
|
|
148
|
-
setTimeout(() => {
|
|
149
|
-
this.sendIframeHeight();
|
|
150
|
-
}, 100);
|
|
151
|
-
});
|
|
152
149
|
// Watch for errors and send the height
|
|
153
150
|
ENGrid.watchForError(this.sendIframeHeight.bind(this));
|
|
154
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Observes document.body for size changes (DOM mutations, font/image
|
|
154
|
+
* loads, CSS transitions) and re-sends the iframe height to the parent.
|
|
155
|
+
*
|
|
156
|
+
* Uses a leading + trailing throttle via debounceWithImmediate: the
|
|
157
|
+
* first change is sent immediately, and the settled height is always
|
|
158
|
+
* re-sent once changes stop for 120ms. Animated transitions therefore
|
|
159
|
+
* don't flood the parent page with one message per frame, but the
|
|
160
|
+
* parent always ends up matching the final resolved height.
|
|
161
|
+
*/
|
|
162
|
+
observeHeightChanges() {
|
|
163
|
+
if (typeof ResizeObserver === "undefined") {
|
|
164
|
+
this.logger.log("ResizeObserver not supported in this browser");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
let lastSent = -1;
|
|
168
|
+
const throttledSend = this.debounceWithImmediate((_entries, _observer, immediate) => {
|
|
169
|
+
const height = document.body.offsetHeight;
|
|
170
|
+
// Skip redundant sends when the settled height is unchanged
|
|
171
|
+
if (height === lastSent) {
|
|
172
|
+
this.logger.log(`iFrame Event - ResizeObserver settled at unchanged height ${height}px, skipping send`);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
lastSent = height;
|
|
176
|
+
this.logger.log(`iFrame Event - ResizeObserver ${immediate ? "leading" : "trailing"} resize: sending height ${height}px`);
|
|
177
|
+
this.sendIframeHeight();
|
|
178
|
+
}, 120);
|
|
179
|
+
this.resizeObserver = new ResizeObserver(throttledSend);
|
|
180
|
+
this.resizeObserver.observe(document.body);
|
|
181
|
+
this.logger.log("iFrame Event - Observing body resize");
|
|
182
|
+
}
|
|
155
183
|
/**
|
|
156
184
|
* Posts a `engrid-iframe-queue:thank-you` message to the parent window
|
|
157
185
|
* when the embedded EN page reaches its Thank You page (the last page
|
|
@@ -299,11 +327,11 @@ export class iFrame {
|
|
|
299
327
|
return (...args) => {
|
|
300
328
|
clearTimeout(timer);
|
|
301
329
|
if (firstEvent) {
|
|
302
|
-
func.apply(this, args);
|
|
330
|
+
func.apply(this, [...args, true]);
|
|
303
331
|
firstEvent = false;
|
|
304
332
|
}
|
|
305
333
|
timer = setTimeout(() => {
|
|
306
|
-
func.apply(this, args);
|
|
334
|
+
func.apply(this, [...args, false]);
|
|
307
335
|
firstEvent = true;
|
|
308
336
|
}, timeout);
|
|
309
337
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ export * from "./expand-region-name";
|
|
|
52
52
|
export * from "./url-to-form";
|
|
53
53
|
export * from "./required-if-visible";
|
|
54
54
|
export * from "./tidycontact";
|
|
55
|
+
export * from "./tidycontact-email";
|
|
55
56
|
export * from "./live-currency";
|
|
56
57
|
export * from "./custom-currency";
|
|
57
58
|
export * from "./autosubmit";
|
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ export * from "./expand-region-name";
|
|
|
52
52
|
export * from "./url-to-form";
|
|
53
53
|
export * from "./required-if-visible";
|
|
54
54
|
export * from "./tidycontact";
|
|
55
|
+
export * from "./tidycontact-email";
|
|
55
56
|
export * from "./live-currency";
|
|
56
57
|
export * from "./custom-currency";
|
|
57
58
|
export * from "./autosubmit";
|
|
@@ -89,6 +89,17 @@ export interface Options {
|
|
|
89
89
|
phone_date_field?: string;
|
|
90
90
|
phone_status_field?: string;
|
|
91
91
|
};
|
|
92
|
+
TidyContactEmail?: false | {
|
|
93
|
+
clientKey: string;
|
|
94
|
+
relayUrl?: string;
|
|
95
|
+
version?: string;
|
|
96
|
+
scriptUrl?: string;
|
|
97
|
+
timeoutMs?: number;
|
|
98
|
+
hardBlock?: boolean;
|
|
99
|
+
prefillSkip?: boolean;
|
|
100
|
+
enRecognition?: boolean;
|
|
101
|
+
pageTypes?: ("DONATION" | "ECARD" | "SURVEY" | "EMAILTOTARGET" | "ADVOCACY" | "SUBSCRIBEFORM" | "EVENT" | "SUPPORTERHUB" | "UNSUBSCRIBE" | "TWEETPAGE" | "UNKNOWN")[];
|
|
102
|
+
};
|
|
92
103
|
MobileCTA?: false | {
|
|
93
104
|
pageType: string;
|
|
94
105
|
label: string;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ENGrid, EngridLogger } from ".";
|
|
2
|
+
// Same selector the TC Email bundle uses to find its own tag (script-config.ts)
|
|
3
|
+
const TC_EMAIL_SCRIPT = "script[src*='raisemore-email'], script[data-raisemore-email]";
|
|
4
|
+
const DEFAULT_RELAY_URL = "https://email-validator.4sitestudios.com";
|
|
5
|
+
const DEFAULT_VERSION = "v1";
|
|
6
|
+
export class TidyContactEmail {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.logger = new EngridLogger("TidyContactEmail", "#FFFFFF", "#4d9068", "📧");
|
|
9
|
+
this.options = null;
|
|
10
|
+
const options = ENGrid.getOption("TidyContactEmail");
|
|
11
|
+
if (!options)
|
|
12
|
+
return;
|
|
13
|
+
this.options = options;
|
|
14
|
+
if (!this.shouldRun())
|
|
15
|
+
return;
|
|
16
|
+
this.loadScript();
|
|
17
|
+
}
|
|
18
|
+
shouldRun() {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.clientKey)) {
|
|
21
|
+
this.logger.danger("clientKey not set. TidyContact Email will not load.");
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
25
|
+
if (searchParams.has("bypassemailvalidation")) {
|
|
26
|
+
this.logger.log("Bypass Email Validation Enabled - not loading TidyContact Email");
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const pageTypes = (_b = this.options.pageTypes) !== null && _b !== void 0 ? _b : [];
|
|
30
|
+
if (pageTypes.length > 0 &&
|
|
31
|
+
pageTypes.indexOf(ENGrid.getPageType()) === -1) {
|
|
32
|
+
this.logger.log("TidyContact Email is disabled on this page type");
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (!ENGrid.getField("supporter.emailAddress")) {
|
|
36
|
+
this.logger.log("E-mail Field Not Found");
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (ENGrid.getOption("NeverBounceAPI") ||
|
|
40
|
+
ENGrid.getOption("FreshAddress")) {
|
|
41
|
+
this.logger.danger("NeverBounce or FreshAddress is also enabled. Two email validators on one field is not supported, so TidyContact Email will not load.");
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (document.querySelector(TC_EMAIL_SCRIPT)) {
|
|
45
|
+
this.logger.log("TidyContact Email script already on the page (manual install). Not loading it again.");
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
loadScript() {
|
|
51
|
+
const options = this.options;
|
|
52
|
+
const relayUrl = (options.relayUrl || DEFAULT_RELAY_URL).replace(/\/+$/, "");
|
|
53
|
+
const script = document.createElement("script");
|
|
54
|
+
script.src =
|
|
55
|
+
options.scriptUrl ||
|
|
56
|
+
`${relayUrl}/embed/engrid/${options.version || DEFAULT_VERSION}/raisemore-email.js`;
|
|
57
|
+
script.setAttribute("data-raisemore-email", "");
|
|
58
|
+
script.setAttribute("data-relay-url", relayUrl);
|
|
59
|
+
script.setAttribute("data-client-key", options.clientKey);
|
|
60
|
+
// Only what the client set; everything else keeps TC Email's own defaults
|
|
61
|
+
const optional = [
|
|
62
|
+
["timeout-ms", options.timeoutMs],
|
|
63
|
+
["hard-block", options.hardBlock],
|
|
64
|
+
["prefill-skip", options.prefillSkip],
|
|
65
|
+
["en-recognition", options.enRecognition],
|
|
66
|
+
];
|
|
67
|
+
optional.forEach(([name, value]) => {
|
|
68
|
+
if (value !== undefined && value !== null) {
|
|
69
|
+
script.setAttribute(`data-${name}`, String(value));
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
script.onload = () => {
|
|
73
|
+
ENGrid.setBodyData("tidycontact-email", "loaded");
|
|
74
|
+
this.logger.success(`Loaded ${script.src}`);
|
|
75
|
+
};
|
|
76
|
+
script.onerror = () => {
|
|
77
|
+
ENGrid.setBodyData("tidycontact-email", "error");
|
|
78
|
+
this.logger.danger(`Could not load ${script.src}. The form keeps working without email validation.`);
|
|
79
|
+
};
|
|
80
|
+
ENGrid.setBodyData("tidycontact-email", "loading");
|
|
81
|
+
document.body.appendChild(script);
|
|
82
|
+
}
|
|
83
|
+
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AppVersion = "0.28.
|
|
1
|
+
export declare const AppVersion = "0.28.7";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AppVersion = "0.28.
|
|
1
|
+
export const AppVersion = "0.28.7";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4site/engrid-scripts",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.7",
|
|
4
4
|
"description": "Scripts for the ENGRID Project",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"strongly-typed-events": "^2.0.9"
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/4site-interactive-studios/engrid#readme",
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "91cc1bb42cdf7660319f912cb8937d37968d2324",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"nodemon": "^2.0.20",
|
|
31
31
|
"typescript": "^4.9.5"
|