From 3ac6fb5acc130cecc2088191b5e2732c18e17ba1 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 18 May 2024 12:13:35 +0200 Subject: [PATCH 01/23] Remove content script and add scripting permission --- manifest.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/manifest.json b/manifest.json index 9018c1ec..7c035516 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,8 @@ "manifest_version": 3, "name": "Pop-a-loon", "description": "The new rising trend (literally) that changes the browser game completely.", - "permissions": ["storage", "alarms", "idle"], + "permissions": ["storage", "alarms", "idle", "scripting"], + "host_permissions": ["https://*/*", "http://*/*"], "icons": { "16": "./resources/icons/icon-16.png", "24": "./resources/icons/icon-24.png", @@ -10,12 +11,6 @@ "48": "./resources/icons/icon-48.png", "128": "./resources/icons/icon-128.png" }, - "content_scripts": [ - { - "matches": ["https://*/*", "http://*/*"], - "js": ["./content.js"] - } - ], "web_accessible_resources": [ { "matches": ["https://*/*", "http://*/*"], From 662bf40ebb8ff31f23f55a6adfe06e451b00a083 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 18 May 2024 12:19:48 +0200 Subject: [PATCH 02/23] Refactor balloon container handling --- src/balloon.ts | 6 ++---- src/const.ts | 3 +++ src/utils.ts | 14 +++++++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/balloon.ts b/src/balloon.ts index b1a57867..054f75ad 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -1,9 +1,7 @@ import browser from 'webextension-polyfill'; import storage from '@/storage'; import { random, sendMessage } from '@utils'; - -export const balloonContainer = document.createElement('div'); -balloonContainer.id = 'balloon-container'; +import { BalloonContainerId } from '@const'; export const balloonResourceLocation = browser.runtime.getURL( 'resources/balloons/' @@ -98,7 +96,7 @@ export default abstract class Balloon { onAnimationend: this.remove.bind(this), }); // Add the balloon to the container - balloonContainer.appendChild(this.element); + document.getElementById(BalloonContainerId)?.appendChild(this.element); } public remove(): void { diff --git a/src/const.ts b/src/const.ts index 5cc63d15..189535ae 100644 --- a/src/const.ts +++ b/src/const.ts @@ -167,10 +167,13 @@ export const devRemoteResponse: Record = new Proxy( }, } ); + // // * Other // +export const BalloonContainerId = 'balloon-container'; + export type hexColor = string; export type Prettify = { diff --git a/src/utils.ts b/src/utils.ts index fd422f79..2bf37fae 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,5 @@ import browser from 'webextension-polyfill'; -import { Message } from '@const'; +import { Message, BalloonContainerId } from '@const'; import { type ClassValue, clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; import storage from '@/storage'; @@ -100,3 +100,15 @@ export async function calculateBalloonSpawnDelay() { return randomDelay / spawnRateMultiplier; } + +function createBalloonContainer() { + const balloonContainer = document.createElement('div'); + balloonContainer.id = BalloonContainerId; + document.body.appendChild(balloonContainer); + return balloonContainer; +} +export function getBalloonContainer() { + return ( + document.getElementById(BalloonContainerId) ?? createBalloonContainer() + ); +} From 75a2d62d7bf514776fbbabfc9d4b0b2582a82526 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 18 May 2024 12:26:54 +0200 Subject: [PATCH 03/23] Dynamically load content scripts --- webpack.config.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index 2abd025d..4d8d6aed 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,6 @@ const fs = require('fs'); const path = require('path'); +const glob = require('glob'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); @@ -30,12 +31,20 @@ console.log(`Building for ${browser} in ${mode} mode`); console.log(`Version: ${process.env.npm_package_version}`); console.log(`Remote: ${process.env.REMOTE}`); +const contentScripts = glob + .sync('./src/content/*.ts') + .reduce((acc, filePath) => { + const fileName = path.basename(filePath, path.extname(filePath)); + acc[fileName] = './' + filePath; + return acc; + }, {}); + module.exports = { mode, entry: { background: './src/background/background.ts', - content: './src/content/content.ts', popup: './src/popup/index.tsx', + ...contentScripts, }, output: { filename: '[name].js', From 1eb52f6f8edf231a23d33ec8fa975a8da95de538 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 18 May 2024 12:27:19 +0200 Subject: [PATCH 04/23] Update content script to spawn one balloon #187 --- src/content/content.ts | 42 ------------------------------------ src/content/spawn-balloon.ts | 25 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 42 deletions(-) delete mode 100644 src/content/content.ts create mode 100644 src/content/spawn-balloon.ts diff --git a/src/content/content.ts b/src/content/content.ts deleted file mode 100644 index cf83e988..00000000 --- a/src/content/content.ts +++ /dev/null @@ -1,42 +0,0 @@ -import browser from 'webextension-polyfill'; -import { Message } from '@const'; -import { balloonContainer } from '@/balloon'; -import { weightedRandom } from '@/utils'; -import * as balloons from '@/balloons'; -import './style.css'; - -(() => { - if ( - // Prevent running in popup - document.body.id === 'pop-a-loon' || - // Prevent multiple script loads - document.body.contains(balloonContainer) - ) { - return; - } - - browser.runtime.onMessage.addListener( - async (message: Message, sender, sendResponse) => { - // Always call sendResponse, this is required - sendResponse(); - // If the message is not spawnBalloon, ignore it - if (message.action !== 'spawnBalloon') return; - - const balloonClasses = Object.values(balloons); - // Make a list from the spawn_chance from each balloon class - const spawnChances = balloonClasses.map( - (BalloonType) => BalloonType.spawn_chance - ); - - // Create a new balloon and make it rise - const Balloon = weightedRandom(balloonClasses, spawnChances, { - default: balloons.Default, - }); - - const balloon = new Balloon(); - balloon.rise(); - } - ); - - document.body.appendChild(balloonContainer); -})(); diff --git a/src/content/spawn-balloon.ts b/src/content/spawn-balloon.ts new file mode 100644 index 00000000..d2462b91 --- /dev/null +++ b/src/content/spawn-balloon.ts @@ -0,0 +1,25 @@ +import * as balloons from '@/balloons'; +import { getBalloonContainer, weightedRandom } from '@/utils'; +import './style.css'; + +(() => { + // Prevent running in popup + if (document.body.id === 'pop-a-loon') return; + + // Add the balloon container to the document + const _ = getBalloonContainer(); + + const balloonClasses = Object.values(balloons); + // Make a list from the spawn_chance from each balloon class + const spawnChances = balloonClasses.map( + (BalloonType) => BalloonType.spawn_chance + ); + + // Create a new balloon and make it rise + const Balloon = weightedRandom(balloonClasses, spawnChances, { + default: balloons.Default, + }); + + const balloon = new Balloon(); + balloon.rise(); +})(); From 0c735092248aa5837ba3eb09c39bf7e8f3ec5c0b Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 18 May 2024 13:28:46 +0200 Subject: [PATCH 05/23] Update background script to use browser.scripting.executeScript for spawning balloons --- src/background/background.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/background/background.ts b/src/background/background.ts index fb9417ee..c95c5130 100644 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -114,15 +114,15 @@ const updateBadgeColors = () => { const alarms = await browser.alarms.getAll(); if (alarms.some((alarm) => alarm.name === 'spawnBalloon')) return skipSpawnMessage('Spawn alarm already set'); - console.log(`Sending spawnBalloon message`); - - // Send the spawnBalloon message - const response = await browser.tabs - .sendMessage(tab.id, { action: 'spawnBalloon' }) - .catch((e) => {}); - if (browser.runtime.lastError) { - browser.runtime.lastError; - } + console.log(`Spawning balloon on tab`, tab.id); + + try { + // Execute content script on tab + await browser.scripting.executeScript({ + files: ['spawn-balloon.js'], + target: { tabId: tab.id }, + }); + } catch (e) {} lastSpawn = now; }; From 4bbcb9ab1768fce7b345637184bdaf22abd32cdf Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 20 May 2024 16:19:56 +0200 Subject: [PATCH 06/23] Update firefox manifest to v3 and add scripting permission #187 --- manifest.chrome.json | 14 +------------- manifest.firefox.json | 23 +++-------------------- manifest.json | 11 +++++++++++ 3 files changed, 15 insertions(+), 33 deletions(-) diff --git a/manifest.chrome.json b/manifest.chrome.json index 2246e3de..0967ef42 100644 --- a/manifest.chrome.json +++ b/manifest.chrome.json @@ -1,13 +1 @@ -{ - "action": { - "default_icon": { - "16": "./resources/icons/icon-16.png", - "24": "./resources/icons/icon-24.png", - "32": "./resources/icons/icon-32.png", - "48": "./resources/icons/icon-48.png", - "128": "./resources/icons/icon-128.png" - }, - "default_title": "Pop-a-loon", - "default_popup": "./popup.html" - } -} +{} diff --git a/manifest.firefox.json b/manifest.firefox.json index 4c1b73a0..9471958b 100644 --- a/manifest.firefox.json +++ b/manifest.firefox.json @@ -1,27 +1,10 @@ { - "manifest_version": 2, - "browser_action": { - "default_icon": { - "16": "./resources/icons/icon-16.png", - "24": "./resources/icons/icon-24.png", - "32": "./resources/icons/icon-32.png", - "48": "./resources/icons/icon-48.png", - "128": "./resources/icons/icon-128.png" - }, - "default_title": "Pop-a-loon", - "default_popup": "./popup.html" - }, "background": { - "scripts": [ - "./background.js" - ] + "scripts": ["./background.js"] }, "browser_specific_settings": { "gecko": { "id": "pop-a-loon@pop-a-loon" } - }, - "web_accessible_resources": [ - "resources/*" - ] -} \ No newline at end of file + } +} diff --git a/manifest.json b/manifest.json index 7c035516..b6bfb569 100644 --- a/manifest.json +++ b/manifest.json @@ -11,6 +11,17 @@ "48": "./resources/icons/icon-48.png", "128": "./resources/icons/icon-128.png" }, + "action": { + "default_icon": { + "16": "./resources/icons/icon-16.png", + "24": "./resources/icons/icon-24.png", + "32": "./resources/icons/icon-32.png", + "48": "./resources/icons/icon-48.png", + "128": "./resources/icons/icon-128.png" + }, + "default_title": "Pop-a-loon", + "default_popup": "./popup.html" + }, "web_accessible_resources": [ { "matches": ["https://*/*", "http://*/*"], From f158804d8a0c954591afe7545a61535d4a437544 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 20 May 2024 19:12:41 +0200 Subject: [PATCH 07/23] Add mini-css-extract-plugin --- package-lock.json | 74 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 75 insertions(+) diff --git a/package-lock.json b/package-lock.json index 9e1c287d..a6c33974 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", "lint-staged": "^15.2.1", + "mini-css-extract-plugin": "^2.9.0", "mkdirp": "^3.0.1", "postcss": "^8.4.33", "prettier": "^3.2.5", @@ -6838,6 +6839,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", diff --git a/package.json b/package.json index 7eb81f42..04c4dd36 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", "lint-staged": "^15.2.1", + "mini-css-extract-plugin": "^2.9.0", "mkdirp": "^3.0.1", "postcss": "^8.4.33", "prettier": "^3.2.5", From 4dec61b7d17be01b3b5598286cd4cd924f995d71 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 20 May 2024 19:59:14 +0200 Subject: [PATCH 08/23] Copy stylesheets to dist and exclude popup stylesheets from being copied --- webpack.config.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/webpack.config.js b/webpack.config.js index 4d8d6aed..4d87e8b5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -82,6 +82,14 @@ module.exports = { patterns: [ // Copy resource files to dist { from: 'resources/', to: 'resources/' }, + // Copy sylesheets to dist but exclude stylesheets from popup folder + { + from: 'src/**/*.css', + globOptions: { + ignore: ['**/popup/**'], + }, + to: 'resources/stylesheets/[name][ext]', + }, // Copy manifest.json to dist { from: `manifest.json`, From 58a887992958fb9511f5d8e571a76b5321490458 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 20 May 2024 20:00:21 +0200 Subject: [PATCH 09/23] Add function to import stylesheets dynamically --- src/utils.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/utils.ts b/src/utils.ts index 2bf37fae..a6773e95 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -112,3 +112,20 @@ export function getBalloonContainer() { document.getElementById(BalloonContainerId) ?? createBalloonContainer() ); } + +export async function importStylesheet(id: string, href: string) { + id = `pop-a-loon-${id}`; + if (!document.getElementById(id)) { + // Fetch the CSS file content + const response = await fetch(href); + const css = await response.text(); + + // Create a