Compare commits
4 Commits
4f9b7b81e0
...
645e0e066a
Author | SHA1 | Date |
---|---|---|
Bauke | 645e0e066a | |
Bauke | a05f54306a | |
Bauke | cd453b3e6f | |
Bauke | e5bf102aa3 |
|
@ -0,0 +1,56 @@
|
|||
import browser from 'webextension-polyfill';
|
||||
|
||||
import {updateBadge} from '../utilities/badge.js';
|
||||
|
||||
type ContextMenu = browser.Menus.CreateCreatePropertiesType;
|
||||
|
||||
export function getContextMenus(): ContextMenu[] {
|
||||
const actionContext =
|
||||
import.meta.env.VITE_BROWSER === 'chromium' ? 'action' : 'browser_action';
|
||||
|
||||
const contextMenus: ContextMenu[] = [
|
||||
{
|
||||
id: 're-nav-toggle-redirects',
|
||||
title: 'Toggle all redirects',
|
||||
contexts: [actionContext],
|
||||
},
|
||||
];
|
||||
|
||||
return contextMenus;
|
||||
}
|
||||
|
||||
export async function initializeContextMenus(): Promise<void> {
|
||||
const contextMenus = getContextMenus();
|
||||
|
||||
await browser.contextMenus.removeAll();
|
||||
|
||||
for (const contextMenu of contextMenus) {
|
||||
browser.contextMenus.create(contextMenu, contextCreated);
|
||||
}
|
||||
}
|
||||
|
||||
function contextCreated(): void {
|
||||
const error = browser.runtime.lastError;
|
||||
|
||||
if (error !== null && error !== undefined) {
|
||||
console.error('Re-Nav', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
export async function contextClicked(
|
||||
contextMenuIds: Set<string>,
|
||||
info: browser.Menus.OnClickData,
|
||||
tab?: browser.Tabs.Tab,
|
||||
): Promise<void> {
|
||||
const id = info.menuItemId.toString();
|
||||
if (!contextMenuIds.has(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id === 're-nav-toggle-redirects') {
|
||||
const state = await browser.storage.local.get({redirectsEnabled: true});
|
||||
const redirectsEnabled = !(state.redirectsEnabled as boolean);
|
||||
await browser.storage.local.set({redirectsEnabled});
|
||||
await updateBadge(redirectsEnabled);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,12 @@
|
|||
import browser from 'webextension-polyfill';
|
||||
|
||||
import storage from '../redirect/storage.js';
|
||||
import {updateBadge} from '../utilities/badge.js';
|
||||
import {
|
||||
contextClicked,
|
||||
getContextMenus,
|
||||
initializeContextMenus,
|
||||
} from './context-menus.js';
|
||||
|
||||
async function browserActionClicked() {
|
||||
await browser.runtime.openOptionsPage();
|
||||
|
@ -10,15 +16,30 @@ if (import.meta.env.VITE_BROWSER === 'chromium') {
|
|||
browser.action.onClicked.addListener(browserActionClicked);
|
||||
} else {
|
||||
browser.browserAction.onClicked.addListener(browserActionClicked);
|
||||
void initializeContextMenus();
|
||||
}
|
||||
|
||||
browser.runtime.onInstalled.addListener(async () => {
|
||||
await initializeContextMenus();
|
||||
await updateBadge();
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
await browser.runtime.openOptionsPage();
|
||||
}
|
||||
});
|
||||
|
||||
browser.runtime.onStartup.addListener(async () => {
|
||||
await updateBadge();
|
||||
});
|
||||
|
||||
browser.webNavigation.onBeforeNavigate.addListener(async (details) => {
|
||||
const {redirectsEnabled} = await browser.storage.local.get({
|
||||
redirectsEnabled: true,
|
||||
});
|
||||
if (redirectsEnabled === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!details.url.startsWith('http') || details.frameId > 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -29,6 +50,10 @@ browser.webNavigation.onBeforeNavigate.addListener(async (details) => {
|
|||
return;
|
||||
}
|
||||
|
||||
const tab = await browser.tabs.query({active: true, lastFocusedWindow: true});
|
||||
const currentTabUrl =
|
||||
tab[0]?.url === undefined ? undefined : new URL(tab[0].url);
|
||||
|
||||
const url = new URL(details.url);
|
||||
const {latestUrl} = await browser.storage.local.get('latestUrl');
|
||||
if (redirectDelta < 30_000 && url.href === latestUrl) {
|
||||
|
@ -41,6 +66,15 @@ browser.webNavigation.onBeforeNavigate.addListener(async (details) => {
|
|||
}
|
||||
|
||||
if (redirect.isMatch(url)) {
|
||||
// Don't redirect if the URL before going to a new page is also a match.
|
||||
// This will happen when the user is already on a website that has a
|
||||
// redirect, but for whatever reason hasn't redirected. So it's safe to
|
||||
// assume that they want to stay on this website, rather than get
|
||||
// redirected.
|
||||
if (currentTabUrl !== undefined && redirect.isMatch(currentTabUrl)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const redirectedUrl = redirect.redirect(url);
|
||||
await browser.tabs.update(details.tabId, {url: redirectedUrl.href});
|
||||
await browser.storage.local.set({
|
||||
|
@ -51,3 +85,12 @@ browser.webNavigation.onBeforeNavigate.addListener(async (details) => {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
browser.contextMenus.onClicked.addListener(async (info, tab) => {
|
||||
const contextMenus = getContextMenus();
|
||||
const contextMenuIds = new Set<string>(
|
||||
contextMenus.map(({id}) => id ?? 're-nav-unknown'),
|
||||
);
|
||||
|
||||
await contextClicked(contextMenuIds, info, tab);
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ export default function createManifest(
|
|||
name: 'Re-Nav',
|
||||
description: 'Navigation redirects for the masses.',
|
||||
version: '0.1.1',
|
||||
permissions: ['storage', 'webNavigation'],
|
||||
permissions: ['contextMenus', 'storage', 'tabs', 'webNavigation'],
|
||||
options_ui: {
|
||||
page: 'options/index.html',
|
||||
open_in_tab: true,
|
||||
|
|
|
@ -68,7 +68,7 @@ export class PageMain extends Component<Props, State> {
|
|||
id: await storage.nextRedirectId(),
|
||||
matcherType: 'hostname',
|
||||
matcherValue: 'example.com',
|
||||
redirectType: 'simple',
|
||||
redirectType: 'hostname',
|
||||
redirectValue: 'example.org',
|
||||
});
|
||||
await storage.savePrepared(await storage.prepareForStorage(redirect));
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import browser from 'webextension-polyfill';
|
||||
|
||||
export async function updateBadge(redirectsEnabled?: boolean): Promise<void> {
|
||||
if (redirectsEnabled === undefined) {
|
||||
const state = await browser.storage.local.get({redirectsEnabled: true});
|
||||
redirectsEnabled = state.redirectsEnabled as boolean;
|
||||
}
|
||||
|
||||
let action: browser.Action.Static = browser.browserAction;
|
||||
if (import.meta.env.VITE_BROWSER === 'chromium') {
|
||||
action = browser.action;
|
||||
}
|
||||
|
||||
await action.setBadgeText({
|
||||
text: redirectsEnabled ? '' : '✗',
|
||||
});
|
||||
|
||||
await action.setBadgeBackgroundColor({
|
||||
color: '#f99fb1',
|
||||
});
|
||||
|
||||
if (import.meta.env.VITE_BROWSER === 'firefox') {
|
||||
action.setBadgeTextColor({color: '#2a2041'});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue