Skip to content

Commit

Permalink
Merge pull request #33 from khiga8/kh-image-validation
Browse files Browse the repository at this point in the history
Don't allow empty alt attribute
  • Loading branch information
khiga8 authored Jul 11, 2022
2 parents 51a6ed2 + 997869e commit f394b98
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 38 deletions.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This is a browser extension that runs a simple JavaScript snippet on github.com
4. Select "Load unpacked".
5. Choose this unzipped repo folder.
6. Navigate to github.com.
7. **Optional but recommended**: Set custom styles to your preference. Learn more in [Customization note](#customization-note).
7. **Optional but recommended**: Set custom styles to your preference. Learn more in the [Customization note](#customization-note).

### Firefox

Expand All @@ -21,17 +21,19 @@ This is a browser extension that runs a simple JavaScript snippet on github.com
3. Select `Load Temporary Add-on...`.
4. Choose a file in the repository directory.
5. Navigate to github.com.
6. **Optional but recommended**: Set custom styles to your preference. Learn more in [Customization note](#customization-note).
6. **Optional but recommended**: Set custom styles to your preference. Learn more in the [Customization note](#customization-note).

## Features

This extension will only run on GitHub domain and does the folowing on all markdown bodies on GitHub:
This extension will only run on GitHub domain and does the following on all markdown bodies on GitHub:

- Creates a text overlay over all images with the alt text. This includes Pull Requests, Issues, Repo READMEs, and Discussions. If an image is missing an alt text, it will appear with a red border. If an image has an empty alt text, the text will show with italicized caption, *hidden*. This image overlay aims to bring awareness about alt text particularly for sighted users who may not rely on alt text.
- Creates a text overlay over all images with the alt text. This includes Pull Requests, Issues, Repo READMEs, and Discussions.
- If an image is missing an alt text, it will appear with a red border.
- **If an image has an empty string alt like `""`, it will also appear with a red border**. Typically, an empty string alt indicates that an image is decorative and should be hidden. However, on GitHub, all markdown images are rendered within a link element. Therefore, we recommend that all images in GitHub markdown have an alt text provided or the link will be announced without a bane,

<img width="600" alt="Example screenshots of two images that have been posted on a GitHub issue, each appearing with alt text overlay. The first has unhelpful alt text based off the filename, `Screen Shot 2022-02-10` while the second image has a more intentional alt text, `Screenshot of example select menu...`." src="https://user-images.githubusercontent.com/16447748/154407948-1d02f35f-52ce-49ed-b098-e3528018230b.png">
<img width="600" alt="Example screenshots of two images that have been posted on a GitHub issue, each appearing with alt text overlay. The first has unhelpful alt text based on the filename, `Screen Shot 2022-02-10` while the second image has a more intentional alt text, `Screenshot of example select menu...`." src="https://user-images.githubusercontent.com/16447748/154407948-1d02f35f-52ce-49ed-b098-e3528018230b.png">

- Appends the heading level that is used after the heading text within markdown bodies. Heading levels are useful for conveying semantics for screen reader, and other assistive technology users. This similarly aims to bring mindfulness particularly for sighted users who may pay less attention to heading level semantics.
- Appends the heading level that is used after the heading text within markdown bodies. Heading levels are useful for conveying semantics for screenreader, and other assistive technology users. This similarly aims to bring mindfulness particularly for sighted users who may pay less attention to heading level semantics.

<img width="600" alt="Example screenshots of heading levels appended at end of heading text line inside a GitHub markdown, each represented by a different color" src="https://user-images.githubusercontent.com/16447748/154763325-57ad4785-691c-4760-b0ca-b2e3cabacd1f.png">

Expand All @@ -40,7 +42,7 @@ This extension will only run on GitHub domain and does the folowing on all markd

The styling I've set may not be suitable for all users. Feel free to customize these however you like when you download these files.

You can do this by modifying `styles.css`. There are CSS variables at the top which you may set to your preference. For example, you may choose to set a different color for each heading level or remove the border. If you'd prefer the headings to be positioned at front, follow the notes in `contentScript.js`. Once changes are made, `Update` on `chrome://extensions/` so changes are reflected in extension.
You can do this by modifying `styles.css`. There are CSS variables at the top which you may set to your preference. For example, you may choose to set a different color for each heading level or remove the border. If you'd prefer the headings to be positioned at the front, follow the notes in `contentScript.js`. Once changes are made, `Update` on `chrome://extensions/` so changes are reflected in the extension.

## Resources

Expand All @@ -55,4 +57,5 @@ You can do this by modifying `styles.css`. There are CSS variables at the top wh

## Bug?

This extension may break if GitHub markup changes.
If you encounter a bug, please file a ticket. Contributions welcome.
86 changes: 55 additions & 31 deletions contentScript.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/* ATTENTION: Based on heading position preference, swap `addHeadingToBack` with `addHeadingToFront` in line 45. */

/* Places heading at end of line */
/* Default. Places heading at end of line */
function addHeadingToBack(heading, headingPrefix) {
headingPrefix.classList.add('github-a11y-heading-prefix', 'github-a11y-heading-prefix-after');
headingPrefix.textContent = ` ${heading.tagName.toLowerCase()}`;
Expand All @@ -16,41 +14,25 @@ function addHeadingToFront(heading, headingPrefix) {
heading.insertBefore(headingPrefix, heading.firstChild);
}

/* Append accessibility info to DOM */
function appendAccessibilityInfo() {
const elements = document.querySelectorAll('.github-a11y-heading-prefix, .github-a11y-img-caption')
for (const element of elements) {
const outdatedElements = document.querySelectorAll('.github-a11y-heading-prefix, .github-a11y-img-caption')
for (const element of outdatedElements) {
element.remove();
}

document.querySelectorAll('.markdown-body').forEach(function(commentBody) {
// Adds alt image overlay. This is hidden from accesibility tree.
commentBody.querySelectorAll('img').forEach(function(image) {
let altText = image.getAttribute('alt');
if (!image.hasAttribute('alt')) {
image.classList.add('github-a11y-img-missing-alt')
} else {
const parentElement = image.parentElement;
if (!parentElement) return;

const subtitle = document.createElement('span');
subtitle.classList.add('github-a11y-img-caption');

if (altText === "") {
altText = "hidden"
subtitle.classList.add('github-a11y-img-caption-empty-alt')
} else {
subtitle.classList.add('github-a11y-img-caption-with-alt');
}
parentElement.classList.add('github-a11y-img-container');

subtitle.setAttribute('aria-hidden', 'true');
subtitle.textContent = altText;

image.insertAdjacentElement('afterend', subtitle);
}
const parent = image.closest('a');
if (!parent || image.closest('animated-image')) return

validateImages(parent, image)
});

commentBody.querySelectorAll('animated-image').forEach(function(animatedImage) {
validateImagesInsideAnimatedPlayer(animatedImage)
});

// Appends heading level to headings. This is hidden from accesibility tree
commentBody.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(function(heading) {
const headingPrefix = document.createElement('span');
headingPrefix.setAttribute('aria-hidden', 'true');
Expand All @@ -60,6 +42,48 @@ function appendAccessibilityInfo() {
});
}

function validateImages(parent, image) {
const altText = image.getAttribute('alt') ? image.getAttribute('alt').trim() : "";
const parentAriaLabel = parent.getAttribute('aria-label') && parent.getAttribute('aria-label').trim()

if (!image.hasAttribute('alt') || altText === "" && !parentAriaLabel) {
image.classList.add('github-a11y-img-missing-alt')
} else {
const subtitle = createSubtitleElement();
parent.classList.add('github-a11y-img-container');

if (parentAriaLabel) {
subtitle.textContent = parentAriaLabel;
} else {
subtitle.textContent = altText;
}

image.insertAdjacentElement('afterend', subtitle);
}
}

function createSubtitleElement() {
const subtitle = document.createElement('span');
subtitle.setAttribute('aria-hidden', 'true');
subtitle.classList.add('github-a11y-img-caption', 'github-a11y-img-caption-with-alt');

return subtitle
}

function validateImagesInsideAnimatedPlayer(animatedImage) {
const image = animatedImage.querySelector('img');
const altText = image.getAttribute('alt') ? image.getAttribute('alt').trim() : "";

if (!image.hasAttribute('alt') || altText === "") {
animatedImage.classList.add('github-a11y-img-missing-alt')
} else {
const subtitle = createSubtitleElement();
subtitle.textContent = altText;
animatedImage.classList.add('github-a11y-img-container');
animatedImage.appendChild(subtitle);
}
}

/* Listen for messages from the background script */
chrome.runtime.onMessage.addListener(() => {
appendAccessibilityInfo();
Expand All @@ -74,7 +98,7 @@ let observer = new MutationObserver(function(mutationList) {
timer = setTimeout(() => {
for (const mutation of mutationList) {
observer.disconnect();
if (mutation.target.closest('.markdown-body')) {
if (mutation.target.closest('.markdown-body, .js-commit-preview')) {
appendAccessibilityInfo();
}
observe();
Expand Down

0 comments on commit f394b98

Please sign in to comment.