Skip to content

Commit

Permalink
Update dictionary sample to use sidePanel.open() (GoogleChrome#1087)
Browse files Browse the repository at this point in the history
* Update dictionary sample to use sidePanel.open()

Updates the dictionary side panel example to use the
sidePanel.open() API. This means we are also able to demonstrate
a way of safely passing data to the side panel without hitting
any race conditions.

* Address feedback
  • Loading branch information
oliverdunk authored Feb 20, 2024
1 parent 7326583 commit 8a4c25d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 23 deletions.
21 changes: 13 additions & 8 deletions functional-samples/sample.sidepanel-dictionary/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@ This example allows users to right-click on a word and see the definition on the

NOTE: This example only defines the word extensions and popup.

## Implementation Notes

When the user selects a word, we need to send it to the side panel, but that
may not be open yet. To handle this we store the word in
`chrome.storage.session`, which results in the following:

- If the side panel is already open, the `storage.session.onChanged` event
will fire in the side panel.
- Otherwise, the value will be loaded from storage when the side panel opens.

## Running this extension

1. Clone this repository.
2. Load this directory in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked).
3. Open the side panel UI
4. Choose the "Dictionary side panel".

<img src="https://wd.imgix.net/image/BhuKGJaIeLNPW9ehns59NfwqKxF2/9QJK3CNx71t67M3MlIUY.png?auto=format&w=385" alt="Dictionary side panel">

5. Go to https://developer.chrome.com/docs/extensions/
6. Right-click on the "Extensions" word.
7. Choose the "Define" context menu
3. Go to https://developer.chrome.com/docs/extensions/
4. Right-click on the "Extensions" word.
5. Choose the "Define" context menu

You should see the definition on the side panel

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
"side_panel": {
"default_path": "sidepanel.html"
},
"permissions": ["sidePanel", "contextMenus"]
"permissions": ["sidePanel", "contextMenus", "storage"]
}
11 changes: 6 additions & 5 deletions functional-samples/sample.sidepanel-dictionary/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ chrome.runtime.onInstalled.addListener(() => {
setupContextMenu();
});

chrome.contextMenus.onClicked.addListener((data) => {
chrome.runtime.sendMessage({
name: 'define-word',
data: { value: data.selectionText }
});
chrome.contextMenus.onClicked.addListener((data, tab) => {
// Store the last word in chrome.storage.session.
chrome.storage.session.set({ lastWord: data.selectionText });

// Make sure the side panel is open.
chrome.sidePanel.open({ tabId: tab.id });
});
35 changes: 26 additions & 9 deletions functional-samples/sample.sidepanel-dictionary/sidepanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,31 @@ const words = {
"A UI surface which appears when an extension's action icon is clicked."
};

chrome.runtime.onMessage.addListener(({ name, data }) => {
if (name === 'define-word') {
// Hide instructions.
document.body.querySelector('#select-a-word').style.display = 'none';

// Show word and definition.
document.body.querySelector('#definition-word').innerText = data.value;
document.body.querySelector('#definition-text').innerText =
words[data.value.toLowerCase()];
chrome.storage.session.get('lastWord', ({ lastWord }) => {
updateDefinition(lastWord);
});

chrome.storage.session.onChanged.addListener((changes) => {
const lastWordChange = changes['lastWord'];

if (!lastWordChange) {
return;
}

updateDefinition(lastWordChange.newValue);
});

function updateDefinition(word) {
// If the side panel was opened manually, rather than using the context menu,
// we might not have a word to show the definition for.
if (!word) return;

// Hide instructions.
document.body.querySelector('#select-a-word').style.display = 'none';

// Show word and definition.
document.body.querySelector('#definition-word').innerText = word;
document.body.querySelector('#definition-text').innerText =
words[word.toLowerCase()] ??
`Unknown word! Supported words: ${Object.keys(words).join(', ')}`;
}

0 comments on commit 8a4c25d

Please sign in to comment.