marketplace.html 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport"
  6. content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8. <title>Logseq Marketplace</title>
  9. <link rel="stylesheet"
  10. href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css"
  11. integrity="sha512-Oy18vBnbSJkXTndr2n6lDMO5NN31UljR8e/ICzVPrGpSud4Gkckb8yUpqhKuUNoE+o9gAb4O/rAxxw1ojyUVzg=="
  12. crossorigin="anonymous" referrerpolicy="no-referrer"/>
  13. <style>
  14. html, body {
  15. padding: 0;
  16. margin: 0;
  17. box-sizing: border-box;
  18. font-family: sans-serif;
  19. width: 100%;
  20. min-height: 100%;
  21. }
  22. html::-webkit-scrollbar-thumb {
  23. background-color: rgba(0, 0, 0, 0.1);
  24. }
  25. html::-webkit-scrollbar {
  26. background-color: rgba(0, 0, 0, 0.05);
  27. }
  28. html::-webkit-scrollbar-thumb:active {
  29. background-color: rgba(0, 0, 0, 0.2);
  30. }
  31. html::-webkit-scrollbar {
  32. width: 6px;
  33. height: 8px;
  34. }
  35. html::-webkit-scrollbar-corner {
  36. background: transparent;
  37. }
  38. body {
  39. display: flex;
  40. }
  41. #app {
  42. display: flex;
  43. justify-content: center;
  44. flex: 1;
  45. width: 900px;
  46. min-height: 100%;
  47. padding: 30px;
  48. margin: 0 auto;
  49. color: #333;
  50. }
  51. #app > strong {
  52. padding-top: 30vh;
  53. font-weight: 400;
  54. }
  55. pre {
  56. max-width: 800px;
  57. }
  58. </style>
  59. </head>
  60. <body>
  61. <div id="app"></div>
  62. <script src="./js/marked.min.js"></script>
  63. <script src="./js/purify.js"></script>
  64. <script>
  65. ;(async function () {
  66. const app = document.getElementById('app')
  67. const url = new URL(location.href)
  68. const setMsg = (msg) => app.innerHTML = `<strong>${msg}</strong>`
  69. const repo = url.searchParams.get('repo')
  70. if (!repo) {
  71. return setMsg('Repo parameter not found!')
  72. }
  73. const setContent = (content) => app.innerHTML = `<main class="markdown-body">${content}</main>`
  74. const endpoint = (repo, branch, file) => `https://raw.githubusercontent.com/${repo}/${branch}/${file}`
  75. let defaultPoints = [
  76. endpoint(repo, 'master', 'README.md'), endpoint(repo, 'main', 'README.md'),
  77. endpoint(repo, 'master', 'readme.md'), endpoint(repo, 'main', 'readme.md')]
  78. let content = ''
  79. let readme
  80. const fixLink = (link) => readme.replace(/[^\/]+\.md$/i, link)
  81. const isRelative = (href) => href && !href.startsWith('http') && !!href.match(/^([.\/]+|[^\/]+)/) &&
  82. href.replace(/^[.\/]+/, '')
  83. marked.use({
  84. renderer: {
  85. link (href, title, text) {
  86. return `<a href="${href}" target="_blank" title="${title}">${text}</a>`
  87. },
  88. image (href, title, text) {
  89. let link = isRelative(href)
  90. if (link) {
  91. link = fixLink(link)
  92. return `<img style="max-width: 100%;" src="${link}" alt="${title}" />`
  93. }
  94. return false
  95. },
  96. },
  97. })
  98. // load exist points content
  99. async function loadPage (points) {
  100. setMsg('Loading ...')
  101. for (let url of points) {
  102. try {
  103. const res = await fetch(url)
  104. if (res.status !== 200) {
  105. throw new Error(res.statusText)
  106. }
  107. content = await res.text()
  108. readme = url
  109. break
  110. } catch (e) {
  111. console.debug('Error:', url, e.message)
  112. }
  113. }
  114. content = marked.parse(content).replace('src="./', `src="${fixLink('')}`)
  115. setContent(DOMPurify.sanitize(content))
  116. }
  117. // load default
  118. await loadPage(defaultPoints)
  119. // handle link
  120. document.querySelector('#app').addEventListener('click', (e) => {
  121. const target = e.target
  122. const href = target.getAttribute('href')
  123. if (!!href && href.endsWith('.md') && !href.startsWith('http')) {
  124. loadPage([
  125. endpoint(repo, 'master', href),
  126. endpoint(repo, 'main', href)
  127. ])
  128. e.preventDefault()
  129. }
  130. })
  131. }())
  132. </script>
  133. </body>
  134. </html>