mirror of
				https://github.com/notion-enhancer/notion-enhancer.git
				synced 2025-10-31 14:18:08 +11:00 
			
		
		
		
	* Basic Functionality * Added smooth scrolling option * Added scroll down distance option * Button hide/show animation * Add percentage distance option * Calculate percentage every update (as opposed to every page change) * Calculate percentage height based on scroller and content height * Licensing and Conventions * Hide button on initialization if top distance is set * Fixed bug with button visibility when opening pages
		
			
				
	
	
		
			124 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
|  * 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");
 | |
| 
 | |
| 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">🠙</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;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|         }
 | |
|     },
 | |
| };
 |