Skip to content

Commit 49728cd

Browse files
authored
Convert MV2 optional permission example to MV3 (GoogleChrome#792)
* Convert optional perms to MV3 * Add readme * change size * Update SS * Update readme * Convert callback to promises
1 parent c72cd1c commit 49728cd

File tree

9 files changed

+237
-0
lines changed

9 files changed

+237
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## Optional permissions in a new tab
2+
3+
This new tab extension demonstrates how extensions can provide users the option to enable an additional feature. In this example, they optionally display top sites.
4+
5+
See [Optional permissions](https://developer.chrome.com/docs/extensions/reference/permissions/) to learn more.
6+
7+
## Testing the extension
8+
9+
Follow the instructions to load an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked, then open a new tab.
10+
11+
It should look like this:
12+
13+
<img src="https://wd.imgix.net/image/BhuKGJaIeLNPW9ehns59NfwqKxF2/28zBZUTWK1aAZPnKs4ZD.png" alt="New tab with the focus of the day and optional feature button" width="500"/>
14+
15+
Then, click on "Allow Extension to Access to top sites". You will see the following message:
16+
17+
<img src="https://wd.imgix.net/image/BhuKGJaIeLNPW9ehns59NfwqKxF2/rPN5Co1OdkuIZpfAAgPg.png" alt="Allow permissions dialog" width="400"/>
18+
19+
If you accept, it will display a list of your top sites.
20+
21+
<img src="https://wd.imgix.net/image/BhuKGJaIeLNPW9ehns59NfwqKxF2/ibZ6PqWHsU2v0Y1h0ig2.png" alt="New tab displaying top sites" width="400"/>
22+
9.89 KB
Loading
767 Bytes
Loading
1.78 KB
Loading
2.86 KB
Loading
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "Optional Permissions New Tab",
3+
"version": "1.0.0",
4+
"description": "Demonstrates optional permissions in extensions",
5+
"permissions": ["storage"],
6+
"optional_permissions": [
7+
"topSites"
8+
],
9+
"icons": {
10+
"16": "images/icon16.png",
11+
"32": "images/icon32.png",
12+
"48": "images/icon48.png",
13+
"128": "images/icon128.png"
14+
},
15+
"chrome_url_overrides": {
16+
"newtab": "newtab.html"
17+
},
18+
"manifest_version": 3
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>New Tab - Optional Permissions</title>
6+
<link rel="stylesheet" type="text/css" href="style.css">
7+
</head>
8+
<body>
9+
<div id="todo_div" class="center colorFun">
10+
<h1 id="display_todo"></h1>
11+
</div>
12+
<div id="display_top"></div>
13+
<form class="center">
14+
<input id="todo_value" placeholder="My focus today is..." />
15+
<input type="submit" value="Submit">
16+
</form>
17+
<footer></footer>
18+
<script src="newtab.js"></script>
19+
</body>
20+
</html>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2022 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+
'use strict';
16+
17+
const newPerms = {
18+
permissions: ['topSites']
19+
};
20+
21+
const sites_div = document.getElementById('display_top');
22+
const todo = document.getElementById('display_todo');
23+
const form = document.querySelector('form');
24+
const footer = document.querySelector('footer');
25+
26+
const createTop = () => { chrome.topSites.get((topSites) => {
27+
topSites.forEach((site) => {
28+
let div = document.createElement('div');
29+
div.className = 'colorFun';
30+
let tooltip = document.createElement('span');
31+
tooltip.innerText = site.title;
32+
tooltip.className = 'tooltip';
33+
let url = document.createElement('a');
34+
url.href = site.url;
35+
let hostname = (new URL(site.url)).hostname;
36+
let image = document.createElement('img');
37+
image.title = site.title;
38+
image.src = 'https://logo.clearbit.com/' + hostname;
39+
url.appendChild(image);
40+
div.appendChild(url);
41+
div.appendChild(tooltip);
42+
sites_div.appendChild(div);
43+
})
44+
})};
45+
46+
47+
48+
chrome.permissions.contains({permissions: ['topSites']}).then((result)=>{
49+
if (result) {
50+
// The extension has the permissions.
51+
createTop();
52+
} else {
53+
// The extension doesn't have the permissions.
54+
let button = document.createElement('button');
55+
button.innerText = 'Allow Extension to Access Top Sites';
56+
button.addEventListener('click', (event) => {
57+
chrome.permissions.request(newPerms).then((granted) => {
58+
if (granted) {
59+
console.log('granted');
60+
sites_div.innerText = '';
61+
createTop();
62+
} else {
63+
console.log('not granted');
64+
}
65+
});
66+
});
67+
footer.appendChild(button);
68+
}
69+
})
70+
71+
form.addEventListener('submit', () => {
72+
let todo_value = document.getElementById('todo_value');
73+
chrome.storage.sync.set({todo: todo_value.value});
74+
});
75+
76+
function setToDo() {
77+
chrome.storage.sync.get(['todo']).then((value)=>{
78+
if (!value.todo) {
79+
todo.innerText = '';
80+
} else {
81+
todo.innerText = value.todo;
82+
}
83+
})
84+
};
85+
86+
setToDo();
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/* Copyright 2022 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+
h1 {
16+
font-family: Verdana, Geneva, Tahoma, sans-serif;
17+
}
18+
19+
#display_top {
20+
margin: auto;
21+
width: 600px;
22+
}
23+
24+
#todo_div {
25+
margin-top: 0px;
26+
height: 100px;
27+
width: 100%;
28+
display: flex;
29+
align-items: center;
30+
justify-content: center;
31+
}
32+
33+
.center {
34+
display: flex;
35+
align-items: center;
36+
justify-content: center;
37+
}
38+
39+
@keyframes color-extravaganza {
40+
0% {background-color: #4285F4;}
41+
10% {background-color: #4285F4;}
42+
25% {background-color: #EA4335;}
43+
50% {background-color: #FBBC04;}
44+
100% {background-color: #34A853;}
45+
}
46+
47+
.colorFun {
48+
position: relative;
49+
height: 100px;
50+
width: 100px;
51+
padding: 10px;
52+
display: inline-block;
53+
margin-top: 60px;
54+
}
55+
56+
.colorFun .tooltip {
57+
visibility: hidden;
58+
width: 120px;
59+
color: #fff;
60+
text-align: center;
61+
padding: 5px 0;
62+
border-radius: 6px;
63+
position: absolute;
64+
z-index: 1;
65+
bottom: 0%;
66+
left: 50%;
67+
margin-left: -60px;
68+
opacity: 0;
69+
transition: opacity 0.3s;
70+
}
71+
72+
73+
#todo_div, .colorFun:hover .tooltip {
74+
visibility: visible;
75+
opacity: 1;
76+
animation-name: color-extravaganza;
77+
animation-duration: 6s;
78+
animation-iteration-count: infinite;
79+
animation-direction: alternate;
80+
}
81+
82+
img {
83+
width: 100px;
84+
}
85+
86+
footer {
87+
position: absolute;
88+
bottom: 20px;
89+
left: 20px;
90+
}

0 commit comments

Comments
 (0)