Skip to content

Commit

Permalink
Feat(MWPW-146367):Added accessibility player controls (NON MPC) (#3053)
Browse files Browse the repository at this point in the history
* updated feature with accessibility code

* video accessiblity added for carousels

* added opt-out functionality

* fixed linting errors

* fixed unit test cases

* fixed adobe tv issue

* hover and focus added

* controls positioned for rtl

* hide-controls hash params added

* how to block controls position bug fix

* dark mode|bug fixes

* code enhancement

* pause-play bug mouse click bug fix

* marquee dark mode|positioning fix

* code enhancement

* handled marquee backward compatiblity

* Added placeholder for labels|indexed video aria-labels

* aria-label added for hover play videos

* async awaited decorateVideo in video.js and other linting errors

* video indexes added

* random video index and unit test cases updated

* daa-ll is synced along with aria-label

* code enhancement

* nala test fix|code coverege

* nala test bug fix

* nala test fix

* right-left positioning is done for screens > 600px and a img fix

* getFedsconfig moved to feds file|url fetched from fedRoot function

* linting fix

* icons adapted to the figma

* carousel and how-to fix with other minor fixes

* playpause wrapper adjusted for window

* icon offset bug fix

* indentation of string literal

* figma match

* figma focus match
  • Loading branch information
sharath-kannan authored Dec 4, 2024
1 parent f8e87ab commit 6e4138c
Show file tree
Hide file tree
Showing 27 changed files with 493 additions and 78 deletions.
1 change: 1 addition & 0 deletions libs/blocks/adobetv/adobetv.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import url('../../styles/iframe.css');
@import url('../video/video.css');

a[href*='.mp4'].hide-video {
visibility: hidden !important;
Expand Down
1 change: 1 addition & 0 deletions libs/blocks/aside/aside.css
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
}

.aside.rounded-corners .foreground .image img,
.aside.rounded-corners .foreground .image:not(:has(.video-container)) .pause-play-wrapper,
.aside.rounded-corners .foreground .image video {
border-radius: 16px;
}
Expand Down
4 changes: 2 additions & 2 deletions libs/blocks/aside/aside.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ function decorateLayout(el) {
}
const foregroundImage = foreground.querySelector(':scope > div:not(.text) img')?.closest('div');
const bgImage = el.querySelector(':scope > div:not(.text):not(.foreground) img')?.closest('div');
const foregroundMedia = foreground.querySelector(':scope > div:not(.text) video, :scope > div:not(.text) a:is([href*=".mp4"], [href*="tv.adobe.com"]), :scope > div:not(.text) iframe[src*="tv.adobe.com"]')?.closest('div');

const foregroundMedia = foreground.querySelector(':scope > div:not(.text) :is(.video-container, video, a[href*=".mp4"], a[href*="tv.adobe.com"]), :scope > div:not(.text) iframe[src*="tv.adobe.com"]')
?.closest('div:not(.video-container)');
const bgMedia = el.querySelector(':scope > div:not(.text):not(.foreground) video, :scope > div:not(.text):not(.foreground) a:is([href*=".mp4"], [href*="tv.adobe.com"])')?.closest('div');
const image = foregroundImage ?? bgImage;
const asideMedia = foregroundMedia ?? bgMedia ?? image;
Expand Down
9 changes: 9 additions & 0 deletions libs/blocks/brick/brick.css
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@
margin: 0;
}

.brick .foreground div > .video-container {
margin: 0;
}

.brick .foreground div > * {
margin-top: var(--spacing-xs);
}
Expand Down Expand Up @@ -342,6 +346,11 @@
position: absolute;
}

.brick.split.row .foreground .brick-media .video-container img,
.brick.split.row .foreground .brick-media .video-container video {
width: 100%;
}

