notion-标题编号.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // ==UserScript==
  2. // @name T-Notion-标题编号
  3. // @namespace Violentmonkey Scripts
  4. // @match *://www.notion.so/*
  5. // @grant none
  6. // @version 1.0
  7. // @author -
  8. // @description 2021/11/5 下午2:18:51
  9. // @require https://git.tianyunperfect.cn/tianyunperfect/web-base/raw/master/monkey/util.js?a=1
  10. // ==/UserScript==
  11. (async () => {
  12. function myHeader() {
  13. // 删除最后gap个数字后seq+1
  14. function leftMoveAndAddSeq(str, gap) {
  15. let arr = str.split(".")
  16. arr[arr.length - 2 - gap] = parseInt(arr[arr.length - 2 - gap]) + 1
  17. while (gap >= 0) {
  18. arr.pop();
  19. gap -= 1;
  20. }
  21. return arr.join(".") + ".";
  22. }
  23. // 删除过去生成的序号
  24. function removeOldPrefix(content) {
  25. return content.replace(/^(\d+\.\d+\.\d+\.\s)/, '').replace(/^(\d+\.\d+\.\s)/, '').replace(/^(\d+\.\s)/, '')
  26. }
  27. // 获取所有的header
  28. const $headers = [...document.querySelectorAll(`.notion-header-block, .notion-sub_header-block, .notion-sub_sub_header-block`)];
  29. // 遍历生成序号,固定格式:
  30. // level1 x.
  31. // level2 x.x.
  32. // level3 x.x.x.
  33. let outermostLevel = 0 // 最外层的level
  34. let lastPrefix = '' // 上一项的前缀
  35. let lastLevel = 0 // 上一项的level
  36. for (let i = 0; i < $headers.length; i++) {
  37. const $header = $headers[i]
  38. const level = $header.classList.contains('notion-header-block')
  39. ? 1 : $header.classList.contains('notion-sub_header-block')
  40. ? 2 : 3
  41. let curPrefix = ''
  42. if (i === 0) {
  43. outermostLevel = level
  44. curPrefix = '1.'
  45. } else {
  46. if (level < outermostLevel) {
  47. // 不规范格式,直接停止转换
  48. break
  49. }
  50. if (level === lastLevel) {
  51. // 同一层级
  52. curPrefix = leftMoveAndAddSeq(lastPrefix, 0)
  53. }
  54. if (level > lastLevel) {
  55. // 下一层级
  56. curPrefix = lastPrefix + 1 + '.'
  57. }
  58. if (level < lastLevel) {
  59. // 外层
  60. if (lastLevel - level === 1) {
  61. if (lastPrefix.length < 4) break
  62. curPrefix = leftMoveAndAddSeq(lastPrefix, 1)
  63. } else if (lastLevel - level === 2) {
  64. if (lastPrefix.length < 6) break
  65. curPrefix = leftMoveAndAddSeq(lastPrefix, 2)
  66. }
  67. }
  68. }
  69. // 删除之前生成的prefix
  70. const originContent = removeOldPrefix($header.textContent)
  71. // 更改dom
  72. const $edit = $header.querySelector('.notranslate[contenteditable=true]')
  73. $edit.textContent = curPrefix + ' ' + originContent
  74. // 手动触发input event 以触发notion进行远程更新
  75. setTimeout(() => {
  76. $edit.dispatchEvent(new Event('input', {
  77. bubbles: true,
  78. cancelable: true,
  79. }))
  80. }, 0)
  81. // 更新变量
  82. lastPrefix = curPrefix
  83. lastLevel = level
  84. }
  85. }
  86. document.onkeydown = function (ev) {
  87. if (ev.key === 'h' && ev.shiftKey) {
  88. ev.preventDefault() // 关闭浏览器快捷键
  89. myHeader()
  90. }
  91. }
  92. setTimeout(() => {
  93. myHeader();
  94. }, 2000);
  95. setInterval(() => {
  96. myHeader();
  97. }, 20000);
  98. })();