Make reading list button hover effect compatible with a11y (#2759) [ci skip]

This commit is contained in:
rhymes 2019-05-08 18:46:39 +02:00 committed by Mac Siri
parent 0690479bb9
commit f2a0314298
8 changed files with 77 additions and 40 deletions

View file

@ -7,12 +7,13 @@
function initializeReadingListIcons() {
setReadingListButtonsState();
addReadingListCountToHomePage();
addHoverEffectToReadingListButtons();
}
// set SAVE or SAVED articles buttons
function setReadingListButtonsState() {
var readingListButtons = document.getElementsByClassName('bookmark-engage');
Array.from(readingListButtons).forEach(button => highlightButton(button));
Array.from(readingListButtons).forEach(highlightButton);
}
// private
@ -75,6 +76,7 @@ function reactToReadingListButtonClick(event) {
function renderButtonState(button, json) {
if (json.result === 'create') {
button.classList.add('selected');
addHoverEffectToReadingListButton(button);
} else {
button.classList.remove('selected');
}
@ -116,6 +118,60 @@ function properButtonFromEvent(event) {
return properElement;
}
/*
Add the hover effect to reading list buttons.
This function makes use of mouseover/mouseevent bubbling behaviors to attach
only two event handlers to the articles container for performance reasons.
*/
function addHoverEffectToReadingListButtons() {
var articlesList = document.getElementsByClassName('articles-list');
Array.from(articlesList).forEach(function(container) {
// we use `bind` so that the event handler will have the correct text in its
// `this` local variable
container.addEventListener(
'mouseover',
readingListButtonMouseHandler.bind('UNSAVE'),
);
container.addEventListener(
'mouseout',
readingListButtonMouseHandler.bind('SAVED'),
);
});
}
/*
Determines if the element is the target of the reading list button hover.
*/
function isReadingListButtonHoverTarget(element) {
var classList = element.classList;
return (
(element.tagName === 'BUTTON' &&
classList.contains('bookmark-engage') &&
classList.contains('selected')) ||
(element.tagName === 'SPAN' && classList.contains('bm-success'))
);
}
function readingListButtonMouseHandler(event) {
var target = event.target;
if (isReadingListButtonHoverTarget(target)) {
event.preventDefault();
var textReplacement = this; // `this` is the text to be replaced
var textSpan;
if (target.tagName === 'BUTTON') {
textSpan = target.getElementsByClassName('bm-success')[0];
} else {
textSpan = target;
}
textSpan.innerHTML = textReplacement;
}
}
/* eslint-enable no-use-before-define */
/* eslint-enable no-undef */
/* eslint-enable func-names */

View file

@ -77,15 +77,15 @@ function buildArticleHTML(article) {
}
var saveButton = '';
if (article.class_name === "Article") {
var saveButton = '<button class="article-engagement-count bookmark-engage" data-reactable-id="'+article.id+'">\
<span class="bm-success"></span>\
<span class="bm-initial"></span>\
</button>'
saveButton = '<button class="article-engagement-count bookmark-engage" data-reactable-id="'+article.id+'">\
<span class="bm-initial">SAVE</span>\
<span class="bm-success">SAVED</span>\
</button>'
} else if (article.class_name === "User") {
var saveButton = '<button style="width: 122px" class="article-engagement-count bookmark-engage follow-action-button"\
saveButton = '<button style="width: 122px" class="article-engagement-count bookmark-engage follow-action-button"\
data-info=\'{"id":'+article.id+',"className":"User"}\' data-follow-action-button>\
&nbsp;\
</button>'
</button>'
}
var publishDate = '';

View file

@ -747,11 +747,6 @@
position: relative;
top: 1px;
}
.bm-initial {
&:after {
content: 'SAVE';
}
}
&.selected {
color: darken($purple, 33%);
background: transparent;
@ -761,14 +756,6 @@
}
.bm-success {
display: inline-block;
&:before {
content: 'SAVED';
}
&:hover:before {
content: 'UNSAVE';
}
}
}
&.following-butt {

View file

@ -20,24 +20,18 @@
</div>
<div class="sidebar-nav-element">
<a class="sidebar-nav-link" href="/readinglist?we-hope-you-like-the-new-and-improved-reading-list---more-positive-changes-coming=woohoo">
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-bookmark.png") %>" /> Reading List
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-bookmark.png") %>" alt="reading list icon" /> Reading List
<span id="reading-list-count"></span>
</a>
<a class="sidebar-nav-link" href="/listings">
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-clipboard.png") %>" /> Listings
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-clipboard.png") %>" alt="listings icon" /> Listings
</a>
<a class="sidebar-nav-link" href="/videos">
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-videocamera.png") %>" /> Videos
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-videocamera.png") %>" alt="videos icon" /> Videos
</a>
<a class="sidebar-nav-link" href="/pod">
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-headphones.png") %>" /> Podcasts
<img class="nav-emoji" src="<%= asset_path("emoji/emoji-one-headphones.png") %>" alt="podcasts icon" /> Podcasts
</a>
<% if 1==2 #not for display yet %>
<a class="sidebar-nav-link" href="/listings">
listings
<span id="reading-list-count"></span>
</a>
<% end %>
</div>
<% end %>
<div class="sidebar-nav-header sidebar-nav-header-middle">

View file

@ -59,7 +59,7 @@
data-reactable-id="<%= story.id %>"
aria-label="Save to reading list"
title="Save to reading list">
<span class="bm-success"></span>
<span class="bm-initial"></span>
<span class="bm-initial">SAVE</span>
<span class="bm-success">SAVED</span>
</button>
</div>

View file

@ -130,8 +130,8 @@
data-reactable-id="<%= @featured_story.id %>"
aria-label="Add to reading list"
title="Add to reading list">
<span class="bm-success"></span>
<span class="bm-initial"></span>
<span class="bm-initial">SAVE</span>
<span class="bm-success">SAVED</span>
</button>
</div>
</a>

View file

@ -3,9 +3,9 @@
<div class="top-bar" id="top-bar">
<nav>
<div id="pwa-nav-buttons" class="pwa-nav-buttons">
<button id="app-back-button"><img src="<%= asset_path("keyboard-left-arrow-button.svg") %>" /></button>
<button id="app-forward-button"><img src="<%= asset_path("keyboard-right-arrow-button.svg") %>" /></button>
<button id="app-refresh-button"><img src="<%= asset_path("refresh-button.svg") %>" /></button>
<button id="app-back-button"><img src="<%= asset_path("keyboard-left-arrow-button.svg") %>" alt="back icon" /></button>
<button id="app-forward-button"><img src="<%= asset_path("keyboard-right-arrow-button.svg") %>" alt="forward icon" /></button>
<button id="app-refresh-button"><img src="<%= asset_path("refresh-button.svg") %>" alt="refresh icon" /></button>
</div>
<a href="#articles-list" class="skip-content-link">Skip to content</a>
<a href="/" class="logo-link" id="logo-link" aria-label="<%= ApplicationConfig["COMMUNITY_NAME"] %> Home"><%= logo_svg %></a>

View file

@ -26,7 +26,7 @@
margin: auto;
max-width: 1250px;
}
@media screen and (min-width: 950px) {
.home {
margin-top: 26px;
@ -97,8 +97,8 @@
<%= render "layouts/signup_modal" unless user_signed_in? %>
<% end %>
<div id="live-article-indicator" class="live-article-indicator"></div>
<%= image_tag("twitter-logo.svg", class: "icon-img", style: "display:none") %>
<%= image_tag("github-logo.svg", class: "icon-img", style: "display:none") %>
<%= image_tag("twitter-logo.svg", class: "icon-img", style: "display:none", alt: "twitter logo") %>
<%= image_tag("github-logo.svg", class: "icon-img", style: "display:none", alt: "github logo") %>
<% end %>
</body>
</html>