Skip to content

Commit 6f2e616

Browse files
authored
[SidePanel API] Add sidePanel.open() cookbook (GoogleChrome#983)
* Init commit * Add sidepanel open cookbook * Add minimum chrome version * Add 116 on readme * Add extension page Add content script * Tweak * Tweak 2 * ¯\_(ツ)_/¯ * Update readme * Update readme * Change sample name in Readme * Bold Chrome 116 for emphasis * Typo fix
1 parent a3966b4 commit 6f2e616

File tree

12 files changed

+144
-4
lines changed

12 files changed

+144
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Opening the side panel through a user interaction
2+
3+
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**.
4+
5+
## Running this extension
6+
7+
1. Clone this repository.
8+
2. Load this directory in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked).
9+
10+
### Test with a context menu
11+
12+
1. Navigate to any page, like [example.com](http://example.com/).
13+
2. Right-click on any word.
14+
3. Choose the context menu "Open side panel".
15+
16+
### Test in an extension page
17+
18+
1. The extension page will open when you install the extension.
19+
2. Click on the "Open side panel" button.
20+
21+
### Test by clicking on an injected element
22+
23+
1. Navigate to [google.com](http://www.google.com/).
24+
2. Scroll to the very bottom of the page.
25+
3. Click on the "Open side panel" button.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const button = new DOMParser().parseFromString(
2+
'<button>Click to open side panel</button>',
3+
'text/html'
4+
).body.firstElementChild;
5+
button.addEventListener('click', function () {
6+
chrome.runtime.sendMessage({ type: 'open_side_panel' });
7+
});
8+
document.body.append(button);
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"manifest_version": 3,
3+
"name": "Open side panel",
4+
"version": "1.0",
5+
"description": "Use user interactions to open the side panel",
6+
"minimum_chrome_version": "116",
7+
"background": {
8+
"service_worker": "service-worker.js"
9+
},
10+
"side_panel": {
11+
"default_path": "sidepanel-global.html"
12+
},
13+
"content_scripts": [
14+
{
15+
"js": ["content-script.js"],
16+
"matches": ["https://www.google.com/*"]
17+
}
18+
],
19+
"permissions": ["sidePanel", "contextMenus"],
20+
"icons": {
21+
"16": "images/icon-16.png",
22+
"48": "images/icon-48.png",
23+
"128": "images/icon-128.png"
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body>
4+
<h1>This is an extension page</h1>
5+
<p>Click on the button below to open the side panel</p>
6+
<button id="openSidePanel">Open side panel</button>
7+
<script src="script.js" type="module"></script>
8+
</body>
9+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// top level await is available in ES modules loaded from script tags
2+
const [tab] = await chrome.tabs.query({
3+
active: true,
4+
lastFocusedWindow: true
5+
});
6+
7+
const tabId = tab.id;
8+
const button = document.getElementById('openSidePanel');
9+
button.addEventListener('click', async () => {
10+
await chrome.sidePanel.open({ tabId });
11+
await chrome.sidePanel.setOptions({
12+
tabId,
13+
path: 'sidepanel-tab.html',
14+
enabled: true
15+
});
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
chrome.runtime.onInstalled.addListener(() => {
16+
chrome.contextMenus.create({
17+
id: 'openSidePanel',
18+
title: 'Open side panel',
19+
contexts: ['all']
20+
});
21+
chrome.tabs.create({ url: 'page.html' });
22+
});
23+
24+
chrome.contextMenus.onClicked.addListener((info, tab) => {
25+
if (info.menuItemId === 'openSidePanel') {
26+
// This will open the panel in all the pages on the current window.
27+
chrome.sidePanel.open({ windowId: tab.windowId });
28+
}
29+
});
30+
31+
chrome.runtime.onMessage.addListener((message, sender) => {
32+
// The callback for runtime.onMessage must return falsy if we're not sending a response
33+
(async () => {
34+
if (message.type === 'open_side_panel') {
35+
// This will open a tab-specific side panel only on the current tab.
36+
await chrome.sidePanel.open({ tabId: sender.tab.id });
37+
await chrome.sidePanel.setOptions({
38+
tabId: sender.tab.id,
39+
path: 'sidepanel-tab.html',
40+
enabled: true
41+
});
42+
}
43+
})();
44+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body>
4+
<h1>Global side panel</h1>
5+
<p>
6+
This is a global side panel, which means it remains open on every tab.
7+
</p>
8+
</body>
9+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body>
4+
<h1>Tab-specific side panel</h1>
5+
<p>This side panel is available and stays open only on the current tab</p>
6+
</body>
7+
</html>

functional-samples/sample.sidepanel-dictionary/manifest.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,5 @@
1313
"side_panel": {
1414
"default_path": "sidepanel.html"
1515
},
16-
"permissions": [
17-
"sidePanel",
18-
"contextMenus"
19-
]
16+
"permissions": ["sidePanel", "contextMenus"]
2017
}

0 commit comments

Comments
 (0)