diff --git a/extension/api/_.mjs b/extension/api/_.mjs index bd0e39d..b56733e 100644 --- a/extension/api/_.mjs +++ b/extension/api/_.mjs @@ -10,13 +10,13 @@ /** environment-specific methods and constants */ export * as env from './env.mjs'; +/** environment-specific filesystem reading */ +export * as fs from './fs.mjs'; /** environment-specific data persistence */ export * as storage from './storage.mjs'; /** helpers for formatting or parsing text */ export * as fmt from './fmt.mjs'; -/** environment-specific filesystem reading */ -export * as fs from './fs.mjs'; /** interactions with the enhancer's repository of mods */ export * as registry from './registry.mjs'; /** pattern and type validators */ diff --git a/extension/api/env.mjs b/extension/api/env.mjs index db7be08..59ebc88 100644 --- a/extension/api/env.mjs +++ b/extension/api/env.mjs @@ -15,13 +15,13 @@ * the environment/platform name code is currently being executed in * @constant {string} */ -export const name = 'extension'; +export const name = 'chrome'; /** * all environments/platforms currently supported by the enhancer * @constant {array} */ -export const supported = ['linux', 'win32', 'darwin', 'extension']; +export const supported = ['linux', 'win32', 'darwin', 'chrome', 'firefox']; /** * the current version of the enhancer diff --git a/extension/api/registry.mjs b/extension/api/registry.mjs index 910d4ae..d79a694 100644 --- a/extension/api/registry.mjs +++ b/extension/api/registry.mjs @@ -26,7 +26,7 @@ export const core = [ ]; /** all available configuration types */ -export const optionTypes = ['toggle', 'select', 'text', 'number', 'color', 'file']; +export const optionTypes = ['toggle', 'select', 'text', 'number', 'color', 'file', 'hotkey']; /** the root database for the current profile */ export const profile = storage.db([ @@ -201,6 +201,7 @@ async function validate(mod) { ); break; case 'text': + case 'hotkey': tests.push(check('options.option.value', option.value, 'string')); break; case 'number': @@ -299,6 +300,7 @@ export const optionDefault = async (id, key) => { case 'text': case 'number': case 'color': + case 'hotkey': return opt.value; case 'select': return opt.values[0]; diff --git a/extension/api/storage.mjs b/extension/api/storage.mjs index 15a63a2..848646b 100644 --- a/extension/api/storage.mjs +++ b/extension/api/storage.mjs @@ -24,7 +24,7 @@ export const get = (path, fallback = undefined) => { if (!path.length) return fallback; const namespace = path.shift(); return new Promise((res, rej) => - chrome.storage.sync.get(async (values) => { + chrome.storage.local.get(async (values) => { let value = values[namespace]; do { if (value === undefined) { @@ -54,7 +54,7 @@ export const set = (path, value) => { } const pathClone = [...path], namespace = path.shift(); - chrome.storage.sync.get(async (values) => { + chrome.storage.local.get(async (values) => { const update = values[namespace] ?? {}; let pointer = update, old; @@ -68,7 +68,7 @@ export const set = (path, value) => { pointer[key] = pointer[key] ?? {}; pointer = pointer[key]; } - chrome.storage.sync.set({ [namespace]: update }, () => { + chrome.storage.local.set({ [namespace]: update }, () => { _onChangeListeners.forEach((listener) => listener({ type: 'set', path: pathClone, new: value, old }) ); diff --git a/extension/api/web.mjs b/extension/api/web.mjs index c4ab25c..2439cf4 100644 --- a/extension/api/web.mjs +++ b/extension/api/web.mjs @@ -190,7 +190,8 @@ export const tooltip = ($ref, text) => { color: var(--theme--ui_tooltip-description); } `; - render(document.head, _$tooltip, _$tooltipStylesheet); + render(document.head, _$tooltipStylesheet); + render(document.body, _$tooltip); } text = md.render(text); $ref.addEventListener('mouseover', (event) => { @@ -199,8 +200,7 @@ export const tooltip = ($ref, text) => { }); $ref.addEventListener('mousemove', (event) => { _$tooltip.style.top = event.clientY - _$tooltip.clientHeight + 'px'; - _$tooltip.style.left = - event.clientX < window.innerWidth / 2 ? event.clientX + 20 + 'px' : ''; + _$tooltip.style.left = event.clientX - _$tooltip.clientWidth + 'px'; }); $ref.addEventListener('mouseout', (event) => { _$tooltip.style.display = ''; @@ -218,20 +218,23 @@ export const addHotkeyListener = (keys, callback) => { if (typeof keys === 'string') keys = keys.split('+'); if (!_hotkeyEvent) { _hotkeyEvent = document.addEventListener('keyup', (event) => { + if (document.activeElement.nodeName === 'INPUT') return; for (const hotkey of _hotkeyEventListeners) { - const matchesEvent = hotkey.keys.every((key) => { + const pressed = hotkey.keys.every((key) => { + key = key.toLowerCase(); const modifiers = { - altKey: 'alt', - ctrlKey: 'ctrl', - metaKey: 'meta', - shiftKey: 'shift', + metaKey: ['meta', 'os', 'win', 'cmd', 'command'], + ctrlKey: ['ctrl', 'control'], + shiftKey: ['shift'], + altKey: ['alt'], }; for (const modifier in modifiers) { - if (key.toLowerCase() === modifiers[modifier] && event[modifier]) return true; + const pressed = modifiers[modifier].includes(key) && event[modifier]; + if (pressed) return true; } - if (key.toLowerCase() === event.key.toLowerCase()) return true; + if (key === event.key.toLowerCase()) return true; }); - if (matchesEvent) hotkey.callback(); + if (pressed) hotkey.callback(); } }); } diff --git a/extension/repo/bypass-preview@cb6fd684-f113-4a7a-9423-8f0f0cff069f/mod.json b/extension/repo/bypass-preview@cb6fd684-f113-4a7a-9423-8f0f0cff069f/mod.json index 1d0cfb4..042abe5 100644 --- a/extension/repo/bypass-preview@cb6fd684-f113-4a7a-9423-8f0f0cff069f/mod.json +++ b/extension/repo/bypass-preview@cb6fd684-f113-4a7a-9423-8f0f0cff069f/mod.json @@ -3,6 +3,7 @@ "id": "cb6fd684-f113-4a7a-9423-8f0f0cff069f", "version": "0.2.0", "description": "go straight to the normal full view when opening a page.", + "preview": "https://cdn.pixabay.com/photo/2021/09/17/15/17/fruit-6633086_960_720.jpg", "tags": ["extension", "automation"], "authors": [ { @@ -10,6 +11,12 @@ "email": "thedragonring.bod@gmail.com", "homepage": "https://dragonwocky.me/", "avatar": "https://dragonwocky.me/avatar.jpg" + }, + { + "name": "fake person", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://cdn.pixabay.com/photo/2015/04/20/13/28/lizard-731336_960_720.jpg" } ], "js": { @@ -18,5 +25,55 @@ "css": { "client": ["client.css"] }, - "options": [] + "options": [ + { + "type": "toggle", + "key": "toggle", + "label": "toggle", + "tooltip": "toggle", + "value": true + }, + { + "type": "select", + "key": "select", + "label": "select", + "tooltip": "select", + "values": ["option A", "option B", "option C"] + }, + { + "type": "text", + "key": "text", + "label": "text", + "tooltip": "text", + "value": "default" + }, + { + "type": "hotkey", + "key": "hotkey", + "label": "hotkey", + "tooltip": "hotkey", + "value": "Ctrl+Shift+H" + }, + { + "type": "number", + "key": "number", + "label": "number", + "tooltip": "number", + "value": 14 + }, + { + "type": "color", + "key": "color", + "label": "color", + "tooltip": "color", + "value": "rgba(125, 26, 250, 0.7)" + }, + { + "type": "file", + "key": "file", + "label": "file", + "tooltip": "file", + "extensions": [".css"] + } + ] } diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.css b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.css index 75087fb..e21c00a 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.css +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.css @@ -9,7 +9,7 @@ -webkit-user-select: none; transition: background 20ms ease-in 0s; cursor: pointer; - color: var(--theme--text_ui); + color: var(--theme--text_secondary); } .enhancer--sidebarMenuLink:hover { background: var(--theme--ui_interactive-hover); diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.mjs index d7b15db..5ed2368 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.mjs +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/client.mjs @@ -14,9 +14,10 @@ export default async function (api, db) { const updateTheme = () => db.set(['theme'], document.querySelector('.notion-dark-theme') ? 'dark' : 'light'); web.addDocumentObserver((mutation) => { - if (mutation.target === document.body) updateTheme(); + if (mutation.target === document.body && document.hasFocus()) updateTheme(); }); - updateTheme(); + if (document.hasFocus()) updateTheme(); + document.addEventListener('visibilitychange', updateTheme); const sidebarSelector = '.notion-sidebar-container .notion-sidebar > div:nth-child(4)'; await web.whenReady([sidebarSelector]); diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/markdown.css b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/markdown.css index b2247b7..dc41b90 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/markdown.css +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/markdown.css @@ -49,7 +49,7 @@ .markdown.markdown-inline a { opacity: 0.7; text-decoration: none; - border-bottom: 0.05em solid var(--theme--text_ui); + border-bottom: 0.05em solid var(--theme--text_secondary); } .markdown.markdown-inline a:hover { opacity: 0.9; @@ -145,7 +145,7 @@ } .markdown .code-toolbar .toolbar-item > * { padding: 0.25rem 0.35rem; - color: var(--theme--text_ui); + color: var(--theme--text_secondary); font-size: 11px; font-family: inherit; } diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu-old.css b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu-old.css deleted file mode 100644 index 98f4498..0000000 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu-old.css +++ /dev/null @@ -1,513 +0,0 @@ -/* - * notion-enhancer core: menu - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -* { - box-sizing: border-box; - word-break: break-word; - text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; - font-size: inherit; - font-family: inherit; - fill: currentColor; -} - -html { - transition: opacity 50ms ease-out; - font-size: var(--theme--font_body-size); -} -html[class] { - opacity: 1 !important; -} - -body { - padding: 2rem 2.5rem; - position: relative; - margin: 0; - background: var(--theme--sidebar); - color: var(--theme--text); - font-family: var(--theme--font_sans); - min-height: 100vh; -} -body a { - color: inherit; -} - -header { - display: flex; - flex-wrap: wrap; - margin-bottom: 1.25rem; -} -header > * { - margin: 0 1.25rem 0.1em 0; - font-size: var(--theme--font_heading1-size); -} -header h1 a { - text-decoration: none; -} -header h1 img { - width: 0.95em; - height: 0.95em; - margin-right: 0.5em; - margin-bottom: -0.1em; -} -header h1 svg { - width: 1em; - height: 1em; - padding-top: 0.3em; - margin-right: 0.2em; -} -header h1 svg[data-icon='info'] { - margin-right: 0em; -} -header h1 svg[data-icon='code'] { - margin-right: 0.3em; -} - -img[data-view-target='notion'] { - cursor: pointer; -} - -main { - display: grid; - grid-gap: 1.25em; - grid-template-columns: 1fr; - opacity: 1; - transition: opacity 200ms ease-out; -} -@media (min-width: 550px) { - main { - grid-template-columns: 1fr 1fr; - } - main > .action--buttons { - grid-column: span 2; - } - [data-view='mod'] main .library--card, - .documentation--body { - max-height: calc(100vh - 10rem); - overflow-y: auto; - } - [data-view='mod'] { - overflow: hidden; - height: 100vh; - } -} -@media (min-width: 850px) { - main { - grid-template-columns: 1fr 1fr 1fr; - } - main > .action--buttons { - grid-column: span 3; - } - [data-view='mod'] main > .documentation--body { - grid-column: span 2; - } -} -@media (min-width: 1350px) { - main { - grid-template-columns: 1fr 1fr 1fr 1fr; - } - main > .action--buttons { - grid-column: span 4; - } - [data-view='mod'] main > .documentation--body { - grid-column: span 3; - } -} -@media (min-width: 2050px) { - main { - grid-template-columns: 1fr 1fr 1fr 1fr 1fr; - } - main > .action--buttons { - grid-column: span 5; - } - [data-view='mod'] main > .documentation--body { - grid-column: span 4; - } -} -main article { - border-radius: 5px; - box-shadow: rgb(0 0 0 / 10%) 0px 20px 25px -5px, rgb(0 0 0 / 4%) 0px 10px 10px -5px; - border: 1px solid var(--theme--divider); - background: var(--theme--page); -} -main article img { - max-width: 100%; -} - -.action--buttons, -.library--expand { - margin: 0; - display: flex; - flex-wrap: wrap; - gap: 0.53em; -} -.library--expand a { - margin-left: auto; -} -.action--buttons a, -.library--expand a { - border-radius: 3px; - padding: 0.35rem 0.45rem; - text-decoration: none; - display: flex; -} -.action--buttons .action--alert { - cursor: pointer; - border-radius: 3px; - padding: 0.35rem 0.45rem; - background: var(--theme--block_grey); - color: var(--theme--block_grey-text); - border: none; - pointer-events: none; - opacity: 0; - transition: opacity 200ms ease-in-out; -} -.action--buttons .action--alert[data-triggered] { - pointer-events: all; - opacity: 1; -} -.action--buttons .action--alert[data-triggered]:hover { - background: none; - color: var(--theme--block_grey-text); - box-shadow: var(--theme--block_grey) 0px 0px 0px 1px inset; -} -.action--buttons span, -.library--expand span { - color: var(--theme--text_property); -} -.action--buttons a:hover, -.action--buttons a.action--active, -.library--expand a:hover { - background: var(--theme--button-hover); -} -.action--buttons svg, -.library--expand svg { - width: 1em; - height: 1em; - padding-top: 2px; - margin-right: 0.3rem; -} -.action--buttons svg *, -.library--expand svg * { - fill: var(--theme--text_property); -} - -.library--preview { - border-bottom: 1px solid var(--theme--divider); -} -.library--version { - font-weight: normal; - font-size: var(--theme--font_ui-size); - border-radius: 5px; - padding: 0.125rem 0.25rem; - background: var(--theme--tag_default); - color: var(--theme--tag_default-text); -} -.library--description { - font-size: 1rem; - margin: 0.25rem 0; -} -.library--tags, -.library--authors { - padding: 0; - list-style-type: none; - display: flex; - flex-wrap: wrap; - margin: 0.5em 0; -} -.library--tags li { - font-size: var(--theme--font_ui-size); - margin: 0 0.5rem 0 0; - opacity: 0.7; -} -.library--authors li { - font-size: var(--theme--font_ui-size); - margin: 0 0.5rem 0 0; -} -.library--authors a { - font-size: var(--theme--font_ui-size); - text-decoration: none; - border-radius: 5px; - padding: 0.125rem 0.25rem 0.25rem 0; -} -.library--authors img { - height: 1em; - width: 1em; - margin-bottom: 0.15625em; - display: inline-block; - vertical-align: middle; - border-radius: 50%; - object-fit: cover; -} - -.library--options { - border-top: 1px solid var(--theme--divider); -} -.library--toggle_label, -.library--select_label, -.library--text_label, -.library--number_label, -.library--color_label, -.library--file_label { - margin: 0.6rem 0; - display: block; - appearance: none; - font-size: var(--theme--font_ui-size); -} -.library--toggle_label *, -.library--select_label *, -.library--text_label *, -.library--number_label *, -.library--color_label *, -.library--file_label * { - appearance: none; - font-family: var(--theme--font_sans); - font-size: var(--theme--font_ui-size); - color: var(--theme--text); -} -label p:not([class]), -label p > span:not([class]), -label > span:not([class]) { - font-size: 1rem; -} -label [data-icon='fa/solid/question-circle'] { - height: var(--theme--font_ui_small-size); - width: var(--theme--font_ui_small-size); - margin-left: 0.25em; - margin-bottom: -1px; -} -.library--toggle_label > p, -.library--toggle_label > p, -.library--select_label > p, -.library--text_label > p, -.library--number_label > p, -.library--color_label > p, -.library--file_label > p { - margin: 0.6rem 0; -} -.library--toggle_label > :not(input) { - align-items: center; - display: flex; - --toggle--bg: var(--theme--toggle_off); - --toggle--translation: 0%; -} -.library--toggle_label > :not(input) .library--toggle { - position: relative; - margin: auto 0 auto auto; - min-width: 2.25rem; - width: 2.25rem; - height: 1.25rem; - display: block; - border-radius: 40px; - background: var(--toggle--bg); - cursor: pointer; -} -.library--toggle_label > :not(input) .library--toggle::after { - content: ''; - transition: transform 200ms ease-out, background 200ms ease-out; - height: 0.8rem; - width: 0.8rem; - left: 0.325rem; - top: 0.2rem; - position: absolute; - border-radius: 100%; - background: var(--theme--toggle_dot); - transform: translateX(var(--toggle--translation)); -} -.library--toggle_label input[type='checkbox']:checked + :not(input) { - --toggle--bg: var(--theme--toggle_on); - --toggle--translation: 100%; -} -.library--toggle_label:focus-within .library--toggle, -.library--file_label:focus-within .library--file, -.library--color_label:focus-within .library--color, -.library--select_label .library--select:focus-within { - outline: -webkit-focus-ring-color auto 1px; -} -.library--toggle_label input, -.library--file_label input { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border-width: 0; -} -.library--text_label textarea { - resize: none; - min-height: calc(1em + 16px); - height: var(--txt--scroll-height); -} -.library--text_label textarea, -.library--number_label input, -.library--select_label .library--select, -.library--color_label .library--color, -.library--file_label .library--file { - width: 100%; - padding: 6px 8px; - background: var(--theme--input); - border-radius: 3px; - border: none; - box-shadow: var(--theme--input-border) 0px 0px 0px 1px inset; -} -.library--select_label .library--select select, -.library--color_label .library--color input { - outline: none; - cursor: pointer; -} -.library--color_label .library--color input { - border-radius: 0; -} -.library--select_label .library--select select option { - background: var(--theme--tag_select); -} -.library--select_label .library--select, -.library--color_label .library--color, -.library--file_label .library--file { - padding: 0; - display: flex; - cursor: pointer; -} -.library--select_label .library--select > :first-child, -.library--color_label .library--color > :first-child, -.library--file_label .library--file > :first-child { - display: flex; - padding: 6px 8px; - background: var(--theme--input-border); -} -.library--select_label .library--select > :first-child svg, -.library--color_label .library--color > :first-child svg, -.library--file_label .library--file > :first-child svg { - width: 0.9em; - margin: auto 0; -} -.library--select_label .library--select > :first-child svg *, -.library--color_label .library--color > :first-child svg *, -.library--file_label .library--file > :first-child svg * { - color: var(--theme--input_icon); -} -.library--select_label .library--select > :last-child, -.library--color_label .library--color > :last-child, -.library--file_label .library--file > :last-child { - margin: auto 0; - padding: 6px 8px; - width: 100%; - height: 100%; - border: none; - background: none; -} -.library--file_label .library--file_title { - display: flex; -} -.library--file_title .library--file_remove { - margin-top: auto; - padding-top: 0.2em; - margin-left: auto; -} -.library--file_title .library--file_remove svg { - cursor: pointer; - width: 0.8em; -} -.library--title, -.library--title h2 { - margin: 0; - font-size: var(--theme--font_ui-size); -} -.library--title h2 > span { - font-size: var(--theme--font_heading2-size); -} - -.library--card > div { - padding: 1rem; -} -[data-view='mod'] main .library--card { - overflow-x: auto; -} -.documentation--body { - padding: 1rem 2rem; - font-size: 1rem; - overflow-x: auto; -} - -.notifications { - position: absolute; - bottom: 1.5rem; - right: 1.5rem; -} -.notification { - background: var(--theme--block_grey); - color: var(--theme--block_grey-text); - max-width: calc(100vw - 3rem); - width: 25rem; - font-size: var(--theme--font_ui-size); - border-top: 4px currentColor solid; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important; - padding: 1.25em 1.5em; - display: flex; - margin-top: 1rem; - position: relative; - transition: opacity 200ms ease-in-out, transform 115ms ease-out 200ms, - margin-top 115ms ease-out 200ms; - transform: scaleY(1); - transform-origin: 100% 100%; - opacity: 0; -} -.notification :not(.notification--dismiss) > svg { - height: 1.5rem; - width: 1.5rem; - margin-top: 0.25rem; - margin-right: 1rem; -} -.notification h3 { - margin: 0 0 0.25rem 0; - font-weight: bold; -} -.notification p { - margin: 0.25rem 0 0.5rem 0; -} -.notification .notification--dismiss { - position: absolute; - top: 0.5rem; - right: 0.75rem; - background: none; - border: none; - padding: 0.15rem 0 0.15rem 0.5rem; - width: var(--theme--font_body-size); - color: currentColor; - cursor: pointer; - transition: opacity 200ms ease-in-out; - opacity: 0; -} -.notification .notification--dismiss svg { - width: 100%; -} -.notification:hover .notification--dismiss, -.notification:focus-within .notification--dismiss { - opacity: 1; -} - -::-webkit-scrollbar { - background: transparent; - width: 10px; - height: 10px; -} -::-webkit-scrollbar-track { - background: var(--theme--scrollbar_track); -} -::-webkit-scrollbar-corner { - background: var(--theme--scrollbar_track); -} -::-webkit-scrollbar-thumb { - background: var(--theme--scrollbar_thumb); -} -::-webkit-scrollbar-thumb:hover { - background: var(--theme--scrollbar_thumb-hover); -} diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs index 873f44d..ccf4a15 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs @@ -29,6 +29,11 @@ const loadTheme = async () => { document.addEventListener('visibilitychange', loadTheme); loadTheme(); +window.addEventListener('beforeunload', (event) => { + // trigger input save + document.activeElement.blur(); +}); + const notifications = { $container: web.html`
`, cache: await db.get(['notifications'], []), @@ -72,10 +77,10 @@ const notifications = { ); return $notification; }, - _changes: false, - changes() { - if (this._changes) return; - this._changes = true; + _onChange: false, + onChange() { + if (this._onChange) return; + this._onChange = true; const $notification = this.add({ icon: 'refresh-cw', message: 'Reload to apply changes.', @@ -112,7 +117,7 @@ const components = { class="mod-preview" src="${web.escape(url)}" alt="" - />`, + >`, title: (title) => web.html`

${web.escape(title)}

`, version: (version) => web.html`v${web.escape(version)}`, tags: (tags) => { @@ -126,40 +131,256 @@ const components = { ${fmt.md.renderInline(description)}

`, authors: (authors) => { - const author = (author) => web.html` + const author = (author) => web.html` ${web.escape(author.name)}'s avatar ${web.escape(author.name)} + > ${web.escape(author.name)} `; return web.render(web.html`

`, ...authors.map(author)); }, - toggle: (checked) => { - const $label = web.html``, - $input = web.html``; + toggle: (label, checked) => { + const $label = web.html``, + $input = web.html``, + $feature = web.html``; $label.addEventListener('keyup', (event) => { if (['Enter', ' '].includes(event.key)) $input.checked = !$input.checked; }); - return web.render( - $label, - $input, - web.html`` - ); + return web.render($label, $input, $feature); }, }; +const $main = web.html`
`, + $sidebar = web.html``, + $options = web.html`
+

Select a mod to view and configure its options.

+
`; + +const options = { + toggle: async (mod, opt) => { + const checked = await registry.profile.get([mod.id, opt.key], opt.value), + $toggle = components.toggle(opt.label, checked), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = $toggle.children[0], + $input = $toggle.children[1]; + if (opt.tooltip) { + $label.prepend($tooltip); + web.tooltip($tooltip, opt.tooltip); + } + $input.addEventListener('change', async (event) => { + await registry.profile.set([mod.id, opt.key], $input.checked); + notifications.onChange(); + }); + return $toggle; + }, + select: async (mod, opt) => { + const value = await registry.profile.get([mod.id, opt.key], opt.values[0]), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $select = web.html``, + $icon = web.html`${web.icon('chevron-down', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $select.addEventListener('change', async (event) => { + await registry.profile.set([mod.id, opt.key], $select.value); + notifications.onChange(); + }); + return web.render($label, $select, $icon); + }, + text: async (mod, opt) => { + const value = await registry.profile.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('type', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', async (event) => { + await registry.profile.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, + number: async (mod, opt) => { + const value = await registry.profile.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('hash', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', async (event) => { + await registry.profile.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, + color: async (mod, opt) => { + const value = await registry.profile.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('droplet', { class: 'input-icon' })}`, + paint = () => { + $input.style.background = $picker.toBackground(); + $input.style.color = $picker.isLight() ? '#000' : '#fff'; + $input.style.padding = ''; + }, + $picker = new web.jscolor($input, { + value, + format: 'rgba', + previewSize: 0, + borderRadius: 3, + borderColor: 'var(--theme--ui_divider)', + controlBorderColor: 'var(--theme--ui_divider)', + backgroundColor: 'var(--theme--bg)', + onInput: paint, + onChange: paint, + }); + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', async (event) => { + await registry.profile.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + paint(); + return web.render($label, $input, $icon); + }, + file: async (mod, opt) => { + const { filename } = (await registry.profile.get([mod.id, opt.key], {})) || {}, + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $pseudo = web.html`Upload file...`, + $input = web.html``, + $icon = web.html`${web.icon('file', { class: 'input-icon' })}`, + $filename = web.html`${web.escape(filename || 'none')}`, + $latest = web.render(web.html``, $filename); + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', (event) => { + const file = event.target.files[0], + reader = new FileReader(); + reader.onload = async (progress) => { + $filename.innerText = file.name; + await registry.profile.set([mod.id, opt.key], { + filename: file.name, + content: progress.currentTarget.result, + }); + notifications.onChange(); + }; + reader.readAsText(file); + }); + $latest.addEventListener('click', (event) => { + $filename.innerText = 'none'; + registry.profile.set([mod.id, opt.key], {}); + }); + return web.render( + web.html`
`, + web.render($label, $input, $pseudo, $icon), + $latest + ); + }, + hotkey: async (mod, opt) => { + const value = await registry.profile.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('command', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('keydown', async (event) => { + event.preventDefault(); + const pressed = [], + modifiers = { + metaKey: 'Meta', + ctrlKey: 'Control', + altKey: 'Alt', + shiftKey: 'Shift', + }; + for (const modifier in modifiers) { + if (event[modifier]) pressed.push(modifiers[modifier]); + } + const empty = ['Backspace', 'Delete'].includes(event.key) && !pressed.length; + if (!empty && !pressed.includes(event.key)) { + let key = event.key; + if (key === ' ') key = 'Space'; + if (key.length === 1) key = event.key.toUpperCase(); + pressed.push(key); + } + $input.value = pressed.join('+'); + await registry.profile.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, +}; + +components.options = async (mod) => { + const $fragment = document.createDocumentFragment(); + for (const opt of mod.options) { + web.render($fragment, await options[opt.type](mod, opt)); + } + if (!mod.options.length) { + web.render($fragment, web.html`

No options.

`); + } + return $fragment; +}; + components.mod = async (mod) => { - const $toggle = components.toggle(await registry.enabled(mod.id)); + const $mod = web.html`
`, + $toggle = components.toggle('', await registry.enabled(mod.id)); $toggle.addEventListener('change', (event) => { registry.profile.set(['_mods', mod.id], event.target.checked); - notifications.changes(); + notifications.onChange(); + }); + $mod.addEventListener('click', async (event) => { + if ($mod.className === 'mod-selected') return; + for (const $selected of document.querySelectorAll('.mod-selected')) { + $selected.className = 'mod'; + } + $mod.className = 'mod-selected'; + web.render( + web.empty($options), + web.render(components.title(mod.name), components.version(mod.version)), + components.tags(mod.tags), + await components.options(mod) + ); }); return web.render( web.html`
`, web.render( - web.html`
`, + $mod, mod.preview ? components.preview( mod.preview.startsWith('http') @@ -179,36 +400,41 @@ components.mod = async (mod) => { ); }; +components._$modListCache = {}; components.modList = async (category) => { - const $search = web.html``, - $list = web.html`
`, - mods = await registry.list( - (mod) => mod.environments.includes(env.name) && mod.tags.includes(category) - ); - web.addHotkeyListener(['/'], () => $search.focus()); - $search.addEventListener('input', (event) => { - const query = $search.value.toLowerCase(); - for (const $mod of $list.children) { - const matches = !query || $mod.innerText.toLowerCase().includes(query); - $mod.classList[matches ? 'remove' : 'add']('hidden'); + $list = web.html`
`, + mods = await registry.list( + (mod) => mod.environments.includes(env.name) && mod.tags.includes(category) + ); + web.addHotkeyListener(['/'], () => $search.focus()); + $search.addEventListener('input', (event) => { + const query = $search.value.toLowerCase(); + for (const $mod of $list.children) { + const matches = !query || $mod.innerText.toLowerCase().includes(query); + $mod.classList[matches ? 'remove' : 'add']('hidden'); + } + }); + for (const mod of mods) { + mod.tags = mod.tags.filter((tag) => tag !== category); + web.render($list, await components.mod(mod)); + mod.tags.unshift(category); } - }); - for (const mod of mods) { - mod.tags = mod.tags.filter((tag) => tag !== category); - web.render($list, await components.mod(mod)); - mod.tags.unshift(category); + components._$modListCache[category] = web.render( + web.html`
`, + web.render( + web.html``, + $search, + web.html`${web.icon('search', { class: 'input-icon' })}` + ), + $list + ); } - return web.render( - web.html`
`, - web.render(web.html`
`, $search), - $list - ); + return components._$modListCache[category]; }; -const $main = web.html`
`, - $sidebar = web.html``; - const $notionNavItem = web.html`

${(await fs.getText('icon/colour.svg')).replace( /width="\d+" height="\d+"/, @@ -221,7 +447,7 @@ $notionNavItem.children[0].addEventListener('click', env.focusNotion); const $coreNavItem = web.html`core`, $extensionsNavItem = web.html`extensions`, $themesNavItem = web.html`themes`, - $supportNavItem = web.html`support`; + $communityNavItem = web.html`community`; web.render( document.body, @@ -235,11 +461,11 @@ web.render( $coreNavItem, $extensionsNavItem, $themesNavItem, - $supportNavItem + $communityNavItem ), $main ), - $sidebar + web.render($sidebar, $options) ) ); diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/mod.json b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/mod.json index a7ac01b..0aa7b7f 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/mod.json +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/mod.json @@ -21,11 +21,11 @@ }, "options": [ { - "type": "text", + "type": "hotkey", "key": "hotkey", - "label": "toggle hotkey", + "label": "toggle focus hotkey", "value": "Ctrl+Alt+E", - "tooltip": "toggles focus between notion & the enhancer menu" + "tooltip": "switches between notion & the enhancer menu" } ] } diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs index 2160aa2..f46b10f 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs @@ -29,49 +29,57 @@ const customClasses = { 'notification': ([color = 'default']) => apply`p-2 ${ color === 'default' - ? 'bg-tag text-tag-text hover:bg-interactive-hover border border-notion-divider' + ? 'bg-tag text-tag-text hover:bg-interactive-hover border border-divider' : `bg-${color}-tag text-${color}-tag-text border border-${color}-text hover:bg-${color}-text` } flex items-center rounded-full mt-3 shadow-md cursor-pointer`, 'notification-text': apply`font-semibold mx-2 flex-auto`, 'notification-icon': apply`fill-current opacity-75 h-4 w-4 mx-2`, 'body-container': apply`flex w-full h-full overflow-hidden`, 'content-container': apply`h-full w-full-96`, - 'nav': apply`px-4 py-3 flex flex-wrap items-center border-b border-notion-divider h-48 sm:h-32 lg:h-16`, + 'nav': apply`px-4 py-3 flex flex-wrap items-center border-b border-divider h-48 sm:h-32 lg:h-16`, 'nav-notion': apply`flex items-center font-semibold text-xl cursor-pointer select-none mr-4 ml-4 sm:mb-4 md:w-full lg:(w-auto ml-0 mb-0)`, 'nav-notion-icon': apply`h-12 w-12 mr-5 sm:(h-6 w-6 mr-3)`, - 'nav-item': apply`ml-4 px-3 py-2 rounded-md text-sm font-medium bg-interactive hover:bg-interactive-hover`, - 'nav-item-selected': apply`ml-4 px-3 py-2 rounded-md text-sm font-medium ring-1 ring-notion-divider bg-notion-secondary`, + 'nav-item': apply`ml-4 px-3 py-2 rounded-md text-sm font-medium hover:bg-interactive-hover focus:bg-interactive-active`, + 'nav-item-selected': apply`ml-4 px-3 py-2 rounded-md text-sm font-medium ring-1 ring-divider bg-notion-secondary`, 'main': apply`transition px-4 py-3 overflow-y-auto max-h-full-48 sm:max-h-full-32 lg:max-h-full-16`, - 'sidebar': apply`h-full w-96 bg-notion-secondary border-l border-notion-divider`, 'mods-list': apply`flex flex-wrap`, 'mod-container': apply`w-full md:w-1/2 lg:w-1/3 xl:w-1/4 2xl:w-1/5 px-2.5 py-2.5 box-border`, 'mod': apply`relative h-full w-full flex flex-col overflow-hidden rounded-lg shadow-lg - bg-notion-secondary border border-notion-divider`, - 'mod-body': apply`px-4 py-3 flex flex-col flex-auto`, + bg-notion-secondary border border-divider cursor-pointer`, + 'mod-selected': apply`mod ring ring-accent-blue-active`, + 'mod-body': apply`px-4 py-3 flex flex-col flex-auto children:cursor-pointer`, 'mod-preview': apply`object-cover w-full h-32`, 'mod-title': apply`mb-2 text-xl font-semibold tracking-tight flex items-center`, 'mod-version': apply`mt-px ml-3 p-1 font-normal text-xs leading-none bg-tag text-tag-text rounded`, - 'mod-tags': apply`text-foreground-ui mb-2 text-xs`, + 'mod-tags': apply`text-foreground-secondary mb-2 text-xs`, 'mod-description': apply`mb-2 text-sm`, 'mod-authors-container': apply`text-sm font-medium`, 'mod-author': apply`flex items-center mb-2`, 'mod-author-avatar': apply`inline object-cover w-5 h-5 rounded-full mr-2`, - 'toggle-box': apply`w-9 h-5 p-0.5 flex items-center bg-toggle-off rounded-full duration-300 ease-in-out`, - 'toggle-label': apply`relative text-sm`, - 'toggle-label-full': apply`relative text-sm flex w-full mt-auto`, - 'toggle-check': apply`appearance-none checked:sibling:(bg-toggle-on after::translate-x-4)`, - 'toggle-check-right': apply`appearance-none ml-auto checked:sibling:(bg-toggle-on after::translate-x-4)`, - 'toggle-feature': apply`after::(${pseudoContent} w-4 h-4 bg-toggle-feature rounded-full duration-300)`, - 'search-container': apply`mx-2.5 my-2.5`, - 'search': apply`transition block w-full px-3 py-2 text-sm rounded-md flex bg-notion-input text-foreground - hover:(ring ring-accent-blue-hover) focus:(outline-none ring ring-accent-blue-active)`, + 'toggle-box': apply`w-9 h-5 p-0.5 flex items-center bg-toggle-off rounded-full duration-300 ease-in-out cursor-pointer`, + 'toggle-label': apply`relative text-sm flex w-full mt-auto`, + 'toggle-check': apply`appearance-none ml-auto checked:sibling:(bg-toggle-on after::translate-x-4)`, + 'toggle-feature': apply`after::(${pseudoContent} w-4 h-4 bg-toggle-feature rounded-full duration-300) cursor-pointer`, + 'sidebar': apply`h-full w-96 px-4 pt-3 pb-32 flex flex-col bg-notion-secondary border-l border-divider`, + 'options-container': apply`px-4 py-3 shadow-inner rounded-lg bg-notion border border-divider space-y-3`, + 'options-empty': apply`text-sm text-foreground-secondary`, + 'input-label': apply`block text-sm mt-2 relative`, + 'input': apply`transition block w-full mt-2 pl-3 pr-14 py-2 text-sm rounded-md flex bg-input text-foreground + appearance-none placeholder-foreground-secondary ring-1 ring-divider focus:(outline-none ring ring-accent-blue-active)`, + 'input-tooltip': apply`h-4 w-4 -mt-1 inline-block mr-2`, + 'input-icon': apply`absolute w-11 h-9 right-0 bottom-0 py-2 px-3 bg-notion-secondary rounded-r-md text-icon`, + 'input-placeholder': apply`text-foreground-secondary`, + 'select-option': apply`bg-notion-secondary`, + 'file-latest': apply`block w-full text-left text-foreground-secondary text-xs mt-2 hover:line-through cursor-pointer`, + 'search-container': apply`block mx-2.5 my-2.5 relative`, + 'search': apply`input pr-12`, }; setup({ preflight: { html: apply`w-full h-full`, - body: apply`w-full h-full bg-notion-bg font-sans text-foreground`, + body: apply`w-full h-full bg-notion font-sans text-foreground`, }, theme: { fontFamily: { @@ -79,18 +87,16 @@ setup({ mono: ['var(--theme--font_mono)'], }, colors: { - 'notion': { - 'bg': 'var(--theme--bg)', - 'secondary': 'var(--theme--bg_secondary)', - 'popup': 'var(--theme--bg_popup)', - 'divider': 'var(--theme--ui_divider)', - 'input': 'var(--theme--ui_input)', - }, + 'notion': 'var(--theme--bg)', + 'notion-secondary': 'var(--theme--bg_secondary)', + 'notion-popup': 'var(--theme--bg_popup)', + 'divider': 'var(--theme--ui_divider)', + 'input': 'var(--theme--ui_input)', 'icon': 'var(--theme--icon)', - 'icon-ui': 'var(--theme--icon_ui)', + 'icon-secondary': 'var(--theme--icon_secondary)', 'foreground': 'var(--theme--text)', - 'foreground-ui': 'var(--theme--text_ui)', - 'interactive': 'var(--theme--ui_interactive)', + 'foreground-secondary': 'var(--theme--text_secondary)', + 'interactive-active': 'var(--theme--ui_interactive-active)', 'interactive-hover': 'var(--theme--ui_interactive-hover)', 'tag': 'var(--theme--tag_default)', 'tag-text': 'var(--theme--tag_default-text)', diff --git a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css index 38983ec..95123c7 100644 --- a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css +++ b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css @@ -4,10 +4,6 @@ * (https://notion-enhancer.github.io/) under the MIT license */ -/* -grey vs text_ui in light mode (check change cover hover text) -*/ - /** layout **/ .notion-frame .notion-scroller [style*='env(safe-area-inset-'][style*=' width: 900px'], @@ -466,7 +462,7 @@ body, } .DayPicker-Day--outside, .DayPicker-Weekday { - color: var(--theme--text_ui) !important; + color: var(--theme--text_secondary) !important; } .notion-timeline-view [style*='height: 100%; border-right: 1px solid rgb(211, 79, 67);'] { border-right: 1px solid var(--theme--accent_red) !important; @@ -713,7 +709,7 @@ body, .notion-body:not(.dark) [style*='fill: rgb(55, 53, 47)'], .notion-body:not(.dark) [style*='fill: rgba(55, 53, 47, 0.']:not([style*='fill: rgba(55, 53, 47, 0.8)']) { - fill: var(--theme--icon_ui) !important; + fill: var(--theme--icon_secondary) !important; } .alarmClock { fill: currentColor !important; @@ -750,13 +746,13 @@ body, .notion-focusable[role='button'][style*='font-size: 14px; border-radius: 3px; box-shadow:']:last-child svg + div { - color: var(--theme--text_ui) !important; + color: var(--theme--text_secondary) !important; } .notion-page-mention-token__title { - border-bottom: 0.05em solid var(--theme--text_ui) !important; + border-bottom: 0.05em solid var(--theme--text_secondary) !important; } .notion-to_do-block [placeholder='To-do'][style*='text-decoration: line-through'] { - text-decoration: line-through var(--theme--text_ui) !important; + text-decoration: line-through var(--theme--text_secondary) !important; } .notion-body.dark [style*=' color: rgba(255, 255, 255, 0.4)'], .notion-body.dark [style^='color: rgba(255, 255, 255, 0.4)'], @@ -765,15 +761,15 @@ body, .notion-page-controls, .notion-page-details-controls, .notion-calendar-view-day { - color: var(--theme--text_ui) !important; + color: var(--theme--text_secondary) !important; } .notion-body.dark [style*='-webkit-text-fill-color: rgba(255, 255, 255, 0.4)'], .notion-body:not(.dark) [style*='-webkit-text-fill-color: rgba(55, 53, 47, 0.4)'] { - -webkit-text-fill-color: var(--theme--text_ui) !important; + -webkit-text-fill-color: var(--theme--text_secondary) !important; } .notion-body.dark [style*='border-color:rgba(255,255,255,0.4)'], .notion-body:not(.dark) [style*='border-color:rgba(55,53,47,0.4)'] { - border-color: var(--theme--text_ui) !important; + border-color: var(--theme--text_secondary) !important; } .notion-body.dark [style*='background: rgb(80, 85, 88)']:not([role='button']), diff --git a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css index 1c5deba..241edee 100644 --- a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css +++ b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css @@ -57,10 +57,10 @@ --theme--ui_tooltip-description: rgba(206, 205, 202, 0.6); --theme--icon: rgba(55, 53, 47, 0.8); - --theme--icon_ui: rgba(55, 53, 47, 0.4); + --theme--icon_secondary: rgba(55, 53, 47, 0.4); --theme--text: rgb(55, 43, 47); - --theme--text_ui: rgba(55, 43, 47, 0.6); + --theme--text_secondary: rgba(55, 43, 47, 0.6); --theme--text_grey: rgb(155, 154, 151); --theme--text_brown: rgb(100, 71, 58); --theme--text_orange: rgb(217, 115, 13); @@ -221,10 +221,10 @@ --theme--ui_tooltip-description: rgba(47, 52, 55, 0.6); --theme--icon: rgba(202, 204, 206); - --theme--icon_ui: rgb(202, 204, 206, 0.6); + --theme--icon_secondary: rgb(202, 204, 206, 0.6); --theme--text: rgba(255, 255, 255, 0.9); - --theme--text_ui: rgba(255, 255, 255, 0.6); + --theme--text_secondary: rgba(255, 255, 255, 0.6); --theme--text_grey: rgba(151, 154, 155, 0.95); --theme--text_brown: rgb(147, 114, 100); --theme--text_orange: rgb(255, 163, 68); diff --git a/extension/worker.js b/extension/worker.js index df68e8a..c2024ae 100644 --- a/extension/worker.js +++ b/extension/worker.js @@ -18,11 +18,11 @@ chrome.action.onClicked.addListener(focusMenu); async function focusNotion() { const tabs = await chrome.tabs.query({ windowId: chrome.windows.WINDOW_ID_CURRENT }), - notion = tabs.find( - (tab) => - new URL(tab.url).host.endsWith('.notion.so') || - new URL(tab.url).host.endsWith('.notion.site') - ); + notion = tabs.find((tab) => { + const url = new URL(tab.url), + matches = url.host.endsWith('.notion.so') || url.host.endsWith('.notion.site'); + return matches; + }); if (notion) { chrome.tabs.highlight({ 'tabs': notion.index }); } else chrome.tabs.create({ url: 'https://notion.so/' });