");vwo_$('head').append(_vwo_sel);return vwo_$('head')[0] && vwo_$('head')[0].lastChild;})("HEAD")}}, R_722072_157_1_2_0:{ fn:function(log,nonce=''){return (function(x) { if(!vwo_$.fn.vwoRevertHtml){ return; }; var ctx=vwo_$(x),el; /*vwo_debug log("Revert","content",""); vwo_debug*/; el=vwo_$('[vwo-element-id="1744062807510"]'); el.revertContentOp().remove();})("HEAD")}}, C_722072_157_1_2_1:{ fn:function(log,nonce=''){return (function(x) {var el,ctx=vwo_$(x); /*vwo_debug log("addElement","body"); vwo_debug*/!(el=vwo_$("body")).find('[vwo-op-1744062793557=""]').length&&el.vwoElement({html:'
\nYou can be the difference in a child making a decision to follow Jesus at camp this summer. Will you help a kid get to Eagle Lake Camps of The Navigators this summer? Give here ยป\n
\n\n You can be the difference in a child making a decision to follow Jesus at camp this summer. Will you help a kid get to Eagle Lake Camps of The Navigators this summer? Give here ยป\n
\nYour monthly partnership will:
Most importantly, you will play an active role in this ongoing work of bringing campers to meet Jesus and grow in their walks with Him. Would you consider becoming a monthly partner today?โ
`, ctaButtons: { "Yes": ``, "No": ``, }, closeButton: false, theme: "NAV", }, memoryMode: 'session', // "session" or "forever"; indicates how long the last interacted state should be remembered minAmount: 5.00, // gift under this amount will be processed (if above the form minimum) and not shown the donation interrupter maxAmount: 100.00, // gifts equal to and above this amount will be processed and not shown the donation interrupter askConditions: function (originalAmount, originalFrequency, state) { const conditions = [ originalFrequency === "One-Time", // "One-Time" or "Recurring" originalAmount > this.minAmount, originalAmount < this.maxAmount, state && state.status !== "shown" && state.status !== "dismissed" && state.status !== "converted", // do not show if the user has already seen the donation interrupter, dismissed the donation interrupter, or converted from the donation interrupter ]; return conditions.every((condition) => typeof condition === 'function' ? !!condition.call(null) : !!condition); // return true if every condition in the array evaluates to true }, askAmount: function (originalAmount) { let askAmount; if (originalAmount >= 400 && originalAmount < 500) { // $400.00 - $499.99 askAmount = 50; } else if (originalAmount >= 300 && originalAmount < 400) { // $300.00 - $399.99 askAmount = 40; } else if (originalAmount >= 200 && originalAmount < 300) { // $200.00 - $299.99 askAmount = 30; } else if (originalAmount >= 100 && originalAmount < 200) { // $100.00 - $199.99 askAmount = 15; } else { // $ 0.01 - $ 99.99 askAmount = 10; } return parseFloat(askAmount); }, }; // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // // // // Run code with configuration from above (function(){ console.log("init"); window.NA.DonationForm.init(config).then((donationFormApi) => { console.log("initialized:", donationFormApi); if (configDonationInterrupter && configDonationInterrupter.enabled === true) { donationFormApi.DonationInterrupter(configDonationInterrupter); console.log("initialized:", donationFormApi.DonationInterrupter); donationFormApi.interceptSubmit(function (capturedEvent) { try { const donationInterrupterApi = this.DonationInterrupter; if (donationFormApi && donationInterrupterApi) { if (donationInterrupterApi.evaluateConditions()) { console.log(donationFormApi); donationInterrupterApi.show(); return false; // do not submit } else { console.warn("Condtions check failed: Donation Interrupter will not be shown."); return true; // submit } } else { throw new ReferenceError("DonationFormApi or DonationInterrupterApi is not defined."); } } catch (error) { console.error("An error occured when handling submit:", error); window.NA?.DonationForm && window.NA.DonationForm.submit(); // retry submit } finally { return false; } }); } }).catch((error) => { console.error("Error creating donation form API:", error); }); })(); }catch(e) {VWO._.vAEH(e);} return vwo_$('head')[0] && vwo_$('head')[0].lastChild;})("head")}}, R_722072_158_1_2_0:{ fn:function(log,nonce=''){return (function(x) { try{ var ctx=vwo_$(x),el; /*vwo_debug log("Revert","content",""); vwo_debug*/; el=vwo_$('[vwo-element-id="1743104387377"]'); el.revertContentOp().remove(); } catch(e) {VWO._.vAEH(e);} try{ var el,ctx=vwo_$(x); /*vwo_debug log("Revert","addElement","body"); vwo_debug*/(el=vwo_$('[vwo-element-id="1743104387378"]')).remove(); } catch(e) {VWO._.vAEH(e);} return vwo_$('head')[0] && vwo_$('head')[0].lastChild;})("head")}}, C_722072_158_1_2_0:{ fn:function(log,nonce=''){return (function(x) { try{ var _vwo_sel = vwo_$("`); !vwo_$("head").find('#1743104387377').length && vwo_$('head').append(_vwo_sel);}catch(e) {VWO._.vAEH(e);} try{}catch(e) {VWO._.vAEH(e);} try{/* ===== Complicated Code Below ===== */ window.HTMLElement.prototype.getSlot = window.HTMLElement.prototype.getSlot || function () { return this.querySelector('slot') || this.shadowRoot.querySelector('slot'); }; window.HTMLElement.prototype.getSlotNodes = window.HTMLElement.prototype.getSlotNodes || function (n) { return (parseInt(n) !== 'NaN' && n >= 0) ? Array.from(this.getSlot().assignedNodes({ flatten: true }))[n] : Array.from(this.getSlot().assignedNodes({ flatten: true })); }; window.HTMLElement.prototype.shadowChildren = window.HTMLElement.prototype.shadowChildren || function (n) { return (parseInt(n) !== 'NaN' && n >= 0) ? Array.from(this.shadowRoot.children)[n] : Array.from(this.shadowRoot.children); }; function shadowQuerySelectorAll (selector) { let matches = []; const isSlot = (element) => element.tagName.toLowerCase() === 'slot'; function traverse(element) { // Helper function to recursively traverse elements if (element instanceof HTMLElement && element.matches(selector) /*&& element !== this*/) // Check if element matches the selector matches.push(element); if (customElements.get(element.tagName.toLowerCase())) { // Traverse through shadow DOM children if element is a custom element with shadow DOM const children = element.shadowRoot ? Array.from(element.shadowRoot.children) : []; children.forEach((child) => traverse(child)); } else { Array.from(element.children).forEach((child) => traverse(child)); // traverse through regular element children } if (isSlot(element)) { // handle traversing slot nodes const slotNodes = element.assignedNodes({ flatten: true }); slotNodes.forEach((slotNode) => { if (slotNode.nodeType === Node.ELEMENT_NODE) traverse(slotNode); }); } } this instanceof Document ? traverse(this.documentElement) : traverse(this); // Start traversal from the root element as long as it's not the Document return matches.length > 0 ? matches : undefined; } function shadowQuerySelector (selector) { let matches = this.shadowQuerySelectorAll(selector) || []; return matches.length > 0 ? matches[0] : undefined; } Object.defineProperties(HTMLElement.prototype, { shadowQuerySelectorAll: { value: shadowQuerySelectorAll, writable: false, configurable: false, enumerable: true, }, shadowQuerySelector: { value: shadowQuerySelector, writable: false, configurable: false, enumerable: true, } }); Object.defineProperties(Document.prototype, { shadowQuerySelectorAll: { value: shadowQuerySelectorAll, writable: false, configurable: false, enumerable: true, }, shadowQuerySelector: { value: shadowQuerySelector, writable: false, configurable: false, enumerable: true, } }); Object.defineProperties(Document, { shadowQuerySelectorAll: { value: shadowQuerySelectorAll, writable: false, configurable: false, enumerable: true, }, shadowQuerySelector: { value: shadowQuerySelector, writable: false, configurable: false, enumerable: true, } }); Object.defineProperty(JSON, 'isValid', { value: function (jsonString) { try { JSON.parse(jsonString); return true; } catch (error) { return false; } }, writable: false, configurable: true, enumerable: true, }); async function asyncWaitForCustomElements (customElementsArray, onCustomElementsDefined = () => {}) { customElementsArray.length === 0 ? onCustomElementsDefined() : customElements.whenDefined(customElementsArray.shift()).then(() => asyncWaitForCustomElements(customElementsArray, onCustomElementsDefined)); } function vwoCustomEvent (labelValue) { window.VWO = window.VWO || []; VWO.event = VWO.event || function () {VWO.push(["event"].concat([].slice.call(arguments)))}; VWO.event("customEvent", { "label": labelValue.toString() }); } const getToken = (key, api = localStorage) => (JSON.isValid(api.getItem(key)) ? JSON.parse(api.getItem(key)) : api.getItem(key)) || null; const setToken = (key, value, api = localStorage) => api.setItem(key, JSON.stringify(value)); const getCurrentDate = (d = new Date()) => d.toISOString().split('T')[0]; const reOneTime = new RegExp(/(one-?time|once|single)/gi), reRecurring = new RegExp(/(recurring|monthly)/gi); window.NA = window.NA || {}; window.NA.DonationPage = window.NA.DonationPage || {}; window.NA.DonationForm = window.NA.DonationForm || {}; async function init (userConfig) { return new Promise((resolve, reject) => { const defaultConfig = { donationForm: { defaultRecurring: false, // true for "Recurring" default, false for "One-Time" default giftArrayAmounts: [], // an array of numbers (like [ 5, 10, 15, 25 ]) or `null` or `[]` for default gift array amounts defaultAmount: null, // a number or `null` for no default anonymousDefault: null, // true/false or null for no default tributeDefault: null, // true/false or null for no default hideCheckboxesAll: false, // true/false to hide the checkboxes button hideCheckboxFreqeuncy: false, hideCheckboxAnonymous: false, hideCheckboxTribute: false, hideCartButton: false, // true/false to hide the "Add to Basket" button } }; userConfig = { ...defaultConfig, ...userConfig }; Object.defineProperty(window.NA, '_config', { value: userConfig, writable: false, configurable: true, enumerable: false, }); const config = { ...window.NA._config }; // // // // // // // function main () { const c_donate_community_staff_information = document.shadowQuerySelector('c-donate-community-staff-information'); const c_donate_community_donate_buttons = document.shadowQuerySelector('c-donate-community-donate-buttons'); // const donationPage = c_donate_community_staff_information.parentElement; const donationPageImage = donationPage.shadowQuerySelectorAll('c-donate-community-staff-information > div > .slds-col')[0]; const donationPageContent = donationPage.shadowQuerySelectorAll('c-donate-community-staff-information > div > .slds-col')[1]; const donationPageTitle = donationPageContent.children[0]; const donationPageSubtitle = donationPageContent.children[1]; const donationFormWidget = donationPageContent.children[2] || c_donate_community_donate_buttons.parentElement; const donationPageAboutTitle = donationPageContent.children[3]; const donationPageCopySection = donationPageContent.children[4] || donationPageContent.shadowQuerySelector('lightning-formatted-text, lightning-formatted-rich-text'); const donationFormGiftArrayButtons = donationFormWidget.shadowQuerySelectorAll('button[value]'); const donationFormGiftArrayOtherAmountInput = donationFormWidget.shadowQuerySelector('lightning-input lightning-primitive-input-simple input[type]'); const donationFormCheckboxes = [...donationPageContent.shadowQuerySelector('c-donate-community-donate-buttons > div').children].find((child) => child.matches('div:has(div lightning-primitive-input-checkbox)')); const donationFormButtons = [...donationFormWidget.shadowQuerySelectorAll('button')].filter((button) => !donationFormGiftArrayButtons.includes(button)); const donationFormButton = { "Donate Now": donationFormButtons[0], "Add to Basket": donationFormButtons[1], }; // // // // Add legacy classes donationPageImage.classList.add("page-image"); donationPageContent.classList.add("donation-form-content"); donationPageTitle.classList.add("page-title"); donationPageSubtitle.classList.add("page-action-text"); donationFormWidget.classList.add("donation-form"); donationPageAboutTitle.classList.add("bottom-title"); donationPageCopySection.classList.add("page-text"); donationFormCheckboxes.classList.add("donation-form-checkboxes"); donationFormButton["Donate Now"].classList.add("donate-action-button"); donationFormButton["Donate Now"].id = "donate-now"; donationFormButton["Add to Basket"].classList.add("donate-action-button"); donationFormButton["Add to Basket"].id = "add-to-basket"; // if (config.donationForm.hideCheckboxesAll === true) { donationFormCheckboxes.style.setProperty("display", "none"); } if (config.donationForm.hideCheckboxFreqeuncy === true) { [...donationFormCheckboxes.children][1]?.style.setProperty("display", "none"); } if (config.donationForm.hideCheckboxAnonymous === true) { [...donationFormCheckboxes.children][2]?.style.setProperty("display", "none"); } if (config.donationForm.hideCheckboxTribute === true) { [...donationFormCheckboxes.children][2]?.style.setProperty("display", "none"); } if (config.donationForm.hideCartButton === true) { donationFormButton["Add to Basket"]?.style.setProperty("display", "none"); donationFormButton["Add to Basket"]?.parentElement?.style.setProperty("display", "none"); donationFormButton["Donate Now"].parentElement.classList = donationFormButton["Donate Now"].parentElement.classList.toString().replaceAll("1-of-2", "2-of-2"); } // // // // // // // // (function donationFormApi () { window.NA.DonationForm = window.NA.DonationForm || {}; Object.defineProperty(window.NA.DonationForm, 'root', { value: donationFormWidget, writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'elements', { value: { Tabs: undefined, GiftArrayButtons: donationFormGiftArrayButtons, GiftArrayOtherAmount: donationFormGiftArrayOtherAmountInput, CheckboxRecurring: donationFormCheckboxes.shadowQuerySelectorAll('lightning-primitive-input-checkbox input[type="checkbox"]')[0], CheckboxAnonymous: donationFormCheckboxes.shadowQuerySelectorAll('lightning-primitive-input-checkbox input[type="checkbox"]')[1], CheckboxTribute: donationFormCheckboxes.shadowQuerySelectorAll('lightning-primitive-input-checkbox input[type="checkbox"]')[2], SubmitButton: donationFormButton["Donate Now"], }, writable: false, configurable: true, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'submit', { value: function doSubmit () { this.elements.SubmitButton?.click(); }, configurable: false, writable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'interceptSubmit', { value: function interceptSubmit (callbackFn, submitButton = this.elements.SubmitButton, hideOriginal = true, maxIntercepts = 1) { const hide = (element) => element?.style.setProperty("display", "none"); const unhide = (element) => element?.style.removeProperty("display"); const submitButtonCopy = submitButton.cloneNode(true); if (!submitButton.id) submitButton.id = "submit-button"; submitButtonCopy.id = submitButton.id ? submitButton.id + "-copy" : "submit-button-copy"; submitButton.after(submitButtonCopy); if (hideOriginal === true) hide(submitButton); const submitButtonMutationObserver = new MutationObserver((mutations, observe) => { for (const mutation of mutations) { const { type, target } = mutation; if (target === submitButton) { switch (type) { case 'attributes': const { attributeName } = mutation; const attributeValue = target.hasAttribute(attributeName) ? target.getAttribute(attributeName) : null; if (!attributeValue) { submitButtonCopy.removeAttribute(attributeName); } else { submitButtonCopy.setAttribute(attributeName, attributeValue); } break; case 'characterData': submitButtonCopy.innerHTML = target.innerHTML; break; default: break; } } } }); submitButtonMutationObserver.observe(submitButton, { childList: true, attributes: true, attributeOldValue: true, characterData: true, characterDataOldValue: true }); if (maxIntercepts && maxIntercepts > 0) { submitButtonCopy.setAttribute("intercepts", "0"); // initialize intercept counter to 0 function interceptCounter (event) { let interceptCount = parseInt(this.getAttribute("intercepts")); this.setAttribute("intercepts", ++interceptCount); if (interceptCount >= maxIntercepts) // reached max number of submit intercepts console.info("Max intercepts reached: original submit button unhidden."), submitButtonMutationObserver?.disconnect(), // disconnect the observer so the following changes don't apply to both buttons unhide(submitButton), // unhide the original submit button so the user won't be prevented from submitting the next time they click it hide(submitButtonCopy), // hide the copy of the submit button that was intercepting this.removeEventListener('click', interceptCounter); } submitButtonCopy.addEventListener('click', interceptCounter); } submitButtonCopy.addEventListener('click', (event) => { const callbackResult = callbackFn.call(this, event); if (callbackResult && callbackResult !== false) { // if callback function result evaluates to true, then submit after the callback window.NA.DonationForm.submit(); } }); }, configurable: false, writable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'getFrequency', { value: function getFrequency () { const recurringCheckbox = this.root.shadowQuerySelectorAll('lightning-primitive-input-checkbox input[type="checkbox"]')[0]; if (recurringCheckbox.checked === true) { return "Recurring"; } else { return "One-Time"; } }, configurable: false, writable: false, enumerable: false, }); Object.defineProperty(window.NA.DonationForm, 'setFrequency', { value: function setFrequency (value) { let toFrequency; if (typeof value === 'boolean') { toFrequency = value ? true : false; } else if (typeof value === 'string') { if (reOneTime.test(value.toLowerCase())) { toFrequency = false; } else if (reRecurring.test(value.toLowerCase())) { toFrequency = true; } else { throw new TypeError(`Argument 0 must be a boolean or string. If string, it must match either "One-Time" or "Recurring".`); } } else { throw new TypeError(`Argument 0 must be a boolean or string.`); } if (this.elements.Tabs && this.elements.Tabs.length === 2) this.elements.Tabs[toFrequency ? 1 : 0]?.click(); const recurringCheckbox = this.root.shadowQuerySelectorAll('lightning-primitive-input-checkbox input[type="checkbox"]')[0]; if (toFrequency === true) { // set frequency to recurring if (!recurringCheckbox.checked) { recurringCheckbox.click(); } else { console.warn("Frequency is already set to recurring:", recurringCheckbox); } } else { // set frequency to one-time if (recurringCheckbox.checked) { recurringCheckbox.click(); } else { console.warn("Frequency is already set to one-time:", recurringCheckbox); } } }, configurable: false, writable: false, enumerable: false, }); Object.defineProperty(window.NA.DonationForm, 'recurring', { get () { return this.getFrequency() === "Recurring" ? true : false; }, set (value) { this.setFrequency(value); } }); Object.defineProperty(window.NA.DonationForm, 'isRecurring', { get () { return this.recurring; } }); Object.defineProperty(window.NA.DonationForm, 'getAmount', { value: function getAmount () { let matchingButton = this.elements.GiftArrayButtons.find((button) => button.classList.contains("donate-selected")); if (matchingButton) { return parseInt(matchingButton.value); } else if (this.elements.GiftArrayOtherAmount?.value.length > 0) { let value = this.elements.GiftArrayOtherAmount.value; value = value.replace(/[^\d\.]/, ''); return parseFloat(value); } else { return undefined; } }, configurable: false, writable: false, enumerable: false, }); Object.defineProperty(window.NA.DonationForm, 'setAmount', { value: function setAmount (value) { if (value === "unset") { this.elements.GiftArrayButtons.forEach((button) => { button.classList.remove("donate-selected", "donate-not-selected"); }); } if (!value || Number.isNaN(parseFloat(value))) throw new TypeError(`Argument 0 must be a boolean or string. If string, it must match either "One-Time" or "Recurring".`); value = parseFloat(value); let matchingButton = this.elements.GiftArrayButtons.find((button) => parseFloat(button.value) === value); if (matchingButton) { return matchingButton.click(); } else { const giftArrayOtherAmountField = this.elements.GiftArrayOtherAmount; giftArrayOtherAmountField.value = parseFloat(value); // form doesn't like the formatted string, so number it is. //giftArrayOtherAmountField.value = parseFloat(value).toLocaleString('en-US', { style: 'currency', currency: 'USD', currencySign: '$', minimumFractionDigits: 2, maximumFractionDigits: 2 }); giftArrayOtherAmountField.dispatchEvent(new Event('change')); giftArrayOtherAmountField.dispatchEvent(new Event('blur')); } }, configurable: false, writable: false, enumerable: false, }); Object.defineProperty(window.NA.DonationForm, 'amount', { get () { return this.getAmount(); }, set (value) { this.setAmount(value); } }); Object.defineProperty(window.NA.DonationForm, 'getGiftArrayValues', { value: function getGiftArrayValues () { return this.elements.GiftArrayButtons.map((button) => parseInt(button.value)); }, writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'setGiftArrayValues', { value: function setGiftArrayValues (valueArray) { if (!Array.isArray(valueArray) || valueArray.some(value => value <= 0)) throw new TypeError("Argument 0 must be an array of positive integers."); if (valueArray.length !== this.elements.GiftArrayButtons.length) throw new RangeError("Argument 0 must be an array of the same length as the number of gift array button elements."); this.elements.GiftArrayButtons.forEach((button, i, buttons) => { button.value = valueArray[i]; button.textContent = button.textContent.replace(/(\d+)/gi, valueArray[i]); }); console.info("Updated gift array values:", ...valueArray); }, writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'onFrequencyChange', { value: new Array(), writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'onAmountChange', { value: new Array(), writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'onSubmit', { value: new Array(), writable: false, configurable: false, enumerablele: true, }); const frequencyChangeEventListener = (event) => { const newFrequency = window.NA.DonationForm.getFrequency(); window.NA.DonationForm.onFrequencyChange.forEach((callback) => { callback.call(window.NA.DonationForm, newFrequency); }); }; const frequencyMutationHandler = new MutationObserver ((mutations, observer) => { for (const mutation of mutations) { switch (mutation.type) { case 'attributes': if (mutation.attributeName === 'checked') { } break; default: break; } } }); //window.NA.DonationForm.elements.CheckboxRecurring && frequencyMutationHandler.observe(window.NA.DonationForm.elements.CheckboxRecurring, { childList: true, attributes: true, attributeFilter: [ 'checked' ] }); window.NA.DonationForm.elements.CheckboxRecurring && window.NA.DonationForm.elements.CheckboxRecurring.addEventListener('change', frequencyChangeEventListener); })(); // // // // // // // // (function donationPageApi () { Object.defineProperty(window.NA.DonationPage, 'root', { value: null, //document.shadowQuerySelector('c-donate-community-staff-information > div'), writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationPage, 'elements', { value: { CopySection: donationPageCopySection, }, writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationPage, 'getCopyHTML', { value: function getCopyHTML () { return this.elements.CopySection.innerHTML; }, writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationPage, 'setCopyHTML', { value: function setCopyHTML (newCopyHTML) { this.elements.CopySection.innerHTML = newCopyHTML; }, writable: false, configurable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationPage, 'copy', { get () { return this.getCopyHTML(); }, set (newCopyHTML) { this.setCopyHTML(newCopyHTML); } }); })(); // // // // // // // // (function cartApi () { const Cart = new Object(); Object.defineProperty(Cart, 'Cart', { value: function addItem (cartItem) { // }, configurable: false, writable: false, enumerable: true, }); Object.defineProperty(window.NA.DonationForm, 'Cart', { value: Cart, configurable: false, writable: false, enumerable: true, }); })(); // // // // // // // // function moveDonationForm () { try { donationPageSubtitle.before(donationPageCopySection); // move the subtitle above the tcopy section, below the main page title donationPageAboutTitle.style.setProperty("display", "none"); // hide the bottom heading (for the About section) } catch (error) { console.error(error); } } moveDonationForm(); // // // // // // // // function makeTabbed () { function createTabs (tabTexts, defaultRecurring = false) { defaultRecurring = defaultRecurring ? true : false; const tabs = document.createElement('div'); tabs.classList.add("tabs"); tabTexts.forEach((tabText, i) => { const tab = document.createElement('div'); let tabClassList = [ "tab" ]; tabClassList.push(reOneTime.test(tabText) ? "onetime" : "recurring"); ((tabClassList.includes("onetime") && defaultRecurring === false) || (tabClassList.includes("recurring") && defaultRecurring === true)) && tabClassList.push('selected'); tab.classList.add(...tabClassList); tab.textContent = tabText; tabs.appendChild(tab); }); return tabs; } const donationFormTabs = createTabs([ config.tabs["one-time"].text, config.tabs["recurring"].text ], config.donationForm.defaultRecurring); donationFormWidget.before(donationFormTabs); window.NA.DonationForm.elements.Tabs = Array.from(donationFormTabs.children); window.NA.DonationForm.elements.Tabs.forEach((tab, i ,tabs) => { tab.addEventListener('click', function (e) { this.classList.add('selected'); if (this.classList.contains('recurring')) { // if "Recurring" tab clicked tabs.find((tab) => tab !== this)?.classList.remove('selected'); window.NA.DonationForm.recurring = true; } else { // if "One-Time" tab clicked tabs.find((tab) => tab !== this)?.classList.remove('selected'); window.NA.DonationForm.recurring = false; } }); }); Object.defineProperty(window.NA.DonationForm, 'onTabClick', { value: new Array(), writable: false, configurable: false, enumerable: true, }); window.NA.DonationForm.elements.Tabs.forEach((tab) => { tab.addEventListener('click', function (e) { window.NA.DonationForm.onTabClick.forEach((callback) => { callback.call(window.NA.DonationForm, this.textContent.trim()); }); }); }); const splitGiftArrayAmounts = { "one-time": config.tabs["one-time"].giftArrayAmounts, "recurring": config.tabs["recurring"].giftArrayAmounts, }; if (((Array.isArray(config.tabs["one-time"].giftArrayAmounts) && config.tabs["one-time"].giftArrayAmounts.length > 0) || (Array.isArray(config.tabs["recurring"].giftArrayAmounts) && config.tabs["recurring"].giftArrayAmounts.length > 0)) // if either one-time or recurring gift array is set, && !(Array.isArray(config.tabs["one-time"].giftArrayAmounts) && config.tabs["one-time"].giftArrayAmounts.length > 0) && (Array.isArray(config.tabs["recurring"].giftArrayAmounts) && config.tabs["recurring"].giftArrayAmounts.length > 0)) { // but not both (unforntuantely no JS XOR). if (!config.tabs["one-time"].giftArrayAmounts) config.tabs["one-time"].giftArrayAmounts = window.NA.DonationForm.getGiftArrayValues(); if (!splitGiftArrayAmounts["recurring"]) config.tabs["recurring"].giftArrayAmounts = window.NA.DonationForm.getGiftArrayValues(); } if ((Array.isArray(config.tabs["one-time"].giftArrayAmounts) && config.tabs["one-time"].giftArrayAmounts.length > 0) || (Array.isArray(config.tabs["recurring"].giftArrayAmounts) && config.tabs["recurring"].giftArrayAmounts.length > 0)) { window.NA.DonationForm.onFrequencyChange.push(function updateGiftArrayAmounts (newFrequency) { let tabKeyName; switch (newFrequency) { case "One-Time": tabKeyName = "one-time"; if (config.hasOwnProperty("tabs") && config.tabs.hasOwnProperty(tabKeyName) && config.tabs[tabKeyName].hasOwnProperty("giftArrayAmounts") && Array.isArray(config.tabs[tabKeyName].giftArrayAmounts)) // if tabs are enabled and configured and gift array values are provided, this.setGiftArrayValues(config.tabs[tabKeyName].giftArrayAmounts); // update the gift array values this.setAmount('unset'); // unselect gift array options whenever frequency changes break; case "Recurring": tabKeyName = "recurring"; if (config.hasOwnProperty("tabs") && config.tabs.hasOwnProperty(tabKeyName) && config.tabs[tabKeyName].hasOwnProperty("giftArrayAmounts") && Array.isArray(config.tabs[tabKeyName].giftArrayAmounts)) // if tabs are enabled and configured and gift array values are provided, this.setGiftArrayValues(config.tabs[tabKeyName].giftArrayAmounts); // update the gift array values this.setAmount('unset'); // unselect gift array options whenever frequency changes break; default: throw new Error("Failed to updated gift array for frequency " + newFrequency + '.'); } }); } window.NA.DonationForm.elements.Tabs?.find((tab) => tab.classList.contains('selected'))?.click(); // apply default selected tab to the form's checkbox } if (config.hasOwnProperty("tabs") && (Object.keys(config.tabs)).length == 2) { // if tabs are enabled and configured makeTabbed(); } // // // // // // // // function configureDonationFormFromURL (searchParams) { const GIFT_ARRAY_VALUE_DELIMITER = ',', MULTIPLE_GIFT_ARRAY_DELIMETER = ';'; if (searchParams.get('amounts') || searchParams.get('array-amounts')) { let amountsParamValue = searchParams.get('amounts') || searchParams.get('array-amounts') || ''; amountsParamValue = decodeURIComponent(amountsParamValue); // convert URI encoded string to normal characters before parsing if (amountsParamValue.includes(MULTIPLE_GIFT_ARRAY_DELIMETER)) { // multiple gift array provided with gift arrays separated by ';' and values separated by ',' const amountArrays = amountsParamValue.split(MULTIPLE_GIFT_ARRAY_DELIMETER).map((amountArrayString) => amountArrayString.includes(GIFT_ARRAY_VALUE_DELIMITER) ? amountArrayString.split(GIFT_ARRAY_VALUE_DELIMITER).map((amount) => parseInt(amount)) : undefined) // convert string to array of arrays of numbers split by ',' and gift arrays separated by ';' if (amountArrays && Array.isArray(amountArrays) && amountArrays.length === 2 && amountArrays.every((amountArray) => amountArray.every((amount) => !Number.isNaN(amount) && Number.isInteger(amount) && amount > 0))) { // if amount arrays is defined as an array with 2 arrays, where every item in EACH of the array is an integer greater than 0 if ((Array.isArray(config.tabs["one-time"].giftArrayAmounts) && config.tabs["one-time"].giftArrayAmounts.length > 0) || (Array.isArray(config.tabs["recurring"].giftArrayAmounts && config.tabs["recurring"].giftArrayAmounts.length > 0))) // if either of the split gift array options are configured console.warn("Split gift array values were configured but the URL contains parameters to set the gift array. The gifty array values from the URL will override the split gift array values configured."); config.tabs["one-time"].giftArrayAmounts = amountArrays[0]; // set configuration one-time gift array values to the first array of values from amountArrays config.tabs["recurring"].giftArrayAmounts = amountArrays[1]; // set configuration recurring gift array values to the second array of values from amountArrays const isRecurring = window.NA.DonationForm.isRecurring; // get the current frequency, window.NA.DonationForm.setGiftArrayValues(amountArrays[isRecurring ? 1 : 0]); // set the gift array values to the new values assigned for that frequency } } else { // single gift array provided with values separated by ',' const amountArray = amountsParamValue.includes(GIFT_ARRAY_VALUE_DELIMITER) ? amountsParamValue.split(GIFT_ARRAY_VALUE_DELIMITER).map((amount) => parseInt(amount)) : undefined; // convert string to array of numbers split by ',' if (amountArray && Array.isArray(amountArray) && amountArray.every((amount) => !Number.isNaN(amount) && Number.isInteger(amount) && amount > 0)) { // if amount array is defined as an array where every item in EACH of the array is an integer greater than 0 if ((Array.isArray(config.tabs["one-time"].giftArrayAmounts) && config.tabs["one-time"].giftArrayAmounts.length > 0) || (Array.isArray(config.tabs["recurring"].giftArrayAmounts && config.tabs["recurring"].giftArrayAmounts.length > 0))) // if either of the split gift array options are configured console.warn("Split gift array values were configured but the URL contains parameters to set the gift array. The gifty array values from the URL will override the split gift array values configured."); config.tabs["one-time"].giftArrayAmounts = amountArray; // set configuration one-time gift array values to the array of values from amountArray config.tabs["recurring"].giftArrayAmounts = amountArray; // set configuration of recurring gift array values to the array of values from amountArray window.NA.DonationForm.setGiftArrayValues(amountArray); // set the gift array values to the new values from the amountArray } } } if (searchParams.get('frequency') || searchParams.get('freq')) { const frequencyParamValue = searchParams.get('frequency') || searchParams.get('freq') || undefined; const frequency = decodeURIComponent(frequencyParamValue); if (frequency) { if (config.defaultRecurring !== undefined && config.defaultRecurring !== null) console.warn("Default frequency is configured but the URL contains parameters to set the default frequency. The frequency from the URL will override the default frequency configured."); window.NA.DonationForm.recurring = reRecurring.test(frequency); } } if (searchParams.get('amount') || searchParams.get('amt')) { const amountParamValue = decodeURIComponent(searchParams.get('amount') || searchParams.get('amt') || undefined); const amount = !Number.isNaN(parseFloat(amountParamValue)) ? parseFloat(amountParamValue) : undefined; if (amount) { if (config.defaultAmount !== undefined && config.defaultAmount !== null) console.warn("Default amount is configured but the URL contains parameters to set the default amount. The amount from the URL will override the default amount configured."); window.NA.DonationForm.setAmount(amount); } } } if (window.location.search.length > 1) { configureDonationFormFromURL(new URLSearchParams(window.location.search)); } // // // // // // // // function addDonationInterrupter (config) { const { content } = config; const DONATION_INTERRUPTER_HTML = ``; document.body.insertAdjacentHTML('beforeend', DONATION_INTERRUPTER_HTML); const dialog = config.uniqueName ? document.getElementById(config.uniqueName) : document.querySelector('dialog.donation-interrupter'); // // // const calculateAskAmount = config.askAmount; const evaluateConditions = config.askConditions; function getMemoryModeStorageApi (memoryMode) { if (memoryMode === 'forever') return localStorage; if (memoryMode === 'session') return sessionStorage; if (memoryMode === 'none') return null; } const DonationInterrupterApi = {}; Object.defineProperties(DonationInterrupterApi, { id: { value: config.uniqueName, writable: false, configurable: true, enumerable: true, }, element: { value: dialog, writable: true, configurable: true, enumerable: true, }, getCTAButtons: { value: function () { const dialog = this.element; const ctaButtons = Array.from(dialog.querySelectorAll('.donation-interrupter--cta button')); return ctaButtons; }, writable: false, configurable: false, enumerable: false, }, memoryMode: { value: config.memoryMode ?? 'none', writable: false, configurable: false, enumerable: false, }, getStoredState: { value: function () { const storageApi = getMemoryModeStorageApi(this.memoryMode); if ( !storageApi ) { return console.error("Failed to read Donation Interrupter status. `memoryMode` is not set."), null; } else { return getToken(this.id, storageApi); } }, writable: false, configurable: false, enumerable: false, }, setStoredState: { value: function (newState) { const storageApi = getMemoryModeStorageApi(this.memoryMode); if ( !storageApi ) { throw new Error("Failed to store Donation Interrupter status. `memoryMode` is not set."); } else { setToken(this.id, newState, storageApi); } }, writable: false, configurable: false, enumerable: false, }, storedState: { get () { return this.getStoredState(); }, set (newStatus) { this.setStoredState(newStatus); } }, getStatus: { value: function () { const state = this.storedState; if (state && state.hasOwnProperty('status')) { return state.status; } else { return state || null; } }, writable: false, configurable: false, enumerable: false, }, setStatus: { value: function (newStatus) { const state = this.storedState; if (state && state.hasOwnProperty('status')) { this.storedState = { ...this.storedState, state: newStatus }; } else if (!state) { this.storedState = { status: newStatus }; } else { this.storedState = newStatus; } }, writable: false, configurable: false, enumerable: false, }, status: { get () { return this.getStatus() || {}; }, set (newStatus) { this.setStatus(newStatus); } }, hide: { value: function hide () { const dialog = this.element; const close = () => { dialog.close(); this.onHide?.forEach((callback) => { callback.call(this, dialog); }); this.status = "dismissed"; }; close(); }, writable: false, configurable: true, enumerable: true, }, show: { value: function show (force = false) { const dialog = this.element; const show = () => { this.update(); dialog.showModal(); this.onShow?.forEach((callback) => { callback.call(this, dialog); }); }; if (this.evaluateConditions) { if (typeof this.evaluateConditions === 'function') { // function that returns a boolean or truthy/falsy value if (this.evaluateConditions() ? true : false) // call the function with this context to be evalutated show(); } else if (Array.isArray(this.evaluateConditions)) { // array of conditions -- each item is evaluated to ensure all are truthy if (this.evaluateConditions.every((condition) => condition ? true : false)) // evaluate each item in teh array show(); } else { // booleans, string, numbers, etc. if (this.evaluateConditions) // any other truthy value show(); } } else { show(); } if (force) { show(); } }, writable: false, configurable: true, enumerable: true, }, evaluateConditions: { value: function () { return evaluateConditions.call(config, window.NA.DonationForm.getAmount(), window.NA.DonationForm.getFrequency(), window.NA.DonationForm.DonationInterrupter?.getStoredState()) ? true : false; }, writable: false, configurable: true, enumerable: false, }, onHide: { value: new Array(), writable: false, configurable: false, enumerable: false, }, onShow: { value: new Array(), writable: false, configurable: false, enumerable: false, }, onCTAButtonClick: { value: new Array(), writable: false, configurable: false, enumerable: false, }, update: { value: function updateData () { const dialog = this.element; if (dialog) { const originalAmount = window.NA.DonationForm.amount, suggestedAmount = calculateAskAmount(originalAmount); [...dialog.querySelectorAll('span[data="amount_original"]')].forEach((span) => span.textContent = originalAmount.toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 2 })); [...dialog.querySelectorAll('span[data="amount_suggested"]')].forEach((span) => span.textContent = suggestedAmount.toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 2 })); } }, writable: false, configurable: false, enumerable: true, }, handleYesClick: { value: function (e) { const suggestedAmount = calculateAskAmount(window.NA.DonationForm.amount); window.NA.DonationForm.recurring = true; window.NA.DonationForm.amount = suggestedAmount; //vwoCustomEvent("yes"); this.hide(); this.status = "converted"; setTimeout(() => { window.NA.DonationForm.submit(); }, 200); }, writable: true, configurable: true, enumerable: false, }, handleNoClick: { value: function (e) { //vwoCustomEvent("no"); this.hide(); window.NA.DonationForm.submit(); }, writable: true, configurable: true, enumerable: false, }, handleOtherClick: { value: function (e) {}, writable: true, configurable: true, enumerable: false, }, }); if (Array.isArray(DonationInterrupterApi.onShow)) { DonationInterrupterApi.onShow.push(function updateState () { const newState = { ...this.getStoredState(), status: "shown", lastSeenDate: getCurrentDate(), }; this.setStoredState(newState); }); DonationInterrupterApi.onShow.push(function sendVWOConversionEvent () { vwoCustomEvent("donationInterrupterShown"); }); } const ctaButtons = DonationInterrupterApi.getCTAButtons(); DonationInterrupterApi.hasOwnProperty('handleYesClick') && ctaButtons.find((ctaButton) => ctaButton.value.match(/yes/gi))?.addEventListener('click', DonationInterrupterApi.handleYesClick.bind(DonationInterrupterApi)); DonationInterrupterApi.hasOwnProperty('handleNoClick') && ctaButtons.find((ctaButton) => ctaButton.value.match(/no/gi))?.addEventListener('click', DonationInterrupterApi.handleNoClick.bind(DonationInterrupterApi)); DonationInterrupterApi.hasOwnProperty('handleOtherClick') && ctaButtons.find((ctaButton) => ctaButton.value.match(/other/gi))?.addEventListener('click', DonationInterrupterApi.handleOtherClick.bind(DonationInterrupterApi)); ctaButtons.forEach((ctaButton, ctaButtonIndex) => { ctaButton.addEventListener('click', (e) => { DonationInterrupterApi.onCTAButtonClick?.forEach((callback) => callback.call(DonationInterrupterApi, e.target, e.target.value)); }); }); if (!DonationInterrupterApi.getStoredState() || !DonationInterrupterApi.getStatus()) // if no state already found on browser storage DonationInterrupterApi.setStoredState({ status: "initialized" }); window.NA.DonationForm.DonationInterrupter = DonationInterrupterApi; // assign the function that initialized the donation interrupter to the DonationInterrupterApi return DonationInterrupterApi; } Object.defineProperty(window.NA.DonationForm, 'DonationInterrupter', { value: addDonationInterrupter, writable: true, configurable: true, enumerable: true, }); // // // // // // // // resolve(window.NA.DonationForm); // resolves the Promise of the init function with the DonationForm API object } // // // // // Initialize only after required custom elements are defined in the custom element registry and appear on the page try { console.group("Donation Form: Init"); asyncWaitForCustomElements(['c-donate-community-staff-information', 'c-donate-community-donate-buttons', 'lightning-input', 'lightning-primitive-input-simple', 'lightning-primitive-input-checkbox', 'lightning-formatted-text'], main); asyncWaitForCustomElements(['c-donate-community-staff-information', 'c-donate-community-donate-buttons', 'lightning-input', 'lightning-primitive-input-simple', 'lightning-primitive-input-checkbox', 'lightning-formatted-rich-text'], main); } catch (error) { console.error(error); reject(error); } finally { console.groupEnd(); } }); } (function(){ window.NA.DonationForm.init = window.NA.DonationForm.init || init; })(); }catch(e) {VWO._.vAEH(e);} return vwo_$('head')[0] && vwo_$('head')[0].lastChild;})("head")}}, ce79_4_1:{ fn:function(executeTrigger, vwo_$) { (// Example Code: This code will stop polling after 5 sec of dom ready (on calling executeTrigger() method) function() { vwo_$(document).ready(function () { // Waiting for 5 more seconds setTimeout(function () { // Call this method to stop the polling executeTrigger(); }, 5000); }); } )() }}, R_722072_79_1_3_1:{ fn:function(){return (function(x) { try{ var el,ctx=vwo_$(x); /*vwo_debug log("Revert","addElement","body"); vwo_debug*/(el=vwo_$('[vwo-element-id="1734023424996"]')).remove(); var ctx=vwo_$(x),el; /*vwo_debug log("Revert","content",""); vwo_debug*/; el=vwo_$('[vwo-element-id="1734023425072"]'); el.revertContentOp().remove(); return vwo_$('head')[0] && vwo_$('head')[0].lastChild; } catch(e) {} })("HEAD")}}, C_722072_79_1_3_1:{ fn:function(){return (function(x) { try{ var _vwo_sel = vwo_$(""); !vwo_$("head").find("#1734023425072").length && vwo_$('head').append(_vwo_sel); !vwo_$("body").find('[vwo-op-1734023424996=""]').length && vwo_$("body").vwoElement({ "html": "", "position": "append", "customBodyElement": true, "addElementId": 1734023424996 }) 'esversion: 8'; const ASK_AMOUNT = 10; const DONATION_INTERRUPTER_GROUP_NAME = "StaffDP" /* all the popups in this test will share the same group name so that the metrics for them are all counted in the test */; // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // // window.HTMLElement.prototype.getSlot = window.HTMLElement.prototype.getSlot || function () { return this.querySelector('slot') || this.shadowRoot.querySelector('slot'); } window.HTMLElement.prototype.getSlotNodes = window.HTMLElement.prototype.getSlotNodes || function (n) { return (parseInt(n) !== 'NaN' && n >= 0) ? Array.from(this.getSlot().assignedNodes({ flatten: true })).at(n) : Array.from(this.getSlot().assignedNodes({ flatten: true })); } window.HTMLElement.prototype.shadowChildren = window.HTMLElement.prototype.shadowChildren || function (n) { return (parseInt(n) !== 'NaN' && n >= 0) ? Array.from(this.shadowRoot.children).at(n) : Array.from(this.shadowRoot.children); } function waitForElement (el, retry, onSuccess = (el) => {}, delay = 30) { if ( !el ) return setTimeout(retry, delay); onSuccess(el); return true; } // function vwoSendEvent (eventName = "customEvent", object = { label: '' }) { window.VWO = window.VWO || []; VWO.event = VWO.event || function () {VWO.push(["event"].concat([].slice.call(arguments)));}; VWO.event(eventName, object); console.log(eventName, object); } const vwoSendEvent_DonationInterrupter = (action, group = undefined) => { if (action === "Shown") vwoSendEvent("custom_DonationInterrupter_Shown", { shown: true, group: group }); else if (action === "Yes") vwoSendEvent("custom_DonationInterrupter_Yes", { yes: true, group: group }); else if (action === "No") vwoSendEvent("custom_DonationInterrupter_No", { donationInterrupterNoClicked: true, group: group }); }; // function getBasketId (tokenName = `LSSIndex:LOCAL{"namespace":"c"}`){ const token = localStorage.getItem(tokenName); if (!token) { return console.error("getBasketId:", "Failed to get token from localStorage:", tokenName); } else { try { const { basket } = JSON.parse(token); // get basket property from the object return basket; } catch (error) { return console.error("getBasketId:", "Failed to parse JSON:", token); } } } function getBasket (basketId) { let token = localStorage.getItem(basketId); if (!token) { const emptyBasket = { "Id": "localBasket", "Basket_Items__r": [], "Total__c": 0, "Number_of_Items__c": 0, "itemMap": {} }; console.info("getBasket:", "Failed to get token from localStorage:", basketId, "\nAttempting to create a new empty basket and retrying..."); localStorage.setItem(basketId, JSON.stringify(emptyBasket)); token = localStorage.getItem(basketId); } if (!token) { return console.error("getBasket:", "Failed to get token from localStorage:", basketId); } else { try { return JSON.parse(token); // get basket property from the object } catch (error) { return console.error("getBasket:", "Failed to parse JSON:", token); } } } function addItemToBasket (item) { const basketId = getBasketId(), basket = getBasket(basketId); if ( basket.Basket_Items__r.find(item => item.id === item.Id) ) { // check if the item Id is already in the cart const foundItem = basket.Basket_Items__r.find(item => item.Id); foundItem["Quantity__c"] += 1; // update the quantity of the found item foundItem["Total_Amount__c"] = foundItem["Amount__c"] * foundItem["Quantity__c"]; // update the quantity of the found item foundItem["Total_Deductible_Amount__c"] = foundItem["Amount__c"] * foundItem["Quantity__c"]; // update the quantity of the found item } else { basket.Basket_Items__r.push(item); // add the item to the array } basket.Number_of_Items__c = basket.Basket_Items__r.length; // update item count basket.Total__c = basket.Basket_Items__r.reduce((total, item) => total + item["Amount__c"], 0); // update total amount basket.itemMap = Object.fromEntries(basket.Basket_Items__r.map((item, index) => ([item.Id, index]))); // update itemMap return localStorage.setItem(basketId, JSON.stringify(basket)); } function setAppealCode (sf_ac) { let queryString; let searchParams = window.location.search; if (searchParams.match('sf_ac')) { const regex = new RegExp(`(${'sf_ac'}=)([^&]*)`); queryString = searchParams.replace(regex, `$1${sf_ac}`); // replace existing appeal code value } else { queryString = searchParams + '&sf_ac=' + sf_ac; // append appeal code } window.history.pushState('', '', '?' + queryString); } // function entangleElements (element1, element2, method = 'innerHTML', options = { attributes: true, childList: true, subtree: true }) { if (!element1 || !element2) return console.error(`entangleElements: ${!element1 && "element1"}${!element1 && !element2 ? " and " : " "} ${!element2 && "element2"} ${!element1 && !element2 ? "are" : "is"} undefined.`); console.log("Entangling:\n", element1, ' ', element2, "\nElement 2 will mirror Element 1's values."); const handleMutation = (mutationList, observer) => { // Callback function to execute when mutations are observed let lastAttributeValues = {}; for (const mutation of mutationList) { switch (mutation.type) { case "attributes": const { attributeName, oldValue } = mutation; if (attributeName !== "style") { // ignore changes to style attribute const currentValue = element1.getAttribute(attributeName); if (currentValue === null) { element2.removeAttribute(attributeName); // mirror element 1 attributes on element 2 by removing null value attribute } else { element2.setAttribute(attributeName, currentValue); // mirror element 1 attributes on element 2 } } break; default: element2[method] = element1[method]; break; } } }; const observer = new MutationObserver(handleMutation); observer.observe(element1, options); // Start observing the target node for configured mutations return observer; } // // // // function init () { if (window.VWOInjected) { console.warn("Do not preview using the VWO Visual Editor."); return; } if (sessionStorage.getItem("NA_DonationInterrupter_StaffDPv2_status") === "dismissed") { console.warn("Popup already dismissed."); return; } try { customElements.whenDefined("c-donate-community-staff-information").then(() => { customElements.whenDefined("c-donate-community-donate-buttons").then(() => { customElements.whenDefined("lightning-input").then(() => { const wrapperForm = document.querySelector('c-donate-community-staff-information'); const wrapperFormInteractive = wrapperForm.shadowRoot.querySelector('c-donate-community-donate-buttons').shadowChildren(0); console.log(wrapperFormInteractive); /// Interface with the giving form and create a window object const form = { getGiftArrayButtons: function () { let w = wrapperFormInteractive; return Array.from(w.children).slice(0, Array.from(w.children).indexOf(w.querySelector('.slds-form-element'))).map(x => x.querySelector('button')); }, getAmount: function () { const sanitizeAmount = a => a.replace(/[^\d\.]/,''); // remove non-digit characters (except for decimals) let selected = this.getGiftArrayButtons().filter(x => x.classList.contains("donate-selected"))[0]; if (selected) { return parseFloat(selected.value); } else { selected = wrapperFormInteractive.querySelector('lightning-input').shadowChildren(0).shadowChildren(0).querySelector('input'); return parseFloat(sanitizeAmount(selected.value)); } console.warn("Amount is not defined: no option is selected.") return undefined; }, setAmount: function (n) { let match; const otherAmount = wrapperFormInteractive.querySelector('lightning-input').shadowChildren(0).shadowChildren(0).querySelector('input'); for (const button of this.getGiftArrayButtons()) { // iterate over gift array buttons if (parseFloat(button.value) === parseFloat(n) ) { // if matching button found for amount otherAmount.value = ''; // clear other amount button.click(); // click the matching button return this.getAmount() === parseFloat(n); // return true if the getAmount() matches the input value } } otherAmount.value = parseFloat(n); // set the other amount field value to the input value otherAmount.dispatchEvent(new Event('change', { bubbles: true })); // trigger a change event to cause the input to be formatted return this.getAmount() === parseFloat(n); // return true if the getAmount() matches the input value }, getRecurring: function () { const checkbox = [...wrapperFormInteractive.querySelector(".slds-grid").querySelectorAll("lightning-input")][0].shadowChildren(0).shadowChildren(0).querySelector('input[type="checkbox"]'); return checkbox.checked; }, setRecurring: function (toRecurring = true) { const checkbox = [...wrapperFormInteractive.querySelector(".slds-grid").querySelectorAll("lightning-input")][0].shadowChildren(0).shadowChildren(0).querySelector('input[type="checkbox"]'); const isRecurring = this.getRecurring(), isOnetime = !isRecurring, toOnetime = !toRecurring; // semantic booleans if ( (isOnetime && toRecurring) || (isRecurring && toOnetime)) { checkbox.click(); } return this.getRecurring() === toRecurring; }, submit: function (btn = this.buttons["Donate Now"]) { return btn.click(); }, }; //form.giftArrayButtons = form.getGiftArrayButtons(); window.NA = window.NA || {}; window.NA.MiniDonationForm = form; waitForElement(wrapperFormInteractive.querySelector('button'), init, (el) => { // wait for form buttons window.NA.MiniDonationForm.buttons = { "Donate Now": Array.from(wrapperFormInteractive.children).slice(Array.from(wrapperFormInteractive.children).indexOf(wrapperFormInteractive.querySelector('.slds-form-element'))).map(x => x.querySelector('button')).filter(y => y)[0], "Add to Basket": Array.from(wrapperFormInteractive.children).slice(Array.from(wrapperFormInteractive.children).indexOf(wrapperFormInteractive.querySelector('.slds-form-element'))).map(x => x.querySelector('button')).filter(y => y)[1], }; window.NA.MiniDonationForm.cloneSubmitButton = function (originalButton = this.buttons["Donate Now"]) { const clonedButton = originalButton.cloneNode(true); // clone the button and its children clonedButton.attributes = originalButton.attributes; // copy attributes clonedButton.id = clonedButton.textContent.trim().replaceAll(' ', '_') + "_copy"; if (clonedButton.style) clonedButton.style = originalButton.style; // copy styles originalButton.after(clonedButton); // insert the fake button after the original //entangleElements(originalButton, clonedButton, 'outerHTML'); // quantum entangle the elements via outerHTML -- does not work if the element is fully replaced when state changed return clonedButton; // return the fake button }; /// Interface with the Donation Interrupter