Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"@commitlint/cli": "^20.0.0",
"@commitlint/config-conventional": "^20.0.0",
"@release-it/conventional-changelog": "^10.0.1",
"@types/chrome": "^0.1.12",
"@types/chrome": "^0.1.36",
"@types/jest": "^30.0.0",
"husky": "^9.1.7",
"jest": "^30.1.3",
Expand Down
131 changes: 97 additions & 34 deletions src/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type Color = string | ColorArray;
type ColorArray = chrome.extensionTypes.ColorArray;

type OpenOptions = chrome.sidePanel.OpenOptions;
type CloseOptions = chrome.sidePanel.CloseOptions;
type PanelOptions = chrome.sidePanel.PanelOptions;
type PanelBehavior = chrome.sidePanel.PanelBehavior;
type IconDetails = opr.sidebarAction.IconDetails;
Expand All @@ -19,6 +20,8 @@ const isAvailableOperaSidebar = (): boolean => globalThis?.opr?.sidebarAction !=
// Chromium standard
const sidePanel = (): typeof chrome.sidePanel | undefined => browser().sidePanel;

export class SidebarError extends Error {}

// Methods
export const getSidebarOptions = (tabId?: number): Promise<PanelOptions> =>
callWithPromise(cb => {
Expand Down Expand Up @@ -56,8 +59,22 @@ export const canOpenSidebar = (): boolean => {
return false;
};

export const canCloseSidebar = (): boolean => {
if (sidePanel()) {
return true;
}

const sb = (sidebarAction() as FirefoxSidebarAction) || undefined;

if (sb) {
return !!sb.close;
}

return false;
};

export const openSidebar = (options: OpenOptions): Promise<void> =>
callWithPromise(cb => {
callWithPromise(async cb => {
const sp = sidePanel();

if (sp) {
Expand All @@ -67,22 +84,47 @@ export const openSidebar = (options: OpenOptions): Promise<void> =>
const sb = sidebarAction() as FirefoxSidebarAction | undefined;

if (sb?.open) {
return sb.open();
const result = sb.open();

if (result instanceof Promise) {
await result;
}

return cb();
}

throw new SidebarError("The sidebarAction.open API is not supported in this browser");
});

export const closeSidebar = (options: CloseOptions): Promise<void> =>
callWithPromise(async cb => {
const sp = sidePanel();

if (sp) {
return sp.close(options, cb);
}

console.warn("The sidebar open API is not supported in this browser");
const sb = sidebarAction() as FirefoxSidebarAction | undefined;

if (sb?.close) {
const result = sb.close();

cb();
if (result instanceof Promise) {
await result;
}

return cb();
}

throw new SidebarError("The sidebarAction.close API is not supported in this browser");
});

export const setSidebarOptions = (options?: PanelOptions): Promise<void> =>
callWithPromise(cb => {
const sp = sidePanel();

if (!sp) {
console.warn("The chrome.sidePanel.setOptions API is not supported for this browser");

return cb();
throw new SidebarError("The chrome.sidePanel.setOptions API is not supported for this browser");
}

sp.setOptions(options || {}, cb);
Expand All @@ -93,12 +135,44 @@ export const setSidebarBehavior = (behavior?: PanelBehavior): Promise<void> =>
const sp = sidePanel();

if (!sp) {
console.warn("The chrome.sidePanel.setPanelBehavior API is not supported in this browser");
throw new SidebarError("The chrome.sidePanel.setPanelBehavior API is not supported in this browser");
}

sp.setPanelBehavior(behavior || {}, cb);
});

export const isOpenSidebar = (windowId?: number): Promise<boolean> =>
callWithPromise(async cb => {
const sb = sidebarAction() as FirefoxSidebarAction | undefined;

if (sb?.isOpen) {
const result = sb.isOpen({windowId});

if (result instanceof Promise) {
return cb(await result);
} else {
return cb(result);
}
}

throw new SidebarError("The sidebarAction.isOpen API is not supported in this browser");
});

export const toggleSidebar = (): Promise<void> =>
callWithPromise(async cb => {
const sb = sidebarAction() as FirefoxSidebarAction | undefined;

if (sb?.toggle) {
const result = sb.toggle();

if (result instanceof Promise) {
await result;
}

return cb();
}

sp.setPanelBehavior(behavior || {}, cb);
throw new SidebarError("The sidebarAction.toggle API is not supported in this browser");
});

// Customs methods
Expand Down Expand Up @@ -153,19 +227,16 @@ export const setSidebarTitle = (title: string | number, tabId?: number): Promise
callWithPromise(async cb => {
const sb = sidebarAction();

if (!sb) {
console.warn("The sidebarAction.setTitle API is supported only in Opera or Firefox");
if (sb?.setTitle) {
const result = sb.setTitle({tabId, title: title.toString()});

if (result instanceof Promise) {
await result;
}
return cb();
}

const result = sb.setTitle({tabId, title: title.toString()});

if (result instanceof Promise) {
await result;
}

cb();
throw new SidebarError("The sidebarAction.setTitle API is supported only in Opera or Firefox");
});

export const setSidebarBadgeText = (text: string | number, tabId?: number): Promise<void> =>
Expand All @@ -178,9 +249,7 @@ export const setSidebarBadgeText = (text: string | number, tabId?: number): Prom
return cb();
}

console.warn("The opr.sidebarAction.setBadgeText API is supported only in Opera");

cb();
throw new SidebarError("The sidebarAction.setBadgeText API is supported only in Opera");
});

export const clearSidebarBadgeText = (tabId?: number): Promise<void> => setSidebarBadgeText("", tabId);
Expand Down Expand Up @@ -211,9 +280,7 @@ export const setSidebarIcon = (details: IconDetails): Promise<void> =>
return cb();
}

console.warn("The sidebarAction.setIcon API is supported only in Opera or Firefox");

cb();
throw new SidebarError("The sidebarAction.setIcon API is supported only in Opera or Firefox");
});

