Skip to content

MEP Next v1#6201

Open
AdobeLinhart wants to merge 58 commits into
stagefrom
mep-next-v1
Open

MEP Next v1#6201
AdobeLinhart wants to merge 58 commits into
stagefrom
mep-next-v1

Conversation

@AdobeLinhart

@AdobeLinhart AdobeLinhart commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

This is a complete rewrite of the MEP button.

The primary objective is to clean up the code base, decouple functions and maintain readability for future edits while implementing new features. All overlay code should live in the mep-overlay folder with shared functions eventually being moved into mep-next.js as needed.

GENERAL

  • Each card should expand/collapse.
  • Expansion should retain states per session.
  • All options should update based on corresponding URL params upon load in.

AUTHENTICATION
Logged in

  • Should display the Actions tab content.

Logged out

  • Should display a Login to AEM Sidekick card for the actions tab content

MEP TAB

  • Toggles the drawer.

DRAWER
Mep Logo

  • Should link to MMM.

Close Icon

  • Toggles the drawer.

Tabs

  • Should switch between Actions and Summary.

ACTIONS
MEP Manifest List

  • Should list manifests running on page.
  • Should list details about the manifest when expanded.
  • Should have a select with the experiments which updates the Preview button on change.

Highlight Toggles

  • Should have toggles for MEP, CaaS, M@S and Other Fragments.
  • Each toggle lists the amount of "updates" on the page with the element count tracked by a mutation observer.
  • Toggles should highlight the corresponding amount of changes on the page and update the Preview button on change.

Toggles

  • Preview Linke MepButton=off should update the Preview button and turn mep off on preview.
  • If avaiable, show toggle for 7 day MMM manifest data.
  • 7 day MMM manifest data should append available manifests to the list when toggled on following the normal manifest requirements.

Spoof Geo

  • Should always display Top Markets.
  • Should disable MEP Lingo and Lingo M@S if unavaiable.
  • Should have a select with available Geo options per radio button.
  • Should update Geo spoof in real time upon change.
  • Upon reload, should default to the first available select that matches the akamaiLocale parameter, otherwise Top Markets "none".

Load Manifest

  • Accepts a manifest URL provided by MEP sidekick.
  • Should update the preview button.

Preview button

  • Should load in with default active manifests for the href.
  • Should update with a param for any changed input options.
  • Should preview options selected upon click.

SUMMARY
Should have Page, Consent, Lingo, M@S and CaaS cards with the following data.

Page

  • Manifests Found
  • Foundation
  • Theme
  • Target Integration
  • Personalization

Consent

  • Level 2 | Performance
  • Level 4 | Advertising

Lingo

  • Mep Lingo Updates
  • Lang First | Lingo
  • Geo Folder
  • Country Cookie
  • User Country
  • Geo + User

Resolves: MWPW-195019

Test URLs:
(Any Milo page, compare old MEP button to new MEP button.)

  • Before: TBD
  • After: TBD

Psi: https://mep-next-v1--milo--adobecom.aem.page/?martech=off

AdobeLinhart and others added 30 commits June 12, 2026 17:07
Pure rename to preserve git history under the new mep-next/ structure. Import path updates follow in the next commit.
Clears the path so the upcoming `git mv preview.js → mep-next.js` will be detected as a rename rather than a modification.
Pure rename to preserve full git history under mep-next/. The empty mep-next.js placeholder was removed in the prior commit so git detects this as a clean rename (100% similarity), not a modification. Import path updates follow in the next commit.
Updates 5 external callers + the moved files' own relative paths after moving preview.js/.css/.test to libs/features/mep/mep-next/mep-next.{js,css,test.js}.
Splits the 466-line M@S section (MAS_OSI_SELECTOR, market detection, card action stacks, badge injection, content observer) module. mep-next.js shrinks from 1805 → 1340 lines.
Extracts the 54-line CaaS section (CAAS_BADGE_CLASS, derivePathsForCards, injectCaasBadges, removeCaasBadges, caasObserver, watchForCaasBlocks, unwatchForCaasBlocks) into its own module. mep-next.js shrinks from 1340 → 1286 lines.

Preview-host rewrite helpers (PREVIEW_HOST_RE, BLOG_PATH_RE, PREVIEW_REPO_HOST_RE, rewriteForPreviewHost, rewriteBlogPreviewHost) stay in mep-next.js — they were physically adjacent to CaaS code but are shared utilities used by the popup logic elsewhere in the file.

