Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MWPW-136885: More SEO-friendly, improved accessibility in merch cards #1791

Merged
merged 15 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions libs/blocks/merch-card/merch-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ const parseContent = (el, merchCard) => {
const innerElements = [
...el.querySelectorAll('h2, h3, h4, h5, p, ul, em'),
];
let bodySlotName = 'body-xs';
let bodySlotName = `body-${merchCard.variant !== MINI_COMPARE_CHART ? 'xs' : 'm'}`;
let headingMCount = 0;

if (merchCard.variant === MINI_COMPARE_CHART) {
Expand All @@ -160,23 +160,31 @@ const parseContent = (el, merchCard) => {
appendSlot(priceSmallType, 'price-commitment', merchCard);
}

let headingSize = 3;
const bodySlot = createTag('div', { slot: bodySlotName });

innerElements.forEach((element) => {
const { tagName } = element;
let { tagName } = element;
if (isHeadingTag(tagName)) {
let slotName = textStyles[tagName];
if (slotName) {
if (['H2', 'H4', 'H5'].includes(tagName)) {
if (['H2', 'H3', 'H4', 'H5'].includes(tagName)) {
if (tagName === 'H2') {
headingMCount += 1;
}
if (headingMCount === 2 && merchCard.variant === MINI_COMPARE_CHART) {
slotName = 'heading-m-price';
}
tagName = `H${headingSize}`;
headingSize += 1;
}
element.setAttribute('slot', slotName);
merchCard.append(element);
const newElement = createTag(tagName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const newElement = createTag(tagName, element.attributes, element.innerHTML, { parent: merchCard});

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not look like it

Copy link
Member Author

@Axelcureno Axelcureno Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I got confused with the another comment.
I tried doing your suggestion, but it seems element.attributes returns a NamedNodeMap which is not compatible with createTag().
Screenshot 2024-01-26 at 2 36 25 PM

Array.from(element.attributes).forEach((attr) => {
newElement.setAttribute(attr.name, attr.value);
});
newElement.innerHTML = element.innerHTML;
merchCard.append(newElement);
}
return;
}
Expand Down
42 changes: 21 additions & 21 deletions test/blocks/merch-card/merch-card.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ describe('Merch Card', () => {
it('Supports Special Offers card', async () => {
document.body.innerHTML = await readFile({ path: './mocks/special-offers.html' });
const merchCard = await init(document.querySelector('.special-offers'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingOne = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="detail-m"]');
const headingOne = merchCard.querySelector('h4[slot="heading-xs"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const footer = merchCard.querySelector('div[slot="footer"]');
const buttons = footer.querySelectorAll('.con-button');
Expand All @@ -56,8 +56,8 @@ describe('Plans Card', () => {
it('Supports COM Plans card', async () => {
document.body.innerHTML = await readFile({ path: './mocks/plans-card.html' });
const merchCard = await init(document.querySelector('.merch-card.plans.icons.secure'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingOne = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="heading-m"]');
const headingOne = merchCard.querySelector('h4[slot="heading-xs"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const detail = merchCard.querySelector('h5[slot="detail-m"]');
const footer = merchCard.querySelector('div[slot="footer"]');
Expand All @@ -84,8 +84,8 @@ describe('Plans Card', () => {
it('Supports EDU Plans card with stock', async () => {
document.body.innerHTML = await readFile({ path: './mocks/plans-card.html' });
const merchCard = await init(document.querySelector('.merch-card.plans.edu.icons.secure'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingOne = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="heading-m"]');
const headingOne = merchCard.querySelector('h4[slot="heading-xs"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const detail = merchCard.querySelector('h5[slot="detail-m"]');
const footer = merchCard.querySelector('div[slot="footer"]');
Expand All @@ -112,8 +112,8 @@ describe('Plans Card', () => {
it('should skip ribbon and altCta creation', async () => {
document.body.innerHTML = await readFile({ path: './mocks/plans-card.html' });
const merchCard = await init(document.querySelector('.plans.icons.skip-ribbon.skip-altCta'));
const heading = merchCard.querySelector('h2[slot=heading-m]');
const headingXs = merchCard.querySelector('h3[slot=heading-xs]');
const heading = merchCard.querySelector('h3[slot=heading-m]');
const headingXs = merchCard.querySelector('h4[slot=heading-xs]');
const body = merchCard.querySelector('div[slot=body-xs]');
const detail = merchCard.querySelector('h5[slot=detail-m]');
const footer = merchCard.querySelector('div[slot="footer"]');
Expand Down Expand Up @@ -146,8 +146,8 @@ describe('Catalog Card', () => {
it('Supports Catalog card', async () => {
document.body.innerHTML = await readFile({ path: './mocks/catalog.html' });
const merchCard = await init(document.querySelector('.merch-card.ribbon'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingOne = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="heading-m"]');
const headingOne = merchCard.querySelector('h4[slot="heading-xs"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const actionMenu = merchCard.querySelector('div[slot="action-menu-content"]');
const detail = merchCard.querySelector('h5[slot="detail-m"]');
Expand Down Expand Up @@ -175,8 +175,8 @@ describe('Catalog Card', () => {
it('Supports Catalog card without badge', async () => {
document.body.innerHTML = await readFile({ path: './mocks/catalog.html' });
const merchCard = await init(document.querySelector('.merch-card.catalog.empty-badge'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingOne = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="heading-m"]');
const headingOne = merchCard.querySelector('h4[slot="heading-xs"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const actionMenu = merchCard.querySelector('div[slot="action-menu-content"]');
const detail = merchCard.querySelector('h5[slot="detail-m"]');
Expand All @@ -202,8 +202,8 @@ describe('Catalog Card', () => {
it('Supports Catalog card without badge and action-menu', async () => {
document.body.innerHTML = await readFile({ path: './mocks/catalog.html' });
const merchCard = await init(document.querySelector('.merch-card.catalog.empty-action-menu'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingOne = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="heading-m"]');
const headingOne = merchCard.querySelector('h4[slot="heading-xs"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const actionMenu = merchCard.querySelector('div[slot="actionMenuContent"]');
const detail = merchCard.querySelector('h5[slot="detail-m"]');
Expand All @@ -229,8 +229,8 @@ describe('Catalog Card', () => {
it('Supports Catalog card with badge without action-menu', async () => {
document.body.innerHTML = await readFile({ path: './mocks/catalog.html' });
const merchCard = await init(document.querySelector('.merch-card.catalog.empty-badge.action-menu-exist'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingOne = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="heading-m"]');
const headingOne = merchCard.querySelector('h4[slot="heading-xs"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const actionMenu = merchCard.querySelector('div[slot="actionMenuContent"]');
const detail = merchCard.querySelector('h5[slot="detail-m"]');
Expand Down Expand Up @@ -270,10 +270,10 @@ describe('Catalog Card', () => {
it('Supports intro-pricing card', async () => {
document.body.innerHTML = await readFile({ path: './mocks/intro-pricing.html' });
const merchCard = await init(document.querySelector('.merch-card'));
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const headingXs = merchCard.querySelector('h3[slot="heading-xs"]');
const heading = merchCard.querySelector('h3[slot="heading-xs"]');
const headingXs = merchCard.querySelector('h4[slot="heading-m"]');
const body = merchCard.querySelector('div[slot="body-xs"]');
const detailBg = merchCard.querySelector('h4[slot="body-xxs"]');
const detailBg = merchCard.querySelector('h5[slot="body-xxs"]');
const footer = merchCard.querySelector('div[slot="footer"]');
const buttons = footer.querySelectorAll('.con-button');

Expand Down Expand Up @@ -310,9 +310,9 @@ describe('Mini Compare Chart Merch Card', () => {
document.body.innerHTML = await readFile({ path: './mocks/mini-compare-chart.html' });
const merchCard = await init(document.querySelector('.merch-card.mini-compare-chart'));
document.querySelector('.section').removeAttribute('data-status');
const heading = merchCard.querySelector('h2[slot="heading-m"]');
const heading = merchCard.querySelector('h3[slot="heading-m"]');
const body = merchCard.querySelector('div[slot="body-m"]');
const priceHeading = merchCard.querySelector('h2[slot="heading-m-price"]');
const priceHeading = merchCard.querySelector('h4[slot="heading-m-price"]');
const footer = merchCard.querySelector('div[slot="footer"]');
const buttons = footer.querySelectorAll('.con-button');
const footerRows = merchCard.querySelector('div[slot="footer-rows"]');
Expand Down
8 changes: 4 additions & 4 deletions test/blocks/merch-card/mocks/special-offers.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
<source type="image/png" srcset="" media="(min-width: 600px)">
<img loading="lazy" alt="" src="" width="5000" height="2812">
</picture>
<h3 id="individuals">INDIVIDUALS</h3>
<h2 id="get-10-off-photoshop">Get 10% off Photoshop.</h2>
<h5 id="individuals">INDIVIDUALS</h5>
<h3 id="get-10-off-photoshop">Get 10% off Photoshop.</h3>
<p>Create gorgeous images, rich graphics, and incredible art. Save 10% for the first year. Ends Mar 20.</p>
<p><a href="https://adobe.com/">See terms</a></p>
<p><em><a href="https://business.adobe.com/">Learn More</a></em> <strong><a href="https://business.adobe.com/">Save now</a></strong></p>
Expand All @@ -33,8 +33,8 @@ <h2 id="get-10-off-photoshop">Get 10% off Photoshop.</h2>
<source type="image/png" srcset="" media="(min-width: 600px)">
<img loading="lazy" alt="" src="" width="5000" height="2812">
</picture>
<h3 id="individuals1">INDIVIDUALS</h3>
<h2 id="get-10-off-photoshop1">Get 10% off Photoshop.</h2>
<h5 id="individuals1">INDIVIDUALS</h5>
<h3 id="get-10-off-photoshop1">Get 10% off Photoshop.</h3>
<p>Create gorgeous images, rich graphics, and incredible art. Save 10% for the first year. Ends Mar 20.</p>
<p><strong>Best for</strong>:</p>
<p><a href="https://adobe.com/">See terms</a></p>
Expand Down
Loading