1. import * as Base64 from "./base64.js";
    
  2. 
    
  3. document.addEventListener("DOMContentLoaded", function () {
    
  4.   var style = document.createElement('style');
    
  5.   var ref = document.querySelector('script');
    
  6.   ref.parentNode.insertBefore(style, ref);
    
  7. 
    
  8.   var form = document.getElementById('chroma');
    
  9.   var textArea = form.elements["text"];
    
  10.   var styleSelect = form.elements["style"];
    
  11.   var languageSelect = form.elements["language"];
    
  12.   var copyButton = form.elements["copy"];
    
  13.   var csrfToken = form.elements["gorilla.csrf.Token"].value;
    
  14.   var output = document.getElementById("output");
    
  15.   var htmlCheckbox = document.getElementById("html");
    
  16. 
    
  17.   (document.querySelectorAll('.notification .delete') || []).forEach((el) => {
    
  18.     const notification = el.parentNode;
    
  19.     el.addEventListener('click', () => {
    
  20.       notification.parentNode.removeChild(notification);
    
  21.     });
    
  22.   });
    
  23. 
    
  24.   // https://stackoverflow.com/a/37697925/7980
    
  25.   function handleTab(e) {
    
  26.     var after, before, end, lastNewLine, changeLength, re, replace, selection, start, val;
    
  27.     if ((e.charCode === 9 || e.keyCode === 9) && !e.altKey && !e.ctrlKey && !e.metaKey) {
    
  28.       e.preventDefault();
    
  29.       start = this.selectionStart;
    
  30.       end = this.selectionEnd;
    
  31.       val = this.value;
    
  32.       before = val.substring(0, start);
    
  33.       after = val.substring(end);
    
  34.       replace = true;
    
  35.       if (start !== end) {
    
  36.         selection = val.substring(start, end);
    
  37.         if (~selection.indexOf('\n')) {
    
  38.           replace = false;
    
  39.           changeLength = 0;
    
  40.           lastNewLine = before.lastIndexOf('\n');
    
  41.           if (!~lastNewLine) {
    
  42.             selection = before + selection;
    
  43.             changeLength = before.length;
    
  44.             before = '';
    
  45.           } else {
    
  46.             selection = before.substring(lastNewLine) + selection;
    
  47.             changeLength = before.length - lastNewLine;
    
  48.             before = before.substring(0, lastNewLine);
    
  49.           }
    
  50.           if (e.shiftKey) {
    
  51.             re = /(\n|^)(\t|[ ]{1,8})/g;
    
  52.             if (selection.match(re)) {
    
  53.               start--;
    
  54.               changeLength--;
    
  55.             }
    
  56.             selection = selection.replace(re, '$1');
    
  57.           } else {
    
  58.             selection = selection.replace(/(\n|^)/g, '$1\t');
    
  59.             start++;
    
  60.             changeLength++;
    
  61.           }
    
  62.           this.value = before + selection + after;
    
  63.           this.selectionStart = start;
    
  64.           this.selectionEnd = start + selection.length - changeLength;
    
  65.         }
    
  66.       }
    
  67.       if (replace && !e.shiftKey) {
    
  68.         this.value = before + '\t' + after;
    
  69.         this.selectionStart = this.selectionEnd = start + 1;
    
  70.       }
    
  71.     }
    
  72.     debouncedEventHandler(e);
    
  73.   }
    
  74. 
    
  75.   function debounce(func, wait, immediate) {
    
  76.     var timeout;
    
  77.     return function () {
    
  78.       var context = this, args = arguments;
    
  79.       var later = function () {
    
  80.         timeout = null;
    
  81.         if (!immediate) func.apply(context, args);
    
  82.       };
    
  83.       var callNow = immediate && !timeout;
    
  84.       clearTimeout(timeout);
    
  85.       timeout = setTimeout(later, wait);
    
  86.       if (callNow) func.apply(context, args);
    
  87.     };
    
  88.   }
    
  89. 
    
  90.   function getFormJSON() {
    
  91.     return {
    
  92.       "language": languageSelect.value,
    
  93.       "style": styleSelect.value,
    
  94.       "text": textArea.value,
    
  95.       "classes": htmlCheckbox.checked,
    
  96.     }
    
  97.   }
    
  98. 
    
  99.   function update(event) {
    
  100.     fetch("api/render", {
    
  101.       method: 'POST',
    
  102.       mode: 'cors',
    
  103.       cache: 'no-cache',
    
  104.       credentials: 'same-origin',
    
  105.       headers: {
    
  106.         'X-CSRF-Token': csrfToken,
    
  107.         'Content-Type': 'application/json',
    
  108.       },
    
  109.       redirect: 'follow',
    
  110.       referrer: 'no-referrer',
    
  111.       body: JSON.stringify(getFormJSON()),
    
  112.     }).then(data => {
    
  113.       data.json().then(
    
  114.         value => {
    
  115.           if (value.language) {
    
  116.             languageSelect.value = value.language;
    
  117.           }
    
  118.           style.innerHTML = "#output { " + value.background + "}";
    
  119.           if (htmlCheckbox.checked) {
    
  120.             output.innerText = value.html;
    
  121.           } else {
    
  122.             output.innerHTML = value.html;
    
  123.           }
    
  124.         }
    
  125.       );
    
  126.     }).catch(reason => {
    
  127.       console.log(reason);
    
  128.     });
    
  129. 
    
  130.     event.preventDefault();
    
  131.   }
    
  132. 
    
  133.   function share(event) {
    
  134.     let data = JSON.stringify(getFormJSON())
    
  135.     data = Base64.encodeURI(data);
    
  136.     location.hash = "#" + data;
    
  137.     try {
    
  138.       navigator.clipboard.writeText(location.href);
    
  139.     } catch (e) {
    
  140.       console.log(e);
    
  141.     }
    
  142.     event.preventDefault();
    
  143.   }
    
  144. 
    
  145.   if (location.hash) {
    
  146.     let json = Base64.decode(location.hash.substring(1))
    
  147.     json = JSON.parse(json);
    
  148.     textArea.value = json.text;
    
  149.     languageSelect.value = json.language;
    
  150.     styleSelect.value = json.style;
    
  151.     htmlCheckbox.checked = json.classes;
    
  152.     update(new Event('change'));
    
  153.   }
    
  154. 
    
  155.   var eventHandler = (event) => update(event);
    
  156.   var debouncedEventHandler = debounce(eventHandler, 250);
    
  157. 
    
  158.   languageSelect.addEventListener('change', eventHandler);
    
  159.   styleSelect.addEventListener('change', eventHandler);
    
  160.   htmlCheckbox.addEventListener('change', eventHandler);
    
  161.   copyButton.addEventListener('click', share);
    
  162. 
    
  163.   textArea.addEventListener('keydown', handleTab);
    
  164.   textArea.addEventListener('change', debouncedEventHandler);
    
  165. });