Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

toggle-images.ts 4.2 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  1. // import { sendEvent } from './events'
  2. import Cookies from 'js-cookie'
  3. // Determines whether images are hidden or displayed on first visit.
  4. const hideImagesByDefault = false
  5. // Set the image placeholder icon here.
  6. const placeholderImagePath = '/assets/images/octicons/image.svg'
  7. /*
  8. * This module adds a new icon button in the margin to toggle all images on the page.
  9. * It uses cookies to keep track of a user's selected image preference.
  10. */
  11. export default function () {
  12. const toggleImagesBtn = document.getElementById('js-toggle-images')
  13. if (!toggleImagesBtn) return
  14. // If there are no images on the page, return!
  15. // Don't include images in tables, which are already small and shouldn't be hidden.
  16. const images = Array.from(document.querySelectorAll('img')).filter((img) => !img.closest('table'))
  17. if (!images.length) return
  18. // The button is hidden by default so it doesn't appear on browsers with JS disabled.
  19. // If there are images on a docs page and JS is enabled, display the toggle button.
  20. toggleImagesBtn.removeAttribute('hidden')
  21. // Look for a cookie with image visibility preference; otherwise, use the default.
  22. const hideImagesPreferred = Cookies.get('hideImagesPreferred') === 'true' || hideImagesByDefault
  23. // Hide the images if that is the preference.
  24. if (hideImagesPreferred) {
  25. toggleImages(images, 'hide')
  26. }
  27. // Get the span elements containing the off and on icons.
  28. const offIcon = document.getElementById('js-off-icon')
  29. const onIcon = document.getElementById('js-on-icon')
  30. // Get the aria-labels from the span elements for the tooltips.
  31. const tooltipImagesOff = offIcon?.getAttribute('aria-label') || ''
  32. const tooltipImagesOn = onIcon?.getAttribute('aria-label') || ''
  33. // Set the starting state depending on user preferences.
  34. if (hideImagesPreferred) {
  35. offIcon?.removeAttribute('hidden')
  36. toggleImagesBtn.setAttribute('aria-label', tooltipImagesOff)
  37. } else {
  38. onIcon?.removeAttribute('hidden')
  39. toggleImagesBtn.setAttribute('aria-label', tooltipImagesOn)
  40. }
  41. // If images are hidden by default, showOnNextClick should be false.
  42. // If images are not hidden by default, showOnNextClick should be true.
  43. let showOnNextClick = !hideImagesPreferred
  44. toggleImagesBtn.addEventListener('click', () => {
  45. if (showOnNextClick) {
  46. // Button should say "Images are off" on first click (depending on prefs)
  47. offIcon?.removeAttribute('hidden')
  48. onIcon?.setAttribute('hidden', 'hidden')
  49. toggleImagesBtn.setAttribute('aria-label', tooltipImagesOff)
  50. toggleImages(images, 'hide')
  51. } else {
  52. // Button should say "Images are on" on another click
  53. offIcon?.setAttribute('hidden', 'hidden')
  54. onIcon?.removeAttribute('hidden')
  55. toggleImagesBtn.setAttribute('aria-label', tooltipImagesOn)
  56. toggleImages(images, 'show')
  57. }
  58. // Remove focus from the button after click so the tooltip does not stay displayed.
  59. // Use settimeout to work around Firefox-specific issue.
  60. setTimeout(() => {
  61. toggleImagesBtn.blur()
  62. }, 100)
  63. // Save this preference as a cookie.
  64. Cookies.set('hideImagesPreferred', showOnNextClick.toString(), {
  65. sameSite: 'strict',
  66. secure: true,
  67. })
  68. // Toggle the action on every click.
  69. showOnNextClick = !showOnNextClick
  70. // TODO Track image toggle events
  71. // sendEvent({ type: 'imageToggle' })
  72. })
  73. }
  74. function toggleImages(images: Array<HTMLImageElement>, action: string) {
  75. for (const img of images) {
  76. toggleImage(img, action)
  77. }
  78. }
  79. function toggleImage(img: HTMLImageElement, action: string) {
  80. const parentEl = img.parentNode as HTMLElement
  81. // Style the parent element and image depending on the state.
  82. if (action === 'show') {
  83. img.src = img.getAttribute('originalSrc') || ''
  84. img.style.border = '2px solid var(--color-auto-gray-2)'
  85. parentEl.style.display = 'block'
  86. parentEl.style.marginTop = '20px'
  87. parentEl.style.padding = '10px 0'
  88. } else {
  89. if (!img.getAttribute('originalSrc')) img.setAttribute('originalSrc', img.src)
  90. img.src = placeholderImagePath
  91. img.style.border = 'none'
  92. parentEl.style.display = 'inline'
  93. parentEl.style.marginTop = '0'
  94. parentEl.style.padding = '1px 6px'
  95. }
  96. }
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...