builder_bottom.html





<script>


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);
    }
    
    </script>
    
    </div>
    </div>
    
    </body>
    </html>