diff --git a/background-layer.js b/background-layer.js new file mode 100644 index 0000000..27ed243 --- /dev/null +++ b/background-layer.js @@ -0,0 +1,38 @@ +(function () { + const BG_DATA_KEY = "backgroundImageData"; + const STYLE_ID = "zen-wallpaper-layer"; + + function apply(dataUrl) { + let s = document.getElementById(STYLE_ID); + if (!dataUrl) { + if (s) s.remove(); + return; + } + if (!s) { + s = document.createElement("style"); + s.id = STYLE_ID; + (document.head || document.documentElement).appendChild(s); + } + s.textContent = ` +body::before { + content: ''; + position: fixed; + inset: 0; + background-image: url('${dataUrl}'); + background-size: cover; + background-position: center; + background-repeat: no-repeat; + z-index: -9999; + pointer-events: none; +} +`; + } + + chrome.storage.local.get(BG_DATA_KEY, (d) => apply(d[BG_DATA_KEY] || "")); + + chrome.storage.onChanged.addListener((changes, area) => { + if (area === "local" && changes[BG_DATA_KEY]) { + apply(changes[BG_DATA_KEY].newValue || ""); + } + }); +})(); diff --git a/manifest.json b/manifest.json index 3ceccd4..2d6f76f 100644 --- a/manifest.json +++ b/manifest.json @@ -28,6 +28,12 @@ "js": ["shared/polyfill.js", "content-script.js"], "run_at": "document_start", "all_frames": false + }, + { + "matches": [""], + "js": ["background-layer.js"], + "run_at": "document_start", + "all_frames": false } ], "background": { diff --git a/popup/popup.html b/popup/popup.html index 091a86b..4217673 100644 --- a/popup/popup.html +++ b/popup/popup.html @@ -72,6 +72,18 @@

Zen Internet

+
+
+ + + +
+
+
diff --git a/popup/popup.js b/popup/popup.js index cdcf3a0..b204450 100644 --- a/popup/popup.js +++ b/popup/popup.js @@ -4,6 +4,7 @@ let SKIP_THEMING_KEY = "skipThemingList"; let FALLBACK_BACKGROUND_KEY = "fallbackBackgroundList"; let STYLES_MAPPING_KEY = "stylesMapping"; const USER_STYLES_MAPPING_KEY = "userStylesMapping"; +const BG_DATA_KEY = "backgroundImageData"; const isFirefox = typeof browser !== "undefined" && typeof browser.runtime !== "undefined" && ( (typeof browser.runtime.getBrowserInfo === "function") || @@ -106,6 +107,8 @@ new (class ExtensionPopup { fallbackBackgroundList = []; hasLoadedFeaturesOnce = false; isInternalUpdate = false; + wallpaperInput = $("wallpaper-file"); + clearWallpaperButton = $("clear-wallpaper"); constructor() { log("Initializing popup class..."); @@ -124,6 +127,8 @@ new (class ExtensionPopup { }); this.checkWelcomeScreen(); + this.wallpaperInput.addEventListener("change", this.saveWallpaper.bind(this)); + this.clearWallpaperButton.addEventListener("click", this.clearWallpaper.bind(this)); this.refetchCSSButton.addEventListener("click", this.refetchCSS.bind(this)); this.refetchCSSButton.addEventListener( @@ -1422,6 +1427,21 @@ new (class ExtensionPopup { $("addon-version").textContent = `v${manifest.version}`; } + saveWallpaper() { + const file = this.wallpaperInput.files[0]; + if (!file) return; + const reader = new FileReader(); + reader.onloadend = () => { + browser.storage.local.set({ [BG_DATA_KEY]: reader.result }).catch(() => {}); + }; + reader.readAsDataURL(file); + } + + clearWallpaper() { + this.wallpaperInput.value = ""; + browser.storage.local.remove(BG_DATA_KEY).catch(() => {}); + } + /** * Toggles the automatic update background process. */ diff --git a/shared/polyfill.js b/shared/polyfill.js index 22adf37..5d761cc 100644 --- a/shared/polyfill.js +++ b/shared/polyfill.js @@ -41,6 +41,7 @@ if (typeof root.browser === "undefined" && typeof root.chrome !== "undefined") { local: { get: wrapPromise(c.storage?.local?.get, c.storage?.local), set: wrapPromise(c.storage?.local?.set, c.storage?.local), + remove: wrapPromise(c.storage?.local?.remove, c.storage?.local), clear: wrapPromise(c.storage?.local?.clear, c.storage?.local), }, onChanged: wrapEvent(c.storage?.onChanged),