diff --git a/CHANGELOG.md b/CHANGELOG.md index 8df2f267..663dbd7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ Changelog --- # Unreleased +# 15.0.1 [Firefox: Theming Bug Fixes] +- Fix tabs not being randomized when creating tabs rapidly in mixed mode. +- Fixes text selection & scrollbar not loading appropriately with their individual tab in mixed mode. +- Fixes text selection & scrollbar not loading appropriately with their individual tab in mixed mode. +- Appropriate theme for *options page* for each tab loads correctly in mixed mode. +- Fixes initialization of a theme, when closing and reopening a browser. +- Mitigates favicon & other theming components to stay themed in mixed mode. +- Fixes search bar widget toggling in *Mixed Mode* reverting all tabs back to using a single theme. # 15.0.0 [Only for Onii-chan] diff --git a/firefoxThemes/manifest.json b/firefoxThemes/manifest.json index e58f3304..30fc2ad0 100644 --- a/firefoxThemes/manifest.json +++ b/firefoxThemes/manifest.json @@ -1,7 +1,7 @@ { "name": "Doki Theme for Firefox", "short_name": "Doki Theme", - "version": "15.0.0", + "version": "15.0.1", "description": "A theme collection of girls from various anime, manga, and visual novels series.", "manifest_version": 2, "icons": { diff --git a/firefoxThemes/modules/modes/mix.js b/firefoxThemes/modules/modes/mix.js index 042feaac..273bbb4d 100644 --- a/firefoxThemes/modules/modes/mix.js +++ b/firefoxThemes/modules/modes/mix.js @@ -1,6 +1,7 @@ import {getRandomThemeId} from "../utils/random.js"; import {loadTheme} from "../utils/themes/browser.js"; - +/*Global Variables*/ +let mixedList = undefined;//Maintain a local list of all mixed tabs /*Separate the New Tab pages from the other types of pages*/ function separateTabs(tabs) { let newTabs = []; @@ -15,7 +16,7 @@ function separateTabs(tabs) { return [newTabs, otherTabs]; } -/*Add all tabs that are not a new tab into the mix collection*/ +/*Add all tabs that are not a new tab into the mix mixedQueue*/ function addOtherTabsToMix(tabs, mixList, themes) { if (tabs.length > 0) { for (const tab of tabs) { @@ -37,51 +38,34 @@ function keepLastTab(tabs) { return lastTabs; } -/*EVENT: When a new tab is created add a random theme to it*/ -function MixTabCreated(tab) { - if (tab.title === "New Tab") { - browser.storage.local.get("waifuThemes") - .then((storage) => { - const chosenThemeId = getRandomThemeId(storage.waifuThemes.themes); - MixedUpdate(tab, chosenThemeId, storage.waifuThemes.themes); - }); - } -} - /*EVENT: Set the theme for the current active tab*/ function MixTabActivated(activeInfo) { - browser.storage.local.get(["waifuThemes", "mixedTabs"]) + browser.storage.local.get(["waifuThemes"]) .then((storage) => { - const currentThemeId = storage.mixedTabs.get(activeInfo.tabId); + //Check if mixed mode is still active. + //This check is when searchbar is toggled during mix mode which disables it + if (!mixedList) { + mixTabCleanup(); + return; + } + const currentThemeId = mixedList.get(activeInfo.tabId); if (currentThemeId) { loadTheme(storage.waifuThemes.themes, currentThemeId); + browser.storage.local.set({currentThemeId}); } }); } /*EVENT: When a tab is closed delete the saved data for it*/ function MixTabClosed(tabId) { - browser.storage.local.get() - .then((storage) => { - storage.mixedTabs.delete(tabId); - browser.storage.local.set({mixedTabs: storage.mixedTabs}); - }); -} - -/*Updates the new tab with a new waifu theme*/ -function MixedUpdate(tab, themeId, themes) { - browser.storage.local.get(["mixedTabs"]) - .then((storage) => { - storage.mixedTabs.set(tab.id, themeId);//Adds the created tab to the list of mixed tabs - browser.storage.local.set({currentThemeId: themeId, mixedTabs: storage.mixedTabs}); - //Update the tab with theme - browser.tabs.update(tab.id, { - loadReplace: true, - url: themes[themeId].page - }); - //Load browser theme - loadTheme(themes, themeId); - }); + //Check if mixed mode is still active. + //This check is when searchbar is toggled during mix mode which disables it + if (!mixedList) { + mixTabCleanup(); + return; + } + mixedList.delete(tabId); + browser.storage.local.set({mixedTabs: mixedList}); } /*Cleans up all things relating to the Mixed tab option*/ @@ -89,13 +73,13 @@ function mixTabCleanup() { browser.storage.local.get("mixedTabs") .then((storage) => { //Removes all listeners - if (browser.tabs.onCreated.hasListener(MixTabCreated)) { - browser.tabs.onCreated.removeListener(MixTabCreated); + if (browser.tabs.onCreated.hasListener(MixTabActivated)) { browser.tabs.onActivated.removeListener(MixTabActivated); browser.tabs.onRemoved.removeListener(MixTabClosed); } if (storage.mixedTabs) { browser.storage.local.set({mixedTabs: undefined}); + mixedList = undefined; } }); } @@ -108,9 +92,9 @@ function setupMixedUpdate(msg) { .then((storage) => { if (!storage.mixedTabs) { storage.mixedTabs = new Map();//Create a new mixed tab list + mixedList = new Map(); } //Activate event listeners - browser.tabs.onCreated.addListener(MixTabCreated);//When a tab is created browser.tabs.onActivated.addListener(MixTabActivated);//When the active tab has been switched browser.tabs.onRemoved.addListener(MixTabClosed);//When a tab has been closed if (tabs.length > 0) { @@ -130,6 +114,7 @@ function setupMixedUpdate(msg) { } else { browser.storage.local.set({currentThemeId, mixedTabs: storage.mixedTabs}); } + mixedList = storage.mixedTabs; //Initialize first (and only) new tab with the default theme loadTheme(themes, currentThemeId); } @@ -137,4 +122,36 @@ function setupMixedUpdate(msg) { }); } -export {setupMixedUpdate, mixTabCleanup}; \ No newline at end of file +/*MESSAGE: Send a message to the page to apply theme*/ +function pageResponse(msg) { + if (!msg.mixMSG) return; + browser.storage.local.get(["currentThemeId", "waifuThemes", "backgroundType", "showWidget"]).then(storage => { + if (!mixedList) { + browser.tabs.sendMessage(msg.pageTab.id, { + pageMSG: true, + waifuThemes: storage.waifuThemes, + currentThemeId: storage.currentThemeId, + backgroundType: storage.backgroundType, + showWidget: storage.showWidget, + }); + } else { + if (!mixedList.has(msg.pageTab.id)) { + mixedList.set(msg.pageTab.id, getRandomThemeId(storage.waifuThemes.themes)); + browser.storage.local.set({mixedTabs: mixedList}); + } + browser.tabs.sendMessage(msg.pageTab.id, { + pageMSG: true, + waifuThemes: storage.waifuThemes, + currentThemeId: storage.currentThemeId, + backgroundType: storage.backgroundType, + showWidget: storage.showWidget, + mixedTabs: mixedList, + pageTab: msg.pageTab + }); + loadTheme(storage.waifuThemes.themes, mixedList.get(msg.pageTab.id)); + } + }); +} + +export {setupMixedUpdate, mixTabCleanup}; +browser.runtime.onMessage.addListener(pageResponse); \ No newline at end of file diff --git a/firefoxThemes/modules/utils/themes/browser.js b/firefoxThemes/modules/utils/themes/browser.js index e60549fa..deef4934 100644 --- a/firefoxThemes/modules/utils/themes/browser.js +++ b/firefoxThemes/modules/utils/themes/browser.js @@ -10,5 +10,13 @@ async function loadTheme(themes, themeId) { const themeJSON = await res.json(); browser.theme.update(themeJSON); } +/*Retrieve the appropriate theme*/ +function getCurrentTheme(themes,themeId,mixedTabs,tab){ + if(mixedTabs){ + themeId = mixedTabs.get(tab.id); + browser.storage.local.set({currentThemeId:themeId}); + } + return themes[themeId]; +} -export {loadTheme}; \ No newline at end of file +export {loadTheme,getCurrentTheme}; \ No newline at end of file diff --git a/firefoxThemes/options/options.js b/firefoxThemes/options/options.js index 42df2fb9..a6916162 100644 --- a/firefoxThemes/options/options.js +++ b/firefoxThemes/options/options.js @@ -14,19 +14,23 @@ function setCss(chosenTheme) { root.style.setProperty('--checkmark-color',colors.classNameColor); } -function initContent() { - browser.storage.local.get(['loadOnStart', 'textSelection', 'scrollbar', 'waifuThemes', 'currentThemeId']) - .then((storage) => { - initCheckbox(loadOnStartCheckbox,!!storage.loadOnStart); - initCheckbox(textSelectionCheckbox,!!storage.textSelection); - initCheckbox(scrollbarCheckbox,!!storage.scrollbar); - setCss(storage.waifuThemes.themes[storage.currentThemeId]) - }); +async function initContent() { + const storage = await browser.storage.local.get(['loadOnStart', 'textSelection', 'scrollbar', 'waifuThemes', 'currentThemeId','mixedTabs']) + initCheckbox(loadOnStartCheckbox,!!storage.loadOnStart); + initCheckbox(textSelectionCheckbox,!!storage.textSelection); + initCheckbox(scrollbarCheckbox,!!storage.scrollbar); + let themeId = storage.currentThemeId; + if(storage.mixedTabs){ + const tab = await browser.tabs.getCurrent(); + themeId = storage.mixedTabs.get(tab.id); + } + setCss(storage.waifuThemes.themes[themeId]); } const onChangeCheckEvents = async (e) => { changeCheckboxState(e); await browser.runtime.sendMessage({ + resourceMSG:true, optionName: e.target.id, optionValue: e.target.className }); diff --git a/firefoxThemes/package.json b/firefoxThemes/package.json index 4351c9a8..a16d18d8 100644 --- a/firefoxThemes/package.json +++ b/firefoxThemes/package.json @@ -1,6 +1,6 @@ { "name": "doki-theme-firefox", - "version": "15.0.0", + "version": "15.0.1", "description": "A theme collection of girls from various anime, manga, and visual novels series.", "main": "index.js", "repository": "https://github.com/doki-theme/doki-theme-web", diff --git a/firefoxThemes/popup/popup.js b/firefoxThemes/popup/popup.js index 03cead25..a021feb5 100644 --- a/firefoxThemes/popup/popup.js +++ b/firefoxThemes/popup/popup.js @@ -36,7 +36,7 @@ const setBackground = async () => { }); const {currentThemeId} = await browser.storage.local.get(["currentThemeId"]) - browser.runtime.sendMessage({currentThemeId}); + browser.runtime.sendMessage({resourceMSG:true,currentThemeId}); } const setHideWidget = async () => { @@ -44,8 +44,7 @@ const setHideWidget = async () => { showWidget: showSearchSwitch.checked }); - const {currentThemeId} = await browser.storage.local.get(["currentThemeId"]) - browser.runtime.sendMessage({currentThemeId}); + browser.runtime.sendMessage({resourceMSG:true,applyWidget:true}); } /*Stores info to set dark mode switch accordingly*/ @@ -81,7 +80,7 @@ const setOpposingTheme = async () => { const newThemeId = newTheme.id; setCSS(newTheme); await browser.storage.local.set({currentThemeId: newThemeId}); - browser.runtime.sendMessage({currentThemeId: newThemeId}); + browser.runtime.sendMessage({resourceMSG:true,currentThemeId: newThemeId}); } } @@ -151,7 +150,7 @@ function setTheme(e) { setCSS(themes[chosenThemeId]); selectTag.value = 'none';// Reset option back to 'choose a waifu' } - browser.runtime.sendMessage({currentThemeId: chosenThemeId, mixState: currentMix}); + browser.runtime.sendMessage({resourceMSG:true,currentThemeId: chosenThemeId, mixState: currentMix}); }); } diff --git a/firefoxThemes/resources.js b/firefoxThemes/resources.js index 0cd998cb..899404e8 100644 --- a/firefoxThemes/resources.js +++ b/firefoxThemes/resources.js @@ -3,7 +3,8 @@ import {mixedStates} from "./modules/utils/states.js"; import {setupMixedUpdate, mixTabCleanup} from "./modules/modes/mix.js"; import {normalUpdate} from "./modules/modes/normal.js"; import {updateOptions} from "./modules/contentConfig.js"; - +import {getRandomThemeId} from "./modules/utils/random.js"; +import {reloadTabs} from "./modules/utils/browser.js"; /*---CLASSES---*/ /*Class Goal: Holds theme data about all waifus*/ @@ -40,26 +41,28 @@ class Theme { } /*Initialize Local Storage & custom new tab page*/ -function startStorage() { - browser.storage.local.get(["currentThemeId", "loadOnStart", "textSelection", "scrollbar"]) - .then((storage) => { - const initStorage = { - waifuThemes: new WaifuThemes(), - }; - //Retrieve all themes if none exists in local storage - browser.storage.local.set(initStorage); - //Load browser theme - if (storage.currentThemeId) { - loadTheme(initStorage.waifuThemes.themes, storage.currentThemeId); - } - if (storage.loadOnStart) { - //When the browser first opens, redirect to custom new tab page - browser.tabs.update({loadReplace: true, url: "waifus/index.html"}); - } - // Register all styles from option page - updateOptions({optionName: "textSelection", optionValue: !!!storage.textSelection}); - updateOptions({optionName: "scrollbar", optionValue: !!!storage.scrollbar}); - }); +async function startStorage() { + const storage = await browser.storage.local.get(["currentThemeId", "loadOnStart", "textSelection", "scrollbar", "mixedTabs"]); + const initStorage = { + waifuThemes: new WaifuThemes(), + }; + //Retrieve all themes if none exists in local storage + browser.storage.local.set(initStorage); + //Load browser theme + if (storage.mixedTabs) { + let themeId = storage.currentThemeId || getRandomThemeId(initStorage.waifuThemes.themes); + updateTabs({mixState: mixedStates.RESET, currentThemeId: themeId}); + } else if (storage.currentThemeId) { + let themeId = storage.currentThemeId || getRandomThemeId(initStorage.waifuThemes.themes); + updateTabs({currentThemeId: themeId}); + } + if (storage.loadOnStart) { + //When the browser first opens, redirect to custom new tab page + browser.tabs.update({loadReplace: true, url: "waifus/index.html"}); + } + // Register all styles from option page + updateOptions({optionName: "textSelection", optionValue: !!!storage.textSelection}); + updateOptions({optionName: "scrollbar", optionValue: !!!storage.scrollbar}); } /*Update all new tabs with new waifu theme*/ @@ -79,15 +82,19 @@ function updateTabs(msg) { } } -/*Update all theme components*/ +/*MESSAGE: Update all theme components*/ function updateTheme(msg) { - if (!msg.optionName) { + if (!msg.resourceMSG) return; + + if (msg.applyWidget) { + reloadTabs({title: 'New Tab'}); + } else if (msg.optionName && msg.optionValue) { + updateOptions(msg); + } else { updateTabs(msg); for (const optionName of ['textSelection', 'scrollbar']) { updateOptions({optionName}); } - } else { - updateOptions(msg); } } diff --git a/firefoxThemes/waifus/faviconLoader.js b/firefoxThemes/waifus/faviconLoader.js deleted file mode 100644 index c32b9178..00000000 --- a/firefoxThemes/waifus/faviconLoader.js +++ /dev/null @@ -1,25 +0,0 @@ -import {buildSVG, svgToPng} from "../modules/utils/themes/logo.js"; - -function setThemedFavicon(currentTheme) { - const faviconOptions = {width: 32, height: 32}; - const faviconSVG = buildSVG(currentTheme, faviconOptions); - svgToPng(faviconSVG, faviconOptions, (imgData) => { - let link = document.querySelector("link[rel~='icon']"); - if (!link) { - link = document.createElement('link'); - link.rel = 'icon'; - document.head.appendChild(link); - } - link.href = imgData; - }); -} - -function applyFaviconTheme() { - browser.storage.local.get(["currentThemeId", "waifuThemes"]).then((storage) => { - const currentTheme = storage.waifuThemes.themes[storage.currentThemeId] || - storage.waifuThemes.themes["19b65ec8-133c-4655-a77b-13623d8e97d3"]; - setThemedFavicon(currentTheme); - }); -} - -applyFaviconTheme(); \ No newline at end of file diff --git a/firefoxThemes/waifus/index.html b/firefoxThemes/waifus/index.html index 1138d9c3..5bb86613 100644 --- a/firefoxThemes/waifus/index.html +++ b/firefoxThemes/waifus/index.html @@ -7,12 +7,8 @@ - - - - - + diff --git a/firefoxThemes/waifus/tab.js b/firefoxThemes/waifus/tab.js index c25b6e14..b8e8a98d 100644 --- a/firefoxThemes/waifus/tab.js +++ b/firefoxThemes/waifus/tab.js @@ -69,30 +69,25 @@ function displayWidget() { `; } -function applyTabListeners() { - browser.storage.local.get(["showWidget", "waifuThemes", "currentThemeId"]) - .then((storage) => { - const currentTheme = storage.waifuThemes.themes[storage.currentThemeId] || - storage.waifuThemes.themes["19b65ec8-133c-4655-a77b-13623d8e97d3"]; // Ryuko Dark - const root = document.querySelector(':root'); - root.style.setProperty('--accent-color', currentTheme.definition.colors.accentColor); - root.style.setProperty('--base-background-color', currentTheme.definition.colors.baseBackground); +function applyTabListeners(storage) { + const currentTheme = storage.currentTheme; + const root = document.querySelector(':root'); + root.style.setProperty('--accent-color', currentTheme.definition.colors.accentColor); + root.style.setProperty('--base-background-color', currentTheme.definition.colors.baseBackground); + if (storage.showWidget === undefined || storage.showWidget) { + displayWidget(); + // set themed icons + setThemedSearchInputIcon(currentTheme); + setThemedAboutIcon(currentTheme); - if (storage.showWidget === undefined || storage.showWidget) { - displayWidget(); - // set themed icons - setThemedSearchInputIcon(currentTheme); - setThemedAboutIcon(currentTheme); + /*---Event Listeners---*/ + const input = document.querySelector("input[type='search']"); + input.addEventListener("input", searchQuery, true); + input.addEventListener("keydown", keyConfirm, true); - /*---Event Listeners---*/ - const input = document.querySelector("input[type='search']"); - input.addEventListener("input", searchQuery, true); - input.addEventListener("keydown", keyConfirm, true); - - const searchButton = document.querySelector(".search-button"); - searchButton.addEventListener("click", confirmSearch, false); - } - }); + const searchButton = document.querySelector(".search-button"); + searchButton.addEventListener("click", confirmSearch, false); + } } -applyTabListeners(); +export {applyTabListeners}; diff --git a/firefoxThemes/waifus/themeLoader.js b/firefoxThemes/waifus/themeLoader.js new file mode 100644 index 00000000..09e6484c --- /dev/null +++ b/firefoxThemes/waifus/themeLoader.js @@ -0,0 +1,36 @@ +import {buildSVG, svgToPng} from "../modules/utils/themes/logo.js"; +import {getCurrentTheme} from "../modules/utils/themes/browser.js"; +import {applyTheme} from "./waifu.js"; +import {applyTabListeners} from "./tab.js"; + +function setThemedFavicon(currentTheme) { + const faviconOptions = {width: 32, height: 32}; + const faviconSVG = buildSVG(currentTheme, faviconOptions); + svgToPng(faviconSVG, faviconOptions, (imgData) => { + let link = document.querySelector("link[rel~='icon']"); + if (!link) { + link = document.createElement('link'); + link.rel = 'icon'; + document.head.appendChild(link); + } + link.href = imgData; + }); +} + +/*Apply All Themes except toolbar themes*/ +function startTheming(msg) { + if (!msg.pageMSG) return; + msg.currentTheme = getCurrentTheme(msg.waifuThemes.themes, msg.currentThemeId, msg.mixedTabs, msg.pageTab); + applyTheme(msg); + applyTabListeners(msg); + setThemedFavicon(msg.currentTheme); +} + +/*MESSAGE: Alerts background script that page is fully loaded and ready to apply theme*/ +async function sendMessage() { + const tab = await browser.tabs.getCurrent(); + browser.runtime.sendMessage({mixMSG: true, pageTab: tab}); +} + +browser.runtime.onMessage.addListener(startTheming); +sendMessage(); \ No newline at end of file diff --git a/firefoxThemes/waifus/waifu.js b/firefoxThemes/waifus/waifu.js index ba56facb..7e8f9e5a 100644 --- a/firefoxThemes/waifus/waifu.js +++ b/firefoxThemes/waifus/waifu.js @@ -21,9 +21,8 @@ function getSecondaryAnchoring(theme) { /*Prepares the Waifu to be displayed on webpage*/ function getWaifu(storage) { - const themes = storage.waifuThemes.themes; //Retrieve path to the image file - const currentTheme = themes[storage.currentThemeId]; + const currentTheme = storage.currentTheme; const primaryBackgroundRelativeUrl = currentTheme.backgrounds.primary; const isPrimaryBackground = !storage.backgroundType; @@ -54,13 +53,9 @@ function loadDokiTheme(storage) { } /*Apply Theme */ -function applyTheme() { - browser.storage.local.get(["waifuThemes", "currentThemeId", "backgroundType"]) - .then((storage) => { - if (Object.keys(storage.waifuThemes.themes).includes(storage.currentThemeId)) { - loadDokiTheme(storage); - } - }); +function applyTheme(storage) { + if (Object.keys(storage.waifuThemes.themes).includes(storage.currentThemeId)) { + loadDokiTheme(storage); + } } - -applyTheme(); +export {applyTheme}; \ No newline at end of file