Skip to content

Commit

Permalink
Merge pull request #18 from heimdallrj/dev
Browse files Browse the repository at this point in the history
v1.1.0
  • Loading branch information
heimdallrj authored Mar 2, 2025
2 parents 49355f5 + b04d042 commit a91a17b
Show file tree
Hide file tree
Showing 28 changed files with 825 additions and 343 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"printWidth": 100,
"printWidth": 80,
"bracketSpacing": true,
"endOfLine": "lf"
}
9 changes: 7 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["javascript"]
"eslint.validate": [
"javascript"
],
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
}
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ When implementing new features or fixing issues, be mindful of *browser differen
- Publish the release.

**Publishing to Browser Stores:**
- Firefox Add-ons: Submit the build artifact to the Firefox Extension Library.
- Chrome Web Store: Not yet published, but planned for future releases.
- **Firefox Add-ons:** Submit the build artifact to the Firefox Extension Library.
- **Chrome Web Store:** Not yet published, but planned for future releases.

## Contributing

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"type": "module",
"namespace": "AutoPurge-Cookies",
"version": "1.1.0",
"scripts": {
"start:dev": "cross-env NODE_ENV=development node scripts/build.js",
"build": "NODE_ENV=production node scripts/build.js",
Expand Down
185 changes: 68 additions & 117 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -1,169 +1,122 @@
const chokidar = require('chokidar');
const fs = require('fs-extra');
const path = require('path');
const chokidar = require('chokidar');
const AdmZip = require('adm-zip');

const BROWSERS = ['chrome', 'firefox'];
const SRC_DIR = 'src';
const DIST_DIR = 'dist';

function getManifestJSON(config, browser, isProduction = false) {
// Delete developer settings
delete config.browser_specific_settings;

const manifest = { ...config };

if (isProduction) {
manifest.name = "AutoPurge-Cookie";
}

if (browser === 'firefox') {
manifest.manifest_version = 2;
manifest.permissions = config.permissions.filter(permission => permission !== 'tabs');
delete manifest.background.service_worker;
} else if (browser === 'chrome') {
manifest.manifest_version = 3;
manifest.permissions = config.permissions.filter(permission => permission !== '<all_urls>');
manifest.host_permissions = ["<all_urls>"];
manifest.action = config.browser_action;
delete manifest.browser_action;
delete manifest.background.scripts;
}

return manifest;
}
const isProduction = process.env.NODE_ENV === 'production';

function shouldIgnorePath(filePath) {
const ignoredFiles = ['.DS_Store', 'Thumbs.db'];
const ignoredDirs = ['__MACOSX'];
const pkg = require("../package.json");

// Check if the file/directory name is in the ignored list
const fileName = path.basename(filePath);
if (ignoredFiles.includes(fileName)) return true;
const DIST_DIR = 'dist';
const BROWSERS = ['Chrome', 'Firefox'];
const SRC_DIR = 'src';

// Check if any parent directory is in the ignored directories list
const pathParts = filePath.split(path.sep);
return pathParts.some(part => ignoredDirs.includes(part));
}
const excludeFileList = ['__MACOSX', '.DS_Store', 'Thumbs.db'];

function getOutputDir(browser, version) {
return path.join(DIST_DIR, `AutoPurge-Cookies_${browser}_${version}`);
const getDistName = (browser) => {
return `${pkg.namespace}_${browser.toLowerCase()}_${pkg.version}`;
}

// Copy a file to all browser directories
async function copyFile(filePath) {
if (shouldIgnorePath(filePath)) {
console.log(`Skipping ignored file/directory: ${filePath}`);
return;
}

// First read the manifest to get the version
const configPath = path.join(SRC_DIR, 'manifest.json');
const config = JSON.parse(await fs.readFile(configPath, 'utf8'));
const version = config.version;
const getFileConfig = (filePath) => {
const targetBrowser = BROWSERS.find(browser => filePath.includes(`/${browser}/`)) || 'Unknown';
const relativeFilePath = path.relative(path.join(SRC_DIR, targetBrowser), filePath);
const destBrowserDir = path.join(DIST_DIR, getDistName(targetBrowser));
const destFilePath = path.join(destBrowserDir, relativeFilePath);

const relativePath = path.relative(SRC_DIR, filePath);

for (const browser of BROWSERS) {
const browserDir = getOutputDir(browser, version);
const destPath = path.join(browserDir, relativePath);

// Handle manifest.json specially
if (path.basename(filePath) === 'manifest.json') {
const currentManifest = JSON.parse(await fs.readFile(filePath, 'utf8'));
const isProduction = process.env.NODE_ENV === 'production';
const modifiedManifest = getManifestJSON(currentManifest, browser, isProduction);
await fs.ensureDir(path.dirname(destPath));
await fs.writeFile(destPath, JSON.stringify(modifiedManifest, null, 2));
console.log(`Modified and copied manifest.json to ${destPath}`);
} else {
await fs.ensureDir(path.dirname(destPath));
await fs.copy(filePath, destPath);
console.log(`Copied ${relativePath} to ${browser}`);
}
}
return { targetBrowser, relativeFilePath, destBrowserDir, srcFilePath: filePath, destFilePath }
}

// Remove a file from all browser directories
async function removeFile(filePath) {
const configPath = path.join(SRC_DIR, 'manifest.json');
const config = JSON.parse(await fs.readFile(configPath, 'utf8'));
const version = config.version;

const relativePath = path.relative(SRC_DIR, filePath);

for (const browser of BROWSERS) {
const browserDir = getOutputDir(browser, version);
const destPath = path.join(browserDir, relativePath);
await fs.remove(destPath);
console.log(`Removed ${relativePath} from ${browser}`);
}
}

async function zipBrowserBuilds(version) {
async function pack() {
for (const browser of BROWSERS) {
const zip = new AdmZip();
const browserDir = getOutputDir(browser, version);

// Read all files in the browser directory
const files = await fs.readdir(browserDir, { recursive: true });
const targetBrowserDir = path.join(DIST_DIR, getDistName(browser));
const files = await fs.readdir(targetBrowserDir, { recursive: true });

for (const file of files) {
const filePath = path.join(browserDir, file);
const filePath = path.join(targetBrowserDir, file);
const stats = await fs.stat(filePath);

if (stats.isFile()) {
// Calculate relative path to maintain directory structure
const relativePath = path.relative(browserDir, filePath);
const relativeFilePath = path.relative(targetBrowserDir, filePath);
const fileContent = await fs.readFile(filePath);
zip.addFile(relativePath, fileContent);
zip.addFile(relativeFilePath, fileContent);
}
}

const zipPath = path.join(DIST_DIR, `AutoPurge-Cookie_${browser}_${version}.zip`);
zip.writeZip(zipPath);
console.log(`Created ${zipPath}`);
const distFilePath = path.join(DIST_DIR, `${getDistName(browser)}.zip`);
zip.writeZip(distFilePath);
console.log(`Created ${distFilePath}`);
}
}

// Modify the initialBuild function
async function initialBuild(isProduction = false) {
async function build() {
try {
// Clean dist directory
await fs.emptyDir(DIST_DIR);

// Get version from manifest
const configPath = path.join(SRC_DIR, 'manifest.json');
const config = JSON.parse(await fs.readFile(configPath, 'utf8'));
const version = config.version;
const files = (await fs.readdir(SRC_DIR, { recursive: true }))
.filter(file => !excludeFileList.some(excluded => file.includes(excluded)));

// Copy all files from src
const files = await fs.readdir(SRC_DIR, { recursive: true });
for (const file of files) {
const filePath = path.join(SRC_DIR, file);
if ((await fs.stat(filePath)).isFile()) {
await copyFile(filePath);
const srcFilePath = path.join(SRC_DIR, file);
if ((await fs.stat(srcFilePath)).isFile()) {
await copyFile(srcFilePath);
}
}

console.log('Initial build completed');

// Create zip files if in production mode
if (isProduction) {
await zipBrowserBuilds(version);
await pack();
}

// Pack for distribution
} catch (error) {
console.error('Build error:', error);
}
}

async function copyFile(srcFilePath) {
const { targetBrowser, relativeFilePath, destFilePath } = getFileConfig(srcFilePath);

if (path.basename(srcFilePath) === 'manifest.json') {
const manifestJSON = JSON.parse(await fs.readFile(srcFilePath, 'utf8'));

manifestJSON.version = pkg.version;
if (isProduction) {
manifestJSON.name = pkg.namespace;
}

await fs.writeFile(destFilePath, JSON.stringify(manifestJSON, null, 2));

console.log(`Modified and copied manifest.json to ${destFilePath}`);

return;
}

await fs.ensureDir(path.dirname(destFilePath));
await fs.copy(srcFilePath, destFilePath);

console.log(`Copied ${relativeFilePath} to ${targetBrowser}`);
}

async function removeFile(srcFilePath) {
const { targetBrowser, relativeFilePath, destFilePath } = getFileConfig(srcFilePath);

await fs.remove(destFilePath);

console.log(`Removed ${relativeFilePath} from ${targetBrowser}`);
}

// Watch for changes
function watchFiles() {
const watcher = chokidar.watch(SRC_DIR, {
ignored: [
/(^|[\/\\])\../, // ignore dotfiles
'**/.__MACOSX/**',
'**/.DS_Store',
'**/Thumbs.db'
'**/Thumbs.db',
],
persistent: true
});
Expand All @@ -177,10 +130,8 @@ function watchFiles() {
console.log('Watching for changes...');
}

// Modify the run function
async function run() {
const isProduction = process.env.NODE_ENV === 'production';
await initialBuild(isProduction);
await build();

// Only watch for changes in development mode
if (!isProduction) {
Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
43 changes: 17 additions & 26 deletions src/background.js → src/Chrome/background.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,21 @@
const browser = window.browser || window.chrome;
const storage = browser.storage.sync || browser.storage;

async function detectBrowser() {
if (typeof window.browser !== "undefined") {
return "firefox";
} else if (typeof window.chrome !== "undefined") {
return "chrome";
} else {
return "unknown";
}
}
const __browser__ = chrome;
const __storage__ = __browser__.storage.local;

// Store for whitelisted domains
let whitelist = [];

// Add a storage change listener to keep whitelist updated
storage.onChanged.addListener((changes, area) => {
// @NOTE Should revisit this logic to determine if it is necessary.
__storage__.onChanged.addListener((changes, area) => {
if (area === 'local' && changes.whitelist) {
whitelist = changes.whitelist.newValue || [];
}
});

// Initial load
async function init() {
const browserName = await detectBrowser();

let __whitelist__ = "whitelist";
if (browserName === "chrome") __whitelist__ = "[whitelist]";

storage.get(__whitelist__, (result) => {
__storage__.get("whitelist", (result) => {
if (!result) return;
whitelist = result.whitelist || [];
});
}
Expand All @@ -41,21 +28,25 @@ function isDomainWhitelisted(domain, whitelist) {
const cleanDomain = domain.startsWith('.') ? domain.slice(1) : domain;

return whitelist.some((whitelistedDomain) => {
// Exact match
if (cleanDomain === whitelistedDomain) return true;
if (cleanDomain === whitelistedDomain) return true; // Exact match

// Subdomain match (ensure it ends with .whitelistedDomain)
if (cleanDomain.endsWith('.' + whitelistedDomain)) return true;
return false;
});
}

__browser__.tabs.onRemoved.addListener((() => {
// @TODO: #17 Should clear cookies on tab is close unless otherwise specifed
}));

// Listen for window close
browser.windows.onRemoved.addListener(async () => {
const result = await storage.get(['autoPurgeEnabled']);
if (!result.autoPurgeEnabled) return;
__browser__.windows.onRemoved.addListener(async () => {
const result = await __storage__.get(['isEnabledAutoPurge']);
if (!result.isEnabledAutoPurge) return;

// Get all cookies
browser.cookies.getAll({}).then((cookies) => {
__browser__.cookies.getAll({}).then((cookies) => {
cookies.forEach((cookie) => {
const domain = cookie.domain.startsWith('.')
? cookie.domain.slice(1)
Expand All @@ -64,7 +55,7 @@ browser.windows.onRemoved.addListener(async () => {
const isWhitelisted = isDomainWhitelisted(domain, whitelist);

if (!isWhitelisted) {
browser.cookies.remove({
__browser__.cookies.remove({
url: `http${cookie.secure ? 's' : ''}://${cookie.domain}${cookie.path
}`,
name: cookie.name,
Expand Down
Loading

0 comments on commit a91a17b

Please sign in to comment.