From aa8b78f9f37c17907767409337987f7fae978986 Mon Sep 17 00:00:00 2001
From: Victor Hargrave <115231412+vhargrave@users.noreply.github.com>
Date: Thu, 12 Dec 2024 21:02:26 +0100
Subject: [PATCH 1/9] MWPW-143385 archive puf & premium-plan blocks (#1284)
---
express/blocks/premium-plan/premium-plan.css | 248 --------
express/blocks/premium-plan/premium-plan.js | 99 ----
express/blocks/puf/check.svg | 3 -
express/blocks/puf/puf.css | 536 ------------------
express/blocks/puf/puf.js | 449 ---------------
express/scripts/utils.js | 13 -
express/styles/styles.css | 4 +-
.../blocks/premium-plan/premium-plan.test.js | 4 -
test/unit/blocks/puf/puf.test.js | 4 -
9 files changed, 2 insertions(+), 1358 deletions(-)
delete mode 100644 express/blocks/premium-plan/premium-plan.css
delete mode 100644 express/blocks/premium-plan/premium-plan.js
delete mode 100644 express/blocks/puf/check.svg
delete mode 100644 express/blocks/puf/puf.css
delete mode 100644 express/blocks/puf/puf.js
delete mode 100644 test/unit/blocks/premium-plan/premium-plan.test.js
delete mode 100644 test/unit/blocks/puf/puf.test.js
diff --git a/express/blocks/premium-plan/premium-plan.css b/express/blocks/premium-plan/premium-plan.css
deleted file mode 100644
index 3d59d0bf0..000000000
--- a/express/blocks/premium-plan/premium-plan.css
+++ /dev/null
@@ -1,248 +0,0 @@
-main .premium-plan-container > div {
- max-width: 100%;
- padding: 0;
-}
-
-main .premium-plan .premium-plan-banner {
- display: flex;
- align-items: center;
- justify-content: center;
- background: var(--gradient-highlight-diagonal);
-}
-
-main .premium-plan .premium-plan-banner-desktop {
- display: none;
-}
-
-main .premium-plan .premium-plan-banner > div {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- padding: 40px 20px 80px 20px;
- max-width: 320px;
-}
-
-main .premium-plan .premium-plan-banner img {
- width: 100%;
- margin-top: 20px;
-}
-
-main .premium-plan .premium-plan-banner h2 {
- color: white;
- font-size: var(--heading-font-size-m);
- line-height: var(--heading-line-height);
- text-align: left;
- max-width: 375px;
-}
-
-main .premium-plan .premium-plan-cards {
- display: flex;
- justify-content: center;
- align-items: center;
- background: linear-gradient(to top, var(--body-alt-background-color), var(--body-alt-background-color)) no-repeat 0 80px;
- margin-top: -80px;
-}
-
-main .premium-plan .premium-plan-cards > div {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
-
- padding: 0 15px 20px 15px;
- box-sizing: border-box;
- max-width: 375px;
-}
-
-main .premium-plan .premium-plan-card {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- padding: 20px 30px 40px 30px;
- background-color: white;
- border-radius: 20px;
- margin-bottom: 30px;
-}
-
-main .premium-plan .premium-plan-card-desktop {
- display: none;
-}
-
-main .premium-plan .premium-plan-card h3 {
- color: var(--color-gray-800);
-}
-
-main .premium-plan .premium-plan-card p {
- margin: 0;
- text-align: left;
- font-size: var(--body-font-size-m);
- font-weight: var(--body-font-weight);
- max-width: 280px;
- color: var(--color-gray-800);
-}
-
-main .premium-plan .premium-plan-card-icon img {
- width: 40px;
-}
-
-main .premium-plan .premium-plan-card h3 {
- text-align: left;
- font-size: var(--heading-font-size-s);
- margin: 10px 0;
- max-width: 260px;
-}
-
-main .premium-plan .premium-plan-card-image img {
- width: 50%;
- margin: 20px 0;
-}
-
-main .premium-plan .premium-plan-card ul {
- display: flex;
- list-style-type: none;
- margin: 0;
- padding-left: 0;
-}
-
-main .premium-plan .premium-plan-card ul li a svg {
- width: 40px;
- height: 40px;
- margin-right: 10px;
- margin-bottom: 0;
-}
-
-@media (min-width: 900px) {
- main .premium-plan {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- padding: 0 20px;
- }
-
- main .premium-plan .premium-plan-banner {
- justify-content: center;
- align-items: center;
- position: relative;
- max-width: 1180px;
- width: 100%;
- border-radius: 15px;
- }
-
- main .premium-plan .premium-plan-banner-mobile {
- display: none;
- }
-
- main .premium-plan .premium-plan-banner-desktop {
- display: flex;
- }
-
- main .premium-plan .premium-plan-banner > div {
- max-width: none;
- width: 100%;
- align-items: flex-start;
- padding: 40px;
- }
-
- main .premium-plan .premium-plan-banner h2 {
- max-width: 500px;
- }
-
- main .premium-plan .premium-plan-banner picture {
- position: absolute;
- top: 50%;
- right: 40px;
- max-width: 320px;
- margin: 0;
- transform: translateY(-50%);
- }
-
- main .premium-plan .premium-plan-cards {
- max-width: 1180px;
- width: 100%;
- background: none;
- margin-top: 20px;
- justify-content: flex-start;
- }
-
- main .premium-plan .premium-plan-cards > div {
- max-width: none;
- flex-direction: row;
- padding: 0;
- justify-content: flex-start;
- }
-
- main .premium-plan .premium-plan-card {
- position: relative;
- width: 415px;
- max-width: 475px;
- border: 2px #E8E8E8 solid;
- padding: 20px 30px;
- margin-right: 20px;
- min-height: 230px;
- }
-
- main .premium-plan .premium-plan-card h3 {
- margin-bottom: 5px;
- }
-
- main .premium-plan .premium-plan-card-desktop {
- display: flex;
- }
-
- main .premium-plan .premium-plan-card-mobile {
- display: none;
- }
-
- main .premium-plan .premium-plan-card-image {
- position: absolute;
- top: 45%;
- right: 30px;
- transform: translateY(-50%);
- width: 120px;
- }
-
- main .premium-plan .premium-plan-card-image img {
- width: 100%;
- }
-
- main .premium-plan .premium-plan-card ul {
- margin-top: auto;
- }
-}
-
-@media (min-width: 1020px) {
- main .premium-plan .premium-plan-banner picture {
- max-width: 480px;
- top: -70px;
- right: 0;
- transform: none;
- }
-}
-
-@media (min-width: 1200px) {
- main .premium-plan .premium-plan-banner picture {
- max-width: 580px;
- top: -90px;
- transform: none;
- }
-}
-
-/* Disable carousel on mobile */
-
-@media (max-width: 899px) {
- main .premium-plan-cards .carousel-container,
- main .premium-plan-cards .carousel-container .carousel-platform {
- display: block;
- max-height: unset;
- }
-
- main .premium-plan-cards .carousel-container a.button.carousel-arrow {
- display: none;
- }
-
- main .premium-plan .premium-plan-cards {
- flex-direction: column;
- }
-}
diff --git a/express/blocks/premium-plan/premium-plan.js b/express/blocks/premium-plan/premium-plan.js
deleted file mode 100644
index ca8b8f3bb..000000000
--- a/express/blocks/premium-plan/premium-plan.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import {
- createTag,
- getIconElement,
- // eslint-disable-next-line import/no-unresolved
-} from '../../scripts/utils.js';
-
-import buildCarousel from '../shared/carousel.js';
-
-export default function decorate($block) {
- if ($block.children.length) {
- const $desktopBanner = $block.children[0];
- if ($desktopBanner) {
- $desktopBanner.classList.add('premium-plan-banner', 'premium-plan-banner-desktop');
- const $desktopBannerCta = $desktopBanner.querySelector('a');
- if ($desktopBannerCta) {
- $desktopBannerCta.classList.add('dark', 'reverse');
- $desktopBannerCta.classList.remove('accent');
- }
- const $desktopImg = $desktopBanner.querySelector('picture:first-child:last-child');
- if ($desktopImg && $desktopImg.parentElement.tagName === 'P') {
- // unwrap single picture if wrapped in p tag
- const $desktopParentDiv = $desktopImg.closest('div');
- const $desktopParentParagraph = $desktopImg.parentNode;
- $desktopParentDiv.insertBefore($desktopImg, $desktopParentParagraph);
- $desktopParentParagraph.remove();
- }
- $desktopBanner.children[0].remove();
- }
- }
- if ($block.children.length > 1) {
- const $mobileBanner = $block.children[1];
- if ($mobileBanner) {
- $mobileBanner.classList.add('premium-plan-banner', 'premium-plan-banner-mobile');
- const $mobileBannerCta = $mobileBanner.querySelector('a');
- if ($mobileBannerCta) {
- $mobileBannerCta.classList.add('dark', 'reverse');
- $mobileBannerCta.classList.remove('accent');
- }
- const $mobileImg = $mobileBanner.querySelector('picture:first-child:last-child');
- if ($mobileImg && $mobileImg.parentElement.tagName === 'P') {
- // unwrap single picture if wrapped in p tag
- const $desktopParentDiv = $mobileImg.closest('div');
- const $desktopParentParagraph = $mobileImg.parentNode;
- $desktopParentDiv.insertBefore($mobileImg, $desktopParentParagraph);
- $desktopParentParagraph.remove();
- }
- $mobileBanner.children[0].remove();
- }
- }
- if ($block.children.length > 2) {
- const $container = createTag('div', { class: 'premium-plan-cards' });
- const $cards = createTag('div');
- $container.append($cards);
- let failsafe = 20;
- while ($block.children.length > 2) {
- const device = $block.children[2].children[0].textContent.trim().toLowerCase();
- const $cardDiv = $block.children[2].children[1];
- const $cardLink = $cardDiv.children[0].querySelector('a');
- let $card;
-
- if ($cardLink) {
- $card = createTag('a', { class: 'premium-plan-card', href: $cardLink.href });
- $cardLink.remove();
- $card.innerHTML = $cardDiv.innerHTML;
- } else {
- $card = $cardDiv;
- $card.classList.add('premium-plan-card');
- }
-
- if (device === 'mobile') {
- $card.classList.add('premium-plan-card-mobile');
- } else if (device === 'desktop') {
- $card.classList.add('premium-plan-card-desktop');
- }
- $cards.append($card);
- $block.children[2].remove();
- failsafe -= 1;
- if (!failsafe) { // prevent a possible infinite loop.
- break;
- }
- const $images = $card.querySelectorAll('picture');
- if ($images.length) {
- $images[0].classList.add('premium-plan-card-icon');
- }
- if ($images.length > 1) {
- $images[1].classList.add('premium-plan-card-image');
- }
- const $links = $card.querySelectorAll('li a');
- if ($links) {
- $links.forEach(($link) => {
- const iconName = $link.textContent.trim().toLowerCase();
- $link.append(getIconElement(iconName));
- });
- }
- }
- $block.append($container);
- buildCarousel('.premium-plan-card', $container);
- }
-}
diff --git a/express/blocks/puf/check.svg b/express/blocks/puf/check.svg
deleted file mode 100644
index 051de2b7a..000000000
--- a/express/blocks/puf/check.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/express/blocks/puf/puf.css b/express/blocks/puf/puf.css
deleted file mode 100644
index a73b0cc37..000000000
--- a/express/blocks/puf/puf.css
+++ /dev/null
@@ -1,536 +0,0 @@
-main .section.puf-container {
- padding-bottom: 0;
-}
-
-main .puf-container > div {
- max-width: none;
-}
-
-main .block.puf .carousel-container {
- overflow: visible;
- transition: max-height 0.3s, min-height 0.3s;
- max-width: 600px;
-}
-
-main .block.puf {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
-}
-
-main .block.puf p {
- margin: 0;
-}
-
-main .block.puf .puf-card-container {
- display: flex;
- justify-content: center;
- border-radius: 20px;
-}
-
-main .block.puf .puf-card {
- position: relative;
- border-radius: 20px;
- box-sizing: border-box;
- padding: 32px 30px 16px 30px;
- background-color: var(--color-white);
-}
-
-main .block.puf .puf-card .puf-card-top {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- margin-bottom: 10px;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-pricing-container {
- display: flex;
- align-items: flex-end;
-}
-
-main .block.puf .puf-card .puf-card-top h3 {
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: var(--heading-font-size-l);
- line-height: var(--heading-line-height);
-}
-
-main .block.puf .puf-card h3 {
- width: 100%;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-pricing-container {
- margin-top: 20px;
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
-}
-
-main .block.puf .puf-card .puf-pricing-suf-container {
- text-align: left;
-}
-
-main .block.puf .puf-card .puf-card-top h2.puf-bp-header {
- color: var(--color-gray-600);
-}
-
-main .block.puf .puf-card .puf-card-top h2.puf-bp-header strong {
- text-decoration: line-through;
-}
-
-main .block.puf .puf-card .puf-card-top h2 {
- display: flex;
- font-size: var(--heading-font-size-m);
- font-weight: var(--heading-font-weight);
- margin: 0;
-}
-
-main .block.puf .puf-card .puf-card-top h2 strong {
- font-size: var(--heading-font-size-xxl);
- font-weight: 800;
- margin-top: -10px;
-}
-
-main .block.puf .puf-card .puf-card-top h2.jpy strong {
- margin-right: 10px;
-}
-
-main .block.puf .puf-card .puf-card-top h3 svg {
- margin-right: 10px;
- width: 32px;
- height: 32px;
-}
-
-main .block.puf .puf-card .puf-card-top h3 img {
- margin-right: 7px;
- width: 37px;
- height: 37px;
-}
-
-main .block.puf .puf-card .puf-card-top a {
- margin-top: 20px;
- width: 100%;
- box-sizing: border-box;
-}
-
-main .block.puf .puf-card .puf-card-top p {
- font-size: var(--body-font-size-m);
- margin-bottom: 20px;
- text-align: left;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-plans {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin: 0 auto;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-plans > div {
- color: var(--color-info-accent);
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-plans > div span {
- color: var(--color-gray-800);
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-plans > div.strong span {
- -webkit-text-stroke-width: 0.6px;
- -webkit-text-stroke-color: var(--color-gray-800);
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-switch {
- position: relative;
- display: inline-block;
- width: 58px;
- height: 31px;
- margin: 0 10px;
- min-width: 58px;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-switch input {
- opacity: 0;
- width: 0;
- height: 0;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-slider {
- position: absolute;
- cursor: pointer;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: var(--color-info-accent);
- -webkit-transition: 0.4s;
- transition: 0.4s;
- border-radius: 34px;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-slider::before {
- position: absolute;
- content: "";
- height: 23px;
- width: 23px;
- left: 4px;
- bottom: 4px;
- background-color: white;
- -webkit-transition: 0.4s;
- transition: 0.4s;
- border-radius: 50%;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-switch input:checked + .puf-card-slider {
- background-color: var(--color-info-accent);
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-switch input:focus + .puf-card-slider {
- box-shadow: 0 0 1px #2196f3;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-switch input:checked + .puf-card-slider:before {
- transform: translateX(26px);
-}
-
-main .block.puf .puf-card .puf-card-bottom {
- display: flex;
- flex-direction: column;
- justify-content: center;
- text-align: center;
-}
-
-main .block.puf .puf-card .puf-card-bottom h3 {
- font-size: var(--body-font-size-xl);
- font-weight: 600;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 20px;
-}
-
-main .block.puf .puf-card .puf-card-bottom p {
- font-size: var(--body-font-size-l);
- margin-bottom: 40px;
- text-align: left;
- display: flex;
- align-items: center;
-}
-
-main .block.puf .puf-card .puf-card-bottom svg {
- height: 22px;
- min-width: 22px;
- margin-right: 8px;
-}
-
-main .block.puf .puf-card .puf-card-bottom h6 {
- font-weight: var(--body-font-weight);
- font-size: var(--body-font-size-s);
- margin: 0;
-}
-
-main .block.puf .puf-card .puf-sup {
- font-size: 0.5em;
-}
-
-main .block.puf .puf-card .puf-text-and-sup-wrapper {
- display: inline;
-}
-
-main .block.puf .puf-card-banner.recommended ~ .puf-card-bottom .puf-highlighted-text,
-main .block.puf .puf-highlighted-text {
- background-color: var(--color-info-accent-light);
- width: 100%;
- border-radius: 12px;
- margin-top: 0;
- box-sizing: border-box;
- padding: 10px;
-}
-
-main .block.puf .puf-divider-text {
- box-sizing: border-box;
- display: flex;
- align-items: center;
- gap: 16px;
-}
-
-main .block.puf .puf-divider-text:before,
-main .block.puf .puf-divider-text:after {
- content: '';
- width: 100%;
- height: 0;
- border: solid 1px var(--color-gray-300);
- flex: 1;
-}
-
-main .block.puf .puf-pricing-footer {
- max-width: 1200px;
- width: 100%;
-}
-
-main .block.puf .puf-pricing-footer .puf-highlighted-text {
- padding: 16px;
- margin-top: 24px;
-}
-
-main .block.puf .puf-card-banner.recommended {
- color: white;
- font-size: var(--body-font-size-l);
-}
-
-main .block.puf .puf-card-banner.recommended .banner-text {
- margin: 0 8px;
-}
-
-main .block.puf .puf-card-container .puf-card-border {
- border-radius: 20px;
- padding: 48px 8px 8px 8px;
- margin-top: 20px;
- height: auto;
- z-index: 0;
-}
-
-main .block.puf .puf-card-container .puf-card-border:has(.recommended) {
- background: linear-gradient(90deg, #ff477b 0%, #5c5ce0 52%, #318fff 100%);
- box-shadow: 0 0 24px #00000029;
-}
-
-main .block.puf .puf-card-container .puf-card {
- border: 1px #e5e5e5 solid;
- border-radius: 20px;
-}
-
-main .block.puf .puf-card .puf-card-banner {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: -50px;
- left: 0;
- width: 100%;
- height: 50px;
- border-radius: 20px 20px 0 0;
-}
-
-main .block.puf .puf-card .puf-card-banner a {
- margin-left: 4px;
- color: unset;
- font-weight: unset;
- text-decoration: underline;
-}
-
-main .block.puf .carousel-container .carousel-platform {
- position: relative;
-}
-
-main .block.puf .carousel-container .carousel-platform .carousel-left-trigger,
-main .block.puf .carousel-container .carousel-platform .carousel-right-trigger {
- align-self: stretch;
- width: 1px;
-}
-
-main .block.puf .carousel-container .carousel-platform .carousel-left-trigger {
- left: 0;
-}
-
-main .block.puf .carousel-container .carousel-platform .carousel-right-trigger {
- right: 0;
-}
-
-main .block.puf .carousel-container {
- position: relative;
-}
-
-main .block.puf .puf-card .puf-card-top .puf-card-plans,
-main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card .puf-card-top .puf-card-plans {
- margin-top: 16px;
-}
-
-main .block.puf .carousel-platform {
- gap: 0px;
- max-height: unset;
- height: 100%;
- min-height: 100%;
-}
-
-main .block.puf .puf-card .puf-card-bottom p {
- margin-bottom: 24px;
-}
-
-main .block.puf .carousel-container .carousel-platform .puf-card-container {
- width: calc(100% - 2px);
-}
-
-main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card {
- max-width: 325px;
-}
-
-main .block.puf .puf-card-banner.recommended ~ .puf-card-bottom .puf-highlighted-text {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-main .block.puf .puf-card-container {
- align-self: start;
-}
-
-main .block.puf .carousel-container .carousel-fader-left,
-main .block.puf .carousel-container .carousel-fader-right {
- margin-top: 86px;
- height: calc(100% - 172px);
-}
-
-main .block.puf .carousel-container .carousel-fader-left a.button.carousel-arrow,
-main .block.puf .carousel-container .carousel-fader-right a.button.carousel-arrow {
- position: sticky;
- top: calc(50% - 16px);
- bottom: calc(50% - 16px);
-}
-
-@media (min-width: 600px) {
- main .block.puf .puf-card-banner.recommended {
- font-size: var(--body-font-size-xl);
- }
-}
-
-
-main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card-border .puf-card {
- box-shadow: 0 0 20px #00000029;
-}
-
-@media (min-width: 900px) {
- main .block.puf .puf-card .puf-card-top .puf-card-plans {
- margin-top: 8px;
- }
-
- main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card .puf-card-top .puf-card-plans {
- margin-top: 0;
- }
-
- main .block.puf .puf-card-container {
- margin-left: auto;
- margin-right: auto;
- }
-
- main .block.puf .puf-card {
- max-width: 610px;
- padding: 40px 60px;
- }
-
- main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card {
- max-width: none;
- }
-
- main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card-border:has(.recommended),
- main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card-border .puf-card {
- box-shadow: none;
- }
-
- main .block.puf .carousel-container .carousel-platform .puf-card-container {
- align-self: stretch;
- max-width: 100%;
- width: auto;
- }
-
- main .block.puf .carousel-container .carousel-platform .puf-card-container .puf-card {
- height: 100%;
- width: 610px;
- margin: 0;
- padding: 40px 60px;
- }
-
- main .block.puf .carousel-container .carousel-platform .carousel-left-trigger,
- main .block.puf .carousel-container .carousel-platform .carousel-right-trigger {
- align-self: stretch;
- position: relative;
- height: auto;
- right: auto;
- left: auto;
- top: auto;
- }
-
- main .block.puf .carousel-container {
- max-width: none;
- max-height: none !important;
- }
-
- main .block.puf .carousel-container {
- margin-bottom: 0;
- }
-
- main .block.puf .carousel-container .carousel-platform {
- align-items: start;
- }
-
- main .block.puf .carousel-platform {
- align-items: start;
- max-height: unset;
- max-width: 100%;
- margin-left: auto;
- margin-right: auto;
- overflow: auto;
- }
-
- main .block.puf .puf-card-container:not(:has(.recommended)) .puf-card {
- padding-left: 60px;
- padding-right: 76px;
- }
-
- main .block.puf .puf-card .puf-card-top .puf-pricing-container {
- margin-top: 10px;
- gap: 4px;
- }
-
- main .block.puf .puf-card .puf-pricing-suf-container div {
- margin: 2px 0;
- line-height: 24px;
- font-size: var(--body-font-size-xl);
- }
-
- main .block.puf .puf-card .puf-card-top .puf-card-plans {
- min-height: 40px;
- }
-
- main .block.puf .puf-card .puf-card-bottom p {
- display: flex;
- align-items: center;
- margin-bottom: 24px;
- text-align: left;
- }
-
- main .block.puf .puf-card .puf-card-bottom svg {
- display: inline-block;
- margin-right: 16px;
- width: 44px;
- height: 44px;
- flex: 0 0 44px;
- }
-
- main .block.puf .puf-card .puf-card-bottom .puf-list-item {
- position: relative;
- }
-
- main .block.puf .puf-card .puf-card-bottom .puf-list-item::before {
- position: absolute;
- display: block;
- content: "";
- left: -30px;
- top: 50%;
- transform: translateY(-50%);
- width: 13px;
- height: 11.5px;
- background-color: var(--color-info-accent);
- -webkit-mask-image: url("/express/blocks/puf/check.svg");
- mask-image: url("/express/blocks/puf/check.svg");
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-position: center;
- -webkit-mask-size: contain;
- mask-repeat: no-repeat;
- mask-position: center;
- mask-size: contain;
- }
-
-}
diff --git a/express/blocks/puf/puf.js b/express/blocks/puf/puf.js
deleted file mode 100644
index bd3021533..000000000
--- a/express/blocks/puf/puf.js
+++ /dev/null
@@ -1,449 +0,0 @@
-import buildCarousel from '../shared/carousel.js';
-import { addPublishDependencies, createTag, getMetadata } from '../../scripts/utils.js';
-import { buildUrl, fetchPlan } from '../../scripts/utils/pricing.js';
-
-let invisContainer;
-let parent;
-
-function pushPricingAnalytics(adobeEventName, sparkEventName, plan) {
- const url = new URL(window.location.href);
- const sparkTouchpoint = url.searchParams.get('touchpointName');
-
- /* eslint-disable no-underscore-dangle */
- /* global digitalData _satellite */
- digitalData._set('primaryEvent.eventInfo.eventName', adobeEventName);
- digitalData._set('spark.eventData.eventName', sparkEventName);
- digitalData._set(
- 'spark.eventData.contextualData4',
- `billingFrequency:${plan.frequency}`,
- );
- digitalData._set(
- 'spark.eventData.contextualData6',
- `commitmentType:${plan.frequency}`,
- );
- digitalData._set(
- 'spark.eventData.contextualData7',
- `currencyCode:${plan.currency}`,
- );
- digitalData._set(
- 'spark.eventData.contextualData9',
- `offerId:${plan.offerId}`,
- );
- digitalData._set('spark.eventData.contextualData10', `price:${plan.price}`);
- digitalData._set(
- 'spark.eventData.contextualData12',
- `productName:${plan.name} - ${plan.frequency}`,
- );
- digitalData._set('spark.eventData.contextualData14', 'quantity:1');
- digitalData._set('spark.eventData.trigger', sparkTouchpoint);
-
- _satellite.track('event', {
- digitalData: digitalData._snapshot(),
- });
-
- digitalData._delete('primaryEvent.eventInfo.eventName');
- digitalData._delete('spark.eventData.eventName');
- digitalData._delete('spark.eventData.contextualData4');
- digitalData._delete('spark.eventData.contextualData6');
- digitalData._delete('spark.eventData.contextualData7');
- digitalData._delete('spark.eventData.contextualData9');
- digitalData._delete('spark.eventData.contextualData10');
- digitalData._delete('spark.eventData.contextualData12');
- digitalData._delete('spark.eventData.contextualData14');
-}
-
-async function selectPlan(card, planUrl, sendAnalyticEvent) {
- const plan = await fetchPlan(planUrl);
-
- if (plan) {
- const pricingCta = card.querySelector('.puf-card-top a');
- const pricingHeader = card.querySelector('.puf-pricing-header');
- const pricingSuf = card.querySelector('.puf-pricing-suf');
- const pricingVat = card.querySelector('.puf-vat-info');
- const pricingBase = card.querySelector('.puf-bp-header');
-
- if (pricingHeader) {
- pricingHeader.innerHTML = plan.formatted || '';
- pricingHeader.classList.add(plan.currency.toLowerCase());
- }
-
- if (pricingBase) {
- pricingBase.innerHTML = plan.formattedBP || '';
- }
-
- if (pricingSuf) pricingSuf.textContent = plan.suffix || '';
- if (pricingVat) pricingVat.textContent = plan.vatInfo || '';
-
- if (pricingCta) {
- pricingCta.href = buildUrl(plan.url, plan.country, plan.language, plan.offerId);
- pricingCta.dataset.planUrl = planUrl;
- pricingCta.id = plan.stringId;
- }
- }
-
- if (sendAnalyticEvent) {
- const adobeEventName = 'adobe.com:express:pricing:commitmentType:selected';
- const sparkEventName = 'pricing:commitmentTypeSelected';
- pushPricingAnalytics(adobeEventName, sparkEventName, plan);
- }
-}
-
-function displayPlans(card, plans) {
- const planContainer = card.querySelector('.puf-card-plans');
- const cardSwitch = createTag('label', { class: 'puf-card-switch' });
- const checkbox = createTag('input', {
- type: 'checkbox',
- class: 'puf-card-checkbox',
- });
- const slider = createTag('span', { class: 'puf-card-slider' });
- const defaultPlan = createTag('div', { class: 'strong' });
- const secondPlan = createTag('div');
-
- defaultPlan.innerHTML = plans[0].text.replace(
- plans[0].plan,
- `${plans[0].plan}`,
- );
- secondPlan.innerHTML = plans[1].text.replace(
- plans[1].plan,
- `${plans[1].plan}`,
- );
-
- planContainer.append(defaultPlan);
- planContainer.append(cardSwitch);
- cardSwitch.append(checkbox);
- cardSwitch.append(slider);
- planContainer.append(secondPlan);
-
- checkbox.addEventListener('change', () => {
- if (checkbox.checked) {
- defaultPlan.classList.remove('strong');
- secondPlan.classList.add('strong');
- selectPlan(card, plans[1].url, true);
- } else {
- defaultPlan.classList.add('strong');
- secondPlan.classList.remove('strong');
- selectPlan(card, plans[0].url, true);
- }
- });
-
- return planContainer;
-}
-
-function buildPlans(plansElement) {
- const plans = [];
-
- plansElement.forEach((plan) => {
- const planLink = plan.querySelector('a');
-
- if (planLink) {
- plans.push({
- url: planLink.href,
- plan: planLink.textContent.trim(),
- text: plan.textContent.trim(),
- });
- }
- });
-
- return plans;
-}
-
-async function decorateCard(block, cardClass = '') {
- const cardClassName = `puf-card ${cardClass}`.trim();
- const cardContainer = createTag('div', { class: 'puf-card-container' });
- const cardBorder = createTag('div', { class: 'puf-card-border' });
- const card = createTag('div', { class: cardClassName });
- const cardBanner = block.children[0].children[0];
- const cardTop = block.children[1].children[0];
- const cardBottom = block.children[2].children[0];
- const cardHeader = cardTop.querySelector('h3, p:first-of-type');
- const cardHeaderIcon = cardTop.querySelector('svg') || cardTop.querySelector('img');
- const cardPricingContainer = createTag('div', {
- class: 'puf-pricing-container',
- });
- const cardBasePriceHeader = createTag('h2', { class: 'puf-bp-header' });
- const cardPricingHeader = createTag('h2', { class: 'puf-pricing-header' });
- const cardPricingSufContainer = createTag('div', {
- class: 'puf-pricing-suf-container',
- });
- const cardPricingSuf = createTag('div', { class: 'puf-pricing-suf' });
- const cardVat = createTag('div', { class: 'puf-vat-info' });
- const cardAdditionalContext = createTag('div', {
- class: 'puf-pricing-context',
- });
- const cardPlansContainer = createTag('div', { class: 'puf-card-plans' });
- const cardCta = createTag('a', { class: 'button large' });
- const plansElement = cardTop.querySelectorAll('li');
- const listItems = cardBottom.querySelectorAll('svg');
- const plans = buildPlans(plansElement);
-
- if (cardClass === 'puf-left'
- && !['off', 'no', 'false'].includes(getMetadata('puf-left-reverse')?.toLowerCase())) {
- cardCta.classList.add('reverse', 'accent');
- }
-
- let formattedHeader = createTag('h3');
- if (cardHeader?.tagName === 'P') {
- formattedHeader.textContent = cardHeader.lastChild.data;
- } else if (cardHeader?.tagName === 'H3') {
- formattedHeader = cardHeader;
- }
-
- cardBanner.classList.add('puf-card-banner');
- cardTop.classList.add('puf-card-top');
- cardBottom.classList.add('puf-card-bottom');
-
- cardPricingContainer.append(
- cardBasePriceHeader,
- cardPricingHeader,
- cardPricingSufContainer,
- );
- cardPricingSufContainer.append(cardPricingSuf, cardVat);
- cardTop.prepend(
- cardHeader,
- cardPricingContainer,
- cardAdditionalContext,
- cardPlansContainer,
- cardCta,
- );
- card.append(cardBanner, cardTop, cardBottom);
-
- if (!cardBanner.textContent.trim()) {
- cardBanner.style.display = 'none';
- } else {
- cardBanner.innerHTML = createTag(
- 'span',
- { class: 'banner-text' },
- cardBanner.innerHTML,
- ).outerHTML;
- cardBanner.classList.add('recommended');
- }
-
- if (cardHeaderIcon) formattedHeader.prepend(cardHeaderIcon);
-
- const ctaTextContainer = cardTop.querySelector('strong');
- if (ctaTextContainer) {
- cardCta.textContent = ctaTextContainer.textContent.trim();
- ctaTextContainer.parentNode.remove();
- } else {
- cardCta.textContent = 'Start your trial';
- }
-
- if (plans.length) {
- await selectPlan(card, plans[0].url, false);
-
- if (plans.length > 1) {
- displayPlans(card, plans);
- }
- }
-
- cardTop.querySelector('ul')
- ?.remove();
-
- const pricingContextContainer = cardTop.querySelector('em');
- if (pricingContextContainer) {
- cardAdditionalContext.textContent = pricingContextContainer.textContent.trim();
- pricingContextContainer.parentNode.remove();
- } else {
- cardAdditionalContext.remove();
- }
-
- // cardContainer.append(card);
- cardContainer.append(cardBorder);
- cardBorder.append(card);
-
- if (listItems) {
- listItems.forEach((listItem) => {
- listItem.parentNode.classList.add('puf-list-item');
- });
- }
-
- return cardContainer;
-}
-
-function wrapTextAndSup(block) {
- const supTags = block.getElementsByTagName('sup');
- Array.from(supTags)
- .forEach((supTag) => {
- supTag.classList.add('puf-sup');
- });
-
- const listItems = block.querySelectorAll('.puf-list-item');
- listItems.forEach((listItem) => {
- const { childNodes } = listItem;
-
- const filteredChildren = Array.from(childNodes)
- .filter((node) => {
- const isSvg = node.tagName && node.tagName.toLowerCase() === 'svg';
- const isTextNode = node.nodeType === Node.TEXT_NODE;
- return !isSvg && (isTextNode || node.nodeType === Node.ELEMENT_NODE);
- });
-
- const filteredChildrenExceptFirstText = filteredChildren.slice(1);
-
- const textAndSupWrapper = createTag('div', {
- class: 'puf-text-and-sup-wrapper',
- });
- textAndSupWrapper.append(...filteredChildrenExceptFirstText);
- listItem.append(textAndSupWrapper);
- });
-}
-
-function formatTextElements(block) {
- const highlightRegex = /^\(\(.*\)\)$/;
- const dividerRegex = /^--.*--$/;
- const blockElements = Array.from(block.querySelectorAll('*'));
-
- if (
- !blockElements.some(
- (el) => highlightRegex.test(el.textContent)
- || dividerRegex.test(el.textContent),
- )
- ) {
- return;
- }
-
- const highlightedEls = blockElements.filter((el) => highlightRegex.test(el.textContent));
-
- highlightedEls.forEach((el) => {
- el.classList.add('puf-highlighted-text');
- el.textContent = el.textContent
- .replace(/^\(\(/, '')
- .replace(/\)\)$/, '');
- });
-
- const dividerElements = blockElements.filter((el) => dividerRegex.test(el.textContent));
-
- dividerElements.forEach((el) => {
- el.classList.add('puf-divider-text');
- el.textContent = el.textContent
- .replace(/^--/, '')
- .replace(/--$/, '');
- });
-}
-
-function decorateFooter(block) {
- if (block?.children?.[3]) {
- const footer = createTag('div', { class: 'puf-pricing-footer' });
- footer.append(block.children[3]);
- return footer;
- } else {
- return '';
- }
-}
-
-function matchTwoElementsHeight(el1, el2) {
- // ^ not the clearest name (sets the shortest of two elements to the tallest element's height)
- if (el1 && el2) {
- const maxHeight = Math.max(
- el1.getBoundingClientRect().height,
- el2.getBoundingClientRect().height,
- );
- el1.style.height = `${maxHeight}px`;
- el2.style.height = `${maxHeight}px`;
- }
-}
-
-function alignContent() {
- const block = document.querySelector('.puf');
- const rightDescription = block.querySelector(
- '.puf-card.puf-right > .puf-card-top > p:last-of-type',
- );
- const leftDescription = block.querySelector(
- '.puf-card.puf-left > .puf-card-top > p:last-of-type',
- );
- const rightHeading = block.querySelector(
- '.puf-card.puf-right > .puf-card-bottom > h3',
- );
- const leftHeading = block.querySelector(
- '.puf-card.puf-left > .puf-card-bottom > h3',
- );
-
- if (rightDescription) rightDescription.style.height = 'auto';
- if (leftDescription) leftDescription.style.height = 'auto';
- if (rightHeading) rightHeading.style.height = 'auto';
- if (leftHeading) leftHeading.style.height = 'auto';
-
- if (window.innerWidth >= 900) {
- matchTwoElementsHeight(rightDescription, leftDescription);
- matchTwoElementsHeight(rightHeading, leftHeading);
- }
-}
-
-const resizeObserver = new ResizeObserver((entries) => {
- entries.forEach(() => {
- alignContent();
- });
-});
-
-async function build1ColDesign(block) {
- const pricingCard = await decorateCard(block);
- const footer = decorateFooter(block);
-
- block.innerHTML = '';
- block.append(pricingCard);
-
- addPublishDependencies('/express/system/offers-new.json?limit=5000');
- wrapTextAndSup(block);
- block.append(footer);
- formatTextElements(block);
-}
-
-async function build2ColDesign(block) {
- invisContainer = createTag('div');
- parent = block.parentElement;
- invisContainer.style.visibility = 'hidden';
- invisContainer.style.display = 'block';
- invisContainer.append(block);
- const main = document.body.querySelector('main');
- main.append(invisContainer);
- const leftCard = await decorateCard(block, 'puf-left');
- const rightCard = await decorateCard(block, 'puf-right');
- const footer = decorateFooter(block);
- block.innerHTML = '';
- block.append(leftCard, rightCard);
- await buildCarousel('.puf-card-container', block);
- parent.append(block);
- invisContainer.remove();
- resizeObserver.observe(rightCard);
- const options = {
- root: document.querySelector('.carousel-platform'),
- rootMargin: '0px',
- threshold: 0.55,
- };
- const carouselContainer = block.querySelector('.carousel-container');
- const callback = (entries) => {
- entries.forEach((entry) => {
- if (!entry.isIntersecting) return;
- if (window.innerWidth >= 900) {
- carouselContainer.style.maxHeight = 'none';
- } else {
- carouselContainer.style.maxHeight = `${entry.target.clientHeight}px`;
- }
- });
- };
-
- const intersectionObserver = new IntersectionObserver(callback, options);
- intersectionObserver.observe(rightCard);
- intersectionObserver.observe(leftCard);
- addPublishDependencies('/express/system/offers-new.json?limit=5000');
- wrapTextAndSup(block);
- block.append(footer);
- formatTextElements(block);
-}
-async function buildPUF(block) {
- const colCount = block?.children[1]?.children?.length;
- switch (colCount) {
- case 1:
- await build1ColDesign(block);
- break;
- case 2:
- await build2ColDesign(block);
- break;
- default:
- break;
- }
-}
-
-export default async function decorate(block) {
- await buildPUF(block);
-}
diff --git a/express/scripts/utils.js b/express/scripts/utils.js
index 82d02a3c9..f03f41f95 100644
--- a/express/scripts/utils.js
+++ b/express/scripts/utils.js
@@ -238,19 +238,6 @@ export function sampleRUM(checkpoint, data = {}, forceSampleRate) {
}
}
-export function addPublishDependencies(url) {
- if (!Array.isArray(url)) {
- // eslint-disable-next-line no-param-reassign
- url = [url];
- }
- window.hlx = window.hlx || {};
- if (window.hlx.dependencies && Array.isArray(window.hlx.dependencies)) {
- window.hlx.dependencies.concat(url);
- } else {
- window.hlx.dependencies = url;
- }
-}
-
export function toClassName(name) {
return name && typeof name === 'string'
? name.trim().toLowerCase().replace(/[^0-9a-z]/gi, '-')
diff --git a/express/styles/styles.css b/express/styles/styles.css
index 034bb8a05..40e867f23 100644
--- a/express/styles/styles.css
+++ b/express/styles/styles.css
@@ -1065,7 +1065,7 @@ body[data-device="mobile"] main .floating-button-wrapper[data-audience="mobile"]
display: block;
}
-main > div:not(.banner-container) .block:not(.pricing-summary, .pricing-cards, .pricing-table, .simplified-pricing-cards, .puf, .split-action, .link-list, .wayfinder, .ratings, .ribbon-banner) a.button.same-fcta {
+main > div:not(.banner-container) .block:not(.pricing-summary, .pricing-cards, .pricing-table, .simplified-pricing-cards, .split-action, .link-list, .wayfinder, .ratings, .ribbon-banner) a.button.same-fcta {
display: none;
}
@@ -1105,7 +1105,7 @@ main .long-form.grid-width-6-desktop.narrow .default-content-wrapper {
text-align: left;
}
- main > div:not(.banner-container) .block:not(.pricing-summary, .pricing-cards, .pricing-table, .puf, .link-list, .wayfinder, .ratings) a.button.same-fcta {
+ main > div:not(.banner-container) .block:not(.pricing-summary, .pricing-cards, .pricing-table, .link-list, .wayfinder, .ratings) a.button.same-fcta {
display: inline-block;
}
}
diff --git a/test/unit/blocks/premium-plan/premium-plan.test.js b/test/unit/blocks/premium-plan/premium-plan.test.js
deleted file mode 100644
index 35dea5820..000000000
--- a/test/unit/blocks/premium-plan/premium-plan.test.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* eslint-env mocha */
-/* eslint-disable no-unused-vars */
-
-const { default: decorate } = await import('../../../../express/blocks/premium-plan/premium-plan.js');
diff --git a/test/unit/blocks/puf/puf.test.js b/test/unit/blocks/puf/puf.test.js
deleted file mode 100644
index c32a0a192..000000000
--- a/test/unit/blocks/puf/puf.test.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* eslint-env mocha */
-/* eslint-disable no-unused-vars */
-
-const { default: decorate } = await import('../../../../express/blocks/puf/puf.js');
From ef095a7f450be66a55f9f88b0c9f5a22c6906bab Mon Sep 17 00:00:00 2001
From: jsandland
Date: Thu, 12 Dec 2024 14:41:50 -0700
Subject: [PATCH 2/9] Allow Authors To Set Background Image in Banner (#1322)
* allow bgImage to be authored for banner
* CSS for bgImage
---
express/blocks/banner/banner.css | 8 ++++++++
express/blocks/banner/banner.js | 14 ++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/express/blocks/banner/banner.css b/express/blocks/banner/banner.css
index 63e641981..a7e3aa6d6 100644
--- a/express/blocks/banner/banner.css
+++ b/express/blocks/banner/banner.css
@@ -8,6 +8,14 @@ main div:has(> .banner.cool) {
background: linear-gradient(170.96deg, #bfe4ff -0.25%, #cecef6 104.12%);
}
+main .section .banner .bg-img-container {
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ padding: 20px;
+ max-height: 300px;
+}
+
main .section.banner-container,
main .section.banner-light-container {
padding: 80px 15px;
diff --git a/express/blocks/banner/banner.js b/express/blocks/banner/banner.js
index ce29f874b..99a48e745 100644
--- a/express/blocks/banner/banner.js
+++ b/express/blocks/banner/banner.js
@@ -6,6 +6,20 @@ export default async function decorate(block) {
const isBannerCoolVariant = block.classList.contains('cool');
const isBannerNarrowVariant = block.classList.contains('narrow');
+ const bgImgURL = block.children[0]?.querySelector('img')?.src;
+ const header = block.querySelector('h2');
+ if (header) {
+ const headerParent = header.parentElement;
+ if (bgImgURL) {
+ const firstChild = block.children[0];
+ if (firstChild) {
+ block.removeChild(firstChild);
+ }
+ headerParent.classList.add('bg-img-container');
+ headerParent.style.backgroundImage = `url(${bgImgURL})`;
+ }
+ }
+
if (isBannerStandoutVariant || isBannerCoolVariant) {
const contentContainer = createTag('div', {
class: 'content-container',
From 208202e9b1c294a695fbf8aa1dac7491b67767a3 Mon Sep 17 00:00:00 2001
From: jsandland
Date: Thu, 12 Dec 2024 15:33:51 -0700
Subject: [PATCH 3/9] Ensures Carousel Card Edit This Template Button Works On
Mobile (#1323)
* ensure edit this template button works
* Update express/blocks/shared/basic-carousel.js
Co-authored-by: Brad Johnson
---------
Co-authored-by: Brad Johnson
---
express/blocks/shared/basic-carousel.js | 43 ++++++++++++-------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/express/blocks/shared/basic-carousel.js b/express/blocks/shared/basic-carousel.js
index 74517f86d..d0841adaf 100644
--- a/express/blocks/shared/basic-carousel.js
+++ b/express/blocks/shared/basic-carousel.js
@@ -169,33 +169,30 @@ function initializeCarousel(selector, parent) {
e.changedTouches[0].clientX,
e.changedTouches[0].clientY,
);
- const parentElement = tappedElement.closest('.template.basic-carousel-element');
+ const isBtn = tappedElement.querySelector('.button-container.singleton-hover');
+ const isCard = tappedElement.closest('.template.basic-carousel-element');
if (tappedElement) {
const shareIconWrapper = tappedElement.closest('.share-icon-wrapper');
- const linkHref = parentElement.querySelector('a').href;
- if (linkHref) {
- if (shareIconWrapper) {
- e.stopPropagation();
- navigator.clipboard.writeText(linkHref).then(() => {
- const tooltip = shareIconWrapper.querySelector('.shared-tooltip');
- if (tooltip) {
- tooltip.classList.add('display-tooltip');
- setTimeout(() => tooltip.classList.remove('display-tooltip'), 2000);
- }
- }).catch((err) => {
- console.error('Failed to copy link:', err);
- });
-
- return;
- }
+ const linkHref = isCard?.querySelector('a')?.href || isBtn?.querySelector('a')?.href;
+ if (linkHref && shareIconWrapper) {
+ e.stopPropagation();
+ navigator.clipboard.writeText(linkHref).then(() => {
+ const tooltip = shareIconWrapper.querySelector('.shared-tooltip');
+ if (tooltip) {
+ tooltip.classList.add('display-tooltip');
+ setTimeout(() => tooltip.classList.remove('display-tooltip'), 2000);
+ }
+ }).catch((err) => {
+ window.lana?.log('Failed to copy link:', err);
+ });
+ return;
}
-
- if (parentElement) {
- const isHoverActive = parentElement.querySelector('.button-container.singleton-hover');
+ if (isCard && linkHref) {
+ const isHoverActive = isCard?.querySelector('.button-container.singleton-hover');
if (isHoverActive && linkHref) {
window.location.href = linkHref;
}
- const tappedIndex = Array.from(elements).indexOf(parentElement);
+ const tappedIndex = Array.from(elements).indexOf(isCard);
if (tappedIndex !== -1) {
if (tappedIndex < currentIndex) {
currentIndex = Math.max(0, tappedIndex);
@@ -204,7 +201,7 @@ function initializeCarousel(selector, parent) {
currentIndex = Math.min(elements.length - 1, tappedIndex);
updateCarousel();
} else {
- const btnContainer = parentElement.querySelector('.button-container');
+ const btnContainer = isCard.querySelector('.button-container');
if (btnContainer) {
btnContainer.dispatchEvent(new Event('carouseltapstart'));
setTimeout(() => {
@@ -213,6 +210,8 @@ function initializeCarousel(selector, parent) {
}
}
}
+ } else if (isBtn && linkHref) {
+ window.location.href = linkHref;
}
}
});
From d802decb983c6067de91d1cfa01f8e99f68943ec Mon Sep 17 00:00:00 2001
From: jsandland
Date: Wed, 18 Dec 2024 18:29:26 +0000
Subject: [PATCH 4/9] How To Steps Accordion (#1324)
* how-to-steps-accordion.js
* how-to-steps-accordion.css
* remove $ from js code
* mobile image aspect ratio maintained between screen sizes, max-width set to 400
* wip - mobile and tablet container sizing complete
* all layout / positioning from mobile to desktop complete for image and video
* ensures video is sized and centered for mobile, tablet and desktop
* ensure hover only applies to header and not sub-text
* set background from mobile to desktop
* ensure background image looks consistent
* use vw for top value for background to allow a dynamic position on window re-size - this prevents the bgImage from moving too low into the steps
* rename to how-to-v2
* remove steps from name
* update CSS classes to use new block name
* adds margin-top to header of video container
---
express/blocks/how-to-v2/how-to-v2.css | 216 +++++++++++++++++++++++++
express/blocks/how-to-v2/how-to-v2.js | 129 +++++++++++++++
2 files changed, 345 insertions(+)
create mode 100644 express/blocks/how-to-v2/how-to-v2.css
create mode 100644 express/blocks/how-to-v2/how-to-v2.js
diff --git a/express/blocks/how-to-v2/how-to-v2.css b/express/blocks/how-to-v2/how-to-v2.css
new file mode 100644
index 000000000..ea7a97634
--- /dev/null
+++ b/express/blocks/how-to-v2/how-to-v2.css
@@ -0,0 +1,216 @@
+main .how-to-v2 h2 {
+ font-size: 22px;
+ text-align: center;
+ padding: 0 24px;
+}
+
+main .how-to-v2 ol {
+ list-style-type: none;
+ font-size: 21px;
+ font-weight: 900;
+}
+
+main .how-to-v2 ol li {
+ padding: 8px 0;
+ cursor: pointer;
+ transition: all 0.21s;
+ display: flex;
+}
+
+main .how-to-v2 ol li .step-indicator {
+ width: 5px;
+ min-width: 5px;
+ background: linear-gradient(-96.68deg, #FF4885 5.24%, #FC7D00 94.76%), #686DF4;
+ border-radius: 2.5px;
+}
+
+main .how-to-v2 ol li .step-content {
+ padding: 8px 16px;
+ margin: 0;
+}
+
+main .how-to-v2 ol li .step-indicator:has(+ div .closed) {
+ background: linear-gradient(95.55deg, rgba(255, 255, 255, 0.5) 4.43%, rgba(255, 255, 255, 0.3) 93.65%), #8F8F8F;
+}
+
+main .how-to-v2 ol li h3 {
+ text-align: left;
+ font-size: 18px;
+ line-height: 23.4px;
+ font-weight: 700;
+}
+
+main .how-to-v2 ol li .detail-container {
+ font-size: 16px;
+ line-height: 20.8px;
+ font-weight: 400;
+}
+
+main .how-to-v2 ol li .detail-container {
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height 0.21s ease-out;
+}
+
+main .how-to-v2 ol li .detail-text {
+ padding-top: 10px;
+}
+
+/* so that there is no initial re-paint */
+main .how-to-v2 ol li:first-child .detail-container {
+ max-height: none;
+}
+
+main .how-to-v2.video lite-youtube,
+main .how-to-v2.image picture {
+ border-radius: 16px;
+ overflow: hidden;
+}
+
+main .how-to-v2 em {
+ font-style: normal;
+ background: linear-gradient(140.08deg, #FF4DD2 67.54%, #FF993B 76.42%);
+ background-size: 108% 108%;
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ font-weight: 900;
+}
+
+main .how-to-v2 .steps-content {
+ display: flex;
+ flex-direction: column;
+ padding: 0 24px;
+ position: relative;
+}
+
+main .how-to-v2 .steps-content .steps-content-backg {
+ position: absolute;
+ width: 100%;
+ top: -24vw;
+ z-index: -1;
+ height: 100%;
+ transform: scale(0.9);
+}
+
+main .how-to-v2 ol.steps {
+ margin: 6px 0 0;
+ padding: 0;
+}
+
+main .how-to-v2 ol.steps .step .step-content h3:hover {
+ background-color: var( --color-gray-100);
+ margin: -8px 0 -8px -16px;
+ padding: 8px 0 8px 16px;
+}
+
+main .how-to-v2.video .video-container {
+ margin-top: 20px;
+}
+
+main .how-to-v2.image .image-container {
+ margin-top: 20px;
+ width: 100%;
+ overflow: hidden;
+}
+
+main .how-to-v2.image .image-container img,
+main .how-to-v2.video .video-container > * {
+ border-radius: 16px;
+ max-width: 400px;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+main .how-to-v2.video .video-container > * {
+ margin-left: auto;
+ margin-right: auto;
+ height: unset;
+}
+
+main .how-to-v2.video,
+main .how-to-v2.image {
+ /* note we don't set margin here because background gradient has to go past into this container */
+ margin: 0;
+ max-width: unset;
+}
+
+@media (min-width: 768px) {
+
+ main .how-to-v2 h2 {
+ font-size: 28px;
+ }
+
+ main .how-to-v2.video,
+ main .how-to-v2.image {
+ max-width: 950px;
+ margin: auto;
+ }
+
+ main .how-to-v2 .steps-content {
+ display: flex;
+ flex-direction: row;
+ padding: 0 24px;
+ }
+
+ main .how-to-v2 .steps-content > * {
+ flex: 1 1 50%;
+ box-sizing: border-box;
+ }
+
+ main .how-to-v2.image .image-container,
+ main .how-to-v2.video .video-container {
+ align-items: center;
+ display: inline-grid;
+ }
+
+ main .how-to-v2.image .image-container img {
+ height: unset;
+ }
+
+ main .how-to-v2 .steps-content .steps {
+ padding-left: 20px;
+ }
+
+ main .how-to-v2 .steps-content .steps-content-backg {
+ left: -90px;
+ width: 67%;
+ transform: scale(0.9);
+ top: -68px;
+ }
+}
+
+@media (min-width: 1280px) {
+
+ main .how-to-v2 h2 {
+ font-size: 36px;
+ }
+
+ main .how-to-v2.video,
+ main .how-to-v2.image {
+ max-width: 1300px;
+ margin: auto;
+ }
+
+ main .how-to-v2.image .image-container img,
+ main .how-to-v2.video .video-container > * {
+ max-height: 300px;
+ max-width: 533px;
+ }
+
+ main .how-to-v2.image .image-container {
+ display: inline-block;
+ }
+
+ main .how-to-v2 .steps-content {
+ margin-top: 30px;
+ }
+
+ main .how-to-v2 ol li h3 {
+ text-align: left;
+ font-size: 22px;
+ line-height: 28.6px;
+ font-weight: 700;
+ }
+}
diff --git a/express/blocks/how-to-v2/how-to-v2.js b/express/blocks/how-to-v2/how-to-v2.js
new file mode 100644
index 000000000..6d4099b25
--- /dev/null
+++ b/express/blocks/how-to-v2/how-to-v2.js
@@ -0,0 +1,129 @@
+/* eslint-disable import/named, import/extensions */
+import { createTag } from '../../scripts/utils.js';
+import { embedYoutube } from '../../scripts/embed-videos.js';
+
+function setStepDetails(block, indexOpenedStep) {
+ const listItems = block.querySelectorAll(':scope li');
+
+ listItems.forEach((item, i) => {
+ const detail = item.querySelector('.detail-container');
+
+ if (i === indexOpenedStep) {
+ detail.classList.remove('closed');
+ detail.style.maxHeight = `${detail.scrollHeight}px`;
+ } else {
+ detail.classList.add('closed');
+ detail.style.maxHeight = '0';
+ }
+ });
+}
+
+function buildAccordion(block, rows, stepsContent) {
+ let indexOpenedStep = 0;
+ const list = createTag('OL', { class: 'steps' });
+
+ rows.forEach((row, i) => {
+ const [stepTitle, stepDetail] = row.querySelectorAll(':scope div');
+
+ const newStepTitle = createTag('h3');
+ newStepTitle.replaceChildren(...stepTitle.childNodes);
+
+ const listItem = createTag('LI', { class: 'step', tabindex: '0' });
+ list.append(listItem);
+
+ const listItemIndicator = createTag('div', { class: 'step-indicator' });
+ const listItemContent = createTag('div', { class: 'step-content' });
+
+ const detailText = stepDetail;
+ detailText.classList.add('detail-text');
+
+ const detailContainer = createTag('div', { class: 'detail-container' });
+
+ if (i !== 0) {
+ detailContainer.classList.add('closed');
+ }
+
+ detailContainer.append(detailText);
+
+ listItem.append(listItemIndicator);
+ listItem.append(listItemContent);
+
+ listItemContent.append(newStepTitle);
+ listItemContent.append(detailContainer);
+
+ const handleOpenDetails = (ev) => {
+ indexOpenedStep = i;
+ setStepDetails(block, indexOpenedStep);
+ ev.preventDefault();
+ };
+
+ newStepTitle.addEventListener('click', handleOpenDetails);
+ listItem.addEventListener('keyup', (ev) => ev.which === 13 && handleOpenDetails(ev));
+ });
+
+ stepsContent.append(list);
+
+ // set this in the next event cycle when scrollHeight has been established
+ setTimeout(() => {
+ setStepDetails(block, indexOpenedStep);
+ }, 0);
+}
+
+export default async function decorate(block) {
+ const isVideoVariant = block.classList.contains('video');
+ const isImageVariant = block.classList.contains('image');
+
+ const section = block.closest('.section');
+ const rows = Array.from(block.children);
+
+ const backgroundRow = block.children[0];
+ const backgroundImage = backgroundRow.querySelector('img');
+ const backgroundURL = backgroundImage?.src;
+ const hasBackground = !!backgroundURL;
+
+ if (hasBackground) {
+ rows.shift();
+ }
+
+ if (isVideoVariant || isImageVariant) {
+ const stepsContent = createTag('div', { class: 'steps-content' });
+
+ if (hasBackground) {
+ // So that background image goes beyond container
+ const stepsContentBackground = createTag('div', { class: 'steps-content-backg' });
+ const stepsContentBackgroundImg = createTag('img', { class: 'steps-content-backg-image' });
+ stepsContent.append(stepsContentBackground);
+ stepsContentBackground.append(stepsContentBackgroundImg);
+ stepsContentBackgroundImg.src = backgroundURL;
+ }
+
+ if (isVideoVariant) {
+ const videoData = rows.shift();
+
+ // remove the added social link from the block DOM
+ block.removeChild(block.children[0]);
+
+ const videoLink = videoData.querySelector('a');
+ const youtubeURL = videoLink?.href;
+ const url = new URL(youtubeURL);
+
+ const videoContainerEl = createTag('div', { class: 'video-container' });
+
+ const videoEl = embedYoutube(url);
+ videoEl.classList.add('video-how-to-steps-accordion');
+
+ videoContainerEl.append(videoEl);
+ stepsContent.append(videoContainerEl);
+ } else {
+ const imageData = rows.shift();
+ const imageEl = imageData.querySelector('picture');
+ const imageContainerEl = createTag('div', { class: 'image-container' });
+ imageContainerEl.append(imageEl);
+ stepsContent.append(imageContainerEl);
+ }
+
+ const heading = section.querySelector('h2, h3, h4');
+ block.replaceChildren(heading, stepsContent);
+ buildAccordion(block, rows, stepsContent);
+ }
+}
From b0b884dbc6713650d92e0e0a38e6c02d42e7e778 Mon Sep 17 00:00:00 2001
From: Eric Chen <159481679+echen-adobe@users.noreply.github.com>
Date: Thu, 9 Jan 2025 12:30:52 -0800
Subject: [PATCH 5/9] Shrink Mobile Fork Button Font (#1328)
* Update mobile-fork-button.css
* Update mobile-fork-button.css
* Update mobile-fork-button.css
* Update mobile-fork-button.css
* ...
* ...
* Update mobile-fork-button.js
* Update mobile-fork-button-frictionless.js
* lint
---
.../mobile-fork-button-frictionless.css | 16 +++++++++++-----
.../mobile-fork-button-frictionless.js | 14 ++++++++++++++
.../mobile-fork-button/mobile-fork-button.css | 16 +++++++++++-----
.../mobile-fork-button/mobile-fork-button.js | 14 ++++++++++++++
4 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.css b/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.css
index 735bb5b86..86b00dc4b 100644
--- a/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.css
+++ b/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.css
@@ -1,5 +1,10 @@
main .floating-button-wrapper.mobile-fork-button-frictionless, main .mobile-fork-button-frictionless {
z-index: 10;
+ --mfb-font-size: 16px;
+}
+
+main .mobile-fork-button-frictionless.long-text {
+ --mfb-font-size: 14px;
}
main .mobile-gating-text {
@@ -8,7 +13,7 @@ main .mobile-gating-text {
text-align: left;
flex-grow: 1;
font-weight: 400;
- font-size: var(--body-font-size-m);
+ font-size: var(--mfb-font-size);
}
main .mobile-gating-text, main .mobile-fork-button-frictionless .floating-button .mobile-gating-row .icon{
@@ -41,7 +46,7 @@ main .mobile-fork-button-frictionless .floating-button.block {
main .mobile-gating-row {
display: flex;
gap: 10px;
- height: 40px;
+ min-height: 40px;
}
main .mobile-gating-header {
@@ -53,9 +58,10 @@ main .mobile-gating-header {
main .mobile-fork-button-frictionless .floating-button a.button:any-link {
border-radius: 20px;
- font-size: var(--body-font-size-m);
- min-width: 136px;
- width: 40%;
+ font-size: var(--mfb-font-size);
+ min-width: 150px;
+ margin: auto;
+ width: 50%;
color: var(--color-white);
background-color: var(--color-info-accent);
border-color: var(--color-info-accent);
diff --git a/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.js b/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.js
index 0ffaf68f7..c6e05be46 100644
--- a/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.js
+++ b/express/blocks/mobile-fork-button-frictionless/mobile-fork-button-frictionless.js
@@ -8,6 +8,16 @@ import {
createFloatingButton,
} from '../shared/floating-cta.js';
+const LONG_TEXT_CUTOFF = 70;
+
+const getTextWidth = (text, font) => {
+ const canvas = document.createElement('canvas');
+ const context = canvas.getContext('2d');
+ context.font = font;
+ const metrics = context.measureText(text);
+ return metrics.width;
+};
+
function buildAction(entry, buttonType) {
const wrapper = createTag('div', { class: 'floating-button-inner-row mobile-gating-row' });
const text = createTag('div', { class: 'mobile-gating-text' });
@@ -94,6 +104,9 @@ function collectFloatingButtonData(eligible) {
});
}
aTag.textContent = text;
+ if (getTextWidth(text, 16) > LONG_TEXT_CUTOFF) {
+ data.longText = true;
+ }
data.tools.push({
icon,
anchor: aTag,
@@ -122,4 +135,5 @@ export default async function decorate(block) {
const linksPopulated = new CustomEvent('linkspopulated', { detail: blockLinks });
document.dispatchEvent(linksPopulated);
}
+ if (data.longText) blockWrapper.classList.add('long-text');
}
diff --git a/express/blocks/mobile-fork-button/mobile-fork-button.css b/express/blocks/mobile-fork-button/mobile-fork-button.css
index 1e7338b2c..f87cae40c 100644
--- a/express/blocks/mobile-fork-button/mobile-fork-button.css
+++ b/express/blocks/mobile-fork-button/mobile-fork-button.css
@@ -1,5 +1,10 @@
main .floating-button-wrapper.mobile-fork-button, main .mobile-fork-button {
z-index: 10;
+ --mfb-font-size: 16px;
+}
+
+main .mobile-fork-button.long-text {
+ --mfb-font-size: 14px;
}
main .mobile-gating-text {
@@ -8,7 +13,7 @@ main .mobile-gating-text {
text-align: left;
flex-grow: 1;
font-weight: 400;
- font-size: var(--body-font-size-m);
+ font-size: var(--mfb-font-size);
}
main .mobile-gating-text, main .mobile-fork-button .floating-button .mobile-gating-row .icon{
@@ -41,7 +46,7 @@ main .mobile-fork-button .floating-button.block {
main .mobile-gating-row {
display: flex;
gap: 10px;
- height: 40px;
+ min-height: 40px;
}
main .mobile-gating-header {
@@ -53,9 +58,10 @@ main .mobile-gating-header {
main .mobile-fork-button .floating-button a.button:any-link {
border-radius: 20px;
- font-size: var(--body-font-size-m);
- min-width: 136px;
- width: 40%;
+ font-size: var(--mfb-font-size);
+ min-width: 150px;
+ margin: auto;
+ width: 50%;
color: var(--color-white);
background-color: var(--color-info-accent);
border-color: var(--color-info-accent);
diff --git a/express/blocks/mobile-fork-button/mobile-fork-button.js b/express/blocks/mobile-fork-button/mobile-fork-button.js
index 4e136fd7a..f6952b010 100644
--- a/express/blocks/mobile-fork-button/mobile-fork-button.js
+++ b/express/blocks/mobile-fork-button/mobile-fork-button.js
@@ -8,6 +8,16 @@ import {
createFloatingButton,
} from '../shared/floating-cta.js';
+const LONG_TEXT_CUTOFF = 70;
+
+const getTextWidth = (text, font) => {
+ const canvas = document.createElement('canvas');
+ const context = canvas.getContext('2d');
+ context.font = font;
+ const metrics = context.measureText(text);
+ return metrics.width;
+};
+
function buildAction(entry, buttonType) {
const wrapper = createTag('div', { class: 'floating-button-inner-row mobile-gating-row' });
const text = createTag('div', { class: 'mobile-gating-text' });
@@ -89,6 +99,9 @@ function collectFloatingButtonData() {
} = completeSet;
const aTag = createTag('a', { title: text, href });
aTag.textContent = text;
+ if (getTextWidth(text, 16) > LONG_TEXT_CUTOFF) {
+ data.longText = true;
+ }
data.tools.push({
icon,
anchor: aTag,
@@ -121,4 +134,5 @@ export default async function decorate(block) {
const linksPopulated = new CustomEvent('linkspopulated', { detail: blockLinks });
document.dispatchEvent(linksPopulated);
}
+ if (data.longText) blockWrapper.classList.add('long-text');
}
From c0c2ea97dc3383c3cbcfbd017743afcbc9c8ce50 Mon Sep 17 00:00:00 2001
From: Eric Chen <159481679+echen-adobe@users.noreply.github.com>
Date: Mon, 13 Jan 2025 09:29:51 -0800
Subject: [PATCH 6/9] Sync Main With Stage (#1332)
* reverted single video variant
* Update columns.css
* Update columns.css
* Update columns.css
* Sync Stage to Main (#1325)
* MWPW-143385 archive puf & premium-plan blocks (#1284)
* Allow Authors To Set Background Image in Banner (#1322)
* allow bgImage to be authored for banner
* CSS for bgImage
* Ensures Carousel Card Edit This Template Button Works On Mobile (#1323)
* ensure edit this template button works
* Update express/blocks/shared/basic-carousel.js
Co-authored-by: Brad Johnson
---------
Co-authored-by: Brad Johnson
---------
Co-authored-by: Victor Hargrave <115231412+vhargrave@users.noreply.github.com>
Co-authored-by: jsandland
* Mobile Fork Button Font Shrink Hotfix (#1331)
* How To Steps Accordion (#1324)
* how-to-steps-accordion.js
* how-to-steps-accordion.css
* remove $ from js code
* mobile image aspect ratio maintained between screen sizes, max-width set to 400
* wip - mobile and tablet container sizing complete
* all layout / positioning from mobile to desktop complete for image and video
* ensures video is sized and centered for mobile, tablet and desktop
* ensure hover only applies to header and not sub-text
* set background from mobile to desktop
* ensure background image looks consistent
* use vw for top value for background to allow a dynamic position on window re-size - this prevents the bgImage from moving too low into the steps
* rename to how-to-v2
* remove steps from name
* update CSS classes to use new block name
* adds margin-top to header of video container
* Update mobile-fork-button.css
* Update mobile-fork-button.css
* Update mobile-fork-button.css
* Update mobile-fork-button.css
* ...
* ...
* Update mobile-fork-button.js
* Update mobile-fork-button-frictionless.js
* lint
* removed this for now
---------
Co-authored-by: jsandland
---------
Co-authored-by: Brad Johnson
Co-authored-by: Victor Hargrave <115231412+vhargrave@users.noreply.github.com>
Co-authored-by: jsandland
From 2dde2b413d367dc1042df016d4ec6ef050a21757 Mon Sep 17 00:00:00 2001
From: jsandland
Date: Thu, 23 Jan 2025 15:07:32 -0700
Subject: [PATCH 7/9] ensure block width fits inside android / iphone as well
as text wraps (#1337)
---
express/blocks/how-to-steps-carousel/how-to-steps-carousel.css | 2 --
1 file changed, 2 deletions(-)
diff --git a/express/blocks/how-to-steps-carousel/how-to-steps-carousel.css b/express/blocks/how-to-steps-carousel/how-to-steps-carousel.css
index 1f3bc46c3..40b18b36f 100755
--- a/express/blocks/how-to-steps-carousel/how-to-steps-carousel.css
+++ b/express/blocks/how-to-steps-carousel/how-to-steps-carousel.css
@@ -11,10 +11,8 @@ main .how-to-steps-carousel-container > picture > img {
main .how-to-steps-carousel-container > div {
background-color: var(--color-gray-100);
border-radius: 40px;
-
margin: 0 24px;
padding: 56px 24px;
- width: 100%;
max-width: fit-content;
}
From 62bee860768433a4361e6b5c64696905e0c75301 Mon Sep 17 00:00:00 2001
From: "J. Casalino"
Date: Fri, 31 Jan 2025 12:21:05 -0500
Subject: [PATCH 8/9] MWPW-166942 Update Kodiak config.yaml
---
.kodiak/config.yaml | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/.kodiak/config.yaml b/.kodiak/config.yaml
index 2e8487ab1..dc1f1c9fa 100644
--- a/.kodiak/config.yaml
+++ b/.kodiak/config.yaml
@@ -1,20 +1,24 @@
version: 1.0
+#### If you have questions about this, please contact #kodiak-security on Slack. ####
+# Every repository requires a unique Service Now ID number. You need to create a new service using
+# the Service Registry Portal https://adobe.service-now.com/service_registry_portal.do#/search
+# You should NOT leave this default!
snow:
- id: 545804 # Milo Express
notifications:
jira:
default:
- project: MWPW # Mandatory
+ project: MWPW # Project queue in which the security ticket will be created. Can be any valid JIRA project.
filters:
include:
- risk_rating: R5
+ risk_rating: R3 # Please do not change this unless instructed to do so.
fields:
- customfield_11800: MWPW-145743 #epic link
+ customfield_11800: MWPW-164516 # Jira epic security tickets will be assigned to.
customfield_12900:
- value: Express dev
- watchers:
+ value: Express dev # Team security tickets will be assigned to
+ watchers: # Everyone who is an admin on your repository should be a watcher.
- dstrong
- vhargrave
- jinglhua
@@ -23,9 +27,9 @@ notifications:
- all66020
- cod87753
- apganapa
- labels:
+ labels: # You can add additional labels to your tickets here. Do not delete/change the first three.
- "OriginatingProcess=Kodiak"
- "security"
- "kodiak-ticket"
components:
- - name: "DevOps Security"
+ - name: "DevOps Security" # Please do not change this.
From 5fdb38c6e66f69a4f049f7b081dc0f33bc53af7f Mon Sep 17 00:00:00 2001
From: Andrei Tuicu
Date: Mon, 5 May 2025 18:56:46 +0200
Subject: [PATCH 9/9] chore: Configure Trusted Hosts for Sidekick (#1338)
---
tools/sidekick/config.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/sidekick/config.json b/tools/sidekick/config.json
index 0e35c5450..022c9bdcd 100644
--- a/tools/sidekick/config.json
+++ b/tools/sidekick/config.json
@@ -2,6 +2,7 @@
"project": "Express",
"host": "www.adobe.com",
"byocdn": true,
+ "trustedHosts": ["milo.adobe.com"],
"plugins": [
{
"id": "metadata",