<!-- webview only -->
<template>
    <section class="bl___rich-text-container" v-html="htmlString"></section>
</template>

<script>
const parser = new DOMParser();
const serializer = new XMLSerializer();
const helper = function (nodeList) {
    return [...nodeList]
        .filter((node) => {
            return (node.nodeType === 1 && tagList.indexOf(node.tagName.toLowerCase()) >= 0) || node.nodeType === 3;
        })
        .map((node) => {
            if (node.nodeType === 1) {
                const tagName = node.tagName.toLowerCase()
                const attrs = {};
                tagInfos[tagList.indexOf(tagName)][1].forEach(attr => {
                    const attrValue = node.getAttribute(attr);
                    if (attrValue !== null) {
                        attrs[attr] = attrValue;
                    }
                });

                return {
                    name: tagName,
                    attrs: attrs,
                    children: helper(node.childNodes)
                };
            } else if (node.nodeType === 3) {
                return {
                    type: 'text',
                    text: node.nodeValue
                }
            }
        });
};
const tagInfos = [["a", ["class", "style"]], ["abbr", ["class", "style"]], ["b", ["class", "style"]], ["blockquote", ["class", "style"]], ["br", ["class", "style"]], ["code", ["class", "style"]], ["col", ["class", "style", "span", "width"]], ["colgroup", ["class", "style", "span", "width"]], ["dd", ["class", "style"]], ["del", ["class", "style"]], ["div", ["class", "style"]], ["dl", ["class", "style"]], ["dt", ["class", "style"]], ["em", ["class", "style"]], ["fieldset", ["class", "style"]], ["h1", ["class", "style"]], ["h2", ["class", "style"]], ["h3", ["class", "style"]], ["h4", ["class", "style"]], ["h5", ["class", "style"]], ["h6", ["class", "style"]], ["hr", ["class", "style"]], ["i", ["class", "style"]], ["img", ["class", "style", "alt", "src", "height", "width"]], ["ins", ["class", "style"]], ["label", ["class", "style"]], ["legend", ["class", "style"]], ["li", ["class", "style"]], ["ol", ["class", "style", "start", "type"]], ["p", ["class", "style"]], ["q", ["class", "style"]], ["span", ["class", "style"]], ["strong", ["class", "style"]], ["sub", ["class", "style"]], ["sup", ["class", "style"]], ["table", ["class", "style", "width"]], ["tbody", ["class", "style"]], ["td", ["class", "style", "colspan", "height", "rowspan", "width"]], ["tfoot", ["class", "style"]], ["th", ["class", "style", "colspan", "height", "rowspan", "width"]], ["thead", ["class", "style"]], ["tr", ["class", "style"]], ["ul", ["class", "style"]]];
const tagList = tagInfos.map(tag => tag[0]);
const spaceValues = ['ensp', 'emsp', 'nbsp'];

export default {
    name: 'RichText',
    props: {
        nodes: {
            type: [Array, String],
            default: []
        },
        space: {
            type: String,
            default: ''
        }
    },
    computed: {
        htmlString() {
            let result = this.nodes;
            if (typeof this.nodes === 'string') {
                const document = parser.parseFromString(this.nodes, 'text/html');
                const body = document.body;
                result = helper(body.childNodes);
            }
            const root = document.createElement('root');
            this.makeDOM(root, result);
            return serializer.serializeToString(root).replace(/<\/?root.*?>/g, '');
        }
    },
    methods: {
        makeDOM(parentNode, nodes) {
            nodes.forEach(({ name, type = 'node', attrs = {}, children = [], text = '' }) => {
                    let thisNode
                    if (type === 'node') {
                        thisNode = document.createElement(name);
                        Object.keys(attrs).forEach(attr => {
                            thisNode.setAttribute(attr, attrs[attr]);
                        });
                        this.makeDOM(thisNode, children);
                    } else {
                        // const textToShow = spaceValues.indexOf(this.space) >= 0 ? text.replace(/ /g, `&${this.space};`) : text;
                        thisNode = document.createTextNode(text);
                    }
                    parentNode.appendChild(thisNode);
            });
        }
    }
}
</script>

<style>
.bl___rich-text-container {
    width: 100%;
}
</style>
