scripts.js


Element.prototype.getNodeData 
= function(key){
    if (this.hasAttribute('data-nodeData')){
        const nodeData = JSON.parse(this.getAttribute('data-nodeData'));
        if (key===null)return nodeData;
        else return nodeData[key];
    } else {
        console.log('data-nodeData is not set on');
        console.log(this);
    }
};

DataTransfer.prototype.getNodeData 
= function(key){
    const nodeData = JSON.parse(this.getData('nodeData'));
    return nodeData[key];
};

class Wyg {
htmlAsNode(html){
    const wrapper = document.createElement('div');
    wrapper.innerHTML = html;
    const node = wrapper.firstChild;
    return node;
}
setupAsContainer(node){
    //node.classList.add('wyg_container');
    var thisArg = this;
    node.addEventListener('drop',
    function(event){
        (new Wyg).dropElement(node,event);
    });
}
addNodeCss(node){
    const copy = node.cloneNode();
    const innerHtmlUUIDIsh = generateUUIDISH();
    copy.innerHTML = innerHtmlUUIDIsh;
    const parts = copy.outerHTML.split(innerHtmlUUIDIsh);
    let beforeText;
    let afterText;
    if (parts.length==2){
        beforeText = parts[0].replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
        afterText = (parts[1] || '.a{}').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
    } else {
        copy.innerHTML = '';
        beforeText = copy.outerHTML;
        afterText = '';
    }

    const sheet = window.document.styleSheets[0];
    const nodeId = generateUUIDISH();
    const selector='.show_html '+'.'+nodeId;
    console.log(parts);
    const beforeRule = selector+':before{'+"\n"+'content:"'
        +( JSON.stringify(beforeText).slice(1, -1) )
        +'";}';
    const afterRule = selector+':after{'+"\n"+'content:"'
        +( JSON.stringify(afterText).slice(1, -1))
        +'";}';

    console.log(beforeRule);
    console.log(afterRule);
    sheet.insertRule(beforeRule);
    sheet.insertRule(afterRule);
    return nodeId;
}
placeNode(nodeData,wyg,xCoord,yCoord){
    const html = nodeData.nodeHtml;
    const isContainer = nodeData.isContainer;
    const insertNode = this.htmlAsNode(html);
    const cssNodeId = this.addNodeCss(insertNode);
    insertNode.classList.add(cssNodeId);
    if (nodeData.isContainer)this.setupAsContainer(insertNode);
    wyg.appendChild(insertNode);
}
dropElement(wyg,event){
    console.log('drop element');
    console.log(event);
    event.preventDefault();
    event.stopPropagation();
    let nodeData = JSON.parse(event.dataTransfer.getData('nodeData'));
    this.placeNode(nodeData,wyg,event.x,event.y)
}
}

function generateUUIDISH() { // Public Domain/MIT
    var d = new Date().getTime();//Timestamp
    var d2 = (performance && performance.now && (performance.now()*1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
    return 'axxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxz'.replace(/\-/g,'_').replace(/[xy]/g, function(c) {
        var r = Math.random() * 16;//random number between 0 and 16
        if(d > 0){//Use timestamp until depleted
            r = (d + r)%16 | 0;
            d = Math.floor(d/16);
        } else {//Use microseconds since page-load if supported
            r = (d2 + r)%16 | 0;
            d2 = Math.floor(d2/16);
        }
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
}
function toggleEditorMode(button){
    const editor = document.getElementById("wyg");
    if (button.innerText=='Show HTML'){
        editor.tagName = 'textarea';
        button.innerText = 'Hide HTML';
        editor.classList.toggle('show_html');
        // editor.setAttribute('data-innerHTML',editor.innerHTML);
        // editor.innerText = editor.innerHTML;
    } else {
        editor.tagName = 'div';
        button.innerText = 'Show HTML';
        editor.classList.toggle('show_html');
        // editor.innerHTML = editor.innerText;
    }
}
function showElementForm(event){
    var element = event.target;

    let request = new Request('/wyg/get_element_form/?nodeId='+encodeURIComponent(element.getNodeData('nodeId')));
    fetch(request)
        .then(response => {
            if (response.status === 200) {
                return response.text();
            }
        })
        .then(formHtml => {
            document.getElementById("settings").innerHTML = formHtml;
        });
}

function showGroupSettings(event){
    let groupName = event.target.getAttribute('data-groupName');
    let request = new Request('/wyg/get_group_settings/?group='
        +encodeURIComponent(groupName)
        );
    fetch(request)
        .then(response => {
            if (response.status === 200) {
                return response.json();
            }
        })
        .then(json => {
            let settingsBox = document.getElementById("settings");
            settingsBox.innerText = '';
            settings_html = json.settings_html;
            settingsBox.innerHTML = settings_html;
        });
}
function showElementsOfGroup(event){
    showGroupSettings(event);
    let groupName = event.target.getAttribute('data-groupName');
    let request = new Request('/wyg/get_elements_from_group/?group='+encodeURIComponent(groupName));
    fetch(request)
        .then(response => {
            if (response.status === 200) {
                return response.json();
            }
        })
        .then(json => {
            let elementsBox = document.getElementById("elementsBox");
            elementsBox.innerText = '';
            var key;
            for (key in json){
                let elementData = json[key];
                let nodeId = key;
                let elementDescription = elementData.description;
                let friendlyName = elementData.friendlyName || nodeId;
                let nodeHtml = elementData.nodeHtml;
                let isContainer = elementData.isContainer;
                
                let element = document.createElement('div');
                element.innerText = friendlyName;
                element.setAttribute('draggable',true);
                element.addEventListener('dragstart',event => dragGroupedElement(event));
                element.addEventListener('click',event=>showElementForm(event));
                element.setAttribute('id','el_'+nodeId);
                element.setAttribute('class','element');
                element.setAttribute('data-nodeData',JSON.stringify(elementData));
                // element.setAttribute('data-description',elementDescription);
                // element.setAttribute('data-nodeId', nodeId);
                // element.setAttribute('data-nodeHtml',nodeHtml);
                // element.setAttribute('data-isContainer',isContainer);
                elementsBox.appendChild(element);
            }
            
        });
}


function dragGroupedElement(event){
    let node = event.target;
    event.dataTransfer.setData("nodeData", 
        JSON.stringify(node.getNodeData(null))
        );
}


function setGroupOfElement(nodeId,groupName){

    let request = new Request('/wyg/set_group_on_element/?group='
        +encodeURIComponent(groupName)
        +'&element='
        +encodeURIComponent(nodeId));
    fetch(request)
        .then(response => {
            if (response.status === 200) {
                return response.text();
            }
        })
        .then(text => {
            console.log("element group was changed. text response:"+ text+"");
        });
}


function dropElementIntoGroup(event){

    let groupDiv = event.target;
    let groupName = groupDiv.id.substring(String('gr_').length);
    let nodeId = JSON.parse(event.dataTransfer.getData("nodeData"));
    let originalNode = document.getElementById("el_"+nodeId);
    
    originalNode.parentNode.removeChild(originalNode);
    let node = document.createElement('span');
    node.innerText = nodeId+", ";
    groupDiv.appendChild(node);

    setGroupOfElement(nodeId,groupName);
}