232 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			232 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
Object.defineProperty(exports, "__esModule", { value: true });
 | 
						|
exports.attributeRules = void 0;
 | 
						|
var boolbase_1 = require("boolbase");
 | 
						|
/**
 | 
						|
 * All reserved characters in a regex, used for escaping.
 | 
						|
 *
 | 
						|
 * Taken from XRegExp, (c) 2007-2020 Steven Levithan under the MIT license
 | 
						|
 * https://github.com/slevithan/xregexp/blob/95eeebeb8fac8754d54eafe2b4743661ac1cf028/src/xregexp.js#L794
 | 
						|
 */
 | 
						|
var reChars = /[-[\]{}()*+?.,\\^$|#\s]/g;
 | 
						|
function escapeRegex(value) {
 | 
						|
    return value.replace(reChars, "\\$&");
 | 
						|
}
 | 
						|
/**
 | 
						|
 * Attributes that are case-insensitive in HTML.
 | 
						|
 *
 | 
						|
 * @private
 | 
						|
 * @see https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
 | 
						|
 */
 | 
						|
var caseInsensitiveAttributes = new Set([
 | 
						|
    "accept",
 | 
						|
    "accept-charset",
 | 
						|
    "align",
 | 
						|
    "alink",
 | 
						|
    "axis",
 | 
						|
    "bgcolor",
 | 
						|
    "charset",
 | 
						|
    "checked",
 | 
						|
    "clear",
 | 
						|
    "codetype",
 | 
						|
    "color",
 | 
						|
    "compact",
 | 
						|
    "declare",
 | 
						|
    "defer",
 | 
						|
    "dir",
 | 
						|
    "direction",
 | 
						|
    "disabled",
 | 
						|
    "enctype",
 | 
						|
    "face",
 | 
						|
    "frame",
 | 
						|
    "hreflang",
 | 
						|
    "http-equiv",
 | 
						|
    "lang",
 | 
						|
    "language",
 | 
						|
    "link",
 | 
						|
    "media",
 | 
						|
    "method",
 | 
						|
    "multiple",
 | 
						|
    "nohref",
 | 
						|
    "noresize",
 | 
						|
    "noshade",
 | 
						|
    "nowrap",
 | 
						|
    "readonly",
 | 
						|
    "rel",
 | 
						|
    "rev",
 | 
						|
    "rules",
 | 
						|
    "scope",
 | 
						|
    "scrolling",
 | 
						|
    "selected",
 | 
						|
    "shape",
 | 
						|
    "target",
 | 
						|
    "text",
 | 
						|
    "type",
 | 
						|
    "valign",
 | 
						|
    "valuetype",
 | 
						|
    "vlink",
 | 
						|
]);
 | 
						|
function shouldIgnoreCase(selector, options) {
 | 
						|
    return typeof selector.ignoreCase === "boolean"
 | 
						|
        ? selector.ignoreCase
 | 
						|
        : selector.ignoreCase === "quirks"
 | 
						|
            ? !!options.quirksMode
 | 
						|
            : !options.xmlMode && caseInsensitiveAttributes.has(selector.name);
 | 
						|
}
 | 
						|
/**
 | 
						|
 * Attribute selectors
 | 
						|
 */
 | 
						|
exports.attributeRules = {
 | 
						|
    equals: function (next, data, options) {
 | 
						|
        var adapter = options.adapter;
 | 
						|
        var name = data.name;
 | 
						|
        var value = data.value;
 | 
						|
        if (shouldIgnoreCase(data, options)) {
 | 
						|
            value = value.toLowerCase();
 | 
						|
            return function (elem) {
 | 
						|
                var attr = adapter.getAttributeValue(elem, name);
 | 
						|
                return (attr != null &&
 | 
						|
                    attr.length === value.length &&
 | 
						|
                    attr.toLowerCase() === value &&
 | 
						|
                    next(elem));
 | 
						|
            };
 | 
						|
        }
 | 
						|
        return function (elem) {
 | 
						|
            return adapter.getAttributeValue(elem, name) === value && next(elem);
 | 
						|
        };
 | 
						|
    },
 | 
						|
    hyphen: function (next, data, options) {
 | 
						|
        var adapter = options.adapter;
 | 
						|
        var name = data.name;
 | 
						|
        var value = data.value;
 | 
						|
        var len = value.length;
 | 
						|
        if (shouldIgnoreCase(data, options)) {
 | 
						|
            value = value.toLowerCase();
 | 
						|
            return function hyphenIC(elem) {
 | 
						|
                var attr = adapter.getAttributeValue(elem, name);
 | 
						|
                return (attr != null &&
 | 
						|
                    (attr.length === len || attr.charAt(len) === "-") &&
 | 
						|
                    attr.substr(0, len).toLowerCase() === value &&
 | 
						|
                    next(elem));
 | 
						|
            };
 | 
						|
        }
 | 
						|
        return function hyphen(elem) {
 | 
						|
            var attr = adapter.getAttributeValue(elem, name);
 | 
						|
            return (attr != null &&
 | 
						|
                (attr.length === len || attr.charAt(len) === "-") &&
 | 
						|
                attr.substr(0, len) === value &&
 | 
						|
                next(elem));
 | 
						|
        };
 | 
						|
    },
 | 
						|
    element: function (next, data, options) {
 | 
						|
        var adapter = options.adapter;
 | 
						|
        var name = data.name, value = data.value;
 | 
						|
        if (/\s/.test(value)) {
 | 
						|
            return boolbase_1.falseFunc;
 | 
						|
        }
 | 
						|
        var regex = new RegExp("(?:^|\\s)".concat(escapeRegex(value), "(?:$|\\s)"), shouldIgnoreCase(data, options) ? "i" : "");
 | 
						|
        return function element(elem) {
 | 
						|
            var attr = adapter.getAttributeValue(elem, name);
 | 
						|
            return (attr != null &&
 | 
						|
                attr.length >= value.length &&
 | 
						|
                regex.test(attr) &&
 | 
						|
                next(elem));
 | 
						|
        };
 | 
						|
    },
 | 
						|
    exists: function (next, _a, _b) {
 | 
						|
        var name = _a.name;
 | 
						|
        var adapter = _b.adapter;
 | 
						|
        return function (elem) { return adapter.hasAttrib(elem, name) && next(elem); };
 | 
						|
    },
 | 
						|
    start: function (next, data, options) {
 | 
						|
        var adapter = options.adapter;
 | 
						|
        var name = data.name;
 | 
						|
        var value = data.value;
 | 
						|
        var len = value.length;
 | 
						|
        if (len === 0) {
 | 
						|
            return boolbase_1.falseFunc;
 | 
						|
        }
 | 
						|
        if (shouldIgnoreCase(data, options)) {
 | 
						|
            value = value.toLowerCase();
 | 
						|
            return function (elem) {
 | 
						|
                var attr = adapter.getAttributeValue(elem, name);
 | 
						|
                return (attr != null &&
 | 
						|
                    attr.length >= len &&
 | 
						|
                    attr.substr(0, len).toLowerCase() === value &&
 | 
						|
                    next(elem));
 | 
						|
            };
 | 
						|
        }
 | 
						|
        return function (elem) {
 | 
						|
            var _a;
 | 
						|
            return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.startsWith(value)) &&
 | 
						|
                next(elem);
 | 
						|
        };
 | 
						|
    },
 | 
						|
    end: function (next, data, options) {
 | 
						|
        var adapter = options.adapter;
 | 
						|
        var name = data.name;
 | 
						|
        var value = data.value;
 | 
						|
        var len = -value.length;
 | 
						|
        if (len === 0) {
 | 
						|
            return boolbase_1.falseFunc;
 | 
						|
        }
 | 
						|
        if (shouldIgnoreCase(data, options)) {
 | 
						|
            value = value.toLowerCase();
 | 
						|
            return function (elem) {
 | 
						|
                var _a;
 | 
						|
                return ((_a = adapter
 | 
						|
                    .getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.substr(len).toLowerCase()) === value && next(elem);
 | 
						|
            };
 | 
						|
        }
 | 
						|
        return function (elem) {
 | 
						|
            var _a;
 | 
						|
            return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.endsWith(value)) &&
 | 
						|
                next(elem);
 | 
						|
        };
 | 
						|
    },
 | 
						|
    any: function (next, data, options) {
 | 
						|
        var adapter = options.adapter;
 | 
						|
        var name = data.name, value = data.value;
 | 
						|
        if (value === "") {
 | 
						|
            return boolbase_1.falseFunc;
 | 
						|
        }
 | 
						|
        if (shouldIgnoreCase(data, options)) {
 | 
						|
            var regex_1 = new RegExp(escapeRegex(value), "i");
 | 
						|
            return function anyIC(elem) {
 | 
						|
                var attr = adapter.getAttributeValue(elem, name);
 | 
						|
                return (attr != null &&
 | 
						|
                    attr.length >= value.length &&
 | 
						|
                    regex_1.test(attr) &&
 | 
						|
                    next(elem));
 | 
						|
            };
 | 
						|
        }
 | 
						|
        return function (elem) {
 | 
						|
            var _a;
 | 
						|
            return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.includes(value)) &&
 | 
						|
                next(elem);
 | 
						|
        };
 | 
						|
    },
 | 
						|
    not: function (next, data, options) {
 | 
						|
        var adapter = options.adapter;
 | 
						|
        var name = data.name;
 | 
						|
        var value = data.value;
 | 
						|
        if (value === "") {
 | 
						|
            return function (elem) {
 | 
						|
                return !!adapter.getAttributeValue(elem, name) && next(elem);
 | 
						|
            };
 | 
						|
        }
 | 
						|
        else if (shouldIgnoreCase(data, options)) {
 | 
						|
            value = value.toLowerCase();
 | 
						|
            return function (elem) {
 | 
						|
                var attr = adapter.getAttributeValue(elem, name);
 | 
						|
                return ((attr == null ||
 | 
						|
                    attr.length !== value.length ||
 | 
						|
                    attr.toLowerCase() !== value) &&
 | 
						|
                    next(elem));
 | 
						|
            };
 | 
						|
        }
 | 
						|
        return function (elem) {
 | 
						|
            return adapter.getAttributeValue(elem, name) !== value && next(elem);
 | 
						|
        };
 | 
						|
    },
 | 
						|
};
 |