diff --git a/repo/.github/workflows/update-parents.yml b/repo/.github/workflows/update-parents.yml new file mode 100644 index 0000000..ac428e4 --- /dev/null +++ b/repo/.github/workflows/update-parents.yml @@ -0,0 +1,29 @@ +name: 'update parent repositories' + +on: + push: + branches: + - dev + +jobs: + sync: + name: update parent + runs-on: ubuntu-latest + strategy: + matrix: + repo: ['notion-enhancer/extension', 'notion-enhancer/desktop'] + steps: + - name: checkout repo + uses: actions/checkout@v2 + with: + token: ${{ secrets.CI_TOKEN }} + submodules: true + repository: ${{ matrix.repo }} + - name: pull updates + run: | + git pull --recurse-submodules + git submodule update --remote --recursive + - name: commit changes + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: '[${{ github.event.repository.name }}] ${{ github.event.head_commit.message }}' diff --git a/repo/LICENSE b/repo/LICENSE new file mode 100644 index 0000000..b503961 --- /dev/null +++ b/repo/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 dragonwocky (https://dragonwocky.me/) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/repo/README.md b/repo/README.md new file mode 100644 index 0000000..0885816 --- /dev/null +++ b/repo/README.md @@ -0,0 +1,5 @@ +# notion-enhancer/repo + +the collection of mods run by the notion-enhancer + +[read the docs online](https://notion-enhancer.github.io/getting-started/features) diff --git a/repo/always-on-top/always-on-top.jpg b/repo/always-on-top/always-on-top.jpg new file mode 100644 index 0000000..bed945f Binary files /dev/null and b/repo/always-on-top/always-on-top.jpg differ diff --git a/repo/always-on-top/button.css b/repo/always-on-top/button.css new file mode 100644 index 0000000..71150b4 --- /dev/null +++ b/repo/always-on-top/button.css @@ -0,0 +1,47 @@ +/** + * notion-enhancer: integrated titlebar + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.always_on_top--button { + display: flex; + align-items: center; +} +.sidebar > .always_on_top--button { + margin: 0 0 0.75rem auto; +} + +.always_on_top--button button { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: 3px; + height: 28px; + width: 33px; + padding: 0 0.25px 0 0; + + margin-left: 2px; + border: none; + background: transparent; + font-size: 18px; +} +.always_on_top--button button svg { + display: block; + width: 20px; + height: 20px; + fill: var(--theme--icon); + color: var(--theme--icon); +} + +.always_on_top--button button:focus, +.always_on_top--button button:hover { + background: var(--theme--ui_interactive-hover); +} +.always_on_top--button button:active { + background: var(--theme--ui_interactive-active); +} diff --git a/repo/always-on-top/button.mjs b/repo/always-on-top/button.mjs new file mode 100644 index 0000000..50f0454 --- /dev/null +++ b/repo/always-on-top/button.mjs @@ -0,0 +1,45 @@ +/** + * notion-enhancer: always on top + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export const createButton = async ({ electron, web, components }, db) => { + let pinIcon = + (await db.get(['pin_icon'])) || + ` + + `, + unpinIcon = + (await db.get(['unpin_icon'])) || + ` + + `; + pinIcon = pinIcon.trim(); + unpinIcon = unpinIcon.trim(); + + pinIcon = + pinIcon.startsWith('') ? pinIcon : web.escape(pinIcon); + unpinIcon = + unpinIcon.startsWith('') + ? unpinIcon + : web.escape(unpinIcon); + + const $button = web.html`
`, + $pin = web.html``, + $unpin = web.html``; + components.addTooltip($pin, '**Pin window to top**'); + components.addTooltip($unpin, '**Unpin window from top**'); + web.render($button, $pin); + + $pin.addEventListener('click', () => { + $pin.replaceWith($unpin); + electron.browser.setAlwaysOnTop(true); + }); + $unpin.addEventListener('click', () => { + $unpin.replaceWith($pin); + electron.browser.setAlwaysOnTop(false); + }); + + return $button; +}; diff --git a/repo/always-on-top/client.mjs b/repo/always-on-top/client.mjs new file mode 100644 index 0000000..7262f15 --- /dev/null +++ b/repo/always-on-top/client.mjs @@ -0,0 +1,17 @@ +/** + * notion-enhancer: always on top + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +import { createButton } from './button.mjs'; + +export default async function (api, db) { + const { web } = api, + topbarActionsSelector = '.notion-topbar-action-buttons'; + + await web.whenReady([topbarActionsSelector]); + const $topbarActions = document.querySelector(topbarActionsSelector), + $button = await createButton(api, db); + $topbarActions.after($button); +} diff --git a/repo/always-on-top/menu.mjs b/repo/always-on-top/menu.mjs new file mode 100644 index 0000000..1250d12 --- /dev/null +++ b/repo/always-on-top/menu.mjs @@ -0,0 +1,20 @@ +/** + * notion-enhancer: always on top + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +import { createButton } from './button.mjs'; + +export default async function (api, db) { + const { web } = api, + sidebarSelector = '.sidebar', + windowButtonsSelector = '.integrated_titlebar--buttons'; + + await web.whenReady([sidebarSelector]); + await new Promise(requestAnimationFrame); + const $sidebar = document.querySelector(sidebarSelector), + $windowButtons = document.querySelector(windowButtonsSelector), + $button = await createButton(api, db); + ($windowButtons || $sidebar).prepend($button); +} diff --git a/repo/always-on-top/mod.json b/repo/always-on-top/mod.json new file mode 100644 index 0000000..efaee88 --- /dev/null +++ b/repo/always-on-top/mod.json @@ -0,0 +1,41 @@ +{ + "name": "always on top", + "id": "be2d75f5-48f5-4ece-98bd-772244e559f3", + "environments": ["linux", "win32", "darwin"], + "version": "0.2.0", + "description": "adds a button that can be used to pin the notion window on top of all other windows at all times.", + "preview": "always-on-top.jpg", + "tags": ["extension", "app"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "client": ["button.css"], + "menu": ["button.css"] + }, + "js": { + "client": ["client.mjs"], + "menu": ["menu.mjs"] + }, + "options": [ + { + "type": "text", + "key": "pin_icon", + "label": "pin window icon", + "tooltip": "**may be an svg string or any unicode symbol e.g. an emoji** (the default icon will be used if this field is left empty)", + "value": "" + }, + { + "type": "text", + "key": "unpin_icon", + "label": "unpin window icon", + "tooltip": "**may be an svg string or any unicode symbol e.g. an emoji** (the default icon will be used if this field is left empty)", + "value": "" + } + ] +} diff --git a/repo/bypass-preview/client.css b/repo/bypass-preview/client.css new file mode 100644 index 0000000..cae2982 --- /dev/null +++ b/repo/bypass-preview/client.css @@ -0,0 +1,9 @@ +/** + * notion-enhancer: bypass preview + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-peek-renderer { + display: none; +} diff --git a/repo/bypass-preview/client.mjs b/repo/bypass-preview/client.mjs new file mode 100644 index 0000000..af5e597 --- /dev/null +++ b/repo/bypass-preview/client.mjs @@ -0,0 +1,37 @@ +/** + * notion-enhancer: bypass preview + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +"use strict"; + +export default function ({ web, notion }, db) { + let _openPage = {}; + + const getCurrentPage = () => ({ + type: web.queryParams().get("p") ? "preview" : "page", + id: notion.getPageID(), + }); + + const interceptPreview = () => { + const currentPage = getCurrentPage(); + if ( + currentPage.id !== _openPage.id || + currentPage.type !== _openPage.type + ) { + const $openAsPage = document.querySelector( + ".notion-peek-renderer a > div" + ); + + if ($openAsPage) { + if (currentPage.id === _openPage.id && currentPage.type === "preview") { + history.back(); + } else $openAsPage.click(); + } + + _openPage = getCurrentPage(); + } + }; + web.addDocumentObserver(interceptPreview, [".notion-peek-renderer"]); +} diff --git a/repo/bypass-preview/mod.json b/repo/bypass-preview/mod.json new file mode 100644 index 0000000..bda76dc --- /dev/null +++ b/repo/bypass-preview/mod.json @@ -0,0 +1,22 @@ +{ + "name": "bypass preview", + "id": "cb6fd684-f113-4a7a-9423-8f0f0cff069f", + "version": "0.2.0", + "description": "go straight to the normal full view when opening a page.", + "tags": ["extension", "automation"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [] +} diff --git a/repo/calendar-scroll/calendar-scroll.png b/repo/calendar-scroll/calendar-scroll.png new file mode 100644 index 0000000..42ab520 Binary files /dev/null and b/repo/calendar-scroll/calendar-scroll.png differ diff --git a/repo/calendar-scroll/client.css b/repo/calendar-scroll/client.css new file mode 100644 index 0000000..2cbdb62 --- /dev/null +++ b/repo/calendar-scroll/client.css @@ -0,0 +1,25 @@ +/** + * notion-enhancer: calendar scroll + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +#enhancer--calendar-scroll { + background: var(--theme--ui_interactive-hover); + border: 1px solid transparent; + font-size: 14px; + color: var(--theme--text); + height: 24px; + border-radius: 3px; + line-height: 1.2; + padding: 0 0.5em; + margin-right: 5px; +} +#enhancer--calendar-scroll:focus, +#enhancer--calendar-scroll:hover { + background: transparent; + border: 1px solid var(--theme--ui_interactive-hover); +} +#enhancer--calendar-scroll:active { + background: var(--theme--ui_interactive-active); +} diff --git a/repo/calendar-scroll/client.mjs b/repo/calendar-scroll/client.mjs new file mode 100644 index 0000000..a13851e --- /dev/null +++ b/repo/calendar-scroll/client.mjs @@ -0,0 +1,41 @@ +/** + * notion-enhancer: calendar scroll + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +const pageSelector = '.notion-page-content', + calendarSelector = '.notion-calendar-view:not([data-calendar-scroll])', + scrollerSelector = '.notion-frame > .notion-scroller', + toolbarSelector = '.notion-calendar-view > :first-child > :first-child > :first-child', + todaySelector = '.notion-calendar-view-day[style*="background:"]'; + +export default function ({ web }, db) { + const insertButton = () => { + document.querySelectorAll(calendarSelector).forEach(($calendar) => { + $calendar.dataset.calendarScroll = true; + const $page = document.querySelector(pageSelector); + if ($page) return; + const $toolbar = $calendar.querySelector(toolbarSelector), + $pageScroller = document.querySelector(scrollerSelector), + $scrollButton = web.html``; + $scrollButton.addEventListener('click', async (event) => { + let $today = $calendar.querySelector(todaySelector); + if (!$today) { + $toolbar.children[4].click(); + await new Promise((res, rej) => setTimeout(res, 500)); + $today = $calendar.querySelector(todaySelector); + } + $pageScroller.scroll({ + top: $today.offsetParent.offsetParent.offsetTop + 70, + behavior: 'auto', + }); + }); + $toolbar.insertBefore($scrollButton, $toolbar.children[2]); + }); + }; + web.addDocumentObserver(insertButton, [calendarSelector]); + insertButton(); +} diff --git a/repo/calendar-scroll/mod.json b/repo/calendar-scroll/mod.json new file mode 100644 index 0000000..5dbd371 --- /dev/null +++ b/repo/calendar-scroll/mod.json @@ -0,0 +1,23 @@ +{ + "name": "calendar scroll", + "id": "b1c7db33-dfee-489a-a76c-0dd66f7ed29a", + "version": "0.2.0", + "description": "adds a button to jump down to the current week in fullpage/infinite-scroll calendars.", + "preview": "calendar-scroll.png", + "tags": ["extension", "shortcut"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [] +} diff --git a/repo/cherry-cola/cherry-cola.png b/repo/cherry-cola/cherry-cola.png new file mode 100644 index 0000000..86a445e Binary files /dev/null and b/repo/cherry-cola/cherry-cola.png differ diff --git a/repo/cherry-cola/mod.json b/repo/cherry-cola/mod.json new file mode 100644 index 0000000..e81c336 --- /dev/null +++ b/repo/cherry-cola/mod.json @@ -0,0 +1,23 @@ +{ + "name": "cherry cola", + "id": "ec5c4640-68d4-4d25-aefd-62c7e9737cfb", + "version": "0.2.0", + "description": "a delightfully plummy, cherry cola flavored theme.", + "preview": "cherry-cola.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "runargs", + "email": "alnbaldon@gmail.com", + "homepage": "http://github.com/runargs", + "avatar": "https://avatars.githubusercontent.com/u/39810066" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/cherry-cola/variables.css b/repo/cherry-cola/variables.css new file mode 100644 index 0000000..e2cc5f9 --- /dev/null +++ b/repo/cherry-cola/variables.css @@ -0,0 +1,172 @@ +/** + * notion-enhancer: cherry cola + * (c) 2020 Alexa Baldon (https://github.com/runargs) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --cola--main: #180915; + --cola--sec: #1d0919; + --cola--tet: #492341; + --cola--info: #9b6890; + --cola--accent: #bf799b; + --cola--light_gray: #ADADAD; + --cola--gray: #8a8a8a; + --cola--brown: #755241; + --cola--orange: #e6846b; + --cola--yellow: #d7b56e; + --cola--green: #8f9b4f; + --cola--blue: #6ebdb7; + --cola--purple: #813d63; + --cola--pink: #d86f71; + --cola--red: #a33232; + + --theme--accent_blue: var(--cola--accent); + --theme--accent_blue-selection: rgba(78, 32, 69, 0.5); + --theme--accent_blue-hover: #bd6992; + --theme--accent_blue-active: #cc86a8; + --theme--accent_blue-text: #fff; + --theme--accent_red: var(--cola--accent); + --theme--accent_red-button: #bf799b63; + --theme--accent_red-text: #fff; + + --theme--bg: var(--cola--main); + --theme--bg_secondary: var(--cola--sec); + --theme--bg_card: var(--cola--sec); + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: var(--cola--sec); + --theme--scrollbar_thumb-hover: var(--cola--accent); + + --theme--ui_divider: rgba(73, 35, 65, 0.7); + --theme--ui_interactive-hover: var(--cola--tet); + --theme--ui_interactive-active: var(--cola--tet); + --theme--ui_toggle-off: rgba(73, 35, 65, 0.7); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: #fff; + --theme--icon_secondary: var(--cola--info); + + --theme--text: #fff; + --theme--text_secondary: var(--cola--info); + --theme--text_gray: var(--cola--gray); + --theme--text_brown: var(--cola--brown); + --theme--text_orange: var(--cola--orange); + --theme--text_yellow: var(--cola--yellow); + --theme--text_green: var(--cola--green); + --theme--text_blue: var(--cola--blue); + --theme--text_purple: var(--cola--purple); + --theme--text_pink: var(--cola--pink); + --theme--text_red: var(--cola--red); + + --theme--highlight_gray: var(--theme--tag_gray); + --theme--highlight_gray-text: var(--theme--tag-text); + --theme--highlight_brown: var(--theme--tag_brown); + --theme--highlight_brown-text: var(--theme--tag-text); + --theme--highlight_orange: var(--theme--tag_orange); + --theme--highlight_orange-text: var(--theme--tag-text); + --theme--highlight_yellow: var(--theme--tag_yellow); + --theme--highlight_yellow-text: var(--theme--tag-text); + --theme--highlight_green: var(--theme--tag_green); + --theme--highlight_green-text: var(--theme--tag-text); + --theme--highlight_blue: var(--theme--tag_blue); + --theme--highlight_blue-text: var(--theme--tag-text); + --theme--highlight_purple: var(--theme--tag_purple); + --theme--highlight_purple-text: var(--theme--tag-text); + --theme--highlight_pink: var(--theme--tag_pink); + --theme--highlight_pink-text: var(--theme--tag-text); + --theme--highlight_red: var(--theme--tag_red); + --theme--highlight_red-text: var(--theme--tag-text); + + --theme--callout_gray: var(--theme--tag_gray); + --theme--callout_gray-text: var(--theme--tag-text); + --theme--callout_brown: var(--theme--tag_brown); + --theme--callout_brown-text: var(--theme--tag-text); + --theme--callout_orange: var(--theme--tag_orange); + --theme--callout_orange-text: var(--theme--tag-text); + --theme--callout_yellow: var(--theme--tag_yellow); + --theme--callout_yellow-text: var(--theme--tag-text); + --theme--callout_green: var(--theme--tag_green); + --theme--callout_green-text: var(--theme--tag-text); + --theme--callout_blue: var(--theme--tag_blue); + --theme--callout_blue-text: var(--theme--tag-text); + --theme--callout_purple: var(--theme--tag_purple); + --theme--callout_purple-text: var(--theme--tag-text); + --theme--callout_pink: var(--theme--tag_pink); + --theme--callout_pink-text: var(--theme--tag-text); + --theme--callout_red: var(--theme--tag_red); + --theme--callout_red-text: var(--theme--tag-text); + + --theme--tag_light_gray: var(--cola--light_gray); + --theme--tag_light_gray-text: var(--cola--main); + --theme--tag_gray: var(--cola--gray); + --theme--tag_gray-text: var(--cola--main); + --theme--tag_brown: var(--cola--brown); + --theme--tag_brown-text: #ffffff; + --theme--tag_orange: var(--cola--orange); + --theme--tag_orange-text: var(--cola--main); + --theme--tag_yellow: var(--cola--yellow); + --theme--tag_yellow-text: var(--cola--main); + --theme--tag_green: var(--cola--green); + --theme--tag_green-text: var(--cola--main); + --theme--tag_blue: var(--cola--blue); + --theme--tag_blue-text: var(--cola--main); + --theme--tag_purple: var(--cola--purple); + --theme--tag_purple-text: #ffffff; + --theme--tag_pink: var(--cola--pink); + --theme--tag_pink-text: var(--cola--main); + --theme--tag_red: var(--cola--red); + --theme--tag_red-text: #ffffff; + + --theme--board_light_gray: var(--cola--light_gray); + --theme--board_light_gray-text: var(--cola--main); + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_gray: var(--cola--gray); + --theme--board_gray-text: var(--cola--main); + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_brown: var(--cola--brown); + --theme--board_brown-text: var(--cola--main); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_orange: var(--cola--orange); + --theme--board_orange-text: var(--cola--main); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_yellow: var(--cola--yellow); + --theme--board_yellow-text: var(--cola--main); + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_green: var(--cola--green); + --theme--board_green-text: var(--cola--main); + --theme--board_green-card: var(--theme--tag_green); + --theme--board_blue: var(--cola--blue); + --theme--board_blue-text: var(--cola--main); + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_purple: var(--cola--purple); + --theme--board_purple-text: var(--cola--main); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_pink: var(--cola--pink); + --theme--board_pink-text: var(--cola--main); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_red: var(--cola--red); + --theme--board_red-text: var(--cola--main); + --theme--board_red-card: var(--theme--tag_red); + + --theme--code_inline: var(--cola--main); + --theme--code_inline-text: var(--cola--accent); + + --theme--code: var(--cola--sec); + --theme--code_function: var(--theme--text_blue); + --theme--code_keyword: var(--theme--text_pink); + --theme--code_tag: var(--theme--text_pink); + --theme--code_operator: var(--theme--text_yellow); + --theme--code_property: var(--theme--text_pink); + --theme--code_builtin: var(--theme--text_yellow); + --theme--code_attr-name: var(--theme--text_yellow); + --theme--code_comment: var(--theme--text_gray); + --theme--code_punctuation: var(--theme--text_gray); + --theme--code_doctype: var(--theme--text_gray); + --theme--code_number: var(--theme--text_purple); + --theme--code_selector: var(--theme--text_orange); + --theme--code_atrule: var(--theme--text_orange); + --theme--code_regex: var(--theme--text_yellow); +} diff --git a/repo/code-line-numbers/client.css b/repo/code-line-numbers/client.css new file mode 100644 index 0000000..5f3a4df --- /dev/null +++ b/repo/code-line-numbers/client.css @@ -0,0 +1,63 @@ +/** + * notion-enhancer: code line numbers + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-code-block.line-numbers { + position: relative; +} +.code_line_numbers--plain:not(:empty) + div, +.code_line_numbers--background:not(:empty) + div, +.code_line_numbers--border:not(:empty) + div { + padding-left: 64px !important; +} + +.code_line_numbers--plain, +.code_line_numbers--background, +.code_line_numbers--border { + position: absolute; + left: 0; + right: calc(100% - 64px); + top: 34px; + bottom: 32px; + padding-right: 27px; + + font-size: 85%; + font-family: var(--theme--font_code); + text-align: right; + line-height: 1.5; + opacity: 0.8; + color: var(--theme--text_secondary); + + overflow: hidden; + pointer-events: none; +} +.code_line_numbers--plain:empty, +.code_line_numbers--background:empty, +.code_line_numbers--border:empty { + display: none; +} +.code_line_numbers--background::before { + content: ''; + position: absolute; + top: 0; + left: 7.25px; + width: calc(100% - 27px); + height: 100%; + display: block; + background-color: var(--theme--bg); + border-radius: 4px; + z-index: -1; +} +.code_line_numbers--border::before { + content: ''; + position: absolute; + top: 0; + right: calc(100% - 52px); + width: 2px; + height: 100%; + display: block; + background-color: var(--theme--ui_divider); +} diff --git a/repo/code-line-numbers/client.mjs b/repo/code-line-numbers/client.mjs new file mode 100644 index 0000000..5072b39 --- /dev/null +++ b/repo/code-line-numbers/client.mjs @@ -0,0 +1,62 @@ +/** + * notion-enhancer: code line numbers + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ web }, db) { + const singleLined = await db.get(['single_lined']), + codeBlockSelector = '.notion-code-block.line-numbers', + numbersClass = `code_line_numbers--${await db.get(['style'])}`, + $temp = web.html``; + + const numberCodeBlock = ($codeBlock) => { + const $numbers = + $codeBlock.querySelector(`.${numbersClass}`) || + web.html`1`; + if (!$codeBlock.contains($numbers)) $codeBlock.prepend($numbers); + + const lines = $codeBlock.lastElementChild.innerText.split(/\r\n|\r|\n/), + wordWrap = $codeBlock.lastElementChild.style.wordBreak === 'break-all'; + if (lines.reverse()[0] === '') lines.pop(); + + let lineNumbers = ''; + for (let i = 1; i <= lines.length + 1; i++) { + lineNumbers += `${i}\n`; + if (wordWrap && lines[i - 1]) { + $temp.innerText = lines[i - 1]; + web.render($codeBlock.lastElementChild, $temp); + const height = parseFloat($temp.getBoundingClientRect().height); + $temp.remove(); + for (let j = 1; j < height / 20.4; j++) lineNumbers += '\n'; + } + } + + if (!singleLined && lines.length < 2) lineNumbers = ''; + if ($numbers.innerText !== lineNumbers) $numbers.innerText = lineNumbers; + }, + numberAllCodeBlocks = () => { + for (const $codeBlock of document.querySelectorAll(codeBlockSelector)) { + numberCodeBlock($codeBlock); + } + }, + observeCodeBlocks = (event) => { + const tempEvent = [...event.addedNodes, ...event.removedNodes].includes($temp), + numbersEvent = + event.target.classList.contains(numbersClass) || + [...event.addedNodes, ...event.removedNodes].some(($node) => + $node?.classList?.contains(numbersClass) + ), + codeEvent = event.target.matches(`${codeBlockSelector}, ${codeBlockSelector} *`); + if (tempEvent || numbersEvent || !codeEvent) return; + + let $codeBlock = event.target; + while (!$codeBlock.matches(codeBlockSelector)) $codeBlock = $codeBlock.parentElement; + numberCodeBlock($codeBlock); + }; + + await web.whenReady(); + numberAllCodeBlocks(); + web.addDocumentObserver(observeCodeBlocks, [codeBlockSelector]); +} diff --git a/repo/code-line-numbers/code-line-numbers.png b/repo/code-line-numbers/code-line-numbers.png new file mode 100644 index 0000000..c1b6b08 Binary files /dev/null and b/repo/code-line-numbers/code-line-numbers.png differ diff --git a/repo/code-line-numbers/mod.json b/repo/code-line-numbers/mod.json new file mode 100644 index 0000000..4e9c0d4 --- /dev/null +++ b/repo/code-line-numbers/mod.json @@ -0,0 +1,36 @@ +{ + "name": "code line numbers", + "id": "d61dc8a7-b195-465b-935f-53eea9efe74e", + "version": "0.4.0", + "description": "adds line numbers to code blocks.", + "preview": "code-line-numbers.png", + "tags": ["extension", "usability"], + "authors": [ + { + "name": "CloudHill", + "email": "rh.cloudhill@gmail.com", + "homepage": "https://github.com/CloudHill", + "avatar": "https://avatars.githubusercontent.com/u/54142180" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [ + { + "type": "toggle", + "key": "single_lined", + "label": "number single-lined code blocks", + "value": false + }, + { + "type": "select", + "key": "style", + "label": "line number style", + "values": ["plain", "background", "border"] + } + ] +} diff --git a/repo/collapsible-properties/client.css b/repo/collapsible-properties/client.css new file mode 100644 index 0000000..84eba06 --- /dev/null +++ b/repo/collapsible-properties/client.css @@ -0,0 +1,56 @@ +/** + * notion-enhancer: collapse properties + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +#enhancer--collapse-properties { + display: flex; + background: var(--theme--ui_interactive-hover); + border: 1px solid transparent; + font-size: 14px; + border-radius: 3px; + line-height: 1.2; + font-weight: 600; + padding: 0.3em 0.5em; + margin: 1em 0; + width: 100%; +} +#enhancer--collapse-properties:focus, +#enhancer--collapse-properties:hover { + background: transparent; + border: 1px solid var(--theme--ui_interactive-hover); +} +#enhancer--collapse-properties:active { + background: var(--theme--ui_interactive-active); +} + +#enhancer--collapse-properties > span { + text-align: left; + color: var(--theme--text); +} +#enhancer--collapse-properties > span:before { + content: 'Properties'; +} +#enhancer--collapse-properties > svg { + fill: var(--theme--icon); + height: 0.8em; + width: 0.8em; + margin: auto 0.5em auto 0; + transition: transform 200ms ease-out 0s; +} + +#enhancer--collapse-properties[data-collapsed='false'] > svg { + transform: rotateZ(180deg); +} +#enhancer--collapse-properties[data-collapsed='true'] > svg { + transform: rotateZ(90deg); +} + +#enhancer--collapse-properties + div { + overflow: hidden; +} +#enhancer--collapse-properties[data-collapsed='true'] + div { + max-height: 0 !important; + opacity: 0; +} diff --git a/repo/collapsible-properties/client.mjs b/repo/collapsible-properties/client.mjs new file mode 100644 index 0000000..28f88e8 --- /dev/null +++ b/repo/collapsible-properties/client.mjs @@ -0,0 +1,35 @@ +/** + * notion-enhancer: collapse properties + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default function ({ web, notion }, db) { + const propertyListSelector = + '.notion-scroller.vertical [style*="env(safe-area-inset-left)"] > [style="width: 100%; font-size: 14px;"]', + $collapseButton = web.html``; + $collapseButton.addEventListener('click', async (event) => { + if ($collapseButton.dataset.collapsed === 'true') { + await db.set([notion.getPageID()], false); + $collapseButton.dataset.collapsed = false; + } else { + await db.set([notion.getPageID()], true); + $collapseButton.dataset.collapsed = true; + } + }); + const insertButton = async () => { + if (document.contains($collapseButton)) return; + const $propertyList = document.querySelector(propertyListSelector); + if ($propertyList) { + $collapseButton.dataset.collapsed = await db.get([notion.getPageID()], true); + $propertyList.before($collapseButton); + } + }; + web.addDocumentObserver(insertButton, [propertyListSelector]); + insertButton(); +} diff --git a/repo/collapsible-properties/collapsible-properties.jpg b/repo/collapsible-properties/collapsible-properties.jpg new file mode 100644 index 0000000..1489e8f Binary files /dev/null and b/repo/collapsible-properties/collapsible-properties.jpg differ diff --git a/repo/collapsible-properties/mod.json b/repo/collapsible-properties/mod.json new file mode 100644 index 0000000..7ef89df --- /dev/null +++ b/repo/collapsible-properties/mod.json @@ -0,0 +1,23 @@ +{ + "name": "collapsible properties", + "id": "4034a578-7dd3-4633-80c6-f47ac5b7b160", + "version": "0.3.0", + "description": "adds a button to quickly collapse/expand page properties that usually push down page content.", + "preview": "collapsible-properties.jpg", + "tags": ["extension", "layout"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "client": ["client.css"] + }, + "js": { + "client": ["client.mjs"] + }, + "options": [] +} diff --git a/repo/components/mod.json b/repo/components/mod.json new file mode 100644 index 0000000..ceb59ed --- /dev/null +++ b/repo/components/mod.json @@ -0,0 +1,33 @@ +{ + "__comment": "pseudo-mod to allow configuration of api-provided components", + "name": "components", + "id": "36a2ffc9-27ff-480e-84a7-c7700a7d232d", + "version": "0.2.0", + "description": "shared notion-style elements.", + "tags": ["core"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + }, + { + "name": "CloudHill", + "email": "rh.cloudhill@gmail.com", + "homepage": "https://github.com/CloudHill", + "avatar": "https://avatars.githubusercontent.com/u/54142180" + } + ], + "js": {}, + "css": {}, + "options": [ + { + "type": "hotkey", + "key": "panel.hotkey", + "label": "toggle panel hotkey", + "value": "Ctrl+Alt+\\", + "tooltip": "**opens/closes the side panel in notion** if a mod that uses it has been enabled" + } + ] +} diff --git a/repo/dark+/dark+.png b/repo/dark+/dark+.png new file mode 100644 index 0000000..b00aaec Binary files /dev/null and b/repo/dark+/dark+.png differ diff --git a/repo/dark+/mod.json b/repo/dark+/mod.json new file mode 100644 index 0000000..1bef8f6 --- /dev/null +++ b/repo/dark+/mod.json @@ -0,0 +1,42 @@ +{ + "name": "dark+", + "id": "c86cfe98-e645-4822-aa6b-e2de1e08bafa", + "version": "0.2.0", + "description": "a vivid-colour near-black theme, with configurable accents.", + "preview": "dark+.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": { + "frame": ["theme.mjs"], + "client": ["theme.mjs"], + "menu": ["theme.mjs"] + }, + "options": [ + { + "type": "color", + "key": "primary", + "label": "primary accent color", + "tooltip": "**replaces notion's blue accent**", + "value": "rgba(46,170,220,1)" + }, + { + "type": "color", + "key": "secondary", + "label": "secondary accent color", + "tooltip": "**replaces notion's red accent**", + "value": "rgba(235,87,87,1)" + } + ] +} diff --git a/repo/dark+/theme.mjs b/repo/dark+/theme.mjs new file mode 100644 index 0000000..ea464fb --- /dev/null +++ b/repo/dark+/theme.mjs @@ -0,0 +1,55 @@ +/** + * notion-enhancer: dark+ + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ fmt }, db) { + { + const primary = await db.get(['primary']), + [r, g, b] = primary + .slice(5, -1) + .split(',') + .map((i) => parseInt(i)); + if (!(r === 46 && g === 170 && b === 220)) { + document.documentElement.style.setProperty('--dark_plus--accent_blue', primary); + document.documentElement.style.setProperty( + '--dark_plus--accent_blue-selection', + `rgba(${r},${g},${b},0.2)` + ); + document.documentElement.style.setProperty( + '--dark_plus--accent_blue-hover', + fmt.rgbLogShade(0.05, primary) + ); + document.documentElement.style.setProperty( + '--dark_plus--accent_blue-active', + fmt.rgbLogShade(0.025, primary) + ); + document.documentElement.style.setProperty( + '--dark_plus--accent_blue-text', + fmt.rgbContrast(r, g, b) + ); + } + } + + { + const secondary = await db.get(['secondary']), + [r, g, b] = secondary + .slice(5, -1) + .split(',') + .map((i) => parseInt(i)); + if (!(r === 235 && g === 87 && b === 87)) { + document.documentElement.style.setProperty('--dark_plus--accent_red', secondary); + document.documentElement.style.setProperty( + '--dark_plus--accent_red-button', + `rgba(${r},${g},${b},0.2)` + ); + document.documentElement.style.setProperty( + '--dark_plus--accent_red-text', + fmt.rgbContrast(r, g, b) + ); + } + } +} diff --git a/repo/dark+/variables.css b/repo/dark+/variables.css new file mode 100644 index 0000000..4f757d7 --- /dev/null +++ b/repo/dark+/variables.css @@ -0,0 +1,132 @@ +/** + * notion-enhancer: dark+ + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --theme--accent_blue: var(--dark_plus--accent_blue, rgb(46, 170, 220)); + --theme--accent_blue-selection: var( + --dark_plus--accent_blue-selection, + rgb(46, 170, 220, 0.25) + ); + --theme--accent_blue-hover: var(--dark_plus--accent_blue-hover, rgb(6, 156, 205)); + --theme--accent_blue-active: var(--dark_plus--accent_blue-active, rgb(0, 141, 190)); + --theme--accent_blue-text: var(--dark_plus--accent_blue-text, #fff); + --theme--accent_red: var(--dark_plus--accent_red, #eb5757); + --theme--accent_red-button: var(--dark_plus--accent_red-button, rgba(235, 87, 87, 0.1)); + --theme--accent_red-text: var(--dark_plus--accent_red-text, #fff); + + --theme--bg: rgb(14, 14, 14); + --theme--bg_secondary: rgb(0, 0, 0); + --theme--bg_card: rgb(0, 0, 0); + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: #181818; + --theme--scrollbar_thumb-hover: #222222; + + --theme--ui_divider: rgba(36, 36, 36, 0.7); + --theme--ui_interactive-hover: rgba(55, 56, 56, 0.3); + --theme--ui_interactive-active: rgba(55, 56, 56, 0.402); + --theme--ui_toggle-on: var(--theme--accent_blue); + --theme--ui_toggle-off: rgb(40, 40, 40); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: rgb(228, 228, 228); + --theme--icon_secondary: rgba(211, 211, 211, 0.637); + + --theme--text: rgb(255, 255, 255); + --theme--text_secondary: rgb(228, 228, 228); + --theme--text_gray: rgba(151, 154, 155, 0.95); + --theme--text_brown: rgb(147, 114, 100); + --theme--text_orange: rgb(255, 163, 68); + --theme--text_yellow: rgb(255, 220, 73); + --theme--text_green: rgb(50, 169, 104); + --theme--text_blue: rgb(82, 156, 202); + --theme--text_purple: rgb(154, 109, 215); + --theme--text_pink: rgb(226, 85, 161); + --theme--text_red: rgb(218, 47, 35); + + --theme--highlight_gray: var(--theme--tag_gray); + --theme--highlight_brown: var(--theme--tag_brown); + --theme--highlight_orange: var(--theme--tag_orange); + --theme--highlight_yellow: var(--theme--tag_yellow); + --theme--highlight_green: var(--theme--tag_green); + --theme--highlight_blue: var(--theme--tag_blue); + --theme--highlight_purple: var(--theme--tag_purple); + --theme--highlight_pink: var(--theme--tag_pink); + --theme--highlight_red: var(--theme--tag_red); + + --theme--callout_gray: rgba(126, 128, 129, 0.301); + --theme--callout_brown: #50331fad; + --theme--callout_orange: rgba(255, 153, 0, 0.315); + --theme--callout_yellow: rgba(183, 156, 0, 0.445); + --theme--callout_green: rgba(50, 129, 47, 0.39); + --theme--callout_blue: rgba(0, 90, 146, 0.521); + --theme--callout_purple: rgba(90, 49, 148, 0.349); + --theme--callout_pink: rgba(243, 61, 158, 0.301); + --theme--callout_red: rgba(122, 20, 20, 0.623); + + --theme--tag_light_gray: rgba(165, 166, 167, 0.5); + --theme--tag_gray: rgba(126, 128, 129, 0.5); + --theme--tag_brown: #50331f; + --theme--tag_orange: rgba(255, 155, 0, 0.58); + --theme--tag_yellow: rgba(183, 155, 0, 1); + --theme--tag_green: rgb(50, 129, 47); + --theme--tag_blue: rgba(0, 90, 146, 0.71); + --theme--tag_purple: rgba(91, 49, 148, 0.74); + --theme--tag_pink: rgba(243, 61, 159, 0.5); + --theme--tag_red: rgb(122, 20, 20); + + --theme--board_light_gray: rgba(165, 166, 167, 0.089); + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_light_gray-card_text: var(--theme--tag_light_gray-text); + --theme--board_gray: rgba(126, 128, 129, 0.089); + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_gray-card_text: var(--theme--tag_gray-text); + --theme--board_brown: #50331f59; + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_brown-card_text: var(--theme--tag_brown-text); + --theme--board_orange: rgba(255, 153, 0, 0.164); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_orange-card_text: var(--theme--tag_orange-text); + --theme--board_yellow: rgba(183, 156, 0, 0.274); + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_yellow-card_text: var(--theme--tag_yellow-text); + --theme--board_green: rgba(50, 129, 47, 0.191); + --theme--board_green-card: var(--theme--tag_green); + --theme--board_green-card_text: var(--theme--tag_green-text); + --theme--board_blue: rgba(0, 90, 146, 0.294); + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_purple: rgba(90, 49, 148, 0.219); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_purple-card_text: var(--theme--tag_purple-text); + --theme--board_pink: rgba(243, 61, 158, 0.191); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_pink-card_text: var(--theme--tag_pink-text); + --theme--board_red: rgba(122, 20, 20, 0.376); + --theme--board_red-card: var(--theme--tag_red); + --theme--board_red-card_text: var(--theme--tag_red-text); + + --theme--code_inline-text: #7dc582; + --theme--code_inline-background: rgb(0, 0, 0); + + --theme--code: rgb(0, 0, 0); + --theme--code_plain: var(--theme--text); + --theme--code_function: #c7e1ff; + --theme--code_keyword: #c397d8; + --theme--code_property: #82aed8; + --theme--code_operator: rgb(166, 175, 201); + --theme--code_regex: #da265f; + --theme--code_property: #82aed8; + --theme--code_builtin: #ff6294; + --theme--code_selector: #ff6294; + --theme--code_comment: rgb(166, 175, 201); + --theme--code_punctuation: rgb(166, 175, 201); + --theme--code_doctype: rgb(166, 175, 201); + --theme--code_number: #c397d8; + --theme--code_string: #7dc582; + --theme--code_atrule: #7dc582; +} diff --git a/repo/dracula/app.css b/repo/dracula/app.css new file mode 100644 index 0000000..449ffe4 --- /dev/null +++ b/repo/dracula/app.css @@ -0,0 +1,84 @@ +/** + * notion-enhancer: dracula + * (c) 2016 Dracula Theme + * (c) 2020 CloudHill + * (c) 2020 mimishahzad + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-dark-theme img[src*='/images/onboarding/use-case-note.png'], +.notion-dark-theme img[src*='/images/onboarding/team-features-illustration.png'] { + filter: invert(1) !important; +} +.notion-dark-theme img[src*='/images/onboarding/checked.svg'] { + filter: hue-rotate(45deg) !important; +} +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 100%; width: 90px; height: 90px;'], +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 3px; width: 56.832px; height: 56.832px; transition: opacity 100ms ease-out 0s;'] { + transition: filter 0.4s ease !important; +} +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 100%; width: 90px; height: 90px;']:hover, +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 3px; width: 56.832px; height: 56.832px; transition: opacity 100ms ease-out 0s;']:hover { + filter: brightness(1.2); +} + +.notion-dark-theme .notion-token-remove-button[role*='button'][tabindex*='0']:hover, +.notion-dark-theme .notion-record-icon { + background: transparent !important; +} + +.notion-dark-theme .notion-focusable:focus-within, +.notion-dark-theme .notion-to_do-block > div > div > div[style*='background:'], +.notion-dark-theme div[role='button'], +[style*='height: 4px;'] > .notion-selectable.notion-collection_view_page-block > *, +.notion-dark-theme .notion-calendar-view-day[style*='background: #282a36;'], +.DayPicker-Day--today, +.notion-dark-theme + .DayPicker:not(.DayPicker--interactionDisabled) + .DayPicker-Day--outside:hover, +.notion-dark-theme + .DayPicker:not(.DayPicker--interactionDisabled) + .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--value) + .DayPicker-Day.DayPicker-Day--start.DayPicker-Day--selected, +.notion-dark-theme .DayPicker-Day.DayPicker-Day--range.DayPicker-Day--start, +.notion-dark-theme .DayPicker-Day.DayPicker-Day--range.DayPicker-Day--end { + transition: color 0.4s ease, background 0.4s ease, box-shadow 0.4s ease !important; +} + +.notion-dark-theme [style*='background: #282a36;'], +.notion-dark-theme + [style*='background: rgb(80, 85, 88);'][style*='color: rgba(255, 255, 255, 0.7)'], +.notion-dark-theme + [style*='background: rgb(80, 85, 88);'][style*='width: 18px;'][style*='height: 18px;'], +.notion-dark-theme + [style*='box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, rgba(15, 15, 15, 0.2) 0px 5px 10px, rgba(15, 15, 15, 0.4) 0px 15px 40px;'], +.notion-dark-theme [style*='background: rgba(151, 154, 155, 0.5);'], +.notion-dark-theme [style*='background: rgba(147, 114, 100, 0.5)'], +.notion-dark-theme [style*='background: rgba(255, 163, 68, 0.5)'], +.notion-dark-theme [style*='background: rgba(255, 220, 73, 0.5)'], +.notion-dark-theme [style*='background: rgba(77, 171, 154, 0.5)'], +.notion-dark-theme [style*='background: rgba(82, 156, 202, 0.5)'], +.notion-dark-theme [style*='background: rgba(154, 109, 215, 0.5)'], +.notion-dark-theme [style*='background: rgba(226, 85, 161, 0.5)'], +.notion-dark-theme [style*='background: rgba(255, 115, 105, 0.5)'] { + box-shadow: 0 2px 4px rgb(0 0 0 / 66%) !important; +} + +.notion-dark-theme .notion-code-block .token.parameter, +.notion-dark-theme .notion-code-block .token.decorator, +.notion-dark-theme .notion-code-block .token.id, +.notion-dark-theme .notion-code-block .token.class, +.notion-dark-theme .notion-code-block .token.pseudo-element, +.notion-dark-theme .notion-code-block .token.pseudo-class, +.notion-dark-theme .notion-code-block .token.attribute { + font-style: italic; +} + +.notion-dark-theme .notion-code-block .token.punctuation { + opacity: 1; +} diff --git a/repo/dracula/dracula.png b/repo/dracula/dracula.png new file mode 100644 index 0000000..035ca0a Binary files /dev/null and b/repo/dracula/dracula.png differ diff --git a/repo/dracula/mod.json b/repo/dracula/mod.json new file mode 100644 index 0000000..3eb186b --- /dev/null +++ b/repo/dracula/mod.json @@ -0,0 +1,28 @@ +{ + "name": "dracula", + "id": "033bff54-50ba-4cec-bdc0-b2ca7e307086", + "version": "0.3.0", + "description": "a theme based on the popular dracula color palette originally by zeno rocha and friends.", + "preview": "dracula.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "dracula", + "email": "zno.rocha@gmail.com", + "homepage": "https://draculatheme.com/", + "avatar": "https://draculatheme.com/static/icons/pack-1/045-dracula.svg" + }, + { + "name": "mimishahzad", + "homepage": "https://github.com/mimishahzad", + "avatar": "https://avatars.githubusercontent.com/u/34081810" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css", "app.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/dracula/variables.css b/repo/dracula/variables.css new file mode 100644 index 0000000..0ef8311 --- /dev/null +++ b/repo/dracula/variables.css @@ -0,0 +1,213 @@ +/** + * notion-enhancer: dracula + * (c) 2016 Dracula Theme + * (c) 2020 mimishahzad + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --dracula--bg: #282a36; + --dracula--bg_lighter: #424450; + --dracula--bg_light: #343746; + --dracula--bg_dark: #21222c; + --dracula--bg_darker: #191a21; + + --dracula--fg: #f8f8f2; + --dracula--fg_dark: #babbba; + + --dracula--comment: #6272a4; + --dracula--selection: #44475a; + --dracula--block_highlight: #44475a75; + + --dracula--light_gray: #CFCFCF; + --dracula--gray: var(--dracula--fg_dark); + --dracula--brown: #6272a4; + --dracula--orange: #ffb86c; + --dracula--yellow: #f1fa8c; + --dracula--green: #50fa7b; + --dracula--blue: #8be9fd; + --dracula--purple: #bd93f9; + --dracula--pink: #ff79c6; + --dracula--red: #ff5555; + + --dracula--bg_light_gray: #71737E; + --dracula--bg_gray: var(--dracula--bg_light); + --dracula--bg_brown: #465079; + --dracula--bg_orange: #8a6345; + --dracula--bg_yellow: #8e9656; + --dracula--bg_green: #3f945f; + --dracula--bg_blue: #498096; + --dracula--bg_purple: #6a549b; + --dracula--bg_pink: #8d4a7c; + --dracula--bg_red: #943844; + + --theme--accent_blue: var(--dracula--purple); + --theme--accent_blue-selection: #bb8dfd3d; + --theme--accent_blue-hover: #b179ff; + --theme--accent_blue-active: #9f5ff8; + --theme--accent_red: var(--dracula--comment); + --theme--accent_red-button: #6273a439; + + --theme--danger_text: var(--dracula--red); + --theme--danger_border: var(--dracula--bg_red); + + --theme--bg: var(--dracula--bg); + --theme--bg_secondary: var(--dracula--bg_dark); + --theme--bg_card: var(--dracula--bg_light); + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: var(--dracula--selection); + --theme--scrollbar_thumb-hover: var(--dracula--comment); + + --theme--ui_divider: var(--dracula--bg_lighter); + --theme--ui_interactive-hover: var(--dracula--block_highlight); + --theme--ui_interactive-active: var(--dracula--bg_lighter); + --theme--ui_toggle-off: var(--dracula--block_highlight); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: var(--dracula--comment); + --theme--icon_secondary: var(--dracula--comment); + + --theme--text: var(--dracula--fg); + --theme--text_secondary: var(--dracula--fg_dark); + --theme--text_gray: var(--dracula--gray); + --theme--text_brown: var(--dracula--brown); + --theme--text_orange: var(--dracula--orange); + --theme--text_yellow: var(--dracula--yellow); + --theme--text_green: var(--dracula--green); + --theme--text_blue: var(--dracula--blue); + --theme--text_purple: var(--dracula--purple); + --theme--text_pink: var(--dracula--pink); + --theme--text_red: var(--dracula--red); + + --theme--highlight_gray: var(--dracula--gray); + --theme--highlight_gray-text: var(--dracula--bg); + --theme--highlight_brown: var(--dracula--brown); + --theme--highlight_brown-text: var(--dracula--fg); + --theme--highlight_orange: var(--dracula--orange); + --theme--highlight_orange-text: var(--dracula--bg); + --theme--highlight_yellow: var(--dracula--yellow); + --theme--highlight_yellow-text: var(--dracula--bg); + --theme--highlight_green: var(--dracula--green); + --theme--highlight_green-text: var(--dracula--bg); + --theme--highlight_blue: var(--dracula--blue); + --theme--highlight_blue-text: var(--dracula--bg); + --theme--highlight_purple: var(--dracula--purple); + --theme--highlight_purple-text: var(--dracula--bg); + --theme--highlight_pink: var(--dracula--pink); + --theme--highlight_pink-text: var(--dracula--bg); + --theme--highlight_red: var(--dracula--red); + --theme--highlight_red-text: var(--dracula--fg); + + --theme--callout_gray: var(--dracula--bg_gray); + --theme--callout_brown: var(--dracula--bg_brown); + --theme--callout_orange: var(--dracula--bg_orange); + --theme--callout_yellow: var(--dracula--bg_yellow); + --theme--callout_green: var(--dracula--bg_green); + --theme--callout_blue: var(--dracula--bg_blue); + --theme--callout_purple: var(--dracula--bg_purple); + --theme--callout_pink: var(--dracula--bg_pink); + --theme--callout_red: var(--dracula--bg_red); + + --theme--tag_default: var(--dracula--comment); + --theme--tag_default-text: var(--dracula--fg); + --theme--tag_light_gray: var(--dracula--light_gray); + --theme--tag_light_gray-text: var(--dracula--bg); + --theme--tag_gray: var(--dracula--gray); + --theme--tag_gray-text: var(--dracula--bg); + --theme--tag_brown: var(--dracula--brown); + --theme--tag_brown-text: var(--dracula--fg); + --theme--tag_orange: var(--dracula--orange); + --theme--tag_orange-text: var(--dracula--bg); + --theme--tag_yellow: var(--dracula--yellow); + --theme--tag_yellow-text: var(--dracula--bg); + --theme--tag_green: var(--dracula--green); + --theme--tag_green-text: var(--dracula--bg); + --theme--tag_blue: var(--dracula--blue); + --theme--tag_blue-text: var(--dracula--bg); + --theme--tag_purple: var(--dracula--purple); + --theme--tag_purple-text: var(--dracula--bg); + --theme--tag_pink: var(--dracula--pink); + --theme--tag_pink-text: var(--dracula--bg); + --theme--tag_red: var(--dracula--red); + --theme--tag_red-text: var(--dracula--fg); + + --theme--board_light_gray: var(--dracula--bg_light_gray); + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_light_gray-card_text: var(--theme--tag_light_gray-text); + --theme--board_light_gray-text: var(--dracula--fg); + --theme--board_gray: var(--dracula--bg_gray); + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_gray-card_text: var(--theme--tag_gray-text); + --theme--board_gray-text: var(--dracula--fg); + --theme--board_brown: var(--dracula--bg_brown); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_brown-card_text: var(--theme--tag_brown-text); + --theme--board_brown-text: var(--dracula--fg); + --theme--board_orange: var(--dracula--bg_orange); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_orange-card_text: var(--theme--tag_orange-text); + --theme--board_orange-text: var(--dracula--fg); + --theme--board_yellow: var(--dracula--bg_yellow); + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_yellow-card_text: var(--theme--tag_yellow-text); + --theme--board_yellow-text: var(--dracula--fg); + --theme--board_green: var(--dracula--bg_green); + --theme--board_green-card: var(--theme--tag_green); + --theme--board_green-card_text: var(--theme--tag_green-text); + --theme--board_green-text: var(--dracula--fg); + --theme--board_blue: var(--dracula--bg_blue); + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_blue-card_text: var(--theme--tag_blue-text); + --theme--board_blue-text: var(--dracula--fg); + --theme--board_purple: var(--dracula--bg_purple); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_purple-card_text: var(--theme--tag_purple-text); + --theme--board_purple-text: var(--dracula--fg); + --theme--board_pink: var(--dracula--bg_pink); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_pink-card_text: var(--theme--tag_pink-text); + --theme--board_pink-text: var(--dracula--fg); + --theme--board_red: var(--dracula--bg_red); + --theme--board_red-card: var(--theme--tag_red); + --theme--board_red-card_text: var(--theme--tag_red-text); + --theme--board_red-text: var(--dracula--fg); + + --theme--code_inline: var(--dracula--bg_light); + --theme--code_inline-text: var(--dracula--green); + + --theme--code: var(--dracula--bg_light); + --theme--code_plain: var(--dracula--fg); + --theme--code_function: var(--dracula--green); + --theme--code_parameter: var(--dracula--orange); + --theme--code_keyword: var(--dracula--pink); + --theme--code_constant: var(--dracula--purple); + --theme--code_tag: var(--dracula--pink); + --theme--code_operator: var(--dracula--pink); + --theme--code_important: var(--dracula--pink); + --theme--code_regex: var(--dracula--red); + --theme--code_property: var(--dracula--blue); + --theme--code_builtin: var(--dracula--blue); + --theme--code_class-name: var(--dracula--blue); + --theme--code_attr-name: var(--dracula--green); + --theme--code_attr-value: var(--dracula--yellow); + --theme--code_selector: var(--dracula--pink); + --theme--code_id: var(--dracula--green); + --theme--code_class: var(--dracula--green); + --theme--code_pseudo-element: var(--dracula--green); + --theme--code_pseudo-class: var(--dracula--green); + --theme--code_attribute: var(--dracula--green); + --theme--code_value: var(--dracula--yellow); + --theme--code_unit: var(--dracula--pink); + --theme--code_comment: var(--dracula--comment); + --theme--code_punctuation: var(--dracula--text); + --theme--code_annotation: var(--theme--code_punctuation); + --theme--code_decorator: var(--dracula--green); + --theme--code_doctype: var(--dracula--fg_dark); + --theme--code_number: var(--dracula--purple); + --theme--code_string: var(--dracula--yellow); + --theme--code_boolean: var(--dracula--purple); +} diff --git a/repo/emoji-sets/client.css b/repo/emoji-sets/client.css new file mode 100644 index 0000000..81e3e7d --- /dev/null +++ b/repo/emoji-sets/client.css @@ -0,0 +1,10 @@ +/** + * notion-enhancer: emoji sets + * (c) 2021 Arecsu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +[aria-label][role='image'][style*='Apple Color Emoji']:not([data-emoji-sets-unsupported]) { + margin-left: 2.5px !important; +} diff --git a/repo/emoji-sets/client.mjs b/repo/emoji-sets/client.mjs new file mode 100644 index 0000000..1e6a9bf --- /dev/null +++ b/repo/emoji-sets/client.mjs @@ -0,0 +1,71 @@ +/** + * notion-enhancer: emoji sets + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ web, env }, db) { + const style = await db.get(['style']), + // real emojis are used on macos instead of the twitter set + nativeEmojiSelector = `[aria-label][role="image"][style*="Apple Color Emoji"]:not([data-emoji-sets-unsupported])`, + imgEmojiSelector = '.notion-emoji:not([data-emoji-sets-unsupported])', + imgEmojiOverlaySelector = `${imgEmojiSelector} + [src*="notion-emojis"]`; + + await Promise.any([web.whenReady([nativeEmojiSelector]), web.whenReady([imgEmojiSelector])]); + + const nativeEmojis = document.querySelectorAll(nativeEmojiSelector).length, + imgEmojis = document.querySelectorAll(imgEmojiSelector).length; + + const unsupportedEmojis = [], + emojiReqs = new Map(), + getEmoji = async (emoji) => { + emoji = encodeURIComponent(emoji); + if (unsupportedEmojis.includes(emoji)) return undefined; + try { + if (!emojiReqs.get(emoji)) { + emojiReqs.set(emoji, fetch(`https://emojicdn.elk.sh/${emoji}?style=${style}`)); + } + const res = await emojiReqs.get(emoji); + if (!res.ok) throw new Error(); + return `url("https://emojicdn.elk.sh/${emoji}?style=${style}") 100% 100% / 100%`; + } catch { + unsupportedEmojis.push(emoji); + return undefined; + } + }; + + if (nativeEmojis) { + const updateEmojis = async () => { + const $emojis = document.querySelectorAll(nativeEmojiSelector); + for (const $emoji of $emojis) { + const emojiSrc = await getEmoji($emoji.ariaLabel); + if (emojiSrc) { + $emoji.style.background = emojiSrc; + $emoji.style.width = '1em'; + $emoji.style.height = '1em'; + $emoji.style.display = 'inline-block'; + $emoji.innerText = ''; + } else $emoji.dataset.emojiSetsUnsupported = true; + } + }; + web.addDocumentObserver(updateEmojis, [nativeEmojiSelector]); + } + + if (style !== 'twitter' && imgEmojis) { + const updateEmojis = async () => { + const $emojis = document.querySelectorAll(imgEmojiSelector); + for (const $emoji of $emojis) { + const emojiSrc = await getEmoji($emoji.ariaLabel); + if (emojiSrc) { + $emoji.style.background = emojiSrc; + $emoji.style.opacity = 1; + if ($emoji.nextElementSibling?.matches?.(imgEmojiOverlaySelector)) { + $emoji.nextElementSibling.style.opacity = 0; + } + } else $emoji.dataset.emojiSetsUnsupported = true; + } + }; + updateEmojis(); + web.addDocumentObserver(updateEmojis, [imgEmojiSelector, imgEmojiOverlaySelector]); + } +} diff --git a/repo/emoji-sets/emoji-sets.jpg b/repo/emoji-sets/emoji-sets.jpg new file mode 100644 index 0000000..1716d4c Binary files /dev/null and b/repo/emoji-sets/emoji-sets.jpg differ diff --git a/repo/emoji-sets/mod.json b/repo/emoji-sets/mod.json new file mode 100644 index 0000000..ac3ba3e --- /dev/null +++ b/repo/emoji-sets/mod.json @@ -0,0 +1,46 @@ +{ + "name": "emoji sets", + "id": "a2401ee1-93ba-4b8c-9781-7f570bf5d71e", + "version": "0.4.0", + "description": "pick from a variety of emoji styles to use.", + "preview": "emoji-sets.jpg", + "tags": ["extension", "customisation"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [ + { + "type": "select", + "key": "style", + "label": "emoji style", + "tooltip": "**initial use may involve some lag and load-time for emojis until they have all been cached**", + "values": [ + "twitter", + "apple", + "google", + "microsoft", + "samsung", + "whatsapp", + "facebook", + "messenger", + "joypixels", + "openmoji", + "emojidex", + "lg", + "htc", + "mozilla" + ] + } + ] +} diff --git a/repo/focus-mode/client.css b/repo/focus-mode/client.css new file mode 100644 index 0000000..d615b0c --- /dev/null +++ b/repo/focus-mode/client.css @@ -0,0 +1,21 @@ +/** + * notion-enhancer: focus mode + * (c) 2020 Arecsu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-sidebar-container[style*='width: 0px;'] ~ div .notion-topbar > :first-child { + opacity: 0 !important; + transition: opacity 200ms ease-in-out !important; +} +.notion-sidebar-container[style*='width: 0px;'] ~ div .notion-topbar > :first-child:hover { + opacity: 1 !important; +} + +[data-focus-mode='padded'] + .notion-sidebar-container[style*='width: 0px;'] + ~ div + .notion-frame { + height: calc(100vh - 90px) !important; +} diff --git a/repo/focus-mode/client.mjs b/repo/focus-mode/client.mjs new file mode 100644 index 0000000..8423026 --- /dev/null +++ b/repo/focus-mode/client.mjs @@ -0,0 +1,12 @@ +/** + * notion-enhancer: focus mode + * (c) 2020 Arecsu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function (api, db) { + if (await db.get(['padded'])) document.body.dataset.focusMode = 'padded'; +} diff --git a/repo/focus-mode/mod.json b/repo/focus-mode/mod.json new file mode 100644 index 0000000..0ffb3c8 --- /dev/null +++ b/repo/focus-mode/mod.json @@ -0,0 +1,39 @@ +{ + "name": "focus mode", + "id": "5a08598d-bfac-4167-9ae8-2bd0e2ef141e", + "version": "0.3.0", + "description": "hide the titlebar/menubar when the sidebar is closed (returns on hover).", + "tags": ["extension", "layout"], + "authors": [ + { + "name": "arecsu", + "email": "alejandro9r@gmail.com", + "homepage": "https://github.com/Arecsu", + "avatar": "https://avatars.githubusercontent.com/u/12679098" + } + ], + "css": { + "frame": ["tabs.css"], + "client": ["client.css"] + }, + "js": { + "frame": ["tabs.mjs"], + "client": ["client.mjs"] + }, + "options": [ + { + "type": "toggle", + "key": "padded", + "label": "even padding", + "tooltip": "matches the empty space at the top and sides of the frame with **extra padding at the bottom when the sidebar is hidden**", + "value": true + }, + { + "type": "toggle", + "key": "tabs", + "label": "hide tabs", + "tooltip": "makes the tab bar transparent unless hovered over", + "value": false + } + ] +} diff --git a/repo/focus-mode/tabs.css b/repo/focus-mode/tabs.css new file mode 100644 index 0000000..8b0414f --- /dev/null +++ b/repo/focus-mode/tabs.css @@ -0,0 +1,14 @@ +/** + * notion-enhancer: focus mode + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +[data-focus-mode='hide-tabs'] header:not(:hover) { + background: var(--theme--bg); + border-bottom-color: transparent; +} +[data-focus-mode='hide-tabs'] header:not(:hover) > * { + opacity: 0; + transition: opacity 200ms ease-in-out; +} diff --git a/repo/focus-mode/tabs.mjs b/repo/focus-mode/tabs.mjs new file mode 100644 index 0000000..6074834 --- /dev/null +++ b/repo/focus-mode/tabs.mjs @@ -0,0 +1,12 @@ +/** + * notion-enhancer: focus mode + * (c) 2020 Arecsu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function (api, db) { + if (await db.get(['tabs'])) document.body.dataset.focusMode = 'hide-tabs'; +} diff --git a/repo/font-chooser/fonts.css b/repo/font-chooser/fonts.css new file mode 100644 index 0000000..7d5b32e --- /dev/null +++ b/repo/font-chooser/fonts.css @@ -0,0 +1,25 @@ +/** + * notion-enhancer: font chooser + * (c) 2021 TorchAtlas (https://github.com/torchatlas/) + * (c) 2021 admiraldus (https://github.com/admiraldus) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root { + --theme--font_sans: var(--font_chooser--sans); + --theme--font_serif: var(--font_chooser--serif); + --theme--font_mono: var(--font_chooser--mono); + --theme--font_code: var(--font_chooser--code); +} + +.notion-quote-block { + font-family: var(--font_chooser--quotes, inherit) !important; +} + +[placeholder='Untitled'], +[placeholder='Heading 1'], +[placeholder='Heading 2'], +[placeholder='Heading 3'] { + font-family: var(--font_chooser--headings, inherit) !important; +} diff --git a/repo/font-chooser/fonts.mjs b/repo/font-chooser/fonts.mjs new file mode 100644 index 0000000..5d344d3 --- /dev/null +++ b/repo/font-chooser/fonts.mjs @@ -0,0 +1,28 @@ +/** + * notion-enhancer: font chooser + * (c) 2021 TorchAtlas (https://github.com/torchatlas/) + * (c) 2021 admiraldus (https://github.com/admiraldus + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({}, db) { + const defaults = { + sans: " -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol'", + serif: + "Lyon-Text, Georgia, YuMincho, 'Yu Mincho', 'Hiragino Mincho ProN', 'Hiragino Mincho Pro', 'Songti TC', 'Songti SC', SimSun, 'Nanum Myeongjo', NanumMyeongjo, Batang, serif", + mono: 'iawriter-mono, Nitti, Menlo, Courier, monospace', + code: "SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace", + quotes: 'inherit', + headings: 'inherit', + }; + for (let style of ['sans', 'serif', 'mono', 'code', 'quotes', 'headings']) { + const font = await db.get([style]); + document.documentElement.style.setProperty( + `--font_chooser--${style}`, + font || defaults[style] + ); + } +} diff --git a/repo/font-chooser/mod.json b/repo/font-chooser/mod.json new file mode 100644 index 0000000..9d36d8a --- /dev/null +++ b/repo/font-chooser/mod.json @@ -0,0 +1,68 @@ +{ + "name": "font chooser", + "id": "e0d8d148-45e7-4d79-8313-e7b2ad8abe16", + "version": "0.4.0", + "description": "set custom fonts.", + "tags": ["extension", "customisation"], + "authors": [ + { + "name": "TorchAtlas", + "homepage": "https://github.com/torchatlas/", + "avatar": "https://avatars.githubusercontent.com/u/12666855" + } + ], + "js": { + "client": ["fonts.mjs"], + "menu": ["fonts.mjs"], + "frame": ["fonts.mjs"] + }, + "css": { + "client": ["fonts.css"], + "menu": ["fonts.css"], + "frame": ["fonts.css"] + }, + "options": [ + { + "type": "text", + "key": "sans", + "label": "sans-serif (inc. ui)", + "tooltip": "**this font needs to be installed on your device** - leave the option blank to use notion's default font", + "value": "" + }, + { + "type": "text", + "key": "serif", + "label": "serif", + "tooltip": "**this font needs to be installed on your device** - leave the option blank to use notion's default font", + "value": "" + }, + { + "type": "text", + "key": "mono", + "label": "monospace", + "tooltip": "**this font needs to be installed on your device** - leave the option blank to use notion's default font", + "value": "" + }, + { + "type": "text", + "key": "code", + "label": "code", + "tooltip": "**this font needs to be installed on your device** - leave the option blank to use notion's default font", + "value": "" + }, + { + "type": "text", + "key": "quotes", + "label": "quotes", + "tooltip": "**this font needs to be installed on your device** - leave the option blank to use notion's default font", + "value": "" + }, + { + "type": "text", + "key": "headings", + "label": "headings", + "tooltip": "**this font needs to be installed on your device** - leave the option blank to use notion's default font", + "value": "" + } + ] +} diff --git a/repo/global-block-links/client.css b/repo/global-block-links/client.css new file mode 100644 index 0000000..66dcc54 --- /dev/null +++ b/repo/global-block-links/client.css @@ -0,0 +1,73 @@ +/** + * notion-enhancer: global block links + * (c) 2021 admiraldus (https://github.com/admiraldus) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.global_block_links--topbar_copy { + display: inline-flex; + align-items: center; + border-radius: 3px; + height: 28px; + min-width: 0px; + padding-right: 8px; + padding-left: 6px; + font-size: 14px; + line-height: 1.2; + color: var(--theme--text); + cursor: pointer; + transition: background 20ms ease-in 0s; + user-select: none; +} +.global_block_links--topbar_copy > svg { + display: block; + height: 16px; + width: 16px; + fill: var(--theme--icon); +} +.global_block_links--topbar_copy > span { + margin-left: 2px; + opacity: 1; + transition: opacity 0.4s ease; +} +.global_block_links--topbar_copy > svg + span { + margin-left: 6px; +} + +.global_block_links--block_copy { + display: flex; + align-items: center; + height: 28px; + width: 100%; + font-size: 14px; + line-height: 1.2; + cursor: pointer; + transition: background 20ms ease-in 0s; + user-select: none; +} +.global_block_links--block_copy > svg { + display: block; + margin-left: 14px; + height: 17px; + width: 17px; + color: var(--theme--icon); +} +.global_block_links--block_copy > span { + margin-right: 14px; + margin-left: 8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.global_block_links--topbar_copy:hover, +.global_block_links--block_copy:hover { + background: var(--theme--ui_interactive-hover); +} + +.global_block_links--hidden { + position: absolute; + top: -9999px; + opacity: 0 !important; +} diff --git a/repo/global-block-links/client.mjs b/repo/global-block-links/client.mjs new file mode 100644 index 0000000..5cd864e --- /dev/null +++ b/repo/global-block-links/client.mjs @@ -0,0 +1,109 @@ +/** + * notion-enhancer: global block links + * (c) 2021 admiraldus (https://github.com/admiraldus) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ web, components, notion }, db) { + const topbarShareSelector = '.notion-topbar-share-menu', + blockActionSelector = + '.notion-overlay-container .notion-scroller.vertical .notion-focusable > div > div > [style*="text-overflow: ellipsis;"]', + hoveredActionSelector = + '.notion-overlay-container .notion-scroller.vertical .notion-focusable[style*="background:"]', + topbarCopyClass = 'global_block_links--topbar_copy', + blockCopyClass = 'global_block_links--block_copy', + hiddenClass = 'global_block_links--hidden'; + + const topbarCopyIcon = await db.get(['topbar_copy_icon']), + topbarCopyText = await db.get(['topbar_copy_text']); + if (topbarCopyIcon || topbarCopyText) { + const $topbarCopyTemplate = web.render( + web.html`
`, + topbarCopyIcon + ? web.html` + + ` + : '', + topbarCopyText + ? web.html` + Copy link + Link copied! + ` + : '' + ); + + const insertTopbarCopy = () => { + const $btns = document.querySelectorAll(topbarShareSelector); + $btns.forEach(($btn) => { + if (!$btn.previousElementSibling?.classList?.contains?.(topbarCopyClass)) { + const $copy = $topbarCopyTemplate.cloneNode(true); + components.addTooltip($copy, '**Copy page link**'); + $btn.before($copy); + + let resetButtonDelay; + $copy.addEventListener('click', () => { + if (topbarCopyText) { + const $copyText = $copy.querySelector('[data-copy]'), + $copiedText = $copy.querySelector('[data-copied]'); + $copyText.classList.add(hiddenClass); + $copiedText.classList.remove(hiddenClass); + clearTimeout(resetButtonDelay); + resetButtonDelay = setTimeout(() => { + $copyText.classList.remove(hiddenClass); + $copiedText.classList.add(hiddenClass); + }, 1250); + } + + web.copyToClipboard(`https://notion.so/${notion.getPageID().replace(/-/g, '')}`); + }); + } + }); + }; + insertTopbarCopy(); + web.addDocumentObserver(insertTopbarCopy, [topbarShareSelector]); + } + + const $blockCopyTemplate = web.html` +
+ ${await components.feather('globe')} + Global link +
`; + + const getLinkButtons = () => + [...document.querySelectorAll(blockActionSelector)] + .filter(($action) => + ['Copy link', '링크 복사', 'リンクをコピー'].includes($action.textContent) + ) + .map(($action) => $action.closest('.notion-focusable')), + insertBlockCopy = () => { + const $btns = getLinkButtons(); + $btns.forEach(($btn) => { + if (!$btn.previousElementSibling?.classList?.contains?.(blockCopyClass)) { + const $copy = $blockCopyTemplate.cloneNode(true); + $btn.before($copy); + + $copy.addEventListener('mouseover', () => { + document.querySelectorAll(hoveredActionSelector).forEach(($action) => { + $action.style.background = ''; + }); + }); + + $copy.addEventListener('click', async () => { + $btn.click(); + const link = await web.readFromClipboard(), + id = link.replace(/.+#(?=\w+)/, ''); + web.copyToClipboard(id.length === 32 ? `https://notion.so/${id}` : link); + }); + } + }); + }; + insertBlockCopy(); + web.addDocumentObserver(insertBlockCopy, [blockActionSelector]); +} diff --git a/repo/global-block-links/global-block-links.jpg b/repo/global-block-links/global-block-links.jpg new file mode 100644 index 0000000..eb84be2 Binary files /dev/null and b/repo/global-block-links/global-block-links.jpg differ diff --git a/repo/global-block-links/mod.json b/repo/global-block-links/mod.json new file mode 100644 index 0000000..698e9b2 --- /dev/null +++ b/repo/global-block-links/mod.json @@ -0,0 +1,35 @@ +{ + "name": "global block links", + "id": "74856af4-6970-455d-bd86-0a385a402dd1", + "version": "0.1.0", + "description": "easily copy the global link of a page or block.", + "preview": "global-block-links.jpg", + "tags": ["extension", "shortcut"], + "authors": [ + { + "name": "admiraldus", + "homepage": "https://github.com/admiraldus", + "avatar": "https://raw.githubusercontent.com/admiraldus/admiraldus/main/module.gif" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [ + { + "key": "topbar_copy_icon", + "label": "copy page links from the topbar (icon)", + "type": "toggle", + "value": true + }, + { + "key": "topbar_copy_text", + "label": "copy page links from the topbar (text)", + "type": "toggle", + "value": true + } + ] +} diff --git a/repo/gruvbox-dark/gruvbox-dark.png b/repo/gruvbox-dark/gruvbox-dark.png new file mode 100644 index 0000000..e0756e3 Binary files /dev/null and b/repo/gruvbox-dark/gruvbox-dark.png differ diff --git a/repo/gruvbox-dark/mod.json b/repo/gruvbox-dark/mod.json new file mode 100644 index 0000000..13b088b --- /dev/null +++ b/repo/gruvbox-dark/mod.json @@ -0,0 +1,29 @@ +{ + "name": "gruvbox dark", + "id": "ad0f5c5c-8b62-4b20-8a54-929e663ea368", + "version": "0.3.0", + "description": "a gray, 'retro groove' palette based on the vim theme of the same name.", + "preview": "gruvbox-dark.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "morhetz", + "email": "morhetz@gmail.com", + "homepage": "https://github.com/morhetz", + "avatar": "https://avatars.githubusercontent.com/u/554231" + }, + { + "name": "jordanrobinson", + "email": "me@jordanrobinson.co.uk", + "homepage": "https://jordanrobinson.co.uk/", + "avatar": "https://avatars.githubusercontent.com/u/1202911" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/gruvbox-dark/variables.css b/repo/gruvbox-dark/variables.css new file mode 100644 index 0000000..4096c4e --- /dev/null +++ b/repo/gruvbox-dark/variables.css @@ -0,0 +1,191 @@ +/** + * notion-enhancer: gruvbox dark + * (c) 2015-2020 morhetz + * (c) 2021 jordanrobinson (https://jordanrobinson.co.uk/) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --gruvbox_dark--bg: #282828; + --gruvbox_dark--light_gray_dark: #B3A89E; + --gruvbox_dark--gray_dark: #928374; + --gruvbox_dark--red_dark: #cc241d; + --gruvbox_dark--red_light: #fb4934; + --gruvbox_dark--green_dark: #98971a; + --gruvbox_dark--green_light: #b8bb26; + --gruvbox_dark--yellow_dark: #d79921; + --gruvbox_dark--yellow_light: #fabd2f; + --gruvbox_dark--blue_dark: #458588; + --gruvbox_dark--blue_light: #83a598; + --gruvbox_dark--purple_dark: #b16286; + --gruvbox_dark--purple_light: #d3869b; + --gruvbox_dark--aqua_dark: #689d6a; + --gruvbox_dark--aqua_light: #8ec07c; + --gruvbox_dark--gray_light: #a89984; + --gruvbox_dark--orange_dark: #d65d0e; + --gruvbox_dark--orange_light: #fe8019; + --gruvbox_dark--fg: #ebdbb2; + --gruvbox_dark--bg0_h: #1d2021; + --gruvbox_dark--bg0: #282828; + --gruvbox_dark--bg1: #3c3836; + --gruvbox_dark--bg2: #504945; + --gruvbox_dark--bg3: #665c54; + --gruvbox_dark--bg4: #7c6f64; + --gruvbox_dark--bg0_s: #32302f; + --gruvbox_dark--fg4: #a89984; + --gruvbox_dark--fg3: #bdae93; + --gruvbox_dark--fg2: #d5c4a1; + --gruvbox_dark--fg1: #ebdbb2; + --gruvbox_dark--fg0: #fbf1c7; + + --theme--accent_blue: var(--gruvbox_dark--bg3); + --theme--accent_blue-selection: rgba(80, 73, 69, 0.5); + --theme--accent_blue-hover: var(--gruvbox_dark--fg3); + --theme--accent_blue-active: var(--gruvbox_dark--fg3); + --theme--accent_red: var(--gruvbox_dark--blue_dark); + --theme--accent_red-button: var(--gruvbox_dark--blue_light); + + --theme--bg: var(--gruvbox_dark--bg0); + --theme--bg_secondary: var(--gruvbox_dark--bg1); + --theme--bg_card: var(--gruvbox_dark--bg3); + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: var(--gruvbox_dark--bg0_s); + --theme--scrollbar_thumb-hover: var(--gruvbox_dark--bg3); + + --theme--ui_divider: var(--gruvbox_dark--gray_light); + --theme--ui_interactive-hover: rgba(80, 73, 69, 0.7); + --theme--ui_interactive-active: rgba(80, 73, 69, 0.9); + --theme--ui_toggle-off: var(--gruvbox_dark--bg4); + --theme--ui_toggle-feature: var(--gruvbox_dark--fg); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: var(--gruvbox_dark--fg0); + --theme--icon_secondary: var(--gruvbox_dark--fg3); + + --theme--text: var(--gruvbox_dark--fg0); + --theme--text_secondary: var(--gruvbox_dark--fg3); + --theme--text_gray: var(--gruvbox_dark--gray_dark); + --theme--text_brown: var(--gruvbox_dark--bg4); + --theme--text_orange: var(--gruvbox_dark--orange_dark); + --theme--text_yellow: var(--gruvbox_dark--yellow_dark); + --theme--text_green: var(--gruvbox_dark--green_dark); + --theme--text_blue: var(--gruvbox_dark--blue_dark); + --theme--text_purple: var(--gruvbox_dark--purple_dark); + --theme--text_pink: var(--gruvbox_dark--purple_light); + --theme--text_red: var(--gruvbox_dark--red_dark); + + --theme--highlight_gray: var(--gruvbox_dark--gray_dark); + --theme--highlight_gray-text: var(--gruvbox_dark--bg0); + --theme--highlight_brown: var(--theme--tag_brown); + --theme--highlight_brown-text: var(--gruvbox_dark--bg0); + --theme--highlight_orange: var(--gruvbox_dark--orange_dark); + --theme--highlight_orange-text: var(--gruvbox_dark--bg0); + --theme--highlight_yellow: var(--gruvbox_dark--yellow_dark); + --theme--highlight_yellow-text: var(--gruvbox_dark--bg0); + --theme--highlight_green: var(--gruvbox_dark--green_dark); + --theme--highlight_green-text: var(--gruvbox_dark--bg0); + --theme--highlight_blue: var(--gruvbox_dark--blue_dark); + --theme--highlight_blue-text: var(--gruvbox_dark--bg0); + --theme--highlight_purple: var(--gruvbox_dark--purple_dark); + --theme--highlight_purple-text: var(--gruvbox_dark--bg0); + --theme--highlight_pink: var(--theme--tag_pink); + --theme--highlight_pink-text: var(--gruvbox_dark--bg0); + --theme--highlight_red: var(--gruvbox_dark--red_dark); + --theme--highlight_red-text: var(--gruvbox_dark--bg0); + + --theme--callout_gray: var(--theme--highlight_gray); + --theme--callout_gray-text: var(--gruvbox_dark--bg0); + --theme--callout_brown: var(--theme--highlight_brown); + --theme--callout_brown-text: var(--gruvbox_dark--bg0); + --theme--callout_orange: var(--theme--highlight_orange); + --theme--callout_orange-text: var(--gruvbox_dark--bg0); + --theme--callout_yellow: var(--theme--highlight_yellow); + --theme--callout_yellow-text: var(--gruvbox_dark--bg0); + --theme--callout_green: var(--theme--highlight_green); + --theme--callout_green-text: var(--gruvbox_dark--bg0); + --theme--callout_blue: var(--theme--highlight_blue); + --theme--callout_blue-text: var(--gruvbox_dark--bg0); + --theme--callout_purple: var(--theme--highlight_purple); + --theme--callout_purple-text: var(--gruvbox_dark--bg0); + --theme--callout_pink: var(--theme--highlight_pink); + --theme--callout_pink-text: var(--gruvbox_dark--bg0); + --theme--callout_red: var(--theme--highlight_red); + --theme--callout_red-text: var(--gruvbox_dark--bg0); + + --theme--tag_default: var(--gruvbox_dark--gray_dark); + --theme--tag_default-text: var(--gruvbox_dark--bg2); + --theme--tag_light_gray: var(--gruvbox_dark--light_gray_dark); + --theme--tag_light_gray-text: var(--gruvbox_dark--bg2); + --theme--tag_gray: var(--gruvbox_dark--gray_dark); + --theme--tag_gray-text: var(--gruvbox_dark--bg2); + --theme--tag_brown: var(--gruvbox_dark--fg3); + --theme--tag_brown-text: var(--gruvbox_dark--bg2); + --theme--tag_orange: var(--gruvbox_dark--orange_dark); + --theme--tag_orange-text: var(--gruvbox_dark--bg0); + --theme--tag_yellow: var(--gruvbox_dark--yellow_dark); + --theme--tag_yellow-text: var(--gruvbox_dark--bg0); + --theme--tag_green: var(--gruvbox_dark--green_dark); + --theme--tag_green-text: var(--gruvbox_dark--bg0); + --theme--tag_blue: var(--gruvbox_dark--blue_dark); + --theme--tag_blue-text: var(--gruvbox_dark--bg0); + --theme--tag_purple: var(--gruvbox_dark--purple_dark); + --theme--tag_purple-text: var(--gruvbox_dark--bg0); + --theme--tag_pink: var(--gruvbox_dark--purple_light); + --theme--tag_pink-text: var(--gruvbox_dark--bg0); + --theme--tag_red: var(--gruvbox_dark--red_dark); + --theme--tag_red-text: var(--gruvbox_dark--bg0); + + --theme--board_light_gray: var(--gruvbox_dark--light_gray_dark); + --theme--board_light_gray-text: var(--gruvbox_dark--bg0); + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_gray: var(--theme--text_gray); + --theme--board_gray-text: var(--gruvbox_dark--bg0); + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_brown: var(--theme--text_brown); + --theme--board_brown-text: var(--gruvbox_dark--bg0); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_orange: var(--theme--text_orange); + --theme--board_orange-text: var(--gruvbox_dark--bg0); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_yellow: var(--theme--text_yellow); + --theme--board_yellow-text: var(--gruvbox_dark--bg0); + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_green: var(--theme--text_green); + --theme--board_green-text: var(--gruvbox_dark--bg0); + --theme--board_green-card: var(--theme--tag_green); + --theme--board_blue: var(--theme--text_blue); + --theme--board_blue-text: var(--gruvbox_dark--bg0); + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_purple: var(--theme--text_purple); + --theme--board_purple-text: var(--gruvbox_dark--bg0); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_pink: var(--theme--text_pink); + --theme--board_pink-text: var(--gruvbox_dark--bg0); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_red: var(--theme--text_red); + --theme--board_red-text: var(--gruvbox_dark--bg0); + --theme--board_red-card: var(--theme--tag_red); + + --theme--code_inline: var(--gruvbox_dark--bg1); + --theme--code_inline-text: var(--gruvbox_dark--blue_light); + + --theme--code: var(--gruvbox_dark--bg1); + --theme--code_function: var(--theme--text_blue); + --theme--code_keyword: var(--theme--text_pink); + --theme--code_tag: var(--theme--text_pink); + --theme--code_operator: var(--theme--text_yellow); + --theme--code_important: var(--theme--text_yellow); + --theme--code_property: var(--theme--text_pink); + --theme--code_builtin: var(--theme--text_yellow); + --theme--code_attr-name: var(--theme--text_yellow); + --theme--code_comment: var(--theme--text_ui); + --theme--code_punctuation: var(--gruvbox_dark--aqua_light); + --theme--code_doctype: var(--gruvbox_dark--aqua_light); + --theme--code_number: var(--theme--text_purple); + --theme--code_string: var(--theme--text_orange); + --theme--code_attr-value: var(--theme--text_orange); +} diff --git a/repo/gruvbox-light/gruvbox-light.png b/repo/gruvbox-light/gruvbox-light.png new file mode 100644 index 0000000..f9a02c4 Binary files /dev/null and b/repo/gruvbox-light/gruvbox-light.png differ diff --git a/repo/gruvbox-light/mod.json b/repo/gruvbox-light/mod.json new file mode 100644 index 0000000..272b2ec --- /dev/null +++ b/repo/gruvbox-light/mod.json @@ -0,0 +1,29 @@ +{ + "name": "gruvbox light", + "id": "54f01911-60fc-4c9d-85b5-5c5ca3dd6b81", + "version": "0.3.0", + "description": "a sepia, 'retro groove' palette based on the vim theme of the same name.", + "preview": "gruvbox-light.png", + "tags": ["theme", "light"], + "authors": [ + { + "name": "morhetz", + "email": "morhetz@gmail.com", + "homepage": "https://github.com/morhetz", + "avatar": "https://avatars.githubusercontent.com/u/554231" + }, + { + "name": "jordanrobinson", + "email": "me@jordanrobinson.co.uk", + "homepage": "https://jordanrobinson.co.uk/", + "avatar": "https://avatars.githubusercontent.com/u/1202911" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/gruvbox-light/variables.css b/repo/gruvbox-light/variables.css new file mode 100644 index 0000000..9b3722f --- /dev/null +++ b/repo/gruvbox-light/variables.css @@ -0,0 +1,196 @@ +/** + * notion-enhancer: gruvbox light + * (c) 2015-2020 morhetz + * (c) 2021 jordanrobinson (https://jordanrobinson.co.uk/) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.light { + /* + * variables are named for consistency with gruvbox dark, + * but the _light variants are actually darker here + */ + --gruvbox_light--bg: #fbf1c7; + --gruvbox_light--light_gray_dark: #B3A89E; + --gruvbox_light--gray_dark: #928374; + --gruvbox_light--red_dark: #cc241d; + --gruvbox_light--red_light: #9d0006; + --gruvbox_light--green_dark: #98971a; + --gruvbox_light--green_light: #79740e; + --gruvbox_light--yellow_dark: #d79921; + --gruvbox_light--yellow_light: #b57614; + --gruvbox_light--blue_dark: #458588; + --gruvbox_light--blue_light: #076678; + --gruvbox_light--purple_dark: #b16286; + --gruvbox_light--purple_light: #b16286; + --gruvbox_light--aqua_dark: #689d6a; + --gruvbox_light--aqua_light: #427b58; + --gruvbox_light--gray_light: #7c6f64; + --gruvbox_light--orange_dark: #d65d0e; + --gruvbox_light--orange_light: #af3a03; + --gruvbox_light--fg: #3c3836; + --gruvbox_light--bg0_h: #f9f5d7; + --gruvbox_light--bg0: #fbf1c7; + --gruvbox_light--bg1: #ebdbb2; + --gruvbox_light--bg2: #d5c4a1; + --gruvbox_light--bg3: #bdae93; + --gruvbox_light--bg4: #a89984; + --gruvbox_light--bg0_s: #f2e5bc; + --gruvbox_light--fg4: #7c6f64; + --gruvbox_light--fg3: #665c54; + --gruvbox_light--fg2: #504945; + --gruvbox_light--fg1: #3c3836; + --gruvbox_light--fg0: #282828; + + --theme--accent_blue: var(--gruvbox_light--bg3); + --theme--accent_blue-selection: rgba(189, 175, 147, 0.5); + --theme--accent_blue-hover: var(--gruvbox_light--fg3); + --theme--accent_blue-active: var(--gruvbox_light--fg3); + --theme--accent_red: var(--gruvbox_light--blue_light); + --theme--accent_red-button: var(--gruvbox_light--blue_dark); + + --theme--bg: var(--gruvbox_light--bg0); + --theme--bg_secondary: var(--gruvbox_light--bg1); + --theme--bg_card: var(--gruvbox_light--bg2); + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: var(--gruvbox_light--bg0_s); + --theme--scrollbar_thumb-hover: var(--gruvbox_light--bg3); + + --theme--ui_divider: var(--gruvbox_light--gray_light); + --theme--ui_interactive-hover: rgba(124, 111, 100, 0.3); + --theme--ui_interactive-active: rgba(124, 111, 100, 0.4); + --theme--ui_input: var(--gruvbox_light--bg3); + --theme--ui_toggle-off: var(--gruvbox_light--bg4); + --theme--ui_toggle-feature: var(--gruvbox_light--bg); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: var(--gruvbox_light--fg0); + --theme--icon_secondary: var(--gruvbox_light--fg3); + + --theme--text: var(--gruvbox_light--fg0); + --theme--text_secondary: var(--gruvbox_light--fg3); + --theme--text_gray: var(--gruvbox_light--gray_dark); + --theme--text_brown: var(--gruvbox_light--bg4); + --theme--text_orange: var(--gruvbox_light--orange_dark); + --theme--text_yellow: var(--gruvbox_light--yellow_dark); + --theme--text_green: var(--gruvbox_light--green_dark); + --theme--text_blue: var(--gruvbox_light--blue_dark); + --theme--text_purple: var(--gruvbox_light--purple_dark); + --theme--text_pink: var(--gruvbox_light--purple_light); + --theme--text_red: var(--gruvbox_light--red_dark); + + --theme--highlight_gray: var(--gruvbox_light--gray_dark); + --theme--highlight_gray-text: var(--gruvbox_light--bg0); + --theme--highlight_brown: var(--theme--tag_brown); + --theme--highlight_brown-text: var(--gruvbox_light--bg0); + --theme--highlight_orange: var(--gruvbox_light--orange_dark); + --theme--highlight_orange-text: var(--gruvbox_light--bg0); + --theme--highlight_yellow: var(--gruvbox_light--yellow_dark); + --theme--highlight_yellow-text: var(--gruvbox_light--bg0); + --theme--highlight_green: var(--gruvbox_light--green_dark); + --theme--highlight_green-text: var(--gruvbox_light--bg0); + --theme--highlight_blue: var(--gruvbox_light--blue_dark); + --theme--highlight_blue-text: var(--gruvbox_light--bg0); + --theme--highlight_purple: var(--gruvbox_light--purple_dark); + --theme--highlight_purple-text: var(--gruvbox_light--bg0); + --theme--highlight_pink: var(--theme--tag_pink); + --theme--highlight_pink-text: var(--gruvbox_light--bg0); + --theme--highlight_red: var(--gruvbox_light--red_dark); + --theme--highlight_red-text: var(--gruvbox_light--bg0); + + --theme--callout_gray: var(--theme--highlight_gray); + --theme--callout_gray-text: var(--gruvbox_light--bg0); + --theme--callout_brown: var(--theme--highlight_brown); + --theme--callout_brown-text: var(--gruvbox_light--bg0); + --theme--callout_orange: var(--theme--highlight_orange); + --theme--callout_orange-text: var(--gruvbox_light--bg0); + --theme--callout_yellow: var(--theme--highlight_yellow); + --theme--callout_yellow-text: var(--gruvbox_light--bg0); + --theme--callout_green: var(--theme--highlight_green); + --theme--callout_green-text: var(--gruvbox_light--bg0); + --theme--callout_blue: var(--theme--highlight_blue); + --theme--callout_blue-text: var(--gruvbox_light--bg0); + --theme--callout_purple: var(--theme--highlight_purple); + --theme--callout_purple-text: var(--gruvbox_light--bg0); + --theme--callout_pink: var(--theme--highlight_pink); + --theme--callout_pink-text: var(--gruvbox_light--bg0); + --theme--callout_red: var(--theme--highlight_red); + --theme--callout_red-text: var(--gruvbox_light--bg0); + + --theme--tag_default: var(--gruvbox_light--gray_dark); + --theme--tag_default-text: var(--gruvbox_light--bg2); + --theme--tag_light_gray: var(--gruvbox_light--light_gray_dark); + --theme--tag_light_gray-text: var(--gruvbox_light--bg0); + --theme--tag_gray: var(--gruvbox_light--gray_dark); + --theme--tag_gray-text: var(--gruvbox_light--bg2); + --theme--tag_brown: var(--gruvbox_light--fg3); + --theme--tag_brown-text: var(--gruvbox_light--bg2); + --theme--tag_orange: var(--gruvbox_light--orange_dark); + --theme--tag_orange-text: var(--gruvbox_light--bg0); + --theme--tag_yellow: var(--gruvbox_light--yellow_dark); + --theme--tag_yellow-text: var(--gruvbox_light--bg0); + --theme--tag_green: var(--gruvbox_light--green_dark); + --theme--tag_green-text: var(--gruvbox_light--bg0); + --theme--tag_blue: var(--gruvbox_light--blue_dark); + --theme--tag_blue-text: var(--gruvbox_light--bg0); + --theme--tag_purple: var(--gruvbox_light--purple_dark); + --theme--tag_purple-text: var(--gruvbox_light--bg0); + --theme--tag_pink: var(--gruvbox_light--purple_light); + --theme--tag_pink-text: var(--gruvbox_light--bg0); + --theme--tag_red: var(--gruvbox_light--red_dark); + --theme--tag_red-text: var(--gruvbox_light--bg0); + + --theme--board_light_gray: var(--gruvbox_light--light_gray_dark); + --theme--board_light_gray-text: var(--gruvbox_light--bg0_h); + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_gray: var(--theme--text_gray); + --theme--board_gray-text: var(--gruvbox_light--bg0); + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_brown: var(--theme--text_brown); + --theme--board_brown-text: var(--gruvbox_light--bg0); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_orange: var(--theme--text_orange); + --theme--board_orange-text: var(--gruvbox_light--bg0); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_yellow: var(--theme--text_yellow); + --theme--board_yellow-text: var(--gruvbox_light--bg0); + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_green: var(--theme--text_green); + --theme--board_green-text: var(--gruvbox_light--bg0); + --theme--board_green-card: var(--theme--tag_green); + --theme--board_blue: var(--theme--text_blue); + --theme--board_blue-text: var(--gruvbox_light--bg0); + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_purple: var(--theme--text_purple); + --theme--board_purple-text: var(--gruvbox_light--bg0); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_pink: var(--theme--text_pink); + --theme--board_pink-text: var(--gruvbox_light--bg0); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_red: var(--theme--text_red); + --theme--board_red-text: var(--gruvbox_light--bg0); + --theme--board_red-card: var(--theme--tag_red); + + --theme--code_inline: var(--gruvbox_light--bg1); + --theme--code_inline-text: var(--gruvbox_light--blue_light); + + --theme--code: var(--gruvbox_light--bg1); + --theme--code_function: var(--theme--text_blue); + --theme--code_keyword: var(--theme--text_pink); + --theme--code_tag: var(--theme--text_pink); + --theme--code_operator: var(--theme--text_yellow); + --theme--code_important: var(--theme--text_yellow); + --theme--code_property: var(--theme--text_pink); + --theme--code_builtin: var(--theme--text_yellow); + --theme--code_attr-name: var(--theme--text_yellow); + --theme--code_comment: var(--theme--text_ui); + --theme--code_punctuation: var(--gruvbox_light--aqua_light); + --theme--code_doctype: var(--gruvbox_light--aqua_light); + --theme--code_number: var(--theme--text_purple); + --theme--code_string: var(--theme--text_orange); + --theme--code_attr-value: var(--theme--text_orange); +} diff --git a/repo/icon-sets/client.css b/repo/icon-sets/client.css new file mode 100644 index 0000000..0259d1e --- /dev/null +++ b/repo/icon-sets/client.css @@ -0,0 +1,236 @@ +/** + * notion-enhancer: icon sets + * (c) 2019 jayhxmo (https://jaymo.io/) + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.icon_sets--tab_button { + position: relative; + padding-top: 6px; + padding-bottom: 6px; + flex-shrink: 0; +} +.icon_sets--tab_button > .notion-focusable { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + height: 28px; + border-radius: 3px; + font-size: 14px; + line-height: 1.2; + padding-left: 8px; + padding-right: 8px; + color: var(--theme--text); +} +.icon_sets--tab_button:hover > .notion-focusable { + background: var(--theme--ui_interactive-hover); +} +.icon_sets--tab_button:active > .notion-focusable { + background: var(--theme--ui_interactive-active); +} + +.icon_sets--view { + padding: 0; + overflow: hidden; + display: flex; + flex-direction: column; + flex-grow: 1; + z-index: 1; +} +.icon_sets--actions { + display: flex; + padding: 10px 14px; +} + +.icon_sets--actions > .notion-focusable-within { + flex-grow: 1; +} +.icon_sets--link_input { + flex-grow: 1; + font-size: 14px; + line-height: 20px; + padding: 4px 6px; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + box-shadow: var(--theme--ui_shadow) 0px 0px 0px 1px inset; + background: var(--theme--ui_input); + cursor: text; + height: 28px; +} +.icon_sets--link_input > input { + font-size: inherit; + line-height: inherit; + border: none; + background: none; + width: 100%; + display: block; + resize: none; + padding: 0px; +} + +.icon_sets--link_submit { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +.icon_sets--upload, +.icon_sets--link_submit { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + border: none; + background: var(--theme--accent_blue); + color: var(--theme--accent_blue-text); + line-height: 1.2; + padding: 6px 8px; + height: 28px; + font-size: 14px; + font-weight: 500; +} +.icon_sets--upload:hover, +.icon_sets--link_submit:hover { + background: var(--theme--accent_blue-hover); +} +.icon_sets--upload:active, +.icon_sets--link_submit:active { + background: var(--theme--accent_blue-active); +} + +.icon_sets--upload { + margin-left: 0.5em; + border-radius: 3px; +} + +.icon_sets--list { + /* scroller */ + height: 100%; + word-break: break-all; + overflow: hidden auto; + padding: 0 14px 10px 14px; +} + +.icon_sets--error { + color: var(--theme--accent_red); +} +.icon_sets--title, +.icon_sets--error { + margin: 6px 0 8px 0; + font-size: 11px; + font-weight: 500; + line-height: 1.2; + user-select: none; + text-transform: uppercase; + border-radius: 2px; + padding: 0.25em; + display: flex; + align-items: center; +} + +.icon_sets--title { + cursor: pointer; + color: var(--theme--text_secondary); +} +.icon_sets--title:hover { + background: var(--theme--ui_interactive-hover); +} +.icon_sets--title:active { + background: var(--theme--ui_interactive-active); +} + +.icon_sets--title .info { + /* tooltips */ + height: 1em; + margin-left: 0.5em; +} + +.icon_sets--spinner { + margin-left: 0.5em; + height: 1em; + width: 1em; +} +.icon_sets--spinner img { + width: 100%; + height: 100%; + animation: rotation 1.3s infinite linear; +} +@keyframes rotation { + from { + transform: rotate(0deg); + } + to { + transform: rotate(359deg); + } +} + +.icon_sets--title a { + color: currentColor; + transition: color 100ms ease-in; +} +.icon_sets--title a:hover { + color: var(--theme--accent_blue); +} + +.icon_sets--title .triangle { + height: 1em; + width: 0.9em; + margin: 0 0.5em 0 0.25em; + transition: transform 200ms ease-out 0s; + transform: rotateZ(180deg); +} +.icon_sets--title[data-collapsed='true'] .triangle { + transform: rotateZ(90deg); +} +.icon_sets--title[data-collapsed='true'] + .icon_sets--set { + height: 0 !important; +} + +.icon_sets--set { + display: flex; + flex-wrap: wrap; + overflow: hidden; + transition: height 200ms ease-out 0s; +} +.icon_sets--icon { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + border-radius: 3px; + width: 32px; + height: 32px; + font-size: 24px; +} +.icon_sets--icon:hover { + background: var(--theme--ui_interactive-hover); +} +.icon_sets--icon:active { + background: var(--theme--ui_interactive-active); +} +.icon_sets--icon > img { + max-width: 24px; + max-height: 24px; +} +.icon_sets--sprite { + width: 24px; + height: 24px; + background-size: 24px; + background-repeat: no-repeat; + pointer-events: none; +} + +.icon_sets--divider { + height: 1px; + margin: 1em 0; + border-bottom: 1px solid var(--theme--ui_divider); +} +.icon_sets--title[data-collapsed='true'] + .icon_sets--set + .icon_sets--divider { + margin-top: 0.5em; +} diff --git a/repo/icon-sets/client.mjs b/repo/icon-sets/client.mjs new file mode 100644 index 0000000..df6e491 --- /dev/null +++ b/repo/icon-sets/client.mjs @@ -0,0 +1,313 @@ +/** + * notion-enhancer: icon sets + * (c) 2019 jayhxmo (https://jaymo.io/) + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +const getImgData = (url) => + new Promise(async (res, rej) => { + const blob = await fetch(url).then((res) => res.blob()), + reader = new FileReader(); + reader.onload = (e) => res(e.target.result); + reader.readAsDataURL(blob); + }); + +export default async function ({ web, fs, components, notion }, db) { + const recentUploads = await db.get(['recent_uploads'], []), + preventQualityReduction = await db.get(['prevent_quality_reduction']), + $triangleSvg = web.html` + + `; + + const customIconSets = [], + customIconsFile = await db.get(['json']); + if (customIconsFile?.content) { + const iconsData = JSON.parse(customIconsFile.content); + customIconSets.push(...(iconsData.icons || iconsData)); + } + + const enhancerIconSets = [], + enhancerIconsUrl = 'https://raw.githubusercontent.com/notion-enhancer/icons/main/'; + if (await db.get(['default_sets'])) { + const iconsData = await fs.getJSON(`${enhancerIconsUrl}/icons.json`); + enhancerIconSets.push(...(iconsData.icons || iconsData)); + } + + const mediaMenuSelector = '.notion-media-menu', + mediaScrollerSelector = '.notion-media-menu > .notion-scroller', + mediaFilterSelector = '.notion-media-menu > :first-child > :last-child', + mediaLinkInputSelector = '.notion-focusable-within > input[type=url]', + tabBtnSelector = (n) => + `.notion-media-menu > :first-child > :first-child > :nth-child(${n})`; + + const renderSetTitle = async (title, loadPromises = [], $tooltip = undefined) => { + const isCollapsed = await db.get(['collapsed', title], false), + $title = web.html`

`, + $spinner = web.html` + + `; + web.render( + $title, + $triangleSvg.cloneNode(true), + web.html`${title}`, + $spinner + ); + $title.addEventListener('click', () => { + const newState = $title.dataset.collapsed !== 'true'; + db.set(['collapsed', title], newState); + $title.dataset.collapsed = newState; + }); + // hide spinner after all icons finish loading + // doesn't need to be waited on by renderers + (async () => { + await Promise.all(loadPromises); + $spinner.remove(); + if ($tooltip) { + const $infoSvg = web.html`${await components.feather('info', { class: 'info' })}`; + components.addTooltip($infoSvg, $tooltip, { offsetDirection: 'right' }); + web.render($title, $infoSvg); + } + })(); + return $title; + }; + + const $iconsTab = web.html`
+
Icons
+
`, + // actions + $iconsLinkInput = web.html``, + $iconsLinkSubmit = web.html``, + $iconsUploadFile = web.html``, + $iconsUploadSubmit = web.render( + web.html``, + 'Upload an image', + $iconsUploadFile + ), + // sets + $setsList = web.html`
`, + // container + $iconsView = web.render( + web.html``, + web.render( + web.html`
`, + web.render( + web.html`
`, + $iconsLinkInput, + $iconsLinkSubmit + ), + $iconsUploadSubmit + ), + web.render($setsList) + ); + + let $mediaMenu, $activeTabUnderline; + const insertIconsTab = async () => { + if (document.contains($mediaMenu)) return; + + // prevent injection into file upload menus + $mediaMenu = document.querySelector(mediaMenuSelector); + if (!$mediaMenu || !$mediaMenu.textContent.includes('Emoji')) return; + + const $emojiTab = document.querySelector(tabBtnSelector(1)), + $emojiScroller = document.querySelector(mediaScrollerSelector), + $emojiFilter = document.querySelector(mediaFilterSelector), + $uploadTab = document.querySelector(tabBtnSelector(2)), + $linkTab = document.querySelector(tabBtnSelector(3)); + $uploadTab.style.display = 'none'; + $linkTab.style.display = 'none'; + if ($activeTabUnderline) $activeTabUnderline.remove(); + $activeTabUnderline = + $emojiTab.children[1] || $uploadTab.children[1] || $linkTab.children[1]; + $emojiTab.after($iconsTab); + $emojiScroller.after($iconsView); + + const renderRecentUploads = async () => { + const $recentUploads = web.html`
`, + loadPromises = []; + for (let i = recentUploads.length - 1; i >= 0; i--) { + const { signed, url } = recentUploads[i], + $icon = web.html` + + `; + web.render($recentUploads, $icon); + $icon.addEventListener('click', (event) => { + if (event.shiftKey) { + recentUploads.splice(i, 1); + db.set(['recent_uploads'], recentUploads); + $icon.remove(); + } else setIcon({ signed, url }); + }); + loadPromises.push( + new Promise((res, rej) => { + $icon.firstElementChild.onload = res; + $icon.firstElementChild.onerror = res; + }) + ); + } + + const $recentUploadsTitle = await renderSetTitle( + 'Recent', + loadPromises, + web.html`

Click to reuse an icon
Shift-click to remove it

` + ); + web.render($setsList, $recentUploadsTitle, $recentUploads); + }, + renderIconSet = async (iconData, enhancerSet = false) => { + try { + const $set = web.html`
`; + if (iconData.sourceUrl?.endsWith?.('/')) { + iconData.sourceUrl = iconData.sourceUrl.slice(0, -1); + } + + const loadPromises = []; + for (let i = 0; i < (iconData.count || iconData.source.length); i++) { + const iconUrl = iconData.sourceUrl + ? Array.isArray(iconData.source) + ? `${iconData.sourceUrl}/${iconData.source[i]}.${iconData.extension}` + : `${iconData.sourceUrl}/${iconData.source}_${i}.${iconData.extension}` + : iconData.source[i], + sprite = enhancerSet + ? `style=" + background-image: url(${enhancerIconsUrl}${iconData.source}/sprite.png); + background-position: 0 -${i * 24}px; + "` + : '', + $img = sprite + ? web.html`
` + : web.html``, + $icon = web.render(web.html``, $img); + web.render($set, $icon); + $icon.addEventListener('click', (event) => { + if (!event.shiftKey) setIcon({ signed: iconUrl, url: iconUrl }); + }); + if (!sprite) { + loadPromises.push( + new Promise((res, rej) => { + $img.onload = res; + $img.onerror = res; + }) + ); + } + } + + const author = iconData.author + ? iconData.authorUrl + ? web.raw`by + ${iconData.author} + ` + : web.raw`by ${web.escape(iconData.author)}` + : '', + $title = await renderSetTitle( + `${web.escape(iconData.name)} ${author}`, + loadPromises + ); + web.render($setsList, $title, $set); + } catch (err) { + console.error(err); + web.render( + $setsList, + web.html`
+ Invalid set: ${web.escape(iconData?.name || 'Unknown')} +
` + ); + } + }, + renderCustomIconSets = async () => { + if (customIconSets.length) { + web.render($setsList, web.html`
`); + } + await Promise.all(customIconSets.map((set) => renderIconSet(set))); + }, + renderEnhancerIconSets = async () => { + if (enhancerIconSets.length) { + web.render($setsList, web.html`
`); + } + await Promise.all( + enhancerIconSets.map((set) => { + set.sourceUrl = set.sourceUrl || enhancerIconsUrl + set.source; + return renderIconSet(set, true); + }) + ); + }; + + const displayIconsTab = async (force = false) => { + if ($iconsTab.contains($activeTabUnderline) && !force) return; + web.render($iconsTab, $activeTabUnderline); + $iconsView.style.display = ''; + $emojiScroller.style.display = 'none'; + $emojiFilter.style.display = 'none'; + web.empty($setsList); + await renderRecentUploads(); + await renderCustomIconSets(); + await renderEnhancerIconSets(); + $iconsView.querySelectorAll('.icon_sets--set').forEach(($set) => { + $set.style.height = `${$set.scrollHeight}px`; + }); + }, + displayEmojiTab = (force = false) => { + if ($emojiTab.contains($activeTabUnderline) && !force) return; + web.render($emojiTab, $activeTabUnderline); + $iconsView.style.display = 'none'; + $emojiScroller.style.display = ''; + $emojiFilter.style.display = ''; + }; + // use onclick instead of eventlistener to override prev + $iconsTab.onclick = displayIconsTab; + $emojiTab.onclick = displayEmojiTab; + // otherwise both may be visible on reopen + displayEmojiTab(true); + + async function setIcon({ signed, url }) { + // without this react gets upset + displayEmojiTab(); + $linkTab.firstChild.click(); + await new Promise(requestAnimationFrame); + + $mediaMenu.parentElement.style.opacity = '0'; + const iconUrl = preventQualityReduction ? await getImgData(signed) : url; + + // call native setter, imitate human input + const $notionLinkInput = $mediaMenu.querySelector(mediaLinkInputSelector), + proto = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value'); + proto.set.call($notionLinkInput, iconUrl); + const inputEvent = new Event('input', { bubbles: true }), + enterKeydownEvent = new KeyboardEvent('keydown', { + bubbles: true, + cancelable: true, + keyCode: 13, + }); + $notionLinkInput.dispatchEvent(inputEvent); + $notionLinkInput.dispatchEvent(enterKeydownEvent); + } + + const submitLinkIcon = () => { + const url = $iconsLinkInput.firstElementChild.value; + if (!url) return; + const icon = { signed: notion.sign(url, notion.getPageID()), url: url }; + setIcon(icon); + recentUploads.push(icon); + db.set(['recent_uploads'], recentUploads); + }; + $iconsLinkInput.onkeyup = (event) => { + if (event.code === 13) submitLinkIcon(); + }; + $iconsLinkSubmit.onclick = submitLinkIcon; + + // upload file to aws, then submit link + $iconsUploadSubmit.onclick = () => $iconsUploadFile.click(); + $iconsUploadFile.onchange = async (event) => { + const file = event.target.files[0], + url = await notion.upload(file), + icon = { signed: notion.sign(url, notion.getPageID()), url: url }; + setIcon(icon); + recentUploads.push(icon); + db.set(['recent_uploads'], recentUploads); + }; + }; + web.addDocumentObserver(insertIconsTab, [mediaMenuSelector]); +} diff --git a/repo/icon-sets/icon-sets.jpg b/repo/icon-sets/icon-sets.jpg new file mode 100644 index 0000000..f44e245 Binary files /dev/null and b/repo/icon-sets/icon-sets.jpg differ diff --git a/repo/icon-sets/mod.json b/repo/icon-sets/mod.json new file mode 100644 index 0000000..72c616b --- /dev/null +++ b/repo/icon-sets/mod.json @@ -0,0 +1,43 @@ +{ + "name": "icon sets", + "id": "2d1f4809-9581-40dd-9bf3-4239db406483", + "version": "0.4.0", + "description": "upload, save and reuse custom icons directly from the icon picker. check out the [icons page](https://notion-enhancer.github.io/advanced/icons) for instructions on loading entire sets.", + "preview": "icon-sets.jpg", + "tags": ["integration", "customisation"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [ + { + "type": "toggle", + "key": "default_sets", + "label": "load default icon sets from github", + "value": true + }, + { + "type": "toggle", + "key": "prevent_quality_reduction", + "label": "prevent icon quality reduction", + "tooltip": "**this may break icons in widgets or be rejected by notion if images are too high quality** - encodes and submits images as data urls to prevent notion from optimising them (reduces image quality by ~20%)", + "value": true + }, + { + "type": "file", + "key": "json", + "label": "custom icon sets (.json)", + "extensions": [".json"] + } + ] +} diff --git a/repo/indentation-lines/client.css b/repo/indentation-lines/client.css new file mode 100644 index 0000000..bcb867a --- /dev/null +++ b/repo/indentation-lines/client.css @@ -0,0 +1,101 @@ +/** + * notion-enhancer: indentation lines + * (c) 2020 Alexa Baldon (https://github.com/runargs) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-page-content .notion-bulleted_list-block > div > div:last-child, +.notion-page-content .notion-numbered_list-block > div > div:last-child, +.notion-page-content .notion-to_do-block > div > div:last-child, +.notion-page-content .notion-toggle-block > div > div:last-child, +.notion-page-content [class$='header-block'] > div > div > div:last-child, +.notion-page-content .notion-table_of_contents-block > div > div > a > div > div { + position: relative; +} + +.notion-page-content .notion-bulleted_list-block > div > div:last-child::before, +.notion-page-content .notion-numbered_list-block > div > div:last-child::before, +.notion-page-content .notion-to_do-block > div > div:last-child::before, +.notion-page-content .notion-toggle-block > div > div:last-child::before, +.notion-page-content [class$='header-block'] > div > div > div:last-child::before, +.notion-page-content .pseudoSelection > div > div:last-child::before { + content: ''; + position: absolute; + height: calc(100% - 2em); + top: 2em; + margin-inline-start: -14.48px; +} +.notion-page-content [class$='header-block'] > div > div > div:last-child::before { + margin-inline-start: -15.48px; +} + +.notion-page-content + .notion-table_of_contents-block + > div + > div + > a + > div + > div:not([style*='margin-left: 0px']) + > div::before { + content: ''; + position: absolute; + height: 100%; + top: 0; + margin-inline-start: -14.48px; +} + +/* add background to block dragger */ +.notion-frame + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + [data-block-id], +.notion-peek-renderer + > div + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + [data-block-id] { + background: var(--theme--bg) !important; + border-radius: 3px; +} +.notion-frame + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + + .notion-focusable, +.notion-peek-renderer + > div + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + + .notion-focusable { + left: -42px !important; + background: transparent !important; +} +.notion-frame + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + + .notion-focusable + > .plus, +.notion-peek-renderer + > div + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + + .notion-focusable + > .plus { + border-radius: 3px; + width: 18px !important; + padding: 0 1px !important; + background: var(--theme--bg) !important; +} +.notion-frame + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + + .notion-focusable + > .plus:hover, +.notion-peek-renderer + > div + > [style*='position: absolute; top: 0px; left: 0px;'] + [style*='position: absolute; top: 3px; left: -20px; width: 18px; height: 24px; pointer-events: auto; cursor: -webkit-grab;'] + + .notion-focusable + > .plus:hover { + background: var(--theme--ui_interactive-hover) !important; +} diff --git a/repo/indentation-lines/client.mjs b/repo/indentation-lines/client.mjs new file mode 100644 index 0000000..3cb8736 --- /dev/null +++ b/repo/indentation-lines/client.mjs @@ -0,0 +1,109 @@ +/** + * notion-enhancer: indentation lines + * (c) 2020 Alexa Baldon (https://github.com/runargs) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web }, db) { + let style = 'solid', + opacity = 1, + rainbow = false; + switch (await db.get(['style'])) { + case 'dashed': + style = 'dashed'; + break; + case 'dotted': + style = 'dotted'; + break; + case 'soft': + opacity = 0.25; + break; + case 'rainbow': + opacity = 0.7; + rainbow = true; + break; + } + + let css = ''; + const colors = ['red', 'pink', 'purple', 'blue', 'green', 'yellow']; + colors.push(...colors, ...colors, ...colors, 'gray'); + + for (const listType of ['bulleted_list', 'numbered_list', 'to_do', 'toggle']) { + if (!(await db.get([listType]))) continue; + css += ` + .notion-page-content .notion-${listType}-block > div > div:last-child::before { + border-left: 1px ${style} var(--indentation_lines--color, currentColor); + opacity: ${opacity}; + }`; + + if (rainbow) { + for (let i = 0; i < colors.length; i++) { + css += ` + .notion-page-content ${`.notion-${listType}-block `.repeat(i + 1)} + > div > div:last-child::before { + --indentation_lines--color: var(--theme--text_${colors[i]}); + }`; + } + } + } + + if (await db.get(['toggle_header'])) { + css += ` + .notion-page-content [class$=header-block] > div > div > div:last-child::before { + border-left: 1px ${style} var(--indentation_lines--color, currentColor); + opacity: ${opacity}; + }`; + + if (rainbow) { + for (let i = 0; i < colors.length; i++) { + css += ` + .notion-page-content ${`[class$=header-block] `.repeat(i + 1)} + > div > div > div:last-child::before{ + --indentation_lines--color: var(--theme--text_${colors[i]}); + }`; + } + } + } + + if (await db.get(['table_of_contents'])) { + css += ` + .notion-page-content .notion-table_of_contents-block > div > div > a > div + > div:not([style*='margin-left: 0px']) > div::before { + border-left: 1px ${style} var(--indentation_lines--color, currentColor); + opacity: ${opacity}; + }`; + + if (rainbow) { + css += ` + .notion-page-content .notion-table_of_contents-block > div > div > a > div + > div[style*='margin-left: 24px'] > div::before { + --indentation_lines--color: var(--theme--text_${colors[0]}); + } + .notion-page-content .notion-table_of_contents-block > div > div > a > div + > div[style*='margin-left: 48px'] > div::before { + --indentation_lines--color: var(--theme--text_${colors[1]}); + }`; + } + } + + if (await db.get(['outliner'])) { + css += ` + .outliner--header:not([style='--outliner--indent:0px;'])::before { + border-left: 1px ${style} var(--indentation_lines--color, currentColor); + opacity: ${opacity}; + }`; + if (rainbow) { + css += ` + .outliner--header[style='--outliner--indent:18px;']::before { + --indentation_lines--color: var(--theme--text_${colors[0]}); + } + .outliner--header[style='--outliner--indent:36px;']::before { + --indentation_lines--color: var(--theme--text_${colors[1]}); + }`; + } + } + + web.render(document.head, web.html``); +} diff --git a/repo/indentation-lines/indentation-lines.jpg b/repo/indentation-lines/indentation-lines.jpg new file mode 100644 index 0000000..0587e6d Binary files /dev/null and b/repo/indentation-lines/indentation-lines.jpg differ diff --git a/repo/indentation-lines/mod.json b/repo/indentation-lines/mod.json new file mode 100644 index 0000000..33a82d9 --- /dev/null +++ b/repo/indentation-lines/mod.json @@ -0,0 +1,72 @@ +{ + "name": "indentation lines", + "id": "35815b3b-3916-4dc6-8769-c9c2448f8b57", + "version": "0.2.0", + "description": "adds vertical relationship lines to make list trees easier to follow.", + "preview": "indentation-lines.jpg", + "tags": ["extension", "usability"], + "authors": [ + { + "name": "runargs", + "email": "alnbaldon@gmail.com", + "homepage": "http://github.com/runargs", + "avatar": "https://avatars.githubusercontent.com/u/39810066" + } + ], + "css": { + "client": ["client.css"] + }, + "js": { + "client": ["client.mjs"] + }, + "options": [ + { + "type": "select", + "key": "style", + "label": "style", + "values": ["solid", "dashed", "dotted", "soft", "rainbow"] + }, + { + "type": "toggle", + "key": "bulleted_list", + "label": "bulleted lists", + "value": true + }, + { + "type": "toggle", + "key": "numbered_list", + "label": "numbered lists", + "value": true + }, + { + "type": "toggle", + "key": "to_do", + "label": "to-do lists", + "value": true + }, + { + "type": "toggle", + "key": "toggle", + "label": "toggle lists", + "value": true + }, + { + "type": "toggle", + "key": "toggle_header", + "label": "toggle headers", + "value": true + }, + { + "type": "toggle", + "key": "table_of_contents", + "label": "tables of contents", + "value": true + }, + { + "type": "toggle", + "key": "outliner", + "label": "outliner (panel extension)", + "value": true + } + ] +} diff --git a/repo/integrated-titlebar/buttons.css b/repo/integrated-titlebar/buttons.css new file mode 100644 index 0000000..3a59d9c --- /dev/null +++ b/repo/integrated-titlebar/buttons.css @@ -0,0 +1,76 @@ +/** + * notion-enhancer: integrated titlebar + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.integrated_titlebar--dragarea { + width: 100%; + display: block; + -webkit-app-region: drag; + background: var(--theme--bg_secondary); + height: var(--integrated_titlebar--dragarea-height); +} + +.integrated_titlebar--buttons { + display: flex; + align-items: center; +} +.sidebar > .integrated_titlebar--buttons { + margin: -0.5rem 0 0.75rem auto; +} + +.integrated_titlebar--buttons button { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: 3px; + height: 28px; + width: 33px; + padding: 0 0.25px 0 0; + + margin-left: 2px; + border: none; + background: transparent; + font-size: 18px; + -webkit-app-region: no-drag; +} +.integrated_titlebar--buttons button svg { + display: block; + width: 20px; + height: 20px; + fill: var(--theme--icon); + color: var(--theme--icon); +} + +.integrated_titlebar--buttons button:focus, +.integrated_titlebar--buttons button:hover { + background: var(--theme--ui_interactive-hover); +} +.integrated_titlebar--buttons button:active { + background: var(--theme--ui_interactive-active); +} +#integrated_titlebar--close:focus, +#integrated_titlebar--close:hover, +#integrated_titlebar--close:active { + background: var(--theme--accent_red); + color: var(--theme--accent_red-text); +} + +.notion-update-sidebar [style*='margin-top: 45px;'] { + margin-top: calc(45px + var(--integrated_titlebar--dragarea-height, 0px)) !important; +} +.notion-topbar { + height: calc(45px + var(--integrated_titlebar--dragarea-height, 0px)) !important; +} +.notion-frame { + height: calc(100vh - 45px - var(--integrated_titlebar--dragarea-height, 0px)) !important; +} + +body > .body-container { + height: calc(100% - var(--integrated_titlebar--dragarea-height, 0px)) !important; +} diff --git a/repo/integrated-titlebar/buttons.mjs b/repo/integrated-titlebar/buttons.mjs new file mode 100644 index 0000000..da307f5 --- /dev/null +++ b/repo/integrated-titlebar/buttons.mjs @@ -0,0 +1,73 @@ +/** + * notion-enhancer: integrated titlebar + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export const createWindowButtons = async ({ electron, web, components }, db) => { + let minimizeIcon = (await db.get(['minimize_icon'])) || (await components.feather('minus')), + maximizeIcon = (await db.get(['maximize_icon'])) || (await components.feather('maximize')), + unmaximizeIcon = + (await db.get(['unmaximize_icon'])) || (await components.feather('minimize')), + closeIcon = (await db.get(['close_icon'])) || (await components.feather('x')); + minimizeIcon = minimizeIcon.trim(); + maximizeIcon = maximizeIcon.trim(); + unmaximizeIcon = unmaximizeIcon.trim(); + closeIcon = closeIcon.trim(); + + minimizeIcon = + minimizeIcon.startsWith('') + ? minimizeIcon + : web.escape(minimizeIcon); + maximizeIcon = + maximizeIcon.startsWith('') + ? maximizeIcon + : web.escape(maximizeIcon); + unmaximizeIcon = + unmaximizeIcon.startsWith('') + ? unmaximizeIcon + : web.escape(unmaximizeIcon); + closeIcon = + closeIcon.startsWith('') + ? closeIcon + : web.escape(closeIcon); + + const $windowButtons = web.html`
`, + $minimize = web.html``, + $maximize = web.html``, + $unmaximize = web.html``, + $close = web.html``; + components.addTooltip($minimize, '**Minimize window**'); + components.addTooltip($maximize, '**Maximize window**'); + components.addTooltip($unmaximize, '**Unmaximize window**'); + components.addTooltip($close, '**Close window**'); + + $minimize.addEventListener('click', () => electron.browser.minimize()); + $maximize.addEventListener('click', () => electron.browser.maximize()); + $unmaximize.addEventListener('click', () => electron.browser.unmaximize()); + $close.addEventListener('click', () => electron.browser.close()); + electron.browser.on('maximize', () => { + $maximize.replaceWith($unmaximize); + }); + electron.browser.on('unmaximize', () => { + $unmaximize.replaceWith($maximize); + }); + + web.render( + $windowButtons, + $minimize, + electron.browser.isMaximized() ? $unmaximize : $maximize, + $close + ); + return $windowButtons; +}; diff --git a/repo/integrated-titlebar/client.mjs b/repo/integrated-titlebar/client.mjs new file mode 100644 index 0000000..f217e60 --- /dev/null +++ b/repo/integrated-titlebar/client.mjs @@ -0,0 +1,58 @@ +/** + * notion-enhancer: integrated titlebar + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import { createWindowButtons } from './buttons.mjs'; + +export default async function (api, db) { + const { web, registry, electron } = api, + tilingMode = await db.get(['tiling']), + dragareaHeight = await db.get(['dragarea_height']), + tabsEnabled = await registry.enabled('e1692c29-475e-437b-b7ff-3eee872e1a42'), + sidebarSelector = '.notion-sidebar', + panelSelector = '#enhancer--panel', + topbarSelector = '.notion-topbar', + topbarActionsSelector = '.notion-topbar-action-buttons'; + if (tilingMode || tabsEnabled) return; + + let sidebarWidth = '0px', + panelWidth = '0px'; + const updateDragareaOffsets = () => { + const $sidebar = document.querySelector(sidebarSelector), + newSidebarWidth = + !$sidebar || $sidebar.style.height === 'auto' ? '0px' : $sidebar.style.width, + $panel = document.querySelector(panelSelector), + newPanelWidth = + $panel && $panel.dataset.enhancerPanelPinned === 'true' + ? window + .getComputedStyle(document.documentElement) + .getPropertyValue('--component--panel-width') + : '0px'; + if (newSidebarWidth !== sidebarWidth) { + sidebarWidth = newSidebarWidth; + electron.sendMessageToHost('sidebar-width', sidebarWidth); + } + if (newPanelWidth !== panelWidth) { + panelWidth = newPanelWidth; + electron.sendMessageToHost('panel-width', panelWidth); + } + }; + web.addDocumentObserver(updateDragareaOffsets); + + await web.whenReady([topbarSelector, topbarActionsSelector]); + const $topbar = document.querySelector(topbarSelector), + $dragarea = web.html`
`; + $topbar.prepend($dragarea); + document.documentElement.style.setProperty( + '--integrated_titlebar--dragarea-height', + dragareaHeight + 'px' + ); + + const $topbarActions = document.querySelector(topbarActionsSelector), + $windowButtons = await createWindowButtons(api, db); + web.render($topbarActions.parentElement, $windowButtons); +} diff --git a/repo/integrated-titlebar/createWindow.cjs b/repo/integrated-titlebar/createWindow.cjs new file mode 100644 index 0000000..39e42e6 --- /dev/null +++ b/repo/integrated-titlebar/createWindow.cjs @@ -0,0 +1,18 @@ +/** + * notion-enhancer: integrated titlebar + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = function (api, db, __exports, __eval) { + __eval(` + const notionRectFromFocusedWindow = getRectFromFocusedWindow; + getRectFromFocusedWindow = (windowState) => { + const rect = notionRectFromFocusedWindow(windowState); + rect.frame = false; + return rect; + }; + `); +}; diff --git a/repo/integrated-titlebar/frame.mjs b/repo/integrated-titlebar/frame.mjs new file mode 100644 index 0000000..f0e7729 --- /dev/null +++ b/repo/integrated-titlebar/frame.mjs @@ -0,0 +1,43 @@ +/** + * notion-enhancer: integrated titlebar + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import { createWindowButtons } from './buttons.mjs'; + +export default async function (api, db) { + const { web, registry } = api, + tilingMode = await db.get(['tiling']), + dragareaHeight = await db.get(['dragarea_height']), + tabsEnabled = await registry.enabled('e1692c29-475e-437b-b7ff-3eee872e1a42'); + + if (tabsEnabled && !tilingMode) { + const windowActionsSelector = '#window-actions'; + await web.whenReady([windowActionsSelector]); + + const $topbarActions = document.querySelector(windowActionsSelector), + $windowButtons = await createWindowButtons(api, db); + web.render($topbarActions, $windowButtons); + } else { + const dragareaSelector = '[style*="-webkit-app-region: drag;"]'; + await web.whenReady([dragareaSelector]); + + const dragarea = document.querySelector(dragareaSelector); + dragarea.style.top = '2px'; + dragarea.style.height = tilingMode ? '0' : `${dragareaHeight}px`; + + document.getElementById('notion').addEventListener('ipc-message', (event) => { + switch (event.channel) { + case 'notion-enhancer:sidebar-width': + dragarea.style.left = event.args[0]; + break; + case 'notion-enhancer:panel-width': + dragarea.style.right = event.args[0]; + break; + } + }); + } +} diff --git a/repo/integrated-titlebar/integrated-titlebar.jpg b/repo/integrated-titlebar/integrated-titlebar.jpg new file mode 100644 index 0000000..0802010 Binary files /dev/null and b/repo/integrated-titlebar/integrated-titlebar.jpg differ diff --git a/repo/integrated-titlebar/menu.mjs b/repo/integrated-titlebar/menu.mjs new file mode 100644 index 0000000..2e015f3 --- /dev/null +++ b/repo/integrated-titlebar/menu.mjs @@ -0,0 +1,29 @@ +/** + * notion-enhancer: integrated titlebar + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import { createWindowButtons } from './buttons.mjs'; + +export default async function (api, db) { + const { web } = api, + tilingMode = await db.get(['tiling']), + dragareaHeight = await db.get(['dragarea_height']), + sidebarSelector = '.sidebar'; + if (tilingMode) return; + + await web.whenReady([sidebarSelector]); + const $dragarea = web.html`
`; + document.body.prepend($dragarea); + document.documentElement.style.setProperty( + '--integrated_titlebar--dragarea-height', + dragareaHeight + 'px' + ); + + const $sidebar = document.querySelector(sidebarSelector), + $windowButtons = await createWindowButtons(api, db); + $sidebar.prepend($windowButtons); +} diff --git a/repo/integrated-titlebar/mod.json b/repo/integrated-titlebar/mod.json new file mode 100644 index 0000000..c84d400 --- /dev/null +++ b/repo/integrated-titlebar/mod.json @@ -0,0 +1,72 @@ +{ + "name": "integrated titlebar", + "id": "a5658d03-21c6-4088-bade-fa4780459133", + "environments": ["linux", "win32"], + "version": "0.11.0", + "description": "replaces the native window titlebar with buttons inset into the app.", + "preview": "integrated-titlebar.jpg", + "tags": ["extension", "layout"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "frame": ["buttons.css"], + "client": ["buttons.css"], + "menu": ["buttons.css"] + }, + "js": { + "frame": ["frame.mjs"], + "client": ["client.mjs"], + "menu": ["menu.mjs"], + "electron": [{ "source": "createWindow.cjs", "target": "main/createWindow.js" }] + }, + "options": [ + { + "type": "toggle", + "key": "tiling", + "label": "tiling window manager mode", + "tooltip": "**completely remove the close/minimise/maximise buttons** (only for advanced use, not recommended)", + "value": false + }, + { + "type": "number", + "key": "dragarea_height", + "label": "dragarea height (px)", + "tooltip": "**the height of the rectangle added to the top of the window, used to drag/move the window around** (dragging is not possible in a frameless window without this bar)", + "value": 12 + }, + { + "type": "text", + "key": "minimize_icon", + "label": "minimize window icon", + "tooltip": "**may be an svg string or any unicode symbol e.g. an emoji** (the default icon will be used if this field is left empty)", + "value": "" + }, + { + "type": "text", + "key": "maximize_icon", + "label": "maximize window icon", + "tooltip": "**may be an svg string or any unicode symbol e.g. an emoji** (the default icon will be used if this field is left empty)", + "value": "" + }, + { + "type": "text", + "key": "unmaximize_icon", + "label": "unmaximize window icon", + "tooltip": "**may be an svg string or any unicode symbol e.g. an emoji** (the default icon will be used if this field is left empty)", + "value": "" + }, + { + "type": "text", + "key": "close_icon", + "label": "close window icon", + "tooltip": "**may be an svg string or any unicode symbol e.g. an emoji** (the default icon will be used if this field is left empty)", + "value": "" + } + ] +} diff --git a/repo/light+/light+.png b/repo/light+/light+.png new file mode 100644 index 0000000..8d6586d Binary files /dev/null and b/repo/light+/light+.png differ diff --git a/repo/light+/mod.json b/repo/light+/mod.json new file mode 100644 index 0000000..cf7fc57 --- /dev/null +++ b/repo/light+/mod.json @@ -0,0 +1,48 @@ +{ + "name": "light+", + "id": "336cbc54-67b9-4b00-b4a2-9cc86eef763b", + "version": "0.2.0", + "description": "a simple white theme that brightens coloured text and blocks, with configurable accents.", + "preview": "light+.png", + "tags": ["theme", "light"], + "authors": [ + { + "name": "Lizishan", + "homepage": "https://www.reddit.com/user/Lizishan", + "avatar": "https://styles.redditmedia.com/t5_110nz4/styles/profileIcon_h1m3b16exoi51.jpg" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": { + "frame": ["theme.mjs"], + "client": ["theme.mjs"], + "menu": ["theme.mjs"] + }, + "options": [ + { + "type": "color", + "key": "primary", + "label": "primary accent color", + "tooltip": "**replaces notion's blue accent**", + "value": "rgba(46,170,220,1)" + }, + { + "type": "color", + "key": "secondary", + "label": "secondary accent color", + "tooltip": "**replaces notion's red accent**", + "value": "rgba(235,87,87,1)" + }, + { + "type": "color", + "key": "highlight", + "label": "highlight accent color", + "tooltip": "**affects dividers, text, icons and hovered scrollbars. set this to rgba(0,0,0,0) to disable it**", + "value": "rgba(0,0,0,0)" + } + ] +} diff --git a/repo/light+/theme.mjs b/repo/light+/theme.mjs new file mode 100644 index 0000000..64c7302 --- /dev/null +++ b/repo/light+/theme.mjs @@ -0,0 +1,70 @@ +/** + * notion-enhancer: light+ + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ fmt }, db) { + { + const primary = await db.get(['primary']), + [r, g, b] = primary + .slice(5, -1) + .split(',') + .map((i) => parseInt(i)); + if (!(r === 46 && g === 170 && b === 220)) { + document.documentElement.style.setProperty('--light_plus--accent_blue', primary); + document.documentElement.style.setProperty( + '--light_plus--accent_blue-selection', + `rgba(${r},${g},${b},0.2)` + ); + document.documentElement.style.setProperty( + '--light_plus--accent_blue-hover', + fmt.rgbLogShade(0.05, primary) + ); + document.documentElement.style.setProperty( + '--light_plus--accent_blue-active', + fmt.rgbLogShade(0.025, primary) + ); + document.documentElement.style.setProperty( + '--light_plus--accent_blue-text', + fmt.rgbContrast(r, g, b) + ); + } + } + + { + const secondary = await db.get(['secondary']), + [r, g, b] = secondary + .slice(5, -1) + .split(',') + .map((i) => parseInt(i)); + if (!(r === 235 && g === 87 && b === 87)) { + document.documentElement.style.setProperty('--light_plus--accent_red', secondary); + document.documentElement.style.setProperty( + '--light_plus--accent_red-button', + `rgba(${r},${g},${b},0.2)` + ); + document.documentElement.style.setProperty( + '--light_plus--accent_red-text', + fmt.rgbContrast(r, g, b) + ); + } + } + + { + const highlight = await db.get(['highlight']), + [r, g, b, a] = highlight + .slice(5, -1) + .split(',') + .map((i) => parseFloat(i)); + if (!(r === 0 && g === 0 && b === 0 && a === 0)) { + document.documentElement.style.setProperty('--light_plus--accent_highlight', highlight); + document.documentElement.style.setProperty( + '--light_plus--accent_highlight-shaded', + fmt.rgbLogShade(0.1, highlight) + ); + } + } +} diff --git a/repo/light+/variables.css b/repo/light+/variables.css new file mode 100644 index 0000000..60531ff --- /dev/null +++ b/repo/light+/variables.css @@ -0,0 +1,137 @@ +/** + * notion-enhancer: light+ + * (c) 2020 Lizishan + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.light { + --theme--accent_blue: var(--light_plus--accent_blue, rgb(46, 170, 220)); + --theme--accent_blue-selection: var( + --light_plus--accent_blue-selection, + rgb(46, 170, 220, 0.25) + ); + --theme--accent_blue-hover: var(--light_plus--accent_blue-hover, rgb(6, 156, 205)); + --theme--accent_blue-active: var(--light_plus--accent_blue-active, rgb(0, 141, 190)); + --theme--accent_blue-text: var(--light_plus--accent_blue-text, #fff); + --theme--accent_red: var(--light_plus--accent_red, #eb5757); + --theme--accent_red-button: var(--light_plus--accent_red-button, rgba(235, 87, 87, 0.1)); + --theme--accent_red-text: var(--light_plus--accent_red-text, #fff); + + --theme--scrollbar_thumb-hover: var(--light_plus--accent_highlight, #aeaca6); + + --theme--ui_divider: var(--light_plus--accent_highlight, rgb(237, 237, 236)); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: var(--light_plus--accent_highlight, rgba(55, 53, 47, 0.8)); + --theme--icon_secondary: var(--light_plus--accent_highlight, rgba(55, 53, 47, 0.4)); + + --theme--text: var(--light_plus--accent_highlight, rgb(55, 43, 47)); + --theme--text_secondary: var(--light_plus--accent_highlight-shaded, rgba(55, 43, 47, 0.6)); + + --theme--text_gray: rgba(151, 154, 155, 0.95); + --theme--text_brown: rgb(167, 126, 100); + --theme--text_orange: rgb(255, 134, 0); + --theme--text_yellow: rgb(255, 195, 0); + --theme--text_green: rgb(0, 171, 0); + --theme--text_blue: rgb(0, 121, 255); + --theme--text_purple: rgb(126, 0, 255); + --theme--text_pink: rgb(255, 0, 208); + --theme--text_red: rgb(255, 0, 0); + + --theme--highlight_gray: rgb(234, 234, 234); + --theme--highlight_gray-text: rgb(17, 17, 17); + --theme--highlight_brown: rgb(206, 206, 206); + --theme--highlight_brown-text: rgb(85, 35, 1); + --theme--highlight_orange: rgb(254, 214, 155); + --theme--highlight_orange-text: rgb(199, 110, 0); + --theme--highlight_yellow: #fcffd8; + --theme--highlight_yellow-text: #ff8c22; + --theme--highlight_green: #d5fded; + --theme--highlight_green-text: #006a00; + --theme--highlight_blue: #e2f5ff; + --theme--highlight_blue-text: #00b2ff; + --theme--highlight_purple: #efe6ff; + --theme--highlight_purple-text: #8334ff; + --theme--highlight_pink: #ffe9f1; + --theme--highlight_pink-text: rgb(255, 0, 127); + --theme--highlight_red: rgb(248, 215, 218); + --theme--highlight_red-text: rgb(138, 0, 10); + + --theme--callout_gray: #e2e3e5; + --theme--callout_gray-text: #383d41; + --theme--callout_brown: rgb(130, 118, 111); + --theme--callout_brown-text: rgb(85, 35, 1); + --theme--callout_orange: rgb(254, 214, 155); + --theme--callout_orange-text: rgb(255, 140, 0); + --theme--callout_yellow: #fcffd8; + --theme--callout_yellow-text: #c76e00; + --theme--callout_green: #d4edda; + --theme--callout_green-text: #155724; + --theme--callout_blue: #cce5ff; + --theme--callout_blue-text: #004085; + --theme--callout_purple: rgb(199, 178, 230); + --theme--callout_purple-text: rgb(90, 49, 148); + --theme--callout_pink: rgb(255, 206, 228); + --theme--callout_pink-text: rgb(255, 0, 127); + --theme--callout_red: #f8d7da; + --theme--callout_red-text: #721c24; + + --theme--tag_default: rgb(234, 234, 234); + --theme--tag_light_gray: rgb(240, 240, 240); + --theme--tag_light_gray-text: rgb(65, 65, 65); + --theme--tag_gray: rgb(234, 234, 234); + --theme--tag_gray-text: rgb(17, 17, 17); + --theme--tag_brown: rgb(206, 206, 206); + --theme--tag_brown-text: rgb(85, 35, 1); + --theme--tag_orange: rgb(254, 214, 155); + --theme--tag_orange-text: rgb(199, 110, 0); + --theme--tag_yellow: #fcffd8; + --theme--tag_yellow-text: #ff8c22; + --theme--tag_green: #d5fded; + --theme--tag_green-text: #006a00; + --theme--tag_blue: #e2f5ff; + --theme--tag_blue-text: #00b2ff; + --theme--tag_purple: #efe6ff; + --theme--tag_purple-text: #8334ff; + --theme--tag_pink: #ffe9f1; + --theme--tag_pink-text: rgb(255, 0, 127); + --theme--tag_red: rgb(248, 215, 218); + --theme--tag_red-text: rgb(138, 0, 10); + + --theme--board_light_gray: #EBEBED; + --theme--board_light_gray-text: #616366; + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_gray: #e2e3e5; + --theme--board_gray-text: #383d41; + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_brown: rgb(130, 118, 111); + --theme--board_brown-text: rgb(85, 35, 1); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_orange: rgb(254, 214, 155); + --theme--board_orange-text: rgb(255, 140, 0); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_yellow: #fcffd8; + --theme--board_yellow-text: #c76e00; + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_green: #d4edda; + --theme--board_green-text: #155724; + --theme--board_green-card: var(--theme--tag_green); + --theme--board_blue: #cce5ff; + --theme--board_blue-text: #004085; + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_purple: rgb(199, 178, 230); + --theme--board_purple-text: rgb(90, 49, 148); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_pink: rgb(255, 206, 228); + --theme--board_pink-text: rgb(255, 0, 127); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_red: #f8d7da; + --theme--board_red-text: #721c24; + --theme--board_red-card: var(--theme--tag_red); + + --theme--code_inline: rgb(179, 39, 39); + --theme--code_inline-text: #e0dfe2; +} diff --git a/repo/material-ocean/material-ocean.png b/repo/material-ocean/material-ocean.png new file mode 100644 index 0000000..838a9ca Binary files /dev/null and b/repo/material-ocean/material-ocean.png differ diff --git a/repo/material-ocean/mod.json b/repo/material-ocean/mod.json new file mode 100644 index 0000000..00a46aa --- /dev/null +++ b/repo/material-ocean/mod.json @@ -0,0 +1,23 @@ +{ + "name": "material ocean", + "id": "69e7ccb2-4aef-484c-876d-3de1b433d2b9", + "version": "0.2.0", + "description": "an oceanic colour palette.", + "preview": "material-ocean.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "blacksuan19", + "email": "abubakaryagob@gmail.com", + "homepage": "http://github.com/blacksuan19", + "avatar": "https://avatars.githubusercontent.com/u/10248473" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/material-ocean/variables.css b/repo/material-ocean/variables.css new file mode 100644 index 0000000..e8a3579 --- /dev/null +++ b/repo/material-ocean/variables.css @@ -0,0 +1,173 @@ +/** + * notion-enhancer: material ocean + * (c) 2020 Abubakar Yagoub (https://blacksuan19.tk) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --ocean--main: #0f111a; + --ocean--sec: #00010a; + --ocean--tet: #000108; + --ocean--accent: #ff4151; + --ocean--light_gray: #E9E9E9; + --ocean--gray: #e0e0e0; + --ocean--brown: #d8b6a6; + --ocean--orange: #fde3c0; + --ocean--yellow: #ebcb8b; + --ocean--green: #a3be8c; + --ocean--blue: #81a1c1; + --ocean--purple: #b48ead; + --ocean--pink: #ffc0cb; + --ocean--red: #bf616a; + + --theme--accent_blue: var(--ocean--accent); + --theme--accent_blue-selection: rgba(255, 65, 81, 0.2); + --theme--accent_blue-hover: #fc3747; + --theme--accent_blue-active: #ff4d5c; + --theme--accent_blue-text: #fff; + --theme--accent_red: var(--ocean--accent); + --theme--accent_red-button: #ff41514b; + --theme--accent_red-text: #fff; + + --theme--bg: var(--ocean--main); + --theme--bg_secondary: var(--ocean--sec); + --theme--bg_card: var(--ocean--sec); + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: var(--ocean--sec); + --theme--scrollbar_thumb-hover: var(--ocean--accent); + + --theme--ui_divider: rgba(255, 255, 255, 0.1); + --theme--ui_interactive-hover: rgb(0, 1, 8, 0.3); + --theme--ui_interactive-active: rgb(0, 1, 8, 0.6); + --theme--ui_toggle-off: #30313c; + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: var(--ocean--gray); + --theme--icon_secondary: var(--ocean--gray); + + --theme--text: #fff; + --theme--text_secondary: var(--ocean--gray); + --theme--text_gray: var(--ocean--gray); + --theme--text_brown: var(--ocean--brown); + --theme--text_orange: var(--ocean--orange); + --theme--text_yellow: var(--ocean--yellow); + --theme--text_green: var(--ocean--green); + --theme--text_blue: var(--ocean--blue); + --theme--text_purple: var(--ocean--purple); + --theme--text_pink: var(--ocean--pink); + --theme--text_red: var(--ocean--red); + + --theme--highlight_gray: var(--ocean--gray); + --theme--highlight_gray-text: var(--ocean--main); + --theme--highlight_brown: var(--ocean--brown); + --theme--highlight_brown-text: var(--ocean--main); + --theme--highlight_orange: var(--ocean--orange); + --theme--highlight_orange-text: var(--ocean--main); + --theme--highlight_yellow: var(--ocean--yellow); + --theme--highlight_yellow-text: var(--ocean--main); + --theme--highlight_green: var(--ocean--green); + --theme--highlight_green-text: var(--ocean--main); + --theme--highlight_blue: var(--ocean--blue); + --theme--highlight_blue-text: var(--ocean--main); + --theme--highlight_purple: var(--ocean--purple); + --theme--highlight_purple-text: var(--ocean--main); + --theme--highlight_pink: var(--ocean--pink); + --theme--highlight_pink-text: var(--ocean--main); + --theme--highlight_red: var(--ocean--red); + --theme--highlight_red-text: var(--ocean--main); + + --theme--callout_gray: #e0e0e089; + --theme--callout_gray-text: var(--ocean--main); + --theme--callout_brown: #d8b6a692; + --theme--callout_brown-text: var(--ocean--main); + --theme--callout_orange: #fde3c09f; + --theme--callout_orange-text: var(--ocean--main); + --theme--callout_yellow: #ffe6a6ad; + --theme--callout_yellow-text: var(--ocean--main); + --theme--callout_green: #a3be8ca3; + --theme--callout_green-text: var(--ocean--main); + --theme--callout_blue: #81a1c1a3; + --theme--callout_blue-text: var(--ocean--main); + --theme--callout_purple: #b48eada8; + --theme--callout_purple-text: var(--ocean--main); + --theme--callout_pink: #ffc0cbb1; + --theme--callout_pink-text: var(--ocean--main); + --theme--callout_red: #bf616a9e; + --theme--callout_red-text: var(--ocean--main); + + --theme--tag_default: var(--ocean--gray); + --theme--tag_default-text: var(--ocean--main); + --theme--tag_light_gray: var(--ocean--light_gray); + --theme--tag_light_gray-text: var(--ocean--main); + --theme--tag_gray: var(--theme--highlight_gray); + --theme--tag_gray-text: var(--ocean--main); + --theme--tag_brown: var(--theme--highlight_brown); + --theme--tag_brown-text: var(--ocean--main); + --theme--tag_orange: var(--theme--highlight_orange); + --theme--tag_orange-text: var(--ocean--main); + --theme--tag_yellow: var(--theme--highlight_yellow); + --theme--tag_yellow-text: var(--ocean--main); + --theme--tag_green: var(--theme--highlight_green); + --theme--tag_green-text: var(--ocean--main); + --theme--tag_blue: var(--theme--highlight_blue); + --theme--tag_blue-text: var(--ocean--main); + --theme--tag_purple: var(--theme--highlight_purple); + --theme--tag_purple-text: var(--ocean--main); + --theme--tag_pink: var(--theme--highlight_pink); + --theme--tag_pink-text: var(--ocean--main); + --theme--tag_red: var(--theme--highlight_red); + --theme--tag_red-text: var(--ocean--main); + + --theme--board_light_gray: var(--ocean--light_gray); + --theme--board_light_gray-text: var(--ocean--main); + --theme--board_light_gray-card: rgba(0, 0, 0, 0.075); + --theme--board_gray: var(--theme--highlight_gray); + --theme--board_gray-text: var(--theme--highlight_gray-text); + --theme--board_gray-card: rgba(0, 0, 0, 0.075); + --theme--board_brown: var(--theme--highlight_brown); + --theme--board_brown-text: var(--theme--highlight_brown-text); + --theme--board_brown-card: rgba(0, 0, 0, 0.075); + --theme--board_orange: var(--theme--highlight_orange); + --theme--board_orange-text: var(--theme--highlight_orange-text); + --theme--board_orange-card: rgba(0, 0, 0, 0.075); + --theme--board_yellow: var(--theme--highlight_yellow); + --theme--board_yellow-text: var(--theme--highlight_yellow-text); + --theme--board_yellow-card: rgba(0, 0, 0, 0.075); + --theme--board_green: var(--theme--highlight_green); + --theme--board_green-text: var(--theme--highlight_green-text); + --theme--board_green-card: rgba(0, 0, 0, 0.075); + --theme--board_blue: var(--theme--highlight_blue); + --theme--board_blue-text: var(--theme--highlight_blue-text); + --theme--board_blue-card: rgba(0, 0, 0, 0.075); + --theme--board_purple: var(--theme--highlight_purple); + --theme--board_purple-text: var(--theme--highlight_purple-text); + --theme--board_purple-card: rgba(0, 0, 0, 0.075); + --theme--board_pink: var(--theme--highlight_pink); + --theme--board_pink-text: var(--theme--highlight_pink-text); + --theme--board_pink-card: rgba(0, 0, 0, 0.075); + --theme--board_red: var(--theme--highlight_red); + --theme--board_red-text: var(--theme--highlight_red-text); + --theme--board_red-card: rgba(0, 0, 0, 0.075); + + --theme--code_inline: var(--ocean--sec); + --theme--code_inline-text: #b3f5c8; + + --theme--code: var(--ocean--sec); + --theme--code_function: var(--theme--text_blue); + --theme--code_keyword: var(--theme--text_pink); + --theme--code_tag: var(--theme--text_pink); + --theme--code_operator: var(--theme--text_yellow); + --theme--code_property: var(--theme--text_pink); + --theme--code_builtin: var(--theme--text_yellow); + --theme--code_attr-name: var(--theme--text_yellow); + --theme--code_comment: var(--theme--text_gray); + --theme--code_punctuation: var(--theme--text_gray); + --theme--code_doctype: var(--theme--text_gray); + --theme--code_number: var(--theme--text_purple); + --theme--code_selector: var(--theme--text_orange); + --theme--code_atrule: var(--theme--text_orange); + --theme--code_regex: var(--theme--text_yellow); +} diff --git a/repo/menu/client.css b/repo/menu/client.css new file mode 100644 index 0000000..0109a3c --- /dev/null +++ b/repo/menu/client.css @@ -0,0 +1,69 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.enhancer--sidebarMenuLink { + user-select: none; + -webkit-user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + color: var(--theme--text_secondary); +} +.enhancer--sidebarMenuLink:hover { + background: var(--theme--ui_interactive-hover); +} +.enhancer--sidebarMenuLink svg { + width: 16px; + height: 16px; + margin-left: 2px; +} +.enhancer--sidebarMenuLink > div { + display: flex; + align-items: center; + min-height: 27px; + font-size: 14px; + padding: 2px 14px; + width: 100%; +} +.enhancer--sidebarMenuLink > div > :first-child { + flex-shrink: 0; + flex-grow: 0; + border-radius: 3px; + width: 22px; + height: 22px; + display: flex; + align-items: center; + justify-content: center; + margin-right: 8px; +} +.enhancer--sidebarMenuLink > div > :nth-child(2) { + flex: 1 1 auto; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.enhancer--sidebarMenuLink:active { + color: var(--theme--text); +} +.enhancer--sidebarMenuLink > div > .enhancer--notificationBubble { + display: flex; +} +.enhancer--sidebarMenuLink > div > .enhancer--notificationBubble > div { + display: inline-flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + font-size: 10px; + font-weight: 600; + border-radius: 3px; + color: var(--theme--accent_red-text); + background: var(--theme--accent_red); +} +.enhancer--sidebarMenuLink > div > .enhancer--notificationBubble > div > span { + margin-bottom: 1px; + margin-left: -0.5px; +} diff --git a/repo/menu/client.mjs b/repo/menu/client.mjs new file mode 100644 index 0000000..62b06e7 --- /dev/null +++ b/repo/menu/client.mjs @@ -0,0 +1,48 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +const notificationsURL = 'https://notion-enhancer.github.io/notifications.json'; + +export default async function ({ env, fs, storage, registry, web }, db) { + web.addHotkeyListener(await db.get(['hotkey']), env.focusMenu); + + const sidebarSelector = '.notion-sidebar-container .notion-sidebar > div:nth-child(3) > div > div:nth-child(2)'; + await web.whenReady([sidebarSelector]); + + const $sidebarLink = web.html``; + $sidebarLink.addEventListener('click', env.focusMenu); + + const notifications = { + cache: await storage.get(['notifications'], []), + provider: await fs.getJSON(notificationsURL), + count: (await registry.errors()).length, + }; + for (const notification of notifications.provider) { + if ( + !notifications.cache.includes(notification.id) && + notification.version === env.version && + (!notification.environments || notification.environments.includes(env.name)) + ) { + notifications.count++; + } + } + if ((await storage.get(['last_read_changelog'])) !== env.version) notifications.count++; + if (notifications.count) { + web.render( + $sidebarLink.children[0], + web.html`
${notifications.count}
` + ); + } + + web.render(document.querySelector(sidebarSelector), $sidebarLink); +} diff --git a/repo/menu/components.mjs b/repo/menu/components.mjs new file mode 100644 index 0000000..0e9d876 --- /dev/null +++ b/repo/menu/components.mjs @@ -0,0 +1,292 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import { fmt, web, registry, components } from '../../api/index.mjs'; +import { notifications } from './notifications.mjs'; +import '../../dep/jscolor.min.js'; + +import '../../dep/markdown-it.min.js'; +const md = markdownit({ linkify: true }); + +export const modComponents = { + preview: (url) => web.html``, + title: (title) => web.html`

${web.escape(title)}

`, + version: (version) => web.html`v${web.escape(version)}`, + tags: (tags) => { + if (!tags.length) return ''; + return web.render( + web.html`

`, + tags.map((tag) => `#${web.escape(tag)}`).join(' ') + ); + }, + description: (description) => { + const $description = web.html`

+ ${md.renderInline(description)} +

`; + $description.querySelectorAll('a').forEach((a) => { + a.target = '_blank'; + }); + return $description; + }, + authors: (authors) => { + const author = (author) => web.html` + ${web.escape(author.name)}'s avatar ${web.escape(author.name)} + `; + return web.render(web.html`

`, ...authors.map(author)); + }, + 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, $feature); + }, +}; + +export const options = { + toggle: async (mod, opt) => { + const profileDB = await registry.profileDB(), + checked = await profileDB.get([mod.id, opt.key], opt.value), + $toggle = modComponents.toggle(opt.label, checked), + $tooltipIcon = web.html`${await components.feather('info', { class: 'input-tooltip' })}`, + $label = $toggle.children[0], + $input = $toggle.children[1]; + if (opt.tooltip) { + $label.prepend($tooltipIcon); + components.addTooltip($tooltipIcon, opt.tooltip, { + offsetDirection: 'left', + maxLines: 3, + }); + } + $input.addEventListener('change', async (_event) => { + await profileDB.set([mod.id, opt.key], $input.checked); + notifications.onChange(); + }); + return $toggle; + }, + + select: async (mod, opt) => { + const profileDB = await registry.profileDB(), + value = await profileDB.get([mod.id, opt.key], opt.values[0]), + $tooltipIcon = web.html`${await components.feather('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltipIcon : '', opt.label) + ), + $options = opt.values.map( + (option) => web.raw`` + ), + $select = web.html``, + $icon = web.html`${await components.feather('chevron-down', { class: 'input-icon' })}`; + if (opt.tooltip) + components.addTooltip($tooltipIcon, opt.tooltip, { + offsetDirection: 'left', + maxLines: 3, + }); + $select.addEventListener('change', async (_event) => { + await profileDB.set([mod.id, opt.key], $select.value); + notifications.onChange(); + }); + return web.render($label, $select, $icon); + }, + + text: async (mod, opt) => { + const profileDB = await registry.profileDB(), + value = await profileDB.get([mod.id, opt.key], opt.value), + $tooltipIcon = web.html`${await components.feather('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltipIcon : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${await components.feather('type', { class: 'input-icon' })}`; + if (opt.tooltip) + components.addTooltip($tooltipIcon, opt.tooltip, { + offsetDirection: 'left', + maxLines: 3, + }); + $input.addEventListener('change', async (_event) => { + await profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, + + number: async (mod, opt) => { + const profileDB = await registry.profileDB(), + value = await profileDB.get([mod.id, opt.key], opt.value), + $tooltipIcon = web.html`${await components.feather('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltipIcon : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${await components.feather('hash', { class: 'input-icon' })}`; + if (opt.tooltip) + components.addTooltip($tooltipIcon, opt.tooltip, { + offsetDirection: 'left', + maxLines: 3, + }); + $input.addEventListener('change', async (_event) => { + await profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, + + color: async (mod, opt) => { + const profileDB = await registry.profileDB(), + value = await profileDB.get([mod.id, opt.key], opt.value), + $tooltipIcon = web.html`${await components.feather('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltipIcon : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${await components.feather('droplet', { class: 'input-icon' })}`, + paint = () => { + $input.style.background = $picker.toBackground(); + const [r, g, b] = $picker + .toRGBAString() + .slice(5, -1) + .split(',') + .map((i) => parseInt(i)); + $input.style.color = fmt.rgbContrast(r, g, b); + $input.style.padding = ''; + }, + $picker = new 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) + components.addTooltip($tooltipIcon, opt.tooltip, { + offsetDirection: 'left', + maxLines: 3, + }); + $input.addEventListener('change', async (_event) => { + await profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + paint(); + return web.render($label, $input, $icon); + }, + + file: async (mod, opt) => { + const profileDB = await registry.profileDB(), + { filename } = (await profileDB.get([mod.id, opt.key], {})) || {}, + $tooltipIcon = web.html`${await components.feather('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

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

`, opt.tooltip ? $tooltipIcon : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${await components.feather('command', { class: 'input-icon' })}`; + if (opt.tooltip) + components.addTooltip($tooltipIcon, opt.tooltip, { + offsetDirection: 'left', + maxLines: 3, + }); + $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 === '+') key = 'Plus'; + if (key.length === 1) key = event.key.toUpperCase(); + pressed.push(key); + } + $input.value = pressed.join('+'); + await profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, +}; diff --git a/repo/menu/markdown.css b/repo/menu/markdown.css new file mode 100644 index 0000000..2a23626 --- /dev/null +++ b/repo/menu/markdown.css @@ -0,0 +1,97 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.markdown table { + border-spacing: 0; + border: 1px solid var(--theme--ui_divider); +} +.markdown table th { + text-align: left; +} +.markdown table th, +.markdown table td { + padding: 5px 8px 6px; + border: 1px solid var(--theme--ui_divider); +} +.markdown h1 { + font-size: 1.875rem; + margin: 1rem 0 0.5rem 0; +} +.markdown h2 { + font-size: 1.5rem; + margin: 1rem 0 0.5rem 0; +} +.markdown h3 { + font-size: 1.25rem; + margin: 1rem 0 0.5rem 0; +} +.markdown h4 { + font-weight: bold; + margin: 0.5rem 0; +} +.markdown ul, +.markdown ol { + padding-left: 1.25rem; +} +.markdown ul { + list-style: disc; +} +.markdown ol { + list-style: decimal; +} +.markdown li { + margin: 1px 0; +} +.markdown ol li { + padding-left: 0.25rem; +} +.markdown blockquote { + border-left: 2px solid currentColor; + padding-left: 0.75rem; + margin: 0.5rem 0; +} +.markdown hr { + border: 0.5px solid var(--theme--ui_divider); +} +.markdown-inline a, +.markdown a { + opacity: 0.7; + text-decoration: none; + border-bottom: 0.05em solid var(--theme--text_secondary); +} +.markdown-inline a:hover, +.markdown a:hover { + opacity: 0.9; +} + +.markdown :not(pre) > code, +.markdown-inline code { + padding: 0.2em 0.4em; + border-radius: 3px; + background: var(--theme--code_inline); + color: var(--theme--code_inline-text); +} +.markdown pre { + padding: 2em 1.25em; + border-radius: 3px; + tab-size: 2; + white-space: pre; + overflow-x: auto; + background: var(--theme--code); + color: var(--theme--code_plain); +} +.markdown pre, +.markdown code, +.markdown-inline code { + font-family: var(--theme--font_code); + font-size: 0.796875rem; + text-align: left; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + hyphens: none; + line-height: 1.5; +} diff --git a/repo/menu/menu.css b/repo/menu/menu.css new file mode 100644 index 0000000..5a11697 --- /dev/null +++ b/repo/menu/menu.css @@ -0,0 +1,25 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +::selection { + background: var(--theme--accent_blue-selection); +} + +::-webkit-scrollbar { + width: 10px; + height: 10px; + background: transparent; +} +::-webkit-scrollbar-track, +::-webkit-scrollbar-corner { + background: var(--theme--scrollbar_track) !important; +} +::-webkit-scrollbar-thumb { + background: var(--theme--scrollbar_thumb) !important; +} +::-webkit-scrollbar-thumb:hover { + background: var(--theme--scrollbar_thumb-hover) !important; +} diff --git a/repo/menu/menu.html b/repo/menu/menu.html new file mode 100644 index 0000000..ec6337a --- /dev/null +++ b/repo/menu/menu.html @@ -0,0 +1,11 @@ + + + + + + notion-enhancer menu + + + + + diff --git a/repo/menu/menu.mjs b/repo/menu/menu.mjs new file mode 100644 index 0000000..ab8105b --- /dev/null +++ b/repo/menu/menu.mjs @@ -0,0 +1,448 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import * as api from '../../api/index.mjs'; +import { notifications, $changelogModal } from './notifications.mjs'; +import { modComponents, options } from './components.mjs'; +import * as router from './router.mjs'; +import './styles.mjs'; + +(async () => { + const { env, fs, storage, electron, registry, web, components } = api; + + for (const mod of await registry.list((mod) => registry.enabled(mod.id))) { + for (let script of mod.js?.menu || []) { + script = await import(fs.localPath(`repo/${mod._dir}/${script}`)); + script.default(api, await registry.db(mod.id)); + } + } + const errors = await registry.errors(); + if (errors.length) { + console.error('[notion-enhancer] registry errors:'); + console.table(errors); + const $errNotification = await notifications.add({ + icon: 'alert-circle', + message: 'Failed to load mods (check console).', + color: 'red', + }); + if (['win32', 'linux', 'darwin'].includes(env.name)) { + $errNotification.addEventListener('click', () => electron.browser.openDevTools()); + } + } + + const db = await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e'), + profileName = await registry.profileName(), + profileDB = await registry.profileDB(); + + web.addHotkeyListener(await db.get(['hotkey']), env.focusNotion); + + globalThis.addEventListener('beforeunload', (_event) => { + // trigger input save + document.activeElement.blur(); + }); + + const $main = web.html`
`, + $sidebar = web.html``, + $options = web.html`
+

Select a mod to view and configure its options.

+
`, + $profile = web.html``; + + // profile + + let _$profileConfig; + const openProfileMenu = async () => { + if (!_$profileConfig) { + const profileNames = [ + ...new Set([ + ...Object.keys(await storage.get(['profiles'], { default: {} })), + profileName, + ]), + ], + $options = profileNames.map( + (profile) => web.raw`` + ), + $select = web.html``, + $edit = web.html``, + $export = web.html``, + $import = web.html``, + $save = web.html``, + $delete = web.html``, + $error = web.html`

`; + + $export.addEventListener('click', async (_event) => { + const now = new Date(), + $a = web.html``; + web.render(document.body, $a); + $a.click(); + $a.remove(); + }); + + $import.addEventListener('change', (event) => { + const file = event.target.files[0], + reader = new FileReader(); + reader.onload = async (progress) => { + try { + const profileUpload = JSON.parse(progress.currentTarget.result); + if (!profileUpload) throw Error; + await storage.set(['profiles', $select.value], profileUpload); + env.reload(); + } catch { + web.render(web.empty($error), 'Invalid JSON uploaded.'); + } + }; + reader.readAsText(file); + }); + + $select.addEventListener('change', (_event) => { + if ($select.value === '--') { + $edit.value = ''; + } else $edit.value = $select.value; + }); + + $save.addEventListener('click', async (_event) => { + if (profileNames.includes($edit.value) && $select.value !== $edit.value) { + web.render( + web.empty($error), + `The profile "${web.escape($edit.value)}" already exists.` + ); + return false; + } + if (!$edit.value || !$edit.value.match(/^[A-Za-z0-9_-]+$/)) { + web.render( + web.empty($error), + 'Profile names may not be empty & may only contain letters, numbers, hyphens and underscores.' + ); + return false; + } + await storage.set(['currentprofile'], $edit.value); + if ($select.value === '--') { + await storage.set(['profiles', $edit.value], {}); + } else if ($select.value !== $edit.value) { + await storage.set( + ['profiles', $edit.value], + await storage.get(['profiles', $select.value], {}) + ); + await storage.set(['profiles', $select.value], undefined); + } + env.reload(); + }); + + $delete.addEventListener('click', async (_event) => { + await storage.set(['profiles', $select.value], undefined); + await storage.set( + ['currentprofile'], + profileNames.find((profile) => profile !== $select.value) || 'default' + ); + env.reload(); + }); + + _$profileConfig = web.render( + web.html`
`, + web.html`

+ Profiles are used to switch entire configurations.
+ Be careful - deleting a profile deletes all configuration + related to it.
+

`, + web.render( + web.html``, + $select, + web.html`${await components.feather('chevron-down', { class: 'input-icon' })}` + ), + web.render( + web.html``, + $edit, + web.html`${await components.feather('type', { class: 'input-icon' })}` + ), + web.render( + web.html`

`, + $export, + $import, + $save, + $delete + ), + $error + ); + } + web.render(web.empty($options), _$profileConfig); + }; + $profile.addEventListener('click', () => openSidebarMenu('profile')); + + // mods + + const $modLists = {}, + generators = { + options: async (mod) => { + const $fragment = document.createDocumentFragment(); + for (const opt of mod.options) { + if (!opt.environments.includes(env.name)) continue; + web.render($fragment, await options[opt.type](mod, opt)); + } + if (!mod.options.length) { + web.render($fragment, web.html`

No options.

`); + } + return $fragment; + }, + mod: async (mod) => { + const $mod = web.html`
`, + $toggle = modComponents.toggle('', await registry.enabled(mod.id)); + $toggle.addEventListener('change', async (event) => { + if (event.target.checked && mod.tags.includes('theme')) { + const mode = mod.tags.includes('light') ? 'light' : 'dark', + id = mod.id, + mods = await registry.list( + async (mod) => + (await registry.enabled(mod.id)) && + mod.tags.includes('theme') && + mod.tags.includes(mode) && + mod.id !== id + ); + for (const mod of mods) { + profileDB.set(['_mods', mod.id], false); + document.querySelector( + `[data-id="${web.escape(mod.id)}"] .toggle-check` + ).checked = false; + } + } + profileDB.set(['_mods', mod.id], event.target.checked); + notifications.onChange(); + }); + $mod.addEventListener('click', () => openSidebarMenu(mod.id)); + return web.render( + web.html`
`, + web.render( + $mod, + mod.preview + ? modComponents.preview( + mod.preview.startsWith('http') + ? mod.preview + : fs.localPath(`repo/${mod._dir}/${mod.preview}`) + ) + : '', + web.render( + web.html`
`, + web.render(modComponents.title(mod.name), modComponents.version(mod.version)), + modComponents.tags(mod.tags), + modComponents.description(mod.description), + modComponents.authors(mod.authors), + mod.environments.includes(env.name) && !registry.core.includes(mod.id) + ? $toggle + : '' + ) + ) + ); + }, + modList: async (category, message = '') => { + if (!$modLists[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'); + } + }); + for (const mod of mods) { + mod.tags = mod.tags.filter((tag) => tag !== category); + web.render($list, await generators.mod(mod)); + mod.tags.unshift(category); + } + $modLists[category] = web.render( + web.html`
`, + web.render( + web.html``, + $search, + web.html`${await components.feather('search', { class: 'input-icon' })}` + ), + message ? web.render(web.html`

`, message) : '', + $list + ); + } + return $modLists[category]; + }, + }; + + async function openModMenu(id) { + let $mod; + for (const $list of Object.values($modLists)) { + $mod = $list.querySelector(`[data-id="${web.escape(id)}"]`); + if ($mod) break; + } + const mod = await registry.get(id); + if (!$mod || !mod || $mod.className === 'mod-selected') return; + + $mod.className = 'mod-selected'; + const fragment = [ + web.render(modComponents.title(mod.name), modComponents.version(mod.version)), + modComponents.tags(mod.tags), + await generators.options(mod), + ]; + web.render(web.empty($options), ...fragment); + } + + // views + + const $notionNavItem = web.html`

+ ${(await fs.getText('media/colour.svg')).replace( + /width="\d+" height="\d+"/, + `class="nav-notion-icon"` + )} + notion-enhancer +

`; + $notionNavItem.addEventListener('click', env.focusNotion); + + const $coreNavItem = web.html`core`, + $extensionsNavItem = web.html`extensions`, + $themesNavItem = web.html`themes`, + $integrationsNavItem = web.html`integrations`, + $changelogNavItem = web.html``; + components.addTooltip($changelogNavItem, '**Update changelog & welcome message**'); + $changelogNavItem.addEventListener('click', () => { + $changelogModal.scrollTop = 0; + $changelogModal.classList.add('modal-visible'); + }); + + web.render( + document.body, + web.render( + web.html`
`, + web.render( + web.html`
`, + web.render( + web.html``, + $notionNavItem, + $coreNavItem, + $extensionsNavItem, + $themesNavItem, + $integrationsNavItem, + web.html`docs`, + web.html`community`, + $changelogNavItem + ), + $main + ), + web.render($sidebar, $profile, $options) + ) + ); + + function selectNavItem($item) { + for (const $selected of document.querySelectorAll('.nav-item-selected')) { + $selected.className = 'nav-item'; + } + $item.className = 'nav-item-selected'; + } + + await generators.modList( + 'core', + `Core mods provide the basics required for + all other extensions and themes to work. They + can't be disabled, but they can be configured + - just click on a mod to access its options.` + ); + router.addView('core', async () => { + web.empty($main); + selectNavItem($coreNavItem); + return web.render($main, await generators.modList('core')); + }); + + await generators.modList( + 'extension', + `Extensions build on the functionality and layout of + the Notion client, modifying and interacting with + existing interfaces.` + ); + router.addView('extensions', async () => { + web.empty($main); + selectNavItem($extensionsNavItem); + return web.render($main, await generators.modList('extension')); + }); + + await generators.modList( + 'theme', + `Themes change Notion's colour scheme. + Dark themes will only work when Notion is in dark mode, + and light themes will only work when Notion is in light mode. + Only one theme of each mode can be enabled at a time.` + ); + router.addView('themes', async () => { + web.empty($main); + selectNavItem($themesNavItem); + return web.render($main, await generators.modList('theme')); + }); + + await generators.modList( + 'integration', + web.html`Integrations are extensions that use an unofficial API + to access and modify content. They are used just like + normal extensions, but may be more dangerous to use.` + ); + router.addView('integrations', async () => { + web.empty($main); + selectNavItem($integrationsNavItem); + return web.render($main, await generators.modList('integration')); + }); + + router.setDefaultView('extensions'); + + router.addQueryListener('id', openSidebarMenu); + function openSidebarMenu(id) { + if (!id) return; + id = web.escape(id); + + const deselectedMods = `.mod-selected:not([data-id="${id}"])`; + for (const $list of Object.values($modLists)) { + for (const $selected of $list.querySelectorAll(deselectedMods)) { + $selected.className = 'mod'; + } + } + router.updateQuery(`?id=${id}`); + + if (id === 'profile') { + openProfileMenu(); + } else openModMenu(id); + } +})(); diff --git a/repo/menu/mod.json b/repo/menu/mod.json new file mode 100644 index 0000000..7689da9 --- /dev/null +++ b/repo/menu/mod.json @@ -0,0 +1,31 @@ +{ + "name": "menu", + "id": "a6621988-551d-495a-97d8-3c568bca2e9e", + "version": "0.11.0", + "description": "the enhancer's graphical menu, related buttons and shortcuts.", + "tags": ["core"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "client": ["client.css"], + "menu": ["menu.css", "markdown.css"] + }, + "js": { + "client": ["client.mjs"] + }, + "options": [ + { + "type": "hotkey", + "key": "hotkey", + "label": "toggle focus hotkey", + "tooltip": "**switches between notion & the enhancer menu**", + "value": "Ctrl+Alt+E" + } + ] +} diff --git a/repo/menu/notifications.mjs b/repo/menu/notifications.mjs new file mode 100644 index 0000000..faf884b --- /dev/null +++ b/repo/menu/notifications.mjs @@ -0,0 +1,146 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +import { env, fs, storage, web, components } from '../../api/index.mjs'; +import { tw } from './styles.mjs'; + +import '../../dep/markdown-it.min.js'; +const md = markdownit({ linkify: true }); + +const notificationsURL = 'https://notion-enhancer.github.io/notifications.json'; +export const notifications = { + $container: web.html`
`, + async add({ icon, message, id = undefined, color = undefined, link = undefined }) { + const $notification = link + ? web.html`` + : web.html``, + resolve = async () => { + if (id !== undefined) { + notifications.cache.push(id); + await storage.set(['notifications'], notifications.cache); + } + $notification.remove(); + }; + $notification.addEventListener('click', resolve); + $notification.addEventListener('keyup', (event) => { + if (['Enter', ' '].includes(event.key)) resolve(); + }); + web.render( + notifications.$container, + web.render( + $notification, + web.html` + ${md.renderInline(message)} + `, + web.html`${await components.feather(icon, { class: 'notification-icon' })}` + ) + ); + return $notification; + }, + _onChange: false, + async onChange() { + if (this._onChange) return; + this._onChange = true; + const $notification = await this.add({ + icon: 'refresh-cw', + message: 'Reload to apply changes.', + }); + $notification.addEventListener('click', env.reload); + }, +}; + +(async () => { + notifications.cache = await storage.get(['notifications'], []); + notifications.provider = await fs.getJSON(notificationsURL); + + web.render(document.body, notifications.$container); + for (const notification of notifications.provider) { + const cached = notifications.cache.includes(notification.id), + versionMatches = notification.version === env.version, + envMatches = !notification.environments || notification.environments.includes(env.name); + if (!cached && versionMatches && envMatches) notifications.add(notification); + } +})(); + +export const $changelogModal = web.render( + web.html`` +); + +(async () => { + const $changelogModalButton = web.html``; + $changelogModalButton.addEventListener('click', async () => { + $changelogModal.classList.remove('modal-visible'); + await storage.set(['last_read_changelog'], env.version); + }); + + web.render( + $changelogModal, + web.render( + web.html``, + web.html``, + web.render(web.html``, $changelogModalButton) + ) + ); + + const lastReadChangelog = await storage.get(['last_read_changelog']); + web.render(document.body, $changelogModal); + if (lastReadChangelog !== env.version) { + $changelogModal.classList.add('modal-visible'); + } +})(); diff --git a/repo/menu/router.mjs b/repo/menu/router.mjs new file mode 100644 index 0000000..2eb88cc --- /dev/null +++ b/repo/menu/router.mjs @@ -0,0 +1,88 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import { web } from '../../api/index.mjs'; + +const _queryListeners = new Set(); + +export function addView(name, loadFunc) { + const handlerFunc = (newView) => { + if (newView === name) return loadFunc(); + return false; + }; + _queryListeners.add({ param: 'view', viewName: name, handlerFunc }); + handlerFunc(web.queryParams().get('view'), null); +} +export function removeView(name) { + const view = [..._queryListeners].find((view) => view.viewName === name); + if (view) _queryListeners.delete(view); +} +export async function setDefaultView(viewName) { + const viewList = [..._queryListeners].filter((q) => q.viewName).map((v) => v.viewName); + if (!viewList.includes(web.queryParams().get('view'))) { + updateQuery(`?view=${viewName}`, true); + } +} + +export function addQueryListener(param, handlerFunc) { + _queryListeners.add({ param: param, handlerFunc }); + handlerFunc(web.queryParams().get(param), null); +} +export function removeQueryListener(handlerFunc) { + const listener = [..._queryListeners].find((view) => view.handlerFunc === handlerFunc); + if (listener) _queryListeners.delete(listener); +} + +export const updateQuery = (search, replace = false) => { + let query = web.queryParams(); + for (const [key, val] of new URLSearchParams(search)) { + query.set(key, val); + } + query = `?${query.toString()}`; + if (location.search !== query) { + if (replace) { + window.history.replaceState(null, null, query); + } else { + window.history.pushState(null, null, query); + } + triggerQueryListeners(); + } +}; + +function router(event) { + event.preventDefault(); + const anchor = event.path + ? event.path.find((anchor) => anchor.nodeName === 'A') + : event.target; + updateQuery(anchor.getAttribute('href')); +} + +let queryCache = ''; +async function triggerQueryListeners() { + if (location.search === queryCache) return; + const newQuery = web.queryParams(), + oldQuery = new URLSearchParams(queryCache); + queryCache = location.search; + for (const listener of _queryListeners) { + const newParam = newQuery.get(listener.param), + oldParam = oldQuery.get(listener.param); + if (newParam !== oldParam) listener.handlerFunc(newParam, oldParam); + } +} + +window.addEventListener('popstate', triggerQueryListeners); + +web.addDocumentObserver( + (mutation) => { + mutation.target.querySelectorAll('a[href^="?"]').forEach((a) => { + a.removeEventListener('click', router); + a.addEventListener('click', router); + }); + }, + ['a[href^="?"]'] +); diff --git a/repo/menu/styles.mjs b/repo/menu/styles.mjs new file mode 100644 index 0000000..0ce7925 --- /dev/null +++ b/repo/menu/styles.mjs @@ -0,0 +1,182 @@ +/** + * notion-enhancer: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +// css-in-js for better component generation + +import { tw, apply, setup } from '../../dep/twind.mjs'; +import { content } from '../../dep/twind-content.mjs'; + +const pseudoContent = content('""'), + mapColorVariables = (color) => ({ + 'text': `var(--theme--text_${color})`, + 'highlight': `var(--theme--highlight_${color})`, + 'highlight-text': `var(--theme--highlight_${color}-text)`, + 'callout': `var(--theme--callout_${color})`, + 'callout-text': `var(--theme--callout_${color}-text)`, + 'tag': `var(--theme--tag_${color})`, + 'tag-text': `var(--theme--tag_${color}-text)`, + 'board': `var(--theme--board_${color})`, + 'board-text': `var(--theme--board_${color}-text)`, + 'board-card': `var(--theme--board_${color}-card)`, + 'board-card_text': `var(--theme--board_${color}-card_text)`, + }); + +const customClasses = { + 'notifications-container': apply`absolute bottom-0 right-0 px-4 py-3 max-w-full w-96 z-10`, + 'notification': ([color = 'default']) => + apply`p-2 border group hover:(filter brightness-125) ${ + color === 'default' + ? 'bg-tag text-tag-text border-divider' + : `bg-${color}-tag text-${color}-tag-text border-${color}-text` + } flex items-center rounded-full mt-3 shadow-md cursor-pointer`, + 'notification-text': apply`text-xs mx-2 flex-auto font-semibold group-hover:(filter brightness-75)`, + 'notification-icon': apply`fill-current opacity-75 h-4 w-4 mx-2`, + 'body-container': apply`flex w-full h-full overflow-hidden`, + 'sidebar': apply`h-full w-96 max-w-3/7 flex-shrink-0 px-4 pt-3 pb-16 overflow-y-auto flex flex-col + bg-notion-secondary border-l border-divider`, + 'content-container': apply`h-full w-full flex flex-col`, + 'nav': apply`px-4 mx-2.5 py-1 flex flex-wrap items-center border-b border-divider + justify-center xl:justify-start`, + 'nav-notion': apply`flex items-center font-semibold text-xl cursor-pointer select-none my-4 + w-full justify-center xl:(mr-4 w-auto justify-start)`, + 'nav-notion-icon': apply`h-6 w-6 mr-2.5`, + 'nav-item': apply`mr-2 px-3 py-2 rounded-md text-sm font-medium + hover:bg-interactive-hover focus:bg-interactive-active mb-2 xl:(mt-1 mb-0)`, + 'nav-item-selected': apply`nav-item ring-1 ring-divider bg-notion-secondary + hover:bg-notion-secondary focus:bg-notion-secondary`, + 'nav-changelog': apply`xl:ml-auto focus:outline-none`, + 'nav-changelog-icon': apply`w-4 h-4`, + 'main': apply`transition px-4 py-3 overflow-y-auto flex-grow`, + 'main-message': apply`mx-2.5 my-2.5 px-px text-sm text-foreground-secondary text-justify`, + '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-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-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`, + 'profile-trigger': apply`block px-4 py-3 mb-2 rounded-md text-sm text-left font-semibold shadow-inner + hover:bg-accent-red-button border border-accent-red text-accent-red focus:(outline-none bg-accent-red-button)`, + 'profile-actions': apply`flex`, + 'profile-save': apply`text-sm px-3 py-2 font-medium mt-2 bg-accent-blue text-accent-blue-text rounded-md flex-grow + hover:bg-accent-blue-hover focus:(bg-accent-blue-active outline-none) text-center`, + 'profile-delete': apply`profile-trigger px-3 py-2 mb-0 ml-2 mt-2 text-center font-medium`, + 'profile-export': apply`profile-save mr-2`, + 'profile-import': apply`profile-save mr-2`, + 'profile-error': apply`text-xs mt-2 text-red-text`, + 'profile-icon-action': apply`w-4 h-4 -mt-1 inline-block`, + 'profile-icon-text': apply`w-4 h-4 -mt-1 inline-block mr-1`, + 'options-container': apply`px-4 py-3 shadow-inner rounded-lg bg-notion border border-divider space-y-3`, + 'options-placeholder': apply`text-sm text-foreground-secondary`, + '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`, + '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`, + 'important-link': apply`text-accent-red border-b border-accent-red opacity-80 hover:opacity-100`, + 'danger': apply`text-red-text`, + 'link': apply`no-underline border-b border-foreground-secondary opacity-70 hover:opacity-90`, + 'modal': apply`fixed flex z-10 inset-0 overflow-y-auto min-h-screen text-center + ease-out duration-300 transition-opacity opacity-0 pointer-events-none`, + 'modal-visible': { + '@apply': apply`ease-in duration-200 opacity-100 pointer-events-auto`, + '& .modal-box': apply`ease-out duration-300 opacity-100 scale-100`, + }, + 'modal-overlay': apply`fixed inset-0 bg-black bg-opacity-50 transition-opacity`, + 'modal-box': apply`inline-block rounded-lg text-left overflow-hidden shadow-xl + transform transition-all m-auto align-middle + ease-in duration-200 opacity-0 scale-95`, + 'modal-body': apply`bg-notion-secondary p-6 pt-4 max-w-xl w-full`, + 'modal-actions': apply`bg-notion py-3 px-6 flex flex-row-reverse`, + 'modal-title': apply`flex`, + 'modal-title-icon': apply`w-20 mr-6`, + 'modal-title-heading': apply`text-xl leading-6 font-medium`, + 'modal-title-description': apply`mt-2 text-sm text-foreground-secondary`, + 'modal-content': { + '@apply': apply`mt-4 text-sm`, + 'p': apply`mt-2`, + }, + 'modal-button': apply`w-full inline-flex justify-center rounded-md text-base font-medium shadow-sm px-4 py-2 + not-focus:hover:bg-interactive-hover focus:bg-interactive-active focus:outline-none`, +}; + +setup({ + preflight: { + html: apply`w-full h-full`, + body: apply`w-full h-full bg-notion font-sans text-foreground`, + }, + theme: { + fontFamily: { + sans: ['var(--theme--font_sans)'], + mono: ['var(--theme--font_code)'], + }, + colors: { + 'black': 'rgba(0,0,0,var(--tw-bg-opacity));', + 'notion': 'var(--theme--bg)', + 'notion-secondary': 'var(--theme--bg_secondary)', + 'notion-card': 'var(--theme--bg_card)', + 'divider': 'var(--theme--ui_divider)', + 'input': 'var(--theme--ui_input)', + 'icon': 'var(--theme--icon)', + 'icon-secondary': 'var(--theme--icon_secondary)', + 'foreground': 'var(--theme--text)', + 'foreground-secondary': 'var(--theme--text_secondary)', + 'interactive-hover': 'var(--theme--ui_interactive-hover)', + 'interactive-active': 'var(--theme--ui_interactive-active)', + 'tag': 'var(--theme--tag_default)', + 'tag-text': 'var(--theme--tag_default-text)', + 'toggle': { + 'on': 'var(--theme--ui_toggle-on)', + 'off': 'var(--theme--ui_toggle-off)', + 'feature': 'var(--theme--ui_toggle-feature)', + }, + 'accent': { + 'blue': 'var(--theme--accent_blue)', + 'blue-hover': 'var(--theme--accent_blue-hover)', + 'blue-active': 'var(--theme--accent_blue-active)', + 'blue-text': 'var(--theme--accent_blue-text)', + 'red': 'var(--theme--accent_red)', + 'red-button': 'var(--theme--accent_red-button)', + 'red-text': 'var(--theme--accent_red-text)', + }, + 'gray': mapColorVariables('gray'), + 'brown': mapColorVariables('brown'), + 'orange': mapColorVariables('orange'), + 'yellow': mapColorVariables('yellow'), + 'green': mapColorVariables('green'), + 'blue': mapColorVariables('blue'), + 'purple': mapColorVariables('purple'), + 'pink': mapColorVariables('pink'), + 'red': mapColorVariables('red'), + }, + extend: { + maxWidth: { '3/7': 'calc((3 / 7) * 100%);' }, + }, + }, + plugins: customClasses, +}); + +tw`hidden ${Object.keys(customClasses).join(' ')}`; + +export { tw }; diff --git a/repo/neutral/app.css b/repo/neutral/app.css new file mode 100644 index 0000000..7a3c3b5 --- /dev/null +++ b/repo/neutral/app.css @@ -0,0 +1,48 @@ +/** + * notion-enhancer: neutral + * (c) 2020 Arecsu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-dark-theme [placeholder='Heading 1'], +.notion-dark-theme [placeholder='Heading 2'], +.notion-dark-theme [placeholder='Heading 3'] { + padding: 3px 1px !important; +} + +/* hide sidebar "new page" button */ +.notion-dark-theme .notion-sidebar > [style*='flex: 0 0 auto; margin-top: auto;'] { + display: none !important; +} + +/* 1.3 supreme ratio. https://www.modularscale.com/ */ +.notion-collection_view_page-block > div[placeholder='Untitled'], +.notion-frame .notion-page-block > div[placeholder='Untitled'], +.notion-overlay-container .notion-page-block > div[placeholder='Untitled'] { + font-size: 33px !important; +} +[placeholder='Heading 1'] { + font-size: 2.2rem !important; +} +[placeholder='Heading 2'] { + font-size: 1.687rem !important; +} +[placeholder='Heading 3'] { + font-size: 1.3rem !important; +} +.notion-frame .notion-scroller.vertical.horizontal .notion-page-content, +.notion-overlay-container .notion-scroller.vertical .notion-page-content { + font-size: 15px !important; +} +.notion-frame + .notion-scroller.vertical.horizontal + .notion-page-content[style*='font-size: 14px'], +.notion-overlay-container + .notion-scroller.vertical + .notion-page-content[style*='font-size: 14px'] { + font-size: 13.5px !important; +} +.notion-code-block [placeholder=' '] { + font-size: 0.9em !important; +} diff --git a/repo/neutral/mod.json b/repo/neutral/mod.json new file mode 100644 index 0000000..dc17747 --- /dev/null +++ b/repo/neutral/mod.json @@ -0,0 +1,23 @@ +{ + "name": "neutral", + "id": "c4435543-4705-4d68-8cf7-d11c342f8089", + "version": "0.2.0", + "description": "smoother colours and text sizing, designed to be more pleasing to the eye.", + "preview": "neutral.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "arecsu", + "email": "alejandro9r@gmail.com", + "homepage": "https://github.com/Arecsu", + "avatar": "https://avatars.githubusercontent.com/u/12679098" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css", "app.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/neutral/neutral.png b/repo/neutral/neutral.png new file mode 100644 index 0000000..7e68fb7 Binary files /dev/null and b/repo/neutral/neutral.png differ diff --git a/repo/neutral/variables.css b/repo/neutral/variables.css new file mode 100644 index 0000000..0e7b76f --- /dev/null +++ b/repo/neutral/variables.css @@ -0,0 +1,141 @@ +/** + * notion-enhancer: neutral + * (c) 2020 Arecsu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --theme--accent_blue: #404040; + --theme--accent_blue-selection: #52525244; + --theme--accent_blue-hover: #6d6d6d; + --theme--accent_blue-active: #cacaca; + --theme--accent_red: #ce535f; + --theme--accent_red-button: #8c3d3dad; + + --theme--bg: #131313; + --theme--bg_secondary: #161616; + --theme--bg_card: #181818; + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: #232425; + --theme--scrollbar_thumb-hover: #373838; + + --theme--ui_shadow: rgba(15, 15, 15, 0.5); + --theme--ui_divider: rgba(78, 78, 78, 0.7); + --theme--ui_interactive-hover: rgb(29, 29, 29); + --theme--ui_interactive-active: rgba(29, 29, 29, 0.7); + --theme--ui_input: #1d1d1d; + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: #dadada; + --theme--icon_secondary: #dadadac0; + + --theme--text: #dadada; + --theme--text_secondary: #dadadac0; + --theme--text_gray: #858585; + --theme--text_brown: #484848; + --theme--text_orange: #ec9873; + --theme--text_yellow: #e2c06f; + --theme--text_green: #92b178; + --theme--text_blue: #719cca; + --theme--text_purple: #ab82bb; + --theme--text_pink: #d285aa; + --theme--text_red: #ce535f; + + --theme--highlight_gray: #585858; + --theme--highlight_brown: #333333; + --theme--highlight_orange: #9a5a3f; + --theme--highlight_yellow: #b58a46; + --theme--highlight_green: #657953; + --theme--highlight_blue: #355475; + --theme--highlight_purple: #775186; + --theme--highlight_pink: #8e4b63; + --theme--highlight_red: #8c3d3d; + + --theme--callout_gray: #585858; + --theme--callout_brown: #333333; + --theme--callout_orange: #9a5a3f; + --theme--callout_yellow: #b58a46; + --theme--callout_green: #657953; + --theme--callout_blue: #355475; + --theme--callout_purple: #775186; + --theme--callout_pink: #8e4b63; + --theme--callout_red: #8c3d3d; + + --theme--tag-text: var(--theme--text); + --theme--tag_default: var(--theme--highlight_gray); + --theme--tag_light_gray: #8A8A8A; + --theme--tag_gray: var(--theme--highlight_gray); + --theme--tag_brown: var(--theme--highlight_brown); + --theme--tag_orange: var(--theme--highlight_orange); + --theme--tag_yellow: var(--theme--highlight_yellow); + --theme--tag_green: var(--theme--highlight_green); + --theme--tag_blue: var(--theme--highlight_blue); + --theme--tag_purple: var(--theme--highlight_purple); + --theme--tag_pink: var(--theme--highlight_pink); + --theme--tag_red: var(--theme--highlight_red); + + --theme--board_light_gray: rgba(112, 112, 112, 0.175); + --theme--board_light_gray-text: #AAAAAA; + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_light_gray-card_text: var(--theme--tag_light_gray-text); + --theme--board_gray: rgba(88, 88, 88, 0.175); + --theme--board_gray-text: var(--theme--text_gray); + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_gray-card_text: var(--theme--tag_gray-text); + --theme--board_brown: rgb(51, 51, 51, 0.175); + --theme--board_brown-text: var(--theme--text_brown); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_brown-card_text: var(--theme--tag_brown-text); + --theme--board_orange: rgb(154, 90, 63, 0.175); + --theme--board_orange-text: var(--theme--text_orange); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_orange-card_text: var(--theme--tag_orange-text); + --theme--board_yellow: rgb(181, 138, 70, 0.175); + --theme--board_yellow-text: var(--theme--text_yellow); + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_yellow-card_text: var(--theme--tag_yellow-text); + --theme--board_green: rgb(101, 121, 83, 0.175); + --theme--board_green-text: var(--theme--text_green); + --theme--board_green-card: var(--theme--tag_green); + --theme--board_green-card_text: var(--theme--tag_green-text); + --theme--board_blue: rgb(53, 84, 117, 0.175); + --theme--board_blue-text: var(--theme--text_blue); + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_blue-card_text: var(--theme--tag_blue-text); + --theme--board_purple: rgb(119, 81, 134, 0.175); + --theme--board_purple-text: var(--theme--text_purple); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_purple-card_text: var(--theme--tag_purple-text); + --theme--board_pink: rgb(142, 75, 99, 0.175); + --theme--board_pink-text: var(--theme--text_pink); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_pink-card_text: var(--theme--tag_pink-text); + --theme--board_red: rgb(140, 61, 61, 0.175); + --theme--board_red-text: var(--theme--text_red); + --theme--board_red-card: var(--theme--tag_red); + --theme--board_red-card_text: var(--theme--tag_red-text); + + --theme--code_inline: #333333; + --theme--code_inline-text: var(--theme--text); + + --theme--code: #0e0e0e; + --theme--code_plain: var(--theme--text); + --theme--code_function: var(--theme--text_blue); + --theme--code_keyword: var(--theme--text_pink); + --theme--code_tag: var(--theme--text_pink); + --theme--code_operator: var(--theme--text_yellow); + --theme--code_important: var(--theme--text_yellow); + --theme--code_property: var(--theme--text_pink); + --theme--code_builtin: var(--theme--text_yellow); + --theme--code_attr-name: var(--theme--text_yellow); + --theme--code_comment: var(--theme--text_gray); + --theme--code_punctuation: var(--theme--text_gray); + --theme--code_doctype: var(--theme--text_gray); + --theme--code_number: var(--theme--text_purple); + --theme--code_string: var(--theme--text_orange); + --theme--code_attr-value: var(--theme--text_orange); +} diff --git a/repo/nord/mod.json b/repo/nord/mod.json new file mode 100644 index 0000000..67f266f --- /dev/null +++ b/repo/nord/mod.json @@ -0,0 +1,28 @@ +{ + "name": "nord", + "id": "d64ad391-1494-4112-80ae-0a3b6f4b0c3f", + "version": "0.2.0", + "description": "an arctic, north-bluish color palette.", + "preview": "nord.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "Artic Ice Studio", + "email": "development@arcticicestudio.com", + "homepage": "https://www.nordtheme.com/", + "avatar": "https://avatars.githubusercontent.com/u/7836623" + }, + { + "name": "MANNNNEN", + "homepage": "https://github.com/MANNNNEN", + "avatar": "https://avatars.githubusercontent.com/u/35939149" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/nord/nord.png b/repo/nord/nord.png new file mode 100644 index 0000000..008a6ca Binary files /dev/null and b/repo/nord/nord.png differ diff --git a/repo/nord/variables.css b/repo/nord/variables.css new file mode 100644 index 0000000..7aaa8da --- /dev/null +++ b/repo/nord/variables.css @@ -0,0 +1,160 @@ +/** + * notion-enhancer: dracula + * (c) 2016 Artic Ice Studio + * (c) 2020 MANNNNEN + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --nord--dark1: #2e3440; + --nord--dark2: #3b4252; + --nord--dark3: #434c5e; + --nord--dark4: #4c566a; + --nord--light1: #d8dee9; + --nord--light2: #e5e9f0; + --nord--light3: #eceff4; + --nord--frost1: #8fbcbb; + --nord--frost2: #88c0d0; + --nord--frost3: #81a1c1; + --nord--frost4: #5e81ac; + --nord--red: #bf616a; + --nord--orange: #d08770; + --nord--yellow: #ebcb8b; + --nord--green: #a3be8c; + --nord--purple: #b48ead; + + --theme--accent_blue: var(--nord--frost2); + --theme--accent_blue-selection: rgb(136 192 208 / 50%); + --theme--accent_blue-hover: var(--nord--frost1); + --theme--accent_blue-active: var(--nord--frost2); + --theme--accent_red: var(--nord--red); + --theme--accent_red-button: rgba(235, 87, 87, 0.2); + + --theme--bg: var(--nord--dark1); + --theme--bg_secondary: var(--nord--dark2); + --theme--bg_card: var(--nord--dark2); + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: var(--nord--dark3); + --theme--scrollbar_thumb-hover: var(--nord--dark4); + + --theme--ui_divider: rgba(255, 255, 255, 0.1); + --theme--ui_interactive-hover: var(--nord--dark4); + --theme--ui_interactive-active: #4c566ade; + --theme--ui_toggle-off: var(--nord--dark4); + --theme--ui_toggle-feature: var(--nord--light1); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: var(--nord--light1); + --theme--icon_secondary: var(--nord--light1); + + --theme--text: var(--nord--light1); + --theme--text_secondary: var(--nord--light1); + + --theme--text_gray: rgba(151, 154, 155, 0.95); + --theme--text_brown: rgb(147, 114, 100); + --theme--text_orange: var(--nord--orange); + --theme--text_yellow: var(--nord--yellow); + --theme--text_green: var(--nord--green); + --theme--text_blue: var(--nord--frost3); + --theme--text_purple: var(--nord--purple); + --theme--text_pink: rgb(193 106 153); + --theme--text_red: var(--nord--red); + + --theme--highlight_gray: rgb(69, 75, 78); + --theme--highlight_brown: rgb(67, 64, 64); + --theme--highlight_orange: var(--nord--orange); + --theme--highlight_yellow: var(--nord--yellow); + --theme--highlight_yellow-text: var(--nord--dark1); + --theme--highlight_green: var(--nord--green); + --theme--highlight_blue: var(--nord--frost3); + --theme--highlight_purple: var(--nord--purple); + --theme--highlight_pink: rgb(193 106 153); + --theme--highlight_red: var(--nord--red); + + --theme--callout_gray: rgb(69, 75, 78); + --theme--callout_brown: rgb(67, 64, 64); + --theme--callout_orange: var(--nord--orange); + --theme--callout_yellow: var(--nord--yellow); + --theme--callout_yellow-text: var(--nord--dark1); + --theme--callout_green: var(--nord--green); + --theme--callout_blue: var(--nord--frost3); + --theme--callout_purple: var(--nord--purple); + --theme--callout_pink: rgb(193 106 153); + --theme--callout_red: var(--nord--red); + + --theme--tag_default: rgba(151, 154, 155, 0.5); + --theme--tag_light_gray: rgba(182, 184, 185, 0.5); + --theme--tag_gray: rgba(151, 154, 155, 0.5); + --theme--tag_brown: rgba(147, 114, 100, 0.5); + --theme--tag_orange: rgba(255, 163, 68, 0.5); + --theme--tag_yellow: rgba(255, 220, 73, 0.5); + --theme--tag_green: rgba(77, 171, 154, 0.5); + --theme--tag_blue: rgba(82, 156, 202, 0.5); + --theme--tag_purple: rgba(154, 109, 215, 0.5); + --theme--tag_pink: rgba(226, 85, 161, 0.5); + --theme--tag_red: rgba(255, 115, 105, 0.5); + + --theme--board_light_gray: rgba(69, 75, 78, 0.3); + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_light_gray-card_text: var(--theme--tag_light_gray-text); + --theme--board_light_gray-text: rgba(161, 162, 163, 0.95); + --theme--board_gray: rgba(69, 75, 78, 0.3); + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_gray-card_text: var(--theme--tag_gray-text); + --theme--board_gray-text: var(--theme--text_gray); + --theme--board_brown: rgba(67, 64, 64, 0.3); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_brown-card_text: var(--theme--tag_brown-text); + --theme--board_brown-text: var(--theme--text_brown); + --theme--board_orange: rgba(89, 74, 58, 0.3); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_orange-card_text: var(--theme--tag_orange-text); + --theme--board_orange-text: var(--theme--text_orange); + --theme--board_yellow: rgba(89, 86, 59, 0.3); + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_yellow-card_text: var(--theme--tag_yellow-text); + --theme--board_yellow-text: var(--theme--text_yellow); + --theme--board_green: rgba(53, 76, 75, 0.3); + --theme--board_green-card: var(--theme--tag_green); + --theme--board_green-card_text: var(--theme--tag_green-text); + --theme--board_green-text: var(--theme--text_green); + --theme--board_blue: rgba(54, 73, 84, 0.3); + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_blue-card_text: var(--theme--tag_blue-text); + --theme--board_blue-text: var(--theme--text_blue); + --theme--board_purple: rgba(68, 63, 87, 0.3); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_purple-card_text: var(--theme--tag_purple-text); + --theme--board_purple-text: var(--theme--text_purple); + --theme--board_pink: rgba(83, 59, 76, 0.3); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_pink-card_text: var(--theme--tag_pink-text); + --theme--board_pink-text: var(--theme--text_pink); + --theme--board_red: rgba(89, 65, 65, 0.3); + --theme--board_red-card: var(--theme--tag_red); + --theme--board_red-card_text: var(--theme--tag_red-text); + --theme--board_red-text: var(--theme--text_red); + + --theme--code_inline: rgba(135, 131, 120, 0.15); + --theme--code_inline-text: var(--nord--red); + + --theme--code: var(--theme--bg_card); + --theme--code_function: var(--theme--text_blue); + --theme--code_keyword: var(--theme--text_pink); + --theme--code_tag: var(--theme--text_pink); + --theme--code_operator: var(--theme--text_yellow); + --theme--code_important: var(--theme--text_yellow); + --theme--code_property: var(--theme--text_pink); + --theme--code_builtin: var(--theme--text_yellow); + --theme--code_attr-name: var(--theme--text_yellow); + --theme--code_comment: var(--theme--text_gray); + --theme--code_punctuation: var(--theme--text_gray); + --theme--code_doctype: var(--theme--text_gray); + --theme--code_number: var(--theme--text_purple); + --theme--code_string: var(--theme--text_orange); + --theme--code_attr-value: var(--theme--text_orange); +} diff --git a/repo/outliner/client.css b/repo/outliner/client.css new file mode 100644 index 0000000..a37d938 --- /dev/null +++ b/repo/outliner/client.css @@ -0,0 +1,47 @@ +/** + * notion-enhancer: outliner + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +#outliner--notice { + color: var(--theme--text_secondary); + font-size: 14px; + margin-top: 0; + margin-bottom: 1rem; +} + +.outliner--header { + position: relative; + margin: 0 -1rem; + padding: 0 1rem; + display: block; + font-size: 14px; + line-height: 2.2; + white-space: nowrap; + overflow: hidden; + user-select: none; + text-overflow: ellipsis; + text-decoration: none; + text-indent: var(--outliner--indent); + color: inherit; + cursor: pointer !important; + transition: background 20ms ease-in; +} +.outliner--header:hover { + background: var(--theme--ui_interactive-hover); +} + +.outliner--header:empty::after { + color: var(--theme--text_secondary); + content: attr(placeholder); +} + +/* indentation lines */ +.outliner--header:not([style='--outliner--indent:0px;'])::before { + content: ''; + height: 100%; + position: absolute; + left: calc((1rem + var(--outliner--indent)) - 11px); +} diff --git a/repo/outliner/client.mjs b/repo/outliner/client.mjs new file mode 100644 index 0000000..73942fd --- /dev/null +++ b/repo/outliner/client.mjs @@ -0,0 +1,90 @@ +/** + * notion-enhancer: outliner + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ web, components }, db) { + const dbNoticeText = 'Open a page to see its table of contents.', + pageNoticeText = 'Click on a heading to jump to it.', + $notice = web.html`

${dbNoticeText}

`; + + const $headingList = web.html`
`; + + let viewFocused = false, + $page; + await components.addPanelView({ + id: '87e077cc-5402-451c-ac70-27cc4ae65546', + icon: web.html` + + + + + + + `, + title: 'Outliner', + $content: web.render(web.html`
`, $notice, $headingList), + onFocus: () => { + viewFocused = true; + $page = document.getElementsByClassName('notion-page-content')[0]; + updateHeadings(); + }, + onBlur: () => { + viewFocused = false; + }, + }); + await web.whenReady(); + + function updateHeadings() { + if (!$page) return; + $notice.innerText = pageNoticeText; + $headingList.style.display = ''; + const $headerBlocks = $page.querySelectorAll('[class^="notion-"][class*="header-block"]'), + $fragment = web.html`
`; + let depth = 0, + indent = 0; + for (const $header of $headerBlocks) { + const id = $header.dataset.blockId.replace(/-/g, ''), + placeholder = $header.querySelector('[placeholder]').getAttribute('placeholder'), + headerDepth = +[...placeholder].reverse()[0]; + if (depth && depth < headerDepth) { + indent += 18; + } else if (depth > headerDepth) { + indent = Math.max(indent - 18, 0); + } + depth = headerDepth; + const $outlineHeader = web.render( + web.html``, + $header.innerText + ); + $outlineHeader.addEventListener('click', (event) => { + location.hash = ''; + }); + web.render($fragment, $outlineHeader); + } + if ($fragment.innerHTML !== $headingList.innerHTML) { + web.render(web.empty($headingList), ...$fragment.children); + } + } + const pageObserver = () => { + if (!viewFocused) return; + if (document.contains($page)) { + updateHeadings(); + } else { + $page = document.querySelector('.notion-page-content'); + if (!$page) { + $notice.innerText = dbNoticeText; + $headingList.style.display = 'none'; + } else updateHeadings(); + } + }; + web.addDocumentObserver(pageObserver, [ + '.notion-page-content', + '.notion-collection_view_page-block', + ]); + pageObserver(); +} diff --git a/repo/outliner/mod.json b/repo/outliner/mod.json new file mode 100644 index 0000000..2ebbb48 --- /dev/null +++ b/repo/outliner/mod.json @@ -0,0 +1,23 @@ +{ + "name": "outliner", + "id": "87e077cc-5402-451c-ac70-27cc4ae65546", + "version": "0.4.0", + "description": "adds a table of contents to the side panel.", + "preview": "outliner.png", + "tags": ["extension", "panel"], + "authors": [ + { + "name": "CloudHill", + "email": "rh.cloudhill@gmail.com", + "homepage": "https://github.com/CloudHill", + "avatar": "https://avatars.githubusercontent.com/u/54142180" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [] +} diff --git a/repo/outliner/outliner.png b/repo/outliner/outliner.png new file mode 100644 index 0000000..925ee6c Binary files /dev/null and b/repo/outliner/outliner.png differ diff --git a/repo/pastel-dark/app.css b/repo/pastel-dark/app.css new file mode 100644 index 0000000..9664dd3 --- /dev/null +++ b/repo/pastel-dark/app.css @@ -0,0 +1,72 @@ +/** + * notion-enhancer: pastel dark + * (c) 2020 u/zenith_illinois + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-dark-theme img[src*='/images/onboarding/use-case-note.png'], +.notion-dark-theme img[src*='/images/onboarding/team-features-illustration.png'] { + filter: invert(1) !important; +} +.notion-dark-theme img[src*='/images/onboarding/checked.svg'] { + filter: hue-rotate(45deg) !important; +} +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 100%; width: 90px; height: 90px;'], +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 3px; width: 56.832px; height: 56.832px; transition: opacity 100ms ease-out 0s;'] { + transition: filter 0.4s ease !important; +} +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 100%; width: 90px; height: 90px;']:hover, +.notion-dark-theme + img[style*='display: block; object-fit: cover; border-radius: 3px; width: 56.832px; height: 56.832px; transition: opacity 100ms ease-out 0s;']:hover { + filter: brightness(1.2); +} + +.notion-dark-theme .notion-token-remove-button[role*='button'][tabindex*='0']:hover, +.notion-dark-theme .notion-record-icon { + background: transparent !important; +} + +.notion-dark-theme .notion-focusable:focus-within, +.notion-dark-theme .notion-to_do-block > div > div > div[style*='background:'], +.notion-dark-theme div[role='button'], +[style*='height: 4px;'] > .notion-selectable.notion-collection_view_page-block > *, +.notion-dark-theme .notion-calendar-view-day[style*='background: rgb(235, 87, 87);'], +.DayPicker-Day--today, +.notion-dark-theme + .DayPicker:not(.DayPicker--interactionDisabled) + .DayPicker-Day--outside:hover, +.notion-dark-theme + .DayPicker:not(.DayPicker--interactionDisabled) + .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--value) + .DayPicker-Day.DayPicker-Day--start.DayPicker-Day--selected, +.notion-dark-theme .DayPicker-Day.DayPicker-Day--range.DayPicker-Day--start, +.notion-dark-theme .DayPicker-Day.DayPicker-Day--range.DayPicker-Day--end { + transition: color 0.4s ease, background 0.4s ease, box-shadow 0.4s ease !important; +} + +.notion-dark-theme :not(.notion-code-block) > * > [style*='background: rgb(63, 68, 71);'], +.notion-dark-theme + .notion-code-block + [style*='background: rgb(63, 68, 71);'] + .notion-code-block, +.notion-dark-theme + [style*='background: rgb(80, 85, 88);'][style*='color: rgba(255, 255, 255, 0.7)'], +.notion-dark-theme + [style*='background: rgb(80, 85, 88);'][style*='width: 18px;'][style*='height: 18px;'], +.notion-dark-theme + [style*='box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, rgba(15, 15, 15, 0.2) 0px 5px 10px, rgba(15, 15, 15, 0.4) 0px 15px 40px;'], +.notion-dark-theme [style*='background: rgba(151, 154, 155, 0.5);'], +.notion-dark-theme [style*='background: rgba(147, 114, 100, 0.5)'], +.notion-dark-theme [style*='background: rgba(255, 163, 68, 0.5)'], +.notion-dark-theme [style*='background: rgba(255, 220, 73, 0.5)'], +.notion-dark-theme [style*='background: rgba(77, 171, 154, 0.5)'], +.notion-dark-theme [style*='background: rgba(82, 156, 202, 0.5)'], +.notion-dark-theme [style*='background: rgba(154, 109, 215, 0.5)'], +.notion-dark-theme [style*='background: rgba(226, 85, 161, 0.5)'], +.notion-dark-theme [style*='background: rgba(255, 115, 105, 0.5)'] { + box-shadow: 0 2px 4px rgb(0 0 0 / 66%) !important; +} diff --git a/repo/pastel-dark/mod.json b/repo/pastel-dark/mod.json new file mode 100644 index 0000000..ba6058b --- /dev/null +++ b/repo/pastel-dark/mod.json @@ -0,0 +1,22 @@ +{ + "name": "pastel dark", + "id": "ed48c585-4a0d-4756-a3e6-9ae662732dac", + "version": "0.2.0", + "description": "a smooth-transition true dark theme with a hint of pastel.", + "preview": "pastel-dark.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "zenith_illinois", + "homepage": "https://www.reddit.com/user/zenith_illinois/", + "avatar": "https://www.redditstatic.com/avatars/defaults/v2/avatar_default_5.png" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css", "app.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/pastel-dark/pastel-dark.png b/repo/pastel-dark/pastel-dark.png new file mode 100644 index 0000000..e6dc5a4 Binary files /dev/null and b/repo/pastel-dark/pastel-dark.png differ diff --git a/repo/pastel-dark/variables.css b/repo/pastel-dark/variables.css new file mode 100644 index 0000000..81f697a --- /dev/null +++ b/repo/pastel-dark/variables.css @@ -0,0 +1,147 @@ +/** + * notion-enhancer: pastel dark + * (c) 2020 u/zenith_illinois + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --theme--accent_blue: #b887f7; + --theme--accent_blue-selection: rgba(184, 135, 247, 0.3); + --theme--accent_blue-hover: #08d7c2; + --theme--accent_blue-active: #b887f7; + --theme--accent_red: #08d7c2; + --theme--accent_red-button: #08d7c226; + + --theme--bg: #0b0b0b; + --theme--bg_secondary: #0f0f0f; + --theme--bg_card: #141414; + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: #141414; + --theme--scrollbar_thumb-hover: #1b1b1b; + + --theme--ui_divider: rgba(255, 255, 255, 0.1); + --theme--ui_interactive-hover: #15161c; + --theme--ui_interactive-active: #18191c; + --theme--ui_toggle-off: #b1aeab; + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: #ffffff; + --theme--icon_secondary: #909090; + + --theme--text: #ffffff; + --theme--text_secondary: #909090; + --theme--text_gray: #b1aeab; + --theme--text_brown: #d8b6a6; + --theme--text_orange: #fde3c0; + --theme--text_yellow: #fcde93; + --theme--text_green: #b3f5c8; + --theme--text_blue: #bfe0fd; + --theme--text_purple: #dac7fa; + --theme--text_pink: #f7b8dc; + --theme--text_red: #f8acb4; + + --theme--highlight_gray: #b1aeab; + --theme--highlight_gray-text: rgb(55, 53, 47); + --theme--highlight_brown: #d8b6a6; + --theme--highlight_brown-text: rgb(55, 53, 47); + --theme--highlight_orange: #fde3c0; + --theme--highlight_orange-text: rgb(55, 53, 47); + --theme--highlight_yellow: #fcde93; + --theme--highlight_yellow-text: rgb(55, 53, 47); + --theme--highlight_green: #b3f5c8; + --theme--highlight_green-text: rgb(55, 53, 47); + --theme--highlight_blue: #bfe0fd; + --theme--highlight_blue-text: rgb(55, 53, 47); + --theme--highlight_purple: #dac7fa; + --theme--highlight_purple-text: rgb(55, 53, 47); + --theme--highlight_pink: #f7b8dc; + --theme--highlight_pink-text: rgb(55, 53, 47); + --theme--highlight_red: #f8acb4; + --theme--highlight_red-text: rgb(55, 53, 47); + + --theme--callout_gray: #c2c1c089; + --theme--callout_brown: #dacec992; + --theme--callout_orange: #fff0dc9f; + --theme--callout_yellow: #ffe6a6ad; + --theme--callout_green: #c8fdd9a3; + --theme--callout_blue: #d1e9ffa3; + --theme--callout_purple: #e3d3ffa8; + --theme--callout_pink: #fdcce8b1; + --theme--callout_red: #ffc8ce9e; + + --theme--tag_light_gray: #C8C6C4; + --theme--tag_light_gray-text: rgb(55, 53, 47); + --theme--tag_gray: #b1aeab; + --theme--tag_gray-text: rgb(55, 53, 47); + --theme--tag_brown: #d8b6a6; + --theme--tag_brown-text: rgb(55, 53, 47); + --theme--tag_orange: #fde3c0; + --theme--tag_orange-text: rgb(55, 53, 47); + --theme--tag_yellow: #fcde93; + --theme--tag_yellow-text: rgb(55, 53, 47); + --theme--tag_green: #b3f5c8; + --theme--tag_green-text: rgb(55, 53, 47); + --theme--tag_blue: #bfe0fd; + --theme--tag_blue-text: rgb(55, 53, 47); + --theme--tag_purple: #dac7fa; + --theme--tag_purple-text: rgb(55, 53, 47); + --theme--tag_pink: #f7b8dc; + --theme--tag_pink-text: rgb(55, 53, 47); + --theme--tag_red: #f8acb4; + --theme--tag_red-text: rgb(55, 53, 47); + + --theme--board_light_gray: #D4D4D389; + --theme--board_light_gray-text: #C8C6C4; + --theme--board_light_gray-card: rgb(255, 255, 255, 0.2); + --theme--board_gray: #c2c1c089; + --theme--board_gray-text: #b1aeab; + --theme--board_gray-card: rgb(255, 255, 255, 0.2); + --theme--board_brown: #dacec992; + --theme--board_brown-text: #d8b6a6; + --theme--board_brown-card: rgb(255, 255, 255, 0.2); + --theme--board_orange: #fff0dc9f; + --theme--board_orange-text: #fde3c0; + --theme--board_orange-card: rgb(255, 255, 255, 0.2); + --theme--board_yellow: #ffe6a6ad; + --theme--board_yellow-text: #fcde93; + --theme--board_yellow-card: rgb(255, 255, 255, 0.2); + --theme--board_green: #c8fdd9a3; + --theme--board_green-text: #b3f5c8; + --theme--board_green-card: rgb(255, 255, 255, 0.2); + --theme--board_blue: #d1e9ffa3; + --theme--board_blue-text: #bfe0fd; + --theme--board_blue-card: rgb(255, 255, 255, 0.2); + --theme--board_purple: #e3d3ffa8; + --theme--board_purple-text: #dac7fa; + --theme--board_purple-card: rgb(255, 255, 255, 0.2); + --theme--board_pink: #fdcce8b1; + --theme--board_pink-text: #f7b8dc; + --theme--board_pink-card: rgb(255, 255, 255, 0.2); + --theme--board_red: #ffc8ce9e; + --theme--board_red-text: #f8acb4; + --theme--board_red-card: rgb(255, 255, 255, 0.2); + + --theme--code_inline: rgb(8, 8, 8); + --theme--code_inline-text: #b3f5c8; + + --theme--code: #0f0f0f; + --theme--code_plain: var(--theme--text); + --theme--code_function: var(--theme--text_blue); + --theme--code_keyword: var(--theme--text_pink); + --theme--code_tag: var(--theme--text_pink); + --theme--code_operator: var(--theme--text_yellow); + --theme--code_important: var(--theme--text_yellow); + --theme--code_property: var(--theme--text_pink); + --theme--code_builtin: var(--theme--text_yellow); + --theme--code_attr-name: var(--theme--text_yellow); + --theme--code_comment: var(--theme--text_gray); + --theme--code_punctuation: var(--theme--text_gray); + --theme--code_doctype: var(--theme--text_gray); + --theme--code_number: var(--theme--text_purple); + --theme--code_string: var(--theme--text_orange); + --theme--code_attr-value: var(--theme--text_orange); +} diff --git a/repo/pinky-boom/mod.json b/repo/pinky-boom/mod.json new file mode 100644 index 0000000..f6e1f74 --- /dev/null +++ b/repo/pinky-boom/mod.json @@ -0,0 +1,22 @@ +{ + "name": "pinky boom", + "id": "b5f43232-391b-415a-9099-4334dc6c7b55", + "version": "0.2.0", + "description": "pinkify your life.", + "preview": "pinky-boom.png", + "tags": ["theme", "light"], + "authors": [ + { + "name": "mugiwarafx", + "homepage": "https://github.com/mugiwarafx", + "avatar": "https://avatars.githubusercontent.com/u/58401248" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/pinky-boom/pinky-boom.png b/repo/pinky-boom/pinky-boom.png new file mode 100644 index 0000000..04473f0 Binary files /dev/null and b/repo/pinky-boom/pinky-boom.png differ diff --git a/repo/pinky-boom/variables.css b/repo/pinky-boom/variables.css new file mode 100644 index 0000000..a5eefdc --- /dev/null +++ b/repo/pinky-boom/variables.css @@ -0,0 +1,151 @@ +/** + * notion-enhancer: pinky boom + * (c) 2020 mugiwarafx + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.light { + --pinky_boom--brown: #a52a2a80; + --pinky_boom--orange: #ffa60080; + --pinky_boom--yellow: #ffff0080; + --pinky_boom--green: #00ff0080; + --pinky_boom--blue: #00ffff80; + --pinky_boom--purple: #9b00ff80; + --pinky_boom--pink: #ff149180; + --pinky_boom--red: #ff000080; + + --theme--accent_blue: deeppink; + --theme--accent_blue-selection: rgba(255, 20, 145, 0.2); + --theme--accent_blue-hover: rgb(255, 57, 163); + --theme--accent_blue-active: rgb(255, 48, 158); + --theme--accent_red: deeppink; + --theme--accent_red-button: rgba(255, 20, 145, 0.2); + + --theme--bg: #fdf0f4; + --theme--bg_secondary: #fce4ec; + --theme--bg_card: #ffd5e4; + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: #f8bbd0; + --theme--scrollbar_thumb-hover: #f48fb1; + + --theme--ui_shadow: #ff89c842; + --theme--ui_divider: #ffbbdf; + --theme--ui_interactive-hover: #fcb9d0; + --theme--ui_interactive-active: #ffccdc; + --theme--ui_toggle-off: #ffc9e6; + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: #56002e; + --theme--icon_secondary: rgba(255, 20, 145, 0.75); + + --theme--text: #56002e; + --theme--text_secondary: rgba(255, 20, 145, 0.75); + + --theme--text_gray: rgb(155, 154, 151); + --theme--text_brown: rgb(100, 71, 58); + --theme--text_orange: rgb(217, 115, 13); + --theme--text_yellow: rgb(223, 171, 1); + --theme--text_green: rgb(15, 123, 108); + --theme--text_blue: rgb(11, 110, 153); + --theme--text_purple: var(--pinky_boom--purple); + --theme--text_pink: var(--pinky_boom--deep-pink); + --theme--text_red: rgb(224, 62, 62); + + --theme--highlight_gray: rgba(128, 128, 128, 0.25); + --theme--highlight_brown: var(--pinky_boom--brown); + --theme--highlight_orange: var(--pinky_boom--orange); + --theme--highlight_orange-text: black; + --theme--highlight_yellow: var(--pinky_boom--yellow); + --theme--highlight_yellow-text: black; + --theme--highlight_green: var(--pinky_boom--green); + --theme--highlight_green-text: black; + --theme--highlight_blue: var(--pinky_boom--blue); + --theme--highlight_blue-text: black; + --theme--highlight_purple: var(--pinky_boom--purple); + --theme--highlight_purple-text: white; + --theme--highlight_pink: var(--pinky_boom--pink); + --theme--highlight_pink-text: white; + --theme--highlight_red: var(--pinky_boom--red); + + --theme--callout_gray: rgba(128, 128, 128, 0.25); + --theme--callout_gray-text: black; + --theme--callout_brown: var(--pinky_boom--brown); + --theme--callout_brown-text: white; + --theme--callout_orange: var(--pinky_boom--orange); + --theme--callout_orange-text: black; + --theme--callout_yellow: var(--pinky_boom--yellow); + --theme--callout_yellow-text: black; + --theme--callout_green: var(--pinky_boom--green); + --theme--callout_green-text: black; + --theme--callout_blue: var(--pinky_boom--blue); + --theme--callout_blue-text: black; + --theme--callout_purple: var(--pinky_boom--purple); + --theme--callout_purple-text: white; + --theme--callout_pink: var(--pinky_boom--pink); + --theme--callout_pink-text: white; + --theme--callout_red: var(--pinky_boom--red); + --theme--callout_red-text: white; + + --theme--board_light_gray: rgba(166, 166, 166, 0.5); + --theme--board_light_gray-text: white; + --theme--board_light_gray-card: rgba(166, 166, 166, 0.25); + --theme--board_gray: rgba(128, 128, 128, 0.5); + --theme--board_gray-text: white; + --theme--board_gray-card: rgba(128, 128, 128, 0.25); + --theme--board_brown: var(--pinky_boom--brown); + --theme--board_brown-text: white; + --theme--board_brown-card: var(--pinky_boom--brown); + --theme--board_orange: var(--pinky_boom--orange); + --theme--board_orange-text: white; + --theme--board_orange-card: var(--pinky_boom--orange); + --theme--board_yellow: var(--pinky_boom--yellow); + --theme--board_yellow-text: white; + --theme--board_yellow-card: var(--pinky_boom--yellow); + --theme--board_green: var(--pinky_boom--green); + --theme--board_green-text: white; + --theme--board_green-card: var(--pinky_boom--green); + --theme--board_blue: var(--pinky_boom--blue); + --theme--board_blue-text: white; + --theme--board_blue-card: var(--pinky_boom--blue); + --theme--board_purple: var(--pinky_boom--purple); + --theme--board_purple-text: white; + --theme--board_purple-card: var(--pinky_boom--purple); + --theme--board_pink: var(--pinky_boom--pink); + --theme--board_pink-text: white; + --theme--board_pink-card: var(--pinky_boom--pink); + --theme--board_red: var(--pinky_boom--red); + --theme--board_red-text: white; + --theme--board_red-card: var(--pinky_boom--red); + + --theme--tag_default: #ffc9e6; + --theme--tag_light_gray: rgba(166, 166, 166, 0.25); + --theme--tag_light_gray-text: black; + --theme--tag_gray: rgba(128, 128, 128, 0.25); + --theme--tag_gray-text: black; + --theme--tag_brown: var(--pinky_boom--brown); + --theme--tag_brown-text: white; + --theme--tag_orange: var(--pinky_boom--orange); + --theme--tag_orange-text: black; + --theme--tag_yellow: var(--pinky_boom--yellow); + --theme--tag_yellow-text: black; + --theme--tag_green: var(--pinky_boom--green); + --theme--tag_green-text: black; + --theme--tag_blue: var(--pinky_boom--blue); + --theme--tag_blue-text: black; + --theme--tag_purple: var(--pinky_boom--purple); + --theme--tag_purple-text: white; + --theme--tag_pink: var(--pinky_boom--pink); + --theme--tag_pink-text: white; + --theme--tag_red: var(--pinky_boom--red); + --theme--tag_red-text: white; + + --theme--code_inline: var(--theme--code); + --theme--code_inline-text: var(--theme--text); + + --theme--code: var(--theme--bg_secondary); + --theme--code_punctuation: #ff46a8; +} diff --git a/repo/playful-purple/mod.json b/repo/playful-purple/mod.json new file mode 100644 index 0000000..ce4c4af --- /dev/null +++ b/repo/playful-purple/mod.json @@ -0,0 +1,27 @@ +{ + "name": "playful purple", + "id": "ae7862a9-5dbe-4f2c-9931-940f3ba5015d", + "version": "0.2.0", + "description": "a purple-shaded theme with bright highlights.", + "preview": "playful-purple.png", + "tags": ["theme", "dark"], + "authors": [ + { + "name": "Lizishan", + "homepage": "https://www.reddit.com/user/Lizishan", + "avatar": "https://styles.redditmedia.com/t5_110nz4/styles/profileIcon_h1m3b16exoi51.jpg" + }, + { + "name": "LVL100ShrekCultist", + "homepage": "https://www.reddit.com/user/LVL100ShrekCultist/", + "avatar": "https://styles.redditmedia.com/t5_2js69j/styles/profileIcon_jvnzmo30fyq41.jpg" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css"], + "menu": ["variables.css"] + }, + "js": {}, + "options": [] +} diff --git a/repo/playful-purple/playful-purple.png b/repo/playful-purple/playful-purple.png new file mode 100644 index 0000000..43930cf Binary files /dev/null and b/repo/playful-purple/playful-purple.png differ diff --git a/repo/playful-purple/variables.css b/repo/playful-purple/variables.css new file mode 100644 index 0000000..cb0d704 --- /dev/null +++ b/repo/playful-purple/variables.css @@ -0,0 +1,152 @@ +/** + * notion-enhancer: playful dark + * (c) 2020 Lizishan + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root.dark { + --theme--accent_blue: rgb(117, 65, 200); + --theme--accent_blue-selection: #9500ff1e; + --theme--accent_blue-hover: rgb(110, 48, 211); + --theme--accent_blue-active: rgb(117, 65, 200); + --theme--accent_red: rgb(150, 84, 226); + --theme--accent_red-button: rgba(150, 84, 226, 0.5); + + --theme--bg: #1e1c26; + --theme--bg_secondary: #24222c; + --theme--bg_card: #19181f; + + --theme--scrollbar_track: transparent; + --theme--scrollbar_thumb: #221f29; + --theme--scrollbar_thumb-hover: #312d3c; + + --theme--ui_divider: rgba(148, 148, 184, 0.5); + --theme--ui_interactive-hover: #282632; + --theme--ui_interactive-active: #2b293a; + --theme--ui_toggle-off: rgb(20, 0, 51); + --theme--ui_corner_action: var(--theme--bg_card); + --theme--ui_corner_action-hover: var(--theme--ui_interactive-hover); + --theme--ui_corner_action-active: var(--theme--ui_interactive-active); + + --theme--icon: #978ec7; + --theme--icon_secondary: #978ec7; + + --theme--text: rgb(239, 235, 255); + --theme--text_secondary: #978ec7; + + --theme--text_brown: rgb(177, 144, 131); + --theme--text_green: rgb(66, 222, 137); + --theme--text_blue: rgb(0, 157, 255); + --theme--text_purple: rgb(162, 94, 255); + --theme--text_red: rgb(240, 52, 38); + + --theme--highlight_gray: rgb(234, 234, 234); + --theme--highlight_gray-text: rgb(17, 17, 17); + --theme--highlight_brown: rgb(206, 206, 206); + --theme--highlight_brown-text: rgb(85, 35, 1); + --theme--highlight_orange: rgb(254, 214, 155); + --theme--highlight_orange-text: rgb(199, 110, 0); + --theme--highlight_yellow: #fcffd8; + --theme--highlight_yellow-text: #ff8c22; + --theme--highlight_green: #d5fded; + --theme--highlight_green-text: #006a00; + --theme--highlight_blue: #e2f5ff; + --theme--highlight_blue-text: #00b2ff; + --theme--highlight_purple: #efe6ff; + --theme--highlight_purple-text: #8334ff; + --theme--highlight_pink: #ffe9f1; + --theme--highlight_pink-text: rgb(255, 0, 127); + --theme--highlight_red: rgb(251, 228, 228); + --theme--highlight_red-text: rgb(138, 0, 10); + + --theme--callout_gray: #e2e3e5; + --theme--callout_gray-text: #383d41; + --theme--callout_brown: rgb(130, 118, 111); + --theme--callout_brown-text: rgb(85, 35, 1); + --theme--callout_orange: rgb(254, 214, 155); + --theme--callout_orange-text: rgb(255, 140, 0); + --theme--callout_yellow: #fcffd8; + --theme--callout_yellow-text: #c76e00; + --theme--callout_green: #d4edda; + --theme--callout_green-text: #155724; + --theme--callout_blue: #cce5ff; + --theme--callout_blue-text: #004085; + --theme--callout_purple: rgb(199, 178, 230); + --theme--callout_purple-text: rgb(90, 49, 148); + --theme--callout_pink: rgb(255, 206, 228); + --theme--callout_pink-text: rgb(255, 0, 127); + --theme--callout_red: #f8d7da; + --theme--callout_red-text: #721c24; + + --theme--tag_default: rgb(234, 234, 234); + --theme--tag_default-text: rgb(17, 17, 17); + --theme--tag_light_gray: rgb(240, 240, 240); + --theme--tag_light_gray-text: rgb(88, 88, 88); + --theme--tag_gray: rgb(234, 234, 234); + --theme--tag_gray-text: rgb(17, 17, 17); + --theme--tag_brown: rgb(206, 206, 206); + --theme--tag_brown-text: rgb(85, 35, 1); + --theme--tag_orange: rgb(254, 214, 155); + --theme--tag_orange-text: rgb(199, 110, 0); + --theme--tag_yellow: #fcffd8; + --theme--tag_yellow-text: #ff8c22; + --theme--tag_green: #d5fded; + --theme--tag_green-text: #006a00; + --theme--tag_blue: #e2f5ff; + --theme--tag_blue-text: #00b2ff; + --theme--tag_purple: #efe6ff; + --theme--tag_purple-text: #8334ff; + --theme--tag_pink: #ffe9f1; + --theme--tag_pink-text: rgb(255, 0, 127); + --theme--tag_red: rgb(251, 228, 228); + --theme--tag_red-text: rgb(138, 0, 10); + + --theme--board_light_gray: #EBEBED; + --theme--board_light_gray-text: #74777A; + --theme--board_light_gray-card: var(--theme--tag_light_gray); + --theme--board_light_gray-card_text: var(--theme--tag_light_gray-text); + --theme--board_gray: #e2e3e5; + --theme--board_gray-text: #383d41; + --theme--board_gray-card: var(--theme--tag_gray); + --theme--board_gray-card_text: var(--theme--tag_gray-text); + --theme--board_brown: rgb(130, 118, 111); + --theme--board_brown-text: rgb(85, 35, 1); + --theme--board_brown-card: var(--theme--tag_brown); + --theme--board_brown-card_text: var(--theme--tag_brown-text); + --theme--board_orange: rgb(254, 214, 155); + --theme--board_orange-text: rgb(255, 140, 0); + --theme--board_orange-card: var(--theme--tag_orange); + --theme--board_orange-card_text: var(--theme--tag_orange-text); + --theme--board_yellow: #fcffd8; + --theme--board_yellow-text: #c76e00; + --theme--board_yellow-card: var(--theme--tag_yellow); + --theme--board_yellow-card_text: var(--theme--tag_yellow-text); + --theme--board_green: #d4edda; + --theme--board_green-text: #155724; + --theme--board_green-card: var(--theme--tag_green); + --theme--board_green-card_text: var(--theme--tag_green-text); + --theme--board_blue: #cce5ff; + --theme--board_blue-text: #004085; + --theme--board_blue-card: var(--theme--tag_blue); + --theme--board_blue-card_text: var(--theme--tag_blue-text); + --theme--board_purple: rgb(199, 178, 230); + --theme--board_purple-text: rgb(90, 49, 148); + --theme--board_purple-card: var(--theme--tag_purple); + --theme--board_purple-card_text: var(--theme--tag_purple-text); + --theme--board_pink: rgb(255, 206, 228); + --theme--board_pink-text: rgb(255, 0, 127); + --theme--board_pink-card: var(--theme--tag_pink); + --theme--board_pink-card_text: var(--theme--tag_pink-text); + --theme--board_red: #f8d7da; + --theme--board_red-text: #721c24; + --theme--board_red-card: var(--theme--tag_red); + --theme--board_red-card_text: var(--theme--tag_red-text); + + --theme--code_inline: rgb(179, 39, 39); + --theme--code_inline-text: #e0dfe2; + + --theme--code: var(--theme--bg_card); + --theme--code_function: rgb(179, 146, 240); + --theme--code_number: hsl(159, 69%, 39%); +} diff --git a/repo/quick-note/client.mjs b/repo/quick-note/client.mjs new file mode 100644 index 0000000..89a7d66 --- /dev/null +++ b/repo/quick-note/client.mjs @@ -0,0 +1,33 @@ +/** + * notion-enhancer: quick note + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web, components, notion }, db) { + const targetDbId = await db.get(['target_db']); + if (!targetDbId) return; + + const newQuickNote = async () => { + try { + const { collection_id } = await notion.get(targetDbId), + noteID = await notion.create( + { + recordValue: { + properties: { title: [[`quick note: ${new Date().toLocaleString()}`]] }, + }, + recordType: 'page', + }, + { parentID: collection_id, parentTable: 'collection' } + ); + location.assign(`https://www.notion.so/${noteID.replace(/-/g, '')}`); + } catch { + alert('quick note failed: target database id did not match any known databases'); + } + }; + + await components.addCornerAction(await components.feather('feather'), newQuickNote); + web.addHotkeyListener(await db.get(['hotkey']), newQuickNote); +} diff --git a/repo/quick-note/mod.json b/repo/quick-note/mod.json new file mode 100644 index 0000000..5166a3f --- /dev/null +++ b/repo/quick-note/mod.json @@ -0,0 +1,35 @@ +{ + "name": "quick note", + "id": "5d7c1677-6f6d-4fb5-8d6f-5067bcd0e24c", + "version": "0.1.0", + "description": "adds a hotkey & a button in the bottom right corner to jump to a new page in a notes database (target database id must be set).", + "preview": "quick-note.png", + "tags": ["integration", "shortcut"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": {}, + "js": { + "client": ["client.mjs"] + }, + "options": [ + { + "type": "text", + "key": "target_db", + "label": "target database id", + "tooltip": "**the uuid of the database in which pages should be created** (the bit after the '/' in the database url, e.g. edbafbd8bb7045cab1408aadaf4edf9d)", + "value": "" + }, + { + "type": "hotkey", + "key": "hotkey", + "label": "hotkey", + "value": "Ctrl+Alt+=" + } + ] +} diff --git a/repo/quick-note/quick-note.png b/repo/quick-note/quick-note.png new file mode 100644 index 0000000..faa3ad5 Binary files /dev/null and b/repo/quick-note/quick-note.png differ diff --git a/repo/registry.json b/repo/registry.json new file mode 100644 index 0000000..6093766 --- /dev/null +++ b/repo/registry.json @@ -0,0 +1,47 @@ +[ + "menu", + "theming", + "components", + + "tweaks", + "font-chooser", + + "integrated-titlebar", + "tray", + "tabs", + "always-on-top", + "view-scale", + + "outliner", + "scroll-to-top", + "indentation-lines", + "right-to-left", + "simpler-databases", + "emoji-sets", + "bypass-preview", + "topbar-icons", + "word-counter", + "code-line-numbers", + "calendar-scroll", + "collapsible-properties", + "weekly-view", + "truncated-titles", + "focus-mode", + "global-block-links", + + "icon-sets", + "quick-note", + + "material-ocean", + "cherry-cola", + "dark+", + "light+", + "dracula", + "pastel-dark", + "neutral", + "nord", + "gruvbox-dark", + "gruvbox-light", + "playful-purple", + "pinky-boom" +] diff --git a/repo/right-to-left/client.css b/repo/right-to-left/client.css new file mode 100644 index 0000000..3597fcc --- /dev/null +++ b/repo/right-to-left/client.css @@ -0,0 +1,26 @@ +/** + * notion-enhancer: right to left + * (c) 2021 obahareth (https://omar.engineer) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.notion-page-content + .notion-table_of_contents-block + > div + > div + > a + > div + > div[style*='margin-left: 24px'] { + margin-inline-start: 24px; +} + +.notion-page-content + .notion-table_of_contents-block + > div + > div + > a + > div + > div[style*='margin-left: 48px'] { + margin-inline-start: 48px; +} diff --git a/repo/right-to-left/client.mjs b/repo/right-to-left/client.mjs new file mode 100644 index 0000000..decba98 --- /dev/null +++ b/repo/right-to-left/client.mjs @@ -0,0 +1,50 @@ +/** + * notion-enhancer: right to left + * (c) 2021 obahareth (https://omar.engineer) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web }, db) { + const pageContentSelector = ` + .notion-page-content > + div[data-block-id]:not([dir]):not(.notion-column_list-block):not(.notion-collection_view_page-block), + [placeholder="Untitled"]:not([dir]), + .notion-column-block > div[data-block-id]:not([dir]), + .notion-collection_view-block:not([dir]), + .notion-table-view:not([dir]), + .notion-board-view:not([dir]), + .notion-gallery-view:not([dir])`, + listItemSelector = ` + div[placeholder="List"]:not([style*="text-align: start"]), + div[placeholder="To-do"]:not([style*="text-align: start"]), + div[placeholder="Toggle"]:not([style*="text-align: start"])`, + inlineEquationSelector = + '.notion-text-equation-token .katex-html:not([style*="direction: rtl;"])'; + + const autoAlignText = () => { + document + .querySelectorAll(pageContentSelector) + .forEach(($block) => $block.setAttribute('dir', 'auto')); + document.querySelectorAll(listItemSelector).forEach(($item) => { + $item.style['text-align'] = 'start'; + }); + document.querySelectorAll(inlineEquationSelector).forEach(($equation) => { + $equation.style.direction = 'rtl'; + $equation.style.display = 'inline-flex'; + $equation.style.flexDirection = 'row-reverse'; + for (const $symbol of $equation.children) { + $symbol.style.direction = 'ltr'; + } + }); + }; + web.addDocumentObserver(autoAlignText, [ + pageContentSelector, + listItemSelector, + inlineEquationSelector, + ]); + await web.whenReady(); + autoAlignText(); +} diff --git a/repo/right-to-left/mod.json b/repo/right-to-left/mod.json new file mode 100644 index 0000000..1a1d396 --- /dev/null +++ b/repo/right-to-left/mod.json @@ -0,0 +1,23 @@ +{ + "name": "right to left", + "id": "b28ee2b9-4d34-4e36-be8a-ab5be3d79f51", + "version": "1.5.0", + "description": "enables auto rtl/ltr text direction detection.", + "preview": "right-to-left.jpg", + "tags": ["extension", "usability"], + "authors": [ + { + "name": "obahareth", + "email": "omar@omar.engineer", + "homepage": "https://omar.engineer", + "avatar": "https://avatars.githubusercontent.com/u/3428118" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [] +} diff --git a/repo/right-to-left/right-to-left.jpg b/repo/right-to-left/right-to-left.jpg new file mode 100644 index 0000000..38956ed Binary files /dev/null and b/repo/right-to-left/right-to-left.jpg differ diff --git a/repo/scroll-to-top/client.mjs b/repo/scroll-to-top/client.mjs new file mode 100644 index 0000000..396984e --- /dev/null +++ b/repo/scroll-to-top/client.mjs @@ -0,0 +1,43 @@ +/** + * notion-enhancer: scroll to top + * (c) 2021 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web, components }, db) { + const scrollStyle = (await db.get(['smooth'])) ? 'smooth' : 'auto', + $scrollButton = await components.addCornerAction( + await components.feather('chevron-up'), + () => { + document.querySelector('.notion-frame > .notion-scroller').scroll({ + top: 0, + left: 0, + behavior: scrollStyle, + }); + } + ); + + let $scroller; + const topDistancePx = +(await db.get(['top_distance_px'])), + topDistancePercent = 0.01 * (await db.get(['top_distance_percent'])), + adjustButtonVisibility = async () => { + if (!$scroller) return; + $scrollButton.classList.add('hidden'); + const scrolledDistance = + $scroller.scrollTop >= topDistancePx || + $scroller.scrollTop >= + ($scroller.scrollHeight - $scroller.clientHeight) * topDistancePercent; + if (scrolledDistance) $scrollButton.classList.remove('hidden'); + }; + web.addDocumentObserver(() => { + $scroller = document.querySelector('.notion-frame > .notion-scroller'); + $scroller.removeEventListener('scroll', adjustButtonVisibility); + $scroller.addEventListener('scroll', adjustButtonVisibility); + }, ['.notion-frame > .notion-scroller']); + adjustButtonVisibility(); + + if (topDistancePx && topDistancePercent) $scrollButton.classList.add('hidden'); +} diff --git a/repo/scroll-to-top/mod.json b/repo/scroll-to-top/mod.json new file mode 100644 index 0000000..cf57cd8 --- /dev/null +++ b/repo/scroll-to-top/mod.json @@ -0,0 +1,42 @@ +{ + "name": "scroll to top", + "id": "0a958f5a-17c5-48b5-8713-16190cae1959", + "version": "0.3.0", + "description": "adds an arrow in the bottom right corner to scroll back to the top of a page.", + "preview": "scroll-to-top.png", + "tags": ["extension", "shortcut"], + "authors": [ + { + "name": "CloudHill", + "email": "rh.cloudhill@gmail.com", + "homepage": "https://github.com/CloudHill", + "avatar": "https://avatars.githubusercontent.com/u/54142180" + } + ], + "css": {}, + "js": { + "client": ["client.mjs"] + }, + "options": [ + { + "type": "toggle", + "key": "smooth", + "label": "smooth scrolling", + "value": true + }, + { + "type": "number", + "key": "top_distance_px", + "label": "distance scrolled until button shown (px)", + "tooltip": "**the distance in pixels that must be scrolled down before the button appears**", + "value": 5000 + }, + { + "type": "number", + "key": "top_distance_percent", + "label": "distance scrolled until button shown (%)", + "tooltip": "**the percentage of the page that must be scrolled down before the button appears**", + "value": 80 + } + ] +} diff --git a/repo/scroll-to-top/scroll-to-top.png b/repo/scroll-to-top/scroll-to-top.png new file mode 100644 index 0000000..0f1c55c Binary files /dev/null and b/repo/scroll-to-top/scroll-to-top.png differ diff --git a/repo/simpler-databases/client.css b/repo/simpler-databases/client.css new file mode 100644 index 0000000..eeb47e8 --- /dev/null +++ b/repo/simpler-databases/client.css @@ -0,0 +1,429 @@ +/** + * notion-enhancer: simpler databases + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.simpler_databases--config_button:hover { + background: linear-gradient( + var(--theme--ui_interactive-hover), + var(--theme--ui_interactive-hover) + ), + linear-gradient(var(--theme--bg), var(--theme--bg)); +} +.simpler_databases--config_button svg { + width: 12px; + height: 12px; + fill: var(--theme--icon_secondary); +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + [style*=' height: 42px;'] + > :last-child { + position: absolute; + top: 4px; + right: 0; + z-index: 99; + pointer-events: auto; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + .simpler_databases--config_button { + box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.05)) 0px 0px 0px 1px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.1)) 0px 3px 6px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.2)) 0px 9px 24px !important; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + .simpler_databases--config_button:not(:hover) { + background: var(--theme--bg); +} + +.simpler_databases--overlay_container { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 999; + overflow: hidden; +} + +.simpler_databases--config_menu { + position: relative; + width: 220px; + max-height: 70vh; + padding: 8px 0; + border-radius: 3px; + box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.05)) 0px 0px 0px 1px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.1)) 0px 3px 6px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.2)) 0px 9px 24px; + background: var(--theme--bg_card); + overflow: hidden auto; +} + +.simpler_databases--config_item-toggle, +.simpler_databases--config_item-input { + display: flex; + align-items: center; + width: 100%; + min-height: 28px; + font-size: 14px; + line-height: 1.2; + user-select: none; +} +.simpler_databases--config_item-toggle { + cursor: pointer; +} +.simpler_databases--config_item-toggle:hover, +.simpler_databases--config_item-toggle:focus { + background: var(--theme--ui_interactive-hover); +} +.simpler_databases--config_item-input { + padding: 6px 0; +} + +.simpler_databases--config_title { + margin: 0 14px; + min-width: 0; + flex: 1 1 auto; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.simpler_databases--config_toggle { + flex-shrink: 0; + position: relative; + height: 14px; + width: 26px; + margin-left: auto; + margin-right: 14px; + padding: 2px; + border-radius: 44px; + cursor: pointer; + user-select: none; + box-sizing: content-box; + background: var(--theme--ui_toggle-off); + transition: background 200ms ease 0s, box-shadow 200ms ease 0s; +} +.simpler_databases--config_toggle[data-toggled='true'] { + background: var(--theme--ui_toggle-on); +} +.simpler_databases--config_toggle::before { + content: ''; + position: absolute; + width: 14px; + height: 14px; + border-radius: 44px; + background: var(--theme--ui_toggle-feature); + transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; +} +.simpler_databases--config_toggle[data-toggled='true']::before { + transform: translateX(12px); +} + +.simpler_databases--config_input { + display: flex; + align-items: center; + height: 28px; + margin: 0 14px; + padding: 3px 6px; + background: var(--theme--ui_input); + box-shadow: var(--theme--ui_shadow) 0px 0px 0px 1px inset; + border-radius: 3px; + font-size: 14px; + line-height: 20px; + cursor: text; + width: 100%; +} +.simpler_databases--config_input input { + font-size: inherit; + line-height: inherit; + border: none; + background: none; + width: 100%; + display: block; + resize: none; + padding: 0; +} + +.simpler_databases--config_divider { + border-bottom: 1px solid var(--theme--ui_divider); + width: 100%; + margin: 6px 0; +} + +.notion-collection_view-block[data-simpler-db-tweaks*='[config-open]'] + [style*=' height: 42px;'] + > :not(:first-child) { + opacity: 1 !important; +} + +/* TWEAKS */ + +/* Toggle */ +.simpler_databases--toggle { + flex-shrink: 0; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 3px; + cursor: pointer; + transition: background 20ms ease-in 0s; +} +.simpler_databases--toggle svg { + width: 12px; + height: 12px; + transform: rotateZ(180deg); + transition: transform 200ms ease-out 0s; +} +.simpler_databases--toggle:hover { + background: var(--theme--ui_interactive-hover); +} + +.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true'] + .simpler_databases--toggle + svg { + transform: rotateZ(90deg); +} + +.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'] > div > .notion-scroller { + transition: height 200ms ease-in, opacity 200ms ease-in; +} +.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true'] + > div + > .notion-scroller { + opacity: 0; + height: 0 !important; +} + +.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true'] + [data-simpler-db-hide-items] + [class$='view'] + > .notion-collection_view-block, +.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true'] + [data-simpler-db-hide-items] + .notion-collection-item { + display: none !important; +} + +/* Title */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[title]']) + [style*=' height: 42px;'] + > [style*='white-space: nowrap; overflow: hidden;'] + [placeholder] { + display: none !important; +} + +/* Icons + Link Arrows */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']) + [style*=' height: 42px;'] + a + :first-child[style*='margin-right: 6px'] { + display: none !important; +} + +/* Views */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[views]']) + [style*=' height: 42px;'] + > [role='button'] { + display: none !important; +} + +/* Toolbar */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[toolbar]']) + .simpler_databases--config_button + ~ * { + display: none !important; +} + +/* Header - table, calendar */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[header_row]']) + .notion-table-view + > .notion-collection_view-block + > :first-child, +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[header_row]']) + .notion-table-view + > .notion-collection_view-block + > :first-child + + div { + display: none !important; +} + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[header_row]']) + .notion-table-view + .notion-collection_view-block + > [style*='height: 34px'] + + div { + border-top: 1px solid var(--theme--ui_divider); +} + +/* New Item - table, board, timeline, list, gallery */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]']) + .notion-table-view-add-row, +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]']) + .notion-board-view + .notion-board-group + > [role='button']:not(.notion-collection-item), +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]']) + .notion-timeline-item-row:last-child, +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]']) + .notion-list-view + > .notion-collection_view-block + > [role='button']:not(.notion-collection-item), +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]']) + .notion-gallery-view + > .notion-collection_view-block + [style*='grid'] + > [role='button'] { + display: none !important; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]']) + .notion-timeline-view + > [style*='padding-bottom: 34px;'] { + padding-bottom: 0 !important; +} + +/* Calc Row - table, timeline */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[calc_row]']) + .notion-table-view-add-row + ~ div:not(.notion-selectable-halo):not([role='button']), +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[calc_row]']) + .notion-timeline-view + > [style*='z-index: 4;']:last-child { + display: none !important; +} + +/* Hidden Columns - board */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[hidden_column]']) + .notion-board-view + > .notion-collection_view-block + [style*='width: 220px;'] { + display: none !important; +} + +/* Add Group - board */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[add_group]']) + .notion-board-view + > .notion-collection_view-block + [style*='width: 180px;'] { + display: none !important; +} + +/* New Column - table */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_column]']) + .notion-table-view-add-column, +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_column]']) + .notion-table-view + .notion-collection-item + > [style*='width: 32px;'] { + display: none !important; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_column]']) + .notion-table-view-add-row + + [style*='padding-right: 32px;'] { + padding-right: 0 !important; +} + +/* Full Width - table */ + +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]']) + .notion-table-view + > .notion-collection_view-block { + max-width: fit-content; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]']) + .notion-table-view + .notion-collection_view-block + > [style*='min-width'] { + min-width: 0 !important; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]']) + .notion-table-view + .notion-collection-item { + width: fit-content; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]']) + .notion-table-view + .notion-collection_view-block + > [style*='height: 34px'] + + div, +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]']) + .notion-table-view + .notion-collection_view-block + > :first-child { + border-left: 1px solid var(--theme--ui_divider); +} + +/* COMPOUND TWEAKS */ + +/* Title and Link disabled > Hide title container */ +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']) + [style*=' height: 42px;'] + > [style*='white-space: nowrap; overflow: hidden;'] { + display: none !important; +} + +/* New Row and Calc Row disabled > Add bottom border - table */ +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[calc_row]']):not([data-simpler-db-tweaks*='[new_item]']) + .notion-table-view + .notion-collection_view-block + > [style*='height: 34px'] + + div { + border-bottom: 1px solid var(--theme--ui_divider); +} + +/* New Column enabled with Full Width disabled > Add right border - table */ +.notion-collection_view-block[data-simpler-db-tweaks][data-simpler-db-tweaks*='[new_column]']:not([data-simpler-db-tweaks*='[full_width]']) + .notion-table-view + .notion-collection_view-block + > [style*='height: 34px'] + + div, +.notion-collection_view-block[data-simpler-db-tweaks][data-simpler-db-tweaks*='[new_column]']:not([data-simpler-db-tweaks*='[full_width]']) + .notion-table-view + .notion-collection_view-block + > :first-child { + border-right: 1px solid var(--theme--ui_divider); +} + +/* REMOVE DATABASE HEADER < Title, Link, Toggle, Views, and Toolbar disabled */ + +/* Hide Header */ +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + [style*='min-height: 42px'] { + min-height: 0 !important; + max-height: 0; + pointer-events: none; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + [style*='height: 42px'] { + overflow: visible !important; +} + +/* Hide Top Border */ +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + :not(.notion-table-view) + > .notion-collection_view-block + > [style*='box-shadow'] { + box-shadow: none !important; +} +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + :not(.notion-table-view) + > .notion-collection_view-block[style*='border-top'], +.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]']) + :not(.notion-table-view) + > .notion-collection_view-block + > [style*='border-top'] { + border-top: none !important; +} diff --git a/repo/simpler-databases/client.mjs b/repo/simpler-databases/client.mjs new file mode 100644 index 0000000..c82a6c9 --- /dev/null +++ b/repo/simpler-databases/client.mjs @@ -0,0 +1,452 @@ +/** + * notion-enhancer: simpler databases + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ web, components }, db) { + const collectionViewSelector = + '.notion-collection_view-block[style*="width"][style*="max-width"]', + collectionAddNewSelector = '.notion-collection-view-item-add', + collectionToolbarSelector = '[style*=" height: 42px"]', + linkedCollectionTitleSelector = `${collectionToolbarSelector} > a [placeholder]`, + viewContainerSelector = '.notion-scroller [class$="view"]', + configButtonClass = 'simpler_databases--config_button', + configButtonSvg = web.raw` + + `, + overlayContainerClass = 'simpler_databases--overlay_container', + configMenuClass = 'simpler_databases--config_menu', + configDividerClass = 'simpler_databases--config_divider', + configItemClass = 'simpler_databases--config_item', + configTitleClass = 'simpler_databases--config_title', + configToggleClass = 'simpler_databases--config_toggle', + configInputClassName = 'simpler_databases--config_input notion-focusable', + configOpenCollectionSelector = + '.notion-collection_view-block[data-simpler-db-tweaks*="[config-open]"]', + collectionToggleClass = 'simpler_databases--toggle', + notionAppSelector = '.notion-app-inner'; + + const replaceTitle = ($collection, state) => { + const $title = $collection.querySelector(linkedCollectionTitleSelector), + blockId = $collection.dataset.blockId; + if (!$title) return; + if (!$title.dataset.originalTitle && state) { + $title.dataset.originalTitle = $title.innerText; + } + + if (!$title.titleObserver) { + if (!state) return; + $title.titleObserver = new MutationObserver(async () => { + const customTitle = await db.get(['collections', blockId, 'replace_title'], false); + if (customTitle && $title.innerText !== customTitle) $title.innerText = customTitle; + }); + } else $title.titleObserver.disconnect(); + + if (state) { + // observe + $title.innerText = state; + $title.titleObserver.observe($title, { characterData: true, childList: true }); + } else { + // reset + $title.titleObserver.disconnect(); + $title.innerText = $title.dataset.originalTitle; + delete $title.dataset.originalTitle; + } + }, + insertToggle = async ($collection, state) => { + const datasetKey = 'simplerDbToggleHidden', + blockId = $collection.dataset.blockId, + $toolbar = $collection.querySelector(collectionToolbarSelector); + if (!$toolbar) return; + + const $collectionView = $collection.querySelector('.notion-scroller'), + hideCollection = () => { + $collectionView.style.height = $collectionView.offsetHeight + 'px'; + requestAnimationFrame(() => { + $collection.dataset[datasetKey] = true; + setTimeout(() => ($collectionView.dataset.simplerDbHideItems = 'true'), 200); // hide drag handles + }); + }, + showCollection = () => { + $collection.dataset[datasetKey] = false; + $collectionView.style.height = ''; + $collectionView.style.height = $collectionView.offsetHeight + 'px'; + $collection.dataset[datasetKey] = true; + + delete $collectionView.dataset.simplerDbHideItems; + requestAnimationFrame(() => { + $collection.dataset[datasetKey] = false; + setTimeout(() => ($collectionView.style.height = ''), 200); + }); + }; + + if (!$collection.dataset[datasetKey]) { + const storedState = await db.get(['collections', blockId, 'toggle_hidden'], false); + if (storedState) { + hideCollection(); + } + } + + let $toggle = $toolbar.querySelector(`.${collectionToggleClass}`); + if ($toggle) { + if (!state) $toggle.remove(); + return; + } else if (state) { + $toggle = web.html` +
+ +
+ `; + $toggle.addEventListener('click', async () => { + const hide = !($collection.dataset[datasetKey] === 'true'); + await db.set(['collections', blockId, 'toggle_hidden'], hide); + if (hide) { + hideCollection(); + } else showCollection(); + }); + $toolbar.prepend($toggle); + } + }; + + const menuItems = [ + { + key: 'replace_title', + name: 'Replace title...', + type: 'input', + linkedOnly: true, + default: '', + action: replaceTitle, + }, + { + key: 'icon', + name: 'Icon', + type: 'toggle', + default: true, + }, + { + key: 'title', + name: 'Title', + type: 'toggle', + default: true, + }, + { + key: 'toggle', + name: 'Toggle', + type: 'toggle', + default: false, + action: insertToggle, + }, + { + key: 'views', + name: 'Views', + type: 'toggle', + default: true, + }, + { + key: 'toolbar', + name: 'Toolbar', + type: 'toggle', + default: true, + }, + { + key: 'divider', + views: ['table', 'board', 'timeline', 'list', 'gallery'], + }, + { + key: 'header_row', + name: 'Header row', + type: 'toggle', + default: true, + views: ['table'], + }, + { + key: 'new_item', + name: 'New row', + type: 'toggle', + default: true, + views: ['table', 'timeline'], + }, + { + key: 'new_item', + name: 'New item', + type: 'toggle', + default: true, + views: ['board', 'list', 'gallery'], + }, + { + key: 'calc_row', + name: 'Calculation row', + type: 'toggle', + default: true, + views: ['table', 'timeline'], + }, + { + key: 'divider', + views: ['table', 'board'], + }, + { + key: 'hidden_column', + name: 'Hidden columns', + type: 'toggle', + default: true, + views: ['board'], + }, + { + key: 'add_group', + name: 'Add group', + type: 'toggle', + default: true, + views: ['board'], + }, + { + key: 'new_column', + name: 'New column', + type: 'toggle', + default: true, + views: ['table'], + }, + { + key: 'full_width', + name: 'Full width', + type: 'toggle', + default: true, + views: ['table'], + }, + ]; + + const isLinked = ($collection) => !!$collection.querySelector(linkedCollectionTitleSelector), + getViewType = ($collection) => + $collection.querySelector(viewContainerSelector)?.className.split('-')[1], + setTweakState = ($collection, key, state) => { + const datasetKey = 'simplerDbTweaks'; + if (!$collection.dataset[datasetKey]) $collection.dataset[datasetKey] = ''; + + key = web.escape(key); + const isActive = $collection.dataset[datasetKey].includes(`[${key}]`); + + if (state && !isActive) { + $collection.dataset[datasetKey] += `[${key}]`; + } else if (!state && isActive) { + const prev = $collection.dataset[datasetKey]; + $collection.dataset[datasetKey] = prev.replace(`[${key}]`, ''); + } + }; + + const clickItem = (event) => { + event.stopPropagation(); + const focusedItem = event.target.closest(`[class^="${configItemClass}"]`); + if (focusedItem) focusedItem.click(); + }, + focusNextItem = (event) => { + event.stopPropagation(); + event.preventDefault(); + const $focusedItem = event.target.closest(`[class^="${configItemClass}"]`); + if (!$focusedItem) return; + let $targetItem = $focusedItem.nextElementSibling; + if (!$targetItem) $targetItem = $focusedItem.parentElement.firstElementChild; + if ($targetItem.classList.contains(configDividerClass)) { + $targetItem = $targetItem.nextElementSibling; + } + const $input = $targetItem.querySelector('input'); + if ($input) { + $input.focus(); + } else $targetItem.focus(); + }, + focusPrevItem = (event) => { + event.stopPropagation(); + event.preventDefault(); + const $focusedItem = event.target.closest(`[class^="${configItemClass}"]`); + if (!$focusedItem) return; + let $targetItem = $focusedItem.previousElementSibling; + if (!$targetItem) $targetItem = $focusedItem.parentElement.lastElementChild; + if ($targetItem.classList.contains(configDividerClass)) { + $targetItem = $targetItem.previousElementSibling; + } + const $input = $targetItem.querySelector('input'); + if ($input) { + $input.focus(); + } else $targetItem.focus(); + }, + keyListeners = [ + { + keys: ['Escape'], + listener: (event) => { + event.stopPropagation(); + hideConfig(); + }, + opts: { listenInInput: true, keydown: true }, + }, + { + keys: [' '], + listener: (event) => clickItem(event), + opts: { keydown: true }, + }, + { + keys: ['Enter'], + listener: (event) => clickItem(event), + opts: { keydown: true }, + }, + { + keys: ['ArrowDown'], + listener: focusNextItem, + opts: { listenInInput: true, keydown: true }, + }, + { + keys: ['ArrowUp'], + listener: focusPrevItem, + opts: { listenInInput: true, keydown: true }, + }, + { + keys: ['Tab'], + listener: focusNextItem, + opts: { listenInInput: true, keydown: true }, + }, + { + keys: ['Shift', 'Tab'], + listener: focusPrevItem, + opts: { listenInInput: true, keydown: true }, + }, + ]; + + const renderConfigItem = async ($collection, menuItem) => { + if (menuItem.key === 'divider') + return web.html`
`; + + const blockId = $collection.dataset.blockId, + storedState = await db.get(['collections', blockId, menuItem.key], menuItem.default), + $item = web.html`
`; + + switch (menuItem.type) { + case 'toggle': + const $label = web.html`
${menuItem.name}
`, + $toggle = web.html`
`; + web.render($item, $label, $toggle); + $item.setAttribute('tabindex', 0); + $item.addEventListener('click', async (e) => { + e.stopPropagation(); + const newState = !($toggle.dataset.toggled === 'true'); + $toggle.dataset.toggled = newState; + await db.set(['collections', blockId, menuItem.key], newState); + setTweakState($collection, menuItem.key, newState); + if (menuItem.action) menuItem.action($collection, newState); + }); + break; + + case 'input': + const $input = web.html`
+ +
`; + web.render($item, $input); + $item.addEventListener('click', (e) => e.stopPropagation()); + if (menuItem.action) { + $input.firstElementChild.addEventListener('input', async (e) => { + e.stopPropagation(); + const newState = e.target.value; + await db.set(['collections', blockId, menuItem.key], newState); + menuItem.action($collection, newState); + }); + } + break; + } + return $item; + }, + renderConfig = async ($collection, $button) => { + if (document.querySelector(`.${overlayContainerClass}`)) return; + + const collectionViewType = getViewType($collection); + if (!collectionViewType) return; + + const $overlay = web.html`
`; + $overlay.addEventListener('click', hideConfig); + web.render(document.querySelector(notionAppSelector), $overlay); + + const $config = web.html`
`, + viewMenuItems = menuItems.filter( + (item) => + (!item.views || item.views.includes(collectionViewType)) && + (!item.linkedOnly || isLinked($collection)) + ), + $menuItemElements = await Promise.all( + viewMenuItems.map((item) => renderConfigItem($collection, item)) + ); + web.render($config, ...$menuItemElements); + const $firstMenuItem = + $config.firstElementChild.getElementsByTagName('input')[0] || + $config.firstElementChild; + + const $position = web.html` +
+
+
+ `; + $position.firstElementChild.appendChild($config); + web.render($overlay, $position); + + const rect = $button.getBoundingClientRect(); + $position.style.left = + Math.min(rect.left + rect.width / 2, window.innerWidth - ($config.offsetWidth + 14)) + + 'px'; + $position.style.top = + Math.min( + rect.top + rect.height / 2, + window.innerHeight - ($config.offsetHeight + 14) + ) + 'px'; + + setTweakState($collection, 'config-open', true); + for (const { keys, listener, opts } of keyListeners) { + web.addHotkeyListener(keys, listener, opts); + } + await $config.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 200 }).finished; + $firstMenuItem.focus(); + }; + async function hideConfig() { + const $overlay = document.querySelector(`.${overlayContainerClass}`), + $collection = document.querySelector(configOpenCollectionSelector); + if (!$overlay) return; + + $overlay.removeEventListener('click', hideConfig); + for (const { listener } of keyListeners) web.removeHotkeyListener(listener); + + await document + .querySelector(`.${configMenuClass}`) + .animate([{ opacity: 1 }, { opacity: 0 }], { duration: 200 }).finished; + setTweakState($collection, 'config-open', false); + $overlay.remove(); + } + + const simplifyCollection = async () => { + for (const $collection of document.querySelectorAll(collectionViewSelector)) { + const blockId = $collection.dataset.blockId, + $addNew = $collection.querySelector(collectionAddNewSelector); + if ($collection.querySelector(`.${configButtonClass}`) || !$addNew) continue; + + const $configButton = $addNew.previousElementSibling.cloneNode(); + $configButton.className = configButtonClass; + $configButton.innerHTML = configButtonSvg; + $configButton.addEventListener('click', () => { + renderConfig($collection, $configButton); + }); + $addNew.parentElement.prepend($configButton); + + for (const item of menuItems) { + if (item.key === 'divider') continue; + const state = await db.get(['collections', blockId, item.key], item.default); + if ((item.type !== 'input' && !item.linkedOnly) || isLinked($collection)) { + setTweakState($collection, item.key, state); + } + if (state && item.action) item.action($collection, state); + } + } + }; + web.addDocumentObserver(simplifyCollection, [collectionViewSelector]); +} diff --git a/repo/simpler-databases/mod.json b/repo/simpler-databases/mod.json new file mode 100644 index 0000000..62d45e3 --- /dev/null +++ b/repo/simpler-databases/mod.json @@ -0,0 +1,23 @@ +{ + "name": "simpler databases", + "id": "752933b5-1258-44e3-b49a-61b4885f8bda", + "version": "0.2.0", + "description": "adds a menu to inline databases to toggle ui elements.", + "preview": "simpler-databases.jpg", + "tags": ["extension", "layout"], + "authors": [ + { + "name": "CloudHill", + "email": "rh.cloudhill@gmail.com", + "homepage": "https://github.com/CloudHill", + "avatar": "https://avatars.githubusercontent.com/u/54142180" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [] +} diff --git a/repo/simpler-databases/simpler-databases.jpg b/repo/simpler-databases/simpler-databases.jpg new file mode 100644 index 0000000..eec09ae Binary files /dev/null and b/repo/simpler-databases/simpler-databases.jpg differ diff --git a/repo/tabs/client.mjs b/repo/tabs/client.mjs new file mode 100644 index 0000000..9373351 --- /dev/null +++ b/repo/tabs/client.mjs @@ -0,0 +1,82 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web, electron }, db) { + const newTabHotkey = await db.get(['new_tab']), + closeTabHotkey = await db.get(['close_tab']), + restoreTabHotkey = await db.get(['restore_tab']), + selectTabModifier = await db.get(['select_modifier']), + prevTabHotkey = await db.get(['prev_tab']), + nextTabHotkey = await db.get(['next_tab']); + web.addHotkeyListener(newTabHotkey, () => { + electron.sendMessageToHost('new-tab'); + }); + web.addHotkeyListener(restoreTabHotkey, () => { + electron.sendMessageToHost('restore-tab'); + }); + web.addHotkeyListener(closeTabHotkey, () => electron.sendMessageToHost('close-tab')); + for (let i = 1; i < 10; i++) { + web.addHotkeyListener([selectTabModifier, i.toString()], () => { + electron.sendMessageToHost('select-tab', i); + }); + } + web.addHotkeyListener(prevTabHotkey, () => { + electron.sendMessageToHost('select-prev-tab') + }); + web.addHotkeyListener(nextTabHotkey, () => { + electron.sendMessageToHost('select-next-tab') + }); + + const breadcrumbSelector = + '.notion-topbar > div > [class="notranslate"] > .notion-focusable:last-child', + imgIconSelector = `${breadcrumbSelector} .notion-record-icon img:not(.notion-emoji)`, + emojiIconSelector = `${breadcrumbSelector} .notion-record-icon img.notion-emoji`, + nativeIconSelector = `${breadcrumbSelector} .notion-record-icon [role="image"]`, + titleSelector = `${breadcrumbSelector} > :not(.notion-record-icon)`, + viewSelector = '.notion-collection-view-select'; + + let title = '', + icon = ''; + const notionSetWindowTitle = __electronApi.setWindowTitle, + getIcon = () => { + const $imgIcon = document.querySelector(imgIconSelector), + $emojiIcon = document.querySelector(emojiIconSelector), + $nativeIcon = document.querySelector(nativeIconSelector); + if ($imgIcon) { + return `url("${$imgIcon.src}") 0 / 100%`; + } + if ($emojiIcon) { + return $emojiIcon.style.background.replace( + /url\("\/images/, + 'url("notion://www.notion.so/images' + ); + } + if ($nativeIcon) return $nativeIcon.ariaLabel; + return ''; + }, + updateTitle = (newTitle = title) => { + if (!newTitle) return; + title = newTitle; + icon = getIcon(); + electron.sendMessageToHost('set-tab-title', title); + electron.sendMessageToHost('set-tab-icon', icon); + notionSetWindowTitle(title); + }; + __electronApi.setWindowTitle = (newTitle) => updateTitle(newTitle); + document.addEventListener('focus', updateTitle); + electron.onMessage('trigger-title-update', () => updateTitle()); + + await web.whenReady([titleSelector]); + const $title = document.querySelector(titleSelector), + $view = document.querySelector(viewSelector); + if (!title && $title) { + if ($view) { + updateTitle(`${$title.innerText} | ${$view.innerText}`); + } else updateTitle($title.innerText); + } +} diff --git a/repo/tabs/createWindow.cjs b/repo/tabs/createWindow.cjs new file mode 100644 index 0000000..bda9a95 --- /dev/null +++ b/repo/tabs/createWindow.cjs @@ -0,0 +1,23 @@ +/** + * notion-enhancer: tabs + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = async function (api, db, __exports, __eval) { + const notionCreateWindow = __exports.createWindow; + __exports.createWindow = (relativeUrl = '', args) => { + const windows = api.electron.getNotionWindows(); + // '/' is used to create new windows intentionally + if (relativeUrl && relativeUrl !== '/' && windows.length) { + const window = api.electron.getFocusedNotionWindow() || windows[0]; + window.webContents.send('notion-enhancer:open-tab', { + notionUrl: `notion://www.notion.so${relativeUrl}`, + }); + return window; + } + return notionCreateWindow(relativeUrl, args); + }; +}; diff --git a/repo/tabs/main.cjs b/repo/tabs/main.cjs new file mode 100644 index 0000000..9900eee --- /dev/null +++ b/repo/tabs/main.cjs @@ -0,0 +1,37 @@ +/** + * notion-enhancer: tabs + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = async function ({}, db, __exports, __eval) { + const electron = require('electron'); + electron.ipcMain.on('notion-enhancer:close-tab', (event, { window, id }) => { + electron.webContents.fromId(window).send('notion-enhancer:close-tab', id); + }); + + __eval(` + const notionHandleActivate = handleActivate; + handleActivate = (relativeUrl) => { + const api = require('notion-enhancer/api/index.cjs'), + { BrowserWindow } = require('electron'), + windows = api.electron.getNotionWindows(), + electronWindows = BrowserWindow.getAllWindows(); + if (relativeUrl && windows.length) { + const win = api.electron.getFocusedNotionWindow() || windows[0]; + win.webContents.send('notion-enhancer:open-tab', { + notionUrl: \`notion://www.notion.so\$\{relativeUrl\}\`, + }); + win.show(); + win.focus(); + } else if (relativeUrl && electronWindows.length && !windows.length) { + // enhancer menu is open: prevent override + const { createWindow } = api.electron.notionRequire('main/createWindow'), + win = createWindow(relativeUrl); + win.focus(); + } else notionHandleActivate(relativeUrl); + }; + `); +}; diff --git a/repo/tabs/mod.json b/repo/tabs/mod.json new file mode 100644 index 0000000..0d3004b --- /dev/null +++ b/repo/tabs/mod.json @@ -0,0 +1,96 @@ +{ + "name": "tabs", + "id": "e1692c29-475e-437b-b7ff-3eee872e1a42", + "environments": ["linux", "win32", "darwin"], + "version": "0.3.0", + "description": "open multiple notion pages in a single window.", + "preview": "tabs.jpg", + "tags": ["extension", "app"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "frame": ["tabs.css"] + }, + "js": { + "client": ["client.mjs"], + "electron": [ + { "source": "main.cjs", "target": "main/main.js" }, + { "source": "systemMenu.cjs", "target": "main/systemMenu.js" }, + { "source": "createWindow.cjs", "target": "main/createWindow.js" }, + { "source": "rendererIndex.cjs", "target": "renderer/index.js" } + ] + }, + "options": [ + { + "type": "toggle", + "key": "remember_last_open", + "label": "remember last open tabs", + "tooltip": "**a continue-where-you-left-off experience** (reopens recently active tabs after an app relaunch)", + "value": true + }, + { + "type": "select", + "key": "label_type", + "label": "tab labels", + "values": ["page icon & title", "page icon only", "page title only"] + }, + { + "type": "select", + "key": "layout_style", + "label": "tab layout", + "values": ["traditional tabbed", "rectangular", "bubble", "compact"] + }, + { + "type": "select", + "key": "select_modifier", + "label": "tab select modifier", + "tooltip": "**usage: Modifier+1 to Modifier+9, Modifier+ArrowLeft and Modifier+ArrowRight**", + "values": [ + "Alt", + "Command", + "Control", + "Super", + "Alt+Shift", + "Command+Shift", + "Control+Shift", + "Super+Shift" + ] + }, + { + "type": "hotkey", + "key": "prev_tab", + "label": "previous tab hotkey", + "value": "Control+Shift+Tab" + }, + { + "type": "hotkey", + "key": "next_tab", + "label": "next tab hotkey", + "value": "Control+Tab" + }, + { + "type": "hotkey", + "key": "new_tab", + "label": "new tab hotkey", + "value": "Control+T" + }, + { + "type": "hotkey", + "key": "close_tab", + "label": "close tab hotkey", + "value": "Control+W" + }, + { + "type": "hotkey", + "key": "restore_tab", + "label": "restore previously opened tab hotkey", + "value": "Control+Shift+T" + } + ] +} diff --git a/repo/tabs/rendererIndex.cjs b/repo/tabs/rendererIndex.cjs new file mode 100644 index 0000000..8a5a5b1 --- /dev/null +++ b/repo/tabs/rendererIndex.cjs @@ -0,0 +1,142 @@ +/** + * notion-enhancer: tabs + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = async function (api, db, __exports, __eval) { + const url = require('url'), + electron = require('electron'), + electronWindow = electron.remote.getCurrentWindow(), + { components, web, env } = api; + + window['__start'] = async () => { + // display:none; to prevent content flash while css loads + document.body.style.display = 'none'; + + const tabCache = new Map(), + Tab = await require('./tab.cjs')(api, db, tabCache); + document.body.dataset.tabLabels = await db.get(['label_type']); + document.body.dataset.tabStyle = await db.get(['layout_style']); + + const $header = web.html`
`, + $tabs = web.html`
`, + $newTab = web.html`
${await components.feather('plus')}
`, + $root = document.querySelector('#root'), + $windowActions = web.html`
`; + document.body.prepend(web.render($header, $tabs, $newTab, $windowActions)); + + // make space for native window buttons on mac + if (env.name === 'darwin') $tabs.style.paddingLeft = '72px'; + + $newTab.addEventListener('click', () => new Tab($tabs, $root)); + electron.ipcRenderer.on('notion-enhancer:close-tab', (event, id) => { + const tab = tabCache.get(id); + if (tab) tab.close(); + }); + electron.ipcRenderer.on( + 'notion-enhancer:open-tab', + (event, opts) => new Tab($tabs, $root, opts) + ); + + const rememberLastOpen = await db.get(['remember_last_open']), + openTabs = await db.get(['last_open_tabs_cache']); + if (rememberLastOpen && openTabs && Array.isArray(openTabs)) { + for (const tab of openTabs) { + new Tab($tabs, $root, { ...tab, cancelAnimation: true }); + } + } else { + new Tab($tabs, $root, { + notionUrl: url.parse(window.location.href, true).query.path, + cancelAnimation: true, + }); + } + window.addEventListener('beforeunload', () => { + const openTabs = [...$tabs.children] + .filter(($tab) => tabCache.get($tab.id)) + .map(($tab) => { + const tab = tabCache.get($tab.id); + return { + notionUrl: tab.$notion.src, + icon: tab.icon, + title: tab.title, + }; + }); + db.set(['last_open_tabs_cache'], openTabs); + }); + + let $draggedTab; + const $dragIndicator = web.html``, + getDragTarget = ($el) => { + while (!$el.matches('.tab, header, body')) $el = $el.parentElement; + if ($el.matches('header')) $el = $el.firstElementChild; + return $el.matches('#tabs, .tab') ? $el : undefined; + }, + resetDraggedTabs = () => { + if ($draggedTab) { + $dragIndicator.remove(); + $draggedTab.style.opacity = ''; + $draggedTab = undefined; + } + }; + $header.addEventListener('dragstart', (event) => { + $draggedTab = getDragTarget(event.target); + $draggedTab.style.opacity = 0.5; + const tab = tabCache.get($draggedTab.id); + event.dataTransfer.setData( + 'text', + JSON.stringify({ + window: electronWindow.webContents.id, + tab: $draggedTab.id, + icon: tab.$tabIcon.innerText || tab.$tabIcon.style.background, + title: tab.$tabTitle.innerText, + url: tab.$notion.src, + }) + ); + }); + $header.addEventListener('dragover', (event) => { + const $target = getDragTarget(event.target); + if ($target) { + if ($target.matches('#tabs')) { + $target.after($dragIndicator); + } else if ($target.matches('#tabs > :first-child')) { + $tabs.before($dragIndicator); + } else $target.before($dragIndicator); + event.preventDefault(); + } + }); + document.addEventListener('drop', (event) => { + const eventData = JSON.parse(event.dataTransfer.getData('text')), + $target = getDragTarget(event.target) || $tabs, + sameWindow = eventData.window === electronWindow.webContents.id, + tabMovement = + !sameWindow || + ($target && + $target !== $draggedTab && + $target !== $draggedTab.nextElementSibling && + ($target.matches('#tabs') ? $target.lastElementChild !== $draggedTab : true)); + if (!sameWindow) { + electron.ipcRenderer.send('notion-enhancer:close-tab', { + window: eventData.window, + id: eventData.tab, + }); + const transferred = new Tab($tabs, $root, { + notionUrl: eventData.url, + cancelAnimation: true, + icon: eventData.icon, + title: eventData.title, + }); + $draggedTab = transferred.$tab; + } + if (tabMovement) { + if ($target.matches('#tabs')) { + $target.append($draggedTab); + } else $target.before($draggedTab); + } + resetDraggedTabs(); + }); + $header.addEventListener('dragend', (event) => resetDraggedTabs()); + }; +}; diff --git a/repo/tabs/systemMenu.cjs b/repo/tabs/systemMenu.cjs new file mode 100644 index 0000000..9460cff --- /dev/null +++ b/repo/tabs/systemMenu.cjs @@ -0,0 +1,20 @@ +/** + * notion-enhancer: tabs + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = async function ({}, db, __exports, __eval) { + const notionSetupSystemMenu = __exports.setupSystemMenu; + __exports.setupSystemMenu = (locale) => { + const { Menu } = require('electron'), + template = notionSetupSystemMenu(locale); + for (const category of template) { + category.submenu = category.submenu.filter((item) => item.role !== 'close'); + } + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); + return template; + }; +}; diff --git a/repo/tabs/tab.cjs b/repo/tabs/tab.cjs new file mode 100644 index 0000000..4e44cc0 --- /dev/null +++ b/repo/tabs/tab.cjs @@ -0,0 +1,296 @@ +/** + * notion-enhancer: tabs + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +let focusedTab; + +module.exports = async function (api, db, tabCache = new Map()) { + const { components, web, fmt, fs } = api, + electron = require('electron'), + electronWindow = electron.remote.getCurrentWindow(), + notionIpc = api.electron.notionRequire('helpers/notionIpc'), + xIcon = await components.feather('x'); + + return class Tab { + id = fmt.uuidv4(); + + $notion = web.html` + + `; + $search = web.html` + + `; + + $tabIcon = web.html``; + $svgIconPlaceholder = web.html` + + + `; + $tabTitle = web.html``; + $closeTab = web.html`${xIcon}`; + $tab = web.render( + web.html`
`, + this.$tabIcon, + this.$svgIconPlaceholder, + this.$tabTitle, + this.$closeTab + ); + + constructor( + $tabList, + $tabContainer, + { + notionUrl = 'notion://www.notion.so/', + cancelAnimation = false, + icon = '', + title = 'notion.so', + cache = tabCache, + } = {} + ) { + this.tabCache = cache; + this.$tabList = $tabList; + this.$tabContainer = $tabContainer; + + this.$notion.src = notionUrl; + this.setTitle(title); + this.setIcon(icon); + this.tabCache.set(this.$tab.id, this); + + electronWindow.on('focus', () => { + if (focusedTab === this) this.$notion.focus(); + }); + this.$tab.addEventListener('click', (event) => { + if (event.target !== this.$closeTab && !this.$closeTab.contains(event.target)) { + this.focus(); + } + }); + this.$closeTab.addEventListener('click', () => this.close()); + + this.open(cancelAnimation); + this.addNotionListeners(); + return this; + } + + open(cancelAnimation = false) { + this.closed = false; + web.render(this.$tabList, this.$tab); + web.render(this.$tabContainer, this.$search); + web.render(this.$tabContainer, this.$notion); + if (!cancelAnimation) { + this.$tab.animate([{ width: '0px' }, { width: `${this.$tab.clientWidth}px` }], { + duration: 100, + easing: 'ease-in', + }).finished; + } + this.focus(); + } + async focus() { + document.querySelectorAll('.notion-webview, .search-webview').forEach(($webview) => { + if (![this.$notion, this.$search].includes($webview)) $webview.style.display = ''; + }); + document.querySelectorAll('.tab.current').forEach(($tab) => { + if ($tab !== this.$tab) $tab.classList.remove('current'); + }); + this.$tab.classList.add('current'); + this.$notion.style.display = 'flex'; + this.$search.style.display = 'flex'; + if (this.domReady) this.focusNotion(); + focusedTab = this; + } + async close() { + const $sibling = this.$tab.nextElementSibling || this.$tab.previousElementSibling; + if ($sibling) { + this.closed = Date.now(); + if (!focusedTab || focusedTab === this) $sibling.click(); + const width = `${this.$tab.clientWidth}px`; + this.$tab.style.width = 0; + this.$tab.style.pointerEvents = 'none'; + await this.$tab.animate([{ width }, { width: '0px' }], { + duration: 100, + easing: 'ease-out', + }).finished; + this.$tab.remove(); + this.$notion.remove(); + this.$search.remove(); + this.$tab.style.width = ''; + this.$tab.style.pointerEvents = ''; + this.domReady = false; + } else electronWindow.close(); + } + + title = ''; + setTitle(title) { + this.title = title; + this.$tabTitle.innerText = title; + } + icon = ''; + setIcon(icon) { + this.icon = icon; + if (icon.startsWith('url(')) { + // img + this.$tabIcon.style.background = icon; + this.$tabIcon.innerText = ''; + } else { + // unicode (native) + this.$tabIcon.innerText = icon; + this.$tabIcon.style.background = ''; + } + } + + webContents() { + return electron.remote.webContents.fromId(this.$notion.getWebContentsId()); + } + focusNotion() { + document.activeElement?.blur?.(); + this.$notion.blur(); + this.$notion.focus(); + requestAnimationFrame(() => { + notionIpc.sendIndexToNotion(this.$notion, 'notion-enhancer:trigger-title-update'); + }); + } + focusSearch() { + document.activeElement?.blur?.(); + this.$search.blur(); + this.$search.focus(); + } + + domReady = false; + addNotionListeners() { + const fromNotion = (channel, listener) => + notionIpc.receiveIndexFromNotion.addListener(this.$notion, channel, listener), + fromSearch = (channel, listener) => + notionIpc.receiveIndexFromSearch.addListener(this.$search, channel, listener), + toSearch = (channel, data) => notionIpc.sendIndexToSearch(this.$search, channel, data); + + this.$notion.addEventListener('dom-ready', () => { + if (focusedTab === this) this.focus(); + this.domReady = true; + + const navigateHistory = (event, cmd) => { + const swipe = event === 'swipe', + back = swipe ? cmd === 'left' : cmd === 'browser-backward', + fwd = swipe ? cmd === 'right' : cmd === 'browser-forward'; + if (back && this.$notion.canGoBack()) this.$notion.goBack(); + if (fwd && this.$notion.canGoForward()) this.$notion.goForward(); + }; + electronWindow.addListener('app-command', (e, cmd) => navigateHistory('app-cmd', cmd)); + electronWindow.addListener('swipe', (e, dir) => navigateHistory('swipe', dir)); + + this.webContents().addListener('found-in-page', (event, result) => { + const matches = result + ? { count: result.matches, index: result.activeMatchOrdinal } + : { count: 0, index: 0 }; + toSearch('search:result', matches); + }); + }); + + notionIpc.proxyAllMainToNotion(this.$notion); + + fromNotion('search:start', () => this.startSearch()); + fromNotion('search:stop', () => this.stopSearch()); + fromNotion('search:set-theme', (theme) => toSearch('search:set-theme', theme)); + fromSearch('search:clear', () => this.clearSearch()); + fromSearch('search:stop', () => this.stopSearch()); + fromSearch('search:next', (query) => this.searchNext(query)); + fromSearch('search:prev', (query) => this.searchPrev(query)); + + fromNotion('zoom', (zoomFactor) => { + this.webContents().setZoomFactor(zoomFactor); + }); + + fromNotion('notion-enhancer:set-tab-title', (title) => this.setTitle(title)); + fromNotion('notion-enhancer:set-tab-icon', (icon) => this.setIcon(icon)); + + fromNotion( + 'notion-enhancer:new-tab', + () => new this.constructor(this.$tabList, this.$tabContainer) + ); + fromNotion('notion-enhancer:close-tab', () => this.close()); + fromNotion('notion-enhancer:restore-tab', () => { + const tab = [...this.tabCache.values()] + .filter((tab) => tab.closed) + .sort((a, b) => b.closed - a.closed)[0]; + if (tab) tab.open(); + }); + fromNotion('notion-enhancer:select-tab', (i) => { + const $tab = i === 9 ? this.$tabList.lastElementChild : this.$tabList.children[i - 1]; + if ($tab) $tab.click(); + }); + fromNotion('notion-enhancer:select-prev-tab', () => { + if (this.$tabList.count == 1) { + return; + } + const $sibling = this.$tab.previousElementSibling; + if ($sibling) { + $sibling.click(); + } + else { + let $tab = this.$tabList.lastElementChild; + if ($tab) { + $tab.click(); + } + } + }); + fromNotion('notion-enhancer:select-next-tab', () => { + if (this.$tabList.count == 1) { + return; + } + const $sibling = this.$tab.nextElementSibling; + if ($sibling) { + $sibling.click(); + } + else { + let $tab = this.$tabList.children[0] + if ($tab) { + $tab.click(); + } + } + }); + } + + #firstQuery = true; + startSearch() { + this.$search.classList.add('search-active'); + this.focusSearch(); + notionIpc.sendIndexToSearch(this.$search, 'search:start'); + notionIpc.sendIndexToNotion(this.$search, 'search:started'); + } + clearSearch() { + this.#firstQuery = true; + this.webContents().stopFindInPage('clearSelection'); + } + stopSearch() { + this.$search.classList.remove('search-active'); + this.focusNotion(); + this.clearSearch(); + notionIpc.sendIndexToSearch(this.$search, 'search:reset'); + notionIpc.sendIndexToNotion(this.$notion, 'search:stopped'); + } + searchNext(query) { + this.webContents().findInPage(query, { + forward: true, + findNext: !this.#firstQuery, + }); + this.#firstQuery = false; + } + searchPrev(query) { + this.webContents().findInPage(query, { + forward: false, + findNext: !this.#firstQuery, + }); + this.#firstQuery = false; + } + }; +}; diff --git a/repo/tabs/tabs.css b/repo/tabs/tabs.css new file mode 100644 index 0000000..3b81480 --- /dev/null +++ b/repo/tabs/tabs.css @@ -0,0 +1,236 @@ +/** + * notion-enhancer: tabs + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +* { + box-sizing: border-box; +} + +html, +body { + height: 100%; + width: 100%; + margin: 0; + padding: 0; + background: var(--theme--bg) !important; + overflow: hidden; +} + +body { + display: flex !important; + flex-direction: column; +} + +header { + display: flex; + background: var(--theme--bg_secondary); + border-bottom: 1px solid var(--theme--ui_divider); + width: 100%; + padding: 0.5em; + user-select: none; + -webkit-app-region: drag; + z-index: 3; + font-size: 16px; +} + +#tabs { + display: flex; + overflow: hidden; +} +.tab { + display: flex; + flex-grow: 1; + flex-shrink: 1; + width: 14em; + max-width: 14em; + overflow: hidden; + padding: 0.4em 0.6em; + + color: var(--theme--text_secondary); + background: var(--theme--bg); + font-family: var(--theme--font_sans); + font-weight: 500; + border: none; + -webkit-app-region: no-drag; +} +.tab:hover { + background: var(--theme--ui_interactive-hover); +} +.tab.current { + background: var(--theme--ui_interactive-active); +} + +.drag-indicator { + z-index: 1; + width: 0.125em; + margin: 0 -0.0625em; + background: var(--theme--accent_blue-selection); +} + +.tab-title { + white-space: nowrap; + overflow: hidden; + margin-right: 0.25em; +} +.tab-icon { + margin-right: 0.375em; + flex-shrink: 0; +} +.tab-icon[style*='background'] { + width: 0.875em; + height: 0.875em; + align-self: center; + margin-right: 0.5em; +} +.tab-icon:not([style*='background']):empty, +.tab-icon + svg { + display: none; +} +.tab-icon:not([style*='background']):empty + svg { + /* placeholder icon */ + flex-shrink: 0; + display: inline-block; + margin: 1px 0.5em 0 0; + width: 1.125em; + height: 1.125em; + display: block; + backface-visibility: hidden; + fill: var(--theme--icon_secondary); +} + +.new-tab, +.tab-close { + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: 0.1875em; + height: 1.25em; + width: 1.25em; + padding: 0 0.25px 0 0; + + align-self: center; + border: none; + background: transparent; + -webkit-app-region: no-drag; +} +.new-tab svg, +.tab-close svg { + width: 0.875em; + height: 0.875em; + fill: var(--theme--icon_secondary); + color: var(--theme--icon_secondary); +} +.new-tab:focus, +.new-tab:hover, +.tab-close:focus, +.tab-close:hover { + background: var(--theme--ui_interactive-hover); +} +.new-tab:active, +.tab-close:active { + background: var(--theme--ui_interactive-active); +} + +.new-tab { + margin: 0 3em 0 0.375em; +} +.tab-close { + margin-left: auto; +} + +#window-actions { + display: flex; + align-items: center; + margin-left: auto; +} +#window-actions > * { + -webkit-app-region: no-drag; +} + +[data-tab-labels='page title only'] .tab-icon { + display: none; +} +[data-tab-labels='page icon only'] .tab { + width: 4em; + max-width: 4em; +} +[data-tab-labels='page icon only'] .tab-title { + display: none; +} + +[data-tab-style='rectangular'] .new-tab, +[data-tab-style='traditional tabbed'] .new-tab { + margin-bottom: -0.25em; +} +[data-tab-style='rectangular'] .tab-close, +[data-tab-style='traditional tabbed'] .tab-close { + align-self: auto; +} +[data-tab-style='rectangular'] .drag-indicator, +[data-tab-style='traditional tabbed'] .drag-indicator, +[data-tab-style='rectangular'] #tabs { + margin-bottom: -0.5em; +} +[data-tab-style='rectangular'] .tab { + padding: 0.6em 0.6em 0.8em 0.6em; +} +[data-tab-style='traditional tabbed'] header { + padding-top: 0.6875em; +} +[data-tab-style='traditional tabbed'] #tabs { + margin: -0.1875em 0 -0.5em 0; +} +[data-tab-style='traditional tabbed'] .tab { + border-top-left-radius: 0.875em; + border-top-right-radius: 0.875em; + padding: 0.6em; +} +[data-tab-style='bubble'] .tab { + border-radius: 0.375em; +} +[data-tab-style='bubble'] .tab:not(:first-child) { + margin-left: 0.5em; +} +[data-tab-style='bubble'] .drag-indicator { + margin: 0 -0.3125em 0 0.1875em; +} +[data-tab-style='bubble'] .drag-indicator:first-child { + margin: 0 0.187em 0 -0.312em; +} +[data-tab-style='compact'] header { + padding: 0; + font-size: 14px; +} +[data-tab-style='compact'] #window-actions { + transform: scale(0.8); + margin-right: -0.35em; +} + +#root { + flex-grow: 1; +} +.notion-webview { + width: 100%; + height: 100%; + display: none; +} +.search-webview { + width: 100%; + height: 60px; + display: none; + transition: transform 70ms ease-in; + transform: translateY(-100%); + pointer-events: none; + position: absolute; + z-index: 2; +} +.search-webview.search-active { + transition: transform 70ms ease-out; + transform: translateY(0%); + pointer-events: auto; +} diff --git a/repo/tabs/tabs.jpg b/repo/tabs/tabs.jpg new file mode 100644 index 0000000..2c9d0ab Binary files /dev/null and b/repo/tabs/tabs.jpg differ diff --git a/repo/theming/_mapColors.js b/repo/theming/_mapColors.js new file mode 100644 index 0000000..9798198 --- /dev/null +++ b/repo/theming/_mapColors.js @@ -0,0 +1,545 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +// a development tool used for generating color variables +// and the contents of colors.css + +// included for posterity/updates +// -- not executed by the enhancer at runtime + +const lightGray = { + 'light': { + 'tag': 'rgba(227, 226, 224, 0.5)', + 'tag-text': 'rgb(50, 48, 44)', + 'board': 'rgba(249, 249, 245, 0.5)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgba(145, 145, 142, 0.5)', + }, + 'dark': { + 'tag': 'rgba(71, 76, 80, 0.7)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgba(51, 55, 59, 0.7)', + 'board-card': 'rgba(60, 65, 68, 0.7)', + 'board-card_text': 'inherit', + 'board-text': 'rgba(107, 112, 116, 0.7)', + }, +}; + +const colors = { + 'gray': { + 'light': { + 'text': 'rgba(120, 119, 116, 1)', + 'highlight': 'rgba(241, 241, 239, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(241, 241, 239)', + 'callout-text': 'currentColor', + 'tag': 'rgb(227, 226, 224)', + 'tag-text': 'rgb(50, 48, 44)', + 'board': 'rgba(247, 247, 245, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(145, 145, 142)', + }, + 'dark': { + 'text': 'rgba(159, 164, 169, 1)', + 'highlight': 'rgba(60, 65, 68, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(60, 65, 68)', + 'callout-text': 'currentColor', + 'tag': 'rgb(71, 76, 80)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(51, 55, 59)', + 'board-card': 'rgb(60, 65, 68)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(107, 112, 116)', + }, + }, + 'brown': { + 'light': { + 'text': 'rgba(159, 107, 83, 1)', + 'highlight': 'rgba(244, 238, 238, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(244, 238, 238)', + 'callout-text': 'currentColor', + 'tag': 'rgb(238, 224, 218)', + 'tag-text': 'rgb(68, 42, 30)', + 'board': 'rgba(250, 246, 245, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(187, 132, 108)', + }, + 'dark': { + 'text': 'rgba(212, 150, 117, 1)', + 'highlight': 'rgba(76, 61, 53, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(76, 61, 53)', + 'callout-text': 'currentColor', + 'tag': 'rgb(92, 71, 61)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(59, 54, 51)', + 'board-card': 'rgb(76, 61, 53)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(155, 98, 69)', + }, + }, + 'orange': { + 'light': { + 'text': 'rgba(217, 115, 13, 1)', + 'highlight': 'rgba(251, 236, 221, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(251, 236, 221)', + 'callout-text': 'currentColor', + 'tag': 'rgb(250, 222, 201)', + 'tag-text': 'rgb(73, 41, 14)', + 'board': 'rgba(252, 245, 242, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(215, 129, 58)', + }, + 'dark': { + 'text': 'rgba(217, 133, 56, 1)', + 'highlight': 'rgba(85, 59, 41, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(85, 59, 41)', + 'callout-text': 'currentColor', + 'tag': 'rgb(136, 84, 44)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(61, 54, 49)', + 'board-card': 'rgb(85, 59, 41)', + 'board-text': 'rgb(168, 92, 30)', + }, + }, + 'yellow': { + 'light': { + 'text': 'rgba(203, 145, 47, 1)', + 'highlight': 'rgba(251, 243, 219, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(251, 243, 219)', + 'callout-text': 'currentColor', + 'tag': 'rgb(253, 236, 200)', + 'tag-text': 'rgb(64, 44, 27)', + 'board': 'rgba(250, 247, 237, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(203, 148, 51)', + }, + 'dark': { + 'text': 'rgba(201, 145, 38, 1)', + 'highlight': 'rgba(79, 64, 41, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(79, 64, 41)', + 'callout-text': 'currentColor', + 'tag': 'rgb(146, 118, 63)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(56, 55, 49)', + 'board-card': 'rgb(79, 64, 41)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(137, 107, 42)', + }, + }, + 'green': { + 'light': { + 'text': 'rgba(68, 131, 97, 1)', + 'highlight': 'rgba(237, 243, 236, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(237, 243, 236)', + 'callout-text': 'currentColor', + 'tag': 'rgb(219, 237, 219)', + 'tag-text': 'rgb(28, 56, 41)', + 'board': 'rgba(244, 248, 243, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(108, 155, 125)', + }, + 'dark': { + 'text': 'rgba(113, 178, 131, 1)', + 'highlight': 'rgba(46, 68, 58, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(46, 68, 58)', + 'callout-text': 'currentColor', + 'tag': 'rgb(50, 82, 65)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(49, 57, 53)', + 'board-card': 'rgb(46, 68, 58)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(61, 124, 86)', + }, + }, + 'blue': { + 'light': { + 'text': 'rgba(51, 126, 169, 1)', + 'highlight': 'rgba(231, 243, 248, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(231, 243, 248)', + 'callout-text': 'currentColor', + 'tag': 'rgb(211, 229, 239)', + 'tag-text': 'rgb(24, 51, 71)', + 'board': 'rgba(241, 248, 251, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(91, 151, 189)', + }, + 'dark': { + 'text': 'rgba(102, 170, 218, 1)', + 'highlight': 'rgba(45, 66, 86, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(45, 66, 86)', + 'callout-text': 'currentColor', + 'tag': 'rgb(42, 78, 107)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(49, 56, 64)', + 'board-card': 'rgb(45, 66, 86)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(46, 117, 164)', + }, + }, + 'purple': { + 'light': { + 'text': 'rgba(144, 101, 176, 1)', + 'highlight': 'rgba(244, 240, 247, 0.8)', + 'highlight-text': 'currentColor', + 'callout': 'rgba(244, 240, 247, 0.8)', + 'callout-text': 'currentColor', + 'tag': 'rgb(232, 222, 238)', + 'tag-text': 'rgb(65, 36, 84)', + 'board': 'rgba(249, 246, 252, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(167, 130, 195)', + }, + 'dark': { + 'text': 'rgba(176, 152, 217, 1)', + 'highlight': 'rgba(69, 58, 91, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(69, 58, 91)', + 'callout-text': 'currentColor', + 'tag': 'rgb(83, 68, 116)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(57, 53, 65)', + 'board-card': 'rgb(69, 58, 91)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(123, 96, 180)', + }, + }, + 'pink': { + 'light': { + 'text': 'rgba(193, 76, 138, 1)', + 'highlight': 'rgba(249, 238, 243, 0.8)', + 'highlight-text': 'currentColor', + 'callout': 'rgba(249, 238, 243, 0.8)', + 'callout-text': 'currentColor', + 'tag': 'rgb(245, 224, 233)', + 'tag-text': 'rgb(76, 35, 55)', + 'board': 'rgba(251, 245, 251, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(205, 116, 159)', + }, + 'dark': { + 'text': 'rgba(223, 132, 209, 1)', + 'highlight': 'rgba(81, 56, 77, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(81, 56, 77)', + 'callout-text': 'currentColor', + 'tag': 'rgb(106, 59, 99)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(60, 53, 58)', + 'board-card': 'rgb(81, 56, 77)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(169, 76, 157)', + }, + }, + 'red': { + 'light': { + 'text': 'rgba(212, 76, 71, 1)', + 'highlight': 'rgba(253, 235, 236, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(253, 235, 236)', + 'callout-text': 'currentColor', + 'tag': 'rgb(255, 226, 221)', + 'tag-text': 'rgb(93, 23, 21)', + 'board': 'rgba(253, 245, 243, 0.7)', + 'board-card': 'white', + 'board-card_text': 'inherit', + 'board-text': 'rgb(225, 111, 100)', + }, + 'dark': { + 'text': 'rgba(234, 135, 140, 1)', + 'highlight': 'rgba(94, 52, 54, 1)', + 'highlight-text': 'currentColor', + 'callout': 'rgb(94, 52, 54)', + 'callout-text': 'currentColor', + 'tag': 'rgb(122, 54, 59)', + 'tag-text': 'rgba(255, 255, 255, 0.88)', + 'board': 'rgb(66, 51, 51)', + 'board-card': 'rgb(94, 52, 54)', + 'board-card_text': 'inherit', + 'board-text': 'rgb(194, 65, 82)', + }, + }, +}; + +function css() { + const rgb = (color) => + color.startsWith('rgba') && color.endsWith(', 1)') + ? `rgb(${color.slice(5, -4)})` + : color, + notCallout = ":not([style*='border-radius'])", + notBoardCard = ":not([style*='box-shadow'])", + isTag = + "[style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;']", + isTagPalette = "[style*='border-radius: 3px;'][style*='width: 18px; height: 18px;']", + isHighlightPalette = + "[style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;']"; + let css = ''; + + // generate light gray separately + css += ` + + /* light gray */ + + .notion-body:not(.dark) [style*='background: ${lightGray.light['tag']}']${isTag}, + .notion-body.dark [style*='background: ${lightGray.dark['tag']}']${isTag} { + background: var(--theme--tag_light_gray) !important; + color: var(--theme--tag_light_gray-text) !important; + } + + .notion-body:not(.dark) [style*='background: ${ + lightGray.light['tag'] + }']${isTagPalette}, + .notion-body.dark [style*='background: ${ + lightGray.dark['board-text'] + }']${isTagPalette} { + background: var(--theme--tag_light_gray) !important; + color: var(--theme--tag_light_gray-text) !important; + } + + .notion-body:not(.dark) + .notion-board-group[style*='background-color: ${lightGray.light['board']}'], + .notion-body.dark + .notion-board-group[style*='background-color: ${lightGray.dark['board']}'], + .notion-body:not(.dark) .notion-board-view > .notion-selectable > :first-child > :nth-child(2) + [style*='background-color: ${lightGray.light['board']}'], + .notion-body.dark .notion-board-view > .notion-selectable > :first-child > :nth-child(2) + [style*='background-color: ${lightGray.dark['board']}'] { + background: var(--theme--board_light_gray) !important; + color: var(--theme--board_light_gray-text) !important; + } + .notion-body:not(.dark) + .notion-board-group[style*='background-color: ${lightGray.light['board']}'] + > [data-block-id] > [rel='noopener noreferrer'], + .notion-body.dark + .notion-board-group[style*='background-color: ${lightGray.dark['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] { + background: var(--theme--board_light_gray-card) !important; + color: var(--theme--board_light_gray-card_text) !important; + } + .notion-body.dark + .notion-board-group[style*='background-color: ${lightGray.dark['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] [placeholder="Untitled"] { + -webkit-text-fill-color: var(--theme--board_light_gray-card_text, var(--theme--board_light_gray-text)) !important; + } + .notion-body:not(.dark) + .notion-board-group[style*='background-color: ${lightGray.light['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; + } + .notion-body.dark + .notion-board-group[style*='background-color: ${lightGray.dark['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; + } + .notion-body:not(.dark) .notion-board-view + [style*='color: ${lightGray.light['board-text']}'], + .notion-body.dark .notion-board-view [style*='color: ${lightGray.dark['board-text']}'], + .notion-body:not(.dark) .notion-board-view + [style*='fill: ${lightGray.light['board-text']}'], + .notion-body.dark .notion-board-view [style*='fill: ${lightGray.dark['board-text']}'] { + color: var(--theme--board_light_gray-text) !important; + fill: var(--theme--board_light_gray-text) !important; + } + `; + + // generate the rest of the colours + for (const c in colors) { + css += ` + + /* ${c} */ + + .notion-body:not(.dark) [style*='color: ${rgb(colors[c].light['text'])}'], + .notion-body:not(.dark) [style*='color:${colors[c].light['text']}'], + .notion-body.dark [style*='color: ${rgb(colors[c].dark['text'])}'], + .notion-body.dark [style*='color:${colors[c].dark['text']}'] { + color: var(--theme--text_${c}) !important; + fill: var(--theme--text_${c}) !important; + } + + + .notion-body:not(.dark) [style*='background: ${ + colors[c].light['highlight'] + }']${notCallout}${notBoardCard}, + .notion-body:not(.dark) [style*='background:${ + colors[c].light['highlight'] + }']${notCallout}${notBoardCard}, + .notion-body:not(.dark) [style*='background: ${rgb( + colors[c].light['highlight'] + )}']${notCallout}${notBoardCard}, + .notion-body:not(.dark) [style*='background:${rgb( + colors[c].light['highlight'] + )}']${notCallout}${notBoardCard}, + .notion-body:not(.dark) [style*='background-color: ${ + colors[c].light['highlight'] + }']${notCallout}${notBoardCard}, + .notion-body.dark [style*='background: ${ + colors[c].dark['highlight'] + }']${notCallout}${notBoardCard}, + .notion-body.dark [style*='background:${ + colors[c].dark['highlight'] + }']${notCallout}${notBoardCard}, + .notion-body.dark [style*='background: ${rgb( + colors[c].dark['highlight'] + )}']${notCallout}${notBoardCard}, + .notion-body.dark [style*='background:${rgb( + colors[c].dark['highlight'] + )}']${notCallout}${notBoardCard}, + .notion-body.dark [style*='background-color: ${ + colors[c].dark['highlight'] + }']${notCallout}${notBoardCard} { + background: var(--theme--highlight_${c}) !important; + color: var(--theme--highlight_${c}-text) !important; + } + + .notion-body:not(.dark) .notion-callout-block > div + > [style*='background: ${colors[c].light['callout']}'], + .notion-body.dark .notion-callout-block > div + > [style*='background: ${colors[c].dark['callout']}'] { + background: var(--theme--callout_${c}) !important; + color: var(--theme--callout_${c}-text) !important; + } + .notion-body:not(.dark) [style*='background: ${colors[c].light['tag']}']${isTag}, + .notion-body.dark [style*='background: ${colors[c].dark['tag']}']${isTag} { + background: var(--theme--tag_${c}) !important; + color: var(--theme--tag_${c}-text) !important; + } + + .notion-body:not(.dark) [style*='background: ${ + colors[c].light['callout'] + }']${isHighlightPalette}, + .notion-body.dark [style*='background: ${ + colors[c].dark['callout'] + }']${isHighlightPalette} { + background: var(--theme--highlight_${c}) !important; + color: var(--theme--highlight_${c}-text) !important; + } + .notion-body:not(.dark) [style*='background: ${ + colors[c].light['tag'] + }']${isTagPalette}, + .notion-body.dark [style*='background: ${ + colors[c].dark['board-text'] + }']${isTagPalette} { + background: var(--theme--tag_${c}) !important; + color: var(--theme--tag_${c}-text) !important; + } + + .notion-body:not(.dark) + .notion-board-group[style*='background-color: ${colors[c].light['board']}'], + .notion-body.dark + .notion-board-group[style*='background-color: ${colors[c].dark['board']}'], + .notion-body:not(.dark) .notion-board-view > .notion-selectable > :first-child > :nth-child(2) + [style*='background-color: ${colors[c].light['board']}'], + .notion-body.dark .notion-board-view > .notion-selectable > :first-child > :nth-child(2) + [style*='background-color: ${colors[c].dark['board']}'] { + background: var(--theme--board_${c}) !important; + color: var(--theme--board_${c}-text) !important; + } + .notion-body:not(.dark) + .notion-board-group[style*='background-color: ${colors[c].light['board']}'] + > [data-block-id] > [rel='noopener noreferrer'], + .notion-body.dark + .notion-board-group[style*='background-color: ${colors[c].dark['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] { + background: var(--theme--board_${c}-card) !important; + color: var(--theme--board_${c}-card_text) !important; + } + .notion-body.dark + .notion-board-group[style*='background-color: ${colors[c].dark['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] [placeholder="Untitled"] { + -webkit-text-fill-color: var(--theme--board_${c}-card_text, var(--theme--board_${c}-text)) !important; + } + .notion-body:not(.dark) + .notion-board-group[style*='background-color: ${colors[c].light['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; + } + .notion-body.dark + .notion-board-group[style*='background-color: ${colors[c].dark['board']}'] + > [data-block-id] > [rel='noopener noreferrer'] > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; + } + .notion-body:not(.dark) .notion-board-view + [style*='color: ${colors[c].light['board-text']}'], + .notion-body.dark .notion-board-view [style*='color: ${ + colors[c].dark['board-text'] + }'], + .notion-body:not(.dark) .notion-board-view + [style*='fill: ${colors[c].light['board-text']}'], + .notion-body.dark .notion-board-view [style*='fill: ${ + colors[c].dark['board-text'] + }'] { + color: var(--theme--board_${c}-text) !important; + fill: var(--theme--board_${c}-text) !important; + } + `; + } + return css; +} + +// 'light' or 'dark' +function vars(mode) { + // order in which variables will appear + const sets = { + 'text': '', + 'highlight': '', + 'callout': '', + // tag_default has the same color in light and dark + 'tag': '--theme--tag_default: rgba(206, 205, 202, 0.5);\n--theme--tag_default-text: var(--theme--text);\n', + 'board': '' + }; + + // light gray separately + for (let key in lightGray[mode]) { + const prefix = key.split('-')[0], + value = lightGray[mode][key]; + if (!sets[prefix]) sets[prefix] = ''; + key = [`--theme--${prefix}_light_gray`, ...key.split('-').slice(1)].join('-'); + sets[prefix] += `${key}: ${value};\n`; + } + + // other colors + for (const color in colors) { + for (let key in colors[color][mode]) { + const prefix = key.split('-')[0], + value = colors[color][mode][key]; + if (!sets[prefix]) sets[prefix] = ''; + key = [`--theme--${prefix}_${color}`, ...key.split('-').slice(1)].join('-'); + sets[prefix] += `${key}: ${value};\n`; + } + } + let vars = ''; + for (const set in sets) { + vars += `\n${sets[set]}`; + } + return vars; +} + +if (process.argv.includes('css')) { + console.log(css()); +} else if (process.argv.includes('light')) { + console.log(vars('light')); +} else if (process.argv.includes('dark')) { + console.log(vars('dark')); +} diff --git a/repo/theming/client.mjs b/repo/theming/client.mjs new file mode 100644 index 0000000..88060be --- /dev/null +++ b/repo/theming/client.mjs @@ -0,0 +1,58 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web, registry, storage, electron }, db) { + const enabledThemes = await registry.list( + async (m) => (await registry.enabled(m.id)) && m.tags.includes('theme') + ); + if (enabledThemes.length || (await db.get(['force_load']))) { + // only override colors if theme is enable for perf + web.loadStylesheet('repo/theming/theme.css'); + web.loadStylesheet('repo/theming/colors.css'); + } + + const updateTheme = async () => { + if (document.visibilityState !== 'visible' && !document.hasFocus()) return; + const isDark = + document.querySelector('.notion-dark-theme') || + document.querySelector('.notion-body.dark'), + isLight = document.querySelector('.notion-light-theme'), + mode = isDark ? 'dark' : isLight ? 'light' : ''; + if (!mode) return; + await storage.set(['theme'], mode); + document.documentElement.classList.add(mode); + document.documentElement.classList.remove(mode === 'light' ? 'dark' : 'light'); + electron.sendMessage('update-theme'); + const searchThemeVars = [ + 'bg', + 'text', + 'icon', + 'icon_secondary', + 'accent_blue', + 'accent_blue-text', + 'accent_blue-hover', + 'accent_blue-active', + 'ui_shadow', + 'ui_divider', + 'ui_input', + 'ui_interactive-hover', + 'ui_interactive-active', + ].map((key) => [ + key, + window.getComputedStyle(document.documentElement).getPropertyValue(`--theme--${key}`), + ]); + electron.sendMessage('set-search-theme', searchThemeVars); + }; + web.addDocumentObserver((mutation) => { + const potentialThemeChange = mutation.target.matches?.('html, body, .notion-app-inner'); + if (potentialThemeChange && document.hasFocus()) updateTheme(); + }); + updateTheme(); + document.addEventListener('visibilitychange', updateTheme); + document.addEventListener('focus', updateTheme); +} diff --git a/repo/theming/colors.css b/repo/theming/colors.css new file mode 100644 index 0000000..d615c01 --- /dev/null +++ b/repo/theming/colors.css @@ -0,0 +1,1218 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +/* light gray */ + +.notion-body:not(.dark) + [style*='background: rgba(227, 226, 224, 0.5)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgba(71, 76, 80, 0.7)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_light_gray) !important; + color: var(--theme--tag_light_gray-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(227, 226, 224, 0.5)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgba(107, 112, 116, 0.7)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_light_gray) !important; + color: var(--theme--tag_light_gray-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(249, 249, 245, 0.5)'], +.notion-body.dark .notion-board-group[style*='background-color: rgba(51, 55, 59, 0.7)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(249, 249, 245, 0.5)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(51, 55, 59, 0.7)'] { + background: var(--theme--board_light_gray) !important; + color: var(--theme--board_light_gray-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(249, 249, 245, 0.5)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgba(51, 55, 59, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_light_gray-card) !important; + color: var(--theme--board_light_gray-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgba(51, 55, 59, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_light_gray-card_text, + var(--theme--board_light_gray-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(249, 249, 245, 0.5)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgba(51, 55, 59, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgba(145, 145, 142, 0.5)'], +.notion-body.dark .notion-board-view [style*='color: rgba(107, 112, 116, 0.7)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgba(145, 145, 142, 0.5)'], +.notion-body.dark .notion-board-view [style*='fill: rgba(107, 112, 116, 0.7)'] { + color: var(--theme--board_light_gray-text) !important; + fill: var(--theme--board_light_gray-text) !important; +} + +/* gray */ + +.notion-body:not(.dark) [style*='color: rgb(120, 119, 116)'], +.notion-body:not(.dark) [style*='color:rgba(120, 119, 116, 1)'], +.notion-body.dark [style*='color: rgb(159, 164, 169)'], +.notion-body.dark [style*='color:rgba(159, 164, 169, 1)'] { + color: var(--theme--text_gray) !important; + fill: var(--theme--text_gray) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(241, 241, 239, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(241, 241, 239, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgb(241, 241, 239)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgb(241, 241, 239)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(241, 241, 239, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(60, 65, 68, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(60, 65, 68, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(60, 65, 68)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(60, 65, 68)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(60, 65, 68, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_gray) !important; + color: var(--theme--highlight_gray-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgb(241, 241, 239)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(60, 65, 68)'] { + background: var(--theme--callout_gray) !important; + color: var(--theme--callout_gray-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(227, 226, 224)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(71, 76, 80)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_gray) !important; + color: var(--theme--tag_gray-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgb(241, 241, 239)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(60, 65, 68)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_gray) !important; + color: var(--theme--highlight_gray-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(227, 226, 224)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(107, 112, 116)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_gray) !important; + color: var(--theme--tag_gray-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(247, 247, 245, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(51, 55, 59)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(247, 247, 245, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(51, 55, 59)'] { + background: var(--theme--board_gray) !important; + color: var(--theme--board_gray-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(247, 247, 245, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(51, 55, 59)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_gray-card) !important; + color: var(--theme--board_gray-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(51, 55, 59)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_gray-card_text, + var(--theme--board_gray-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(247, 247, 245, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(51, 55, 59)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(145, 145, 142)'], +.notion-body.dark .notion-board-view [style*='color: rgb(107, 112, 116)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(145, 145, 142)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(107, 112, 116)'] { + color: var(--theme--board_gray-text) !important; + fill: var(--theme--board_gray-text) !important; +} + +/* brown */ + +.notion-body:not(.dark) [style*='color: rgb(159, 107, 83)'], +.notion-body:not(.dark) [style*='color:rgba(159, 107, 83, 1)'], +.notion-body.dark [style*='color: rgb(212, 150, 117)'], +.notion-body.dark [style*='color:rgba(212, 150, 117, 1)'] { + color: var(--theme--text_brown) !important; + fill: var(--theme--text_brown) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(244, 238, 238, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(244, 238, 238, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgb(244, 238, 238)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgb(244, 238, 238)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(244, 238, 238, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(76, 61, 53, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(76, 61, 53, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(76, 61, 53)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(76, 61, 53)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(76, 61, 53, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_brown) !important; + color: var(--theme--highlight_brown-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgb(244, 238, 238)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(76, 61, 53)'] { + background: var(--theme--callout_brown) !important; + color: var(--theme--callout_brown-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(238, 224, 218)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(92, 71, 61)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_brown) !important; + color: var(--theme--tag_brown-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgb(244, 238, 238)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(76, 61, 53)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_brown) !important; + color: var(--theme--highlight_brown-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(238, 224, 218)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(155, 98, 69)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_brown) !important; + color: var(--theme--tag_brown-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(250, 246, 245, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(59, 54, 51)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(250, 246, 245, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(59, 54, 51)'] { + background: var(--theme--board_brown) !important; + color: var(--theme--board_brown-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(250, 246, 245, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(59, 54, 51)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_brown-card) !important; + color: var(--theme--board_brown-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(59, 54, 51)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_brown-card_text, + var(--theme--board_brown-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(250, 246, 245, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(59, 54, 51)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(187, 132, 108)'], +.notion-body.dark .notion-board-view [style*='color: rgb(155, 98, 69)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(187, 132, 108)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(155, 98, 69)'] { + color: var(--theme--board_brown-text) !important; + fill: var(--theme--board_brown-text) !important; +} + +/* orange */ + +.notion-body:not(.dark) [style*='color: rgb(217, 115, 13)'], +.notion-body:not(.dark) [style*='color:rgba(217, 115, 13, 1)'], +.notion-body.dark [style*='color: rgb(217, 133, 56)'], +.notion-body.dark [style*='color:rgba(217, 133, 56, 1)'] { + color: var(--theme--text_orange) !important; + fill: var(--theme--text_orange) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(251, 236, 221, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(251, 236, 221, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgb(251, 236, 221)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgb(251, 236, 221)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(251, 236, 221, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(85, 59, 41, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(85, 59, 41, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(85, 59, 41)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(85, 59, 41)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(85, 59, 41, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_orange) !important; + color: var(--theme--highlight_orange-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgb(251, 236, 221)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(85, 59, 41)'] { + background: var(--theme--callout_orange) !important; + color: var(--theme--callout_orange-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(250, 222, 201)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(136, 84, 44)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_orange) !important; + color: var(--theme--tag_orange-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgb(251, 236, 221)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(85, 59, 41)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_orange) !important; + color: var(--theme--highlight_orange-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(250, 222, 201)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(168, 92, 30)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_orange) !important; + color: var(--theme--tag_orange-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(252, 245, 242, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(61, 54, 49)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(252, 245, 242, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(61, 54, 49)'] { + background: var(--theme--board_orange) !important; + color: var(--theme--board_orange-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(252, 245, 242, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(61, 54, 49)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_orange-card) !important; + color: var(--theme--board_orange-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(61, 54, 49)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_orange-card_text, + var(--theme--board_orange-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(252, 245, 242, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(61, 54, 49)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(215, 129, 58)'], +.notion-body.dark .notion-board-view [style*='color: rgb(168, 92, 30)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(215, 129, 58)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(168, 92, 30)'] { + color: var(--theme--board_orange-text) !important; + fill: var(--theme--board_orange-text) !important; +} + +/* yellow */ + +.notion-body:not(.dark) [style*='color: rgb(203, 145, 47)'], +.notion-body:not(.dark) [style*='color:rgba(203, 145, 47, 1)'], +.notion-body.dark [style*='color: rgb(201, 145, 38)'], +.notion-body.dark [style*='color:rgba(201, 145, 38, 1)'] { + color: var(--theme--text_yellow) !important; + fill: var(--theme--text_yellow) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(251, 243, 219, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(251, 243, 219, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgb(251, 243, 219)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgb(251, 243, 219)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(251, 243, 219, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(79, 64, 41, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(79, 64, 41, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(79, 64, 41)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(79, 64, 41)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(79, 64, 41, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_yellow) !important; + color: var(--theme--highlight_yellow-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgb(251, 243, 219)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(79, 64, 41)'] { + background: var(--theme--callout_yellow) !important; + color: var(--theme--callout_yellow-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(253, 236, 200)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(146, 118, 63)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_yellow) !important; + color: var(--theme--tag_yellow-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgb(251, 243, 219)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(79, 64, 41)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_yellow) !important; + color: var(--theme--highlight_yellow-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(253, 236, 200)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(137, 107, 42)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_yellow) !important; + color: var(--theme--tag_yellow-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(250, 247, 237, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(56, 55, 49)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(250, 247, 237, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(56, 55, 49)'] { + background: var(--theme--board_yellow) !important; + color: var(--theme--board_yellow-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(250, 247, 237, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(56, 55, 49)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_yellow-card) !important; + color: var(--theme--board_yellow-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(56, 55, 49)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_yellow-card_text, + var(--theme--board_yellow-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(250, 247, 237, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(56, 55, 49)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(203, 148, 51)'], +.notion-body.dark .notion-board-view [style*='color: rgb(137, 107, 42)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(203, 148, 51)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(137, 107, 42)'] { + color: var(--theme--board_yellow-text) !important; + fill: var(--theme--board_yellow-text) !important; +} + +/* green */ + +.notion-body:not(.dark) [style*='color: rgb(68, 131, 97)'], +.notion-body:not(.dark) [style*='color:rgba(68, 131, 97, 1)'], +.notion-body.dark [style*='color: rgb(113, 178, 131)'], +.notion-body.dark [style*='color:rgba(113, 178, 131, 1)'] { + color: var(--theme--text_green) !important; + fill: var(--theme--text_green) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(237, 243, 236, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(237, 243, 236, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgb(237, 243, 236)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgb(237, 243, 236)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(237, 243, 236, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(46, 68, 58, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(46, 68, 58, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(46, 68, 58)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(46, 68, 58)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(46, 68, 58, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_green) !important; + color: var(--theme--highlight_green-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgb(237, 243, 236)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(46, 68, 58)'] { + background: var(--theme--callout_green) !important; + color: var(--theme--callout_green-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(219, 237, 219)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(50, 82, 65)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_green) !important; + color: var(--theme--tag_green-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgb(237, 243, 236)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(46, 68, 58)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_green) !important; + color: var(--theme--highlight_green-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(219, 237, 219)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(61, 124, 86)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_green) !important; + color: var(--theme--tag_green-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(244, 248, 243, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(49, 57, 53)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(244, 248, 243, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(49, 57, 53)'] { + background: var(--theme--board_green) !important; + color: var(--theme--board_green-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(244, 248, 243, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(49, 57, 53)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_green-card) !important; + color: var(--theme--board_green-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(49, 57, 53)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_green-card_text, + var(--theme--board_green-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(244, 248, 243, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(49, 57, 53)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(108, 155, 125)'], +.notion-body.dark .notion-board-view [style*='color: rgb(61, 124, 86)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(108, 155, 125)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(61, 124, 86)'] { + color: var(--theme--board_green-text) !important; + fill: var(--theme--board_green-text) !important; +} + +/* blue */ + +.notion-body:not(.dark) [style*='color: rgb(51, 126, 169)'], +.notion-body:not(.dark) [style*='color:rgba(51, 126, 169, 1)'], +.notion-body.dark [style*='color: rgb(102, 170, 218)'], +.notion-body.dark [style*='color:rgba(102, 170, 218, 1)'] { + color: var(--theme--text_blue) !important; + fill: var(--theme--text_blue) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(231, 243, 248, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(231, 243, 248, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgb(231, 243, 248)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgb(231, 243, 248)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(231, 243, 248, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(45, 66, 86, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(45, 66, 86, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(45, 66, 86)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(45, 66, 86)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(45, 66, 86, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_blue) !important; + color: var(--theme--highlight_blue-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgb(231, 243, 248)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(45, 66, 86)'] { + background: var(--theme--callout_blue) !important; + color: var(--theme--callout_blue-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(211, 229, 239)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(42, 78, 107)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_blue) !important; + color: var(--theme--tag_blue-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgb(231, 243, 248)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(45, 66, 86)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_blue) !important; + color: var(--theme--highlight_blue-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(211, 229, 239)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(46, 117, 164)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_blue) !important; + color: var(--theme--tag_blue-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(241, 248, 251, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(49, 56, 64)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(241, 248, 251, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(49, 56, 64)'] { + background: var(--theme--board_blue) !important; + color: var(--theme--board_blue-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(241, 248, 251, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(49, 56, 64)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_blue-card) !important; + color: var(--theme--board_blue-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(49, 56, 64)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_blue-card_text, + var(--theme--board_blue-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(241, 248, 251, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(49, 56, 64)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(91, 151, 189)'], +.notion-body.dark .notion-board-view [style*='color: rgb(46, 117, 164)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(91, 151, 189)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(46, 117, 164)'] { + color: var(--theme--board_blue-text) !important; + fill: var(--theme--board_blue-text) !important; +} + +/* purple */ + +.notion-body:not(.dark) [style*='color: rgb(144, 101, 176)'], +.notion-body:not(.dark) [style*='color:rgba(144, 101, 176, 1)'], +.notion-body.dark [style*='color: rgb(176, 152, 217)'], +.notion-body.dark [style*='color:rgba(176, 152, 217, 1)'] { + color: var(--theme--text_purple) !important; + fill: var(--theme--text_purple) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(244, 240, 247, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(244, 240, 247, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgba(244, 240, 247, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(244, 240, 247, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(244, 240, 247, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(69, 58, 91, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(69, 58, 91, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(69, 58, 91)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(69, 58, 91)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(69, 58, 91, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_purple) !important; + color: var(--theme--highlight_purple-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgba(244, 240, 247, 0.8)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(69, 58, 91)'] { + background: var(--theme--callout_purple) !important; + color: var(--theme--callout_purple-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(232, 222, 238)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(83, 68, 116)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_purple) !important; + color: var(--theme--tag_purple-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(244, 240, 247, 0.8)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(69, 58, 91)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_purple) !important; + color: var(--theme--highlight_purple-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(232, 222, 238)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(123, 96, 180)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_purple) !important; + color: var(--theme--tag_purple-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(249, 246, 252, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(57, 53, 65)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(249, 246, 252, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(57, 53, 65)'] { + background: var(--theme--board_purple) !important; + color: var(--theme--board_purple-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(249, 246, 252, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(57, 53, 65)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_purple-card) !important; + color: var(--theme--board_purple-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(57, 53, 65)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_purple-card_text, + var(--theme--board_purple-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(249, 246, 252, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(57, 53, 65)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(167, 130, 195)'], +.notion-body.dark .notion-board-view [style*='color: rgb(123, 96, 180)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(167, 130, 195)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(123, 96, 180)'] { + color: var(--theme--board_purple-text) !important; + fill: var(--theme--board_purple-text) !important; +} + +/* pink */ + +.notion-body:not(.dark) [style*='color: rgb(193, 76, 138)'], +.notion-body:not(.dark) [style*='color:rgba(193, 76, 138, 1)'], +.notion-body.dark [style*='color: rgb(223, 132, 209)'], +.notion-body.dark [style*='color:rgba(223, 132, 209, 1)'] { + color: var(--theme--text_pink) !important; + fill: var(--theme--text_pink) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(249, 238, 243, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(249, 238, 243, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgba(249, 238, 243, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(249, 238, 243, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(249, 238, 243, 0.8)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(81, 56, 77, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(81, 56, 77, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(81, 56, 77)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(81, 56, 77)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(81, 56, 77, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_pink) !important; + color: var(--theme--highlight_pink-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgba(249, 238, 243, 0.8)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(81, 56, 77)'] { + background: var(--theme--callout_pink) !important; + color: var(--theme--callout_pink-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(245, 224, 233)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(106, 59, 99)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_pink) !important; + color: var(--theme--tag_pink-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(249, 238, 243, 0.8)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(81, 56, 77)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_pink) !important; + color: var(--theme--highlight_pink-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(245, 224, 233)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(169, 76, 157)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_pink) !important; + color: var(--theme--tag_pink-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(251, 245, 251, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(60, 53, 58)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(251, 245, 251, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(60, 53, 58)'] { + background: var(--theme--board_pink) !important; + color: var(--theme--board_pink-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(251, 245, 251, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(60, 53, 58)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_pink-card) !important; + color: var(--theme--board_pink-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(60, 53, 58)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_pink-card_text, + var(--theme--board_pink-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(251, 245, 251, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(60, 53, 58)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(205, 116, 159)'], +.notion-body.dark .notion-board-view [style*='color: rgb(169, 76, 157)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(205, 116, 159)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(169, 76, 157)'] { + color: var(--theme--board_pink-text) !important; + fill: var(--theme--board_pink-text) !important; +} + +/* red */ + +.notion-body:not(.dark) [style*='color: rgb(212, 76, 71)'], +.notion-body:not(.dark) [style*='color:rgba(212, 76, 71, 1)'], +.notion-body.dark [style*='color: rgb(234, 135, 140)'], +.notion-body.dark [style*='color:rgba(234, 135, 140, 1)'] { + color: var(--theme--text_red) !important; + fill: var(--theme--text_red) !important; +} + +.notion-body:not(.dark) + [style*='background: rgba(253, 235, 236, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgba(253, 235, 236, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background: rgb(253, 235, 236)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background:rgb(253, 235, 236)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body:not(.dark) + [style*='background-color: rgba(253, 235, 236, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgba(94, 52, 54, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgba(94, 52, 54, 1)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background: rgb(94, 52, 54)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background:rgb(94, 52, 54)']:not([style*='border-radius']):not([style*='box-shadow']), +.notion-body.dark + [style*='background-color: rgba(94, 52, 54, 1)']:not([style*='border-radius']):not([style*='box-shadow']) { + background: var(--theme--highlight_red) !important; + color: var(--theme--highlight_red-text) !important; +} + +.notion-body:not(.dark) + .notion-callout-block + > div + > [style*='background: rgb(253, 235, 236)'], +.notion-body.dark .notion-callout-block > div > [style*='background: rgb(94, 52, 54)'] { + background: var(--theme--callout_red) !important; + color: var(--theme--callout_red-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(255, 226, 221)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'], +.notion-body.dark + [style*='background: rgb(122, 54, 59)'][style*='align-items: center;'][style*='border-radius: 3px; padding-left: '][style*='line-height: 120%;'] { + background: var(--theme--tag_red) !important; + color: var(--theme--tag_red-text) !important; +} + +.notion-body:not(.dark) + [style*='background: rgb(253, 235, 236)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'], +.notion-body.dark + [style*='background: rgb(94, 52, 54)'][style*='align-items: center; justify-content: center; width: 22px; height: 22px;'][style*='border-radius: 3px; font-weight: 500;'] { + background: var(--theme--highlight_red) !important; + color: var(--theme--highlight_red-text) !important; +} +.notion-body:not(.dark) + [style*='background: rgb(255, 226, 221)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'], +.notion-body.dark + [style*='background: rgb(194, 65, 82)'][style*='border-radius: 3px;'][style*='width: 18px; height: 18px;'] { + background: var(--theme--tag_red) !important; + color: var(--theme--tag_red-text) !important; +} + +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(253, 245, 243, 0.7)'], +.notion-body.dark .notion-board-group[style*='background-color: rgb(66, 51, 51)'], +.notion-body:not(.dark) + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgba(253, 245, 243, 0.7)'], +.notion-body.dark + .notion-board-view + > .notion-selectable + > :first-child + > :nth-child(2) + [style*='background-color: rgb(66, 51, 51)'] { + background: var(--theme--board_red) !important; + color: var(--theme--board_red-text) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(253, 245, 243, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'], +.notion-body.dark + .notion-board-group[style*='background-color: rgb(66, 51, 51)'] + > [data-block-id] + > [rel='noopener noreferrer'] { + background: var(--theme--board_red-card) !important; + color: var(--theme--board_red-card_text) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(66, 51, 51)'] + > [data-block-id] + > [rel='noopener noreferrer'] + [placeholder='Untitled'] { + -webkit-text-fill-color: var( + --theme--board_red-card_text, + var(--theme--board_red-text) + ) !important; +} +.notion-body:not(.dark) + .notion-board-group[style*='background-color: rgba(253, 245, 243, 0.7)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(255, 255, 255, 0.2) !important; +} +.notion-body.dark + .notion-board-group[style*='background-color: rgb(66, 51, 51)'] + > [data-block-id] + > [rel='noopener noreferrer'] + > .notion-focusable:hover { + background: rgba(0, 0, 0, 0.1) !important; +} +.notion-body:not(.dark) .notion-board-view [style*='color: rgb(225, 111, 100)'], +.notion-body.dark .notion-board-view [style*='color: rgb(194, 65, 82)'], +.notion-body:not(.dark) .notion-board-view [style*='fill: rgb(225, 111, 100)'], +.notion-body.dark .notion-board-view [style*='fill: rgb(194, 65, 82)'] { + color: var(--theme--board_red-text) !important; + fill: var(--theme--board_red-text) !important; +} diff --git a/repo/theming/electronSearch.css b/repo/theming/electronSearch.css new file mode 100644 index 0000000..c1dcf0b --- /dev/null +++ b/repo/theming/electronSearch.css @@ -0,0 +1,61 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +#container { + background: var(--theme--bg) !important; + box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.05)) 0px 0px 0px 1px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.1)) 0px 3px 6px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.2)) 0px 9px 24px !important; +} + +#container #results { + color: var(--theme--text) !important; +} + +#container #prev, +#container #next { + border-color: var(--theme--ui_divider) !important; +} +#container .enabled:focus, +#container .enabled:hover { + background: var(--theme--ui_interactive-hover) !important; +} +#container .enabled:active { + background: var(--theme--ui_interactive-active) !important; +} +#container #prev svg, +#container #next svg { + fill: var(--theme--icon_secondary) !important; +} +#container #button-separator { + background: var(--theme--ui_divider) !important; +} + +#container #search-icon svg, +#container #clear-icon svg { + fill: var(--theme--icon) !important; +} +#container #input-wrap #search { + background: var(--theme--ui_input) !important; + color: var(--theme--text) !important; +} + +#container #done { + background: var(--theme--accent_blue) !important; + color: var(--theme--accent_blue-text) !important; +} +#container #done:focus, +#container #done:hover { + background: var(--theme--accent_blue-hover) !important; +} +#container #done:active { + background: var(--theme--accent_blue-active) !important; +} + +#container .enabled::after, +#container #done::after { + background: transparent !important; +} diff --git a/repo/theming/frame.mjs b/repo/theming/frame.mjs new file mode 100644 index 0000000..a02d873 --- /dev/null +++ b/repo/theming/frame.mjs @@ -0,0 +1,19 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web, storage, electron }, db) { + await web.whenReady(); + + const updateTheme = async () => { + const mode = await storage.get(['theme'], 'light'); + document.documentElement.classList.add(mode); + document.documentElement.classList.remove(mode === 'light' ? 'dark' : 'light'); + }; + electron.onMessage('update-theme', updateTheme); + updateTheme(); +} diff --git a/repo/theming/main.cjs b/repo/theming/main.cjs new file mode 100644 index 0000000..750623f --- /dev/null +++ b/repo/theming/main.cjs @@ -0,0 +1,21 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = async function ({}, db, __exports, __eval) { + const electron = require('electron'); + electron.ipcMain.on('notion-enhancer:update-theme', () => { + electron.webContents + .getAllWebContents() + .forEach((webContents) => webContents.send('notion-enhancer:update-theme')); + }); + electron.ipcMain.on('notion-enhancer:set-search-theme', (event, theme) => { + electron.webContents + .getAllWebContents() + .forEach((webContents) => webContents.send('notion-enhancer:set-search-theme', theme)); + }); +}; diff --git a/repo/theming/menu.mjs b/repo/theming/menu.mjs new file mode 100644 index 0000000..7e65808 --- /dev/null +++ b/repo/theming/menu.mjs @@ -0,0 +1,26 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web, registry, storage, electron }, db) { + await web.whenReady(); + + const updateTheme = async () => { + const mode = await storage.get(['theme'], 'light'); + document.documentElement.classList.add(mode); + document.documentElement.classList.remove(mode === 'light' ? 'dark' : 'light'); + }; + document.addEventListener('visibilitychange', updateTheme); + electron.onMessage('update-theme', updateTheme); + updateTheme(); + + for (const mod of await registry.list((mod) => registry.enabled(mod.id))) { + for (const sheet of mod.css?.menu || []) { + web.loadStylesheet(`repo/${mod._dir}/${sheet}`); + } + } +} diff --git a/repo/theming/mod.json b/repo/theming/mod.json new file mode 100644 index 0000000..dca8b51 --- /dev/null +++ b/repo/theming/mod.json @@ -0,0 +1,38 @@ +{ + "name": "theming", + "id": "0f0bf8b6-eae6-4273-b307-8fc43f2ee082", + "version": "0.11.0", + "description": "the default theme variables, required by other themes & extensions.", + "tags": ["core"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "frame": ["variables.css"], + "client": ["variables.css", "prism.css", "patches.css"], + "menu": ["variables.css"] + }, + "js": { + "frame": ["frame.mjs"], + "client": ["client.mjs"], + "menu": ["menu.mjs"], + "electron": [ + { "source": "main.cjs", "target": "main/main.js" }, + { "source": "rendererSearch.cjs", "target": "renderer/search.js" } + ] + }, + "options": [ + { + "type": "toggle", + "key": "force_load", + "label": "force load overrides", + "tooltip": "**override notion's colours even if no themes are enabled**", + "value": false + } + ] +} diff --git a/repo/theming/patches.css b/repo/theming/patches.css new file mode 100644 index 0000000..7f307d8 --- /dev/null +++ b/repo/theming/patches.css @@ -0,0 +1,253 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +/** layout **/ + +.notion-frame + > .notion-scroller.vertical.horizontal + > .pseudoSelection + > div + > div:nth-child(3)[style*='width: 900px'], +.notion-frame + > .notion-scroller.vertical.horizontal + > .pseudoSelection + + div + > :nth-child(1)[style*='width: 900px'], +.notion-frame + > .notion-scroller.vertical.horizontal + > :nth-child(2) + > :nth-child(2)[style*='display: flex; width: 100%; justify-content: center;'] + > :nth-child(1)[style*='width: 900px'] { + width: var(--theme--page-width) !important; +} +.notion-frame + > .notion-scroller.vertical.horizontal + > .pseudoSelection + > div + > div:nth-child(3):not([style*='width: 900px']), +.notion-frame + > .notion-scroller.vertical.horizontal + > .pseudoSelection + + div + > :nth-child(1):not([style*='width: 900px']), +.notion-frame + > .notion-scroller.vertical.horizontal + > :nth-child(2) + > :nth-child(2)[style*='display: flex; width: 100%; justify-content: center;'] + > :nth-child(1):not([style*='width: 900px']) { + width: var(--theme--page-width_full) !important; +} +.notion-page-content [style*='width: 100%; max-width:'][style*='align-self: center;'] { + max-width: 100% !important; +} +.notion-frame [style*='padding-right: calc(96px + env(safe-area-inset-right));'] { + padding-right: var(--theme--page-padding) !important; +} +.notion-frame [style*='padding-left: calc(96px + env(safe-area-inset-left));'] { + padding-left: var(--theme--page-padding) !important; +} +[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;'], +[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;'] + img { + height: var(--theme--page_banner-height) !important; + background: transparent !important; +} + +.notion-peek-renderer > :nth-child(2) { + max-width: var(--theme--page_preview-width) !important; +} +.notion-peek-renderer + .notion-scroller.vertical + [style*='padding-left: calc(126px + env(safe-area-inset-left));'] { + padding-left: var(--theme--page_preview-padding) !important; +} +.notion-peek-renderer + .notion-scroller.vertical + [style*='padding-right: calc(126px + env(safe-area-inset-right));'] { + padding-right: var(--theme--page_preview-padding) !important; +} +.notion-peek-renderer + .notion-scroller.vertical + [style*='margin-left: calc(126px + env(safe-area-inset-left));'] { + margin-left: var(--theme--page_preview-padding) !important; +} +.notion-peek-renderer + .notion-scroller.vertical + [style*='margin-right: calc(126px + env(safe-area-inset-right));'] { + margin-right: var(--theme--page_preview-padding) !important; +} +.notion-peek-renderer .notion-page-content { + padding-left: var(--theme--page_preview-padding) !important; + padding-right: var(--theme--page_preview-padding) !important; + width: 100%; +} +.notion-peek-renderer + .notion-scroller.vertical + [style*='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 20vh;'], +.notion-peek-renderer + .notion-scroller.vertical + [style*='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 20vh;'] + img { + height: var(--theme--page_preview_banner-height) !important; + background: transparent !important; +} + +.notion-topbar-action-buttons { + width: auto !important; +} +.notion-cursor-listener > [style*='z-index: 102'] { + z-index: 99 !important; +} + +/* typography */ + +[style*='Segoe UI'] { + font-family: var(--theme--font_sans) !important; +} +[style*='Georgia'] { + font-family: var(--theme--font_serif) !important; +} +[style*='iawriter-mono'] { + font-family: var(--theme--font_mono) !important; +} +[style*='SFMono-Regular'] { + font-family: var(--theme--font_code) !important; +} + +/** remove white pixels in iframe corners **/ + +.notion-page-content iframe { + border-radius: 0px !important; +} + +/** scrollbars **/ + +::-webkit-scrollbar-track, +::-webkit-scrollbar-corner { + background: var(--theme--scrollbar_track) !important; +} +::-webkit-scrollbar-thumb { + background: var(--theme--scrollbar_thumb) !important; +} +::-webkit-scrollbar-thumb:hover { + background: var(--theme--scrollbar_thumb-hover) !important; +} + +/** consistent corner button styling **/ + +.notion-overlay-container + [style*='border-radius: 3px;'][style*='position: relative; max-width: calc(100vw - 24px); box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px; overflow: hidden;'][style*='padding: 4px 8px; font-size: 12px; line-height: 1.4; font-weight: 500;'] { + background: var(--theme--ui_tooltip) !important; + box-shadow: var(--theme--ui_shadow) 0px 1px 4px !important; + color: var(--theme--ui_tooltip-title) !important; +} +.notion-overlay-container + [style*='border-radius: 3px;'][style*='position: relative; max-width: calc(100vw - 24px); box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px; overflow: hidden;'][style*='padding: 4px 8px; font-size: 12px; line-height: 1.4; font-weight: 500;'] + [style*='color: '] { + color: var(--theme--ui_tooltip-description) !important; +} +.onboarding-checklist-button > .graduationCap + .notion-focusable { + background: var(--theme--ui_tooltip) !important; +} +.onboarding-checklist-button .closeSmall { + fill: var(--theme--ui_tooltip-title) !important; +} +.graduationCap { + fill: var(--theme--icon) !important; +} +.notion-help-button, +.onboarding-checklist-button { + opacity: 1 !important; + color: var(--theme--icon); + fill: var(--theme--icon); + background: var(--theme--ui_corner_action) !important; + box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.15)) 0px 0px 0px 1px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.15)) 0px 2px 4px !important; + cursor: pointer; +} +.notion-help-button:hover, +.onboarding-checklist-button:hover { + background: var(--theme--ui_corner_action-hover) !important; +} +.notion-help-button:active, +.onboarding-checklist-button:active { + background: var(--theme--ui_corner_action-active) !important; +} + +/* backgrounds */ + +[style*='height: calc(100% + 17px); background:'][style*='width: 20px; margin-left: -20px; margin-top: -17px;'], +.notion-board-view .notion-focusable[role='button'][style*='height: 33px; width: 35px'], +.notion-board-view + > :first-child + > :first-child + > :last-child[style*='background'][style*='margin-left: 20px'], +.notion-discussion-input > div > div[style*='background'], +.notion-body.dark + .notion-default-overlay-container + [style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];'] + [style*='grid-column: property-start / value-end; background: rgba(255, 255, 255, 0.02);'], +.notion-body:not(.dark) + .notion-default-overlay-container + [style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];'] + [style*='grid-column: property-start / value-end; background: rgba(0, 0, 0, 0.02);'], +.notion-board-view [style*='width: 20px; margin-left: -20px; margin-top: -8px;'], +.notion-page-block > div > div > div[style*='background-color: white;'], +.line-numbers.notion-code-block + div .notion-focusable:not(:hover), +.notion-overlay-container + [style*='position: relative; max-width: calc(100vw - 24px); box-shadow:'] + > [style*='display: flex; align-items: center; padding: 8px 10px; width: 100%; background:'], +.notion-default-overlay-container + > div:nth-child(3) + > div + > div:nth-child(2) + > div:nth-child(2) + > div + > div + > div + > div + > div + > div:nth-child(2)[style*='position: absolute; display: inline-flex; min-width: 100%; height: 32px; z-index: 1; background:'], +.notion-default-overlay-container + > div:nth-child(2) + > div + > div:nth-child(2) + > div:nth-child(2) + > div + > div + > div + > div + > div + > div:nth-child(2)[style*='position: absolute; display: inline-flex; min-width: 100%; height: 32px; z-index: 1; background:'], +.notion-frame .notion-scroller[style*='background:'], +.notion-page-template-modal .notion-scroller[style*='background:'], +.notion-peek-renderer .notion-scroller[style*='background:'], +.notion-frame > div > div > div[style*='max-width: 100%'][style*='background-color'], +.notion-peek-renderer + > div + > .notion-scroller + > div + > div[style*='max-width: 100%'][style*='background-color'], +.notion-page-template-modal + > div + > .notion-scroller + > div + > div[style*='max-width: 100%'][style*='background-color'], +.notion-selectable.notion-collection_view-block + .notion-board-view + > .notion-selectable.notion-collection_view-block + > :first-child + > [style*='width: 20px'], +.notion-body.dark + [style*='background: linear-gradient(rgba(47, 52, 55, 0) 0px, rgb(47, 52, 55) 10px, rgb(47, 52, 55) 100%);'], +.notion-body:not(.dark) + [style*='background: linear-gradient(rgba(255, 255, 255, 0) 0px, white 10px, white 100%);'], +.notion-body.dark .notion-collection_view_page-block [style*='background: rgb(47, 52, 55);'], +.notion-body:not(.dark) + .notion-collection_view_page-block + [style*='background: white;']:not([style*='box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, rgba(15, 15, 15, 0.1) 0px 2px 4px;']) { + background: transparent !important; +} diff --git a/repo/theming/prism.css b/repo/theming/prism.css new file mode 100644 index 0000000..42d82bc --- /dev/null +++ b/repo/theming/prism.css @@ -0,0 +1,156 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.token.property { + color: var(--theme--code_property) !important; +} +.token.tag { + color: var(--theme--code_tag) !important; +} +.token.boolean { + color: var(--theme--code_boolean) !important; +} +.token.number { + color: var(--theme--code_number) !important; +} +.token.constant { + color: var(--theme--code_constant) !important; +} +.token.symbol { + color: var(--theme--code_symbol) !important; +} +.token.deleted { + color: var(--theme--code_deleted) !important; +} +.token.selector { + color: var(--theme--code_selector) !important; +} +.token.attr-name { + color: var(--theme--code_attr-name) !important; +} +.token.string { + color: var(--theme--code_string) !important; +} +.token.char { + color: var(--theme--code_char) !important; +} +.token.builtin { + color: var(--theme--code_builtin) !important; +} +.token.inserted { + color: var(--theme--code_inserted) !important; +} +.token.operator { + color: var(--theme--code_operator) !important; +} +.token.entity { + color: var(--theme--code_entity) !important; +} +.token.url { + color: var(--theme--code_url) !important; +} +.token.variable { + color: var(--theme--code_variable) !important; +} +.token.comment { + color: var(--theme--code_comment) !important; +} +.token.cdata { + color: var(--theme--code_cdata) !important; +} +.token.prolog { + color: var(--theme--code_prolog) !important; +} +.token.doctype { + color: var(--theme--code_doctype) !important; +} +.token.atrule { + color: var(--theme--code_atrule) !important; +} +.token.attr-value { + color: var(--theme--code_attr-value) !important; +} +.token.keyword { + color: var(--theme--code_keyword) !important; +} +.token.regex { + color: var(--theme--code_regex) !important; +} +.token.important { + color: var(--theme--code_important) !important; +} +.token.function { + color: var(--theme--code_function) !important; +} +.token.class-name { + color: var(--theme--code_class-name) !important; +} +.token.parameter { + color: var(--theme--code_parameter) !important; +} +.token.decorator { + color: var(--theme--code_decorator) !important; +} +.token.id { + color: var(--theme--code_id) !important; +} +.token.class { + color: var(--theme--code_class) !important; +} +.token.pseudo-element { + color: var(--theme--code_pseudo-element) !important; +} +.token.pseudo-class { + color: var(--theme--code_pseudo-class) !important; +} +.token.attribute { + color: var(--theme--code_attribute) !important; +} +.token.value { + color: var(--theme--code_value) !important; +} +.token.unit { + color: var(--theme--code_unit) !important; +} +.token.punctuation { + color: var(--theme--code_punctuation) !important; + opacity: 0.7 !important; +} +.token.annotation { + color: var(--theme--code_annotation) !important; +} + +.token.operator { + background: transparent !important; +} +.token.namespace { + opacity: 0.7 !important; +} +.token.important, +.token.bold { + font-weight: bold !important; +} +.token.italic { + font-style: italic !important; +} +.token.entity { + cursor: help !important; +} +.token a { + color: inherit !important; +} +.token.punctuation.brace-hover, +.token.punctuation.brace-selected { + outline: solid 1px !important; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + background: none !important; +} diff --git a/repo/theming/rendererSearch.cjs b/repo/theming/rendererSearch.cjs new file mode 100644 index 0000000..ed6a2cb --- /dev/null +++ b/repo/theming/rendererSearch.cjs @@ -0,0 +1,18 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = async function ({ web, electron }, db, __exports, __eval) { + await web.whenReady(); + web.loadStylesheet('repo/theming/electronSearch.css'); + + electron.onMessage('set-search-theme', (event, theme) => { + for (const [key, value] of theme) { + document.documentElement.style.setProperty(`--theme--${key}`, value); + } + }); +}; diff --git a/repo/theming/theme.css b/repo/theming/theme.css new file mode 100644 index 0000000..4473a89 --- /dev/null +++ b/repo/theming/theme.css @@ -0,0 +1,773 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +/* backgrounds */ + +.OnboardingHighlight + div > [style*='background-color'] { + background-color: rgba(0, 0, 0, 0.5) !important; +} + +body, +.notion-cursor-listener, +.notion-frame, +.notion-timeline-view, +.notion-workspace-plan-choose, +.notion-onboarding-popup, +.notion-workspace-create, +.notion-workspace-invite, +.notion-scroller.vertical + > [style*='display: flex; justify-content: center; z-index: 3; flex-shrink: 0;'][style*='background: '], +.notion-cursor-listener > div > :first-child[style*='z-index: 100;'], +.notion-space-settings > div > div > div:nth-child(2) > div[style*='background'], +.notion-body.dark .notion-collection_view_page-block > [style*='background: rgb(47, 52, 55)'], +.notion-body.dark .notion-collection_view_page-block[style*='background: rgb(47, 52, 55)'], +.notion-body:not(.dark) .notion-collection_view_page-block > [style*='background: white'], +.notion-body:not(.dark) .notion-collection_view_page-block[style*='background: white'], +.notion-body.dark .notion-collection_view-block > [style*='background: rgb(47, 52, 55)'], +.notion-body.dark .notion-collection_view-block[style*='background: rgb(47, 52, 55)'], +.notion-body:not(.dark) .notion-collection_view-block > [style*='background: white'], +.notion-body:not(.dark) .notion-collection_view-block[style*='background: white'], +.notion-body.dark .notion-timeline-view [style*='background: rgb(47, 52, 55)'], +.notion-body:not(.dark) + .notion-timeline-view + [style*='background: white']:not(.notion-timeline-item), +.notion-body:not(.dark) .notion-timeline-view [style*='background: rgb(253, 253, 253);'], +.notion-updates-menu footer > div[style*='background'], +:not(.notion-sidebar-container) > div > div > .notion-sidebar > :nth-child(2), +:not(.notion-sidebar-container) > div > div > .notion-sidebar > :nth-child(3), +:not(.notion-sidebar-container) > div > div > .notion-sidebar > :nth-child(3) > :nth-child(2), +.notion-peek-renderer > div[style*='background'], +.notion-peek-renderer > div[style*='background'] > :first-child, +.notion-peek-renderer > div[style*='background'] > :first-child > div > :nth-child(3), +.notion-page-template-modal, +.notion-update-sidebar-tab-updates-header, +.notion-update-sidebar-tab-updates-header + .notion-scroller, +.notion-update-sidebar-tab-comments-header, +.notion-update-sidebar-tab-comments-header + div, +.notion-code-block > div > div > [style*='background: '][style$='padding-right: 105px;'], +[style*='z-index: 84'] { + background: var(--theme--bg) !important; +} +.notion-timeline-item-row + div > div > div, +.notion-timeline-view > :nth-child(2) > :first-child > div > div { + border: 1px solid var(--theme--bg) !important; + background: var(--theme--ui_toggle-off) !important; +} +.notion-timeline-item-row + div > div > div svg, +.notion-timeline-view > :nth-child(2) > :first-child > div > div svg { + fill: var(--theme--bg) !important; +} + +.notion-sidebar-container, +.notion-sidebar > [style*='border-top-right-radius'], +.notion-space-settings > div > div > div:first-child[style*='background'], +.notion-body.dark .notion-collection_view_page-block [style*='background: rgb(55, 60, 63)'], +.notion-body:not(.dark) + .notion-collection_view_page-block + [style*='background: rgb(247, 246, 243)'], +.notion-body.dark .notion-collection_view-block [style*='background: rgb(55, 60, 63)'], +.notion-body:not(.dark) + .notion-collection_view-block + [style*='background: rgb(247, 246, 243)'], +.notion-body.dark .notion-timeline-view [style*='background: rgb(55, 60, 63)'], +.notion-body:not(.dark) .notion-timeline-view [style*='background: rgb(247, 246, 243)'], +.notion-space-settings + > div + > div + > div:nth-child(2) + table + td[style*='background:']:not([style*='background: transparent']), +.notion-timeline-view > :first-child > div, +.notion-body:not(.dark) + .notion-timeline-view + > div + > div + > [style*='background: rgb(247, 247, 247); border-radius: 11px;'], +.notion-page-template-modal > :last-child, +.notion-page-template-modal > :last-child > div > :last-child, +.notion-embed-block .pseudoSelection, +.notion-video-block .pseudoSelection, +.notion-image-block .pseudoSelection, +.notion-file-block .pseudoSelection, +.notion-pdf-block .pseudoSelection, +.notion-bookmark-block .pseudoSelection, +.notion-miro-block .pseudoSelection, +.notion-codepen-block .pseudoSelection, +.notion-framer-block .pseudoSelection, +.notion-figma-block .pseudoSelection, +.notion-drive-block .pseudoSelection, +.notion-gist-block .pseudoSelection, +.notion-tweet-block .pseudoSelection, +.notion-maps-block .pseudoSelection, +.notion-replit-block .pseudoSelection, +.notion-typeform-block .pseudoSelection, +.notion-abstract-block .pseudoSelection, +.notion-invision-block .pseudoSelection, +.notion-loom-block .pseudoSelection, +.notion-excalidraw-block .pseudoSelection, +.notion-sketch-block .pseudoSelection, +.notion-whimsical-block .pseudoSelection, +.notion-equation-block > div > div, +.notion-factory-block > div > div > div > div > [style*='background'][style*='margin-top'] { + background: var(--theme--bg_secondary) !important; +} + +.notion-default-overlay-container + [style*='position: absolute; inset: 0px; background: rgba(15, 15, 15, 0.6);']:empty { + background: var(--theme--ui_shadow) !important; +} + +.notion-body.dark + [style*='box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, rgba(15, 15, 15, 0.2) 0px 3px 6px, rgba(15, 15, 15, 0.4) 0px 9px 24px;'], +.notion-body:not(.dark) + [style*='box-shadow: rgba(15, 15, 15, 0.05) 0px 0px 0px 1px, rgba(15, 15, 15, 0.1) 0px 3px 6px, rgba(15, 15, 15, 0.2) 0px 9px 24px;'], +.notion-body.dark + [style*='box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, rgba(15, 15, 15, 0.2) 0px 3px 6px, rgba(15, 15, 15, 0.4) 0px 9px 24px;'], +.notion-body:not(.dark) + [style*='box-shadow: rgba(15, 15, 15, 0.05) 0px 0px 0px 1px, rgba(15, 15, 15, 0.1) 0px 3px 6px, rgba(15, 15, 15, 0.2) 0px 9px 24px;'], +[data-overlay] + > div + > [style*='position: relative; z-index: 1; box-shadow:'][style*='border-radius: 3px;'][style*='margin-bottom: 0px; top: 90px; overflow: hidden; width: 75%; max-width: 600px; min-height: 50px; max-height: 80vh;']:nth-child(2), +.notion-overlay-container.notion-default-overlay-container + [style*='display: flex'] + > [style*='position: relative; max-width:'][style*='overflow: hidden'] + footer + > [style*='background-color:'], +.notion-updates-menu > :first-child > div[style*='background'], +#notion-app + > div + > div.notion-overlay-container.notion-default-overlay-container + > div:nth-child(2) + > div + > div:nth-child(2)[style*='margin-bottom: 0px; top: 90px; overflow: hidden; width: 75%;'], +.notion-default-overlay-container + > div + > div:not(.notion-peek-renderer) + > [style*='box-shadow'], +[style*='z-index:'][style*='box-shadow: '][style*='font-size: 12px;'][style*='min-height: 24px; overflow: hidden; pointer-events:'], +:not(.notion-login) + > .notion-focusable[role='button'][tabindex='0'][style*='box-shadow:'][style*='background:'][style*='transition: background 20ms ease-in 0s; cursor: pointer;']:not([style*='rgb(46, 170, 220);']):not([style*='rgb(6, 156, 205);']):not([style*='rgb(0, 141, 190);']):not([style*='flex: 1 1 0%; white-space: nowrap; height: 26px; border-radius: 3px 0px 0px 3px;']):not([style*='rgb(225, 98, 89)']), +.notion-text-action-menu > div > div, +.notion-default-overlay-container + [style*='min-width: 300px;'] + [style*='width: 240px'] + > .notion-focusable:not(:hover), +.notion-transclusion_reference-block > div > div > :nth-child(3), +.notion-transclusion_container-block > div > div > :nth-child(3), +.notion-page-block > div > div > div > .notion-focusable:not(:hover), +.notion-workspace-create + [style*='font-size: 12px;'] + + .notion-focusable[role='button']:not(:hover) { + background: var(--theme--bg_card) !important; + box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.05)) 0px 0px 0px 1px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.1)) 0px 3px 6px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.2)) 0px 9px 24px !important; +} +[style*='z-index:'][style*='box-shadow: '][style*='font-size: 12px;'][style*='min-height: 24px; overflow: hidden; pointer-events:'] + > .notion-focusable { + color: var(--theme--text) !important; +} + +.notion-calendar-view + .notion-selectable.notion-page-block.notion-collection-item + > a[style*='background:'] { + background: var(--theme--bg_card) !important; + box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.05)) 0px 0px 0px 1px, + var(--theme--ui_shadow, rgba(15, 15, 15, 0.1)) 0px 2px 4px !important; +} + +.notion-media-menu > div > div > div[style*='background'], +.notion-media-menu > div > div > div > div[style*='background']:not(.notion-focusable), +.notion-body.dark + .notion-default-overlay-container + [style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];'], +.notion-focusable[style*='background: rgb(80, 85, 88);']:not(.notion-help-button):not(.onboarding-checklist-button), +.notion-body:not(.dark) + .notion-default-overlay-container + [style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];'] + .notion-focusable[style*='background: white;'], +.notion-timeline-item, +.notion-collection-item > a { + background: var(--theme--bg_card) !important; +} + +.notion-timeline-view + > div + > div + > [style*='height: 100%; background-image: linear-gradient(to right, '] { + background-image: linear-gradient( + to right, + var(--theme--bg) 20%, + transparent 100% + ) !important; +} +.notion-timeline-view + > div + > div + > [style*='height: 100%; background-image: linear-gradient(to left, '] { + background-image: linear-gradient( + to left, + var(--theme--bg) 20%, + transparent 100% + ) !important; +} + +/** ui **/ + +.notion-page-mention-token.notion-enable-hover:hover { + box-shadow: 0 0 0 3px var(--theme--ui_interactive-hover) !important; + background: var(--theme--ui_interactive-hover) !important; +} + +.notion-to_do-block [style*='background: rgb(46, 170, 220);'], +.notion-focusable + > [style*='width: 16px; height: 16px;'][style*='background: rgb(46, 170, 220);'], +.notion-focusable > [style*='border-radius: 44px;'][style*='background: rgb(46, 170, 220);'] { + background: var(--theme--ui_toggle-on) !important; +} +.notion-body.dark + .notion-focusable + > [style*='border-radius: 44px;'][style*='background: rgba(202, 204, 206, 0.3);'], +.notion-body:not(.dark) + .notion-focusable + > [style*='border-radius: 44px;'][style*='background: rgba(135, 131, 120, 0.3);'] { + background: var(--theme--ui_toggle-off) !important; +} + +.notion-focusable + > [style*='width: 16px; height: 16px;'][style*='background: rgb(46, 170, 220);'] + .check, +.notion-to_do-block .check { + fill: var(--theme--ui_toggle-feature) !important; +} +.notion-focusable > [style*='border-radius: 44px;'] > div:empty { + background: var(--theme--ui_toggle-feature) !important; +} + +.notion-body.dark [style*='background: rgba(255, 255, 255, 0.1)'], +.notion-body:not(.dark) [style*='background: rgba(55, 53, 47, 0.08)'], +.notion-focusable[style*='z-index:'][style*='box-shadow: '][style*='font-size: 12px;'][style*='min-height: 24px; overflow: hidden; pointer-events:']:hover, +:not(.notion-login) + > .notion-focusable[role='button'][tabindex='0'][style*='box-shadow:'][style*='background:'][style*='transition: background 20ms ease-in 0s; cursor: pointer;']:not([style*='rgb(46, 170, 220);']):not([style*='rgb(6, 156, 205);']):not([style*='rgb(0, 141, 190);']):not([style*='flex: 1 1 0%; white-space: nowrap; height: 26px; border-radius: 3px 0px 0px 3px;']):not([style*='rgb(225, 98, 89)']):hover, +[style*='z-index:'][style*='box-shadow: '][style*='font-size: 12px;'][style*='min-height: 24px; overflow: hidden; pointer-events:'] + > .notion-focusable[style*='background']:hover, +.notion-body:not(.dark) + .notion-default-overlay-container + [style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];'] + .notion-focusable[style*='background: rgb(239, 239, 238);'], +.line-numbers.notion-code-block + div .notion-focusable:hover { + background: var(--theme--ui_interactive-hover) !important; + color: var(--theme--text) !important; + fill: var(--theme--text) !important; +} +.notion-body:not(.dark) [style*='background: rgba(55, 53, 47, 0.16)'], +.notion-body.dark .notion-focusable[role='button'][style*='background: rgb(63, 68, 71);'], +.notion-body:not(.dark) + .notion-focusable[role='button'][style*='background: rgba(55, 53, 47, 0.16)'], +[style*='z-index:'][style*='box-shadow: '][style*='font-size: 12px;'][style*='min-height: 24px; overflow: hidden; pointer-events:'] + > .notion-focusable[style*='background']:active, +.notion-body:not(.dark) + .notion-default-overlay-container + [style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];'] + .notion-focusable[style*='background: rgb(233, 233, 231);'] { + background: var(--theme--ui_interactive-active) !important; + color: var(--theme--text) !important; + fill: var(--theme--text) !important; +} +.notion-body:not(.dark) [style*='background: rgba(55, 53, 47, 0.16)'] svg, +.notion-body.dark .notion-focusable[role='button'][style*='background: rgb(63, 68, 71);'] svg { + color: var(--theme--text) !important; + fill: var(--theme--text) !important; +} + +.notion-focusable-within, +.notion-share-menu + .notion-block-permission-settings-public-access + + div + > div + > div + > div + > div + > .notion-focusable:first-child[role='button'][tabindex='0'][style*='user-select: none;'], +.notion-overlay-container + > div:nth-child(2) + > div + > div:nth-child(2) + > div:nth-child(2) + > div + > div + > div + > div + > div + > div:nth-child(1)[style*='display: flex; width: 100%; position: relative; z-index: 2; padding: 6px 10px; font-size: 14px; background:'], +.notion-overlay-container + > div:nth-child(3) + > div + > div:nth-child(2) + > div:nth-child(2) + > div + > div + > div + > div + > div + > div:nth-child(1)[style*='display: flex; width: 100%; position: relative; z-index: 2; padding: 6px 10px; font-size: 14px; background:'], +#notion-app + > div + > div.notion-overlay-container.notion-default-overlay-container + > [data-overlay='true'] + > div + > div:nth-child(2) + > div:nth-child(2) + > div + > div + > div + > div + > div:nth-child(1) + > div[style*='background'] { + background: var(--theme--ui_input) !important; +} + +.notion-body.dark + [style*='border-radius: 20px; box-shadow: rgba(255, 255, 255, 0.07) 0px 0px 0px 2px inset;'], +.notion-body:not(.dark) + [style*='border-radius: 20px; box-shadow: rgba(55, 53, 47, 0.09) 0px 0px 0px 2px inset;'] { + box-shadow: var(--theme--ui_divider) 0px 0px 0px 2px inset !important; +} +.notion-body.dark + [style*='box-shadow: rgba(255, 255, 255, 0.07) 0px 0px 0px 1px inset; border-radius: 3px;'], +.notion-body:not(.dark) + [style*='box-shadow: rgba(55, 53, 47, 0.09) 0px 0px 0px 1px inset; border-radius: 3px;'], +.notion-gallery-view + .notion-focusable[role='button'][style*='font-size: 14px; border-radius: 3px; box-shadow:']:last-child { + box-shadow: var(--theme--ui_divider) 0px 0px 0px 1px inset !important; +} +.notion-body.dark + [style*='border-radius: 3px; box-shadow: rgba(255, 255, 255, 0.1) 0px 0px 0px 1px;'], +.notion-body:not(.dark) + [style*='border-radius: 3px; box-shadow: rgba(55, 53, 47, 0.1) 0px 0px 0px 1px;'] { + box-shadow: var(--theme--ui_divider) 0px 0px 0px 1px !important; +} + +#notion-app + .DayPicker-Day--today:not(.DayPicker-Day--selected):not(.DayPicker-Day--value):not(.DayPicker-Day--start):not(.DayPicker-Day--end) { + color: var(--theme--accent_red-text) !important; +} +#notion-app + .DayPicker-Day--today:not(.DayPicker-Day--selected):not(.DayPicker-Day--value):not(.DayPicker-Day--start):not(.DayPicker-Day--end)::after, +.notion-timeline-view [style*='background: rgb(211, 79, 67); width: 22px;'], +.notion-timeline-view + [style*='width: 7px; height: 7px; background: rgb(211, 79, 67); border-radius: 100%;'] { + background: var(--theme--accent_red) !important; +} +#notion-app .DayPicker-Day.DayPicker-Day--range.DayPicker-Day--start, +#notion-app .DayPicker-Day.DayPicker-Day--range.DayPicker-Day--end { + background-color: var(--theme--accent_blue) !important; +} +#notion-app .DayPicker-Day.DayPicker-Day--range:hover { + border-radius: 0 !important; +} +.notion-calendar-view-day[style*='background'] { + background-color: var(--theme--accent_red) !important; + color: var(--theme--accent_red-text) !important; +} +.DayPicker-Day--outside, +.DayPicker-Weekday { + 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; +} + +/* link underline */ + +.notion-body.dark + [style*='background-image: linear-gradient(to right, rgba(255, 255, 255, 0.14) 0%, rgba(255, 255, 255, 0.14) 100%);'], +.notion-body:not(.dark) + [style*='background-image: linear-gradient(to right, rgba(55, 53, 47, 0.16) 0%, rgba(55, 53, 47, 0.16) 100%);'] { + background-image: linear-gradient( + to right, + var(--theme--ui_divider) 0%, + var(--theme--ui_divider) 100% + ) !important; +} + +/** dividers **/ + +.notion-body.dark + .notion-page-content + .notranslate[style*='border-bottom: 1px solid rgba(255, 255, 255, 0.14);'], +.notion-body:not(.dark) + .notion-page-content + .notranslate[style*='border-bottom: 1px solid rgba(55, 53, 47, 0.16);'] { + border-bottom: 1px solid var(--theme--ui_divider) !important; +} + +.notion-body.dark [style*='border-top: 1px solid rgb(77, 81, 83)'], +.notion-body.dark [style*='border-top: 1px solid rgb(63, 66, 69)'], +.notion-body.dark [style*='border-top: 1px solid rgb(63, 66, 67)'], +.notion-body.dark [style*='border-top: 1px solid rgb(60, 63, 67)'], +.notion-body.dark [style*='border-top: 1px solid rgba(255, 255, 255, 0.14);'], +.notion-body.dark [style*='border-top: 1px solid rgba(255, 255, 255, 0.07)'], +.notion-body:not(.dark) [style*='border-top: 1px solid rgb(233, 233, 231)'], +.notion-body:not(.dark) [style*='border-top: 1px solid rgb(237, 237, 236)'], +.notion-body:not(.dark) [style*='border-top: 1px solid rgb(238, 238, 237)'], +.notion-body:not(.dark) [style*='border-top: 1px solid rgba(55, 53, 47, 0.09)'], +.notion-body:not(.dark) [style*='border-top: 1px solid rgba(55, 53, 47, 0.16)'] { + border-top: 1px solid var(--theme--ui_divider) !important; +} +.notion-body.dark [style*='border-bottom: 1px solid rgb(77, 81, 83)'], +.notion-body.dark [style*='border-bottom: 1px solid rgb(63, 66, 69)'], +.notion-body.dark [style*='border-bottom: 1px solid rgb(63, 66, 67)'], +.notion-body.dark [style*='border-bottom: 1px solid rgb(60, 63, 67)'], +.notion-body.dark [style*='border-bottom: 1px solid rgba(255, 255, 255, 0.14);'], +.notion-body.dark [style*='border-bottom: 1px solid rgba(255, 255, 255, 0.07)'], +.notion-body:not(.dark) [style*='border-bottom: 1px solid rgb(233, 233, 231)'], +.notion-body:not(.dark) [style*='border-bottom: 1px solid rgb(237, 237, 236)'], +.notion-body:not(.dark) [style*='border-bottom: 1px solid rgb(238, 238, 237)'], +.notion-body:not(.dark) [style*='border-bottom: 1px solid rgba(55, 53, 47, 0.09)'], +.notion-body:not(.dark) [style*='border-bottom: 1px solid rgba(55, 53, 47, 0.16)'] { + border-bottom: 1px solid var(--theme--ui_divider) !important; +} +.notion-body.dark [style*='border-right: 1px solid rgb(77, 81, 83)'], +.notion-body.dark [style*='border-right: 1px solid rgb(63, 66, 69)'], +.notion-body.dark [style*='border-right: 1px solid rgb(63, 66, 67)'], +.notion-body.dark [style*='border-right: 1px solid rgb(60, 63, 67)'], +.notion-body.dark [style*='border-right: 1px solid rgba(255, 255, 255, 0.14);'], +.notion-body.dark [style*='border-right: 1px solid rgba(255, 255, 255, 0.07)'], +.notion-body:not(.dark) [style*='border-right: 1px solid rgb(233, 233, 231)'], +.notion-body:not(.dark) [style*='border-right: 1px solid rgb(237, 237, 236)'], +.notion-body:not(.dark) [style*='border-right: 1px solid rgb(238, 238, 237)'], +.notion-body:not(.dark) [style*='border-right: 1px solid rgba(55, 53, 47, 0.09)'], +.notion-body:not(.dark) [style*='border-right: 1px solid rgba(55, 53, 47, 0.16)'] { + border-right: 1px solid var(--theme--ui_divider) !important; +} +.notion-body.dark [style*='border-left: 1px solid rgb(77, 81, 83)'], +.notion-body.dark [style*='border-left: 1px solid rgb(63, 66, 69)'], +.notion-body.dark [style*='border-left: 1px solid rgb(63, 66, 67)'], +.notion-body.dark [style*='border-left: 1px solid rgb(60, 63, 67)'], +.notion-body.dark [style*='border-left: 1px solid rgba(255, 255, 255, 0.14);'], +.notion-body.dark [style*='border-left: 1px solid rgba(255, 255, 255, 0.07)'], +.notion-body:not(.dark) [style*='border-left: 1px solid rgb(233, 233, 231)'], +.notion-body:not(.dark) [style*='border-left: 1px solid rgb(237, 237, 236)'], +.notion-body:not(.dark) [style*='border-left: 1px solid rgb(238, 238, 237)'], +.notion-body:not(.dark) [style*='border-left: 1px solid rgba(55, 53, 47, 0.09)'], +.notion-body:not(.dark) [style*='border-left: 1px solid rgba(55, 53, 47, 0.16)'] { + border-left: 1px solid var(--theme--ui_divider) !important; +} +.notion-body.dark [style*='border: 1px solid rgb(77, 81, 83)'], +.notion-body.dark [style*='border: 1px solid rgb(63, 66, 69)'], +.notion-body.dark [style*='border: 1px solid rgb(63, 66, 67)'], +.notion-body.dark [style*='border: 1px solid rgb(60, 63, 67)'], +.notion-body.dark [style*='border: 1px solid rgba(255, 255, 255, 0.14);'], +.notion-body.dark [style*='border: 1px solid rgba(255, 255, 255, 0.07)'], +.notion-body:not(.dark) [style*='border: 1px solid rgb(233, 233, 231)'], +.notion-body:not(.dark) [style*='border: 1px solid rgb(237, 237, 236)'], +.notion-body:not(.dark) [style*='border: 1px solid rgb(238, 238, 237)'], +.notion-body:not(.dark) [style*='border: 1px solid rgba(55, 53, 47, 0.09)'], +.notion-body:not(.dark) [style*='border: 1px solid rgba(55, 53, 47, 0.16)'] { + border: 1px solid var(--theme--ui_divider) !important; +} +.notion-body.dark [style*='border-color: 1px solid rgb(77, 81, 83)'], +.notion-body.dark [style*='border-color: 1px solid rgb(63, 66, 69)'], +.notion-body.dark [style*='border-color: 1px solid rgb(63, 66, 67)'], +.notion-body.dark [style*='border-color: 1px solid rgb(60, 63, 67)'], +.notion-body.dark [style*='border-color: 1px solid rgba(255, 255, 255, 0.14);'], +.notion-body.dark [style*='border-color: 1px solid rgba(255, 255, 255, 0.07)'], +.notion-body:not(.dark) [style*='border-color: 1px solid rgb(233, 233, 231)'], +.notion-body:not(.dark) [style*='border-color: 1px solid rgb(237, 237, 236)'], +.notion-body:not(.dark) [style*='border-color: 1px solid rgb(238, 238, 237)'], +.notion-body:not(.dark) [style*='border-color: 1px solid rgba(55, 53, 47, 0.09)'], +.notion-body:not(.dark) [style*='border-color: 1px solid rgba(55, 53, 47, 0.16)'], +.notion-callout-block > div > :not([style*='border-color: transparent']) { + border-color: var(--theme--ui_divider) !important; +} + +.notion-body.dark [style*='box-shadow: rgb(77, 81, 83) -1px 0px 0px'], +.notion-body.dark [style*='box-shadow: rgba(255, 255, 255, 0.07) -1px 0px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(233, 233, 231) -1px 0px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgba(55, 53, 47, 0.09) -1px 0px 0px'], +.notion-body.dark [style*='box-shadow: rgb(63, 66, 69) -1px 0px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(237, 237, 236) -1px 0px 0px'] { + box-shadow: var(--theme--ui_divider) -1px 0px 0px !important; +} +.notion-body.dark [style*='box-shadow: rgb(77, 81, 83) 1px 0px 0px'], +.notion-body.dark [style*='box-shadow: rgba(255, 255, 255, 0.07) 1px 0px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(233, 233, 231) 1px 0px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgba(55, 53, 47, 0.09) 1px 0px 0px'], +.notion-body.dark [style*='box-shadow: rgb(63, 66, 69) 1px 0px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(237, 237, 236) 1px 0px 0px'] { + box-shadow: var(--theme--ui_divider) 1px 0px 0px !important; +} +.notion-body.dark [style*='box-shadow: rgb(77, 81, 83) 0px -1px 0px'], +.notion-body.dark [style*='box-shadow: rgba(255, 255, 255, 0.07) 0px -1px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(233, 233, 231) 0px -1px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgba(55, 53, 47, 0.09) 0px -1px 0px'], +.notion-body.dark [style*='box-shadow: rgb(63, 66, 69) 0px -1px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(237, 237, 236) 0px -1px 0px'] { + box-shadow: var(--theme--ui_divider) 0px -1px 0px !important; +} +.notion-body.dark [style*='box-shadow: rgb(77, 81, 83) 0px 1px 0px'], +.notion-body.dark [style*='box-shadow: rgba(255, 255, 255, 0.07) 0px 1px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(233, 233, 231) 0px 1px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgba(55, 53, 47, 0.09) 0px 1px 0px'], +.notion-body.dark [style*='box-shadow: rgb(63, 66, 69) 0px 1px 0px'], +.notion-body:not(.dark) [style*='box-shadow: rgb(237, 237, 236) 0px 1px 0px'] { + box-shadow: var(--theme--ui_divider) 0px 1px 0px !important; +} + +.notion-body.dark [style*='height: 1px;'][style*='background: rgba(255, 255, 255, 0.07);'], +.notion-body:not(.dark) [style*='height: 1px;'][style*='background: rgba(55, 53, 47, 0.09);'] { + background: var(--theme--ui_divider) !important; +} +.notion-body.dark + [style*='box-shadow: rgb(47, 52, 55) -3px 0px 0px, rgb(63, 66, 69) 0px 1px 0px;'], +.notion-body:not(.dark) + [style*='box-shadow: white -3px 0px 0px, rgb(233, 233, 231) 0px 1px 0px;'] { + box-shadow: var(--theme--ui_divider) 0px 1px 0px !important; +} +.notion-body.dark + .notion-collection_view_page-block + > [style*='box-shadow: rgb(47, 52, 55) -3px 0px 0px;'], +.notion-body:not(.dark) + .notion-collection_view_page-block + > [style*='box-shadow: white -3px 0px 0px;'], +.notion-body.dark + .notion-collection_view-block + > [style*='box-shadow: rgb(47, 52, 55) -3px 0px 0px;'], +.notion-body:not(.dark) + .notion-collection_view-block + > [style*='box-shadow: white -3px 0px 0px;'] { + box-shadow: transparent -3px 0px 0px !important; +} +.notion-focusable[role='button'][style*='box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px;'] { + box-shadow: var(--theme--ui_divider) 0px 0px 0px 1px !important; +} + +.notion-sidebar-container[style*='box-shadow:'] { + box-shadow: var(--theme--ui_divider) -2px 0px 0px 0px inset !important; +} + +/** colours **/ + +[style*='background: rgb(46, 170, 220)'] { + background: var(--theme--accent_blue) !important; + color: var(--theme--accent_blue-text) !important; +} +[style*='background: rgb(6, 156, 205);'] { + background: var(--theme--accent_blue-hover) !important; + color: var(--theme--accent_blue-text) !important; +} +[style*='background: rgb(0, 141, 190);'] { + background: var(--theme--accent_blue-active) !important; + color: var(--theme--accent_blue-text) !important; +} +[style*='background: rgb(46, 170, 220)'] .chevronDown, +[style*='background: rgb(6, 156, 205);'] .chevronDown, +[style*='background: rgb(0, 141, 190);'] .chevronDown { + fill: var(--theme--accent_blue-text) !important; +} +[style*='fill: rgb(46, 170, 220)'] { + fill: var(--theme--accent_blue) !important; +} +[style*=' color: rgb(46, 170, 220)'], +[style^='color: rgb(46, 170, 220)'] { + color: var(--theme--accent_blue) !important; +} +[style*='background: rgba(46, 170, 220, 0.'], +[style*='background-color: rgba(46, 170, 220, 0.'] { + background-color: var(--theme--accent_blue-selection) !important; +} +*::selection { + background: var(--theme--accent_blue-selection, rgba(26, 170, 220, 0.3)) !important; +} +.notion-page-mention-token::selection, +.notion-selectable-halo { + background: var(--theme--accent_blue-selection, rgba(26, 170, 220, 0.2)) !important; +} +.notion-focusable-within:focus-within, +.notion-focusable:focus-visible { + box-shadow: var(--theme--accent_blue-active, rgba(26, 170, 220, 0.7)) 0px 0px 0px 1px inset, + var(--theme--accent_blue-active, rgba(26, 170, 220, 0.4)) 0px 0px 0px 2px !important; +} +.notion-sidebar-switcher:focus-visible { + box-shadow: none !important; +} +.notion-onboarding-plan-type-team[style*='box-shadow: rgb(46, 170, 220)'], +.notion-onboarding-plan-type-personal[style*='box-shadow: rgb(46, 170, 220)'] { + box-shadow: var(--theme--accent_blue) 0px 0px 0px 2px !important; +} + +@keyframes pulsing-button-border { + 0% { + border-color: var(--theme--accent_blue) !important; + } + 50% { + border-color: rgba(255, 255, 255, 0) !important; + } + 100% { + border-color: var(--theme--accent_blue) !important; + } +} + +[style*='background-color: rgb(235, 87, 87); height: 28px; width: 28px;'], +.notion-login [style*='background: rgb(225, 98, 89)'], +.notion-login [style*='background: rgb(207, 83, 74)'], +.notion-login [style*='background: rgb(191, 77, 69)'] { + background: var(--theme--accent_red) !important; + border-color: var(--theme--accent_red) !important; +} +[style*='background: rgb(235, 87, 87); color: white; border-radius: 3px;']:not([role='button']) { + background: var(--theme--accent_red) !important; + color: var(--theme--accent_red-text) !important; +} +[style*='color: rgb(235, 87, 87); border: 1px solid rgba(235, 87, 87, 0.5);'][role='button'] { + color: var(--theme--accent_red) !important; + border: 1px solid var(--theme--accent_red) !important; +} +.notion-focusable[style*='border-radius: 3px;'][style*='color: rgb(235, 87, 87);'][role='button'], +[style*='font-size: 12px; font-weight: 600; color: rgb(235, 87, 87);'], +[style*='flex-shrink: 0; margin-top: -1px; margin-right: 4px; fill: rgb(235, 87, 87);'], +[style*='font-size: 12px;'] > [style*='pointer-events: none; color: rgb(235, 87, 87);'] { + color: var(--theme--accent_red) !important; + fill: var(--theme--accent_red) !important; +} +.notion-focusable[style*='border-radius: 3px;'][style*='background: rgba(235, 87, 87, 0.1);'][role='button']:hover { + background: var(--theme--accent_red-button) !important; +} + +.notion-transclusion_container-block > div > div > div[style*='border: 2px'], +.notion-transclusion_reference-block > div > div > div[style*='border: 2px'] { + border-color: var(--theme--accent_red, #e38676) !important; +} + +.notion-text-mention-token[style*='color:#2EAADC;'] { + color: var(--theme--accent_blue) !important; +} +.notion-text-mention-token[style*='color:#EB5757;'], +.notion-link:hover { + color: var(--theme--accent_red) !important; +} + +.notion-body.dark [style*='fill: rgb(202, 204, 206)'], +.notion-body:not(.dark) [style*='fill: rgba(55, 53, 47, 0.8)'] { + fill: var(--theme--icon) !important; +} +.notion-body.dark [style*='fill: rgba(202, 204, 206, 0.'], +.notion-body.dark [style*='fill: rgba(255, 255, 255, 0.'], +.notion-body:not(.dark) [style*='fill: rgba(25, 23, 17, 0.'], +.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_secondary) !important; +} +.alarmClock, +.notion-to_do-block .checkboxSquare[style*='fill: inherit'] { + fill: currentColor !important; +} + +.notion-app-inner, +.notion-page-content, +.notion-selectable.notion-page-block .notion-focusable > [style*=';color:'], +.notion-record-icon.notranslate.notion-focusable, +.notion-topbar-share-menu.notion-focusable, +.notion-collection-view-select.notion-focusable, +.notion-body.dark [style*=' color: rgba(255, 255, 255, 0.9);'], +.notion-body.dark [style^='color: rgba(255, 255, 255, 0.9);'], +.notion-body:not(.dark) [style*=' color: rgb(55, 53, 47)'], +.notion-body:not(.dark) [style^='color: rgb(55, 53, 47)'] { + color: var(--theme--text) !important; +} +.notion-body.dark [style*='border-bottom: 2px solid rgba(255, 255, 255, 0.9);'], +.notion-body:not(.dark) [style*='border-bottom: 2px solid rgb(55, 53, 47);'] { + border-bottom: 2px solid var(--theme--text) !important; +} +.notion-body.dark [style*='caret-color: rgba(255, 255, 255, 0.9)'], +.notion-body:not(.dark) [style*='caret-color: rgb(55, 53, 47)'] { + caret-color: var(--theme--text) !important; +} +.notion-body.dark [style*=' color: rgba(255, 255, 255, 0.6)'], +.notion-body.dark [style^='color: rgba(255, 255, 255, 0.6)'], +.notion-body.dark [style^='color:rgba(255, 255, 255, 0.6)'], +.notion-body:not(.dark) [style*=' color: rgba(55, 53, 47, 0.6)'], +.notion-body:not(.dark) [style^='color: rgba(55, 53, 47, 0.6)'], +.notion-body:not(.dark) [style^='color:rgba(55, 53, 47, 0.6)'], +.notion-sidebar-container > [style*='color'], +.notion-gallery-view + .notion-focusable[role='button'][style*='font-size: 14px; border-radius: 3px; box-shadow:']:last-child + svg + + div, +.notion-body.dark [style*=' color: rgba(255, 255, 255, 0.4)'], +.notion-body.dark [style^='color: rgba(255, 255, 255, 0.4)'], +.notion-body:not(.dark) [style*=' color: rgba(55, 53, 47, 0.4)'], +.notion-body:not(.dark) [style^='color: rgba(55, 53, 47, 0.4)'], +.notion-page-controls, +.notion-page-details-controls, +.notion-calendar-view-day { + color: var(--theme--text_secondary) !important; +} + +.notion-page-mention-token__title { + 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_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_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_secondary) !important; +} + +/* make sure to change in _mapColors.js as well if colors ever change */ +.notion-body.dark [style*='background: rgb(80, 85, 88)']:not([role='button']), +.notion-body.dark [style*='background-color: rgb(80, 85, 88)']:not([role='button']), +.notion-body:not(.dark) [style*='background: rgba(206, 205, 202, 0.5)']:not([role='button']), +.notion-body:not(.dark) + [style*='background-color: rgba(206, 205, 202, 0.5)']:not([role='button']), +.notion-sidebar-container + .notion-sidebar + [style*='margin-top'] + > .notion-focusable[style*='border-radius'] { + background: var(--theme--tag_default) !important; + color: var(--theme--tag_default-text) !important; +} + +/** code **/ + +.notion-page-content [style*='color:#EB5757']:not(.notion-text-mention-token) { + color: var(--theme--code_inline-text) !important; + background: var(--theme--code_inline) !important; +} + +.notion-code-block > div > div { + background: var(--theme--code) !important; +} +.notion-code-block > div { + color: var(--theme--code_plain) !important; +} + +/** simple tables **/ + +.notion-table-selection-overlay [style*='border: 2px solid rgb(116, 182, 219);'] { + border: 2px solid var(--theme--accent_blue) !important; +} +.notion-table-row-selector, +.notion-table-column-selector, +.notion-table-block .notion-focusable [style*='background: rgba(55, 53, 47, 0.06);'] { + background: var(--theme--ui_interactive-hover) !important; +} +.notion-table-row [style*='background: rgb(116, 182, 219);'], +.notion-table-row-selector[style*='background: rgb(116, 182, 219);'], +.notion-table-column-selector[style*='background: rgb(116, 182, 219);'], +.notion-table-block .notion-focusable [style*='background: rgb(116, 182, 219);'] { + background: var(--theme--accent_blue) !important; +} +.notion-table-row td[style*='background:'] { + background: var(--theme--bg_secondary) !important; +} diff --git a/repo/theming/variables.css b/repo/theming/variables.css new file mode 100644 index 0000000..8ff0aad --- /dev/null +++ b/repo/theming/variables.css @@ -0,0 +1,407 @@ +/** + * notion-enhancer: theming + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +:root { + --theme--page-padding: calc(96px + env(safe-area-inset-left)); + --theme--page-width: 900px; + --theme--page-width_full: 100%; + --theme--page_banner-height: 30vh; + --theme--page_preview-padding: 8rem; + --theme--page_preview-width: 977px; + --theme--page_preview_banner-height: 20vh; + + --theme--font_sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, + 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol'; + --theme--font_serif: Lyon-Text, Georgia, YuMincho, 'Yu Mincho', 'Hiragino Mincho ProN', + 'Hiragino Mincho Pro', 'Songti TC', 'Songti SC', SimSun, 'Nanum Myeongjo', NanumMyeongjo, + Batang, serif; + --theme--font_mono: iawriter-mono, Nitti, Menlo, Courier, monospace; + --theme--font_code: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; + + --theme--accent_blue: rgb(46, 170, 220); + --theme--accent_blue-selection: rgb(46, 170, 220, 0.25); + --theme--accent_blue-hover: rgb(6, 156, 205); + --theme--accent_blue-active: rgb(0, 141, 190); + --theme--accent_blue-text: #fff; + --theme--accent_red: #eb5757; + --theme--accent_red-button: rgba(235, 87, 87, 0.1); + --theme--accent_red-text: #fff; +} + +:root.light { + --theme--bg: #fff; + --theme--bg_secondary: rgb(247, 246, 243); + --theme--bg_card: #fff; + + --theme--scrollbar_track: #edece9; + --theme--scrollbar_thumb: #d3d1cb; + --theme--scrollbar_thumb-hover: #aeaca6; + + --theme--ui_shadow: rgba(15, 15, 15, 0.05); + --theme--ui_divider: rgb(237, 237, 236); + --theme--ui_interactive-hover: rgba(55, 53, 47, 0.08); + --theme--ui_interactive-active: rgba(55, 53, 47, 0.16); + --theme--ui_toggle-on: var(--theme--accent_blue); + --theme--ui_toggle-off: rgba(135, 131, 120, 0.3); + --theme--ui_toggle-feature: #fff; + --theme--ui_input: rgba(242, 241, 238, 0.6); + --theme--ui_tooltip: rgb(15, 15, 15); + --theme--ui_tooltip-title: rgba(255, 255, 255, 0.9); + --theme--ui_tooltip-description: rgba(206, 205, 202, 0.6); + --theme--ui_corner_action: white; + --theme--ui_corner_action-hover: rgb(239, 239, 238); + --theme--ui_corner_action-active: rgb(223, 223, 222); + + --theme--icon: rgba(55, 53, 47, 0.8); + --theme--icon_secondary: rgba(55, 53, 47, 0.4); + + --theme--text: rgb(55, 43, 47); + --theme--text_secondary: rgba(55, 43, 47, 0.6); + + --theme--text_gray: rgba(120, 119, 116, 1); + --theme--text_brown: rgba(159, 107, 83, 1); + --theme--text_orange: rgba(217, 115, 13, 1); + --theme--text_yellow: rgba(203, 145, 47, 1); + --theme--text_green: rgba(68, 131, 97, 1); + --theme--text_blue: rgba(51, 126, 169, 1); + --theme--text_purple: rgba(144, 101, 176, 1); + --theme--text_pink: rgba(193, 76, 138, 1); + --theme--text_red: rgba(212, 76, 71, 1); + + --theme--highlight_gray: rgba(241, 241, 239, 1); + --theme--highlight_gray-text: currentColor; + --theme--highlight_brown: rgba(244, 238, 238, 1); + --theme--highlight_brown-text: currentColor; + --theme--highlight_orange: rgba(251, 236, 221, 1); + --theme--highlight_orange-text: currentColor; + --theme--highlight_yellow: rgba(251, 243, 219, 1); + --theme--highlight_yellow-text: currentColor; + --theme--highlight_green: rgba(237, 243, 236, 1); + --theme--highlight_green-text: currentColor; + --theme--highlight_blue: rgba(231, 243, 248, 1); + --theme--highlight_blue-text: currentColor; + --theme--highlight_purple: rgba(244, 240, 247, 0.8); + --theme--highlight_purple-text: currentColor; + --theme--highlight_pink: rgba(249, 238, 243, 0.8); + --theme--highlight_pink-text: currentColor; + --theme--highlight_red: rgba(253, 235, 236, 1); + --theme--highlight_red-text: currentColor; + + --theme--callout_gray: rgb(241, 241, 239); + --theme--callout_gray-text: currentColor; + --theme--callout_brown: rgb(244, 238, 238); + --theme--callout_brown-text: currentColor; + --theme--callout_orange: rgb(251, 236, 221); + --theme--callout_orange-text: currentColor; + --theme--callout_yellow: rgb(251, 243, 219); + --theme--callout_yellow-text: currentColor; + --theme--callout_green: rgb(237, 243, 236); + --theme--callout_green-text: currentColor; + --theme--callout_blue: rgb(231, 243, 248); + --theme--callout_blue-text: currentColor; + --theme--callout_purple: rgba(244, 240, 247, 0.8); + --theme--callout_purple-text: currentColor; + --theme--callout_pink: rgba(249, 238, 243, 0.8); + --theme--callout_pink-text: currentColor; + --theme--callout_red: rgb(253, 235, 236); + --theme--callout_red-text: currentColor; + + --theme--tag_default: rgba(206, 205, 202, 0.5); + --theme--tag_default-text: var(--theme--text); + --theme--tag_light_gray: rgba(227, 226, 224, 0.5); + --theme--tag_light_gray-text: rgb(50, 48, 44); + --theme--tag_gray: rgb(227, 226, 224); + --theme--tag_gray-text: rgb(50, 48, 44); + --theme--tag_brown: rgb(238, 224, 218); + --theme--tag_brown-text: rgb(68, 42, 30); + --theme--tag_orange: rgb(250, 222, 201); + --theme--tag_orange-text: rgb(73, 41, 14); + --theme--tag_yellow: rgb(253, 236, 200); + --theme--tag_yellow-text: rgb(64, 44, 27); + --theme--tag_green: rgb(219, 237, 219); + --theme--tag_green-text: rgb(28, 56, 41); + --theme--tag_blue: rgb(211, 229, 239); + --theme--tag_blue-text: rgb(24, 51, 71); + --theme--tag_purple: rgb(232, 222, 238); + --theme--tag_purple-text: rgb(65, 36, 84); + --theme--tag_pink: rgb(245, 224, 233); + --theme--tag_pink-text: rgb(76, 35, 55); + --theme--tag_red: rgb(255, 226, 221); + --theme--tag_red-text: rgb(93, 23, 21); + + --theme--board_light_gray: rgba(249, 249, 245, 0.5); + --theme--board_light_gray-card: white; + --theme--board_light_gray-card_text: inherit; + --theme--board_light_gray-text: rgba(145, 145, 142, 0.5); + --theme--board_gray: rgba(247, 247, 245, 0.7); + --theme--board_gray-card: white; + --theme--board_gray-card_text: inherit; + --theme--board_gray-text: rgb(145, 145, 142); + --theme--board_brown: rgba(250, 246, 245, 0.7); + --theme--board_brown-card: white; + --theme--board_brown-card_text: inherit; + --theme--board_brown-text: rgb(187, 132, 108); + --theme--board_orange: rgba(252, 245, 242, 0.7); + --theme--board_orange-card: white; + --theme--board_orange-card_text: inherit; + --theme--board_orange-text: rgb(215, 129, 58); + --theme--board_yellow: rgba(250, 247, 237, 0.7); + --theme--board_yellow-card: white; + --theme--board_yellow-card_text: inherit; + --theme--board_yellow-text: rgb(203, 148, 51); + --theme--board_green: rgba(244, 248, 243, 0.7); + --theme--board_green-card: white; + --theme--board_green-card_text: inherit; + --theme--board_green-text: rgb(108, 155, 125); + --theme--board_blue: rgba(241, 248, 251, 0.7); + --theme--board_blue-card: white; + --theme--board_blue-card_text: inherit; + --theme--board_blue-text: rgb(91, 151, 189); + --theme--board_purple: rgba(249, 246, 252, 0.7); + --theme--board_purple-card: white; + --theme--board_purple-card_text: inherit; + --theme--board_purple-text: rgb(167, 130, 195); + --theme--board_pink: rgba(251, 245, 251, 0.7); + --theme--board_pink-card: white; + --theme--board_pink-card_text: inherit; + --theme--board_pink-text: rgb(205, 116, 159); + --theme--board_red: rgba(253, 245, 243, 0.7); + --theme--board_red-card: white; + --theme--board_red-card_text: inherit; + --theme--board_red-text: rgb(225, 111, 100); + + --theme--code_inline: rgba(135, 131, 120, 0.15); + --theme--code_inline-text: #eb5757; + + --theme--code: #f7f6f3; + --theme--code_plain: var(--theme--text); + --theme--code_property: #905; + --theme--code_tag: var(--theme--code_property); + --theme--code_boolean: var(--theme--code_property); + --theme--code_number: var(--theme--code_property); + --theme--code_constant: var(--theme--code_property); + --theme--code_symbol: var(--theme--code_property); + --theme--code_deleted: var(--theme--code_property); + --theme--code_selector: #690; + --theme--code_attr-name: var(--theme--code_selector); + --theme--code_string: var(--theme--code_selector); + --theme--code_char: var(--theme--code_selector); + --theme--code_builtin: var(--theme--code_selector); + --theme--code_inserted: var(--theme--code_selector); + --theme--code_operator: #9a6e3a; + --theme--code_entity: var(--theme--code_operator); + --theme--code_url: var(--theme--code_operator); + --theme--code_variable: var(--theme--code_regex); + --theme--code_comment: slategray; + --theme--code_cdata: var(--theme--code_comment); + --theme--code_prolog: var(--theme--code_comment); + --theme--code_doctype: var(--theme--code_comment); + --theme--code_atrule: #07a; + --theme--code_attr-value: var(--theme--code_atrule); + --theme--code_keyword: var(--theme--code_atrule); + --theme--code_regex: #e90; + --theme--code_important: var(--theme--code_regex); + --theme--code_function: #dd4a68; + --theme--code_class-name: var(--theme--code_function); + --theme--code_parameter: var(--theme--code_plain); + --theme--code_decorator: var(--theme--code_plain); + --theme--code_id: var(--theme--code_plain); + --theme--code_class: var(--theme--code_plain); + --theme--code_pseudo-element: var(--theme--code_plain); + --theme--code_pseudo-class: var(--theme--code_plain); + --theme--code_attribute: var(--theme--code_plain); + --theme--code_value: var(--theme--code_plain); + --theme--code_unit: var(--theme--code_plain); + --theme--code_punctuation: #999; + --theme--code_annotation: var(--theme--code_plain); +} + +:root.dark { + --theme--bg: rgb(47, 52, 55); + --theme--bg_secondary: rgb(55, 60, 63); + --theme--bg_card: rgb(63, 68, 71); + + --theme--scrollbar_track: rgba(202, 204, 206, 0.04); + --theme--scrollbar_thumb: #474c50; + --theme--scrollbar_thumb-hover: rgba(202, 204, 206, 0.3); + + --theme--ui_shadow: rgba(15, 15, 15, 0.15); + --theme--ui_divider: rgb(255, 255, 255, 0.07); + --theme--ui_interactive-hover: rgba(255, 255, 255, 0.1); + --theme--ui_interactive-active: rgb(63, 68, 71); + --theme--ui_toggle-on: var(--theme--accent_blue); + --theme--ui_toggle-off: rgba(202, 204, 206, 0.3); + --theme--ui_toggle-feature: #fff; + --theme--ui_input: rgba(15, 15, 15, 0.3); + --theme--ui_tooltip: rgb(202, 204, 206); + --theme--ui_tooltip-title: rgb(15, 15, 15); + --theme--ui_tooltip-description: rgba(47, 52, 55, 0.6); + --theme--ui_corner_action: rgb(80, 85, 88); + --theme--ui_corner_action-hover: rgb(98, 102, 104); + --theme--ui_corner_action-active: rgb(120, 123, 123); + + --theme--icon: rgba(202, 204, 206); + --theme--icon_secondary: rgb(202, 204, 206, 0.6); + + --theme--text: rgba(255, 255, 255, 0.9); + --theme--text_secondary: rgba(255, 255, 255, 0.6); + + --theme--text_gray: rgba(159, 164, 169, 1); + --theme--text_brown: rgba(212, 150, 117, 1); + --theme--text_orange: rgba(217, 133, 56, 1); + --theme--text_yellow: rgba(201, 145, 38, 1); + --theme--text_green: rgba(113, 178, 131, 1); + --theme--text_blue: rgba(102, 170, 218, 1); + --theme--text_purple: rgba(176, 152, 217, 1); + --theme--text_pink: rgba(223, 132, 209, 1); + --theme--text_red: rgba(234, 135, 140, 1); + + --theme--highlight_gray: rgba(60, 65, 68, 1); + --theme--highlight_gray-text: currentColor; + --theme--highlight_brown: rgba(76, 61, 53, 1); + --theme--highlight_brown-text: currentColor; + --theme--highlight_orange: rgba(85, 59, 41, 1); + --theme--highlight_orange-text: currentColor; + --theme--highlight_yellow: rgba(79, 64, 41, 1); + --theme--highlight_yellow-text: currentColor; + --theme--highlight_green: rgba(46, 68, 58, 1); + --theme--highlight_green-text: currentColor; + --theme--highlight_blue: rgba(45, 66, 86, 1); + --theme--highlight_blue-text: currentColor; + --theme--highlight_purple: rgba(69, 58, 91, 1); + --theme--highlight_purple-text: currentColor; + --theme--highlight_pink: rgba(81, 56, 77, 1); + --theme--highlight_pink-text: currentColor; + --theme--highlight_red: rgba(94, 52, 54, 1); + --theme--highlight_red-text: currentColor; + + --theme--callout_gray: rgb(60, 65, 68); + --theme--callout_gray-text: currentColor; + --theme--callout_brown: rgb(76, 61, 53); + --theme--callout_brown-text: currentColor; + --theme--callout_orange: rgb(85, 59, 41); + --theme--callout_orange-text: currentColor; + --theme--callout_yellow: rgb(79, 64, 41); + --theme--callout_yellow-text: currentColor; + --theme--callout_green: rgb(46, 68, 58); + --theme--callout_green-text: currentColor; + --theme--callout_blue: rgb(45, 66, 86); + --theme--callout_blue-text: currentColor; + --theme--callout_purple: rgb(69, 58, 91); + --theme--callout_purple-text: currentColor; + --theme--callout_pink: rgb(81, 56, 77); + --theme--callout_pink-text: currentColor; + --theme--callout_red: rgb(94, 52, 54); + --theme--callout_red-text: currentColor; + + --theme--tag_default: rgba(206, 205, 202, 0.5); + --theme--tag_default-text: var(--theme--text); + --theme--tag_light_gray: rgba(71, 76, 80, 0.7); + --theme--tag_light_gray-text: rgba(255, 255, 255, 0.88); + --theme--tag_gray: rgb(71, 76, 80); + --theme--tag_gray-text: rgba(255, 255, 255, 0.88); + --theme--tag_brown: rgb(92, 71, 61); + --theme--tag_brown-text: rgba(255, 255, 255, 0.88); + --theme--tag_orange: rgb(136, 84, 44); + --theme--tag_orange-text: rgba(255, 255, 255, 0.88); + --theme--tag_yellow: rgb(146, 118, 63); + --theme--tag_yellow-text: rgba(255, 255, 255, 0.88); + --theme--tag_green: rgb(50, 82, 65); + --theme--tag_green-text: rgba(255, 255, 255, 0.88); + --theme--tag_blue: rgb(42, 78, 107); + --theme--tag_blue-text: rgba(255, 255, 255, 0.88); + --theme--tag_purple: rgb(83, 68, 116); + --theme--tag_purple-text: rgba(255, 255, 255, 0.88); + --theme--tag_pink: rgb(106, 59, 99); + --theme--tag_pink-text: rgba(255, 255, 255, 0.88); + --theme--tag_red: rgb(122, 54, 59); + --theme--tag_red-text: rgba(255, 255, 255, 0.88); + + --theme--board_light_gray: rgba(51, 55, 59, 0.7); + --theme--board_light_gray-card: rgba(60, 65, 68, 0.7); + --theme--board_light_gray-card_text: inherit; + --theme--board_light_gray-text: rgba(107, 112, 116, 0.7); + --theme--board_gray: rgb(51, 55, 59); + --theme--board_gray-card: rgb(60, 65, 68); + --theme--board_gray-card_text: inherit; + --theme--board_gray-text: rgb(107, 112, 116); + --theme--board_brown: rgb(59, 54, 51); + --theme--board_brown-card: rgb(76, 61, 53); + --theme--board_brown-card_text: inherit; + --theme--board_brown-text: rgb(155, 98, 69); + --theme--board_orange: rgb(61, 54, 49); + --theme--board_orange-card: rgb(85, 59, 41); + --theme--board_orange-text: rgb(168, 92, 30); + --theme--board_yellow: rgb(56, 55, 49); + --theme--board_yellow-card: rgb(79, 64, 41); + --theme--board_yellow-card_text: inherit; + --theme--board_yellow-text: rgb(137, 107, 42); + --theme--board_green: rgb(49, 57, 53); + --theme--board_green-card: rgb(46, 68, 58); + --theme--board_green-card_text: inherit; + --theme--board_green-text: rgb(61, 124, 86); + --theme--board_blue: rgb(49, 56, 64); + --theme--board_blue-card: rgb(45, 66, 86); + --theme--board_blue-card_text: inherit; + --theme--board_blue-text: rgb(46, 117, 164); + --theme--board_purple: rgb(57, 53, 65); + --theme--board_purple-card: rgb(69, 58, 91); + --theme--board_purple-card_text: inherit; + --theme--board_purple-text: rgb(123, 96, 180); + --theme--board_pink: rgb(60, 53, 58); + --theme--board_pink-card: rgb(81, 56, 77); + --theme--board_pink-card_text: inherit; + --theme--board_pink-text: rgb(169, 76, 157); + --theme--board_red: rgb(66, 51, 51); + --theme--board_red-card: rgb(94, 52, 54); + --theme--board_red-card_text: inherit; + --theme--board_red-text: rgb(194, 65, 82); + + --theme--code_inline: rgba(135, 131, 120, 0.15); + --theme--code_inline-text: #eb5757; + + --theme--code: rgb(63, 68, 71); + --theme--code_plain: var(--theme--text); + --theme--code_property: hsl(350, 40%, 70%); + --theme--code_tag: var(--theme--code_property); + --theme--code_boolean: var(--theme--code_property); + --theme--code_number: var(--theme--code_property); + --theme--code_constant: var(--theme--code_property); + --theme--code_symbol: var(--theme--code_property); + --theme--code_deleted: #f00; + --theme--code_selector: hsl(75, 70%, 60%); + --theme--code_attr-name: var(--theme--code_selector); + --theme--code_string: var(--theme--code_selector); + --theme--code_char: var(--theme--code_selector); + --theme--code_builtin: var(--theme--code_selector); + --theme--code_inserted: var(--theme--code_selector); + --theme--code_operator: hsl(40, 90%, 60%); + --theme--code_entity: var(--theme--code_operator); + --theme--code_url: var(--theme--code_operator); + --theme--code_variable: var(--theme--code_operator); + --theme--code_comment: hsl(30, 20%, 50%); + --theme--code_cdata: var(--theme--code_comment); + --theme--code_prolog: var(--theme--code_comment); + --theme--code_doctype: var(--theme--code_comment); + --theme--code_atrule: hsl(350, 40%, 70%); + --theme--code_attr-value: var(--theme--code_atrule); + --theme--code_keyword: var(--theme--code_atrule); + --theme--code_regex: #e90; + --theme--code_important: var(--theme--code_regex); + --theme--code_function: var(--theme--code_plain); + --theme--code_class-name: var(--theme--code_function); + --theme--code_parameter: var(--theme--code_plain); + --theme--code_decorator: var(--theme--code_plain); + --theme--code_id: var(--theme--code_plain); + --theme--code_class: var(--theme--code_plain); + --theme--code_pseudo-element: var(--theme--code_plain); + --theme--code_pseudo-class: var(--theme--code_plain); + --theme--code_attribute: var(--theme--code_plain); + --theme--code_value: var(--theme--code_plain); + --theme--code_unit: var(--theme--code_plain); + --theme--code_punctuation: var(--theme--code_plain); + --theme--code_annotation: var(--theme--code_plain); +} diff --git a/repo/topbar-icons/client.mjs b/repo/topbar-icons/client.mjs new file mode 100644 index 0000000..0e57db2 --- /dev/null +++ b/repo/topbar-icons/client.mjs @@ -0,0 +1,59 @@ +/** + * notion-enhancer: topbar icons + * (c) 2020 CloudHill (https://github.com/CloudHill) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web, components }, db) { + await web.whenReady(['.notion-topbar-action-buttons']); + + const observeButton = (selector, label = '') => { + const updateButton = () => { + const $btns = document.querySelectorAll(selector); + $btns.forEach(($btn) => { + $btn.style.width = 'auto'; + $btn.style.fontSize = '14px'; + $btn.style.lineHeight = '1.2'; + $btn.style.paddingLeft = '8px'; + $btn.style.paddingRight = '8px'; + const innerHTML = label || $btn.ariaLabel; + if ($btn.innerHTML !== innerHTML) $btn.innerHTML = innerHTML; + }); + }; + web.addDocumentObserver(updateButton, [selector]); + updateButton(); + }; + + if ((await db.get(['share'])) === true) { + const selector = '.notion-topbar-share-menu', + label = await components.feather('share-2', { + style: 'width:16px;height:16px;color:var(--theme--icon);', + }); + observeButton(selector, label); + } + + if ((await db.get(['comments'])) === false) { + const selector = '.notion-topbar-comments-button'; + observeButton(selector); + } + + if ((await db.get(['updates'])) === false) { + const selector = + '.notion-topbar-updates-button, .notion-topbar-share-menu ~ [aria-label="Updates"]'; + observeButton(selector); + } + + if ((await db.get(['favorite'])) === false) { + const selector = '.notion-topbar-share-menu ~ [aria-label^="Fav"]'; + observeButton(selector); + } + + if ((await db.get(['more'])) === false) { + const selector = '.notion-topbar-more-button', + label = 'More'; + observeButton(selector, label); + } +} diff --git a/repo/topbar-icons/mod.json b/repo/topbar-icons/mod.json new file mode 100644 index 0000000..895872e --- /dev/null +++ b/repo/topbar-icons/mod.json @@ -0,0 +1,57 @@ +{ + "name": "topbar icons", + "id": "e0700ce3-a9ae-45f5-92e5-610ded0e348d", + "version": "0.3.0", + "description": "choose between text or icons for the topbar buttons.", + "preview": "topbar-icons.jpg", + "tags": ["extension", "customisation"], + "authors": [ + { + "name": "CloudHill", + "email": "rh.cloudhill@gmail.com", + "homepage": "https://github.com/CloudHill", + "avatar": "https://avatars.githubusercontent.com/u/54142180" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": {}, + "options": [ + { + "type": "toggle", + "key": "share", + "label": "share", + "tooltip": "**on = icon, off = text**", + "value": false + }, + { + "type": "toggle", + "key": "comments", + "label": "comments", + "tooltip": "**on = icon, off = text**", + "value": true + }, + { + "type": "toggle", + "key": "updates", + "label": "updates", + "tooltip": "**on = icon, off = text**", + "value": true + }, + { + "type": "toggle", + "key": "favorite", + "label": "favorite", + "tooltip": "**on = icon, off = text**", + "value": true + }, + { + "type": "toggle", + "key": "more", + "label": "more (3 dots)", + "tooltip": "**on = icon, off = text**", + "value": true + } + ] +} diff --git a/repo/topbar-icons/topbar-icons.jpg b/repo/topbar-icons/topbar-icons.jpg new file mode 100644 index 0000000..04f8c75 Binary files /dev/null and b/repo/topbar-icons/topbar-icons.jpg differ diff --git a/repo/tray/client.mjs b/repo/tray/client.mjs new file mode 100644 index 0000000..051c743 --- /dev/null +++ b/repo/tray/client.mjs @@ -0,0 +1,17 @@ +/** + * notion-enhancer: tray + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ electron, env, web }, db) { + const runInBackground = await db.get(['run_in_background']); + if (!runInBackground) return; + + // force new window creation on create new window hotkey + // hotkey is built into notion, so can't be changed, + // but is broken by this mod's window duplication prevention + web.addHotkeyListener([env.name === 'darwin' ? 'Meta' : 'Ctrl', 'Shift', 'N'], () => + electron.sendMessage('create-new-window') + ); +} diff --git a/repo/tray/createWindow.cjs b/repo/tray/createWindow.cjs new file mode 100644 index 0000000..4589738 --- /dev/null +++ b/repo/tray/createWindow.cjs @@ -0,0 +1,58 @@ +/** + * notion-enhancer: tray + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +module.exports = async function (api, db, __exports, __eval) { + const electron = require('electron'), + urlHelpers = api.electron.notionRequire('helpers/urlHelpers'), + runInBackground = await db.get(['run_in_background']); + if (!runInBackground) return; + + let appQuit = false; + electron.app.once('before-quit', () => { + appQuit = true; + }); + + const notionCreateWindow = __exports.createWindow; + __exports.createWindow = (relativeUrl = '', args) => { + const windows = api.electron.getNotionWindows(); + if (windows.length) windows.forEach((win) => win.show()); + + if (relativeUrl || !windows.length) { + // hijack close event to hide instead + const window = notionCreateWindow(relativeUrl, args); + window.prependListener('close', (e) => { + const isLastWindow = electron.BrowserWindow.getAllWindows().length === 1; + if (!appQuit && isLastWindow) { + window.hide(); + e.preventDefault(); + throw new Error(': prevent window close'); + } + }); + + // no other windows yet + opened at startup = hide + const wasOpenedAtStartup = + process.argv.includes('--startup') || + app.getLoginItemSettings({ args: ['--startup'] }).wasOpenedAtLogin; + if (!windows.length && wasOpenedAtStartup) { + window.once('ready-to-show', () => window.hide()); + } + + return window; + } else { + const window = api.electron.getFocusedNotionWindow() || windows[0]; + // prevents duplicate windows on dock/taskbar click + window.focus(); + if (relativeUrl) { + // handle requests passed via the notion:// protocol + // or ctrl+click + window.loadURL(urlHelpers.getIndexUrl(relativeUrl)); + } + return window; + } + }; +}; diff --git a/repo/tray/main.cjs b/repo/tray/main.cjs new file mode 100644 index 0000000..057161c --- /dev/null +++ b/repo/tray/main.cjs @@ -0,0 +1,108 @@ +/** + * notion-enhancer: tray + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +let tray; + +module.exports = async function (api, db, __exports, __eval) { + const { env, registry } = api, + electron = require('electron'), + path = require('path'), + enhancerIcon = path.resolve(`${__dirname}/../../media/colour-x16.png`), + hotkey = await db.get(['hotkey']), + openAtStartup = await db.get(['startup']), + runInBackground = await db.get(['run_in_background']), + menuHotkey = await ( + await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e') + ).get(['hotkey']); + + const toggleWindows = (checkFocus = true) => { + const windows = electron.BrowserWindow.getAllWindows(); + if (runInBackground) { + // hide + if (windows.some((win) => (checkFocus ? win.isFocused() : true) && win.isVisible())) { + windows.forEach((win) => [win.isFocused() && win.blur(), win.hide()]); + } else windows.forEach((win) => win.show()); + } else { + // minimize + if (windows.some((win) => (checkFocus ? win.isFocused() : true) && !win.isMinimized())) { + windows.forEach((win) => win.minimize()); + } else windows.forEach((win) => win.restore()); + } + }; + + await electron.app.whenReady(); + electron.app.setLoginItemSettings({ openAtLogin: openAtStartup, args: ['--startup'] }); + + tray = new electron.Tray(enhancerIcon); + tray.setToolTip('notion-enhancer'); + tray.on('click', () => toggleWindows(false)); + electron.globalShortcut.register(hotkey, toggleWindows); + + // connects to client hotkey listener + // manually forces new window creation + // since notion's default is broken by + // duplicate window prevention + const createWindow = () => { + const { createWindow } = api.electron.notionRequire('main/createWindow.js'); + createWindow('/'); + }; + electron.ipcMain.on('notion-enhancer:create-new-window', createWindow); + + const contextMenu = electron.Menu.buildFromTemplate([ + { + type: 'normal', + label: 'notion-enhancer', + icon: enhancerIcon, + enabled: false, + }, + { type: 'separator' }, + { + type: 'normal', + label: 'docs', + click: () => electron.shell.openExternal('https://notion-enhancer.github.io/'), + }, + { + type: 'normal', + label: 'source code', + click: () => electron.shell.openExternal('https://github.com/notion-enhancer/'), + }, + { + type: 'normal', + label: 'community', + click: () => electron.shell.openExternal('https://discord.gg/sFWPXtA'), + }, + { + type: 'normal', + label: 'enhancements menu', + accelerator: menuHotkey, + click: env.focusMenu, + }, + { type: 'separator' }, + { + type: 'normal', + label: 'toggle visibility', + accelerator: hotkey, + click: toggleWindows, + }, + { + type: 'normal', + label: 'new window', + click: createWindow, + accelerator: 'CmdOrCtrl+Shift+N', + }, + { + label: 'relaunch', + click: env.reload, + }, + { + label: 'quit', + role: 'quit', + }, + ]); + tray.setContextMenu(contextMenu); +}; diff --git a/repo/tray/mod.json b/repo/tray/mod.json new file mode 100644 index 0000000..7e3cc02 --- /dev/null +++ b/repo/tray/mod.json @@ -0,0 +1,47 @@ +{ + "name": "tray", + "id": "f96f4a73-21af-4e3f-a68f-ab4976b020da", + "environments": ["linux", "win32", "darwin"], + "version": "0.11.0", + "description": "adds an icon to the system tray/menubar for extra app/window management features (e.g. open on startup, a global hotkey).", + "preview": "tray.jpg", + "tags": ["extension", "app"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": {}, + "js": { + "client": ["client.mjs"], + "electron": [ + { "source": "main.cjs", "target": "main/main.js" }, + { "source": "createWindow.cjs", "target": "main/createWindow.js" } + ] + }, + "options": [ + { + "type": "toggle", + "key": "startup", + "label": "open notion on startup", + "tooltip": "**if the 'run notion in the background' option is also enabled, the app will open in the background on startup** (this option may require relaunching the app BEFORE restarting your system to properly take effect)", + "value": false + }, + { + "type": "toggle", + "key": "run_in_background", + "label": "run notion in the background", + "tooltip": "**pressing the close button or toggling window visibility will hide the app, running notion in the background** (instead of quitting or minimizing it)", + "value": true + }, + { + "type": "hotkey", + "key": "hotkey", + "label": "toggle window visibility hotkey", + "value": "Ctrl+Shift+A" + } + ] +} diff --git a/repo/tray/tray.jpg b/repo/tray/tray.jpg new file mode 100644 index 0000000..af425b0 Binary files /dev/null and b/repo/tray/tray.jpg differ diff --git a/repo/truncated-titles/client.mjs b/repo/truncated-titles/client.mjs new file mode 100644 index 0000000..b0fe2d6 --- /dev/null +++ b/repo/truncated-titles/client.mjs @@ -0,0 +1,66 @@ +/** + * notion-enhancer: truncated titles + * (c) 2021 admiraldus (https://github.com/admiraldus) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ web, components }, db) { + const enhanceTableTitles = await db.get(['tables']), + enhanceTimelineItems = await db.get(['timelines']), + tableCellSelector = '.notion-table-view-header-cell', + tableTitleSelector = `${tableCellSelector} div[style*="text-overflow"]`, + timelineItemSelector = '.notion-timeline-item', + $elements = []; + + const addTooltips = () => { + if (enhanceTableTitles) { + document.querySelectorAll(tableTitleSelector).forEach(($tableTitle) => { + if ($elements.includes($tableTitle)) return; + + if ($tableTitle.scrollWidth > $tableTitle.clientWidth) { + components.addTooltip( + $tableTitle.parentElement.parentElement.parentElement, + web.html`${web.escape($tableTitle.innerText)}`, + 750 + ); + $elements.push($tableTitle); + } + }); + } + + if (enhanceTimelineItems) { + document.querySelectorAll(timelineItemSelector).forEach(($timelineItem) => { + const $title = $timelineItem.nextElementSibling.firstElementChild; + $title.style.position = 'absolute'; + $title.style.left = $timelineItem.style.left; + + if ($elements.includes($timelineItem)) return; + $elements.push($timelineItem); + + $title.style.width = $timelineItem.clientWidth + 'px'; + $title.firstElementChild.firstElementChild.style.maxWidth = + $timelineItem.clientWidth + 'px'; + $timelineItem.addEventListener('mouseover', (event) => { + $title.style.width = '100%'; + $title.firstElementChild.firstElementChild.style.maxWidth = '400px'; + }); + $timelineItem.addEventListener('mouseout', async (event) => { + if (!$timelineItem.matches(':hover')) { + $title.style.width = $timelineItem.clientWidth + 'px'; + $title.firstElementChild.firstElementChild.style.maxWidth = + $timelineItem.clientWidth + 'px'; + } + }); + }); + } + }; + + await web.whenReady(); + addTooltips(); + web.addDocumentObserver(addTooltips, [ + tableCellSelector, + timelineItemSelector, + `${timelineItemSelector} + div > :first-child`, + ]); +} diff --git a/repo/truncated-titles/mod.json b/repo/truncated-titles/mod.json new file mode 100644 index 0000000..eb2cf39 --- /dev/null +++ b/repo/truncated-titles/mod.json @@ -0,0 +1,33 @@ +{ + "name": "truncated titles", + "id": "1794c0bd-7b96-46ad-aa0b-fc4bd76fc7fb", + "version": "0.2.0", + "description": "see the full text of a truncated title on hover.", + "preview": "truncated-titles.jpg", + "tags": ["extension", "layout"], + "authors": [ + { + "name": "admiraldus", + "homepage": "https://github.com/admiraldus", + "avatar": "https://raw.githubusercontent.com/admiraldus/admiraldus/main/module.gif" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": {}, + "options": [ + { + "type": "toggle", + "key": "tables", + "label": "table titles", + "value": true + }, + { + "type": "toggle", + "key": "timelines", + "label": "timeline items", + "value": true + } + ] +} diff --git a/repo/truncated-titles/truncated-titles.jpg b/repo/truncated-titles/truncated-titles.jpg new file mode 100644 index 0000000..94a1cdb Binary files /dev/null and b/repo/truncated-titles/truncated-titles.jpg differ diff --git a/repo/tweaks/client.css b/repo/tweaks/client.css new file mode 100644 index 0000000..dac5ef4 --- /dev/null +++ b/repo/tweaks/client.css @@ -0,0 +1,132 @@ +/** + * notion-enhancer: tweaks + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (c) 2020 arecsu + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.enhancer--tweak-responsive_breakpoint + .notion-column_list-block + [style='display: flex;'] + > div { + width: 100% !important; +} +.enhancer--tweak-responsive_breakpoint .notion-column_list-block [style='display: flex;'] { + flex-direction: column !important; +} +.enhancer--tweak-responsive_breakpoint .notion-app-inner, +.enhancer--tweak-full_width_pages .notion-app-inner { + --theme--page-width: 100%; + --theme--page-padding: calc(48px + env(safe-area-inset-left)); +} + +.enhancer--tweak-normalise_table_scroll + .notion-frame + .notion-page-content + .notion-collection_view-block, +.enhancer--tweak-normalise_table_scroll .notion-peek-renderer .notion-collection_view-block, +.enhancer--tweak-normalise_table_scroll + .notion-page-template-modal + .notion-collection_view-block, +.enhancer--tweak-normalise_table_dscroll .notion-collection-view-body .notion-table-view { + width: 100% !important; + padding: 0 !important; +} +.enhancer--tweak-normalise_table_scroll + .notion-collection_view-block + > [contenteditable] + > .notion-scroller + > [class$='view'][style*='padding'], +.enhancer--tweak-normalise_table_scroll + .notion-collection_view-block + > :first-child[style*='padding-right'] { + padding: 1px !important; +} + +.enhancer--tweak-snappy_transitions * { + animation-duration: 0s !important; + transition-duration: 0s !important; +} +.enhancer--tweak-snappy_transitions .notion-selectable-halo { + opacity: 1 !important; +} + +.enhancer--tweak-hide_help .notion-help-button { + display: none !important; +} + +.enhancer--tweak-hide_slash_for_commands [contenteditable]:empty:after { + content: ' ' !important; +} + +.enhancer--tweak-thicker_bold .notion-page-content span[style*='font-weight:600'] { + font-weight: 700 !important; +} + +.enhancer--tweak-spaced_lines .notion-page-content .notion-selectable.notion-text-block { + line-height: 1.65 !important; + margin-top: 0.75em !important; +} + +.enhancer--tweak-condensed_bullets .notion-selectable.notion-bulleted_list-block { + margin-top: -1.5px !important; + margin-bottom: -1.5px !important; +} + +.enhancer--tweak-bracketed_links .notion-link-token span { + border-bottom: none !important; +} +.enhancer--tweak-bracketed_links .notion-link-token:before { + content: '[['; + opacity: 0.7; + transition: opacity 100ms ease-in; +} +.enhancer--tweak-bracketed_links .notion-link-token:after { + content: ']]'; + opacity: 0.7; + transition: opacity 100ms ease-in; +} +.enhancer--tweak-bracketed_links .notion-link-token:hover::before, +.enhancer--tweak-bracketed_links .notion-link-token:hover::after { + opacity: 1; +} + +.enhancer--tweak-accented_links .notion-link-token { + color: var(--theme--accent_blue) !important; +} +.enhancer--tweak-accented_links .notion-link-token span[style*='border-bottom:0.05em'] { + opacity: 1 !important; + border-color: var(--theme--accent_blue) !important; +} + +.enhancer--tweak-quotation_marks + .notion-quote-block + [style*='border-left: 3px solid currentcolor;'] { + position: relative; + padding-left: 24px !important; + padding-right: 18px !important; +} +.enhancer--tweak-quotation_marks .notion-quote-block [placeholder='Empty quote']::before, +.enhancer--tweak-quotation_marks .notion-quote-block [placeholder='Empty quote']::after { + font-family: Georgia, serif; + font-size: 24px; + font-weight: bold; + position: absolute; +} +.enhancer--tweak-quotation_marks .notion-quote-block [placeholder='Empty quote']::before { + content: '\201C'; + left: 8px; + top: -2px; +} +.enhancer--tweak-quotation_marks .notion-quote-block [placeholder='Empty quote']::after { + content: '\201D'; + right: 2px; + bottom: -2px; +} + +.enhancer--tweak-img_alignment-left .notion-image-block { + align-self: start !important; +} +.enhancer--tweak-img_alignment-right .notion-image-block { + align-self: end !important; +} diff --git a/repo/tweaks/client.mjs b/repo/tweaks/client.mjs new file mode 100644 index 0000000..66a2660 --- /dev/null +++ b/repo/tweaks/client.mjs @@ -0,0 +1,55 @@ +/** + * notion-enhancer: tweaks + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web }, db) { + const cssInsert = await db.get(['insert.css']); + if (cssInsert?.filename) { + document.head.append( + web.html`` + ); + } + + const responsiveBreakpointPx = +(await db.get(['tweak.responsive_breakpoint_px'])), + responsiveBreakpointPercent = + screen.width * 0.01 * (await db.get(['tweak.responsive_breakpoint_percent'])), + addResponsiveBreakpoint = () => { + document.body.classList.remove('enhancer--tweak-responsive_breakpoint'); + if ( + window.innerWidth <= responsiveBreakpointPx || + window.innerWidth <= responsiveBreakpointPercent + ) { + document.body.classList.add('enhancer--tweak-responsive_breakpoint'); + } + }; + window.addEventListener('resize', addResponsiveBreakpoint); + addResponsiveBreakpoint(); + + const tweaks = [ + 'full_width_pages', + 'normalise_table_scroll', + 'hide_help', + 'hide_slash_for_commands', + 'snappy_transitions', + 'thicker_bold', + 'spaced_lines', + 'condensed_bullets', + 'bracketed_links', + 'accented_links', + 'quotation_marks', + ]; + for (const tweak of tweaks) { + if (await db.get([`tweak.${tweak}`])) { + document.body.classList.add(`enhancer--tweak-${tweak}`); + } + } + + const imgAlignment = await db.get(['tweak.img_alignment']); + if (imgAlignment !== 'center') { + document.body.classList.add(`enhancer--tweak-img_alignment-${imgAlignment}`); + } +} diff --git a/repo/tweaks/mod.json b/repo/tweaks/mod.json new file mode 100644 index 0000000..b57e912 --- /dev/null +++ b/repo/tweaks/mod.json @@ -0,0 +1,124 @@ +{ + "name": "tweaks", + "id": "5174a483-c88d-4bf8-a95f-35cd330b76e2", + "version": "0.2.0", + "description": "common style/layout changes and custom code insertion. check out the [tweaks page](https://notion-enhancer.github.io/advanced/tweaks) for more.", + "tags": ["extension", "customisation"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "css": { + "client": ["client.css"] + }, + "js": { + "client": ["client.mjs"] + }, + "options": [ + { + "type": "file", + "key": "insert.css", + "label": "css insert", + "tooltip": "**upload a css file that will be applied to the notion client**", + "extensions": [".css"] + }, + { + "type": "number", + "key": "tweak.responsive_breakpoint_px", + "label": "responsive columns breakpoint (px)", + "tooltip": "the **width in pixels below which in-page columns are resized** to appear full-width to reduce content squishing", + "value": 600 + }, + { + "type": "number", + "key": "tweak.responsive_breakpoint_percent", + "label": "responsive columns breakpoint (%)", + "tooltip": "the **percentage of the screen below which in-page columns are resized to appear full-width** to reduce content squishing", + "value": 30 + }, + { + "type": "toggle", + "key": "tweak.full_width_pages", + "label": "full width pages", + "tooltip": "**decreases padding so every page appears full width**", + "value": false + }, + { + "type": "toggle", + "key": "tweak.normalise_table_scroll", + "label": "wrap tables to page width", + "tooltip": "**force horizontally scrollable tables to respect the width and padding of a page when they overflow**", + "value": true + }, + { + "type": "toggle", + "key": "tweak.snappy_transitions", + "label": "snappy transitions", + "tooltip": "enabling this **eliminates css animation time**, but will not prevent motion e.g. the sidebar popping out", + "value": false + }, + { + "type": "toggle", + "key": "tweak.hide_help", + "label": "hide help button", + "value": false + }, + { + "type": "toggle", + "key": "tweak.hide_slash_for_commands", + "label": "hide \"Type '/' for commands\"", + "value": false + }, + { + "type": "toggle", + "key": "tweak.thicker_bold", + "label": "thicker bold text", + "value": true + }, + { + "type": "toggle", + "key": "tweak.spaced_lines", + "label": "readable line spacing", + "tooltip": "**greater line spacing between text blocks**", + "value": false + }, + { + "type": "toggle", + "key": "tweak.condensed_bullets", + "label": "condense bullet points", + "tooltip": "**tighter line spacing between bullet point blocks**", + "value": false + }, + { + "type": "toggle", + "key": "tweak.bracketed_links", + "label": "bracketed links", + "tooltip": "**render links surrounded with [[brackets]] instead of __underlined__**", + "value": false + }, + { + "type": "toggle", + "key": "tweak.accented_links", + "label": "accented links", + "tooltip": "**links are shown by default with notion's blue colour or a theme's equivalent**", + "value": false + }, + { + "type": "toggle", + "key": "tweak.quotation_marks", + "label": "quote block quotation marks", + "tooltip": "**wrap quote block content in large, decorative serif quotation marks**", + "value": false + }, + { + "type": "select", + "key": "tweak.img_alignment", + "label": "image alignment", + "values": ["center", "left", "right"] + } + ] +} diff --git a/repo/view-scale/client.css b/repo/view-scale/client.css new file mode 100644 index 0000000..652cad1 --- /dev/null +++ b/repo/view-scale/client.css @@ -0,0 +1,90 @@ +/** + * notion-enhancer: view scale + * (c) 2021 SP12893678 (https://sp12893678.tk/) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +.view_scale--container { + border: 1px solid var(--theme--ui_divider); + border-radius: 9999px !important; + margin: 0 4px; + padding: 0 5px 0 4px; + align-items: center; + justify-content: center; + display: flex; +} + +.view_scale--slider { + appearance: none; + outline: 0; + border: 0px; + overflow: hidden; + width: 150px; + height: 20px; + margin: auto 4px auto 0; + cursor: ew-resize; + border-radius: 9999px; +} +.view_scale--slider::-webkit-slider-runnable-track { + appearance: none; + height: 20px; + background-color: var(--theme--ui_toggle-off); +} +.view_scale--slider::-webkit-slider-thumb { + appearance: none; + position: relative; + width: 20px; + height: 20px; + border-radius: 9999px; + border: 0px; + background: var(--theme--ui_toggle-on); + box-shadow: -100px 0 0 90px var(--theme--ui_toggle-on), + inset 0 0 0 20px var(--theme--ui_toggle-on); + transition: 0.2s; +} +.view_scale--slider:active::-webkit-slider-thumb { + background: var(--theme--ui_toggle-feature); + box-shadow: -100px 0 0 90px var(--theme--ui_toggle-on), + inset 0 0 0 2px var(--theme--ui_toggle-on); +} + +.view_scale--counter { + font-size: 14px; + margin: auto 4px auto 0; + width: 5ch; + text-align: right; +} + +.view_scale--button { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: 9999px; + height: 20px; + width: 20px; + padding: 0 0.25px 0 0; + + margin-left: 2px; + border: none; + background: transparent; + font-size: 18px; +} +.view_scale--button:focus, +.view_scale--button:hover { + background: var(--theme--ui_interactive-hover); +} +.view_scale--button:active { + background: var(--theme--ui_interactive-active); +} +.view_scale--button svg { + display: block; + width: 14px; + height: 14px; + fill: var(--theme--icon); + color: var(--theme--icon); +} diff --git a/repo/view-scale/client.mjs b/repo/view-scale/client.mjs new file mode 100644 index 0000000..95ae64c --- /dev/null +++ b/repo/view-scale/client.mjs @@ -0,0 +1,87 @@ +/** + * notion-enhancer: view scale + * (c) 2021 SP12893678 (https://sp12893678.tk/) + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +export default async function ({ electron, web, components }, db) { + let zoomFactor = (await db.get(['default_zoom'])) / 100, + updateScale = () => {}; + electron.webFrame.setZoomFactor(zoomFactor); + + const zoomOffset = (await db.get(['offset'])) / 100, + zoomMin = 0.5, + zoomMax = 2, + getZoomFactor = () => electron.webFrame.getZoomFactor(), + setZoomFactor = (zoomFactor) => electron.webFrame.setZoomFactor(zoomFactor), + zoomPlus = (multiplier = 1) => { + zoomFactor = Math.min(getZoomFactor() + zoomOffset * multiplier, zoomMax); + setZoomFactor(zoomFactor); + updateScale(); + }, + zoomMinus = (multiplier = 1) => { + zoomFactor = Math.max(getZoomFactor() - zoomOffset * multiplier, zoomMin); + setZoomFactor(zoomFactor); + updateScale(); + }; + + const mousewheelModifier = await db.get(['mousewheel']); + if (mousewheelModifier !== '-- none --') { + const mousewheelModifierKey = { + Control: 'ctrlKey', + Alt: 'altKey', + Command: 'metaKey', + Shift: 'shiftKey', + }[mousewheelModifier]; + document.addEventListener('wheel', (event) => { + if (event[mousewheelModifierKey] && event.deltaY < 0) zoomPlus(); + if (event[mousewheelModifierKey] && event.deltaY > 0) zoomMinus(); + }); + } + + const showVisualSlider = await db.get(['ui']); + if (showVisualSlider) { + const topbarActionsSelector = + '.notion-topbar-action-buttons > div[style="display: flex;"]'; + await web.whenReady([topbarActionsSelector]); + + const $topbarActions = document.querySelector(topbarActionsSelector), + $scaleContainer = web.html`
`, + $scaleSlider = web.html``, + $scaleCounter = web.html`100%`, + $scalePlus = web.html``, + $scaleMinus = web.html``; + components.addTooltip($scalePlus, '**Zoom into the window**'); + components.addTooltip($scaleMinus, '**Zoom out of the window**'); + updateScale = () => { + if (getZoomFactor() !== zoomFactor) zoomFactor = getZoomFactor(); + $scaleSlider.value = Math.round(zoomFactor * 100); + $scaleCounter.innerHTML = Math.round(zoomFactor * 100) + '%'; + }; + updateScale(); + + $scaleSlider.addEventListener('input', () => { + zoomFactor = $scaleSlider.value / 100; + $scaleCounter.innerHTML = Math.round(zoomFactor * 100) + '%'; + }); + $scaleSlider.addEventListener('change', () => setZoomFactor(zoomFactor)); + $scalePlus.addEventListener('click', () => zoomPlus()); + $scaleMinus.addEventListener('click', () => zoomMinus()); + + $topbarActions.prepend( + web.render($scaleContainer, $scaleSlider, $scaleCounter, $scalePlus, $scaleMinus) + ); + + web.addHotkeyListener(['Ctrl', '+'], updateScale); + web.addHotkeyListener(['Ctrl', '-'], updateScale); + web.addHotkeyListener(['Ctrl', '0'], updateScale); + web.addHotkeyListener(['Command', '+'], updateScale); + web.addHotkeyListener(['Command', '-'], updateScale); + web.addHotkeyListener(['Command', '0'], updateScale); + } +} diff --git a/repo/view-scale/mod.json b/repo/view-scale/mod.json new file mode 100644 index 0000000..0a9059c --- /dev/null +++ b/repo/view-scale/mod.json @@ -0,0 +1,48 @@ +{ + "name": "view scale", + "id": "e71ce1e0-024c-435e-a25e-7dd50448d1df", + "environments": ["linux", "win32", "darwin"], + "version": "0.1.0", + "description": "zoom in/out of the notion window with the mousewheel or a visual slider (`ctrl/cmd +/-` are available in-app by default).", + "preview": "view-scale.jpg", + "tags": ["extension", "app"], + "authors": [ + { + "name": "SP12893678", + "homepage": "https://sp12893678.tk/", + "avatar": "https://sp12893678.tk/img/avatar.jpg" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [ + { + "type": "number", + "key": "offset", + "label": "scale +/- offset (%)", + "value": 10 + }, + { + "type": "number", + "key": "default_zoom", + "label": "default scale (%)", + "value": 100 + }, + { + "type": "toggle", + "key": "ui", + "label": "visual slider", + "value": true + }, + { + "type": "select", + "key": "mousewheel", + "label": "mousewheel scaling keyboard modifier", + "values": ["Control", "Alt", "Command", "Shift", "-- none --"] + } + ] +} diff --git a/repo/view-scale/view-scale.jpg b/repo/view-scale/view-scale.jpg new file mode 100644 index 0000000..f7ee516 Binary files /dev/null and b/repo/view-scale/view-scale.jpg differ diff --git a/repo/weekly-view/client.mjs b/repo/weekly-view/client.mjs new file mode 100644 index 0000000..426f5ba --- /dev/null +++ b/repo/weekly-view/client.mjs @@ -0,0 +1,71 @@ +/** + * notion-enhancer: weekly view + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +export default async function ({ web }, db) { + const pageSelector = '.notion-page-content', + calendarSelector = '.notion-calendar-view', + viewSelector = + '.notion-page-content > .notion-selectable.notion-collection_view-block', + viewControlSelector = ':scope>div>div>div>div>div', + todaySelector = '.notion-calendar-view-day[style*="background"]', + weekSelector = '[style^="position: relative; display: flex; height: "]', + toolbarBtnSelector = + '.notion-calendar-view > :first-child > :first-child > :first-child > :nth-last-child(2)'; + + const transformCalendarView = () => { + const $page = document.querySelector(pageSelector); + document.querySelectorAll(viewSelector).forEach(async ($view) => { + let currentText; + // Get view controls children nodes, convert to array, filter out non-text + const $viewNodes = [] + .slice.call($view.querySelector(viewControlSelector).children) + .filter(node => node.tagName.toLowerCase().match(/(div|span)/g)); + + // Find current view by analyzing children (which changes on viewport) + if ($viewNodes.length === 1) + { + // Mobile: Simple dropdown button (like legacy), text is current view + currentText = $viewNodes[0].innerText.toLowerCase(); + } else { + // Wide/Desktop: Tabs listed, current view indicated by border style + currentText = $viewNodes + // Find selected view by border style (possibly fragile) + .filter(($e) => $e.children[0].style.borderBottomWidth.toString() === '2px')[0] + .innerText.toLowerCase(); + } + + if (currentText !== 'weekly') return; + + const $calendar = $view.parentElement.parentElement.parentElement.parentElement; + if (!$calendar.querySelector(todaySelector)) { + $calendar.querySelector(toolbarBtnSelector).click(); + } + await new Promise((res, rej) => requestAnimationFrame(res)); + if ($page) { + for (const $week of $calendar.querySelectorAll(weekSelector)) { + if (!$week.querySelector(todaySelector)) { + $week.style.height = 0; + $week.style.visibility = 'hidden'; + } + } + } else { + const $weekContainer = $calendar.querySelector(weekSelector).parentElement; + for (const $week of $calendar.querySelectorAll(weekSelector)) { + if ($week.querySelector(todaySelector)) { + $weekContainer.style.maxHeight = $week.style.height; + break; + } else { + $week.style.height = '0'; + $week.style.visibility = 'hidden'; + } + } + } + }); + }; + web.addDocumentObserver(transformCalendarView, [calendarSelector]); +} diff --git a/repo/weekly-view/mod.json b/repo/weekly-view/mod.json new file mode 100644 index 0000000..6128450 --- /dev/null +++ b/repo/weekly-view/mod.json @@ -0,0 +1,21 @@ +{ + "name": "weekly view", + "id": "4c7acaea-6596-4590-85e5-8ac5a1455e8f", + "version": "0.6.0", + "description": "calendar views named \"weekly\" will show only the current week.", + "preview": "weekly-view.jpg", + "tags": ["extension", "layout"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": {}, + "options": [] +} diff --git a/repo/weekly-view/weekly-view.jpg b/repo/weekly-view/weekly-view.jpg new file mode 100644 index 0000000..345d33d Binary files /dev/null and b/repo/weekly-view/weekly-view.jpg differ diff --git a/repo/word-counter/client.css b/repo/word-counter/client.css new file mode 100644 index 0000000..bd44781 --- /dev/null +++ b/repo/word-counter/client.css @@ -0,0 +1,40 @@ +/** + * notion-enhancer: word counter + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +#word-counter--notice { + color: var(--theme--text_secondary); + font-size: 14px; + margin-top: 0; +} + +.word-counter--stat { + display: block; + background: var(--theme--ui_interactive-hover); + color: var(--theme--text); + font-size: 14px; + line-height: 1.2; + border: 1px solid transparent; + border-radius: 3px; + padding: 6px 8px; + cursor: pointer; + user-select: none; +} +.word-counter--stat:focus, +.word-counter--stat:hover { + background: transparent; + border: 1px solid var(--theme--ui_interactive-hover); +} +.word-counter--stat:active { + background: var(--theme--ui_interactive-active); +} + +.word-counter--stat svg { + display: inline-block; + height: 1em; + width: 1em; + margin: 0 0.4em -2px 0; + color: var(--theme--icon_secondary); +} diff --git a/repo/word-counter/client.mjs b/repo/word-counter/client.mjs new file mode 100644 index 0000000..30722d3 --- /dev/null +++ b/repo/word-counter/client.mjs @@ -0,0 +1,108 @@ +/** + * notion-enhancer: word counter + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +const humanTime = (mins) => { + let readable = ''; + if (1 <= mins) { + readable += `${Math.floor(mins)} min`; + if (2 <= mins) readable += 's'; + } + const secs = Math.round((mins % 1) * 60); + if (1 <= secs) { + if (1 <= mins) readable += ' '; + readable += `${secs} sec`; + if (2 <= secs) readable += 's'; + } + return readable; +}; + +export default async function ({ web, components }, db) { + const dbNoticeText = 'Open a page to see its word count.', + pageNoticeText = 'Click a stat to copy it.', + $notice = web.html`

${dbNoticeText}

`; + + const $wordCount = web.html`12`, + $characterCount = web.html`12`, + $sentenceCount = web.html`12`, + $blockCount = web.html`12`, + $readingTime = web.html`10 mins`, + $readingTooltip = web.html`${await components.feather('info')}`, + $speakingTime = web.html`18 secs`, + $speakingTooltip = web.html`${await components.feather('info')}`, + $statList = web.render( + web.html`
`, + web.render(web.html`

`, $wordCount, ' words'), + web.render(web.html`

`, $characterCount, ' characters'), + web.render(web.html`

`, $sentenceCount, ' sentences'), + web.render(web.html`

`, $blockCount, ' blocks'), + web.render( + web.html`

`, + $readingTooltip, + $readingTime, + ' reading time' + ), + web.render( + web.html`

`, + $speakingTooltip, + $speakingTime, + ' speaking time' + ) + ); + $statList.querySelectorAll('.word-counter--stat').forEach(($stat) => { + $stat.addEventListener('click', () => web.copyToClipboard($stat.innerText)); + }); + components.addTooltip($readingTooltip, '**~ 275 wpm**', { offsetDirection: 'left' }); + components.addTooltip($speakingTooltip, '**~ 180 wpm**', { offsetDirection: 'left' }); + + let viewFocused = false, + $page; + await components.addPanelView({ + id: 'b99deb52-6955-43d2-a53b-a31540cd19a5', + icon: await components.feather('type'), + title: 'Word Counter', + $content: web.render(web.html`
`, $notice, $statList), + onFocus: () => { + viewFocused = true; + $page = document.getElementsByClassName('notion-page-content')[0]; + updateStats(); + }, + onBlur: () => { + viewFocused = false; + }, + }); + + function updateStats() { + if (!$page) return; + const words = $page.innerText.split(/[^\w]+/).length; + $wordCount.innerText = words; + $characterCount.innerText = $page.innerText.length; + $sentenceCount.innerText = $page.innerText.split('.').length; + $blockCount.innerText = $page.querySelectorAll('[data-block-id]').length; + $readingTime.innerText = humanTime(words / 275); + $speakingTime.innerText = humanTime(words / 180); + } + const pageObserver = () => { + if (!viewFocused) return; + if (document.contains($page)) { + updateStats(); + } else { + $page = document.getElementsByClassName('notion-page-content')[0]; + if ($page) { + $notice.innerText = pageNoticeText; + $statList.style.display = ''; + updateStats(); + } else { + $notice.innerText = dbNoticeText; + $statList.style.display = 'none'; + } + } + }; + web.addDocumentObserver(pageObserver, [ + '.notion-page-content', + '.notion-collection_view_page-block', + ]); + pageObserver(); +} diff --git a/repo/word-counter/mod.json b/repo/word-counter/mod.json new file mode 100644 index 0000000..ad52d9f --- /dev/null +++ b/repo/word-counter/mod.json @@ -0,0 +1,23 @@ +{ + "name": "word counter", + "id": "b99deb52-6955-43d2-a53b-a31540cd19a5", + "version": "0.3.0", + "description": "view word/character/sentence/block count & speaking/reading times in the side panel.", + "preview": "word-counter.jpg", + "tags": ["extension", "panel"], + "authors": [ + { + "name": "dragonwocky", + "email": "thedragonring.bod@gmail.com", + "homepage": "https://dragonwocky.me/", + "avatar": "https://dragonwocky.me/avatar.jpg" + } + ], + "js": { + "client": ["client.mjs"] + }, + "css": { + "client": ["client.css"] + }, + "options": [] +} diff --git a/repo/word-counter/word-counter.jpg b/repo/word-counter/word-counter.jpg new file mode 100644 index 0000000..43978fc Binary files /dev/null and b/repo/word-counter/word-counter.jpg differ