Imports:
- mep-next.js: drops mepCaasConfigUrls (only used in CaaS); adds import block from ./mep-caas.js for the 4 identifiers still referenced (injectCaasBadges, removeCaasBadges, watchForCaasBlocks, unwatchForCaasBlocks)
- mep-caas.js: imports createTag from utils and mepCaasConfigUrls from caas/utils

Single commit so `git log -C --find-copies-harder mep-caas.js` traces provenance back through mep-next.js → preview.js.

Tests: no test file changes needed (no test references CaaS internals). mep-next (118), mep-mas-subcollection (34), and mmm tests all pass.
@AdobeLinhart AdobeLinhart requested review from a team and vgoodric as code owners June 18, 2026 22:11
@aem-code-sync

aem-code-sync Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch.
In case there are problems, just click the checkbox below to rerun the respective action.

  • Re-sync branch
Commits

Comment thread libs/utils/utils.js
@@ -1,3 +1,5 @@
import init from './image-video-link.js';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-unused-vars> reported by reviewdog 🐶
'init' is defined but never used.

Comment thread libs/utils/utils.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-shadow> reported by reviewdog 🐶
'init' is already declared in the upper scope on line 1 column 8.

const splitText = textContent.split('|');

Comment thread libs/utils/utils.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-shadow> reported by reviewdog 🐶
'init' is already declared in the upper scope on line 1 column 8.

mep: mepParam,

Comment thread libs/utils/utils.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-shadow> reported by reviewdog 🐶
'init' is already declared in the upper scope on line 1 column 8.

ajo,

Comment thread libs/utils/utils.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-shadow> reported by reviewdog 🐶
'init' is already declared in the upper scope on line 1 column 8.

