1function preceding(element) { 2 return element && (element.previousElementSibling || preceding(element.parentNode)); 3} 4 5function deriveFilename(element) { 6 // TODO: Make pattern and default name configurable 7 const match = element && element.textContent.match(/^\s*(.+[/\\])?([^/\\]+\.\w+)\s*$/); 8 return match ? match[2] : "code.txt"; 9} 10 11window.addEventListener("load", () => { 12 for (const codeElement of document.querySelectorAll("#dokuwiki__content pre.code")) { 13 const code = codeElement.textContent; 14 // Try to interpret the element before the <pre> element as file name 15 const filename = deriveFilename(preceding(codeElement)); 16 const button = document.createElement("button"); 17 button.textContent = "Download"; 18 button.classList.add("downloadcodeblock"); 19 button.addEventListener("click", () => { 20 // Support for browser.downloads.download isn't good yet, so use <a> instead 21 const a = document.createElement("a"); 22 a.href = "data:text/plain;charset=utf-8," + encodeURIComponent(code); 23 a.download = filename; 24 a.click(); 25 }, false); 26 codeElement.parentNode.insertBefore(button, codeElement); 27 } 28}, false); 29