@lookalike/widget 1.1.0 โ 1.2.1
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/dist/README.md +2 -2
- package/dist/lookalike-widget.js +262 -21
- package/dist/lookalike-widget.min.js +1 -1
- package/package.json +1 -1
package/dist/README.md
CHANGED
package/dist/lookalike-widget.js
CHANGED
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
// Lookalike Widget - Standalone Embed Version
|
|
9
9
|
// Self-contained widget for copy/paste embedding (no Wix dependencies)
|
|
10
10
|
// Uses shadow DOM for complete encapsulation
|
|
11
|
+
// Version 1.2.0 - Debug Enhanced
|
|
11
12
|
|
|
13
|
+
const WIDGET_VERSION = '1.2.0';
|
|
12
14
|
const DEFAULT_UUID = '019b4c51-7701-726a-8f59-e89a854682f3';
|
|
13
15
|
|
|
16
|
+
console.log(`๐ Lookalike Widget v${WIDGET_VERSION} loading...`);
|
|
17
|
+
|
|
14
18
|
function getBaseUrl() {
|
|
15
19
|
const hostname = window.location.hostname;
|
|
16
20
|
if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
|
@@ -36,10 +40,22 @@ class LookalikeWidget extends HTMLElement {
|
|
|
36
40
|
this.currentIframe = null;
|
|
37
41
|
this.shadow = null;
|
|
38
42
|
this.messageHandler = null;
|
|
43
|
+
this.isInWixEmbed = false;
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
connectedCallback() {
|
|
42
|
-
console.log(
|
|
47
|
+
console.log(`๐ Lookalike Widget v${WIDGET_VERSION} initializing...`);
|
|
48
|
+
console.log('๐ Environment Info:', {
|
|
49
|
+
hostname: window.location.hostname,
|
|
50
|
+
href: window.location.href,
|
|
51
|
+
referrer: document.referrer,
|
|
52
|
+
userAgent: navigator.userAgent,
|
|
53
|
+
viewport: `${window.innerWidth}x${window.innerHeight}`,
|
|
54
|
+
inIframe: window !== window.parent
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Detect if we're in a Wix custom code embed (or similar constrained iframe)
|
|
58
|
+
this.detectWixEmbed();
|
|
43
59
|
|
|
44
60
|
// Create shadow DOM for encapsulation
|
|
45
61
|
this.shadow = this.attachShadow({ mode: 'closed' });
|
|
@@ -51,6 +67,53 @@ class LookalikeWidget extends HTMLElement {
|
|
|
51
67
|
this.initLive();
|
|
52
68
|
}
|
|
53
69
|
|
|
70
|
+
detectWixEmbed() {
|
|
71
|
+
console.log('๐ Starting Wix embed detection...');
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
// Check if we're in an iframe and can't access parent
|
|
75
|
+
const inIframe = window !== window.parent;
|
|
76
|
+
console.log('๐ฑ In iframe:', inIframe);
|
|
77
|
+
|
|
78
|
+
// Check for Wix-specific indicators
|
|
79
|
+
const wixHostname = window.location.hostname.includes('wix.com') || window.location.hostname.includes('wixsite.com');
|
|
80
|
+
const wixSearch = window.location.search.includes('wix');
|
|
81
|
+
const wixReferrer = document.referrer.includes('wix');
|
|
82
|
+
const smallDimensions = window.innerWidth < 500 || window.innerHeight < 300;
|
|
83
|
+
|
|
84
|
+
console.log('๐ Wix Detection Results:', {
|
|
85
|
+
inIframe,
|
|
86
|
+
wixHostname,
|
|
87
|
+
wixSearch,
|
|
88
|
+
wixReferrer,
|
|
89
|
+
smallDimensions,
|
|
90
|
+
windowSize: `${window.innerWidth}x${window.innerHeight}`
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const hasWixIndicators = wixHostname || wixSearch || wixReferrer || (inIframe && smallDimensions);
|
|
94
|
+
|
|
95
|
+
this.isInWixEmbed = inIframe && hasWixIndicators;
|
|
96
|
+
|
|
97
|
+
if (this.isInWixEmbed) {
|
|
98
|
+
console.log('โ
Wix embed environment DETECTED - using full-screen overlay mode');
|
|
99
|
+
} else {
|
|
100
|
+
console.log('โ Standard environment detected - using normal positioning');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Force Wix mode for testing if URL contains debug parameter
|
|
104
|
+
if (window.location.search.includes('force-wix-mode')) {
|
|
105
|
+
console.log('๐งช FORCE WIX MODE activated via URL parameter');
|
|
106
|
+
this.isInWixEmbed = true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
} catch (error) {
|
|
110
|
+
// If we can't access parent due to cross-origin, assume we're in an embed
|
|
111
|
+
console.log('โ ๏ธ Cross-origin iframe error:', error.message);
|
|
112
|
+
this.isInWixEmbed = true;
|
|
113
|
+
console.log('๐ Cross-origin iframe detected - using full-screen overlay mode');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
54
117
|
loadConfiguration() {
|
|
55
118
|
// Read configuration from HTML attributes
|
|
56
119
|
if (this.hasAttribute('uuid')) {
|
|
@@ -117,7 +180,53 @@ class LookalikeWidget extends HTMLElement {
|
|
|
117
180
|
initLive() {
|
|
118
181
|
console.log('๐ Initializing live widget with config:', this.config);
|
|
119
182
|
|
|
120
|
-
|
|
183
|
+
if (this.isInWixEmbed) {
|
|
184
|
+
this.initWixEmbedMode();
|
|
185
|
+
} else {
|
|
186
|
+
this.initStandardMode();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
this.injectShadowContent();
|
|
190
|
+
this.injectIframe();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
initWixEmbedMode() {
|
|
194
|
+
console.log('๐ฑ Initializing Wix embed mode with full-screen overlay');
|
|
195
|
+
|
|
196
|
+
// Make the host element a full-screen transparent overlay
|
|
197
|
+
const overlayStyles = `
|
|
198
|
+
position: fixed;
|
|
199
|
+
top: 0;
|
|
200
|
+
left: 0;
|
|
201
|
+
width: 100vw;
|
|
202
|
+
height: 100vh;
|
|
203
|
+
border: 0;
|
|
204
|
+
z-index: 9999;
|
|
205
|
+
background: transparent;
|
|
206
|
+
pointer-events: none;
|
|
207
|
+
display: block;
|
|
208
|
+
`;
|
|
209
|
+
|
|
210
|
+
this.style.cssText = overlayStyles;
|
|
211
|
+
|
|
212
|
+
console.log('๐จ Applied overlay styles:', overlayStyles);
|
|
213
|
+
console.log('๐ Host element computed styles:', {
|
|
214
|
+
position: getComputedStyle(this).position,
|
|
215
|
+
width: getComputedStyle(this).width,
|
|
216
|
+
height: getComputedStyle(this).height,
|
|
217
|
+
zIndex: getComputedStyle(this).zIndex,
|
|
218
|
+
pointerEvents: getComputedStyle(this).pointerEvents
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Add collapsed class initially
|
|
222
|
+
this.className = 'collapsed wix-embed';
|
|
223
|
+
console.log('๐ท๏ธ Applied classes:', this.className);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
initStandardMode() {
|
|
227
|
+
console.log('๐ป Initializing standard mode');
|
|
228
|
+
|
|
229
|
+
// Set host element positioning and initial size (original behavior)
|
|
121
230
|
this.style.cssText = `
|
|
122
231
|
position: fixed;
|
|
123
232
|
bottom: 16px;
|
|
@@ -136,9 +245,6 @@ class LookalikeWidget extends HTMLElement {
|
|
|
136
245
|
|
|
137
246
|
// Add collapsed class initially
|
|
138
247
|
this.className = 'collapsed';
|
|
139
|
-
|
|
140
|
-
this.injectShadowContent();
|
|
141
|
-
this.injectIframe();
|
|
142
248
|
}
|
|
143
249
|
|
|
144
250
|
injectShadowContent() {
|
|
@@ -151,18 +257,60 @@ class LookalikeWidget extends HTMLElement {
|
|
|
151
257
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
152
258
|
}
|
|
153
259
|
|
|
154
|
-
|
|
260
|
+
/* Standard mode styles */
|
|
261
|
+
:host(.collapsed:not(.wix-embed)) {
|
|
155
262
|
height: 60px !important;
|
|
156
263
|
max-height: 60px !important;
|
|
157
264
|
}
|
|
158
265
|
|
|
159
|
-
:host(.expanded) {
|
|
266
|
+
:host(.expanded:not(.wix-embed)) {
|
|
267
|
+
height: 520px;
|
|
268
|
+
max-height: calc(100vh - 32px);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/* Wix embed mode: container for positioned widget */
|
|
272
|
+
.wix-widget-container {
|
|
273
|
+
position: absolute;
|
|
274
|
+
bottom: 16px;
|
|
275
|
+
right: 16px;
|
|
276
|
+
width: 380px;
|
|
277
|
+
height: 60px;
|
|
278
|
+
max-width: calc(100vw - 32px);
|
|
279
|
+
border-radius: 16px;
|
|
280
|
+
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
|
|
281
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
282
|
+
background: transparent;
|
|
283
|
+
pointer-events: auto;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* Debug info overlay */
|
|
287
|
+
.debug-info {
|
|
288
|
+
position: absolute;
|
|
289
|
+
top: 10px;
|
|
290
|
+
left: 10px;
|
|
291
|
+
background: rgba(0, 0, 0, 0.8);
|
|
292
|
+
color: white;
|
|
293
|
+
padding: 8px;
|
|
294
|
+
border-radius: 4px;
|
|
295
|
+
font-size: 11px;
|
|
296
|
+
font-family: monospace;
|
|
297
|
+
z-index: 10000;
|
|
298
|
+
max-width: 300px;
|
|
299
|
+
pointer-events: none;
|
|
300
|
+
white-space: pre-line;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
:host(.wix-embed.collapsed) .wix-widget-container {
|
|
304
|
+
height: 60px;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
:host(.wix-embed.expanded) .wix-widget-container {
|
|
160
308
|
height: 520px;
|
|
161
309
|
max-height: calc(100vh - 32px);
|
|
162
310
|
}
|
|
163
311
|
|
|
164
312
|
@media (max-width: 639px) {
|
|
165
|
-
:host(.expanded) {
|
|
313
|
+
:host(.expanded:not(.wix-embed)) {
|
|
166
314
|
width: 100vw;
|
|
167
315
|
height: 100vh;
|
|
168
316
|
max-width: none;
|
|
@@ -173,13 +321,13 @@ class LookalikeWidget extends HTMLElement {
|
|
|
173
321
|
box-shadow: none;
|
|
174
322
|
}
|
|
175
323
|
|
|
176
|
-
:host {
|
|
324
|
+
:host(:not(.wix-embed)) {
|
|
177
325
|
width: calc(100vw - 16px);
|
|
178
326
|
right: 8px;
|
|
179
327
|
bottom: 8px;
|
|
180
328
|
}
|
|
181
329
|
|
|
182
|
-
:host(.collapsed) {
|
|
330
|
+
:host(.collapsed:not(.wix-embed)) {
|
|
183
331
|
height: 60px !important;
|
|
184
332
|
max-height: 60px !important;
|
|
185
333
|
width: calc(100vw - 16px);
|
|
@@ -188,6 +336,33 @@ class LookalikeWidget extends HTMLElement {
|
|
|
188
336
|
border-radius: 16px;
|
|
189
337
|
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
|
|
190
338
|
}
|
|
339
|
+
|
|
340
|
+
/* Wix embed mobile styles */
|
|
341
|
+
:host(.wix-embed.expanded) .wix-widget-container {
|
|
342
|
+
width: 100vw;
|
|
343
|
+
height: 100vh;
|
|
344
|
+
max-width: none;
|
|
345
|
+
max-height: none;
|
|
346
|
+
bottom: 0;
|
|
347
|
+
right: 0;
|
|
348
|
+
border-radius: 0;
|
|
349
|
+
box-shadow: none;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.wix-widget-container {
|
|
353
|
+
width: calc(100vw - 16px);
|
|
354
|
+
right: 8px;
|
|
355
|
+
bottom: 8px;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
:host(.wix-embed.collapsed) .wix-widget-container {
|
|
359
|
+
height: 60px !important;
|
|
360
|
+
width: calc(100vw - 16px);
|
|
361
|
+
right: 8px;
|
|
362
|
+
bottom: 8px;
|
|
363
|
+
border-radius: 16px;
|
|
364
|
+
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
|
|
365
|
+
}
|
|
191
366
|
}
|
|
192
367
|
|
|
193
368
|
.loading {
|
|
@@ -254,17 +429,46 @@ class LookalikeWidget extends HTMLElement {
|
|
|
254
429
|
|
|
255
430
|
this.shadow.appendChild(style);
|
|
256
431
|
|
|
432
|
+
// Add debug info if URL contains debug parameter
|
|
433
|
+
if (window.location.search.includes('debug') || window.location.search.includes('force-wix-mode')) {
|
|
434
|
+
this.addDebugInfo();
|
|
435
|
+
}
|
|
436
|
+
|
|
257
437
|
// Create container for iframe
|
|
258
438
|
const container = document.createElement('div');
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
439
|
+
|
|
440
|
+
if (this.isInWixEmbed) {
|
|
441
|
+
// In Wix embed mode, create a positioned container within the full-screen overlay
|
|
442
|
+
container.className = 'wix-widget-container';
|
|
443
|
+
} else {
|
|
444
|
+
// In standard mode, container fills the host element
|
|
445
|
+
container.style.cssText = `
|
|
446
|
+
width: 100%;
|
|
447
|
+
height: 100%;
|
|
448
|
+
border-radius: inherit;
|
|
449
|
+
`;
|
|
450
|
+
}
|
|
264
451
|
|
|
265
452
|
this.shadow.appendChild(container);
|
|
266
453
|
}
|
|
267
454
|
|
|
455
|
+
addDebugInfo() {
|
|
456
|
+
const debugDiv = document.createElement('div');
|
|
457
|
+
debugDiv.className = 'debug-info';
|
|
458
|
+
|
|
459
|
+
const info = `Lookalike Widget v${WIDGET_VERSION}
|
|
460
|
+
Mode: ${this.isInWixEmbed ? 'Wix Embed' : 'Standard'}
|
|
461
|
+
Viewport: ${window.innerWidth}x${window.innerHeight}
|
|
462
|
+
In iframe: ${window !== window.parent}
|
|
463
|
+
Hostname: ${window.location.hostname}
|
|
464
|
+
Classes: ${this.className}`;
|
|
465
|
+
|
|
466
|
+
debugDiv.textContent = info;
|
|
467
|
+
this.shadow.appendChild(debugDiv);
|
|
468
|
+
|
|
469
|
+
console.log('๐ Debug info added to widget');
|
|
470
|
+
}
|
|
471
|
+
|
|
268
472
|
buildIframeSrc() {
|
|
269
473
|
if (!this.config.storyfileUuid) {
|
|
270
474
|
console.error('โ No storyfile UUID configured');
|
|
@@ -296,11 +500,29 @@ class LookalikeWidget extends HTMLElement {
|
|
|
296
500
|
}
|
|
297
501
|
|
|
298
502
|
injectIframe() {
|
|
299
|
-
const
|
|
503
|
+
const containerSelector = this.isInWixEmbed ? '.wix-widget-container' : 'div:last-child';
|
|
504
|
+
const container = this.shadow.querySelector(containerSelector);
|
|
505
|
+
|
|
506
|
+
console.log('๐ผ๏ธ Injecting iframe into container:', containerSelector);
|
|
507
|
+
console.log('๐ฆ Container found:', !!container);
|
|
508
|
+
|
|
509
|
+
if (container) {
|
|
510
|
+
console.log('๐ Container rect:', container.getBoundingClientRect());
|
|
511
|
+
console.log('๐จ Container computed styles:', {
|
|
512
|
+
position: getComputedStyle(container).position,
|
|
513
|
+
width: getComputedStyle(container).width,
|
|
514
|
+
height: getComputedStyle(container).height,
|
|
515
|
+
bottom: getComputedStyle(container).bottom,
|
|
516
|
+
right: getComputedStyle(container).right
|
|
517
|
+
});
|
|
518
|
+
}
|
|
300
519
|
|
|
301
520
|
// Remove existing iframe if present
|
|
302
|
-
const existingIframe = container
|
|
303
|
-
if (existingIframe)
|
|
521
|
+
const existingIframe = container?.querySelector('iframe');
|
|
522
|
+
if (existingIframe) {
|
|
523
|
+
console.log('๐๏ธ Removing existing iframe');
|
|
524
|
+
existingIframe.remove();
|
|
525
|
+
}
|
|
304
526
|
|
|
305
527
|
const iframeSrc = this.buildIframeSrc();
|
|
306
528
|
if (!iframeSrc) {
|
|
@@ -308,6 +530,8 @@ class LookalikeWidget extends HTMLElement {
|
|
|
308
530
|
return;
|
|
309
531
|
}
|
|
310
532
|
|
|
533
|
+
console.log('๐ Creating iframe with src:', iframeSrc);
|
|
534
|
+
|
|
311
535
|
const iframe = document.createElement('iframe');
|
|
312
536
|
iframe.className = 'loading';
|
|
313
537
|
iframe.src = iframeSrc;
|
|
@@ -315,19 +539,22 @@ class LookalikeWidget extends HTMLElement {
|
|
|
315
539
|
iframe.loading = 'lazy';
|
|
316
540
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups allow-presentation');
|
|
317
541
|
|
|
318
|
-
iframe.onerror = () => {
|
|
319
|
-
console.error('โ Failed to load widget iframe');
|
|
542
|
+
iframe.onerror = (error) => {
|
|
543
|
+
console.error('โ Failed to load widget iframe:', error);
|
|
320
544
|
this.showLoadingError(container);
|
|
321
545
|
};
|
|
322
546
|
|
|
323
547
|
iframe.onload = () => {
|
|
324
548
|
console.log('โ
Iframe loaded successfully');
|
|
549
|
+
console.log('๐ Iframe rect after load:', iframe.getBoundingClientRect());
|
|
325
550
|
iframe.classList.remove('loading');
|
|
326
551
|
};
|
|
327
552
|
|
|
328
553
|
this.currentIframe = iframe;
|
|
329
554
|
this.setupMessageHandling(iframe);
|
|
330
555
|
container.appendChild(iframe);
|
|
556
|
+
|
|
557
|
+
console.log('๐ฏ Iframe injection complete');
|
|
331
558
|
}
|
|
332
559
|
|
|
333
560
|
setupMessageHandling(iframe) {
|
|
@@ -337,6 +564,8 @@ class LookalikeWidget extends HTMLElement {
|
|
|
337
564
|
}
|
|
338
565
|
|
|
339
566
|
this.messageHandler = (e) => {
|
|
567
|
+
console.log('๐จ Received message:', e.data, 'from:', e.origin);
|
|
568
|
+
|
|
340
569
|
if (e.source !== iframe.contentWindow) return;
|
|
341
570
|
|
|
342
571
|
if (e.data?.type === 'lookalike-widget-ready') {
|
|
@@ -348,7 +577,18 @@ class LookalikeWidget extends HTMLElement {
|
|
|
348
577
|
if (ev.data?.type === 'lookalike-widget-resize') {
|
|
349
578
|
const newClass = ev.data.collapsed ? 'collapsed' : 'expanded';
|
|
350
579
|
console.log(`๐ Widget resize: ${this.className} โ ${newClass}`);
|
|
351
|
-
|
|
580
|
+
console.log('๐ Before resize - Host element rect:', this.getBoundingClientRect());
|
|
581
|
+
|
|
582
|
+
this.className = this.isInWixEmbed ? `${newClass} wix-embed` : newClass;
|
|
583
|
+
|
|
584
|
+
// Log after resize
|
|
585
|
+
setTimeout(() => {
|
|
586
|
+
console.log('๐ After resize - Host element rect:', this.getBoundingClientRect());
|
|
587
|
+
const container = this.shadow.querySelector(this.isInWixEmbed ? '.wix-widget-container' : 'div:last-child');
|
|
588
|
+
if (container) {
|
|
589
|
+
console.log('๐ Widget container rect:', container.getBoundingClientRect());
|
|
590
|
+
}
|
|
591
|
+
}, 100);
|
|
352
592
|
}
|
|
353
593
|
};
|
|
354
594
|
|
|
@@ -361,6 +601,7 @@ class LookalikeWidget extends HTMLElement {
|
|
|
361
601
|
};
|
|
362
602
|
|
|
363
603
|
window.addEventListener('message', this.messageHandler);
|
|
604
|
+
console.log('๐ Message handler installed');
|
|
364
605
|
}
|
|
365
606
|
|
|
366
607
|
showConfigurationError(container) {
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* Copy/paste embed widget for conversational AI avatars
|
|
6
6
|
* Usage: <lookalike-widget uuid="your-uuid"></lookalike-widget>
|
|
7
7
|
*/
|
|
8
|
-
const DEFAULT_UUID="019b4c51-7701-726a-8f59-e89a854682f3";function getBaseUrl(){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e?(console.log("๐ Local development detected"),"http://localhost:3000"):(console.log("๐ Using production URL"),"https://lookalike.com")}const BASE_URL=getBaseUrl();class LookalikeWidget extends HTMLElement{constructor(){super(),this.config={storyfileUuid:null,primaryColor:"#2563eb",enableText:!0,enableVideo:!0,enableAudio:!0},this.currentIframe=null,this.shadow=null,this.messageHandler=null}connectedCallback(){console.log("๐ Lookalike Widget initializing..."),this.shadow=this.attachShadow({mode:"closed"}),this.loadConfiguration(),this.initLive()}loadConfiguration(){this.hasAttribute("uuid")&&(this.config.storyfileUuid=this.getAttribute("uuid")),this.hasAttribute("color")&&(this.config.primaryColor=this.getAttribute("color")),this.hasAttribute("text")&&(this.config.enableText="false"!==this.getAttribute("text")),this.hasAttribute("video")&&(this.config.enableVideo="false"!==this.getAttribute("video")),this.hasAttribute("audio")&&(this.config.enableAudio="false"!==this.getAttribute("audio")),this.config.storyfileUuid||(this.config.storyfileUuid=DEFAULT_UUID,console.log("๐ง Using default UUID:",DEFAULT_UUID)),console.log("๐ฅ Loaded config from attributes:",this.config)}static get observedAttributes(){return["uuid","color","text","video","audio"]}attributeChangedCallback(e,t,n){if(t!==n&&this.shadow){switch(console.log(`๐ Attribute changed: ${e} = ${n}`),e){case"uuid":this.config.storyfileUuid=n;break;case"color":this.config.primaryColor=n;break;case"text":this.config.enableText="false"!==n;break;case"video":this.config.enableVideo="false"!==n;break;case"audio":this.config.enableAudio="false"!==n}console.log("๐ Updated config after attribute change:",this.config),this.isConnected&&(this.shadow.innerHTML="",this.initLive())}}initLive(){console.log("๐ Initializing live widget with config:",this.config),this.style.cssText="\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 380px;\n height: 60px;\n max-width: calc(100vw - 32px);\n border: 0;\n border-radius: 16px;\n z-index: 9999;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n background: transparent;\n display: block;\n ",this.className="collapsed",this.injectShadowContent(),this.injectIframe()}injectShadowContent(){const e=document.createElement("style");e.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n :host {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n :host(.collapsed) {\n height: 60px !important;\n max-height: 60px !important;\n }\n\n :host(.expanded) {\n height: 520px;\n max-height: calc(100vh - 32px);\n }\n\n @media (max-width: 639px) {\n :host(.expanded) {\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n bottom: 0;\n right: 0;\n border-radius: 0;\n box-shadow: none;\n }\n \n :host {\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n }\n \n :host(.collapsed) {\n height: 60px !important;\n max-height: 60px !important;\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n }\n }\n \n .loading {\n background: #f3f4f6;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n border-radius: inherit;\n }\n \n .loading::after {\n content: 'Loading chat...';\n color: #6b7280;\n font-size: 14px;\n }\n\n .error-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n background: #f9fafb;\n border-radius: inherit;\n border: 2px dashed #d1d5db;\n color: #6b7280;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n padding: 20px;\n box-sizing: border-box;\n }\n\n .error-icon {\n font-size: 24px;\n margin-bottom: 8px;\n }\n\n .error-title {\n font-size: 14px;\n font-weight: 500;\n margin-bottom: 4px;\n }\n\n .error-message {\n font-size: 12px;\n }\n\n .error-uuid {\n font-size: 11px;\n margin-top: 8px;\n opacity: 0.7;\n }\n\n iframe {\n width: 100%;\n height: 100%;\n border: 0;\n border-radius: inherit;\n }\n ",this.shadow.appendChild(e);const t=document.createElement("div");t.style.cssText="\n width: 100%;\n height: 100%;\n border-radius: inherit;\n ",this.shadow.appendChild(t)}buildIframeSrc(){if(!this.config.storyfileUuid)return console.error("โ No storyfile UUID configured"),null;const e=new URL(`/${this.config.storyfileUuid}/chat`,BASE_URL);e.searchParams.set("embed",""),e.searchParams.set("variant","floating"),e.searchParams.set("anchor","bottom-right");const t=[];return this.config.enableText&&t.push("text"),this.config.enableAudio&&t.push("audio"),this.config.enableVideo&&t.push("video"),t.length>0&&t.length<3&&e.searchParams.set("modes",t.join(",")),this.config.primaryColor&&"#2563eb"!==this.config.primaryColor&&e.searchParams.set("theme",`primary:${this.config.primaryColor}`),console.log("๐ Built iframe URL:",e.toString()),e.toString()}injectIframe(){const e=this.shadow.querySelector("div:last-child"),t=e.querySelector("iframe");t&&t.remove();const n=this.buildIframeSrc();if(!n)return void this.showConfigurationError(e);const i=document.createElement("iframe");i.className="loading",i.src=n,i.allow="microphone; camera",i.loading="lazy",i.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-presentation"),i.onerror=()=>{console.error("โ Failed to load widget iframe"),this.showLoadingError(e)},i.onload=()=>{console.log("โ
Iframe loaded successfully"),i.classList.remove("loading")},this.currentIframe=i,this.setupMessageHandling(i),e.appendChild(i)}setupMessageHandling(e){this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.messageHandler=t=>{if(t.source===e.contentWindow&&"lookalike-widget-ready"===t.data?.type){console.log("๐ Widget ready, setting up communication");const t=new MessageChannel;t.port1.onmessage=e=>{if(console.log("๐ Received resize message:",e.data),"lookalike-widget-resize"===e.data?.type){const t=e.data.collapsed?"collapsed":"expanded";console.log(`๐ Widget resize: ${this.className} โ ${t}`),this.className=t}},e.contentWindow.postMessage({type:"lookalike-init-channel"},BASE_URL,[t.port2])}},window.addEventListener("message",this.messageHandler)}showConfigurationError(e){e.innerHTML='\n <div class="error-container">\n <div class="error-icon">โ ๏ธ</div>\n <div class="error-title">Configuration Error</div>\n <div class="error-message">No UUID configured. Please add a uuid attribute.</div>\n <div class="error-uuid">Expected: <lookalike-widget uuid="your-uuid"></div>\n </div>\n '}showLoadingError(e){e.innerHTML=`\n <div class="error-container">\n <div class="error-icon">โ ๏ธ</div>\n <div class="error-title">Widget Loading Error</div>\n <div class="error-message">Check console for details</div>\n <div class="error-uuid">UUID: ${this.config.storyfileUuid}</div>\n </div>\n `}disconnectedCallback(){this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null)}}customElements.define("lookalike-widget",LookalikeWidget),"undefined"!=typeof module&&module.exports&&(module.exports=LookalikeWidget);
|
|
8
|
+
const WIDGET_VERSION="1.2.0",DEFAULT_UUID="019b4c51-7701-726a-8f59-e89a854682f3";function getBaseUrl(){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e?(console.log("๐ Local development detected"),"http://localhost:3000"):(console.log("๐ Using production URL"),"https://lookalike.com")}console.log("๐ Lookalike Widget v1.2.0 loading...");const BASE_URL=getBaseUrl();class LookalikeWidget extends HTMLElement{constructor(){super(),this.config={storyfileUuid:null,primaryColor:"#2563eb",enableText:!0,enableVideo:!0,enableAudio:!0},this.currentIframe=null,this.shadow=null,this.messageHandler=null,this.isInWixEmbed=!1}connectedCallback(){console.log("๐ Lookalike Widget v1.2.0 initializing..."),console.log("๐ Environment Info:",{hostname:window.location.hostname,href:window.location.href,referrer:document.referrer,userAgent:navigator.userAgent,viewport:`${window.innerWidth}x${window.innerHeight}`,inIframe:window!==window.parent}),this.detectWixEmbed(),this.shadow=this.attachShadow({mode:"closed"}),this.loadConfiguration(),this.initLive()}detectWixEmbed(){console.log("๐ Starting Wix embed detection...");try{const e=window!==window.parent;console.log("๐ฑ In iframe:",e);const n=window.location.hostname.includes("wix.com")||window.location.hostname.includes("wixsite.com"),i=window.location.search.includes("wix"),t=document.referrer.includes("wix"),o=window.innerWidth<500||window.innerHeight<300;console.log("๐ Wix Detection Results:",{inIframe:e,wixHostname:n,wixSearch:i,wixReferrer:t,smallDimensions:o,windowSize:`${window.innerWidth}x${window.innerHeight}`});const s=n||i||t||e&&o;this.isInWixEmbed=e&&s,this.isInWixEmbed?console.log("โ
Wix embed environment DETECTED - using full-screen overlay mode"):console.log("โ Standard environment detected - using normal positioning"),window.location.search.includes("force-wix-mode")&&(console.log("๐งช FORCE WIX MODE activated via URL parameter"),this.isInWixEmbed=!0)}catch(e){console.log("โ ๏ธ Cross-origin iframe error:",e.message),this.isInWixEmbed=!0,console.log("๐ Cross-origin iframe detected - using full-screen overlay mode")}}loadConfiguration(){this.hasAttribute("uuid")&&(this.config.storyfileUuid=this.getAttribute("uuid")),this.hasAttribute("color")&&(this.config.primaryColor=this.getAttribute("color")),this.hasAttribute("text")&&(this.config.enableText="false"!==this.getAttribute("text")),this.hasAttribute("video")&&(this.config.enableVideo="false"!==this.getAttribute("video")),this.hasAttribute("audio")&&(this.config.enableAudio="false"!==this.getAttribute("audio")),this.config.storyfileUuid||(this.config.storyfileUuid=DEFAULT_UUID,console.log("๐ง Using default UUID:",DEFAULT_UUID)),console.log("๐ฅ Loaded config from attributes:",this.config)}static get observedAttributes(){return["uuid","color","text","video","audio"]}attributeChangedCallback(e,n,i){if(n!==i&&this.shadow){switch(console.log(`๐ Attribute changed: ${e} = ${i}`),e){case"uuid":this.config.storyfileUuid=i;break;case"color":this.config.primaryColor=i;break;case"text":this.config.enableText="false"!==i;break;case"video":this.config.enableVideo="false"!==i;break;case"audio":this.config.enableAudio="false"!==i}console.log("๐ Updated config after attribute change:",this.config),this.isConnected&&(this.shadow.innerHTML="",this.initLive())}}initLive(){console.log("๐ Initializing live widget with config:",this.config),this.isInWixEmbed?this.initWixEmbedMode():this.initStandardMode(),this.injectShadowContent(),this.injectIframe()}initWixEmbedMode(){console.log("๐ฑ Initializing Wix embed mode with full-screen overlay");const e="\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n border: 0;\n z-index: 9999;\n background: transparent;\n pointer-events: none;\n display: block;\n ";this.style.cssText=e,console.log("๐จ Applied overlay styles:",e),console.log("๐ Host element computed styles:",{position:getComputedStyle(this).position,width:getComputedStyle(this).width,height:getComputedStyle(this).height,zIndex:getComputedStyle(this).zIndex,pointerEvents:getComputedStyle(this).pointerEvents}),this.className="collapsed wix-embed",console.log("๐ท๏ธ Applied classes:",this.className)}initStandardMode(){console.log("๐ป Initializing standard mode"),this.style.cssText="\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 380px;\n height: 60px;\n max-width: calc(100vw - 32px);\n border: 0;\n border-radius: 16px;\n z-index: 9999;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n background: transparent;\n display: block;\n ",this.className="collapsed"}injectShadowContent(){const e=document.createElement("style");e.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n :host {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n /* Standard mode styles */\n :host(.collapsed:not(.wix-embed)) {\n height: 60px !important;\n max-height: 60px !important;\n }\n\n :host(.expanded:not(.wix-embed)) {\n height: 520px;\n max-height: calc(100vh - 32px);\n }\n\n /* Wix embed mode: container for positioned widget */\n .wix-widget-container {\n position: absolute;\n bottom: 16px;\n right: 16px;\n width: 380px;\n height: 60px;\n max-width: calc(100vw - 32px);\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n background: transparent;\n pointer-events: auto;\n }\n\n /* Debug info overlay */\n .debug-info {\n position: absolute;\n top: 10px;\n left: 10px;\n background: rgba(0, 0, 0, 0.8);\n color: white;\n padding: 8px;\n border-radius: 4px;\n font-size: 11px;\n font-family: monospace;\n z-index: 10000;\n max-width: 300px;\n pointer-events: none;\n white-space: pre-line;\n }\n\n :host(.wix-embed.collapsed) .wix-widget-container {\n height: 60px;\n }\n\n :host(.wix-embed.expanded) .wix-widget-container {\n height: 520px;\n max-height: calc(100vh - 32px);\n }\n\n @media (max-width: 639px) {\n :host(.expanded:not(.wix-embed)) {\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n bottom: 0;\n right: 0;\n border-radius: 0;\n box-shadow: none;\n }\n \n :host(:not(.wix-embed)) {\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n }\n \n :host(.collapsed:not(.wix-embed)) {\n height: 60px !important;\n max-height: 60px !important;\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n }\n\n /* Wix embed mobile styles */\n :host(.wix-embed.expanded) .wix-widget-container {\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n bottom: 0;\n right: 0;\n border-radius: 0;\n box-shadow: none;\n }\n \n .wix-widget-container {\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n }\n \n :host(.wix-embed.collapsed) .wix-widget-container {\n height: 60px !important;\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n }\n }\n \n .loading {\n background: #f3f4f6;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n border-radius: inherit;\n }\n \n .loading::after {\n content: 'Loading chat...';\n color: #6b7280;\n font-size: 14px;\n }\n\n .error-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n background: #f9fafb;\n border-radius: inherit;\n border: 2px dashed #d1d5db;\n color: #6b7280;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n padding: 20px;\n box-sizing: border-box;\n }\n\n .error-icon {\n font-size: 24px;\n margin-bottom: 8px;\n }\n\n .error-title {\n font-size: 14px;\n font-weight: 500;\n margin-bottom: 4px;\n }\n\n .error-message {\n font-size: 12px;\n }\n\n .error-uuid {\n font-size: 11px;\n margin-top: 8px;\n opacity: 0.7;\n }\n\n iframe {\n width: 100%;\n height: 100%;\n border: 0;\n border-radius: inherit;\n }\n ",this.shadow.appendChild(e),(window.location.search.includes("debug")||window.location.search.includes("force-wix-mode"))&&this.addDebugInfo();const n=document.createElement("div");this.isInWixEmbed?n.className="wix-widget-container":n.style.cssText="\n width: 100%;\n height: 100%;\n border-radius: inherit;\n ",this.shadow.appendChild(n)}addDebugInfo(){const e=document.createElement("div");e.className="debug-info";const n=`Lookalike Widget v1.2.0\nMode: ${this.isInWixEmbed?"Wix Embed":"Standard"}\nViewport: ${window.innerWidth}x${window.innerHeight}\nIn iframe: ${window!==window.parent}\nHostname: ${window.location.hostname}\nClasses: ${this.className}`;e.textContent=n,this.shadow.appendChild(e),console.log("๐ Debug info added to widget")}buildIframeSrc(){if(!this.config.storyfileUuid)return console.error("โ No storyfile UUID configured"),null;const e=new URL(`/${this.config.storyfileUuid}/chat`,BASE_URL);e.searchParams.set("embed",""),e.searchParams.set("variant","floating"),e.searchParams.set("anchor","bottom-right");const n=[];return this.config.enableText&&n.push("text"),this.config.enableAudio&&n.push("audio"),this.config.enableVideo&&n.push("video"),n.length>0&&n.length<3&&e.searchParams.set("modes",n.join(",")),this.config.primaryColor&&"#2563eb"!==this.config.primaryColor&&e.searchParams.set("theme",`primary:${this.config.primaryColor}`),console.log("๐ Built iframe URL:",e.toString()),e.toString()}injectIframe(){const e=this.isInWixEmbed?".wix-widget-container":"div:last-child",n=this.shadow.querySelector(e);console.log("๐ผ๏ธ Injecting iframe into container:",e),console.log("๐ฆ Container found:",!!n),n&&(console.log("๐ Container rect:",n.getBoundingClientRect()),console.log("๐จ Container computed styles:",{position:getComputedStyle(n).position,width:getComputedStyle(n).width,height:getComputedStyle(n).height,bottom:getComputedStyle(n).bottom,right:getComputedStyle(n).right}));const i=n?.querySelector("iframe");i&&(console.log("๐๏ธ Removing existing iframe"),i.remove());const t=this.buildIframeSrc();if(!t)return void this.showConfigurationError(n);console.log("๐ Creating iframe with src:",t);const o=document.createElement("iframe");o.className="loading",o.src=t,o.allow="microphone; camera",o.loading="lazy",o.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-presentation"),o.onerror=e=>{console.error("โ Failed to load widget iframe:",e),this.showLoadingError(n)},o.onload=()=>{console.log("โ
Iframe loaded successfully"),console.log("๐ Iframe rect after load:",o.getBoundingClientRect()),o.classList.remove("loading")},this.currentIframe=o,this.setupMessageHandling(o),n.appendChild(o),console.log("๐ฏ Iframe injection complete")}setupMessageHandling(e){this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.messageHandler=n=>{if(console.log("๐จ Received message:",n.data,"from:",n.origin),n.source===e.contentWindow&&"lookalike-widget-ready"===n.data?.type){console.log("๐ Widget ready, setting up communication");const n=new MessageChannel;n.port1.onmessage=e=>{if(console.log("๐ Received resize message:",e.data),"lookalike-widget-resize"===e.data?.type){const n=e.data.collapsed?"collapsed":"expanded";console.log(`๐ Widget resize: ${this.className} โ ${n}`),console.log("๐ Before resize - Host element rect:",this.getBoundingClientRect()),this.className=this.isInWixEmbed?`${n} wix-embed`:n,setTimeout(()=>{console.log("๐ After resize - Host element rect:",this.getBoundingClientRect());const e=this.shadow.querySelector(this.isInWixEmbed?".wix-widget-container":"div:last-child");e&&console.log("๐ Widget container rect:",e.getBoundingClientRect())},100)}},e.contentWindow.postMessage({type:"lookalike-init-channel"},BASE_URL,[n.port2])}},window.addEventListener("message",this.messageHandler),console.log("๐ Message handler installed")}showConfigurationError(e){e.innerHTML='\n <div class="error-container">\n <div class="error-icon">โ ๏ธ</div>\n <div class="error-title">Configuration Error</div>\n <div class="error-message">No UUID configured. Please add a uuid attribute.</div>\n <div class="error-uuid">Expected: <lookalike-widget uuid="your-uuid"></div>\n </div>\n '}showLoadingError(e){e.innerHTML=`\n <div class="error-container">\n <div class="error-icon">โ ๏ธ</div>\n <div class="error-title">Widget Loading Error</div>\n <div class="error-message">Check console for details</div>\n <div class="error-uuid">UUID: ${this.config.storyfileUuid}</div>\n </div>\n `}disconnectedCallback(){this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null)}}customElements.define("lookalike-widget",LookalikeWidget),"undefined"!=typeof module&&module.exports&&(module.exports=LookalikeWidget);
|