Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add instructions for injecting button and tab-specific side panel functionality Fixes #1179 #1414

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
21 changes: 19 additions & 2 deletions functional-samples/cookbook.sidepanel-open/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Opening the side panel through a user interaction

This example demonstrates using [`chrome.sidePanel.open()`](https://developer.chrome.com/docs/extensions/reference/sidePanel/#method-open) to open a global side panel through a context menu click and a tab-specific side panel by clicking a button in an extension page or a button click injected by a content script. This feature will be available starting **Chrome 116**.
This example demonstrates using [`chrome.sidePanel.open()`](https://developer.chrome.com/docs/extensions/reference/sidePanel/#method-open) to open a global side panel through a context menu click and a tab-specific side panel by clicking a button on an extension page or by clicking a button injected via a content script. This feature will be available starting **Chrome 116**.

## Running this extension

Expand All @@ -22,4 +22,21 @@ This example demonstrates using [`chrome.sidePanel.open()`](https://developer.ch

1. Navigate to [google.com](http://www.google.com/).
2. Scroll to the very bottom of the page.
3. Click on the "Open side panel" button.
3. You should see a button labeled "Click to open side panel" (this is injected by the content script).
4. Click on the button.
5. The side panel should open, showing the content from `sidepanel-tab.html`. This side panel is tab-specific and will remain open only on the current tab.

### Key Changes:

- **Injected Button on Google**: The extension now injects a button labeled "Click to open side panel" at the bottom of the page on `google.com`. Clicking this button opens a tab-specific side panel with the content from `sidepanel-tab.html`.
- **Tab-Specific Side Panel**: The side panel is now tab-specific when triggered by the injected button on a web page, ensuring it only opens on the current tab, rather than globally.

## Permissions

The extension requires the following permissions:
- `sidePanel`: To interact with Chrome’s side panel API.
- `contextMenus`: To create a context menu item for opening the global side panel.

## Notes

This extension utilizes the new Chrome feature, available starting Chrome 116, that allows opening a side panel through a user interaction.
11 changes: 5 additions & 6 deletions functional-samples/cookbook.sidepanel-open/content-script.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const button = new DOMParser().parseFromString(
'<button>Click to open side panel</button>',
'text/html'
).body.firstElementChild;
button.addEventListener('click', function () {
const button = document.createElement('button');
button.textContent = 'Click to open side panel';
button.addEventListener('click', () => {
chrome.runtime.sendMessage({ type: 'open_side_panel' });
});
document.body.append(button);

document.body.appendChild(button);
14 changes: 9 additions & 5 deletions functional-samples/cookbook.sidepanel-open/manifest.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"manifest_version": 3,
"name": "Open side panel",
"version": "1.0",
"description": "Shows how to call sidePanel.open() to open a global side panel.",
"name": "Open Side Panel",
"version": "1.0.0",
"description": "Demonstrates opening a global and tab-specific side panel using Chrome's sidePanel API.",
"minimum_chrome_version": "116",
"background": {
"service_worker": "service-worker.js"
"service_worker": "service-worker.js",
"type": "module"
},
"action": {
"default_popup": "page.html"
},
"side_panel": {
"default_path": "sidepanel-global.html"
Expand All @@ -16,7 +20,7 @@
"matches": ["https://www.google.com/*"]
}
],
"permissions": ["sidePanel", "contextMenus"],
"permissions": ["sidePanel", "contextMenus", "activeTab"],
"icons": {
"16": "images/icon-16.png",
"48": "images/icon-48.png",
Expand Down
34 changes: 18 additions & 16 deletions functional-samples/cookbook.sidepanel-open/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,29 @@ chrome.runtime.onInstalled.addListener(() => {
title: 'Open side panel',
contexts: ['all']
});

// Automatically open the extension's main page after installation
chrome.tabs.create({ url: 'page.html' });
});

chrome.contextMenus.onClicked.addListener((info, tab) => {
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
if (info.menuItemId === 'openSidePanel') {
// This will open the panel in all the pages on the current window.
chrome.sidePanel.open({ windowId: tab.windowId });
await chrome.sidePanel.open({ tabId: tab.id });
await chrome.sidePanel.setOptions({
tabId: tab.id,
path: 'sidepanel-global.html',
enabled: true
});
}
});

chrome.runtime.onMessage.addListener((message, sender) => {
// The callback for runtime.onMessage must return falsy if we're not sending a response
(async () => {
if (message.type === 'open_side_panel') {
// This will open a tab-specific side panel only on the current tab.
await chrome.sidePanel.open({ tabId: sender.tab.id });
await chrome.sidePanel.setOptions({
tabId: sender.tab.id,
path: 'sidepanel-tab.html',
enabled: true
});
}
})();
chrome.runtime.onMessage.addListener(async (message, sender) => {
if (message.type === 'open_side_panel') {
await chrome.sidePanel.open({ tabId: sender.tab.id });
await chrome.sidePanel.setOptions({
tabId: sender.tab.id,
path: 'sidepanel-tab.html',
enabled: true
});
}
});