Compare commits

..

No commits in common. "dev" and "v0.10.1" have entirely different histories.
dev ... v0.10.1

278 changed files with 12222 additions and 13612 deletions

23
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@ -0,0 +1,23 @@
---
name: bug report
about: report any broken/glitchy enhancer behaviour
title: ''
labels: bug
assignees: ''
---
FILL OUT THIS TEMPLATE, REMOVING/REPLACING EVERYTHING HERE WITH YOUR OWN INFORMATION.
BE AS CLEAR AND CONCISE AS POSSIBLE.
**describe the bug**
what is the bug - what happens?
**expected behaviour**
why is this a bug - what should be happening?
**screenshots**
if applicable, add screenshots of your problem.
**platform**
what OS are you using? e.g. windows 7, windows 10, WSL, ubuntu, arch linux, macOS

View File

@ -0,0 +1,21 @@
---
name: feature request
about: got an idea for a new feature?
title: ''
labels: enhancement
assignees: ''
---
FILL OUT THIS TEMPLATE, REMOVING/REPLACING EVERYTHING HERE WITH YOUR OWN INFORMATION.
BE AS CLEAR AND CONCISE AS POSSIBLE.
**problem**
why do you need this feature? e.g. smoother app experience, sharing/displaying content for other users, ____ always frustrates you
**solution**
how do you want this feature to appear/act? do you have any suggestions for how it could be implemented?
**alternatives (optional)**
have you tried to do this yourself? have you seen it done somewhere else?
would a different feature remove the need for this?

107
.gitignore vendored
View File

@ -1,9 +1,104 @@
# builds # Logs
dist/ logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# dependencies # Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/ node_modules/
jspm_packages/
# yarn # TypeScript v1 declaration files
.yarn/ typings/
.pnp.*
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port

View File

@ -1,127 +1,9 @@
# changelog # changelog
### v0.11.0 (dev) **potential future features (not confirmed)**
a complete redesign & rewrite of the enhancer, with new features and a port to the browser as a chrome extension. - [highlight/mark viewer](https://chrome.google.com/webstore/detail/notion%2B-mark-manager/hipgmnlpnimedfepbfbfiaobohhffcfc)
- [advanced math editor](https://github.com/Manueloccorso/NotionMathEditor_BrowserExtension)
#### new
- cross-environment and properly documented api to replace helpers.
- cross-environment mod loader structure.
- "integrations", a category of mods that can access/use an unofficial notion api.
- notifications sourced from an online endpoint for sending global user alerts.
- simplify user installations by depending on the chrome web store and [notion-repackaged](https://github.com/notion-enhancer/notion-repackaged).
- separate menu profiles for mod configurations.
- a hotkey option type that allows typing in/pressing a hotkey to enter it, instead of typing.
- a rainbow indentation lines style.
- border & background style options for the code line numbers extension.
- an icon sets option to encode images to data urls to prevent quality reduction.
- customisation of integrated titlebar & always on top window buttons.
- an open on startup option under the tray mod.
- optional icon or title-only tab labels.
- choice of tab layout styles: traditional tabbed, traditional, bubble and compact.
- a hotkey for reopening closed tabs.
- an option to remember last open tabs for a continue-where-you-left-off experience
(recently active tabs are reopened after an app relaunch).
#### improved
- split the core mod into separate mods for specific features.
- theming variables that are applied more specifically, less laggy, and less complicated.
- merged bracketed-links into tweaks.
- a redesigned menu with nicer ui, separate categories for mods and a sidebar for configuration.
- simplified and smoothened the side panel + moved it to the core so any mod can hook into it.
- font chooser option for heading fonts.
- renamed "property-layout" to "collapsible properties", added per-page memory of collapse state.
- chevron icon instead of arrow for scroll to top.
- moved word counter to display in the side panel instead of within the page,
implemented a more accurate word counter method.
- the topbar icons extension defaults to the notion default topbar icons for comment/updates/favorite/more,
but can revert them to text (it still adds a custom icon for the share button).
- relative indenting in outliner.
- rtl support for toggles, indentation lines, table of contents and databases + force inline math to ltr.
- replaced the "truncated table titles" extension with a "truncated titles" extension
with an option to truncate timeline item titles.
- renamed "notion icons" to "icon sets" with new support for uploading/reusing custom icons
directly within the icon picker.
- moved the tray to its own configurable and enable/disable-able mod, with window management enhancements
that follow more sensible defaults and work more reliably.
- tabs will auto shrink/expand to take up available space instead of wrapping to a second line.
- a visually revamped cli to more clearly and aesthetically communicate status and usage.
- cli can now detect and apply to user-only installations on macOS.
- a shortcut built into the cli to fix the "you do not have permission to open this app" error on macos.
#### removed
- integrated scrollbar tweak (notion now includes by default).
- js insert. css insert moved to tweaks mod.
- majority of layout and font size variables - better to leave former to notion and use `ctrl +`/`ctrl -` for latter.
- the "panel sites" extension, due to it's limited/buggy functionality and incompatibility with reimplementation.
#### fixed
- bypass csp restrictions.
- many. like many many. all the bugfixes. (mostly a side effect of completely rewriting everything,
but reported extension-specific bugs were all intentionally fixed.)
#### themes
- "nord" = an arctic, north-bluish color palette.
- "gruvbox light" = a sepia, 'retro groove' palette based on the vim theme of the same name.
- "gruvbox dark" = a gray, 'retro groove' palette based on the vim theme of the same name.
- "light+" = a simple white theme that brightens coloured text and blocks,
with configurable accents (formerly littlepig light).
- "playful purple" = a purple-shaded theme with bright highlights (formerly littlepig dark and gameish).
- "pinky boom" = pinkify your life.
#### extensions
- "calendar scroll" = add a button to jump down to the current week in fullpage/infinite-scroll calendars.
- "global block links" = easily copy the global link of a page or block.
- "collapsible headers" = adds toggles to collapse header sections of pages.
- "simpler databases" = adds a menu to inline databases to toggle ui elements.
- "view scale" = zoom in/out of the notion window with the mousewheel or a visual slider (`ctrl/cmd +/-` are available in-app by default).
#### tweaks
- wrap tables to page width. - hide "Type '/' for commands".
- quote block quotation marks.
- responsive columns breakpoint (%).
- accented links.
- full width pages.
- image alignment (center/left/right).
#### integrations
- "quick note" = 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).
**below this point the enhancer was desktop-only. in v0.11.0 it was been ported to also**
**run as a chrome extension. changes made to both are indicated above.**
### v0.10.2 (2020-12-05)
again, an emergency release for bugfixes.
not properly documented and new features have not yet been fully reviewed/edited.
- new: side panel - adds an extra sidebar on the right for use by other mods,
toggleable with `ctrl+shift+backslash`.
- improved: notion icons uses spritesheets for faster loading of icons.
- improved: icon sets can be hidden/toggled.
- improved: toggles in the enhancer menu follow the same style as notion's toggles.
- improved: separate quote font variable & option in the font chooser mod (`--theme_[dark|light]--font_quote`).
- improved: option to hide the "page details" text for the word counter extension.
- bugfix: notion icons tab is now visible in fullpage databases.
- bugfix: code line numbers handles wrapped code blocks.
- bugfix: file explorer no longer opens when enhancer menu is opened.
- bugfix: enable the remote module in webviews (windows/tabs) for compatibility with the
updated version of electron used by new notion builds (>= 2.0.10).
- bugfix: add support for enhancing an `app` folder if there is no `app.asar` file present.
- extension: "outliner" = table of contents in right sidebar.
- extension: "panel sites" = embed sites on the site panel.
- extension: "indentation lines" = adds vertical relationship lines to make list trees easier to follow.
- extension: "truncated table titles" = see the full text of the truncated table titles on hover over.
> 📥 `npm i -g notion-enhancer@0.10.2`
### v0.10.1 (2020-11-18) ### v0.10.1 (2020-11-18)
@ -364,7 +246,7 @@ complete rewrite with node.js.
- bugfix: odd mix of `\\` and `/` being used for windows filepaths. - bugfix: odd mix of `\\` and `/` being used for windows filepaths.
- bugfix: app no longer crashes when sidebar is toggled. - bugfix: app no longer crashes when sidebar is toggled.
> 📥 [notion-enhancer.v0.7.0.zip](https://github.com/notion-enhancer/desktop/archive/v0.7.0.zip) > 📥 [notion-enhancer.v0.7.0.zip](https://github.com/notion-enhancer/notion-enhancer/archive/v0.7.0.zip)
### v0.6.0 (2020-06-30) ### v0.6.0 (2020-06-30)
@ -378,7 +260,7 @@ complete rewrite with node.js.
- improved: more obviously visible drag area. - improved: more obviously visible drag area.
- bugfix: specify UTF-8 encoding to prevent multibyte/gbk codec errors (thanks to [@etnperlong](https://github.com/etnperlong)). - bugfix: specify UTF-8 encoding to prevent multibyte/gbk codec errors (thanks to [@etnperlong](https://github.com/etnperlong)).
> 📥 [notion-enhancer.v0.6.0.zip](https://github.com/notion-enhancer/desktop/archive/v0.6.0.zip) > 📥 [notion-enhancer.v0.6.0.zip](https://github.com/notion-enhancer/notion-enhancer/archive/v0.6.0.zip)
### v0.5.0 (2020-05-23) ### v0.5.0 (2020-05-23)
@ -390,12 +272,12 @@ complete rewrite with node.js.
improved: scrollbar colours that fit better with notion's theming. improved: scrollbar colours that fit better with notion's theming.
- bugfix: un-break having multiple notion windows open. - bugfix: un-break having multiple notion windows open.
> 📥 [notion-enhancer.v0.5.0.zip](https://github.com/notion-enhancer/desktop/archive/v0.5.0.zip) > 📥 [notion-enhancer.v0.5.0.zip](https://github.com/notion-enhancer/notion-enhancer/archive/v0.5.0.zip)
**development here taken over by [@dragonwocky](https://github.com/dragonwocky).** **development here taken over by [@dragonwocky](https://github.com/dragonwocky).**
**the ~~crossed out~~ features below are no longer features included by default,** **the ~~crossed out~~ features below are no longer features included by default,**
**but can still easily be added as [custom tweaks](https://github.com/notion-enhancer/tweaks).** **but can still easily be added as [custom tweaks](TWEAKS.md).**
### v0.4.1 (2020-02-13) ### v0.4.1 (2020-02-13)

111
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,111 @@
# contributing
the enhancer is a tool for the community, so who best to build it but the community?
these guidelines are designed for smooth communication, management and development on this project.
following them shows respect to the developer/s spending their free time on it, and makes it easiest for them to improve the tool.
**found a bug / something isn't working as expected?** create a
[bug report](https://github.com/notion-enhancer/notion-enhancer/issues/new?labels=bug&template=bug-report.md).
> SECURITY ISSUE? (e.g. PERSONAL/NOTION DATA BEING INTERFERED WITH)
> EMAIL ME INSTEAD: [thedragonring.bod@gmail.com](mailto:thedragonring.bod@gmail.com)
**have a cool new feature idea / there's something you just wish you could do?** submit a
[feature request](https://github.com/notion-enhancer/notion-enhancer/issues/new?labels=enhancement&template=feature-request.md).
> enhancements are applied only locally -
> features should be designed only to improve the user experience.
**know your way around notion/electron/js/css and have some code to contribute?** great! read below for guidelines
on how to create a helpful pull request and what happens with your code afterwards. it's probably also helpful to
join the [discord server](https://discord.gg/sFWPXtA).
**for information on how to actually create a theme or module with the notion-enhancer api, check the [docs](DOCUMENTATION.md).**
## testing
first, remove any other installations of the enhancer: `npm remove -g notion-enhancer`
to download and install the latest code, run:
```sh
git clone https://github.com/notion-enhancer/notion-enhancer
cd notion-enhancer
git checkout dev
npm link
notion-enhancer apply -y
```
to update the dev build, go into the downloaded folder and run `git pull`. (make sure any work-in-progress themes etc. are copied somewhere else safely first.)
to remove the dev build, go into the downloaded folder and run:
```sh
notion-enhancer remove -n
npm unlink
```
## conventions
the enhancer is a **core** extended by included **modules**.
the core can be further split into the **installer** and the **modloader**.
modules are either **extensions** or **themes**.
each module is separately versioned, following the [semver](https://semver.org/) scheme.
depending on the content and scale of a contribution, it may constitute an update on its own or may be merged into a larger update.
to keep a consistent & informative code style it is preferred to name variables with
`snake_case`, functions/methods with `camelCase`, and classes with `PascalCase`.
if a variable is a reference to a DOM element, it may be helpful to prefix it with a `$`.
some variables beginning with a double underscore are `__folder` paths and `ALL_CAPS` variables
are constant. this is not required, but these styles should not be used for any other purpose.
the master branch is kept consistent with the current release,
so all changes should be made to the dev branch.
## review
active core devs will manually look through each pull request and communicate with contributors before merging to
make sure it is:
**a) safe.** system details (e.g. IP, clipboard) + notion user data are considered private unless directly shared by the user.
none of this should be accessed or transmitted to an external server.
**b) functional.** is there a better way to do this? can extra dependencies be removed or replaced by newer web technologies?
how can this be made as user-friendly as possible?
**c) bug-free.** where possible, code should be tested on a variety of platforms in a variety of situations so it can be
confirmed that it won't break anything for the user and is robust enough to handle use by both
power users and non-tech-savvy users.
## translating
future versions of the enhancer will have multi-language support.
if you are willing to help with translation, let me know and i'll contact you when i'm ready.
## licensing
this project is distributed under the [MIT](https://choosealicense.com/licenses/mit/) license.
the project as a whole is copyrighted by core devs in the [LICENSE](LICENSE) file.
when modifying a file, add your copyright to it in the format:
```
/*
* module or project name
* (c) year name <email> (website)
* under the MIT license
*/
```
all code contributed to this repository remains attributed to the contributor,
but full rights are granted for it to be used under the terms of the MIT license.
on the occasion that the contributed code should be removed or overwritten,
the contributor's copyright may be removed from the file.
by opening a pull request in this repository, you agree to the above conditions.
dependencies remain separately licensed to their various authors.

217
DOCUMENTATION.md Normal file
View File

@ -0,0 +1,217 @@
# documentation
the enhancer is essentially a modloader for notion. this document contains the specifications of
how those modules can be made and what they should contain.
this file assumes basic working knowledge of modern javascript and css. since these are the languages
executable within the notion app, these are the languages enhancements must be written in.
want to contribute? check the [contribution guidelines](CONTRIBUTING.md).
for support, join the [discord server](https://discord.gg/sFWPXtA).
## creating a mod
_to understand best how notion's app works, check out [the electron docs](https://www.electronjs.org/docs/),_
_explore the contents of your local extracted `app.asar`, and navigate the html structure with the devtools web inspector._
_look through [the existing modules](mods)_
_for examples of the stuff described below in action._
_at the moment, for ease of development and use (and security assurance), there's no way for users_
_to install their own modules. this means that testing modules requires_
_[running a dev build of the enhancer](CONTRIBUTING.md#testing). a better system is in the works._
_once your mod is working, open a pull request to add it to the enhancer!_
each directory in the `mods` folder is considered a module, with the file entry points `mod.js`,
`variables.css`, `app.css`, `tabs.css` and `menu.css`.
| file | description |
| ------------ | --------------------------------------------------------------------- |
| `mod.js` | **required:** describes the module and contains functional javascript |
| `styles.css` | **optional:** a css file automatically inserted into each app window |
## mod.js
```js
// not valid js!
// a visual representation of the contents/type
// of this file's exported object.
module.exports = {
id: String of uuidv4,
name: String of short_name,
tags?: Array<String> of categories,
desc: String of markdown,
version: String of semver,
author: String of github_username OR {
name: String of author_name,
link: String of url,
avatar: String of image_source,
},
options?: Array<{
key: String,
label: String,
desc?: String,
type: String in ['toggle', 'select', 'input', 'file'],
value: Boolean or Array<String> or String or Number or null,
platformOverwrite?: {
darwin?: Boolean or Array<String> or String or Number or null,
win32?: Boolean or Array<String> or String or Number or null,
linux?: Boolean or Array<String> or String or Number or null,
}
}>,
hacks?: {
[k: 'insert-point' (e.g. 'main/createWindow.js')]: function (
store, // used for configuration and persisting of data (explanation below).
__exports // module.exports of the target file. if you don't understand that, don't use it.
) {}
}
};
```
| key | value | type |
| ------- | ----------------------------------------------------------------------------------------------- | ---------------------- |
| id | **required:** uuidv4 - generate a new one [here](https://www.uuidgenerator.net) | _string_ |
| name | **required:** short name (e.g. `'ocean theme'`) | _string_ |
| tags | **required:** categories/type (e.g. `'extension'`, `'theme'`, `'light'`, `'dark'`) | _array\<string\>_ |
| desc | **optional:** 1-3 sentence description of what the module is/does, with basic markdown support. | _string_ |
| version | **required:** semver (e.g. `'0.3.7'`) | _string_ |
| author | **required:** see below: original extension creator | _string_ or \<object\> |
| options | **optional:** see below: options made available in the enhancer menu (accessible from the tray) | _array\<object\>_ |
| hacks | **optional:** see below: code inserted at various points | _object_ |
> a module that with the primary function of being a hack should be tagged as an extension,
> while a module that has the primary function of adding styles should be tagged as a theme.
#### author
by default this is assumed to be a github username: just pass it as a string and
the link/avatar will be automatically found.
if you'd rather customise this, pass this object:
| key | value | type |
| ------ | ------------------------------------------ | -------- |
| name | **required:** author's (your?) name | _string_ |
| link | **required:** link to the author's profile | _string_ |
| avatar | **required:** url for the author's avatar | _string_ |
#### options
| key | value | type |
| ----------------- | ---------------------------------------------------------------------------------------- | --------------------------- |
| key | **required:** key to save value to the mod `store` | _string_ |
| label | **required:** short description/name of option to be shown in menu | _string_ |
| desc | **optional:** extended information to be shown on hover | _string_ |
| type | **required:** input type (see below) | _string_ |
| extensions | **optional:** allowed file extensions (only use with a file option), e.g. `['js', 'ts']` | _array\<string\>_ |
| value | **optional:** default or possible value/s for option | see below |
| platformOverwrite | **optional:** remove the option from the menu and force a value on a specific platform | _\<object\>_ as shown above |
| type | value |
| ------ | -------------------- |
| toggle | _boolean_ |
| select | _array\<string\>_ |
| input | _string_ or _number_ |
| color | _string_ |
| file | none |
> the file option stores only a filepath, not the file itself.
## hacks
each "hack" is a function taking 2 arguments.
1. the **`store`** argument, which allows access to the module settings/options defined in `mod.js`
(those set in the menu, or used internally by the module). each module store is automatically saved to +
loaded from `~/.notion-enhancer/id.json`.
it should always be called as `store({ defaults })` (not stored in a variable),
but otherwise treated as a normal object to access and set things.
2. the **`__exports`** argument, which is the `module.exports` of the file being modded.
this can be used to call or replace functions from notion.
this hack is applied to whichever file (`.js`-only) is set as the function key. these can be found within the `app` folder.
files under the `main` folder are executed on app launch in a process shared
between all app windows (consider it a backend). files under the `renderer` folder are
executed on window launch in a pre-window process: the client-side javascript
normally expected to run on a webpage.
unless scripts need to change app logic (e.g. to add the tray menu),
they should usually be applied to `renderer/preload.js` to interact
with the app window itself.
e.g.
```js
// sayhi.js
module.exports = function (store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
console.log(store({ name: 'dragonwocky' }).name);
});
};
// mod.js
module.exports.hacks = {
'renderer/preload.js': require('./sayhi.js'),
};
```
### the `enhancement://` protocol
any files within the `mods` folder can be loaded with the `enhancement://` protocol.
for example, inserting an image from the core mod: `<img src="enhancement://core/image.png">`.
## `variables.css`
**inserted into all windows.**
(put font import statements here too.)
the enhancer has been designed with theming in mind, so as much of notion's colours
and typography as possible and some basic spacing (both for the light and dark themes) have been mapped out
using css variables.
this set of variables is 100% mandatory to use if you wish to use or change anything they handle
(particularly colours). this is necessary to keep all themes consistently working
(e.g. responding properly to light/dark theme changes), and it makes theming a lot easier -
notion's html structure needs some complex selectors to properly modify it,
and it means theme authors don't have to worry about separately updating their theme every time something changes.
the full/up-to-date list of variables and their default values can be found in the
[core `variables.css` file](mods/core/variables.css). each variable is named something along the lines of
`--theme_mode--target_name-property`. still not sure what a variable does? try changing it and seeing what happens.
these are all made possible by the core module. if you believe this set of variables is buggy or lacking in any way,
consider opening a pull request to fix those issues - please do not try and reinvent the wheel unnecessarily.
> ### using variables
>
> variables should be defined per-mode, but used without specifying. for example:
>
> ```css
> :root {
> --theme_dark--main: rgb(5, 5, 5);
> }
> .demo-element {
> background: var(--theme--main);
> }
> ```
>
> this to simplify styling and make it possible for things like the "night shift" module to work,
> by leaving the choice of light/dark theme up to the user and then directing the right values to
> the relevant variables.
## `app.css`
**inserted into the notion app window.**
## `tabs.css`
**inserted into the notion app container for styling tabs.**
## `menu.css`
**inserted into the enhancements menu.**

View File

@ -1,6 +1,7 @@
MIT License MIT License
Copyright (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/) Copyright (c) 2020 TarasokUA
Copyright (c) 2020 dragonwocky
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

455
README.md
View File

@ -1,5 +1,454 @@
# notion-enhancer/desktop # <img src="./mods/core/icons/mac+linux.png" height="20px"> notion-enhancer
Customise the all-in-one productivity workspace Notion. notion.so is a pretty awesome tool already, but there's always room for improvements.
it might just be a preference, it might be something crucial to your setup,
it might be something users have been asking for for a long time,
or it might even be something you haven't realised you need yet
\- there's something that would make your user experience a lot better.
[read the docs online](https://notion-enhancer.github.io/) this package is a mod-loader for the desktop app, with custom colour theming and extra feature enhancements.
want to contribute? check out the [contribution guidelines](CONTRIBUTING.md) and the [documentation](DOCUMENTATION.md).
for support, join the [discord server](https://discord.gg/sFWPXtA).
### supported desktop clients
- the [official windows/mac releases](https://notion.so/desktop).
- the arch linux AUR [notion-app](https://aur.archlinux.org/packages/notion-app/) package.
- the linux [notion-app](https://github.com/jaredallard/notion-app) installer.
- [@haydn-jones](https://github.com/haydn-jones/)'s fork of the
linux [notion-deb-builder](https://github.com/haydn-jones/notion-deb-builder).
mobile clients are not supported and due to system limitations/restrictions cannot be.
a chrome extension may be coming soon for web client support.
## installation
> **if you are updating from v0.7.0 or earlier,** things have changed, more information is available
> in this [update guide](UPDATING.md). please read that before following these instructions.
- ensure that no notion windows/processes are running by ending all Notion processes in your task manager.
- `CMD + ALT + ESC` on mac and `CTRL + SHIFT + ESC` on windows/linux to open task manager.
- [install node.js](https://nodejs.org/en/download/)
- you may need to restart your computer.
- notion-enhancer will use node.js, you do not need to interact with it aside from downloading to install notion-enhancer.
- open your computer's terminal, **not the node.js command prompt.**
- **windows 10:** search in your start menu (click windows key or icon in bottom left of screen) for _'cmd'_ or _'command prompt'_.
- **mac:** search in spotlight (magnifying glass in top right of screen) for _'terminal'_.
- type and enter the following line(s) based on your operating system, if there are multiple lines, make sure to enter them _one by one_ .
- **windows 10:**
```
npm i -g notion-enhancer
```
- **mac:** this may ask you to enter your password, instead of hiding your password with \*\*\* symbols, mac terminal hides it by making it invisible. simply type your password and click enter.
```
sudo chmod -R a+wr /usr/local/lib/node_modules
sudo chmod -R a+wr /usr/local/bin
sudo chmod -R a+wr /Applications/Notion.app/Contents/Resources
npm i -g notion-enhancer
```
- **debian/ubuntu, chromeOS, wsl (to modify the win10 app):**
```
bash curl -sL https://deb.nodesource.com setup_current.x | sudo -E bash -
sudo apt-get install -y nodejs
npm i -g notion-enhancer
```
- **arch linux, manjaro:**
- install the [aur package](https://aur.archlinux.org/packages/notion-enhancer) with your aur helper (e.g. `yay -S notion-enhancer`).
### command-line interface
the enhancements should be automatically applied on installation
and automatically removed on uninstallation.
on some platforms this may throw errors if done without
elevated/admin permissions, though, so if it hasn't automatically
installed you will still need to use these commands.
```
Usage:
$ notion-enhancer <command> [options]
Commands:
apply : add enhancements to the notion app
remove : return notion to its pre-enhanced/pre-modded state
check : check the current state of the notion app
For more info, run any command with the `--help` flag:
$ notion-enhancer apply --help
$ notion-enhancer remove --help
$ notion-enhancer check --help
Options:
-y, --yes : skip prompts (may overwrite data)
-n, --no : skip prompts (may cause failures)
-d, --dev : show detailed error messages (for debug purposes)
-h, --help : display usage information
-v, --version : display version number
```
### faq
**when will the update be out?**
i code this in my free time, in-between my other commitments. there are no ETAs.
**the themes aren't working?**
if you pick a dark theme it will only be applied if notion is in dark mode,
and if you pick a light theme it will only work if notion is in light mode.
do `CMD/CTRL+SHIFT+L` to toggle between them.
**is this against notion's terms of service? can i get in trouble for using it?**
definitely not! i contacted their support team to check, and the response was awesome:
> "Thanks for taking the time to share this with us. Userscripts and userstyles are definitely
> cool ideas and would be helpful for many users! ... I'll also share this with the rest of the
> team to take to heart for future improvements."
**how do i uninstall the enhancer?**
run `npm remove -g notion-enhancer`.
## features
most of the enhancer's functionality is split into configurable enhancement modules,
but some basic improvements necessary for things to work are built in by values:
- the notion:// url scheme/protocol is patched to work on linux.
- a tray/menubar icon: links relevant to the enhancer + buttons to manage notion windows.
once applied, modules can be configured via the graphical menu,
which is opened from the tray/menubar icon or with `OPTION/ALT+E`.
![](https://user-images.githubusercontent.com/16874139/97819046-34e8b600-1cfa-11eb-8fa6-a3ad5374cd0b.png)
currently all modules come pre-installed for technical reasons, security assurance, and ease-of-use.
these include:
### notion-enhancer core
**tags:** #core
**description:** the cli, modloader, menu, & tray.
**author:** [dragonwocky](https://github.com/dragonwocky/)
| option | extended description | type | values/defaults | platform-specific details |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -------------------------- | ------------------------- |
| auto-resolve theme conflicts | when a theme is enabled any other themes of the same mode (light/dark) will be disabled. | toggle | no | |
| hide app on open | app can be made visible by clicking the tray icon or using the hotkey. | toggle | no | |
| auto-maximise windows | whenever a window is un-hidden or is created it will be maximised. | toggle | no | |
| close window to the tray | pressing the × close button will hide the app instead of quitting it. it can be re-shown by clicking the tray icon or using the hotkey. | toggle | yes | |
| integrated titlebar | replace the native titlebar with buttons inset into the app. | toggle | yes | macOS: forced on |
| tiling window manager mode | completely remove the close/minimise/maximise buttons - this is for a special type of window manager. if you don't understand it, don't use it. | toggle | no | macOS: forced off |
| window display hotkey | used to toggle hiding/showing all app windows. | [accelerator](https://github.com/electron/electron/blob/master/docs/api/accelerator.md) input | `CommandOrControl+Shift+A` | |
| open enhancements menu hotkey | used to toggle opening/closing this menu while notion is focused. | [accelerator](https://github.com/electron/electron/blob/master/docs/api/accelerator.md) input | `Alt+E` | |
| values/defaults page id/url | every new tab/window that isn't opening a url via the notion:// protocol will load this page. to get a page link from within the app, go to the triple-dot menu and click "copy link". leave blank to just load the last page you opened. | text input | `Alt+E` | |
![](https://user-images.githubusercontent.com/16874139/97819249-7a59b300-1cfb-11eb-99fa-de945fe8e3d9.png)
### tabs
**tags:** #core #extension
**description:** have multiple notion pages open in a single window.
**author:** [dragonwocky](https://github.com/dragonwocky/)
| option | type | values/defaults |
| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| tab select modifier (key+1, +2, +3, ... +9 and key+left/right arrows) | select | `Alt`, `Command`, `Control`, `Super`, `Alt+Shift`, `Command+Shift`, `Control+Shift`, `Super+Shift` |
| new tab keybinding | [accelerator](https://github.com/electron/electron/blob/master/docs/api/accelerator.md) input | `CommandOrControl+T` |
| close tab keybinding | [accelerator](https://github.com/electron/electron/blob/master/docs/api/accelerator.md) input | `CommandOrControl+W` |
![](https://user-images.githubusercontent.com/16874139/97821456-9dd62b00-1d06-11eb-8c3a-e9f77bbd740e.png)
### tweaks
**tags:** #core #extension
**description:** common style/layout changes.
**author:** [dragonwocky](https://github.com/dragonwocky/)
| option | extended description | type | values/defaults | platform-specific details |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------ | --------------- | ------------------------- |
| height of frameless dragarea | the rectangle added at the top of a window in "integrated titlebar" mode, used to drag/move the window. | number input | 15 | macOS: forced to 0 |
| width to wrap columns at | the size in pixels below which in-page columns are resized to appear full width so content isn't squished. | number input | 600 | |
| integrated scrollbars | use scrollbars that fit better into notion's ui instead of the default chrome ones. | toggle | yes | |
| snappy transitions | | toggle | no | |
| thicker bold text | | toggle | yes | |
| more readable line spacing | | toggle | no | |
| hide help button | | toggle | no | |
![](https://user-images.githubusercontent.com/16874139/97819829-1638ee00-1cff-11eb-80c6-f270c2ba0f37.png)
### always on top
**tags:** #extension
**description:** add an arrow/button to show the notion window
on top of other windows even if it's not focused.
**author:** [dragonwocky](https://github.com/dragonwocky/)
![](https://user-images.githubusercontent.com/16874139/97820478-79784f80-1d02-11eb-9e32-caac4563d8f0.png)
### bracketed links
**tags:** #extension
**description:** render links surrounded with \[\[brackets]] instead of underlined.
**author:** [arecsu](https://github.com/arecsu/)
![](https://user-images.githubusercontent.com/16874139/97820501-9f9def80-1d02-11eb-8ad8-b1ddf1ed9599.png)
### bypass preview
**tags:** #extension
**description:** go straight to the normal full view when opening a page.
**author:** [dragonwocky](https://github.com/dragonwocky/)
### calendar scroll
**tags:** #extension
**description:** add a button to scroll down to the current week in fullpage/infinite-scroll calendars.
**author:** [dragonwocky](https://github.com/dragonwocky/)
![](https://user-images.githubusercontent.com/16874139/97820611-fe636900-1d02-11eb-8f78-0536103e25aa.png)
### cherry cola
**tags:** #theme #dark
**description:** a delightfully plummy, cherry cola flavored theme.
**author:** [runargs](https://github.com/runargs)
![](https://user-images.githubusercontent.com/16874139/97819898-9fe8bb80-1cff-11eb-846f-1a66e0302ebd.png)
### custom inserts
**tags:** #extension
**description:** link files for small client-side tweaks. (not sure how to do something? check out the
[tweaks](https://github.com/notion-enhancer/notion-enhancer/blob/master/TWEAKS.md) collection.)
**author:** [dragonwocky](https://github.com/dragonwocky/)
| option | type |
| --------------------- | ---- |
| css insert | file |
| client-side js insert | file |
### dark+
**tags:** #theme #dark
**description:** a vivid-colour near-black theme.
**author:** [dragonwocky](https://github.com/dragonwocky/)
| option | type | values/defaults |
| -------------- | ----- | ------------------ |
| primary colour | color | `rgb(177, 24, 24)` |
![](https://user-images.githubusercontent.com/16874139/97820632-19ce7400-1d03-11eb-85a9-87f6d957dc96.png)
### dracula
**tags:** #theme #dark
**description:** a theme based on the popular dracula color palette originally by zeno rocha and friends.
**author:** [dracula](https://github.com/dracula/)
![](https://user-images.githubusercontent.com/16874139/97820175-04f0e100-1d01-11eb-9ede-b6e033a28cbc.png)
### emoji sets
**tags:** #extension
**description:** pick from a variety of emoji styles to use.
**author:** [dragonwocky](https://github.com/dragonwocky/)
| option | type | values/defaults |
| ------ | ------ | --------------------------------------------------------------------------------------------------------------- |
| style | select | twitter, apple, google, microsoft, samsung, whatsapp, facebook, joypixels, openmoji, emojidex, lg, htc, mozilla |
![](https://user-images.githubusercontent.com/16874139/97820652-3f5b7d80-1d03-11eb-80a6-34089b946711.png)
### focus mode
**tags:** #extension
**description:** hide the titlebar/menubar if the sidebar is closed (will be shown on hover).
**author:** [arecsu](https://github.com/arecsu/)
| option | extended description | type | values/defaults |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | --------------- |
| add padding to bottom of the page | will only take effect when the sidebar is hidden. aims to make the canvas as symmetrical/consistent as possible: if there is empty space on 3 sides, the 4th should follow. | toggle | on |
![](https://user-images.githubusercontent.com/16874139/97820337-da535800-1d01-11eb-9df5-55567cba2cc4.png)
### font chooser
**tags:** #extension
**description:** customize fonts. for each option, type in the name of
the font you would like to use, or leave it blank to not change anything.
**author:** [torchatlas](https://github.com/torchatlas)
| option | type |
| -------------------- | ---------- |
| sans-serif (inc. ui) | text input |
| serif | text input |
| monospace | text input |
| code | text input |
![](https://user-images.githubusercontent.com/16874139/97820678-61ed9680-1d03-11eb-8f9f-54c1c5faf25e.png)
### gameish
**tags:** #theme #dark
**description:** a purple, "gamer-styled" theme with a blocky-font.
**author:** [LVL100ShrekCultist](https://reddit.com/user/LVL100ShrekCultist/)
![](https://user-images.githubusercontent.com/16874139/97820696-75006680-1d03-11eb-8046-c3cb871ad34c.png)
### littlepig dark
**tags:** #theme #dark
**description:** a purple monospaced theme using emojis and colourful text.
**author:** [Lizishan](https://www.reddit.com/user/Lizishan/)
![](https://user-images.githubusercontent.com/16874139/97820718-919c9e80-1d03-11eb-9749-e04faef82e2d.png)
### littlepig light
**tags:** #theme #light
**description:** a bright monospaced theme using emojis and colourful text.
**author:** [Lizishan](https://www.reddit.com/user/Lizishan/)
![](https://user-images.githubusercontent.com/16874139/97820868-446cfc80-1d04-11eb-80ba-48cbedd62ed1.png)
### material ocean
**tags:** #theme #dark
**description:** an oceanic colour palette.
**author:** [blacksuan19](https://github.com/blacksuan19)
![](https://user-images.githubusercontent.com/16874139/97820253-6d3fc280-1d01-11eb-86d1-9932b364bad8.png)
### neutral
**tags:** #theme #dark
**description:** smoother colours and fonts, designed to be more pleasing to the eye.
**author:** [arecsu](https://github.com/arecsu/)
![](https://user-images.githubusercontent.com/16874139/97821029-fad0e180-1d04-11eb-9bad-2c76e9fa7613.png)
### night shift
**tags:** #extension #theme
**description:** sync dark/light theme with the system (overrides normal theme setting).
**author:** [dragonwocky](https://github.com/dragonwocky/)
### pastel dark
**tags:** #theme #dark
**description:** a true dark theme with a hint of pastel.
**author:** [zenith_illinois](https://reddit.com/user/zenith_illinois/)
![](https://user-images.githubusercontent.com/16874139/97820893-60709e00-1d04-11eb-8d52-55ab44000786.png)
### property layout
**tags:** #extension
**description:** auto-collapse page properties that usually push down page content.
**author:** [alexander-kazakov](https://github.com/alexander-kazakov/)
![](https://user-images.githubusercontent.com/16874139/97820916-81d18a00-1d04-11eb-8e07-b7519590157a.png)
### right-to-left
**tags:** #extension
**description:** enables auto rtl/ltr text direction detection.
**author:** [obahareth](https://github.com/obahareth/)
![](https://user-images.githubusercontent.com/16874139/97820953-a7f72a00-1d04-11eb-98c0-6ad83d097682.png)
### scroll to top
**tags:** #extension
**description:** add an arrow above the help button to scroll back to the top of a page.
**author:** [CloudHill](https://github.com/CloudHill/)
| option | type | values/defaults |
| --------------------------------------- | ------------ | --------------- |
| smooth scrolling | toggle | on |
| distance scrolled until button is shown | number input | 50 |
| unit to measure distance with | select | percent, pixels |
![](https://user-images.githubusercontent.com/16874139/97820445-4c2ba180-1d02-11eb-9d1a-911bca266f7f.png)
### weekly view
**tags:** #extension
**description:** calendar views named "weekly" will show only the 7 days of this week.
**author:** [adihd](https://github.com/adihd/)
![](https://user-images.githubusercontent.com/16874139/97820985-bf361780-1d04-11eb-9e2a-786a7c37477d.png)
### word counter
**tags:** #extension
**description:** add page details: word/character/sentence/block count & speaking/reading times.
**author:** [dragonwocky](https://github.com/dragonwocky/)
![](https://user-images.githubusercontent.com/16874139/97821003-d37a1480-1d04-11eb-8aaa-9e5dfea495eb.png)
## contributors
[@TarasokUA](https://github.com/TarasokUA/) wrote the first versions of this in python, in early 2020.
a couple months after I ([@dragonwocky](https://github.com/dragonwocky/)) picked the project up, at first extending
upon the original base and later moving to the javascript module system.
the enhancer wouldn't be anything near to what it is now though without
interested community members testing, coding and ideating features - some are listed as
[contributors](https://github.com/notion-enhancer/notion-enhancer/graphs/contributors) here on github,
but many more have been helping out on discord and in emails.
individual modules have their original authors attributed.

241
TWEAKS.md Normal file
View File

@ -0,0 +1,241 @@
# tweaks
the enhancer comes with some built-in colour themes and layout improvements,
but to get even more control over how the app looks you can use the file picker in the
"custom inserts" module to inject your own javascript or css into it.
to make your own css file to add, make sure that your file manager has "show file extensions" ticked, then
create a text document and make sure the name ends in `.css` (e.g. `notion-tweaks.css`).
this page is a collection of tested visual tweaks users often ask about.
they should all also work in notion's web client, if copied into a customiser
like [stylus](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=en).
css below will work for every instance of the element, but if you wish to hide only a specific element
(e.g. the '+ new' table row) it is recommended that you prepend each selector with
`[data-block-id='ID']`.
if you don't know what css is and are interested, check out some youtube videos
or [try a free short course like the one on codecademy](https://www.codecademy.com/learn/learn-css).
**the following tweaks were previously on this page and have since been moved to the**
**more stable and theme-compatible css variable system described in the**
**[developer documentation](DOCUMENTATION.md#variable-theming):**
- colour theming
- custom fonts and font sizes
- wider page preview
- thinner cover image
if you are attempting to customise the web client, the css previously used for these can be found
[in the legacy documentation](https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/STYLING.md).
### hide discussions (the comment threads at the top of each page)
```css
[style*='env(safe-area-inset-left)']:not(.notion-page-content)
[style*='width: 100%; height: 1px;'],
.notion-page-view-discussion {
display: none !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/discussion-default.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/discussion-hidden.jpg?raw=true" width="45%"></img>
### hide backlinks
note: this only hides the trigger. if you've already got backlinks shown,
then use the 3 dots up in the top-right corner to remove them.
```css
.notion-page-details-controls {
display: none !important;
}
```
<img src="https://user-images.githubusercontent.com/16874139/92044159-f3eb2880-edc0-11ea-9cc9-7adcec540905.png" width="45%"> <img src="https://user-images.githubusercontent.com/16874139/92044290-42002c00-edc1-11ea-96fa-147d84eb0555.png" width="45%">
### hide the '+ new' gallery button
```css
.notion-gallery-view
.notion-selectable.notion-collection_view-block
> [role='button'],
.notion-gallery-view
.notion-selectable.notion-collection_view_page-block
> [role='button'] {
display: none !important;
}
```
<img src="https://user-images.githubusercontent.com/16874139/90969951-30f22800-e542-11ea-954c-e36873e19217.png" width="45%"></img> <img src="https://user-images.githubusercontent.com/16874139/90969962-55e69b00-e542-11ea-8ed3-287922805210.png" width="45%"></img>
### sticky table/list row
note: this will make the first row stick to the top of the screen when scrolling down.
to stick a specific row replace `:nth-child(2)` with `[data-block-id="ROW_BLOCK_ID_HERE"]`.
does not apply to inline databases.
```css
.notion-collection_view_page-block
.notion-page-block.notion-collection-item:nth-child(2) {
background: var(--theme--main);
z-index: 10;
position: sticky;
top: 0;
}
.notion-table-view
.notion-collection_view_page-block
.notion-page-block.notion-collection-item:nth-child(2) {
top: 32px;
}
```
![image](https://user-images.githubusercontent.com/16874139/94878420-a1c12400-04a0-11eb-8e74-2f01e2e696cd.png)
### table columns below 100px
**not recommended!** this may cause buggy viewing.
as it is a per-table-column style, unlike most others here, it must be prepended with the block ID and repeated for each column.
to see how to do this, watch [this video](https://www.youtube.com/watch?v=6V7eqShm_4w).
```css
[data-block-id^='tableID']
> [style^='display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);']
> div:nth-child(1)
> div:nth-child(COL_NUMBER)
> div:nth-child(1),
[data-block-id^='tableID']
> [style^='position: relative; min-width: calc(100% - 192px);']
> [data-block-id]
> div:nth-child(COL_NUMBER),
[data-block-id^='tableID'] > div:nth-child(5) > div:nth-child(COL_NUMBER) {
width: 32px !important;
}
[data-block-id^='tableID']
[style^='position: absolute; top: 0px; left: 0px; pointer-events: none;']:not(.notion-presence-container) {
display: none;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-before.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-columnunder100px.jpg?raw=true" width="45%"></img>
### hide '+ new' table row
```css
.notion-table-view-add-row {
display: none !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-before.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-hideaddrow.jpg?raw=true" width="45%"></img>
### hide calculations table row
```css
.notion-table-view-add-row + div {
display: none !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-before.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-hidecalculationsrow.jpg?raw=true" width="45%"></img>
### centre-align table column headers
```css
.notion-table-view-header-cell > div > div {
margin: 0px auto;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-before.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-centredheaders.jpg?raw=true" width="45%"></img>
### smaller table column header icons
```css
[style^='display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);']
div:nth-child(1)
svg {
height: 10px !important;
width: 10px !important;
margin-right: -4px;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-before.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-smallercolumnicons.jpg?raw=true" width="45%"></img>
### remove icons from table column headers
```css
.notion-table-view-header-cell [style^='margin-right: 6px;'] {
display: none !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-before.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-hidecolumnicons.jpg?raw=true" width="45%"></img>
### removing/decreasing side padding for tables
```css
[style^='flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;']
.notion-table-view,
[class='notion-scroller'] > .notion-table-view {
padding-left: 35px !important;
padding-right: 15px !important;
min-width: 0% !important;
}
[style^='flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;']
.notion-selectable
.notion-scroller.horizontal::-webkit-scrollbar-track {
margin-left: 10px;
margin-right: 10px;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-before.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/table-shrinkpadding.jpg?raw=true" width="45%"></img>
### hide '+ new' board row
```css
.notion-board-group
[style='user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; display: inline-flex; align-items: center; flex-shrink: 0; white-space: nowrap; height: 32px; border-radius: 3px; font-size: 14px; line-height: 1.2; min-width: 0px; padding-left: 6px; padding-right: 8px; color: rgba(255, 255, 255, 0.4); width: 100%;'] {
display: none !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-default.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-hideaddnew.jpg?raw=true" width="45%"></img>
### hide board view hidden columns
```css
.notion-board-view > [data-block-id] > div:nth-last-child(2),
.notion-board-view > [data-block-id] > div:first-child > div:nth-last-child(2) {
display: none !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-default.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-hidehidden.jpg?raw=true" width="45%"></img>
### hide board view 'add a group'
```css
.notion-board-view > [data-block-id] > div:last-child,
.notion-board-view > [data-block-id] > div:first-child > div:last-child {
display: none !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-default.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-hideaddgroup.jpg?raw=true" width="45%"></img>
### removing/decreasing side padding for boards
```css
.notion-board-view {
padding-left: 10px !important;
padding-right: 10px !important;
}
```
<img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-default.jpg?raw=true" width="45%"></img> <img src="https://github.com/notion-enhancer/notion-enhancer/blob/b5043508d91df76f145f0f48c2c63d7dd1c27543/screenshots/board-shrinkpadding.jpg?raw=true" width="45%"></img>

55
UPDATING.md Normal file
View File

@ -0,0 +1,55 @@
# updating
the enhancer is still a young project, so it's growing quickly. this means a lot of stuff is changing internally
\- and, sometimes, externally.
previously (<= v0.7.0), the enhancer was a python script with a couple of resource files, and if you
wanted to customise things you had to go in and edit those files. in v0.8.0 there has been a complete
rewrite and overhaul: now this is a program that makes use of a number of modules and a graphical menu.
## installation dependencies
previously, python and the node.js `asar` package both had to be manually installed.
node.js is the only current requirement of the enhancer.
- python is no longer a dependency: keep it, get rid of it - up to you.
- the package installs asar itself in a more scoped environment: if you're confident with
the command line, you can remove the package with `npm remove -g asar`. otherwise, it
won't do any damage to just leave it.
## keeping the files
enhancement is done fully from the command prompt.
by default, there are no files for you to worry about.
you can delete the folder the old version of the enhancer is kept in.
(though you may want to keep the `user.css` file: see below.)
## user.css styling
when you first load the enhancer, there's no single file you can edit to see instant changes.
instead, the "custom inserts" module is used: you can use it to pick any javascript or css file anywhere
on your computer and include it every time you load up notion.
to make your own css file, make sure that your file manager has "show file extensions" ticked, then
create a text document and make sure the name ends in `.css` (e.g. `notion-tweaks.css`). or, just use
the old `user.css` from before the update.
most of the same css snippets will work, but some (e.g. preview page width) have been moved to the new variable
system, plus new ones have been found. it's a good idea to check what you have against the [tweaks](TWEAKS.md)
page and the [css theming documentation](DOCUMENTATION.md#variable-theming).
## configuration
"what happened to the tray options?"
"how can I set a custom window visibility toggle hotkey?"
these options and more have been moved to the graphical menu, which can be opened from the
tray or with `ALT+E` (while the notion app is focused).
## installing
just follow the normal [installation steps](README.md#installation) (starting from step 2, you should
already have node.js installed). don't worry about running `cleaner.py`, the new version will detect and overwrite
the old for you.

71
bin.js Executable file
View File

@ -0,0 +1,71 @@
#!/usr/bin/env node
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (https://dragonwocky.me/notion-enhancer) under the MIT license
*/
'use strict';
const cli = require('cac')('notion-enhancer'),
{ EnhancerError } = require('./pkg/helpers.js');
// === title ===
// ...information
// * warning
// > prompt
// -- response
// ~~ exit
// ### error ###
cli.option('-y, --yes', ': skip prompts (may overwrite data)');
cli.option('-n, --no', ': skip prompts (may cause failures)');
cli.option('-d, --dev', ': show detailed error messages (for debug purposes)');
cli
.command('apply', ': add the enhancer to the notion app')
.action(async (options) => {
console.info('=== NOTION ENHANCEMENT LOG ===');
await require('./pkg/apply.js')({
overwrite_version: options.yes ? 'y' : options.no ? 'n' : undefined,
friendly_errors: !options.dev,
});
console.info('=== END OF LOG ===');
});
cli
.command('remove', ': return notion to its pre-enhanced/pre-modded state')
.action(async (options) => {
console.info('=== NOTION RESTORATION LOG ===');
await require('./pkg/remove.js')({
delete_data: options.yes ? 'y' : options.no ? 'n' : undefined,
friendly_errors: !options.dev,
});
console.info('=== END OF LOG ===');
});
cli
.command('check', ': check the current state of the notion app')
.action(async (options) => {
try {
console.info((await require('./pkg/check.js')()).msg);
} catch (err) {
console.error(err instanceof EnhancerError ? err.message : err);
}
});
let helpCalled = false;
cli.globalCommand.option('-h, --help', ': display usage information');
cli.globalCommand.helpCallback = (sections) => {
sections[0].body += '\nhttps://github.com/notion-enhancer/notion-enhancer';
helpCalled = true;
};
cli.showHelpOnExit = true;
cli.globalCommand.option('-v, --version', ': display version number');
cli.globalCommand.versionNumber = require('./package.json').version;
cli.showVersionOnExit = true;
cli.parse();
if (!cli.matchedCommand && !helpCalled && !cli.options.version)
cli.outputHelp();

331
bin.mjs
View File

@ -1,331 +0,0 @@
#!/usr/bin/env node
/**
* notion-enhancer
* (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (https://notion-enhancer.github.io/) under the MIT license
*/
import os from "node:os";
import { createRequire } from "node:module";
import chalk from "chalk-template";
import arg from "arg";
import {
backupApp,
enhanceApp,
getInsertVersion,
getResourcePath,
restoreApp,
setNotionPath,
} from "./scripts/enhance-desktop-app.mjs";
import { greaterThan } from "./src/core/updateCheck.mjs";
import { existsSync } from "node:fs";
const nodeRequire = createRequire(import.meta.url),
manifest = nodeRequire("./package.json");
let __quiet, __debug;
const print = (...args) => __quiet || process.stdout.write(chalk(...args)),
printObject = (value) => __quiet || console.dir(value, { depth: null }),
clearLine = `\r\x1b[K`,
showCursor = `\x1b[?25h`,
hideCursor = `\x1b[?25l`,
cursorUp = (n) => `\x1b[${n}A`,
cursorForward = (n) => `\x1b[${n}C`;
let __confirmation;
const readStdin = () => {
return new Promise((res) => {
process.stdin.resume();
process.stdin.setEncoding("utf8");
process.stdin.once("data", (key) => {
process.stdin.pause();
res(key);
});
});
},
promptConfirmation = async (prompt) => {
let input;
const validInputs = ["Y", "y", "N", "n"],
promptLength = ` > ${prompt} [Y/n]: `.length;
// prevent line clear remove existing stdout
print`\n`;
do {
// clear line and repeat prompt until valid input is received
print`${cursorUp(1)}${clearLine} {inverse > ${prompt} [Y/n]:} `;
// autofill prompt response if --yes, --no or --quiet flags passed
if (validInputs.includes(__confirmation)) {
input = __confirmation;
print`${__confirmation}\n`;
} else input = (await readStdin()).trim();
if (!input) {
// default to Y if enter is pressed w/out input
input = "Y";
print`${cursorUp(1)}${cursorForward(promptLength)}Y\n`;
}
} while (!validInputs.includes(input));
// move cursor to immediately after input
print`${cursorUp(1)}${cursorForward(promptLength + 1)}`;
return input;
};
let __spinner;
const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
stopSpinner = () => {
if (!__spinner) return;
clearInterval(__spinner);
// show cursor and overwrite spinner with arrow on completion
print`\b{bold.yellow →}\n${showCursor}`;
__spinner = undefined;
},
startSpinner = () => {
// cleanup prev spinner if necessary
stopSpinner();
// hide cursor and print first frame
print`${hideCursor}{bold.yellow ${spinnerFrames[0]}}`;
let i = 0;
__spinner = setInterval(() => {
i++;
// overwrite spinner with next frame
print`\b{bold.yellow ${spinnerFrames[i % spinnerFrames.length]}}`;
}, 80);
};
const compileOptsToArgSpec = (options) => {
const args = {};
for (const [opt, [type]] of options) {
const aliases = opt.split(", ").map((alias) => alias.split("=")[0]),
param = aliases[1] ?? aliases[0];
args[param] = type;
for (let i = 0; i < aliases.length; i++) {
if (aliases[i] === param) continue;
args[aliases[i]] = param;
}
}
return args;
},
compileOptsToJsonOutput = (options) => {
// the structure used to define options above
// is convenient and compact, but requires additional
// parsing to understand. this function processes
// options into a more explicitly defined structure
return options.map(([opt, [type, description]]) => {
const option = {
aliases: opt.split(", ").map((alias) => alias.split("=")[0]),
type,
description,
},
example = opt
.split(", ")
.map((alias) => alias.split("=")[1])
.find((value) => value);
if (example) option.example = example;
return option;
});
};
let __json;
const printHelp = (commands, options) => {
const { name, version, homepage } = manifest,
usage = `${name} <command> [options]`;
if (__json) {
printObject({
name,
version,
homepage,
usage,
commands: Object.fromEntries(commands),
options: compileOptsToJsonOutput(options),
});
} else {
const cmdPad = Math.max(...commands.map(([cmd]) => cmd.length)),
optPad = Math.max(...options.map((opt) => opt[0].length)),
parseCmd = (cmd) =>
chalk` ${cmd[0].padEnd(cmdPad)} {grey :} ${cmd[1]}`,
parseOpt = (opt) =>
chalk` ${opt[0].padEnd(optPad)} {grey :} ${opt[1][1]}`;
print`{bold.whiteBright.underline ${name} v${version}}\n{grey ${homepage}}
\n{bold.whiteBright USAGE}\n${name} <command> [options]
\n{bold.whiteBright COMMANDS}\n${commands.map(parseCmd).join("\n")}
\n{bold.whiteBright OPTIONS}\n${options.map(parseOpt).join("\n")}\n`;
}
},
printVersion = () => {
if (__json) {
printObject({
[manifest.name]: manifest.version,
node: process.version.slice(1),
platform: process.platform,
architecture: process.arch,
os: os.release(),
});
} else {
const nodeVersion = `node@${process.version}`,
enhancerVersion = `${manifest.name}@v${manifest.version}`,
osVersion = `${process.platform}-${process.arch}/${os.release()}`;
print`${enhancerVersion} via ${nodeVersion} on ${osVersion}\n`;
}
};
try {
const commands = [
// ["command", "description"]
["apply", "Inject the notion-enhancer into Notion desktop."],
["remove", "Restore Notion desktop to its pre-enhanced state."],
["check", "Report Notion desktop's enhancement state."],
],
// prettier-ignore
options = [
// ["alias, option=example", [type, "description"]]
["--path=</path/to/notion/resources>", [String, "Manually provide a Notion installation location."]],
["--no-backup", [Boolean, "Skip backup; enhancement will be irreversible."]],
["--json", [Boolean, "Output JSON from the `check` and `--version` commands."]],
["-y, --yes", [Boolean, 'Skip prompts; assume "yes" and run non-interactively.']],
["-n, --no", [Boolean, 'Skip prompts; assume "no" and run non-interactively.']],
["-q, --quiet", [Boolean, 'Skip prompts; assume "no" unless -y and hide all output.']],
["-d, --debug", [Boolean, "Show detailed error messages and keep extracted files."]],
["-h, --help", [Boolean, "Display usage information for this CLI."]],
["-v, --version", [Boolean, "Display this CLI's version number."]],
];
const args = arg(compileOptsToArgSpec(options));
if (args["--debug"]) __debug = true;
if (args["--quiet"]) __quiet = true;
if (args["--json"]) __json = true;
if (args["--no"] || args["--quiet"]) __confirmation = "n";
if (args["--yes"]) __confirmation = "y";
if (args["--help"]) printHelp(commands, options), process.exit();
if (args["--version"]) printVersion(), process.exit();
if (args["--path"]) setNotionPath(args["--path"]);
const appPath = getResourcePath("app.asar"),
backupPath = getResourcePath("app.asar.bak"),
insertVersion = await getInsertVersion(),
updateAvailable = greaterThan(manifest.version, insertVersion);
const messages = {
"notion-found": insertVersion
? // prettier-ignore
`Notion desktop found with ${manifest.name} v${insertVersion
} applied${updateAvailable ? "" : " (up to date)"}.`
: `Notion desktop found (no enhancements applied).`,
"notion-not-found": `Notion desktop not found.`,
// prettier-ignore
"update-available": chalk`v${manifest.version
} is available! To apply, run {underline ${manifest.name} apply -y}.`,
// prettier-ignore
"update-confirm": `${updateAvailable ? "Upgrade" : "Downgrade"
} to ${manifest.name}${manifest.name} v${manifest.version}?`,
"backup-found": `Restoring to pre-enhanced state from backup...`,
"backup-not-found": chalk`No backup found: to restore Notion desktop to its pre-enhanced state,
uninstall it and reinstall Notion from {underline https://www.notion.so/desktop}.`,
"backup-app": `Backing up app before enhancement...`,
"enhance-app": `Enhancing and patching app sources...`,
};
const SUCCESS = chalk`{bold.whiteBright SUCCESS} {green ✔}`,
FAILURE = chalk`{bold.whiteBright FAILURE} {red ✘}`,
CANCELLED = chalk`{bold.whiteBright CANCELLED} {red ✘}`,
INCOMPLETE = Symbol();
const interactiveRestore = async () => {
if (!backupPath || !existsSync(backupPath)) {
print` {red * ${messages["backup-not-found"]}}\n`;
return FAILURE;
}
print` {grey * ${messages["backup-found"]}} `;
startSpinner();
await restoreApp();
stopSpinner();
return SUCCESS;
};
const getNotion = () => {
if (!appPath || !existsSync(appPath)) {
print` {red * ${messages["notion-not-found"]}}\n`;
return FAILURE;
} else {
print` {grey * ${messages["notion-found"]}}\n`;
return INCOMPLETE;
}
},
compareVersions = async () => {
if (!insertVersion) return INCOMPLETE;
// same version already applied
if (insertVersion === manifest.version) return SUCCESS;
// diff version already applied
print` {grey * ${messages["notion-found"]}}\n`;
const replace = await promptConfirmation(messages["update-confirm"]);
print`\n`;
return ["Y", "y"].includes(replace)
? (await interactiveRestore()) === SUCCESS
? INCOMPLETE
: FAILURE
: CANCELLED;
},
interactiveEnhance = async () => {
if (!args["--no-backup"]) {
print` {grey * ${messages["backup-app"]}} `;
startSpinner();
await backupApp();
stopSpinner();
}
print` {grey * ${messages["enhance-app"]}} `;
startSpinner();
await enhanceApp(__debug);
stopSpinner();
return SUCCESS;
};
switch (args["_"][0]) {
case "apply": {
print`{bold.whiteBright [${manifest.name.toUpperCase()}] APPLY}\n`;
let res = getNotion();
if (res === INCOMPLETE) res = await compareVersions();
if (res === INCOMPLETE) res = await interactiveEnhance();
print`${res}\n`;
break;
}
case "remove": {
print`{bold.whiteBright [${manifest.name.toUpperCase()}] REMOVE}\n`;
let res = getNotion();
if (res === INCOMPLETE) {
res = insertVersion ? await interactiveRestore() : SUCCESS;
}
print`${res}\n`;
break;
}
case "check": {
if (__json) {
const cliVersion = manifest.version,
state = { appPath, backupPath, insertVersion, cliVersion };
if (appPath && !existsSync(appPath)) state.appPath = null;
if (backupPath && !existsSync(backupPath)) state.backupPath = null;
printObject(state), process.exit();
}
print`{bold.whiteBright [${manifest.name.toUpperCase()}] CHECK}\n`;
let res = getNotion();
if (res === INCOMPLETE && updateAvailable) {
print` {grey * ${messages["update-available"]}}\n`;
}
break;
}
default:
printHelp(commands, options);
}
} catch (err) {
stopSpinner();
const message = err.message.split("\n")[0];
if (__debug) {
print`{bold.red ${err.name}:} ${message}\n{grey ${err.stack
.split("\n")
.splice(1)
.map((at) => at.replace(/\s{4}/g, " "))
.join("\n")}}`;
} else {
print`{bold.red Error:} ${message} {grey (Run with -d for more information.)}\n`;
}
}

20
mods/alwaysontop/mod.js Normal file
View File

@ -0,0 +1,20 @@
/*
* always on top
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
// this is just a pseudo mod to "separate" the button
// from the core module - the core still handles actually
// making it work.
module.exports = {
id: '72886371-dada-49a7-9afc-9f275ecf29d3',
tags: ['extension'],
name: 'always on top',
desc:
"add an arrow/button to show the notion window on top of other windows even if it's not focused.",
version: '0.1.1',
author: 'dragonwocky',
};

View File

@ -0,0 +1,24 @@
/*
* bracketed links
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Arecsu
* under the MIT license
*/
.notion-link-token span {
border-bottom: none !important;
}
.notion-link-token:before {
content: '[[';
opacity: 0.7;
transition: opacity 100ms ease-in;
}
.notion-link-token:after {
content: ']]';
opacity: 0.7;
transition: opacity 100ms ease-in;
}
.notion-link-token:hover::before,
.notion-link-token:hover::after {
opacity: 1;
}

View File

@ -0,0 +1,16 @@
/*
* bracketed links
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: '60e14feb-a81d-4ffb-9b12-7585d346bad8',
tags: ['extension'],
name: 'bracketed links',
desc: 'render links surrounded with [[brackets]] instead of __underlined__.',
version: '0.1.0',
author: 'arecsu',
};

View File

@ -0,0 +1,9 @@
/*
* bypass preview
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
.notion-peek-renderer {
display: none;
}

View File

@ -0,0 +1,55 @@
/*
* bypass preview
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: 'cb6fd684-f113-4a7a-9423-8f0f0cff069f',
tags: ['extension'],
name: 'bypass preview',
desc: 'go straight to the normal full view when opening a page.',
version: '0.1.2',
author: 'dragonwocky',
hacks: {
'renderer/preload.js'(store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
let queue = [];
const observer = new MutationObserver((list, observer) => {
if (!queue.length) requestIdleCallback(() => handle(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
});
let lastPageID;
function handle(list) {
queue = [];
const pageID = (location.search
.slice(1)
.split('&')
.map((opt) => opt.split('='))
.find((opt) => opt[0] === 'p') || [
'',
...location.pathname.split(/(-|\/)/g).reverse(),
])[1],
preview = document.querySelector(
'.notion-peek-renderer [style*="height: 45px;"] a'
);
if (!pageID) return;
if (preview) {
if (pageID === lastPageID) {
history.back();
} else preview.click();
} else lastPageID = pageID;
}
});
},
},
};

View File

@ -0,0 +1,21 @@
/*
* calendar scroll
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
#calendar-scroll-to-week {
background: var(--theme--interactive_hover);
border: 1px solid transparent;
font-size: var(--theme--font_label-size);
color: var(--theme--text);
height: 24px;
border-radius: 3px;
line-height: 1.2;
padding: 0 0.5em;
margin-right: 5px;
}
#calendar-scroll-to-week:hover {
background: transparent;
border: 1px solid var(--theme--interactive_hover);
}

View File

@ -0,0 +1,79 @@
/*
* calendar scroll
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: 'b1c7db33-dfee-489a-a76c-0dd66f7ed29a',
tags: ['extension'],
name: 'calendar scroll',
desc:
'add a button to scroll down to the current week in fullpage/infinite-scroll calendars.',
version: '0.1.1',
author: 'dragonwocky',
hacks: {
'renderer/preload.js'(store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
const attempt_interval = setInterval(enhance, 500);
function enhance() {
const notion_elem = document.querySelector('.notion-frame');
if (!notion_elem) return;
clearInterval(attempt_interval);
const button = createElement(
'<button id="calendar-scroll-to-week">Scroll</button>'
);
button.addEventListener('click', (event) => {
const collection_view = document.querySelector(
'.notion-collection-view-select'
);
if (!collection_view) return;
const day = [
...collection_view.parentElement.parentElement.parentElement.parentElement.getElementsByClassName(
'notion-calendar-view-day'
),
].find((day) => day.style.background);
if (!day) return;
const scroller = document.querySelector(
'.notion-frame .notion-scroller'
);
scroller.scroll({
top: day.offsetParent.offsetParent.offsetTop + 70,
});
setTimeout(
() =>
scroller.scroll({
top: day.offsetParent.offsetParent.offsetTop + 70,
}),
100
);
});
handle();
const observer = new MutationObserver(handle);
observer.observe(notion_elem, {
childList: true,
subtree: true,
});
function handle(list, observer) {
if (document.querySelector('#calendar-scroll-to-week')) return;
const arrow = document.querySelector(
'.notion-selectable.notion-collection_view_page-block .chevronLeft'
);
if (arrow)
arrow.parentElement.parentElement.insertBefore(
button,
arrow.parentElement
);
}
}
});
},
},
};

12
mods/cherrycola/app.css Normal file
View File

@ -0,0 +1,12 @@
/*
* cherry cola
* (c) 2020 Alexa Baldon (https://github.com/runargs)
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
/* quotations as serif */
.notion-dark-theme .notion-quote-block {
font-family: Georgia, 'Times New Roman', Times, serif;
background-color: var(--cola-sec);
}

16
mods/cherrycola/mod.js Normal file
View File

@ -0,0 +1,16 @@
/*
* cherry cola
* (c) 2020 Alexa Baldon (https://github.com/runargs)
* under the MIT license
*/
'use strict';
module.exports = {
id: 'ec5c4640-68d4-4d25-aefd-62c7e9737cfb',
tags: ['theme', 'dark'],
name: 'cherry cola',
desc: 'a delightfully plummy, cherry cola flavored theme.',
version: '0.1.0',
author: 'runargs',
};

View File

@ -0,0 +1,144 @@
/*
* cherry cola
* (c) 2020 Alexa Baldon (https://github.com/runargs)
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
:root {
--cola-main: #180915;
--cola-sec: #1d0919;
--cola-tet: #492341;
--cola-info: #9b6890;
--cola-accent: #bf799b;
--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;
/* main */
--theme_dark--main: var(--cola-main);
--theme_dark--sidebar: var(--cola-sec);
--theme_dark--overlay: rgba(29, 9, 25, 0.5);
--theme_dark--dragarea: #210a1c;
--theme_dark--box-shadow: rgba(20, 0, 16, 0.2) 0px 0px 0px 1px,
rgba(20, 0, 16, 0.2) 0px 2px 4px;
--theme_dark--box-shadow_strong: rgba(20, 0, 16, 0.1) 0px 0px 0px 1px,
rgba(20, 0, 16, 0.2) 0px 3px 6px, rgba(20, 0, 16, 0.4) 0px 9px 24px;
/* scrollbar */
--theme_dark--scrollbar: var(--cola-sec);
--theme_dark--scrollbar_hover: var(--cola-accent);
/* database */
--theme_dark--card: var(--cola-sec);
--theme_dark--gallery: var(--cola-sec);
--theme_dark--select_input: var(--cola-tet);
--theme_dark--table-border: var(--cola-tet);
--theme_dark--ui-border: rgba(73, 35, 65, 0.7);
--theme_dark--interactive_hover: var(--cola-tet);
--theme_dark--button_close: var(--cola-accent);
/* select/hover/click */
--theme_dark--selected: rgba(78, 32, 69, 0.5);
--theme_dark--primary: var(--cola-accent);
--theme_dark--primary_hover: var(--cola-accent);
--theme_dark--primary_click: var(--cola-sec);
--theme_dark--primary_indicator: var(--cola-accent);
--theme_dark--option_active-background: var(--theme_dark--primary);
--theme_dark--option_hover-background: var(--theme_dark--primary_hover);
/* danger */
--theme_dark--danger_text: #eb5757;
--theme_dark--danger_border: rgba(235, 87, 87, 0.5);
/* default text colors */
--theme_dark--text: #ffffff;
--theme_dark--text_ui: var(--cola-info);
--theme_dark--text_ui_info: var(--cola-info);
/* text color options */
--theme_dark--text_gray: var(--cola-gray);
--theme_dark--text_brown: var(--cola-brown);
--theme_dark--text_orange: var(--cola-orange);
--theme_dark--text_yellow: var(--cola-yellow);
--theme_dark--text_green: var(--cola-green);
--theme_dark--text_blue: var(--cola-blue);
--theme_dark--text_purple: var(--cola-purple);
--theme_dark--text_pink: var(--cola-pink);
--theme_dark--text_red: var(--cola-red);
--theme_dark--select-text: var(--cola-main);
--theme_dark--select_gray: var(--cola-gray);
--theme_dark--select_brown: var(--cola-brown);
--theme_dark--select_brown-text: #ffffff;
--theme_dark--select_orange: var(--cola-orange);
--theme_dark--select_yellow: var(--cola-yellow);
--theme_dark--select_green: var(--cola-green);
--theme_dark--select_blue: var(--cola-blue);
--theme_dark--select_purple: var(--cola-purple);
--theme_dark--select_purple-text: #ffffff;
--theme_dark--select_pink: var(--cola-pink);
--theme_dark--select_red: var(--cola-red);
--theme_dark--select_red-text: #ffffff;
--theme_dark--line-text: var(--cola-main);
--theme_dark--line_gray: var(--cola-gray);
--theme_dark--line_brown: var(--cola-brown);
--theme_dark--line_orange: var(--cola-orange);
--theme_dark--line_yellow: var(--cola-yellow);
--theme_dark--line_green: var(--cola-green);
--theme_dark--line_blue: var(--cola-blue);
--theme_dark--line_purple: var(--cola-purple);
--theme_dark--line_pink: var(--cola-pink);
--theme_dark--line_red: var(--cola-red);
--theme_dark--bg-text: var(--theme_dark--select-text);
--theme_dark--bg_gray: var(--theme_dark--select_gray);
--theme_dark--bg_brown: var(--theme_dark--select_brown);
--theme_dark--bg_orange: var(--theme_dark--select_orange);
--theme_dark--bg_yellow: var(--theme_dark--select_yellow);
--theme_dark--bg_green: var(--theme_dark--select_green);
--theme_dark--bg_blue: var(--theme_dark--select_blue);
--theme_dark--bg_purple: var(--theme_dark--select_purple);
--theme_dark--bg_pink: var(--theme_dark--select_pink);
--theme_dark--bg_red: var(--theme_dark--select_red);
/* callout blocks */
--theme_dark--callout-text: var(--theme_dark--line-text);
--theme_dark--callout_gray: var(--theme_dark--line_gray);
--theme_dark--callout_brown: var(--theme_dark--line_brown);
--theme_dark--callout_orange: var(--theme_dark--line_orange);
--theme_dark--callout_yellow: var(--theme_dark--line_yellow);
--theme_dark--callout_green: var(--theme_dark--line_green);
--theme_dark--callout_blue: var(--theme_dark--line_blue);
--theme_dark--callout_purple: var(--theme_dark--line_purple);
--theme_dark--callout_pink: var(--theme_dark--line_pink);
--theme_dark--callout_red: var(--theme_dark--line_red);
/* incline/code text */
--theme_dark--code_inline-text: var(--cola-accent);
--theme_dark--code_inline-background: var(--cola-main);
--theme_dark--code-text: var(--theme_dark--text);
--theme_dark--code-background: var(--cola-sec);
--theme_dark--code_function: var(--theme_dark--text_blue);
--theme_dark--code_keyword: var(--theme_dark--text_pink);
--theme_dark--code_tag: var(--theme_dark--text_pink);
--theme_dark--code_operator: var(--theme_dark--text_yellow);
--theme_dark--code_important: var(--theme_dark--text_yellow);
--theme_dark--code_property: var(--theme_dark--text_pink);
--theme_dark--code_builtin: var(--theme_dark--text_yellow);
--theme_dark--code_attr-name: var(--theme_dark--text_yellow);
--theme_dark--code_comment: var(--theme_dark--text_gray);
--theme_dark--code_punctuation: var(--theme_dark--text_gray);
--theme_dark--code_doctype: var(--theme_dark--text_gray);
--theme_dark--code_number: var(--theme_dark--text_purple);
--theme_dark--code_string: var(--theme_dark--text_orange);
--theme_dark--code_attr-value: var(--theme_dark--text_orange);
}

View File

@ -0,0 +1,24 @@
/*
* code line numbers
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
.notion-code-block.line-numbers > div {
position: relative;
}
.code-numbered {
padding-left: 48px !important;
}
#code-line-numbers {
font-size: var(--theme--font_code-size) !important;
font-family: var(--theme--font_code) !important;
opacity: 0.5;
text-align: right;
position: absolute;
right: calc(100% - 30px);
overflow: hidden;
pointer-events: none;
}

View File

@ -0,0 +1,91 @@
/*
* code line numbers
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
'use strict';
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: 'd61dc8a7-b195-465b-935f-53eea9efe74e',
tags: ['extension'],
name: 'code line numbers',
desc: 'adds line numbers to code blocks.',
version: '1.0.0',
author: 'CloudHill',
options: [
{
key: 'single_lined',
label: 'show line numbers on single-lined code blocks',
type: 'toggle',
value: false,
},
],
hacks: {
'renderer/preload.js'(store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
let queue = [];
const observer = new MutationObserver((list, observer) => {
if (!queue.length) requestAnimationFrame(() => handle(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
function handle(list) {
queue = [];
for (let { addedNodes } of list) {
if (
addedNodes[0] &&
addedNodes[0].dataset &&
addedNodes[0].dataset.tokenIndex &&
addedNodes[0].parentElement
) {
const block = addedNodes[0].parentElement.parentElement;
if (
block &&
block.classList &&
block.classList.contains('notion-code-block')
) {
let numbers = block.querySelector('#code-line-numbers');
if (!numbers) {
numbers = createElement(
'<span id="code-line-numbers"></span>'
);
const blockStyle = window.getComputedStyle(block.children[0]);
numbers.style.top = blockStyle.paddingTop;
numbers.style.bottom = blockStyle.paddingBottom;
block.append(numbers);
const temp = createElement('<div>A</div>');
block.children[0].append(temp);
block.lineHeight = temp.getBoundingClientRect().height;
temp.remove();
}
const lines = Math.round(
numbers.getBoundingClientRect().height / block.lineHeight
);
if (lines > 1) {
block.children[0].classList.add('code-numbered');
numbers.innerText = Array.from(
Array(lines),
(e, i) => i + 1
).join('\n');
}
}
}
}
}
});
},
},
};

9
mods/core/app.css Normal file
View File

@ -0,0 +1,9 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
@import './css/theme.css';
@import './css/scrollbars.css';
@import './css/titlebar.css';

106
mods/core/buttons.js Normal file
View File

@ -0,0 +1,106 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = (store) => {
const helpers = require('../../pkg/helpers.js'),
path = require('path'),
fs = require('fs-extra'),
browser = require('electron').remote.getCurrentWindow(),
is_mac = process.platform === 'darwin',
buttons = {
element: helpers.createElement('<div class="window-buttons-area"></div>'),
insert: [
...((store('mods')['72886371-dada-49a7-9afc-9f275ecf29d3'] || {})
.enabled
? ['alwaysontop']
: []),
...(store().frameless && !store().tiling_mode && !is_mac
? ['minimize', 'maximize', 'close']
: []),
],
icons: {
raw: {
alwaysontop: {
on: fs.readFile(
path.resolve(`${__dirname}/icons/alwaysontop_on.svg`)
),
off: fs.readFile(
path.resolve(`${__dirname}/icons/alwaysontop_off.svg`)
),
},
minimize: fs.readFile(
path.resolve(`${__dirname}/icons/minimize.svg`)
),
maximize: {
on: fs.readFile(path.resolve(`${__dirname}/icons/maximize_on.svg`)),
off: fs.readFile(
path.resolve(`${__dirname}/icons/maximize_off.svg`)
),
},
close: fs.readFile(path.resolve(`${__dirname}/icons/close.svg`)),
},
alwaysontop() {
return browser.isAlwaysOnTop()
? buttons.icons.raw.alwaysontop.on
: buttons.icons.raw.alwaysontop.off; // '🠙' : '🠛'
},
minimize() {
return buttons.icons.raw.minimize; // '⚊'
},
maximize() {
return browser.isMaximized()
? buttons.icons.raw.maximize.on
: buttons.icons.raw.maximize.off; // '🗗' : '🗖'
},
close() {
return buttons.icons.raw.close; // '⨉'
},
},
actions: {
async alwaysontop() {
browser.setAlwaysOnTop(!browser.isAlwaysOnTop());
this.innerHTML = await buttons.icons.alwaysontop();
},
minimize() {
browser.minimize();
},
async maximize() {
browser.isMaximized() ? browser.unmaximize() : browser.maximize();
this.innerHTML = await buttons.icons.maximize();
},
close() {
browser.close();
},
},
};
if (!buttons.insert.includes('alwaysontop')) browser.setAlwaysOnTop(false);
(async () => {
for (let btn of buttons.insert) {
buttons.element.innerHTML += `<button class="window-button btn-${btn}">${await buttons.icons[
btn
]()}</button>`;
}
for (let btn of buttons.insert) {
buttons.element.querySelector(`.window-button.btn-${btn}`).onclick =
buttons.actions[btn];
}
if (store().frameless && !store().tiling_mode && !is_mac) {
window.addEventListener('resize', (event) => {
Promise.resolve(buttons.icons.maximize()).then((icon) => {
icon = icon.toString();
const el = buttons.element.querySelector('.btn-maximize');
if (el.innerHTML != icon) el.innerHTML = icon;
});
});
}
})();
return buttons;
};

270
mods/core/client.js Normal file
View File

@ -0,0 +1,270 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* under the MIT license
*/
'use strict';
module.exports = (store, __exports) => {
const electron = require('electron'),
helpers = require('../../pkg/helpers.js'),
notionIpc = require(`${helpers.__notion.replace(
/\\/g,
'/'
)}/app/helpers/notionIpc.js`),
{ toKeyEvent } = require('keyboardevent-from-electron-accelerator'),
tabsEnabled = (store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {})
.enabled;
document.defaultView.addEventListener('keyup', (event) => {
// additional hotkeys
if (event.key === 'F5') location.reload();
// open menu on hotkey toggle
if (store().menu_toggle) {
const hotkey = {
ctrlKey: false,
metaKey: false,
altKey: false,
shiftKey: false,
...toKeyEvent(store().menu_toggle),
};
let triggered = true;
for (let prop in hotkey)
if (
hotkey[prop] !== event[prop] &&
!(prop === 'key' && event[prop] === 'Dead')
)
triggered = false;
if (triggered) electron.ipcRenderer.send('enhancer:open-menu');
}
if (tabsEnabled) {
const tabStore = () => store('e1692c29-475e-437b-b7ff-3eee872e1a42');
if (tabStore().select_modifier) {
// switch between tabs via key modifier
const select_tab_modifier = {
ctrlKey: false,
metaKey: false,
altKey: false,
shiftKey: false,
...toKeyEvent(tabStore().select_modifier),
};
let triggered = true;
for (let prop in select_tab_modifier)
if (select_tab_modifier[prop] !== event[prop]) triggered = false;
if (
triggered &&
[
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'ArrowRight',
'ArrowLeft',
].includes(event.key)
)
electron.ipcRenderer.sendToHost('enhancer:select-tab', event.key);
}
if (tabStore().new_tab) {
// create/close tab keybindings
const new_tab_keybinding = {
ctrlKey: false,
metaKey: false,
altKey: false,
shiftKey: false,
...toKeyEvent(tabStore().new_tab),
};
let triggered = true;
for (let prop in new_tab_keybinding)
if (new_tab_keybinding[prop] !== event[prop]) triggered = false;
if (triggered) electron.ipcRenderer.sendToHost('enhancer:new-tab');
}
if (tabStore().close_tab) {
const close_tab_keybinding = {
ctrlKey: false,
metaKey: false,
altKey: false,
shiftKey: false,
...toKeyEvent(tabStore().close_tab),
};
let triggered = true;
for (let prop in close_tab_keybinding)
if (close_tab_keybinding[prop] !== event[prop]) triggered = false;
if (triggered) electron.ipcRenderer.sendToHost('enhancer:close-tab');
}
}
});
const attempt_interval = setInterval(enhance, 500);
async function enhance() {
if (
!document.querySelector('.notion-frame') ||
!document.querySelector('.notion-sidebar') ||
!document.querySelector('.notion-topbar')
)
return;
clearInterval(attempt_interval);
// frameless
if (store().frameless && !store().tiling_mode && !tabsEnabled) {
document.body.classList.add('frameless');
// draggable area
document
.querySelector('.notion-topbar')
.prepend(helpers.createElement('<div class="window-dragarea"></div>'));
}
// window buttons
if (!tabsEnabled) {
const buttons = require('./buttons.js')(store);
document
.querySelector('.notion-topbar > div[style*="display: flex"]')
.appendChild(buttons.element);
}
document
.querySelector('.notion-history-back-button')
.parentElement.nextElementSibling.classList.add(
'notion-topbar-breadcrumb'
);
document
.querySelector('.notion-topbar-share-menu')
.parentElement.classList.add('notion-topbar-actions');
const getStyle = (prop) =>
getComputedStyle(
document.querySelector('.notion-app-inner')
).getPropertyValue(prop);
// external theming
document.defaultView.addEventListener('keydown', (event) => {
if ((event.ctrlKey || event.metaKey) && event.key === 'f') {
notionIpc.sendNotionToIndex('search:set-theme', {
'mode': document.querySelector('.notion-dark-theme')
? 'dark'
: 'light',
'colors': {
'white': getStyle('--theme--option_active-color'),
'blue': getStyle('--theme--option_active-background'),
},
'borderRadius': 3,
'textColor': getStyle('--theme--text'),
'popoverBackgroundColor': getStyle('--theme--card'),
'popoverBoxShadow': getStyle('--theme--box-shadow_strong'),
'inputBoxShadow': `box-shadow: ${getStyle(
`--theme--primary`
)} 0px 0px 0px 1px inset, ${getStyle(
`--theme--primary_hover`
)} 0px 0px 0px 2px !important`,
'inputBackgroundColor': getStyle('--theme--main'),
'dividerColor': getStyle('--theme--table-border'),
'shadowOpacity': 0.2,
});
}
});
function setAppTheme() {
const theme = document.querySelector('.notion-dark-theme')
? 'dark'
: 'light';
electron.ipcRenderer.send('enhancer:set-app-theme', theme);
}
setAppTheme();
new MutationObserver(setAppTheme).observe(
document.querySelector('.notion-app-inner'),
{ attributes: true }
);
electron.ipcRenderer.on('enhancer:get-app-theme', setAppTheme);
if (tabsEnabled) {
let tab_title = { img: '', emoji: '', text: '' };
if (process.platform === 'darwin')
document
.querySelector('.notion-sidebar [style*="37px"]:empty')
.remove();
const TITLE_OBSERVER = new MutationObserver(() =>
__electronApi.setWindowTitle('notion.so')
);
__electronApi.setWindowTitle = (title) => {
const $container =
document.querySelector(
'.notion-peek-renderer [style="padding-left: calc(126px + env(safe-area-inset-left)); padding-right: calc(126px + env(safe-area-inset-right)); max-width: 100%; width: 100%;"]'
) ||
document.querySelector(
'.notion-frame [style="padding-left: calc(96px + env(safe-area-inset-left)); padding-right: calc(96px + env(safe-area-inset-right)); max-width: 100%; margin-bottom: 8px; width: 100%;"]'
) ||
document.querySelector('.notion-peak-renderer') ||
document.querySelector('.notion-frame'),
icon = $container.querySelector(
'.notion-record-icon img:not([src^="data:"])'
),
img =
icon && icon.getAttribute('src')
? `<img src="${
icon.getAttribute('src').startsWith('/')
? 'notion://www.notion.so'
: ''
}${icon.getAttribute('src')}">`
: '',
emoji = icon ? icon.getAttribute('aria-label') : '';
let text = $container.querySelector('[placeholder="Untitled"]');
text = text
? text.innerText || 'Untitled'
: [
setTimeout(() => __electronApi.setWindowTitle(title), 250),
title,
][1];
TITLE_OBSERVER.disconnect();
TITLE_OBSERVER.observe($container, {
childList: true,
subtree: true,
characterData: true,
attributes: true,
});
if (
tab_title.img !== img ||
tab_title.emoji !== emoji ||
tab_title.text !== text
) {
tab_title = {
img,
emoji,
text,
};
electron.ipcRenderer.sendToHost('enhancer:set-tab-title', tab_title);
}
};
__electronApi.openInNewWindow = (urlPath) => {
electron.ipcRenderer.sendToHost(
'enhancer:new-tab',
`notion://www.notion.so${urlPath}`
);
};
} else if (store().frameless && !store().tiling_mode) {
let sidebar_width;
function setSidebarWidth(list) {
const new_sidebar_width =
list[0].target.style.height === 'auto'
? '0px'
: list[0].target.style.width;
if (new_sidebar_width !== sidebar_width) {
sidebar_width = new_sidebar_width;
electron.ipcRenderer.sendToHost(
'enhancer:sidebar-width',
sidebar_width
);
}
}
new MutationObserver(setSidebarWidth).observe(
document.querySelector('.notion-sidebar'),
{ attributes: true }
);
setSidebarWidth([{ target: document.querySelector('.notion-sidebar') }]);
}
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

85
mods/core/createWindow.js Normal file
View File

@ -0,0 +1,85 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* under the MIT license
*/
'use strict';
module.exports = (store, __exports) => {
const electron = require('electron'),
allWindows = () =>
electron.BrowserWindow.getAllWindows().filter(
(win) => win.getTitle() !== 'notion-enhancer menu'
),
// createWindow = __exports.createWindow,
path = require('path'),
helpers = require('../../pkg/helpers.js');
__exports.createWindow = function (relativeUrl, focused_window) {
if (!relativeUrl) relativeUrl = '';
const window_state = require(`${helpers.__notion.replace(
/\\/g,
'/'
)}/app/node_modules/electron-window-state/index.js`)({
defaultWidth: 1320,
defaultHeight: 860,
}),
rect = {
x: window_state.x,
y: window_state.y,
width: window_state.width,
height: window_state.height,
};
focused_window =
focused_window || electron.BrowserWindow.getFocusedWindow();
if (focused_window && !focused_window.isMaximized()) {
rect.x = focused_window.getPosition()[0] + 20;
rect.y = focused_window.getPosition()[1] + 20;
rect.width = focused_window.getSize()[0];
rect.height = focused_window.getSize()[1];
}
const window = new electron.BrowserWindow({
show: false,
backgroundColor: '#ffffff',
titleBarStyle: 'hiddenInset',
frame: !store().frameless,
webPreferences: {
preload: path.resolve(`${helpers.__notion}/app/renderer/index.js`),
webviewTag: true,
session: electron.session.fromPartition('persist:notion'),
},
...rect,
});
window.once('ready-to-show', function () {
if (
!store().openhidden ||
allWindows().some((win) => win.isVisible() && win.id != window.id)
) {
window.show();
window.focus();
if (store().maximized) window.maximize();
if (
(focused_window && focused_window.isFullScreen()) ||
window_state.isFullScreen
)
window.setFullScreen(true);
}
});
let intended_quit = false;
window.on('close', (e) => {
if (intended_quit || !store().close_to_tray || allWindows().length > 1) {
window_state.saveState(window);
window = null;
} else {
e.preventDefault();
window.hide();
}
});
electron.app.on('before-quit', () => (intended_quit = true));
window.loadURL(__exports.getIndexUrl(relativeUrl));
return window;
};
return __exports.createWindow;
};

43
mods/core/css/buttons.css Normal file
View File

@ -0,0 +1,43 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* under the MIT license
*/
.window-buttons-area {
display: flex;
align-items: center;
font-size: 14px;
}
.window-button {
background: transparent;
border: 0;
margin: 0px 0px 0px 9px;
width: 32px;
line-height: 26px;
border-radius: 4px;
font-size: 16px;
transition: background 0.2s;
cursor: default;
}
.window-button svg {
margin-top: 8px;
width: 14px;
height: 14px;
}
.window-button svg path {
fill: currentColor;
}
.window-button svg line {
stroke: currentColor;
}
.window-button:hover {
background: var(--theme--interactive_hover);
box-shadow: 0 0 0 0.5px var(--theme--interactive_hover-border);
}
.window-button.btn-close:hover {
background: var(--theme--button_close);
color: var(--theme--button_close-fill);
}

View File

@ -0,0 +1,29 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* under the MIT license
*/
[data-tweaks*='[smooth_scrollbars]'] .notion-scroller {
cursor: auto;
}
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar {
width: 8px; /* vertical */
height: 8px; /* horizontal */
-webkit-app-region: no-drag;
}
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-corner {
background-color: transparent; /* overlap */
}
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-thumb {
border-radius: 5px;
}
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-thumb {
background-color: var(--theme--scrollbar);
border: 1px solid var(--theme--scrollbar-border);
}
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-thumb:hover {
background: var(--theme--scrollbar_hover);
}

991
mods/core/css/theme.css Normal file
View File

@ -0,0 +1,991 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* (c) 2020 Arecsu
* (c) 2020 u/zenith_illinois
* under the MIT license
*/
/** app **/
.notion-body,
.notion-body.dark [style*='background: rgb(47, 52, 55)'],
.notion-body.dark [style*='background-color: rgb(47, 52, 55)'],
.notion-body:not(.dark)
.notion-light-theme
[style*='background: white']:not(.notion-help-button),
.notion-body:not(.dark)
.notion-dark-theme
[style*='background: white']:not(.notion-help-button):not([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:not(.dark) [style*='background-color: white'] {
background: var(--theme--main) !important;
}
.notion-sidebar > div,
.notion-body.dark [style*='background: rgb(55, 60, 63)'],
.notion-body.dark [style*='background: rgb(120, 123, 123)'],
.notion-body:not(.dark) [style*='background: rgb(247, 246, 243)'],
.notion-body:not(.dark) [style*='background: rgb(223, 223, 222)'] {
background: var(--theme--sidebar) !important;
}
.notion-peek-renderer,
[style*='background: rgba(15, 15, 15, 0.6)'] {
background: var(--theme--overlay) !important;
}
.notion-frame
.notion-scroller
[style*='env(safe-area-inset-'][style*=' width: 900px'],
.notion-frame
.notion-scroller
[style*='env(safe-area-inset-'][style*=';width: 900px'],
.notion-frame
.notion-scroller
[style*='height: 30vh']
[style*='pointer-events:'][style*='max-width: 100%; width: 900px'] {
width: var(--theme--page_normal-width) !important;
}
.notion-frame
[style*='padding-left: calc(96px + env(safe-area-inset-left)); padding-right: calc(96px + env(safe-area-inset-right));'] {
padding-left: var(--theme--page-padding) !important;
padding-right: var(--theme--page-padding) !important;
}
.notion-page-content [data-block-id][style*='max-width'] {
max-width: 100% !important;
}
.notion-frame
.notion-scroller
[style*='env(safe-area-inset-'][style*=' width: 100%'],
.notion-frame
.notion-scroller
[style*='height: 30vh']
[style*='pointer-events:'][style*='max-width: 100%; width: 100%'] {
width: var(--theme--page_full-width) !important;
}
.notion-frame .notion-scroller [style*='padding-left: 136.5px;'] {
padding-left: 0 !important;
}
.notion-frame .notion-scroller [style*='padding-right: 136.5px;'] {
padding-right: 0 !important;
}
.notion-collection_view-block > :first-child,
.notion-collection_view-block .notion-scroller > :first-child {
padding-left: 0 !important;
padding-right: 0 !important;
}
.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--preview_banner-height) !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;
}
/* colour help button - one of the few specific classes notion does give us */
.notion-help-button {
background: var(--theme--interactive_hover) !important;
box-shadow: 0 0 0 0.5px var(--theme--interactive_hover-border) !important;
}
/* page preview sizing */
.notion-peek-renderer > div:nth-child(2) {
max-width: var(--theme--preview-width) !important;
}
.notion-peek-renderer .notion-page-content [style*='max-width: 943px;'] {
max-width: none !important;
}
.notion-peek-renderer
.notion-scroller.vertical
[style*='padding-left: calc(126px + env(safe-area-inset-left));'] {
padding-left: var(--theme--preview-padding) !important;
}
.notion-peek-renderer
.notion-scroller.vertical
[style*='padding-right: calc(126px + env(safe-area-inset-right));'] {
padding-right: var(--theme--preview-padding) !important;
}
.notion-peek-renderer
.notion-scroller.vertical
[style*='margin-left: calc(126px + env(safe-area-inset-left));'] {
margin-left: var(--theme--preview-padding) !important;
}
.notion-peek-renderer
.notion-scroller.vertical
[style*='margin-right: calc(126px + env(safe-area-inset-right));'] {
margin-right: var(--theme--preview-padding) !important;
}
.notion-peek-renderer .notion-page-content {
padding-left: var(--theme--preview-padding) !important;
padding-right: var(--theme--preview-padding) !important;
width: 100%;
}
/** fonts **/
[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;
}
.notion-frame .notion-page-block div[placeholder='Untitled'],
.notion-overlay-container .notion-page-block div[placeholder='Untitled'] {
font-size: calc(
var(--theme--font_body-size) * (var(--theme--font_heading1-size) / 1em)
) !important;
}
[placeholder='Heading 1'] {
font-size: calc(
var(--theme--font_body-size) * (var(--theme--font_heading1-size) / 1em)
) !important;
}
[placeholder='Heading 2'] {
font-size: calc(
var(--theme--font_body-size) * (var(--theme--font_heading2-size) / 1em)
) !important;
}
[placeholder='Heading 3'] {
font-size: calc(
var(--theme--font_body-size) * (var(--theme--font_heading3-size) / 1em)
) !important;
}
.notion-frame .notion-scroller.vertical.horizontal [style*='font-size: 14px'],
.notion-overlay-container .notion-scroller.vertical [style*='font-size: 14px'] {
font-size: var(--theme--font_label-size) !important;
}
.notion-frame .notion-scroller.vertical.horizontal .notion-page-content,
.notion-overlay-container .notion-scroller.vertical .notion-page-content {
font-size: var(--theme--font_body-size) !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: var(--theme--font_body-size_small) !important;
}
.notion-code-block [placeholder=' '] {
font-size: var(--theme--font_code-size) !important;
}
.notion-sidebar [style*='font-size: 14px'] {
font-size: var(--theme--font_sidebar-size) !important;
}
/** text-block readability **/
.notion-page-content .notion-selectable.notion-text-block {
line-height: var(--theme--text-block_line-height) !important;
margin-top: var(--theme--text-block_margin-top) !important;
}
/** databases **/
.notion-body.dark [style*='background: rgb(63, 68, 71)'],
.notion-body.dark [style*='background-color: rgb(64, 68, 71);'],
.notion-body:not(.dark)
.notion-scroller.horizontal.vertical
.notion-selectable
> a[style*='background: white'],
.notion-body:not(.dark) [style*='background: rgb(247, 246, 243)'],
.notion-body:not(.dark)
.notion-dark-theme
[style*='background: white'][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;'] {
background: var(--theme--card) !important;
}
.notion-body.dark
.notion-page-block.notion-collection-item
[style*='background: rgba(255, 255, 255, 0.05)'],
.notion-body:not(.dark)
.notion-page-block.notion-collection-item
[style*='background: rgba(55, 53, 47, 0.024)'] {
background: var(--theme--gallery) !important;
}
.notion-body.dark .notion-scroller > [style*='rgb(55, 60, 63)'],
.notion-body:not(.dark) [style*='background: rgba(242, 241, 238, 0.6)'] {
background: var(--theme--select_input) !important;
}
.notion-body.dark
[style*='box-shadow: rgba(255, 255, 255, 0.14) 0px -1px inset;'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.16) 0px -1px 0px inset'] {
box-shadow: rgba(55, 53, 47, 0.16) 0px -1px inset !important;
}
.notion-body.dark [style*='box-shadow: rgba(255, 255, 255, 0.07) 0px 1px 0px'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.09) 0px 1px 0px'] {
box-shadow: var(--theme--ui-border) 0px 1px 0px !important;
}
.notion-body.dark
[style*='box-shadow: rgba(255, 255, 255, 0.14) 0px 1px 0px inset'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.16) 0px 1px 0px inset'] {
box-shadow: var(--theme--table-border) 0px 1px 0px inset !important;
}
.notion-body.dark [style*='box-shadow: rgb(47, 52, 55) -3px 0px 0px'] {
box-shadow: var(--theme--main) -3px 0px 0px !important;
}
.notion-body:not(.dark) [style*='box-shadow: white -3px 0px 0px;'] {
box-shadow: none !important;
}
.notion-body.dark
[style*='box-shadow: rgb(47, 52, 55) -3px 0px 0px, rgba(255, 255, 255, 0.14) 0px 1px 0px'],
.notion-body:not(.dark)
[style*='box-shadow: white -3px 0px 0px, rgba(55, 53, 47, 0.16) 0px 1px 0px'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(255, 255, 255, 0.07) 0px -1px 0px'] {
box-shadow: var(--theme--main) -3px 0px 0px,
var(--theme--ui-border) 0px 1px 0px !important;
}
.notion-body.dark [style*='border-top: 1px solid rgba(255, 255, 255,'],
.notion-body:not(.dark) [style*='border-top: 1px solid rgba(55, 53, 47,'] {
border-top: 1px solid var(--theme--table-border) !important;
}
.notion-body.dark
[style*='box-shadow: rgba(255, 255, 255, 0.14) -1px 0px 0px'] {
box-shadow: var(--theme--table-border) -1px 0px 0px !important;
}
.notion-body.dark [style*='border-bottom: 1px solid rgba(255, 255, 255,'],
.notion-body:not(.dark) [style*='border-bottom: 1px solid rgba(55, 53, 47,'] {
border-bottom: 1px solid var(--theme--table-border) !important;
}
.notion-body.dark [style*='box-shadow: rgba(255, 255, 255, 0.14) 0px 1px 0px'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.16) 0px 1px 0px'] {
box-shadow: var(--theme--table-border) 0px 1px 0px !important;
}
.notion-body.dark [style*='border-right: 1px solid rgba(255, 255, 255,'],
.notion-body:not(.dark) [style*='border-right: 1px solid rgba(55, 53, 47,'] {
border-right: 1px solid var(--theme--table-border) !important;
}
.notion-body.dark [style*='box-shadow: rgba(255, 255, 255, 0.07) 0px -1px 0px'],
.notion-body.dark [style*='box-shadow: rgba(55, 53, 47, 0.09) 0px -1px 0px'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.09) 0px -1px 0px'] {
box-shadow: var(--theme--ui-border) 0px -1px 0px !important;
}
.notion-body.dark [style*='border-left: 1px solid rgba(255, 255, 255,'],
.notion-body.dark
.notion-block-permission-settings-public-access
[role='button'][style*='border-left: none'],
.notion-body:not(.dark) [style*='border-left: 1px solid rgba(55, 53, 47,'] {
border-left: 1px solid var(--theme--table-border) !important;
}
.notion-body.dark
[style*='box-shadow: rgba(255, 255, 255, 0.14) 1px 0px 0px inset'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.16) 1px 0px 0px inset'] {
box-shadow: var(--theme--table-border) 1px 0px 0px inset !important;
}
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.09) -1px 0px 0px'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(55, 53, 47, 0.16) -1px 0px 0px'] {
box-shadow: -1px -1px 0 var(--theme--table-border) !important;
}
.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--bg_gray) 0%,
var(--theme--bg_gray) 100%
) !important;
}
.notion-body.dark [style*='background: rgb(71, 76, 80)'],
.notion-body.dark [style*='background: rgb(80, 85, 88)'],
.notion-body.dark [style*='background: rgb(98, 102, 104)'],
.notion-body.dark [style*='height: 1px; background: rgba(255, 255, 255, 0.07)'],
.notion-body:not(.dark) [style*='background: rgba(55, 53, 47,'],
.notion-body:not(.dark) [style*='background: rgb(239, 239, 238)'],
.notion-body:not(.dark) [style*='background: rgba(206, 205, 202, 0.5)'] {
background: var(--theme--interactive_hover) !important;
box-shadow: 0 0 0 0.5px var(--theme--interactive_hover-border) !important;
}
/* normalise inline-table size */
.notion-page-content .notion-collection_view-block[style*=' width'],
.notion-page-content .notion-collection_view-block[style^='width'] {
width: 100% !important;
}
.notion-page-content
.notion-collection_view-block
[style*='padding-left: 50px'],
.notion-page-content
.notion-collection_view-block
[style*='padding-left: 96px'],
.notion-page-content
.notion-collection_view-block
[style*='padding-left: 126px'] {
padding-left: 0 !important;
}
.notion-page-content
.notion-collection_view-block
[style*='padding-right: 50px'],
.notion-page-content
.notion-collection_view-block
[style*='padding-right: 96px'],
.notion-page-content
.notion-collection_view-block
[style*='padding-right: 126px'] {
padding-right: 0 !important;
}
.notion-page-content
.notion-collection_view-block
[style*='min-width: calc(100% - 192px);'],
.notion-page-content
.notion-collection_view-block
[style*='min-width: 708px;'] {
min-width: 100% !important;
}
.notion-page-content .notion-collection_view-block > div {
padding: 0 1px;
}
/* smooth transitions */
.notion-calendar-view-day,
.DayPicker-Day--today:not(.DayPicker-Day--selected):not(.DayPicker-Day--value):not(.DayPicker-Day--start):not(.DayPicker-Day--end),
.DayPicker-Day.DayPicker-Day--start.DayPicker-Day--selected,
.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day--outside:hover,
.DayPicker:not(.DayPicker--interactionDisabled)
.DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--value):not(.DayPicker-Day--start):not(.DayPicker-Day--end) {
transition: all 200ms ease !important;
}
.notion-token-remove-button {
transition: opacity 200ms ease !important;
}
.notion-to_do-block > div > div > div[style*='background:'] {
transition: background 200ms ease !important;
}
/* fix button resizing */
.notion-collection_view-block [role='button'],
.notion-collection_view_page-block [role='button'] {
border-width: 0 !important;
}
/** general ui **/
::selection,
[style*='background: rgba(46, 170, 220,']:not([style*='background: rgba(46, 170, 220, 0)']),
[style*='background-color: rgba(46, 170, 220,']:not([style*='background-color: rgba(46, 170, 220, 0)']) {
background: var(--theme--selected) !important;
}
[style*=' color: rgb(46, 170, 220)'],
[style^='color: rgb(46, 170, 220)'] {
color: var(--theme--primary) !important;
}
[style*='fill: rgb(46, 170, 220)'] {
fill: var(--theme--primary) !important;
}
[style*='background: rgb(46, 170, 220)'],
[style*='background-color: rgb(46, 170, 220)'] {
background: var(--theme--primary) !important;
}
[style*='box-shadow: rgb(46, 170, 220) 0px 0px 0px 2px inset'] {
box-shadow: var(--theme--primary) 0px 0px 0px 2px inset !important;
}
[style*='background: rgb(6, 156, 205)'] {
background: var(--theme--primary_hover) !important;
}
[style*='background: rgb(0, 141, 190)'] {
background: var(--theme--primary_click) !important;
}
.DayPicker-Day--today:not(.DayPicker-Day--selected):not(.DayPicker-Day--value):not(.DayPicker-Day--start):not(.DayPicker-Day--end)::after,
[style*='background: rgb(235, 87, 87)'] {
background: var(--theme--primary_indicator) !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'] {
box-shadow: var(--theme--box-shadow_strong) !important;
}
.notion-body.dark
[style*='box-shadow: rgba(15, 15, 15, 0.2) 0px 0px 0px 1px, rgba(15, 15, 15, 0.2) 0px 2px 4px'],
.notion-body:not(.dark)
[style*='box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, rgba(15, 15, 15, 0.1) 0px 2px 4px'] {
box-shadow: var(--theme--box-shadow) !important;
}
.notion-to_do-block > div [role='button']:hover,
.notion-to_do-block > div [role='button']:hover .checkboxSquare,
.notion-to_do-block > div [role='button']:hover .check {
background: var(--theme--option_hover-background) !important;
}
.notion-to_do-block > div [role='button']:hover .checkboxSquare path,
.notion-to_do-block > div [role='button']:hover .check polygon {
fill: var(--theme--option_hover-color) !important;
}
.notion-to_do-block > div [role='button']:not(:hover) .check {
background: var(--theme--option_active-background) !important;
}
.notion-to_do-block > div [role='button']:not(:hover) .check polygon {
fill: var(--theme--option_active-color) !important;
}
.notion-to_do-block .checkboxSquare {
background: var(--theme--option-background) !important;
}
.notion-to_do-block .checkboxSquare path {
fill: var(--theme--option-color) !important;
}
[style*='color: rgb(235, 87, 87); border: 1px solid rgba(235, 87, 87, 0.5);'] {
color: var(--theme--danger_text) !important;
border: 1px solid var(--theme--danger_border) !important;
}
/* inputs */
.notion-focusable:focus-within {
box-shadow: var(--theme--primary_hover) 0px 0px 0px 2px !important;
}
/** content colours **/
.notion-body,
.notion-frame .notion-page-block,
.notion-body.dark [style*=' color: rgba(255, 255, 255, 0.9)'],
.notion-body.dark [style^='color: rgba(255, 255, 255, 0.9)'],
.notion-body.dark [style*=' color: rgba(255, 255, 255, 0.7)'],
.notion-body.dark [style^='color: rgba(255, 255, 255, 0.7)'],
.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*='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(25, 23, 17, 0.6)'] {
color: var(--theme--text_ui) !important;
}
::placeholder {
opacity: 1 !important;
}
::placeholder,
[style*='-webkit-text-fill-color:'],
.notion-body.dark [style*='color: rgba(255, 255, 255, 0.4)'],
.notion-body.dark [style*='color: rgba(255, 255, 255, 0.4)']::before,
.notion-body:not(.dark) [style*='color: rgba(55, 53, 47, 0.4)'],
.notion-body:not(.dark) [style*='color: rgba(55, 53, 47, 0.4)']::before {
color: var(--theme--text_ui_info) !important;
-webkit-text-fill-color: var(--theme--text_ui_info) !important;
}
.notion-body.dark [style*='fill: rgb(202, 204, 206)'] {
fill: var(--theme--text) !important;
}
.notion-body.dark [style*='fill: rgba(255, 255, 255, 0.6)'],
.notion-body:not(.dark) [style*='fill: rgba(55, 53, 47, 0.8)'],
.notion-body:not(.dark) [style*='fill: rgba(55, 53, 47, 0.6)'],
.notion-body:not(.dark) [style*='fill: rgba(25, 23, 17, 0.6)'] {
fill: var(--theme--text_ui) !important;
}
.notion-body.dark [style*='fill: rgba(202, 204, 206, 0.6)'],
.notion-body.dark [style*='fill: rgba(202, 204, 206, 0.4)'],
.notion-body:not(.dark) [style*='fill: rgba(55, 53, 47, 0.4)'],
.notion-body:not(.dark) [style*='fill: rgba(55, 53, 47, 0.3)'] {
fill: var(--theme--text_ui_info) !important;
}
.notion-body.dark [style*='border-color:rgba(255,255,255,0.4);opacity:0.7'],
.notion-body:not(.dark) [style*='border-color:rgba(55,53,47,0.4);opacity:0.7'] {
border-color: var(--theme--text_ui_info) !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(151,154,155,0.95)'],
.notion-body.dark
[style*='color: rgba(255, 255, 255, 0.6); fill: rgba(255, 255, 255, 0.6);'],
.notion-body:not(.dark) [style*='color:rgb(155,154,151)'],
.notion-body:not(.dark)
[style*='color: rgba(55, 53, 47, 0.6); fill: rgba(55, 53, 47, 0.6);'] {
color: var(--theme--text_gray) !important;
fill: var(--theme--text_gray) !important;
}
.notion-body.dark [style*='background:rgb(69,75,78)'],
.notion-body:not(.dark) [style*='background:rgb(235,236,237)'] {
background: var(--theme--bg_gray) !important;
color: var(--theme--bg_gray-text) !important;
}
.notion-body.dark
[style*='color:rgba(151,154,155,0.95)']
[style*='background:rgb(69,75,78)'],
.notion-body.dark
[style*='color: rgba(255, 255, 255, 0.6); fill: rgba(255, 255, 255, 0.6);']
[style*='background:rgb(69,75,78)'],
.notion-body:not(.dark)
[style*='color:rgb(155,154,151)']
[style*='background:rgb(235,236,237)'],
.notion-body:not(.dark)
[style*='color: rgba(55, 53, 47, 0.6); fill: rgba(55, 53, 47, 0.6);']
[style*='background:rgb(235,236,237)'] {
background: var(--theme--bg_gray) !important;
color: var(--theme--text_gray) !important;
fill: var(--theme--text_gray) !important;
}
.notion-body.dark [style*='background: rgb(69, 75, 78)'],
.notion-body:not(.dark) [style*='background: rgb(235, 236, 237)'] {
background: var(--theme--line_gray) !important;
color: var(--theme--line_gray-text) !important;
}
.notion-body.dark [style*='background: rgba(151, 154, 155, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(140, 46, 0, 0.2)'] {
background: var(--theme--select_gray) !important;
color: var(--theme--select_gray-text) !important;
}
.notion-body.dark [style*='background: rgba(69, 75, 78, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(235, 236, 237, 0.3)'] {
background: var(--theme--callout_gray) !important;
color: var(--theme--callout_gray-text) !important;
}
.notion-body.dark [style*='color:rgb(147,114,100)'],
.notion-body.dark
[style*='color: rgb(147, 114, 100); fill: rgb(147, 114, 100);'],
.notion-body:not(.dark) [style*='color:rgb(100,71,58)'],
.notion-body:not(.dark)
[style*='color: rgb(100, 71, 58); fill: rgb(100, 71, 58);'] {
color: var(--theme--text_brown) !important;
fill: var(--theme--text_brown) !important;
}
.notion-body.dark [style*='background:rgb(67,64,64)'],
.notion-body:not(.dark) [style*='background:rgb(233,229,227)'] {
background: var(--theme--bg_brown) !important;
color: var(--theme--bg_brown-text) !important;
}
.notion-body.dark
[style*='color:rgb(147,114,100)']
[style*='background:rgb(67,64,64)'],
.notion-body.dark
[style*='color: rgb(147, 114, 100); fill: rgb(147, 114, 100);']
[style*='background:rgb(67,64,64)'],
.notion-body:not(.dark)
[style*='color:rgb(100,71,58)']
[style*='background:rgb(233,229,227)'],
.notion-body:not(.dark)
[style*='color: rgb(100, 71, 58); fill: rgb(100, 71, 58);']
[style*='background:rgb(233,229,227)'] {
background: var(--theme--bg_brown) !important;
color: var(--theme--text_brown) !important;
fill: var(--theme--text_brown) !important;
}
.notion-body.dark [style*='background: rgb(67, 64, 64)'],
.notion-body:not(.dark) [style*='background: rgb(233, 229, 227)'] {
background: var(--theme--line_brown) !important;
color: var(--theme--line_brown-text) !important;
}
.notion-body.dark [style*='background: rgba(147, 114, 100, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(140, 46, 0, 0.2)'] {
background: var(--theme--select_brown) !important;
color: var(--theme--select_brown-text) !important;
}
.notion-body.dark [style*='background: rgba(67, 64, 64, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(233, 229, 227, 0.3)'] {
background: var(--theme--callout_brown) !important;
color: var(--theme--callout_brown-text) !important;
}
.notion-body.dark [style*='color:rgb(255,163,68)'],
.notion-body.dark [style*='color: rgb(255, 163, 68); fill: rgb(255, 163, 68);'],
.notion-body:not(.dark) [style*='color:rgb(217,115,13)'],
.notion-body:not(.dark)
[style*='color: rgb(217, 115, 13); fill: rgb(217, 115, 13);'] {
color: var(--theme--text_orange) !important;
fill: var(--theme--text_orange) !important;
}
.notion-body.dark [style*='background:rgb(89,74,58)'],
.notion-body:not(.dark) [style*='background:rgb(250,235,221)'] {
background: var(--theme--bg_orange) !important;
color: var(--theme--bg_orange-text) !important;
}
.notion-body.dark
[style*='color:rgb(255,163,68)']
[style*='background:rgb(89,74,58)'],
.notion-body.dark
[style*='color: rgb(255, 163, 68); fill: rgb(255, 163, 68);']
[style*='background:rgb(89,74,58)'],
.notion-body:not(.dark)
[style*='color:rgb(217,115,13)']
[style*='background:rgb(250,235,221)'],
.notion-body:not(.dark)
[style*='color: rgb(217, 115, 13); fill: rgb(217, 115, 13);']
[style*='background:rgb(250,235,221)'] {
background: var(--theme--bg_orange) !important;
color: var(--theme--text_orange) !important;
fill: var(--theme--text_orange) !important;
}
.notion-body.dark [style*='background: rgb(89, 74, 58)'],
.notion-body:not(.dark) [style*='background: rgb(250, 235, 221)'] {
background: var(--theme--line_orange) !important;
color: var(--theme--line_orange-text) !important;
}
.notion-body.dark [style*='background: rgba(255, 163, 68, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(245, 93, 0, 0.2)'] {
background: var(--theme--select_orange) !important;
color: var(--theme--select_orange-text) !important;
}
.notion-body.dark [style*='background: rgba(89, 74, 58, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(250, 235, 221, 0.3)'] {
background: var(--theme--callout_orange) !important;
color: var(--theme--callout_orange-text) !important;
}
.notion-body.dark [style*='color:rgb(255,220,73)'],
.notion-body.dark [style*='color: rgb(255, 220, 73); fill: rgb(255, 220, 73);'],
.notion-body:not(.dark) [style*='color:rgb(223,171,1)'],
.notion-body:not(.dark)
[style*='color: rgb(223, 171, 1); fill: rgb(223, 171, 1);'] {
color: var(--theme--text_yellow) !important;
fill: var(--theme--text_yellow) !important;
}
.notion-body.dark [style*='background:rgb(89,86,59)'],
.notion-body:not(.dark) [style*='background:rgb(251,243,219)'] {
background: var(--theme--bg_yellow) !important;
color: var(--theme--bg_yellow-text) !important;
}
.notion-body.dark
[style*='color:rgb(255,220,73)']
[style*='background:rgb(89,86,59)'],
.notion-body.dark
[style*='color: rgb(255, 220, 73); fill: rgb(255, 220, 73);']
[style*='background:rgb(89,86,59)'],
.notion-body:not(.dark)
[style*='color:rgb(223,171,1)']
[style*='background:rgb(251,243,219)'],
.notion-body:not(.dark)
[style*='color: rgb(223, 171, 1); fill: rgb(223, 171, 1);']
[style*='background:rgb(251,243,219)'] {
background: var(--theme--bg_yellow) !important;
color: var(--theme--text_yellow) !important;
fill: var(--theme--text_yellow) !important;
}
.notion-body.dark [style*='background: rgb(89, 86, 59)'],
.notion-body:not(.dark) [style*='background: rgb(251, 243, 219)'] {
background: var(--theme--line_yellow) !important;
color: var(--theme--line_yellow-text) !important;
}
.notion-body.dark [style*='background: rgba(255, 220, 73, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(233, 168, 0, 0.2)'] {
background: var(--theme--select_yellow) !important;
color: var(--theme--select_yellow-text) !important;
}
.notion-body.dark [style*='background: rgba(89, 86, 59, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(251, 243, 219, 0.3)'] {
background: var(--theme--callout_yellow) !important;
color: var(--theme--callout_yellow-text) !important;
}
.notion-body.dark [style*='color:rgb(77,171,154)'],
.notion-body.dark [style*='color: rgb(77, 171, 154); fill: rgb(77, 171, 154);'],
.notion-body:not(.dark) [style*='color:rgb(15,123,108)'],
.notion-body:not(.dark)
[style*='color: rgb(15, 123, 108); fill: rgb(15, 123, 108);'] {
color: var(--theme--text_green) !important;
fill: var(--theme--text_green) !important;
}
.notion-body.dark [style*='background:rgb(53,76,75)'],
.notion-body:not(.dark) [style*='background:rgb(221,237,234)'] {
background: var(--theme--bg_green) !important;
color: var(--theme--bg_green-text) !important;
}
.notion-body.dark
[style*='color:rgb(77,171,154)']
[style*='background:rgb(53,76,75)'],
.notion-body.dark
[style*='color: rgb(77, 171, 154); fill: rgb(77, 171, 154);']
[style*='background:rgb(53,76,75)'],
.notion-body:not(.dark)
[style*='color:rgb(15,123,108)']
[style*='background:rgb(221,237,234)'],
.notion-body:not(.dark)
[style*='color: rgb(15, 123, 108); fill: rgb(15, 123, 108);']
[style*='background:rgb(221,237,234)'] {
background: var(--theme--bg_green) !important;
color: var(--theme--text_green) !important;
fill: var(--theme--text_green) !important;
}
.notion-body.dark [style*='background: rgb(53, 76, 75)'],
.notion-body:not(.dark) [style*='background: rgb(221, 237, 234)'] {
background: var(--theme--line_green) !important;
color: var(--theme--line_green-text) !important;
}
.notion-body.dark [style*='background: rgba(77, 171, 154, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(0, 135, 107, 0.2)'] {
background: var(--theme--select_green) !important;
color: var(--theme--select_green-text) !important;
}
.notion-body.dark [style*='background: rgba(53, 76, 75, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(221, 237, 234, 0.3)'] {
background: var(--theme--callout_green) !important;
color: var(--theme--callout_green-text) !important;
}
.notion-body.dark [style*='color:rgb(82,156,202)'],
.notion-body.dark [style*='color: rgb(82, 156, 202); fill: rgb(82, 156, 202);'],
.notion-body:not(.dark) [style*='color:rgb(11,110,153)'],
.notion-body:not(.dark)
[style*='color: rgb(11, 110, 153); fill: rgb(11, 110, 153);'] {
color: var(--theme--text_blue) !important;
fill: var(--theme--text_blue) !important;
}
.notion-body.dark [style*='background:rgb(54,73,84)'],
.notion-body:not(.dark) [style*='background:rgb(221,235,241)'] {
background: var(--theme--bg_blue) !important;
color: var(--theme--bg_blue-text) !important;
}
.notion-body.dark
[style*='color:rgb(82,156,202)']
[style*='background:rgb(54,73,84)'],
.notion-body.dark
[style*='color: rgb(82, 156, 202); fill: rgb(82, 156, 202);']
[style*='background:rgb(54,73,84)'],
.notion-body:not(.dark)
[style*='color:rgb(11,110,153)']
[style*='background:rgb(221,235,241)'],
.notion-body:not(.dark)
[style*='color: rgb(11, 110, 153); fill: rgb(11, 110, 153);']
[style*='background:rgb(221,235,241)'] {
background: var(--theme--bg_blue) !important;
color: var(--theme--text_blue) !important;
fill: var(--theme--text_blue) !important;
}
.notion-body.dark [style*='background: rgb(54, 73, 84)'],
.notion-body:not(.dark) [style*='background: rgb(221, 235, 241)'] {
background: var(--theme--line_blue) !important;
color: var(--theme--line_blue-text) !important;
}
.notion-body.dark [style*='background: rgba(82, 156, 202, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(0, 120, 223, 0.2)'] {
background: var(--theme--select_blue) !important;
color: var(--theme--select_blue-text) !important;
}
.notion-body.dark [style*='background: rgba(54, 73, 84, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(221, 235, 241, 0.3)'] {
background: var(--theme--callout_blue) !important;
color: var(--theme--callout_blue-text) !important;
}
.notion-body.dark [style*='color:rgb(154,109,215)'],
.notion-body.dark
[style*='color: rgb(154, 109, 215); fill: rgb(154, 109, 215);'],
.notion-body:not(.dark) [style*='color:rgb(105,64,165)'],
.notion-body:not(.dark)
[style*='color: rgb(105, 64, 165); fill: rgb(105, 64, 165);'] {
color: var(--theme--text_purple) !important;
fill: var(--theme--text_purple) !important;
}
.notion-body.dark [style*='background:rgb(68,63,87)'],
.notion-body:not(.dark) [style*='background:rgb(234,228,242)'] {
background: var(--theme--bg_purple) !important;
color: var(--theme--bg_purple-text) !important;
}
.notion-body.dark
[style*='color:rgb(154,109,215)']
[style*='background:rgb(68,63,87)'],
.notion-body.dark
[style*='color: rgb(154, 109, 215); fill: rgb(154, 109, 215);']
[style*='background:rgb(68,63,87)'],
.notion-body:not(.dark)
[style*='color:rgb(105,64,165)']
[style*='background:rgb(234,228,242)'],
.notion-body:not(.dark)
[style*='color: rgb(105, 64, 165); fill: rgb(105, 64, 165);']
[style*='background:rgb(234,228,242)'] {
background: var(--theme--bg_purple) !important;
color: var(--theme--text_purple) !important;
fill: var(--theme--text_purple) !important;
}
.notion-body.dark [style*='background: rgb(68, 63, 87)'],
.notion-body:not(.dark) [style*='background: rgb(234, 228, 242)'] {
background: var(--theme--line_purple) !important;
color: var(--theme--line_purple-text) !important;
}
.notion-body.dark [style*='background: rgba(154, 109, 215, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(103, 36, 222, 0.2)'] {
background: var(--theme--select_purple) !important;
color: var(--theme--select_purple-text) !important;
}
.notion-body.dark [style*='background: rgba(68, 63, 87, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(234, 228, 242, 0.3)'] {
background: var(--theme--callout_purple) !important;
color: var(--theme--callout_purple-text) !important;
}
.notion-body.dark [style*='color:rgb(226,85,161)'],
.notion-body.dark [style*='color: rgb(226, 85, 161); fill: rgb(226, 85, 161);'],
.notion-body:not(.dark) [style*='color:rgb(173,26,114)'],
.notion-body:not(.dark)
[style*='color: rgb(173, 26, 114); fill: rgb(173, 26, 114);'] {
color: var(--theme--text_pink) !important;
fill: var(--theme--text_pink) !important;
}
.notion-body.dark [style*='background:rgb(83,59,76)'],
.notion-body:not(.dark) [style*='background:rgb(244,223,235)'] {
background: var(--theme--bg_pink) !important;
color: var(--theme--bg_pink-text) !important;
}
.notion-body.dark
[style*='color:rgb(226,85,161)']
[style*='background:rgb(83,59,76)'],
.notion-body.dark
[style*='color: rgb(226, 85, 161); fill: rgb(226, 85, 161);']
[style*='background:rgb(83,59,76)'],
.notion-body:not(.dark)
[style*='color:rgb(173,26,114)']
[style*='background:rgb(244,223,235)'],
.notion-body:not(.dark)
[style*='color: rgb(173, 26, 114); fill: rgb(173, 26, 114);']
[style*='background:rgb(244,223,235)'] {
background: var(--theme--bg_pink) !important;
color: var(--theme--text_pink) !important;
fill: var(--theme--text_pink) !important;
}
.notion-body.dark [style*='background: rgb(83, 59, 76)'],
.notion-body:not(.dark) [style*='background: rgb(244, 223, 235)'] {
background: var(--theme--line_pink) !important;
color: var(--theme--line_pink-text) !important;
}
.notion-body.dark [style*='background: rgba(226, 85, 161, 0.5)'],
.notion-body:not(.dark) [style*='background: rgba(221, 0, 129, 0.2)'] {
background: var(--theme--select_pink) !important;
color: var(--theme--select_pink-text) !important;
}
.notion-body.dark [style*='background: rgba(83, 59, 76, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(244, 223, 235, 0.3)'] {
background: var(--theme--callout_pink) !important;
color: var(--theme--callout_pink-text) !important;
}
.notion-body.dark [style*='color:rgb(255,115,105)'],
.notion-body.dark
[style*='color: rgb(255, 115, 105); fill: rgb(255, 115, 105);'],
.notion-body:not(.dark) [style*='color:rgb(224,62,62)'],
.notion-body:not(.dark)
[style*='color: rgb(224, 62, 62); fill: rgb(224, 62, 62);'] {
color: var(--theme--text_red) !important;
fill: var(--theme--text_red) !important;
}
.notion-body.dark [style*='background:rgb(89,65,65)'],
.notion-body:not(.dark) [style*='background:rgb(251,228,228)'] {
background: var(--theme--bg_red) !important;
color: var(--theme--bg_red-text) !important;
}
.notion-body.dark
[style*='color:rgb(255,115,105)']
[style*='background:rgb(89,65,65)'],
.notion-body.dark
[style*='color: rgb(255, 115, 105); fill: rgb(255, 115, 105);']
[style*='background:rgb(89,65,65)'],
.notion-body:not(.dark)
[style*='color:rgb(224,62,62)']
[style*='background:rgb(251,228,228)'],
.notion-body:not(.dark)
[style*='color: rgb(224, 62, 62); fill: rgb(224, 62, 62);']
[style*='background:rgb(251,228,228)'] {
background: var(--theme--bg_red) !important;
color: var(--theme--text_red) !important;
fill: var(--theme--text_red) !important;
}
.notion-body.dark [style*='background: rgb(89, 65, 65)'],
.notion-body:not(.dark) [style*='background: rgb(251, 228, 228)'] {
background: var(--theme--line_red) !important;
color: var(--theme--line_red-text) !important;
}
.notion-body.dark [style*='background: rgba(255, 115, 105, 0.5);'],
.notion-body:not(.dark) [style*='background: rgba(255, 0, 26, 0.2)'] {
background: var(--theme--select_red) !important;
color: var(--theme--select_red-text) !important;
}
.notion-body.dark [style*='background: rgba(89, 65, 65, 0.3)'],
.notion-body:not(.dark) [style*='background: rgba(251, 228, 228, 0.3)'] {
background: var(--theme--callout_red) !important;
color: var(--theme--callout_red-text) !important;
}
/* fix highlight padding: this isn't a typo */
[style*='background:rgb('] {
padding-bottom: 3px !important;
}
/** code **/
[style*='color:#EB5757'] {
color: var(--theme--code_inline-text) !important;
background: var(--theme--code_inline-background) !important;
}
.notion-page-content .notion-code-block {
background: var(--theme--code-background) !important;
}
.notion-code-block > div {
color: var(--theme--code-text) !important;
}
.notion-code-block .token.function {
color: var(--theme--code_function) !important;
}
.notion-code-block .token.keyword {
color: var(--theme--code_keyword) !important;
}
.notion-code-block .token.tag {
color: var(--theme--code_tag) !important;
}
.notion-code-block .token.operator {
color: var(--theme--code_operator) !important;
}
.notion-code-block .token.important {
color: var(--theme--code_important) !important;
}
.notion-code-block .token.property {
color: var(--theme--code_property) !important;
}
.notion-code-block .token.builtin {
color: var(--theme--code_builtin) !important;
}
.notion-code-block .token.attr-name {
color: var(--theme--code_attr-name) !important;
}
.notion-code-block .token.attr-value {
color: var(--theme--code_attr-value) !important;
}
.notion-code-block .token.comment {
color: var(--theme--code_comment) !important;
}
.notion-code-block .token.punctuation {
color: var(--theme--code_punctuation) !important;
}
.notion-code-block .token.doctype {
color: var(--theme--code_doctype) !important;
}
.notion-code-block .token.number {
color: var(--theme--code_number) !important;
}
.notion-code-block .token.string {
color: var(--theme--code_string) !important;
}

View File

@ -0,0 +1,48 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* under the MIT license
*/
@import './buttons.css';
.frameless .notion-topbar {
height: calc(var(--configured--dragarea_height, 15px) + 45px) !important;
}
.frameless .window-dragarea {
height: var(--configured--dragarea_height, 15px);
width: 100%;
}
.frameless .window-dragarea {
background: var(--theme--dragarea);
}
.frameless [style*='top: 10.4972px'] {
top: calc(10.4972px + var(--configured--dragarea_height, 15px)) !important;
}
@media (max-width: 760px) {
.frameless .notion-topbar {
height: calc(var(--configured--dragarea_height, 15px) + 80px) !important;
}
.frameless .notion-topbar > :nth-child(2) {
height: 80px !important;
display: grid !important;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}
.window-buttons-area {
grid-row: 1;
grid-column: 9 / span end;
justify-content: flex-end;
}
.notion-topbar-breadcrumb {
grid-row: 2;
grid-column: 1 / span 8;
}
.notion-topbar-actions {
grid-row: 2;
grid-column: 9 / span end;
justify-content: flex-end;
}
}

762
mods/core/enhancerMenu.js Normal file
View File

@ -0,0 +1,762 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
const store = require('../../pkg/store.js'),
{ createElement, getEnhancements } = require('../../pkg/helpers.js'),
fs = require('fs-extra'),
path = require('path'),
electron = require('electron'),
{ toKeyEvent } = require('keyboardevent-from-electron-accelerator');
window['__start'] = async () => {
document.body.setAttribute('data-platform', process.platform);
// mod loader
const modules = getEnhancements();
if (modules.loaded.length) {
console.info(
`<notion-enhancer> enhancements loaded: ${modules.loaded
.map((mod) => mod.name)
.join(', ')}.`
);
}
if (modules.invalid.length) {
createAlert(
'error',
`invalid mods found: ${modules.invalid
.map((mod) => `<b>${mod}</b>`)
.join(', ')}.`
).append();
}
const coreStore = (...args) => {
const mod = modules.loaded.find(
(m) => m.id === '0f0bf8b6-eae6-4273-b307-8fc43f2ee082'
);
return !args.length
? store(mod.id, mod.defaults)
: args.length === 1 && typeof args[0] === 'object'
? store(mod.id, { ...mod.defaults, ...args[0] })
: store(args[0], { ...mod.defaults, ...args[1] });
};
electron.ipcRenderer.send('enhancer:get-app-theme');
electron.ipcRenderer.on('enhancer:set-app-theme', (event, theme) => {
document.body.className = `notion-${theme}-theme`;
});
const buttons = require('./buttons.js')(() => ({
'72886371-dada-49a7-9afc-9f275ecf29d3': {
enabled: (store('mods')['72886371-dada-49a7-9afc-9f275ecf29d3'] || {})
.enabled,
},
tiling_mode: coreStore().tiling_mode,
frameless: coreStore().frameless,
}));
document.querySelector('#titlebar').appendChild(buttons.element);
function createAlert(type, message) {
if (!type)
throw Error('<notion-enhancer> @ createAlert: no alert type specified');
const el = createElement(`
<section class="${type}" role="alert">
<p>${message}</p>
</section>
`);
return {
el,
resolve() {
el.remove();
},
prepend() {
document.querySelector('#alerts').prepend(el);
return this;
},
append() {
document.querySelector('#alerts').appendChild(el);
return this;
},
};
}
// update checker
fetch(
`https://api.github.com/repos/notion-enhancer/notion-enhancer/releases/latest`
)
.then((res) => res.json())
.then((res) => {
const raw_v = require('./mod.js').version,
version = {
local: raw_v.split(/[~-]/g)[0],
repo: res.tag_name.slice(1),
};
if (version.local == version.repo) return;
// compare func from https://github.com/substack/semver-compare
version.sorted = [version.local, version.repo].sort((a, b) => {
const pa = a.split('.'),
pb = b.split('.');
for (let i = 0; i < 3; i++) {
let na = Number(pa[i]),
nb = Number(pb[i]);
if (na > nb) return 1;
if (nb > na) return -1;
if (!isNaN(na) && isNaN(nb)) return 1;
if (isNaN(na) && !isNaN(nb)) return -1;
}
return 0;
});
createAlert(
'warning',
version.sorted[0] == version.local
? `update <b>v${version.repo}</b> available!<br>
run <code>npm i -g notion-enhancer</code>`
: `local build <b>v${raw_v}</b> is unstable.`
).prepend();
});
const $popup = document.querySelector('#popup');
document.addEventListener('keyup', (event) => {
if (event.key === 'F5') location.reload();
// further-configuration popup
if (
$popup.classList.contains('visible') &&
['Enter', 'Escape'].includes(event.key)
)
$popup.classList.remove('visible');
// close window on hotkey toggle
if (coreStore().menu_toggle) {
const hotkey = {
ctrlKey: false,
metaKey: false,
altKey: false,
shiftKey: false,
...toKeyEvent(coreStore().menu_toggle),
};
let triggered = true;
for (let prop in hotkey)
if (
hotkey[prop] !== event[prop] &&
!(prop === 'key' && event[prop] === 'Dead')
)
triggered = false;
if (triggered || ((event.ctrlKey || event.metaKey) && event.key === 'w'))
electron.remote.getCurrentWindow().close();
}
// focus search
const meta =
!(event.ctrlKey || event.metaKey) && !event.altKey && !event.shiftKey;
if (
meta &&
document.activeElement.getAttribute('tabindex') === '0' &&
event.key === 'Enter'
)
document.activeElement.click();
if (document.activeElement.tagName.toLowerCase() === 'input') {
if (document.activeElement.type === 'checkbox' && event.key === 'Enter')
document.activeElement.checked = !document.activeElement.checked;
if (
['Escape', 'Enter'].includes(event.key) &&
document.activeElement.type !== 'checkbox' &&
(document.activeElement.parentElement.id !== 'search' ||
event.key === 'Escape')
)
document.activeElement.blur();
} else if (meta && event.key === '/')
document.querySelector('#search > input').focus();
if (
(event.ctrlKey || event.metaKey) &&
event.key === 'f' &&
!event.altKey &&
!event.shiftKey
)
document.querySelector('#search > input').focus();
});
let colorpicker_target = null;
const $colorpicker = colorjoe
.rgb('colorpicker')
.on('change', function (color) {
if (!colorpicker_target) return;
colorpicker_target.elem.style.setProperty(
'--configured--color-value',
color.css()
);
store(colorpicker_target.id)[colorpicker_target.key] = color.css();
})
.update();
document
.querySelector('#colorpicker')
.appendChild(createElement('<button class="close-modal"></button>'));
document.querySelectorAll('#popup .close-modal').forEach((el) =>
el.addEventListener('click', (event) => {
$popup.classList.remove('visible');
})
);
const conflicts = {
relaunch: null,
detected: () =>
store('mods', {
conflicts: { dark: false, light: false },
}).conflicts,
alerts: [],
check() {
document.body.classList.remove('conflict');
conflicts.alerts.forEach((alert) => alert.resolve());
conflicts.alerts = [];
const enabled = modules.loaded.filter(
(mod) =>
store('mods', { [mod.id]: { enabled: false } })[mod.id].enabled &&
mod.tags.includes('theme')
),
dark = enabled.filter((mod) => mod.tags.includes('dark')),
light = enabled.filter((mod) => mod.tags.includes('light'));
for (let mode of [
[dark, 'dark'],
[light, 'light'],
]) {
const conflictID = mode[0]
.map((mod) => mod.id)
.sort()
.join('||');
if (
conflicts.detected()[mode[1]] &&
conflicts.detected()[mode[1]][0] === conflictID &&
conflicts.detected()[mode[1]][1]
)
continue;
if (mode[0].length > 1) {
document.body.classList.add('conflict');
conflicts.detected()[mode[1]] = [conflictID, false];
const alert = createAlert(
'error',
`conflicting ${mode[1]} themes: ${mode[0]
.map((mod) => `<b>${mod.name}</b>`)
.join(
', '
)}. <br> resolve or <span data-action="dismiss" tabindex="0">dismiss</span> to continue.`
);
alert.el
.querySelector('[data-action="dismiss"]')
.addEventListener('click', (event) => {
conflicts.detected()[mode[1]] = [conflictID, true];
conflicts.check();
});
alert.append();
conflicts.alerts.push(alert);
} else conflicts.detected()[mode[1]] = false;
}
search();
},
};
function modified() {
conflicts.check();
if (conflicts.relaunch) return;
conflicts.relaunch = createAlert(
'info',
'changes may not fully apply until <span data-action="relaunch" tabindex="0">app relaunch</span>.'
);
conflicts.relaunch.el
.querySelector('[data-action="relaunch"]')
.addEventListener('click', (event) => {
electron.remote.app.relaunch();
electron.remote.app.quit();
});
conflicts.relaunch.append();
}
const search_filters = {
enabled: true,
disabled: true,
tags: new Set(
modules.loaded
.map((mod) => mod.tags)
.flat()
.sort()
),
};
function innerText(elem) {
let text = '';
for (let $node of elem.childNodes) {
if ($node.nodeType === 3) text += $node.textContent;
if ($node.nodeType === 1) {
if ($node.getAttribute('data-tooltip'))
text += $node.getAttribute('data-tooltip');
text += ['text', 'number'].includes($node.type)
? $node.value
: innerText($node);
}
}
return text;
}
function search() {
modules.loaded.forEach((mod) => {
const $search_input = document.querySelector('#search > input'),
conflictingIDs = [conflicts.detected().dark, conflicts.detected().light]
.filter((conflict) => conflict && !conflict[1])
.map(([mods, dismissed]) => mods.split('||'))
.flat();
if (
conflictingIDs.length ||
document.body.classList.contains('reorder')
) {
$search_input.disabled = true;
} else $search_input.disabled = false;
if (
!document.body.classList.contains('reorder') &&
(conflictingIDs.length
? !conflictingIDs.some((id) => id.includes(mod.id))
: (mod.elem.classList.contains('enabled') &&
!search_filters.enabled) ||
(mod.elem.classList.contains('disabled') &&
!search_filters.disabled) ||
!mod.tags.some((tag) => search_filters.tags.has(tag)) ||
($search_input.value &&
!innerText(mod.elem)
.toLowerCase()
.includes($search_input.value.toLowerCase().trim())))
)
return (mod.elem.style.display = 'none');
mod.elem.style.display = 'block';
});
}
document.querySelector('#search > input').addEventListener('input', search);
function createTag(tagname, onclick, color) {
if (!tagname)
throw Error('<notion-enhancer> @ createTag: no tagname specified');
if (!onclick)
throw Error('<notion-enhancer> @ createTag: no action specified');
const el = createElement(
`<span class="selected" ${
color ? `style="--tag_color: ${color}" ` : ''
}tabindex="0">${tagname}</span>`
);
document.querySelector('#tags').append(el);
el.addEventListener('click', (event) => {
if (
!document.body.classList.contains('reorder') &&
!document.body.classList.contains('conflict')
) {
el.className = el.className === 'selected' ? '' : 'selected';
onclick(el.className === 'selected');
}
});
return el;
}
createTag('enabled', (state) => [
((search_filters.enabled = state), search()),
]);
createTag('disabled', (state) => [
(search_filters.disabled = state),
search(),
]);
for (let tag of search_filters.tags)
createTag(`#${tag}`, (state) => [
state ? search_filters.tags.add(tag) : search_filters.tags.delete(tag),
search(),
]);
// mod info + options
function markdown(string) {
const parsed = string
.split('\n')
.map((line) =>
line
.trim()
.replace(/\s+/g, ' ')
// > quote
.replace(/^>\s+(.+)$/g, '<blockquote>$1</blockquote>')
// ~~strikethrough~~
.replace(/([^\\])?~~((?:(?!~~).)*[^\\])~~/g, '$1<s>$2</s>')
// __underline__
.replace(/([^\\])?__((?:(?!__).)*[^\\])__/g, '$1<u>$2</u>')
// **bold**
.replace(/([^\\])?\*\*((?:(?!\*\*).)*[^\\])\*\*/g, '$1<b>$2</b>')
// *italic*
.replace(/([^\\])?\*([^*]*[^\\*])\*/g, '$1<i>$2</i>')
// _italic_
.replace(/([^\\])?_([^_]*[^\\_])_/g, '$1<i>$2</i>')
// `code`
.replace(/([^\\])?`([^`]*[^\\`])`/g, '$1<code>$2</code>')
// ![image_title](source)
.replace(
/([^\\])?\!\[([^\]]*[^\\\]]?)\]\(([^)]*[^\\)])\)/g,
`$1<img alt="$2" src="$3" onerror="this.remove()">`
)
// [link](destination)
.replace(
/([^\\])?\[([^\]]*[^\\\]]?)\]\(([^)]*[^\\)])\)/g,
'$1<a href="$3">$2</a>'
)
)
.map((line) =>
line.startsWith('<blockquote>') ? line : `<p>${line}</p>`
)
.join('');
return parsed;
}
const file_icon = await fs.readFile(
path.resolve(`${__dirname}/icons/file.svg`)
),
question_icon = (
await fs.readFile(path.resolve(`${__dirname}/icons/question.svg`))
).toString();
function createOption(opt, id) {
let $opt;
const desc = opt.desc
? question_icon.replace(
'<svg',
`<svg data-tooltip="${opt.desc.replace(/"/g, '&quot;')}"`
)
: '';
switch (opt.type) {
case 'toggle':
$opt = `
<input type="checkbox" id="${opt.type}_${id}--${opt.key}"
${store(id, { [opt.key]: opt.value })[opt.key] ? 'checked' : ''}/>
<label for="${opt.type}_${id}--${opt.key}">
<span class="name">${opt.label}${desc}</span>
<span class="switch"><span class="dot"></span></span>
</label>
`;
break;
case 'select':
$opt = `
<label for="${opt.type}_${id}--${opt.key}">${opt.label}${desc}</label>
<select id="${opt.type}_${id}--${opt.key}">
${opt.value
.map((val) => `<option value="${val}">${val}</option>`)
.join('')}
</select>
`;
break;
case 'input':
$opt = `
<label for="${opt.type}_${id}--${opt.key}">${opt.label}${desc}</label>
<input type="${typeof value === 'number' ? 'number' : 'text'}" id="${
opt.type
}_${id}--${opt.key}">
`;
break;
case 'color':
$opt = `
<label for="${opt.type}_${id}--${opt.key}">${opt.label}${desc}</label>
<input type="button" id="${opt.type}_${id}--${opt.key}">
`;
break;
case 'file':
$opt = `
<input type="file" id="${opt.type}_${id}--${opt.key}"
${
opt.extensions
? ` accept="${opt.extensions
.map((ext) => (ext.startsWith('.') ? ext : `.${ext}`))
.join(',')}"`
: ''
}>
<label for="${opt.type}_${id}--${opt.key}">
<span class="label">
<span class="name">${opt.label}${desc}</span>
<button class="clear"></button>
</span>
<span class="choose">
${file_icon}
<span class="path">${
store(id)[opt.key]
? store(id)[opt.key].split(path.sep).reverse()[0]
: 'choose a file...'
}</span>
</span>
</label>
`;
}
$opt = createElement(`<p class="${opt.type}">${$opt}</p>`);
if (opt.type === 'color') {
$opt
.querySelector(`#${opt.type}_${id}--${opt.key}`)
.style.setProperty(
'--configured--color-value',
store(id, { [opt.key]: opt.value })[opt.key]
);
} else if (opt.type === 'file') {
$opt.querySelector('.clear').addEventListener('click', (event) => {
store(id)[opt.key] = '';
$opt.querySelector('.path').innerText = 'choose a file...';
});
} else {
$opt.querySelector(`#${opt.type}_${id}--${opt.key}`).value = store(id, {
[opt.key]: opt.type === 'select' ? opt.value[0] : opt.value,
})[opt.key];
}
return $opt;
}
const $modules = document.querySelector('#modules'),
fileExists = (file) => fs.pathExistsSync(path.resolve(file));
for (let mod of modules.loaded) {
const enabled =
mod.alwaysActive ||
store('mods', {
[mod.id]: { enabled: false },
})[mod.id].enabled,
author =
typeof mod.author === 'object'
? mod.author
: {
name: mod.author,
link: `https://github.com/${mod.author}`,
avatar: `https://github.com/${mod.author}.png`,
};
if (enabled) {
for (let sheet of ['menu', 'variables']) {
if (fileExists(`${__dirname}/../${mod.dir}/${sheet}.css`)) {
document.head.appendChild(
createElement(
`<link rel="stylesheet" href="enhancement://${mod.dir}/${sheet}.css">`
)
);
}
}
}
mod.elem = createElement(`
<section class="${enabled ? 'enabled' : 'disabled'}${
mod.tags.includes('core') ? ' core' : ''
}" id="${mod.id}">
<div class="meta">
<h3 ${
mod.alwaysActive
? `>${mod.name}`
: `class="toggle">
<input type="checkbox" id="enable_${mod.id}"
${enabled ? 'checked' : ''} />
<label for="enable_${mod.id}">
<span class="name">${mod.name}</span>
<span class="switch"><span class="dot"></span></span>
</label>`
}</h3>
<p class="tags">${mod.tags
.map((tag) => (tag.startsWith('#') ? tag : `#${tag}`))
.join(' ')}</p>
<div class="desc">${markdown(mod.desc)}</div>
<p>
<a href="${author.link}" class="author">
<img src="${author.avatar}" onerror="this.src='./icons/user.png'">
${author.name}
</a>
<span class="version">v${mod.version}</span>
</p>
</div>
${
mod.options && mod.options.length
? '<div class="options"></div>'
: ''
}
</section>
`);
const $enable = mod.elem.querySelector(`#enable_${mod.id}`);
if ($enable)
$enable.addEventListener('click', (event) => {
store('mods', { [mod.id]: { enabled: false } })[mod.id].enabled =
$enable.checked;
mod.elem.className = store('mods', { [mod.id]: { enabled: false } })[
mod.id
].enabled
? 'enabled'
: 'disabled';
if (
$enable.checked &&
coreStore().autoresolve &&
mod.tags.includes('theme')
) {
modules.loaded.forEach((other) => {
const $other_enable = other.elem.querySelector(
`#enable_${other.id}`
);
if (
other !== mod &&
$other_enable &&
$other_enable.checked &&
other.tags.includes('theme')
) {
for (let mode of ['dark', 'light'])
if (other.tags.includes(mode) && mod.tags.includes(mode))
$other_enable.click();
}
});
}
search();
modified();
});
const $options = mod.elem.querySelector('.options');
if ($options)
for (const opt of mod.options) {
if (
Object.keys(opt.platformOverwrite || {}).some(
(platform) => process.platform === platform
)
) {
continue;
}
const $opt = createOption(opt, mod.id);
if (opt.type === 'color') {
const $preview = $opt.querySelector('input');
$opt.addEventListener('click', (event) => {
colorpicker_target = {
id: mod.id,
key: opt.key,
elem: $preview,
};
$colorpicker.set(store(mod.id)[opt.key]);
$popup.classList.add('visible');
});
} else {
$opt
.querySelector(`#${opt.type}_${mod.id}--${opt.key}`)
.addEventListener('change', (event) => {
modified();
if (opt.type === 'toggle') {
store(mod.id)[opt.key] = event.target.checked;
} else if (opt.type === 'file') {
if (event.target.files.length)
store(mod.id)[opt.key] = event.target.files[0].path;
$opt.querySelector('.path').innerText = store(mod.id)[opt.key]
? store(mod.id)[opt.key].split(path.sep).reverse()[0]
: 'choose a file...';
} else
store(mod.id)[opt.key] =
typeof opt.value === 'number'
? +event.target.value
: event.target.value;
});
}
$options.appendChild($opt);
}
if (mod.tags.includes('core')) $modules.append(mod.elem);
}
document
.querySelectorAll('input[type="checkbox"]')
.forEach((checkbox) =>
checkbox.addEventListener('click', (event) => event.target.blur())
);
conflicts.check();
// draggable re-ordering
const draggable = {
state: 0,
tags: ['b', 'span'],
$toggle: document.querySelector('#draggable-toggle'),
list: modules.loaded
.filter((m) => !m.tags.includes('core'))
.map((m) => m.elem),
target: null,
render() {
draggable.target = null;
for (let $node of draggable.list) {
$node.draggable = false;
$modules.append($node);
}
},
mouseover(event) {
if (!draggable.target && event.target.innerText) {
for (let $node of draggable.list) $node.draggable = false;
const $node = draggable.list.find(
(node) => node.innerText === event.target.innerText
);
if ($node) $node.draggable = draggable.state;
}
},
};
document.addEventListener('dragstart', (event) => {
draggable.target = event.target;
event.target.style.opacity = 0.5;
});
document.addEventListener('dragend', (event) => {
event.target.style.opacity = '';
});
document.addEventListener('dragover', (event) => {
event.preventDefault();
document
.querySelectorAll('.dragged-over')
.forEach((el) => el.classList.remove('dragged-over'));
const $node = [
draggable.list[0].previousElementSibling,
...draggable.list,
].find((node) => node.innerText === event.target.innerText);
if ($node) $node.classList.add('dragged-over');
});
document.addEventListener('drop', (event) => {
event.preventDefault();
document
.querySelectorAll('.dragged-over')
.forEach((el) => el.classList.remove('dragged-over'));
if (
draggable.target &&
draggable.target.innerText !== event.target.innerText
) {
const from = draggable.list.findIndex(
(node) => node.innerText === draggable.target.innerText
),
to =
event.target.innerText ===
draggable.list[0].previousElementSibling.innerText
? 0
: draggable.list.findIndex(
(node) => node.innerText === event.target.innerText
) + 1;
if (to >= 0) {
draggable.list.splice(
to > from ? to - 1 : to,
0,
draggable.list.splice(from, 1)[0]
);
store('mods').priority = draggable.list.map((m) => m.id);
}
}
draggable.render();
modified();
});
document.addEventListener('mouseover', draggable.mouseover);
draggable.render();
draggable.$toggle.addEventListener('click', (event) => {
draggable.state = !draggable.state;
draggable.tags = draggable.tags.reverse();
draggable.$toggle.innerHTML = `
<${draggable.tags[0]} data-bolded="configure">configure</${draggable.tags[0]}> |
<${draggable.tags[1]} data-bolded="reorder">reorder</${draggable.tags[1]}>
`;
document.body.classList[draggable.state ? 'add' : 'remove']('reorder');
$modules
.querySelectorAll('input')
.forEach((input) => (input.disabled = draggable.state));
search();
});
const $tooltip = document.querySelector('#tooltip');
document.querySelectorAll('[data-tooltip]').forEach((el) => {
el.addEventListener('mouseenter', (e) => {
$tooltip.innerText = el.getAttribute('data-tooltip');
$tooltip.classList.add('active');
});
el.addEventListener('mouseover', (e) => {
$tooltip.style.top = e.clientY - $tooltip.clientHeight + 'px';
$tooltip.style.left =
e.clientX < window.innerWidth / 2 ? e.clientX + 'px' : '';
$tooltip.style.right =
e.clientX > window.innerWidth / 2
? window.innerWidth - e.clientX + 'px'
: '';
});
el.addEventListener('mouseleave', (e) =>
$tooltip.classList.remove('active')
);
});
};

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" fill="currentColor" viewBox="0 0 250 250"><path d="M124.859 234.52L67.5474 135.736H102.683V12.184H147.323V135.736H182.459L124.859 234.52Z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" fill="currentColor" viewBox="0 0 250 250"><path d="M102.683 234.52V110.968H67.5474L124.859 12.184L182.459 110.968H147.323V234.52H102.683Z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" fill="none" viewBox="0 0 250 250"><line x1="21.393" x2="233.525" y1="229.525" y2="17.393" stroke="#000" stroke-miterlimit="4.139" stroke-width="30"/><line x1="17.607" x2="229.739" y1="17.393" y2="229.525" stroke="#000" stroke-linejoin="round" stroke-width="30"/></svg>

After

Width:  |  Height:  |  Size: 333 B

1
mods/core/icons/file.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"/></svg>

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" fill="currentColor" viewBox="0 0 250 250"><path d="M14.7346 227.26V7.03998H235.215V227.26H14.7346ZM46.4546 195.8H203.495V70.48H46.4546V195.8Z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 235 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" fill="currentColor" viewBox="0 0 250 250"><path d="M16.1311 225.96V76.72H84.5111V8.07999H233.751V157.32H165.371V225.96H16.1311ZM110.771 53.58V76.72H165.371V131.32H207.491V53.58H110.771ZM42.3911 199.96H139.111V122.22H42.3911V199.96Z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 325 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" fill="currentColor" viewBox="0 0 250 250"><path d="M17.8021 138.04V106.072H232.074V138.04H17.8021Z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 192 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z"/></svg>

After

Width:  |  Height:  |  Size: 849 B

BIN
mods/core/icons/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

BIN
mods/core/icons/windows.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

673
mods/core/menu.css Normal file
View File

@ -0,0 +1,673 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
@import './css/buttons.css';
@import './css/scrollbars.css';
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
* {
box-sizing: border-box;
word-break: break-word;
text-decoration: none;
text-size-adjust: 100%;
font-family: var(--theme--font_sans);
outline-color: var(--theme--table-border);
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: block;
overflow: hidden;
background: var(--theme--main);
color: var(--theme--text);
}
main {
padding: 1em 1em 2.9em 1em;
height: 100%;
overflow: auto;
}
main section {
border-radius: 2px;
margin-bottom: 0.75em;
}
/* inline formatting */
code {
border-radius: 0.1em;
padding: 0.2em 0.4em;
font: 0.85em var(--theme--font_code);
background: var(--theme--code_inline-background);
}
button {
color: var(--theme--text);
}
u {
text-decoration: underline;
}
s {
text-decoration: line-through;
}
/* titlebar */
#titlebar::before {
content: '';
position: absolute;
width: 100%;
-webkit-app-region: no-drag;
top: 0;
left: 0;
height: 2px;
}
#titlebar {
display: flex;
-webkit-app-region: drag;
background: var(--theme--dragarea);
}
#titlebar button {
-webkit-app-region: no-drag;
}
#titlebar .window-buttons-area {
margin: 0.4em 0.4em 0.4em auto;
}
#titlebar .window-buttons-area:empty {
display: none;
}
[data-platform='darwin'] #titlebar {
height: 2.65em;
}
/* alerts */
#alerts [role='alert'] {
display: flex;
padding: 0.75em;
background: var(--theme--interactive_hover);
border: 1px solid var(--theme--interactive_hover-border);
}
#alerts [role='alert']::before {
content: '!';
display: block;
/* margin: auto 0; */
font-weight: bold;
font-size: 1.2em;
padding-right: 0.5rem;
color: var(--theme--interactive_hover-border);
}
#alerts [role='alert'] p {
font-size: 1rem;
margin: auto 0;
padding-left: 0.5em;
color: var(--theme--line_text);
}
#alerts .error::before {
color: var(--theme--select_red);
}
#alerts .error {
color: var(--theme--line_red-text);
background: var(--theme--line_red);
border-color: var(--theme--select_red);
}
#alerts .warning::before {
color: var(--theme--select_yellow);
}
#alerts .warning {
color: var(--theme--line_yellow-text);
background: var(--theme--line_yellow);
border-color: var(--theme--select_yellow);
}
#alerts .info::before {
color: var(--theme--select_blue);
}
#alerts .info {
color: var(--theme--line_blue-text);
background: var(--theme--line_blue);
border-color: var(--theme--select_blue);
}
#alerts .success::before {
content: '✓';
color: var(--theme--select_green);
}
#alerts .success {
color: var(--theme--line_green-text);
background: var(--theme--line_green);
border-color: var(--theme--select_green);
}
#alerts code {
background: transparent;
text-decoration: underline;
}
[data-action] {
text-decoration: underline dotted;
cursor: pointer;
}
/* search */
#search {
position: relative;
margin-bottom: 0.75em;
}
#search > svg {
position: absolute;
width: 1em;
height: 1em;
top: 1.3em;
left: 1em;
}
#search > svg path {
fill: var(--theme--text_ui_info);
}
#search > input {
width: 100%;
padding: 1em 1.4em 1em 2.8em;
font: 1em var(--theme--font_sans);
background: var(--theme--card);
border: 1px solid var(--theme--table-border);
color: var(--theme--text);
border-radius: 2px;
}
#search > input::placeholder {
font-weight: bold;
color: var(--theme--text_ui_info);
}
#search > input:focus {
box-shadow: var(--theme--table-border) 0.04em 0.04em,
var(--theme--table-border) -0.04em -0.04em,
var(--theme--table-border) -0.04em 0.04em,
var(--theme--table-border) 0.04em -0.04em;
outline: none;
}
#search #tags > span {
cursor: pointer;
display: inline-block;
font-size: 0.8em;
padding: 0.2em 0.5em;
margin-top: 0.5em;
background: var(--theme--option-background);
color: var(--theme--option-color);
border-radius: 2px;
transition: color 200ms, background 200ms, opacity 200ms;
user-select: none;
}
#search #tags > span:not(:last-child) {
margin-right: 0.5em;
}
#search #tags > span:hover {
background: var(--theme--option_hover-background);
color: var(--theme--option_hover-color);
}
#search #tags > span::before {
content: '× ';
}
#search #tags > .selected {
background: var(--tag_color, var(--theme--option_active-background));
color: var(--theme--option_active-color);
}
#search #tags > .selected::before {
content: '✓ ';
}
/* module meta */
#modules {
position: relative;
}
#modules section {
background: var(--theme--sidebar);
border: 1px solid var(--theme--table-border);
}
#modules section > div {
padding: 0.75em;
}
.notion-light-theme #modules section {
background: var(--theme--main);
}
#modules section h3,
#modules section p {
margin: 0;
font-size: 1rem;
}
#modules section .desc {
margin: 0.3em 0 0.4em 0;
font-size: 0.9em;
}
#modules section .desc p {
font-size: inherit;
margin: 0;
}
#modules section .desc blockquote {
margin: 0.3em 0;
border-left: 0.3em solid var(--theme--table-border);
padding-left: 0.7em;
}
#modules section .desc a {
color: currentColor;
text-decoration: underline dotted;
}
#modules section .desc img {
width: 100%;
max-width: 20em;
margin: 0.5em 0;
}
#modules section .desc :first-child img:first-child {
margin-top: 0;
}
#modules section .desc :last-child img:last-child {
margin-bottom: 0;
}
#modules section .author {
color: currentColor;
}
#modules section .author img {
max-height: 1em;
max-width: 1em;
margin-bottom: 0.15625em;
display: inline-block;
vertical-align: middle;
border-radius: 50%;
}
#modules section .tags,
#modules section .version {
font-size: 0.85em;
color: var(--theme--text_ui);
}
/* module options */
#modules .disabled .options {
display: none;
}
#modules section .options {
border-top: 1px solid var(--theme--table-border);
background: var(--theme--card);
}
#modules section .options p {
font-size: 0.9em;
}
#modules section .options p:not(:last-child) {
padding-bottom: 0.5em;
border-bottom: 0.5px solid var(--theme--table-border);
margin-bottom: 0.5em;
}
svg[data-tooltip] {
height: 1em;
width: 1em;
margin: 0 0 -2px 1px;
color: var(--theme--text_ui_info);
}
#tooltip {
pointer-events: none;
position: absolute;
padding: 0.25em 0.5em 0.5em 0.5em;
margin: 0 1em;
border-radius: 3px;
box-shadow: var(--theme--box-shadow_strong);
border-right-width: 1px;
font-size: calc(var(--theme--font_label-size) * 0.8);
background: var(--theme--interactive_hover);
opacity: 0;
transition: opacity 120ms ease-in;
}
#tooltip.active {
opacity: 1;
}
.toggle *,
.input *,
.select *,
.color *,
.file * {
cursor: pointer;
}
.select select,
.input input[type='text'],
.input input[type='number'],
.file input[type='file'] + label .choose {
width: 100%;
margin: 0.25em 0;
font-size: 0.9rem;
padding: 0.4rem 0.2rem;
border: none;
color: var(--theme--text);
background: var(--theme--main);
}
.select select:focus,
.input input[type='text']:focus,
.input input[type='number']:focus,
.file input[type='file']:focus + label .choose,
.file input[type='file'] + label .choose:hover {
outline: var(--theme--table-border) solid 2px;
}
.file input[type='file'],
.toggle input[type='checkbox'] {
opacity: 0;
width: 0.1px;
height: 0.1px;
position: fixed;
}
.input input[type='text'],
.input input[type='number'] {
padding: 0.4rem;
cursor: text;
}
.file input[type='file'] + label .label {
position: relative;
display: flex;
}
.file input[type='file'] + label .label .name {
flex-basis: calc(100% - 1.5rem);
}
.file input[type='file'] + label .label .clear {
font-size: 1rem;
position: absolute;
top: 0.4em;
right: 0;
width: 1em;
height: 0.1em;
border: 0.35em solid var(--theme--card);
background: currentColor;
}
.file input[type='file'] + label .choose {
display: block;
white-space: nowrap;
overflow: hidden;
}
.file input[type='file'] + label .choose svg {
padding-top: 0.5em;
height: 1.25em;
width: 1.25em;
}
.toggle input[type='checkbox'] + label {
display: flex;
}
.toggle input[type='checkbox'] + label .name {
flex-basis: calc(100% - 2.25em);
margin-right: 0.75em;
}
.toggle input[type='checkbox'] + label .switch {
position: relative;
margin-top: 0.5em;
float: right;
height: 0.65em;
width: 2em;
background: var(--theme--main);
border-radius: 5px;
transition: background 300ms;
}
.toggle input[type='checkbox'] + label .switch::before {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border-radius: inherit;
background: linear-gradient(
90deg,
var(--theme--primary),
var(--theme--primary_click)
);
opacity: var(--menu--toggle_opacity, 0);
transition: opacity 300ms;
}
.toggle input[type='checkbox'] + label .switch .dot {
position: absolute;
width: 1em;
height: 1em;
top: -0.15em;
border-radius: 50%;
transform: translateX(var(--menu--toggle_offset, 0));
transition: transform 350ms, box-shadow 350ms;
background: var(--theme--option_active-color);
/* box-shadow: 2px 1px 4px var(--theme--table-border); */
}
.toggle input[type='checkbox']:checked:focus + label .switch {
background: none !important;
}
.toggle input[type='checkbox']:focus + label .switch::before,
.toggle input[type='checkbox']:focus + label .switch .dot {
border: 1px solid var(--theme--table-border);
}
.toggle input[type='checkbox']:checked + label {
--menu--toggle_offset: 1em;
--menu--toggle_opacity: 1;
}
.color {
display: flex;
}
.color label {
flex-basis: 70%;
}
.color input[type='button'] {
flex-basis: 30%;
box-shadow: 2px 1px 4px var(--theme--table-border);
border: 1px solid var(--theme--option_active-color);
border-radius: 3px;
background: var(--configured--color-value);
margin: 0;
}
.color input[type='button']:focus {
box-shadow: 3px 2px 5px var(--theme--table-border);
}
/* further-configuration popup */
#popup,
#popup-overlay {
position: absolute;
top: 0;
height: 100vh;
width: 100vw;
}
#popup {
display: none;
}
#popup.visible {
display: flex;
animation: fade 200ms ease;
}
#popup-overlay {
background: var(--theme--overlay);
}
.colorPicker {
margin: auto;
position: relative;
border: 1px solid var(--theme--table-border);
background: var(--theme--card);
}
.colorPicker .twod {
border-radius: 4px;
}
.colorPicker .twod .bg {
border-radius: 2px;
}
.colorPicker .oned,
.colorPicker .oned .bg {
margin-left: 0;
height: 212.5px;
}
.colorPicker .oned .bg {
border-radius: 4px;
border: 1px solid var(--theme--table-border);
}
.colorPicker > button {
display: block;
position: absolute;
bottom: 8px;
right: 8px;
margin: 0;
padding: 0;
border: none;
width: 21px;
height: 20px;
cursor: pointer;
background: transparent;
transition: background 0.2s;
}
.colorPicker > button::after {
content: '×';
font-size: 1.5em;
position: relative;
bottom: 5px;
}
.colorPicker > button:hover {
background: var(--theme--interactive_hover);
border-radius: 4px;
box-shadow: 0 0 0 0.5px var(--theme--interactive_hover-border);
}
.colorPicker > button:focus {
outline: none;
box-shadow: 0 0 0 1px var(--theme--table-border);
}
.colorPicker .twod .pointer .shape.shape1 {
width: 11px;
height: 11px;
}
.colorPicker .twod .pointer .shape.shape2 {
width: 9px;
height: 9px;
}
.colorPicker .oned .pointer .shape {
height: 6.5px;
margin-left: 0;
border: 2px solid #fff;
box-shadow: 0 0 0 1px #000;
}
.shape {
cursor: pointer;
}
@media (max-width: 300px) {
.colorPicker .twod,
.colorPicker .twod .bg {
width: 200px;
height: 200px;
}
.colorPicker .oned,
.colorPicker .oned .bg {
height: 172.5px;
}
}
@media (max-width: 250px) {
.colorPicker .twod,
.colorPicker .twod .bg {
width: 150px;
height: 150px;
}
.colorPicker .oned,
.colorPicker .oned .bg {
height: 132.5px;
}
}
/* draggable re-ordering of mods */
#draggable-toggle {
background: none;
border: none;
margin-top: 0.8em;
padding-left: 0;
cursor: pointer;
color: var(--theme--text_ui);
}
[data-bolded] {
display: inline-flex;
flex-direction: column;
}
[data-bolded]::after {
content: attr(data-bolded);
height: 0;
visibility: hidden;
overflow: hidden;
user-select: none;
pointer-events: none;
font-weight: bold;
}
.reorder #search #tags > span,
.reorder #search #tags > span:hover,
.conflict #search #tags > span,
.conflict #search #tags > span:hover {
opacity: 0.7;
background: var(--theme--option-background);
}
.reorder #search #tags > .selected,
.reorder #search #tags > .selected:hover,
.conflict #search #tags > .selected,
.conflict #search #tags > .selected:hover {
background: var(--tag_color, var(--theme--option_active-background));
}
.reorder #modules .dragged-over::after {
content: '';
height: 0.25em;
width: 99%;
position: absolute;
margin: 0.3em 0;
opacity: 0.7;
background: var(--theme--selected);
}
.reorder #modules .switch,
.reorder #modules .tags,
.reorder #modules .desc,
.reorder #modules .options,
.reorder #modules .author,
.reorder #modules .version {
display: none;
}
.reorder #modules .core .toggle * {
cursor: text;
}
.reorder #modules section:not(.core) label::before {
content: '::';
margin-right: 0.4em;
color: var(--theme--text_ui);
}

43
mods/core/menu.html Normal file
View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html data-tweaks="[smooth_scrollbars]" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>notion-enhancer menu</title>
<script src="./colorjoe/min.js"></script>
<link rel="stylesheet" href="./colorjoe/picker.css" />
<style>
body {
display: none;
}
</style>
</head>
<body class="notion-dark-theme">
<header id="titlebar"></header>
<main>
<div id="alerts"></div>
<div id="search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
></path>
</svg>
<input type="text" placeholder="search ('/' to focus)" />
<div id="tags"></div>
<button id="draggable-toggle">
<b data-bolded="configure">configure</b> |
<span data-bolded="reorder">reorder</span>
</button>
</div>
<div id="modules"></div>
</main>
<section id="popup">
<div id="popup-overlay" class="close-modal"></div>
<div id="colorpicker"></div>
</section>
<span id="tooltip"></span>
<script>
window['__start']();
</script>
</body>
</html>

103
mods/core/mod.js Normal file
View File

@ -0,0 +1,103 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: '0f0bf8b6-eae6-4273-b307-8fc43f2ee082',
alwaysActive: true,
tags: ['core'],
name: 'notion-enhancer core',
desc: 'the cli, modloader, menu, & tray.',
version: require('../../package.json').version,
author: 'dragonwocky',
options: [
{
key: 'autoresolve',
label: 'auto-resolve theme conflicts',
desc:
'when a theme is enabled any other themes of the same mode (light/dark) will be disabled.',
type: 'toggle',
value: false,
},
{
key: 'openhidden',
label: 'hide app on open',
desc:
'app can be made visible by clicking the tray icon or using the hotkey.',
type: 'toggle',
value: false,
},
{
key: 'maximized',
label: 'auto-maximise windows',
desc:
'whenever a window is un-hidden or is created it will be maximised.',
type: 'toggle',
value: false,
},
{
key: 'close_to_tray',
label: 'close window to the tray',
desc: `pressing the × close button will hide the app instead of quitting it.\
it can be re-shown by clicking the tray icon or using the hotkey.`,
type: 'toggle',
value: true,
platformOverwrite: {
darwin: true,
},
},
{
key: 'frameless',
label: 'integrated titlebar',
desc: `replace the native titlebar with buttons inset into the app.`,
type: 'toggle',
value: true,
platformOverwrite: {
darwin: false,
},
},
{
key: 'tiling_mode',
label: 'tiling window manager mode',
desc: `completely remove the close/minimise/maximise buttons -
this is for a special type of window manager. if you don't understand it, don't use it.`,
type: 'toggle',
value: false,
},
{
key: 'hotkey',
label: 'window display hotkey:',
desc: 'used to toggle hiding/showing all app windows.',
type: 'input',
value: 'CommandOrControl+Shift+A',
},
{
key: 'menu_toggle',
label: 'open enhancements menu hotkey:',
desc: 'used to toggle opening/closing this menu while notion is focused.',
type: 'input',
value: 'Alt+E',
},
{
key: 'default_page',
label: 'default page id/url:',
desc: `every new tab/window that isn't opening a url via the notion://\
protocol will load this page. to get a page link from within the app,\
go to the triple-dot menu and click "copy link".\
leave blank to just load the last page you opened.`,
type: 'input',
value: '',
},
],
hacks: {
'main/main.js': require('./tray.js'),
'main/systemMenu.js': require('./systemMenu.js'),
'main/createWindow.js': require('./createWindow.js'),
'renderer/index.js': require('./render.js'),
'renderer/preload.js': require('./client.js'),
},
};

1068
mods/core/render.js Normal file

File diff suppressed because it is too large Load Diff

476
mods/core/systemMenu.js Normal file
View File

@ -0,0 +1,476 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = (store, __exports) => {
const electron = require('electron'),
fs = require('fs-extra'),
{ __notion } = require('../../pkg/helpers.js'),
createWindow = require(`${__notion}/app/main/createWindow.js`),
config = require(`${__notion}/app/config.js`),
notion_intl = require(`${__notion}/app/shared/notion-intl/index.js`),
localizationHelper = require(`${__notion}/app/helpers/localizationHelper.js`),
isMac = process.platform === 'darwin',
// why is it inversed? i have no idea, but for some reason this is what works
tabsEnabled = !(store('mods')['e1692c29-475e-437b-b7ff-3eee872e1a42'] || {})
.enabled,
menuMessages = notion_intl.defineMessages({
fileMenuTitle: {
id: 'desktopTopbar.fileMenu.title',
defaultMessage: 'File',
},
editMenuTitle: {
id: 'desktopTopbar.editMenu.title',
defaultMessage: 'Edit',
},
viewMenuTitle: {
id: 'desktopTopbar.viewMenu.title',
defaultMessage: 'View',
},
windowMenuTitle: {
id: 'desktopTopbar.windowMenu.title',
defaultMessage: 'Window',
},
helpTitle: {
id: 'desktopTopbar.helpMenu.title',
defaultMessage: 'Help',
},
newWindow: {
id: 'desktopTopbar.fileMenu.newWindow',
defaultMessage: 'New Window',
},
closeWindow: {
id: 'desktopTopbar.fileMenu.close',
defaultMessage: 'Close Window',
},
quit: {
id: 'desktopTopbar.fileMenu.quit',
defaultMessage: 'Exit',
},
undo: {
id: 'desktopTopbar.editMenu.undo',
defaultMessage: 'Undo',
},
redo: {
id: 'desktopTopbar.editMenu.redo',
defaultMessage: 'Redo',
},
cut: {
id: 'desktopTopbar.editMenu.cut',
defaultMessage: 'Cut',
},
copy: {
id: 'desktopTopbar.editMenu.copy',
defaultMessage: 'Copy',
},
paste: {
id: 'desktopTopbar.editMenu.paste',
defaultMessage: 'Paste',
},
selectAll: {
id: 'desktopTopbar.editMenu.selectAll',
defaultMessage: 'Select All',
},
startSpeaking: {
id: 'desktopTopbar.editMenu.speech.startSpeaking',
defaultMessage: 'Start Speaking',
},
stopSpeaking: {
id: 'desktopTopbar.editMenu.speech.stopSpeaking',
defaultMessage: 'Stop Speaking',
},
speech: {
id: 'desktopTopbar.editMenu.speech',
defaultMessage: 'Speech',
},
reload: {
id: 'desktopTopbar.viewMenu.reload',
defaultMessage: 'Reload',
},
togglefullscreen: {
id: 'desktopTopbar.viewMenu.togglefullscreen',
defaultMessage: 'Toggle Full Screen',
},
toggleDevTools: {
id: 'desktopTopbar.toggleDevTools',
defaultMessage: 'Toggle Developer Tools',
},
toggleWindowDevTools: {
id: 'desktopTopbar.toggleWindowDevTools',
defaultMessage: 'Toggle Window Developer Tools',
},
maximize: {
id: 'desktopTopbar.windowMenu.maximize',
defaultMessage: 'Maximize',
},
minimize: {
id: 'desktopTopbar.windowMenu.minimize',
defaultMessage: 'Minimize',
},
zoom: {
id: 'desktopTopbar.windowMenu.zoom',
defaultMessage: 'Zoom',
},
front: {
id: 'desktopTopbar.windowMenu.front',
defaultMessage: 'Front',
},
close: {
id: 'desktopTopbar.windowMenu.close',
defaultMessage: 'Close',
},
help: {
id: 'desktopTopbar.helpMenu.openHelpAndSupport',
defaultMessage: 'Open Help & Support',
},
reset: {
id: 'desktopTopbar.appMenu.resetAppAndClearData',
defaultMessage: 'Reset App & Clear Local Data',
},
about: {
id: 'desktopTopbar.appMenu.about',
defaultMessage: 'About Notion',
},
services: {
id: 'desktopTopbar.appMenu.services',
defaultMessage: 'Services',
},
hide: { id: 'desktopTopbar.appMenu.hide', defaultMessage: 'Hide Notion' },
hideOthers: {
id: 'desktopTopbar.appMenu.hideOthers',
defaultMessage: 'Hide Others',
},
unhide: {
id: 'desktopTopbar.appMenu.unhide',
defaultMessage: 'Show All',
},
quitMac: { id: 'desktopTopbar.appMenu.quit', defaultMessage: 'Quit' },
}),
escapeAmpersand = (message) => message.replace(/&/g, '&&');
__exports.setupSystemMenu = (locale) => {
const intl = localizationHelper.createIntlShape(locale),
fileMenu = {
role: 'fileMenu',
label: escapeAmpersand(intl.formatMessage(menuMessages.fileMenuTitle)),
submenu: isMac
? [
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.newWindow)
),
accelerator: 'CmdOrCtrl+Shift+N',
click: () => createWindow.createWindow(),
},
...(tabsEnabled
? [
{
role: 'close',
label: escapeAmpersand(
intl.formatMessage(menuMessages.closeWindow)
),
},
]
: []),
]
: [
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.newWindow)
),
accelerator: 'CmdOrCtrl+Shift+N',
click: () => createWindow.createWindow(),
},
...(tabsEnabled
? [
{
role: 'quit',
label: escapeAmpersand(
intl.formatMessage(menuMessages.quit)
),
},
]
: []),
],
},
editMenu = {
role: 'editMenu',
label: escapeAmpersand(intl.formatMessage(menuMessages.editMenuTitle)),
submenu: isMac
? [
{
role: 'undo',
label: escapeAmpersand(intl.formatMessage(menuMessages.undo)),
},
{
role: 'redo',
label: escapeAmpersand(intl.formatMessage(menuMessages.redo)),
},
{ type: 'separator' },
{
role: 'cut',
label: escapeAmpersand(intl.formatMessage(menuMessages.cut)),
},
{
role: 'copy',
label: escapeAmpersand(intl.formatMessage(menuMessages.copy)),
},
{
role: 'paste',
label: escapeAmpersand(intl.formatMessage(menuMessages.paste)),
},
{
role: 'selectAll',
label: escapeAmpersand(
intl.formatMessage(menuMessages.selectAll)
),
},
{ type: 'separator' },
{
label: escapeAmpersand(intl.formatMessage(menuMessages.speech)),
submenu: [
{
role: 'startSpeaking',
label: escapeAmpersand(
intl.formatMessage(menuMessages.startSpeaking)
),
},
{
role: 'stopSpeaking',
label: escapeAmpersand(
intl.formatMessage(menuMessages.stopSpeaking)
),
},
],
},
]
: [
{
role: 'undo',
label: escapeAmpersand(intl.formatMessage(menuMessages.undo)),
},
{
role: 'redo',
label: escapeAmpersand(intl.formatMessage(menuMessages.redo)),
},
{ type: 'separator' },
{
role: 'cut',
label: escapeAmpersand(intl.formatMessage(menuMessages.cut)),
},
{
role: 'copy',
label: escapeAmpersand(intl.formatMessage(menuMessages.copy)),
},
{
role: 'paste',
label: escapeAmpersand(intl.formatMessage(menuMessages.paste)),
},
{ type: 'separator' },
{
role: 'selectAll',
label: escapeAmpersand(
intl.formatMessage(menuMessages.selectAll)
),
},
],
},
viewMenu = {
role: 'viewMenu',
label: escapeAmpersand(intl.formatMessage(menuMessages.viewMenuTitle)),
submenu: [
{
label: escapeAmpersand(intl.formatMessage(menuMessages.reload)),
accelerator: 'CmdOrCtrl+R',
click() {
const focusedWebContents = electron.webContents.getFocusedWebContents();
if (focusedWebContents) {
if (focusedWebContents.hostWebContents) {
for (const webContentsInstance of electron.webContents.getAllWebContents()) {
if (
webContentsInstance.hostWebContents ===
focusedWebContents.hostWebContents
) {
webContentsInstance.reload();
}
}
} else {
focusedWebContents.reload();
}
}
},
},
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.toggleDevTools)
),
accelerator: isMac ? 'Alt+Command+I' : 'Ctrl+Shift+I',
click() {
let focusedWebContents = electron.webContents.getFocusedWebContents();
if (focusedWebContents) {
const focusedWebContentsUrl = focusedWebContents.getURL();
if (
focusedWebContentsUrl.startsWith('file://') &&
focusedWebContentsUrl.endsWith('/search.html')
) {
const notionWebviewWebContents = electron.webContents
.getAllWebContents()
.find(
(webContentsInstance) =>
webContentsInstance.hostWebContents ===
focusedWebContents.hostWebContents &&
webContentsInstance !== focusedWebContents
);
if (notionWebviewWebContents) {
focusedWebContents = notionWebviewWebContents;
}
}
focusedWebContents.toggleDevTools();
}
},
},
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.toggleWindowDevTools)
),
accelerator: isMac ? 'Shift+Alt+Command+I' : 'Alt+Ctrl+Shift+I',
visible: false,
click(menuItem, focusedWindow) {
if (focusedWindow) {
focusedWindow.webContents.toggleDevTools();
}
},
},
{ type: 'separator' },
{
role: 'togglefullscreen',
label: escapeAmpersand(
intl.formatMessage(menuMessages.togglefullscreen)
),
},
],
},
windowMenu = {
role: 'windowMenu',
label: escapeAmpersand(
intl.formatMessage(menuMessages.windowMenuTitle)
),
submenu: isMac
? [
{
role: 'minimize',
label: escapeAmpersand(
intl.formatMessage(menuMessages.minimize)
),
},
{
role: 'zoom',
label: escapeAmpersand(intl.formatMessage(menuMessages.zoom)),
},
{ type: 'separator' },
{
role: 'front',
label: escapeAmpersand(intl.formatMessage(menuMessages.front)),
},
]
: [
{
role: 'minimize',
label: escapeAmpersand(
intl.formatMessage(menuMessages.minimize)
),
},
{
label: escapeAmpersand(
intl.formatMessage(menuMessages.maximize)
),
click(item, focusedWindow) {
if (focusedWindow) {
if (focusedWindow.isMaximized()) {
focusedWindow.unmaximize();
} else {
focusedWindow.maximize();
}
}
},
},
...(tabsEnabled
? [
{
role: 'close',
label: escapeAmpersand(
intl.formatMessage(menuMessages.close)
),
},
]
: []),
],
},
helpMenu = {
role: 'help',
label: escapeAmpersand(intl.formatMessage(menuMessages.helpTitle)),
submenu: [
{
label: escapeAmpersand(intl.formatMessage(menuMessages.help)),
click() {
electron.shell.openExternal(config.default.baseURL + '/help');
},
},
],
},
appMenu = {
role: 'appMenu',
submenu: [
{
role: 'about',
label: escapeAmpersand(intl.formatMessage(menuMessages.about)),
},
{ type: 'separator' },
{
label: escapeAmpersand(intl.formatMessage(menuMessages.reset)),
async click(item, focusedWindow) {
await fs.remove(electron.app.getPath('userData'));
electron.app.relaunch();
electron.app.exit();
},
},
{ type: 'separator' },
{
role: 'services',
label: escapeAmpersand(intl.formatMessage(menuMessages.services)),
},
{ type: 'separator' },
{
role: 'hide',
label: escapeAmpersand(intl.formatMessage(menuMessages.hide)),
},
{
role: 'hideOthers',
label: escapeAmpersand(intl.formatMessage(menuMessages.hideOthers)),
},
{
role: 'unhide',
label: escapeAmpersand(intl.formatMessage(menuMessages.unhide)),
},
...(tabsEnabled
? [
{ type: 'separator' },
{
role: 'quit',
label: escapeAmpersand(
intl.formatMessage(menuMessages.quitMac)
),
},
]
: []),
],
},
template = [fileMenu, editMenu, viewMenu, windowMenu, helpMenu];
if (isMac) template.unshift(appMenu);
const menu = electron.Menu.buildFromTemplate(template);
electron.Menu.setApplicationMenu(menu);
};
};

196
mods/core/tabs.css Normal file
View File

@ -0,0 +1,196 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
@import './css/buttons.css';
* {
box-sizing: border-box;
word-break: break-word;
text-decoration: none;
text-size-adjust: 100%;
font-family: var(--theme--font_sans) !important;
outline-color: var(--theme--table-border);
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes tabSlide {
from {
width: 0;
}
to {
width: 8.5em;
}
}
body:not(.error)::after {
z-index: 1;
content: '';
position: absolute;
left: calc(50% - 15px);
top: calc(50% + 10px);
width: 18px;
height: 18px;
opacity: 0.5;
border: 4px solid var(--theme--text);
border-top-color: transparent;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
html,
body,
#root {
background: var(--theme--main) !important;
position: relative;
height: 100%;
margin: 0;
}
#root {
display: flex;
flex-direction: column;
}
[data-platform='darwin'] #titlebar {
padding-left: 4em;
}
#titlebar::before {
content: '';
position: absolute;
width: 100%;
-webkit-app-region: no-drag;
top: 0;
left: 0;
height: 2px;
}
#titlebar {
display: flex;
flex-shrink: 1;
user-select: none;
-webkit-app-region: drag;
background: var(--theme--dragarea);
}
#titlebar button {
color: var(--theme--text);
-webkit-app-region: no-drag;
border: none;
background: transparent;
}
#titlebar .window-buttons-area {
margin: 0.5em 0.55em 0.5em auto;
}
#titlebar .window-buttons-area:empty {
display: none;
}
#open-enhancer-menu::before {
content: '';
height: 1.25em;
width: 1.25em;
display: inline-block;
margin: auto 1em -0.25em 1em;
background-size: contain;
background-image: url('enhancement://core/icons/mac+linux.png');
background-repeat: no-repeat;
}
#tabs {
margin-top: auto;
flex-wrap: wrap;
display: flex;
align-items: center;
}
#tabs .tab:not(.new):not(.current) {
flex: 1 1 30px;
min-width: 30px;
}
#tabs button:nth-child(16) {
display: none;
opacity: 0;
}
#tabs .tab {
display: inline-flex;
background: var(--theme--main);
border: none;
font-size: 1.15em;
padding: 0.2em 0.4em;
text-align: left;
border-bottom: 0.22em solid var(--theme--table-border);
opacity: 0.8;
}
#tabs .tab img {
object-fit: cover;
height: 1em;
width: 1em;
border-radius: 3px;
margin: 0 0.5em -0.16em 0.1em;
}
#tabs .tab:not(.new) {
margin-top: 0.5em;
}
#tabs .tab:not(.new) span:not(.close) {
width: 8.5em;
margin-right: 0.22em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#tabs .tab.slideIn span:not(.close) {
animation: tabSlide 100ms ease-in-out;
}
#tabs .tab.slideOut {
width: 0;
animation: tabSlide 100ms ease-in-out reverse;
}
#tabs .tab .close {
padding: 0 0.35em 0.1em 0.3em;
margin-left: auto;
font-weight: bold;
}
#tabs .tab.current {
opacity: 1;
background: var(--theme--selected);
border-bottom: 0.22em solid var(--theme--option_active-background);
}
#tabs .tab.new {
background: none;
border: none;
margin-left: -0.1em;
margin-top: 0.3em;
}
#tabs .tab.new span {
padding: 0 0.35em 0.1em 0.3em;
font-weight: bold;
}
#tabs .tab:hover {
opacity: 1;
}
#tabs .tab .close:hover,
#tabs .tab.new span:hover,
#titlebar .window-button:hover {
border-radius: 0.22em;
background: var(--theme--table-border);
box-shadow: 0 0 0 0.5px var(--theme--interactive_hover-border);
}
#titlebar .window-button.btn-close:hover {
background: var(--theme--button_close);
color: var(--theme--button_close-fill);
}
#tabs .tab.dragged-over {
box-shadow: inset 0.22em 0 0 0 var(--theme--selected);
}
.notion {
z-index: 2;
width: 100%;
height: 100%;
display: none;
}

258
mods/core/tray.js Normal file
View File

@ -0,0 +1,258 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* under the MIT license
*/
'use strict';
let tray, enhancer_menu;
module.exports = (store, __exports) => {
const electron = require('electron'),
path = require('path'),
is_mac = process.platform === 'darwin',
is_win = process.platform === 'win32',
helpers = require('../../pkg/helpers.js'),
getAllWindows = electron.BrowserWindow.getAllWindows;
function newWindow() {
require('./createWindow.js')(
store,
require(path.resolve(`${helpers.__notion}/app/main/createWindow.js`))
)(
'',
getAllWindows().find((win) => win !== enhancer_menu)
);
}
electron.app.on('second-instance', (event, args, workingDirectory) => {
const windows = getAllWindows();
if (windows.some((win) => win.isVisible())) {
newWindow();
} else {
windows.forEach((window) => {
window.show();
window.focus();
if (store().maximized) window.maximize();
});
}
});
electron.app.once('ready', () => {
// tray
tray = new electron.Tray(
is_win
? path.resolve(`${__dirname}/icons/windows.ico`)
: new electron.nativeImage.createFromPath(
path.resolve(`${__dirname}/icons/mac+linux.png`)
).resize({
width: 16,
height: 16,
})
);
// menu
electron.ipcMain.on('enhancer:open-menu', openEnhancerMenu);
electron.ipcMain.on('enhancer:set-app-theme', (event, arg) => {
electron.webContents
.getAllWebContents()
.forEach((webContents) =>
webContents.send('enhancer:set-app-theme', arg)
);
});
electron.ipcMain.on('enhancer:get-app-theme', (event, arg) => {
electron.webContents
.getAllWebContents()
.forEach((webContents) =>
webContents.send('enhancer:get-app-theme', arg)
);
});
electron.ipcMain.on('enhancer:close-tab', (event, target, tab) => {
electron.webContents
.fromId(target)
.webContents.send('enhancer:close-tab', tab);
});
function calculateWindowPos(width, height) {
const screen = electron.screen.getDisplayNearestPoint({
x: tray.getBounds().x,
y: tray.getBounds().y,
});
// left
if (screen.workArea.x > 0)
return {
x: screen.workArea.x,
y: screen.workArea.height - height,
};
// top
if (screen.workArea.y > 0)
return {
x: Math.round(
tray.getBounds().x + tray.getBounds().width / 2 - width / 2
),
y: screen.workArea.y,
};
// right
if (screen.workArea.width < screen.bounds.width)
return {
x: screen.workArea.width - width,
y: screen.bounds.height - height,
};
// bottom
return {
x: Math.round(
tray.getBounds().x + tray.getBounds().width / 2 - width / 2
),
y: screen.workArea.height - height,
};
}
function openEnhancerMenu() {
if (enhancer_menu) return enhancer_menu.show();
const window_state = require(`${helpers.__notion.replace(
/\\/g,
'/'
)}/app/node_modules/electron-window-state/index.js`)({
file: 'menu.windowstate.json',
path: helpers.__data,
defaultWidth: 275,
defaultHeight: 600,
});
electron.shell.openExternal(JSON.stringify(window_state));
enhancer_menu = new electron.BrowserWindow({
show: true,
frame: !store().frameless,
titleBarStyle: 'hiddenInset',
x:
window_state.x ||
calculateWindowPos(window_state.width, window_state.height).x,
y:
window_state.y ||
calculateWindowPos(window_state.width, window_state.height).y,
width: window_state.width,
height: window_state.height,
webPreferences: {
preload: path.resolve(`${__dirname}/enhancerMenu.js`),
nodeIntegration: true,
session: electron.session.fromPartition('persist:notion'),
},
});
enhancer_menu.loadURL('enhancement://core/menu.html');
enhancer_menu.on('close', (e) => {
window_state.saveState(enhancer_menu);
enhancer_menu = null;
});
// enhancer_menu.webContents.openDevTools();
}
// tray
const contextMenu = electron.Menu.buildFromTemplate([
{
type: 'normal',
label: 'GitHub',
click: () => {
electron.shell.openExternal(
'https://github.com/notion-enhancer/notion-enhancer/blob/master/DOCUMENTATION.md'
);
},
},
{
type: 'normal',
label: 'Discord',
click: () => {
electron.shell.openExternal('https://discord.gg/sFWPXtA');
},
},
{
type: 'separator',
},
{
type: 'normal',
label: 'Bug Report',
click: () => {
electron.shell.openExternal(
'https://github.com/notion-enhancer/notion-enhancer/issues/new?labels=bug&template=bug-report.md'
);
},
},
{
type: 'normal',
label: 'Feature Request',
click: () => {
electron.shell.openExternal(
'https://github.com/notion-enhancer/notion-enhancer/issues/new?labels=enhancement&template=feature-request.md'
);
},
},
{
type: 'separator',
},
{
type: 'normal',
label: 'Enhancements',
accelerator: store().menu_toggle,
click: openEnhancerMenu,
},
{
type: 'normal',
label: 'New Window',
click: newWindow(),
accelerator: 'CommandOrControl+Shift+N',
},
{
type: 'normal',
label: 'Toggle Visibility',
accelerator: store().hotkey,
click: toggleWindows,
},
{
type: 'separator',
},
{
label: 'Relaunch',
click: () => {
electron.app.relaunch();
electron.app.quit();
},
},
{
label: 'Quit',
role: 'quit',
},
]);
tray.setContextMenu(contextMenu);
tray.setToolTip('Notion');
// hotkey
function showWindows(windows) {
if (is_mac) electron.app.show();
if (store().maximized) windows.forEach((win) => [win.maximize()]);
else windows.forEach((win) => win.show());
electron.app.focus({ steal: true });
}
function hideWindows(windows) {
windows.forEach((win) => [win.isFocused() && win.blur(), win.hide()]);
if (is_mac) electron.app.hide();
}
function toggleWindows() {
const windows = getAllWindows();
if (windows.some((win) => win.isVisible())) hideWindows(windows);
else showWindows(windows);
}
tray.on('click', toggleWindows);
if (store().hotkey) {
electron.globalShortcut.register(store().hotkey, () => {
const windows = getAllWindows();
if (windows.some((win) => win.isFocused() && win.isVisible()))
hideWindows(windows);
else showWindows(windows);
});
}
});
};

711
mods/core/variables.css Normal file
View File

@ -0,0 +1,711 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 TarasokUA
* (c) 2020 Arecsu
* (c) 2020 u/zenith_illinois
* under the MIT license
*/
:root {
/** dark **/
--theme_dark--main: rgb(47, 52, 55);
--theme_dark--sidebar: rgb(55, 60, 63);
--theme_dark--overlay: rgba(15, 15, 15, 0.6);
--theme_dark--dragarea: #272d2f;
--theme_dark--box-shadow: rgba(15, 15, 15, 0.2) 0px 0px 0px 1px,
rgba(15, 15, 15, 0.2) 0px 2px 4px;
--theme_dark--box-shadow_strong: 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;
--theme_dark--page_normal-width: 900px;
--theme_dark--page_full-width: 100%;
--theme_dark--page-padding: calc(96px + env(safe-area-inset-left));
--theme_dark--page_banner-height: 30vh;
--theme_dark--preview-width: 977px;
--theme_dark--preview-padding: 8rem;
--theme_dark--preview_banner-height: 20vh;
--theme_dark--font_sans: -apple-system, BlinkMacSystemFont, 'Segoe UI',
Helvetica, 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji',
'Segoe UI Symbol';
--theme_dark--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_dark--font_mono: iawriter-mono, Nitti, Menlo, Courier, monospace;
--theme_dark--font_code: SFMono-Regular, Consolas, 'Liberation Mono', Menlo,
Courier, monospace;
--theme_dark--font_title-size: 40px;
--theme_dark--font_heading1-size: 1.875em;
--theme_dark--font_heading2-size: 1.5em;
--theme_dark--font_heading3-size: 1.25em;
--theme_dark--font_label-size: 14px;
--theme_dark--font_body-size: 16px;
--theme_dark--font_body-size_small: 14px;
--theme_dark--font_code-size: 0.796875em;
--theme_dark--font_sidebar-size: 14px;
--theme_dark--text-block_line-height: 1.5;
--theme_dark--text-block_margin-top: 1px;
--theme_dark--scrollbar: #505457;
--theme_dark--scrollbar-border: transparent;
--theme_dark--scrollbar_hover: #696d6f;
--theme_dark--card: rgb(63, 68, 71);
--theme_dark--gallery: rgba(255, 255, 255, 0.05);
--theme_dark--select_input: rgb(55, 60, 63);
--theme_dark--table-border: rgba(255, 255, 255, 0.1);
--theme_dark--ui-border: rgba(255, 255, 255, 0.07);
--theme_dark--interactive_hover: rgb(71, 76, 80);
--theme_dark--interactive_hover-border: transparent;
--theme_dark--button_close: #e81123;
--theme_dark--button_close-fill: white;
--theme_dark--selected: rgba(46, 170, 220, 0.2);
--theme_dark--primary: rgb(46, 170, 220);
--theme_dark--primary_hover: rgb(6, 156, 205);
--theme_dark--primary_click: rgb(0, 141, 190);
--theme_dark--primary_indicator: rgb(235, 87, 87);
--theme_dark--option-color: white;
--theme_dark--option-background: transparent;
--theme_dark--option_active-color: white;
--theme_dark--option_active-background: var(--theme_dark--primary);
--theme_dark--option_hover-color: white;
--theme_dark--option_hover-background: rgb(71, 76, 80);
--theme_dark--danger_text: rgb(235, 87, 87);
--theme_dark--danger_border: rgba(235, 87, 87, 0.5);
--theme_dark--text: rgba(255, 255, 255, 0.9);
--theme_dark--text_ui: rgba(255, 255, 255, 0.6);
--theme_dark--text_ui_info: rgba(255, 255, 255, 0.4);
--theme_dark--text_gray: rgba(151, 154, 155, 0.95);
--theme_dark--text_brown: rgb(147, 114, 100);
--theme_dark--text_orange: rgb(255, 163, 68);
--theme_dark--text_yellow: rgb(255, 220, 73);
--theme_dark--text_green: rgb(77, 171, 154);
--theme_dark--text_blue: rgb(82, 156, 202);
--theme_dark--text_purple: rgb(154, 109, 215);
--theme_dark--text_pink: rgb(226, 85, 161);
--theme_dark--text_red: rgb(255, 115, 105);
--theme_dark--bg-text: var(--theme_dark--text);
--theme_dark--bg_gray: rgb(69, 75, 78);
--theme_dark--bg_gray-text: var(--theme_dark--bg-text);
--theme_dark--bg_brown: rgb(67, 64, 64);
--theme_dark--bg_brown-text: var(--theme_dark--bg-text);
--theme_dark--bg_orange: rgb(89, 74, 58);
--theme_dark--bg_orange-text: var(--theme_dark--bg-text);
--theme_dark--bg_yellow: rgb(89, 86, 59);
--theme_dark--bg_yellow-text: var(--theme_dark--bg-text);
--theme_dark--bg_green: rgb(53, 76, 75);
--theme_dark--bg_green-text: var(--theme_dark--bg-text);
--theme_dark--bg_blue: rgb(54, 73, 84);
--theme_dark--bg_blue-text: var(--theme_dark--bg-text);
--theme_dark--bg_purple: rgb(68, 63, 87);
--theme_dark--bg_purple-text: var(--theme_dark--bg-text);
--theme_dark--bg_pink: rgb(83, 59, 76);
--theme_dark--bg_pink-text: var(--theme_dark--bg-text);
--theme_dark--bg_red: rgb(89, 65, 65);
--theme_dark--bg_red-text: var(--theme_dark--bg-text);
--theme_dark--line-text: var(--theme_dark--text);
--theme_dark--line_gray: rgb(69, 75, 78);
--theme_dark--line_gray-text: var(--theme_dark--line-text);
--theme_dark--line_brown: rgb(67, 64, 64);
--theme_dark--line_brown-text: var(--theme_dark--line-text);
--theme_dark--line_orange: rgb(89, 74, 58);
--theme_dark--line_orange-text: var(--theme_dark--line-text);
--theme_dark--line_yellow: rgb(89, 86, 59);
--theme_dark--line_yellow-text: var(--theme_dark--line-text);
--theme_dark--line_green: rgb(53, 76, 75);
--theme_dark--line_green-text: var(--theme_dark--line-text);
--theme_dark--line_blue: rgb(54, 73, 84);
--theme_dark--line_blue-text: var(--theme_dark--line-text);
--theme_dark--line_purple: rgb(68, 63, 87);
--theme_dark--line_purple-text: var(--theme_dark--line-text);
--theme_dark--line_pink: rgb(83, 59, 76);
--theme_dark--line_pink-text: var(--theme_dark--line-text);
--theme_dark--line_red: rgb(89, 65, 65);
--theme_dark--line_red-text: var(--theme_dark--line-text);
--theme_dark--select-text: var(--theme_dark--text);
--theme_dark--select_gray: rgba(151, 154, 155, 0.5);
--theme_dark--select_gray-text: var(--theme_dark--select-text);
--theme_dark--select_brown: rgba(147, 114, 100, 0.5);
--theme_dark--select_brown-text: var(--theme_dark--select-text);
--theme_dark--select_orange: rgba(255, 163, 68, 0.5);
--theme_dark--select_orange-text: var(--theme_dark--select-text);
--theme_dark--select_yellow: rgba(255, 220, 73, 0.5);
--theme_dark--select_yellow-text: var(--theme_dark--select-text);
--theme_dark--select_green: rgba(77, 171, 154, 0.5);
--theme_dark--select_green-text: var(--theme_dark--select-text);
--theme_dark--select_blue: rgba(82, 156, 202, 0.5);
--theme_dark--select_blue-text: var(--theme_dark--select-text);
--theme_dark--select_purple: rgba(154, 109, 215, 0.5);
--theme_dark--select_purple-text: var(--theme_dark--select-text);
--theme_dark--select_pink: rgba(226, 85, 161, 0.5);
--theme_dark--select_pink-text: var(--theme_dark--select-text);
--theme_dark--select_red: rgba(255, 115, 105, 0.5);
--theme_dark--select_red-text: var(--theme_dark--select-text);
--theme_dark--callout-text: var(--theme_dark--text);
--theme_dark--callout_gray: rgba(69, 75, 78, 0.3);
--theme_dark--callout_gray-text: var(--theme_dark--callout-text);
--theme_dark--callout_brown: rgba(67, 64, 64, 0.3);
--theme_dark--callout_brown-text: var(--theme_dark--callout-text);
--theme_dark--callout_orange: rgba(89, 74, 58, 0.3);
--theme_dark--callout_orange-text: var(--theme_dark--callout-text);
--theme_dark--callout_yellow: rgba(89, 86, 59, 0.3);
--theme_dark--callout_yellow-text: var(--theme_dark--callout-text);
--theme_dark--callout_green: rgba(53, 76, 75, 0.3);
--theme_dark--callout_green-text: var(--theme_dark--callout-text);
--theme_dark--callout_blue: rgba(54, 73, 84, 0.3);
--theme_dark--callout_blue-text: var(--theme_dark--callout-text);
--theme_dark--callout_purple: rgba(68, 63, 87, 0.3);
--theme_dark--callout_purple-text: var(--theme_dark--callout-text);
--theme_dark--callout_pink: rgba(83, 59, 76, 0.3);
--theme_dark--callout_pink-text: var(--theme_dark--callout-text);
--theme_dark--callout_red: rgba(89, 65, 65, 0.3);
--theme_dark--callout_red-text: var(--theme_dark--callout-text);
--theme_dark--code_inline-text: #eb5757;
--theme_dark--code_inline-background: rgba(135, 131, 120, 0.15);
--theme_dark--code-text: var(--theme_dark--text);
--theme_dark--code-background: var(--theme_dark--card);
--theme_dark--code_function: rgba(255, 255, 255, 0.9);
--theme_dark--code_keyword: hsl(350, 40%, 70%);
--theme_dark--code_tag: hsl(350, 40%, 70%);
--theme_dark--code_operator: hsl(40, 90%, 60%);
--theme_dark--code_important: #e90;
--theme_dark--code_property: hsl(350, 40%, 70%);
--theme_dark--code_builtin: hsl(75, 70%, 60%);
--theme_dark--code_attr-name: hsl(75, 70%, 60%);
--theme_dark--code_comment: hsl(30, 20%, 50%);
--theme_dark--code_punctuation: rgba(255, 255, 255, 0.9);
--theme_dark--code_doctype: hsl(30, 20%, 50%);
--theme_dark--code_number: hsl(350, 40%, 70%);
--theme_dark--code_string: hsl(75, 70%, 60%);
--theme_dark--code_attr-value: hsl(350, 40%, 70%);
/** light **/
--theme_light--main: white;
--theme_light--sidebar: rgb(247, 246, 243);
--theme_light--overlay: rgba(15, 15, 15, 0.6);
--theme_light--dragarea: rgba(55, 53, 47, 0.04);
--theme_light--box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px,
rgba(15, 15, 15, 0.1) 0px 2px 4px;
--theme_light--box-shadow_strong: 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;
--theme_light--page_normal-width: 900px;
--theme_light--page_full-width: 100%;
--theme_light--page-padding: calc(96px + env(safe-area-inset-left));
--theme_light--page_banner-height: 30vh;
--theme_light--preview-width: 977px;
--theme_light--preview-padding: 8rem;
--theme_light--preview_banner-height: 20vh;
--theme_light--font_sans: -apple-system, BlinkMacSystemFont, 'Segoe UI',
Helvetica, 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji',
'Segoe UI Symbol';
--theme_light--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_light--font_mono: iawriter-mono, Nitti, Menlo, Courier, monospace;
--theme_light--font_code: SFMono-Regular, Consolas, 'Liberation Mono', Menlo,
Courier, monospace;
--theme_light--font_title-size: 40px;
--theme_light--font_heading1-size: 1.875em;
--theme_light--font_heading2-size: 1.5em;
--theme_light--font_heading3-size: 1.25em;
--theme_light--font_label-size: 14px;
--theme_light--font_body-size: 16px;
--theme_light--font_body-size_small: 14px;
--theme_light--font_code-size: 0.796875em;
--theme_light--font_sidebar-size: 14px;
--theme_light--text-block_line-height: 1.5;
--theme_light--text-block_margin-top: 1px;
--theme_light--scrollbar: #d9d8d6;
--theme_light--scrollbar-border: #cacac8;
--theme_light--scrollbar_hover: #cacac8;
--theme_light--card: rgb(247, 247, 247);
--theme_light--gallery: rgba(55, 53, 47, 0.024);
--theme_light--select_input: rgba(242, 241, 238, 0.6);
--theme_light--table-border: rgba(55, 53, 47, 0.16);
--theme_light--ui-border: rgba(55, 53, 47, 0.09);
--theme_light--interactive_hover: rgb(239, 239, 239);
--theme_light--interactive_hover-border: transparent;
--theme_light--button_close: #e81123;
--theme_light--button_close-fill: white;
--theme_light--selected: rgba(46, 170, 220, 0.2);
--theme_light--primary: rgb(46, 170, 220);
--theme_light--primary_hover: rgb(6, 156, 205);
--theme_light--primary_click: rgb(0, 141, 190);
--theme_light--primary_indicator: rgb(235, 87, 87);
--theme_light--option-color: black;
--theme_light--option-background: transparent;
--theme_light--option_hover-color: black;
--theme_light--option_hover-background: rgba(55, 53, 47, 0.08);
--theme_light--option_active-color: white;
--theme_light--option_active-background: var(--theme_light--primary);
--theme_light--danger_text: rgb(235, 87, 87);
--theme_light--danger_border: rgba(235, 87, 87, 0.5);
--theme_light--text: rgb(55, 53, 47);
--theme_light--text_ui: rgba(55, 53, 47, 0.6);
--theme_light--text_ui: rgba(55, 53, 47, 0.6);
--theme_light--text_ui_info: rgba(55, 53, 47, 0.4);
--theme_light--text_gray: rgb(155, 154, 151);
--theme_light--text_brown: rgb(100, 71, 58);
--theme_light--text_orange: rgb(217, 115, 13);
--theme_light--text_yellow: rgb(223, 171, 1);
--theme_light--text_green: rgb(15, 123, 108);
--theme_light--text_blue: rgb(11, 110, 153);
--theme_light--text_purple: rgb(105, 64, 165);
--theme_light--text_pink: rgb(173, 26, 114);
--theme_light--text_red: rgb(224, 62, 62);
--theme_light--bg-text: var(--theme_light--text);
--theme_light--bg_gray: rgb(235, 236, 237);
--theme_light--bg_gray-text: var(--theme_light--bg-text);
--theme_light--bg_brown: rgb(233, 229, 227);
--theme_light--bg_brown-text: var(--theme_light--bg-text);
--theme_light--bg_orange: rgb(250, 235, 221);
--theme_light--bg_orange-text: var(--theme_light--bg-text);
--theme_light--bg_yellow: rgb(251, 243, 219);
--theme_light--bg_yellow-text: var(--theme_light--bg-text);
--theme_light--bg_green: rgb(221, 237, 234);
--theme_light--bg_green-text: var(--theme_light--bg-text);
--theme_light--bg_blue: rgb(221, 235, 241);
--theme_light--bg_blue-text: var(--theme_light--bg-text);
--theme_light--bg_purple: rgb(234, 228, 242);
--theme_light--bg_purple-text: var(--theme_light--bg-text);
--theme_light--bg_pink: rgb(244, 223, 235);
--theme_light--bg_pink-text: var(--theme_light--bg-text);
--theme_light--bg_red: rgb(251, 228, 228);
--theme_light--bg_red-text: var(--theme_light--bg-text);
--theme_light--line-text: var(--theme_light--text);
--theme_light--line_gray: rgb(235, 236, 237);
--theme_light--line_gray-text: var(--theme_light--line-text);
--theme_light--line_brown: rgb(233, 229, 227);
--theme_light--line_brown-text: var(--theme_light--line-text);
--theme_light--line_orange: rgb(250, 235, 221);
--theme_light--line_orange-text: var(--theme_light--line-text);
--theme_light--line_yellow: rgb(251, 243, 219);
--theme_light--line_yellow-text: var(--theme_light--line-text);
--theme_light--line_green: rgb(221, 237, 234);
--theme_light--line_green-text: var(--theme_light--line-text);
--theme_light--line_blue: rgb(221, 235, 241);
--theme_light--line_blue-text: var(--theme_light--line-text);
--theme_light--line_purple: rgb(234, 228, 242);
--theme_light--line_purple-text: var(--theme_light--line-text);
--theme_light--line_pink: rgb(244, 223, 235);
--theme_light--line_pink-text: var(--theme_light--line-text);
--theme_light--line_red: rgb(251, 228, 228);
--theme_light--line_red-text: var(--theme_light--line-text);
--theme_light--select-text: var(--theme_light--text);
--theme_light--select_gray: rgba(140, 46, 0, 0.2);
--theme_light--select_gray-text: var(--theme_light--select-text);
--theme_light--select_brown: rgba(140, 46, 0, 0.2);
--theme_light--select_brown-text: var(--theme_light--select-text);
--theme_light--select_orange: rgba(245, 93, 0, 0.2);
--theme_light--select_orange-text: var(--theme_light--select-text);
--theme_light--select_yellow: rgba(233, 168, 0, 0.2);
--theme_light--select_yellow-text: var(--theme_light--select-text);
--theme_light--select_green: rgba(0, 135, 107, 0.2);
--theme_light--select_green-text: var(--theme_light--select-text);
--theme_light--select_blue: rgba(0, 120, 223, 0.2);
--theme_light--select_blue-text: var(--theme_light--select-text);
--theme_light--select_purple: rgba(103, 36, 222, 0.2);
--theme_light--select_purple-text: var(--theme_light--select-text);
--theme_light--select_pink: rgba(221, 0, 129, 0.2);
--theme_light--select_pink-text: var(--theme_light--select-text);
--theme_light--select_red: rgba(255, 0, 26, 0.2);
--theme_light--select_red-text: var(--theme_light--select-text);
--theme_light--callout-text: var(--theme_light--text);
--theme_light--callout_gray: rgba(235, 236, 237, 0.3);
--theme_light--callout_gray-text: var(--theme_light--callout-text);
--theme_light--callout_brown: rgba(233, 229, 227, 0.3);
--theme_light--callout_brown-text: var(--theme_light--callout-text);
--theme_light--callout_orange: rgba(250, 235, 221, 0.3);
--theme_light--callout_orange-text: var(--theme_light--callout-text);
--theme_light--callout_yellow: rgba(251, 243, 219, 0.3);
--theme_light--callout_yellow-text: var(--theme_light--callout-text);
--theme_light--callout_green: rgba(221, 237, 234, 0.3);
--theme_light--callout_green-text: var(--theme_light--callout-text);
--theme_light--callout_blue: rgba(221, 235, 241, 0.3);
--theme_light--callout_blue-text: var(--theme_light--callout-text);
--theme_light--callout_purple: rgba(234, 228, 242, 0.3);
--theme_light--callout_purple-text: var(--theme_light--callout-text);
--theme_light--callout_pink: rgba(244, 223, 235, 0.3);
--theme_light--callout_pink-text: var(--theme_light--callout-text);
--theme_light--callout_red: rgba(251, 228, 228, 0.3);
--theme_light--callout_red-text: var(--theme_light--callout-text);
--theme_light--code_inline-text: #eb5757;
--theme_light--code_inline-background: rgba(135, 131, 120, 0.15);
--theme_light--code-text: var(--theme_light--text);
--theme_light--code-background: var(--theme_light--card);
--theme_light--code_function: #dd4a68;
--theme_light--code_keyword: #07a;
--theme_light--code_tag: #905;
--theme_light--code_operator: #9a6e3a;
--theme_light--code_important: #e90;
--theme_light--code_property: #905;
--theme_light--code_builtin: #690;
--theme_light--code_attr-name: #690;
--theme_light--code_comment: slategray;
--theme_light--code_punctuation: #999;
--theme_light--code_doctype: slategray;
--theme_light--code_number: #905;
--theme_light--code_string: #690;
--theme_light--code_attr-value: #07a;
}
.notion-dark-theme {
--theme--main: var(--theme_dark--main);
--theme--sidebar: var(--theme_dark--sidebar);
--theme--overlay: var(--theme_dark--overlay);
--theme--dragarea: var(--theme_dark--dragarea);
--theme--box-shadow: var(--theme_dark--box-shadow);
--theme--box-shadow_strong: var(--theme_dark--box-shadow_strong);
--theme--page_normal-width: var(--theme_dark--page_normal-width);
--theme--page_full-width: var(--theme_dark--page_full-width);
--theme--page-padding: var(--theme_dark--page-padding);
--theme--page_banner-height: var(--theme_dark--page_banner-height);
--theme--preview-width: var(--theme_dark--preview-width);
--theme--preview-padding: var(--theme_dark--preview-padding);
--theme--preview_banner-height: var(--theme_dark--preview_banner-height);
--theme--font_sans: var(--theme_dark--font_sans);
--theme--font_serif: var(--theme_dark--font_serif);
--theme--font_mono: var(--theme_dark--font_mono);
--theme--font_code: var(--theme_dark--font_code);
--theme--font_title-size: var(--theme_dark--font_title-size);
--theme--font_heading1-size: var(--theme_dark--font_heading1-size);
--theme--font_heading2-size: var(--theme_dark--font_heading2-size);
--theme--font_heading3-size: var(--theme_dark--font_heading3-size);
--theme--font_label-size: var(--theme_dark--font_label-size);
--theme--font_body-size: var(--theme_dark--font_body-size);
--theme--font_body-size_small: var(--theme_dark--font_body-size_small);
--theme--font_code-size: var(--theme_dark--font_code-size);
--theme--font_sidebar-size: var(--theme_dark--font_sidebar-size);
--theme--text-block_line-height: var(--theme_dark--text-block_line-height);
--theme--text-block_margin-top: var(--theme_dark--text-block_margin-top);
--theme--scrollbar: var(--theme_dark--scrollbar);
--theme--scrollbar-border: var(--theme_dark--scrollbar-border);
--theme--scrollbar_hover: var(--theme_dark--scrollbar_hover);
--theme--card: var(--theme_dark--card);
--theme--gallery: var(--theme_dark--gallery);
--theme--select_input: var(--theme_dark--select_input);
--theme--table-border: var(--theme_dark--table-border);
--theme--ui-border: var(--theme_dark--ui-border);
--theme--interactive_hover: var(--theme_dark--interactive_hover);
--theme--interactive_hover-border: var(
--theme_dark--interactive_hover-border
);
--theme--button_close: var(--theme_dark--button_close);
--theme--button_close-fill: var(--theme_dark--button_close-fill);
--theme--selected: var(--theme_dark--selected);
--theme--primary: var(--theme_dark--primary);
--theme--primary_hover: var(--theme_dark--primary_hover);
--theme--primary_click: var(--theme_dark--primary_click);
--theme--primary_indicator: var(--theme_dark--primary_indicator);
--theme--option-color: var(--theme_dark--option-color);
--theme--option-background: var(--theme_dark--option-background);
--theme--option_active-color: var(--theme_dark--option_active-color);
--theme--option_active-background: var(
--theme_dark--option_active-background
);
--theme--option_hover-color: var(--theme_dark--option_hover-color);
--theme--option_hover-background: var(--theme_dark--option_hover-background);
--theme--danger_text: var(--theme_dark--danger_text);
--theme--danger_border: var(--theme_dark--danger_border);
--theme--text: var(--theme_dark--text);
--theme--text_ui: var(--theme_dark--text_ui);
--theme--text_ui_info: var(--theme_dark--text_ui_info);
--theme--text_gray: var(--theme_dark--text_gray);
--theme--text_brown: var(--theme_dark--text_brown);
--theme--text_orange: var(--theme_dark--text_orange);
--theme--text_yellow: var(--theme_dark--text_yellow);
--theme--text_green: var(--theme_dark--text_green);
--theme--text_blue: var(--theme_dark--text_blue);
--theme--text_purple: var(--theme_dark--text_purple);
--theme--text_pink: var(--theme_dark--text_pink);
--theme--text_red: var(--theme_dark--text_red);
--theme--select-text: var(--theme_dark--select-text);
--theme--bg-text: var(--theme_dark--bg-text);
--theme--bg_gray: var(--theme_dark--bg_gray);
--theme--bg_gray-text: var(--theme_dark--bg_gray-text);
--theme--bg_brown: var(--theme_dark--bg_brown);
--theme--bg_brown-text: var(--theme_dark--bg_brown-text);
--theme--bg_orange: var(--theme_dark--bg_orange);
--theme--bg_orange-text: var(--theme_dark--bg_orange-text);
--theme--bg_yellow: var(--theme_dark--bg_yellow);
--theme--bg_yellow-text: var(--theme_dark--bg_yellow-text);
--theme--bg_green: var(--theme_dark--bg_green);
--theme--bg_green-text: var(--theme_dark--bg_green-text);
--theme--bg_blue: var(--theme_dark--bg_blue);
--theme--bg_blue-text: var(--theme_dark--bg_blue-text);
--theme--bg_purple: var(--theme_dark--bg_purple);
--theme--bg_purple-text: var(--theme_dark--bg_purple-text);
--theme--bg_pink: var(--theme_dark--bg_pink);
--theme--bg_pink-text: var(--theme_dark--bg_pink-text);
--theme--bg_red: var(--theme_dark--bg_red);
--theme--bg_red-text: var(--theme_dark--bg_red-text);
--theme--line-text: var(--theme_dark--line-text);
--theme--line_gray: var(--theme_dark--line_gray);
--theme--line_gray-text: var(--theme_dark--line_gray-text);
--theme--line_brown: var(--theme_dark--line_brown);
--theme--line_brown-text: var(--theme_dark--line_brown-text);
--theme--line_orange: var(--theme_dark--line_orange);
--theme--line_orange-text: var(--theme_dark--line_orange-text);
--theme--line_yellow: var(--theme_dark--line_yellow);
--theme--line_yellow-text: var(--theme_dark--line_yellow-text);
--theme--line_green: var(--theme_dark--line_green);
--theme--line_green-text: var(--theme_dark--line_green-text);
--theme--line_blue: var(--theme_dark--line_blue);
--theme--line_blue-text: var(--theme_dark--line_blue-text);
--theme--line_purple: var(--theme_dark--line_purple);
--theme--line_purple-text: var(--theme_dark--line_purple-text);
--theme--line_pink: var(--theme_dark--line_pink);
--theme--line_pink-text: var(--theme_dark--line_pink-text);
--theme--line_red: var(--theme_dark--line_red);
--theme--line_red-text: var(--theme_dark--line_red-text);
--theme--select_gray: var(--theme_dark--select_gray);
--theme--select_gray-text: var(--theme_dark--select_gray-text);
--theme--select_brown: var(--theme_dark--select_brown);
--theme--select_brown-text: var(--theme_dark--select_brown-text);
--theme--select_orange: var(--theme_dark--select_orange);
--theme--select_orange-text: var(--theme_dark--select_orange-text);
--theme--select_yellow: var(--theme_dark--select_yellow);
--theme--select_yellow-text: var(--theme_dark--select_yellow-text);
--theme--select_green: var(--theme_dark--select_green);
--theme--select_green-text: var(--theme_dark--select_green-text);
--theme--select_blue: var(--theme_dark--select_blue);
--theme--select_blue-text: var(--theme_dark--select_blue-text);
--theme--select_purple: var(--theme_dark--select_purple);
--theme--select_purple-text: var(--theme_dark--select_purple-text);
--theme--select_pink: var(--theme_dark--select_pink);
--theme--select_pink-text: var(--theme_dark--select_pink-text);
--theme--select_red: var(--theme_dark--select_red);
--theme--select_red-text: var(--theme_dark--select_red-text);
--theme--callout-text: var(--theme_dark--callout-text);
--theme--callout_gray: var(--theme_dark--callout_gray);
--theme--callout_gray-text: var(--theme_dark--callout_gray-text);
--theme--callout_brown: var(--theme_dark--callout_brown);
--theme--callout_brown-text: var(--theme_dark--callout_brown-text);
--theme--callout_orange: var(--theme_dark--callout_orange);
--theme--callout_orange-text: var(--theme_dark--callout_orange-text);
--theme--callout_yellow: var(--theme_dark--callout_yellow);
--theme--callout_yellow-text: var(--theme_dark--callout_yellow-text);
--theme--callout_green: var(--theme_dark--callout_green);
--theme--callout_green-text: var(--theme_dark--callout_green-text);
--theme--callout_blue: var(--theme_dark--callout_blue);
--theme--callout_blue-text: var(--theme_dark--callout_blue-text);
--theme--callout_purple: var(--theme_dark--callout_purple);
--theme--callout_purple-text: var(--theme_dark--callout_purple-text);
--theme--callout_pink: var(--theme_dark--callout_pink);
--theme--callout_pink-text: var(--theme_dark--callout_pink-text);
--theme--callout_red: var(--theme_dark--callout_red);
--theme--callout_red-text: var(--theme_dark--callout_red-text);
--theme--code_inline-text: var(--theme_dark--code_inline-text);
--theme--code_inline-background: var(--theme_dark--code_inline-background);
--theme--code-text: var(--theme_dark--code-text);
--theme--code-background: var(--theme_dark--code-background);
--theme--code_function: var(--theme_dark--code_function);
--theme--code_keyword: var(--theme_dark--code_keyword);
--theme--code_tag: var(--theme_dark--code_tag);
--theme--code_operator: var(--theme_dark--code_operator);
--theme--code_important: var(--theme_dark--code_important);
--theme--code_property: var(--theme_dark--code_property);
--theme--code_builtin: var(--theme_dark--code_builtin);
--theme--code_attr-name: var(--theme_dark--code_attr-name);
--theme--code_comment: var(--theme_dark--code_comment);
--theme--code_punctuation: var(--theme_dark--code_punctuation);
--theme--code_doctype: var(--theme_dark--code_doctype);
--theme--code_number: var(--theme_dark--code_number);
--theme--code_string: var(--theme_dark--code_string);
--theme--code_attr-value: var(--theme_dark--code_attr-value);
}
.notion-light-theme {
--theme--main: var(--theme_light--main);
--theme--sidebar: var(--theme_light--sidebar);
--theme--overlay: var(--theme_light--overlay);
--theme--dragarea: var(--theme_light--dragarea);
--theme--box-shadow: var(--theme_light--box-shadow);
--theme--box-shadow_strong: var(--theme_light--box-shadow_strong);
--theme--page_normal-width: var(--theme_light--page_normal-width);
--theme--page_full-width: var(--theme_light--page_full-width);
--theme--page-padding: var(--theme_light--page-padding);
--theme--page_banner-height: var(--theme_light--page_banner-height);
--theme--preview-width: var(--theme_light--preview-width);
--theme--preview-padding: var(--theme_light--preview-padding);
--theme--preview_banner-height: var(--theme_light--preview_banner-height);
--theme--font_sans: var(--theme_light--font_sans);
--theme--font_serif: var(--theme_light--font_serif);
--theme--font_mono: var(--theme_light--font_mono);
--theme--font_code: var(--theme_light--font_code);
--theme--font_title-size: var(--theme_light--font_title-size);
--theme--font_heading1-size: var(--theme_light--font_heading1-size);
--theme--font_heading2-size: var(--theme_light--font_heading2-size);
--theme--font_heading3-size: var(--theme_light--font_heading3-size);
--theme--font_label-size: var(--theme_light--font_label-size);
--theme--font_body-size: var(--theme_light--font_body-size);
--theme--font_body-size_small: var(--theme_light--font_body-size_small);
--theme--font_code-size: var(--theme_light--font_code-size);
--theme--font_sidebar-size: var(--theme_light--font_sidebar-size);
--theme--text-block_line-height: var(--theme_light--text-block_line-height);
--theme--text-block_margin-top: var(--theme_light--text-block_margin-top);
--theme--scrollbar: var(--theme_light--scrollbar);
--theme--scrollbar-border: var(--theme_light--scrollbar-border);
--theme--scrollbar_hover: var(--theme_light--scrollbar_hover);
--theme--card: var(--theme_light--card);
--theme--gallery: var(--theme_light--gallery);
--theme--select_input: var(--theme_light--select_input);
--theme--table-border: var(--theme_light--table-border);
--theme--ui-border: var(--theme_light--ui-border);
--theme--interactive_hover: var(--theme_light--interactive_hover);
--theme--interactive_hover-border: var(
--theme_light--interactive_hover-border
);
--theme--button_close: var(--theme_light--button_close);
--theme--button_close-fill: var(--theme_light--button_close-fill);
--theme--selected: var(--theme_light--selected);
--theme--primary: var(--theme_light--primary);
--theme--primary_hover: var(--theme_light--primary_hover);
--theme--primary_click: var(--theme_light--primary_click);
--theme--primary_indicator: var(--theme_light--primary_indicator);
--theme--option-color: var(--theme_light--option-color);
--theme--option-background: var(--theme_light--option-background);
--theme--option_hover-color: var(--theme_light--option_hover-color);
--theme--option_hover-background: var(--theme_light--option_hover-background);
--theme--option_active-color: var(--theme_light--option_active-color);
--theme--option_active-background: var(
--theme_light--option_active-background
);
--theme--danger_text: var(--theme_light--danger_text);
--theme--danger_border: var(--theme_light--danger_border);
--theme--text: var(--theme_light--text);
--theme--text_ui: var(--theme_light--text_ui);
--theme--text_ui_info: var(--theme_light--text_ui_info);
--theme--text_gray: var(--theme_light--text_gray);
--theme--text_brown: var(--theme_light--text_brown);
--theme--text_orange: var(--theme_light--text_orange);
--theme--text_yellow: var(--theme_light--text_yellow);
--theme--text_green: var(--theme_light--text_green);
--theme--text_blue: var(--theme_light--text_blue);
--theme--text_purple: var(--theme_light--text_purple);
--theme--text_pink: var(--theme_light--text_pink);
--theme--text_red: var(--theme_light--text_red);
--theme--select-text: var(--theme_light--select-text);
--theme--bg-text: var(--theme_light--bg-text);
--theme--bg_gray: var(--theme_light--bg_gray);
--theme--bg_gray-text: var(--theme_light--bg_gray-text);
--theme--bg_brown: var(--theme_light--bg_brown);
--theme--bg_brown-text: var(--theme_light--bg_brown-text);
--theme--bg_orange: var(--theme_light--bg_orange);
--theme--bg_orange-text: var(--theme_light--bg_orange-text);
--theme--bg_yellow: var(--theme_light--bg_yellow);
--theme--bg_yellow-text: var(--theme_light--bg_yellow-text);
--theme--bg_green: var(--theme_light--bg_green);
--theme--bg_green-text: var(--theme_light--bg_green-text);
--theme--bg_blue: var(--theme_light--bg_blue);
--theme--bg_blue-text: var(--theme_light--bg_blue-text);
--theme--bg_purple: var(--theme_light--bg_purple);
--theme--bg_purple-text: var(--theme_light--bg_purple-text);
--theme--bg_pink: var(--theme_light--bg_pink);
--theme--bg_pink-text: var(--theme_light--bg_pink-text);
--theme--bg_red: var(--theme_light--bg_red);
--theme--bg_red-text: var(--theme_light--bg_red-text);
--theme--line-text: var(--theme_light--line-text);
--theme--line_gray: var(--theme_light--line_gray);
--theme--line_gray-text: var(--theme_light--line_gray-text);
--theme--line_brown: var(--theme_light--line_brown);
--theme--line_brown-text: var(--theme_light--line_brown-text);
--theme--line_orange: var(--theme_light--line_orange);
--theme--line_orange-text: var(--theme_light--line_orange-text);
--theme--line_yellow: var(--theme_light--line_yellow);
--theme--line_yellow-text: var(--theme_light--line_yellow-text);
--theme--line_green: var(--theme_light--line_green);
--theme--line_green-text: var(--theme_light--line_green-text);
--theme--line_blue: var(--theme_light--line_blue);
--theme--line_blue-text: var(--theme_light--line_blue-text);
--theme--line_purple: var(--theme_light--line_purple);
--theme--line_purple-text: var(--theme_light--line_purple-text);
--theme--line_pink: var(--theme_light--line_pink);
--theme--line_pink-text: var(--theme_light--line_pink-text);
--theme--line_red: var(--theme_light--line_red);
--theme--line_red-text: var(--theme_light--line_red-text);
--theme--select_gray: var(--theme_light--select_gray);
--theme--select_gray-text: var(--theme_light--select_gray-text);
--theme--select_brown: var(--theme_light--select_brown);
--theme--select_brown-text: var(--theme_light--select_brown-text);
--theme--select_orange: var(--theme_light--select_orange);
--theme--select_orange-text: var(--theme_light--select_orange-text);
--theme--select_yellow: var(--theme_light--select_yellow);
--theme--select_yellow-text: var(--theme_light--select_yellow-text);
--theme--select_green: var(--theme_light--select_green);
--theme--select_green-text: var(--theme_light--select_green-text);
--theme--select_blue: var(--theme_light--select_blue);
--theme--select_blue-text: var(--theme_light--select_blue-text);
--theme--select_purple: var(--theme_light--select_purple);
--theme--select_purple-text: var(--theme_light--select_purple-text);
--theme--select_pink: var(--theme_light--select_pink);
--theme--select_pink-text: var(--theme_light--select_pink-text);
--theme--select_red: var(--theme_light--select_red);
--theme--select_red-text: var(--theme_light--select_red-text);
--theme--callout-text: var(--theme_light--callout-text);
--theme--callout_gray: var(--theme_light--callout_gray);
--theme--callout_gray-text: var(--theme_light--callout_gray-text);
--theme--callout_brown: var(--theme_light--callout_brown);
--theme--callout_brown-text: var(--theme_light--callout_brown-text);
--theme--callout_orange: var(--theme_light--callout_orange);
--theme--callout_orange-text: var(--theme_light--callout_orange-text);
--theme--callout_yellow: var(--theme_light--callout_yellow);
--theme--callout_yellow-text: var(--theme_light--callout_yellow-text);
--theme--callout_green: var(--theme_light--callout_green);
--theme--callout_green-text: var(--theme_light--callout_green-text);
--theme--callout_blue: var(--theme_light--callout_blue);
--theme--callout_blue-text: var(--theme_light--callout_blue-text);
--theme--callout_purple: var(--theme_light--callout_purple);
--theme--callout_purple-text: var(--theme_light--callout_purple-text);
--theme--callout_pink: var(--theme_light--callout_pink);
--theme--callout_pink-text: var(--theme_light--callout_pink-text);
--theme--callout_red: var(--theme_light--callout_red);
--theme--callout_red-text: var(--theme_light--callout_red-text);
--theme--code_inline-text: var(--theme_light--code_inline-text);
--theme--code_inline-background: var(--theme_light--code_inline-background);
--theme--code-text: var(--theme_light--code-text);
--theme--code-background: var(--theme_light--code-background);
--theme--code_function: var(--theme_light--code_function);
--theme--code_keyword: var(--theme_light--code_keyword);
--theme--code_tag: var(--theme_light--code_tag);
--theme--code_operator: var(--theme_light--code_operator);
--theme--code_important: var(--theme_light--code_important);
--theme--code_property: var(--theme_light--code_property);
--theme--code_builtin: var(--theme_light--code_builtin);
--theme--code_attr-name: var(--theme_light--code_attr-name);
--theme--code_comment: var(--theme_light--code_comment);
--theme--code_punctuation: var(--theme_light--code_punctuation);
--theme--code_doctype: var(--theme_light--code_doctype);
--theme--code_number: var(--theme_light--code_number);
--theme--code_string: var(--theme_light--code_string);
--theme--code_attr-value: var(--theme_light--code_attr-value);
}

View File

@ -0,0 +1,65 @@
/*
* custom inserts
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: 'b4b0aced-2059-43bf-8d1d-ccd757ee5ebb',
tags: ['extension'],
name: 'custom inserts',
desc: `link files for small client-side tweaks. (not sure how to do something? check out the
[tweaks](https://github.com/notion-enhancer/notion-enhancer/blob/master/TWEAKS.md) collection.)`,
version: '0.1.3',
author: 'dragonwocky',
options: [
{
key: 'css',
label: 'css insert',
type: 'file',
extensions: ['css'],
},
{
key: 'js',
label: 'client-side js insert',
type: 'file',
extensions: ['js'],
},
],
hacks: {
'renderer/preload.js'(store, __exports) {
const fs = require('fs-extra');
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
if (store().css) {
try {
document
.querySelector('head')
.appendChild(
createElement(
`<style type="text/css">${fs.readFileSync(
store().css
)}</style>`
)
);
} catch (err) {
console.warn('<custom-inserts> invalid css file... unsetting.');
store().css = '';
}
}
if (store().js) {
try {
require(store().js);
} catch (err) {
console.warn('<custom-inserts> invalid js file... unsetting.');
store().js = '';
}
}
});
},
},
};

52
mods/dark+/mod.js Normal file
View File

@ -0,0 +1,52 @@
/*
* dark+
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: 'c86cfe98-e645-4822-aa6b-e2de1e08bafa',
tags: ['theme', 'dark'],
name: 'dark+',
desc: 'a vivid-colour near-black theme.',
version: '0.1.6',
author: 'dragonwocky',
options: [
{
key: 'primary',
label: 'primary colour',
type: 'color',
value: 'rgb(177, 24, 24)',
},
],
hacks: {
'renderer/preload.js'(store, __exports) {
const color = require('./one-color.js')(store().primary);
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
document.documentElement.style.setProperty(
'--theme_dark--selected',
color.lightness(0.35).alpha(0.2).cssa()
);
document.documentElement.style.setProperty(
'--theme_dark--primary',
color.hex()
);
document.documentElement.style.setProperty(
'--theme_dark--primary_hover',
color.lightness(0.5).hex()
);
document.documentElement.style.setProperty(
'--theme_dark--primary_click',
color.lightness(0.6).hex()
);
document.documentElement.style.setProperty(
'--theme_dark--primary_indicator',
color.lightness(0.4).hex()
);
});
},
},
};

2
mods/dark+/one-color.js Normal file

File diff suppressed because one or more lines are too long

98
mods/dark+/variables.css Normal file
View File

@ -0,0 +1,98 @@
/*
* dark+
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Alexa Baldon (https://github.com/runargs)
* under the MIT license
*/
:root {
--theme_dark--main: rgb(5, 5, 5);
--theme_dark--sidebar: rgb(1, 1, 1);
--theme_dark--dragarea: #000;
--theme_dark--box-shadow_strong: none;
--theme_dark--scrollbar: #23242599;
--theme_dark--scrollbar-border: transparent;
--theme_dark--scrollbar_hover: #37383899;
--theme_dark--card: rgb(8, 8, 8);
--theme_dark--gallery: rgba(26, 26, 26, 0.3);
--theme_dark--select_input: rgb(12, 12, 12);
--theme_dark--table-border: rgba(46, 46, 46, 0.7);
--theme_dark--ui-border: var(--theme_dark--table-border);
--theme_dark--interactive_hover:rgba(55, 56, 56, 0.3);
--theme_dark--option_hover-background: rgb(32, 32, 32);
--theme_dark--text: rgb(228, 228, 228);
--theme_dark--text_ui: rgba(211, 211, 211, 0.637);
--theme_dark--text_ui_info: rgba(211, 211, 211, 0.466);
--theme_dark--text_gray: rgba(151, 154, 155, 0.95);
--theme_dark--text_brown: rgb(147, 114, 100);
--theme_dark--text_orange: rgb(255, 163, 68);
--theme_dark--text_yellow: rgb(255, 220, 73);
--theme_dark--text_green: rgb(50, 169, 104);
--theme_dark--text_blue: rgb(82, 156, 202);
--theme_dark--text_purple: rgb(154, 109, 215);
--theme_dark--text_pink: rgb(226, 85, 161);
--theme_dark--text_red: rgb(218, 47, 35);
--theme_dark--select_gray: rgba(126, 128, 129, 0.5);
--theme_dark--select_brown: #50331f;
--theme_dark--select_orange: rgba(255, 155, 0, 0.58);
--theme_dark--select_yellow: rgba(183, 155, 0, 1);
--theme_dark--select_green: rgb(50, 129, 47);
--theme_dark--select_blue: rgba(0, 90, 146, 0.71);
--theme_dark--select_purple: rgba(91, 49, 148, 0.74);
--theme_dark--select_pink: rgba(243, 61, 159, 0.5);
--theme_dark--select_red: rgb(122, 20, 20);
--theme_dark--bg_gray: var(--theme_dark--select_gray);
--theme_dark--bg_brown: var(--theme_dark--select_brown);
--theme_dark--bg_orange: var(--theme_dark--select_orange);
--theme_dark--bg_yellow: var(--theme_dark--select_yellow);
--theme_dark--bg_green: var(--theme_dark--select_green);
--theme_dark--bg_blue: var(--theme_dark--select_blue);
--theme_dark--bg_purple: var(--theme_dark--select_purple);
--theme_dark--bg_pink: var(--theme_dark--select_pink);
--theme_dark--bg_red: var(--theme_dark--select_red);
--theme_dark--line_gray: rgba(126, 128, 129, 0.301);
--theme_dark--line_brown: #50331fad;
--theme_dark--line_orange: rgba(255, 153, 0, 0.315);
--theme_dark--line_yellow: rgba(183, 156, 0, 0.445);
--theme_dark--line_green: rgba(50, 129, 47, 0.39);
--theme_dark--line_blue: rgba(0, 90, 146, 0.521);
--theme_dark--line_purple: rgba(90, 49, 148, 0.349);
--theme_dark--line_pink: rgba(243, 61, 158, 0.301);
--theme_dark--line_red: rgba(122, 20, 20, 0.623);
--theme_dark--callout_gray: rgba(126, 128, 129, 0.089);
--theme_dark--callout_brown: #50331f59;
--theme_dark--callout_orange: rgba(255, 153, 0, 0.164);
--theme_dark--callout_yellow: rgba(183, 156, 0, 0.274);
--theme_dark--callout_green: rgba(50, 129, 47, 0.191);
--theme_dark--callout_blue: rgba(0, 90, 146, 0.294);
--theme_dark--callout_purple: rgba(90, 49, 148, 0.219);
--theme_dark--callout_pink: rgba(243, 61, 158, 0.191);
--theme_dark--callout_red: rgba(122, 20, 20, 0.376);
--theme_dark--code_inline-text: #7dc582;
--theme_dark--code_inline-background: rgb(8, 8, 8);
--theme_dark--code-background: rgb(8, 8, 8);
--theme_dark--code_function: #c7e1ff;
--theme_dark--code_keyword: #c397d8;
--theme_dark--code_tag: #82aed8;
--theme_dark--code_operator: rgb(166, 175, 201);
--theme_dark--code_important: #da265f;
--theme_dark--code_property: #82aed8;
--theme_dark--code_builtin: #ff6294;
--theme_dark--code_attr-name: #ff6294;
--theme_dark--code_comment: rgb(166, 175, 201);
--theme_dark--code_punctuation: rgb(166, 175, 201);
--theme_dark--code_doctype: rgb(166, 175, 201);
--theme_dark--code_number: #c397d8;
--theme_dark--code_string: #7dc582;
--theme_dark--code_attr-value: #7dc582;
}

View File

@ -1,12 +1,13 @@
/** /*
* notion-enhancer: pastel dark * dracula
* (c) 2020 u/zenith_illinois * (c) 2020 @mimishahzad386#5651
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/) * (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (https://notion-enhancer.github.io/) under the MIT license * under the MIT license
*/ */
.notion-dark-theme img[src*='/images/onboarding/use-case-note.png'], .notion-dark-theme img[src*='/images/onboarding/use-case-note.png'],
.notion-dark-theme img[src*='/images/onboarding/team-features-illustration.png'] { .notion-dark-theme
img[src*='/images/onboarding/team-features-illustration.png'] {
filter: invert(1) !important; filter: invert(1) !important;
} }
.notion-dark-theme img[src*='/images/onboarding/checked.svg'] { .notion-dark-theme img[src*='/images/onboarding/checked.svg'] {
@ -25,7 +26,13 @@
filter: brightness(1.2); filter: brightness(1.2);
} }
.notion-dark-theme .notion-token-remove-button[role*='button'][tabindex*='0']:hover, .notion-dark-theme
[style*='font-family: Fira Code, Menlo, Courier, monospace;'] {
filter: hue-rotate(170deg) !important;
}
.notion-dark-theme
.notion-token-remove-button[role*='button'][tabindex*='0']:hover,
.notion-dark-theme .notion-record-icon { .notion-dark-theme .notion-record-icon {
background: transparent !important; background: transparent !important;
} }
@ -33,8 +40,10 @@
.notion-dark-theme .notion-focusable:focus-within, .notion-dark-theme .notion-focusable:focus-within,
.notion-dark-theme .notion-to_do-block > div > div > div[style*='background:'], .notion-dark-theme .notion-to_do-block > div > div > div[style*='background:'],
.notion-dark-theme div[role='button'], .notion-dark-theme div[role='button'],
[style*='height: 4px;'] > .notion-selectable.notion-collection_view_page-block > *, [style*='height: 4px;']
.notion-dark-theme .notion-calendar-view-day[style*='background: rgb(235, 87, 87);'], > .notion-selectable.notion-collection_view_page-block
> *,
.notion-dark-theme .notion-calendar-view-day[style*='background: #282a36;'],
.DayPicker-Day--today, .DayPicker-Day--today,
.notion-dark-theme .notion-dark-theme
.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker:not(.DayPicker--interactionDisabled)
@ -48,11 +57,7 @@
transition: color 0.4s ease, background 0.4s ease, box-shadow 0.4s ease !important; 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 [style*='background: #282a36;'],
.notion-dark-theme
.notion-code-block
[style*='background: rgb(63, 68, 71);']
.notion-code-block,
.notion-dark-theme .notion-dark-theme
[style*='background: rgb(80, 85, 88);'][style*='color: rgba(255, 255, 255, 0.7)'], [style*='background: rgb(80, 85, 88);'][style*='color: rgba(255, 255, 255, 0.7)'],
.notion-dark-theme .notion-dark-theme

18
mods/dracula/mod.js Normal file
View File

@ -0,0 +1,18 @@
/*
* dracula
* (c) 2020 @mimishahzad386#5651
* (c) 2020 dracula
* under the MIT license
*/
'use strict';
module.exports = {
id: '033bff54-50ba-4cec-bdc0-b2ca7e307086',
tags: ['theme', 'dark'],
name: 'dracula',
desc:
'a theme based on the popular dracula color palette originally by zeno rocha and friends. ',
version: '0.1.0',
author: 'dracula',
};

131
mods/dracula/variables.css Normal file
View File

@ -0,0 +1,131 @@
/*
* dracula
* (c) 2020 @mimishahzad386#5651
* (c) 2020 dracula
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Alexa Baldon (https://github.com/runargs)
* under the MIT license
*/
:root {
--theme_dark--main: #282a36;
--theme_dark--sidebar: #21232c;
--theme_dark--overlay: rgba(13, 13, 14, 0.5);
--theme_dark--dragarea: #20222b;
--theme_dark--font_sans: -apple-system, BlinkMacSystemFont, 'Segoe UI',
Helvetica, 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji',
'Segoe UI Symbol';
--theme_dark--scrollbar: #393c4d;
--theme_dark--scrollbar_hover: #576591;
--theme_dark--card: #3c3f50;
--theme_dark--gallery: #323546;
--theme_dark--select_input: #474a5c;
--theme_dark--table-border: #484b59;
--theme_dark--ui-border: var(--theme_dark--table-border);
--theme_dark--interactive_hover: rgba(64, 73, 105, 0.7);
--theme_dark--button_close: #ff5555;
--theme_dark--selected: rgba(189, 147, 249, 0.3);
--theme_dark--primary: #bd93f9;
--theme_dark--primary_hover: #8be9fd;
--theme_dark--primary_click: #bd93f9;
--theme_dark--primary_indicator: #8be9fd;
--theme_dark--option_active-background: var(--theme_dark--primary);
--theme_dark--option_hover-background: var(--theme_dark--primary_hover);
--theme_dark--danger_text: #ff5555;
--theme_dark--danger_border: #ffb86c;
--theme_dark--text: #f8f8f2;
--theme_dark--text_ui: #f8f8f2;
--theme_dark--text_ui_info: #f8f8f2;
--theme_dark--text_gray: #807e8d;
--theme_dark--text_brown: #6272a4;
--theme_dark--text_orange: #ffb86c;
--theme_dark--text_yellow: #f1fa8c;
--theme_dark--text_green: #50fa7b;
--theme_dark--text_blue: #8be9fd;
--theme_dark--text_purple: #bd93f9;
--theme_dark--text_pink: #ff79c6;
--theme_dark--text_red: #ff5555;
--theme_dark--select-text: #000000;
--theme_dark--select_gray: #454158;
--theme_dark--select_gray-text: #f5f5f5;
--theme_dark--select_brown: #6272a4;
--theme_dark--select_brown-text: #f5f5f5;
--theme_dark--select_orange: #ffb86c;
--theme_dark--select_yellow: #f1fa8c;
--theme_dark--select_green: #50fa7b;
--theme_dark--select_blue: #8be9fd;
--theme_dark--select_purple: #bd93f9;
--theme_dark--select_pink: #ff79c6;
--theme_dark--select_red: #ff5555;
--theme_dark--select_red-text: #f5f5f5;
--theme_dark--bg-text: var(--theme_dark--select-text);
--theme_dark--bg_gray: var(--theme_dark--select_gray);
--theme_dark--bg_gray-text: #f5f5f5;
--theme_dark--bg_brown: var(--theme_dark--select_brown);
--theme_dark--bg_brown-text: #f5f5f5;
--theme_dark--bg_orange: var(--theme_dark--select_orange);
--theme_dark--bg_yellow: var(--theme_dark--select_yellow);
--theme_dark--bg_green: var(--theme_dark--select_green);
--theme_dark--bg_blue: var(--theme_dark--select_blue);
--theme_dark--bg_purple: var(--theme_dark--select_purple);
--theme_dark--bg_pink: var(--theme_dark--select_pink);
--theme_dark--bg_red: var(--theme_dark--select_red);
--theme_dark--bg_red-text: #f5f5f5;
--theme_dark--line-text: #000000;
--theme_dark--line_gray: #3c3f50;
--theme_dark--line_gray-text: #f5f5f5;
--theme_dark--line_brown: #6272a4;
--theme_dark--line_brown-text: #f5f5f5;
--theme_dark--line_orange: #ffb86c;
--theme_dark--line_yellow: #f1fa8c;
--theme_dark--line_green: #50fa7b;
--theme_dark--line_blue: #8be9fd;
--theme_dark--line_purple: #bd93f9;
--theme_dark--line_pink: #ff79c6;
--theme_dark--line_red: #ff5555;
--theme_dark--line_red-text: #f5f5f5;
--theme_dark--callout-text: var(--theme_dark--line-text);
--theme_dark--callout_gray: var(--theme_dark--line_gray);
--theme_dark--callout_gray-text: #f5f5f5;
--theme_dark--callout_brown: var(--theme_dark--line_brown);
--theme_dark--callout_brown-text: #f5f5f5;
--theme_dark--callout_orange: var(--theme_dark--line_orange);
--theme_dark--callout_yellow: var(--theme_dark--line_yellow);
--theme_dark--callout_green: var(--theme_dark--line_green);
--theme_dark--callout_blue: var(--theme_dark--line_blue);
--theme_dark--callout_purple: var(--theme_dark--line_purple);
--theme_dark--callout_pink: var(--theme_dark--line_pink);
--theme_dark--callout_red: var(--theme_dark--line_red);
--theme_dark--callout_red-text: #f5f5f5;
--theme_dark--code_inline-text: #50fa7b;
--theme_dark--code_inline-background: #3c3f50;
--theme_dark--code-text: var(--theme_dark--text);
--theme_dark--code-background: #3c3f50;
--theme_dark--code_function: var(--theme_dark--text_blue);
--theme_dark--code_keyword: var(--theme_dark--text_pink);
--theme_dark--code_tag: var(--theme_dark--text_pink);
--theme_dark--code_operator: var(--theme_dark--text_yellow);
--theme_dark--code_important: var(--theme_dark--text_yellow);
--theme_dark--code_property: var(--theme_dark--text_pink);
--theme_dark--code_builtin: var(--theme_dark--text_yellow);
--theme_dark--code_attr-name: var(--theme_dark--text_yellow);
--theme_dark--code_comment: var(--theme_dark--text_ui);
--theme_dark--code_punctuation: #d2d0dc;
--theme_dark--code_doctype: #d2d0dc;
--theme_dark--code_number: var(--theme_dark--text_purple);
--theme_dark--code_string: var(--theme_dark--text_orange);
--theme_dark--code_attr-value: var(--theme_dark--text_orange);
}

145
mods/emoji-sets/mod.js Normal file
View File

@ -0,0 +1,145 @@
/*
* emoji sets
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: 'a2401ee1-93ba-4b8c-9781-7f570bf5d71e',
tags: ['extension'],
name: 'emoji sets',
desc: 'pick from a variety of emoji styles to use.',
version: '0.3.0',
author: 'dragonwocky',
options: [
{
key: 'style',
label: '',
type: 'select',
value: [
'twitter',
'apple',
'google',
'microsoft',
'samsung',
'whatsapp',
'facebook',
'joypixels',
'openmoji',
'emojidex',
'lg',
'htc',
'mozilla',
],
},
],
hacks: {
'renderer/preload.js'(store, __exports) {
let tweaked = false;
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
let queue = [];
const observer = new MutationObserver((list, observer) => {
if (!queue.length) requestAnimationFrame(handle);
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true,
});
function handle() {
queue = [];
const isMac = process.platform === 'darwin',
native =
(store().style === 'microsoft' && process.platform === 'win32') ||
(store().style === 'apple' && isMac);
if (store().style !== (isMac ? 'apple' : 'twitter') || tweaked) {
if (isMac) {
if (native) {
document
.querySelectorAll('span[role="image"][aria-label]')
.forEach((el) => {
el.style.background = '';
el.style.color = 'currentColor';
});
} else {
document
.querySelectorAll('span[role="image"][aria-label]')
.forEach((el) => {
if (!el.style.background.includes(store().style)) {
el.style.background = `url(https://emojicdn.elk.sh/${el.getAttribute(
'aria-label'
)}?style=${store().style})`;
el.style.width = el.parentElement.style.fontSize;
el.style.backgroundSize = 'contain';
el.style.backgroundRepeat = 'no-repeat';
el.style.color = 'transparent';
}
});
}
} else {
document
.querySelectorAll(
'[src*="notion-emojis.s3"]:not(.notion-emoji)'
)
.forEach((el) => el.remove());
if (native) {
document.querySelectorAll('.notion-emoji').forEach((el) => {
if (
el.parentElement.querySelectorAll(
'span[role="image"][aria-label]'
).length !==
el.parentElement.querySelectorAll('.notion-emoji').length
) {
el.insertAdjacentHTML(
'beforebegin',
`<span
role="image"
aria-label="${el.getAttribute('alt')}"
style='font-family: "Apple Color Emoji", "Segoe UI Emoji",
NotoColorEmoji, "Noto Color Emoji", "Segoe UI Symbol",
"Android Emoji", EmojiSymbols; line-height: 1em;'
>${el.getAttribute('alt')}</span>`
);
el.style.display = 'none';
if (el.parentElement.getAttribute('contenteditable'))
el.remove();
} else if (
el.previousElementSibling.matches(
'span[role="image"][aria-label]'
)
) {
el.previousElementSibling.innerText = el.getAttribute(
'alt'
);
el.setAttribute('aria-label', el.getAttribute('alt'));
}
});
} else {
document.querySelectorAll('.notion-emoji').forEach((el) => {
el.parentElement
.querySelectorAll('span[role="image"][aria-label]')
.forEach((text) => text.remove());
el.style.display = 'inline-block';
if (!el.style.background.includes(store().style)) {
el.style.background = `url(https://emojicdn.elk.sh/${el.getAttribute(
'aria-label'
)}?style=${store().style})`;
el.style.backgroundSize = 'contain';
el.style.backgroundRepeat = 'no-repeat';
el.style.opacity = 1;
}
});
}
}
tweaked = true;
}
}
});
},
},
};

28
mods/focus-mode/app.css Normal file
View File

@ -0,0 +1,28 @@
/*
* focus mode
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Arecsu
* under the MIT license
*/
.notion-sidebar-container[style*='width: 0px;'] + .notion-frame .notion-topbar {
opacity: 0 !important;
transition: opacity 200ms ease-in-out !important;
}
.notion-sidebar-container[style*='width: 0px;']
+ .notion-frame
.notion-topbar:hover {
opacity: 1 !important;
}
/* add space at the bottom of the main frame when sidebar is hidden
* -- matches space at top for titlebar */
[data-focusmode='padded'] .notion-dark-theme .notion-frame {
transition: height 100ms ease 0s;
}
[data-focusmode='padded']
.notion-sidebar-container[style*='width: 0px;']
+ .notion-frame {
height: calc(
100% - (var(--configured--dragarea_height, 10px) + 45px)
) !important;
}

36
mods/focus-mode/mod.js Normal file
View File

@ -0,0 +1,36 @@
/*
* focus mode
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Arecsu
* under the MIT license
*/
'use strict';
module.exports = {
id: '5a08598d-bfac-4167-9ae8-2bd0e2ef141e',
tags: ['extension'],
name: 'focus mode',
desc:
'hide the titlebar/menubar if the sidebar is closed (will be shown on hover).',
version: '0.2.0',
author: 'arecsu',
options: [
{
key: 'padded',
label: 'add padding to bottom of the page',
desc: `will only take effect when the sidebar is hidden. aims to make the canvas\
as symmetrical/consistent as possible: if there is empty space on 3 sides, the 4th should follow.`,
type: 'toggle',
value: true,
},
],
hacks: {
'renderer/preload.js': (store, __exports) => {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
if (store().padded) document.body.dataset.focusmode = 'padded';
});
},
},
};

59
mods/font-chooser/mod.js Normal file
View File

@ -0,0 +1,59 @@
/*
* font chooser
* (c) 2020 torchatlas (https://bit.ly/torchatlas)
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: 'e0d8d148-45e7-4d79-8313-e7b2ad8abe16',
tags: ['extension'],
name: 'font chooser',
desc:
'customize fonts. for each option, type in the name of the font you would like to use, or leave it blank to not change anything.',
version: '0.1.1',
author: 'torchatlas',
options: [
{
key: 'sans',
label: 'sans-serif (inc. ui):',
type: 'input',
value: '',
},
{
key: 'serif',
label: 'serif:',
type: 'input',
value: '',
},
{
key: 'mono',
label: 'monospace:',
type: 'input',
value: '',
},
{
key: 'code',
label: 'code:',
type: 'input',
value: '',
},
],
hacks: {
'renderer/preload.js'(store, __exports) {
const attempt_interval = setInterval(enhance, 500);
async function enhance() {
if (!document.querySelector('.notion-app-inner')) return;
clearInterval(attempt_interval);
for (let style of ['sans', 'serif', 'mono', 'code']) {
if (!store()[style]) continue;
document
.querySelector('.notion-app-inner')
.style.setProperty(`--theme--font_${style}`, store()[style]);
}
}
},
},
};

14
mods/gameish/app.css Normal file
View File

@ -0,0 +1,14 @@
/*
* gameish
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 u/LVL100ShrekCultist
* under the MIT license
*/
.notion-dark-theme
.notion-scroller.vertical.horizontal
.notion-table-view
.notion-selectable.notion-collection_view-block
> :first-child {
background: var(--theme--card) !important;
}

22
mods/gameish/mod.js Normal file
View File

@ -0,0 +1,22 @@
/*
* gameish
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 u/LVL100ShrekCultist
* under the MIT license
*/
'use strict';
module.exports = {
id: 'ad923617-e76e-408e-9f23-490738a3223f',
tags: ['theme', 'dark'],
name: 'gameish',
desc: 'a purple, "gamer-styled" theme with a blocky-font.',
version: '0.1.4',
author: {
name: 'LVL100ShrekCultist',
link: 'https://www.reddit.com/user/LVL100ShrekCultist/',
avatar:
'https://styles.redditmedia.com/t5_2js69j/styles/profileIcon_jvnzmo30fyq41.jpg',
},
};

View File

@ -0,0 +1,71 @@
/*
* gameish
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 u/LVL100ShrekCultist
* under the MIT license
*/
@import 'https://fonts.googleapis.com/css2?family=Baumans&family=Comfortaa&family=DM+Mono&family=Gruppo&family=Nova+Mono&family=Offside&family=Press+Start+2P&family=Righteous&display=swap';
:root {
--theme_dark--main: #1e1c26;
--theme_dark--sidebar: #24222c;
--theme_dark--dragarea: #19181f;
--theme_dark--font_sans: 'Offside', -apple-system, BlinkMacSystemFont,
'Segoe UI', Helvetica, 'Apple Color Emoji', Arial, sans-serif,
'Segoe UI Emoji', 'Segoe UI Symbol';
--theme_dark--font_mono: 'DM Mono', iawriter-mono, Nitti, Menlo, Courier,
monospace;
--theme_dark--font_code: 'DM Mono', SFMono-Regular, Consolas,
'Liberation Mono', Menlo, Courier, monospace;
--theme_dark--scrollbar: #221f29;
--theme_dark--scrollbar_hover: #312d3c;
--theme_dark--gallery: rgba(162, 162, 162, 0.01);
--theme_dark--table-border: rgba(148, 148, 184, 0.5);
--theme_dark--interactive_hover: #282632;
--theme_dark--selected: rgba(85, 68, 156, 0.3);
--theme_dark--primary: rgb(106, 47, 200);
--theme_dark--primary_hover: rgb(110, 48, 211);
--theme_dark--primary_click: rgb(117, 65, 200);
--theme_dark--primary_indicator: rgb(150, 84, 226);
--theme_dark--option_hover-background: rgb(20, 0, 51);
--theme_dark--danger_text: rgb(235, 87, 87);
--theme_dark--danger_border: rgba(235, 87, 87, 0.5);
--theme_dark--text: rgba(255, 255, 255, 0.9);
--theme_dark--text_ui: rgba(255, 255, 255, 0.6);
--theme_dark--text_ui_info: rgba(255, 255, 255, 0.4);
--theme_dark--text_gray: rgba(151, 154, 155, 0.95);
--theme_dark--text_brown: rgb(112, 87, 77);
--theme_dark--text_yellow: #ffe529;
--theme_dark--text_green: #64d97b;
--theme_dark--text_purple: #d43cc7;
--theme_dark--text_red: #d93939;
--theme_dark--select_red: rgba(216, 57, 46, 0.5);
--theme_dark--bg_brown: rgb(78, 57, 48);
--theme_dark--bg_orange: rgb(136, 80, 48);
--theme_dark--bg_yellow: #fbe2287c;
--theme_dark--bg_red: rgb(151, 62, 62);
--theme_dark--line_brown: var(--theme_dark--bg_brown);
--theme_dark--line_orange: var(--theme_dark--bg_orange);
--theme_dark--line_yellow: var(--theme_dark--bg_yellow);
--theme_dark--line_red: var(--theme_dark--bg_red);
--theme_dark--callout_brown: var(--theme_dark--bg_brown);
--theme_dark--callout_orange: var(--theme_dark--bg_orange);
--theme_dark--callout_yellow: var(--theme_dark--bg_yellow);
--theme_dark--callout_red: var(--theme_dark--bg_red);
--theme_dark--code_inline-text: #d9cbec;
--theme_dark--code_inline-background: #24222c;
}

View File

@ -0,0 +1,88 @@
/*
* littlepig
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 Lizishan
* under the MIT license
*/
/* todo 颜色 */
.notion-body.dark .notion-dark-theme [style*='background: rgb(46, 170, 220)'],
.notion-body.dark
.notion-dark-theme
[style*='background-color: rgb(46, 170, 220)'] {
background: var(--theme_dark--option_active-background) !important;
}
/* ===================== header =========================== */
.notion-dark-theme [placeholder*='Heading 1'] {
color: var(--littlepig_dark--h1_text) !important;
}
.notion-dark-theme [placeholder*='Heading 2'] {
margin-bottom: 16px;
border-bottom: 4px solid var(--littlepig_dark--h2_text);
display: inline-block;
color: var(--littlepig_dark--h2_text) !important;
width: auto !important;
padding: 6px 12px 6px 0 !important;
position: relative;
}
.notion-dark-theme [placeholder*='Heading 2']::before {
content: '🔥 ';
}
.notion-dark-theme [placeholder*='Heading 3'] {
width: fit-content !important;
padding: 4px 10px !important;
border-radius: 10px;
border: 2px solid var(--littlepig_dark--h3_text);
color: var(--littlepig_dark--h3_text) !important;
background-color: #fbf8e7;
display: inline-block;
margin-bottom: 14px;
}
.notion-dark-theme [placeholder*='Heading 3']::before {
content: '📌 ';
}
/* list 样式 */
.notion-dark-theme
[style*='font-size: 1.5em; line-height: 1; margin-bottom: 0.1em;'] {
color: #a830fd !important;
}
/* quoteblock 样式 */
.notion-dark-theme
.notion-quote-block
[style*='caret-color: rgba(255, 255, 255, 0.9);'] {
font-size: 0.85em !important;
border-left: none !important;
padding: 0.5em 0.5em 0.5em 1.9em !important;
position: relative;
margin: 10px 0;
background: var(--theme_dark--card);
border-radius: 3px;
}
.notion-dark-theme
.notion-quote-block
[style*='caret-color: rgba(255, 255, 255, 0.9);']::before {
content: '\201C';
font-family: Georgia, serif;
font-size: 44px;
font-weight: bold;
color: #7b08fa;
position: absolute;
left: 0px;
top: -24px;
}
/* link style */
.notion-dark-theme .notion-link-token span {
border-bottom: 0.05em solid;
border-color: rgb(233, 51, 38) !important;
border-width: 3px !important;
opacity: 1 !important;
}
.notion-dark-theme .notion-link-token span:hover {
color: rgb(233, 51, 38) !important;
}

View File

@ -0,0 +1,22 @@
/*
* littlepig
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Lizishan
* under the MIT license
*/
'use strict';
module.exports = {
id: 'ad923617-e76e-418e-9f23-490738a32299',
tags: ['theme', 'dark'],
name: 'littlepig dark',
desc: 'a purple monospaced theme using emojis and colourful text.',
version: '0.1.2',
author: {
name: 'Lizishan',
link: 'https://www.reddit.com/user/Lizishan/',
avatar:
'https://styles.redditmedia.com/t5_110nz4/styles/profileIcon_h1m3b16exoi51.jpg',
},
};

View File

@ -0,0 +1,125 @@
/*
* littlepig
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 Lizishan
* under the MIT license
*/
@import 'https://dev-cats.github.io/code-snippets/JetBrainsMono.css';
:root {
--theme_dark--main: #1e1c26;
--theme_dark--sidebar: #24222c;
--theme_dark--dragarea: #19181f;
--theme_dark--font_sans: 'JetBrains Mono';
--theme_dark--font_serif: 'JetBrains Mono';
--theme_dark--font_mono: 'JetBrains Mono';
--theme_dark--font_code: 'JetBrains Mono';
--theme_dark--scrollbar: #221f29;
--theme_dark--scrollbar_hover: #312d3c;
--theme_dark--card: #24222c;
--theme_dark--gallery: rgba(162, 162, 162, 0.01);
--theme_dark--table-border: rgba(148, 148, 184, 0.5);
--theme_dark--interactive_hover: #282632;
--theme_dark--selected: #9500ff6b;
--theme_dark--primary: rgb(106, 47, 200);
--theme_dark--primary_hover: rgb(110, 48, 211);
--theme_dark--primary_click: rgb(117, 65, 200);
--theme_dark--primary_indicator: rgb(150, 84, 226);
--theme_dark--option_hover-background: rgb(20, 0, 51);
--theme_dark--text: rgba(200, 200, 200, 0.8);
/* 文本颜色 */
--theme_dark--text_brown: rgb(177, 144, 131);
--theme_dark--text_green: rgb(66, 222, 137);
--theme_dark--text_blue: rgb(0, 157, 255);
--theme_dark--text_purple: rgb(162, 94, 255);
--theme_dark--text_red: rgb(240, 52, 38);
/* 文本背景色 */
--theme_dark--line_gray: rgb(69, 75, 78);
--theme_dark--line_brown: rgb(78, 57, 48);
--theme_dark--line_orange: rgb(136, 80, 48);
--theme_dark--line_yellow: #fbe2287c;
--theme_dark--line_red: rgb(151, 62, 62);
/* 标题色 */
--littlepig_dark--h1_text: #c264fe;
--littlepig_dark--h2_text: #e2bafe;
--littlepig_dark--h3_text: #7b08fa;
/* todo */
--theme_dark--option_active-color: #7b08fa;
--theme_dark--option_active-background: #1d1c26;
/* inline code */
--theme_dark--code_inline-text: #e0dfe2;
--theme_dark--code_inline-background: rgb(179, 39, 39);
--theme_dark--code_function: rgb(179, 146, 240);
--theme_dark--code_number: hsl(159, 69%, 39%);
/* 标签颜色 + 文本背景色 */
--theme_dark--bg_gray: rgb(234, 234, 234);
--theme_dark--bg_gray-text: rgb(17, 17, 17);
--theme_dark--bg_brown: rgb(206, 206, 206);
--theme_dark--bg_brown-text: rgb(85, 35, 1);
--theme_dark--bg_orange: rgb(254, 214, 155);
--theme_dark--bg_orange-text: rgb(199, 110, 0);
--theme_dark--bg_yellow: #fcffd8;
--theme_dark--bg_yellow-text: #ff8c22;
--theme_dark--bg_green: #d5fded;
--theme_dark--bg_green-text: #006a00;
--theme_dark--bg_blue: #e2f5ff;
--theme_dark--bg_blue-text: #00b2ff;
--theme_dark--bg_purple: #efe6ff;
--theme_dark--bg_purple-text: #8334ff;
--theme_dark--bg_pink: #ffe9f1;
--theme_dark--bg_pink-text: rgb(255, 0, 127);
--theme_dark--bg_red: rgb(251, 228, 228);
--theme_dark--bg_red-text: rgb(138, 0, 10);
--theme_dark--select_gray: rgb(234, 234, 234);
--theme_dark--select_gray-text: rgb(17, 17, 17);
--theme_dark--select_brown: rgb(206, 206, 206);
--theme_dark--select_brown-text: rgb(85, 35, 1);
--theme_dark--select_orange: rgb(254, 214, 155);
--theme_dark--select_orange-text: rgb(199, 110, 0);
--theme_dark--select_yellow: #fcffd8;
--theme_dark--select_yellow-text: #ff8c22;
--theme_dark--select_green: #d5fded;
--theme_dark--select_green-text: #006a00;
--theme_dark--select_blue: #e2f5ff;
--theme_dark--select_blue-text: #00b2ff;
--theme_dark--select_purple: #efe6ff;
--theme_dark--select_purple-text: #8334ff;
--theme_dark--select_pink: #ffe9f1;
--theme_dark--select_pink-text: rgb(255, 0, 127);
--theme_dark--select_red: rgb(251, 228, 228);
--theme_dark--select_red-text: rgb(138, 0, 10);
/* callout 颜色 */
--theme_dark--callout_gray: #e2e3e5;
--theme_dark--callout_gray-text: #383d41;
--theme_dark--callout_brown: rgb(130, 118, 111);
--theme_dark--callout_brown-text: rgb(85, 35, 1);
--theme_dark--callout_orange: rgb(254, 214, 155);
--theme_dark--callout_orange-text: rgb(255, 140, 0);
--theme_dark--callout_yellow: #fcffd8;
--theme_dark--callout_yellow-text: #c76e00;
--theme_dark--callout_green: #d4edda;
--theme_dark--callout_green-text: #155724;
--theme_dark--callout_blue: #cce5ff;
--theme_dark--callout_blue-text: #004085;
--theme_dark--callout_purple: rgb(199, 178, 230);
--theme_dark--callout_purple-text: rgb(90, 49, 148);
--theme_dark--callout_pink: rgb(255, 206, 228);
--theme_dark--callout_pink-text: rgb(255, 0, 127);
--theme_dark--callout_red: #f8d7da;
--theme_dark--callout_red-text: #721c24;
}

View File

@ -0,0 +1,93 @@
/*
* littlepig
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 Lizishan
* under the MIT license
*/
/* todo 颜色 */
.notion-body:not(.dark)
.notion-light-theme
[style*='background: rgb(46, 170, 220)'],
.notion-body:not(.dark)
.notion-light-theme
[style*='background-color: rgb(46, 170, 220)'] {
background: var(--theme_dark--option_active-background) !important;
}
.notion-body:not(.dark) [style*='background: rgb(46, 170, 220)'][role='button'],
.notion-body:not(.dark)
[style*='background: rgb(46, 170, 220);'][style*='width: 26px'] {
background: var(--theme_light--primary) !important;
}
/* ===================== header =========================== */
.notion-body:not(.dark) [placeholder*='Heading 1'] {
color: var(--littlepig_light--h1_text) !important;
}
.notion-body:not(.dark) [placeholder*='Heading 2'] {
margin-bottom: 16px;
border-bottom: 4px solid var(--littlepig_light--h2_text);
display: inline-block;
color: var(--littlepig_light--h2_text) !important;
width: auto !important;
padding: 6px 12px 6px 0 !important;
position: relative;
}
.notion-body:not(.dark) [placeholder*='Heading 2']::before {
content: '🔥 ';
}
.notion-body:not(.dark) [placeholder*='Heading 3'] {
width: fit-content !important;
padding: 4px 10px !important;
border-radius: 10px;
border: 2px solid #42b983;
color: var(--littlepig_light--h3_text) !important;
background-color: #fbf8e7;
display: inline-block;
margin-bottom: 14px;
}
.notion-body:not(.dark) [placeholder*='Heading 3']::before {
content: '📌 ';
}
/* list 样式 */
.notion-body:not(.dark)
[style*='font-size: 1.5em; line-height: 1; margin-bottom: 0.1em;'] {
color: #41b983 !important;
}
/* quoteblock 样式 */
.notion-body:not(.dark) .notion-quote-block [style*='rgb(55, 53, 47);'] {
font-size: 0.85em !important;
border-left: none !important;
padding: 0.5em 0.5em 0.5em 1.9em !important;
position: relative;
margin: 10px 0;
background: var(--theme_light--card);
border-radius: 3px;
}
.notion-body:not(.dark)
.notion-quote-block
[style*='caret-color: rgb(55, 53, 47);']::before {
content: '\201C';
font-family: Georgia, serif;
font-size: 44px;
font-weight: bold;
color: #42b983;
position: absolute;
left: 0px;
top: -24px;
}
/* link style */
.notion-body:not(.dark) .notion-link-token span {
border-bottom: 0.05em solid;
border-color: rgb(233, 51, 38) !important;
border-width: 3px !important;
opacity: 1 !important;
}
.notion-body:not(.dark) .notion-link-token span:hover {
color: rgb(233, 51, 38) !important;
}

View File

@ -0,0 +1,22 @@
/*
* littlepig
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Lizishan
* under the MIT license
*/
'use strict';
module.exports = {
id: 'ad923617-e76e-408e-9f23-490738a32238',
tags: ['theme', 'light'],
name: 'littlepig light',
desc: 'a bright monospaced theme using emojis and colourful text.',
version: '0.1.1',
author: {
name: 'Lizishan',
link: 'https://www.reddit.com/user/Lizishan/',
avatar:
'https://styles.redditmedia.com/t5_110nz4/styles/profileIcon_h1m3b16exoi51.jpg',
},
};

View File

@ -0,0 +1,104 @@
/*
* littlepig
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 Lizishan
* under the MIT license
*/
@import 'https://dev-cats.github.io/code-snippets/JetBrainsMono.css';
:root {
--theme_light--font_sans: 'JetBrains Mono';
--theme_light--font_serif: 'JetBrains Mono';
--theme_light--font_mono: 'JetBrains Mono';
--theme_light--font_code: 'JetBrains Mono';
--theme_light--selected: rgba(177, 24, 24, 0.22);
--theme_light--primary: rgb(177, 24, 24);
--theme_light--primary_hover: rgb(202, 26, 26);
--theme_light--primary_click: rgb(219, 41, 41);
--theme_light--primary_indicator: rgb(202, 26, 26);
/* 文本颜色 */
--theme_light--text_gray: rgba(151, 154, 155, 0.95);
--theme_light--text_brown: rgb(167, 126, 100);
--theme_light--text_orange: rgb(255, 134, 0);
--theme_light--text_yellow: rgb(255, 195, 0);
--theme_light--text_green: rgb(0, 171, 0);
--theme_light--text_blue: rgb(0, 121, 255);
--theme_light--text_purple: rgb(126, 0, 255);
--theme_light--text_pink: rgb(255, 0, 208);
--theme_light--text_red: rgb(255, 0, 0);
/* 文本背景色 */
--theme_light--bg_gray: rgb(234, 234, 234);
--theme_light--bg_gray-text: rgb(17, 17, 17);
--theme_light--bg_brown: rgb(206, 206, 206);
--theme_light--bg_brown-text: rgb(85, 35, 1);
--theme_light--bg_orange: rgb(254, 214, 155);
--theme_light--bg_orange-text: rgb(199, 110, 0);
--theme_light--bg_yellow: #fcffd8;
--theme_light--bg_yellow-text: #ff8c22;
--theme_light--bg_green: #d5fded;
--theme_light--bg_green-text: #006a00;
--theme_light--bg_blue: #e2f5ff;
--theme_light--bg_blue-text: #00b2ff;
--theme_light--bg_purple: #efe6ff;
--theme_light--bg_purple-text: #8334ff;
--theme_light--bg_pink: #ffe9f1;
--theme_light--bg_pink-text: rgb(255, 0, 127);
--theme_light--bg_red: rgb(248, 215, 218);
--theme_light--bg_red-text: rgb(138, 0, 10);
--theme_light--select_gray: rgb(234, 234, 234);
--theme_light--select_gray-text: rgb(17, 17, 17);
--theme_light--select_brown: rgb(206, 206, 206);
--theme_light--select_brown-text: rgb(85, 35, 1);
--theme_light--select_orange: rgb(254, 214, 155);
--theme_light--select_orange-text: rgb(199, 110, 0);
--theme_light--select_yellow: #fcffd8;
--theme_light--select_yellow-text: #ff8c22;
--theme_light--select_green: #d5fded;
--theme_light--select_green-text: #006a00;
--theme_light--select_blue: #e2f5ff;
--theme_light--select_blue-text: #00b2ff;
--theme_light--select_purple: #efe6ff;
--theme_light--select_purple-text: #8334ff;
--theme_light--select_pink: #ffe9f1;
--theme_light--select_pink-text: rgb(255, 0, 127);
--theme_light--select_red: rgb(248, 215, 218);
--theme_light--select_red-text: rgb(138, 0, 10);
/* 标题色 */
--littlepig_light--h1_text: #008800;
--littlepig_light--h2_text: #006a00;
--littlepig_light--h3_text: #003e00;
/* todo */
--theme_light--option_active-color: #008800;
--theme_light--option_active-background: #ffffff;
/* inline code */
--theme_light--code_inline-text: #e0dfe2;
--theme_light--code_inline-background: rgb(179, 39, 39);
/* callout 颜色 */
--theme_light--callout_gray: #e2e3e5;
--theme_light--callout_gray-text: #383d41;
--theme_light--callout_brown: rgb(130, 118, 111);
--theme_light--callout_brown-text: rgb(85, 35, 1);
--theme_light--callout_orange: rgb(254, 214, 155);
--theme_light--callout_orange-text: rgb(255, 140, 0);
--theme_light--callout_yellow: #fcffd8;
--theme_light--callout_yellow-text: #c76e00;
--theme_light--callout_green: #d4edda;
--theme_light--callout_green-text: #155724;
--theme_light--callout_blue: #cce5ff;
--theme_light--callout_blue-text: #004085;
--theme_light--callout_purple: rgb(199, 178, 230);
--theme_light--callout_purple-text: rgb(90, 49, 148);
--theme_light--callout_pink: rgb(255, 206, 228);
--theme_light--callout_pink-text: rgb(255, 0, 127);
--theme_light--callout_red: #f8d7da;
--theme_light--callout_red-text: #721c24;
}

View File

@ -0,0 +1,16 @@
/*
* material ocean
* (c) 2020 Abubakar Yagoub <i@blacksuan19.me> (https://blacksuan19.tk)
* under the MIT license
*/
'use strict';
module.exports = {
id: '69e7ccb2-4aef-484c-876d-3de1b433d2b9',
tags: ['theme', 'dark'],
name: 'material ocean',
desc: 'an oceanic colour palette.',
version: '0.1.0',
author: 'blacksuan19',
};

View File

@ -0,0 +1,126 @@
/*
* material ocean
* (c) 2020 Abubakar Yagoub <i@blacksuan19.me> (https://blacksuan19.tk)
* under the MIT license
*/
:root {
--ocean-main: #0f111a;
--ocean-sec: #00010a;
--ocean-tet: #000108;
--ocean-accent: #ff4151;
--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_dark--main: var(--ocean-main);
--theme_dark--sidebar: var(--ocean-sec);
--theme_dark--overlay: rgba(0, 1, 10, 0.5);
--theme_dark--dragarea: var(--ocean-sec);
--theme_dark--scrollbar: var(--ocean-sec);
--theme_dark--scrollbar_hover: var(--ocean-accent);
--theme_dark--card: var(--ocean-sec);
--theme_dark--gallery: var(--ocean-sec);
--theme_dark--select_input: var(--ocean-tet);
--theme_dark--table-border: rgba(255, 255, 255, 0.1);
--theme_dark--ui-border: var(--theme_dark--table-border);
--theme_dark--interactive_hover: var(--ocean-tet);
--theme_dark--button_close: var(--ocean-accent);
--theme_dark--selected: rgba(255, 65, 81, 0.2);
--theme_dark--primary: var(--ocean-accent);
--theme_dark--primary_hover: var(--ocean-accent);
--theme_dark--primary_click: var(--ocean-sec);
--theme_dark--primary_indicator: var(--ocean-accent);
--theme_dark--option_active-background: var(--theme_dark--primary);
--theme_dark--option_hover-background: var(--theme_dark--primary_hover);
--theme_dark--danger_text: #eb5757;
--theme_dark--danger_border: rgba(235, 87, 87, 0.5);
--theme_dark--text: #ffffff;
--theme_dark--text_ui: var(--ocean-gray);
--theme_dark--text_ui_info: var(--ocean-gray);
--theme_dark--text_gray: var(--ocean-gray);
--theme_dark--text_brown: var(--ocean-brown);
--theme_dark--text_orange: var(--ocean-orange);
--theme_dark--text_yellow: var(--ocean-yellow);
--theme_dark--text_green: var(--ocean-green);
--theme_dark--text_blue: var(--ocean-blue);
--theme_dark--text_purple: var(--ocean-purple);
--theme_dark--text_pink: var(--ocean-pink);
--theme_dark--text_red: var(--ocean-red);
--theme_dark--bg-text: var(--ocean-main);
--theme_dark--bg_gray: var(--ocean-gray);
--theme_dark--bg_brown: var(--ocean-brown);
--theme_dark--bg_orange: var(--ocean-orange);
--theme_dark--bg_yellow: var(--ocean-yellow);
--theme_dark--bg_green: var(--ocean-green);
--theme_dark--bg_blue: var(--ocean-blue);
--theme_dark--bg_purple: var(--ocean-purple);
--theme_dark--bg_pink: var(--ocean-pink);
--theme_dark--bg_red: var(--ocean-red);
--theme_dark--line-text: var(--ocean-main);
--theme_dark--line_gray: #e0e0e089;
--theme_dark--line_brown: #d8b6a692;
--theme_dark--line_orange: #fde3c09f;
--theme_dark--line_yellow: #ffe6a6ad;
--theme_dark--line_green: #a3be8ca3;
--theme_dark--line_blue: #81a1c1a3;
--theme_dark--line_purple: #b48eada8;
--theme_dark--line_pink: #ffc0cbb1;
--theme_dark--line_red: #bf616a9e;
--theme_dark--select-text: var(--theme_dark--bg-text);
--theme_dark--select_gray: var(--theme_dark--bg_gray);
--theme_dark--select_brown: var(--theme_dark--bg_brown);
--theme_dark--select_orange: var(--theme_dark--bg_orange);
--theme_dark--select_yellow: var(--theme_dark--bg_yellow);
--theme_dark--select_green: var(--theme_dark--bg_green);
--theme_dark--select_blue: var(--theme_dark--bg_blue);
--theme_dark--select_purple: var(--theme_dark--bg_purple);
--theme_dark--select_pink: var(--theme_dark--bg_pink);
--theme_dark--select_red: var(--theme_dark--bg_red);
--theme_dark--callout-text: var(--theme_dark--line-text);
--theme_dark--callout_gray: var(--theme_dark--line_gray);
--theme_dark--callout_brown: var(--theme_dark--line_brown);
--theme_dark--callout_orange: var(--theme_dark--line_orange);
--theme_dark--callout_yellow: var(--theme_dark--line_yellow);
--theme_dark--callout_green: var(--theme_dark--line_green);
--theme_dark--callout_blue: var(--theme_dark--line_blue);
--theme_dark--callout_purple: var(--theme_dark--line_purple);
--theme_dark--callout_pink: var(--theme_dark--line_pink);
--theme_dark--callout_red: var(--theme_dark--line_red);
--theme_dark--code_inline-text: #b3f5c8;
--theme_dark--code_inline-background: var(--ocean-sec);
--theme_dark--code-text: var(--theme_dark--text);
--theme_dark--code-background: var(--ocean-sec);
--theme_dark--code_function: var(--theme_dark--text_blue);
--theme_dark--code_keyword: var(--theme_dark--text_pink);
--theme_dark--code_tag: var(--theme_dark--text_pink);
--theme_dark--code_operator: var(--theme_dark--text_yellow);
--theme_dark--code_important: var(--theme_dark--text_yellow);
--theme_dark--code_property: var(--theme_dark--text_pink);
--theme_dark--code_builtin: var(--theme_dark--text_yellow);
--theme_dark--code_attr-name: var(--theme_dark--text_yellow);
--theme_dark--code_comment: var(--theme_dark--text_gray);
--theme_dark--code_punctuation: var(--theme_dark--text_gray);
--theme_dark--code_doctype: var(--theme_dark--text_gray);
--theme_dark--code_number: var(--theme_dark--text_purple);
--theme_dark--code_string: var(--theme_dark--text_orange);
--theme_dark--code_attr-value: var(--theme_dark--text_orange);
}

19
mods/neutral/app.css Normal file
View File

@ -0,0 +1,19 @@
/*
* neutral
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Arecsu
* 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;
}

17
mods/neutral/mod.js Normal file
View File

@ -0,0 +1,17 @@
/*
* neutral
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Arecsu
* under the MIT license
*/
'use strict';
module.exports = {
id: 'c4435543-4705-4d68-8cf7-d11c342f8089',
tags: ['theme', 'dark'],
name: 'neutral',
desc: 'smoother colours and fonts, designed to be more pleasing to the eye.',
version: '0.1.4',
author: 'arecsu',
};

134
mods/neutral/variables.css Normal file
View File

@ -0,0 +1,134 @@
/*
* neutral
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Arecsu
* under the MIT license
*/
@import 'https://rsms.me/inter/inter.css';
@import 'https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400&display=swap';
:root {
/** dark **/
--theme_dark--main: #131313;
--theme_dark--sidebar: #161616;
--theme_dark--overlay: rgba(15, 15, 15, 0.6);
--theme_dark--dragarea: #111111;
--theme_dark--box-shadow: rgba(15, 15, 15, 0.5) 0px 0px 0px 1px,
rgba(15, 15, 15, 0.5) 0px 2px 4px;
--theme_dark--font_sans: 'Inter', -apple-system, BlinkMacSystemFont,
'Segoe UI', Helvetica, 'Apple Color Emoji', Arial, sans-serif,
'Segoe UI Emoji', 'Segoe UI Symbol';
--theme_dark--font_mono: 'Roboto Mono', iawriter-mono, Nitti, Menlo, Courier,
monospace;
--theme_dark--font_code: 'Roboto Mono', SFMono-Regular, Consolas,
'Liberation Mono', Menlo, Courier, monospace;
/* 1.3 supreme ratio. https://www.modularscale.com/ */
--theme_dark--font_title-size: 33px;
--theme_dark--font_heading1-size: 2.2em;
--theme_dark--font_heading2-size: 1.687em;
--theme_dark--font_heading3-size: 1.3em;
--theme_dark--font_label-size: 14px;
--theme_dark--font_body-size: 15px;
--theme_dark--font_body-size_small: 13.5px;
--theme_dark--font_code-size: 0.9em;
--theme_dark--font_sidebar-size: 14px;
--theme_dark--scrollbar: #232425;
--theme_dark--scrollbar-border: transparent;
--theme_dark--scrollbar_hover: #373838;
--theme_dark--card: #181818;
--theme_dark--gallery: rgba(105, 105, 105, 0.05);
--theme_dark--select_input: #1d1d1d;
--theme_dark--table-border: rgba(78, 78, 78, 0.7);
--theme_dark--ui-border: var(--theme_dark--table-border);
--theme_dark--interactive_hover: rgb(29, 29, 29);
--theme_dark--selected: #52525244;
--theme_dark--primary: #404040;
--theme_dark--primary_hover: #6d6d6d;
--theme_dark--primary_click: #cacaca;
--theme_dark--primary_indicator: #6d6d6d;
--theme_dark--option_hover-background: #484848;
--theme_dark--danger_text: #ce535f;
--theme_dark--danger_border: #8c3d3d;
--theme_dark--text: #dadada;
--theme_dark--text_ui: #dadadad0;
--theme_dark--text_ui_info: #dadadab4;
--theme_dark--text_gray: #858585;
--theme_dark--text_brown: #484848;
--theme_dark--text_orange: #ec9873;
--theme_dark--text_yellow: #e2c06f;
--theme_dark--text_green: #92b178;
--theme_dark--text_blue: #719cca;
--theme_dark--text_purple: #ab82bb;
--theme_dark--text_pink: #d285aa;
--theme_dark--text_red: #ce535f;
--theme_dark--bg_gray: #585858;
--theme_dark--bg_brown: #333333;
--theme_dark--bg_orange: #9a5a3f;
--theme_dark--bg_yellow: #b58a46;
--theme_dark--bg_green: #657953;
--theme_dark--bg_blue: #355475;
--theme_dark--bg_purple: #775186;
--theme_dark--bg_pink: #8e4b63;
--theme_dark--bg_red: #8c3d3d;
--theme_dark--line_gray: #585858;
--theme_dark--line_brown: #333333;
--theme_dark--line_orange: #9a5a3f;
--theme_dark--line_yellow: #b58a46;
--theme_dark--line_green: #657953;
--theme_dark--line_blue: #355475;
--theme_dark--line_purple: #775186;
--theme_dark--line_pink: #8e4b63;
--theme_dark--line_red: #8c3d3d;
--theme_dark--select_gray: var(--theme_dark--bg_gray);
--theme_dark--select_brown: var(--theme_dark--bg_brown);
--theme_dark--select_orange: var(--theme_dark--bg_orange);
--theme_dark--select_yellow: var(--theme_dark--bg_yellow);
--theme_dark--select_green: var(--theme_dark--bg_green);
--theme_dark--select_blue: var(--theme_dark--bg_blue);
--theme_dark--select_purple: var(--theme_dark--bg_purple);
--theme_dark--select_pink: var(--theme_dark--bg_pink);
--theme_dark--select_red: var(--theme_dark--bg_red);
--theme_dark--callout_gray: rgba(88, 88, 88, 0.175);
--theme_dark--callout_brown: rgb(51, 51, 51, 0.175);
--theme_dark--callout_orange: rgb(154, 90, 63, 0.175);
--theme_dark--callout_yellow: rgb(181, 138, 70, 0.175);
--theme_dark--callout_green: rgb(101, 121, 83, 0.175);
--theme_dark--callout_blue: rgb(53, 84, 117, 0.175);
--theme_dark--callout_purple: rgb(119, 81, 134, 0.175);
--theme_dark--callout_pink: rgb(142, 75, 99, 0.175);
--theme_dark--callout_red: rgb(140, 61, 61, 0.175);
--theme_dark--code_inline-text: var(--theme_dark--text);
--theme_dark--code_inline-background: #333333;
--theme_dark--code-text: var(--theme_dark--text);
--theme_dark--code-background: #0e0e0e;
--theme_dark--code_function: var(--theme_dark--text_blue);
--theme_dark--code_keyword: var(--theme_dark--text_pink);
--theme_dark--code_tag: var(--theme_dark--text_pink);
--theme_dark--code_operator: var(--theme_dark--text_yellow);
--theme_dark--code_important: var(--theme_dark--text_yellow);
--theme_dark--code_property: var(--theme_dark--text_pink);
--theme_dark--code_builtin: var(--theme_dark--text_yellow);
--theme_dark--code_attr-name: var(--theme_dark--text_yellow);
--theme_dark--code_comment: var(--theme_dark--text_gray);
--theme_dark--code_punctuation: var(--theme_dark--text_gray);
--theme_dark--code_doctype: var(--theme_dark--text_gray);
--theme_dark--code_number: var(--theme_dark--text_purple);
--theme_dark--code_string: var(--theme_dark--text_orange);
--theme_dark--code_attr-value: var(--theme_dark--text_orange);
}

47
mods/night-shift/mod.js Normal file
View File

@ -0,0 +1,47 @@
/*
* night shift
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: '9a71bbff-e87d-4a0b-8a2c-a93473113c30',
tags: ['extension', 'theme'],
name: 'night shift',
desc:
'sync dark/light theme with the system (overrides normal theme setting).',
version: '0.1.2',
author: 'dragonwocky',
hacks: {
'renderer/preload.js'(store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
const attempt_interval = setInterval(enhance, 500);
function enhance() {
const notion_elem = document.querySelector('.notion-app-inner');
if (!notion_elem) return;
clearInterval(attempt_interval);
handle([{ target: notion_elem }]);
const observer = new MutationObserver(handle);
observer.observe(notion_elem, {
attributes: true,
subtree: true,
});
function handle(list, observer) {
const mode = `notion-app-inner notion-${
window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light'
}-theme`;
if (notion_elem.className !== mode) notion_elem.className = mode;
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', handle);
}
}
});
},
},
};

170
mods/notion-icons/app.css Normal file
View File

@ -0,0 +1,170 @@
/*
* notion-icons
* (c) 2019 jayhxmo (https://jaymo.io/)
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
.hide-active-bar > :nth-child(2) {
display: none;
}
.notion-icons--tab,
.notion-icons--tab > div {
color: var(--theme--text) !important;
}
.notion-icons--tab > div:hover,
.notion-icons--icon:hover,
.notion-icons--toggle:hover {
background: var(--theme--interactive_hover);
box-shadow: 0 0 0 0.5px var(--theme--interactive_hover-border) !important;
}
#notion-icons {
position: absolute;
top: 1px;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
flex-direction: column;
align-items: stretch;
background: var(--theme--card);
border-radius: 3px;
padding: 8px 12px;
overflow-x: hidden;
overflow-y: scroll;
}
.notion-icons--icon-set {
margin-bottom: 8px;
color: var(--theme--text);
font-size: 11px;
line-height: 1.5;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 600;
border-radius: 2px;
}
.notion-icons--icon-set.error {
color: var(--theme--text_red);
background: var(--theme--line_red);
border: 1px solid var(--theme--select_red);
padding: 8px 16px;
}
.notion-icons--icon-set.error::after {
content: '!';
display: block;
font-size: 1.6em;
line-height: 0.9;
float: right;
}
.notion-icons--icon-set.alert .notion-icons--toggle {
color: var(--theme--line_yellow-text);
background: var(--theme--line_yellow);
border: 1px solid var(--theme--select_yellow);
margin-left: -1px;
margin-right: -1px;
}
.notion-icons--icon-set.alert .notion-icons--toggle:hover {
background: var(--theme--select_yellow);
}
.notion-icons--toggle {
display: flex;
align-items: center;
user-select: none;
cursor: pointer;
margin-bottom: 8px;
padding: 0.25em;
border-radius: 2px;
transition: background 200ms, margin-bottom 200ms ease-in;
}
.notion-icons--toggle .triangle {
width: 0.9em;
height: 1em;
margin: 0 0.75em 0 0.5em;
transition: transform 200ms ease-out 0s;
transform: rotateZ(180deg);
}
.notion-icons--toggle a {
color: var(--theme-text);
transition: color 20ms ease-in;
}
.notion-icons--toggle a:hover {
color: var(--theme--primary);
}
.notion-icons--body {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
flex-grow: 1;
margin-left: 1.2em;
overflow: hidden;
transition: height 200ms ease-in, opacity 200ms ease-in;
}
.hidden-set {
padding-bottom: 0;
}
.hidden-set .notion-icons--toggle {
margin-bottom: 0;
}
.hidden-set .triangle {
transform: rotateZ(90deg);
}
.hidden-set .notion-icons--body {
opacity: 0;
}
.notion-icons--icon {
cursor: pointer;
user-select: none;
transition: background 20ms ease-in;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
width: 40px;
height: 40px;
padding: 4px;
}
.notion-icons--icon.error {
font-size: 20px;
background: var(--theme--line_yellow);
border: 1px solid var(--theme--select_yellow);
color: var(--theme--text_yellow);
}
.notion-icons--icon.error:hover {
background: var(--theme--select_yellow);
}
.notion-icons--icon img {
width: 100%;
height: 100%;
}
.notion-icons--spinner img {
animation: rotation 1.3s infinite linear;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}

363
mods/notion-icons/mod.js Normal file
View File

@ -0,0 +1,363 @@
/*
* notion-icons
* (c) 2019 jayhxmo (https://jaymo.io/)
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
'use strict';
const { createElement } = require('../../pkg/helpers.js'),
fs = require('fs-extra');
module.exports = {
id: '2d1f4809-9581-40dd-9bf3-4239db406483',
tags: ['extension'],
name: 'notion icons',
desc:
'Use custom icon sets directly in Notion.',
version: '1.0.0',
author: 'jayhxmo',
options: [
{
key: 'hide',
label: 'hide icon sets by default.',
type: 'toggle',
value: false,
},
{
key: 'json',
label: 'insert custom json',
type: 'file',
extensions: ['json'],
},
],
hacks: {
'renderer/preload.js'(store, __exports) {
let garbageCollector = [];
const iconsUrl = 'https://raw.githubusercontent.com/notion-enhancer/icons/main/';
function getAsync(urlString, callback) {
let httpReq = new XMLHttpRequest();
httpReq.onreadystatechange = function() {
if (httpReq.readyState == 4 && httpReq.status == 200) callback(httpReq.responseText);
};
httpReq.open('GET', urlString, true);
httpReq.send(null);
}
// Retrieve Icons data
let notionIconsData;
getAsync(iconsUrl + 'icons.json', iconsData => {
notionIconsData = JSON.parse(iconsData);
});
// Retrieve custom Icons data
let customIconsData;
if (store().json) {
customIconsData = JSON.parse(
fs.readFileSync(store().json)
)
}
function getTab(n, button = false) {
return document.querySelector(
`.notion-media-menu > :first-child > :first-child > :nth-child(${n}) ${button ? 'div' : ''}`
);
}
function isCurrentTab(n) {
return getTab(n).childNodes.length > 1;
}
// Submits the icon's url as an image link
function setPageIcon(iconUrl) {
const input = document.querySelector('input[type=url]');
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype, 'value'
).set;
nativeInputValueSetter.call(input, iconUrl);
input.dispatchEvent(
new Event('input', { bubbles: true })
);
input.dispatchEvent(
new KeyboardEvent('keydown', { bubbles: true, cancelable: true, keyCode: 13 })
);
removeIcons();
}
function addIconsTab() {
// Disconnect observer if the modal is open.
if (document.querySelector('.notion-overlay-container'))
overlayContainerObserver.disconnect();
// Prevent Icons tab duplication
if (getTab(5)) {
removeIcons();
return;
}
// Change 'Upload an image' to 'Upload'
getTab(2, true).innerText = 'Upload';
// Initialize Icons tab
const iconsTab = getTab(3).cloneNode(true);
iconsTab.className = 'notion-icons--tab'
iconsTab.firstChild.innerText = 'Icons';
iconsTab.firstChild.addEventListener('click', renderIconsOverlay);
// Insert Icons tab
const tabStrip = getTab(1).parentElement;
tabStrip.insertBefore(iconsTab, tabStrip.lastChild);
// Remove the Icons overlay when clicking...
const closeTriggers = [
// The fog layer
document.querySelector('.notion-overlay-container [style*="width: 100vw; height: 100vh;"]'),
// The first three buttons
...Array.from( Array(3), (e, i) => getTab(i + 1, true) ),
// The remove button
getTab(5).lastChild,
];
closeTriggers.forEach(trigger => {
trigger.addEventListener('click', removeIcons);
garbageCollector.push(trigger);
})
// Remove the Icons overlay when pressing the Escape key
document.querySelector('.notion-media-menu')
.addEventListener('keydown', e => {
if (e.keyCode === 27) removeIcons();
});
}
function renderIconSet(iconData) {
const iconSet = createElement(
'<div class="notion-icons--icon-set"></div>'
)
try {
const authorText = iconData.author
? iconData.authorUrl
? ` by <a target="_blank" href="${iconData.authorUrl}" style="opacity: 0.6;">${iconData.author}</a>`
: ` by <span style="opacity: 0.6;">${iconData.author}</span>`
: '';
const iconSetToggle = createElement(
`<div class="notion-icons--toggle">
<svg viewBox="0 0 100 100" class="triangle"><polygon points="5.9,88.2 50,11.8 94.1,88.2"></polygon></svg>
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${iconData.name}${authorText}</div>
<div class="notion-icons--spinner" style="margin-left: auto; margin-right: 8px; width: 1.2em; height: 1.2em;">
<img src="/images/loading-spinner.4dc19970.svg" />
</div>
</div>`
);
const iconSetBody = createElement(
'<div class="notion-icons--body"></div>'
);
iconSet.append(iconSetToggle);
iconSet.append(iconSetBody);
const promiseArray = [];
// Render Icons
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];
const icon = createElement(`<div class="notion-icons--icon"><img src="${iconUrl}" /></div>`);
iconSetBody.append(icon);
garbageCollector.push(icon);
icon.addEventListener('click', () => setPageIcon(iconUrl));
// Make sure elements load
promiseArray.push(
new Promise((resolve, reject) => {
icon.firstChild.onload = resolve;
icon.firstChild.onerror = () => {
reject();
icon.classList.add('error');
icon.innerHTML = '!';
};
})
);
}
// Hide spinner after all icons finish loading
(async () => {
const spinner = iconSetToggle.querySelector('.notion-icons--spinner'),
loadPromise = Promise.all(promiseArray);
loadPromise.then(
() => spinner.remove(),
() => {
iconSet.classList.add('alert')
spinner.remove();
}
)
})();
// Set up Toggle
requestAnimationFrame(() => {
iconSetBody.style.height = iconSetBody.style.maxHeight = `${iconSetBody.offsetHeight}px`;
if (store().hide) iconSetToggle.click();
});
iconSetToggle.addEventListener('click', e => {
if (e.target.nodeName === 'A') return;
iconSet.classList.toggle('hidden-set')
iconSetBody.style.height = iconSet.classList.contains('hidden-set')
? 0
: iconSetBody.style.maxHeight;
});
} catch (err) {
iconSet.classList.add('error');
iconSet.innerHTML = `Invalid Icon Set: ${iconData.name}`;
}
return iconSet;
}
function renderIconsOverlay() {
if (!isCurrentTab(4)) {
// Switch to 3rd tab so that the link can be inputed in the underlay
if (!isCurrentTab(3)) getTab(3, true).click();
// Set active bar on Icons Tab
const iconsTab = getTab(4);
const activeBar = createElement(
`<div id="notion-icons--active-bar"></div>`
)
activeBar.style = 'border-bottom: 2px solid var(--theme--text); position: absolute; bottom: -1px; left: 8px; right: 8px;';
iconsTab.append(activeBar);
getTab(4).style.position = 'relative';
getTab(3).className = 'hide-active-bar';
// Convert Icons data into renderable
const iconSets = [];
if (customIconsData && customIconsData.icons) {
customIconsData.icons.forEach(i => {
iconSets.push( renderIconSet(i) );
});
// Divider
iconSets.push(
createElement(
'<div style="height: 1px; margin-bottom: 9px; border-bottom: 1px solid var(--theme--table-border);"></div>'
)
)
}
if (notionIconsData && notionIconsData.icons) {
notionIconsData.icons.forEach(i => {
i.sourceUrl = i.sourceUrl || (iconsUrl + i.source);
iconSets.push( renderIconSet(i) );
});
}
// Create Icons overlay
const notionIcons = createElement(
'<div id="notion-icons"></div>'
);
iconSets.forEach( set => notionIcons.append(set) );
// Insert Icons overlay
document.querySelector('.notion-media-menu > .notion-scroller')
.append(notionIcons);
}
}
function removeIcons() {
const notionIcons = document.getElementById('notion-icons'),
activeBar = document.getElementById('notion-icons--active-bar');
if (notionIcons)
notionIcons.remove();
if (activeBar) {
activeBar.remove();
getTab(4).style.position = '';
}
getTab(3).className = '';
if (garbageCollector.length) {
for (let i = 0; i < garbageCollector.length; i++) {
garbageCollector[i] = null;
}
garbageCollector = [];
}
}
// Wait for DOM change before adding the Icons tab
// (React does not render immediately on click)
const overlayContainerObserver = new MutationObserver(list => {
if (list) addIconsTab()
});
function initializeIcons() {
overlayContainerObserver.observe(
document.querySelector('.notion-overlay-container'),
{ attributes: true, childList: true, characterData: true }
);
}
// Initialize icons tab when clicking on notion page icons
function initializeIconTriggerListener() {
const iconTriggers = document.querySelectorAll('.notion-record-icon[aria-disabled="false"]');
iconTriggers.forEach(trigger => {
trigger.removeEventListener('click', initializeIcons);
trigger.addEventListener('click', initializeIcons);
garbageCollector.push(trigger);
});
}
document.addEventListener('readystatechange', () => {
if (document.readyState !== 'complete') return false;
let queue = [];
const observer = new MutationObserver((list, observer) => {
if (!queue.length) requestAnimationFrame(() => process(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
function process(list) {
queue = [];
for (let { addedNodes } of list) {
if (
addedNodes[0] && (
(
addedNodes[0].classList && (
addedNodes[0].className === 'notion-page-content' ||
addedNodes[0].classList.contains('notion-record-icon') ||
addedNodes[0].classList.contains('notion-page-block') ||
addedNodes[0].classList.contains('notion-callout-block')
)
) || addedNodes[0].nodeName === 'A'
)
) {
initializeIconTriggerListener();
}
}
}
});
},
},
};

View File

@ -1,14 +1,13 @@
/** /*
* notion-enhancer: dracula * pastel dark
* (c) 2016 Dracula Theme * (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill * (c) 2020 u/zenith_illinois
* (c) 2020 mimishahzad * under the MIT license
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (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/use-case-note.png'],
.notion-dark-theme img[src*='/images/onboarding/team-features-illustration.png'] { .notion-dark-theme
img[src*='/images/onboarding/team-features-illustration.png'] {
filter: invert(1) !important; filter: invert(1) !important;
} }
.notion-dark-theme img[src*='/images/onboarding/checked.svg'] { .notion-dark-theme img[src*='/images/onboarding/checked.svg'] {
@ -27,7 +26,13 @@
filter: brightness(1.2); filter: brightness(1.2);
} }
.notion-dark-theme .notion-token-remove-button[role*='button'][tabindex*='0']:hover, .notion-dark-theme
[style*='font-family: iawriter-mono, Nitti, Menlo, Courier, monospace;'] {
filter: hue-rotate(170deg) !important;
}
.notion-dark-theme
.notion-token-remove-button[role*='button'][tabindex*='0']:hover,
.notion-dark-theme .notion-record-icon { .notion-dark-theme .notion-record-icon {
background: transparent !important; background: transparent !important;
} }
@ -35,8 +40,11 @@
.notion-dark-theme .notion-focusable:focus-within, .notion-dark-theme .notion-focusable:focus-within,
.notion-dark-theme .notion-to_do-block > div > div > div[style*='background:'], .notion-dark-theme .notion-to_do-block > div > div > div[style*='background:'],
.notion-dark-theme div[role='button'], .notion-dark-theme div[role='button'],
[style*='height: 4px;'] > .notion-selectable.notion-collection_view_page-block > *, [style*='height: 4px;']
.notion-dark-theme .notion-calendar-view-day[style*='background: #282a36;'], > .notion-selectable.notion-collection_view_page-block
> *,
.notion-dark-theme
.notion-calendar-view-day[style*='background: rgb(235, 87, 87);'],
.DayPicker-Day--today, .DayPicker-Day--today,
.notion-dark-theme .notion-dark-theme
.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker:not(.DayPicker--interactionDisabled)
@ -50,7 +58,7 @@
transition: color 0.4s ease, background 0.4s ease, box-shadow 0.4s ease !important; 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(63, 68, 71);'],
.notion-dark-theme .notion-dark-theme
[style*='background: rgb(80, 85, 88);'][style*='color: rgba(255, 255, 255, 0.7)'], [style*='background: rgb(80, 85, 88);'][style*='color: rgba(255, 255, 255, 0.7)'],
.notion-dark-theme .notion-dark-theme
@ -68,17 +76,3 @@
.notion-dark-theme [style*='background: rgba(255, 115, 105, 0.5)'] { .notion-dark-theme [style*='background: rgba(255, 115, 105, 0.5)'] {
box-shadow: 0 2px 4px rgb(0 0 0 / 66%) !important; 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;
}

21
mods/pastel-dark/mod.js Normal file
View File

@ -0,0 +1,21 @@
/*
* pastel dark
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 u/zenith_illinois
* under the MIT license
*/
'use strict';
module.exports = {
id: '033bff54-50ba-4cec-bdc0-b2ca7e307085',
tags: ['theme', 'dark'],
name: 'pastel dark',
desc: 'a smooth-transition true dark theme with a hint of pastel.',
version: '0.1.4',
author: {
name: 'zenith_illinois',
link: 'https://www.reddit.com/user/zenith_illinois/',
avatar: 'https://www.redditstatic.com/avatars/avatar_default_18_46A508.png',
},
};

View File

@ -0,0 +1,119 @@
/*
* pastel dark
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 u/zenith_illinois
* under the MIT license
*/
@import 'https://rsms.me/inter/inter.css';
:root {
--theme_dark--main: #0b0b0b;
--theme_dark--sidebar: #0f0f0f;
--theme_dark--overlay: rgba(15, 15, 15, 0.6);
--theme_dark--dragarea: #0d0d0d;
--theme_dark--font_sans: 'Inter', -apple-system, BlinkMacSystemFont,
'Segoe UI', Helvetica, 'Apple Color Emoji', Arial, sans-serif,
'Segoe UI Emoji', 'Segoe UI Symbol';
--theme_dark--scrollbar: #141414;
--theme_dark--scrollbar_hover: #1b1b1b;
--theme_dark--card: #0f0f0f;
--theme_dark--gallery: rgba(8, 8, 8, 0.05);
--theme_dark--select_input: #0d0d0d;
--theme_dark--table-border: rgba(255, 255, 255, 0.1);
--theme_dark--ui-border: var(--theme_dark--table-border);
--theme_dark--interactive_hover: #1e1e1e5c;
--theme_dark--button_close: #eb5757;
--theme_dark--selected: rgba(184, 135, 247, 0.3);
--theme_dark--primary: #b887f7;
--theme_dark--primary_hover: #08d7c2;
--theme_dark--primary_click: #b887f7;
--theme_dark--primary_indicator: #08d7c2;
--theme_dark--option_active-background: var(--theme_dark--primary);
--theme_dark--option_hover-background: var(--theme_dark--primary_hover);
--theme_dark--danger_text: #eb5757;
--theme_dark--danger_border: rgba(235, 87, 87, 0.5);
--theme_dark--text: #ffffff;
--theme_dark--text_ui: #909090;
--theme_dark--text_ui_info: #464646;
--theme_dark--text_gray: #b1aeab;
--theme_dark--text_brown: #d8b6a6;
--theme_dark--text_orange: #fde3c0;
--theme_dark--text_yellow: #fcde93;
--theme_dark--text_green: #b3f5c8;
--theme_dark--text_blue: #bfe0fd;
--theme_dark--text_purple: #dac7fa;
--theme_dark--text_pink: #f7b8dc;
--theme_dark--text_red: #f8acb4;
--theme_dark--bg-text: rgb(55, 53, 47);
--theme_dark--bg_gray: #b1aeab;
--theme_dark--bg_brown: #d8b6a6;
--theme_dark--bg_orange: #fde3c0;
--theme_dark--bg_yellow: #fcde93;
--theme_dark--bg_green: #b3f5c8;
--theme_dark--bg_blue: #bfe0fd;
--theme_dark--bg_purple: #dac7fa;
--theme_dark--bg_pink: #f7b8dc;
--theme_dark--bg_red: #f8acb4;
--theme_dark--line-text: rgb(34, 34, 34);
--theme_dark--line_gray: #c2c1c089;
--theme_dark--line_brown: #dacec992;
--theme_dark--line_orange: #fff0dc9f;
--theme_dark--line_yellow: #ffe6a6ad;
--theme_dark--line_green: #c8fdd9a3;
--theme_dark--line_blue: #d1e9ffa3;
--theme_dark--line_purple: #e3d3ffa8;
--theme_dark--line_pink: #fdcce8b1;
--theme_dark--line_red: #ffc8ce9e;
--theme_dark--select-text: var(--theme_dark--bg-text);
--theme_dark--select_gray: var(--theme_dark--bg_gray);
--theme_dark--select_brown: var(--theme_dark--bg_brown);
--theme_dark--select_orange: var(--theme_dark--bg_orange);
--theme_dark--select_yellow: var(--theme_dark--bg_yellow);
--theme_dark--select_green: var(--theme_dark--bg_green);
--theme_dark--select_blue: var(--theme_dark--bg_blue);
--theme_dark--select_purple: var(--theme_dark--bg_purple);
--theme_dark--select_pink: var(--theme_dark--bg_pink);
--theme_dark--select_red: var(--theme_dark--bg_red);
--theme_dark--callout-text: var(--theme_dark--line-text);
--theme_dark--callout_gray: var(--theme_dark--line_gray);
--theme_dark--callout_brown: var(--theme_dark--line_brown);
--theme_dark--callout_orange: var(--theme_dark--line_orange);
--theme_dark--callout_yellow: var(--theme_dark--line_yellow);
--theme_dark--callout_green: var(--theme_dark--line_green);
--theme_dark--callout_blue: var(--theme_dark--line_blue);
--theme_dark--callout_purple: var(--theme_dark--line_purple);
--theme_dark--callout_pink: var(--theme_dark--line_pink);
--theme_dark--callout_red: var(--theme_dark--line_red);
--theme_dark--code_inline-text: #b3f5c8;
--theme_dark--code_inline-background: rgb(8, 8, 8);
--theme_dark--code-text: var(--theme_dark--text);
--theme_dark--code-background: #0f0f0f;
--theme_dark--code_function: var(--theme_dark--text_blue);
--theme_dark--code_keyword: var(--theme_dark--text_pink);
--theme_dark--code_tag: var(--theme_dark--text_pink);
--theme_dark--code_operator: var(--theme_dark--text_yellow);
--theme_dark--code_important: var(--theme_dark--text_yellow);
--theme_dark--code_property: var(--theme_dark--text_pink);
--theme_dark--code_builtin: var(--theme_dark--text_yellow);
--theme_dark--code_attr-name: var(--theme_dark--text_yellow);
--theme_dark--code_comment: var(--theme_dark--text_gray);
--theme_dark--code_punctuation: var(--theme_dark--text_gray);
--theme_dark--code_doctype: var(--theme_dark--text_gray);
--theme_dark--code_number: var(--theme_dark--text_purple);
--theme_dark--code_string: var(--theme_dark--text_orange);
--theme_dark--code_attr-value: var(--theme_dark--text_orange);
}

View File

@ -0,0 +1,48 @@
/*
* property layout
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 alexander-kazakov
* under the MIT license
*/
.propertylayout-enhanced {
overflow: hidden;
transition: max-height 200ms ease-in, opacity 200ms ease-in;
}
.propertylayout-hidden {
max-height: 0 !important;
opacity: 0;
}
.propertylayout-toggle {
width: 100%;
text-align: left;
font-size: 0.85em;
font-weight: 600;
padding: 0.25em;
background: transparent;
color: var(--theme--text_ui);
border: none;
border-radius: 2px;
transition: background 200ms, margin-bottom 200ms ease-in;
}
.notion-scroller.vertical > div > :first-child .propertylayout-toggle {
margin-top: 1em;
}
.propertylayout-toggle[data-action='show'] {
margin-bottom: 1em;
}
.propertylayout-toggle:hover {
background: var(--theme--interactive_hover);
}
.propertylayout-toggle .triangle {
width: 0.6875em;
height: 0.6875em;
margin: 0 0.75em 0 0.5em;
transition: transform 200ms ease-out 0s;
transform: rotateZ(90deg);
}
.propertylayout-toggle[data-action="hide"] .triangle {
transform: rotateZ(180deg);
}

View File

@ -0,0 +1,78 @@
/*
* property layout
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 alexander-kazakov
* under the MIT license
*/
'use strict';
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: '4034a578-7dd3-4633-80c6-f47ac5b7b160',
tags: ['extension'],
name: 'property layout',
desc: 'auto-collapse page properties that usually push down page content.',
version: '0.2.4',
author: 'alexander-kazakov',
hacks: {
'renderer/preload.js'(store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
let queue = [];
const observer = new MutationObserver((list, observer) => {
if (!queue.length) requestAnimationFrame(() => handle(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
function handle(list) {
queue = [];
let properties = document.querySelector(
'.notion-scroller.vertical [style*="env(safe-area-inset-left)"] > [style="width: 100%; font-size: 14px;"]'
);
if (
properties &&
!properties.classList.contains('propertylayout-enhanced')
) {
properties.classList.add(
'propertylayout-enhanced',
'propertylayout-hidden'
);
const toggle = createElement(
'<button class="propertylayout-toggle" data-action="show">Properties</button>'
);
toggle.prepend(
createElement('<svg viewBox="0 0 100 100" class="triangle"><polygon points="5.9,88.2 50,11.8 94.1,88.2 "></polygon></svg>')
);
toggle.addEventListener('click', (event) => {
properties.style.maxHeight = properties.children[0].offsetHeight + 'px';
setTimeout(() => {
properties.classList.toggle('propertylayout-hidden');
toggle.setAttribute(
'data-action',
properties.classList.contains('propertylayout-hidden')
? 'show'
: 'hide'
);
}, 0);
});
const propObserver = new MutationObserver(() => {
properties.style.maxHeight = '';
});
propObserver.observe(properties, {
childList: true,
subtree: true,
});
if (properties.previousElementSibling) {
properties.previousElementSibling.append(toggle);
} else properties.parentElement.prepend(toggle);
}
}
});
},
},
};

67
mods/right-to-left/mod.js Normal file
View File

@ -0,0 +1,67 @@
/*
* right-to-left
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Omar Bahareth
* under the MIT license
*/
'use strict';
module.exports = {
id: 'b28ee2b9-4d34-4e36-be8a-ab5be3d79f51',
tags: ['extension'],
name: 'right-to-left',
desc: 'enables auto rtl/ltr text direction detection.',
version: '1.4.1',
author: 'obahareth',
hacks: {
'renderer/preload.js'(store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
let queue = [];
const DOCUMENT_OBSERVER = new MutationObserver((list, observer) => {
if (!queue.length) requestIdleCallback(() => handle(queue));
queue.push(...list);
}),
PAGE_OBSERVER = new MutationObserver(autoAlignPageContent);
DOCUMENT_OBSERVER.observe(document.body, {
childList: true,
subtree: true,
});
function handle(list) {
queue = [];
for (let { addedNodes } of list) {
if (
addedNodes[0] &&
addedNodes[0].className === 'notion-page-content'
) {
autoAlignPageContent();
PAGE_OBSERVER.disconnect();
PAGE_OBSERVER.observe(addedNodes[0], {
childList: true,
subtree: false,
});
}
}
}
function autoAlignPageContent() {
document
.querySelectorAll(
`.notion-page-content > div[data-block-id]:not([dir]):not(.notion-column_list-block),
[placeholder="Untitled"]:not([dir]),
.notion-column-block > div[data-block-id]:not([dir])`
)
.forEach((block) => block.setAttribute('dir', 'auto'));
document
.querySelectorAll(
"div[placeholder='List'], div[placeholder='To-do']"
)
.forEach((item) => {
item.style['text-align'] = '-webkit-auto';
});
}
});
},
},
};

View File

@ -0,0 +1,60 @@
/*
* scroll-to-top
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
.bottom-right-buttons {
position: absolute;
bottom: 33px;
right: 33px;
z-index: 101;
cursor: default;
pointer-events: none;
}
.bottom-right-buttons > div {
margin-top: 8px;
pointer-events: auto;
user-select: none;
transition: opacity 700ms ease 0s, color 700ms ease 0s,
transform 700ms ease 0s;
cursor: pointer;
position: static !important;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 100%;
font-size: 20px;
background: var(--theme--interactive_hover);
box-shadow: 0 0 0 0.5px var(--theme--interactive_hover-border);
}
.notion-scroll-button {
display: flex !important;
}
.notion-scroll-button.hidden {
pointer-events: none;
visibility: hidden;
opacity: 0;
transform: translateY(10px);
transition-property: opacity, transform, visibility;
transition-delay: 0, 0, 700ms;
}
.notion-scroll-button > svg {
width: 18px;
height: 18px;
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" fill="currentColor" viewBox="0 0 250 250"><path fill="currentColor" d="M102.683 234.52V110.968H67.5474L124.859 12.184L182.459 110.968H147.323V234.52H102.683Z"/></svg>

After

Width:  |  Height:  |  Size: 231 B

137
mods/scroll-to-top/mod.js Normal file
View File

@ -0,0 +1,137 @@
/*
* scroll-to-top
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
'use strict';
const { createElement } = require('../../pkg/helpers.js'),
path = require('path'),
fs = require('fs-extra');
module.exports = {
id: '0a958f5a-17c5-48b5-8713-16190cae1959',
tags: ['extension'],
name: 'scroll to top',
desc:
'add an arrow above the help button to scroll back to the top of a page.',
version: '1.0.0',
author: 'CloudHill',
options: [
{
key: 'smooth',
label: 'smooth scrolling',
type: 'toggle',
value: true,
},
{
key: 'top',
label: 'distance scrolled until button is shown:',
type: 'input',
value: 50,
},
{
key: 'unit',
label: 'unit to measure distance with:',
type: 'select',
value: ['percent', 'pixels'],
},
],
hacks: {
'renderer/preload.js'(store, __exports) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
const attempt_interval = setInterval(enhance, 500);
function enhance() {
if (!document.querySelector('.notion-frame')) return;
clearInterval(attempt_interval);
const $container = document.createElement('div');
const $help = document.querySelector('.notion-help-button');
const $scroll = createElement(
'<div class="notion-scroll-button" role="button"></div>'
);
(async () => {
$scroll.innerHTML = await fs.readFile(
path.resolve(`${__dirname}/arrow.svg`) // 🠙;
)
})();
$container.className = 'bottom-right-buttons';
$help.after($container);
$container.append($scroll);
$container.append($help);
if (store().top > 0) $scroll.classList.add('hidden');
$scroll.addEventListener('click', () => {
document.querySelector('.notion-frame > .notion-scroller').scroll({
top: 0,
left: 0,
behavior: store().smooth ? 'smooth' : 'auto',
});
});
let queue = [];
let $scroller = document.querySelector(
'.notion-frame > .notion-scroller'
);
let top = store().top || 0;
const observer = new MutationObserver((list, observer) => {
if (!queue.length) requestAnimationFrame(() => handle(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
function handle(list) {
queue = [];
setScrollDistance();
for (let { addedNodes } of list) {
if (
addedNodes[0] &&
(addedNodes[0].className === 'notion-page-content' ||
addedNodes[0].className === 'notion-scroller') &&
top > 0
) {
$scroll.classList.add('hidden');
$scroller = document.querySelector(
'.notion-frame > .notion-scroller'
);
setScrollDistance();
$scroller.addEventListener('scroll', (event) => {
if (
Math.ceil(event.target.scrollTop) < $scroller.top_distance
)
$scroll.classList.add('hidden');
else $scroll.classList.remove('hidden');
});
}
}
}
function setScrollDistance() {
$scroller.top_distance = top;
if (top > 0 && store().unit === 'percent') {
let content_height = Array.from($scroller.children).reduce(
(h, c) => h + c.offsetHeight,
0
);
$scroller.top_distance *=
(content_height - $scroller.offsetHeight) / 100;
}
}
}
});
},
},
};

49
mods/tabs/mod.js Normal file
View File

@ -0,0 +1,49 @@
/*
* tabs
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
// this is just a pseudo mod to "separate" the options
// from the core module - the core still handles actually
// making it work.
module.exports = {
id: 'e1692c29-475e-437b-b7ff-3eee872e1a42',
tags: ['core', 'extension'],
name: 'tabs',
desc: 'have multiple notion pages open in a single window.',
version: '0.1.0',
author: 'dragonwocky',
options: [
{
key: 'select_modifier',
label:
'tab select modifier (key+1, +2, +3, ... +9 and key+left/right arrows):',
type: 'select',
value: [
'Alt',
'Command',
'Control',
'Super',
'Alt+Shift',
'Command+Shift',
'Control+Shift',
'Super+Shift',
],
},
{
key: 'new_tab',
label: 'new tab keybinding:',
type: 'input',
value: 'CommandOrControl+T',
},
{
key: 'close_tab',
label: 'close tab keybinding:',
type: 'input',
value: 'CommandOrControl+W',
},
],
};

28
mods/topbar-icons/app.css Normal file
View File

@ -0,0 +1,28 @@
/*
* topbar icons
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
.notion-topbar-icon {
width: 32px;
padding: 0 7px !important;
}
.notion-topbar-icon:not(:first-child) > *:not(div) {
display: none !important;
}
.notion-topbar-icon > div,
.notion-topbar-icon svg {
width: 18px;
height: 18px;
}
.notion-topbar-icon[style*="padding-left: 8px"] > div > :last-child {
display: none;
}
.notion-topbar-icon[style*="padding-left: 6px"] > div > :first-child {
display: none;
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,6.8l1.3,2.6l0.6,1.2l1.3,0.2l2.8,0.4l-2,2l-1,0.9l0.2,1.3l0.5,2.8l-2.5-1.3L12,16.3l-1.2,0.6l-2.5,1.3l0.5-2.8L9,14.1 l-1-0.9l-2-2l2.8-0.4l1.3-0.2l0.6-1.2L12,6.8 M12,1.1L8.4,8.3L0.5,9.4L6.2,15l-1.4,7.9l7.1-3.7l7.1,3.7L17.7,15l5.8-5.6l-7.9-1.1 L12,1.1L12,1.1z"/></svg>

After

Width:  |  Height:  |  Size: 359 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><polygon points="12 1.1 15.6 8.3 23.5 9.4 17.8 15 19.1 22.9 12 19.2 4.9 22.9 6.2 15 .5 9.4 8.4 8.3"/></svg>

After

Width:  |  Height:  |  Size: 190 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18.5,15.1c-0.9,0-1.8,0.4-2.4,1l-7.3-3.6c0-0.2,0-0.3,0-0.5s0-0.4,0-0.5l7.3-3.6c0.6,0.6,1.4,1,2.4,1 c1.8,0,3.3-1.5,3.3-3.3s-1.5-3.3-3.3-3.3s-3.3,1.5-3.3,3.3c0,0.2,0,0.4,0,0.5L7.9,9.7c-0.6-0.6-1.4-1-2.4-1c-1.8,0-3.3,1.5-3.3,3.3 s1.5,3.3,3.3,3.3c0.9,0,1.8-0.4,2.4-1l7.3,3.6c0,0.2,0,0.3,0,0.5c0,1.8,1.5,3.3,3.3,3.3c1.8,0,3.3-1.5,3.3-3.3S20.3,15.1,18.5,15.1z"/></svg>

After

Width:  |  Height:  |  Size: 454 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><polygon points="20.6 6 18 3.4 12 9.4 6 3.4 3.4 6 9.4 12 3.4 18 6 20.6 12 14.6 18 20.6 20.6 18 14.6 12"/></svg>

After

Width:  |  Height:  |  Size: 194 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><polygon points="9.4 20.6 24 6 21.4 3.4 9.4 15.4 2.6 8.6 0 11.1"/></svg>

After

Width:  |  Height:  |  Size: 155 B

122
mods/topbar-icons/mod.js Normal file
View File

@ -0,0 +1,122 @@
/*
* topbar icons
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 CloudHill
* under the MIT license
*/
'use strict';
const { createElement } = require('../../pkg/helpers.js'),
path = require('path'),
fs = require('fs-extra');
module.exports = {
id: 'e0700ce3-a9ae-45f5-92e5-610ded0e348d',
tags: ['extension'],
name: 'topbar icons',
desc:
'replaces the topbar buttons with icons.',
options: [
{
key: 'share',
label: 'share',
type: 'toggle',
value: true,
},
{
key: 'updates',
label: 'updates',
type: 'toggle',
value: true,
},
{
key: 'favorite',
label: 'favorite',
type: 'toggle',
value: true,
},
],
version: '1.0.0',
author: 'CloudHill',
hacks: {
'renderer/preload.js'(store, __exports) {
const icons = {
selected: [
...(store().updates ? ['updates'] : []),
...(store().favorite ? ['favorite'] : []),
],
share: fs.readFile(path.resolve(`${__dirname}/icons/share.svg`)),
updates: {
on: fs.readFile(path.resolve(`${__dirname}/icons/updates_on.svg`)),
off: fs.readFile(path.resolve(`${__dirname}/icons/updates_off.svg`)),
},
favorite: {
on: fs.readFile(path.resolve(`${__dirname}/icons/favorite_on.svg`)),
off: fs.readFile(path.resolve(`${__dirname}/icons/favorite_off.svg`)),
},
};
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
const attempt_interval = setInterval(enhance, 500);
function enhance() {
if (!document.querySelector('.notion-topbar-actions')) return;
clearInterval(attempt_interval);
setIcons(document.querySelector('.notion-topbar-actions'));
let queue = [];
const observer = new MutationObserver((list, observer) => {
if (!queue.length) requestAnimationFrame(() => handle(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
function handle(list) {
queue = [];
for (let { addedNodes } of list) {
if (
addedNodes[0] &&
addedNodes[0].className === 'notion-page-content' &&
document.querySelector('.notion-peek-renderer')
) {
const $topbarButtons = document.querySelector(
'.notion-peek-renderer .notion-topbar-share-menu'
).parentElement;
if ($topbarButtons.className == 'notion-topbar-actions') return;
$topbarButtons.className = 'notion-topbar-actions';
setIcons($topbarButtons);
}
}
}
async function setIcons(buttons) {
const buttonList = buttons.children;
if (store().share) {
buttonList[0].classList.add('notion-topbar-icon');
buttonList[0].innerHTML = await icons.share;
}
const elements = {
updates: buttonList[1],
favorite: buttonList[2],
};
for (let btn of icons.selected) {
elements[btn].classList.add('notion-topbar-icon')
elements[btn].prepend(
createElement(
`<div>${(await icons[btn].off).toString()}
${(await icons[btn].on).toString()}</div>`
)
);
}
}
}
});
},
},
};

100
mods/tweaks/app.css Normal file
View File

@ -0,0 +1,100 @@
/*
* tweaks
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
[data-tweaks*='[responsive_breakpoint]']
.notion-column_list-block
[style='display: flex;']
> div {
width: 100% !important;
}
[data-tweaks*='[responsive_breakpoint]']
.notion-column_list-block
[style='display: flex;'] {
flex-direction: column !important;
}
[data-tweaks*='[responsive_breakpoint]'] .notion-app-inner {
--theme_dark--page_normal-width: 100%;
--theme_dark--page-padding: calc(48px + env(safe-area-inset-left));
--theme_light--page_normal-width: 100%;
--theme_light--page-padding: calc(48px + env(safe-area-inset-left));
}
[data-tweaks*='[snappy_transitions]'] * {
animation-duration: 0s !important;
transition-duration: 0s !important;
}
[data-tweaks*='[snappy_transitions]'] .notion-selectable-halo {
opacity: 1 !important;
}
[data-tweaks*='[hide_help]'] .notion-help-button {
display: none !important;
}
[data-tweaks*='[thicker_bold]']
.notion-page-content
span[style*='font-weight:600'] {
font-weight: 700 !important;
}
[data-tweaks*='[spaced_lines]'] {
--theme_dark--text-block_line-height: 1.65;
--theme_dark--text-block_margin-top: 0.75em;
--theme_light--text-block_line-height: 1.65;
--theme_light--text-block_margin-top: 0.75em;
}
[data-tweaks*='[condensed_bullets]']
.notion-selectable.notion-bulleted_list-block {
line-height: 1.1 !important;
margin-top: -1.5px !important;
margin-bottom: -1.5px !important;
}
[data-tweaks*='[indentation_lines']
div.notion-selectable.notion-bulleted_list-block > div > div:last-child,
[data-tweaks*='[indentation_lines']
div.notion-selectable.notion-numbered_list-block > div > div:last-child {
position: relative;
}
[data-tweaks*='[indentation_lines']
div.notion-selectable.notion-bulleted_list-block > div > div:last-child::before,
[data-tweaks*='[indentation_lines']
div.notion-selectable.notion-numbered_list-block > div > div:last-child::before {
content: "";
position: absolute;
height: calc(100% - 2em);
top: 2em;
left: -14.48px;
border-left: 1px solid;
}
[data-tweaks*='[indentation_lines_dashed]']
div.notion-selectable.notion-bulleted_list-block > div > div:last-child::before,
[data-tweaks*='[indentation_lines_dashed]']
div.notion-selectable.notion-numbered_list-block > div > div:last-child::before {
border-left-style: dashed;
}
[data-tweaks*='[indentation_lines_dotted]']
div.notion-selectable.notion-bulleted_list-block > div > div:last-child::before,
[data-tweaks*='[indentation_lines_dotted]']
div.notion-selectable.notion-numbered_list-block > div > div:last-child::before {
border-left-style: dotted;
}
[data-tweaks*='[indentation_lines_soft]']
div.notion-selectable.notion-bulleted_list-block > div > div:last-child::before,
[data-tweaks*='[indentation_lines_soft]']
div.notion-selectable.notion-numbered_list-block > div > div:last-child::before {
opacity: 0.25;
}
[data-tweaks*='[scroll_db_toolbars]'] .notion-frame > .notion-scroller > [style*="overflow: visible;"],
[data-tweaks*='[scroll_db_toolbars]'] .notion-page-content .notion-collection_view-block > :first-child {
overflow-x: auto !important;
}
[data-tweaks*='[scroll_db_toolbars]'] .notion-frame > .notion-scroller > [style*="overflow: visible;"]::-webkit-scrollbar,
[data-tweaks*='[scroll_db_toolbars]'] .notion-page-content .notion-collection_view-block > :first-child::-webkit-scrollbar {
display: none;
}

Some files were not shown because too many files have changed in this diff Show More