e360-doc-table.user.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // ==UserScript==
  2. // @name E360 Table Transformer
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description try to take over the world!
  6. // @author You
  7. // @match https://open.e.360.cn/*
  8. // @grant GM_setClipboard
  9. // ==/UserScript==
  10. (function() {
  11. 'use strict';
  12. const regexpGeneric = /^(?:List|Set)<([^>]+)>$/i
  13. const convertType = (type) => {
  14. let isList = false
  15. if (type.endsWith('[]')) {
  16. isList = true
  17. type = type.substring(0, type.length - 2)
  18. } else if (regexpGeneric.test(type)) {
  19. isList = true
  20. type = regexpGeneric.exec(type)[1]
  21. }
  22. switch (type.toLowerCase()) {
  23. case 'long':
  24. case 'float':
  25. case 'double':
  26. case 'int':
  27. case 'number':
  28. case 'integer': type = 'number'; break
  29. case 'boolean': type = 'boolean'; break
  30. case 'string': type = 'string'; break
  31. }
  32. if (isList) type += '[]'
  33. return type
  34. }
  35. const parseRow = (row) => {
  36. const tds = row.querySelectorAll('td')
  37. const tdl = tds.length;
  38. const hasOptional = tdl === 4
  39. if (tdl < 3) return ''
  40. const name = tds[0].innerText.trim()
  41. if (!name) return ''
  42. const type = tds[1].innerText.trim()
  43. const optional = hasOptional && tds[2].innerText.trim().toLowerCase().includes('no')
  44. const comment = tds[hasOptional ? 3 : 2].innerText.trim()
  45. return ` ${name.replace(/\n/g, '')}${optional ? '?' : ''}: ${convertType(type)} // ${comment.replace(/\n/g, ' ')}\n`
  46. }
  47. const parseRows = (rows) => {
  48. if (!rows.length) return
  49. let content = ''
  50. rows.forEach(row => {
  51. content += parseRow(row)
  52. })
  53. GM_setClipboard(content)
  54. return content
  55. }
  56. const parseTable = (tableDiv) => {
  57. const result = document.createElement('pre')
  58. result.append(document.createTextNode(parseRows(tableDiv.querySelectorAll('tr:nth-child(n+1)'))))
  59. tableDiv.parentElement.insertBefore(result, tableDiv)
  60. }
  61. const createButton = (container) => {
  62. if (container?.dataset?.dump) return
  63. container.dataset.dump = true
  64. container.style.position = 'relative'
  65. const btn = document.createElement('button')
  66. btn.append(document.createTextNode('Dump'))
  67. btn.addEventListener('click', () => {
  68. parseTable(container)
  69. btn.remove()
  70. })
  71. btn.style.position = 'absolute'
  72. btn.style.top = '0'
  73. btn.style.right = '2em'
  74. btn.style.zIndex = 10000
  75. container.prepend(btn)
  76. }
  77. const ob = new MutationObserver(mutations => {
  78. mutations.forEach(({ target }) => {
  79. if (target?.tagName === 'BODY') {
  80. setTimeout(() => {
  81. document.querySelectorAll(".markdown-section table").forEach(createButton)
  82. }, 1000)
  83. }
  84. })
  85. })
  86. ob.observe(document.body, { subtree: true, childList: true })
  87. })();