scroll.js 3.8 KB

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