JSFiddle - React, Tailwind, and code Playground

by nathan

HTML

<div class="modal background javascript-disabled"></div>
    <div class="modal message javascript-disabled">
      It appears that JavaScript is disabled. You may see a message asking you
      Allow Blocked Content, or similar. You must allow it for this to work.
    </div>
    <div id="main-input-container">
      <textarea id="main-input" placeholder="Paste data here (Ctrl + V)" required="required"></textarea>
      <div class="clear-button">✕</div>
    </div>

    <hr>

    <div class="line" title="Tick this when pasting from MS Access">
        <label for="excl-first-line-option">Exclude first line</label>
        <input type="checkbox" id="excl-first-line-option">
        <label for="excl-first-line-option" id="auto-exclude-notice" class="instructions">
            &#8592; Set automatically!
        </label>
    </div>

    <div class="line" title="SITS:Vision can&#39;t handle long text being pasted. Reduce this if you have problems.">
        <label for="group-size">Groups of</label>
        <input type="number" id="group-size" step="10" value="300">
    </div>

    <div id="delimiter-options">
        <div class="line" title="Retrieve all in list">
            <label for="delimiter-or">Or (<tt>·|</tt>)</label>
            <input id="delimiter-or" type="radio" name="delimiter" value="·|" checked="checked">
        </div>
        <!--div class="line" title="Retrieve values matching all wildcards in list">
            <label for="delimiter-and">And (<tt>·&amp;</tt>)</label>
            <input id="delimiter-and" type="radio" name="delimiter" value="·&amp;">
        </div-->
        <div class="line" title="Exclude values from retrieve (you need to add a ·! prefix)">
            <label for="delimiter-and-not">And not (<tt>·&amp;·!</tt>)</label>
            <input id="delimiter-and-not" type="radio" name="delimiter" value="·&amp;·!">
        </div>
        <div class="line">
            <label for="delimiter-other">Other</label>
            <input...

CSS

html {
    width: 100%;
    height: 100%;
}
body:not(.javascript-enabled) {
    width: 100%;
    hegith: 100%;
    overflow: hidden;
    margin: 0;
    padding: 0;
}
body.javascript-enabled .javascript-disabled {
    display: none;
}
.modal {
    position: fixed;
}
.modal.message {
    top: 40%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
    width: 30%;
    min-width: 200px;
    border: 3px black solid;
    background-color: white;
    z-index: 11;
    padding: 10px;
}
.modal.background {
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.6);
    z-index: 10;
}
div#main-input-container {
    position: relative;
}
textarea#main-input {
  width: 100%;
  box-sizing: border-box;
  overflow-y: scroll;
  height: 100px;
}
textarea+.clear-button {
    position: absolute;
    top: 0;
    right: 1em;
    width: 1em;
    height: 1em;
    cursor: pointer;
    color: lightgrey;
}
textarea+.clear-button:hover {
    color: black;
}
textarea:invalid+.clear-button {
    display: none;
}
.line>label:first-child {
    display: inline-block;
    width: 8em;
}
.instructions.fading {
    animation: fadeout 1s .5s ease-in;
    -webkit-animation: fadeout 1s .5s ease-in;
    color: grey;
/*    border: thin grey solid;
    background-color: #ffc;
    margin: 10px 0px;
    padding: 2px 10px;
    position: relative;
    z-index: 2;
    top: -2px;*/
}
.instructions:not(.fading) {
    animation: none;
    -webkit-animation: none;
    display: none;
}
@keyframes fadeout {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}
@-webkit-keyframes fadeout {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}
#results>span {
    width: 10em;
    display: inline-block;
    font-family: monospace;
}
#results>input {
/*    width: calc(100% - 10em - 3px);*/
    width: 100%;
    display: block;
}

JavaScript

/*
better version of the DOM-JavaScript implementation:
 * method chaining `element.setAttribute("a", "b").addEventListener("click", fn)`
 * functions on collections `collection.addEventListener("click", fn)`
 * multiple events: el.addEventListener("click focus", fn);

Not fully featured... add features as-and-when you need them!

*/
window.dom = (function (document) {

    dom.createElement = createElement;
    dom.querySelector = querySelector;
    dom.querySelectorAll = querySelector;

    DomCollection.prototype.addEventListener = domCollectionAddEventListener;
    DomCollection.prototype.removeEventListener =
        domCollectionRemoveEventListener;
    DomCollection.prototype.appendChild = domCollectionAppendChild;
    DomCollection.prototype.focus = domCollectionFocus;
    DomCollection.prototype.forEach = domCollectionForEach;
    DomCollection.prototype.getAttribute = domCollectionGetAttribute;
    DomCollection.prototype.setAttribute = domCollectionSetAttribute;

    return dom;

    function createElement(sel) {
        var tagName = (sel.match(/^[a-z]+/i) || ["div"])[0],
            id = (sel.match(/(?=\#)[a-z]+/i) || [])[0],
            attributes = (sel.match(/\[\w+\=\w+\]/m)) || [],
            classes = (sel.match(/\.\w+/m) || []),
            el;
        el = document.createElement(tagName);
        if (id) {
            el.id = id;
        }
        attributes.forEach(function (attr) {
            var attrName = attr.match(/^\[\w+/)[0].replace("[", ""),
                attrVal = attr.match(/\w+\]$/)[0].replace("]", "");
            el.setAttribute(attrName, attrVal);
        });
        classes.forEach(function (className) {
            el.classList.add(className.replace(".", ""));
        });
        return dom(el);
    }
    function dom(a) {
        if (typeof a === "string") {
            return dom.querySelector(a);
        }
        if (typeof a.length !== "number") {
            return new DomCollection([a]);
        }
        return new...