refac: improve multi browser support

This commit is contained in:
sethburkart123
2024-08-29 16:28:56 +10:00
parent f996e4bf19
commit 125ebfbaea
26 changed files with 519 additions and 133 deletions
+16
View File
@@ -0,0 +1,16 @@
# Copy this file to .env.submit and fill in the values as you wish to publish
CHROME_EXTENSION_ID=
CHROME_CLIENT_ID=
CHROME_CLIENT_SECRET=
CHROME_REFRESH_TOKEN=
CHROME_PUBLISH_TARGET=
CHROME_SKIP_SUBMIT_REVIEW=
FIREFOX_EXTENSION_ID=
FIREFOX_JWT_ISSUER=
FIREFOX_JWT_SECRET=
FIREFOX_CHANNEL=
EDGE_PRODUCT_ID=
EDGE_CLIENT_ID=
EDGE_CLIENT_SECRET=
EDGE_ACCESS_TOKEN_URL=
EDGE_SKIP_SUBMIT_REVIEW= # true or false
+73
View File
@@ -0,0 +1,73 @@
name: MVP - make, version & publish
on:
push:
branches:
- main
workflow_dispatch: # This line adds manual triggering from the GitHub UI
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
make_version_publish:
name: Make, Version & Publish
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Setup Node 20.x
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Install bun & Deps
run: |
npm install bun -g
bun install
- name: 'Build - all browsers'
id: buildProject
run: MODE=chrome vite build && MODE=firefox vite build
- name: '[ V E R S I O N ] : Create or Update Release Pull Request - Version Changes'
id: changesets
uses: changesets/action@v1
with:
version: bun run version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: 'Get current version info from package.json'
if: steps.changesets.outputs.hasChangesets == 'false'
id: package
run: |
echo "::set-output name=PACKAGE_NAME::$(jq -r .name package.json)"
echo "::set-output name=PACKAGE_VERSION::$(jq -r .version package.json)"
working-directory: ${{ github.workspace }}
- name: 'Check if a git release already exists for current version'
if: steps.changesets.outputs.hasChangesets == 'false'
id: checkRelease
run: |
TAG_NAME=${{ steps.package.outputs.PACKAGE_NAME }}@${{ steps.package.outputs.PACKAGE_VERSION }}
if gh release view $TAG_NAME &>/dev/null; then
echo "Release $TAG_NAME already exists."
echo "RELEASE_EXISTS=true" >> $GITHUB_ENV
else
echo "RELEASE_EXISTS=false" >> $GITHUB_ENV
fi
- name: 'Create Release Archive(s) - zip 🫰 it 🫰 up 🫰 !'
id: zip
if: steps.changesets.outputs.hasChangesets == 'false'
run: bun run zip
- name: 'Create a git release w/ notes & release archive(s)'
id: gitRelease
if: steps.changesets.outputs.hasChangesets == 'false' && env.RELEASE_EXISTS != 'true'
run: bun run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PACKAGE_NAME: ${{ steps.package.outputs.PACKAGE_NAME }}
PACKAGE_VERSION: ${{ steps.package.outputs.PACKAGE_VERSION }}
+2 -11
View File
@@ -7,24 +7,15 @@ yarn.lock
.parcel-cache
.env
.env.submit
# Build
extension.zip
build/
dist/
betterseqtaplus-safari/
.million/
.vscode/
**/.DS_Store
# Sentry Config File
.env.sentry-build-plugin
# Sentry Config File
.env.sentry-build-plugin
# Sentry Config File
.env.sentry-build-plugin
# Sentry Config File
.sentryclirc
+16
View File
@@ -0,0 +1,16 @@
import fs from "fs";
import mime from "mime-types";
export const base64Loader = {
name: "base64-loader",
transform(_: any, id: string) {
const [filePath, query] = id.split("?");
if (query !== "base64") return null;
const data = fs.readFileSync(filePath, { encoding: 'base64' });
const mimeType = mime.lookup(filePath);
const dataURL = `data:${mimeType};base64,${data}`;
return `export default '${dataURL}';`;
},
};
+33
View File
@@ -0,0 +1,33 @@
import type { Browser, BuildTarget, Manifest } from './types'
import type { AnyCase } from './utils'
/**
*
*
* @export
* @param {Manifest} manifest
* @param {AnyCase<Browser>} browser
* @return {*} {@link BuildTarget}
*/
export function createManifest(
manifest: Manifest,
browser: AnyCase<Browser>,
): BuildTarget {
return {
manifest,
browser,
}
}
/**
* create a base Manifest to inherit from
* type Manifest = chrome.runtime.ManifestV3
*
* use as shared base to extend inBrowser manifests
*
* @export
* @param {Manifest} manifest
* @return {*} {@link Manifest}
*/
export function createManifestBase(manifest: Manifest): Manifest {
return manifest
}
+90
View File
@@ -0,0 +1,90 @@
const glob = require('glob');
const semver = require('semver');
const { execSync } = require('child_process');
const path = require('path');
function getLatestVersion(files) {
console.log('Files passed to getLatestVersion:', files);
const versions = files.map(file => {
const match = file.match(/@(\d+\.\d+\.\d+)-/);
console.log('Matching file:', file, 'Version found:', match ? match[1] : 'None');
return match ? match[1] : null;
}).filter(Boolean);
console.log('Extracted versions:', versions);
const latestVersion = semver.maxSatisfying(versions, '*');
console.log('Latest version:', latestVersion);
return latestVersion;
}
function getLatestFiles(browser) {
const pattern = `dist/betterseqtaplus@*-*${browser}.zip`;
console.log('Glob pattern:', pattern);
const files = glob.sync(pattern);
console.log('Files found for browser', browser, ':', files);
const latestVersion = getLatestVersion(files);
const latestFile = files.find(file => file.includes(latestVersion));
console.log('Latest file for browser', browser, ':', latestFile);
return latestFile;
}
function zipSources() {
const zipFileName = `dist/betterseqtaplus@latest-sources.zip`;
const excludePatterns = [
'node_modules',
'dist',
'.env*',
'.git',
'.github',
'.vscode',
'LICENSE',
'package.json'
].map(pattern => `-x!${pattern}`).join(' ');
const zipCommand = `7z a ${zipFileName} . ${excludePatterns}`;
console.log('Zipping project sources with command:', zipCommand);
execSync(zipCommand, { stdio: 'inherit' });
return zipFileName;
}
function runPublishCommand(browsers) {
const chromeZip = browsers.includes('chrome') ? getLatestFiles('chrome') : null;
const firefoxZip = browsers.includes('firefox') ? getLatestFiles('firefox') : null;
const firefoxSourcesZip = browsers.includes('firefox') ? zipSources() : null;
console.log('Chrome zip:', chromeZip);
console.log('Firefox zip:', firefoxZip);
console.log('Firefox sources zip:', firefoxSourcesZip);
if (browsers.length === 0) {
console.log('No browsers specified. Exiting.');
process.exit(0);
}
if ((browsers.includes('chrome') && !chromeZip) || (browsers.includes('firefox') && (!firefoxZip || !firefoxSourcesZip))) {
console.error('Could not find required zip files for specified browsers.');
process.exit(1);
}
let command = 'publish-extension';
if (chromeZip) {
command += ` --chrome-zip ${chromeZip}`;
}
if (firefoxZip && firefoxSourcesZip) {
command += ` --firefox-zip ${firefoxZip} --firefox-sources-zip ${firefoxSourcesZip}`;
}
console.log('Running command:', command);
execSync(command, { stdio: 'inherit' });
}
// Parse command-line arguments
const args = process.argv.slice(2);
const browserIndex = args.indexOf('--b');
const browsers = browserIndex !== -1 ? args.slice(browserIndex + 1) : [];
runPublishCommand(browsers);
+104
View File
@@ -0,0 +1,104 @@
import type { ManifestV3Export } from '@crxjs/vite-plugin'
import { type AnyCase, createEnum } from './utils'
export const FrameworkEnum = {
React: 'React',
Vanilla: 'Vanilla',
Preact: 'Preact',
Lit: 'Lit',
Svelte: 'Svelte',
Vue: 'Vue',
} as const
export const BrowserEnum = {
Chrome: 'Chrome',
Brave: 'Brave',
Opera: 'Opera',
Edge: 'Edge',
Firefox: 'Firefox',
Safari: 'Safari',
} as const
const LanguageEnum = {
TypeScript: 'TypeScript',
JavaScript: 'JavaScript',
} as const
export const StyleEnum = {
Tailwind: 'Tailwind',
} as const
export const PackageManagerEnum = {
Bun: 'Bun',
PnPm: 'PnPm',
Npm: 'Npm',
Yarn: 'Yarn',
} as const
// see: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/firefox-webext-browser/index.d.ts
export type BrowserSpecificSettings = {
browser_specific_settings?: {
gecko?: {
id: string
strict_min_version?: string
strict_max_version?: string
}
}
}
export type Manifest = ManifestV3Export
export type ManifestIcons = chrome.runtime.ManifestIcons
export type ManifestBackground = chrome.runtime.ManifestV3['background']
export type ManifestContentScripts =
chrome.runtime.ManifestV3['content_scripts']
export type ManifestWebAccessibleResources =
chrome.runtime.ManifestV3['web_accessible_resources']
export type ManifestCommands = chrome.runtime.ManifestV3['commands']
export type ManifestAction = chrome.runtime.ManifestV3['action']
export type ManifestPermissions = chrome.runtime.ManifestV3['permissions']
export type ManifestOptionsUI = chrome.runtime.ManifestV3['options_ui']
export type ManifestURLOverrides =
chrome.runtime.ManifestV3['chrome_url_overrides']
export type BrowserName<T extends string> = Capitalize<T> | Lowercase<T>
export type BrowserEnumType<T extends string> = {
[browser in BrowserName<T>]: BrowserName<T>
}
export type BuildMode = AnyCase<Browser>
export type BuildTarget = {
manifest: Manifest
browser: AnyCase<Browser>
}
export type BuildConfig = {
command?: 'build' | 'serve'
mode?: AnyCase<Browser> | string | undefined
}
export interface Repository {
type: string
url?: string
bugs?: Bugs
}
export interface Bugs {
url?: string
email?: string
}
export type Browser = (typeof BrowserEnum)[keyof typeof BrowserEnum]
export const Browser: AnyCase<Browser> = createEnum(BrowserEnum)
export type PackageManager =
(typeof PackageManagerEnum)[keyof typeof PackageManagerEnum]
export const PackageManager: AnyCase<PackageManager> =
createEnum(PackageManagerEnum)
export type Framework = (typeof FrameworkEnum)[keyof typeof FrameworkEnum]
export const Framework: AnyCase<Framework> = createEnum(FrameworkEnum)
export type Style = (typeof StyleEnum)[keyof typeof StyleEnum]
export const Style: AnyCase<Style> = createEnum(StyleEnum)
export type Language = (typeof LanguageEnum)[keyof typeof LanguageEnum]
export const Language: AnyCase<Language> = createEnum(LanguageEnum)
+21
View File
@@ -0,0 +1,21 @@
export type ObjectValues<T> = T[keyof T]
export function createEnum<T extends Record<string, string>>(enumObj: T) {
return Object.values(enumObj) as unknown as ObjectValues<T>
}
export type AnyCase<T extends string> =
| Uppercase<T>
| Lowercase<T>
| Capitalize<T>
| Uncapitalize<T>
export type AnyCaseLanguage<T extends string, K extends string> =
| Uppercase<T | K>
| Lowercase<T | K>
| Capitalize<T | K>
| Uncapitalize<T | K>
export type OptionalKeys<T> = {
[K in keyof T as undefined extends T[K] ? K : never]: T[K]
}
-32
View File
@@ -1,32 +0,0 @@
{
"manifest_version": 3,
"name": "BetterSEQTA+",
"version": "3.2.6",
"description": "Enhance SEQTA Learn's usability and aesthetics! A fork of BetterSEQTA to continue development, and incorporate a plethora of new features!",
"icons": {
"32": "src/resources/icons/icon-32.png",
"48": "src/resources/icons/icon-48.png",
"64": "src/resources/icons/icon-64.png"
},
"action": {
"browser_style": true,
"default_popup": "src/interface/index.html#settings",
"default_icon": {
"32": "src/resources/icons/icon-32.png",
"48": "src/resources/icons/icon-48.png",
"64": "src/resources/icons/icon-64.png"
}
},
"permissions": ["tabs", "notifications", "storage", "activeTab"],
"host_permissions": ["<all_urls>"],
"background": {
"scripts": ["src/background.ts"]
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["src/SEQTA.ts"],
"run_at": "document_start"
}
]
}
+22 -8
View File
@@ -1,15 +1,20 @@
{
"name": "betterseqtaplus",
"version": "3.3.0",
"version": "3.3.1",
"type": "module",
"description": "Enhance SEQTA Learn's usability and aesthetics! A fork of BetterSEQTA to continue development, and incorporate a plethora of new features!",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"dev": "vite dev",
"dev:firefox": "VITE_TARGET=firefox vite build --watch",
"build": "vite build",
"build:firefox": "VITE_TARGET=firefox vite build",
"package": "rimraf ./dist/*.map && 7z a -tzip extension.zip ./dist/*"
"dev": "MODE=chrome vite dev",
"dev:firefox": "MODE=firefox vite build --watch",
"build": "MODE=chrome vite build && MODE=firefox vite build",
"build:chrome": "MODE=chrome vite build",
"build:firefox": "MODE=firefox vite build",
"build:safari": "MODE=safari vite build",
"convert:safari": "xcrun safari-web-extension-converter dist/safari --project-location . --app-name $npm_package_name-safari",
"release": "gh release create $npm_package_name@$npm_package_version ./dist/*.zip --generate-notes",
"publish": "bun lib/publish.js --b",
"zip": "bedframe zip"
},
"targets": {
"prod": {
@@ -19,22 +24,29 @@
}
},
"keywords": [],
"author": "",
"author": {
"name": "SethBurkart123",
"email": "betterseqta@betterseqta.com",
"url": "https://github.com/BetterSEQTA/BetterSEQTA-plus"
},
"license": "MIT",
"devDependencies": {
"@crxjs/vite-plugin": "^2.0.0-beta.23",
"@types/mime-types": "^2.1.4",
"@vitejs/plugin-react-swc": "^3.6.0",
"eslint": "^8.56.0",
"glob": "^11.0.0",
"mime-types": "^2.1.35",
"parcel": "^2.11.0",
"prettier": "^3.2.5",
"process": "^0.11.10",
"sass": "^1.70.0",
"sass-loader": "^13.3.3",
"semver": "^7.6.3",
"url": "^0.11.3"
},
"dependencies": {
"@bedframe/cli": "^0.0.85",
"@blocknote/core": "^0.14.1",
"@blocknote/mantine": "^0.14.1",
"@blocknote/react": "^0.14.1",
@@ -59,10 +71,12 @@
"color": "^4.2.3",
"dompurify": "^3.0.8",
"framer-motion": "^11.0.25",
"kolorist": "^1.8.0",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"million": "latest",
"motion": "^10.17.0",
"publish-browser-extension": "^2.2.1",
"react": "^18.2.0",
"react-best-gradient-color-picker": "3.0.5",
"react-dom": "^18.2.0",
@@ -76,7 +90,7 @@
"ts-loader": "^9.5.1",
"typescript": "^5.3.3",
"uuid": "^9.0.1",
"vite": "^5.2.2",
"vite": "^5.4.2",
"webextension-polyfill": "^0.10.0"
}
}
+23 -29
View File
@@ -5,42 +5,36 @@ import browser from 'webextension-polyfill'
import { animate, spring, stagger } from 'motion'
// Internal utilities and functions
import { delay } from './seqta/utils/delay'
import stringToHTML from './seqta/utils/stringToHTML'
import { MessageHandler } from './seqta/utils/listeners/MessageListener'
import { initializeSettingsState, settingsState } from './seqta/utils/listeners/SettingsState'
import { StorageChangeHandler } from './seqta/utils/listeners/StorageChanges'
import { eventManager } from './seqta/utils/listeners/EventManager'
import { delay } from '@/seqta/utils/delay'
import stringToHTML from '@/seqta/utils/stringToHTML'
import { MessageHandler } from '@/seqta/utils/listeners/MessageListener'
import { initializeSettingsState, settingsState } from '@/seqta/utils/listeners/SettingsState'
import { StorageChangeHandler } from '@/seqta/utils/listeners/StorageChanges'
import { eventManager } from '@/seqta/utils/listeners/EventManager'
// UI and theme management
import loading, { AppendLoadingSymbol } from './seqta/ui/Loading'
import { enableCurrentTheme } from './seqta/ui/themes/enableCurrent'
import { updateAllColors } from './seqta/ui/colors/Manager'
import { SettingsResizer } from './seqta/ui/SettingsResizer'
import { AddBetterSEQTAElements } from './seqta/ui/AddBetterSEQTAElements'
import loading, { AppendLoadingSymbol } from '@/seqta/ui/Loading'
import { enableCurrentTheme } from '@/seqta/ui/themes/enableCurrent'
import { updateAllColors } from '@/seqta/ui/colors/Manager'
import { SettingsResizer } from '@/seqta/ui/SettingsResizer'
import { AddBetterSEQTAElements } from '@/seqta/ui/AddBetterSEQTAElements'
// JSON content
import MenuitemSVGKey from './seqta/content/MenuItemSVGKey.json'
import ShortcutLinks from './seqta/content/links.json'
import MenuitemSVGKey from '@/seqta/content/MenuItemSVGKey.json'
import ShortcutLinks from '@/seqta/content/links.json'
// Icons and fonts
import IconFamily from './resources/fonts/IconFamily.woff'
import LogoLight from './resources/icons/betterseqta-light-icon.png'
import LogoLightOutline from './resources/icons/betterseqta-light-outline.png'
import icon48 from './resources/icons/icon-48.png?base64'
import assessmentsicon from './seqta/icons/assessmentsIcon'
import coursesicon from './seqta/icons/coursesIcon'
import IconFamily from '@/resources/fonts/IconFamily.woff'
import LogoLight from '@/resources/icons/betterseqta-light-icon.png'
import LogoLightOutline from '@/resources/icons/betterseqta-light-outline.png'
import icon48 from '@/resources/icons/icon-48.png?base64'
import assessmentsicon from '@/seqta/icons/assessmentsIcon'
import coursesicon from '@/seqta/icons/coursesIcon'
// Stylesheets
import iframeCSS from './css/iframe.scss?raw'
import injectedCSS from './css/injected.scss?inline'
import documentLoadCSS from './css/documentload.scss?inline'
declare global {
interface Window {
chrome?: any
}
}
import iframeCSS from '@/css/iframe.scss?raw'
import injectedCSS from '@/css/injected.scss?inline'
import documentLoadCSS from '@/css/documentload.scss?inline'
let SettingsClicked = false
export let MenuOptionsOpen = false
@@ -975,7 +969,7 @@ export function addExtensionSettings() {
if (extensionContainer) extensionContainer.appendChild(extensionPopup)
const extensionIframe: HTMLIFrameElement = document.createElement('iframe')
extensionIframe.src = `${browser.runtime.getURL('src/interface/index.html')}#settings/embedded`
extensionIframe.src = `${browser.runtime.getURL('interface/index.html')}#settings/embedded`
extensionIframe.id = 'ExtensionIframe'
extensionIframe.setAttribute('allowTransparency', 'true')
extensionIframe.setAttribute('excludeDarkCheck', 'true')
+4 -3
View File
@@ -245,13 +245,14 @@ const ThemeSelector: ForwardRefExoticComponent<Omit<ThemeSelectorProps, "ref"> &
className="w-full h-[1px] my-2 bg-zinc-100 dark:bg-zinc-600"
></div>}
<button
onClick={() => browser.tabs.create({ url: browser.runtime.getURL('src/interface/index.html#store')})}
<a
href={browser.runtime.getURL('interface/index.html#store')}
target="_blank"
className="flex items-center justify-center w-full transition aspect-theme rounded-xl bg-zinc-100 dark:bg-zinc-900 dark:text-white"
>
<span className="text-xl font-IconFamily">{'\uecc5'}</span>
<span className="ml-2">Theme Store</span>
</button>
</a>
<button
onClick={() => browser.runtime.sendMessage({ type: 'currentTab', info: 'OpenThemeCreator' })}
+4
View File
@@ -15,3 +15,7 @@
::-webkit-scrollbar {
display: none;
}
button, a {
@apply text-[0.875rem];
}
+4
View File
@@ -0,0 +1,4 @@
import { createManifest } from '../../lib/createManifest'
import baseManifest from './manifest.json'
export const brave = createManifest(baseManifest, 'brave')
+4
View File
@@ -0,0 +1,4 @@
import { createManifest } from '../../lib/createManifest'
import baseManifest from './manifest.json'
export const chrome = createManifest(baseManifest, 'chrome')
+4
View File
@@ -0,0 +1,4 @@
import { createManifest } from '../../lib/createManifest'
import baseManifest from './manifest.json'
export const edge = createManifest(baseManifest, 'edge')
+20
View File
@@ -0,0 +1,20 @@
import { createManifest } from '../../lib/createManifest'
import baseManifest from './manifest.json'
import pkg from '../../package.json'
const updatedFirefoxManifest = {
...baseManifest,
background: {
scripts: [baseManifest.background.service_worker],
},
action: {
"default_popup": "interface/index.html#settings",
},
browser_specific_settings: {
gecko: {
id: pkg.author.email,
},
}
}
export const firefox = createManifest(updatedFirefoxManifest, 'firefox')
+11 -11
View File
@@ -4,38 +4,38 @@
"version": "3.3.1",
"description": "Enhance SEQTA Learn's usability and aesthetics! A fork of BetterSEQTA to continue development add add heaps more features!",
"icons": {
"32": "src/resources/icons/icon-32.png",
"48": "src/resources/icons/icon-48.png",
"64": "src/resources/icons/icon-64.png"
"32": "resources/icons/icon-32.png",
"48": "resources/icons/icon-48.png",
"64": "resources/icons/icon-64.png"
},
"action": {
"browser_style": true,
"default_popup": "src/interface/index.html#settings",
"default_popup": "interface/index.html#settings",
"default_icon": {
"32": "src/resources/icons/icon-32.png",
"48": "src/resources/icons/icon-48.png",
"64": "src/resources/icons/icon-64.png"
"32": "resources/icons/icon-32.png",
"48": "resources/icons/icon-48.png",
"64": "resources/icons/icon-64.png"
}
},
"permissions": ["tabs", "notifications", "storage"],
"host_permissions": ["https://newsapi.org/", "*://*/*"],
"background": {
"service_worker": "src/background.ts"
"service_worker": "background.ts"
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["src/SEQTA.ts"],
"js": ["SEQTA.ts"],
"run_at": "document_start"
}
],
"web_accessible_resources": [
{
"resources": ["src/interface/index.html"],
"resources": ["interface/index.html"],
"matches": ["*://*/*"]
},
{
"resources": ["src/seqta/ui/background/background.html"],
"resources": ["seqta/ui/background/background.html"],
"matches": ["*://*/*"]
},
{
+4
View File
@@ -0,0 +1,4 @@
import { createManifest } from '../../lib/createManifest'
import baseManifest from './manifest.json'
export const opera = createManifest(baseManifest, 'opera')
+16
View File
@@ -0,0 +1,16 @@
import { createManifest } from '../../lib/createManifest'
import baseManifest from './manifest.json'
const updatedSafariManifest = {
...baseManifest,
browser_specific_settings: {
safari: {
strict_min_version: '15.4',
strict_max_version: '*',
},
// ^^^ https://developer.apple.com/documentation/safariservices/safari_web_extensions/optimizing_your_web_extension_for_safari#3743239
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings#safari_properties
},
}
export const safari = createManifest(updatedSafariManifest, 'safari')
+1 -1
View File
@@ -8,6 +8,6 @@ export async function appendBackgroundToUI() {
background.id = 'background';
background.classList.add('imageBackground');
background.setAttribute('excludeDarkCheck', 'true');
background.src = browser.runtime.getURL('src/seqta/ui/background/background.html');
background.src = browser.runtime.getURL('seqta/ui/background/background.html');
parent!.appendChild(background);
}
+1 -1
View File
@@ -11,7 +11,7 @@ export function OpenThemeCreator( themeID: string = '' ) {
const width = '310px';
const themeCreatorIframe: HTMLIFrameElement = document.createElement('iframe');
themeCreatorIframe.src = `${browser.runtime.getURL('src/interface/index.html')}${ themeID != '' ? `?themeID=${themeID}` : '' }#themeCreator`;
themeCreatorIframe.src = `${browser.runtime.getURL('interface/index.html')}${ themeID != '' ? `?themeID=${themeID}` : '' }#themeCreator`;
themeCreatorIframe.id = 'themeCreatorIframe';
themeCreatorIframe.setAttribute('allowTransparency', 'true');
themeCreatorIframe.setAttribute('excludeDarkCheck', 'true');
+1 -1
View File
@@ -93,7 +93,7 @@ class StorageManager {
/**
* Register a listener for a setting.
* @param prop The setting to listen to.
* @param listener The listener to call when the setting changes.
* @param listener The listener to call when the setting changes -> takes two arguments, (newValue, oldValue)
*/
public register(prop: keyof SettingsState, listener: ChangeListener): void {
if (!this.listeners[prop]) {
+2 -1
View File
@@ -36,7 +36,8 @@ export class StorageChangeHandler {
updateAllColors();
}
private handleOnOffChange() {
private handleOnOffChange(newValue: boolean) {
if (newValue) return;
browser.runtime.sendMessage({ type: 'reloadTabs' });
}
+5
View File
@@ -19,5 +19,10 @@
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"paths": {
"@/*": ["./src/*"],
"$lib": ["./lib/*"],
}
},
}
+36 -33
View File
@@ -1,45 +1,46 @@
import { defineConfig } from 'vite';
import { join } from 'path';
import fs from 'fs';
import mime from 'mime-types';
import { join, resolve } from 'path';
import manifest from './manifest.json';
import firefoxManifest from './manifest.firefox.json';
import type { BuildTarget } from './lib/types';
//import MillionLint from '@million/lint';
import react from '@vitejs/plugin-react-swc';
//import MillionLint from '@million/lint';
import { crx } from '@crxjs/vite-plugin';
import million from "million/compiler";
import { base64Loader } from './lib/base64loader';
const isFirefox = process.env.VITE_TARGET === 'firefox';
import { chrome } from './src/manifests/chrome';
import { brave } from './src/manifests/brave';
import { edge } from './src/manifests/edge';
import { firefox } from './src/manifests/firefox';
import { opera } from './src/manifests/opera';
import { safari } from './src/manifests/safari';
import { crx } from '@crxjs/vite-plugin';
const base64Loader = {
name: "base64-loader",
transform(_: any, id: string) {
const [filePath, query] = id.split("?");
if (query !== "base64") return null;
const targets: BuildTarget[] = [
chrome, brave, edge, firefox, opera, safari
]
const data = fs.readFileSync(filePath, { encoding: 'base64' });
const mimeType = mime.lookup(filePath);
const dataURL = `data:${mimeType};base64,${data}`;
return `export default '${dataURL}';`;
},
};
const plugins = [
react(),
base64Loader,
million.vite({ auto: true }),
//MillionLint.vite(), /* enable for testing and debugging performance */
crx({
manifest: isFirefox ? firefoxManifest : manifest,
browser: isFirefox ? 'firefox' : 'chrome'
})
];
const mode = process.env.MODE || 'chrome';
export default defineConfig({
plugins: plugins,
plugins: [
base64Loader,
react(),
million.vite({ auto: true }),
//MillionLint.vite(), /* enable for testing and debugging performance */
crx({
manifest: targets.find(t => t.browser === mode.toLowerCase())?.manifest ?? chrome.manifest,
browser: mode.toLowerCase() === "firefox" ? "firefox" : "chrome"
})
],
root: resolve(__dirname, './src'),
resolve: {
alias: {
'@': resolve(__dirname, './src'),
'$lib': resolve(__dirname, './lib'),
},
},
server: {
port: 5173,
hmr: {
@@ -49,7 +50,9 @@ export default defineConfig({
}
},
build: {
minify: true,
outDir: resolve(__dirname, 'dist', mode),
emptyOutDir: true,
minify: false,
rollupOptions: {
input: {
settings: join(__dirname, 'src', 'interface', 'index.html'),