mirror of
				https://github.com/notion-enhancer/notion-enhancer.git
				synced 2025-11-01 06:38:08 +11:00 
			
		
		
		
	upload outliner extension
This commit is contained in:
		
							parent
							
								
									cf1eb203ca
								
							
						
					
					
						commit
						6b6626c966
					
				
							
								
								
									
										51
									
								
								mods/outliner/app.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								mods/outliner/app.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | /* | ||||||
|  |  * outliner | ||||||
|  |  * (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/) | ||||||
|  |  * (c) 2020 CloudHill | ||||||
|  |  * under the MIT license | ||||||
|  |  */ | ||||||
|  |   | ||||||
|  | .outliner { | ||||||
|  |   max-height: 100%; | ||||||
|  |   overflow: hidden auto; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .outline-header { | ||||||
|  |   display: flex; | ||||||
|  |   align-items: center; | ||||||
|  |   height: 2.2em; | ||||||
|  |   cursor: pointer; | ||||||
|  |   user-select: none; | ||||||
|  |   transition: background 20ms ease-in; | ||||||
|  | } | ||||||
|  | .outline-header:hover { | ||||||
|  |   background: var(--theme--interactive_hover); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .outline-header a { | ||||||
|  |   width: 100%; | ||||||
|  |   height: 100%; | ||||||
|  |   padding: 0 14px; | ||||||
|  |   line-height: 2.2; | ||||||
|  |   color: inherit; | ||||||
|  |   text-decoration: none; | ||||||
|  |    | ||||||
|  |   white-space: nowrap; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .outline-header a:empty:before { | ||||||
|  |   color: var(--theme--text_ui_info); | ||||||
|  |   content: attr(placeholder); | ||||||
|  |   display: block; | ||||||
|  | } | ||||||
|  | .outline-header.notion-header-block a { | ||||||
|  |   text-indent: 0; | ||||||
|  | } | ||||||
|  | .outline-header.notion-sub_header-block a { | ||||||
|  |   text-indent: 18px; | ||||||
|  | } | ||||||
|  | .outline-header.notion-sub_sub_header-block a { | ||||||
|  |   text-indent: 36px; | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								mods/outliner/icon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								mods/outliner/icon.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> | ||||||
|  | 	<circle cx="5" cy="7" r="2.8"/> | ||||||
|  | 	<circle cx="5" cy="17" r="2.79"/> | ||||||
|  | 	<path d="M21,5.95H11c-0.55,0-1-0.45-1-1v0c0-0.55,0.45-1,1-1h10c0.55,0,1,0.45,1,1v0C22,5.5,21.55,5.95,21,5.95z"/> | ||||||
|  | 	<path d="M17,10.05h-6c-0.55,0-1-0.45-1-1v0c0-0.55,0.45-1,1-1h6c0.55,0,1,0.45,1,1v0C18,9.6,17.55,10.05,17,10.05z"/> | ||||||
|  | 	<path d="M21,15.95H11c-0.55,0-1-0.45-1-1v0c0-0.55,0.45-1,1-1h10c0.55,0,1,0.45,1,1v0C22,15.5,21.55,15.95,21,15.95z" /> | ||||||
|  | 	<path d="M17,20.05h-6c-0.55,0-1-0.45-1-1v0c0-0.55,0.45-1,1-1h6c0.55,0,1,0.45,1,1v0C18,19.6,17.55,20.05,17,20.05z"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 633 B | 
							
								
								
									
										23
									
								
								mods/outliner/mod.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								mods/outliner/mod.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | /* | ||||||
|  |  * outliner | ||||||
|  |  * (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
 | ||||||
|  |  * (c) 2020 CloudHill | ||||||
|  |  * under the MIT license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  |   id: '87e077cc-5402-451c-ac70-27cc4ae65546', | ||||||
|  |   tags: ['extension', 'panel'], | ||||||
|  |   name: 'outliner', | ||||||
|  |   desc: 'table of contents.', | ||||||
|  |   version: '1.0.0', | ||||||
|  |   author: 'CloudHill', | ||||||
|  |   panel: { | ||||||
|  |     html: "panel.html", | ||||||
|  |     name: "Outline", | ||||||
|  |     icon: "icon.svg", | ||||||
|  |     js: "panel.js", | ||||||
|  |   } | ||||||
|  | }; | ||||||
							
								
								
									
										2
									
								
								mods/outliner/panel.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								mods/outliner/panel.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | <div class="outliner"> | ||||||
|  | </div> | ||||||
							
								
								
									
										115
									
								
								mods/outliner/panel.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								mods/outliner/panel.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | |||||||
|  | /* | ||||||
|  |  * outliner | ||||||
|  |  * (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
 | ||||||
|  |  * (c) 2020 CloudHill | ||||||
|  |  * under the MIT license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const { createElement } = require("../../pkg/helpers"); | ||||||
|  | 
 | ||||||
|  | module.exports = (store) => {     | ||||||
|  |   function initOutliner() { | ||||||
|  |     // Find headers when switching panels
 | ||||||
|  |     if (document.querySelector('.notion-page-content')) { | ||||||
|  |       startContentObserver(); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // Observe for page changes
 | ||||||
|  |     const pageObserver = new MutationObserver((list, observer) => { | ||||||
|  |       for ( let { addedNodes } of list) { | ||||||
|  |         if (addedNodes[0]) { | ||||||
|  |           if (addedNodes[0].className === 'notion-page-content') { | ||||||
|  |             startContentObserver(); | ||||||
|  |           } | ||||||
|  |           // Clear outline on database pages
 | ||||||
|  |           else if (addedNodes[0].className === 'notion-scroller') { | ||||||
|  |             contentObserver.disconnect(); | ||||||
|  |             const outline = document.querySelector('.outliner'); | ||||||
|  |             if (outline) outline.textContent = ''; | ||||||
|  |           } | ||||||
|  |         }  | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |     pageObserver.observe(document.body, { | ||||||
|  |       childList: true, | ||||||
|  |       subtree: true, | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  |     // Observe for header changes
 | ||||||
|  |     const contentObserver = new MutationObserver((list, observer) => { | ||||||
|  |       list.forEach(m => { | ||||||
|  |         if ( | ||||||
|  |           ( | ||||||
|  |             m.type === 'childList' && | ||||||
|  |             ( | ||||||
|  |               isHeaderElement(m.target) || | ||||||
|  |               isHeaderElement(m.addedNodes[0]) || | ||||||
|  |               isHeaderElement(m.removedNodes[0]) | ||||||
|  |             ) | ||||||
|  |           ) || | ||||||
|  |           ( | ||||||
|  |             m.type === 'characterData' && | ||||||
|  |             isHeaderElement(m.target.parentElement) | ||||||
|  |           ) | ||||||
|  |         ) findHeaders(); | ||||||
|  |       }) | ||||||
|  |     }); | ||||||
|  |     function startContentObserver() { | ||||||
|  |       findHeaders(); | ||||||
|  |       contentObserver.disconnect(); | ||||||
|  |       contentObserver.observe( | ||||||
|  |         document.querySelector('.notion-page-content'), | ||||||
|  |         { | ||||||
|  |           childList: true, | ||||||
|  |           subtree: true, | ||||||
|  |           characterData: true, | ||||||
|  |         } | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function findHeaders() { | ||||||
|  |     const outline = document.querySelector('.outliner'); | ||||||
|  |     if (!outline) { | ||||||
|  |       pageObserver.disconnect(); | ||||||
|  |       observer.disconnect(); | ||||||
|  |     } | ||||||
|  |     outline.textContent = ''; | ||||||
|  | 
 | ||||||
|  |     const pageContent = document.querySelector('.notion-page-content'); | ||||||
|  |     const headerBlocks = pageContent.querySelectorAll('[class*="header-block"]'); | ||||||
|  |      | ||||||
|  |     headerBlocks.forEach(block => { | ||||||
|  |       const blockId = block.dataset.blockId.replace(/-/g, ''); | ||||||
|  |       const placeholder = block.querySelector('[placeholder]').getAttribute('placeholder'); | ||||||
|  |       const header = createElement(` | ||||||
|  |         <div class="outline-header ${block.classList[1]}"> | ||||||
|  |           <a href="${window.location.pathname}#${blockId}" | ||||||
|  |             placeholder="${placeholder}">${block.innerText}</a> | ||||||
|  |         </div> | ||||||
|  |       `);
 | ||||||
|  | 
 | ||||||
|  |       outline.append(header); | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function isHeaderElement(el) { | ||||||
|  |     let placeholder; | ||||||
|  |     if (el) { | ||||||
|  |       if ( | ||||||
|  |         el.querySelector &&  | ||||||
|  |         el.querySelector('[placeholder]') | ||||||
|  |       ) { | ||||||
|  |         placeholder = el.querySelector('[placeholder]').getAttribute('placeholder') | ||||||
|  |       } else if (el.getAttribute) { | ||||||
|  |         placeholder = el.getAttribute('placeholder'); | ||||||
|  |       }  | ||||||
|  |     } | ||||||
|  |     if (!placeholder) placeholder = ''; | ||||||
|  |     return placeholder.includes('Heading'); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return initOutliner; | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user