All files / gogocode-core/src/html-core html-traverse.js

67.07% Statements 55/82
55.26% Branches 42/76
78.57% Functions 11/14
67.53% Lines 52/77

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 14937x 37x 135x 134x 1x     135x 1x 5x       3054x       3054x             3054x   958x 958x   958x           760x     958x 958x 853x 720x 137x     133x       958x   958x                                           958x 958x 958x 958x               958x                 2096x 1804x 1804x 28x 28x   28x 28x 28x   28x                                   292x 292x 6x     292x           3054x 744x       744x 744x 2915x 2915x 2915x 2915x 2915x   2915x   135x  
const { escapeRegExp } = require('../util');
module.exports = (ast, transformMap = {}, filePath, deleteComment) => {
    if (ast.nodeType) {
        handleNode(ast)
    } else Iif (ast.content && ast.content.children && ast.content.children.length > 0) {
        traversChildnode(ast.content.children);
    }
    if (Array.isArray(ast)) {
        ast.forEach(a => { 
            handleNode(a)
        });
    }
    function handleNode(node) {
        const posIndex = node.parentRef && node.parentRef.content.children && Array.isArray(node.parentRef.content.children)
            ? node.parentRef.content.children.indexOf(node)
            : undefined;
            
        const extra = {
            document: ast,
            nodeRef: node,
            posIndex,
            parentRef: node.parentRef,
            filePath
        }
        if (node.nodeType == 'tag' || node.nodeType == 'script') {  // 标签处理
            // 属性处理
            const attrs = node.content.attributes || [];
            const attrMap = {};
            
            attrs.forEach(attr => {
                // 处理属性值的引号
                // let content = attr.value.content.trim();
                // if (content[0] == content[content.length - 1]) {
                //     if (content.match(content[0]))
                // }
                attrMap[attr.key.content] = attr;
            });
 
            const tagHandle = transformMap.tag || [];
            tagHandle.forEach(h => {
                if (h.value) {
                    if (h.value == node.content.name) {
                        h.handle(node.content, Object.assign({ attrs, attrMap }, extra));    
                    }
                } else {
                    h.handle(node.content, Object.assign({ attrs, attrMap }, extra));
                }
            });
 
            const attrHandle = transformMap.attr || [];
            
            attrHandle.forEach(h => {
                const { key, value } = h;
                if (value) { // 某个属性有确定的key和value)
                    if (attrMap[key] && attrMap[key].value && (attrMap[key].value.content.replace(/\s/g, '') == value)) {
                        h.handle(node.content, 
                            Object.assign({ attrs, attrMap }, extra)
                        );
                    }
                } else if (key) {
                    if (attrMap[key]) { // 只要有某个属性
                        h.handle(node.content, 
                            Object.assign({ attrs, attrMap }, extra)
                        );
                    }
                } else {
                    h.handle(node.content, 
                        Object.assign({ attrs, attrMap }, extra)
                    );
                }
                
            });
 
            const eventHandle = transformMap.event || [];
            const attrKeys = Object.keys(attrMap);
            const eventAttr = attrKeys.filter(k => k.match('mx-'))[0];
            Iif (eventAttr) {
                eventHandle.forEach(h => {
                    h.handle(node.content, 
                        Object.assign({ }, extra)
                    );
                });
            }
 
            Iif (transformMap.abandonAttr) {
                for (let i = 0; i< attrs.length; i++) {
                    const attr = attrs[i];
                    if (attr && transformMap.abandonAttr.indexOf(attr.key.content) > -1) {
                        attrs.splice(i, 1);
                        i--;
                    }
                }
            }
        } else if (node.nodeType == 'text') { // 字符串处理
            const handle = transformMap.text || [];
            handle.forEach(h => {
                let isContain = false;
                switch (h.type) {
                case 'containOne':
                    isContain = h.value.some(v => node.content.value.content.match(escapeRegExp(v)))
                    Eif (isContain) {
                        h.handle(node, extra);
                    }
                    break;
                case 'containAll':
                    isContain = h.value.every(v => node.content.value.content.match(escapeRegExp(v)))
                    if (isContain) {
                        h.handle(node, extra);
                    }
                    break;
                case 'equal': 
                    if (node.content.value.content == h.value) {
                        h.handle(node, extra);
                    }
                    break;
                default:
                    h.handle(node, extra)
                }
            });
        } else {
            // 其他节点类型
            const handle = transformMap[node.nodeType];
            handle && handle.forEach(h => {
                h.handle(node, extra);
            })
 
            Iif (deleteComment && node.nodeType == 'comment') {
                // 删除所有注释
                extra.parentRef.content.children.splice(extra.posIndex, 1)
            }
        }
 
        if (node.content.children && node.content.children.length) {
            traversChildnode(node.content.children)
        }
    }
    function traversChildnode(list) {
        let index = 0;
        while(list[index]) {
            const node = list[index];
            node._index = index;
            node.reached || handleNode(node);
            node.reached = true;
            index++;
        }
        list.forEach(item => item.reached = false)
    }
    return ast;
}