add duplicate load guard so extension defers to page native uncloseai.js

This commit is contained in:
russell@unturf.com 2026-02-23 10:57:02 -05:00
parent 3f190723b4
commit 6417d3853f

View file

@ -22,6 +22,12 @@ import * as TTS from "./src/tts.js";
import * as UI from "./src/ui.js";
import { UncloseVault } from "./src/vault.js";
// Duplicate load guard: if a page already includes uncloseai.js natively,
// the extension should not re-initialize. Module exports remain available,
// but window globals, event listeners, and DOM side effects only run once.
const __alreadyLoaded = window.__UNCLOSEAI_LOADED__ === true;
window.__UNCLOSEAI_LOADED__ = true;
// -------------------------
// Vault Support
// -------------------------
@ -120,37 +126,43 @@ export { chatHistory } from "./src/chat.js";
// -------------------------
// Global Scope Exports (for backward compatibility)
// Side effects only run once: if the page already loaded uncloseai.js,
// the extension copy skips initialization but module exports still work.
// -------------------------
// Export functions to global scope for HTML onclick handlers
window.handleUserInput = Chat.handleUserInput;
window.readPageWithHermes = PageReader.readPageWithHermes;
window.sendMessage = Chat.sendMessage;
window.speakText = TTS.speakText;
window.uploadFile = FileUpload.uploadFile;
window.openTTSModal = UI.openTTSModal;
window.openTranslateModal = UI.openTranslateModal;
window.toggleUncloseaiEmbeddedModal = async () =>
if (!__alreadyLoaded) {
// Export functions to global scope for HTML onclick handlers
window.handleUserInput = Chat.handleUserInput;
window.readPageWithHermes = PageReader.readPageWithHermes;
window.sendMessage = Chat.sendMessage;
window.speakText = TTS.speakText;
window.uploadFile = FileUpload.uploadFile;
window.openTTSModal = UI.openTTSModal;
window.openTranslateModal = UI.openTranslateModal;
window.toggleUncloseaiEmbeddedModal = async () =>
await UI.toggleUncloseaiEmbeddedModal();
window.extractWebpageContent = Content.extractWebpageContent;
window.getSelectedModel = Models.getSelectedModel;
window.getSelectedModelEndpoint = Models.getSelectedModelEndpoint;
window.showProgressIndicator = FileUpload.showProgressIndicator;
window.hideProgressIndicator = FileUpload.hideProgressIndicator;
window.handleTTSFromElement = UI.handleTTSFromElement;
window.handleUploadFromElement = UI.handleUploadFromElement;
window.handleSmartTranslate = UI.handleSmartTranslate;
window.UncloseVault = UncloseVault;
window.extractWebpageContent = Content.extractWebpageContent;
window.getSelectedModel = Models.getSelectedModel;
window.getSelectedModelEndpoint = Models.getSelectedModelEndpoint;
window.showProgressIndicator = FileUpload.showProgressIndicator;
window.hideProgressIndicator = FileUpload.hideProgressIndicator;
window.handleTTSFromElement = UI.handleTTSFromElement;
window.handleUploadFromElement = UI.handleUploadFromElement;
window.handleSmartTranslate = UI.handleSmartTranslate;
window.UncloseVault = UncloseVault;
// Initialize on page load
window.addEventListener("load", async () => {
// Initialize on page load
window.addEventListener("load", async () => {
console.log("uncloseai.js: window.onload event fired.");
// Load CryptoJS and initialize vault early
await ensureCryptoJS();
if (UncloseVault.isAvailable()) {
const restored = UncloseVault.init();
console.log("uncloseai.js: Vault initialized, session restored:", restored);
console.log(
"uncloseai.js: Vault initialized, session restored:",
restored,
);
}
// Check skip init flag first
@ -163,7 +175,8 @@ window.addEventListener("load", async () => {
);
// Still create floating button for preview windows, but skip other initialization
const SHOW_FLOATING_BUTTON = window.UNCLOSEAI_FLOATING_BUTTON !== false;
const SHOW_FLOATING_BUTTON =
window.UNCLOSEAI_FLOATING_BUTTON !== false;
if (SHOW_FLOATING_BUTTON) {
UI.createFloatingAIButton();
}
@ -171,10 +184,10 @@ window.addEventListener("load", async () => {
}
UI.initializeSystem();
});
});
// Export helper functions for class-based integrations
window.handleCustomChat = async (button) => {
// Export helper functions for class-based integrations
window.handleCustomChat = async (button) => {
const container = button.parentElement;
const input = container.querySelector("[data-chat-input]");
const chatBox = container.querySelector("[data-chat-box]");
@ -204,6 +217,11 @@ window.handleCustomChat = async (button) => {
} catch (error) {
thinkingDiv.innerHTML = `<strong>Error:</strong> ${error.message}`;
}
};
};
console.log("uncloseai.js: Modular version loaded successfully");
console.log("uncloseai.js: Modular version loaded successfully");
} else {
console.log(
"uncloseai.js: page already has uncloseai loaded, skipping duplicate initialization",
);
}