From c0f847949f3e702dd4ece4cf86a392f5568bba71 Mon Sep 17 00:00:00 2001 From: dragonwocky Date: Thu, 22 Oct 2020 08:54:06 +1100 Subject: [PATCH] clarity improvements for scroll to top extension --- repo/scroll-to-top/mod.js | 228 +++++++++++++++++----------------- repo/scroll-to-top/style.css | 54 -------- repo/scroll-to-top/styles.css | 55 ++++++++ 3 files changed, 172 insertions(+), 165 deletions(-) delete mode 100644 repo/scroll-to-top/style.css create mode 100644 repo/scroll-to-top/styles.css diff --git a/repo/scroll-to-top/mod.js b/repo/scroll-to-top/mod.js index afb1fd6..11c9316 100644 --- a/repo/scroll-to-top/mod.js +++ b/repo/scroll-to-top/mod.js @@ -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( - '
🠙
' // 🠙; - ) - - $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( + '
🠙
' // 🠙; + ); + + $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; + } + } + } + }); + }, + }, }; diff --git a/repo/scroll-to-top/style.css b/repo/scroll-to-top/style.css deleted file mode 100644 index 84e3fb1..0000000 --- a/repo/scroll-to-top/style.css +++ /dev/null @@ -1,54 +0,0 @@ -/* - * scroll-to-top - * (c) 2020 dragonwocky (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 -} \ No newline at end of file diff --git a/repo/scroll-to-top/styles.css b/repo/scroll-to-top/styles.css new file mode 100644 index 0000000..044e7f8 --- /dev/null +++ b/repo/scroll-to-top/styles.css @@ -0,0 +1,55 @@ +/* + * scroll-to-top + * (c) 2020 dragonwocky (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; +}