Greasy Fork is available in English.

Message

一款优雅的原生JS页面消息提示插件,兼容性良好,无任何依赖。 An elegant native JS page message prompt plug-in, good compatibility, no dependency.

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greasyfork.org/scripts/462234/1497815/Message.js

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Qmsg = factory());
})(this, (function () { 'use strict';

    /**
     * 兼容处理
     */
    function CompatibleProcessing() {
        /* 处理Object.assign不存在的问题 */
        try {
            if (typeof Object.assign !== "function") {
                Object.assign = function (target) {
                    target = Object(target);
                    if (arguments.length > 1) {
                        let sourceList = [...arguments].splice(1, arguments.length - 1);
                        sourceList.forEach((sourceItem) => {
                            for (var sourceKey in sourceItem) {
                                if (Object.prototype.hasOwnProperty.call(sourceItem, sourceKey)) {
                                    target[sourceKey] = sourceItem[sourceKey];
                                }
                            }
                        });
                    }
                    return target;
                };
            }
        }
        catch (error) {
            console.warn(error);
        }
        /* 'classList' 兼容处理,add,remove不支持传入多个cls参数 */
        try {
            if (!("classList" in document.documentElement)) {
                Object.defineProperty(HTMLElement.prototype, "classList", {
                    get: function () {
                        var self = this;
                        function update(fn) {
                            return function (value) {
                                var classes = self.className.split(/\s+/g), index = classes.indexOf(value);
                                fn(classes, index, value);
                                self.className = classes.join(" ");
                            };
                        }
                        return {
                            add: update(function (classes, index, value) {
                                if (!~index)
                                    classes.push(value);
                            }),
                            remove: update(function (classes, index) {
                                if (~index)
                                    classes.splice(index, 1);
                            }),
                            toggle: update(function (classes, index, value) {
                                if (~index)
                                    classes.splice(index, 1);
                                else
                                    classes.push(value);
                            }),
                            contains: function (value) {
                                return !!~self.className.split(/\s+/g).indexOf(value);
                            },
                            item: function (index) {
                                return self.className.split(/\s+/g)[index] || null;
                            },
                        };
                    },
                });
            }
        }
        catch (error) {
            console.warn(error);
        }
    }

    const QmsgAnimation = {
        /** 状态 & 动画 */
        $state: {
            opening: "MessageMoveIn",
            done: "",
            closing: "MessageMoveOut",
        },
        $name: {
            startNameList: [
                "animationName",
                "WebkitAnimationName",
                "MozAnimationName",
                "msAnimationName",
                "OAnimationName",
            ],
            endNameList: [
                "animationend",
                "webkitAnimationEnd",
                "mozAnimationEnd",
                "MSAnimationEnd",
                "oanimationend",
            ],
        },
        /**
         * 获取元素上的animationName属性
         * @param element
         */
        getStyleAnimationNameValue(element) {
            for (let index = 0; index < this.$name.startNameList.length; index++) {
                let animationName = this.$name.startNameList[index];
                let animationNameValue = element.style[animationName];
                if (animationNameValue != null) {
                    return animationNameValue;
                }
            }
        },
        /**
         * 设置元素上的animationName属性
         * @param element
         * @param animationNameValue
         */
        setStyleAnimationName(element, animationNameValue = "") {
            this.$name.startNameList.forEach((animationName) => {
                if (animationName in element.style) {
                    element.style[animationName] = animationNameValue;
                }
            });
        },
    };

    const QmsgConfig = {
        /** 声明插件名称 */
        PLUGIN_NAME: "qmsg",
        /** 命名空间,用于css和事件 */
        NAMESPACE: "qmsg",
        /** 实例配置的固定的默认值 */
        INS_DEFAULT: {},
        /** 固定的默认值 */
        DEFAULT: {
            animation: true,
            autoClose: true,
            content: "",
            html: false,
            isHTML: false,
            position: "top",
            showClose: false,
            maxNums: 5,
            onClose: null,
            showIcon: true,
            showMoreContent: false,
            showReverse: false,
            timeout: 2500,
            type: "info",
            zIndex: 50000,
            style: "",
            customClass: "",
            isLimitWidth: false,
            limitWidthNum: 200,
            limitWidthWrap: "no-wrap",
            consoleLogContent: false,
        },
        /**
         * 是否支持动画属性
         */
        CAN_ANIMATION: Boolean(QmsgAnimation.getStyleAnimationNameValue(document.createElement("div")) !=
            null),
    };

    const QmsgHeaderCloseIcon = '<svg width="16" height="16" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M14 14L34 34" stroke="#909399" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 34L34 14" stroke="#909399" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>';
    const QmsgIcon = {
        info: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512 64q190.016 4.992 316.512 131.488T960 512q-4.992 190.016-131.488 316.512T512 960q-190.016-4.992-316.512-131.488T64 512q4.992-190.016 131.488-316.512T512 64zm67.008 275.008q26.016 0 43.008-15.488t16.992-41.504-16.992-41.504-42.496-15.488-42.496 15.488-16.992 41.504 16.992 41.504 42.016 15.488zm12 360q0-6.016.992-16T592 664l-52.992 60.992q-8 8.992-16.512 14.016T508 742.016q-8.992-4-8-14.016l88-276.992q4.992-28-8.992-48t-44.992-24q-35.008.992-76.512 29.504t-72.512 72.512v15.008q-.992 10.016 0 19.008l52.992-60.992q8-8.992 16.512-14.016T468 437.024q10.016 4.992 7.008 16l-87.008 276q-7.008 24.992 7.008 44.512T444 800.032q50.016-.992 84-28.992t63.008-72z" fill="#909399"/></svg>',
        warning: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512 64C264.64 64 64 264.64 64 512c0 247.424 200.64 448 448 448 247.488 0 448-200.576 448-448 0-247.36-200.512-448-448-448zm0 704c-26.432 0-48-21.504-48-48s21.568-48 48-48c26.624 0 48 21.504 48 48s-21.376 48-48 48zm48-240c0 26.56-21.376 48-48 48-26.432 0-48-21.44-48-48V304c0-26.56 21.568-48 48-48 26.624 0 48 21.44 48 48v224z" fill="#E6A23C"/></svg>',
        error: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512 64C264.58 64 64 264.58 64 512s200.58 448 448 448 448-200.57 448-448S759.42 64 512 64zm158.39 561.14a32 32 0 1 1-45.25 45.26L512 557.26 398.86 670.4a32 32 0 0 1-45.25-45.26L466.75 512 353.61 398.86a32 32 0 0 1 45.25-45.25L512 466.74l113.14-113.13a32 32 0 0 1 45.25 45.25L557.25 512z" fill="#F56C6C"/></svg>',
        success: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512 64q190.016 4.992 316.512 131.488T960 512q-4.992 190.016-131.488 316.512T512 960q-190.016-4.992-316.512-131.488T64 512q4.992-190.016 131.488-316.512T512 64zm-56 536l-99.008-99.008q-12-11.008-27.488-11.008t-27.008 11.488-11.488 26.496 11.008 27.008l127.008 127.008q11.008 11.008 27.008 11.008t27.008-11.008l263.008-263.008q15.008-15.008 9.504-36.512t-27.008-27.008-36.512 9.504z" fill="#67C23A"/></svg>',
        loading: '<svg class="animate-turn" width="16" height="16" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" fill-opacity=".01" d="M0 0h48v48H0z"/><path d="M4 24c0 11.046 8.954 20 20 20s20-8.954 20-20S35.046 4 24 4" stroke="#409eff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M36 24c0-6.627-5.373-12-12-12s-12 5.373-12 12 5.373 12 12 12" stroke="#409eff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>',
    };

    const QmsgInstanceStorage = {
        QmsgList: [],
        /**
         * 移除实例
         * @param uuid
         */
        remove(uuid) {
            for (let index = 0; index < QmsgInstanceStorage.QmsgList.length; index++) {
                if (QmsgInstanceStorage.QmsgList[index].uuid === uuid) {
                    QmsgInstanceStorage.QmsgList.splice(index, 1);
                    return;
                }
            }
        },
    };

    const QmsgCSS = {
        css: `@charset "utf-8";
      .qmsg.qmsg-wrapper{position:fixed;top:16px;left:0;z-index:50000;display:flex;box-sizing:border-box;margin:0;padding:0;width:100%;color:rgba(0,0,0,.55);list-style:none;font-variant:tabular-nums;font-size:13px;line-height:1;font-feature-settings:"tnum";pointer-events:none;flex-direction:column;}
      .qmsg.qmsg-data-position-center,.qmsg.qmsg-data-position-left,.qmsg.qmsg-data-position-right{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);}
      .qmsg.qmsg-data-position-bottom,.qmsg.qmsg-data-position-bottomleft,.qmsg.qmsg-data-position-bottomright{position:fixed;top:unset;bottom:0;bottom:8px;left:50%;transform:translate(-50%,0);}
      .qmsg.qmsg-data-position-bottomleft .qmsg-item,.qmsg.qmsg-data-position-left .qmsg-item,.qmsg.qmsg-data-position-topleft .qmsg-item{text-align:left;}
      .qmsg.qmsg-data-position-bottom .qmsg-item,.qmsg.qmsg-data-position-center .qmsg-item,.qmsg.qmsg-data-position-top .qmsg-item{text-align:center;}
      .qmsg.qmsg-data-position-bottomright .qmsg-item,.qmsg.qmsg-data-position-right .qmsg-item,.qmsg.qmsg-data-position-topright .qmsg-item{text-align:right;}
      .qmsg .qmsg-item{position:relative;padding:8px;text-align:center;-webkit-animation-duration:.3s;animation-duration:.3s;}
      .qmsg .qmsg-item .qmsg-count{position:absolute;top:-4px;left:-4px;display:inline-block;height:16px;min-width:16px;border-radius:2px;background-color:red;color:#fff;text-align:center;font-size:12px;line-height:16px;-webkit-animation-duration:.3s;animation-duration:.3s;}
      .qmsg .qmsg-item:first-child{margin-top:-8px;}
      .qmsg .qmsg-content{position:relative;display:inline-block;padding:10px 12px;max-width:80%;min-width:40px;border-radius:4px;background:#fff;box-shadow:0 4px 12px rgba(0,0,0,.15);text-align:center;pointer-events:all;}
      .qmsg .qmsg-content [class^=qmsg-content-]{display:flex;align-items:center;}
      .qmsg .qmsg-icon{position:relative;top:1px;display:inline-block;margin-right:8px;color:inherit;vertical-align:-.125em;text-align:center;text-transform:none;font-style:normal;font-size:16px;line-height:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}
      .qmsg .qmsg-icon svg{display:inline-block;}
      .qmsg .qmsg-content .qmsg-show-more-content{display:flex;align-items:center;white-space:unset;overflow:unset;text-overflow:unset;padding-right:unset}
      .qmsg .qmsg-content-info .qmsg-icon{color:#1890ff;}
      .qmsg .qmsg-icon-close{margin:0;margin-left:8px;padding:0;outline:0;border:none;background-color:transparent;color:rgba(0,0,0,.45);font-size:12px;cursor:pointer;transition:color .3s;}
      .qmsg .qmsg-icon-close:hover>svg path{stroke:#555;}
      .qmsg .qmsg-icon-close.qmsg-show-more-content{position:unset;overflow:unset;padding-left:6px;margin-right:0}
      .qmsg .animate-turn{animation:MessageTurn 1s linear infinite;-webkit-animation:MessageTurn 1s linear infinite;}
      @keyframes MessageTurn{
            0%{-webkit-transform:rotate(0);}
            25%{-webkit-transform:rotate(90deg);}
            50%{-webkit-transform:rotate(180deg);}
            75%{-webkit-transform:rotate(270deg);}
            100%{-webkit-transform:rotate(360deg);}
      }
      @-webkit-keyframes MessageTurn{
            0%{-webkit-transform:rotate(0);}
            25%{-webkit-transform:rotate(90deg);}
            50%{-webkit-transform:rotate(180deg);}
            75%{-webkit-transform:rotate(270deg);}
            100%{-webkit-transform:rotate(360deg);}
      }
      @-webkit-keyframes MessageMoveOut{
            0%{max-height:150px;opacity:1;}
            to{max-height:0;opacity:0;}
      }
      @keyframes MessageMoveOut{
            0%{max-height:150px;opacity:1;}
            to{max-height:0;opacity:0;}
      }
      @-webkit-keyframes MessageMoveIn{
            0%{opacity:0;transform:translateY(-100%);transform-origin:0 0;}
            to{opacity:1;transform:translateY(0);transform-origin:0 0;}
      }
      @keyframes MessageMoveIn{
            0%{opacity:0;transform:translateY(-100%);transform-origin:0 0;}
            to{opacity:1;transform:translateY(0);transform-origin:0 0;}
      }
      @-webkit-keyframes MessageShake{
            0%,100%{opacity:1;transform:translateX(0);}
            25%,75%{opacity:.75;transform:translateX(-4px);}
            50%{opacity:.25;transform:translateX(4px);}
      }
      @keyframes MessageShake{
            0%,100%{opacity:1;transform:translateX(0);}
            25%,75%{opacity:.75;transform:translateX(-4px);}
            50%{opacity:.25;transform:translateX(4px);}
      }`,
        /**
         * 获取CSS元素
         */
        getStyleElement() {
            let cssResourceNode = document.createElement("style");
            cssResourceNode.setAttribute("type", "text/css");
            cssResourceNode.setAttribute("data-type", QmsgConfig.PLUGIN_NAME);
            cssResourceNode.innerHTML = this.css;
            return cssResourceNode;
        },
    };

    /**
     * 每条消息的构造函数
     */
    class QmsgMsg {
        /**
         * setTimeout的id
         */
        timeId;
        /**
         * 启动时间
         */
        startTime;
        /**
         * 关闭时间
         */
        endTime;
        /**
         * Qmsg的配置
         */
        setting;
        /**
         * uuid
         */
        uuid;
        /**
         * 当前动画状态
         */
        state;
        /**
         * 当前相同消息的数量
         */
        repeatNum;
        /**
         * 主元素
         */
        $Qmsg;
        constructor(option, uuid) {
            this.timeId = void 0;
            this.startTime = Date.now();
            this.endTime = null;
            // this.#setting = Object.assign({}, QmsgStore.DEFAULT, this.option);
            this.setting = QmsgUtils.toDynamicObject(QmsgConfig.DEFAULT, option, QmsgConfig.INS_DEFAULT);
            this.uuid = uuid;
            this.state = "opening";
            this.$Qmsg = document.createElement("div");
            this.repeatNum = 1;
            this.detectionType();
            this.init();
            if (this.setting.consoleLogContent) {
                // 控制台输出content
                console.log(this.setting.content);
            }
        }
        /**
         * 获取当前配置
         * @returns
         */
        getSetting() {
            return this.setting;
        }
        /**
         * 获取当前相同的数量
         * @returns
         */
        getRepeatNum() {
            return this.repeatNum;
        }
        /**
         * 设置repeatNum值
         * @param num 重复的数量
         */
        setRepeatNum(num) {
            this.repeatNum = num;
        }
        /**
         * 设置repeatNum自增
         */
        setRepeatNumIncreasing() {
            this.repeatNum++;
        }
        /**
         * 初始化元素
         */
        init() {
            let QmsgContext = this;
            if (this.setting.customClass &&
                typeof this.setting.customClass === "string") {
                /* 设置自定义类名 */
                this.$Qmsg.classList.add(this.setting.customClass);
            }
            // 设置svg图标
            let $svg = QmsgIcon[this.setting.type || "info"];
            let contentClassName = QmsgUtils.getNameSpacify("content-" + this.setting.type || "info");
            if (this.setting.showClose) {
                // 显示 关闭图标
                contentClassName += " " + QmsgUtils.getNameSpacify("content-with-close");
            }
            // 内容兼容处理
            let content = this.setting.content || "";
            // 关闭图标 自定义额外className
            let extraCloseIconClassName = "";
            // 关闭图标svg
            let $closeSvg = QmsgHeaderCloseIcon;
            if (this.setting.showMoreContent) {
                // 显示更多内容
                contentClassName += "qmsg-show-more-content";
                extraCloseIconClassName += "qmsg-show-more-content";
            }
            let $closeIcon = "";
            if (this.setting.showClose) {
                /* 显示右上角的关闭图标按钮 */
                $closeIcon = `<i class="qmsg-icon qmsg-icon-close ${extraCloseIconClassName}">${$closeSvg}</i>`;
            }
            /* 内容 */
            let $content = document.createElement("span");
            let $positionClassName = QmsgUtils.getNameSpacify("data-position", this.setting.position.toLowerCase());
            if (this.setting.html || this.setting.isHTML) {
                /* 内容是html */
                $content.innerHTML = content;
            }
            else {
                /* 内容是纯文本 */
                $content.innerText = content;
            }
            if (this.setting.isLimitWidth) {
                /* 限制宽度 */
                let limitWidthNum = this.setting.limitWidthNum;
                if (typeof limitWidthNum === "string") {
                    if (QmsgUtils.isNumber(limitWidthNum)) {
                        limitWidthNum = limitWidthNum + "px";
                    }
                }
                else {
                    limitWidthNum = limitWidthNum.toString() + "px";
                }
                $content.style.maxWidth = limitWidthNum;
                $content.style.width = limitWidthNum;
                /* 设置换行 */
                if (this.setting.limitWidthWrap === "no-wrap") {
                    /* 禁止换行 */
                    $content.style.whiteSpace = "nowrap";
                }
                else if (this.setting.limitWidthWrap === "ellipsis") {
                    /* 禁止换行且显示省略号 */
                    $content.style.whiteSpace = "nowrap";
                    $content.style.overflow = "hidden";
                    $content.style.textOverflow = "ellipsis";
                }
                else if (this.setting.limitWidthWrap === "wrap") {
                    /* 允许换行 */
                    /* 默认的 */
                    $content.style.whiteSpace = "";
                }
            }
            this.$Qmsg.innerHTML = /*html*/ `
        <div class="qmsg-content">
            <div class="${contentClassName}">
            ${this.setting.showIcon ? `<i class="qmsg-icon">${$svg}</i>` : ""}
                ${$content.outerHTML}
                ${$closeIcon}
            </div>
        </div>
        `;
            /** 内容容器 */
            let $contentContainer = this.$Qmsg.querySelector(".qmsg-content");
            this.$Qmsg.classList.add(QmsgUtils.getNameSpacify("item"));
            this.$Qmsg.setAttribute(QmsgUtils.getNameSpacify("uuid"), this.uuid);
            // 获取页面中的shadowRoot的容器元素
            let $shadowContainer = document.querySelector(".qmsg-shadow-container");
            let $shadowRoot = $shadowContainer?.shadowRoot;
            if (!$shadowContainer) {
                // 页面中不存在ShadowRoot容器元素
                // 添加新增的ShadowRoot容器元素
                $shadowContainer = document.createElement("div");
                $shadowContainer.className = "qmsg-shadow-container";
                $shadowRoot = $shadowContainer.attachShadow({ mode: "open" });
                let __$wrapper__ = document.createElement("div");
                __$wrapper__.classList.add(QmsgConfig.NAMESPACE, QmsgUtils.getNameSpacify("wrapper"), QmsgUtils.getNameSpacify("is-initialized"));
                __$wrapper__.classList.add($positionClassName);
                $shadowRoot.appendChild(QmsgCSS.getStyleElement());
                $shadowRoot.appendChild(__$wrapper__);
                if (this.setting.style != null) {
                    // 插入自定义的style
                    // 这里需要插入到每一条的Qmsg内,以便移除实例时把style也移除
                    let __$ownStyle__ = document.createElement("style");
                    __$ownStyle__.setAttribute("type", "text/css");
                    __$ownStyle__.setAttribute("data-id", this.uuid);
                    __$ownStyle__.innerHTML = this.setting.style;
                    $contentContainer.insertAdjacentElement("afterend", __$ownStyle__);
                }
                document.body.appendChild($shadowContainer);
            }
            if ($shadowRoot == null) {
                throw new TypeError(QmsgConfig.PLUGIN_NAME + " $shadowRoot is null");
            }
            let $wrapper = $shadowRoot.querySelector(`.${QmsgConfig.NAMESPACE}.${$positionClassName}`);
            if (!$wrapper) {
                $wrapper = document.createElement("div");
                $wrapper.classList.add(QmsgConfig.NAMESPACE, QmsgUtils.getNameSpacify("wrapper"), QmsgUtils.getNameSpacify("is-initialized"));
                $wrapper.classList.add($positionClassName);
                $shadowRoot.appendChild($wrapper);
            }
            if (this.setting.showReverse) {
                $wrapper.style.flexDirection = "column-reverse";
            }
            else {
                $wrapper.style.flexDirection = "column";
            }
            let zIndex = this.setting.zIndex;
            if (typeof zIndex === "function") {
                zIndex = zIndex();
            }
            if (!isNaN(zIndex)) {
                $wrapper.style.zIndex = zIndex.toString();
            }
            $wrapper.appendChild(this.$Qmsg);
            this.setState(this.$Qmsg, "opening");
            if (this.setting.showClose) {
                /* 关闭按钮绑定点击事件 */
                let $closeIcon = this.$Qmsg.querySelector(".qmsg-icon-close");
                if ($closeIcon) {
                    $closeIcon.addEventListener("click", function () {
                        QmsgContext.close();
                    });
                }
            }
            /* 监听动画完成 */
            let animationendEvent = (event) => {
                let animationNameValue = QmsgAnimation.getStyleAnimationNameValue(QmsgContext.$Qmsg);
                if (animationNameValue === QmsgAnimation.$state.closing) {
                    // 当前触发的是关闭
                    QmsgContext.endTime = Date.now();
                    QmsgContext.destroy();
                }
                QmsgAnimation.setStyleAnimationName(QmsgContext.$Qmsg);
            };
            QmsgAnimation.$name.endNameList.forEach(function (animationendName) {
                QmsgContext.$Qmsg.addEventListener(animationendName, animationendEvent);
            });
            if (this.setting.autoClose) {
                /* 自动关闭 */
                // 获取时间戳
                this.timeId = QmsgUtils.setTimeout(() => {
                    this.close();
                }, this.setting.timeout);
                let enterEvent = (event) => {
                    /* 鼠标滑入,清除定时器,清除开始时间和结束时间 */
                    this.startTime = null;
                    this.endTime = null;
                    QmsgUtils.clearTimeout(this.timeId);
                    this.timeId = void 0;
                };
                let leaveEvent = (event) => {
                    /* 鼠标滑出,重启定时器,创建新的开始时间和timeId */
                    if (this.timeId != null) {
                        // 似乎enterEvent函数未正确调用?
                        console.warn("timeId is not null,mouseenter may be not first trigger");
                        return;
                    }
                    this.startTime = Date.now();
                    this.timeId = QmsgUtils.setTimeout(() => {
                        this.close();
                    }, this.setting.timeout);
                };
                this.$Qmsg.addEventListener("touchstart", () => {
                    // 由于移动端不支持mouseout且会触发mouseenter
                    // 那么需要移除该监听
                    this.$Qmsg.removeEventListener("mouseenter", enterEvent);
                    this.$Qmsg.removeEventListener("mouseout", leaveEvent);
                }, {
                    capture: true,
                    once: true,
                });
                this.$Qmsg.addEventListener("mouseenter", enterEvent);
                this.$Qmsg.addEventListener("mouseout", leaveEvent);
            }
        }
        /**
         * 对timeout进行检测并转换
         * 当timeout为string时,转换为number
         * timeout必须在规定范围内
         */
        detectionType() {
            if (this.setting.timeout != null &&
                typeof this.setting.timeout === "string") {
                this.setting.timeout = parseInt(this.setting.timeout);
            }
            if (isNaN(this.setting.timeout)) {
                this.setting.timeout = QmsgConfig.DEFAULT.timeout;
            }
            if (!(this.setting.timeout != null &&
                parseInt(this.setting.timeout.toString()) >= 0 &&
                parseInt(this.setting.timeout.toString()) <= Number.MAX_VALUE)) {
                this.setting.timeout = QmsgConfig.DEFAULT.timeout;
            }
            if (typeof this.setting.zIndex === "function") {
                this.setting.zIndex = this.setting.zIndex();
            }
            if (this.setting.zIndex != null &&
                typeof this.setting.zIndex === "string") {
                this.setting.zIndex = parseInt(this.setting.zIndex);
            }
            if (isNaN(this.setting.zIndex)) {
                this.setting.zIndex =
                    typeof QmsgConfig.DEFAULT.zIndex === "function"
                        ? QmsgConfig.DEFAULT.zIndex()
                        : QmsgConfig.DEFAULT.zIndex;
            }
        }
        /**
         * 设置元素动画状态 开启/关闭
         * @param QmsgMsg
         * @param state
         */
        setState(element, state) {
            if (!state || !QmsgAnimation.$state[state])
                return;
            this.state = state;
            QmsgAnimation.setStyleAnimationName(element, QmsgAnimation.$state[state]);
        }
        /**
         * 设置消息数量统计
         */
        setMsgCount() {
            let QmsgContext = this;
            let countClassName = QmsgUtils.getNameSpacify("count");
            let wrapperClassName = `div.${QmsgUtils.getNameSpacify("data-position", this.setting.position.toLowerCase())} [class^="qmsg-content-"]`;
            let $content = this.$Qmsg.querySelector(wrapperClassName);
            if (!$content) {
                throw new TypeError("$content is null");
            }
            let $count = $content.querySelector("." + countClassName);
            if (!$count) {
                $count = document.createElement("span");
                $count.classList.add(countClassName);
                $content.appendChild($count);
            }
            $count.innerHTML = this.getRepeatNum().toString();
            QmsgAnimation.setStyleAnimationName($count);
            QmsgAnimation.setStyleAnimationName($count, "MessageShake");
            /* 重置定时器 */
            QmsgUtils.clearTimeout(this.timeId);
            if (this.setting.autoClose) {
                this.timeId = QmsgUtils.setTimeout(function () {
                    QmsgContext.close();
                }, this.setting.timeout);
            }
        }
        /**
         * 关闭Qmsg(会触发动画)
         */
        close() {
            this.setState(this.$Qmsg, "closing");
            if (QmsgConfig.CAN_ANIMATION) {
                /* 支持动画 */
                QmsgInstanceStorage.remove(this.uuid);
            }
            else {
                /* 不支持动画 */
                this.destroy();
            }
            let onCloseCallBack = this.setting.onClose;
            if (onCloseCallBack && typeof onCloseCallBack === "function") {
                onCloseCallBack.call(this);
            }
        }
        /**
         * 销毁Qmsg
         */
        destroy() {
            this.endTime = Date.now();
            this.$Qmsg.remove();
            QmsgUtils.clearTimeout(this.timeId);
            QmsgInstanceStorage.remove(this.uuid);
        }
        /**
         * 设置内容文本
         */
        setText(text) {
            let $content = this.$Qmsg.querySelector("div[class^=qmsg-content-] > span");
            if ($content) {
                $content.innerText = text;
                this.setting.content = text;
            }
            else {
                throw new TypeError("$content is null");
            }
        }
        /**
         * 设置内容超文本
         */
        setHTML(text) {
            let $content = this.$Qmsg.querySelector("div[class^=qmsg-content-] > span");
            if ($content) {
                $content.innerHTML = text;
                this.setting.content = text;
            }
            else {
                throw new TypeError("$content is null");
            }
        }
    }

    const createCache = (lastNumberWeakMap) => {
        return (collection, nextNumber) => {
            lastNumberWeakMap.set(collection, nextNumber);
            return nextNumber;
        };
    };

    /*
     * The value of the constant Number.MAX_SAFE_INTEGER equals (2 ** 53 - 1) but it
     * is fairly new.
     */
    const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER === undefined ? 9007199254740991 : Number.MAX_SAFE_INTEGER;
    const TWO_TO_THE_POWER_OF_TWENTY_NINE = 536870912;
    const TWO_TO_THE_POWER_OF_THIRTY = TWO_TO_THE_POWER_OF_TWENTY_NINE * 2;
    const createGenerateUniqueNumber = (cache, lastNumberWeakMap) => {
        return (collection) => {
            const lastNumber = lastNumberWeakMap.get(collection);
            /*
             * Let's try the cheapest algorithm first. It might fail to produce a new
             * number, but it is so cheap that it is okay to take the risk. Just
             * increase the last number by one or reset it to 0 if we reached the upper
             * bound of SMIs (which stands for small integers). When the last number is
             * unknown it is assumed that the collection contains zero based consecutive
             * numbers.
             */
            let nextNumber = lastNumber === undefined ? collection.size : lastNumber < TWO_TO_THE_POWER_OF_THIRTY ? lastNumber + 1 : 0;
            if (!collection.has(nextNumber)) {
                return cache(collection, nextNumber);
            }
            /*
             * If there are less than half of 2 ** 30 numbers stored in the collection,
             * the chance to generate a new random number in the range from 0 to 2 ** 30
             * is at least 50%. It's benifitial to use only SMIs because they perform
             * much better in any environment based on V8.
             */
            if (collection.size < TWO_TO_THE_POWER_OF_TWENTY_NINE) {
                while (collection.has(nextNumber)) {
                    nextNumber = Math.floor(Math.random() * TWO_TO_THE_POWER_OF_THIRTY);
                }
                return cache(collection, nextNumber);
            }
            // Quickly check if there is a theoretical chance to generate a new number.
            if (collection.size > MAX_SAFE_INTEGER) {
                throw new Error('Congratulations, you created a collection of unique numbers which uses all available integers!');
            }
            // Otherwise use the full scale of safely usable integers.
            while (collection.has(nextNumber)) {
                nextNumber = Math.floor(Math.random() * MAX_SAFE_INTEGER);
            }
            return cache(collection, nextNumber);
        };
    };

    const LAST_NUMBER_WEAK_MAP = new WeakMap();
    const cache = createCache(LAST_NUMBER_WEAK_MAP);
    const generateUniqueNumber = createGenerateUniqueNumber(cache, LAST_NUMBER_WEAK_MAP);

    const isCallNotification = (message) => {
        return message.method !== undefined && message.method === 'call';
    };

    const isClearResponse = (message) => {
        return typeof message.id === 'number' && typeof message.result === 'boolean';
    };

    const load = (url) => {
        // Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification.
        const scheduledIntervalFunctions = new Map([[0, () => { }]]); // tslint:disable-line no-empty
        const scheduledTimeoutFunctions = new Map([[0, () => { }]]); // tslint:disable-line no-empty
        const unrespondedRequests = new Map();
        const worker = new Worker(url);
        worker.addEventListener('message', ({ data }) => {
            if (isCallNotification(data)) {
                const { params: { timerId, timerType } } = data;
                if (timerType === 'interval') {
                    const idOrFunc = scheduledIntervalFunctions.get(timerId);
                    if (typeof idOrFunc === undefined) {
                        throw new Error('The timer is in an undefined state.');
                    }
                    if (typeof idOrFunc === 'number') {
                        const timerIdAndTimerType = unrespondedRequests.get(idOrFunc);
                        if (timerIdAndTimerType === undefined ||
                            timerIdAndTimerType.timerId !== timerId ||
                            timerIdAndTimerType.timerType !== timerType) {
                            throw new Error('The timer is in an undefined state.');
                        }
                    }
                    else if (typeof idOrFunc === 'function') {
                        idOrFunc();
                    }
                }
                else if (timerType === 'timeout') {
                    const idOrFunc = scheduledTimeoutFunctions.get(timerId);
                    if (typeof idOrFunc === undefined) {
                        throw new Error('The timer is in an undefined state.');
                    }
                    if (typeof idOrFunc === 'number') {
                        const timerIdAndTimerType = unrespondedRequests.get(idOrFunc);
                        if (timerIdAndTimerType === undefined ||
                            timerIdAndTimerType.timerId !== timerId ||
                            timerIdAndTimerType.timerType !== timerType) {
                            throw new Error('The timer is in an undefined state.');
                        }
                    }
                    else if (typeof idOrFunc === 'function') {
                        idOrFunc();
                        // A timeout can be savely deleted because it is only called once.
                        scheduledTimeoutFunctions.delete(timerId);
                    }
                }
            }
            else if (isClearResponse(data)) {
                const { id } = data;
                const timerIdAndTimerType = unrespondedRequests.get(id);
                if (timerIdAndTimerType === undefined) {
                    throw new Error('The timer is in an undefined state.');
                }
                const { timerId, timerType } = timerIdAndTimerType;
                unrespondedRequests.delete(id);
                if (timerType === 'interval') {
                    scheduledIntervalFunctions.delete(timerId);
                }
                else {
                    scheduledTimeoutFunctions.delete(timerId);
                }
            }
            else {
                const { error: { message } } = data;
                throw new Error(message);
            }
        });
        const clearInterval = (timerId) => {
            if (typeof scheduledIntervalFunctions.get(timerId) === 'function') {
                const id = generateUniqueNumber(unrespondedRequests);
                unrespondedRequests.set(id, { timerId, timerType: 'interval' });
                scheduledIntervalFunctions.set(timerId, id);
                worker.postMessage({
                    id,
                    method: 'clear',
                    params: { timerId, timerType: 'interval' }
                });
            }
        };
        const clearTimeout = (timerId) => {
            if (typeof scheduledTimeoutFunctions.get(timerId) === 'function') {
                const id = generateUniqueNumber(unrespondedRequests);
                unrespondedRequests.set(id, { timerId, timerType: 'timeout' });
                scheduledTimeoutFunctions.set(timerId, id);
                worker.postMessage({
                    id,
                    method: 'clear',
                    params: { timerId, timerType: 'timeout' }
                });
            }
        };
        const setInterval = (func, delay = 0, ...args) => {
            const timerId = generateUniqueNumber(scheduledIntervalFunctions);
            scheduledIntervalFunctions.set(timerId, () => {
                func(...args);
                // Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func().
                if (typeof scheduledIntervalFunctions.get(timerId) === 'function') {
                    worker.postMessage({
                        id: null,
                        method: 'set',
                        params: {
                            delay,
                            now: performance.timeOrigin + performance.now(),
                            timerId,
                            timerType: 'interval'
                        }
                    });
                }
            });
            worker.postMessage({
                id: null,
                method: 'set',
                params: {
                    delay,
                    now: performance.timeOrigin + performance.now(),
                    timerId,
                    timerType: 'interval'
                }
            });
            return timerId;
        };
        const setTimeout = (func, delay = 0, ...args) => {
            const timerId = generateUniqueNumber(scheduledTimeoutFunctions);
            scheduledTimeoutFunctions.set(timerId, () => func(...args));
            worker.postMessage({
                id: null,
                method: 'set',
                params: {
                    delay,
                    now: performance.timeOrigin + performance.now(),
                    timerId,
                    timerType: 'timeout'
                }
            });
            return timerId;
        };
        return {
            clearInterval,
            clearTimeout,
            setInterval,
            setTimeout
        };
    };

    const createLoadOrReturnBroker = (loadBroker, worker) => {
        let broker = null;
        return () => {
            if (broker !== null) {
                return broker;
            }
            const blob = new Blob([worker], { type: 'application/javascript; charset=utf-8' });
            const url = URL.createObjectURL(blob);
            broker = loadBroker(url);
            // Bug #1: Edge up until v18 didn't like the URL to be revoked directly.
            setTimeout(() => URL.revokeObjectURL(url));
            return broker;
        };
    };

    // This is the minified and stringified code of the worker-timers-worker package.
    const worker = `(()=>{"use strict";const e=new Map,t=new Map,r=t=>{const r=e.get(t);return void 0!==r&&(clearTimeout(r),e.delete(t),!0)},s=e=>{const r=t.get(e);return void 0!==r&&(clearTimeout(r),t.delete(e),!0)},o=(e,t)=>{const r=performance.now(),s=e+t-r-performance.timeOrigin;return{expected:r+s,remainingDelay:s}},i=(e,t,r,s)=>{const o=r-performance.now();o>0?e.set(t,setTimeout(i,o,e,t,r,s)):(e.delete(t),postMessage({id:null,method:"call",params:{timerId:t,timerType:s}}))};addEventListener("message",(({data:n})=>{try{if("clear"===n.method){const{id:e,params:{timerId:t,timerType:o}}=n;if("interval"===o)postMessage({id:e,result:r(t)});else{if("timeout"!==o)throw new Error('The given type "'.concat(o,'" is not supported'));postMessage({id:e,result:s(t)})}}else{if("set"!==n.method)throw new Error('The given method "'.concat(n.method,'" is not supported'));{const{params:{delay:r,now:s,timerId:a,timerType:m}}=n;if("interval"===m)((t,r,s)=>{const{expected:n,remainingDelay:a}=o(t,s);e.set(r,setTimeout(i,a,e,r,n,"interval"))})(r,a,s);else{if("timeout"!==m)throw new Error('The given type "'.concat(m,'" is not supported'));((e,r,s)=>{const{expected:n,remainingDelay:a}=o(e,s);t.set(r,setTimeout(i,a,t,r,n,"timeout"))})(r,a,s)}}}}catch(e){postMessage({error:{message:e.message},id:n.id,result:null})}}))})();`; // tslint:disable-line:max-line-length

    const loadOrReturnBroker = createLoadOrReturnBroker(load, worker);
    const clearInterval = (timerId) => loadOrReturnBroker().clearInterval(timerId);
    const clearTimeout = (timerId) => loadOrReturnBroker().clearTimeout(timerId);
    const setInterval = (...args) => loadOrReturnBroker().setInterval(...args);
    const setTimeout$1 = (...args) => loadOrReturnBroker().setTimeout(...args);

    const QmsgUtils = {
        /**
         * 生成带插件名的名称
         * @param args
         */
        getNameSpacify(...args) {
            let result = QmsgConfig.NAMESPACE;
            for (let index = 0; index < args.length; ++index) {
                result += "-" + args[index];
            }
            return result;
        },
        /**
         * 判断字符是否是数字
         * @param text 需要判断的字符串
         */
        isNumber(text) {
            let isNumberPattern = /^\d+$/;
            return isNumberPattern.test(text);
        },
        /**
         * 获取唯一性的UUID
         */
        getUUID() {
            return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (value) {
                let randValue = (Math.random() * 16) | 0, newValue = value == "x" ? randValue : (randValue & 0x3) | 0x8;
                return newValue.toString(16);
            });
        },
        /**
         * 合并参数为配置信息,用于创建Msg实例
         * @param content 文本内容
         * @param config 配置
         */
        mergeArgs(content = "", config) {
            let opts = {};
            if (arguments.length === 0) {
                return opts;
            }
            if (config != null) {
                // 传入了2个参数
                // string object
                // object object
                opts.content = content;
                if (typeof config === "object" && config != null) {
                    return Object.assign(opts, config);
                }
            }
            else {
                // 传入了1个参数
                // object
                // string
                if (typeof content === "object" && content != null) {
                    return Object.assign(opts, content);
                }
                else {
                    opts.content = content;
                }
            }
            return opts;
        },
        /**
         * 通过配置信息 来判断是否为同一条消息,并返回消息实例
         * @param option 配置项
         */
        judgeReMsg(option) {
            option = option || {};
            let optionString = JSON.stringify(option);
            /* 寻找已生成的实例是否存在配置相同的 */
            let findQmsgItemInfo = QmsgInstanceStorage.QmsgList.find((item) => {
                return item.config === optionString;
            });
            let QmsgInstance = findQmsgItemInfo?.instance;
            if (QmsgInstance == null) {
                /* 不存在,创建个新的 */
                let uuid = QmsgUtils.getUUID();
                let QmsgItemInfo = {
                    uuid: uuid,
                    config: optionString,
                    instance: new QmsgMsg(option, uuid),
                };
                QmsgInstanceStorage.QmsgList.push(QmsgItemInfo);
                let QmsgListLength = QmsgInstanceStorage.QmsgList.length;
                let maxNums = QmsgItemInfo.instance.getSetting().maxNums;
                /**
                 * 关闭多余的消息
                 */
                if (QmsgListLength > maxNums) {
                    for (let index = 0; index < QmsgListLength - maxNums; index++) {
                        let item = QmsgInstanceStorage.QmsgList[index];
                        item && item.instance.getSetting().autoClose && item.instance.close();
                    }
                }
                findQmsgItemInfo = QmsgItemInfo;
                QmsgInstance = QmsgItemInfo.instance;
            }
            else {
                if (!QmsgInstance.getRepeatNum()) {
                    QmsgInstance.setRepeatNum(2);
                }
                else {
                    if (QmsgInstance.getRepeatNum() >= 99) ;
                    else {
                        QmsgInstance.setRepeatNumIncreasing();
                    }
                }
                QmsgInstance.setMsgCount();
            }
            if (QmsgInstance) {
                QmsgInstance.$Qmsg.setAttribute("data-count", QmsgInstance?.getRepeatNum().toString());
            }
            else {
                throw new TypeError("QmsgInstance is null");
            }
            return QmsgInstance;
        },
        /**
         * 转换为动态对象
         * @param obj 需要配置的对象
         * @param other_obj 获取的其它对象
         */
        toDynamicObject(obj, ...other_objs) {
            let __obj__ = Object.assign({}, obj);
            Object.keys(__obj__).forEach((keyName) => {
                let objValue = __obj__[keyName];
                Object.defineProperty(__obj__, keyName, {
                    get() {
                        let findIndex = other_objs.findIndex((other_obj) => {
                            // 判断其他对象中是否有该属性
                            return other_obj.hasOwnProperty.call(other_obj, keyName);
                        });
                        if (findIndex !== -1) {
                            return other_objs[findIndex][keyName];
                        }
                        else {
                            return objValue;
                        }
                    },
                    set(newValue) {
                        objValue = newValue;
                    },
                });
            });
            return __obj__;
        },
        /**
         * 自动使用 Worker 执行 setTimeout
         */
        setTimeout(callback, timeout) {
            try {
                return setTimeout$1(callback, timeout);
            }
            catch (error) {
                return globalThis.setTimeout(callback, timeout);
            }
        },
        /**
         * 配合 QmsgUtils.setTimeout 使用
         */
        clearTimeout(timeId) {
            try {
                if (timeId != null) {
                    clearTimeout(timeId);
                }
            }
            catch (error) {
            }
            finally {
                globalThis.clearTimeout(timeId);
            }
        },
        /**
         * 自动使用 Worker 执行 setInterval
         */
        setInterval(callback, timeout) {
            try {
                return setInterval(callback, timeout);
            }
            catch (error) {
                return globalThis.setInterval(callback, timeout);
            }
        },
        /**
         * 配合 QmsgUtils.setInterval 使用
         */
        clearInterval(timeId) {
            try {
                if (timeId != null) {
                    clearInterval(timeId);
                }
            }
            catch (error) {
            }
            finally {
                globalThis.clearInterval(timeId);
            }
        },
    };

    /* 执行兼容 */
    CompatibleProcessing();
    const QmsgEvent = {
        visibilitychange: {
            eventConfig: {
                /**
                 * 添加visibilitychange事件监听
                 * 当页面切换时,如果切换前的页面存在Qmsg实例且未关闭,切换后,页面活跃度会降低,导致setTimeout/setInterval失效或丢失事件
                 * 监听visibilitychange,判断切换回来时,如果当前时间-开始时间大于timeout,则关闭
                 * 如果设置了动画,使用close,否则使用destroy
                 */
                callback() {
                    if (document.visibilityState === "visible") {
                        // 回到页面
                        for (let index = 0; index < QmsgInstanceStorage.QmsgList.length; index++) {
                            let QmsgInstance = QmsgInstanceStorage.QmsgList[index];
                            if (QmsgInstance.instance.endTime == null &&
                                QmsgInstance.instance.startTime != null &&
                                Date.now() - QmsgInstance.instance.startTime >=
                                    QmsgInstance.instance.getSetting().timeout) {
                                // 超出时间,关闭
                                QmsgInstance.instance.close();
                            }
                        }
                    }
                },
                option: {
                    capture: true,
                },
            },
            addEvent() {
                if ("visibilityState" in document) {
                    document.addEventListener("visibilitychange", QmsgEvent.visibilitychange.eventConfig.callback, QmsgEvent.visibilitychange.eventConfig.option);
                }
                else {
                    console.error("visibilityState not support");
                }
            },
            removeEvent() {
                document.removeEventListener("visibilitychange", QmsgEvent.visibilitychange.eventConfig.callback, QmsgEvent.visibilitychange.eventConfig.option);
            },
        },
    };
    class Qmsg {
        /** 数据 */
        $data;
        $eventUtils;
        constructor() {
            this.$data = {
                version: "2024.12.6",
                config: QmsgConfig,
                icon: QmsgIcon,
                instanceStorage: QmsgInstanceStorage,
            };
            this.$eventUtils = QmsgEvent;
            this.$eventUtils.visibilitychange.addEvent();
        }
        /**
         * 修改默认配置
         * @param option
         */
        config(option) {
            if (option == null)
                return;
            if (typeof option !== "object")
                return;
            QmsgConfig.INS_DEFAULT = null;
            QmsgConfig.INS_DEFAULT = option;
        }
        info(content, option) {
            let params = QmsgUtils.mergeArgs(content, option);
            params.type = "info";
            return QmsgUtils.judgeReMsg.call(this, params);
        }
        warning(content, option) {
            let params = QmsgUtils.mergeArgs(content, option);
            params.type = "warning";
            return QmsgUtils.judgeReMsg.call(this, params);
        }
        success(content, option) {
            let params = QmsgUtils.mergeArgs(content, option);
            params.type = "success";
            return QmsgUtils.judgeReMsg.call(this, params);
        }
        error(content, option) {
            let params = QmsgUtils.mergeArgs(content, option);
            params.type = "error";
            return QmsgUtils.judgeReMsg.call(this, params);
        }
        loading(content, config) {
            let params = QmsgUtils.mergeArgs(content, config);
            params.type = "loading";
            params.autoClose = false;
            return QmsgUtils.judgeReMsg.call(this, params);
        }
        /**
         * 根据uuid删除Qmsg实例和元素
         * @param uuid
         */
        remove(uuid) {
            QmsgInstanceStorage.remove(uuid);
        }
        /**
         * 关闭当前Qmsg创建的所有的实例
         */
        closeAll() {
            for (let index = QmsgInstanceStorage.QmsgList.length - 1; index >= 0; index--) {
                let item = QmsgInstanceStorage.QmsgList[index];
                item && item.instance && item.instance.close();
            }
        }
    }
    let qmsg = new Qmsg();

    return qmsg;

}));
//# sourceMappingURL=index.umd.js.map