@lookalike/widget 1.2.0 โ†’ 1.2.3

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 CHANGED
@@ -73,8 +73,8 @@ A lightweight, self-contained widget for embedding Lookalike conversational AI a
73
73
 
74
74
  ## File Sizes
75
75
 
76
- - **Minified**: ~11KB
77
- - **Gzipped**: ~3KB (estimated)
76
+ - **Minified**: ~14KB
77
+ - **Gzipped**: ~4KB (estimated)
78
78
 
79
79
  ## License
80
80
 
@@ -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.3';
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') {
@@ -40,7 +44,15 @@ class LookalikeWidget extends HTMLElement {
40
44
  }
41
45
 
42
46
  connectedCallback() {
43
- console.log('๐Ÿš€ Lookalike Widget initializing...');
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
+ });
44
56
 
45
57
  // Detect if we're in a Wix custom code embed (or similar constrained iframe)
46
58
  this.detectWixEmbed();
@@ -56,30 +68,66 @@ class LookalikeWidget extends HTMLElement {
56
68
  }
57
69
 
58
70
  detectWixEmbed() {
71
+ console.log('๐Ÿ” Starting Wix embed detection...');
72
+ console.log('๐Ÿ”— Current URL:', window.location.href);
73
+ console.log('๐Ÿ”— Search params:', window.location.search);
74
+
75
+ // Check for force mode FIRST
76
+ const forceWixMode = window.location.search.includes('force-wix-mode') ||
77
+ window.location.href.includes('force-wix-mode') ||
78
+ document.querySelector('script[src*="force-wix-mode"]');
79
+
80
+ if (forceWixMode) {
81
+ console.log('๐Ÿงช FORCE WIX MODE DETECTED - overriding all detection');
82
+ this.isInWixEmbed = true;
83
+ return;
84
+ }
85
+
59
86
  try {
60
87
  // Check if we're in an iframe and can't access parent
61
88
  const inIframe = window !== window.parent;
89
+ console.log('๐Ÿ“ฑ In iframe:', inIframe);
62
90
 
63
91
  // Check for Wix-specific indicators
64
- const hasWixIndicators =
65
- window.location.hostname.includes('wix.com') ||
66
- window.location.hostname.includes('wixsite.com') ||
67
- window.location.search.includes('wix') ||
68
- document.referrer.includes('wix') ||
69
- (inIframe && (
70
- window.innerWidth < 500 || // Typical small embed size
71
- window.innerHeight < 300
72
- ));
92
+ const wixHostname = window.location.hostname.includes('wix.com') || window.location.hostname.includes('wixsite.com');
93
+ const wixSearch = window.location.search.includes('wix');
94
+ const wixReferrer = document.referrer.includes('wix');
95
+ const smallDimensions = window.innerWidth < 500 || window.innerHeight < 300;
96
+
97
+ console.log('๐Ÿ” Wix Detection Results:', {
98
+ inIframe,
99
+ wixHostname,
100
+ wixSearch,
101
+ wixReferrer,
102
+ smallDimensions,
103
+ windowSize: `${window.innerWidth}x${window.innerHeight}`,
104
+ referrer: document.referrer,
105
+ parentAccessible: this.canAccessParent()
106
+ });
107
+
108
+ const hasWixIndicators = wixHostname || wixSearch || wixReferrer || (inIframe && smallDimensions);
73
109
 
74
110
  this.isInWixEmbed = inIframe && hasWixIndicators;
75
111
 
76
112
  if (this.isInWixEmbed) {
77
- console.log('๐Ÿ” Detected Wix embed environment - using full-screen overlay mode');
113
+ console.log('โœ… Wix embed environment DETECTED - using full-screen overlay mode');
114
+ } else {
115
+ console.log('โŒ Standard environment detected - using normal positioning');
78
116
  }
117
+
79
118
  } catch (error) {
80
119
  // If we can't access parent due to cross-origin, assume we're in an embed
120
+ console.log('โš ๏ธ Cross-origin iframe error:', error.message);
81
121
  this.isInWixEmbed = true;
82
- console.log('๐Ÿ” Cross-origin iframe detected - using full-screen overlay mode');
122
+ console.log('๐Ÿ”’ Cross-origin iframe detected - using full-screen overlay mode');
123
+ }
124
+ }
125
+
126
+ canAccessParent() {
127
+ try {
128
+ return !!window.parent.location.href;
129
+ } catch (e) {
130
+ return false;
83
131
  }
84
132
  }
