This commit is contained in:
runargs 2020-10-27 12:40:59 -04:00
commit 93ba1a44a6
40 changed files with 659 additions and 511 deletions

View File

@ -13,27 +13,27 @@ a flexibility update.
higher up on the list = higher priority of application = loaded last in order to override others.
(excluding the core, which though pinned to the top of the list is always loaded first so theming
variables can be modified.)
- new: in-page columns are disabled/wrapped and pages are wider when
the window is narrower than 600px for improved responsiveness.
- new: relaunch button in tray menu.
- new: a core mod option to make transitions snappy/0s.
- new: a core mod option for a default page id/url (all new windows will load it instead of the
normal "most recent" page).
- new: css variables for increasing line spacing/paragraph margins.
- new: patch the notion:// url scheme/protocol to work on linux.
- new: menu shows theme conflicts + a core mod option to auto-resolve theme conflicts.
- new: a `-n` cli option.
- improved: menu will now respect integrated titlebar setting.
- improved: use keyup listeners instead of a globalShortcut for the enhancements menu toggle.
- improved: overwrite `app.asar.bak` if already exists (e.g. for app updates).
- improved: additional menu option descriptions on hover.
- improved: listen to prefers-color-scheme to better change theme in night shift.
- bugfix: removed messenger emoji set as the provider no longer supports it.
- bugfix: remove shadow around light mode board headers
\+ minor text colour fixes for night shift theming.
- bugfix: remove shadow around light mode board headers.
- bugfix: properly detect/respond to `EACCES`/`EBUSY` errors.
- bugfix: night shift checks every interaction,
will respond to system changes without any manual changes.
- bugfix: toc blocks can have text colours.
- bugfix: bypass preview extension works with the back/forward keyboard shortcuts.
- bugfix: (maybe) fix csp issues under proxy.
- bugfix: remove focus mode footer from neutral theme.
- bugfix: remove focus mode footer from neutral theme + better contrast in calendar views.
- bugfix: improvements to the colour theming, particularly to make real- and fake-light/dark
modes (as applied by the night shift extension) look consistent.
relevant variables (assuming all are prefixed by `--theme_[dark|light]--`):
@ -44,23 +44,35 @@ a flexibility update.
- bugfix: right-to-left extension applies to text in columns.
- bugfix: block text colour applies to text with backgrounds.
- bugfix: font applied to wrong mode with littlepig dark.
- bugfix: keep "empty" top bar visible in the menu.
- bugfix: set NSRequiresAquaSystemAppearance to false in /Applications/Notion.app/Contents/Info.plist
so system dark/light mode can be properly detected.
- tweak: sticky table/list rows.
- theme: "material ocean" = an oceanic colour palette.
- theme: "dracula" = a theme based on the popular dracula color palette
originally by zeno rocha and friends.
- extension: "tabs" = have multiple notion pages open in a single window.
- extension: "tabs" = have multiple notion pages open in a single window. tabs can be controlled
with keyboard shortcuts and dragged/reordered within/between windows.
- extension: "scroll to top" = add an arrow above the help button to scroll back to the top of a page.
- extension: "tweaks" = common style/layout changes. includes:
- new: make transitions snappy/0s.
- new: in-page columns are disabled/wrapped and pages are wider when
the window is narrower than 600px for improved responsiveness.
- new: thicker bold text for better visibility.
- new: more readable line spacing.
- moved: smooth scrollbars.
- moved: change dragarea height.
- moved: hide help.
a fork of notion-deb-builder that does generate an app.asar has been created and is once again supported.
// todo
- bugfix: night shift working on macOS.
- bugfix: windows are properly hidden/shown on macOS.
- extension: "tweaks" = common style/layout changes.
- new: a `-n` cli option.
- improved: overwrite `app.asar.bak` if already exists.
- improved: additionally menu item descriptions on hover.
MACOS SPECIFIC FIXES
- close to tray: perma-true
- frameless mode: perma-false
- open ext. menu hotkey not working?
### v0.9.1 (2020-09-26)

View File

@ -49,7 +49,7 @@ 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
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 `$`.

View File

