Fix infinite recursion in overlay-web-adapter.js

- Store original console.log before templates override it
- Use originalConsoleLog throughout the adapter to prevent recursion
- Templates override console.log to call window.overlay.log, which was calling console.log again
parent 18ca7a4b
......@@ -22,21 +22,24 @@
*/
(function() {
console.log('[WebAdapter] Loading overlay web adapter...');
// Store original console.log BEFORE any overrides happen
const originalConsoleLog = console.log.bind(console);
originalConsoleLog('[WebAdapter] Loading overlay web adapter...');
// Check if we're running in Qt WebChannel environment
const isQtEnvironment = typeof qt !== 'undefined' && qt.webChannelTransport;
console.log('[WebAdapter] Environment detected:', isQtEnvironment ? 'Qt WebChannel' : 'Web Browser');
originalConsoleLog('[WebAdapter] Environment detected:', isQtEnvironment ? 'Qt WebChannel' : 'Web Browser');
// Provide function to load Qt scripts dynamically (only works in Qt environment)
window.loadQtScripts = function() {
if (!isQtEnvironment) {
console.log('[WebAdapter] Not loading Qt scripts - not in Qt environment');
originalConsoleLog('[WebAdapter] Not loading Qt scripts - not in Qt environment');
return false;
}
console.log('[WebAdapter] Loading Qt scripts for Qt environment');
originalConsoleLog('[WebAdapter] Loading Qt scripts for Qt environment');
// Load qwebchannel.js
const qwebchannelScript = document.createElement('script');
......@@ -53,7 +56,7 @@
// If already in Qt environment, load Qt scripts and exit
if (isQtEnvironment) {
console.log('[WebAdapter] Qt environment detected, loading Qt scripts');
originalConsoleLog('[WebAdapter] Qt environment detected, loading Qt scripts');
// Load Qt scripts when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', window.loadQtScripts);
......@@ -66,7 +69,7 @@
// Web environment - prevent Qt script loading errors
// Create dummy QWebChannel for browsers (prevents errors from qrc:/// URLs)
window.QWebChannel = function(transport, callback) {
console.log('[WebAdapter] QWebChannel called in web environment - using adapter instead');
originalConsoleLog('[WebAdapter] QWebChannel called in web environment - using adapter instead');
// The adapter already set up window.overlay, so just call callback if provided
if (callback && window.overlay) {
callback({ objects: { overlay: window.overlay } });
......@@ -78,7 +81,7 @@
if (event.target && (event.target.tagName === 'SCRIPT' || event.target.tagName === 'LINK')) {
const src = event.target.src || event.target.href || '';
if (src.startsWith('qrc:///') || src.startsWith('overlay://')) {
console.log('[WebAdapter] Suppressed Qt URL error:', src);
originalConsoleLog('[WebAdapter] Suppressed Qt URL error:', src);
event.preventDefault();
event.stopPropagation();
return true;
......@@ -91,7 +94,7 @@
if (event.reason && event.reason.message) {
const msg = event.reason.message;
if (msg.includes('qrc:///') || msg.includes('overlay://')) {
console.log('[WebAdapter] Suppressed Qt URL promise rejection:', msg);
originalConsoleLog('[WebAdapter] Suppressed Qt URL promise rejection:', msg);
event.preventDefault();
return true;
}
......@@ -102,7 +105,7 @@
const originalFetch = window.fetch;
window.fetch = function(url, options) {
if (typeof url === 'string' && (url.startsWith('qrc:///') || url.startsWith('overlay://'))) {
console.log('[WebAdapter] Blocking fetch to Qt URL:', url);
originalConsoleLog('[WebAdapter] Blocking fetch to Qt URL:', url);
return Promise.resolve(new Response('', { status: 200 }));
}
return originalFetch.apply(this, arguments);
......@@ -112,7 +115,7 @@
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
if (typeof url === 'string' && (url.startsWith('qrc:///') || url.startsWith('overlay://'))) {
console.log('[WebAdapter] Blocking XHR to Qt URL:', url);
originalConsoleLog('[WebAdapter] Blocking XHR to Qt URL:', url);
// Return without actually opening - will fail silently
return;
}
......@@ -123,14 +126,14 @@
const originalWrite = document.write;
document.write = function(content) {
if (typeof content === 'string' && (content.includes('qrc:///') || content.includes('overlay://'))) {
console.log('[WebAdapter] Blocking document.write with Qt URLs');
originalConsoleLog('[WebAdapter] Blocking document.write with Qt URLs');
return;
}
return originalWrite.apply(this, arguments);
};
// Web environment - set up postMessage bridge
console.log('[WebAdapter] Setting up postMessage bridge for web environment');
originalConsoleLog('[WebAdapter] Setting up postMessage bridge for web environment');
// Data storage
let fixtureData = null;
......@@ -173,9 +176,9 @@
// Signals
dataUpdated: new Signal(),
// Log function
// Log function - use original console.log to avoid recursion
log: function(message) {
console.log('[Overlay]', message);
originalConsoleLog('[Overlay]', message);
},
// Get fixture data - returns Promise (async like Qt)
......@@ -315,12 +318,12 @@
return;
}
console.log('[WebAdapter] Received message:', message.type);
originalConsoleLog('[WebAdapter] Received message:', message.type);
switch (message.type) {
case 'fixtureData':
fixtureData = message.fixtures || [];
console.log('[WebAdapter] Fixture data updated:', fixtureData.length, 'fixtures');
originalConsoleLog('[WebAdapter] Fixture data updated:', fixtureData.length, 'fixtures');
break;
case 'timerState':
......@@ -328,7 +331,7 @@
running: message.running,
remaining_seconds: message.remaining_seconds || 0
} : message;
console.log('[WebAdapter] Timer state updated:', timerState);
originalConsoleLog('[WebAdapter] Timer state updated:', timerState);
// Emit signal for templates listening to dataUpdated
window.overlay.dataUpdated.emit({ timer_update: timerState });
break;
......@@ -338,23 +341,23 @@
running: message.running,
remaining_seconds: message.remaining_seconds || 0
} : message;
console.log('[WebAdapter] Timer update received:', timerState);
originalConsoleLog('[WebAdapter] Timer update received:', timerState);
window.overlay.dataUpdated.emit({ timer_update: timerState });
break;
case 'licenseText':
licenseText = message.licenseText || '';
console.log('[WebAdapter] License text updated');
originalConsoleLog('[WebAdapter] License text updated');
break;
case 'completedMatches':
completedMatches = message.matches || [];
console.log('[WebAdapter] Completed matches updated:', completedMatches.length, 'matches');
originalConsoleLog('[WebAdapter] Completed matches updated:', completedMatches.length, 'matches');
break;
case 'winningOutcomes':
winningOutcomes = message.outcomes || [];
console.log('[WebAdapter] Winning outcomes updated:', winningOutcomes.length, 'outcomes');
originalConsoleLog('[WebAdapter] Winning outcomes updated:', winningOutcomes.length, 'outcomes');
break;
case 'initialData':
......@@ -368,7 +371,7 @@
if (message.licenseText) {
licenseText = message.licenseText;
}
console.log('[WebAdapter] Initial data received');
originalConsoleLog('[WebAdapter] Initial data received');
// Emit signal for templates
window.overlay.dataUpdated.emit(overlayData);
break;
......@@ -376,27 +379,27 @@
case 'dataUpdated':
// Overlay data update
overlayData = { ...overlayData, ...message };
console.log('[WebAdapter] Overlay data updated:', Object.keys(message));
originalConsoleLog('[WebAdapter] Overlay data updated:', Object.keys(message));
// Emit signal for templates
window.overlay.dataUpdated.emit(message);
break;
case 'matchUpdate':
console.log('[WebAdapter] Match update received');
originalConsoleLog('[WebAdapter] Match update received');
window.overlay.dataUpdated.emit({ match_update: message });
break;
case 'resultUpdate':
console.log('[WebAdapter] Result update received');
originalConsoleLog('[WebAdapter] Result update received');
window.overlay.dataUpdated.emit({ result_update: message });
break;
case 'videoStateChanged':
console.log('[WebAdapter] Video state changed:', message.state);
originalConsoleLog('[WebAdapter] Video state changed:', message.state);
break;
case 'streamStateChanged':
console.log('[WebAdapter] Stream state changed:', message.state);
originalConsoleLog('[WebAdapter] Stream state changed:', message.state);
break;
case 'positionChanged':
......@@ -404,13 +407,13 @@
break;
default:
console.log('[WebAdapter] Unknown message type:', message.type);
originalConsoleLog('[WebAdapter] Unknown message type:', message.type);
}
});
// Request initial data when DOM is ready
function requestInitialData() {
console.log('[WebAdapter] Requesting initial data from parent');
originalConsoleLog('[WebAdapter] Requesting initial data from parent');
if (window.parent !== window) {
window.parent.postMessage({ type: 'requestInitialData' }, '*');
......@@ -433,7 +436,7 @@
setTimeout(requestInitialData, 100);
}
console.log('[WebAdapter] Web overlay adapter initialized');
originalConsoleLog('[WebAdapter] Web overlay adapter initialized');
// Flush any buffered console logs
if (typeof window.flushConsoleBuffer === 'function') {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment