Skip to content

Commit

Permalink
Create keyboard clicking context menu in the browser action (#158)
Browse files Browse the repository at this point in the history
* Create keyboard clicking context menu in the browser action
  • Loading branch information
david-tejada authored Jul 20, 2023
1 parent e94a443 commit 20e4bc1
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 27 deletions.
17 changes: 8 additions & 9 deletions src/background/actions/toggleKeyboardClicking.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import browser from "webextension-polyfill";
import { retrieve, store } from "../../common/storage";
import { urls } from "../../common/urls";
import { setBrowserActionIcon } from "../utils/browserAction";

export async function toggleKeyboardClicking() {
const keyboardClicking = await retrieve("keyboardClicking");
await store("keyboardClicking", !keyboardClicking);
const keyboardClickingOld = await retrieve("keyboardClicking");
await store("keyboardClicking", !keyboardClickingOld);
}

browser.storage.onChanged.addListener(async (changes) => {
if ("keyboardClicking" in changes) {
const iconPath = (await retrieve("keyboardClicking"))
? urls.iconKeyboard48.pathname
: urls.icon48.pathname;
await setBrowserActionIcon();

await (browser.action
? browser.action.setIcon({ path: iconPath })
: browser.browserAction.setIcon({ path: iconPath }));
const keyboardClicking = await retrieve("keyboardClicking");
await browser.contextMenus.update("keyboard-clicking", {
checked: keyboardClicking,
});
}
});
10 changes: 7 additions & 3 deletions src/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import { toggleKeyboardClicking } from "./actions/toggleKeyboardClicking";
import { handleRequestFromTalon } from "./messaging/handleRequestFromTalon";
import { handleRequestFromContent } from "./messaging/handleRequestFromContent";
import { sendRequestToContent } from "./messaging/sendRequestToContent";
import { browserAction } from "./utils/browserAction";
import { contextMenusOnClicked } from "./misc/createContextMenus";

// We need to add the listener right away or else clicking the context menu item
// while the background script/service worker is inactive might fail.
browser.contextMenus.onClicked.addListener(contextMenusOnClicked);

(async () => {
await initBackgroundScript();
})();

browser.runtime.onMessage.addListener(handleRequestFromContent);

// MV2: browser.browserAction
// MV3: browser.action
(browser.browserAction ?? browser.action).onClicked.addListener(async () => {
browserAction.onClicked.addListener(async () => {
await toggleHintsGlobal();
});

Expand Down
27 changes: 27 additions & 0 deletions src/background/misc/createContextMenus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import browser from "webextension-polyfill";
import { retrieve } from "../../common/storage";
import { toggleKeyboardClicking } from "../actions/toggleKeyboardClicking";

export async function createContextMenus() {
const keyboardClicking = await retrieve("keyboardClicking");

const contexts: browser.Menus.ContextType[] = browser.browserAction
? ["browser_action"]
: ["action"];

browser.contextMenus.create({
id: "keyboard-clicking",
title: "Keyboard Clicking",
type: "checkbox",
contexts,
checked: keyboardClicking,
});
}

export async function contextMenusOnClicked({
menuItemId,
}: browser.Menus.OnClickData) {
if (menuItemId === "keyboard-clicking") {
await toggleKeyboardClicking();
}
}
17 changes: 10 additions & 7 deletions src/background/setup/initBackgroundScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import {
} from "../../common/storage";
import { urls } from "../../common/urls";
import { watchNavigation } from "../hints/watchNavigation";
import { createContextMenus } from "../misc/createContextMenus";
import { resetTabMarkers } from "../misc/tabMarkers";
import { setBrowserActionIcon } from "../utils/browserAction";
import { isSafari } from "../utils/isSafari";
import { trackRecentTabs } from "./trackRecentTabs";

/**
Expand Down Expand Up @@ -55,6 +58,9 @@ export async function initBackgroundScript() {
async ({ reason, previousVersion }) => {
if (reason !== "install" && reason !== "update") return;

await setBrowserActionIcon();
await createContextMenus();

const switchedToSyncStorage = await retrieve("switchedToSyncStorage");
if (!switchedToSyncStorage) await switchToSyncStorage();

Expand Down Expand Up @@ -108,14 +114,11 @@ export async function initBackgroundScript() {
browser.runtime.onStartup.addListener(async () => {
await resetTabMarkers();
await resetHintsStacks();
await setBrowserActionIcon();

const keyboardClicking = await retrieve("keyboardClicking");
if (keyboardClicking) {
await (browser.action
? browser.action.setIcon({ path: urls.iconKeyboard48.pathname })
: browser.browserAction.setIcon({
path: urls.iconKeyboard48.pathname,
}));
// In Safari we need to create the menus every time the browser starts.
if (isSafari()) {
await createContextMenus();
}

await store("hintsToggleTabs", new Map());
Expand Down
25 changes: 25 additions & 0 deletions src/background/utils/browserAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import browser from "webextension-polyfill";
import { urls } from "../../common/urls";
import { retrieve } from "../../common/storage";

/**
* `browser.browserAction` for MV2 and `browser.action` for MV3.
*/
export const browserAction = browser.action
? browser.action
: browser.browserAction;

/**
* Set the browserAction icon depending on wether keyboardClicking is enabled.
*/
export async function setBrowserActionIcon() {
const keyboardClicking = await retrieve("keyboardClicking");
const iconPath = keyboardClicking
? urls.iconKeyboard48.pathname
: urls.icon48.pathname;

// I can't use await here because of a bug in Safari that makes the promise
// to never resolve and any further code not to execute. The bug seems to be
// fixed in recent versions of Safari (^16.4).
void browserAction.setIcon({ path: iconPath });
}
6 changes: 1 addition & 5 deletions src/background/utils/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import {
ResponseToTalon,
} from "../../typings/RequestFromTalon";
import { notify } from "./notify";

function isSafari(): boolean {
if (!navigator.vendor) return false;
return navigator.vendor.includes("Apple");
}
import { isSafari } from "./isSafari";

async function getClipboardManifestV3(): Promise<string | undefined> {
const hasDocument = await chrome.offscreen.hasDocument();
Expand Down
4 changes: 4 additions & 0 deletions src/background/utils/isSafari.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function isSafari(): boolean {
if (!navigator.vendor) return false;
return navigator.vendor.includes("Apple");
}
3 changes: 2 additions & 1 deletion src/mv2-safari/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"clipboardWrite",
"notifications",
"nativeMessaging",
"webNavigation"
"webNavigation",
"contextMenus"
],
"content_scripts": [
{
Expand Down
3 changes: 2 additions & 1 deletion src/mv2/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"clipboardRead",
"clipboardWrite",
"notifications",
"webNavigation"
"webNavigation",
"contextMenus"
],
"content_scripts": [
{
Expand Down
3 changes: 2 additions & 1 deletion src/mv3/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"clipboardWrite",
"notifications",
"webNavigation",
"offscreen"
"offscreen",
"contextMenus"
],
"content_scripts": [
{
Expand Down

0 comments on commit 20e4bc1

Please sign in to comment.