@lovalingo/lovalingo 0.5.29 → 0.6.0

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.
Files changed (148) hide show
  1. package/README.md +34 -0
  2. package/dist/chunk-2FZR2AKF.mjs +88 -0
  3. package/dist/chunk-7D5LBV45.mjs +46 -0
  4. package/dist/chunk-CJOSN7RA.mjs +90 -0
  5. package/dist/chunk-VAHA2TOX.mjs +3440 -0
  6. package/dist/chunk-ZMRCSUM7.mjs +26 -0
  7. package/dist/chunk-ZVYKEEUF.mjs +220 -0
  8. package/dist/core.d.mts +131 -0
  9. package/dist/core.d.ts +131 -0
  10. package/dist/core.js +3561 -0
  11. package/dist/core.mjs +19 -0
  12. package/dist/index.d.mts +5 -0
  13. package/dist/index.d.ts +5 -25
  14. package/dist/index.js +3885 -28
  15. package/dist/index.mjs +33 -0
  16. package/dist/react-router.d.mts +101 -0
  17. package/dist/react-router.d.ts +101 -0
  18. package/dist/react-router.js +353 -0
  19. package/dist/react-router.mjs +14 -0
  20. package/dist/tanstack-router.d.mts +22 -0
  21. package/dist/tanstack-router.d.ts +22 -0
  22. package/dist/tanstack-router.js +162 -0
  23. package/dist/tanstack-router.mjs +8 -0
  24. package/package.json +34 -3
  25. package/dist/__tests__/languageFlags.test.d.ts +0 -1
  26. package/dist/__tests__/languageFlags.test.js +0 -42
  27. package/dist/__tests__/mergeEntitlements.test.d.ts +0 -1
  28. package/dist/__tests__/mergeEntitlements.test.js +0 -27
  29. package/dist/components/AixsterProvider.d.ts +0 -1
  30. package/dist/components/AixsterProvider.js +0 -1
  31. package/dist/components/LangLink.d.ts +0 -20
  32. package/dist/components/LangLink.js +0 -38
  33. package/dist/components/LangRouter.d.ts +0 -37
  34. package/dist/components/LangRouter.js +0 -191
  35. package/dist/components/LanguageSwitcher.d.ts +0 -17
  36. package/dist/components/LanguageSwitcher.js +0 -257
  37. package/dist/components/LovalingoProvider.d.ts +0 -10
  38. package/dist/components/LovalingoProvider.js +0 -413
  39. package/dist/components/NavigationOverlay.d.ts +0 -6
  40. package/dist/components/NavigationOverlay.js +0 -22
  41. package/dist/components/provider/__tests__/seoUtils.test.d.ts +0 -1
  42. package/dist/components/provider/__tests__/seoUtils.test.js +0 -13
  43. package/dist/components/provider/editModeUtils.d.ts +0 -6
  44. package/dist/components/provider/editModeUtils.js +0 -59
  45. package/dist/components/provider/localeUtils.d.ts +0 -8
  46. package/dist/components/provider/localeUtils.js +0 -46
  47. package/dist/components/provider/providerConstants.d.ts +0 -12
  48. package/dist/components/provider/providerConstants.js +0 -11
  49. package/dist/components/provider/seoUtils.d.ts +0 -8
  50. package/dist/components/provider/seoUtils.js +0 -118
  51. package/dist/components/provider/useEditModeOverlay.d.ts +0 -7
  52. package/dist/components/provider/useEditModeOverlay.js +0 -134
  53. package/dist/components/provider/useHistoryNavigationPatch.d.ts +0 -3
  54. package/dist/components/provider/useHistoryNavigationPatch.js +0 -47
  55. package/dist/components/provider/useProviderCache.d.ts +0 -12
  56. package/dist/components/provider/useProviderCache.js +0 -82
  57. package/dist/context/AixsterContext.d.ts +0 -3
  58. package/dist/context/AixsterContext.js +0 -2
  59. package/dist/context/LangContext.d.ts +0 -1
  60. package/dist/context/LangContext.js +0 -2
  61. package/dist/context/LangRoutingContext.d.ts +0 -8
  62. package/dist/context/LangRoutingContext.js +0 -7
  63. package/dist/context/LovalingoContext.d.ts +0 -1
  64. package/dist/context/LovalingoContext.js +0 -1
  65. package/dist/hooks/provider/useBundleLoading.d.ts +0 -33
  66. package/dist/hooks/provider/useBundleLoading.js +0 -380
  67. package/dist/hooks/provider/useDomRules.d.ts +0 -15
  68. package/dist/hooks/provider/useDomRules.js +0 -38
  69. package/dist/hooks/provider/useLinkAutoPrefix.d.ts +0 -12
  70. package/dist/hooks/provider/useLinkAutoPrefix.js +0 -146
  71. package/dist/hooks/provider/useNavigationPrefetch.d.ts +0 -12
  72. package/dist/hooks/provider/useNavigationPrefetch.js +0 -82
  73. package/dist/hooks/provider/usePageviewTracking.d.ts +0 -10
  74. package/dist/hooks/provider/usePageviewTracking.js +0 -44
  75. package/dist/hooks/provider/usePrehide.d.ts +0 -5
  76. package/dist/hooks/provider/usePrehide.js +0 -72
  77. package/dist/hooks/provider/useSitemapLinkTag.d.ts +0 -7
  78. package/dist/hooks/provider/useSitemapLinkTag.js +0 -28
  79. package/dist/hooks/provider/useStringMissReporting.d.ts +0 -14
  80. package/dist/hooks/provider/useStringMissReporting.js +0 -155
  81. package/dist/hooks/useAixster.d.ts +0 -6
  82. package/dist/hooks/useAixster.js +0 -14
  83. package/dist/hooks/useAixsterEdit.d.ts +0 -5
  84. package/dist/hooks/useAixsterEdit.js +0 -13
  85. package/dist/hooks/useAixsterTranslate.d.ts +0 -4
  86. package/dist/hooks/useAixsterTranslate.js +0 -12
  87. package/dist/hooks/useLang.d.ts +0 -16
  88. package/dist/hooks/useLang.js +0 -23
  89. package/dist/hooks/useLangNavigate.d.ts +0 -24
  90. package/dist/hooks/useLangNavigate.js +0 -40
  91. package/dist/hooks/useLovalingo.d.ts +0 -1
  92. package/dist/hooks/useLovalingo.js +0 -1
  93. package/dist/hooks/useLovalingoEdit.d.ts +0 -1
  94. package/dist/hooks/useLovalingoEdit.js +0 -1
  95. package/dist/hooks/useLovalingoTranslate.d.ts +0 -1
  96. package/dist/hooks/useLovalingoTranslate.js +0 -1
  97. package/dist/types.d.ts +0 -76
  98. package/dist/types.js +0 -1
  99. package/dist/utils/api.d.ts +0 -42
  100. package/dist/utils/api.js +0 -395
  101. package/dist/utils/apiTypes.d.ts +0 -78
  102. package/dist/utils/apiTypes.js +0 -1
  103. package/dist/utils/apiUtils.d.ts +0 -4
  104. package/dist/utils/apiUtils.js +0 -54
  105. package/dist/utils/domRules.d.ts +0 -2
  106. package/dist/utils/domRules.js +0 -150
  107. package/dist/utils/hash.d.ts +0 -9
  108. package/dist/utils/hash.js +0 -27
  109. package/dist/utils/languageFlags.d.ts +0 -7
  110. package/dist/utils/languageFlags.js +0 -90
  111. package/dist/utils/logger.d.ts +0 -3
  112. package/dist/utils/logger.js +0 -40
  113. package/dist/utils/markerEngine.d.ts +0 -12
  114. package/dist/utils/markerEngine.js +0 -109
  115. package/dist/utils/markerEngineApply.d.ts +0 -3
  116. package/dist/utils/markerEngineApply.js +0 -136
  117. package/dist/utils/markerEngineConstants.d.ts +0 -10
  118. package/dist/utils/markerEngineConstants.js +0 -12
  119. package/dist/utils/markerEngineCritical.d.ts +0 -2
  120. package/dist/utils/markerEngineCritical.js +0 -98
  121. package/dist/utils/markerEngineDomUtils.d.ts +0 -8
  122. package/dist/utils/markerEngineDomUtils.js +0 -74
  123. package/dist/utils/markerEngineFilters.d.ts +0 -2
  124. package/dist/utils/markerEngineFilters.js +0 -26
  125. package/dist/utils/markerEngineMisses.d.ts +0 -5
  126. package/dist/utils/markerEngineMisses.js +0 -81
  127. package/dist/utils/markerEngineOriginals.d.ts +0 -5
  128. package/dist/utils/markerEngineOriginals.js +0 -29
  129. package/dist/utils/markerEngineScan.d.ts +0 -5
  130. package/dist/utils/markerEngineScan.js +0 -162
  131. package/dist/utils/markerEngineState.d.ts +0 -4
  132. package/dist/utils/markerEngineState.js +0 -14
  133. package/dist/utils/markerEngineStats.d.ts +0 -3
  134. package/dist/utils/markerEngineStats.js +0 -28
  135. package/dist/utils/markerEngineTranslations.d.ts +0 -3
  136. package/dist/utils/markerEngineTranslations.js +0 -49
  137. package/dist/utils/markerEngineTypes.d.ts +0 -62
  138. package/dist/utils/markerEngineTypes.js +0 -1
  139. package/dist/utils/markerEngineViewport.d.ts +0 -2
  140. package/dist/utils/markerEngineViewport.js +0 -27
  141. package/dist/utils/mergeEntitlements.d.ts +0 -2
  142. package/dist/utils/mergeEntitlements.js +0 -7
  143. package/dist/utils/nonLocalizedPaths.d.ts +0 -12
  144. package/dist/utils/nonLocalizedPaths.js +0 -136
  145. package/dist/utils/pathNormalizer.d.ts +0 -49
  146. package/dist/utils/pathNormalizer.js +0 -115
  147. package/dist/version.d.ts +0 -1
  148. package/dist/version.js +0 -1
@@ -1,118 +0,0 @@
1
- export function applySeoBundle(bundle, hreflangEnabled) {
2
- try {
3
- const head = document.head;
4
- if (!head)
5
- return;
6
- if (!bundle)
7
- return;
8
- const seo = (bundle?.seo && typeof bundle.seo === 'object' ? bundle.seo : {});
9
- const alternates = (bundle?.alternates && typeof bundle.alternates === 'object' ? bundle.alternates : {});
10
- const setOrCreateMeta = (attrs, content) => {
11
- const key = attrs.name ? `meta[name="${attrs.name}"]` : attrs.property ? `meta[property="${attrs.property}"]` : '';
12
- const selector = key || 'meta';
13
- const existing = selector ? head.querySelector(selector) : null;
14
- const el = existing || document.createElement('meta');
15
- for (const [k, v] of Object.entries(attrs)) {
16
- el.setAttribute(k, v);
17
- }
18
- el.setAttribute('content', content);
19
- if (!existing)
20
- head.appendChild(el);
21
- };
22
- const setOrCreateTitle = (value) => {
23
- const existing = head.querySelector('title');
24
- if (existing) {
25
- existing.textContent = value;
26
- return;
27
- }
28
- const el = document.createElement('title');
29
- el.textContent = value;
30
- head.appendChild(el);
31
- };
32
- const getString = (value) => (typeof value === 'string' && value.trim() ? value.trim() : '');
33
- const title = getString(seo.title);
34
- if (title)
35
- setOrCreateTitle(title);
36
- const description = getString(seo.description);
37
- if (description)
38
- setOrCreateMeta({ name: 'description' }, description);
39
- const robots = getString(seo.robots);
40
- if (robots)
41
- setOrCreateMeta({ name: 'robots' }, robots);
42
- const ogTitle = getString(seo.og_title);
43
- if (ogTitle)
44
- setOrCreateMeta({ property: 'og:title' }, ogTitle);
45
- const ogDescription = getString(seo.og_description);
46
- if (ogDescription)
47
- setOrCreateMeta({ property: 'og:description' }, ogDescription);
48
- const ogImage = getString(seo.og_image);
49
- if (ogImage)
50
- setOrCreateMeta({ property: 'og:image' }, ogImage);
51
- const ogImageAlt = getString(seo.og_image_alt);
52
- if (ogImageAlt)
53
- setOrCreateMeta({ property: 'og:image:alt' }, ogImageAlt);
54
- const twitterCard = getString(seo.twitter_card);
55
- if (twitterCard)
56
- setOrCreateMeta({ name: 'twitter:card' }, twitterCard);
57
- const twitterTitle = getString(seo.twitter_title);
58
- if (twitterTitle)
59
- setOrCreateMeta({ name: 'twitter:title' }, twitterTitle);
60
- const twitterDescription = getString(seo.twitter_description);
61
- if (twitterDescription)
62
- setOrCreateMeta({ name: 'twitter:description' }, twitterDescription);
63
- const twitterImage = getString(seo.twitter_image);
64
- if (twitterImage)
65
- setOrCreateMeta({ name: 'twitter:image' }, twitterImage);
66
- const twitterImageAlt = getString(seo.twitter_image_alt);
67
- if (twitterImageAlt)
68
- setOrCreateMeta({ name: 'twitter:image:alt' }, twitterImageAlt);
69
- const canonicalHref = resolveCanonicalHref(seo, alternates);
70
- const languages = alternates.languages && typeof alternates.languages === 'object' ? alternates.languages : {};
71
- const hasAnyAlternate = Boolean(alternates.xDefault) || Object.values(languages).some(Boolean);
72
- if (!canonicalHref && !(hreflangEnabled && hasAnyAlternate))
73
- return;
74
- // Why: search engines may ignore hreflang/canonical when multiple conflicting tags exist (we want sitemap + head parity).
75
- head
76
- .querySelectorAll('link[rel="canonical"], link[rel="alternate"][hreflang], link[data-Lovalingo="hreflang"], link[data-Lovalingo="canonical"]')
77
- .forEach((el) => el.remove());
78
- if (canonicalHref) {
79
- const canonical = document.createElement('link');
80
- canonical.rel = 'canonical';
81
- canonical.href = canonicalHref;
82
- canonical.setAttribute('data-Lovalingo', 'canonical');
83
- head.appendChild(canonical);
84
- }
85
- if (!hreflangEnabled)
86
- return;
87
- for (const [lang, href] of Object.entries(languages)) {
88
- if (!href)
89
- continue;
90
- const link = document.createElement('link');
91
- link.rel = 'alternate';
92
- link.hreflang = lang;
93
- link.href = href;
94
- link.setAttribute('data-Lovalingo', 'hreflang');
95
- head.appendChild(link);
96
- }
97
- if (alternates.xDefault) {
98
- const xDefault = document.createElement('link');
99
- xDefault.rel = 'alternate';
100
- xDefault.hreflang = 'x-default';
101
- xDefault.href = alternates.xDefault;
102
- xDefault.setAttribute('data-Lovalingo', 'hreflang');
103
- head.appendChild(xDefault);
104
- }
105
- }
106
- catch {
107
- // ignore SEO errors
108
- }
109
- }
110
- export function resolveCanonicalHref(seo, alternates) {
111
- const alt = alternates && typeof alternates === "object" ? alternates : null;
112
- // Why: when alternates exist, canonical must be self-referencing for the active locale.
113
- if (alt && typeof alt.canonical === "string" && alt.canonical.trim())
114
- return alt.canonical.trim();
115
- if (typeof seo?.canonical_url === "string" && seo.canonical_url.trim())
116
- return seo.canonical_url.trim();
117
- return "";
118
- }
@@ -1,7 +0,0 @@
1
- type UseEditModeOverlayArgs = {
2
- editMode: boolean;
3
- excludeElement: (selector: string) => Promise<void>;
4
- setEditMode: React.Dispatch<React.SetStateAction<boolean>>;
5
- };
6
- export declare function useEditModeOverlay({ editMode, excludeElement, setEditMode }: UseEditModeOverlayArgs): void;
7
- export {};
@@ -1,134 +0,0 @@
1
- import { useEffect, useRef } from 'react';
2
- import { buildCssSelector } from './editModeUtils';
3
- import { EDIT_HINT_ID, EDIT_HIGHLIGHT_ID, EDIT_UI_ATTR } from './providerConstants';
4
- export function useEditModeOverlay({ editMode, excludeElement, setEditMode }) {
5
- const editSavingRef = useRef(false);
6
- useEffect(() => {
7
- if (typeof window === 'undefined')
8
- return;
9
- const existingHighlight = document.getElementById(EDIT_HIGHLIGHT_ID);
10
- const existingHint = document.getElementById(EDIT_HINT_ID);
11
- if (!editMode) {
12
- existingHighlight?.remove();
13
- existingHint?.remove();
14
- return;
15
- }
16
- const highlight = existingHighlight ||
17
- (() => {
18
- const node = document.createElement('div');
19
- node.id = EDIT_HIGHLIGHT_ID;
20
- node.setAttribute(EDIT_UI_ATTR, 'true');
21
- node.setAttribute('data-lovalingo-exclude', 'true');
22
- node.style.position = 'fixed';
23
- node.style.pointerEvents = 'none';
24
- node.style.zIndex = '2147483646';
25
- node.style.border = '2px solid #22c55e';
26
- node.style.background = 'rgba(34, 197, 94, 0.12)';
27
- node.style.borderRadius = '8px';
28
- node.style.boxSizing = 'border-box';
29
- node.style.transition = 'transform 80ms ease, width 80ms ease, height 80ms ease';
30
- node.style.display = 'none';
31
- document.body.appendChild(node);
32
- return node;
33
- })();
34
- const hint = existingHint ||
35
- (() => {
36
- const node = document.createElement('div');
37
- node.id = EDIT_HINT_ID;
38
- node.setAttribute(EDIT_UI_ATTR, 'true');
39
- node.setAttribute('data-lovalingo-exclude', 'true');
40
- node.style.position = 'fixed';
41
- node.style.left = '12px';
42
- node.style.bottom = '12px';
43
- node.style.zIndex = '2147483647';
44
- node.style.background = 'rgba(10, 10, 10, 0.85)';
45
- node.style.color = '#ffffff';
46
- node.style.fontSize = '12px';
47
- node.style.lineHeight = '1.4';
48
- node.style.padding = '8px 10px';
49
- node.style.borderRadius = '8px';
50
- node.style.border = '1px solid rgba(255, 255, 255, 0.15)';
51
- node.style.pointerEvents = 'none';
52
- node.style.maxWidth = '280px';
53
- node.textContent = 'Edit Mode: click an element to exclude. Press Esc to exit.';
54
- document.body.appendChild(node);
55
- return node;
56
- })();
57
- let rafId = null;
58
- let pendingTarget = null;
59
- const previousCursor = document.body.style.cursor;
60
- document.body.style.cursor = 'crosshair';
61
- const updateHighlight = () => {
62
- rafId = null;
63
- if (!pendingTarget) {
64
- highlight.style.display = 'none';
65
- return;
66
- }
67
- const rect = pendingTarget.getBoundingClientRect();
68
- if (rect.width <= 0 || rect.height <= 0) {
69
- highlight.style.display = 'none';
70
- return;
71
- }
72
- highlight.style.display = 'block';
73
- highlight.style.width = `${rect.width}px`;
74
- highlight.style.height = `${rect.height}px`;
75
- highlight.style.transform = `translate(${rect.left}px, ${rect.top}px)`;
76
- };
77
- const onMove = (event) => {
78
- const rawTarget = event.target;
79
- const target = rawTarget instanceof HTMLElement ? rawTarget : rawTarget instanceof Node ? rawTarget.parentElement : null;
80
- if (!target || target.closest(`[${EDIT_UI_ATTR}="true"]`)) {
81
- pendingTarget = null;
82
- }
83
- else if (target === document.body || target === document.documentElement) {
84
- pendingTarget = null;
85
- }
86
- else {
87
- pendingTarget = target;
88
- }
89
- if (rafId !== null)
90
- return;
91
- rafId = window.requestAnimationFrame(updateHighlight);
92
- };
93
- const onClick = async (event) => {
94
- const rawTarget = event.target;
95
- const target = rawTarget instanceof HTMLElement ? rawTarget : rawTarget instanceof Node ? rawTarget.parentElement : null;
96
- if (!target || target.closest(`[${EDIT_UI_ATTR}="true"]`))
97
- return;
98
- event.preventDefault();
99
- event.stopPropagation();
100
- event.stopImmediatePropagation();
101
- const selector = buildCssSelector(target);
102
- if (!selector)
103
- return;
104
- if (editSavingRef.current)
105
- return;
106
- editSavingRef.current = true;
107
- try {
108
- await excludeElement(selector);
109
- }
110
- finally {
111
- editSavingRef.current = false;
112
- }
113
- };
114
- const onKeyDown = (event) => {
115
- if (event.key === 'Escape') {
116
- event.preventDefault();
117
- setEditMode(false);
118
- }
119
- };
120
- document.addEventListener('mousemove', onMove, true);
121
- document.addEventListener('click', onClick, true);
122
- document.addEventListener('keydown', onKeyDown, true);
123
- return () => {
124
- document.removeEventListener('mousemove', onMove, true);
125
- document.removeEventListener('click', onClick, true);
126
- document.removeEventListener('keydown', onKeyDown, true);
127
- if (rafId !== null)
128
- window.cancelAnimationFrame(rafId);
129
- highlight.remove();
130
- hint.remove();
131
- document.body.style.cursor = previousCursor;
132
- };
133
- }, [editMode, excludeElement, setEditMode]);
134
- }
@@ -1,3 +0,0 @@
1
- type OnNavigateRef = React.MutableRefObject<() => void>;
2
- export declare function useHistoryNavigationPatch(onNavigateRef: OnNavigateRef): void;
3
- export {};
@@ -1,47 +0,0 @@
1
- import { useEffect, useRef } from 'react';
2
- export function useHistoryNavigationPatch(onNavigateRef) {
3
- const historyPatchedRef = useRef(false);
4
- const originalHistoryRef = useRef(null);
5
- useEffect(() => {
6
- if (typeof window === 'undefined')
7
- return;
8
- if (historyPatchedRef.current)
9
- return;
10
- historyPatchedRef.current = true;
11
- const historyObj = window.history;
12
- const originalPushState = historyObj.pushState.bind(historyObj);
13
- const originalReplaceState = historyObj.replaceState.bind(historyObj);
14
- originalHistoryRef.current = { pushState: originalPushState, replaceState: originalReplaceState };
15
- const safeOnNavigate = () => {
16
- try {
17
- onNavigateRef.current();
18
- }
19
- catch {
20
- // ignore
21
- }
22
- };
23
- historyObj.pushState = ((...args) => {
24
- const ret = originalPushState(...args);
25
- safeOnNavigate();
26
- return ret;
27
- });
28
- historyObj.replaceState = ((...args) => {
29
- const ret = originalReplaceState(...args);
30
- safeOnNavigate();
31
- return ret;
32
- });
33
- window.addEventListener('popstate', safeOnNavigate);
34
- window.addEventListener('hashchange', safeOnNavigate);
35
- return () => {
36
- const originals = originalHistoryRef.current;
37
- if (originals) {
38
- historyObj.pushState = originals.pushState;
39
- historyObj.replaceState = originals.replaceState;
40
- }
41
- window.removeEventListener('popstate', safeOnNavigate);
42
- window.removeEventListener('hashchange', safeOnNavigate);
43
- originalHistoryRef.current = null;
44
- historyPatchedRef.current = false;
45
- };
46
- }, [onNavigateRef]);
47
- }
@@ -1,12 +0,0 @@
1
- type UseProviderCacheArgs = {
2
- overlayBgColor?: string | null;
3
- resolvedApiKey: string;
4
- };
5
- export declare function useProviderCache({ overlayBgColor, resolvedApiKey }: UseProviderCacheArgs): {
6
- readonly brandingEnabled: boolean;
7
- readonly setBrandingEnabled: import("react").Dispatch<import("react").SetStateAction<boolean>>;
8
- readonly setCachedBrandingEnabled: (enabled: boolean | null | undefined) => void;
9
- readonly getCachedLoadingBgColor: () => string;
10
- readonly setCachedLoadingBgColor: (color: string | null | undefined) => void;
11
- };
12
- export {};
@@ -1,82 +0,0 @@
1
- import { useCallback, useEffect, useState } from 'react';
2
- import { BRANDING_STORAGE_PREFIX, LOADING_BG_STORAGE_PREFIX } from './providerConstants';
3
- export function useProviderCache({ overlayBgColor, resolvedApiKey }) {
4
- const loadingBgStorageKey = `${LOADING_BG_STORAGE_PREFIX}:${resolvedApiKey || 'anonymous'}`;
5
- const brandingStorageKey = `${BRANDING_STORAGE_PREFIX}:${resolvedApiKey || 'anonymous'}`;
6
- const readBrandingCache = useCallback(() => {
7
- try {
8
- const cached = (localStorage.getItem(brandingStorageKey) || '').trim();
9
- if (cached === '0')
10
- return false;
11
- if (cached === '1')
12
- return true;
13
- }
14
- catch {
15
- // ignore
16
- }
17
- return true;
18
- }, [brandingStorageKey]);
19
- const [brandingEnabled, setBrandingEnabled] = useState(readBrandingCache);
20
- const getCachedLoadingBgColor = useCallback(() => {
21
- const configured = (overlayBgColor || '').toString().trim();
22
- if (/^#[0-9a-fA-F]{6}$/.test(configured))
23
- return configured;
24
- try {
25
- const cached = localStorage.getItem(loadingBgStorageKey) || '';
26
- if (/^#[0-9a-fA-F]{6}$/.test(cached.trim()))
27
- return cached.trim();
28
- }
29
- catch {
30
- // ignore
31
- }
32
- // Why: default to the site's existing background to reduce a visible white flash on non-white themes.
33
- try {
34
- const bodyBg = window.getComputedStyle(document.body).backgroundColor;
35
- if (bodyBg && bodyBg !== 'transparent' && bodyBg !== 'rgba(0, 0, 0, 0)')
36
- return bodyBg;
37
- const htmlBg = window.getComputedStyle(document.documentElement).backgroundColor;
38
- if (htmlBg && htmlBg !== 'transparent' && htmlBg !== 'rgba(0, 0, 0, 0)')
39
- return htmlBg;
40
- }
41
- catch {
42
- // ignore
43
- }
44
- return '#ffffff';
45
- }, [loadingBgStorageKey, overlayBgColor]);
46
- const setCachedLoadingBgColor = useCallback((color) => {
47
- const next = (color || '').toString().trim();
48
- if (!/^#[0-9a-fA-F]{6}$/.test(next))
49
- return;
50
- try {
51
- localStorage.setItem(loadingBgStorageKey, next);
52
- }
53
- catch {
54
- // ignore
55
- }
56
- }, [loadingBgStorageKey]);
57
- useEffect(() => {
58
- // Why: make `overlayBgColor` the source of truth while keeping the existing cache key for backwards compatibility.
59
- const configured = (overlayBgColor || '').toString().trim();
60
- if (!/^#[0-9a-fA-F]{6}$/.test(configured))
61
- return;
62
- setCachedLoadingBgColor(configured);
63
- }, [overlayBgColor, setCachedLoadingBgColor]);
64
- const setCachedBrandingEnabled = useCallback((enabled) => {
65
- try {
66
- localStorage.setItem(brandingStorageKey, enabled === false ? '0' : '1');
67
- }
68
- catch {
69
- // ignore
70
- }
71
- }, [brandingStorageKey]);
72
- useEffect(() => {
73
- setBrandingEnabled(readBrandingCache());
74
- }, [readBrandingCache]);
75
- return {
76
- brandingEnabled,
77
- setBrandingEnabled,
78
- setCachedBrandingEnabled,
79
- getCachedLoadingBgColor,
80
- setCachedLoadingBgColor,
81
- };
82
- }
@@ -1,3 +0,0 @@
1
- import React from 'react';
2
- import { LovalingoContextValue } from '../types';
3
- export declare const LovalingoContext: React.Context<LovalingoContextValue | null>;
@@ -1,2 +0,0 @@
1
- import { createContext } from 'react';
2
- export const LovalingoContext = createContext(null);
@@ -1 +0,0 @@
1
- export declare const LangContext: import("react").Context<string | null>;
@@ -1,2 +0,0 @@
1
- import { createContext } from "react";
2
- export const LangContext = createContext(null);
@@ -1,8 +0,0 @@
1
- import type { NonLocalizedPathRule } from "../utils/nonLocalizedPaths";
2
- export type LangRoutingContextValue = {
3
- defaultLang: string;
4
- nonLocalizedPaths: NonLocalizedPathRule[];
5
- inactivePages: string[];
6
- status: "unknown" | "loading" | "ready" | "error";
7
- };
8
- export declare const LangRoutingContext: import("react").Context<LangRoutingContextValue>;
@@ -1,7 +0,0 @@
1
- import { createContext } from "react";
2
- export const LangRoutingContext = createContext({
3
- defaultLang: "",
4
- nonLocalizedPaths: [],
5
- inactivePages: [],
6
- status: "unknown",
7
- });
@@ -1 +0,0 @@
1
- export { LovalingoContext } from "./AixsterContext";
@@ -1 +0,0 @@
1
- export { LovalingoContext } from "./AixsterContext";
@@ -1,33 +0,0 @@
1
- import type React from "react";
2
- import type { LovalingoAPI, ProjectEntitlements } from "../../utils/api";
3
- import type { NonLocalizedPathRule } from "../../utils/nonLocalizedPaths";
4
- import type { PathNormalizationConfig } from "../../utils/pathNormalizer";
5
- type UseBundleLoadingOptions = {
6
- apiRef: React.MutableRefObject<LovalingoAPI>;
7
- resolvedApiKey: string;
8
- defaultLocale: string;
9
- routing: "path" | "query";
10
- allLocales: string[];
11
- nonLocalizedPaths: NonLocalizedPathRule[];
12
- enhancedPathConfig: PathNormalizationConfig;
13
- mode: "dom" | undefined;
14
- autoApplyRules: boolean;
15
- seoProp: boolean;
16
- isSeoActive: () => boolean;
17
- applySeoBundle: (bundle: {
18
- seo?: Record<string, unknown>;
19
- alternates?: any;
20
- jsonld?: any;
21
- } | null, hreflangEnabled: boolean) => void;
22
- setEntitlements: React.Dispatch<React.SetStateAction<ProjectEntitlements | null>>;
23
- setBrandingEnabled: React.Dispatch<React.SetStateAction<boolean>>;
24
- setCachedBrandingEnabled: (enabled: boolean | null | undefined) => void;
25
- setCachedLoadingBgColor: (color: string | null | undefined) => void;
26
- getCachedLoadingBgColor: () => string;
27
- };
28
- export declare function useBundleLoading({ apiRef, resolvedApiKey, defaultLocale, routing, allLocales, nonLocalizedPaths, enhancedPathConfig, mode, autoApplyRules, seoProp, isSeoActive, applySeoBundle, setEntitlements, setBrandingEnabled, setCachedBrandingEnabled, setCachedLoadingBgColor, getCachedLoadingBgColor, }: UseBundleLoadingOptions): {
29
- isLoading: boolean;
30
- isNavigatingRef: React.MutableRefObject<boolean>;
31
- loadData: (targetLocale: string, previousLocale?: string) => Promise<void>;
32
- };
33
- export {};