if (languageBanner === 'on') {

Comment thread libs/utils/utils.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-shadow> reported by reviewdog 🐶
'init' is already declared in the upper scope on line 1 column 8.

const { default: loadGeoRouting } = await import('../features/georoutingv2/georoutingv2.js');

Comment thread libs/utils/utils.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-shadow> reported by reviewdog 🐶
'init' is already declared in the upper scope on line 1 column 8.

Comment thread libs/utils/utils.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚫 [eslint] <no-shadow> reported by reviewdog 🐶
'init' is already declared in the upper scope on line 1 column 8.

const sourceFromUrl = PAGE_URL.searchParams.get('marketsSource');

Comment on lines +189 to +193
function setHighlightData(manifests) {
const { mep } = getConfig();
if (!mep?.experiments) return;

manifests.forEach(({ selectedVariant, manifest }) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

manifests is undefined here and mep.experiments is always at least [] (initialized in personalization.js), so the guard never short-circuits and this throws. That aborts init() before setDefaultFragments() runs — which is why the default fragment badges do not currently render.

Suggested change
function setHighlightData(manifests) {
const { mep } = getConfig();
if (!mep?.experiments) return;
manifests.forEach(({ selectedVariant, manifest }) => {
function setHighlightData() {
const { mep } = getConfig();
if (!mep?.experiments) return;
mep.experiments.forEach(({ selectedVariant, manifest }) => {

});
}

function setBadgeHandlers() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

setBadgeHandlers here duplicates setBadgeEventListeners above (same selector, same ::before visibility check, same window.open on click) -- both end up attached to document.body. Today it's masked by the setHighlightData crash aborting init() before this line runs, so only one handler is registered. Once that's fixed, both will fire on every badge click and open the fragment in two tabs(tested locally to confirm). Want to pick one and drop the other before this lands.

Comment on lines +395 to +419
onSidekickAuth(async (isAuthed) => {
const mockAuth = new URLSearchParams(window.location.search).get('mock-auth');
const finalAuth = mockAuth !== null ? mockAuth === 'true' : isAuthed;
// eslint-disable-next-line no-console
console.log('[mep-overlay] sidekick auth state:', finalAuth, mockAuth !== null ? '(mocked)' : '');
if (finalAuth === authenticated) return;
authenticated = finalAuth;

const drawerEl = document.querySelector('#mep-drawer');
const contentEl = drawerEl?.querySelector('.mep-tab-content[data-tab="0"]');
if (!contentEl) return;

if (!authenticated) {
contentEl.replaceChildren(buildLoginCard());
drawerEl.querySelector('.mep-footer')?.remove();
return;
}

const cards = buildActionsContent(svgData, pageId);
contentEl.replaceChildren(...cards);
drawerEl.appendChild(buildFooter());
await Promise.all(cards.map((c) => c.ready).filter(Boolean));
setDefaultValues();
setPreviewButton();
}, { envs: ['prod', 'stage'] });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The following were marked TEMP in the original mep-next-v1-auth-updates commits: the envs: ['prod',
'stage'] expansion (your line 418), the mock-auth override block, and the console.log here. Each had a "remove before merge" comment explaining it was test scaffolding. Those comments got dropped during integration but the code stayed. Can we tighten envs back to ['prod'] and drop the mock-auth block + console.log before this is merged?

});
}

export function getPageUpdates(label) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The body + subtree pattern itself isn't new — caasObserver and masObserver in mep-caas.js/mep-mas.js (carried over from preview.js) already use it, but they have an unwatch* teardown and an enable-guard inside the callback. What's new here is that getPageUpdates creates a fresh observer per call and gets invoked 4× from CARD_DATA.actions (MEP, Caas, M@S, Other Fragments) -- 4 perpetual document-wide observers with no teardown and no enable guard. Can they reuse the existing watchers, or scope to the drawer count nodes and disconnect when the drawer closes?

};

let debounceTimer;
const observer = new MutationObserver((mutations) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a second M@S observer doing what watchForMasContent (in mep-mas.js) already does -- same body + subtree, same M@S targets. Can the summary refresh hook into the existing watcher instead of starting a parallel one?

Comment on lines +4 to +5
import {
} from '../mep-caas.js';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit empty import.

@@ -1780,7 +1226,7 @@ export async function saveToMmm() {
}
export default async function decoratePreviewMode() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

After utils.js switched the preview entry to mep-overlay-highlight.js + mep-overlay.js, decoratePreviewMode here is no longer reachable in production -- and most of the helpers only it calls go with it:

Dead (delete):

  • createPreviewPill
  • addHighlightData (duplicate of setHighlightData in mep-overlay-highlight.js)
  • markDefaultFragments (duplicate of setDefaultFragments)
  • addFragmentBadgeClickHandlers (duplicate of the badge-click handler in mep-overlay-highlight.js)

Not replicated in the new overlay -- needs porting before delete:

  • adjustBadgesForZeroHeightSections and adjustStackedBadges. These write --badge-top-offset, which the new overlay
    reads (mep-overlay-highlight.js:221, mep-overlay-highlight.css:196) but never writes. They handle badges in zero-height sections and stacked display: contents badges -- both currently broken on the new path (false-green tests mask this since they exercise decoratePreviewMode).

Duplicated and still in use -- maybe consolidate to one home:

  • API_URLS, parseMepConfig, parsePageAndUrl (also defined in mep-overlay-logic.js; reached by mmm.js through this
    file, so the surviving copy needs to live somewhere both paths can import from)

Live, unchanged: getMepPopup, saveToMmm, escapeHtml, mep-next.css (for mmm.js/personalization.js).

Can decoratePreviewMode + the dead helpers be deleted, the two adjust-badge functions ported to the new overlay init, and the duplicates consolidated?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This file's 118 tests are all run against decoratePreviewMode from mep-next.js, which is no longer the production preview path — utils.js now loads mep-overlay-highlight.js + mep-overlay.js. The live mep-overlay-* path has zero coverage, so green CI here doesn't tell us whether the new overlay works.
Can the tests be retargeted at the live entry points before this merges?

@markpadbe

Copy link
Copy Markdown
Contributor

A couple CI items:

  • ESLint: import init from './image-video-link.js'; at the top of libs/utils/utils.js is unused and shadows local init in 7+ places. Looks like an accidental IDE auto-import -- one-line delete.
  • Nala: failing across MAS, MEP, and MILO. The MEP button suite (mep-button.{spec,page,test}.js) will probably need a full rewrite (let's discuss with @jpratt2) -- every selector targets the old preview-pill/popup, replaced by the FAB/drawer, and there's new surface (auth gate, 4-way toggles, spoof-geo, card state) with no coverage. mep-actions/mep-order don't touch the UI so hopefully unaffected. Some unrelated MILO failures (e.g., brand-concierge) should re-triage cleanly after a rebase onto current stage.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request is not passing all required checks. Please see this discussion for information on how to get all checks passing. Inconsistent checks can be manually retried. If a test absolutely can not pass for a good reason, please add a comment with an explanation to the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants