Vue API 看板 (^3.0.0)

更方便的查看 Vue API

  1. // ==UserScript==
  2. // @name:zh-CN Vue API 看板 (^3.0.0)
  3. // @name Vue API Dashboard (^3.0.0)
  4. // @namespace https://github.com/xianghongai/Vue-API-Dashboard
  5. // @version 0.0.2
  6. // @description:zh-CN 更方便的查看 Vue API
  7. // @description Better view for Vue API
  8. // @author Nicholas Hsiang / 山茶树和葡萄树
  9. // @icon https://haleclipse.org/favicon.ico
  10. // @match https://v3.cn.vuejs.org/api/*
  11. // @match https://v3.vuejs.org/api/*
  12. // @require https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js
  13. // @grant none
  14. // ==/UserScript==
  15. (() => {
  16. "use strict";
  17.  
  18. const titleText = "Vue API Dashboard";
  19.  
  20. const gridSelector = ".sidebar .sidebar-links-extend";
  21. const girdIsList = false; // 如果提取的是一个 Node 数组
  22. const columnSelector = ".sidebar-links-extend>li";
  23. const columnTitleSelector = ".sidebar-links-extend>li>a.sidebar-link";
  24. const menuListSelector = ".sidebar-sub-headers";
  25. const menuItemSelector = ".sidebar-sub-headers li";
  26.  
  27. const menuItemActionSelector = null;
  28.  
  29. const helpEnable = false;
  30. const helpSelector = "";
  31.  
  32. // 使用本扩展的样式风格,将会替换原站点的菜单风格
  33. const customStyleEnable = true; // Dark & Light
  34. const cloneNodeEnable = true; // 保留原 DOM 节点?
  35.  
  36. const compactColumnEnable = true; // 紧凑模式,将会合并一些少的列
  37. const compactColumnLimit = 13; // 多列数据组合上限
  38.  
  39. function initialExtraStyle() {
  40. return `
  41. .hs-dashboard__toggle {
  42. top: 5px;
  43. }
  44. `;
  45. }
  46.  
  47. /* ------------------------------------------------------------------------- */
  48.  
  49. let wrapperEle = null;
  50. let themeSwitchEle = null;
  51. let themeSwitchForm = null;
  52.  
  53. const bodyContainer = document.querySelector("body");
  54.  
  55. function initialDashboard() {
  56. initialToggle();
  57. initialStyle(initialExtraStyle);
  58. initialMenu(cloneNodeEnable);
  59. initialHelp();
  60. handleEvent();
  61. handleTheme(true);
  62. }
  63.  
  64. let interval = null;
  65.  
  66. function ready() {
  67. replaceSideBar();
  68. const originEle = document.querySelector(gridSelector);
  69. if (originEle) {
  70. clearInterval(interval);
  71. // Dashboard
  72. initialDashboard();
  73. // Other
  74. }
  75. }
  76.  
  77. interval = setInterval(ready, 1000);
  78.  
  79. function replaceSideBar() {
  80. $(".links").css("right","2.5rem");
  81. $(".sidebar").append('<ul class="sidebar-links-extend" style="display:none"><li><a href="/api/application-config.html" class="active sidebar-link" aria-current="page" one-link-mark="yes">应用配置</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/application-config.html#errorhandler" class="sidebar-link" one-link-mark="yes">errorHandler</a></li><li class="sidebar-sub-header"><a href="/api/application-config.html#warnhandler" class="sidebar-link" one-link-mark="yes">warnHandler</a></li><li class="sidebar-sub-header"><a href="/api/application-config.html#globalproperties" class="sidebar-link" one-link-mark="yes">globalProperties</a></li><li class="sidebar-sub-header"><a href="/api/application-config.html#iscustomelement" class="sidebar-link" one-link-mark="yes">isCustomElement</a></li><li class="sidebar-sub-header"><a href="/api/application-config.html#optionmergestrategies" class="sidebar-link" one-link-mark="yes">optionMergeStrategies</a></li><li class="sidebar-sub-header"><a href="/api/application-config.html#performance" class="sidebar-link" one-link-mark="yes">performance</a></li></ul></li><li><a href="/api/application-api.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">应用 API</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/application-api.html#component" class="sidebar-link" one-link-mark="yes">component</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#config" class="sidebar-link" one-link-mark="yes">config</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#directive" class="sidebar-link" one-link-mark="yes">directive</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#mixin" class="sidebar-link" one-link-mark="yes">mixin</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#mount" class="sidebar-link" one-link-mark="yes">mount</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#provide" class="sidebar-link" one-link-mark="yes">provide</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#unmount" class="sidebar-link" one-link-mark="yes">unmount</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#use" class="sidebar-link" one-link-mark="yes">use</a></li><li class="sidebar-sub-header"><a href="/api/application-api.html#version" class="sidebar-link" one-link-mark="yes">version</a></li></ul></li><li><a href="/api/global-api.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">全局 API</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/global-api.html#createapp" class="sidebar-link" one-link-mark="yes">createApp</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#h" class="sidebar-link" one-link-mark="yes">h</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#definecomponent" class="sidebar-link" one-link-mark="yes">defineComponent</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#defineasynccomponent" class="sidebar-link" one-link-mark="yes">defineAsyncComponent</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#resolvecomponent" class="sidebar-link" one-link-mark="yes">resolveComponent</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#resolvedynamiccomponent" class="sidebar-link" one-link-mark="yes">resolveDynamicComponent</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#resolvedirective" class="sidebar-link" one-link-mark="yes">resolveDirective</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#withdirectives" class="sidebar-link" one-link-mark="yes">withDirectives</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#createrenderer" class="sidebar-link" one-link-mark="yes">createRenderer</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#nexttick" class="sidebar-link" one-link-mark="yes">nextTick</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#mergeprops" class="sidebar-link" one-link-mark="yes">mergeProps</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#usecssmodule" class="sidebar-link" one-link-mark="yes">useCssModule</a></li><li class="sidebar-sub-header"><a href="/api/global-api.html#version" class="sidebar-link" one-link-mark="yes">version</a></li></ul></li><li><a href="/api/options-api.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">选项 </a><ul class="sidebar-sub-headers"><li><a href="/api/options-data.html" class="sidebar-link" one-link-mark="yes">Data</a></li><li><a href="/api/options-dom.html" class="sidebar-link" one-link-mark="yes">DOM</a></li><li><a href="/api/options-lifecycle-hooks.html" class="sidebar-link" one-link-mark="yes">生命周期钩子</a></li><li><a href="/api/options-assets.html" class="sidebar-link" one-link-mark="yes">选项/资源</a></li><li><a href="/api/options-composition.html" class="sidebar-link" one-link-mark="yes">组合</a></li><li><a href="/api/options-misc.html" class="sidebar-link" one-link-mark="yes">杂项</a></li></ul></li><li><a href="/api/instance-properties.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">实例 property</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/instance-properties.html#data" class="sidebar-link" one-link-mark="yes">$data</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#props" class="sidebar-link" one-link-mark="yes">$props</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#el" class="sidebar-link" one-link-mark="yes">$el</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#options" class="sidebar-link" one-link-mark="yes">$options</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#parent" class="sidebar-link" one-link-mark="yes">$parent</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#root" class="sidebar-link" one-link-mark="yes">$root</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#slots" class="sidebar-link" one-link-mark="yes">$slots</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#refs" class="sidebar-link" one-link-mark="yes">$refs</a></li><li class="sidebar-sub-header"><a href="/api/instance-properties.html#attrs" class="sidebar-link" one-link-mark="yes">$attrs</a></li></ul></li><li><a href="/api/instance-methods.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">实例方法</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/instance-methods.html#watch" class="sidebar-link" one-link-mark="yes">$watch</a></li><li class="sidebar-sub-header"><a href="/api/instance-methods.html#emit" class="sidebar-link" one-link-mark="yes">$emit</a></li><li class="sidebar-sub-header"><a href="/api/instance-methods.html#forceupdate" class="sidebar-link" one-link-mark="yes">$forceUpdate</a></li><li class="sidebar-sub-header"><a href="/api/instance-methods.html#nexttick" class="sidebar-link" one-link-mark="yes">$nextTick</a></li></ul></li><li><a href="/api/directives.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">指令</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/directives.html#v-text" class="sidebar-link" one-link-mark="yes">v-text</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-html" class="sidebar-link" one-link-mark="yes">v-html</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-show" class="sidebar-link" one-link-mark="yes">v-show</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-if" class="sidebar-link" one-link-mark="yes">v-if</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-else" class="sidebar-link" one-link-mark="yes">v-else</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-else-if" class="sidebar-link" one-link-mark="yes">v-else-if</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-for" class="sidebar-link" one-link-mark="yes">v-for</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-on" class="sidebar-link" one-link-mark="yes">v-on</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-bind" class="sidebar-link" one-link-mark="yes">v-bind</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-model" class="sidebar-link" one-link-mark="yes">v-model</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-slot" class="sidebar-link" one-link-mark="yes">v-slot</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-pre" class="sidebar-link" one-link-mark="yes">v-pre</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-cloak" class="sidebar-link" one-link-mark="yes">v-cloak</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-once" class="sidebar-link" one-link-mark="yes">v-once</a></li><li class="sidebar-sub-header"><a href="/api/directives.html#v-is" class="sidebar-link" one-link-mark="yes">v-is</a></li></ul></li><li><a href="/api/special-attributes.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">特殊指令</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/special-attributes.html#key" class="sidebar-link" one-link-mark="yes">key</a></li><li class="sidebar-sub-header"><a href="/api/special-attributes.html#ref" class="sidebar-link" one-link-mark="yes">ref</a></li><li class="sidebar-sub-header"><a href="/api/special-attributes.html#is" class="sidebar-link" one-link-mark="yes">is</a></li></ul></li><li><a href="/api/built-in-components.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">内置组件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/built-in-components.html#component" class="sidebar-link" one-link-mark="yes">component</a></li><li class="sidebar-sub-header"><a href="/api/built-in-components.html#transition" class="sidebar-link" one-link-mark="yes">transition</a></li><li class="sidebar-sub-header"><a href="/api/built-in-components.html#transition-group" class="sidebar-link" one-link-mark="yes">transition-group</a></li><li class="sidebar-sub-header"><a href="/api/built-in-components.html#keep-alive" class="sidebar-link" one-link-mark="yes">keep-alive</a></li><li class="sidebar-sub-header"><a href="/api/built-in-components.html#slot" class="sidebar-link" one-link-mark="yes">slot</a></li><li class="sidebar-sub-header"><a href="/api/built-in-components.html#teleport" class="sidebar-link" one-link-mark="yes">teleport</a></li></ul></li><li><a href="/api/reactivity-api.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">响应性 API</a><ul class="sidebar-sub-headers"><li><a href="/api/basic-reactivity.html" class="sidebar-link" one-link-mark="yes">响应性基础 API</a></li><li><a href="/api/refs-api.html" class="sidebar-link" one-link-mark="yes">Refs</a></li><li><a href="/api/computed-watch-api.html" class="sidebar-link" one-link-mark="yes">Computed 与 watch</a></li></ul></li><li><a href="/api/composition-api.html" class="active sidebar-link" one-link-mark="yes" aria-current="page">组合式 API</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/api/composition-api.html#setup" class="sidebar-link" one-link-mark="yes">setup</a></li><li class="sidebar-sub-header"><a href="/api/composition-api.html#生命周期钩子" class="sidebar-link" one-link-mark="yes">生命周期钩子</a></li><li class="sidebar-sub-header"><a href="/api/composition-api.html#provide-inject" class="sidebar-link" one-link-mark="yes">Provide / Inject</a></li><li class="sidebar-sub-header"><a href="/api/composition-api.html#getcurrentinstance" class="sidebar-link" one-link-mark="yes">getCurrentInstance</a></li></ul></li></ul>');
  82. }
  83.  
  84. // #region MENU
  85. /** 生成 Menu */
  86. function initialMenu(clone) {
  87. // Wrapper
  88. wrapperEle = document.createElement("section");
  89. wrapperEle.classList.add("hs-dashboard__wrapper", "hs-hide");
  90.  
  91. if (customStyleEnable) {
  92. wrapperEle.setAttribute("id", "hs-dashboard");
  93. }
  94.  
  95. // Header
  96. const headerEle = document.createElement("header");
  97. headerEle.classList.add("hs-dashboard__header");
  98.  
  99. // Title → Header
  100. const titleEle = document.createElement("h1");
  101. titleEle.classList.add("hs-dashboard__title");
  102. titleEle.innerText = titleText || "";
  103. headerEle.appendChild(titleEle);
  104.  
  105. // Theme → Header
  106. if (customStyleEnable) {
  107. const themeEle = document.createElement("div");
  108. themeEle.classList.add("hs-theme-switch");
  109. themeEle.innerHTML = initialThemeTpl();
  110. headerEle.appendChild(themeEle);
  111. }
  112.  
  113. // Menu
  114. const containerEle = document.createElement("div");
  115. containerEle.classList.add("hs-dashboard__container");
  116.  
  117. // 1. 先从页面上获取 DOM 生成 gird
  118. let gridEle = null;
  119. let nodeTemp = null;
  120.  
  121. if (girdIsList) {
  122. gridEle = document.createElement("div");
  123. const gridListEle = document.querySelectorAll(gridSelector);
  124. gridListEle &&
  125. gridListEle.forEach((element) => {
  126. nodeTemp = clone ? element.cloneNode(true) : element;
  127. gridEle.appendChild(nodeTemp);
  128. });
  129. } else {
  130. nodeTemp = document.querySelector(gridSelector);
  131. gridEle = clone ? nodeTemp.cloneNode(true) : nodeTemp;
  132. gridEle && nodeTemp.removeAttribute("id");
  133. }
  134.  
  135. gridEle.classList.add("hs-dashboard__grid"); // 追加新的样式
  136.  
  137. // Menu → Container
  138. containerEle.appendChild(gridEle);
  139.  
  140. // 2. 内部元素追加新的样式
  141. // 2.1 column
  142. const columnEle = containerEle.querySelectorAll(columnSelector);
  143. columnEle.forEach((element) => {
  144. element.classList.add("hs-dashboard__column");
  145. });
  146.  
  147. // 2.2 title
  148. const columnTitleEle = containerEle.querySelectorAll(columnTitleSelector);
  149. columnTitleEle.forEach((element) => {
  150. element.classList.add("hs-dashboard__title");
  151. });
  152.  
  153. // 2.3 menu list
  154. const menuListEle = containerEle.querySelectorAll(menuListSelector);
  155. menuListEle.forEach((element) => {
  156. element.classList.add("hs-dashboard__list");
  157. });
  158.  
  159. // 2.4 menu item
  160. const menuItemEle = containerEle.querySelectorAll(menuItemSelector);
  161. menuItemEle.forEach((element) => {
  162. element.classList.add("hs-dashboard__item");
  163. });
  164.  
  165. // 2.5 menu item action
  166. if (menuItemActionSelector) {
  167. const actionEle = containerEle.querySelector(menuItemActionSelector);
  168. const menuItemTemp = getParents(actionEle, menuItemSelector);
  169. menuItemTemp.classList.add("hs-active");
  170. }
  171.  
  172. if (compactColumnEnable) {
  173. const { columns, layout } = compactColumn(containerEle, compactColumnLimit);
  174.  
  175. const ul = document.createElement("ul");
  176. ul.classList.add("hs-dashboard__grid");
  177.  
  178. Array.isArray(layout) &&
  179. layout.forEach((item) => {
  180. const li = document.createElement("li");
  181. li.classList.add("hs-dashboard__column");
  182.  
  183. if (Array.isArray(item)) {
  184. item.forEach((index) => {
  185. const columnItem = columns[index];
  186. const title = columnItem.querySelector(".hs-dashboard__title");
  187. const list = columnItem.querySelector(".hs-dashboard__list");
  188. title && li.appendChild(title);
  189. list && li.appendChild(list);
  190. });
  191. } else {
  192. const columnItem = columns[item];
  193. const title = columnItem.querySelector(".hs-dashboard__title");
  194. const list = columnItem.querySelector(".hs-dashboard__list");
  195. title && li.appendChild(title);
  196. list && li.appendChild(list);
  197. }
  198.  
  199. ul.appendChild(li);
  200. });
  201.  
  202. containerEle.removeChild(gridEle);
  203. containerEle.appendChild(ul);
  204. }
  205.  
  206. // header,container → wrapper
  207. wrapperEle.appendChild(headerEle);
  208. wrapperEle.appendChild(containerEle);
  209.  
  210. // wrapper → body
  211. bodyContainer.appendChild(wrapperEle);
  212. }
  213.  
  214. function compactColumn(containerEle, limit) {
  215. // 只能按列去查,有的列里面是没有 list 的
  216. let columns = containerEle.querySelectorAll(".hs-dashboard__column");
  217. let columnCount = []; // 相邻的数相加不超过指定值,就合并到一个新数组,将组成新的 column
  218. let layout = []; // 计算出来的新的数据布局方式
  219.  
  220. if (columns && columns.length) {
  221. columns.forEach((element) => {
  222. const listItem = element.querySelectorAll(".hs-dashboard__item");
  223. columnCount.push(listItem.length);
  224. });
  225.  
  226. /**
  227. * DESIGN NOTES
  228. *
  229. * 相邻的数相加
  230. *
  231. * 1. 将相邻的坐标存放在 arr
  232. * 2. 计算 arr 中坐标的数据量是否超过指定值
  233. * 3. 没超过,继续往 arr 推坐标
  234. * 4. 原先没超过,新的一进来就超过了,说明原先的已经到了阈值,原先的可以合并了推到布局中,但新的要记录下来,参与下一轮计算
  235. * 5. 下一个本身已经超过了阈值,看原先是否有参与计算的,然后各自推到布局中
  236. */
  237.  
  238. limit = limit || 12;
  239.  
  240. let arr = []; // 待合并的对象
  241. let acc = 0; // 累加判断是否临界
  242. const length = columnCount.length; // 是否到最后
  243.  
  244. columnCount.forEach((item, index) => {
  245. // 1. 新的值临界
  246. if (item > limit) {
  247. // 原先的是一个待合并的集合,还是只是一个单独的值
  248. if (arr.length > 1) {
  249. layout.push(arr);
  250. } else if (arr.length === 1) {
  251. layout.push(arr[0]);
  252. }
  253.  
  254. layout.push(index);
  255.  
  256. arr = [];
  257. acc = 0;
  258. } else {
  259. // 计算总的数据量
  260. acc += item;
  261.  
  262. // 总数据量临界
  263. if (acc > limit) {
  264. if (arr.length) {
  265. if (arr.length > 1) {
  266. layout.push(arr);
  267. } else {
  268. layout.push(arr[0]);
  269. }
  270. }
  271.  
  272. // 新的值参与下一次计算
  273. arr = [index];
  274. acc = item;
  275. } else {
  276. // 新的值没有临界
  277. arr.push(index);
  278. }
  279. }
  280.  
  281. if (index === length - 1 && arr.length) {
  282. layout.push(arr);
  283. }
  284. });
  285. }
  286.  
  287. return { columns, layout };
  288. }
  289. // #endregion MENU
  290.  
  291. // #region Event
  292. /** 注册(不可用)事件 */
  293. function handleEvent() {
  294. if (!wrapperEle) {
  295. wrapperEle = document.querySelector(".hs-dashboard__wrapper");
  296. }
  297.  
  298. if (!themeSwitchEle) {
  299. themeSwitchEle = document.querySelector(".hs-theme-switch");
  300. }
  301.  
  302. if (!themeSwitchForm) {
  303. themeSwitchForm = document.querySelector(".hs-theme-switch__form-control");
  304. }
  305.  
  306. bodyContainer.addEventListener("click", (event) => {
  307. const targetEle = event.target;
  308.  
  309. const itemEle = getParents(targetEle, ".hs-dashboard__item");
  310.  
  311. const isItem = hasClass(targetEle, "hs-dashboard__item");
  312.  
  313. const isItemWrapper = getParents(targetEle, ".hs-dashboard__column") && getParents(targetEle, ".hs-dashboard__list");
  314.  
  315. const isToggle = getParents(targetEle, ".hs-dashboard__toggle-menu") || hasClass(targetEle, "hs-dashboard__toggle-menu");
  316.  
  317. const isHelp = getParents(targetEle, ".hs-dashboard__toggle-help") || hasClass(targetEle, "hs-dashboard__toggle-help");
  318.  
  319. const isTheme = getParents(targetEle, ".hs-theme-switch") || hasClass(targetEle, "hs-theme-switch");
  320.  
  321. if (itemEle || isItem || isItemWrapper) {
  322. window.setTimeout(() => {
  323. clearStyle(wrapperEle);
  324. }, 300);
  325.  
  326. handleItemClick(itemEle, isItem, targetEle);
  327. } else if (isToggle) {
  328. wrapperEle.classList.toggle("hs-hide");
  329. bodyContainer.classList.toggle("hs-body-overflow_hide");
  330. } else if (isHelp) {
  331. clearStyle(wrapperEle);
  332. handleHelp();
  333. } else if (isTheme) {
  334. handleTheme();
  335. }
  336. });
  337. }
  338.  
  339. /** 导航点击 */
  340. function handleItemClick(itemEle, isItem, targetEle) {
  341. let itemTemp = null;
  342.  
  343. if (itemEle) {
  344. itemTemp = itemEle;
  345. } else if (isItem) {
  346. itemTemp = targetEle;
  347. }
  348.  
  349. if (itemTemp) {
  350. const items = wrapperEle.querySelectorAll(".hs-dashboard__item");
  351. items.forEach((element) => {
  352. element.classList.remove("hs-active");
  353. element.querySelector("a").classList.remove("active");
  354. });
  355. itemTemp.classList.add("hs-active");
  356. }
  357. }
  358.  
  359. /** 退出预览 */
  360. function clearStyle(wrapperEle) {
  361. wrapperEle.classList.add("hs-hide");
  362. bodyContainer.classList.remove("hs-body-overflow_hide");
  363. }
  364. // #endregion Event
  365.  
  366. // #region HELP
  367. /** 是否启用‘页面滚动至指定位置’ */
  368. function initialHelp() {
  369. if (!helpEnable) {
  370. const ele = document.querySelector(".hs-dashboard__toggle-help");
  371. ele.classList.add("hs-hide");
  372. }
  373. }
  374.  
  375. /** 页面滚动至指定位置 */
  376. function handleHelp() {
  377. if (!helpSelector) {
  378. return false;
  379. }
  380.  
  381. const helpEle = document.querySelector(helpSelector);
  382. const top = helpEle.getBoundingClientRect().top + window.pageYOffset;
  383.  
  384. window.scrollTo({
  385. top,
  386. behavior: "smooth",
  387. });
  388. }
  389. // #endregion HELP
  390.  
  391. // #region STYLE
  392. /** 添加样式 */
  393. function initialStyle(param) {
  394. let tpl = initialStyleTpl();
  395. const headEle = document.head || document.getElementsByTagName("head")[0];
  396. const styleEle = document.createElement("style");
  397.  
  398. let str = null;
  399.  
  400. if (typeof param === "function") {
  401. str = param();
  402. } else if (typeof param === "string") {
  403. str = param;
  404. }
  405.  
  406. if (typeof str === "string") {
  407. tpl += str;
  408. }
  409.  
  410. styleEle.type = "text/css";
  411.  
  412. if (styleEle.styleSheet) {
  413. styleEle.styleSheet.cssText = tpl;
  414. } else {
  415. styleEle.appendChild(document.createTextNode(tpl));
  416. }
  417.  
  418. headEle.appendChild(styleEle);
  419. }
  420.  
  421. /** 样式表 */
  422. function initialStyleTpl() {
  423. return `
  424.  
  425. :root {
  426. --item-height: 36px;
  427. --hs-font-size-base: 15px;
  428. --hs-global-spacing: 1rem;
  429. --hs-color-primary: #1890ff;
  430. --hs-spacing-horizontal: var(--hs-global-spacing);
  431.  
  432. --hs-color-white: #fff;
  433. --hs-color-black: #000;
  434. --hs-color-gray-0: var(--hs-color-white);
  435. --hs-color-gray-100: #f5f6f7;
  436. --hs-color-gray-200: #ebedf0;
  437. --hs-color-gray-300: #dadde1;
  438. --hs-color-gray-400: #ccd0d5;
  439. --hs-color-gray-500: #bec3c9;
  440. --hs-color-gray-600: #8d949e;
  441. --hs-color-gray-700: #606770;
  442. --hs-color-gray-800: #444950;
  443. --hs-color-gray-900: #1c1e21;
  444. --hs-color-gray-1000: var(--hs-color-black);
  445. --hs-color-emphasis-0: var(--hs-color-gray-0);
  446. --hs-color-emphasis-100: var(--hs-color-gray-100);
  447. --hs-color-emphasis-200: var(--hs-color-gray-200);
  448. --hs-color-emphasis-300: var(--hs-color-gray-300);
  449. --hs-color-emphasis-400: var(--hs-color-gray-400);
  450. --hs-color-emphasis-500: var(--hs-color-gray-500);
  451. --hs-color-emphasis-600: var(--hs-color-gray-600);
  452. --hs-color-emphasis-700: var(--hs-color-gray-700);
  453. --hs-color-emphasis-800: var(--hs-color-gray-800);
  454. --hs-color-emphasis-900: var(--hs-color-gray-900);
  455. --hs-color-emphasis-1000: var(--hs-color-gray-1000);
  456. }
  457. .hs-hide {
  458. display: none !important;
  459. }
  460.  
  461. .hs-body-overflow_hide {
  462. height: 100% !important;
  463. overflow: hidden !important;
  464. }
  465.  
  466. /* #region toggle */
  467. .hs-dashboard__toggle {
  468. position: fixed;
  469. z-index: 99999;
  470. top: 15px;
  471. right: 5px;
  472. }
  473.  
  474. .hs-dashboard__toggle-item {
  475. position: relative;
  476. width: 28px;
  477. height: 28px;
  478. margin-top: 10px;
  479. margin-bottom: 10px;
  480. overflow: hidden;
  481. line-height: 1 !important;
  482. border-radius: 50%;
  483. border: 1px solid #ccc;
  484. text-align: center;
  485. color: #555;
  486. background-color: #fff;
  487. cursor: pointer;
  488. transition: all 0.2s;
  489. }
  490.  
  491. .hs-dashboard__toggle-item:hover {
  492. border-color: #aaa;
  493. color: #111;
  494. }
  495.  
  496. .hs-dashboard__toggle-icon svg{
  497. position: absolute;
  498. top: 50%;
  499. left: 50%;
  500. z-index: 9;
  501. transform: translate(-50%, -50%);
  502. font-style: normal !important;
  503. }
  504. /* #endregion toggle */
  505.  
  506. /* #region wrapper */
  507. .hs-dashboard__wrapper {
  508. position: fixed;
  509. top: 0;
  510. right: 0;
  511. bottom: 0;
  512. left: 0;
  513. z-index: 99998;
  514. overflow-y: auto;
  515. background-color: #fff;
  516. font-size: var(--hs-font-size-base);
  517. }
  518.  
  519. .hs-dashboard__wrapper::-webkit-scrollbar {
  520. width: 8px;
  521. height: 6px;
  522. background: rgba(0, 0, 0, 0.1);
  523. }
  524.  
  525. .hs-dashboard__wrapper::-webkit-scrollbar-thumb {
  526. background: rgba(0, 0, 0, 0.3);
  527. }
  528.  
  529. .hs-dashboard__wrapper::-webkit-scrollbar-track {
  530. background: rgba(0, 0, 0, 0.1);
  531. }
  532. /* #endregion wrapper */
  533.  
  534. .hs-dashboard__header {
  535. position: relative;
  536. padding-top: 10px;
  537. text-align: center;
  538. }
  539.  
  540. .hs-dashboard__header .hs-dashboard__title {
  541. margin: 0;
  542. padding-top: 10px;
  543. padding-bottom: 10px;
  544. font-size: 1em;
  545. font-weight: normal;
  546. }
  547.  
  548. /* #region theme */
  549. .hs-theme-switch {
  550. display: flex;
  551. touch-action: pan-x;
  552. position: relative;
  553. background-color: #fff;
  554. border: 0;
  555. margin: 0;
  556. padding: 0;
  557. user-select: none;
  558. -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  559. -webkit-tap-highlight-color: transparent;
  560. cursor: pointer;
  561. }
  562.  
  563. .hs-theme-switch {
  564. width: 50px;
  565. height: 24px;
  566. padding: 0;
  567. border-radius: 30px;
  568. background-color: #4d4d4d;
  569. transition: all 0.2s ease;
  570. }
  571.  
  572. .hs-dashboard__header .hs-theme-switch {
  573. position: absolute;
  574. top: 10px;
  575. left: 10px;
  576. }
  577.  
  578. .hs-theme-switch__style {
  579. position: relative;
  580. width: 24px;
  581. height: 24px;
  582. line-height: 1;
  583. font-size: 20px;
  584. text-align: center;
  585. }
  586.  
  587. .hs-theme-switch__icon svg {
  588. position: absolute;
  589. top: 50%;
  590. left: 50%;
  591. transform: translate(-50%, -50%);
  592. }
  593.  
  594. .hs-theme-switch__thumb {
  595. position: absolute;
  596. top: 1px;
  597. left: 1px;
  598. width: 22px;
  599. height: 22px;
  600. border: 1px solid #ff7938;
  601. border-radius: 50%;
  602. background-color: #fafafa;
  603. box-sizing: border-box;
  604. transition: all 0.25s ease;
  605. }
  606.  
  607. .hs-theme-switch_checked .hs-theme-switch__thumb {
  608. left: 27px;
  609. border-color: #4d4d4d;
  610. }
  611.  
  612. .hs-toggle-screenreader-only {
  613. border: 0;
  614. clip: rect(0 0 0 0);
  615. height: 1px;
  616. margin: -1px;
  617. overflow: hidden;
  618. padding: 0;
  619. position: absolute;
  620. width: 1px;
  621. }
  622. /* #endregion theme */
  623.  
  624. /* #region grid */
  625. .hs-dashboard__grid {
  626. display: flex;
  627. justify-content: space-around;
  628. margin: 0;
  629. padding: 0 40px;
  630. list-style: none;
  631. }
  632.  
  633. .hs-dashboard__column {
  634. padding-right: 10px;
  635. padding-left: 10px;
  636. }
  637.  
  638. .hs-dashboard__column a {
  639. display: block;
  640. padding-left: 20px !important;
  641. padding-right: 40px !important;
  642. text-decoration: none;
  643. }
  644.  
  645. .hs-dashboard__container ul:not(.hs-dashboard__grid) {
  646. padding: 0;
  647. }
  648.  
  649. .hs-dashboard__container li {
  650. padding-left: 0 !important;
  651. list-style: none;
  652. }
  653.  
  654. .hs-dashboard__column .hs-dashboard__title {
  655. display: block;
  656. padding-left: var(--hs-spacing-horizontal) !important;
  657. padding-right: calc(var(--hs-spacing-horizontal) * 2) !important;
  658. text-align: left;
  659. margin-top: 10px !important;
  660. }
  661.  
  662. .hs-dashboard__column .hs-dashboard__list {
  663. margin-top: 10px !important;
  664. }
  665.  
  666. .hs-dashboard__column .hs-dashboard__list+.hs-dashboard__title {
  667. margin-top: var(--hs-global-spacing);
  668. padding-top: var(--hs-global-spacing);
  669. }
  670.  
  671. .hs-dashboard__column .hs-dashboard__list .hs-dashboard__item {
  672. margin: 0 !important;
  673. padding-left: 0 !important;
  674. padding-right: 0 !important;
  675. height: var(--item-height);
  676. line-height: var(--item-height);
  677. }
  678. /* #endregion grid */
  679.  
  680. /* #region custom */
  681. #hs-dashboard.hs-dashboard__wrapper {
  682. transition: all 0.2s ease;
  683. }
  684.  
  685. #hs-dashboard .hs-dashboard__column .hs-dashboard__title {
  686. font-size: 14px;
  687. line-height: 1.5715;
  688. color: rgba(0, 0, 0, 0.45);
  689. }
  690.  
  691. #hs-dashboard a {
  692. overflow: hidden;
  693. white-space: nowrap;
  694. font-size: 14px;
  695. text-overflow: ellipsis;
  696. text-decoration: none;
  697. color: rgba(0, 0, 0, 0.85);
  698. transition: color 0.3s ease;
  699. }
  700.  
  701. #hs-dashboard a:hover {
  702. color: var(--hs-color-primary);
  703. text-decoration: none;
  704. outline: 0;
  705. }
  706.  
  707. /* light */
  708. #hs-dashboard.hs-dashboard__wrapper_light {
  709. color: #161616;
  710. background-color: #fff;
  711. }
  712.  
  713. #hs-dashboard.hs-dashboard__wrapper_light .hs-dashboard__list+.hs-dashboard__title {
  714. border-top: 1px solid var(--hs-color-gray-300);
  715. }
  716.  
  717. /* dark */
  718. #hs-dashboard.hs-dashboard__wrapper_dark {
  719. color: #fff;
  720. background-color: #161616;
  721. }
  722.  
  723. #hs-dashboard.hs-dashboard__wrapper_dark .hs-dashboard__list+.hs-dashboard__title {
  724. border-top: 1px solid var(--hs-color-gray-600);
  725. }
  726.  
  727. #hs-dashboard.hs-dashboard__wrapper_dark .hs-dashboard__title {
  728. font-weight: bold;
  729. color: #fff;
  730. }
  731.  
  732. #hs-dashboard.hs-dashboard__wrapper_dark a {
  733. color: #fff;
  734. }
  735.  
  736. #hs-dashboard.hs-dashboard__wrapper_dark a:hover {
  737. color: var(--hs-color-primary);
  738. }
  739.  
  740. #hs-dashboard .hs-dashboard__item.active,
  741. #hs-dashboard .hs-dashboard__item.active a,
  742. #hs-dashboard .hs-dashboard__item .active,
  743. #hs-dashboard .hs-dashboard__item.hs-active,
  744. #hs-dashboard .hs-dashboard__item.hs-active a {
  745. color: var(--hs-color-primary);
  746. }
  747.  
  748. #hs-dashboard .hs-dashboard__item.hs-active {
  749. background-color: #e6f7ff;
  750. }
  751.  
  752. #hs-dashboard .hs-dashboard__item {
  753. position: relative;
  754. }
  755.  
  756. #hs-dashboard .hs-dashboard__item::after {
  757. content: ' ';
  758. position: absolute;
  759. top: 0;
  760. right: 0;
  761. bottom: 0;
  762. border-right: 3px solid var(--hs-color-primary);
  763. transform: scaleY(0.0001);
  764. transition: transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1),
  765. opacity 0.15s cubic-bezier(0.215, 0.61, 0.355, 1),
  766. -webkit-transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
  767. opacity: 0;
  768. }
  769.  
  770. #hs-dashboard .hs-dashboard__item.hs-active::after {
  771. transform: scaleY(1);
  772. opacity: 1;
  773. transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
  774. opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
  775. -webkit-transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
  776. }
  777. /* #endregion custom */
  778.  
  779. `;
  780. }
  781. // #endregion STYLE
  782.  
  783. // #region TOGGLE
  784. /** 生成 Dashboard 开关 */
  785. function initialToggle() {
  786. const tpl = initialToggleTpl();
  787. const ele = document.createElement("section");
  788. // ele.className = 'hs-dashboard__toggle';
  789. // ele.setAttribute("class", "hs-dashboard__toggle");
  790. ele.classList.add("hs-dashboard__toggle");
  791. ele.innerHTML = tpl;
  792.  
  793. // toggle → body
  794. bodyContainer.appendChild(ele);
  795. }
  796. /** Dashboard 开关 DOM */
  797. function initialToggleTpl() {
  798. return `
  799. <!-- menu -->
  800. <div class="hs-dashboard__toggle-item hs-dashboard__toggle-menu">
  801. <i class="hs-dashboard__toggle-icon">
  802. <svg
  803. viewBox="64 64 896 896"
  804. focusable="false"
  805. data-icon="appstore"
  806. width="1em"
  807. height="1em"
  808. fill="currentColor"
  809. aria-hidden="true"
  810. >
  811. <path
  812. d="M464 144H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H212V212h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H612V212h200v200zM464 544H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H212V612h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H612V612h200v200z"
  813. ></path>
  814. </svg>
  815. </i>
  816. </div>
  817. <!-- api -->
  818. <div class="hs-dashboard__toggle-item hs-dashboard__toggle-help">
  819. <i class="hs-dashboard__toggle-icon">
  820. <svg
  821. viewBox="64 64 896 896"
  822. focusable="false"
  823. class=""
  824. data-icon="bulb"
  825. width="1em"
  826. height="1em"
  827. fill="currentColor"
  828. aria-hidden="true"
  829. >
  830. <path
  831. d="M632 888H392c-4.4 0-8 3.6-8 8v32c0 17.7 14.3 32 32 32h192c17.7 0 32-14.3 32-32v-32c0-4.4-3.6-8-8-8zM512 64c-181.1 0-328 146.9-328 328 0 121.4 66 227.4 164 284.1V792c0 17.7 14.3 32 32 32h264c17.7 0 32-14.3 32-32V676.1c98-56.7 164-162.7 164-284.1 0-181.1-146.9-328-328-328zm127.9 549.8L604 634.6V752H420V634.6l-35.9-20.8C305.4 568.3 256 484.5 256 392c0-141.4 114.6-256 256-256s256 114.6 256 256c0 92.5-49.4 176.3-128.1 221.8z"
  832. ></path>
  833. </svg>
  834. </i>
  835. </div>
  836. `;
  837. }
  838. // #endregion TOGGLE
  839.  
  840. // #region THEME
  841. function handleTheme(isInit) {
  842. if (isInit) {
  843. const theme = localStorage.getItem("hs_dashboard_theme");
  844.  
  845. if (theme && theme === "dark") {
  846. themeSwitchForm.checked = true;
  847. } else {
  848. themeSwitchForm.checked = false;
  849. }
  850. } else {
  851. themeSwitchForm.click();
  852. }
  853.  
  854. const checked = themeSwitchForm.checked;
  855.  
  856. if (checked) {
  857. localStorage.setItem("hs_dashboard_theme", "dark");
  858. wrapperEle.classList.add("hs-dashboard__wrapper_dark");
  859. wrapperEle.classList.remove("hs-dashboard__wrapper_light");
  860. themeSwitchEle.classList.add("hs-theme-switch_checked");
  861. } else {
  862. localStorage.setItem("hs_dashboard_theme", "light");
  863. wrapperEle.classList.add("hs-dashboard__wrapper_light");
  864. wrapperEle.classList.remove("hs-dashboard__wrapper_dark");
  865. themeSwitchEle.classList.remove("hs-theme-switch_checked");
  866. }
  867. }
  868.  
  869. function initialThemeTpl() {
  870. return `
  871. <input type="checkbox" class="hs-toggle-screenreader-only hs-theme-switch__form-control" title="Dark mode" />
  872. <div class="hs-theme-switch__style hs-theme-switch__style_dark">
  873. <i class="hs-theme-switch__icon">
  874. <svg
  875. t="1588325093630"
  876. class="icon"
  877. viewBox="0 0 1024 1024"
  878. version="1.1"
  879. xmlns="http://www.w3.org/2000/svg"
  880. p-id="11008"
  881. width="1em"
  882. height="1em"
  883. >
  884. <path
  885. d="M483.555556 964.266667c-164.977778 0-315.733333-85.333333-398.222223-224.711111 19.911111 2.844444 39.822222 2.844444 56.888889 2.844444 275.911111 0 500.622222-224.711111 500.622222-500.622222 0-68.266667-14.222222-133.688889-39.822222-193.422222 201.955556 54.044444 347.022222 238.933333 347.022222 449.422222 0 256-210.488889 466.488889-466.488888 466.488889z"
  886. fill="#F7FF53"
  887. p-id="11009"
  888. ></path>
  889. <path
  890. d="M631.466667 73.955556c179.2 62.577778 301.511111 230.4 301.511111 423.822222 0 247.466667-201.955556 449.422222-449.422222 449.422222-147.911111 0-281.6-71.111111-364.088889-187.733333H142.222222c284.444444 0 517.688889-233.244444 517.688889-517.688889 0-56.888889-8.533333-113.777778-28.444444-167.822222M571.733333 22.755556C605.866667 88.177778 625.777778 162.133333 625.777778 241.777778c0 267.377778-216.177778 483.555556-483.555556 483.555555-31.288889 0-59.733333-2.844444-88.177778-8.533333 79.644444 156.444444 241.777778 264.533333 429.511112 264.533333 267.377778 0 483.555556-216.177778 483.555555-483.555555C967.111111 261.688889 796.444444 65.422222 571.733333 22.755556z"
  891. fill="#303133"
  892. p-id="11010"
  893. ></path>
  894. <path
  895. d="M787.911111 455.111111c-5.688889-2.844444-8.533333-8.533333-5.688889-14.222222 5.688889-17.066667-2.844444-42.666667-19.911111-48.355556-17.066667-5.688889-39.822222 8.533333-45.511111 22.755556-2.844444 5.688889-8.533333 8.533333-14.222222 5.688889-5.688889-2.844444-8.533333-8.533333-5.688889-14.222222 8.533333-25.6 42.666667-45.511111 73.955555-34.133334 28.444444 11.377778 39.822222 48.355556 31.288889 73.955556-2.844444 5.688889-8.533333 8.533333-14.222222 8.533333"
  896. fill="#303133"
  897. p-id="11011"
  898. ></path>
  899. <path
  900. d="M608.711111 620.088889c-14.222222 0-28.444444-2.844444-39.822222-11.377778-31.288889-22.755556-31.288889-65.422222-31.288889-68.266667 0-8.533333 8.533333-17.066667 17.066667-17.066666s17.066667 8.533333 17.066666 17.066666 2.844444 31.288889 17.066667 39.822223c11.377778 8.533333 25.6 8.533333 45.511111 0 8.533333-2.844444 19.911111 2.844444 22.755556 11.377777 2.844444 8.533333-2.844444 19.911111-11.377778 22.755556-14.222222 2.844444-25.6 5.688889-36.977778 5.688889zM571.733333 540.444444z"
  901. fill="#FF2929"
  902. p-id="11012"
  903. ></path>
  904. <path
  905. d="M810.666667 588.8c-5.688889 19.911111-36.977778 28.444444-68.266667 19.911111-31.288889-8.533333-54.044444-34.133333-48.355556-54.044444 5.688889-19.911111 36.977778-28.444444 68.266667-19.911111 34.133333 11.377778 54.044444 34.133333 48.355556 54.044444"
  906. fill="#FFA450"
  907. p-id="11013"
  908. ></path>
  909. <path
  910. d="M864.711111 270.222222c14.222222 42.666667 19.911111 91.022222 19.911111 136.533334 0 258.844444-213.333333 466.488889-477.866666 466.488888-96.711111 0-187.733333-28.444444-264.533334-76.8 82.488889 93.866667 204.8 156.444444 344.177778 156.444445C736.711111 952.888889 938.666667 756.622222 938.666667 512c0-88.177778-28.444444-173.511111-73.955556-241.777778z"
  911. fill="#FF7938"
  912. p-id="11014"
  913. ></path>
  914. </svg>
  915. </i>
  916. </div>
  917. <div class="hs-theme-switch__style hs-theme-switch__style_light">
  918. <i class="hs-theme-switch__icon">
  919. <svg
  920. t="1588324703446"
  921. class="icon"
  922. viewBox="0 0 1024 1024"
  923. version="1.1"
  924. xmlns="http://www.w3.org/2000/svg"
  925. p-id="6232"
  926. width="1em"
  927. height="1em"
  928. >
  929. <path
  930. d="M792.35 835.94l-128.09-30.32c-17.73-4.2-36.12 3.66-45.34 19.37l-66.64 113.52c-15.83 26.97-54.67 27.4-71.1 0.79l-69.14-112.02c-9.57-15.5-28.13-22.95-45.76-18.36l-127.39 33.15c-30.26 7.88-58.03-19.29-50.83-49.72l30.32-128.09c4.2-17.73-3.66-36.12-19.37-45.34L85.49 552.28c-26.97-15.83-27.4-54.67-0.79-71.1l112.02-69.14c15.5-9.57 22.95-28.13 18.36-45.76l-33.15-127.39c-7.88-30.26 19.29-58.03 49.72-50.83l128.09 30.32c17.73 4.2 36.12-3.66 45.34-19.37l66.64-113.52c15.83-26.97 54.67-27.4 71.1-0.79l69.14 112.02c9.57 15.5 28.13 22.95 45.76 18.36l127.39-33.15c30.26-7.88 58.03 19.29 50.83 49.72l-30.32 128.09c-4.2 17.73 3.66 36.12 19.37 45.34l113.52 66.64c26.97 15.83 27.4 54.67 0.79 71.1l-112.02 69.14c-15.5 9.57-22.95 28.13-18.36 45.76l33.15 127.39c7.88 30.26-19.29 58.03-49.72 50.83z"
  931. fill="#FF7938"
  932. p-id="6233"
  933. ></path>
  934. <path
  935. d="M512 512m-207.66 0a207.66 207.66 0 1 0 415.32 0 207.66 207.66 0 1 0-415.32 0Z"
  936. fill="#F7FF53"
  937. p-id="6234"
  938. ></path>
  939. <path
  940. d="M442.78 468.74m-25.96 0a25.96 25.96 0 1 0 51.92 0 25.96 25.96 0 1 0-51.92 0Z"
  941. fill="#303133"
  942. p-id="6235"
  943. ></path>
  944. <path
  945. d="M581.22 468.74m-25.96 0a25.96 25.96 0 1 0 51.92 0 25.96 25.96 0 1 0-51.92 0Z"
  946. fill="#303133"
  947. p-id="6236"
  948. ></path>
  949. <path
  950. d="M442.78 582.02s17.31 48.31 69.22 48.31 69.22-48.31 69.22-48.31H442.78z"
  951. fill="#FF2929"
  952. p-id="6237"
  953. ></path>
  954. </svg>
  955. </i>
  956. </div>
  957. <div class="hs-theme-switch__thumb"></div>
  958. `;
  959. }
  960. // #endregion THEME
  961.  
  962. // #region COMMON
  963. function hasClass(el, className) {
  964. if (el.classList) {
  965. return el.classList.contains(className);
  966. } else {
  967. return !!el.className.match(new RegExp("(\\s|^)" + className + "(\\s|$)"));
  968. }
  969. }
  970.  
  971. function getParents(elem, selector) {
  972. // Element.matches() polyfill
  973. if (!Element.prototype.matches) {
  974. Element.prototype.matches =
  975. Element.prototype.matchesSelector ||
  976. Element.prototype.mozMatchesSelector ||
  977. Element.prototype.msMatchesSelector ||
  978. Element.prototype.oMatchesSelector ||
  979. Element.prototype.webkitMatchesSelector ||
  980. function(s) {
  981. var matches = (this.document || this.ownerDocument).querySelectorAll(s),
  982. i = matches.length;
  983. while (--i >= 0 && matches.item(i) !== this) {}
  984. return i > -1;
  985. };
  986. }
  987.  
  988. // Get the closest matching element
  989. for (; elem && elem !== document; elem = elem.parentNode) {
  990. if (elem.matches(selector)) return elem;
  991. }
  992. return null;
  993. }
  994.  
  995. function queryDirectChildren(parent, selector) {
  996. const nodes = parent.querySelectorAll(selector);
  997. const filteredNodes = [].slice.call(nodes).filter((item) => item.parentNode.closest(selector) === parent.closest(selector));
  998. return filteredNodes;
  999. }
  1000. // #endregion
  1001. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址