@salla.sa/twilight-components
Version:
Salla Web Component
327 lines (322 loc) • 13.1 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client';
import { d as defineCustomElement$3 } from './salla-loading2.js';
import { d as defineCustomElement$2 } from './salla-modal2.js';
const sallaLoginModalCss = "iframe{-moz-transition:height 0.3s;-ms-transition:height 0.3s;-o-transition:height 0.3s;-webkit-transition:height 0.3s;transition:height 0.3s;width:100%}";
const SallaLoginModal$1 = /*@__PURE__*/ proxyCustomElement(class SallaLoginModal extends HTMLElement {
constructor() {
super();
this.__registerHost();
/**
* Does the merchant/current location for visitor allow to login using mobile, By default outside KSA is `false`
*/
this.isMobileAllowed = true;
/**
* Does the merchant require registration with email & mobile
*/
this.isEmailRequired = false;
/**
* Once the api verify success, it will be login the customer in web pages
*/
this.supportWebAuth = true;
/**
* Reload after a successful login
*/
this.withoutReload = false;
this.htmlElement = document.documentElement;
this.messages = [];
this.isClosable = true;
this.iframeLoaded = false;
this.scrolling = 'no';
this.direction = document.dir;
this.canRenderIframe = false;
salla.event.on('login::open', (data) => {
var _a;
if (!this.isEmailAllowed && !this.isMobileAllowed) {
salla.logger.warn('Please enable atleast one login type to use this component.');
return;
}
this.withoutReload = (_a = data === null || data === void 0 ? void 0 : data.withoutReload) !== null && _a !== void 0 ? _a : this.withoutReload;
this.open(data);
this.openModal();
});
salla.event.on('modal::close', (data) => {
if (this.iframe)
this.sendMessageToIframe({
source: 'login',
type: 'modal_closed',
data,
});
});
salla.onReady(() => {
this.api = salla.config.get('store.api');
this.storeId = salla.config.get('store.id');
});
}
componentDidLoad() {
window.addEventListener('message', (event) => {
if (event.data.source != "login") {
return;
}
salla.log(`salla-account:: recived an event`, event.data);
let action = event.data.type.replace('iframe::', '');
let value = event.data.message;
//if we need skip some events
// if (action === 'dispatchEvent' && [].includes(value.event)) {
// return;
// }
// if (action == "dispatchEvent") {
// return this.host.dispatchEvent(new CustomEvent(value.name, {
// cancelable: true,
// bubbles: true,
// detail: value.payload
// }));
// }
if (action == 'ready') {
if (value.isPasskeyPage) {
this.createPassKey.postMessage({ source: "login", type: "init_passkey_page", data: {
token: salla.storage.get('token'),
store_id: salla.config.get('store.id'),
locale: salla.config.get('user.language_code'),
redirect: salla.config.get('store.url')
} }, salla.config.get('login.url'));
return;
}
this.handleIframeReadyAction();
return;
}
if (action == 'height') {
return (this.iframe.height = (value === null || value === void 0 ? void 0 : value.height) + 'px');
}
//share the iframe storage, so login too
if (action == "storage") {
return this.handleIframeStorageAction(value);
}
// if (action == "success") {
// this.isClosable = true;
// confetti.startConfetti(1200, 50, 150);
// }
if (action == "scrolling") {
this.scrolling = value;
this.isClosable = false;
return;
}
if (action == "direction") {
return document.dir = this.direction = value ? "rtl" : "ltr";
}
if (action == 'notify') {
return salla.notify[value.type](value.message);
}
// temporary condition until we handle both cases separately
if (action == 'authenticated' || action == 'authenticated_web_auth') {
!(value === null || value === void 0 ? void 0 : value.withoutClose) && this.close();
return salla.auth.api.handlAfterAuthenticatedResponse(value, this.supportWebAuth)
.then(() => !((value === null || value === void 0 ? void 0 : value.withoutReload) || this.withoutReload) && setTimeout(() => window.location.reload(), 1000));
}
if (action == 'dispatchEvent' && value.event == 'auth::verified') {
salla.log('Ignored dispatchEvent `auth::verified` from iframe');
//we don't need to fire this event because it have listeners for it, and already it's fired/firing from `salla.auth.api.handlAfterAuthenticatedResponse` already we are handling it
return;
}
if (action == 'dispatchEvent') {
return salla.event.emit(value.event, ...value.payload);
}
if (action == 'reload') {
if (value === null || value === void 0 ? void 0 : value.withClose)
this.modal.close();
return window.location.reload();
}
if (action === 'open_page') {
return window.location.href = value.url;
}
if (action === 'open_passkey_page') {
this.createPassKey = window.open(`${salla.config.get('login.url')}/create-passkey`);
return;
}
if (action == "close") {
this.close();
}
});
this.observeDarkModeChanges();
setTimeout(() => Salla.event.emit('salla-login::ready'), 1);
}
/**
* Open login component
*/
async open(_event = null) {
/**
* This is a workaround until we remove all the user objet from twig files
* When the user is already login, let's reload the page
*/
if (!salla.config.isGuest()) {
if (!this.withoutReload) {
return location.reload();
}
// Fire an event if withoutReload is true
return;
}
return this.modal.open();
}
close() {
Salla.event.emit('salla-login::closing');
this.modal.close();
this.iframeLoaded = false;
this.canRenderIframe = false;
this.host.dispatchEvent(new CustomEvent('salla-login:closed', {
cancelable: true,
bubbles: true,
detail: null
}));
Salla.event.emit('salla-login::closed');
}
handleIframeReadyAction() {
this.sendInitMessage();
this.sendMessageToIframe({
source: 'login',
type: 'width',
data: document.body.clientWidth,
});
}
observeDarkModeChanges() {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === 'class') {
this.sendMessageToIframe({
source: 'login',
type: 'darkMode',
data: { isDark: this.htmlElement.classList.contains('dark') ? true : false },
});
}
});
});
// observing the HTML element for attribute changes
observer.observe(this.htmlElement, { attributes: true });
}
async handleIframeStorageAction(value) {
let token, cartUserId = salla.storage.get('cart.user_id');
Object.entries(value).filter(item => !salla.storage.get(item[0]))
.forEach(([key, value]) => {
salla.log('Shared storage from accounts domain', key, value);
let cleanedValue = (typeof value === 'string') ? value.replace(/^"|"$/g, '') : value;
salla.storage.set(key, cleanedValue);
if (key === 'token') {
token = cleanedValue;
}
if (key === 'user' && cartUserId && cleanedValue.id !== cartUserId) {
salla.cart.reset();
}
});
if (token) {
this.modal.close();
salla.auth.event.tokenFetched(token);
!salla.auth.api.isSessionless() && await salla.auth.api.request('auth/jwt');
setTimeout(() => window.location.reload(), 100);
return;
}
}
sendMessageToIframe(message) {
if (!this.iframe)
return;
return this.iframe.contentWindow.postMessage(message, '*');
}
sendInitMessage() {
let headers = this.headers;
try {
headers = typeof headers === 'string' ? JSON.parse(headers) : headers;
}
catch (error) {
console.error('Failed to parse headers!', this.headers, error);
headers = undefined;
}
const storageObject = {
user: salla.storage.get('user'),
s_translations: salla.storage.get('s_translations'),
token: salla.storage.get('token'),
};
storageObject.user || (delete storageObject.user);
storageObject.s_translations || (delete storageObject.s_translations);
storageObject.token || (delete storageObject.token);
this.sendMessageToIframe({
source: "login",
type: "init",
data: {
id: this.storeId,
lang: salla.lang.locale,
isDark: this.htmlElement.classList.contains('dark') ? true : false,
apiUrl: this.api.replace(/\/+$/, ''),
supportWebAuth: this.supportWebAuth,
withoutReload: this.withoutReload,
inline: this.inline,
settings: salla.config.all(),
headers: headers,
storage: storageObject,
}
});
}
openModal() {
if (!this.canRenderIframe) {
this.canRenderIframe = true;
}
this.modal.open();
}
render() {
if (this.inline) {
return this.getLoginDom();
}
return (h("salla-modal", { class: "s-login-modal", ref: modal => this.modal = modal, width: "xs" }, this.getLoginDom()));
}
getLoginDom() {
if (!this.canRenderIframe)
return '';
return h("iframe", { src: salla.config.get('login.url', 'https://accounts.salla.com'), title: "Salla Login", class: "hide-scroll", loading: 'lazy', ref: iframe => { this.iframe = iframe; }, allow: "publickey-credentials-get; publickey-credentials-create", scrolling: this.scrolling, frameborder: "0", width: "100%" });
}
get host() { return this; }
static get style() { return sallaLoginModalCss; }
}, [0, "salla-login-modal", {
"isEmailAllowed": [1028, "is-email-allowed"],
"isMobileAllowed": [1028, "is-mobile-allowed"],
"isEmailRequired": [1028, "is-email-required"],
"supportWebAuth": [516, "support-web-auth"],
"inline": [516],
"storeId": [1032, "store-id"],
"api": [1],
"headers": [1025],
"withoutReload": [1028, "without-reload"],
"messages": [32],
"isClosable": [32],
"iframeLoaded": [32],
"scrolling": [32],
"direction": [32],
"canRenderIframe": [32],
"open": [64]
}]);
function defineCustomElement$1() {
if (typeof customElements === "undefined") {
return;
}
const components = ["salla-login-modal", "salla-loading", "salla-modal"];
components.forEach(tagName => { switch (tagName) {
case "salla-login-modal":
if (!customElements.get(tagName)) {
customElements.define(tagName, SallaLoginModal$1);
}
break;
case "salla-loading":
if (!customElements.get(tagName)) {
defineCustomElement$3();
}
break;
case "salla-modal":
if (!customElements.get(tagName)) {
defineCustomElement$2();
}
break;
} });
}
const SallaLoginModal = SallaLoginModal$1;
const defineCustomElement = defineCustomElement$1;
export { SallaLoginModal, defineCustomElement };
//# sourceMappingURL=salla-login-modal.js.map
//# sourceMappingURL=salla-login-modal.js.map