.brick .foreground .brick-media video,
.brick.split.row .foreground .brick-media video {
object-fit: fill;
Expand Down
2 changes: 1 addition & 1 deletion libs/blocks/carousel/carousel.css
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ html[dir="rtl"] .carousel-slides .section.carousel-slide {
overflow: hidden;
}

.carousel .carousel-slide > div p > video {
.carousel .carousel-slide > div p :is(.video-holder, video) {
width: 100%;
height: auto;
}
Expand Down
8 changes: 5 additions & 3 deletions libs/blocks/carousel/carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ function moveSlides(event, carouselElements, jumpToIndex) {
referenceSlide.classList.remove('reference-slide');
referenceSlide.style.order = null;
activeSlide.classList.remove('active');
activeSlide.querySelectorAll('a').forEach((focusableElement) => { focusableElement.setAttribute('tabindex', -1); });
activeSlide.querySelectorAll('a, video').forEach((focusableElement) => focusableElement.setAttribute('tabindex', -1));
activeSlideIndicator.classList.remove('active');
activeSlideIndicator.setAttribute('tabindex', -1);

Expand Down Expand Up @@ -230,10 +230,12 @@ function moveSlides(event, carouselElements, jumpToIndex) {
if (index < show) {
tabIndex = 0;
}
slide.querySelectorAll('a').forEach((focusableElement) => { focusableElement.setAttribute('tabindex', tabIndex); });
slide.querySelectorAll('a,:not(.video-container, .pause-play-wrapper) > video')
.forEach((focusableElement) => { focusableElement.setAttribute('tabindex', tabIndex); });
});
} else {
activeSlide.querySelectorAll('a').forEach((focusableElement) => { focusableElement.setAttribute('tabindex', 0); });
activeSlide.querySelectorAll('a,:not(.video-container, .pause-play-wrapper) > video')
.forEach((focusableElement) => { focusableElement.setAttribute('tabindex', 0); });
}
activeSlideIndicator.classList.add('active');
activeSlideIndicator.setAttribute('tabindex', 0);
Expand Down
10 changes: 7 additions & 3 deletions libs/blocks/figure/figure.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { applyHoverPlay, decorateAnchorVideo } from '../../utils/decorate.js';
import { applyHoverPlay, decorateAnchorVideo, applyAccessibilityEvents, decoratePausePlayWrapper, isVideoAccessible } from '../../utils/decorate.js';
import { createTag } from '../../utils/utils.js';

function buildCaption(pEl) {
Expand Down Expand Up @@ -31,7 +31,11 @@ function decorateVideo(clone, figEl) {
);
}
applyHoverPlay(videoTag);
figEl.prepend(videoTag);
if (!videoTag.controls && isVideoAccessible(anchorTag)) {
applyAccessibilityEvents(videoTag);
decoratePausePlayWrapper(videoTag, 'autoplay');
}
figEl.prepend(clone.querySelector('.video-container, .pause-play-wrapper, video'));
}
}

