131 lines
		
	
	
		
			4 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			4 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| 
 | |
| {{- if (and (eq .Kind "page") (ne .Layout "archives") (ne .Layout "search") (.Param "ShowCodeCopyButtons")) }}
 | |
| <script>
 | |
|   document.querySelectorAll('pre > code').forEach((codeblock) => {
 | |
|     const container = codeblock.parentNode.parentNode;
 | |
| 
 | |
|     const copybutton = document.createElement('button');
 | |
|     copybutton.classList.add('copy-code');
 | |
|     copybutton.innerText = '{{- i18n "code_copy" | default "copy" }}';
 | |
| 
 | |
|     function copyingDone() {
 | |
|       copybutton.innerText = '{{- i18n "code_copied" | default "copied!" }}';
 | |
|       setTimeout(() => {
 | |
|         copybutton.innerText = '{{- i18n "code_copy" | default "copy" }}';
 | |
|       }, 2000);
 | |
|     }
 | |
| 
 | |
|     copybutton.addEventListener('click', (cb) => {
 | |
|       if ('clipboard' in navigator) {
 | |
|         navigator.clipboard.writeText(codeblock.textContent);
 | |
|         copyingDone();
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       const range = document.createRange();
 | |
|       range.selectNodeContents(codeblock);
 | |
|       const selection = window.getSelection();
 | |
|       selection.removeAllRanges();
 | |
|       selection.addRange(range);
 | |
|       try {
 | |
|         document.execCommand('copy');
 | |
|         copyingDone();
 | |
|       } catch (e) { };
 | |
|       selection.removeRange(range);
 | |
|     });
 | |
| 
 | |
|     if (container.classList.contains("highlight")) {
 | |
|       container.appendChild(copybutton);
 | |
|     } else if (container.parentNode.firstChild == container) {
 | |
|       // td containing LineNos
 | |
|     } else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
 | |
|       // table containing LineNos and code
 | |
|       codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
 | |
|     } else {
 | |
|       // code blocks not having highlight as parent class
 | |
|       codeblock.parentNode.appendChild(copybutton);
 | |
|     }
 | |
|   });
 | |
| </script>
 | |
| {{- end }}
 | |
| 
 | |
| 
 | |
| 
 | |
| {{/* ToC Scroll */}}
 | |
| <script>
 | |
|   // NOTE use closure instead of DOMContentLoaded because of InstantClick,
 | |
|   // every page loaded by InstantClick should run the <script> tags again.
 | |
|   (function() {
 | |
|     const enableTocScroll = '{{- if (and (eq .Kind "page") (.Content) (.Param "ShowToc") (.Param "TocSide")) }}1{{ end }}' == '1'
 | |
|     if (!enableTocScroll) {
 | |
|       return
 | |
|     }
 | |
|     if (!document.querySelector('.toc')) {
 | |
|       console.log('no toc found, ignore toc scroll')
 | |
|       return
 | |
|     }
 | |
|     // console.log('enable toc scroll')
 | |
| 
 | |
|     // always get an array here
 | |
|     const scrollListeners = window.scrollListeners
 | |
|     const headings = document.querySelectorAll('h1[id],h2[id],h3[id],h4[id],h5[id]');
 | |
|     const activeClass = 'active';
 | |
| 
 | |
|     // Make the first header active
 | |
|     let activeHeading = headings[0];
 | |
|     getLinkByHeading(activeHeading).classList.add(activeClass);
 | |
| 
 | |
|     const onScroll = () => {
 | |
|       const passedHeadings = [];
 | |
|       for (const h of headings) {
 | |
|         // 5 px as a buffer
 | |
|         if (getOffsetTop(h) < 5) {
 | |
|           passedHeadings.push(h)
 | |
|         } else {
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|       if (passedHeadings.length > 0) {
 | |
|         newActiveHeading = passedHeadings[passedHeadings.length - 1];
 | |
|       } else {
 | |
|         newActiveHeading = headings[0];
 | |
|       }
 | |
|       if (activeHeading != newActiveHeading) {
 | |
|         getLinkByHeading(activeHeading).classList.remove(activeClass);
 | |
|         activeHeading = newActiveHeading;
 | |
|         getLinkByHeading(activeHeading).classList.add(activeClass);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     let timer = null;
 | |
|     const scrollListener = () => {
 | |
|       if (timer !== null) {
 | |
|         clearTimeout(timer)
 | |
|       }
 | |
|       timer = setTimeout(onScroll, 50)
 | |
|     }
 | |
|     window.addEventListener('scroll', scrollListener, false);
 | |
|     scrollListeners.push(scrollListener)
 | |
| 
 | |
|     function getLinkByHeading(heading) {
 | |
|       const id = encodeURI(heading.getAttribute('id')).toLowerCase();
 | |
|       return document.querySelector(`.toc ul li a[href="#${id}"]`);
 | |
|     }
 | |
| 
 | |
|     function getOffsetTop(heading) {
 | |
|       if (!heading.getClientRects().length) {
 | |
|         return 0;
 | |
|       }
 | |
|       let rect = heading.getBoundingClientRect();
 | |
|       return rect.top
 | |
|     }
 | |
|   })();
 | |
|   </script>
 | |
| 
 | |
| {{- if (.Param "EnableImageZoom") }}
 | |
| <script>
 | |
|   mediumZoom('.entry-cover img');
 | |
|   mediumZoom('.post-content img:not([no-zoom])');
 | |
| </script>
 | |
| {{- end }}
 | 