85
133
 
@@ -163,7 +211,7 @@ class LookalikeWidget extends HTMLElement {
163
211
  console.log('๐Ÿ“ฑ Initializing Wix embed mode with full-screen overlay');
164
212
 
165
213
  // Make the host element a full-screen transparent overlay
166
- this.style.cssText = `
214
+ const overlayStyles = `
167
215
  position: fixed;
168
216
  top: 0;
169
217
  left: 0;
@@ -176,8 +224,20 @@ class LookalikeWidget extends HTMLElement {
176
224
  display: block;
177
225
  `;
178
226
 
227
+ this.style.cssText = overlayStyles;
228
+
229
+ console.log('๐ŸŽจ Applied overlay styles:', overlayStyles);
230
+ console.log('๐Ÿ“ Host element computed styles:', {
231
+ position: getComputedStyle(this).position,
232
+ width: getComputedStyle(this).width,
233
+ height: getComputedStyle(this).height,
234
+ zIndex: getComputedStyle(this).zIndex,
235
+ pointerEvents: getComputedStyle(this).pointerEvents
236
+ });
237
+
179
238
  // Add collapsed class initially
180
239
  this.className = 'collapsed wix-embed';
240
+ console.log('๐Ÿท๏ธ Applied classes:', this.className);
181
241
  }
182
242
 
183
243
  initStandardMode() {
@@ -240,6 +300,25 @@ class LookalikeWidget extends HTMLElement {
240
300
  pointer-events: auto;
241
301
  }
242
302
 
303
+ /* Debug info overlay */
304
+ .debug-info {
305
+ position: absolute;
306
+ top: 10px;
307
+ right: 10px;
308
+ background: rgba(0, 0, 0, 0.8);
309
+ color: white;
310
+ padding: 6px 8px;
311
+ border-radius: 4px;
312
+ font-size: 10px;
313
+ font-family: monospace;
314
+ z-index: 10000;
315
+ max-width: 200px;
316
+ pointer-events: none;
317
+ white-space: pre-line;
318
+ opacity: 0.7;
319
+ transform: translateY(0);
320
+ }
321
+
243
322
  :host(.wix-embed.collapsed) .wix-widget-container {
244
323
  height: 60px;
245
324
  }
@@ -369,6 +448,11 @@ class LookalikeWidget extends HTMLElement {
369
448
 
370
449
  this.shadow.appendChild(style);
371
450
 
451
+ // Add debug info if URL contains debug parameter
452
+ if (window.location.search.includes('debug') || window.location.search.includes('force-wix-mode')) {
453
+ this.addDebugInfo();
454
+ }
455
+
372
456
  // Create container for iframe
373
457
  const container = document.createElement('div');
374
458
 
@@ -387,6 +471,21 @@ class LookalikeWidget extends HTMLElement {
387
471
  this.shadow.appendChild(container);
388
472
  }
389
473
 
474
+ addDebugInfo() {
475
+ const debugDiv = document.createElement('div');
476
+ debugDiv.className = 'debug-info';
477
+
478
+ const info = `v${WIDGET_VERSION} | ${this.isInWixEmbed ? 'Wix' : 'Std'}
479
+ ${window.innerWidth}x${window.innerHeight}
480
+ iframe: ${window !== window.parent}
481
+ classes: ${this.className}`;
482
+
483
+ debugDiv.textContent = info;
484
+ this.shadow.appendChild(debugDiv);
485
+
486
+ console.log('๐Ÿ› Debug info added to widget (top-right corner)');
487
+ }
488
+
390
489
  buildIframeSrc() {
391
490
  if (!this.config.storyfileUuid) {
392
491
  console.error('โŒ No storyfile UUID configured');
@@ -418,11 +517,29 @@ class LookalikeWidget extends HTMLElement {
418
517
  }
419
518
 
420
519
  injectIframe() {
421
- const container = this.shadow.querySelector(this.isInWixEmbed ? '.wix-widget-container' : 'div:last-child');
520
+ const containerSelector = this.isInWixEmbed ? '.wix-widget-container' : 'div:last-child';
521
+ const container = this.shadow.querySelector(containerSelector);
522
+
523
+ console.log('๐Ÿ–ผ๏ธ Injecting iframe into container:', containerSelector);
524
+ console.log('๐Ÿ“ฆ Container found:', !!container);
525
+
526
+ if (container) {
527
+ console.log('๐Ÿ“ Container rect:', container.getBoundingClientRect());
528
+ console.log('๐ŸŽจ Container computed styles:', {
529
+ position: getComputedStyle(container).position,
530
+ width: getComputedStyle(container).width,
531
+ height: getComputedStyle(container).height,
532
+ bottom: getComputedStyle(container).bottom,
533
+ right: getComputedStyle(container).right
534
+ });
535
+ }
422
536
 
423
537
  // Remove existing iframe if present
424
- const existingIframe = container.querySelector('iframe');
425
- if (existingIframe) existingIframe.remove();
538
+ const existingIframe = container?.querySelector('iframe');
539
+ if (existingIframe) {
540
+ console.log('๐Ÿ—‘๏ธ Removing existing iframe');
541
+ existingIframe.remove();
542
+ }
426
543
 
427
544
  const iframeSrc = this.buildIframeSrc();
428
545
  if (!iframeSrc) {
@@ -430,6 +547,8 @@ class LookalikeWidget extends HTMLElement {
430
547
  return;
431
548
  }
432
549
 
550
+ console.log('๐Ÿ”— Creating iframe with src:', iframeSrc);
551
+
433
552
  const iframe = document.createElement('iframe');
434
553
  iframe.className = 'loading';
435
554
  iframe.src = iframeSrc;
@@ -437,19 +556,22 @@ class LookalikeWidget extends HTMLElement {
437
556
  iframe.loading = 'lazy';
438
557
  iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups allow-presentation');
439
558
 
440
- iframe.onerror = () => {
441
- console.error('โŒ Failed to load widget iframe');
559
+ iframe.onerror = (error) => {
560
+ console.error('โŒ Failed to load widget iframe:', error);
442
561
  this.showLoadingError(container);
443
562
  };
444
563
 
445
564
  iframe.onload = () => {
446
565
  console.log('โœ… Iframe loaded successfully');
566
+ console.log('๐Ÿ“ Iframe rect after load:', iframe.getBoundingClientRect());
447
567
  iframe.classList.remove('loading');
448
568
  };
449
569
 
450
570
  this.currentIframe = iframe;
451
571
  this.setupMessageHandling(iframe);
452
572
  container.appendChild(iframe);
573
+
574
+ console.log('๐ŸŽฏ Iframe injection complete');
453
575
  }
454
576
 
455
577
  setupMessageHandling(iframe) {
@@ -459,6 +581,8 @@ class LookalikeWidget extends HTMLElement {
459
581
  }
460
582
 
461
583
  this.messageHandler = (e) => {
584
+ console.log('๐Ÿ“จ Received message:', e.data, 'from:', e.origin);
585
+
462
586
  if (e.source !== iframe.contentWindow) return;
463
587
 
464
588
  if (e.data?.type === 'lookalike-widget-ready') {
@@ -470,7 +594,18 @@ class LookalikeWidget extends HTMLElement {
470
594
  if (ev.data?.type === 'lookalike-widget-resize') {
471
595
  const newClass = ev.data.collapsed ? 'collapsed' : 'expanded';
472
596
  console.log(`๐Ÿ“ Widget resize: ${this.className} โ†’ ${newClass}`);
473
- this.className = newClass;
597
+ console.log('๐Ÿ“ Before resize - Host element rect:', this.getBoundingClientRect());
598
+
599
+ this.className = this.isInWixEmbed ? `${newClass} wix-embed` : newClass;
600
+
601
+ // Log after resize
602
+ setTimeout(() => {
603
+ console.log('๐Ÿ“ After resize - Host element rect:', this.getBoundingClientRect());
604
+ const container = this.shadow.querySelector(this.isInWixEmbed ? '.wix-widget-container' : 'div:last-child');
605
+ if (container) {
606
+ console.log('๐Ÿ“ Widget container rect:', container.getBoundingClientRect());
607
+ }
608
+ }, 100);
474
609
  }
475
610
  };
476
611
 
@@ -483,6 +618,7 @@ class LookalikeWidget extends HTMLElement {
483
618
  };
484
619
 
485
620
  window.addEventListener('message', this.messageHandler);
621
+ console.log('๐Ÿ‘‚ Message handler installed');
486
622
  }
487
623
 
488
624
  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,this.isInWixEmbed=!1}connectedCallback(){console.log("๐Ÿš€ Lookalike Widget initializing..."),this.detectWixEmbed(),this.shadow=this.attachShadow({mode:"closed"}),this.loadConfiguration(),this.initLive()}detectWixEmbed(){try{const e=window!==window.parent,n=window.location.hostname.includes("wix.com")||window.location.hostname.includes("wixsite.com")||window.location.search.includes("wix")||document.referrer.includes("wix")||e&&(window.innerWidth<500||window.innerHeight<300);this.isInWixEmbed=e&&n,this.isInWixEmbed&&console.log("๐Ÿ” Detected Wix embed environment - using full-screen overlay mode")}catch(e){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"),this.style.cssText="\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.className="collapsed wix-embed"}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 :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);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)}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.shadow.querySelector(this.isInWixEmbed?".wix-widget-container":"div:last-child"),n=e.querySelector("iframe");n&&n.remove();const i=this.buildIframeSrc();if(!i)return void this.showConfigurationError(e);const t=document.createElement("iframe");t.className="loading",t.src=i,t.allow="microphone; camera",t.loading="lazy",t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-presentation"),t.onerror=()=>{console.error("โŒ Failed to load widget iframe"),this.showLoadingError(e)},t.onload=()=>{console.log("โœ… Iframe loaded successfully"),t.classList.remove("loading")},this.currentIframe=t,this.setupMessageHandling(t),e.appendChild(t)}setupMessageHandling(e){this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.messageHandler=n=>{if(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}`),this.className=n}},e.contentWindow.postMessage({type:"lookalike-init-channel"},BASE_URL,[n.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: &lt;lookalike-widget uuid="your-uuid"&gt;</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.3",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.3 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.3 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(){if(console.log("๐Ÿ” Starting Wix embed detection..."),console.log("๐Ÿ”— Current URL:",window.location.href),console.log("๐Ÿ”— Search params:",window.location.search),window.location.search.includes("force-wix-mode")||window.location.href.includes("force-wix-mode")||document.querySelector('script[src*="force-wix-mode"]'))return console.log("๐Ÿงช FORCE WIX MODE DETECTED - overriding all detection"),void(this.isInWixEmbed=!0);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}`,referrer:document.referrer,parentAccessible:this.canAccessParent()});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")}catch(e){console.log("โš ๏ธ Cross-origin iframe error:",e.message),this.isInWixEmbed=!0,console.log("๐Ÿ”’ Cross-origin iframe detected - using full-screen overlay mode")}}canAccessParent(){try{return!!window.parent.location.href}catch(e){return!1}}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 right: 10px;\n background: rgba(0, 0, 0, 0.8);\n color: white;\n padding: 6px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-family: monospace;\n z-index: 10000;\n max-width: 200px;\n pointer-events: none;\n white-space: pre-line;\n opacity: 0.7;\n transform: translateY(0);\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=`v1.2.3 | ${this.isInWixEmbed?"Wix":"Std"}\n${window.innerWidth}x${window.innerHeight}\niframe: ${window!==window.parent}\nclasses: ${this.className}`;e.textContent=n,this.shadow.appendChild(e),console.log("๐Ÿ› Debug info added to widget (top-right corner)")}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: &lt;lookalike-widget uuid="your-uuid"&gt;</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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lookalike/widget",
3
- "version": "1.2.0",
3
+ "version": "1.2.3",
4
4
  "description": "Lookalike conversational AI widget for easy embedding",
5
5
  "main": "dist/lookalike-widget.js",
6
6
  "module": "dist/lookalike-widget.js",