diff --git a/functional-samples/tutorial.focus-mode-debugging/README.md b/functional-samples/tutorial.focus-mode-debugging/README.md new file mode 100644 index 0000000000..b31270b1c2 --- /dev/null +++ b/functional-samples/tutorial.focus-mode-debugging/README.md @@ -0,0 +1,14 @@ +# Oliver Focus Mode + +Extension used in the [Debugging Chrome extensions](https://www.youtube.com/watch?v=Ta-YTDhiBIQ) DevTools Tips video. This extension simplifies the styling of the extensions and Chrome Web Store documentation pages so that they are easier to read when the action icon is clicked. + +This extension is based on the [Focus Mode](/functional-samples/tutorial.focus-mode/) extension. + +**Note:** `background.js` and `focus-mode.js` are intentionally broken. Try to fix them, and compare your fixes with the code in the `fixed` folder. + +## 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. Visit a page in the Extensions or Chrome Web Store sections on developer.chrome.com, e.g https://developer.chrome.com/docs/extensions/mv3/getstarted/tut-focus-mode/. +4. Click the extension icon to toggle focus mode. diff --git a/functional-samples/tutorial.focus-mode-debugging/background.js b/functional-samples/tutorial.focus-mode-debugging/background.js new file mode 100644 index 0000000000..7e153923be --- /dev/null +++ b/functional-samples/tutorial.focus-mode-debugging/background.js @@ -0,0 +1,44 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +chrome.runtime.onInstalled.addListener(() => { + chrome.action.setBadgeText({ + text: 'OFF' + }); +}); + +const extensions = 'https://developer.chrome.com/docs/extensions'; +const webstore = 'https://developer.chrome.com/docs/webstore'; + +// When the user clicks on the extension action +chrome.action.onClicked.addListener(async (tab) => { + if (tab.url?.startsWith(extensions) || tab.url?.startsWith(webstore)) { + // We retrieve the action badge to check if the extension is 'ON' or 'OFF' + const prevState = await chrome.action.getBadgeText({ tabId: tab.id }); + // Next state will always be the opposite + const nextState = prevState === 'ON' ? 'OFF' : 'ON'; + + // Set the action badge to the next state + await chrome.action.setBadgeText({ + tabId: tab.id, + text: nextState + }); + + if (nextState === 'ON') { + chrome.tabs.sendMessage(tab.id, { data: 'focus-on' }); + } else if (nextState === 'OFF') { + chrome.tabs.sendMessage(tab.id, { data: 'focus-off' }); + } + } +}); diff --git a/functional-samples/tutorial.focus-mode-debugging/fixed/background.js b/functional-samples/tutorial.focus-mode-debugging/fixed/background.js new file mode 100644 index 0000000000..7e153923be --- /dev/null +++ b/functional-samples/tutorial.focus-mode-debugging/fixed/background.js @@ -0,0 +1,44 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +chrome.runtime.onInstalled.addListener(() => { + chrome.action.setBadgeText({ + text: 'OFF' + }); +}); + +const extensions = 'https://developer.chrome.com/docs/extensions'; +const webstore = 'https://developer.chrome.com/docs/webstore'; + +// When the user clicks on the extension action +chrome.action.onClicked.addListener(async (tab) => { + if (tab.url?.startsWith(extensions) || tab.url?.startsWith(webstore)) { + // We retrieve the action badge to check if the extension is 'ON' or 'OFF' + const prevState = await chrome.action.getBadgeText({ tabId: tab.id }); + // Next state will always be the opposite + const nextState = prevState === 'ON' ? 'OFF' : 'ON'; + + // Set the action badge to the next state + await chrome.action.setBadgeText({ + tabId: tab.id, + text: nextState + }); + + if (nextState === 'ON') { + chrome.tabs.sendMessage(tab.id, { data: 'focus-on' }); + } else if (nextState === 'OFF') { + chrome.tabs.sendMessage(tab.id, { data: 'focus-off' }); + } + } +}); diff --git a/functional-samples/tutorial.focus-mode-debugging/fixed/focus-mode.js b/functional-samples/tutorial.focus-mode-debugging/fixed/focus-mode.js new file mode 100644 index 0000000000..889d4ee4dd --- /dev/null +++ b/functional-samples/tutorial.focus-mode-debugging/fixed/focus-mode.js @@ -0,0 +1,24 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +chrome.runtime.onMessage.addListener((msg) => { + switch (msg.data) { + case 'focus-on': + document.body.setAttribute('data-focus-mode', 'on'); + break; + case 'focus-off': + document.body.removeAttribute('data-focus-mode'); + break; + } +}); diff --git a/functional-samples/tutorial.focus-mode-debugging/focus-mode.css b/functional-samples/tutorial.focus-mode-debugging/focus-mode.css new file mode 100644 index 0000000000..254fa88219 --- /dev/null +++ b/functional-samples/tutorial.focus-mode-debugging/focus-mode.css @@ -0,0 +1,29 @@ +/* +Copyright 2023 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +body[data-focus-mode='on'] + > .scaffold + > :is(top-nav, navigation-rail, side-nav, footer), +body[data-focus-mode='on'] main > :not(:last-child), +body[data-focus-mode='on'] main > :last-child > navigation-tree, +body[data-focus-mode='on'] main .toc-container { + display: none; +} + +body[data-focus-mode='on'] main > :last-child { + margin-top: min(10vmax, 10rem); + margin-bottom: min(10vmax, 10rem); +} diff --git a/functional-samples/tutorial.focus-mode-debugging/focus-mode.js b/functional-samples/tutorial.focus-mode-debugging/focus-mode.js new file mode 100644 index 0000000000..b3a838fab8 --- /dev/null +++ b/functional-samples/tutorial.focus-mode-debugging/focus-mode.js @@ -0,0 +1,24 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +chrome.runtime.onMessage.addListener((msg) => { + switch (msg) { + case 'focus-on': + document.body.setAttribute('data-focus-mode', 'on'); + break; + case 'focus-off': + document.body.removeAttribute('data-focus-mode'); + break; + } +}); diff --git a/functional-samples/tutorial.focus-mode-debugging/images/icon-128.png b/functional-samples/tutorial.focus-mode-debugging/images/icon-128.png new file mode 100644 index 0000000000..2088c59e96 Binary files /dev/null and b/functional-samples/tutorial.focus-mode-debugging/images/icon-128.png differ diff --git a/functional-samples/tutorial.focus-mode-debugging/images/icon-16.png b/functional-samples/tutorial.focus-mode-debugging/images/icon-16.png new file mode 100644 index 0000000000..038e6b461e Binary files /dev/null and b/functional-samples/tutorial.focus-mode-debugging/images/icon-16.png differ diff --git a/functional-samples/tutorial.focus-mode-debugging/images/icon-32.png b/functional-samples/tutorial.focus-mode-debugging/images/icon-32.png new file mode 100644 index 0000000000..45d4cac511 Binary files /dev/null and b/functional-samples/tutorial.focus-mode-debugging/images/icon-32.png differ diff --git a/functional-samples/tutorial.focus-mode-debugging/images/icon-48.png b/functional-samples/tutorial.focus-mode-debugging/images/icon-48.png new file mode 100644 index 0000000000..4186379a93 Binary files /dev/null and b/functional-samples/tutorial.focus-mode-debugging/images/icon-48.png differ diff --git a/functional-samples/tutorial.focus-mode-debugging/manifest.json b/functional-samples/tutorial.focus-mode-debugging/manifest.json new file mode 100644 index 0000000000..8cbdeb92a1 --- /dev/null +++ b/functional-samples/tutorial.focus-mode-debugging/manifest.json @@ -0,0 +1,40 @@ +{ + "manifest_version": 3, + "name": "Oliver Focus Mode", + "description": "Example extension from DevTools Tips video.", + "version": "1.0", + "icons": { + "16": "images/icon-16.png", + "32": "images/icon-32.png", + "48": "images/icon-48.png", + "128": "images/icon-128.png" + }, + "background": { + "service_worker": "background.js" + }, + "action": { + "default_icon": { + "16": "images/icon-16.png", + "32": "images/icon-32.png", + "48": "images/icon-48.png", + "128": "images/icon-128.png" + } + }, + "permissions": [], + "host_permissions": ["https://developer.chrome.com/*"], + "commands": { + "_execute_action": { + "suggested_key": { + "default": "Ctrl+B", + "mac": "Command+B" + } + } + }, + "content_scripts": [ + { + "js": ["focus-mode.js"], + "css": ["focus-mode.css"], + "matches": ["https://developer.chrome.com/*"] + } + ] +}