😎 Give your xaringan slides some style
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

225 líneas
6.1KB

  1. ;(function () {
  2. function findPkgdownGlobalRoot () {
  3. const origin = window.location.origin
  4. const path = window.location.pathname.replace(/[^/]+$/, '')
  5. // Special cases supported by our versioned pkgdown workflow
  6. const specials = [/dev\//, /preview\//, /v\d+\.\d+\.\d+\//]
  7. for (const special of specials) {
  8. if (special.test(path)) {
  9. return origin + path.split(special)[0]
  10. }
  11. }
  12. const pkgdownDirs = ['articles', 'news', 'reference']
  13. for (const pkgdownDir of pkgdownDirs) {
  14. if (path.includes(pkgdownDir)) {
  15. return origin + path.split(`${pkgdownDir}/`)[0]
  16. }
  17. }
  18. return origin + path
  19. }
  20. function pathDir (url) {
  21. return url.replace(/\/[^/]+$/, '/')
  22. }
  23. function ensureTrailingSlash (url) {
  24. return /\/$/.test(url) ? url : url + '/'
  25. }
  26. function ensureFullPath (url) {
  27. return /^\//.test(url) ? window.location.origin + url : url
  28. }
  29. function findPkgdownLocalRoot () {
  30. // get `src` attribute of the current <script> tag
  31. const scripts = document.getElementsByTagName('script')
  32. const currentScript = scripts[scripts.length - 1]
  33. let src = pathDir(currentScript.getAttribute('src'))
  34. if (!src.includes('/') || src === '/') {
  35. src = ''
  36. }
  37. const currentDir = pathDir(window.location.href)
  38. const root = new URL(currentDir + src).toString()
  39. return ensureTrailingSlash(root)
  40. }
  41. function makeNewPkgdownLink (newBase) {
  42. newBase = ensureFullPath(newBase)
  43. newBase = ensureTrailingSlash(newBase)
  44. return window.location.href.replace(findPkgdownLocalRoot(), newBase)
  45. }
  46. async function getVersions () {
  47. let versionsUrl
  48. if (window.PKGDOWN_VERSIONS_URL) {
  49. versionsUrl = window.PKGDOWN_VERSIONS_URL
  50. } else {
  51. let pkgdownRoot = findPkgdownGlobalRoot()
  52. if (!/\/$/.test(pkgdownRoot)) {
  53. pkgdownRoot += '/'
  54. }
  55. versionsUrl = pkgdownRoot + 'doc-versions.json'
  56. }
  57. try {
  58. const response = await fetch(versionsUrl)
  59. return response.json()
  60. } catch {
  61. return null
  62. }
  63. }
  64. function createVersionDropdown (current, versions) {
  65. if (typeof versions === 'string') {
  66. console.error(
  67. '`doc-versions.json` should be an array or object, not a string'
  68. )
  69. return
  70. }
  71. const dropdown = document.createElement('ul')
  72. dropdown.classList.add('navbar-nav')
  73. const li = document.createElement('li')
  74. li.classList.add('nav-item', 'dropdown')
  75. dropdown.appendChild(li)
  76. const a = document.createElement('a')
  77. a.classList.add('nav-link', 'dropdown-toggle')
  78. if (current.matches('.text-danger')) {
  79. a.classList.add('text-danger')
  80. }
  81. a.href = '#'
  82. a.role = 'button'
  83. a.dataset.bsToggle = 'dropdown'
  84. a.ariaExpanded = false
  85. a.innerText = current.innerText
  86. li.appendChild(a)
  87. const ul = document.createElement('ul')
  88. ul.classList.add('dropdown-menu')
  89. li.appendChild(ul)
  90. if (versions.constructor === Object) {
  91. versions = [versions]
  92. }
  93. versions.forEach(item => {
  94. if (item === '---') {
  95. ul.appendChild(createVersionDropdownDivider())
  96. return
  97. }
  98. // if item is a string, it is a header
  99. if (typeof item === 'string') {
  100. ul.appendChild(createVersionDropdownHeader(item))
  101. return
  102. }
  103. const version = item.version ? item.version : item.text.replace(/^v/, '')
  104. const isCurrent = current.innerText === version
  105. ul.appendChild(createVersionDropdownItem(item, isCurrent))
  106. })
  107. return dropdown
  108. }
  109. function createVersionDropdownItem ({ text, url }, isCurrent = false) {
  110. const li = document.createElement('li')
  111. const a = document.createElement('a')
  112. a.classList.add('dropdown-item')
  113. if (isCurrent) a.classList.add('active')
  114. // link to current page in the other version (may not exist!)
  115. a.href = makeNewPkgdownLink(url)
  116. a.innerText = text
  117. li.appendChild(a)
  118. return li
  119. }
  120. function createVersionDropdownDivider () {
  121. // <li><hr class="dropdown-divider"></li>
  122. const li = document.createElement('li')
  123. const hr = document.createElement('hr')
  124. hr.classList.add('dropdown-divider')
  125. li.appendChild(hr)
  126. return li
  127. }
  128. function createVersionDropdownHeader (text) {
  129. // <li><h6 class="dropdown-header">Dropdown header</h6></li>
  130. const li = document.createElement('li')
  131. const h6 = document.createElement('h6')
  132. h6.classList.add('dropdown-header')
  133. h6.innerText = text
  134. li.appendChild(h6)
  135. return li
  136. }
  137. function insertBanner (banner) {
  138. if (!banner) return
  139. const main = document.querySelector('main')
  140. if (!main) return
  141. let { html, class: classes } = banner
  142. if (typeof classes === 'string') {
  143. // Classes can be a string or an array of strings
  144. classes = [classes]
  145. }
  146. // <div class="d-block px-3 py-2 text-center text-bold skippy">
  147. // <a href="https://getbootstrap.com/" class="text-white text-decoration-none">There's a newer version of Bootstrap!</a>
  148. // </div>
  149. const div = document.createElement('div')
  150. div.classList.add('alert', 'px-3', 'py-2', 'text-center', ...classes)
  151. div.innerHTML = html
  152. div.querySelectorAll('a').forEach(a => {
  153. if (!a.hasAttribute('href')) {
  154. a.href = makeNewPkgdownLink(findPkgdownGlobalRoot())
  155. }
  156. })
  157. main.insertAdjacentElement('afterbegin', div)
  158. return div
  159. }
  160. function maybeInsertBanner (versions) {
  161. if (!versions) return
  162. if (!Array.isArray(versions)) return
  163. // keep versions entries that are objects with a `banner` property
  164. versions = versions.filter(item => item && item.banner)
  165. const localRoot = findPkgdownLocalRoot()
  166. for (const version of versions) {
  167. const versionUrl = ensureFullPath(version.url)
  168. if (localRoot === versionUrl) {
  169. return insertBanner(version.banner)
  170. }
  171. }
  172. }
  173. async function replaceVersionWithMenu () {
  174. const current = document.querySelector('.navbar .navbar-brand + small')
  175. if (!current) return
  176. const versions = await getVersions()
  177. if (!versions) return
  178. const dropdown = createVersionDropdown(current, versions)
  179. current.replaceWith(dropdown)
  180. maybeInsertBanner(versions)
  181. }
  182. replaceVersionWithMenu()
  183. })()