From 36e869f0355a4a46bacfeac37d0e6820bf6807dc Mon Sep 17 00:00:00 2001 From: Sean Archibeque Date: Thu, 7 Nov 2024 11:44:38 -0700 Subject: [PATCH 1/9] MWPW-160360 - Decorate standalone text with body default styles (#3060) * style wrappers when no nested elements * better logic and check for text nodes in elements * dialing in util * keep contains text function in decorate js * use is magic in emtpy elements selector * simplify el contains text function * early return in block text decorator * codecov on decorate block text * adjust decorate and marquee anchors to hopefully pass tests * style wrappers when no nested elements * better logic and check for text nodes in elements * dialing in util * keep contains text function in decorate js * use is magic in emtpy elements selector * simplify el contains text function * early return in block text decorator * codecov on decorate block text * adjust decorate and marquee anchors to hopefully pass tests * fix marquee anchors for nala --- .../blocks/marquee-anchors/marquee-anchors.js | 10 ++++------ libs/utils/decorate.js | 20 ++++++++++++------- test/blocks/text/mocks/body.html | 13 ++++++++++++ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/libs/blocks/marquee-anchors/marquee-anchors.js b/libs/blocks/marquee-anchors/marquee-anchors.js index 7594d1b02b..8f66bc7817 100644 --- a/libs/blocks/marquee-anchors/marquee-anchors.js +++ b/libs/blocks/marquee-anchors/marquee-anchors.js @@ -54,11 +54,11 @@ export default function init(el) { decorateBlockText(copy, blockTypeSizes.default[size]); const links = createTag('div', { class: 'links' }, list); const foreground = createTag('div', { class: 'foreground' }, copy); - decorateBlockText(links, blockTypeSizes.default.xsmall); foreground.append(links); el.append(foreground); - [...list].forEach((i) => { + [...list].forEach((i, index) => { + decorateBlockText(i, blockTypeSizes.default.xsmall); const aTag = i.querySelector('a'); if (aTag?.textContent.charAt(0) === '#') { const content = i.querySelector(':scope > div'); @@ -73,12 +73,10 @@ export default function init(el) { } else { aTag.classList.add('external'); } + } else { + i.classList.add(`links-${index === 0 ? 'header' : 'footer'}`); } }); - const emptyLinkRows = links.querySelectorAll(':scope > div:not([class])'); - if (emptyLinkRows[0]) emptyLinkRows[0].classList.add('links-header'); - if (emptyLinkRows[1]) emptyLinkRows[1].classList.add('links-footer', 'body-s'); - decorateBlockText(emptyLinkRows[0], blockTypeSizes.default.xsmall); const anchors = el.querySelectorAll('.anchor-link'); if (anchors.length) decorateAnchors(anchors); diff --git a/libs/utils/decorate.js b/libs/utils/decorate.js index d794ba14e9..36e23dd055 100644 --- a/libs/utils/decorate.js +++ b/libs/utils/decorate.js @@ -65,9 +65,16 @@ export function decorateIconArea(el) { }); } +function elContainsText(el) { + return [...el.childNodes].some(({ nodeType, innerText, textContent }) => ( + (nodeType === Node.ELEMENT_NODE && innerText.trim() !== '') + || (nodeType === Node.TEXT_NODE && textContent.trim() !== '') + )); +} + export function decorateBlockText(el, config = ['m', 's', 'm'], type = null) { - let headings = el.querySelectorAll('h1, h2, h3, h4, h5, h6'); if (!el.classList.contains('default')) { + let headings = el?.querySelectorAll('h1, h2, h3, h4, h5, h6'); if (headings) { if (type === 'hasDetailHeading' && headings.length > 1) headings = [...headings].splice(1); headings.forEach((h) => h.classList.add(`heading-${config[0]}`)); @@ -77,13 +84,12 @@ export function decorateBlockText(el, config = ['m', 's', 'm'], type = null) { decorateIconArea(el); } } - const emptyEls = el.querySelectorAll('p:not([class]), ul:not([class]), ol:not([class])'); + const bodyStyle = `body-${config[1]}`; + const emptyEls = el?.querySelectorAll(':is(p, ul, ol, div):not([class])'); if (emptyEls.length) { - emptyEls.forEach((p) => p.classList.add(`body-${config[1]}`)); - } else { - [...el.querySelectorAll('div:not([class])')] - .filter((emptyDivs) => emptyDivs.textContent.trim() !== '') - .forEach((text) => text.classList.add(`body-${config[1]}`)); + [...emptyEls].filter(elContainsText).forEach((e) => e.classList.add(bodyStyle)); + } else if (!el.classList.length && elContainsText(el)) { + el.classList.add(bodyStyle); } } const buttonSize = config.length > 3 ? `button-${config[3]}` : ''; diff --git a/test/blocks/text/mocks/body.html b/test/blocks/text/mocks/body.html index bfb7a5a52f..3c338727ab 100644 --- a/test/blocks/text/mocks/body.html +++ b/test/blocks/text/mocks/body.html @@ -334,3 +334,16 @@

Text – Full-Width, Medium

+
+
+
+
XXS Body - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+ +
From fe3acdb89e549891c51e90eac4a2654b3613c676 Mon Sep 17 00:00:00 2001 From: rohitsahu Date: Fri, 8 Nov 2024 00:14:45 +0530 Subject: [PATCH 2/9] [MWPW-154662] [Accessibility] Visual list is not marked up as list: section (#3101) * make mini-compare footer rows unordered list for accessiblity * dummy commit * Revert "dummy commit" This reverts commit a3a882449c681f5f9c4f2eb1477cb0b7e3113f17. --------- Co-authored-by: Rohit Sahu --- libs/blocks/merch-card/merch-card.js | 2 +- libs/deps/mas/mas.js | 1 + libs/deps/mas/merch-card.js | 1 + libs/features/mas/mas/dist/mas.js | 1 + .../mas/web-components/src/variants/mini-compare-chart.css.js | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/blocks/merch-card/merch-card.js b/libs/blocks/merch-card/merch-card.js index b2483481dd..e1c9f34f26 100644 --- a/libs/blocks/merch-card/merch-card.js +++ b/libs/blocks/merch-card/merch-card.js @@ -398,7 +398,7 @@ const decorateFooterRows = (merchCard, footerRows) => { const rowIcon = row.firstElementChild.querySelector('picture'); const rowText = row.querySelector('div > div:nth-child(2)').innerHTML; const rowTextParagraph = createTag('div', { class: 'footer-row-cell-description' }, rowText); - const footerRowCell = createTag('div', { class: 'footer-row-cell' }); + const footerRowCell = createTag('ul', { class: 'footer-row-cell' }); if (rowIcon) { rowIcon.classList.add('footer-row-icon'); footerRowCell.appendChild(rowIcon); diff --git a/libs/deps/mas/mas.js b/libs/deps/mas/mas.js index f8917dbd0b..aa4f594fc5 100644 --- a/libs/deps/mas/mas.js +++ b/libs/deps/mas/mas.js @@ -612,6 +612,7 @@ merch-card[variant="ccd-action"] .price-strikethrough { justify-content: start; place-items: center; padding: var(--consonant-merch-spacing-xs) var(--consonant-merch-spacing-s); + margin-block: 0px; } merch-card[variant="mini-compare-chart"] .footer-row-cell-description { diff --git a/libs/deps/mas/merch-card.js b/libs/deps/mas/merch-card.js index 1f779dbe14..52e084329d 100644 --- a/libs/deps/mas/merch-card.js +++ b/libs/deps/mas/merch-card.js @@ -636,6 +636,7 @@ merch-card[variant="ccd-action"] .price-strikethrough { justify-content: start; place-items: center; padding: var(--consonant-merch-spacing-xs) var(--consonant-merch-spacing-s); + margin-block: 0px; } merch-card[variant="mini-compare-chart"] .footer-row-cell-description { diff --git a/libs/features/mas/mas/dist/mas.js b/libs/features/mas/mas/dist/mas.js index f8917dbd0b..aa4f594fc5 100644 --- a/libs/features/mas/mas/dist/mas.js +++ b/libs/features/mas/mas/dist/mas.js @@ -612,6 +612,7 @@ merch-card[variant="ccd-action"] .price-strikethrough { justify-content: start; place-items: center; padding: var(--consonant-merch-spacing-xs) var(--consonant-merch-spacing-s); + margin-block: 0px; } merch-card[variant="mini-compare-chart"] .footer-row-cell-description { diff --git a/libs/features/mas/web-components/src/variants/mini-compare-chart.css.js b/libs/features/mas/web-components/src/variants/mini-compare-chart.css.js index 167102700d..3a48a8b1e6 100644 --- a/libs/features/mas/web-components/src/variants/mini-compare-chart.css.js +++ b/libs/features/mas/web-components/src/variants/mini-compare-chart.css.js @@ -75,6 +75,7 @@ export const CSS = ` justify-content: start; place-items: center; padding: var(--consonant-merch-spacing-xs) var(--consonant-merch-spacing-s); + margin-block: 0px; } merch-card[variant="mini-compare-chart"] .footer-row-cell-description { From 948a940ac687edc010fe85613bbfa4f6faa0d597 Mon Sep 17 00:00:00 2001 From: Robert Bogos <146744221+robert-bogos@users.noreply.github.com> Date: Thu, 7 Nov 2024 20:44:52 +0200 Subject: [PATCH 3/9] [MWPW-161098] Links conversion localization support (#3120) * links conversion localization support * added unit tests --- libs/scripts/scripts.js | 2 +- libs/utils/utils.js | 14 ++++++++++---- test/utils/utils.test.js | 12 ++++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/libs/scripts/scripts.js b/libs/scripts/scripts.js index 2c62d13178..bb4e690d87 100644 --- a/libs/scripts/scripts.js +++ b/libs/scripts/scripts.js @@ -19,7 +19,7 @@ import { import locales from '../utils/locales.js'; // Production Domain -const prodDomains = ['milo.adobe.com']; +const prodDomains = ['milo.adobe.com', 'business.adobe.com', 'www.adobe.com']; const stageDomainsMap = { 'www.stage.adobe.com': { diff --git a/libs/utils/utils.js b/libs/utils/utils.js index bfa70f2e7d..baf303c781 100644 --- a/libs/utils/utils.js +++ b/libs/utils/utils.js @@ -646,21 +646,27 @@ const decorateCopyLink = (a, evt) => { }; export function convertStageLinks({ anchors, config, hostname, href }) { - if (config.env?.name === 'prod' || !config.stageDomainsMap) return; - const matchedRules = Object.entries(config.stageDomainsMap) + const { env, stageDomainsMap, locale } = config; + if (env?.name === 'prod' || !stageDomainsMap) return; + const matchedRules = Object.entries(stageDomainsMap) .find(([domain]) => (new RegExp(domain)).test(href)); if (!matchedRules) return; const [, domainsMap] = matchedRules; [...anchors].forEach((a) => { + const hasLocalePrefix = a.pathname.startsWith(locale.prefix); + const noLocaleLink = hasLocalePrefix ? a.href.replace(locale.prefix, '') : a.href; const matchedDomain = Object.keys(domainsMap) - .find((domain) => (new RegExp(domain)).test(a.href)); + .find((domain) => (new RegExp(domain)).test(noLocaleLink)); if (!matchedDomain) return; - a.href = a.href.replace( + const convertedLink = noLocaleLink.replace( new RegExp(matchedDomain), domainsMap[matchedDomain] === 'origin' ? `${matchedDomain.includes('https') ? 'https://' : ''}${hostname}` : domainsMap[matchedDomain], ); + const convertedUrl = new URL(convertedLink); + convertedUrl.pathname = `${hasLocalePrefix ? locale.prefix : ''}${convertedUrl.pathname}`; + a.href = convertedUrl.toString(); if (/(\.page|\.live).*\.html(?=[?#]|$)/.test(a.href)) a.href = a.href.replace(/\.html(?=[?#]|$)/, ''); }); } diff --git a/test/utils/utils.test.js b/test/utils/utils.test.js index c211ddbf76..196d44df8b 100644 --- a/test/utils/utils.test.js +++ b/test/utils/utils.test.js @@ -537,16 +537,18 @@ describe('Utils', () => { it('should convert links when stageDomainsMap provided without regex', async () => { const stageConfig = { ...config, + locale: { prefix: '/ae_ar' }, env: { name: 'stage' }, stageDomainsMap, }; Object.entries(stageDomainsMap).forEach(([hostname, domainsMap]) => { const anchors = Object.keys(domainsMap).map((d) => utils.createTag('a', { href: `https://${d}` })); + const localizedAnchors = Object.keys(domainsMap).map((d) => utils.createTag('a', { href: `https://${d}/ae_ar` })); const externalAnchors = externalDomains.map((url) => utils.createTag('a', { href: url })); utils.convertStageLinks({ - anchors: [...anchors, ...externalAnchors], + anchors: [...anchors, ...localizedAnchors, ...externalAnchors], config: stageConfig, hostname, href: `https://${hostname}`, @@ -565,16 +567,22 @@ describe('Utils', () => { const { hostname, map } = stageDomainsMapWRegex; const stageConfigWRegex = { ...config, + locale: { prefix: '/de' }, env: { name: 'stage' }, stageDomainsMap: map, }; Object.entries(map).forEach(([, domainsMap]) => { const anchors = Object.keys(domainsMap).map((d) => utils.createTag('a', { href: d.replace('^', '') })); + const localizedAnchors = Object.keys(domainsMap).map((d) => { + const convertedUrl = new URL(d.replace('^', '')); + convertedUrl.pathname = `de/${convertedUrl.pathname}`; + return utils.createTag('a', { href: convertedUrl.toString() }); + }); const externalAnchors = externalDomains.map((url) => utils.createTag('a', { href: url })); utils.convertStageLinks({ - anchors: [...anchors, ...externalAnchors], + anchors: [...anchors, ...localizedAnchors, ...externalAnchors], config: stageConfigWRegex, hostname, href: `https://${hostname}`, From 8b372b4049f1ce695577f85aa23428bcc32a53a2 Mon Sep 17 00:00:00 2001 From: Megan Thomas Date: Thu, 7 Nov 2024 10:44:58 -0800 Subject: [PATCH 4/9] MWPW-160966 Fix next-gen sidekick preflight (#3126) --- libs/blocks/preflight/panels/seo.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/libs/blocks/preflight/panels/seo.js b/libs/blocks/preflight/panels/seo.js index f240762218..92a94d66dd 100644 --- a/libs/blocks/preflight/panels/seo.js +++ b/libs/blocks/preflight/panels/seo.js @@ -313,15 +313,19 @@ async function getResults() { const icons = [h1, title, canon, desc, body, lorem, links]; const red = icons.find((icon) => icon === 'red'); - if (red) { - const sk = document.querySelector('aem-sidekick, helix-sidekick'); - if (sk) { - const publishBtn = sk.shadowRoot.querySelector('div.publish.plugin button'); - publishBtn.addEventListener('click', () => { - sendResults(); - }); - } - } + if (!red) return; + + const aemSk = document.querySelector('aem-sidekick'); + const hlxSk = document.querySelector('helix-sidekick'); + if (!aemSk && !hlxSk) return; + + const publishBtn = aemSk + ? aemSk.shadowRoot.querySelector('plugin-action-bar').shadowRoot.querySelector('sk-action-button.publish') + : hlxSk.shadowRoot.querySelector('div.publish.plugin button'); + + publishBtn.addEventListener('click', () => { + sendResults(); + }); } export default function Panel() { From 819e6f39a47c08ee76e77ceb9dbdfaa5d22b0ee8 Mon Sep 17 00:00:00 2001 From: Joaquin Rivero Date: Fri, 8 Nov 2024 02:45:09 +0800 Subject: [PATCH 5/9] MWPW-159032: Accessibility requirements floating label (#3137) Adds a floating label as accessibility requirements for comments field --- .../review/components/review/Comments.js | 8 +-- libs/blocks/review/review.css | 55 ++++++++++++------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/libs/blocks/review/components/review/Comments.js b/libs/blocks/review/components/review/Comments.js index 8fcb0a3b25..355bd567f8 100644 --- a/libs/blocks/review/components/review/Comments.js +++ b/libs/blocks/review/components/review/Comments.js @@ -6,7 +6,6 @@ import { } from '../../../../deps/htm-preact.js'; function Comments({ - label, comment, handleCommentChange, placeholderText, @@ -61,20 +60,19 @@ function Comments({ `; return html`
-