@occluze/tether 0.6.6 → 0.6.8
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/README.md +3 -3
- package/dist/esm/astro.js +2 -2
- package/dist/esm/chunks/account-C3NP6HFB.js +1 -0
- package/dist/esm/chunks/account-pages-WLK374FO.js +1 -0
- package/dist/esm/chunks/analytics-G3SAWMNL.js +1 -0
- package/dist/esm/chunks/chunk-27PJJZGC.js +1 -0
- package/dist/esm/chunks/chunk-2FSXS55U.js +1 -0
- package/dist/esm/chunks/chunk-FCSWQDVV.js +1 -0
- package/dist/esm/chunks/chunk-FOMSMIAM.js +1 -0
- package/dist/esm/chunks/chunk-GZJTCLLW.js +1 -0
- package/dist/esm/chunks/chunk-HEQILZVR.js +1 -0
- package/dist/esm/chunks/chunk-JOOEXYF3.js +4 -0
- package/dist/esm/chunks/chunk-MPTQYLSM.js +1 -0
- package/dist/esm/chunks/chunk-NEHZ37TU.js +3 -0
- package/dist/esm/chunks/chunk-V74KGEJF.js +1 -0
- package/dist/esm/chunks/chunk-VT4CDUJJ.js +1 -0
- package/dist/esm/chunks/chunk-YJLWX2HK.js +1 -0
- package/dist/esm/chunks/diagnose-6VVGZNTY.js +14 -0
- package/dist/esm/chunks/extras-GJVRDFM3.js +1 -0
- package/dist/esm/chunks/markets-ui-UNB4PTA7.js +1 -0
- package/dist/esm/chunks/search-OU75RNQL.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -1
- package/dist/presets/barba.esm.js +56 -36
- package/dist/tether.account-pages.js +776 -432
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +655 -321
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +318 -191
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +334 -243
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +78 -33
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +3171 -1998
- package/dist/tether.markets.js +231 -126
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +0 -0
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +221 -126
- package/dist/tether.search.min.js +1 -1
- package/package.json +23 -4
- package/src/account/addresses-view.js +92 -0
- package/src/account/browser-session.js +359 -0
- package/src/account/markup.js +48 -0
- package/src/account/operations.js +180 -0
- package/src/account/order-lines.js +96 -0
- package/src/account/order-list.js +91 -0
- package/src/account/order-page.js +192 -0
- package/src/account/page-events.js +288 -0
- package/src/account/server-client.js +172 -0
- package/src/account/shared.js +111 -0
- package/src/account/shopify-auth.js +150 -0
- package/src/account/subscriptions-view.js +158 -0
- package/src/account-api.js +118 -0
- package/src/account-links.js +35 -0
- package/src/account-pages.js +68 -284
- package/src/account.js +281 -317
- package/src/amounts.js +36 -0
- package/src/analytics-shopify.js +241 -0
- package/src/analytics.js +304 -184
- package/src/api-version.js +75 -25
- package/src/astro.js +233 -68
- package/src/cart/checkout.js +97 -0
- package/src/cart/drawer.js +138 -0
- package/src/cart/mutations.js +234 -0
- package/src/cart/render.js +294 -0
- package/src/cart/store.js +326 -0
- package/src/cart.js +322 -481
- package/src/client.js +214 -78
- package/src/collection.js +126 -57
- package/src/config.js +323 -59
- package/src/controls/cart-controls.js +155 -0
- package/src/controls/discount.js +96 -0
- package/src/controls/extras.js +63 -0
- package/src/controls/navigation.js +83 -0
- package/src/diagnose-markup.js +333 -0
- package/src/diagnose.js +251 -202
- package/src/dom.js +219 -220
- package/src/extras.js +119 -37
- package/src/fragments.js +115 -22
- package/src/images.js +104 -0
- package/src/index.js +245 -285
- package/src/initial.js +78 -66
- package/src/lazy-iife.js +92 -22
- package/src/lazy.js +25 -4
- package/src/loader.js +263 -124
- package/src/market-codes.js +35 -0
- package/src/markets-ui.js +169 -55
- package/src/markets.js +286 -85
- package/src/markup.js +64 -0
- package/src/mounting.js +214 -91
- package/src/page-market.js +116 -0
- package/src/parts/account-pages.js +4 -1
- package/src/parts/account.js +4 -1
- package/src/parts/analytics.js +4 -1
- package/src/parts/diagnose.js +4 -1
- package/src/parts/extras.js +4 -1
- package/src/parts/markets.js +4 -1
- package/src/parts/search.js +4 -1
- package/src/presets/barba.js +120 -30
- package/src/product-events.js +130 -0
- package/src/product-render.js +257 -0
- package/src/product-state.js +318 -0
- package/src/product.js +233 -459
- package/src/repeaters.js +173 -0
- package/src/search.js +277 -107
- package/src/selling-plans.js +107 -47
- package/src/server.js +168 -205
- package/src/shopify-values.js +89 -0
- package/src/status.js +99 -39
- package/src/store-html.js +0 -0
- package/src/storefront/catalog.js +199 -0
- package/src/storefront/json-ld.js +167 -0
- package/src/variant-render.js +165 -0
- package/types/astro.d.ts +13 -2
- package/types/index.d.ts +178 -27
- package/types/server.d.ts +89 -17
- package/dist/esm/chunks/account-QUBHQG3C.js +0 -1
- package/dist/esm/chunks/account-pages-VWDHF6WA.js +0 -1
- package/dist/esm/chunks/analytics-SLATWPLC.js +0 -1
- package/dist/esm/chunks/chunk-64TUD3QR.js +0 -1
- package/dist/esm/chunks/chunk-AJLPU2JC.js +0 -4
- package/dist/esm/chunks/chunk-FIOZPPC5.js +0 -1
- package/dist/esm/chunks/chunk-K2YEQAIH.js +0 -1
- package/dist/esm/chunks/chunk-L2TRRKYV.js +0 -1
- package/dist/esm/chunks/chunk-RREHGH4A.js +0 -1
- package/dist/esm/chunks/chunk-VC46IEJQ.js +0 -1
- package/dist/esm/chunks/chunk-VCPI7MJ2.js +0 -1
- package/dist/esm/chunks/chunk-VPVJPNB4.js +0 -1
- package/dist/esm/chunks/chunk-ZIUIWEON.js +0 -1
- package/dist/esm/chunks/diagnose-VXQBSD3A.js +0 -14
- package/dist/esm/chunks/extras-R4X34VQL.js +0 -1
- package/dist/esm/chunks/markets-ui-F3R5T5EL.js +0 -1
- package/dist/esm/chunks/search-NILMGYXG.js +0 -1
package/dist/tether.markets.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
(() => {
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __export = (target, all) => {
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
|
|
17
18
|
// tether-core:config.js
|
|
18
19
|
var m = window.Tether.__core["config.js"];
|
|
19
|
-
var { DEFAULTS, cfg, configure, isConfigured, log, reportError, warn } = m;
|
|
20
|
+
var { DEFAULTS, cfg, configure, isConfigured, log, reportError, resolveConfig, toMetafieldIdentifier, warn } = m;
|
|
20
21
|
|
|
21
22
|
// tether-core:client.js
|
|
22
23
|
var m2 = window.Tether.__core["client.js"];
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
|
|
25
26
|
// tether-core:cart.js
|
|
26
27
|
var m3 = window.Tether.__core["cart.js"];
|
|
27
|
-
var { Cart,
|
|
28
|
+
var { Cart, trapFocus } = m3;
|
|
28
29
|
|
|
29
30
|
// tether-core:collection.js
|
|
30
31
|
var m4 = window.Tether.__core["collection.js"];
|
|
@@ -36,165 +37,244 @@
|
|
|
36
37
|
|
|
37
38
|
// tether-core:dom.js
|
|
38
39
|
var m6 = window.Tether.__core["dom.js"];
|
|
39
|
-
var { attr, busy, cdnUrl,
|
|
40
|
+
var { attr, busy, cdnUrl, emit, formatDate, formatMoney, formatPercent, get, has, hasTemplate, imageUrl, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, repeatKeyed, sameImage, scoped, sel, setImage, setSelected, setStoreHtml, setText, setTextTracked, show, toAttributes, watchImages } = m6;
|
|
40
41
|
|
|
41
42
|
// tether-core:mounting.js
|
|
42
43
|
var m7 = window.Tether.__core["mounting.js"];
|
|
43
44
|
var { hydrateFromPage, liveLists, liveProducts, mountProduct, mountedLists, mountedProducts, pruneLive, retryFailed, settleMarket, trackMarket, within } = m7;
|
|
44
45
|
|
|
46
|
+
// tether-core:market-codes.js
|
|
47
|
+
var m8 = window.Tether.__core["market-codes.js"];
|
|
48
|
+
var { toCountry, toLanguage } = m8;
|
|
49
|
+
|
|
45
50
|
// src/markets.js
|
|
46
|
-
var
|
|
47
|
-
var
|
|
51
|
+
var ALL_SOURCES = ["saved", "server", "webflow"];
|
|
52
|
+
var DEFAULT_COOKIE = "tether_country";
|
|
48
53
|
var storageKey = () => `${cfg.prefix}:market:${cfg.domain}`;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
function localStorageIfAllowed() {
|
|
55
|
+
if (typeof window === "undefined") return null;
|
|
56
|
+
try {
|
|
57
|
+
return window.localStorage;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function pageEnv() {
|
|
63
|
+
const hasWindow = typeof window !== "undefined";
|
|
64
|
+
return {
|
|
65
|
+
document: typeof document !== "undefined" ? document : null,
|
|
66
|
+
location: hasWindow ? window.location : null,
|
|
67
|
+
storage: localStorageIfAllowed(),
|
|
68
|
+
global: hasWindow ? window : {}
|
|
69
|
+
};
|
|
64
70
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
function parseJsonOrNull(text) {
|
|
72
|
+
try {
|
|
73
|
+
return (
|
|
74
|
+
/** @type {unknown} */
|
|
75
|
+
JSON.parse(text)
|
|
76
|
+
);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (error instanceof SyntaxError) return null;
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function toMarket(value) {
|
|
83
|
+
if (typeof value !== "object" || value === null) return null;
|
|
84
|
+
const country = toCountry(Reflect.get(value, "country"));
|
|
85
|
+
if (!country) return null;
|
|
86
|
+
const locale = (
|
|
87
|
+
/** @type {unknown} */
|
|
88
|
+
Reflect.get(value, "locale")
|
|
89
|
+
);
|
|
90
|
+
return {
|
|
91
|
+
country,
|
|
92
|
+
language: toLanguage(Reflect.get(value, "language")) ?? void 0,
|
|
93
|
+
locale: typeof locale === "string" && locale ? locale : void 0
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function readSavedMarket(storage = localStorageIfAllowed()) {
|
|
97
|
+
const text = storage?.getItem(storageKey());
|
|
98
|
+
return text ? toMarket(parseJsonOrNull(text)) : null;
|
|
71
99
|
}
|
|
72
100
|
function readCookie(doc, name) {
|
|
73
101
|
if (!doc || !name) return null;
|
|
74
|
-
const
|
|
75
|
-
return
|
|
102
|
+
const cookie = doc.cookie.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${name}=`));
|
|
103
|
+
return cookie ? decodeURIComponent(cookie.slice(name.length + 1)) : null;
|
|
76
104
|
}
|
|
77
|
-
|
|
105
|
+
function lookupLocale(locales, key) {
|
|
78
106
|
if (!locales || !key) return null;
|
|
79
|
-
const
|
|
80
|
-
const found = Object.keys(locales).find((
|
|
81
|
-
return found ? locales[found] : null;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
107
|
+
const wanted = key.toLowerCase();
|
|
108
|
+
const found = Object.keys(locales).find((name) => name.toLowerCase() === wanted);
|
|
109
|
+
return found ? locales[found] ?? null : null;
|
|
110
|
+
}
|
|
111
|
+
function readServerHint(markets, env) {
|
|
112
|
+
const meta = (name) => env.document?.querySelector(`meta[name="${name}"]`)?.getAttribute("content");
|
|
113
|
+
return {
|
|
114
|
+
country: Reflect.get(env.global, "TETHER_COUNTRY") || meta("tether-country") || readCookie(env.document, markets.cookie || DEFAULT_COOKIE),
|
|
115
|
+
language: Reflect.get(env.global, "TETHER_LANGUAGE") || meta("tether-language")
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function readWebflowLocale(markets, env) {
|
|
119
|
+
const segment = (env.location?.pathname ?? "/").split("/").find((part) => part !== "");
|
|
120
|
+
const fromPath = lookupLocale(markets.locales, segment);
|
|
121
|
+
if (fromPath) return fromPath;
|
|
122
|
+
const lang = env.document?.documentElement.getAttribute("lang");
|
|
123
|
+
if (!lang) return null;
|
|
124
|
+
const mapped = lookupLocale(markets.locales, lang) ?? lookupLocale(markets.locales, lang.split("-")[0]);
|
|
125
|
+
if (mapped) return { locale: lang, ...mapped };
|
|
126
|
+
if (markets.locales && markets.strict) return null;
|
|
127
|
+
const region = lang.split("-")[1];
|
|
128
|
+
return { language: lang, country: region?.length === 2 ? region : null, locale: lang };
|
|
129
|
+
}
|
|
130
|
+
function readSource(source, markets, env) {
|
|
131
|
+
switch (source) {
|
|
132
|
+
case "saved":
|
|
133
|
+
return markets.remember === false ? null : readSavedMarket(env.storage);
|
|
134
|
+
case "server":
|
|
135
|
+
return readServerHint(markets, env);
|
|
136
|
+
case "webflow":
|
|
137
|
+
return readWebflowLocale(markets, env);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
var isMarketSource = (name) => ALL_SOURCES.some((source) => source === name);
|
|
141
|
+
function sourcesFor(detect) {
|
|
142
|
+
if (!detect) return ["saved"];
|
|
143
|
+
if (detect === true) return ALL_SOURCES;
|
|
144
|
+
return (
|
|
145
|
+
/** @type {unknown[]} */
|
|
146
|
+
[detect].flat().filter(isMarketSource)
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
function detectMarket(markets = cfg.markets, env = pageEnv()) {
|
|
150
|
+
const config = markets ?? {};
|
|
151
|
+
if (config.detect === false) return {};
|
|
152
|
+
const sources = {};
|
|
153
|
+
const found = { sources };
|
|
154
|
+
for (const source of sourcesFor(config.detect)) {
|
|
155
|
+
const hint = readSource(source, config, env);
|
|
156
|
+
if (!hint) continue;
|
|
157
|
+
const country = toCountry(hint.country);
|
|
158
|
+
const language = toLanguage(hint.language);
|
|
159
|
+
const locale = typeof hint.locale === "string" && hint.locale ? hint.locale : null;
|
|
160
|
+
if (country && !found.country) {
|
|
161
|
+
found.country = country;
|
|
162
|
+
sources.country = source;
|
|
163
|
+
}
|
|
164
|
+
if (language && !found.language) {
|
|
165
|
+
found.language = language;
|
|
166
|
+
sources.language = source;
|
|
167
|
+
}
|
|
168
|
+
if (locale && !found.locale) {
|
|
169
|
+
found.locale = locale;
|
|
170
|
+
sources.locale = source;
|
|
90
171
|
}
|
|
91
|
-
},
|
|
92
|
-
server(m8, env) {
|
|
93
|
-
const meta = (name) => env.document?.querySelector?.(`meta[name="${name}"]`)?.getAttribute("content");
|
|
94
|
-
const country = env.global.TETHER_COUNTRY || meta("tether-country") || readCookie(env.document, m8.cookie || "tether_country");
|
|
95
|
-
const language = env.global.TETHER_LANGUAGE || meta("tether-language");
|
|
96
|
-
return { country, language };
|
|
97
|
-
},
|
|
98
|
-
webflow(m8, env) {
|
|
99
|
-
const segment = (env.location?.pathname || "/").split("/").filter(Boolean)[0];
|
|
100
|
-
const fromPath = lookup(m8.locales, segment);
|
|
101
|
-
if (fromPath) return fromPath;
|
|
102
|
-
const lang = env.document?.documentElement?.getAttribute("lang");
|
|
103
|
-
if (!lang) return null;
|
|
104
|
-
const mapped = lookup(m8.locales, lang) || lookup(m8.locales, lang.split("-")[0]);
|
|
105
|
-
if (mapped) return { locale: lang, ...mapped };
|
|
106
|
-
if (m8.locales && m8.strict) return null;
|
|
107
|
-
const region = lang.split("-")[1];
|
|
108
|
-
return { language: lang, country: region && region.length === 2 ? region : null, locale: lang };
|
|
109
172
|
}
|
|
110
|
-
|
|
111
|
-
function detectMarket(markets = cfg.markets, env = defaultEnv()) {
|
|
112
|
-
const m8 = markets || {};
|
|
113
|
-
if (m8.detect === false) return {};
|
|
114
|
-
const list = !m8.detect ? ["saved"] : m8.detect === true ? ["saved", "server", "webflow"] : [].concat(m8.detect);
|
|
115
|
-
markets = m8;
|
|
116
|
-
const out = { sources: {} };
|
|
117
|
-
list.forEach((name) => {
|
|
118
|
-
const r = readers[name]?.(markets, env);
|
|
119
|
-
if (!r) return;
|
|
120
|
-
const vals = { country: toCountry(r.country), language: toLanguage(r.language), locale: r.locale || null };
|
|
121
|
-
Object.entries(vals).forEach(([k, v]) => {
|
|
122
|
-
if (v && !out[k]) {
|
|
123
|
-
out[k] = v;
|
|
124
|
-
out.sources[k] = name;
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
return out;
|
|
173
|
+
return found;
|
|
129
174
|
}
|
|
130
|
-
function
|
|
131
|
-
if (cfg.markets?.remember === false) return;
|
|
175
|
+
function storeIfAllowed(key, value) {
|
|
132
176
|
try {
|
|
133
|
-
localStorage.setItem(
|
|
177
|
+
localStorage.setItem(key, value);
|
|
134
178
|
} catch {
|
|
179
|
+
return;
|
|
135
180
|
}
|
|
136
181
|
}
|
|
182
|
+
function rememberMarket(market) {
|
|
183
|
+
if (cfg.markets?.remember === false) return;
|
|
184
|
+
const saved = { country: market.country, language: market.language || void 0, locale: market.locale || void 0 };
|
|
185
|
+
storeIfAllowed(storageKey(), JSON.stringify(saved));
|
|
186
|
+
}
|
|
137
187
|
var localizationPromise = null;
|
|
138
188
|
function clearLocalization() {
|
|
139
189
|
localizationPromise = null;
|
|
140
190
|
}
|
|
191
|
+
var LOCALIZATION_QUERY = `query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}`;
|
|
141
192
|
function getLocalization() {
|
|
142
193
|
if (!localizationPromise) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
194
|
+
const loading = gql(LOCALIZATION_QUERY);
|
|
195
|
+
localizationPromise = loading.then(
|
|
196
|
+
(data) => data.localization,
|
|
197
|
+
(error) => {
|
|
198
|
+
localizationPromise = null;
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
);
|
|
147
202
|
}
|
|
148
203
|
return localizationPromise;
|
|
149
204
|
}
|
|
150
205
|
|
|
151
206
|
// src/markets-ui.js
|
|
207
|
+
var DEFAULT_LABEL = "{name} ({currency})";
|
|
208
|
+
var DEFAULT_BIND = "name";
|
|
209
|
+
function countryField(country, field) {
|
|
210
|
+
switch (field) {
|
|
211
|
+
case "name":
|
|
212
|
+
return country.name;
|
|
213
|
+
case "code":
|
|
214
|
+
return country.isoCode;
|
|
215
|
+
case "currency":
|
|
216
|
+
return country.currency.isoCode;
|
|
217
|
+
case "symbol":
|
|
218
|
+
return country.currency.symbol;
|
|
219
|
+
default:
|
|
220
|
+
return "";
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
var fillLabel = (template, country) => template.replace(
|
|
224
|
+
/\{(name|code|currency|symbol)\}/g,
|
|
225
|
+
(_match, field) => countryField(country, field)
|
|
226
|
+
);
|
|
227
|
+
function fillCountrySelect(select, countries, current) {
|
|
228
|
+
const template = select.getAttribute(attr("country-label")) || DEFAULT_LABEL;
|
|
229
|
+
const only = (select.getAttribute(attr("countries")) || "").toUpperCase().split(/[\s,]+/).filter(Boolean);
|
|
230
|
+
const listed = only.length ? only.map((code) => countries.find((country) => country.isoCode === code)).filter((country) => country !== void 0) : countries;
|
|
231
|
+
select.replaceChildren(...listed.map((country) => new Option(fillLabel(template, country), country.isoCode)));
|
|
232
|
+
select.value = current;
|
|
233
|
+
if (select.value !== current) select.selectedIndex = -1;
|
|
234
|
+
select.disabled = listed.length < 2 && !select.hasAttribute(attr("always-enabled"));
|
|
235
|
+
}
|
|
236
|
+
function fillCountries(selects, binds, localization) {
|
|
237
|
+
const current = (cfg.country || localization.country.isoCode).toUpperCase();
|
|
238
|
+
const countries = [...localization.availableCountries].sort(
|
|
239
|
+
(a, b) => a.name.localeCompare(b.name, cfg.locale || void 0)
|
|
240
|
+
);
|
|
241
|
+
const inUse = countries.find((country) => country.isoCode === current) ?? localization.country;
|
|
242
|
+
selects.forEach((select) => {
|
|
243
|
+
fillCountrySelect(select, countries, current);
|
|
244
|
+
});
|
|
245
|
+
binds.forEach((el) => {
|
|
246
|
+
el.textContent = countryField(inUse, get(el, "country-bind") || DEFAULT_BIND);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
152
249
|
function renderCountrySelects(root = document) {
|
|
153
|
-
const selects =
|
|
250
|
+
const selects = (
|
|
251
|
+
/** @type {HTMLSelectElement[]} */
|
|
252
|
+
within(root, `select${sel("country-select")}`)
|
|
253
|
+
);
|
|
154
254
|
const binds = within(root, sel("country-bind"));
|
|
155
255
|
if (!selects.length && !binds.length) return Promise.resolve();
|
|
156
|
-
return getLocalization().then((
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
selects.forEach((s) => {
|
|
162
|
-
const tpl = s.getAttribute(attr("country-label")) || "{name} ({currency})";
|
|
163
|
-
const only = (s.getAttribute(attr("countries")) || "").toUpperCase().split(/[\s,]+/).filter(Boolean);
|
|
164
|
-
const list = only.length ? only.map((c) => countries.find((x) => x.isoCode === c)).filter(Boolean) : countries;
|
|
165
|
-
s.innerHTML = "";
|
|
166
|
-
list.forEach((c) => s.appendChild(new Option(fill(tpl, c), c.isoCode)));
|
|
167
|
-
s.value = current;
|
|
168
|
-
if (s.value !== current) s.selectedIndex = -1;
|
|
169
|
-
s.disabled = list.length < 2 && !s.hasAttribute(attr("always-enabled"));
|
|
170
|
-
});
|
|
171
|
-
binds.forEach((el) => {
|
|
172
|
-
const k = get(el, "country-bind") || "name";
|
|
173
|
-
const v = { name: info?.name, code: info?.isoCode, currency: info?.currency?.isoCode, symbol: info?.currency?.symbol }[k];
|
|
174
|
-
el.textContent = v || "";
|
|
175
|
-
});
|
|
176
|
-
}).catch((err) => reportError(err, "country select"));
|
|
256
|
+
return getLocalization().then((localization) => {
|
|
257
|
+
fillCountries(selects, binds, localization);
|
|
258
|
+
}).catch((error) => {
|
|
259
|
+
reportError(error, "country select");
|
|
260
|
+
});
|
|
177
261
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const changed = country !== String(cfg.country || "").toUpperCase() || lang !== cfg.language || loc !== cfg.locale;
|
|
186
|
-
cfg.country = country;
|
|
187
|
-
cfg.language = lang || void 0;
|
|
188
|
-
cfg.locale = loc;
|
|
189
|
-
if (remember) rememberMarket({ country, language: lang, locale: own });
|
|
190
|
-
if (!changed) {
|
|
191
|
-
renderCountrySelects();
|
|
192
|
-
return Cart.state;
|
|
193
|
-
}
|
|
262
|
+
var localeEntryFor = (country) => Object.values(cfg.markets?.locales ?? {}).find((entry) => toCountry(entry.country) === country);
|
|
263
|
+
function languageFor(language, entry) {
|
|
264
|
+
if (language !== void 0) return toLanguage(language);
|
|
265
|
+
if (!entry) return cfg.language;
|
|
266
|
+
return entry.language ? toLanguage(entry.language) : void 0;
|
|
267
|
+
}
|
|
268
|
+
function rerenderInMarket(country) {
|
|
194
269
|
clearProductCache();
|
|
195
270
|
const jobs = [];
|
|
196
|
-
if (
|
|
197
|
-
|
|
271
|
+
if (Cart.id()) {
|
|
272
|
+
jobs.push(
|
|
273
|
+
Cart.setBuyerIdentity({ countryCode: country }, { create: false }).catch((error) => {
|
|
274
|
+
reportError(error, "cart country");
|
|
275
|
+
})
|
|
276
|
+
);
|
|
277
|
+
}
|
|
198
278
|
pruneLive();
|
|
199
279
|
liveLists.forEach((list) => jobs.push(list.load()));
|
|
200
280
|
liveProducts.forEach((el) => {
|
|
@@ -202,12 +282,37 @@
|
|
|
202
282
|
mountedProducts.delete(el);
|
|
203
283
|
mountProduct(el);
|
|
204
284
|
});
|
|
205
|
-
|
|
285
|
+
return jobs;
|
|
286
|
+
}
|
|
287
|
+
async function setCountry(code, { language, locale, remember = true } = {}) {
|
|
288
|
+
const country = toCountry(code);
|
|
289
|
+
if (!country) throw new TetherError(`Not a country code: ${code}`, { code: "INVALID_COUNTRY" });
|
|
290
|
+
const entry = localeEntryFor(country);
|
|
291
|
+
const ownLocale = locale || entry?.locale;
|
|
292
|
+
const nextLocale = ownLocale || cfg.locale;
|
|
293
|
+
const nextLanguage = languageFor(language, entry);
|
|
294
|
+
const changed = country !== cfg.country?.toUpperCase() || nextLanguage !== cfg.language || nextLocale !== cfg.locale;
|
|
295
|
+
cfg.country = country;
|
|
296
|
+
cfg.language = nextLanguage || void 0;
|
|
297
|
+
cfg.locale = nextLocale;
|
|
298
|
+
if (remember) rememberMarket({ country, language: nextLanguage, locale: ownLocale });
|
|
299
|
+
if (!changed) {
|
|
300
|
+
void renderCountrySelects();
|
|
301
|
+
return Cart.state;
|
|
302
|
+
}
|
|
303
|
+
if (language !== void 0) clearLocalization();
|
|
304
|
+
const jobs = rerenderInMarket(country);
|
|
305
|
+
void renderCountrySelects();
|
|
206
306
|
emit("country-changed", { country, language: cfg.language });
|
|
207
307
|
await Promise.all(jobs);
|
|
208
308
|
return Cart.state;
|
|
209
309
|
}
|
|
210
310
|
|
|
211
311
|
// src/parts/markets.js
|
|
212
|
-
|
|
312
|
+
var { Tether } = (
|
|
313
|
+
/** @type {Window & { Tether?: { __parts: Record<string, unknown> } }} */
|
|
314
|
+
window
|
|
315
|
+
);
|
|
316
|
+
if (!Tether) throw new Error("tether.markets.js runs after the Tether script, which loads it");
|
|
317
|
+
Tether.__parts["markets"] = markets_ui_exports;
|
|
213
318
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
"use strict";(()=>{var B=Object.defineProperty;var H=(e,t)=>{for(var o in t)B(e,o,{get:t[o],enumerable:!0})};var T={};H(T,{detectMarket:()=>F,getLocalization:()=>y,renderCountrySelects:()=>L,setCountry:()=>be});var J=window.Tether.__core["config.js"],{DEFAULTS:Te,cfg:a,configure:_e,isConfigured:xe,log:Ee,reportError:h,resolveConfig:Se,toMetafieldIdentifier:Ae,warn:Pe}=J;var K=window.Tether.__core["client.js"],{TetherError:_,endpoint:ke,gql:x,request:Ue,unwrap:ve,withContext:je}=K;var W=window.Tether.__core["cart.js"],{Cart:f,trapFocus:Re}=W;var Y=window.Tether.__core["collection.js"],{ListScope:Fe,listSelector:E}=Y;var G=window.Tether.__core["loader.js"],{clearProductCache:S,getProduct:ze,getProducts:De,getRecommendations:qe,hydrateProducts:$e,normalizeProductKey:Be,primeProduct:He,refreshProducts:Je,takeStale:Ke}=G;var Q=window.Tether.__core["dom.js"],{attr:p,busy:Ye,cdnUrl:Ge,emit:A,formatDate:Qe,formatMoney:Ve,formatPercent:Ze,get:P,has:Xe,hasTemplate:et,imageUrl:tt,notifyLayoutChanged:ot,parseJSONAttr:nt,productUrl:rt,qsa:ct,repeat:at,repeatKeyed:lt,sameImage:it,scoped:ut,sel:w,setImage:st,setSelected:dt,setStoreHtml:ft,setText:gt,setTextTracked:mt,show:pt,toAttributes:yt,watchImages:ht}=Q;var V=window.Tether.__core["mounting.js"],{hydrateFromPage:Ct,liveLists:I,liveProducts:k,mountProduct:U,mountedLists:bt,mountedProducts:v,pruneLive:j,retryFailed:Lt,settleMarket:Tt,trackMarket:_t,within:C}=V;var Z=window.Tether.__core["market-codes.js"],{toCountry:s,toLanguage:d}=Z;var O=["saved","server","webflow"],X="tether_country",R=()=>`${a.prefix}:market:${a.domain}`;function M(){if(typeof window>"u")return null;try{return window.localStorage}catch{return null}}function ee(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:M(),global:e?window:{}}}function te(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function oe(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let o=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof o=="string"&&o?o:void 0}}function ne(e=M()){let t=e?.getItem(R());return t?oe(te(t)):null}function re(e,t){if(!e||!t)return null;let o=e.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith(`${t}=`));return o?decodeURIComponent(o.slice(t.length+1)):null}function b(e,t){if(!e||!t)return null;let o=t.toLowerCase(),r=Object.keys(e).find(n=>n.toLowerCase()===o);return r?e[r]??null:null}function ce(e,t){let o=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content");return{country:Reflect.get(t.global,"TETHER_COUNTRY")||o("tether-country")||re(t.document,e.cookie||X),language:Reflect.get(t.global,"TETHER_LANGUAGE")||o("tether-language")}}function ae(e,t){let o=(t.location?.pathname??"/").split("/").find(i=>i!==""),r=b(e.locales,o);if(r)return r;let n=t.document?.documentElement.getAttribute("lang");if(!n)return null;let l=b(e.locales,n)??b(e.locales,n.split("-")[0]);if(l)return{locale:n,...l};if(e.locales&&e.strict)return null;let c=n.split("-")[1];return{language:n,country:c?.length===2?c:null,locale:n}}function le(e,t,o){switch(e){case"saved":return t.remember===!1?null:ne(o.storage);case"server":return ce(t,o);case"webflow":return ae(t,o)}}var ie=e=>O.some(t=>t===e);function ue(e){return e?e===!0?O:[e].flat().filter(ie):["saved"]}function F(e=a.markets,t=ee()){let o=e??{};if(o.detect===!1)return{};let r={},n={sources:r};for(let l of ue(o.detect)){let c=le(l,o,t);if(!c)continue;let i=s(c.country),u=d(c.language),m=typeof c.locale=="string"&&c.locale?c.locale:null;i&&!n.country&&(n.country=i,r.country=l),u&&!n.language&&(n.language=u,r.language=l),m&&!n.locale&&(n.locale=m,r.locale=l)}return n}function se(e,t){try{localStorage.setItem(e,t)}catch{return}}function N(e){if(a.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};se(R(),JSON.stringify(t))}var g=null;function z(){g=null}var de="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}";function y(){return g||(g=x(de).then(t=>t.localization,t=>{throw g=null,t})),g}var fe="{name} ({currency})",ge="name";function D(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var me=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(o,r)=>D(t,r));function pe(e,t,o){let r=e.getAttribute(p("country-label"))||fe,n=(e.getAttribute(p("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),l=n.length?n.map(c=>t.find(i=>i.isoCode===c)).filter(c=>c!==void 0):t;e.replaceChildren(...l.map(c=>new Option(me(r,c),c.isoCode))),e.value=o,e.value!==o&&(e.selectedIndex=-1),e.disabled=l.length<2&&!e.hasAttribute(p("always-enabled"))}function ye(e,t,o){let r=(a.country||o.country.isoCode).toUpperCase(),n=[...o.availableCountries].sort((c,i)=>c.name.localeCompare(i.name,a.locale||void 0)),l=n.find(c=>c.isoCode===r)??o.country;e.forEach(c=>{pe(c,n,r)}),t.forEach(c=>{c.textContent=D(l,P(c,"country-bind")||ge)})}function L(e=document){let t=C(e,`select${w("country-select")}`),o=C(e,w("country-bind"));return!t.length&&!o.length?Promise.resolve():y().then(r=>{ye(t,o,r)}).catch(r=>{h(r,"country select")})}var he=e=>Object.values(a.markets?.locales??{}).find(t=>s(t.country)===e);function we(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:a.language}function Ce(e){S();let t=[];return f.id()&&t.push(f.setBuyerIdentity({countryCode:e},{create:!1}).catch(o=>{h(o,"cart country")})),j(),I.forEach(o=>t.push(o.load())),k.forEach(o=>{o.closest(E())||(v.delete(o),U(o))}),t}async function be(e,{language:t,locale:o,remember:r=!0}={}){let n=s(e);if(!n)throw new _(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let l=he(n),c=o||l?.locale,i=c||a.locale,u=we(t,l),m=n!==a.country?.toUpperCase()||u!==a.language||i!==a.locale;if(a.country=n,a.language=u||void 0,a.locale=i,r&&N({country:n,language:u,locale:c}),!m)return L(),f.state;t!==void 0&&z();let $=Ce(n);return L(),A("country-changed",{country:n,language:a.language}),await Promise.all($),f.state}var{Tether:q}=window;if(!q)throw new Error("tether.markets.js runs after the Tether script, which loads it");q.__parts.markets=T;})();
|
package/dist/tether.min.js
CHANGED
|
Binary file
|