From 2614acdada4aab2d10f896ef627bff882f2bf2b8 Mon Sep 17 00:00:00 2001 From: Okan Sahin <39759830+mokimo@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:08:33 +0200 Subject: [PATCH 1/4] Increase 404 rum tracking to 10% (#2448) * Increase 404 rum tracking to 10% * Address feedback * Address feedback * Increase the general tracking weight for 404 pages * Increase tracking for 404s * Improve ID creation * Use getMetadata --- libs/scripts/scripts.js | 2 ++ libs/utils/samplerum.js | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libs/scripts/scripts.js b/libs/scripts/scripts.js index 154e81967c..3fce88cd92 100644 --- a/libs/scripts/scripts.js +++ b/libs/scripts/scripts.js @@ -14,6 +14,7 @@ import { loadArea, loadLana, setConfig, + getMetadata, } from '../utils/utils.js'; // Production Domain @@ -161,6 +162,7 @@ const eagerLoad = (img) => { }()); (async function loadPage() { + if (getMetadata('template') === '404') window.SAMPLE_PAGEVIEWS_AT_RATE = 'high'; performance.mark('loadpage'); setConfig(config); loadLana({ clientId: 'milo' }); diff --git a/libs/utils/samplerum.js b/libs/utils/samplerum.js index 652a13bd06..58f0ec07aa 100644 --- a/libs/utils/samplerum.js +++ b/libs/utils/samplerum.js @@ -28,11 +28,12 @@ export function sampleRUM(checkpoint, data = {}) { try { window.hlx = window.hlx || {}; if (!window.hlx.rum) { - const usp = new URLSearchParams(window.location.search); - const weight = (usp.get('rum') === 'on') ? 1 : 100; // with parameter, weight is 1. Defaults to 100. - const id = Array.from({ length: 75 }, (_, i) => String.fromCharCode(48 + i)).filter((a) => /\d|[A-Z]/i.test(a)).filter(() => Math.random() * 75 > 70).join(''); - const random = Math.random(); - const isSelected = (random * weight < 1); + const weight = (window.SAMPLE_PAGEVIEWS_AT_RATE === 'high' && 10) + || (window.SAMPLE_PAGEVIEWS_AT_RATE === 'low' && 1000) + || (new URLSearchParams(window.location.search).get('rum') === 'on' && 1) + || 100; + const id = Math.random().toString(36).slice(-4); + const isSelected = (Math.random() * weight < 1); const firstReadTime = Date.now(); const urlSanitizers = { full: () => window.location.href, @@ -44,7 +45,7 @@ export function sampleRUM(checkpoint, data = {}) { rumSessionStorage.pages = rumSessionStorage.pages ? rumSessionStorage.pages + 1 : 1; sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(rumSessionStorage)); // eslint-disable-next-line object-curly-newline, max-len - window.hlx.rum = { weight, id, random, isSelected, firstReadTime, sampleRUM, sanitizeURL: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'], rumSessionStorage }; + window.hlx.rum = { weight, id, isSelected, firstReadTime, sampleRUM, sanitizeURL: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'], rumSessionStorage }; } const { weight, id, firstReadTime } = window.hlx.rum; From 96ba26c0f0ab9ad1e17762dad1f771efd6f0fae2 Mon Sep 17 00:00:00 2001 From: Mark Perry <124626043+markpadbe@users.noreply.github.com> Date: Thu, 13 Jun 2024 09:08:40 -0700 Subject: [PATCH 2/4] MWPW-151790[MILO][MEP] Organize getPersConfig function in personalization.js (#2454) * replace overridePersonalizationVariant function * Fix chaining * Move parseMepParam * add additional optional chaining operator Co-authored-by: Vivian A Goodrich <101133187+vgoodric@users.noreply.github.com> * Refactor personalization.js * Remove comment * Add back in deleted variants --------- Co-authored-by: Vivian A Goodrich <101133187+vgoodric@users.noreply.github.com> --- .../personalization/personalization.js | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/libs/features/personalization/personalization.js b/libs/features/personalization/personalization.js index 7762907071..c214bafa89 100644 --- a/libs/features/personalization/personalization.js +++ b/libs/features/personalization/personalization.js @@ -495,10 +495,10 @@ const getVariantInfo = (line, variantNames, variants, manifestId) => { }); }; -export function parseConfig(data, manifestId) { +export function parseManifestVariants(data, manifestId) { if (!data?.length) return null; - const config = {}; + const manifestConfig = {}; const experiences = data.map((d) => normalizeKeys(d)); try { @@ -512,12 +512,12 @@ export function parseConfig(data, manifestId) { experiences.forEach((line) => getVariantInfo(line, variantNames, variants, manifestId)); - config.variants = variants; - config.variantNames = variantNames; - return config; + manifestConfig.variants = variants; + manifestConfig.variantNames = variantNames; + return manifestConfig; } catch (e) { /* c8 ignore next 3 */ - console.log('error parsing personalization config:', e, experiences); + console.log('error parsing personalization manifestConfig:', e, experiences); } return null; } @@ -612,7 +612,7 @@ const createDefaultExperiment = (manifest) => ({ variants: {}, }); -export async function getPersConfig(info, variantOverride = false) { +export async function getManifestConfig(info, variantOverride = false) { const { name, manifestData, @@ -637,17 +637,17 @@ export async function getPersConfig(info, variantOverride = false) { if (!persData) return null; let manifestId = getFileName(manifestPath); - const globalConfig = getConfig(); - if (!globalConfig.mep?.preview) { + const config = getConfig(); + if (!config.mep?.preview) { manifestId = false; } else if (name) { manifestId = `${name}: ${manifestId}`; } - const config = parseConfig(persData, manifestId); + const manifestConfig = parseManifestVariants(persData, manifestId); - if (!config) { + if (!manifestConfig) { /* c8 ignore next 3 */ - console.log('Error loading personalization config: ', name || manifestPath); + console.log('Error loading personalization manifestConfig: ', name || manifestPath); return null; } @@ -661,8 +661,8 @@ export async function getPersConfig(info, variantOverride = false) { acc[item.key] = item.value; return acc; }, {}); - config.manifestOverrideName = infoObj?.['manifest-override-name']?.toLowerCase(); - config.manifestType = infoObj?.['manifest-type']?.toLowerCase(); + manifestConfig.manifestOverrideName = infoObj?.['manifest-override-name']?.toLowerCase(); + manifestConfig.manifestType = infoObj?.['manifest-type']?.toLowerCase(); const executionOrder = { 'manifest-type': 1, 'manifest-execution-order': 1, @@ -672,43 +672,43 @@ export async function getPersConfig(info, variantOverride = false) { const index = infoKeyMap[key].indexOf(infoObj[key]); executionOrder[key] = index > -1 ? index : 1; }); - config.executionOrder = `${executionOrder['manifest-execution-order']}-${executionOrder['manifest-type']}`; + manifestConfig.executionOrder = `${executionOrder['manifest-execution-order']}-${executionOrder['manifest-type']}`; } else { // eslint-disable-next-line prefer-destructuring - config.manifestType = infoKeyMap['manifest-type'][1]; - config.executionOrder = '1-1'; + manifestConfig.manifestType = infoKeyMap['manifest-type'][1]; + manifestConfig.executionOrder = '1-1'; } - config.manifestPath = normalizePath(manifestPath); + manifestConfig.manifestPath = normalizePath(manifestPath); const selectedVariantName = await getPersonalizationVariant( - config.manifestPath, - config.variantNames, + manifestConfig.manifestPath, + manifestConfig.variantNames, variantLabel, ); - if (selectedVariantName && config.variantNames.includes(selectedVariantName)) { - config.run = true; - config.selectedVariantName = selectedVariantName; - config.selectedVariant = config.variants[selectedVariantName]; + if (selectedVariantName && manifestConfig.variantNames.includes(selectedVariantName)) { + manifestConfig.run = true; + manifestConfig.selectedVariantName = selectedVariantName; + manifestConfig.selectedVariant = manifestConfig.variants[selectedVariantName]; } else { /* c8 ignore next 2 */ - config.selectedVariantName = 'default'; - config.selectedVariant = 'default'; + manifestConfig.selectedVariantName = 'default'; + manifestConfig.selectedVariant = 'default'; } const placeholders = manifestPlaceholders || data?.placeholders?.data; if (placeholders) { updateConfig( - parsePlaceholders(placeholders, getConfig(), config.selectedVariantName), + parsePlaceholders(placeholders, getConfig(), manifestConfig.selectedVariantName), ); } - config.name = name; - config.manifest = manifestPath; - config.manifestUrl = manifestUrl; - config.disabled = disabled; - config.event = event; - return config; + manifestConfig.name = name; + manifestConfig.manifest = manifestPath; + manifestConfig.manifestUrl = manifestUrl; + manifestConfig.disabled = disabled; + manifestConfig.event = event; + return manifestConfig; } export const deleteMarkedEls = (rootEl = document) => { @@ -838,7 +838,7 @@ export async function applyPers(manifests, postLCP = false) { if (!manifests?.length) return; let experiments = manifests; for (let i = 0; i < experiments.length; i += 1) { - experiments[i] = await getPersConfig(experiments[i], config.mep?.variantOverride); + experiments[i] = await getManifestConfig(experiments[i], config.mep?.variantOverride); } experiments = cleanAndSortManifestList(experiments); From 083f2f1bf5d85ccc654360ac42fa29a753e3196b Mon Sep 17 00:00:00 2001 From: Ryan Clayton Date: Thu, 13 Jun 2024 10:08:47 -0600 Subject: [PATCH 3/4] [MWPW-151673] Library templates (#2455) * [MWPW-151673] Library templates Add templates to sidekick library Resolves: MWPW-151673 * Fixing library unit tests --------- Co-authored-by: Ryan Clayton --- libs/blocks/library-config/library-config.css | 19 ++++- libs/blocks/library-config/library-config.js | 13 ++++ libs/blocks/library-config/lists/blocks.js | 9 ++- libs/blocks/library-config/lists/templates.js | 76 +++++++++++++++++++ .../mocks/blocks/chart/docx.html | 4 +- .../blocks/container/docx-container.html | 6 +- .../blocks/container/docx-single-block.html | 2 +- .../mocks/blocks/marquee/docx.html | 8 +- .../mocks/blocks/text/docx.html | 4 +- 9 files changed, 125 insertions(+), 16 deletions(-) create mode 100644 libs/blocks/library-config/lists/templates.js diff --git a/libs/blocks/library-config/library-config.css b/libs/blocks/library-config/library-config.css index e143cfaa74..1f7b6df019 100644 --- a/libs/blocks/library-config/library-config.css +++ b/libs/blocks/library-config/library-config.css @@ -277,7 +277,8 @@ input.sk-library-search-input:focus { padding: 0 24px; } -.sk-library li.placeholder { +.sk-library li.placeholder, +.sk-library li.template { padding: 0 12px; } @@ -287,6 +288,22 @@ input.sk-library-search-input:focus { padding: 0 12px; } +.sk-library li.template { + display: flex; + align-items: stretch; + justify-content: end; +} + +.sk-library li.template .item-title { + flex: 1 1 100%; +} + +.sk-library li.template button { + position: static; + height: unset; + width: 44px; +} + .in-page { display: flex; justify-content: center; diff --git a/libs/blocks/library-config/library-config.js b/libs/blocks/library-config/library-config.js index 885e7b089b..c7bc4f2026 100644 --- a/libs/blocks/library-config/library-config.js +++ b/libs/blocks/library-config/library-config.js @@ -7,6 +7,11 @@ async function loadBlocks(content, list, query) { blocks(content, list, query); } +async function loadTemplates(content, list) { + const { default: templates } = await import('./lists/templates.js'); + templates(content, list); +} + async function loadPlaceholders(content, list) { const { default: placeholders } = await import('./lists/placeholders.js'); placeholders(content, list); @@ -65,6 +70,9 @@ async function loadList(type, content, list) { addSearch(content, list); loadBlocks(content, list, query); break; + case 'templates': + loadTemplates(content, list); + break; case 'placeholders': loadPlaceholders(content, list); break; @@ -122,6 +130,7 @@ async function combineLibraries(base, supplied) { const library = { assets: await fetchAssetsData(assetsPath), blocks: base.blocks.data, + templates: base.templates?.data, icons: base.icons?.data, personalization_tags: base.personalization?.data, placeholders: base.placeholders?.data, @@ -135,6 +144,10 @@ async function combineLibraries(base, supplied) { if (supplied.placeholders.data.length > 0) { library.placeholders = supplied.placeholders.data; } + + if (supplied.templates?.data.length > 0) { + library.templates.push(...supplied.templates.data); + } } return library; diff --git a/libs/blocks/library-config/lists/blocks.js b/libs/blocks/library-config/lists/blocks.js index ffd35d8395..f5f59352f1 100644 --- a/libs/blocks/library-config/lists/blocks.js +++ b/libs/blocks/library-config/lists/blocks.js @@ -43,13 +43,14 @@ function getContainerName(container) { return getAuthorName(container) || getBlockName(firstBlock); } -function getTable(block) { +export function getTable(block, returnDom = false) { const name = getBlockName(block); const rows = [...block.children]; const maxCols = rows.reduce((cols, row) => ( row.children.length > cols ? row.children.length : cols), 0); const table = document.createElement('table'); table.setAttribute('border', 1); + table.setAttribute('style', 'width: 100%'); const headerRow = document.createElement('tr'); headerRow.append(createTag('th', { colspan: maxCols }, name)); table.append(headerRow); @@ -57,6 +58,7 @@ function getTable(block) { const tr = document.createElement('tr'); [...row.children].forEach((col) => { const td = document.createElement('td'); + td.setAttribute('style', `width: ${100 / row.children.length}%`); if (row.children.length < maxCols) { td.setAttribute('colspan', maxCols); } @@ -65,10 +67,11 @@ function getTable(block) { }); table.append(tr); }); + if (returnDom) return table; return table.outerHTML; } -function handleLinks(element, path) { +export function handleLinks(element, path) { if (!element || !path) return; try { const url = new URL(path); @@ -83,7 +86,7 @@ function handleLinks(element, path) { } } -function decorateImages(element, path) { +export function decorateImages(element, path) { if (!element || !path) return; try { const url = new URL(path); diff --git a/libs/blocks/library-config/lists/templates.js b/libs/blocks/library-config/lists/templates.js new file mode 100644 index 0000000000..2c1f780078 --- /dev/null +++ b/libs/blocks/library-config/lists/templates.js @@ -0,0 +1,76 @@ +import { createTag } from '../../../utils/utils.js'; +import createCopy from '../library-utils.js'; +import { getTable, decorateImages, handleLinks } from './blocks.js'; + +function createSpace() { + const br = createTag('br'); + return createTag('p', null, br); +} + +function formatDom(aemDom, path) { + // Decorate Links + handleLinks(aemDom, path); + + // Decorate Images + decorateImages(aemDom, path); + + // Decorate Blocks + const divs = aemDom.querySelectorAll('main > div > div'); + divs.forEach((div) => { + // Give table some space + div.insertAdjacentElement('afterend', createSpace()); + + const table = getTable(div, true); + div.parentElement.replaceChild(table, div); + }); + + // Decorate Sections + const sections = aemDom.body.querySelectorAll('main > div'); + const formattedSections = [...sections].map((section, idx) => { + const fragment = new DocumentFragment(); + if (idx > 0) { + const divider = createTag('p', null, '---'); + fragment.append(divider, createSpace()); + } + fragment.append(...section.querySelectorAll(':scope > *')); + + return fragment; + }); + const flattedDom = createTag('div'); + flattedDom.append(...formattedSections); + return flattedDom; +} + +async function formatTemplate(path) { + const resp = await fetch(path); + if (!resp.ok) window.lana.log('Could not fetch template path', { tags: 'errorType=info,module=sidekick-templates' }); + + const html = await resp.text(); + const dom = new DOMParser().parseFromString(html, 'text/html'); + return formatDom(dom, path); +} + +export default async function loadTemplates(templates, list) { + templates.forEach(async (template) => { + const titleText = createTag('p', { class: 'item-title' }, template.name); + const title = createTag('li', { class: 'template' }, titleText); + const previewButton = createTag('button', { class: 'preview-group' }, 'Preview'); + const copy = createTag('button', { class: 'copy' }); + const formatted = await formatTemplate(template.path); + + list.append(title); + title.append(previewButton, copy); + + previewButton.addEventListener('click', (e) => { + e.stopPropagation(); + window.open(template.path, '_templatepreview'); + }); + + copy.addEventListener('click', (e) => { + e.target.classList.add('copied'); + setTimeout(() => { e.target.classList.remove('copied'); }, 3000); + const blob = new Blob([formatted.outerHTML], { type: 'text/html' }); + createCopy(blob); + }); + }); +} diff --git a/test/blocks/library-config/mocks/blocks/chart/docx.html b/test/blocks/library-config/mocks/blocks/chart/docx.html index 096d052cac..957326f441 100644 --- a/test/blocks/library-config/mocks/blocks/chart/docx.html +++ b/test/blocks/library-config/mocks/blocks/chart/docx.html @@ -1,3 +1,3 @@ -
chart (area, green, border)
+
chart (area, green, border)

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

-
Revenue dollars: 2020 vs 2021 forecasted vs 2021 actuals.
https://main--milo--adobecom.hlx.page/docs/library/blocks/chart_data/areachart.json
Footnote lorem ipsum dolor sit amet, consectetuer adipiscing elit.
\ No newline at end of file +
Revenue dollars: 2020 vs 2021 forecasted vs 2021 actuals.
https://main--milo--adobecom.hlx.page/docs/library/blocks/chart_data/areachart.json
Footnote lorem ipsum dolor sit amet, consectetuer adipiscing elit.
diff --git a/test/blocks/library-config/mocks/blocks/container/docx-container.html b/test/blocks/library-config/mocks/blocks/container/docx-container.html index d1311e15a7..752c26d474 100644 --- a/test/blocks/library-config/mocks/blocks/container/docx-container.html +++ b/test/blocks/library-config/mocks/blocks/container/docx-container.html @@ -1,15 +1,15 @@ -
carousel (lightbox)
Carousel lightbox
section-metadata
stylexxl spacing

---

Avocado surprise

+
carousel (lightbox)
Carousel lightbox
section-metadata
stylexxl spacing

---

Avocado surprise

-

section-metadata
carouselCarousel lightbox
styleCenter

---

Cabage surprise

+

section-metadata
carouselCarousel lightbox
styleCenter

---

Cabage surprise

-

section-metadata
carouselCarousel lightbox
styleCenter

---

\ No newline at end of file +

section-metadata
carouselCarousel lightbox
styleCenter

---

diff --git a/test/blocks/library-config/mocks/blocks/container/docx-single-block.html b/test/blocks/library-config/mocks/blocks/container/docx-single-block.html index 99f92a87e0..169dcc33bd 100644 --- a/test/blocks/library-config/mocks/blocks/container/docx-single-block.html +++ b/test/blocks/library-config/mocks/blocks/container/docx-single-block.html @@ -1 +1 @@ -
carousel (container0)
Carousel container
\ No newline at end of file +
carousel (container0)
Carousel container
diff --git a/test/blocks/library-config/mocks/blocks/marquee/docx.html b/test/blocks/library-config/mocks/blocks/marquee/docx.html index c2514138a5..ff240b8b7f 100644 --- a/test/blocks/library-config/mocks/blocks/marquee/docx.html +++ b/test/blocks/library-config/mocks/blocks/marquee/docx.html @@ -1,11 +1,11 @@ -
marquee
+
marquee
-
+

@@ -18,11 +18,11 @@

Heading XL Marquee standard medium left

Body M Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.

Lorem ipsum Learn more Text link

-
+ -
\ No newline at end of file +
diff --git a/test/blocks/library-config/mocks/blocks/text/docx.html b/test/blocks/library-config/mocks/blocks/text/docx.html index 71a0437c5a..2d9e67ce1d 100644 --- a/test/blocks/library-config/mocks/blocks/text/docx.html +++ b/test/blocks/library-config/mocks/blocks/text/docx.html @@ -1,5 +1,5 @@ -
text
+
text

Text

Kick things off with hundreds of premium and free presets you can access with your Lightroom subscription.

Learn more Explore the premium collection

-
\ No newline at end of file +
From 0cdd84a70797bfd40919e3d41cdb03cf61167d61 Mon Sep 17 00:00:00 2001 From: Sean Archibeque Date: Thu, 13 Jun 2024 10:08:54 -0600 Subject: [PATCH 4/4] MWPW-151885 - [LocUI] messaging for auth redirect (#2463) * foe locui block that displays the message to re-run * update message --- libs/blocks/locui/locui.css | 8 ++++++++ libs/blocks/locui/locui.js | 16 ++++++++++++++++ libs/utils/utils.js | 1 + 3 files changed, 25 insertions(+) create mode 100644 libs/blocks/locui/locui.css create mode 100644 libs/blocks/locui/locui.js diff --git a/libs/blocks/locui/locui.css b/libs/blocks/locui/locui.css new file mode 100644 index 0000000000..2c9de0b76a --- /dev/null +++ b/libs/blocks/locui/locui.css @@ -0,0 +1,8 @@ +.locui.container { + margin: 0 auto; + margin-top: 10vh; + max-width: 700px; + border-radius: 10px; + border: 10px solid #eee; + padding: 10px 30px 30px; +} diff --git a/libs/blocks/locui/locui.js b/libs/blocks/locui/locui.js new file mode 100644 index 0000000000..2c9acdac1b --- /dev/null +++ b/libs/blocks/locui/locui.js @@ -0,0 +1,16 @@ +import { createTag } from '../../utils/utils.js'; + +export default function init(el) { + el.classList.add('container'); + const heading = createTag('h2', null, 'Missing project details'); + const paragraph = createTag('p', null, 'The project details were removed after you logged in. To resolve this:'); + const steps = createTag('ol', null); + const stepList = ['Close this window or tab.', 'Open your project Excel file.', 'Click "Localize..." in Sidekick again.']; + stepList.forEach((step) => steps.append(createTag('li', null, step))); + const learnmore = createTag('a', { + class: 'con-button', + href: 'https://milo.adobe.com/docs/authoring/localization#:~:text=at%20render%20time.-,Troubleshooting,-Error%20matrix', + target: '_blank', + }, 'Learn More'); + el.append(heading, paragraph, steps, learnmore); +} diff --git a/libs/utils/utils.js b/libs/utils/utils.js index ed41f1ad0d..a70602485f 100644 --- a/libs/utils/utils.js +++ b/libs/utils/utils.js @@ -41,6 +41,7 @@ const MILO_BLOCKS = [ 'icon-block', 'iframe', 'instagram', + 'locui', 'marketo', 'marquee', 'marquee-anchors',