scroll.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. var scroll = (() => {
  2. function race (done) {
  3. Promise.race([
  4. Promise.all([
  5. new Promise((resolve) => {
  6. var images = Array.from(document.querySelectorAll('img'))
  7. if (!images.length) {
  8. resolve()
  9. }
  10. else {
  11. var loaded = 0
  12. images.forEach((img) => {
  13. img.addEventListener('load', () => {
  14. if (++loaded === images.length) {
  15. resolve()
  16. }
  17. }, {once: true})
  18. })
  19. }
  20. }),
  21. new Promise((resolve) => {
  22. var code = Array.from(document.querySelectorAll('code[class^=language-]'))
  23. if (!state.content.syntax || !code.length) {
  24. resolve()
  25. }
  26. else {
  27. setTimeout(() => resolve(), 40)
  28. }
  29. }),
  30. new Promise((resolve) => {
  31. var diagrams = Array.from(document.querySelectorAll('code.mermaid'))
  32. if (!state.content.mermaid || !diagrams.length) {
  33. resolve()
  34. }
  35. else {
  36. var timeout = setInterval(() => {
  37. var svg = Array.from(document.querySelectorAll('code.mermaid svg'))
  38. if (diagrams.length === svg.length) {
  39. clearInterval(timeout)
  40. resolve()
  41. }
  42. }, 50)
  43. }
  44. }),
  45. new Promise((resolve) => {
  46. if (!state.content.mathjax) {
  47. resolve()
  48. }
  49. else {
  50. var timeout = setInterval(() => {
  51. if (mj.loaded) {
  52. clearInterval(timeout)
  53. resolve()
  54. }
  55. }, 50)
  56. }
  57. })
  58. ]),
  59. new Promise((resolve) => setTimeout(resolve, 500))
  60. ])
  61. .then(done)
  62. }
  63. function listen (container, done) {
  64. var listener = /html|body/i.test(container.nodeName) ? window : container
  65. var timeout = null
  66. listener.addEventListener('scroll', () => {
  67. clearTimeout(timeout)
  68. timeout = setTimeout(done, 100)
  69. })
  70. }
  71. function get (container, prefix, offset) {
  72. var key = prefix + location.origin + location.pathname
  73. if (offset) {
  74. container.scrollTop = offset
  75. return
  76. }
  77. try {
  78. container.scrollTop = parseInt(localStorage.getItem(key))
  79. }
  80. catch (err) {
  81. chrome.storage.local.get(key, (res) => {
  82. container.scrollTop = parseInt(res[key])
  83. })
  84. }
  85. }
  86. function set (container, prefix) {
  87. var key = prefix + location.origin + location.pathname
  88. try {
  89. listen(container, () => {
  90. localStorage.setItem(key, container.scrollTop)
  91. })
  92. }
  93. catch (err) {
  94. listen(container, () => {
  95. chrome.storage.local.set({[key]: container.scrollTop})
  96. })
  97. }
  98. }
  99. var listening = false
  100. return (update) => {
  101. race(() => {
  102. var container = ((html = $('html')) => (
  103. html.scrollTop = 1,
  104. html.scrollTop ? (html.scrollTop = 0, html) : $('body')
  105. ))()
  106. if (!update && location.hash && $(location.hash)) {
  107. get(container, 'md-', $(location.hash).offsetTop)
  108. }
  109. else {
  110. get(container, 'md-')
  111. }
  112. if (state.content.toc) {
  113. setTimeout(() => get($('#_toc'), 'md-toc-'), 10)
  114. }
  115. if (!listening) {
  116. listening = true
  117. set(container, 'md-')
  118. if (state.content.toc) {
  119. setTimeout(() => set($('#_toc'), 'md-toc-'), 10)
  120. }
  121. }
  122. })
  123. }
  124. })()