Code coverage report for htmlcs/lib/parse.js

Statements: 100% (49 / 49)      Branches: 100% (8 / 8)      Functions: 100% (8 / 8)      Lines: 100% (49 / 49)      Ignored: none     

All files » htmlcs/lib/ » parse.js
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          1 1 1   1 1     1 890   890   890 852     890       1 38   38   38 113   113 113   113 113     38   38       1 38 38 38       38 327   327 11659     397 397 397     11262         327               1 38     38     38     38 327       38     38     38     38 796       38   38     1  
/**
 * @file parse code
 * @author nighca<nighca@live.cn>
 */
 
var htmlparser2 = require('htmlparser2');
var Parser = htmlparser2.Parser;
var DomHandler = htmlparser2.DomHandler;
 
var util = require('./util');
var Node = require('./node');
 
// transform node to Node instance & recursively transform its children
var transformRecursively = function (node, root) {
    root = root || node;
 
    Node.init(node, root);
 
    node.childNodes.forEach(function (childNode) {
        transformRecursively(childNode, root);
    });
 
    return node;
};
 
// wrap dom with <document>
var wrapDocument = function (arr) {
    var document = htmlparser2.parseDOM('<document></document>')[0];
 
    document.children = arr;
 
    for (var i = 0; i < arr.length; i++) {
        var node = arr[i];
 
        node.prev = arr[i - 1] || null;
        node.next = arr[i + 1] || null;
 
        node.root = document;
        node.parent = null;
    }
 
    transformRecursively(document);
 
    return document;
};
 
// gen a position method with given content
var genPosition = function (content) {
    var start = 0;
    var line = 0;
    var col = 0;
 
    // the position method
    // elements should be passed with startIndex-low-to-high
    return function (element) {
        var index = element.startIndex;
 
        for (; start <= index; start++) {
            switch (content[start]) {
 
                case '\n':
                    col = -1;
                    line++;
                    break;
 
                default:
                    col++;
 
            }
        }
 
        element.startPos = {
            line: line + 1,
            col: col + 1
        };
    };
};
 
// parse given html content to document object
var parse = function (htmlCode, options) {
    htmlCode = htmlCode.replace(/\r\n/g, '\n');
 
    // record all elements
    var elements = [];
 
    // handler during parse
    var handlerOption = {
        withStartIndices: true
    };
    var handler = new DomHandler(handlerOption, function (element) {
        elements.push(element);
    });
 
    // parser
    var parser = new Parser(handler, options);
 
    // do parse
    parser.end(htmlCode);
 
    // method to position element
    var position = genPosition(htmlCode);
 
    // position elements one by one (sorted to position high-efficiently)
    elements.sort(function (e1, e2) {
        return e1.startIndex - e2.startIndex;
    }).forEach(position);
 
    // wrap dom with <document>
    var document = wrapDocument(handler.dom);
 
    return document;
};
 
module.exports = parse;