export const setSidebarBadgeTextColor = (color: Color, tabId?: number): Promise<void> =>
Expand All @@ -226,9 +293,7 @@ export const setSidebarBadgeTextColor = (color: Color, tabId?: number): Promise<
return cb();
}

console.warn("The opr.sidebarAction.setBadgeTextColor API is supported only in Opera");

cb();
throw new SidebarError("The sidebarAction.setBadgeTextColor API is supported only in Opera");
});

export const setSidebarBadgeBgColor = (color: Color, tabId?: number): Promise<void> =>
Expand All @@ -241,9 +306,7 @@ export const setSidebarBadgeBgColor = (color: Color, tabId?: number): Promise<vo
return cb();
}

console.warn("The opr.sidebarAction.setBadgeBackgroundColor API is supported only in Opera");

cb();
throw new SidebarError("The sidebarAction.setBadgeBackgroundColor API is supported only in Opera");
});

export const getSidebarTitle = (tabId?: number): Promise<string> =>
Expand All @@ -258,7 +321,7 @@ export const getSidebarTitle = (tabId?: number): Promise<string> =>
return (sb as any).getTitle({tabId});
}

throw new Error("The sidebarAction.getTitle API not available");
throw new SidebarError("The sidebarAction.getTitle API not available");
});

export const getSidebarBadgeText = (tabId?: number): Promise<string> =>
Expand All @@ -269,7 +332,7 @@ export const getSidebarBadgeText = (tabId?: number): Promise<string> =>
return sb.getBadgeText({tabId}, cb);
}

throw new Error("The opr.sidebarAction.getBadgeText API is supported only in Opera");
throw new SidebarError("The sidebarAction.getBadgeText API is supported only in Opera");
});

export const getSidebarBadgeTextColor = (tabId?: number): Promise<ColorArray> =>
Expand All @@ -280,7 +343,7 @@ export const getSidebarBadgeTextColor = (tabId?: number): Promise<ColorArray> =>
return sb.getBadgeTextColor({tabId}, cb);
}

throw new Error("The opr.sidebarAction.getBadgeTextColor API is supported only in Opera");
throw new SidebarError("The sidebarAction.getBadgeTextColor API is supported only in Opera");
});

export const getSidebarBadgeBgColor = (tabId?: number): Promise<ColorArray> =>
Expand All @@ -291,5 +354,5 @@ export const getSidebarBadgeBgColor = (tabId?: number): Promise<ColorArray> =>
return sb.getBadgeBackgroundColor({tabId}, cb);
}

throw new Error("The opr.sidebarAction.getBadgeBackgroundColor API is supported only in Opera");
throw new SidebarError("The sidebarAction.getBadgeBackgroundColor API is supported only in Opera");
});