Merge branch 'main' into update-billing-topics
This commit is contained in:
1
assets/images/octicons/image.svg
Normal file
1
assets/images/octicons/image.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.75 2.5a.25.25 0 00-.25.25v10.5c0 .138.112.25.25.25h.94a.76.76 0 01.03-.03l6.077-6.078a1.75 1.75 0 012.412-.06L14.5 10.31V2.75a.25.25 0 00-.25-.25H1.75zm12.5 11H4.81l5.048-5.047a.25.25 0 01.344-.009l4.298 3.889v.917a.25.25 0 01-.25.25zm1.75-.25V2.75A1.75 1.75 0 0014.25 1H1.75A1.75 1.75 0 000 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0016 13.25zM5.5 6a.5.5 0 11-1 0 .5.5 0 011 0zM7 6a2 2 0 11-4 0 2 2 0 014 0z"></path></svg>
|
||||
|
After Width: | Height: | Size: 548 B |
@@ -175,3 +175,10 @@ learning_track_nav:
|
||||
prevGuide: Previous guide
|
||||
nextGuide: Next guide
|
||||
contributor_callout: This article is contributed and maintained by
|
||||
toggle_images:
|
||||
off: Images are off, click to show
|
||||
on: Images are on, click to hide
|
||||
hide_single: Hide image
|
||||
show_single: Show image
|
||||
scroll_button:
|
||||
scroll_to_top: Scroll to top
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<button class="arrow-for-scrolling-top" id="js-scroll-top">
|
||||
{% octicon "chevron-up" %}
|
||||
<button class="arrow-for-scrolling-top tooltipped tooltipped-n tooltipped-no-delay" aria-label="{% data ui.scroll_button.scroll_to_top %}" id="js-scroll-top">
|
||||
{% octicon "chevron-up" %}
|
||||
</button>
|
||||
|
||||
6
includes/toggle-images.html
Normal file
6
includes/toggle-images.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<button class="toggle-images tooltipped tooltipped-nw tooltipped-no-delay" id="js-toggle-images" hidden>
|
||||
<span id="js-off-icon" aria-label="{% data ui.toggle_images.off %}" hidden>{% octicon "eye-closed" %}</span>
|
||||
<span id="js-on-icon" aria-label="{% data ui.toggle_images.on %}" hidden>{% octicon "eye" %}</span>
|
||||
<span id="js-hide-single-image" aria-label="{% data ui.toggle_images.hide_single %}" hidden></span>
|
||||
<span id="js-show-single-image" aria-label="{% data ui.toggle_images.show_single %}" hidden></span>
|
||||
</button>
|
||||
@@ -20,6 +20,7 @@ import devToc from './dev-toc'
|
||||
import releaseNotes from './release-notes'
|
||||
import showMore from './show-more'
|
||||
import airgapLinks from './airgap-links'
|
||||
import toggleImages from './toggle-images'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
displayPlatformSpecificContent()
|
||||
@@ -42,4 +43,5 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
initializeEvents()
|
||||
experiment()
|
||||
helpfulness()
|
||||
toggleImages()
|
||||
})
|
||||
|
||||
159
javascripts/toggle-images.js
Normal file
159
javascripts/toggle-images.js
Normal file
@@ -0,0 +1,159 @@
|
||||
// import { sendEvent } from './events'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
// Determines whether images are hidden or displayed on first visit.
|
||||
const hideImagesByDefault = false
|
||||
|
||||
// Set the image placeholder icon here.
|
||||
const placeholderImagePath = '/assets/images/octicons/image.svg'
|
||||
|
||||
/*
|
||||
* This module does two main things:
|
||||
* 1. Wraps every image in a button so they can be toggled individually.
|
||||
* 2. Adds a new icon button in the margin to toggle all images on the page.
|
||||
* It uses cookies to keep track of a user's selected image preference.
|
||||
*/
|
||||
export default function () {
|
||||
const toggleImagesBtn = document.getElementById('js-toggle-images')
|
||||
if (!toggleImagesBtn) return
|
||||
|
||||
// If there are no images on the page, return!
|
||||
// Don't include images in tables, which are already small and shouldn't be hidden.
|
||||
const images = [...document.querySelectorAll('img')].filter(img => !img.closest('table'))
|
||||
if (!images.length) return
|
||||
|
||||
// The button is hidden by default so it doesn't appear on browsers with JS disabled.
|
||||
// If there are images on a docs page and JS is enabled, display the toggle button.
|
||||
toggleImagesBtn.removeAttribute('hidden')
|
||||
|
||||
// Look for a cookie with image visibility preference; otherwise, use the default.
|
||||
const hideImagesPreferred = (Cookies.get('hideImagesPreferred') === 'true') || hideImagesByDefault
|
||||
|
||||
/*
|
||||
* 1. INDIVIDUAL IMAGE HANDLING
|
||||
*/
|
||||
|
||||
// Get the aria-labels from the span elements containing the hide/show tooltips for single images.
|
||||
// (We do it this way instead of hardcoding text in JS for localization friendliness.)
|
||||
const tooltipHideSingle = document.getElementById('js-hide-single-image').getAttribute('aria-label')
|
||||
const tooltipShowSingle = document.getElementById('js-show-single-image').getAttribute('aria-label')
|
||||
|
||||
// For every image...
|
||||
for (const img of images) {
|
||||
const parentSpan = img.parentNode
|
||||
// Create a button and add some attributes.
|
||||
const parentButton = document.createElement('button')
|
||||
parentButton.classList.add('tooltipped', 'tooltipped-nw', 'tooltipped-no-delay', 'btn-toggle-image')
|
||||
// Wrap the image in the button.
|
||||
parentButton.appendChild(img)
|
||||
// Replace the image's parent span with the new button.
|
||||
// This mostly applies to images in ordered lists nested in spans (via lib/render-content/create-processor.js).
|
||||
// It will have no effect with images that are not in ordered lists.
|
||||
parentSpan.parentNode.replaceChild(parentButton, parentSpan)
|
||||
|
||||
// Set the relevant tooltip text, and hide the image if that is the preference.
|
||||
if (hideImagesPreferred) {
|
||||
parentButton.setAttribute('aria-label', tooltipShowSingle)
|
||||
toggleImage(img, 'hide', tooltipShowSingle)
|
||||
} else {
|
||||
parentButton.setAttribute('aria-label', tooltipHideSingle)
|
||||
}
|
||||
|
||||
// On any individual image button click...
|
||||
parentButton.addEventListener('click', (e) => {
|
||||
// Determine current state.
|
||||
const hideOnNextClick = parentButton.getAttribute('aria-label') === tooltipShowSingle
|
||||
|
||||
// Hide or show the image!
|
||||
if (hideOnNextClick) {
|
||||
toggleImage(img, 'show', tooltipHideSingle)
|
||||
} else {
|
||||
toggleImage(img, 'hide', tooltipShowSingle)
|
||||
}
|
||||
|
||||
// Remove focus from the button after click so the tooltip does not stay displayed.
|
||||
parentButton.blur()
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. PAGE-WIDE TOGGLE BUTTON HANDLING
|
||||
*/
|
||||
|
||||
// Get the span elements containing the off and on icons.
|
||||
const offIcon = document.getElementById('js-off-icon')
|
||||
const onIcon = document.getElementById('js-on-icon')
|
||||
|
||||
// Get the aria-labels from the span elements for the tooltips.
|
||||
const tooltipImagesOff = offIcon.getAttribute('aria-label')
|
||||
const tooltipImagesOn = onIcon.getAttribute('aria-label')
|
||||
|
||||
// Set the starting state depending on user preferences.
|
||||
if (hideImagesPreferred) {
|
||||
offIcon.removeAttribute('hidden')
|
||||
toggleImagesBtn.setAttribute('aria-label', tooltipImagesOff)
|
||||
} else {
|
||||
onIcon.removeAttribute('hidden')
|
||||
toggleImagesBtn.setAttribute('aria-label', tooltipImagesOn)
|
||||
}
|
||||
|
||||
// If images are hidden by default, showOnNextClick should be false.
|
||||
// If images are not hidden by default, showOnNextClick should be true.
|
||||
let showOnNextClick = !hideImagesPreferred
|
||||
|
||||
toggleImagesBtn.addEventListener('click', (e) => {
|
||||
if (showOnNextClick) {
|
||||
// Button should say "Images are off" on first click (depending on prefs)
|
||||
offIcon.removeAttribute('hidden')
|
||||
onIcon.setAttribute('hidden', true)
|
||||
toggleImagesBtn.setAttribute('aria-label', tooltipImagesOff)
|
||||
toggleImages(images, 'hide', tooltipShowSingle)
|
||||
} else {
|
||||
// Button should say "Images are on" on another click
|
||||
offIcon.setAttribute('hidden', true)
|
||||
onIcon.removeAttribute('hidden')
|
||||
toggleImagesBtn.setAttribute('aria-label', tooltipImagesOn)
|
||||
toggleImages(images, 'show', tooltipHideSingle)
|
||||
}
|
||||
|
||||
// Remove focus from the button after click so the tooltip does not stay displayed.
|
||||
toggleImagesBtn.blur()
|
||||
|
||||
// Save this preference as a cookie.
|
||||
Cookies.set('hideImagesPreferred', showOnNextClick)
|
||||
|
||||
// Toggle the action on every click.
|
||||
showOnNextClick = !showOnNextClick
|
||||
|
||||
// TODO Track image toggle events
|
||||
// sendEvent({ type: 'imageToggle' })
|
||||
})
|
||||
}
|
||||
|
||||
function toggleImages (images, action, tooltipText) {
|
||||
for (const img of images) {
|
||||
toggleImage(img, action, tooltipText)
|
||||
}
|
||||
}
|
||||
|
||||
function toggleImage (img, action, tooltipText) {
|
||||
const parentButton = img.parentNode
|
||||
|
||||
// Style the parent button and image depending on the state.
|
||||
if (action === 'show') {
|
||||
img.src = img.getAttribute('originalSrc')
|
||||
img.style.border = '2px solid var(--color-auto-gray-2)'
|
||||
parentButton.setAttribute('aria-label', tooltipText)
|
||||
parentButton.style.display = 'block'
|
||||
parentButton.style['margin-top'] = '20px'
|
||||
parentButton.style.padding = '10px 0'
|
||||
} else {
|
||||
if (!img.getAttribute('originalSrc')) img.setAttribute('originalSrc', img.src)
|
||||
img.src = placeholderImagePath
|
||||
img.style.border = 'none'
|
||||
parentButton.setAttribute('aria-label', tooltipText)
|
||||
parentButton.style.display = 'inline'
|
||||
parentButton.style['margin-top'] = '0'
|
||||
parentButton.style.padding = '1px 6px'
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
{% include support-section %}
|
||||
{% include small-footer %}
|
||||
{% include scroll-button %}
|
||||
{% include toggle-images %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -19,10 +19,22 @@ img[src*="https://github.githubassets.com/images/icons/emoji"] {
|
||||
align: absmiddle;
|
||||
}
|
||||
|
||||
.markdown-body li img {
|
||||
max-width: calc(100% - 32px);
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
max-height: 600px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body button.btn-toggle-image {
|
||||
border: none;
|
||||
margin-top: 20px;
|
||||
padding: 10px 0;
|
||||
max-width: calc(100% - 32px);
|
||||
background-color: transparent;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.markdown-body button.btn-toggle-image img {
|
||||
padding: 0;
|
||||
max-height: 500px;
|
||||
border: 2px solid var(--color-auto-gray-2);
|
||||
}
|
||||
|
||||
@@ -38,4 +38,5 @@ $marketing-font-path: "/dist/fonts/";
|
||||
@import "summary.scss";
|
||||
@import "syntax-highlighting.scss";
|
||||
@import "tables.scss";
|
||||
@import "toggle-images-button.scss";
|
||||
@import "underline-dashed.scss";
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
button.arrow-for-scrolling-top {
|
||||
opacity: 0;
|
||||
transition: 1s;
|
||||
transition: 0.2s;
|
||||
background-color: var(--color-auto-blue-5);
|
||||
color: var(--color-text-inverse);
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
right: 60px;
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
border: none;
|
||||
transition: 1s;
|
||||
transition: 0.2s;
|
||||
}
|
||||
}
|
||||
|
||||
15
stylesheets/toggle-images-button.scss
Normal file
15
stylesheets/toggle-images-button.scss
Normal file
@@ -0,0 +1,15 @@
|
||||
button.toggle-images {
|
||||
opacity: 1;
|
||||
transition: 0.2s;
|
||||
background-color: var(--color-auto-blue-5);
|
||||
color: var(--color-text-inverse);
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
margin-right: 10px;
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
}
|
||||
Reference in New Issue
Block a user