Expand Down Expand Up @@ -68,7 +72,7 @@ export function buildFigure(blockEl) {
const link = clone.querySelector('a');
if (link) {
const img = figEl.querySelector('picture') || figEl.querySelector('video');
if (img) {
if (img && !link.classList.contains('pause-play-wrapper')) {
// wrap picture or video in A tag
link.textContent = '';
link.append(img);
Expand Down
3 changes: 1 addition & 2 deletions libs/blocks/global-footer/global-footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
} from '../../utils/utils.js';

import {
getFedsPlaceholderConfig,
getExperienceName,
getAnalyticsValue,
loadDecorateMenu,
Expand All @@ -23,7 +22,7 @@ import {
isDarkMode,
} from '../global-navigation/utilities/utilities.js';

import { getFederatedUrl } from '../../utils/federated.js';
import { getFederatedUrl, getFedsPlaceholderConfig } from '../../utils/federated.js';

import { replaceKey } from '../../features/placeholders.js';

Expand Down
3 changes: 2 additions & 1 deletion libs/blocks/global-navigation/features/profile/dropdown.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getConfig } from '../../../../utils/utils.js';
import { toFragment, getFedsPlaceholderConfig, trigger, closeAllDropdowns, logErrorFor } from '../../utilities/utilities.js';
import { toFragment, trigger, closeAllDropdowns, logErrorFor } from '../../utilities/utilities.js';
import { replaceKeyArray } from '../../../../features/placeholders.js';
import { getFedsPlaceholderConfig } from '../../../../utils/federated.js';

const getLanguage = (ietfLocale) => {
if (!ietfLocale.length) return 'en';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
toFragment,
getFedsPlaceholderConfig,
isDesktop,
setCurtainState,
trigger,
Expand All @@ -10,6 +9,7 @@ import {
import { replaceKeyArray } from '../../../../features/placeholders.js';
import { getConfig } from '../../../../utils/utils.js';
import { debounce } from '../../../../utils/action.js';
import { getFedsPlaceholderConfig } from '../../../../utils/federated.js';

const CONFIG = {
suggestions: {
Expand Down
6 changes: 3 additions & 3 deletions libs/blocks/global-navigation/global-navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
getActiveLink,
getAnalyticsValue,
getExperienceName,
getFedsPlaceholderConfig,
hasActiveLink,
isActiveLink,
icons,
Expand All @@ -40,6 +39,7 @@ import {
setDisableAEDState,
getDisableAEDState,
} from './utilities/utilities.js';
import { getFedsPlaceholderConfig } from '../../utils/federated.js';

import { replaceKey, replaceKeyArray } from '../../features/placeholders.js';

Expand Down Expand Up @@ -679,7 +679,7 @@ class Gnav {

return this.loadDelayed().then(() => {
this.blocks.search.instance = new this.Search(this.blocks.search.config);
}).catch(() => {});
}).catch(() => { });
};

isToggleExpanded = () => this.elements.mobileToggle?.getAttribute('aria-expanded') === 'true';
Expand Down Expand Up @@ -773,7 +773,7 @@ class Gnav {
if (allSvgImgs.length === 2) return allSvgImgs[1];

const images = blockLinks.filter((blockLink) => imgRegex.test(blockLink.href)
|| imgRegex.test(blockLink.textContent));
|| imgRegex.test(blockLink.textContent));
if (images.length === 2) return getBrandImage(images[1], isBrandImage);
}
const svgImg = rawBlock.querySelector('picture img[src$=".svg"]');
Expand Down
20 changes: 1 addition & 19 deletions libs/blocks/global-navigation/utilities/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import {
getConfig, getMetadata, loadStyle, loadLana, decorateLinks, localizeLink,
} from '../../../utils/utils.js';
import { getFederatedContentRoot, getFederatedUrl } from '../../../utils/federated.js';
import { getFederatedContentRoot, getFederatedUrl, getFedsPlaceholderConfig } from '../../../utils/federated.js';
import { processTrackingLabels } from '../../../martech/attributes.js';
import { replaceText } from '../../../features/placeholders.js';

Expand Down Expand Up @@ -108,24 +108,6 @@ export const federatePictureSources = ({ section, forceFederate } = {}) => {
});
};

let fedsPlaceholderConfig;
export const getFedsPlaceholderConfig = ({ useCache = true } = {}) => {
if (useCache && fedsPlaceholderConfig) return fedsPlaceholderConfig;

const { locale, placeholders } = getConfig();
const libOrigin = getFederatedContentRoot();

fedsPlaceholderConfig = {
locale: {
...locale,
contentRoot: `${libOrigin}${locale.prefix}/federal/globalnav`,
},
placeholders,
};

return fedsPlaceholderConfig;
};

export function getAnalyticsValue(str, index) {
if (typeof str !== 'string' || !str.length) return str;

Expand Down
2 changes: 1 addition & 1 deletion libs/blocks/hero-marquee/hero-marquee.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export default async function init(el) {
foreground.classList.add('foreground', `cols-${fRows.length}`);
let copy = fRows[0];
const anyTag = foreground.querySelector('p, h1, h2, h3, h4, h5, h6');
const asset = foreground.querySelector('div > picture, div > video, div > a[href*=".mp4"], div > a.image-link');
const asset = foreground.querySelector('div > picture, :is(.video-container, .pause-play-wrapper), div > video, div > a[href*=".mp4"], div > a.image-link');
const allRows = foreground.querySelectorAll('div > div');
copy = anyTag.closest('div');
copy.classList.add('copy');
Expand Down
2 changes: 1 addition & 1 deletion libs/blocks/how-to/how-to.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const setJsonLd = (heading, description, mainImage, stepsLd) => {
};

const getImage = (el) => el.querySelector('picture') || el.querySelector('a[href$=".svg"');
const getVideo = (el) => el.querySelector('video') || el.querySelector('.milo-video');
const getVideo = (el) => el.querySelector('.video-container, .pause-play-wrapper, video, .milo-video');

const getHowToInfo = (el) => {
const infoDiv = el.querySelector(':scope > div > div');
Expand Down
2 changes: 1 addition & 1 deletion libs/blocks/marquee/marquee.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function decorateSplit(el, foreground, media) {

let mediaCreditInner;
const txtContent = media?.lastChild?.textContent?.trim();
if (txtContent?.match(/^http.*\.mp4/) || media?.lastChild?.tagName === 'VIDEO') return;
if (txtContent?.match(/^http.*\.mp4/) || media?.lastChild?.tagName === 'VIDEO' || media.querySelector('.video-holder video')) return;
if (txtContent) {
mediaCreditInner = createTag('p', { class: 'body-s' }, txtContent);
} else if (media.lastElementChild?.tagName !== 'PICTURE') {
Expand Down
149 changes: 149 additions & 0 deletions libs/blocks/video/video.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,153 @@ a[href*='.mp4'].hide-video {
video {
max-width: 100%;
height: auto;
object-fit: cover;
}

:is(.marquee, .aside.split) .pause-play-wrapper img.accessibility-control {
min-height: 40px;
}

.video-container {
display: flex;
position: relative;
height: 100%;
width: fit-content;
margin: auto;
}

:is(.aside, .marquee, .quiz-marquee) .video-container {
width: auto;
}

.brick-media .video-container {
width: 100%;
height: 100%;
border-radius: inherit;
}

.pause-play-wrapper {
display: flex;
width: fit-content;
margin: auto;
}

.video-container .pause-play-wrapper {
position: absolute;
bottom: 2%;
right: 2%;
margin: 0;
justify-content: center;
align-items: center;
border-radius: 50%;
z-index: 2;
padding: 3px;
cursor: pointer;
}

.video-container .pause-play-wrapper .offset-filler {
display: inherit;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: inherit;
background: var(--color-gray-800);
}

:is(.marquee:not(.light), .dark) .video-container .pause-play-wrapper {
padding: 1px;
}

:is(.marquee:not(.light), .dark) .video-container .pause-play-wrapper:focus-visible {
background: #000;
}

:is(.marquee:not(.light), .dark) .video-container .pause-play-wrapper .offset-filler {
border: 2px solid #fff;
}

.video-container .pause-play-wrapper:focus-visible {
background: #fff;
}

.video-container .pause-play-wrapper .offset-filler:hover {
background: #000;
}

.video-container .pause-play-wrapper:focus-visible {
outline: var(--color-accent-focus-ring) solid 2px;
}

.video-container .pause-play-wrapper .offset-filler.is-playing .play-icon,
.video-container .pause-play-wrapper .offset-filler:not(.is-playing) .pause-icon {
display: none;
}

:is(.editorial-card, .hero-marquee, .marquee):not(:has(.video-container)) .pause-play-wrapper,
.editorial-card .video-container {
width: auto;
height: 100%;
}

.brick .brick-media:not(:has(.video-container)) .pause-play-wrapper {
border-radius: 0;
border-top-right-radius: inherit;
border-bottom-right-radius: inherit;
width: auto;
height: 100%;
margin: 0;
}

[dir="rtl"] .brick .brick-media:not(:has(.video-container)) .pause-play-wrapper {
border-top-left-radius: inherit;
border-bottom-left-radius: inherit;
}

.hero-marquee .background .video-container {
position: inherit;
}

:is(.video-container .pause-play-wrapper, .aside.split.split-left .split-image) img.accessibility-control {
width: auto;
}

.video-container .pause-play-wrapper img.hidden {
display: none;
}

.marquee .background .video-container {
display: contents;
}

.how-to .how-to-media .video-container {
height: fit-content;
}

@media (min-width: 600px) {
.media:not(.media-reverse-mobile, .media-reversed) .video-container .pause-play-wrapper,
:is(.marquee.row-reversed .asset, .marquee-anchors, .hero-marquee.asset-left) .video-container .pause-play-wrapper,
:is(.aside:not(.split), .aside.split.split-right) .video-container .pause-play-wrapper {
left: 2%;
}

:is(.section[class*="-up"] .media .foreground .image:first-child, .aside .foreground .image:nth-last-child(1))
.video-container .pause-play-wrapper {
left: auto;
right: 2%;
}

[dir="rtl"] :is(.marquee.split:not(.row-reversed), .media:is(.media-reverse-mobile, .media-reversed),
.hero-marquee:not(.asset-left) :is([class*="foreground"]), .aside.split:not(.split-right),
.aside .foreground.container .image:nth-last-child(1), .brick.media-right, .how-to) .video-container .pause-play-wrapper {
left: 2%;
right: auto;
}
}

@media (min-width: 600px) and (max-width: 1199px) {
.hero-marquee.asset-left .video-container.video-holder .pause-play-wrapper {
left: auto;
right: 2%;
}
}
Loading

0 comments on commit 6e4138c

Please sign in to comment.