clarity improvements for scroll to top extension

This commit is contained in:
dragonwocky 2020-10-22 08:54:06 +11:00
parent fb63601ebf
commit 7885b2c204
Signed by: dragonwocky
GPG Key ID: C7A48B7846AA706D
4 changed files with 173 additions and 165 deletions

View File

@ -49,6 +49,7 @@ a flexibility update.
- 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: "scroll to top" = add an arrow above the help button to scroll back to the top of a page.
a fork of notion-deb-builder that does generate an app.asar has been created and is once again supported.

View File

@ -5,119 +5,125 @@
* under the MIT license
*/
"use strict";
'use strict';
const { createElement } = require("../../pkg/helpers.js");
const { createElement } = require('../../pkg/helpers.js');
module.exports = {
id: "0a958f5a-17c5-48b5-8713-16190cae1959",
tags: ["extension"],
name: "scroll-to-top",
desc: "add a scroll to top button.",
version: "1.0.0",
author: "CloudHill",
options: [
{
key: "smooth",
label: "smooth scrolling",
type: "toggle",
value: true,
},
{
key: "top",
label: "scroll down distance to show button",
type: "input",
value: 80,
},
{
key: "percent",
label: "set distance as a percentage",
type: "toggle",
value: true,
},
],
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">&#129049;</div>' // 🠙;
)
$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(() => process(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
function process(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().percent) {
let content_height = Array.from($scroller.children)
.reduce((h, c) => h + c.offsetHeight, 0);
$scroller.top_distance *= (content_height - $scroller.offsetHeight) / 100;
}
}
}
});
}
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">&#129049;</div>' // 🠙;
);
$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(() => process(queue));
queue.push(...list);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
function process(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;
}
}
}
});
},
},
};

View File

@ -1,54 +0,0 @@
/*
* 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
}

View File

@ -0,0 +1,55 @@
/*
* 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;
}