Highlight Area

sample

[[iframe http://shitake-crude-production.wdfiles.com/local--code/highlight-area/2#zy style="height: 0; width: 100%;" class="html-block-iframe"]]


export var container = {};
 
export var init = (deco=(r=>r), val={}) => {
  var H = document.querySelectorAll('highlight-area');
 
  var resizeTA = (deco, elm) => {
    var cur = elm.selectionEnd || elm.selectionStart || 0;
    var changed = (container[elm.parentElement.id].focus.index !== cur);
    container[elm.parentElement.id].focus.index = cur;
    var rep = t => t.replace(/</g, "&lt;");
 
    elm.tgtElm.innerHTML = rep(elm.value.slice(0,cur)) + '<span class="cursor"></span>' + rep(elm.value.slice(cur)) + '\u200b';
 
    deco(elm.tgtElm);
    elm.tgtElm.style.height = "unset";
    elm.parentElement.style.height = (elm.tgtElm.scrollHeight + 20) + "px";
    elm.tgtElm.style.height = "100%";
 
    var tgt = elm.tgtElm.querySelector(".cursor");
    var thisNode = false;
 
    if(tgt.previousSibling==tgt.parentElement) {;}
    else if(tgt && tgt.previousSibling && tgt.previousSibling.classList) {
      container[elm.parentElement.id].focus.text = tgt.previousSibling.innerText;
      container[elm.parentElement.id].focus.class = tgt.previousSibling.classList.value;
      tgt.previousSibling.classList.add("cursor_before");
    }else {
      try {
        var node = tgt.previousSibling;
        var text = node.textContent;
        var s = document.createElement('span');
        s.textContent = text;
        s.setAttribute("class", "cursor_before _node");
        var d;
        for (var i = 0, c = node.parentElement.childNodes; i < c.length; i++) {
          if (node == c[i]) {
            d = i;
            break;
          }
        }
        if(!isNaN(d)) {
          container[elm.parentElement.id].focus.text = text;
      container[elm.parentElement.id].focus.class = false;
          node.parentElement.insertBefore(s, node.parentElement.childNodes[d]);
          node.remove();
          thisNode = true;
        }
      }catch(e) {}
    }
 
    if(tgt && tgt.nextSibling && tgt.nextSibling.classList) {
      if(!thisNode) {
        tgt.nextSibling.classList.add("cursor_after");
        container[elm.parentElement.id].focus.text += tgt.nextSibling.innerText;
      }
    }
    else if(thisNode) {
      try {
        var node = tgt.nextSibling;
        var text = node.textContent;
        var s = document.createElement('span');
        s.textContent = text;
        s.setAttribute("class", "cursor_after _node");
        var d;
        for (var i = 0, c = node.parentElement.childNodes; i < c.length; i++) {
          if (node == c[i]) {
            d = i;
            break;
          }
        }
        if(!isNaN(d)) {
          container[elm.parentElement.id].focus.text += text;
          node.parentElement.insertBefore(s, node.parentElement.childNodes[d]);
          node.remove();
        }
      }catch(e) {}
    }
    if(changed) {
      container[elm.parentElement.id].onChange(container[elm.parentElement.id].focus);
    }
 
  }
 
  for(var h of H) {
    container[h.id] = {element: h, focus: {text: "", class: "", index: 0}, onChange: function() {}};
    var t = h.querySelector('textarea');
    var c = h.querySelector('code');
    t.tgtElm = c;
    if(val[h.id]) {
      t.value = val[h.id];
    }
    resizeTA(deco, t);
    for(var _ of ["blur", "input", "focus", "keydown", "keyup", "click", "touchend", "selectionchange"]) {
      t.addEventListener(_, (e)=> {
        resizeTA(deco, e.target);
      })
    }
 
  }
 
  window.addEventListener('hl-all-resize', () => {
    for(var h of H) {
      var t = h.querySelector('textarea');
      resizeTA(deco, t);
    }
  });
 
  if(window !== window.parent) {//based on C-take's resizing iframe method
    var site = `http://${document.referrer.split("http://")[1].split("/")[0]}/`;
    var _wrap = document.createElement("div");
    document.body.appendChild(_wrap);
    var _old= 0;
    var url = location.href.replace(/^.*\//,'/');
 
    (function _f() {
      var _new = _wrap.getBoundingClientRect().top;
      if(_new !== _old){
        var iframe = document.createElement("iframe");
        var _rand = String(Math.floor(Math.random() * 10000));
        _wrap.innerHTML = '';
        iframe.src = `${site}common--javascript/resize-iframe.html?${_rand}#${_new}${url}`;
        iframe.style.display = "none";
        _wrap.appendChild(iframe);
        _old = _new;
      }
      setTimeout(_f, 250);
    })();
  }
 
}
 
class highlightArea extends HTMLElement {
    constructor() {
        super();
        this.render();
    }
    render() {
        var t = document.createElement('textarea'),
        p = document.createElement('pre'),
        c = document.createElement('code'),
        cls = this.getAttribute('data-type'),
        val = this.getAttribute('data-value');
 
        !cls || t.setAttribute('placeholder', cls.toUpperCase()), c.setAttribute('class', cls);
        !val || t.setAttribute('value', val);
 
        t.setAttribute('spellcheck', 'false');
 
        this.append(t);
        this.append(p);
        p.append(c);
        this.removeAttribute('data-type');
        this.removeAttribute('data-value');
    }
}
customElements.define('highlight-area', highlightArea);
 
class highlightSetUp extends HTMLElement {
    constructor() {
        super();
        this.render();
    }
    render() {
        var _1 = document.createElement('script'),
        _2 = document.createElement('link'),
        _3 = document.createElement('style');
        _1.src = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js';
        _2.setAttribute('rel', 'stylesheet');
        _2.setAttribute('href', 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css');
        _3.innerHTML = `@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;1,300&display=swap');body {-webkit-text-size-adjust: 100%;}highlight-area {display: block;position: relative;}highlight-area textarea {-webkit-appearance: none;background: #223747;border-radius: 0;box-shadow: 1px 1px 3px #aaa!important;box-sizing: border-box;caret-color: #a97;color: transparent;display: block;font-family: 'IBM Plex Mono',monospace;font-size: 16px;height: 100%;line-height: 1.4;margin: 0;overflow: hidden;padding: 0 .5em;resize: none;transition: border .2s;white-space: pre-wrap;width: 100%;word-break: break-all;}highlight-area textarea::selection {background: #4d90fe;color: transparent;}highlight-area textarea:focus {box-shadow: 1px 1px 3px #4d90fe;outline: none;}highlight-area pre {height: 100%;left: 0;line-height: 1.4;margin: 0;pointer-events: none;position: absolute;top: 0;width: 100%;}highlight-area pre code, highlight-area pre code.hljs {background: rgba(0,0,0,0);box-shadow: none;box-sizing: border-box;color: #a97;display: block;font-family: 'IBM Plex Mono',monospace;font-size: 16px;height: 100%;overflow: hidden;padding: 0 .5em;white-space: pre-wrap!important;width: 100%;word-break: break-all;}highlight-area pre code * {font-weight: normal!important;}highlight-area textarea:disabled + pre code,highlight-area textarea:disabled + pre code * {color: #aaa;}highlight-area .hljs-string, highlight-area .hljs-regexp, highlight-area .hljs-addition, highlight-area .hljs-attribute, highlight-area .hljs-meta-string {font-style: italic;}highlight-area pre code .cursor {display: none;}highlight-area textarea:focus + pre code .cursor_before, highlight-area textarea:focus + pre code .cursor_after {text-decoration: underline;}`;
        this.append(_1);
        this.append(_2);
        this.append(_3);
        _1.onload = () => {
            window.dispatchEvent(new Event('hljs-onloaded'));
        }
    }
}
customElements.define('highlight-setup', highlightSetUp);
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License