@ -51,6 +51,7 @@ module.exports = {
options?: Array<{
key: String,
label: String,
description?: String,
type: String in ['toggle', 'select', 'input', 'file'],
value: Boolean or Array<String> or String or Number or null
}>,
@ -94,13 +95,14 @@ if you'd rather customise this, pass this object:
#### 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_ |
| 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 |
| 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_ |
| description | **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 |
| type | value |
| ------ | -------------------- |

View File

@ -91,6 +91,7 @@ For more info, run any command with the `--help` flag:
Options:
-y, --yes : skip prompts (may overwrite data)
-n, --no : skip prompts (may cause failures)
-d, --dev : show detailed error messages (not recommended)
-h, --help : display usage information
-v, --version : display version number

6
bin.js
View File

@ -20,6 +20,7 @@ const cli = require('cac')('notion-enhancer'),
// ### 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');
cli
@ -27,7 +28,7 @@ cli
.action(async (options) => {
console.info('=== NOTION ENHANCEMENT LOG ===');
await require('./pkg/apply.js')({
overwrite_version: options.yes,
overwrite_version: options.yes ? 'y' : options.no ? 'n' : undefined,
friendly_errors: !options.dev,
});
console.info('=== END OF LOG ===');
@ -37,8 +38,7 @@ cli
.action(async (options) => {
console.info('=== NOTION RESTORATION LOG ===');
await require('./pkg/remove.js')({
overwrite_asar: options.yes,
delete_data: options.yes,
delete_data: options.yes ? 'y' : options.no ? 'n' : undefined,
friendly_errors: !options.dev,
});
console.info('=== END OF LOG ===');

View File

@ -6,7 +6,7 @@
'use strict';
const helpers = require('../../pkg/helpers.js');
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: 'b1c7db33-dfee-489a-a76c-0dd66f7ed29a',
@ -26,7 +26,7 @@ module.exports = {
if (!notion_elem) return;
clearInterval(attempt_interval);
const button = helpers.createElement(
const button = createElement(
'<button id="calendar-scroll-to-week">Scroll</button>'
);
button.addEventListener('click', (event) => {

View File

@ -24,7 +24,7 @@
/* Main */
--theme_dark--main: var(--cola-main);
--theme_dark--sidebar: var(--cola-sec);
--theme_dark--overlay: 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;

View File

@ -79,12 +79,6 @@ module.exports = (store, __exports) => {
return;
clearInterval(attempt_interval);
// toggleable styles
if (store().smooth_scrollbars)
document.body.classList.add('smooth-scrollbars');
if (store().snappy_transitions)
document.body.classList.add('snappy-transitions');
// frameless
if (store().frameless && !store().tiling_mode && !tabsEnabled) {
document.body.classList.add('frameless');
@ -92,10 +86,6 @@ module.exports = (store, __exports) => {
document
.querySelector('.notion-topbar')
.prepend(helpers.createElement('<div class="window-dragarea"></div>'));
document.documentElement.style.setProperty(
'--configured--dragarea_height',
`${store().dragarea_height + 2}px`
);
}
// window buttons
@ -156,8 +146,10 @@ module.exports = (store, __exports) => {
'--theme--sidebar',
'--theme--overlay',
'--theme--dragarea',
'--theme--box-shadow_strong',
'--theme--font_sans',
'--theme--font_code',
'--theme--font_label-size',
'--theme--scrollbar',
'--theme--scrollbar-border',
'--theme--scrollbar_hover',
@ -224,7 +216,38 @@ module.exports = (store, __exports) => {
if (tabsEnabled) {
let tab_title = '';
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 [aria-label]:not([src^="data:"])'
),
text = $container.querySelector('[placeholder="Untitled"]');
title =
(icon ? `<img src="${icon.getAttribute('src')}">` : '') +
(text
? text.innerText
: [
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 !== title) {
tab_title = title;
electron.ipcRenderer.sendToHost('enhancer:set-tab-title', title);

View File

@ -117,6 +117,9 @@ s {
#titlebar .window-buttons-area:empty {
display: none;
}
[data-platform='darwin'] #titlebar {
height: 2.65em;
}
/* alerts */
@ -342,6 +345,29 @@ s {
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 *,
@ -415,6 +441,7 @@ s {
}
.toggle input[type='checkbox'] + label .name {
flex-basis: calc(100% - 2.25em);
margin-right: 0.75em;
}
.toggle input[type='checkbox'] + label .switch {
position: relative;

View File

@ -1,26 +0,0 @@
/*
* notion-enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
@media (max-width: 600px) {
.notion-column_list-block [style='display: flex;'] > div {
width: 100% !important;
}
.notion-column_list-block [style='display: flex;'] {
flex-direction: column !important;
}
.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));
}
}
.snappy-transitions * {
animation-duration: 0s !important;
transition-duration: 0s !important;
}

View File

@ -5,25 +5,25 @@
* under the MIT license
*/
.smooth-scrollbars .notion-scroller {
[data-tweaks*='[smooth_scrollbars]'] .notion-scroller {
cursor: auto;
}
.smooth-scrollbars ::-webkit-scrollbar {
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar {
width: 8px; /* vertical */
height: 8px; /* horizontal */
-webkit-app-region: no-drag;
}
.smooth-scrollbars ::-webkit-scrollbar-corner {
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-corner {
background-color: transparent; /* overlap */
}
.smooth-scrollbars ::-webkit-scrollbar-thumb {
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-thumb {
border-radius: 5px;
}
.smooth-scrollbars ::-webkit-scrollbar-thumb {
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-thumb {
background-color: var(--theme--scrollbar);
border: 1px solid var(--theme--scrollbar-border);
}
.smooth-scrollbars ::-webkit-scrollbar-thumb:hover {
[data-tweaks*='[smooth_scrollbars]'] ::-webkit-scrollbar-thumb:hover {
background: var(--theme--scrollbar_hover);
}

View File

@ -75,6 +75,9 @@ body,
flex-direction: column;
}
[data-platform='darwin'] #titlebar {
padding-left: 4em;
}
#titlebar::before {
content: '';
position: absolute;
@ -127,6 +130,10 @@ body,
border-bottom: 4px solid var(--theme--table-border);
opacity: 0.8;
}
#tabs .tab img {
width: 1em;
margin: 0 0.5em -3px 0.1em;
}
#tabs .tab:first-child {
margin-top: 0.5em;
}

View File

@ -28,6 +28,7 @@
.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;
}
@ -198,7 +199,7 @@
/** text-block readability **/
.notion-selectable.notion-text-block {
.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;
}

View File

@ -14,6 +14,8 @@ const store = require('../../pkg/store.js'),
{ toKeyEvent } = require('keyboardevent-from-electron-accelerator');
window['__start'] = async () => {
document.body.setAttribute('data-platform', process.platform);
// mod loader
const modules = helpers.getEnhancements();
if (modules.loaded.length)
@ -137,7 +139,7 @@ window['__start'] = async () => {
!(event.ctrlKey || event.metaKey) && !event.altKey && !event.shiftKey;
if (
meta &&
document.activeElement.parentElement.id === 'tags' &&
document.activeElement.getAttribute('tabindex') === '0' &&
event.key === 'Enter'
)
document.activeElement.click();
@ -226,7 +228,7 @@ window['__start'] = async () => {
.map((mod) => `<b>${mod.name}</b>`)
.join(
', '
)}. <br> resolve or <span data-action="dismiss">dismiss</span> to continue.`
)}. <br> resolve or <span data-action="dismiss" tabindex="0">dismiss</span> to continue.`
);
alert.el
.querySelector('[data-action="dismiss"]')
@ -246,7 +248,7 @@ window['__start'] = async () => {
if (conflicts.relaunch) return;
conflicts.relaunch = createAlert(
'info',
'changes may not fully apply until <span data-action="relaunch">app relaunch</span>.'
'changes may not fully apply until <span data-action="relaunch" tabindex="0">app relaunch</span>.'
);
conflicts.relaunch.el
.querySelector('[data-action="relaunch"]')
@ -271,10 +273,13 @@ window['__start'] = async () => {
let text = '';
for (let $node of elem.childNodes) {
if ($node.nodeType === 3) text += $node.textContent;
if ($node.nodeType === 1)
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;
}
@ -387,24 +392,35 @@ window['__start'] = async () => {
}
const file_icon = await fs.readFile(
path.resolve(`${__dirname}/icons/file.svg`)
);
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 description = opt.description
? question_icon.replace(
'<svg',
`<svg data-tooltip="${opt.description.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}</span>
<span class="name">${opt.label}${description}</span>
<span class="switch"><span class="dot"></span></span>
</label>
`;
break;
case 'select':
$opt = `
<label for="${opt.type}_${id}--${opt.key}">${opt.label}</label>
<label for="${opt.type}_${id}--${opt.key}">${
opt.label
}${description}</label>
<select id="${opt.type}_${id}--${opt.key}">
${opt.value
.map((val) => `<option value="${val}">${val}</option>`)
@ -414,7 +430,9 @@ window['__start'] = async () => {
break;
case 'input':
$opt = `
<label for="${opt.type}_${id}--${opt.key}">${opt.label}</label>
<label for="${opt.type}_${id}--${opt.key}">${
opt.label
}${description}</label>
<input type="${typeof value === 'number' ? 'number' : 'text'}" id="${
opt.type
}_${id}--${opt.key}">
@ -422,7 +440,7 @@ window['__start'] = async () => {
break;
case 'color':
$opt = `
<label for="${opt.type}_${id}--${opt.key}">${opt.label}</label>
<label for="${opt.type}_${id}--${opt.key}">${opt.label}${description}</label>
<input type="button" id="${opt.type}_${id}--${opt.key}">
`;
break;
@ -438,7 +456,7 @@ window['__start'] = async () => {
}>
<label for="${opt.type}_${id}--${opt.key}">
<span class="label">
<span class="name">${opt.label}</span>
<span class="name">${opt.label}${description}</span>
<button class="clear"></button>
</span>
<span class="choose">
@ -485,8 +503,11 @@ window['__start'] = async () => {
);
}
const enabled = store('mods', { [mod.id]: { enabled: false } })[mod.id]
.enabled,
const enabled =
mod.alwaysActive ||
store('mods', {
[mod.id]: { enabled: false },
})[mod.id].enabled,
author =
typeof mod.author === 'object'
? mod.author
@ -496,14 +517,10 @@ window['__start'] = async () => {
avatar: `https://github.com/${mod.author}.png`,
};
mod.elem = helpers.createElement(`
<section class="${
mod.id === '0f0bf8b6-eae6-4273-b307-8fc43f2ee082' || enabled
? 'enabled'
: 'disabled'
}" id="${mod.id}">
<section class="${enabled ? 'enabled' : 'disabled'}" id="${mod.id}">
<div class="meta">
<h3 ${
mod.id === '0f0bf8b6-eae6-4273-b307-8fc43f2ee082'
mod.alwaysActive
? `>${mod.name}`
: `class="toggle">
<input type="checkbox" id="enable_${mod.id}"
@ -611,6 +628,25 @@ window['__start'] = async () => {
.forEach((checkbox) =>
checkbox.addEventListener('click', (event) => event.target.blur())
);
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')
);
});
conflicts.check();
// draggable re-ordering

View File

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 929 B

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html class="smooth-scrollbars" lang="en">
<html data-tweaks="[smooth_scrollbars]" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@ -31,6 +31,7 @@
<div id="popup-overlay" class="close-modal"></div>
<div id="colorpicker"></div>
</section>
<span id="tooltip"></span>
<script>
window['__start']();
</script>

View File

@ -8,6 +8,7 @@
module.exports = {
id: '0f0bf8b6-eae6-4273-b307-8fc43f2ee082',
alwaysActive: true,
tags: ['core'],
name: 'notion-enhancer core',
desc: 'the cli, modloader, menu, & tray.',
@ -17,72 +18,72 @@ module.exports = {
{
key: 'autoresolve',
label: 'auto-resolve theme conflicts',
description:
'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',
description:
'app can be made visible by clicking the tray icon or using the hotkey.',
type: 'toggle',
value: false,
},
{
key: 'maximized',
label: 'auto-maximise windows',
description:
'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',
description: `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,
},
{
key: 'frameless',
label: 'integrated titlebar',
description: `replace the native titlebar with buttons inset into the app.`,
type: 'toggle',
value: true,
},
{
key: 'dragarea_height',
label: 'height of frameless dragarea:',
type: 'input',
value: 15,
},
{
key: 'tiling_mode',
label: 'tiling window manager mode',
type: 'toggle',
value: false,
},
{
key: 'smooth_scrollbars',
label: 'integrated scrollbars',
type: 'toggle',
value: true,
},
{
key: 'snappy_transitions',
label: 'snappy transitions',
description: `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:',
description: 'used to toggle hiding/showing all app windows.',
type: 'input',
value: 'CommandOrControl+Shift+A',
},
{
key: 'menu_toggle',
label: 'open enhancements menu hotkey:',
description:
'used to toggle opening/closing this menu while notion is focused.',
type: 'input',
value: 'Alt+E',
},
{
key: 'default_page',
label: 'open to default page id/url:',
label: 'default page id/url:',
description: `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: '',
},

View File

@ -744,7 +744,11 @@ module.exports = (store, __exports) => {
this.views.tabs[id] = $tab;
},
},
React.createElement('span', {}, title),
React.createElement('span', {
dangerouslySetInnerHTML: {
__html: title,
},
}),
React.createElement(
'span',
{
@ -972,6 +976,8 @@ module.exports = (store, __exports) => {
window['__start'] = () => {
document.head.innerHTML += `<link rel="stylesheet" href="${__dirname}/css/tabs.css" />`;
document.body.setAttribute('data-platform', process.platform);
const modules = getEnhancements();
for (let mod of modules.loaded) {
for (let font of mod.fonts || []) {
@ -1069,7 +1075,7 @@ module.exports = (store, __exports) => {
dragarea.setAttribute(
'style',
`${default_styles} top: 2px; height: ${
store().dragarea_height
store('cf8a7b27-5a4c-4d45-a4cb-1d2bbc9e9014').dragarea_height
}px; left: ${event.args[0]};`
);
});

View File

@ -8,4 +8,3 @@
@import './css/variables.css';
@import './css/scrollbars.css';
@import './css/titlebar.css';
@import './css/responsive.css';

View File

@ -6,7 +6,7 @@
'use strict';
const helpers = require('../../pkg/helpers.js');
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: 'b4b0aced-2059-43bf-8d1d-ccd757ee5ebb',
@ -40,7 +40,7 @@ module.exports = {
document
.querySelector('head')
.appendChild(
helpers.createElement(
createElement(
`<style type="text/css">${fs.readFileSync(
store().css
)}</style>`

View File

@ -1,5 +1,5 @@
/*
* dracula-theme
* dracula
* (c) 2020 u/mimi-shahzad
* (c) 2020 Dracula Theme
* under the MIT license

View File

@ -1,30 +1,33 @@
/*
* dracula-theme
* dracula
* (c) 2020 u/mimi-shahzad
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (c) 2020 Dracula Theme
* under the MIT license
*/
:root {
--theme_dark--main: #282a36;
--theme_dark--sidebar: #282a36;
--theme_dark--overlay: #282a36;
--theme_dark--dragarea: #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: #282a36;
--theme_dark--scrollbar_hover: #6272a4;
--theme_dark--scrollbar: #393c4d;
--theme_dark--scrollbar_hover: #576591;
--theme_dark--card: #6272a4;
--theme_dark--gallery: #282a36;
--theme_dark--table-border: #6272a4;
--theme_dark--interactive_hover: #282a36;
--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: #3c3f50;
--theme_dark--button_close: #ff5555;
--theme_dark--selected: #454158;
--theme_dark--selected: rgba(189, 147, 249, 0.3);
--theme_dark--primary: #bd93f9;
--theme_dark--primary_hover: #8be9fd;
--theme_dark--primary_click: #bd93f9;
@ -40,7 +43,7 @@
--theme_dark--text_ui: #f8f8f2;
--theme_dark--text_ui_info: #f8f8f2;
--theme_dark--text_gray: #454158;
--theme_dark--text_gray: #807e8d;
--theme_dark--text_brown: #6272a4;
--theme_dark--text_orange: #ffb86c;
--theme_dark--text_yellow: #f1fa8c;
@ -52,7 +55,9 @@
--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;
@ -60,10 +65,13 @@
--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);
@ -71,10 +79,13 @@
--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: #454158;
--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;
@ -82,10 +93,13 @@
--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);
@ -93,11 +107,12 @@
--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: #44475a;
--theme_dark--code_inline-background: #3c3f50;
--theme_dark--code-text: var(--theme_dark--text);
--theme_dark--code-background: #44475a;
--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);
@ -107,8 +122,8 @@
--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: var(--theme_dark--text_gray);
--theme_dark--code_doctype: var(--theme_dark--text_gray);
--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);

View File

@ -1,16 +0,0 @@
/*
* hide help button
* (c) 2020 coryzibell
* under the MIT license
*/
'use strict';
module.exports = {
id: 'd4ebe9f3-974a-4c01-a6a9-94bc4296851d',
tags: ['extension'],
name: 'hide help',
desc: "hide the help button if you don't need it.",
version: '1.0.0',
author: 'coryzibell',
};

View File

@ -1,9 +0,0 @@
/*
* hide help button
* (c) 2020 coryzibell
* under the MIT license
*/
.notion-help-button {
display: none !important;
}

View File

@ -21,7 +21,7 @@
--theme_dark--main: var(--ocean-main);
--theme_dark--sidebar: var(--ocean-sec);
--theme_dark--overlay: var(--ocean-sec);
--theme_dark--overlay: rgba(0, 1, 10, 0.5);
--theme_dark--dragarea: var(--ocean-sec);
--theme_dark--scrollbar: var(--ocean-sec);

View File

@ -9,9 +9,11 @@
/** dark **/
--theme_dark--main: #131313;
--theme_dark--sidebar: #171717;
--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,
@ -36,7 +38,7 @@
--theme_dark--scrollbar-border: transparent;
--theme_dark--scrollbar_hover: #373838;
--theme_dark--card: #171717;
--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);

View File

@ -12,7 +12,7 @@ module.exports = {
name: 'night shift',
desc:
'sync dark/light theme with the system (overrides normal theme setting).',
version: '0.1.1',
version: '0.1.2',
author: 'dragonwocky',
hacks: {
'renderer/preload.js'(store, __exports) {
@ -23,19 +23,22 @@ module.exports = {
const notion_elem = document.querySelector('.notion-app-inner');
if (!notion_elem) return;
clearInterval(attempt_interval);
process([{ target: notion_elem }]);
const observer = new MutationObserver(process);
handle([{ target: notion_elem }]);
const observer = new MutationObserver(handle);
observer.observe(notion_elem, {
attributes: true,
subtree: true,
});
function process(list, observer) {
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);
}
}
});

View File

@ -7,7 +7,7 @@
'use strict';
const helpers = require('../../pkg/helpers.js');
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: '4034a578-7dd3-4633-80c6-f47ac5b7b160',
@ -42,7 +42,7 @@ module.exports = {
'propertylayout-enhanced',
'propertylayout-hidden'
);
const toggle = helpers.createElement(
const toggle = createElement(
'<button class="propertylayout-toggle" data-action="show">properties</button>'
);
toggle.addEventListener('click', (event) => {

98
mods/tweaks/mod.js Normal file
View File

@ -0,0 +1,98 @@
/*
* tweaks
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* under the MIT license
*/
'use strict';
module.exports = {
id: 'cf8a7b27-5a4c-4d45-a4cb-1d2bbc9e9014',
alwaysActive: true,
tags: ['core', 'extension'],
name: 'tweaks',
desc: 'common style/layout changes.',
version: '0.1.0',
author: 'dragonwocky',
options: [
{
key: 'dragarea_height',
label: 'height of frameless dragarea:',
description: `the rectangle added at the top of a window in "integrated titlebar" mode,\
used to drag/move the window.`,
type: 'input',
value: 15,
},
{
key: 'responsive_breakpoint',
label: 'width to wrap columns at:',
description: `the size in pixels below which in-page columns are resized to appear\
full width so content isn't squished.`,
type: 'input',
value: 600,
},
{
key: 'smooth_scrollbars',
label: 'integrated scrollbars',
description:
"use scrollbars that fit better into notion's ui instead of the default chrome ones.",
type: 'toggle',
value: true,
},
{
key: 'snappy_transitions',
label: 'snappy transitions',
type: 'toggle',
value: false,
},
{
key: 'thicker_bold',
label: 'thicker bold text',
type: 'toggle',
value: true,
},
{
key: 'spaced_lines',
label: 'more readable line spacing',
type: 'toggle',
value: false,
},
{
key: 'hide_help',
label: 'hide help button',
type: 'toggle',
value: false,
},
],
hacks: {
'renderer/preload.js': (store, __exports) => {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
document.body.dataset.tweaks = [
'smooth_scrollbars',
'snappy_transitions',
'thicker_bold',
'spaced_lines',
'hide_help',
]
.filter((tweak) => store()[tweak])
.map((tweak) => `[${tweak}]`)
.join('');
document.documentElement.style.setProperty(
'--configured--dragarea_height',
`${store().dragarea_height + 2}px`
);
const addResponsiveBreakpoint = () => {
document.body.dataset.tweaks = document.body.dataset.tweaks.replace(
/\[responsive_breakpoint\]/g,
''
);
if (window.outerWidth <= store().responsive_breakpoint)
document.body.dataset.tweaks += '[responsive_breakpoint]';
};
window.addEventListener('resize', addResponsiveBreakpoint);
addResponsiveBreakpoint();
});
},
},
};

45
mods/tweaks/styles.css Normal file
View File

@ -0,0 +1,45 @@
/*
* 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*='[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;
}

View File

@ -16,41 +16,38 @@ module.exports = {
author: 'adihd',
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);
process([{ target: notion_elem }]);
const observer = new MutationObserver(process);
observer.observe(notion_elem, {
childList: true,
subtree: true,
});
function process(list, observer) {
document
.querySelectorAll('.notion-collection-view-select')
.forEach((collection_view) => {
if (collection_view.innerText != 'weekly') return;
const days = collection_view.parentElement.parentElement.parentElement.parentElement.getElementsByClassName(
'notion-calendar-view-day'
),
today = [...days].find((day) => day.style.background),
height = today
? getComputedStyle(
today.parentElement.parentElement
).getPropertyValue('height')
: 0;
for (let day of days)
day.parentElement.parentElement.style.height = 0;
if (today)
today.parentElement.parentElement.style.height = height;
});
}
const attempt_interval = setInterval(enhance, 500);
function enhance() {
const notion_elem = document.querySelector('.notion-frame');
if (!notion_elem) return;
clearInterval(attempt_interval);
process([{ target: notion_elem }]);
const observer = new MutationObserver(process);
observer.observe(notion_elem, {
childList: true,
subtree: true,
});
function process(list, observer) {
document
.querySelectorAll('.notion-collection-view-select')
.forEach((collection_view) => {
if (collection_view.innerText != 'weekly') return;
const days = collection_view.parentElement.parentElement.parentElement.parentElement.getElementsByClassName(
'notion-calendar-view-day'
),
today = [...days].find((day) => day.style.background),
height = today
? getComputedStyle(
today.parentElement.parentElement
).getPropertyValue('height')
: 0;
for (let day of days)
day.parentElement.parentElement.style.height = 0;
if (today)
today.parentElement.parentElement.style.height = height;
});
}
});
}
},
},
};

View File

@ -6,9 +6,7 @@
'use strict';
const { createElement } = require('../../pkg/helpers.js'),
fs = require('fs-extra'),
path = require('path');
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: 'b99deb52-6955-43d2-a53b-a31540cd19a5',
@ -44,10 +42,7 @@ module.exports = {
if (2 <= secs) readable += 's';
}
return readable;
},
questionBubble = fs
.readFileSync(path.resolve(`${__dirname}/question.svg`))
.toString();
};
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
@ -109,12 +104,24 @@ module.exports = {
(prev, key) =>
prev +
(Array.isArray(details[key])
? `<p><b>${
details[key][0]
}</b> ${key} ${questionBubble.replace(
'<svg',
`<svg data-tooltip="${details[key][1]}"`
)}</p>`
? `<p>
<b>${details[key][0]}</b> ${key}
<!-- from https://fontawesome.com/icons/question-circle?style=regular -->
<svg data-tooltip="${details[key][1]}" 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"
></path>
</svg>
</p>`
: `<p><b>${details[key]}</b> ${key}</p>`),
''
)}`;

View File

@ -47,8 +47,7 @@
position: absolute;
padding: 0.25em 0.5em;
border-radius: 3px;
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);
border-right-width: 1px;
font-size: calc(var(--theme--font_label-size) * 0.8);
background: var(--theme--interactive_hover);

198
package-lock.json generated
View File

@ -1,198 +0,0 @@
{
"name": "notion-enhancer",
"version": "0.9.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@jsdevtools/file-path-filter": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@jsdevtools/file-path-filter/-/file-path-filter-3.0.2.tgz",
"integrity": "sha512-+SbZG6stIE/nRF2PpRnubtuzhh4pouDsk/hEWwM5mKsSKlFfr4ziAE5VMogGG/K++i9NHbUTxxW0y4vdM678ew==",
"requires": {
"glob-to-regexp": "^0.4.1"
}
},
"@jsdevtools/readdir-enhanced": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/@jsdevtools/readdir-enhanced/-/readdir-enhanced-6.0.4.tgz",
"integrity": "sha512-I6D6Omu6C7XWHzvlVbXeCS0FSxYYQ13XzdrFuo1K30unnRSpdt9AxY2KyJZbYJyfI2uNNidqDkG9/K/y699AjA==",
"requires": {
"@jsdevtools/file-path-filter": "^3.0.2"
}
},
"@types/glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
"integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
"optional": true,
"requires": {
"@types/minimatch": "*",
"@types/node": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"optional": true
},
"@types/node": {
"version": "14.11.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz",
"integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==",
"optional": true
},
"asar": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/asar/-/asar-3.0.3.tgz",
"integrity": "sha512-k7zd+KoR+n8pl71PvgElcoKHrVNiSXtw7odKbyNpmgKe7EGRF9Pnu3uLOukD37EvavKwVFxOUpqXTIZC5B5Pmw==",
"requires": {
"@types/glob": "^7.1.1",
"chromium-pickle-js": "^0.2.0",
"commander": "^5.0.0",
"glob": "^7.1.6",
"minimatch": "^3.0.4"
}
},
"at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"cac": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.6.1.tgz",
"integrity": "sha512-uhki4T3Ax68hw7Dufi0bATVAF8ayBSwOKUEJHjObPrUN4tlQ8Lf7oljpTje/mArLxYN0D743c2zJt4C1bVTCqg=="
},
"chromium-pickle-js": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
"integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU="
},
"commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"fs-extra": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
"integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^1.0.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
},
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"jsonfile": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^1.0.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"readdir-enhanced": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/readdir-enhanced/-/readdir-enhanced-6.0.4.tgz",
"integrity": "sha512-MWY048D/nEpHwqdnsBiUxpqjJPkEw2i2RmY5gM2Gadn0rkHS/DhUBqrYTkOqKHF4RoUlYZZ8GnP4ymlRGuo30A==",
"requires": {
"@jsdevtools/readdir-enhanced": "6.0.4"
}
},
"universalify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
}
}

107
pkg/Info.plist Normal file
View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AsarIntegrity</key>
<string>{"checksums":{"app.asar":"ZpfV8GYpkh6txWRLY2kyhxy+u/IqxXQicxy6MJr5nNo+FpB7+OvoU+S+6vpgTFAriFyk1Vzdm3LL3r2YdtqkKQ==","electron.asar":"GSTmZZ4QxBFCHgDFXN5eV94sbMRBgM04kw+f9bM+XZB00NCsFz1+8yIOYHycj0X6OoxeOOi08sk4Epi5a2kCDQ=="}}</string>
<key>BuildMachineOSBuild</key>
<string>17D102</string>
<key>CFBundleDisplayName</key>
<string>Notion</string>
<key>CFBundleExecutable</key>
<string>Notion</string>
<key>CFBundleIconFile</key>
<string>Notion.icns</string>
<key>CFBundleIdentifier</key>
<string>notion.id</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Notion</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.0.8</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>notion</string>
<key>CFBundleURLSchemes</key>
<array>
<string>notion</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>2.0.8</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTSDKBuild</key>
<string>10.13</string>
<key>DTSDKName</key>
<string>macosx10.13</string>
<key>DTXcode</key>
<string>0941</string>
<key>DTXcodeBuild</key>
<string>9F2000</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
<key>LSMinimumSystemVersion</key>
<string>10.10.0</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>127.0.0.1</key>
<dict>
<key>NSIncludesSubdomains</key>
<false/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
<false/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>1.0</string>
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
<key>localhost</key>
<dict>
<key>NSIncludesSubdomains</key>
<false/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
<false/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>1.0</string>
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2020 Notion Labs, Incorporated</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs access to the microphone</string>
<key>NSPrincipalClass</key>
<string>AtomApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSRequiresAquaSystemAppearance</key>
<false/>
</dict>
</plist>

View File

@ -31,31 +31,40 @@ module.exports = async function ({ overwrite_version, friendly_errors } = {}) {
return true;
case 2:
console.warn(` * ${check_app.msg}`);
do {
const valid = () =>
typeof overwrite_version === 'string' &&
['y', 'n', ''].includes(overwrite_version.toLowerCase());
if (valid()) {
console.info(
` > overwrite? [Y/n]: ${overwrite_version.toLowerCase()}`
);
}
while (!valid()) {
process.stdout.write(' > overwrite? [Y/n]: ');
overwrite_version = await helpers.readline();
} while (
overwrite_version &&
!['y', 'n'].includes(overwrite_version.toLowerCase())
);
overwrite_version =
!overwrite_version || overwrite_version.toLowerCase() === 'y';
if (!overwrite_version) {
}
if (overwrite_version.toLowerCase() === 'n') {
console.info(' ~~ keeping previous version: exiting.');
return false;
}
console.info(
' -- removing previous enhancements before applying new version.'
);
await require('./remove.js')({
overwrite_asar: true,
delete_data: false,
});
if (
!(await require('./remove.js')({
delete_data: 'n',
friendly_errors,
}))
) {
return false;
}
}
console.info(' ...unpacking app.asar.');
const asar_app = path.resolve(`${helpers.__notion}/app.asar`);
const asar_app = path.resolve(`${helpers.__notion}/app.asar`),
asar_bak = path.resolve(`${helpers.__notion}/app.asar.bak`);
extractAll(asar_app, `${path.resolve(`${helpers.__notion}/app`)}`);
await fs.move(asar_app, path.resolve(`${helpers.__notion}/app.asar.bak`));
if (await fs.pathExists(asar_bak)) fs.remove(asar_bak);
await fs.move(asar_app, asar_bak);
// patching launch script target of custom wrappers
if (
@ -83,6 +92,18 @@ module.exports = async function ({ overwrite_version, friendly_errors } = {}) {
}
}
// patching app properties so dark/light mode can be detected
if (
process.platform === 'darwin' &&
(await fs.pathExists(path.resolve(`${helpers.__notion}/../Info.plist`)))
) {
fs.copy(
path.resolve(`${__dirname}/Info.plist`),
path.resolve(`${helpers.__notion}/../Info.plist`),
{ overwrite: true }
);
}
for await (let insertion_target of readdirIterator(
path.resolve(`${helpers.__notion}/app`),
{

View File

@ -117,12 +117,14 @@ function getEnhancements() {
for (let dir of modules.dirs) {
try {
const mod = require(`../mods/${dir}/mod.js`);
if (!mod.tags) mod.tags = [];
if (
!mod.id ||
modules.IDs.includes(mod.id) ||
!mod.name ||
!mod.version ||
!mod.author ||
!mod.tags.every((tag) => typeof tag === 'string') ||
(mod.fonts && !mod.fonts.every((font) => typeof font === 'string')) ||
(mod.options &&
!mod.options.every((opt) =>
@ -140,6 +142,7 @@ function getEnhancements() {
...mod,
dir,
});
if (!mod.tags.includes('core')) mod.alwaysActive = false;
} catch (err) {
// console.error(err);
modules.invalid.push(dir);

View File

@ -108,19 +108,23 @@ example usage:
```js
console.warn(' * conflicting file found.');
let overwrite;
do {
while (
typeof overwrite !== 'string' ||
!['y', 'n', ''].includes(overwrite.toLowerCase())
) {
// using stdout.write means that there is no newline
// between prompt and input.
process.stdout.write(' > overwrite? [Y/n]: ');
overwrite = await helpers.readline();
process.stdout.write(' > delete? [Y/n]: ');
// ask for a Y/n until a valid answer is received.
// pressing enter without input is assumed to be a "yes".
} while (overwrite && !['y', 'n'].includes(overwrite.toLowerCase()));
overwrite = !overwrite || overwrite.toLowerCase() === 'y';
if (overwrite) {
console.info(' -- overwriting file.');
overwrite = await helpers.readline();
}
if (overwrite.toLowerCase() === 'n') {
console.info(' -- keeping file: skipping step.');
} else {
// do stuff
} else console.info(' -- keeping file: skipping step.');
console.info(' -- overwriting file.');
}
```
---

View File

@ -8,12 +8,12 @@
const fs = require('fs-extra'),
path = require('path'),
helpers = require('./helpers.js'),
{ __notion, getEnhancements, createElement } = require('./helpers.js'),
store = require('./store.js');
module.exports = function (__file, __exports) {
__file = __file
.slice(path.resolve(`${helpers.__notion}/app`).length + 1)
.slice(path.resolve(`${__notion}/app`).length + 1)
.replace(/\\/g, '/');
if (__file === 'main/security.js') {
@ -54,47 +54,51 @@ module.exports = function (__file, __exports) {
]);
}
const modules = helpers.getEnhancements();
for (let mod of [
let modules = getEnhancements();
modules = [
...modules.loaded.filter((m) => m.tags.includes('core')),
...modules.loaded.filter((m) => !m.tags.includes('core')).reverse(),
]) {
if (
mod.id === '0f0bf8b6-eae6-4273-b307-8fc43f2ee082' ||
store('mods', { [mod.id]: { enabled: false } })[mod.id].enabled
) {
if (
__file === 'renderer/preload.js' &&
fs.pathExistsSync(
path.resolve(`${__dirname}/../mods/${mod.dir}/styles.css`)
)
) {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
];
if (__file === 'renderer/preload.js') {
document.addEventListener('readystatechange', (event) => {
if (document.readyState !== 'complete') return false;
for (let mod of modules) {
if (
(mod.alwaysActive ||
store('mods', { [mod.id]: { enabled: false } })[mod.id].enabled) &&
fs.pathExistsSync(
path.resolve(`${__dirname}/../mods/${mod.dir}/styles.css`)
)
) {
for (let rules of [
`enhancement://${mod.dir}/styles.css`,
...(mod.fonts || []),
]) {
document
.querySelector('head')
.appendChild(
helpers.createElement(`<link rel="stylesheet" href="${rules}">`)
);
document.head.appendChild(
createElement(`<link rel="stylesheet" href="${rules}">`)
);
}
}
}
});
}
for (let mod of modules) {
if (
(mod.alwaysActive ||
store('mods', { [mod.id]: { enabled: false } })[mod.id].enabled) &&
mod.hacks &&
mod.hacks[__file]
) {
mod.hacks[__file]((...args) => {
if (!args.length) return store(mod.id, mod.defaults);
if (args.length === 1 && typeof args[0] === 'object')
return store(mod.id, { ...mod.defaults, ...args[0] });
const other_mod = modules.find((m) => m.id === args[0]);
return store(args[0], {
...(other_mod ? other_mod.defaults : {}),
...(args[1] || {}),
});
}
if (mod.hacks && mod.hacks[__file]) {
mod.hacks[__file]((...args) => {
if (!args.length) return store(mod.id, mod.defaults);
if (args.length === 1 && typeof args[0] === 'object')
return store(mod.id, { ...mod.defaults, ...args[0] });
const other_mod = modules.loaded.find((m) => m.id === args[0]);
return store(args[0], {
...(other_mod ? other_mod.defaults : {}),
...args[1],
});
}, __exports);
}
}, __exports);
}
}
};

View File

@ -18,11 +18,7 @@ const fs = require('fs-extra'),
// ~~ exit
// ### error ###
module.exports = async function ({
overwrite_asar,
delete_data,
friendly_errors,
} = {}) {
module.exports = async function ({ delete_data, friendly_errors } = {}) {
try {
// extracted asar: modded
const app_folder = path.resolve(`${helpers.__notion}/app`);
@ -38,50 +34,30 @@ module.exports = async function ({
if (await fs.pathExists(path.resolve(`${helpers.__notion}/app.asar`))) {
console.warn(' * app.asar already exists!');
if (overwrite_asar === undefined) {
do {
process.stdout.write(' > overwrite? [Y/n]: ');
overwrite_asar = await helpers.readline();
} while (
overwrite_asar &&
!['y', 'n'].includes(overwrite_asar.toLowerCase())
);
overwrite_asar =
!overwrite_asar || overwrite_asar.toLowerCase() === 'y';
}
console.info(
overwrite_asar
? ' -- overwriting app.asar with app.asar.bak'
: ' -- removing app.asar.bak'
);
}
await (overwrite_asar || overwrite_asar === undefined
? fs.move(asar_bak, path.resolve(`${helpers.__notion}/app.asar`), {
overwrite: true,
})
: fs.remove(asar_bak));
console.info(' -- removing app.asar.bak');
fs.remove(asar_bak);
} else
await fs.move(asar_bak, path.resolve(`${helpers.__notion}/app.asar`));
} else console.warn(` * ${asar_bak} not found: step skipped.`);
// cleaning data folder: ~/.notion-enhancer
if (await fs.pathExists(helpers.__data)) {
console.info(` ...data folder ${helpers.__data} found.`);
if (delete_data === undefined) {
do {
process.stdout.write(' > delete? [Y/n]: ');
delete_data = await helpers.readline();
} while (
delete_data &&
!['y', 'n'].includes(delete_data.toLowerCase())
);
delete_data = !delete_data || delete_data.toLowerCase() === 'y';
const valid = () =>
typeof delete_data === 'string' &&
['y', 'n', ''].includes(delete_data.toLowerCase());
if (valid())
console.info(` > delete? [Y/n]: ${delete_data.toLowerCase()}`);
while (!valid()) {
process.stdout.write(' > delete? [Y/n]: ');
delete_data = await helpers.readline();
}
console.info(
delete_data
? ` -- deleting ${helpers.__data}`
: ` -- keeping ${helpers.__data}`
delete_data.toLowerCase() === 'n'
? ` -- keeping ${helpers.__data}`
: ` -- deleting ${helpers.__data}`
);
if (delete_data) await fs.remove(helpers.__data);
if (delete_data.toLowerCase() !== 'n') await fs.remove(helpers.__data);
} else console.warn(` * ${helpers.__data} not found: step skipped.`);
// patching launch script target of custom wrappers