Editor.js


Wyg.Editor = class {


    constructor(templateCode,valuesCode=''){
        this.templateCode = templateCode;
        this.valuesCode = valuesCode;   
        this.map = new Wyg.Map();
        this.fields = Wyg.Parser.fields(templateCode,valuesCode);
        for (const key in this.fields){
            const field = this.fields[key];
            this.map.push('field',field);
        }
        this.savedValues = Wyg.Parser.fields(this.valuesCode);
        for (const key in this.savedValues){
            const savedValue = this.savedValues[key];
            const field = this.map.fieldFromParam('key',savedValue.key);
            if (field!==undefined)field.setValue(savedValue.value);
        }
        this.node = this.createNode();
    }

    updateValue(fieldKey,newValue){
        const field = this.map.fieldFromParam('key',fieldKey);
        const ref = this.map.refFrom('field',field);
        field.setValue(newValue);
        this.valuesCode = this.makeValuesCode();
        Wyg.Page.instance.valuesNode.value = this.valuesCode;
        Wyg.Page.instance.outputNode.value = this.getOutputCode();
        // console.log(this.valuesCode);
    }

    makeValuesCode(){
        let html = '';
        let keys = [];
        for (const index in this.fields){
            const field = this.fields[index];
            // console.log('fieldkey:'+field.key);
            if (field.value==field.defaultValue){
                keys.push({'key':field.key,'value':'default'});
                // keys[field.key] = 'default';
            } else {
                keys.push({'key':field.key,'value':field.value});
                // keys[field.key] = field.value;
            }
        }

        keys = keys.sort(function (a, b) {
            
            if (a.value=='default'&&b.value=='default')return 0;
            else if (a.value=='default')return 1;
            else if (b.value=='default')return -1;
            else return 0;
        });

        for (const index in this.savedValues){
            const field = this.savedValues[index];
            let skip = false;
            for (const fieldData of keys){
                if (field.key==fieldData.key){
                    skip = true;
                }
            }
            if (skip)continue;
            keys.push({'key':field.key,'value':field.value});
        }

        for (const fieldData of keys){

            html += '{{'+fieldData.key+'='+fieldData.value+'}}'+"\n";
        }
        return html;
    }

    

    replaceAttributeCode(node,templateNode){
        if (node.attributes===undefined){
            return;
        }
        for (let index =0;index<node.attributes.length;index++){
            const attribute = node.attributes[index];
            const templateAttribute = templateNode.attributes[index];
            const name = attribute.localName;
            const code = attribute.value.trim();
            
            if (!Wyg.Field.isCode(code))continue;

            const dataField = new Wyg.Field(code);
            let field = this.map.fieldFromParam('key',dataField.key);
            if (field===undefined){
                field = new Wyg.Field(code);
            }
            field.setTargets(attribute,templateAttribute,node);
            this.map.push('field',field,'node',node);
            field.setValue(field.value);
            
        }

    }
    isContainer(node){
        const notContainerTags = ['no_tag_found', 'input','br','textarea', '#text'];
        if (notContainerTags.includes((node.tagName || node.nodeName || 'no_tag_found').toLowerCase())){
            return false;
        }
        return true;

    }
    replaceTextNodes(node,templateNode){
        // const ref = this.map.refFromNode(node);
        for (let index =0;index<node.childNodes.length;index++){
            const child = node.childNodes[index];
            const templateChild = templateNode.childNodes[index];
            //// next line is of concern maybe
            this.replaceCode(child,templateChild);

            if (child.nodeValue===undefined
                ||!(/\{\{[^\}\n]*\}\}/g.test(child.nodeValue))){
                    continue;
            }
            const dataFields = Wyg.Parser.fields(child.nodeValue,this.valuesCode);
            for (const key in dataFields){
                const dataField = dataFields[key];
                const field = this.map.fieldFromParam('key',dataField.key);
                field.setTargets(child,templateChild,child);
                this.map.push('field',field,'node',node);
                // child.nodeValue = field.value;
                field.setValue(field.value);
            }
        }    
    }
    replaceChildCode(node,templateNode){
        if (node.children===undefined)return;
        for (let index =0;index<node.children.length;index++){
            const child = node.children[index];
            const templateChild = templateNode.children[index];
            if (child.outerHTML===undefined)continue;
            this.replaceCode(child,templateChild);
        }
    }
    replaceCode(node,templateNode){
        const code = node.outerHTML;
        this.map.push('node',node);
        this.map.push('templateNode',templateNode,'node',node);
        this.map.push('code',code,'node',node);
        this.replaceAttributeCode(node,templateNode);
        this.replaceTextNodes(node,templateNode);
        this.replaceChildCode(node,templateNode);

    }
    showCssEditor(aFieldKey){

        const field = this.map.fieldFromParam('key',aFieldKey);
        const ref = this.map.refFrom('field',field);
        const node = ref.node;
        // console.log(node);
        throw 'css editing needs work';

    }
    showJsEditor(aFieldKey){
        // console.log(aFieldKey);
        const field = this.map.fieldFromParam('key',aFieldKey);
        const ref = this.map.refFrom('field',field);
        const node = ref.node;
        // console.log(node);

        throw 'js editing needs work';
    }

    createNode(){
        // console.log('create node');
        const node = Wyg.Parser.htmlAsNode(this.templateCode,true,'div');
        node.classList.add('wyg-wrapper');
        // console.log(node);
        const templateNode = node.cloneNode(true);
        this.node = node;
        this.templateNode = templateNode;
        this.replaceChildCode(node,templateNode);
        return node;
    }

    deleteNode(node){
        const ref = this.map.refFrom('node',node);
        const templateNode = ref.templateNode;
        templateNode.parentNode.removeChild(templateNode);
        node.parentNode.removeChild(node);
        this.map.removeWhere('node',node);
        this.templateCode = this.templateNode.outerHTML;
        
    }

    getOutputCode(){
        return this.node.innerHTML.replace(` data-wyg-highlight="true"`,'');
        const editor = this.node;
        console.log(editor);
        return;
        const node = Wyg.Parser.htmlAsNode(this.templateCode,true,'div');
        // node.classList.add('wyg-wrapper');
        // console.log(node);
        const templateNode = node.cloneNode(true);
        // this.node = node;
        // this.templateNode = templateNode;
        this.replaceChildCode(node,templateNode);
        return node.innerHTML;
    }
};