add duplicate load guard so extension defers to page native uncloseai.js
This commit is contained in:
parent
3f190723b4
commit
6417d3853f
1 changed files with 96 additions and 78 deletions
|
|
@ -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,90 +126,102 @@ 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 () =>
|
||||
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;
|
||||
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;
|
||||
|
||||
// Initialize on page load
|
||||
window.addEventListener("load", async () => {
|
||||
console.log("uncloseai.js: window.onload event fired.");
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Check skip init flag first
|
||||
if (window.UNCLOSEAI_SKIP_INIT === true) {
|
||||
console.log(
|
||||
"uncloseai.js: Skipping full initialization as requested by flag.",
|
||||
);
|
||||
console.log(
|
||||
"uncloseai.js: Creating floating button only for preview windows.",
|
||||
);
|
||||
|
||||
// Still create floating button for preview windows, but skip other initialization
|
||||
const SHOW_FLOATING_BUTTON = window.UNCLOSEAI_FLOATING_BUTTON !== false;
|
||||
if (SHOW_FLOATING_BUTTON) {
|
||||
UI.createFloatingAIButton();
|
||||
// Load CryptoJS and initialize vault early
|
||||
await ensureCryptoJS();
|
||||
if (UncloseVault.isAvailable()) {
|
||||
const restored = UncloseVault.init();
|
||||
console.log(
|
||||
"uncloseai.js: Vault initialized, session restored:",
|
||||
restored,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
UI.initializeSystem();
|
||||
});
|
||||
// Check skip init flag first
|
||||
if (window.UNCLOSEAI_SKIP_INIT === true) {
|
||||
console.log(
|
||||
"uncloseai.js: Skipping full initialization as requested by flag.",
|
||||
);
|
||||
console.log(
|
||||
"uncloseai.js: Creating floating button only for preview windows.",
|
||||
);
|
||||
|
||||
// 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]");
|
||||
const message = input.value.trim();
|
||||
|
||||
if (!message) return;
|
||||
|
||||
// Add user message
|
||||
chatBox.innerHTML += `<div style="margin: 2px 0; padding: 2px; background: #e3f2fd; border-radius: 2px; font-size: 0.9em;"><strong>You:</strong> ${message}</div>`;
|
||||
input.value = "";
|
||||
|
||||
// Add AI thinking indicator
|
||||
const thinkingDiv = document.createElement("div");
|
||||
thinkingDiv.style.cssText =
|
||||
"margin: 2px 0; padding: 2px; background: #f5f5f5; border-radius: 2px; font-size: 0.9em;";
|
||||
thinkingDiv.innerHTML = "<strong>AI:</strong> <em>thinking...</em>";
|
||||
chatBox.appendChild(thinkingDiv);
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
|
||||
try {
|
||||
let response = "";
|
||||
for await (const chunk of Chat.sendMessage(message)) {
|
||||
response += chunk;
|
||||
thinkingDiv.innerHTML = `<strong>AI:</strong> ${response}`;
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
// Still create floating button for preview windows, but skip other initialization
|
||||
const SHOW_FLOATING_BUTTON =
|
||||
window.UNCLOSEAI_FLOATING_BUTTON !== false;
|
||||
if (SHOW_FLOATING_BUTTON) {
|
||||
UI.createFloatingAIButton();
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
thinkingDiv.innerHTML = `<strong>Error:</strong> ${error.message}`;
|
||||
}
|
||||
};
|
||||
|
||||
console.log("uncloseai.js: Modular version loaded successfully");
|
||||
UI.initializeSystem();
|
||||
});
|
||||
|
||||
// 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]");
|
||||
const message = input.value.trim();
|
||||
|
||||
if (!message) return;
|
||||
|
||||
// Add user message
|
||||
chatBox.innerHTML += `<div style="margin: 2px 0; padding: 2px; background: #e3f2fd; border-radius: 2px; font-size: 0.9em;"><strong>You:</strong> ${message}</div>`;
|
||||
input.value = "";
|
||||
|
||||
// Add AI thinking indicator
|
||||
const thinkingDiv = document.createElement("div");
|
||||
thinkingDiv.style.cssText =
|
||||
"margin: 2px 0; padding: 2px; background: #f5f5f5; border-radius: 2px; font-size: 0.9em;";
|
||||
thinkingDiv.innerHTML = "<strong>AI:</strong> <em>thinking...</em>";
|
||||
chatBox.appendChild(thinkingDiv);
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
|
||||
try {
|
||||
let response = "";
|
||||
for await (const chunk of Chat.sendMessage(message)) {
|
||||
response += chunk;
|
||||
thinkingDiv.innerHTML = `<strong>AI:</strong> ${response}`;
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
}
|
||||
} catch (error) {
|
||||
thinkingDiv.innerHTML = `<strong>Error:</strong> ${error.message}`;
|
||||
}
|
||||
};
|
||||
|
||||
console.log("uncloseai.js: Modular version loaded successfully");
|
||||
} else {
|
||||
console.log(
|
||||
"uncloseai.js: page already has uncloseai loaded, skipping duplicate initialization",
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue