notion-标题编号.js 3.5 KB

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