Swagger Tool DAWN

内部使用swagger-ui增强脚本,方便复制url为函数

当前为 2020-05-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Swagger Tool DAWN
  3. // @version 1.0.2
  4. // @description 内部使用swagger-ui增强脚本,方便复制url为函数
  5. // @author lixiang
  6. // @match http://*/swagger-ui.html*
  7. // @require https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.4/clipboard.min.js
  8.  
  9. // @grant GM_addStyle
  10. // @run-at document-end
  11. // @license MIT
  12. // @namespace https://greasyfork.org/users/559637
  13. // ==/UserScript==
  14. // https://developer.chrome.com/extensions/match_patterns
  15. (async function (open) {
  16. function splitLast (str) {
  17. const lastIndex = str.lastIndexOf('/')
  18. return str.slice(lastIndex + 1)
  19. }
  20. function highlight () {
  21. for (const codeblock of document.getElementsByTagName('code')) {
  22. hljs.highlightBlock(codeblock)
  23. }
  24. }
  25. function addOutCss (href) {
  26. var head = document.querySelector('head')
  27. var link = document.createElement('link')
  28. link.href = href + ''
  29. link.rel = 'stylesheet'
  30. link.type = 'text/css'
  31. head.appendChild(link)
  32. }
  33. function firstUpperCase (str) {
  34. return str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase())
  35. }
  36. function splitLastSecond (str) {
  37. const arr = str.split('/')
  38. return arr[arr.length - 2]
  39. }
  40. function toHump (str) {
  41. if (!str) { return }
  42. let newStr = ''
  43. let big = false
  44. for (const i in str) {
  45. let s = str[i]
  46. if (big) {
  47. s = s.toLocaleUpperCase()
  48. big = false
  49. }
  50. if (s === '_') { big = true } else newStr += s
  51. }
  52. return newStr
  53. }
  54. function getSelectValue () {
  55. const selectUrl = document.querySelector('#selectUrl')
  56. const index = selectUrl.selectedIndex // 序号,取当前选中选项的序号
  57. const select = selectUrl.options[index].value
  58. return select
  59. }
  60. function getUrlName (url) {
  61. const type = getSelectValue()
  62. let urlName = ''
  63. if (type === 'first') {
  64. urlName = toHump(splitLast(url))
  65. } else if (type === 'second') {
  66. const urlName2 = firstUpperCase(toHump(splitLast(url)))
  67. const urlName1 = toHump(splitLastSecond(url))
  68. urlName = urlName1 + urlName2
  69. }
  70. return urlName
  71. }
  72. function getPrefix () {
  73. return document.querySelector('#urlPrefix').value ? '/' + document.querySelector('#urlPrefix').value : ''
  74. }
  75. function setClipboardDisplay (e) {
  76. const text = e.text
  77. document.querySelector('#cliDisplaySpan').textContent = text
  78. highlight()
  79. e.clearSelection()
  80. }
  81. function addSheet (params) {
  82. GM_addStyle(
  83. `
  84. #cliDisplay .hljs {
  85. display: block !important;
  86. overflow-x: auto !important;
  87. padding: 0.5em !important;
  88. color: #abb2bf !important;
  89. background: #282c34 !important;
  90. }
  91.  
  92. #cliDisplay .hljs-comment,
  93. #cliDisplay .hljs-quote {
  94. color: #5c6370 !important;
  95. font-style: italic !important;
  96. }
  97.  
  98. #cliDisplay .hljs-doctag,
  99. #cliDisplay .hljs-keyword,
  100. #cliDisplay .hljs-formula {
  101. color: #c678dd !important;
  102. }
  103.  
  104. #cliDisplay .hljs-section,
  105. #cliDisplay .hljs-name,
  106. #cliDisplay .hljs-selector-tag,
  107. #cliDisplay .hljs-deletion,
  108. #cliDisplay .hljs-subst {
  109. color: #e06c75 !important;
  110. }
  111.  
  112. #cliDisplay .hljs-literal {
  113. color: #56b6c2 !important;
  114. }
  115.  
  116. #cliDisplay .hljs-string,
  117. #cliDisplay .hljs-regexp,
  118. #cliDisplay .hljs-addition,
  119. #cliDisplay .hljs-attribute,
  120. #cliDisplay .hljs-meta-string {
  121. color: #98c379 !important;
  122. }
  123.  
  124. #cliDisplay .hljs-built_in,
  125. #cliDisplay .hljs-class .hljs-title {
  126. color: #e6c07b !important;
  127. }
  128.  
  129. #cliDisplay .hljs-attr,
  130. #cliDisplay .hljs-variable,
  131. #cliDisplay .hljs-template-variable,
  132. #cliDisplay .hljs-type,
  133. #cliDisplay .hljs-selector-class,
  134. #cliDisplay .hljs-selector-attr,
  135. #cliDisplay .hljs-selector-pseudo,
  136. #cliDisplay .hljs-number {
  137. color: #d19a66 !important;
  138. }
  139.  
  140. #cliDisplay .hljs-symbol,
  141. #cliDisplay .hljs-bullet,
  142. #cliDisplay .hljs-link,
  143. #cliDisplay .hljs-meta,
  144. #cliDisplay .hljs-selector-id,
  145. #cliDisplay .hljs-title {
  146. color: #61aeee !important;
  147. }
  148.  
  149. #cliDisplay .hljs-emphasis {
  150. font-style: italic !important;
  151. }
  152.  
  153. #cliDisplay .hljs-strong {
  154. font-weight: bold !important;
  155. }
  156.  
  157. #cliDisplay .hljs-link {
  158. text-decoration: underline !important;
  159. }
  160.  
  161. `
  162. )
  163. GM_addStyle(
  164. `
  165. ::-webkit-scrollbar {
  166. width: 6px;
  167. height: 6px;
  168. }
  169. ::-webkit-scrollbar-track {
  170. border-radius: 3px;
  171. background: #c678dd57;
  172. -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.08);
  173. }
  174. ::-webkit-scrollbar-thumb {
  175. border-radius: 3px;
  176. background: rgba(0,0,0,0.12);
  177. -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.2);
  178. }
  179. .swagger-section #header {
  180. position:relative;
  181. }
  182. .search_wrapper {
  183. }
  184. .setting_card {
  185. position: absolute;
  186. background: #fff;
  187. border: 1px solid rgba(0,0,0,0.2);
  188. border-radius: 8px;
  189. box-shadow: 0 1px 2px 0 rgba(60,64,67,.30), 0 2px 6px 2px rgba(60,64,67,.15);
  190. overflow-x: hidden;
  191. padding-top: 0;
  192. height: 120px;
  193. width: 320px;
  194. right: 10px;
  195. top: 60px;
  196. padding: 10px 10px;
  197. visibility:hidden;
  198. z-index:1
  199. }
  200. .setting_item {
  201. padding: 5px 0;
  202. margin-bottom: 5px;
  203. border-bottom: 1px solid #f2f2f2;
  204. }
  205. .setting_icon {
  206. position:absolute;
  207. right:10px;
  208. top:10px;
  209. cursor: pointer;
  210. }
  211. .setting_icon:hover {
  212. animation: myRotate 3s linear infinite;
  213. }
  214. @keyframes myRotate{
  215. 0%{ -webkit-transform: rotate(0deg);}
  216. 50%{ -webkit-transform: rotate(180deg);}
  217. 100%{ -webkit-transform: rotate(360deg);}
  218. }
  219. .card {
  220. position: relative;
  221. background: #282c34 !important;
  222.  
  223. margin: 1rem 0;
  224. padding: 1em 1em;
  225. border-radius: 0.2rem;
  226. border:none !important;
  227. max-height: 150px;
  228. overflow: auto;
  229. }
  230. .card:hover {
  231. box-shadow:2px 2px 9px 0px #1e3b50;
  232. }
  233. .header-label {
  234. color:#666;
  235. width: 120px;
  236. display: inline-block;
  237. }
  238. select {
  239. border: 1px solid #ccc;
  240. padding: 7px 0px;
  241. border-radius: 3px;
  242. padding-left: 5px;
  243. -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  244. box-shadow: inset 0 1px 1px rgba(80, 69, 69, 0.075);
  245. -webkit-transition: border-color ease-in-out 0.15s,
  246. -webkit-box-shadow ease-in-out 0.15s;
  247. -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  248. transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  249. }
  250. option {
  251. height: 30px;
  252. padding: 5px 4px;
  253. }
  254. input {
  255. border: 1px solid #ccc;
  256. padding: 7px 0px;
  257. border-radius: 3px;
  258. padding-left: 5px;
  259. -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  260. box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  261. -webkit-transition: border-color ease-in-out 0.15s,
  262. -webkit-box-shadow ease-in-out 0.15s;
  263. -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  264. transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  265. }
  266. input:focus {
  267. border-color: #66afe9;
  268. outline: 0;
  269. -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
  270. 0 0 8px rgba(102, 175, 233, 0.6);
  271. box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
  272. 0 0 8px rgba(102, 175, 233, 0.6);
  273. }
  274. button {
  275. display: inline-block;
  276. position: relative;
  277. cursor: pointer;
  278. padding: 7px 4px;
  279. color: white;
  280. font-size: 0.7em;
  281. text-align: center;
  282. text-decoration: none;
  283. text-transform: uppercase;
  284. vertical-align: middle;
  285. white-space: nowrap;
  286. outline: none;
  287. border: none;
  288. -webkit-user-select: none;
  289. -moz-user-select: none;
  290. -ms-user-select: none;
  291. user-select: none;
  292. border-radius: 2px;
  293. background-color: #89bf04;
  294. }
  295. button + button {
  296. margin-left: 5px;
  297. }
  298. button:hover {
  299. background-color: #aee032;
  300. text-decoration: none;
  301. box-shadow: 0 4px 10px 0px rgba(0, 0, 0, 0.225);
  302. }
  303. `)
  304. }
  305. function readyAsync () {
  306. return new Promise((resolve, reject) => {
  307. XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
  308. console.log('XMLHttpRequest.prototype.open -> url', url)
  309. this.addEventListener('readystatechange', () => {
  310. }, false)
  311. let timer = null
  312. let inited = false
  313. let myUrl = null
  314. if (url.includes('api-docs')) {
  315. myUrl = url
  316. timer = setInterval(() => {
  317. if (inited) {
  318. clearInterval(timer)
  319. inited = false
  320. } else {
  321. const elementArr = document.querySelectorAll('.http_method')
  322. if (elementArr.length !== 0) {
  323. if (myUrl.includes('api-docs')) {
  324. inited = true
  325. resolve(myUrl)
  326. }
  327. }
  328. }
  329. }, 1000)
  330. }
  331. open.call(this, method, url, async, user, pass)
  332. }
  333. })
  334. }
  335. function readyAndWatch (func) {
  336. XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
  337. this.addEventListener('readystatechange', () => {
  338. }, false)
  339. let timer = null
  340. let inited = false
  341. let myUrl = null
  342. if (url.includes('api-docs')) {
  343. myUrl = url
  344. timer = setInterval(() => {
  345. if (inited) {
  346. clearInterval(timer)
  347. inited = false
  348. } else {
  349. const elementArr = document.querySelectorAll('.http_method')
  350. if (elementArr.length !== 0) {
  351. if (myUrl.includes('api-docs')) {
  352. console.log('timer -> myUrl', myUrl)
  353. inited = true
  354. func(myUrl)
  355. }
  356. }
  357. }
  358. }, 1000)
  359. }
  360. open.call(this, method, url, async, user, pass)
  361. }
  362. }
  363. function getJsonAsync (url) {
  364. return new Promise((resolve, reject) => {
  365. const res = fetch(url)
  366. .then(res => {
  367. return res.json()
  368. })
  369. .catch(e => {
  370. reject(e)
  371. })
  372. res.then(res => {
  373. const totalRes = res
  374. resolve(totalRes)
  375. })
  376. })
  377. }
  378.  
  379. function createExpand () {
  380. document.querySelector('#message-bar').insertAdjacentHTML('afterbegin', `
  381. <button id='collapse'>合起全部</button>
  382. <button id='expandAll'>展开全部</button>
  383. `)
  384. document.querySelector('#collapse').onclick = collapse
  385. document.querySelector('#expandAll').onclick = expandAll
  386. function expandAll () {
  387. const list = document.querySelector('#resources')
  388. const items = list.children;
  389. [...items].forEach(li => {
  390. li.classList.add('active')
  391. li.querySelector('ul.endpoints').style.display = 'block'
  392. })
  393. }
  394. function collapse () {
  395. const list = document.querySelector('#resources')
  396. const items = list.children;
  397. [...items].forEach(li => {
  398. li.classList.remove('active')
  399. li.querySelector('ul.endpoints').style.display = 'none'
  400. })
  401. }
  402. }
  403.  
  404. function createCliDisplay () {
  405. document.querySelector('#message-bar').insertAdjacentHTML('afterbegin',
  406. `
  407. <pre class='card' id='cliDisplay'><code class='code javascript' id='cliDisplaySpan'>剪贴板展示</code></pre>
  408. `
  409. )
  410. }
  411. function createCopyUrlAll (totalRes) {
  412. const blockArr = document.querySelectorAll('#resources > .resource')
  413.  
  414. blockArr.forEach(ele => {
  415. const button = document.createElement('button')
  416. button.innerHTML = '复制所有url'
  417. button.classList.add('copy_url_all')
  418.  
  419. ele.querySelector('.heading').children[0].prepend(button)
  420.  
  421. const paths = new Set();
  422.  
  423. [...ele.querySelector('.endpoints').children].forEach(li => {
  424. const url = li.querySelector('.path').children[0].innerHTML
  425. const method = li
  426. .querySelector('.http_method')
  427. .children[2].innerHTML.toUpperCase()
  428. const note = li.querySelector('.markdown').children[0].innerHTML
  429. const obj = {
  430. url,
  431. method,
  432. note
  433. }
  434. const objStr = JSON.stringify(obj)
  435. paths.add(objStr)
  436. })
  437. button.dataset.clipboardText = Array.from(paths).join(';')
  438. })
  439. }
  440. function createCopyUrl () {
  441. const elementArr = document.querySelectorAll('.endpoint')
  442. elementArr.forEach(ele => {
  443. const button = document.createElement('button')
  444. button.innerHTML = '复制url'
  445. button.classList.add('copy_url')
  446. ele.querySelector('.http_method').prepend(button)
  447. const url = ele.querySelector('.path').children[0].innerHTML
  448. const method = ele.querySelector('.http_method').children[2].innerHTML.toUpperCase()
  449. const note = ele.querySelector('.markdown').children[0].innerHTML
  450. const obj = {
  451. url,
  452. method,
  453. note
  454. }
  455. const objStr = JSON.stringify(obj)
  456. button.dataset.clipboardText = objStr
  457. })
  458. }
  459. function createCopyFunc (totalRes) {
  460. const elementArr = document.querySelectorAll('.endpoint')
  461. elementArr.forEach(ele => {
  462. const button = document.createElement('button')
  463. button.innerHTML = '复制为async函数'
  464. button.classList.add('copy_func')
  465. ele.querySelector('.http_method').prepend(button)
  466. const url = ele.querySelector('.path').children[0].innerHTML
  467.  
  468. const pathRes = totalRes.paths[url].get || totalRes.paths[url].post
  469. const parameters = pathRes.parameters
  470. if (!parameters) {
  471. return
  472. }
  473. const parameterLast = parameters[parameters.length - 1]
  474.  
  475. let ref
  476. let comment
  477. if (parameterLast.in === 'body') {
  478. if (parameterLast.schema.$ref) {
  479. ref = splitLast(parameterLast.schema.$ref)
  480.  
  481. const definition = totalRes.definitions[ref]
  482. if (definition) {
  483. const properties = definition.properties
  484.  
  485. const parameters = Object.keys(properties).map(key => {
  486. const property = properties[key]
  487. const obj = {}
  488. obj.name = key
  489. obj.description = property.description
  490. obj.type = property.type
  491.  
  492. return obj
  493. })
  494.  
  495. comment = parameters.reduce((acc, cur) => {
  496. if (cur.name == 'token') {
  497. return acc
  498. }
  499. acc = `${acc}
  500. ${cur.name}:'',//${cur.description} ${cur.type}`
  501. return acc
  502. }, '')
  503. }
  504. }
  505. } else {
  506. comment = parameters.reduce((acc, cur) => {
  507. if (cur.name == 'token') {
  508. return acc
  509. }
  510. acc = `${acc}
  511. ${cur.name}:'', //${cur.description} ${cur.type}`
  512. return acc
  513. }, '')
  514. }
  515.  
  516. if (!comment) {
  517. comment = '//无需参数'
  518. }
  519. const obj = {
  520. url,
  521. comment
  522. }
  523. button.dataset.clipboardText = JSON.stringify(obj)
  524. })
  525. }
  526. function createButtonTable (ele) {
  527. const elementArr = document.querySelectorAll('.endpoint')
  528. elementArr.forEach(ele => {
  529. const button = document.createElement('button')
  530. button.innerHTML = '复制为列表项'
  531. button.classList.add('copy_table')
  532. if (ele.querySelector('.description')) {
  533. ele.querySelector('.description').prepend(button)
  534. const description = ele.querySelector('.description')
  535. const div = description.querySelectorAll('div')
  536. const list = [...div]
  537. const table = list.reduce((acc, cur) => {
  538. if (cur.querySelector('.propDesc')) {
  539. const propName = cur.querySelector('.propName').innerHTML
  540. const noPropNameList = ['code', 'data', 'message', 'list', 'pageNum', 'pageSize', 'total ']
  541. if (noPropNameList.includes(propName)) {
  542. return acc
  543. }
  544. const propDesc = cur.querySelector('.propDesc').querySelector('p').innerHTML
  545. acc = `
  546. ${acc}
  547. {
  548. prop:"${propName}",
  549. label:"${propDesc}"
  550. },
  551. `
  552. return acc
  553. } else {
  554. return acc
  555. }
  556. }, '')
  557. button.dataset.clipboardText = table
  558. }
  559. })
  560. }
  561.  
  562. function clipboard () {
  563. const clipboardUrl = new ClipboardJS('.copy_url', {
  564. text: function (trigger) {
  565. const objStr = trigger.dataset.clipboardText
  566. const obj = JSON.parse(objStr)
  567. const urlPrefix = getPrefix()
  568. const urlName = getUrlName(obj.url)
  569. const url = `export const ${urlName} = data => request('${urlPrefix}${obj.url}', data,"${obj.method}")//${obj.note}`
  570. return url
  571. }
  572. })
  573.  
  574. const clipboardUrlAll = new ClipboardJS('.copy_url_all', {
  575. text: function (trigger) {
  576. const arr = trigger.dataset.clipboardText.split(';')
  577. const paths = new Set()
  578. arr.forEach(objStr => {
  579. const obj = JSON.parse(objStr)
  580. const urlPrefix = getPrefix()
  581. const urlName = getUrlName(obj.url)
  582. const url = `export const ${urlName} = data => request('${urlPrefix}${obj.url}', data,"${obj.method}")//${obj.note}`
  583. paths.add(url)
  584. })
  585. return Array.from(paths).join('\n')
  586. }
  587. })
  588.  
  589. const clipboardFunc = new ClipboardJS('.copy_func', {
  590. text: function (trigger) {
  591. const objStr = trigger.dataset.clipboardText
  592. const obj = JSON.parse(objStr)
  593. const comment = obj.comment
  594. const asyncName = getUrlName(obj.url)
  595. const fun = `
  596. async ${asyncName}Async() {
  597. let params = {
  598. ${comment}
  599. }
  600. let res = await api.${asyncName}(params)
  601. },
  602. `
  603. return fun
  604. }
  605. })
  606. const clipboardTable = new ClipboardJS('.copy_table', {
  607. text: function (trigger) {
  608. const table = trigger.dataset.clipboardText
  609. return table
  610. }
  611. })
  612.  
  613. clipboardUrl.on('success', setClipboardDisplay)
  614. clipboardUrlAll.on('success', setClipboardDisplay)
  615. clipboardFunc.on('success', setClipboardDisplay)
  616. clipboardTable.on('success', setClipboardDisplay)
  617. }
  618. function createSelect () {
  619. document.querySelector('.setting_card').insertAdjacentHTML('afterbegin',
  620. `
  621. <div class='setting_item'>
  622. <label for="selectUrl" class='header-label'>url截取范围:</label>
  623. <select name='selectUrl' id='selectUrl'>
  624. <option value="first" selected = "selected">最后一级</option>
  625. <option value="second">最后二级</option>
  626. </select>
  627. </div>
  628. `
  629. )
  630. }
  631. function createInput () {
  632. document.querySelector('.setting_card').insertAdjacentHTML('afterbegin',
  633. `
  634. <div class='setting_item'>
  635. <label for="prefix" class='header-label'>url前缀:</label>
  636. <input type="text" id="urlPrefix" name="prefix" placeholder='后端微服务名'>
  637. </div>
  638. `
  639. )
  640. }
  641. function createSetting () {
  642. document.querySelector('#header').insertAdjacentHTML('beforeend',
  643. `
  644. <div class='setting_icon'>
  645. <svg t="1589098334770" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2404" width="35" height="35"><path d="M935.69113 523.130435c0-58.590609 36.797217-108.232348 88.30887-128a513.669565 513.669565 0 0 0-56.097391-135.635478 136.97113 136.97113 0 0 1-181.047652-181.092174A515.962435 515.962435 0 0 0 651.152696 22.26087 137.371826 137.371826 0 0 1 523.130435 110.569739 137.171478 137.171478 0 0 1 395.130435 22.26087a513.669565 513.669565 0 0 0-135.635478 56.141913 137.126957 137.126957 0 0 1-28.093218 152.932174 137.371826 137.371826 0 0 1-152.887652 28.16A510.21913 510.21913 0 0 0 22.26087 395.130435 137.371826 137.371826 0 0 1 110.569739 523.130435c0 58.590609-36.797217 108.232348-88.308869 128a513.669565 513.669565 0 0 0 56.141913 135.635478 136.97113 136.97113 0 0 1 180.980869 181.092174A515.650783 515.650783 0 0 0 395.130435 1024a137.371826 137.371826 0 0 1 128.022261-88.30887c58.590609 0 108.232348 36.797217 128 88.30887a513.669565 513.669565 0 0 0 135.635478-56.097391 137.126957 137.126957 0 0 1 28.093217-152.998957 137.371826 137.371826 0 0 1 152.887652-28.137739A510.21913 510.21913 0 0 0 1024 651.130435a137.171478 137.171478 0 0 1-88.30887-128.022261z m-401.719652 152.442435a141.55687 141.55687 0 1 1 0.111305-283.11374 141.55687 141.55687 0 0 1-0.111305 283.11374z" fill="#2DAA9D" p-id="2405"></path><path d="M754.042435 512c0-34.370783 21.593043-63.510261 51.801043-75.108174a301.345391 301.345391 0 0 0-32.901565-79.560348 80.361739 80.361739 0 0 1-106.22887-106.228869 302.703304 302.703304 0 0 0-79.604869-32.946087A80.584348 80.584348 0 0 1 512 269.957565 80.473043 80.473043 0 0 1 436.891826 218.156522c-27.959652 7.123478-54.761739 18.209391-79.560348 32.946087a80.450783 80.450783 0 0 1-16.473043 89.711304 80.584348 80.584348 0 0 1-89.711305 16.517565A299.341913 299.341913 0 0 0 218.156522 436.891826 80.584348 80.584348 0 0 1 269.957565 512c0 34.370783-21.593043 63.510261-51.801043 75.108174 7.123478 27.959652 18.209391 54.761739 32.946087 79.560348a80.361739 80.361739 0 0 1 106.184348 106.228869 302.525217 302.525217 0 0 0 79.604869 32.946087A80.584348 80.584348 0 0 1 512 754.042435c34.370783 0 63.510261 21.593043 75.108174 51.801043 27.959652-7.123478 54.761739-18.18713 79.560348-32.901565a80.450783 80.450783 0 0 1 16.473043-89.755826 80.584348 80.584348 0 0 1 89.711305-16.517565 299.341913 299.341913 0 0 0 32.990608-79.560348A80.473043 80.473043 0 0 1 754.042435 512z m-235.675826 89.421913a83.033043 83.033043 0 1 1 0.044521-166.066087 83.033043 83.033043 0 0 1-0.044521 166.066087z" fill="#A4E8E1" p-id="2406"></path></svg>
  646. </div>
  647. <div class='setting_card'>
  648. </div>
  649. `
  650. )
  651. document.querySelector('.setting_icon').onclick = changeShow
  652. let isShow = false
  653. function changeShow () {
  654. if (isShow) {
  655. isShow = false
  656. document.querySelector('.setting_card').style.visibility = 'hidden'
  657. } else {
  658. isShow = true
  659. document.querySelector('.setting_card').style.visibility = 'visible'
  660. }
  661. }
  662. }
  663. function createSearch (params) {
  664. document.querySelector('#header').insertAdjacentHTML('beforeend',
  665. `
  666. <div class='search_wrapper'>
  667. <label for="search" class='header-label'>搜索:</label>
  668. <input type="text" id="search" name="search" placeholder='输入汉字'>
  669. </div>
  670. `
  671. )
  672. }
  673. addSheet()
  674. async function init (url) {
  675. const totalRes = await getJsonAsync(url)
  676. createExpand()
  677. createSetting()
  678. createSelect()
  679. createInput()
  680.  
  681. createCliDisplay()
  682. createCopyFunc(totalRes)
  683. createCopyUrl()
  684. createCopyUrlAll()
  685. createButtonTable()
  686. clipboard()
  687. highlight()
  688. }
  689. readyAndWatch(init)
  690. }
  691. )(XMLHttpRequest.prototype.open)