cookie-umd

UMD build of cookie

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/501949/1418023/cookie-umd.js

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name          cookie-umd
// @namespace     flomk.userscripts
// @version       1.0
// @description   UMD build of cookie
// @author        flomk
// ==/UserScript==
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
	typeof define === 'function' && define.amd ? define(['exports'], factory) :
	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cookie = {}));
})(this, (function (exports) { 'use strict';
    const __toString = Object.prototype.toString
    
    /**
     * RegExp to match field-content in RFC 7230 sec 3.2
     *
     * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
     * field-vchar   = VCHAR / obs-text
     * obs-text      = %x80-FF
     */
    
    const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
    
    /**
     * Parse a cookie header.
     *
     * Parse the given cookie header string into an object
     * The object has the various cookies as keys(names) => values
     *
     * @param {string} str
     * @param {object} [options]
     * @return {object}
     * @public
     */
    
    const parse = (str, options) => {
        if (typeof str !== 'string') {
            throw new TypeError('argument str must be a string');
        }
    
        var obj = {}
        var opt = options || {};
        var dec = opt.decode || decode;
    
        var index = 0
        while (index < str.length) {
            var eqIdx = str.indexOf('=', index)
    
            // no more cookie pairs
            if (eqIdx === -1) {
                break
            }
    
            var endIdx = str.indexOf(';', index)
    
            if (endIdx === -1) {
                endIdx = str.length
            } else if (endIdx < eqIdx) {
                // backtrack on prior semicolon
                index = str.lastIndexOf(';', eqIdx - 1) + 1
                continue
            }
    
            var key = str.slice(index, eqIdx).trim()
    
            // only assign once
            if (undefined === obj[key]) {
                var val = str.slice(eqIdx + 1, endIdx).trim()
    
                // quoted values
                if (val.charCodeAt(0) === 0x22) {
                    val = val.slice(1, -1)
                }
    
                obj[key] = tryDecode(val, dec);
            }
    
            index = endIdx + 1
        }
    
        return obj;
    };
    
    /**
     * Serialize data into a cookie header.
     *
     * Serialize the a name value pair into a cookie string suitable for
     * http headers. An optional options object specified cookie parameters.
     *
     * serialize('foo', 'bar', { httpOnly: true })
     *   => "foo=bar; httpOnly"
     *
     * @param {string} name
     * @param {string} val
     * @param {object} [options]
     * @return {string}
     * @public
     */
    
    const serialize = (name, val, options) => {
        var opt = options || {};
        var enc = opt.encode || encode;
    
        if (typeof enc !== 'function') {
            throw new TypeError('option encode is invalid');
        }
    
        if (!fieldContentRegExp.test(name)) {
            throw new TypeError('argument name is invalid');
        }
    
        var value = enc(val);
    
        if (value && !fieldContentRegExp.test(value)) {
            throw new TypeError('argument val is invalid');
        }
    
        var str = name + '=' + value;
    
        if (null != opt.maxAge) {
            var maxAge = opt.maxAge - 0;
    
            if (isNaN(maxAge) || !isFinite(maxAge)) {
                throw new TypeError('option maxAge is invalid')
            }
    
            str += '; Max-Age=' + Math.floor(maxAge);
        }
    
        if (opt.domain) {
            if (!fieldContentRegExp.test(opt.domain)) {
                throw new TypeError('option domain is invalid');
            }
    
            str += '; Domain=' + opt.domain;
        }
    
        if (opt.path) {
            if (!fieldContentRegExp.test(opt.path)) {
                throw new TypeError('option path is invalid');
            }
    
            str += '; Path=' + opt.path;
        }
    
        if (opt.expires) {
            var expires = opt.expires
    
            if (!isDate(expires) || isNaN(expires.valueOf())) {
                throw new TypeError('option expires is invalid');
            }
    
            str += '; Expires=' + expires.toUTCString()
        }
    
        if (opt.httpOnly) {
            str += '; HttpOnly';
        }
    
        if (opt.secure) {
            str += '; Secure';
        }
    
        if (opt.partitioned) {
            str += '; Partitioned'
        }
    
        if (opt.priority) {
            var priority = typeof opt.priority === 'string'
                ? opt.priority.toLowerCase()
                : opt.priority
    
            switch (priority) {
                case 'low':
                    str += '; Priority=Low'
                    break
                case 'medium':
                    str += '; Priority=Medium'
                    break
                case 'high':
                    str += '; Priority=High'
                    break
                default:
                    throw new TypeError('option priority is invalid')
            }
        }
    
        if (opt.sameSite) {
            var sameSite = typeof opt.sameSite === 'string'
                ? opt.sameSite.toLowerCase() : opt.sameSite;
    
            switch (sameSite) {
                case true:
                    str += '; SameSite=Strict';
                    break;
                case 'lax':
                    str += '; SameSite=Lax';
                    break;
                case 'strict':
                    str += '; SameSite=Strict';
                    break;
                case 'none':
                    str += '; SameSite=None';
                    break;
                default:
                    throw new TypeError('option sameSite is invalid');
            }
        }
    
        return str;
    };
    
    /**
     * URL-decode string value. Optimized to skip native call when no %.
     *
     * @param {string} str
     * @returns {string}
     */
    
    const decode = str => str.indexOf('%') !== -1 ? decodeURIComponent(str) : str;
    
    /**
     * URL-encode value.
     *
     * @param {string} val
     * @returns {string}
     */
    
    const encode = val => encodeURIComponent(val);
    
    /**
     * Determine if value is a Date.
     *
     * @param {*} val
     * @private
     */
    
    const isDate = val => __toString.call(val) === '[object Date]' || val instanceof Date;
    
    /**
     * Try decoding a string using a decoding function.
     *
     * @param {string} str
     * @param {function} decode
     * @private
     */
    
    const tryDecode = (str, decode) => {
        try {
            return decode(str);
        } catch (e) {
            return str;
        }
    };
    
    
    
    exports.parse = parse;
    exports.serialize = serialize;
}));