Created
November 2, 2023 14:30
-
-
Save KTruong008/635378945abfe804893d980483588971 to your computer and use it in GitHub Desktop.
Example hooking into button
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
</style> | |
<script> | |
import { onDestroy } from "svelte"; | |
import { checkoutButtonSelectors } from "../constants.js"; | |
import { shopSpecificOverrides } from "../overrides.js"; | |
import { | |
areStylesheetsLoaded$, | |
settings$, | |
showCheckoutErrors$, | |
isCheckoutReady$, | |
} from "../stores.js"; | |
import { isCartPage, isProductPage } from "../utils.js"; | |
import CartWidget from "../cart-widget/cart-widget.svelte"; | |
const shopOrigin = Shopify.shop; | |
// Usually use settings, but overrides have more flexibility for page-specific selectors | |
const checkoutButtonOverride = shopSpecificOverrides[ | |
shopOrigin | |
]?.checkoutButtonSelector?.(); | |
/** | |
* - Find insertion point | |
* - Load cart widget | |
*/ | |
const { | |
// Default overrides for checkout button target | |
checkoutButtonSelector, | |
checkoutButtonAnchorSelector, | |
// Position overrides | |
positionOverrideSelector, | |
positionOverrideAnchorSelector, | |
// Page-specific overrides (more specific than checkoutButtonSelectors) | |
productPageCheckoutButtonSelector, | |
productPageCheckoutButtonAnchorSelector, | |
productPagePositionOverrideSelector, | |
productPagePositionOverrideAnchorSelector, | |
cartPageCheckoutButtonSelector, | |
cartPageCheckoutButtonAnchorSelector, | |
cartPagePositionOverrideSelector, | |
cartPagePositionOverrideAnchorSelector, | |
} = $settings$; | |
let hasCartWidgetLoaded = false; | |
/** | |
* Weird bug on pop-ups on Safari desktop | |
* | |
* main.js will check and find checkout target | |
* But when rendering app.svelte there is no target. | |
* Target appears only when popup is active but check is already done. | |
* | |
* Can remedy with an observer in app.svelte but it's kind of more work than I want. | |
*/ | |
// let checkoutButton = checkoutButtonSelector | |
// ? document?.querySelector?.(checkoutButtonSelector) | |
// : checkoutButtonOverride | |
// ? document?.querySelector?.(checkoutButtonOverride) | |
// : Array.from(document.querySelectorAll(checkoutButtonSelectors))?.find?.( | |
// (e) => window.getComputedStyle(e).visibility !== "hidden" | |
// ); | |
/** | |
* Re-write the above logic | |
* | |
* if isCartPage(), use cartPageCheckoutButtonSelector | |
* else if isProductPage(), use productPageCheckoutButtonSelector | |
* | |
* cartPage and productPage selectors are more specific than checkoutButtonSelector, but checkoutButtonSelector is still more specific than checkoutButtonOverride and checkoutButtonSelectors | |
* | |
* and so on... | |
*/ | |
let checkoutButton; | |
let checkoutButtonAnchor; | |
let positionOverrideTarget; | |
let positionOverrideAnchor; | |
// Cart page | |
if (isCartPage()) { | |
checkoutButton = cartPageCheckoutButtonSelector | |
? document?.querySelector?.(cartPageCheckoutButtonSelector) | |
: checkoutButtonSelector | |
? document?.querySelector?.(checkoutButtonSelector) | |
: checkoutButtonOverride | |
? document?.querySelector?.(checkoutButtonOverride) | |
: Array.from(document.querySelectorAll(checkoutButtonSelectors))?.find?.( | |
(e) => window.getComputedStyle(e).visibility !== "hidden" | |
); | |
checkoutButtonAnchor = cartPageCheckoutButtonAnchorSelector | |
? document?.querySelector?.(cartPageCheckoutButtonAnchorSelector) | |
: checkoutButtonAnchorSelector | |
? document?.querySelector?.(checkoutButtonAnchorSelector) | |
: null; | |
positionOverrideTarget = cartPagePositionOverrideSelector | |
? document?.querySelector?.(cartPagePositionOverrideSelector) | |
: positionOverrideSelector | |
? document?.querySelector?.(positionOverrideSelector) | |
: null; | |
positionOverrideAnchor = cartPagePositionOverrideAnchorSelector | |
? document?.querySelector?.(cartPagePositionOverrideAnchorSelector) | |
: positionOverrideAnchorSelector | |
? document?.querySelector?.(positionOverrideAnchorSelector) | |
: null; | |
// Product page | |
} else if (isProductPage()) { | |
checkoutButton = productPageCheckoutButtonSelector | |
? document?.querySelector?.(productPageCheckoutButtonSelector) | |
: checkoutButtonSelector | |
? document?.querySelector?.(checkoutButtonSelector) | |
: checkoutButtonOverride | |
? document?.querySelector?.(checkoutButtonOverride) | |
: Array.from(document.querySelectorAll(checkoutButtonSelectors))?.find?.( | |
(e) => window.getComputedStyle(e).visibility !== "hidden" | |
); | |
checkoutButtonAnchor = productPageCheckoutButtonAnchorSelector | |
? document?.querySelector?.(productPageCheckoutButtonAnchorSelector) | |
: checkoutButtonAnchorSelector | |
? document?.querySelector?.(checkoutButtonAnchorSelector) | |
: null; | |
positionOverrideTarget = productPagePositionOverrideSelector | |
? document?.querySelector?.(productPagePositionOverrideSelector) | |
: positionOverrideSelector | |
? document?.querySelector?.(positionOverrideSelector) | |
: null; | |
positionOverrideAnchor = productPagePositionOverrideAnchorSelector | |
? document?.querySelector?.(productPagePositionOverrideAnchorSelector) | |
: positionOverrideAnchorSelector | |
? document?.querySelector?.(positionOverrideAnchorSelector) | |
: null; | |
// Default | |
} else { | |
checkoutButton = checkoutButtonSelector | |
? document?.querySelector?.(checkoutButtonSelector) | |
: checkoutButtonOverride | |
? document?.querySelector?.(checkoutButtonOverride) | |
: Array.from(document.querySelectorAll(checkoutButtonSelectors))?.find?.( | |
(e) => window.getComputedStyle(e).visibility !== "hidden" | |
); | |
checkoutButtonAnchor = checkoutButtonAnchorSelector | |
? document?.querySelector?.(checkoutButtonAnchorSelector) | |
: null; | |
positionOverrideTarget = positionOverrideSelector | |
? document?.querySelector?.(positionOverrideSelector) | |
: null; | |
positionOverrideAnchor = positionOverrideAnchorSelector | |
? document?.querySelector?.(positionOverrideAnchorSelector) | |
: null; | |
} | |
let checkoutButtonTarget = checkoutButton?.parentNode; | |
// let positionOverrideTarget = | |
// positionOverrideSelector && | |
// document.querySelector?.(positionOverrideSelector); | |
// let positionOverrideAnchor = | |
// positionOverrideAnchorSelector && | |
// document.querySelector?.(positionOverrideAnchorSelector); | |
/** | |
* Dawn theme hack | |
* | |
* https://developer.mozilla.org/en-US/docs/Web/API/Element/classList | |
*/ | |
const isDawnTheme = | |
window?.Shopify?.theme?.name === "Dawn" || | |
checkoutButtonTarget?.classList?.contains?.("cart__ctas"); | |
if (isDawnTheme && checkoutButtonTarget) { | |
checkoutButtonTarget.style["flex-direction"] = "column"; | |
checkoutButtonTarget.style["align-items"] = "center"; | |
} | |
if (window.debugKaspud) { | |
console.log("--app.svelte--"); | |
console.log("checkoutButtonTarget: ", checkoutButtonTarget); | |
console.log("$areStylesheetsLoaded$: ", $areStylesheetsLoaded$); | |
console.log("hasCartWidgetLoaded: ", hasCartWidgetLoaded); | |
} | |
$: { | |
if (checkoutButtonTarget && $areStylesheetsLoaded$ && !hasCartWidgetLoaded) { | |
new CartWidget({ | |
target: positionOverrideTarget || checkoutButtonTarget, | |
anchor: positionOverrideAnchor || checkoutButtonAnchor, | |
}); | |
checkoutButtonTarget.appendChild(checkoutButton); | |
checkoutButton.removeEventListener("touchstart", handleCheckoutButtonClick); | |
checkoutButton.removeEventListener("touchend", handleCheckoutButtonClick); | |
checkoutButton.removeEventListener("mousedown", handleCheckoutButtonClick); | |
checkoutButton.removeEventListener("click", handleCheckoutButtonClick); | |
checkoutButton.addEventListener("touchstart", handleCheckoutButtonClick); | |
checkoutButton.addEventListener("touchend", handleCheckoutButtonClick); | |
checkoutButton.addEventListener("mousedown", handleCheckoutButtonClick); | |
checkoutButton.addEventListener("click", handleCheckoutButtonClick); | |
/** | |
* Checks for re-renders within THIS component only. | |
* | |
* The global check is in utils.js and used in main.js | |
*/ | |
hasCartWidgetLoaded = true; | |
} | |
} | |
function handleCheckoutButtonClick(e) { | |
if (shopOrigin === "spectrum-gardening.myshopify.com") { | |
return; | |
} | |
if (!$isCheckoutReady$) { | |
e.preventDefault(); | |
showCheckoutErrors$.set(true); | |
} | |
} | |
onDestroy(() => { | |
checkoutButton.removeEventListener("touchstart", handleCheckoutButtonClick); | |
checkoutButton.removeEventListener("touchend", handleCheckoutButtonClick); | |
checkoutButton.removeEventListener("mousedown", handleCheckoutButtonClick); | |
checkoutButton.removeEventListener("click", handleCheckoutButtonClick); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment