wiimart-extension/content.js
2025-07-05 20:02:24 -04:00

218 lines
8.9 KiB
JavaScript

// content.js
// Log that the content script is running
console.log("Content script is running.");
// --- Feature Detection for Cross-Browser Compatibility ---
const runtimeAPI = typeof browser !== 'undefined' ? browser : chrome;
const storageAPI = runtimeAPI.storage; // This will be browser.storage or chrome.storage
// --- Original Font Loading Logic ---
let fontLoaded = false;
function loadFont() {
const fontUrl = runtimeAPI.runtime.getURL("fonts/fot_rodin_pro_m.ttf");
const style = document.createElement('style');
style.textContent = `
@font-face {
font-family: 'Wii NTLG PGothic JPN Regular';
src: url('${fontUrl}') format('truetype');
}
body {
font-family: 'Wii NTLG PGothic JPN Regular', sans-serif !important;
}
* {
font-family: 'Wii NTLG PGothic JPN Regular', sans-serif !important;
}
#text03-01, #text05-01, #text06-01 {
display: flex; /* Enable flexbox */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
height: 100vh; /* Full height of the viewport */
width: 100%; /* Full width */
}
.buttonTextBlackM {
font-size: 24px; /* Adjust font size as needed */
color: black; /* Set text color */
text-align: center; /* Center text within the div */
}
`;
const head = document.head || document.getElementsByTagName('head')[0];
if (head) {
head.appendChild(style);
console.log("Font loaded into <head>.");
return "Font loaded into <head>";
}
const observer = new MutationObserver(() => {
const head = document.head || document.getElementsByTagName('head')[0];
if (head) {
head.appendChild(style);
observer.disconnect();
console.log("Font loaded into <head> via MutationObserver.");
return "Font loaded into <head> via MutationObserver";
}
});
observer.observe(document, { childList: true, subtree: true });
const fallbackTimeout = setTimeout(() => {
if (!document.head || !document.head.contains(style)) {
document.body.appendChild(style);
console.log("Font loaded into <body> as a fallback.");
observer.disconnect();
return "Font loaded into <body> as a fallback";
}
}, 1000);
setTimeout(() => {
if (!document.head || !document.body.contains(style)) {
console.error("Failed to load font: <head> and <body> are not available.");
return "Failed to load font: <head> and <body> are not available.";
}
observer.disconnect();
clearTimeout(fallbackTimeout);
}, 2000);
return "Font loading initiated";
}
// Check the font state on page load
function checkFontState() {
storageAPI.local.get(['fontDisabled']).then(function(result) {
if (!result.fontDisabled) {
loadFont(); // Call loadFont, no need to return its string status here
} else {
console.log("Font loading disabled by preference.");
}
}).catch(error => console.error("Error checking font state:", error));
}
const soundFilePaths = [
'', // Index 0 (unused)
'audio/1.wav',
'audio/2.wav',
'audio/3.wav',
'audio/4.wav',
'audio/5.wav',
'audio/6.wav',
'audio/7.wav'
];
const bgmFilePath = 'audio/bgm.wav'; // Define BGM file path
// Generate the full, web-accessible URLs
const generatedSoundUrls = [];
for (let i = 0; i < soundFilePaths.length; i++) {
if (soundFilePaths[i]) {
generatedSoundUrls[i] = runtimeAPI.runtime.getURL(soundFilePaths[i]);
} else {
generatedSoundUrls[i] = '';
}
}
const generatedBgmUrl = runtimeAPI.runtime.getURL(bgmFilePath); // Generate BGM URL
// Function to load class definitions and inject globals
const loadClassDefinitions = async () => {
let classDefinitionsUrl = runtimeAPI.runtime.getURL('classDefinitions.js');
try {
const response = await fetch(classDefinitionsUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const classDefinitionsText = await response.text();
// Get the current BGM enabled state from storage
const storageResult = await storageAPI.local.get(['bgmEnabled']);
const bgmInitiallyEnabled = storageResult.bgmEnabled === true; // Default to false if not set
const script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
// PREPEND the sound and BGM URLs as global variables *before* the classDefinitions.js content
script.textContent = `
(function() {
// Define global variables that classDefinitions.js can access
window._wiiShopSoundUrls_ = ${JSON.stringify(generatedSoundUrls)};
window._wiiShopBgmUrl_ = ${JSON.stringify(generatedBgmUrl)};
window._wiiShopBgmInitiallyEnabled_ = ${JSON.stringify(bgmInitiallyEnabled)}; // Pass BGM state
})();
` + classDefinitionsText; // Append the actual classDefinitions.js content
document.documentElement.insertBefore(script, document.documentElement.firstChild);
script.onload = function() {
this.remove();
// Clean up the global variables after classDefinitions.js has likely used them
// These are no longer needed as they are referenced immediately by the injected script.
// delete window._wiiShopSoundUrls_;
// delete window._wiiShopBgmUrl_;
// delete window._wiiShopBgmInitiallyEnabled_; // Clean up BGM state
};
console.log("classDefinitions.js and global URLs injected into page context via script element.");
} catch (error) {
console.error("Failed to load class definitions:", error);
}
};
// Load the class definitions
loadClassDefinitions();
// Load the existing trace and points from localStorage
checkFontState(); // Call checkFontState to initiate font loading
// --- Initial BGM Playback on DOMContentLoaded ---
document.addEventListener('DOMContentLoaded', async () => {
// Give a slight delay to ensure classDefinitions.js and window.extensionStorage are fully ready
await new Promise(resolve => setTimeout(resolve, 50));
// Request the initial BGM enabled state from the background script via extensionStorage
// We expect extensionStorage to be available after classDefinitions.js is injected
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.get === 'function') {
try {
const bgmEnabled = await window.extensionStorage.get('bgmEnabled');
console.log("Initial BGM enabled state from storage:", bgmEnabled);
if (bgmEnabled === true) { // Explicitly check for true
console.log("Attempting to play initial BGM from content script.");
// Use the new sendMessageToBackground proxy for BGM control
// This will send a request to /_extension_storage?action=playBGM&bgmUrl=...
window.extensionStorage.sendMessageToBackground({
action: "playBGM",
bgmUrl: generatedBgmUrl
});
}
} catch (error) {
console.error("Error retrieving initial BGM state or sending play request:", error);
}
} else {
console.warn("window.extensionStorage not available for initial BGM check.");
}
});
// Listener for messages from the popup (if any, specifically for BGM toggle)
runtimeAPI.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "toggleBGMImmediate") {
if (request.enabled) {
console.log("Received toggleBGMImmediate from popup: Play BGM.");
// Send a message to background via extensionStorage proxy for consistency
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.sendMessageToBackground === 'function') {
window.extensionStorage.sendMessageToBackground({
action: "playBGM",
bgmUrl: generatedBgmUrl
});
}
} else {
console.log("Received toggleBGMImmediate from popup: Stop BGM.");
// Send a message to background via extensionStorage proxy for consistency
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.sendMessageToBackground === 'function') {
window.extensionStorage.sendMessageToBackground({
action: "stopBGM"
});
}
}
}
});