all files / src/ index.js

100% Statements 87/87
79.31% Branches 23/29
100% Functions 20/20
100% Lines 83/83
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            81×         44× 27× 27×                                                       44×   48× 15× 15× 15×     42×   27× 27×             27× 27× 27×   27×   27×       27× 26× 26×            
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) Eif (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var stream = require("stream");
var parser2 = require("htmlparser2");
/**
 * Self closed tag predicator
 * @internal
 **/
function isSelfClosedTag(tagname) {
    return tagname === "br" || tagname === "img";
}
/**
 * Transform HTML stream
 **/
var Transformer = (function (_super) {
    __extends(Transformer, _super);
    function Transformer(option) {
        var _this = _super.call(this, option) || this;
        _this.buffer = "";
        _this.tagModifier = {};
        _this.beforeCloseTags = {};
        _this.textTransforms = [];
        _this.parser = new parser2.Parser({
            ontext: function (text) { return _this._onText(text); },
            onopentag: function (name, attrib) { return _this._onOpenTag(name, attrib); },
            onclosetag: function (name) { return _this._onCloseTag(name); }
        }, {
            recognizeSelfClosing: false
        });
        return _this;
    }
    /**
     * Append transform for tag attribute value.
     * @param tagname Target tag name. can use '*' for any tag
     * @param attribute Attribute name. can use '*' for any attribute
     * @param pattern Attribute pattern to transform
     * @param transformer Transform function.
     **/
    Transformer.prototype.onTag = function (tagname, attribute, pattern, transformer) {
        tagname = tagname.toLowerCase();
        Eif (this.tagModifier[tagname] == null) {
            this.tagModifier[tagname] = {};
        }
        attribute = attribute.toLowerCase();
        Eif (this.tagModifier[tagname][attribute] == null) {
            this.tagModifier[tagname][attribute] = [];
        }
        this.tagModifier[tagname][attribute].push([pattern, transformer]);
        return this;
    };
    /**
     * Insert some value before closing tag
     * @param tagname Target tag name. Can't use '*'
     * @param transformer Generator that returns inserted before closing tag
     **/
    Transformer.prototype.onBeforeClosingTag = function (tagname, transformer) {
        tagname = tagname.toLowerCase();
        Eif (this.beforeCloseTags[tagname] == null) {
            this.beforeCloseTags[tagname] = [];
        }
        this.beforeCloseTags[tagname].push(transformer);
        return this;
    };
    /**
     * Append text node transform
     * @param pattern Text pattern to find
     * @param transformer text node content transform function
     **/
    Transformer.prototype.onText = function (pattern, transformer) {
        this.textTransforms.push([pattern, transformer]);
        return this;
    };
    Transformer.prototype._onText = function (text) {
        this.push(Transformer._transformString(text, this.textTransforms));
    };
    Transformer._transformString = function (text, transforms) {
        for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) {
            var transform = transforms_1[_i];
            var execRes = transform[0].exec(text);
            if (execRes) {
                return transform[1](text, execRes);
            }
        }
        return text;
    };
    Transformer.prototype._onOpenTag = function (name, attrib) {
        var lowerName = name.toLowerCase();
        for (var _i = 0, _a = Object.keys(this.tagModifier)
            .filter(function (v) { return v === lowerName || v === "*"; }); _i < _a.length; _i++) {
            var tagKey = _a[_i];
            var attribModifiers = this.tagModifier[tagKey];
            var _loop_1 = function (attribKey) {
                for (var _i = 0, _a = Object.keys(attribModifiers)
                    .filter(function (v) { return v === attribKey.toLowerCase() || v === "*"; }); _i < _a.length; _i++) {
                    var attribTarget = _a[_i];
                    var valueModifiers = attribModifiers[attribTarget];
                    attrib[attribKey] = Transformer._transformString(attrib[attribKey], valueModifiers);
                }
            };
            for (var _b = 0, _c = Object.keys(attrib); _b < _c.length; _b++) {
                var attribKey = _c[_b];
                _loop_1(attribKey);
            }
        }
        var attribsStr = Object.keys(attrib).map(function (k) { return " " + k + "=\"" + attrib[k] + "\""; }).join("");
        var trailling = isSelfClosedTag(name) ? "/" : "";
        if (isSelfClosedTag(name)) {
            this._onProcessCloseTag(name);
        }
        this.push("<" + name + attribsStr + trailling + ">");
    };
    Transformer.prototype._onProcessCloseTag = function (name) {
        if (this.beforeCloseTags[name]) {
            for (var _i = 0, _a = this.beforeCloseTags[name]; _i < _a.length; _i++) {
                var transformer = _a[_i];
                this.push(transformer());
            }
        }
    };
    Transformer.prototype._onCloseTag = function (name) {
        if (!isSelfClosedTag(name)) {
            this._onProcessCloseTag(name);
            this.push("</" + name + ">");
        }
    };
    Transformer.prototype._transform = function (chunk, encoding, callback) {
        var chunkStr = typeof chunk === "string" ? chunk : chunk.toString('utf-8');
        this.parser.write(chunkStr);
        callback();
    };
    Transformer.prototype._flush = function (callback) {
        this.parser.end();
    };
    return Transformer;
}(stream.Transform));
exports.Transformer = Transformer;
//# sourceMappingURL=index.js.map