Skip to content

Instantly share code, notes, and snippets.

@KTruong008
Created November 2, 2023 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KTruong008/635378945abfe804893d980483588971 to your computer and use it in GitHub Desktop.
Save KTruong008/635378945abfe804893d980483588971 to your computer and use it in GitHub Desktop.
Example hooking into button
<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