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