1 Star 0 Fork 34

/outline.js

forked from Yaohaixiao/outline.js 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
anchors.min.js.map 77.83 KB
一键复制 编辑 原始数据 按行查看 历史
{"version":3,"file":"anchors.min.js","sources":["utils/types/isString.js","utils/lang/hasOwn.js","utils/lang/toString.js","utils/types/isFunction.js","utils/types/isObject.js","utils/observer/_subscribers.js","utils/observer/_hasDirectSubscribersFor.js","utils/observer/has.js","utils/observer/_hasSubscribers.js","utils/observer/emit.js","utils/types/isTypedArray.js","utils/lang/guid.js","utils/observer/_removeSubscriber.js","utils/observer/off.js","utils/observer/_removeSubscriberByToken.js","base.js","utils/lang/extend.js","utils/observer/on.js","utils/types/isElement.js","utils/lang/easeInQuad.js","utils/dom/_getScrollElement.js","utils/dom/offsetTop.js","utils/dom/matches.js","utils/dom/getParentOrHost.js","utils/event/enum.js","utils/event/_off.js","utils/event/_delete.js","utils/event/purgeElement.js","utils/event/getListeners.js","utils/event/off.js","utils/event/on.js","utils/event/getTarget.js","utils/dom/resolveTextNode.js","utils/dom/closest.js","utils/types/isArray.js","utils/icons/symbols.js","utils/icons/defaults.js","utils/icons/getSymbols.js","utils/icons/getSymbol.js","utils/icons/paint.js","utils/icons/add.js","utils/lang/trim.js","utils/types/isDOM.js","utils/types/isHTMLCollection.js","utils/types/isFragment.js","utils/types/isTextNode.js","utils/dom/setAttribute.js","utils/types/isSVG.js","utils/icons/icon.js","utils/icons/createElement.js","_updateHeading.js","utils/dom/createElement.js","utils/dom/removeClass.js","utils/dom/hasClass.js","_resetHeading.js","utils/types/isEmpty.js","getChapters.js","utils/lang/stripTags.js","_getChapterParentIdByDiffer.js","_getChaptersWithCode.js","anchors.js","utils/lang/toTree.js","utils/dom/scrollTo.js","utils/lang/later.js","utils/event/stop.js"],"sourcesContent":["/**\n * 检测数据是否为 String 类型\n * ========================================================================\n * @method isArray\n * @param {*} str\n * @returns {boolean}\n */\nconst isString = (str) => {\n return typeof str === 'string'\n}\n\nexport default isString\n","/**\n * 检测对象自身属性中是否具有指定的属性。\n * ========================================================================\n * @method hasOwn\n * @param {Object} obj - (必须)检测的目标对象\n * @param {String} prop - (必须)属性名\n * @returns {Boolean}\n */\nconst hasOwn = (obj, prop) => {\n const hasOwnProperty = Object.prototype.hasOwnProperty\n return obj && hasOwnProperty.call(obj, prop)\n}\n\nexport default hasOwn\n","/**\n * Object 对象原型上的 toString 方法\n * ========================================================================\n * @method toString\n * @param {*} val\n * @returns {string}\n */\nconst toString = (val) => {\n return Object.prototype.toString.apply(val)\n}\n\nexport default toString\n","import toString from '../lang/toString'\n\n/**\n * 检测测试数据是否为 Function 类型\n * ========================================================================\n * @method isFunction\n * @param {*} val - (必须)待检测的数据\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\n */\nconst isFunction = (val) => {\n return typeof val === 'function' || toString(val) === '[object Function]'\n}\n\nexport default isFunction\n","import toString from '../lang/toString'\nimport isFunction from './isFunction'\n\n/**\n * 检测数据是否为 Object 类型\n * ========================================================================\n * @method isObject\n * @param {*} o\n * @returns {boolean}\n */\nconst isObject = (o) => {\n return (\n (toString(o) === '[object Object]' ||\n typeof o === 'object' ||\n isFunction(o)) &&\n o !== null\n )\n}\n\nexport default isObject\n","/**\n * 存储订阅者(主题和处理器的)私有对象\n * ========================================================================\n * @type {{}}\n * @private\n */\nconst _subscribers = {}\n\nexport default _subscribers\n","import _subscribers from './_subscribers'\nimport hasOwn from '../lang/hasOwn'\n\n/**\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\n * ========================================================================\n * @method _hasDirectSubscribersFor\n * @param {String} topic - (必须)订阅主题字符串\n * @returns {Boolean}\n */\nconst _hasDirectSubscribersFor = (topic) => {\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\n}\n\nexport default _hasDirectSubscribersFor\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\nimport _hasSubscribers from './_hasSubscribers'\n\n/**\n * 判断是否存在包含 topic 指定的订阅者信息\n * ========================================================================\n * @method has\n * @param {String} topic - (必须)主题名称\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\n * @returns {Boolean}\n */\nconst has = (topic, isDirect = true) => {\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\n}\n\nexport default has\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\n\n/**\n * 判断是否存在包含给定 topic 相关的订阅者信息\n * ========================================================================\n * @method _hasSubscribers\n * @param {String} topic - (必须)订阅主题字符串\n * @returns {Boolean}\n */\nconst _hasSubscribers = (topic) => {\n let found = _hasDirectSubscribersFor(topic)\n let position = topic.lastIndexOf('.')\n\n while (!found && position !== -1) {\n topic = topic.substring(0, position)\n position = topic.lastIndexOf('.')\n found = _hasDirectSubscribersFor(topic)\n }\n\n return found\n}\n\nexport default _hasSubscribers\n","import isTypedArray from '../types/isTypedArray'\nimport _subscribers from './_subscribers'\nimport has from './has'\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\n\n/**\n * (异步)发布订阅主题信息\n * ========================================================================\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\n * ========================================================================\n * @method emit\n * @param {String} topic - (必须)主题名称\n * @param {Object} [data] - (可选)数据对象\n * @param {Boolean} [async] - (可选) 是否异步发布\n */\nconst emit = (topic, data, async = true) => {\n const execute = (topic) => {\n if (!_hasDirectSubscribersFor(topic)) {\n return false\n }\n\n _subscribers[topic].forEach((subscriber) => {\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\n // 采用 toString() 方法转化为普通(JSON)字符串\n const message = isTypedArray(data) ? data.toString() : data\n\n subscriber.callback.call(subscriber.context || subscriber, message)\n })\n }\n const deliver = () => {\n let subscriber = topic\n let position = topic.lastIndexOf('.')\n\n while (position !== -1) {\n subscriber = subscriber.substring(0, position)\n position = subscriber.lastIndexOf('.')\n\n execute(subscriber)\n }\n\n // 执行 topic 对应的处理器\n execute(topic)\n // 执行特殊 topic:'*'(监听全部消息的发布)\n execute('*')\n }\n\n if (!has(topic)) {\n return false\n }\n\n if (async) {\n setTimeout(deliver, 10)\n } else {\n deliver()\n }\n}\n\nexport default emit\n","import toString from '../lang/toString'\n/**\n * 判断检测数据是否为 Typed Arrays 类型的数据\n * ========================================================================\n * @param {*} val\n * @returns {boolean}\n */\nconst isTypedArray = (val) => {\n const TYPES = [\n '[object Int8Array]',\n '[object Uint8Array]',\n '[object Uint8ClampedArray]',\n '[object Int16Array]',\n '[object Uint16Array]',\n '[object Int32Array]',\n '[object Uint32Array]',\n '[object Float32Array]',\n '[object Float64Array]',\n '[object BigInt64Array]',\n '[object BigUint64Array]'\n ]\n\n return TYPES.indexOf(toString(val)) > -1\n}\n\nexport default isTypedArray\n","/**\n * 生成唯一 id 字符串的函数\n * ========================================================================\n * @method guid\n * @param {String} [prefix] - 生成 id 的前缀字符串\n * @return {String} 返回一个表示唯一 id 的字符串\n */\nconst guid = (() => {\n let uuid = 0\n\n return (prefix) => {\n uuid += 1\n\n return prefix ? prefix + '-' + uuid : 'guid-' + uuid\n }\n})()\n\nexport default guid\n","import _subscribers from './_subscribers'\nimport hasOwn from '../lang/hasOwn'\n\n/**\n * 删除与给定 topic 相同的订阅者信息\n * ========================================================================\n * @method _removeSubscriber\n * @param {String} topic - (必须)订阅主题字符串\n * @returns {Boolean}\n */\nconst _removeSubscriber = (topic) => {\n if (!hasOwn(_subscribers, topic)) {\n return false\n }\n\n delete _subscribers[topic]\n}\n\nexport default _removeSubscriber\n","import has from './has'\nimport _removeSubscriber from './_removeSubscriber'\nimport _removeSubscriberByToken from './_removeSubscriberByToken'\n\n/**\n * 取消订阅主题\n * ========================================================================\n * @method off\n * @param {String} topic - (必须)订阅的主题\n * @param {Function|String} [token] - (可选)订阅主题的处理器函数或者唯一 Id 值\n */\nconst off = (topic, token) => {\n if (!has(topic)) {\n return false\n }\n\n if (token) {\n _removeSubscriberByToken(token)\n } else {\n _removeSubscriber(topic)\n }\n}\n\nexport default off\n","import _subscribers from './_subscribers'\nimport _removeSubscriber from './_removeSubscriber'\n\n/**\n * 通过订阅者 token 值删除订阅者信息\n * ========================================================================\n * @method _removeSubscriberByToken\n * @param {String} token - 订阅者 token 字符串\n * @returns {boolean}\n * @private\n */\nconst _removeSubscriberByToken = (token) => {\n const keys = Object.keys(_subscribers)\n let index = -1\n\n if (!token || keys.length < 1) {\n return false\n }\n\n keys.forEach((subject) => {\n const subscriber = _subscribers[subject]\n let topic\n\n subscriber.forEach((execution, j) => {\n if (execution.callback === token || execution.token === token) {\n topic = execution.topic\n subscriber.splice(index, j)\n }\n })\n\n /* istanbul ignore else */\n if (subscriber.length < 1) {\n _removeSubscriber(topic)\n }\n })\n}\n\nexport default _removeSubscriberByToken\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\nimport publish from './utils/observer/emit'\r\nimport subscribe from './utils/observer/on'\r\nimport unsubscribe from './utils/observer/off'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(this.attr(options))\r\n return this\r\n }\r\n\r\n $emit(event, data) {\r\n publish(event, data)\r\n return this\r\n }\r\n\r\n $on(event, callback) {\r\n subscribe(event, callback, this)\r\n return this\r\n }\r\n\r\n $off(event, callback) {\r\n unsubscribe(event, callback)\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\n\n/**\n * 扩展对象\n * ========================================================================\n * @method extend\n * @param {Object} origin\n * @param {Object} source\n */\nconst extend = (origin, source) => {\n const keys = Object.keys(source)\n\n keys.forEach((prop) => {\n if (hasOwn(source, prop)) {\n origin[prop] = source[prop]\n }\n })\n}\n\nexport default extend\n","import _subscribers from './_subscribers'\nimport isFunction from '../types/isFunction'\nimport guid from '../lang/guid'\n\n/**\n * 订阅主题,并给出处理器函数\n * ========================================================================\n * @method on\n * @param {String} topic - (必须)主题名称\n * @param {Function} handler - (必须)主题的处理器函数\n * @param {Object} [context] - (可选)指定 this 执行上下文\n * @return {String} - 唯一的 token 字符串,例如:'guid-1'。\n */\nconst on = (topic, handler, context = null) => {\n const token = guid()\n let subject = typeof topic === 'symbol' ? topic.toString() : topic\n\n if (!isFunction(handler)) {\n return ''\n }\n\n /* istanbul ignore else */\n if (!_subscribers[subject]) {\n _subscribers[subject] = []\n }\n\n _subscribers[subject].push({\n topic: subject,\n callback: handler,\n context,\n token\n })\n\n return token\n}\n\nexport default on\n","import isObject from './isObject'\n\n/**\n * 检测数据是否为 HTMLElement DOM 节点\n * ========================================================================\n * @method isElement\n * @param {*} o\n * @returns {boolean}\n */\nconst isElement = (o) => {\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\n}\n\nexport default isElement\n","/**\n * 返回给定值的平方值\n * ========================================================================\n * @method easeInQuad\n * @param {Number} x\n * @returns {number}\n */\nconst easeInQuad = (x) => {\n return x * x\n}\n\nexport default easeInQuad\n","import isString from '../types/isString'\nimport isElement from '../types/isElement'\n\n/**\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\n * ========================================================================\n * @method _getScrollElement\n * @param {String|HTMLElement} scrollElement\n * @returns {Element}\n * @private\n */\nconst _getScrollElement = (scrollElement = null) => {\n let $rootElements\n let $scrollElement\n\n if (!scrollElement) {\n $rootElements = document.querySelectorAll('html,body')\n $scrollElement =\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\n ? $rootElements[0]\n : $rootElements[1]\n } else {\n if (isString(scrollElement)) {\n $scrollElement = document.querySelector(scrollElement)\n } else if (isElement(scrollElement)) {\n $scrollElement = scrollElement\n }\n }\n\n return $scrollElement\n}\n\nexport default _getScrollElement\n","/**\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\n * ========================================================================\n * @method offsetTop\n * @param {HTMLElement} el - DOM 节点\n * @returns {Number}\n */\nconst offsetTop = (el) => {\n let top = el.offsetTop\n\n if (el.offsetParent !== null) {\n top += offsetTop(el.offsetParent)\n }\n\n return top\n}\n\nexport default offsetTop\n","/**\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\n * ========================================================================\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\n * 标 DOM 元素是否为事件代理所期望触发的目标。\n * ========================================================================\n * @method matches\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\n * @param {HTMLElement} el - (必须)DOM 元素\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\n * @returns {Boolean}\n */\nconst matches = (el, selector = '') => {\n const sel = selector.replace(/^>/i, '')\n\n if (!selector || !sel || !el) {\n return false\n }\n\n /* istanbul ignore else */\n if (el.matches) {\n return el.matches(sel)\n } else if (el.msMatchesSelector) {\n return el.msMatchesSelector(sel)\n } else {\n return false\n }\n}\n\nexport default matches\n","/**\n * 获取 DOM 元素的父节点\n * ========================================================================\n * @method getParentOrHost\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\n * @returns {*|HTMLElement}\n */\nconst getParentOrHost = (el) => {\n return el.host && el !== document && el.host.nodeType\n ? el.host\n : el.parentNode\n}\n\nexport default getParentOrHost\n","export const CAPTURE_EVENTS = [\n 'focusout',\n 'blur',\n 'focusin',\n 'focus',\n 'load',\n 'unload',\n 'mouseenter',\n 'mouseleave'\n]\n","import { CAPTURE_EVENTS } from './enum'\nimport _delete from './_delete'\n\n/**\n * (私有方法)取消 type 类型的代理事件绑定\n * ========================================================================\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\n * ========================================================================\n * @method _off\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\n * @param {String} type - (必须)事件类型\n * @param {Function} fn - (必须)事件处理器回调函数\n * @private\n */\nconst _off = (el, type, fn) => {\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\n\n /* istanbul ignore else */\n if (fn._delegateListener) {\n fn = fn._delegateListener\n delete fn._delegateListener\n }\n\n // 移除缓存的 _listeners 数据\n _delete(el, type, fn)\n\n el.removeEventListener(type, fn, capture)\n}\n\nexport default _off\n","/**\n * 删除 DOM 元素缓存的 _listeners 数据\n * ========================================================================\n * @method _delete\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\n * @param {String} type - 事件类型(名称)\n * @param {Function} [fn] - 事件处理器回调函数\n */\nconst _delete = function (el, type, fn) {\n const listeners = el._listeners\n let index = -1\n\n if (listeners.length < 1) {\n return false\n }\n\n // 移除缓存的 _listeners 数据\n listeners.forEach((listener, i) => {\n const handler = listener.fn\n\n if (type === listener.type) {\n index = i\n\n if (handler === fn) {\n index = i\n }\n }\n })\n\n /* istanbul ignore else */\n if (index > -1) {\n listeners.splice(index, 1)\n }\n}\n\nexport default _delete\n","import isString from '../types/isString'\nimport isElement from '../types/isElement'\nimport getListeners from './getListeners'\nimport _off from './_off'\n\n/**\n * 销毁(type 类型的)代理事件绑定\n * ========================================================================\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\n * ========================================================================\n * @method purgeElement\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\n * @param {String|Boolean} type - (必须)事件类型\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\n */\nconst purgeElement = function (el, type, recurse = false) {\n const $element = isString(el) ? document.querySelector(el) : el\n const $children = $element.childNodes\n const listeners = getListeners($element, type)\n\n listeners.forEach((listener) => {\n _off($element, listener.type, listener.fn)\n })\n\n if (\n (recurse || type === true || arguments.length === 1) &&\n $element &&\n $children\n ) {\n $children.forEach(($child) => {\n if (isElement($child)) {\n purgeElement($child, type, recurse)\n }\n })\n }\n}\n\nexport default purgeElement\n","import isString from '../types/isString'\n\n/**\n * 获取 DOM 元素(type 事件类型)事件绑定信息\n * ========================================================================\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\n * ========================================================================\n * @methods getListeners\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\n * @param {String} [type] - (可选)事件类型\n * @returns {Array} - 已绑定的事件信息\n */\nconst getListeners = (el, type) => {\n let listeners = el._listeners || []\n\n if (isString(type) && type) {\n listeners = listeners.filter((listener) => {\n return listener.type === type\n })\n }\n\n return listeners\n}\n\nexport default getListeners\n","import purgeElement from './purgeElement'\nimport isFunction from '../types/isFunction'\nimport _off from './_off'\n\n/**\n * 取消 type 类型的代理事件绑定\n * ========================================================================\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\n * ========================================================================\n * @method off\n * @param {HTMLElement|Object} el - (必须)取消事件绑定的 DOM 元素\n * @param {String} type - (必须)事件类型\n * @param {Function} [fn] - (可选)事件处理器回调函数\n */\nconst off = (el, type, fn) => {\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\n if (!isFunction(fn)) {\n return purgeElement(el, type)\n }\n\n _off(el, type, fn)\n}\n\nexport default off\n","import closest from '../dom/closest'\nimport off from './off'\nimport getTarget from './getTarget'\n\nimport { CAPTURE_EVENTS } from './enum'\n\n/**\n * 绑定代理事件\n * ========================================================================\n * @method on\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\n * @param {Boolean} once - (可选)是否仅触发一次\n */\nconst on = (el, selector, type, fn, data, context, once = false) => {\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\n\n const listener = function (evt) {\n const target = getTarget(evt)\n // 通过 Element.matches 方法获得点击的目标元素\n const delegateTarget = closest(target, selector, el)\n let overrideContext = context || el\n\n evt.delegateTarget = delegateTarget\n\n // 当设置为 true 时,则事件处理器回调函数的\n // this 上下文指向为 data 对象\n if (context === true) {\n overrideContext = data\n }\n\n /* istanbul ignore else */\n if (delegateTarget) {\n // 仅触发一次\n /* istanbul ignore else */\n if (once === true) {\n off(el, type, listener)\n }\n\n fn.call(overrideContext, evt, data)\n }\n }\n\n if (!el._listeners) {\n el._listeners = []\n }\n\n // 缓存 options 元素绑定的事件处理器\n el._listeners.push({\n el,\n selector,\n type,\n fn: listener,\n data,\n context,\n capture\n })\n\n // 缓存包装后的事件处理器\n fn._delegateListener = listener\n\n el.addEventListener(type, listener, capture)\n}\n\nexport default on\n","import resolveTextNode from '../dom/resolveTextNode'\n\n/**\n * 返回触发事件的 target DOM 元素\n * ========================================================================\n * @method getTarget\n * @param {Event} evt - Event 对象\n * @return {HTMLElement} - Event 对象的 target DOM 元素\n */\nconst getTarget = function (evt) {\n const target = evt.target\n\n return resolveTextNode(target)\n}\n\nexport default getTarget\n","/**\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\n * resolveTextNode() 方法则会返回实际的目标节点。\n * ========================================================================\n * @method resolveTextNode\n * @param {HTMLElement|Text} el - 要解析的节点\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\n */\nconst resolveTextNode = function (el) {\n if (el && el.nodeType === 3) {\n return el.parentNode\n }\n\n return el\n}\n\nexport default resolveTextNode\n","import matches from './matches'\nimport getParentOrHost from './getParentOrHost'\n\n/**\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\n * ========================================================================\n * @method closest\n * @param {HTMLElement} el - (必须)DOM 元素\n * @param {String} selector - (必须)DOM 元素的选择其\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\n */\nconst closest = (el, selector, ctx, includeCTX) => {\n const context = ctx || document\n\n if (!el) {\n return null\n }\n\n do {\n /* istanbul ignore else */\n if (\n (selector != null &&\n (selector.startsWith('>')\n ? el.parentNode === context && matches(el, selector)\n : matches(el, selector))) ||\n (includeCTX && el === context)\n ) {\n return el\n }\n\n /* istanbul ignore else */\n if (el === context) {\n break\n }\n\n /* jshint boss:true */\n } while ((el = getParentOrHost(el)))\n}\n\nexport default closest\n","import toString from '../lang/toString'\n\n/**\n * 检测数据是否为 Array 类型\n * ========================================================================\n * @method isArray\n * @param {*} o\n * @returns {boolean}\n */\nconst isArray = (o) => {\n if (Array.isArray) {\n return Array.isArray(o)\n } else {\n return toString(o) === '[object Array]'\n }\n}\n\nexport default isArray\n","import DEFAULTS from './defaults'\n\nconst SYMBOLS = [...DEFAULTS]\n\nexport default SYMBOLS\n","const DEFAULTS = [\n '<symbol id=\"outline-icon-up\" viewBox=\"0 0 1024 1024\"><path d=\"M494.784 261.696c0.832-0.448 1.536-1.216 2.368-1.536a38.72 38.72 0 0 1 46.08 8.256l277.824 302.272a41.92 41.92 0 0 1-1.536 58.048 39.104 39.104 0 0 1-56.448-1.6L513.728 355.904 260.736 626.048a39.104 39.104 0 0 1-56.448 1.088 41.6 41.6 0 0 1-1.088-57.984L483.84 269.696c0.512-0.512 1.344-0.768 1.92-1.408l1.088-1.344c2.368-2.496 5.312-3.648 8-5.248z\"></path></symbol>',\n '<symbol id=\"outline-icon-down\" viewBox=\"0 0 1024 1024\"><path d=\"M494.784 762.304c0.832 0.448 1.536 1.216 2.368 1.536 15.232 7.488 33.92 4.992 46.08-8.256l277.824-302.272a41.92 41.92 0 0 0-1.536-58.048 39.104 39.104 0 0 0-56.448 1.6l-249.344 271.232-252.992-270.144a39.104 39.104 0 0 0-56.448-1.088 41.6 41.6 0 0 0-1.088 57.984l280.576 299.456c0.512 0.512 1.344 0.768 1.92 1.408l1.088 1.344c2.368 2.496 5.312 3.648 8 5.248z\"></path></symbol>',\n '<symbol id=\"outline-icon-menu\" viewBox=\"0 0 1024 1024\"><path d=\"M320 256h640V128H320zM320 576h640V448H320zM320 896h640v-128H320zM64 256h128V128H64zM64 576h128V448H64zM64 896h128v-128H64z\"></path></symbol>',\n '<symbol id=\"outline-icon-file\" viewBox=\"0 0 1024 1024\"><path d=\"M320 640h256v128H320z\"></path><path d=\"M320 448h384v128H320z\"></path><path d=\"M640 0l320 320v557.696C960 958.528 909.824 1024 848 1024H176C114.176 1024 64 958.528 64 877.696V146.304C64 65.472 114.176 0 176 0H640z m0 128H192v768h640V320h-192V128z\"></path></symbol>',\n '<symbol id=\"outline-icon-hash\" viewBox=\"0 0 24 24\"><path d=\"M14.216 10l-0.444 4h-3.988l0.444-4zM15.006 2.89l-0.568 5.11h-3.988l0.543-4.89c0.061-0.549-0.335-1.043-0.883-1.104s-1.043 0.335-1.104 0.884l-0.568 5.11h-4.438c-0.552 0-1 0.448-1 1s0.448 1 1 1h4.216l-0.444 4h-3.772c-0.552 0-1 0.448-1 1s0.448 1 1 1h3.549l-0.543 4.89c-0.061 0.549 0.335 1.043 0.883 1.104s1.043-0.335 1.104-0.883l0.569-5.111h3.988l-0.543 4.89c-0.061 0.549 0.335 1.043 0.883 1.104s1.043-0.335 1.104-0.883l0.568-5.111h4.438c0.552 0 1-0.448 1-1s-0.448-1-1-1h-4.216l0.444-4h3.772c0.552 0 1-0.448 1-1s-0.448-1-1-1h-3.549l0.543-4.89c0.061-0.549-0.335-1.043-0.883-1.104s-1.043 0.335-1.104 0.883z\"></path></symbol>',\n '<symbol id=\"outline-icon-close\" viewBox=\"0 0 1024 1024\"><path d=\"M536.96 491.648L310.592 265.344a32 32 0 1 0-45.248 45.248L491.584 536.96l-226.304 226.304a32 32 0 0 0 45.312 45.248l226.24-226.304 226.304 226.304a32 32 0 0 0 45.248-45.248L582.144 536.896l226.304-226.24a32 32 0 0 0-45.248-45.248L536.896 491.584z\"></path></symbol>',\n '<symbol id=\"outline-icon-homepage\" viewBox=\"0 0 26 28\"><path d=\"M22 15.5v7.5c0 0.547-0.453 1-1 1h-6v-6h-4v6h-6c-0.547 0-1-0.453-1-1v-7.5c0-0.031 0.016-0.063 0.016-0.094l8.984-7.406 8.984 7.406c0.016 0.031 0.016 0.063 0.016 0.094zM25.484 14.422l-0.969 1.156c-0.078 0.094-0.203 0.156-0.328 0.172h-0.047c-0.125 0-0.234-0.031-0.328-0.109l-10.813-9.016-10.813 9.016c-0.109 0.078-0.234 0.125-0.375 0.109-0.125-0.016-0.25-0.078-0.328-0.172l-0.969-1.156c-0.172-0.203-0.141-0.531 0.063-0.703l11.234-9.359c0.656-0.547 1.719-0.547 2.375 0l3.813 3.187v-3.047c0-0.281 0.219-0.5 0.5-0.5h3c0.281 0 0.5 0.219 0.5 0.5v6.375l3.422 2.844c0.203 0.172 0.234 0.5 0.063 0.703z\"></path></symbol>',\n '<symbol id=\"outline-icon-github\" viewBox=\"0 0 24 28\"><path d=\"M12 2c6.625 0 12 5.375 12 12 0 5.297-3.437 9.797-8.203 11.391-0.609 0.109-0.828-0.266-0.828-0.578 0-0.391 0.016-1.687 0.016-3.297 0-1.125-0.375-1.844-0.812-2.219 2.672-0.297 5.484-1.313 5.484-5.922 0-1.313-0.469-2.375-1.234-3.219 0.125-0.313 0.531-1.531-0.125-3.187-1-0.313-3.297 1.234-3.297 1.234-0.953-0.266-1.984-0.406-3-0.406s-2.047 0.141-3 0.406c0 0-2.297-1.547-3.297-1.234-0.656 1.656-0.25 2.875-0.125 3.187-0.766 0.844-1.234 1.906-1.234 3.219 0 4.594 2.797 5.625 5.469 5.922-0.344 0.313-0.656 0.844-0.766 1.609-0.688 0.313-2.438 0.844-3.484-1-0.656-1.141-1.844-1.234-1.844-1.234-1.172-0.016-0.078 0.734-0.078 0.734 0.781 0.359 1.328 1.75 1.328 1.75 0.703 2.141 4.047 1.422 4.047 1.422 0 1 0.016 1.937 0.016 2.234 0 0.313-0.219 0.688-0.828 0.578-4.766-1.594-8.203-6.094-8.203-11.391 0-6.625 5.375-12 12-12zM4.547 19.234c0.031-0.063-0.016-0.141-0.109-0.187-0.094-0.031-0.172-0.016-0.203 0.031-0.031 0.063 0.016 0.141 0.109 0.187 0.078 0.047 0.172 0.031 0.203-0.031zM5.031 19.766c0.063-0.047 0.047-0.156-0.031-0.25-0.078-0.078-0.187-0.109-0.25-0.047-0.063 0.047-0.047 0.156 0.031 0.25 0.078 0.078 0.187 0.109 0.25 0.047zM5.5 20.469c0.078-0.063 0.078-0.187 0-0.297-0.063-0.109-0.187-0.156-0.266-0.094-0.078 0.047-0.078 0.172 0 0.281s0.203 0.156 0.266 0.109zM6.156 21.125c0.063-0.063 0.031-0.203-0.063-0.297-0.109-0.109-0.25-0.125-0.313-0.047-0.078 0.063-0.047 0.203 0.063 0.297 0.109 0.109 0.25 0.125 0.313 0.047zM7.047 21.516c0.031-0.094-0.063-0.203-0.203-0.25-0.125-0.031-0.266 0.016-0.297 0.109s0.063 0.203 0.203 0.234c0.125 0.047 0.266 0 0.297-0.094zM8.031 21.594c0-0.109-0.125-0.187-0.266-0.172-0.141 0-0.25 0.078-0.25 0.172 0 0.109 0.109 0.187 0.266 0.172 0.141 0 0.25-0.078 0.25-0.172zM8.937 21.438c-0.016-0.094-0.141-0.156-0.281-0.141-0.141 0.031-0.234 0.125-0.219 0.234 0.016 0.094 0.141 0.156 0.281 0.125s0.234-0.125 0.219-0.219z\"></path></symbol>',\n '<symbol id=\"outline-icon-issues\" viewBox=\"0 0 24 28\"><path d=\"M25.5 15c0 0.547-0.453 1-1 1h-3.5c0 1.953-0.422 3.422-1.047 4.531l3.25 3.266c0.391 0.391 0.391 1.016 0 1.406-0.187 0.203-0.453 0.297-0.703 0.297s-0.516-0.094-0.703-0.297l-3.094-3.078s-2.047 1.875-4.703 1.875v-14h-2v14c-2.828 0-4.891-2.063-4.891-2.063l-2.859 3.234c-0.203 0.219-0.469 0.328-0.75 0.328-0.234 0-0.469-0.078-0.672-0.25-0.406-0.375-0.438-1-0.078-1.422l3.156-3.547c-0.547-1.078-0.906-2.469-0.906-4.281h-3.5c-0.547 0-1-0.453-1-1s0.453-1 1-1h3.5v-4.594l-2.703-2.703c-0.391-0.391-0.391-1.016 0-1.406s1.016-0.391 1.406 0l2.703 2.703h13.188l2.703-2.703c0.391-0.391 1.016-0.391 1.406 0s0.391 1.016 0 1.406l-2.703 2.703v4.594h3.5c0.547 0 1 0.453 1 1zM18 6h-10c0-2.766 2.234-5 5-5s5 2.234 5 5z\"></path></symbol>',\n '<symbol id=\"outline-icon-tags\" viewBox=\"0 0 26 28\"><path d=\"M7 7c0-1.109-0.891-2-2-2s-2 0.891-2 2 0.891 2 2 2 2-0.891 2-2zM23.672 16c0 0.531-0.219 1.047-0.578 1.406l-7.672 7.688c-0.375 0.359-0.891 0.578-1.422 0.578s-1.047-0.219-1.406-0.578l-11.172-11.188c-0.797-0.781-1.422-2.297-1.422-3.406v-6.5c0-1.094 0.906-2 2-2h6.5c1.109 0 2.625 0.625 3.422 1.422l11.172 11.156c0.359 0.375 0.578 0.891 0.578 1.422zM29.672 16c0 0.531-0.219 1.047-0.578 1.406l-7.672 7.688c-0.375 0.359-0.891 0.578-1.422 0.578-0.812 0-1.219-0.375-1.75-0.922l7.344-7.344c0.359-0.359 0.578-0.875 0.578-1.406s-0.219-1.047-0.578-1.422l-11.172-11.156c-0.797-0.797-2.312-1.422-3.422-1.422h3.5c1.109 0 2.625 0.625 3.422 1.422l11.172 11.156c0.359 0.375 0.578 0.891 0.578 1.422z\"></path></symbol>'\n]\n\nexport default DEFAULTS\n","import isString from '../types/isString'\nimport getSymbol from './getSymbol'\nimport SYMBOLS from './symbols'\n\n/**\n *\n * @method getSymbols\n * @param {String} [name]\n * @param {String} [iconSet]\n * @returns {string[]|*}\n */\nconst getSymbols = (name, iconSet = 'icon') => {\n if (isString(name)) {\n return getSymbol(name, iconSet)\n }\n\n return [...SYMBOLS]\n}\n\nexport default getSymbols\n","import SYMBOLS from './symbols'\n\n/**\n * @method getSymbol\n * @param {String} name\n * @param {String} [iconSet]\n * @returns {String}\n */\nconst getSymbol = (name, iconSet = 'icon') => {\n const patternName = /id=\"(.*?)\"/\n const patternSet = /^(\\w+)-/\n const symbols = SYMBOLS\n\n return symbols.find((symbol) => {\n const names = patternName.exec(symbol)\n const fullName = names[1]\n const sets = patternSet.exec(fullName)\n const setName = sets[1]\n const iconName =\n iconSet === 'icon' ? `${iconSet}-${name}` : `${iconSet}-icon-${name}`\n\n return setName === iconSet && fullName === iconName\n })\n}\n\nexport default getSymbol\n","import add from './add'\nimport getSymbols from './getSymbols'\n\n/**\n * 绘制 SVG 图标集\n * ========================================================================\n * @method paint\n * @param {String|Array} symbol\n */\nconst paint = (symbol = '') => {\n const $body = document.body\n let $icons = document.querySelector('#outline-icons')\n let symbols = []\n\n add(symbol)\n symbols = getSymbols()\n\n if ($icons) {\n $icons.innerHTML = symbols.join('')\n } else {\n $icons = document.createElement('div')\n $icons.innerHTML =\n `<svg id=\"outline-icons\" aria-hidden=\"true\" style=\"position:absolute;display:none;width:0;height:0;overflow:hidden;\">` +\n `${symbols.join('')}` +\n `</svg>`\n $body.insertBefore($icons.firstChild, $body.firstChild)\n }\n}\n\nexport default paint\n","import isArray from '../types/isArray'\nimport isString from '../types/isString'\nimport SYMBOLS from './symbols'\n\n/**\n * @method add\n * @param {Array|String} symbols\n * @return {Boolean}\n */\nconst add = (symbols) => {\n if (!symbols) {\n return false\n }\n\n if (isArray(symbols) && symbols.length > 0) {\n symbols.forEach((symbol) => {\n /* istanbul ignore else */\n if (SYMBOLS.indexOf(symbol) === -1 && isString(symbol)) {\n SYMBOLS.push(symbol)\n }\n })\n } else {\n /* istanbul ignore else */\n if (isString(symbols)) {\n SYMBOLS.push(symbols)\n }\n }\n}\n\nexport default add\n","import isString from '../types/isString'\n\n/**\n * 清楚字符串起始位置所有的空格\n * ========================================================================\n * @method trim\n * @param {string} str\n * @returns {string|Boolean}\n */\nconst trim = (str) => {\n if (!isString(str)) {\n return false\n }\n return str.replace(/(^\\s+)|(\\s+$)/g, '')\n}\n\nexport default trim\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\nimport isObject from './isObject'\n\nconst isFragment = (fragment) => {\n return !!(\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\n )\n}\n\nexport default isFragment\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","/**\n * 给 DOM 节点设置属性/值\n * ========================================================================\n * @method setAttribute\n * @param {HTMLElement} el - DOM 节点\n * @param {String} attr - 属性名称\n * @param {String|Number|Boolean} value - 属性值\n */\nconst setAttribute = (el, attr, value) => {\n let tagName = el.tagName.toLowerCase()\n\n switch (attr) {\n case 'style':\n el.style.cssText = value\n break\n case 'value':\n if (tagName === 'input' || tagName === 'textarea') {\n el.value = value\n } else {\n el.setAttribute(attr, value)\n }\n break\n case 'className':\n el.className = value\n break\n default:\n el.setAttribute(attr, value)\n break\n }\n}\n\nexport default setAttribute\n","import isString from './isString'\n\nconst isSVG = (str) => {\n const declaration = '(?:<\\\\?xml[^>]*>\\\\s*)?'\n const doctype =\n '(?:<\\\\!doctype svg[^>]*\\\\s*(?:\\\\[?(?:\\\\s*<![^>]*>\\\\s*)*\\\\]?)*[^>]*>\\\\s*)?'\n const content = '<svg[^>]*>[^]*<\\\\/svg>\\\\s*$'\n const svg = `^\\\\s*${declaration}${doctype}${content}\\\\s*$`\n const pattern = new RegExp(svg, 'i')\n\n return isString(str) && pattern.test(str)\n}\n\nexport default isSVG\n","import createElement from './createElement'\n\n/**\n * 创建 SVG 图标 DOM 元素\n * ========================================================================\n * @method icon\n * @alias createElement\n * @see createElement\n * @param {String} name\n * @param {Object} [options]\n * @param {Number|Array} [options.size]\n * @param {String} [options.color]\n * @param {String} [options.iconSet]\n * @returns {HTMLElement}\n */\nconst icon = (name, options = {}) => {\n return createElement(name, options)\n}\n\nexport default icon\n","import isArray from '../types/isArray'\nimport isString from '../types/isString'\nimport isSVG from '../types/isSVG'\n\n/**\n * 创建 SVG 图标 DOM 元素\n * ========================================================================\n * @method createElement\n * @param {String} name\n * @param {Object} [options]\n * @param {Number|Array} [options.size]\n * @param {String} [options.color]\n * @param {String} [options.iconSet]\n * @returns {HTMLElement}\n */\nconst createElement = (name, options = {}) => {\n const size = options.size || 0\n const color = options.color || ''\n const iconSet = options.iconSet || ''\n const width = isArray(size) ? size[0] : size\n const height = isArray(size) ? size[1] : size\n const defaultRules = size ? `width:${width}px;height:${height}px;` : ''\n const cssRules = color ? defaultRules + `color:${color}` : defaultRules\n const $icon = document.createElement('i')\n let binds = ''\n let svg = ''\n let $svg\n\n if (!isString(name)) {\n return null\n }\n\n if (isSVG(name)) {\n svg = name\n } else {\n binds =\n iconSet && iconSet !== 'icon'\n ? `xlink:href=\"#${iconSet}-icon-${name}\"`\n : `xlink:href=\"#icon-${name}\"`\n svg =\n `<svg aria-hidden=\"true\" class=\"outline-icon__svg\" style=\"${cssRules}\">` +\n `<use ${binds}></use>` +\n `</svg>`\n }\n\n $icon.className = 'outline-icon'\n $icon.innerHTML = svg\n\n if (isSVG(name)) {\n $svg = $icon.querySelector('svg')\n $svg.setAttribute('aria-hidden', 'true')\n $svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg')\n $svg.setAttribute('class', 'outline-icon__svg')\n $svg.setAttribute('width', '200')\n $svg.setAttribute('height', '200')\n $svg.style.cssText = cssRules\n }\n\n return $icon\n}\n\nexport default createElement\n","import trim from './utils/lang/trim'\nimport createElement from './utils/dom/createElement'\nimport setAttribute from './utils/dom/setAttribute'\n\nimport icon from './utils/icons/icon'\n\nconst _updateHeading = ($heading, i, options) => {\n const CLS_HEADING = 'outline-heading'\n const hasAnchor = options.hasAnchor || true\n const isAtStart = options.isAtStart || true\n const showCode = options.showCode || false\n const chapterCode = options.chapterCode || ''\n const anchorURL = options.anchorURL || ''\n const headingId = `heading-${i}`\n const attrs = {\n id: headingId,\n className: isAtStart ? `${CLS_HEADING} ${CLS_HEADING}_start` : CLS_HEADING,\n 'data-id': i\n }\n const keys = Object.keys(attrs)\n const text = trim($heading.innerHTML)\n let $anchor\n let $icon\n\n keys.forEach((prop) => {\n setAttribute($heading, prop, attrs[prop])\n })\n\n if (showCode) {\n $heading.innerHTML = chapterCode + ' ' + text\n }\n\n if (!hasAnchor) {\n return false\n }\n\n $icon = icon('hash', { iconSet: 'outline' })\n $anchor = createElement(\n 'a',\n {\n id: `anchor-${i}`,\n className: `${CLS_HEADING}__anchor anchor-${i}`,\n href: anchorURL || `#${headingId}`,\n target: anchorURL ? '_blank' : 'self',\n 'data-id': i\n },\n $icon\n )\n $heading.appendChild($anchor)\n}\n\nexport default _updateHeading\n","import hasOwn from '../lang/hasOwn'\nimport isObject from '../types/isObject'\nimport isString from '../types/isString'\nimport isArray from '../types/isArray'\nimport isDOM from '../types/isDOM'\nimport setAttribute from './setAttribute'\n\n/**\n * 创建 DOM 节点,并添加属性和子节点\n * ========================================================================\n * @method createElement\n * @param {String} tagName - 标签名称\n * @param {Object|Array} attrs - 属性对象或者子节点\n * @param {Array|HTMLElement|DocumentFragment|String} [children] - 子节点数组\n * @returns {HTMLElement}\n */\nconst createElement = (tagName, attrs, children) => {\n const $fragment = document.createDocumentFragment()\n const $el = document.createElement(tagName)\n const isValidChild = (child) => {\n return isDOM(child) || isString(child)\n }\n const append = (child) => {\n let $child\n\n if (!isValidChild(child)) {\n return false\n }\n\n if (isDOM(child)) {\n $child = child\n } else if (isString(child)) {\n $child = document.createTextNode(child)\n }\n\n $fragment.appendChild($child)\n }\n\n if (isObject(attrs)) {\n Object.keys(attrs).forEach((attr) => {\n if (hasOwn(attrs, attr)) {\n setAttribute($el, attr, attrs[attr])\n }\n })\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\n attrs.forEach((child) => {\n append(child)\n })\n }\n\n if (isArray(children)) {\n children.forEach((child) => {\n append(child)\n })\n } else {\n append(children)\n }\n\n $el.appendChild($fragment)\n\n return $el\n}\n\nexport default createElement\n","import trim from '../lang/trim'\nimport hasClass from './hasClass'\n\n/**\n * 移除 DOM 节点的 className 样式\n * ========================================================================\n * @method removeClass\n * @param {HTMLElement} el - DOM 节点\n * @param {String} className - 样式名称\n * @returns {Boolean}\n */\nconst removeClass = (el, className) => {\n let allClass = el.className\n let classList\n\n if (!allClass || !hasClass(el, className)) {\n return false\n }\n\n classList = el.classList\n\n if (classList?.remove) {\n classList.remove(className)\n } else {\n allClass = trim(allClass.replace(className, ''))\n el.className = allClass\n }\n}\n\nexport default removeClass\n","import isElement from '../types/isElement'\n/**\n * 检测 DOM 节点是否包含名为 className 的样式\n * ========================================================================\n * @method hasClass\n * @param {HTMLElement} el - DOM 节点\n * @param {String} className - 样式名称\n * @returns {Boolean}\n */\nconst hasClass = (el, className) => {\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\n let allClass\n let classList\n\n if (!isElement(el)) {\n return false\n }\n\n allClass = el.className\n\n if (!allClass) {\n return false\n }\n\n classList = el.classList\n\n if (classList?.contains) {\n return el.classList.contains(className)\n }\n\n return !!pattern.exec(allClass)\n}\n\nexport default hasClass\n","import removeClass from './utils/dom/removeClass'\nimport isEmpty from './utils/types/isEmpty'\nimport trim from './utils/lang/trim'\n\nconst _resetHeading = ($heading, hasAnchor = true, isAtStart = true) => {\n const CLS_HEADING = 'outline-heading'\n const text = $heading.innerHTML\n const pattern = /^\\d+(\\.?\\d+)*\\s?/gi\n let $anchor\n\n $heading.innerHTML = text.replace(pattern, '')\n $heading.removeAttribute('id')\n $heading.removeAttribute('data-id')\n\n removeClass($heading, CLS_HEADING)\n\n if (!hasAnchor) {\n return false\n }\n\n $anchor = $heading.querySelector(`.${CLS_HEADING}__anchor`)\n\n if (isAtStart) {\n removeClass($heading, `${CLS_HEADING}_start`)\n }\n\n if (isEmpty(trim($heading.className))) {\n $heading.removeAttribute('class')\n }\n\n $heading.removeChild($anchor)\n}\n\nexport default _resetHeading\n","import isString from './isString'\n/**\n * 检测数据是否为空字符串\n * ========================================================================\n * @method isEmpty\n * @param {String} str\n * @returns {boolean}\n */\nconst isEmpty = (str) => {\n return isString(str) && str === ''\n}\n\nexport default isEmpty\n","import trim from './utils/lang/trim'\nimport stripTags from './utils/lang/stripTags'\nimport isFunction from './utils/types/isFunction'\n\nimport _getChapterParentIdByDiffer from './_getChapterParentIdByDiffer'\nimport _getChaptersWithCode from './_getChaptersWithCode'\n\n/**\n * 根据文章中的 h1~h6 标签,自动分析返回文章章节数据\n * ========================================================================\n * @method getChapters\n * @param {Array} headings\n * @param {Boolean} [showCode]\n * @param {Function} [chapterTextFilter]\n * @return {*|*[]}\n */\nconst getChapters = (headings, showCode = true, chapterTextFilter = null) => {\n let previous = 1\n let level = 0\n let text = ''\n const chapters = []\n\n headings.forEach((heading, i) => {\n const tagName = heading.tagName\n const headingLevel = tagName.replace(/h/i, '')\n let current = parseInt(headingLevel, 10)\n let pid = -1\n\n // 场景1:当前标题是前一个标题的子标题\n // 当前标题的(标题标签)序号 > 前一个标题的序号:两个相连的标题是父标题 -> 子标题关系;\n // h2 (前一个标题)\n // h3 (当前标题)\n if (current > previous) {\n level += 1\n\n // 第一层级的 pid 是 -1\n if (level === 1) {\n pid = -1\n } else {\n pid = i - 1\n }\n }\n // 场景2:当前标题和前一个标题层级相同\n // 当前标题的(标题标签)序号 = 前一个标题的序号\n // h2 (前一个标题)\n // h2 (当前标题)\n // 当前标题的(标题标签)序号 < 前一个标题的序号,并且当前标题序号 > 当前的级别\n // h2\n // h4 (前一个标题)\n // h3 (当前标题:这种情况我们还是任务 h3 是 h2 的下一级章节)\n else if (current === previous || (current < previous && current > level)) {\n // H1 的层级肯定是 1\n if (current === 1) {\n level = 1\n pid = -1\n } else {\n pid = chapters[i - 1].pid\n }\n }\n // 场景3:当前标题比前一个标题层级高\n else if (current <= level) {\n // H1 的层级肯定是 1\n if (current === 1) {\n level = 1\n } else {\n level = level - (previous - current)\n\n if (level <= 1) {\n level = 1\n }\n }\n\n // 第一级的标题\n if (level === 1) {\n pid = -1\n } else {\n // 通过当前标题和前一个标题之间的等级差,获得当前标题的父标题ID\n pid = _getChapterParentIdByDiffer(chapters, previous - current, i)\n }\n }\n\n previous = current\n\n text = stripTags(trim(heading.innerHTML))\n\n if (isFunction(chapterTextFilter)) {\n text = chapterTextFilter(text)\n }\n\n chapters.push({\n id: i,\n pid: pid,\n level: level,\n rel: `heading-${i}`,\n text,\n tagName\n })\n })\n\n return showCode ? _getChaptersWithCode(chapters) : chapters\n}\n\nexport default getChapters\n","import isString from '../types/isString'\n\n/**\n * 过滤所有 HTML 标签\n * ========================================================================\n * @method stripTags\n * @param {string} str\n * @returns {string}\n */\nconst stripTags = (str) => {\n if (!isString(str)) {\n return ''\n }\n return str.replace(/<\\/?[^>]+(>|$)/g, '')\n}\n\nexport default stripTags\n","const _getChapterParentIdByDiffer = (chapters, differ, index) => {\n let previous = chapters[index - 1]\n let pid\n let i\n\n for (i = 0; i < differ; i += 1) {\n pid = previous.pid\n previous = chapters[pid]\n }\n\n pid = previous.pid\n\n return pid\n}\n\nexport default _getChapterParentIdByDiffer\n","import isArray from './utils/types/isArray'\n\nconst _getChaptersWithCode = (chapters) => {\n const groups = {}\n const cb = (o) => {\n return [o.pid]\n }\n\n chapters.forEach((o) => {\n const group = JSON.stringify(cb(o))\n\n groups[group] = groups[group] || []\n groups[group].push(o)\n\n o.index = groups[group].length\n if (o.pid === -1) {\n o.code = String(o.index)\n }\n })\n\n Object.keys(groups).forEach((group) => {\n groups[group].forEach((c) => {\n const subjects = groups[`[${c.id}]`]\n if (!subjects || !isArray(subjects)) {\n return false\n }\n subjects.forEach((o) => {\n o.code = c.code + '.' + o.index\n })\n })\n })\n\n return chapters\n}\n\nexport default _getChaptersWithCode\n","import Base from './base'\n\n// 在文章的标题生成 anchor 链接\nimport isString from './utils/types/isString'\nimport isFunction from './utils/types/isFunction'\nimport isElement from './utils/types/isElement'\nimport toTree from './utils/lang/toTree'\nimport later from './utils/lang/later'\nimport scrollTo from './utils/dom/scrollTo'\nimport _getScrollElement from './utils/dom/_getScrollElement'\nimport offsetTop from './utils/dom/offsetTop'\nimport on from './utils/event/on'\nimport off from './utils/event/off'\nimport stop from './utils/event/stop'\nimport paint from './utils/icons/paint'\n\nimport _updateHeading from './_updateHeading'\nimport _resetHeading from './_resetHeading'\nimport getChapters from './getChapters'\n\nclass Anchors extends Base {\n constructor(options) {\n super()\n\n this.attrs = Anchors.DEFAULTS\n this.$articleElement = null\n this.$scrollElement = null\n this.$headings = []\n this.chapters = []\n\n if (options) {\n this.initialize(options)\n }\n }\n\n initialize(options) {\n const showCode = this.attr('showCode') || true\n let created\n let scrollElement\n let selector\n let $articleElement\n let articleElement\n\n this.attr(options)\n articleElement = this.attr('articleElement')\n scrollElement = this.attr('scrollElement')\n selector = this.attr('selector')\n created = this.attr('created')\n\n if (isString(articleElement)) {\n $articleElement = document.querySelector(articleElement)\n } else if (isElement(articleElement)) {\n $articleElement = articleElement\n }\n\n if (!$articleElement) {\n return this\n }\n\n this.$articleElement = $articleElement\n this.$scrollElement = _getScrollElement(scrollElement)\n this.$headings = [...$articleElement.querySelectorAll(selector)]\n\n if (this.$headings.length < 1) {\n return this\n }\n\n this.chapters = getChapters(\n this.$headings,\n showCode,\n this.attr('chapterTextFilter')\n )\n\n if (isFunction(created)) {\n created.call(this)\n }\n\n this.render().addListeners()\n\n return this\n }\n\n getChapters(isTreeStructured = false) {\n const chapters = this.chapters\n return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters\n }\n\n count() {\n return this.chapters.length\n }\n\n render() {\n const mounted = this.attr('mounted')\n const hasAnchor = this.attr('hasAnchor')\n const isAtStart = this.attr('isAtStart')\n const showCode = this.attr('showCode')\n const anchorURL = this.attr('anchorURL')\n const $headings = this.$headings\n const chapters = this.getChapters()\n\n paint()\n\n $headings.forEach(($heading, i) => {\n const chapterCode = chapters[i].code\n _updateHeading($heading, i, {\n hasAnchor,\n isAtStart,\n showCode,\n chapterCode,\n anchorURL\n })\n })\n\n if (isFunction(mounted)) {\n mounted.call(this)\n }\n\n return this\n }\n\n scrollTo(top, after) {\n const el = this.$scrollElement\n\n scrollTo(el, top, after)\n\n return this\n }\n\n destroy() {\n const hasAnchor = this.attr('hasAnchor')\n const isAtStart = this.attr('isAtStart')\n const beforeDestroy = this.attr('beforeDestroy')\n const afterDestroy = this.attr('afterDestroy')\n const $headings = this.$headings\n\n if (isFunction(beforeDestroy)) {\n beforeDestroy.call(this)\n }\n\n this.removeListeners()\n $headings.forEach(($heading) => {\n _resetHeading($heading, hasAnchor, isAtStart)\n })\n\n this.attr(Anchors.DEFAULTS)\n this.$articleElement = null\n this.$scrollElement = null\n this.$headings = []\n this.chapters = []\n\n if (isFunction(afterDestroy)) {\n afterDestroy.call(this)\n }\n\n return this\n }\n\n onAnchorTrigger(evt) {\n const anchorURL = this.attr('anchorURL')\n const afterScroll = this.attr('afterScroll')\n const stickyHeight = this.attr('stickyHeight')\n const $anchor = evt.delegateTarget\n const $heading = $anchor.parentNode\n const top = offsetTop($heading) - (stickyHeight + 10)\n const $scrollElement = this.$scrollElement\n const min = 0\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\n const after = () => {\n if (isFunction(afterScroll)) {\n afterScroll.call(this, 'anchor')\n }\n\n later(() => {\n this.$emit('toolbar:update', {\n top,\n min,\n max\n })\n })\n }\n\n this.scrollTo(top, after)\n\n if (!anchorURL) {\n stop(evt)\n }\n\n return this\n }\n\n addListeners() {\n const $articleElement = this.$articleElement\n\n on(\n $articleElement,\n '.outline-heading__anchor',\n 'click',\n this.onAnchorTrigger,\n this,\n true\n )\n\n return this\n }\n\n removeListeners() {\n const $articleElement = this.$articleElement\n\n off($articleElement, 'click', this.onAnchorTrigger)\n\n return this\n }\n}\n\nAnchors.DEFAULTS = {\n scrollElement: 'html,body',\n articleElement: '#article',\n selector: 'h1,h2,h3,h4,h5,h6',\n stickyHeight: 0,\n anchorURL: '',\n hasAnchor: true,\n isAtStart: true,\n showCode: false,\n created: null,\n mounted: null,\n afterScroll: null,\n beforeDestroy: null,\n afterDestroy: null,\n chapterTextFilter: null\n}\n\nexport default Anchors\n","const toTree = (list, nodeKey, parentKey) => {\r\n const map = {}\r\n const roots = []\r\n\r\n list.forEach((item, i) => {\r\n // initialize the map\r\n map[item[nodeKey]] = i\r\n // initialize the children\r\n item.children = []\r\n })\r\n\r\n list.forEach((item) => {\r\n const node = list[map[item[parentKey]]]\r\n\r\n if (item[parentKey] !== -1) {\r\n // if you have dangling branches check that map[node.parentId] exists\r\n node.children.push(item)\r\n } else {\r\n roots.push(item)\r\n }\r\n })\r\n\r\n return roots\r\n}\r\n\r\nexport default toTree\r\n","import easeInQuad from '../lang/easeInQuad'\nimport isFunction from '../types/isFunction'\nimport _getScrollElement from './_getScrollElement'\n\n/**\n * 指定 rootElement DOM 节点滚动到指定 top 位置\n * ========================================================================\n * @method scrollTo\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\n * @param {Number} top - (必须)滚动的 scrollTop 数值\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\n */\nconst scrollTo = (scrollElement, top, afterStop) => {\n const $scrollElement = _getScrollElement(scrollElement)\n let scrollTop = $scrollElement.scrollTop\n let step = 0\n const distance = top - scrollTop\n const MAX_HEIGHT = $scrollElement.scrollHeight\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\n const stop = (top) => {\n if (isFunction(afterStop)) {\n afterStop(top)\n }\n\n return false\n }\n const play = () => {\n step += 1\n\n // 向上滚动\n if (distance < 0) {\n scrollTop -= easeInQuad(step)\n $scrollElement.scrollTop = scrollTop\n\n if (scrollTop <= top) {\n $scrollElement.scrollTop = top\n return stop(top)\n }\n } else {\n scrollTop += easeInQuad(step)\n $scrollElement.scrollTop = scrollTop\n\n if (scrollTop >= MAX_TOP) {\n $scrollElement.scrollTop = MAX_TOP\n return stop(MAX_TOP)\n }\n }\n\n requestAnimationFrame(play)\n }\n\n requestAnimationFrame(play)\n}\n\nexport default scrollTo\n","import isFunction from '../types/isFunction'\n\n/**\n * later - 延迟执行方法\n * ========================================================================\n * @method later\n * @param {Function} fn\n * @param {Number} [delay]\n * @returns {number|boolean}\n */\nconst later = (fn, delay = 300) => {\n if (!isFunction(fn)) {\n return false\n }\n\n return setTimeout(() => {\n fn()\n }, delay)\n}\n\nexport default later\n","/**\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\n * ========================================================================\n * @method stop\n * @param {Event} evt - 事件对象\n *\n * @example\n * <div id=\"nav\" class=\"nav\">\n * <a id=\"service\" class=\"anchor\" href=\"https://www.yaohaixiao.com/serivce\">Service</a>\n * <a id=\"help\" class=\"anchor\" href=\"https://www.yaohaixiao.com/help\">Help</a>\n * </div>\n *\n * const $nav = document.querySelector('#nav')\n * const $service = document.querySelector('.anchor')\n *\n * on($nav, 'click', function(evt) {\n * console.log('你点击了导航栏')\n * })\n *\n * on($anchor, 'click', function(evt) {\n * console.log('tagName', this.tagName)\n *\n * // 工作台输出:'a'\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\n * stopEvent(evt)\n * })\n */\nconst stop = function (evt) {\n evt.stopPropagation()\n evt.preventDefault()\n}\n\nexport default stop\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","_subscribers","_hasDirectSubscribersFor","topic","length","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","data","async","execute","forEach","subscriber","message","indexOf","callback","context","deliver","setTimeout","guid","uuid","prefix","_removeSubscriber","off","token","keys","subject","execution","j","splice","_removeSubscriberByToken","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","arguments","destroy","removeListeners","reload","$emit","event","publish","$on","handler","push","subscribe","$off","unsubscribe","isElement","nodeName","tagName","nodeType","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","document","querySelector","querySelectorAll","scrollTop","offsetTop","el","top","offsetParent","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","CAPTURE_EVENTS","_off","type","fn","capture","_delegateListener","listeners","_listeners","index","listener","i","_delete","removeEventListener","purgeElement","recurse","$element","$children","childNodes","filter","getListeners","$child","on","once","evt","target","getTarget","delegateTarget","ctx","includeCTX","startsWith","closest","overrideContext","addEventListener","isArray","Array","SYMBOLS","getSymbols","name","iconSet","patternName","patternSet","find","symbol","fullName","exec","iconName","getSymbol","paint","$body","body","$icons","symbols","add","innerHTML","join","createElement","insertBefore","firstChild","trim","isDOM","isHTMLCollection","fragment","isTextNode","setAttribute","toLowerCase","style","cssText","className","isSVG","pattern","RegExp","test","icon","size","color","width","height","defaultRules","cssRules","$icon","$svg","binds","svg","_updateHeading","$heading","CLS_HEADING","hasAnchor","isAtStart","showCode","chapterCode","anchorURL","headingId","id","text","$anchor","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","every","href","removeClass","classList","allClass","contains","hasClass","remove","_resetHeading","removeAttribute","removeChild","getChapters","headings","chapterTextFilter","previous","level","chapters","heading","headingLevel","current","parseInt","pid","differ","_getChapterParentIdByDiffer","rel","groups","group","JSON","stringify","cb","code","String","c","subjects","_getChaptersWithCode","Anchors","super","DEFAULTS","$articleElement","$headings","created","articleElement","isTreeStructured","list","nodeKey","parentKey","map","roots","item","node","toTree","count","mounted","scrollTo","after","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","beforeDestroy","afterDestroy","onAnchorTrigger","afterScroll","stickyHeight","max","clientHeight","delay","later","min","stopPropagation","preventDefault"],"mappings":"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"}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/qdplatform/outline.js.git
[email protected]:qdplatform/outline.js.git
qdplatform
outline.js
outline.js
master

搜索帮助