Skip to content

Commit

Permalink
fix(sm-import): improve header parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
catalan-adobe committed Aug 20, 2024
1 parent ea47c18 commit 207bed5
Showing 1 changed file with 177 additions and 42 deletions.
219 changes: 177 additions & 42 deletions js/sections-mapping/import/parsers/header.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
/* global WebImporter */

const brandLogoMapping = [
{
checkFn: (e) => e.querySelector('a > picture, a > img'),
parseFn: (e, targetEl, bodyWidth, x) => {
if (bodyWidth && x < bodyWidth / 2) {
targetEl.append(e);
const linkedPictureEl = document.createElement('div');
const linkEl = e.parentElement;
linkEl.parentElement.append(linkedPictureEl);
linkedPictureEl.append(document.createElement('br'));
linkedPictureEl.append(linkEl);
linkedPictureEl.prepend(...linkEl.children);
console.log('brand logo is an anchor containing an image >>', linkEl.textContent.replaceAll(/[\n\t]/gm, '').trim(), '<<');
if (linkEl.textContent.replaceAll(/[\n\t]/gm, '').trim().length === 0) {
linkEl.textContent = linkEl.href;
}

if (linkedPictureEl.closest('li')) {
const liEl = linkedPictureEl.closest('li');
targetEl.append(...liEl.children);
liEl.remove();
} else {
targetEl.append(linkedPictureEl);
}
console.log('brand logo is an anchor containing an image', e);
return true;
}
return false;
Expand All @@ -15,7 +35,13 @@ const brandLogoMapping = [
if (bodyWidth && x < bodyWidth / 2) {
const imgEl = e.closest('picture, img');
if (imgEl) {
targetEl.append(imgEl);
if (imgEl.closest('li')) {
const liEl = imgEl.closest('li');
targetEl.append(...liEl.children);
liEl.remove();
} else {
targetEl.append(imgEl);
}
}
return true;
}
Expand All @@ -26,7 +52,13 @@ const brandLogoMapping = [
checkFn: (e) => e.querySelector('img'),
parseFn: (e, targetEl, bodyWidth, x) => {
if (bodyWidth && x < bodyWidth / 2) {
targetEl.append(e);
if (e.closest('li')) {
const liEl = e.closest('li');
targetEl.append(...liEl.children);
liEl.remove();
} else {
targetEl.append(e);
}
return true;
}
return false;
Expand Down Expand Up @@ -80,66 +112,169 @@ function getBrandLogo(rootEl, document, { bodyWidth, originURL }) {
return brandEl;
}

export default function headerParser(el, { document, params, allMappings }) {
const containerEl = document.createElement('div');
const navMapping = [
{
checkFn: (e) => [...e.querySelectorAll('nav ul, nav ol')]
.filter((i) => !i.parentElement.closest('ul, ol') && !i.hasAttribute('data-hlx-imp-hidden-div'))
.reduce((acc, navListEl) => {
let x = null;
try {
x = JSON.parse(navListEl.closest('div')?.getAttribute('data-hlx-imp-rect')).x;
} catch (err) {
console.error('error', err);
}

const bodyWidth = allMappings.sections[0]?.blocks[0]?.width;
const originURL = new URL(params.originalURL).origin;
if (!acc || x < acc.x) {
return {
el: navListEl,
x,
};
}

// get brand logo
const brandEl = getBrandLogo(el, document, { bodyWidth, originURL });
return acc;
}, null),
parseFn: (e, targetEl) => {
targetEl.append(e?.el);
return true;
},
},
{
checkFn: (e) => [...e.querySelectorAll('nav')]
.filter((i) => !i.parentElement.closest('nav') && !i.hasAttribute('data-hlx-imp-hidden-div'))
.reduce((acc, navListEl) => {
let x = null;
try {
x = JSON.parse(navListEl.closest('div')?.getAttribute('data-hlx-imp-rect')).x;
} catch (err) {
console.error('error', err);
}

// get navigation content
if (!acc || x < acc.x) {
return {
el: navListEl,
x,
};
}

return acc;
}, null),
parseFn: (e, targetEl) => {
targetEl.append(e?.el);
return true;
},
},
{
checkFn: (e, { bodyWidth }) => [...e.querySelectorAll('ol,ul')].filter((f) => f.parentElement.closest('ol,ul') === null).reduce(
(acc, listEl) => {
console.log('listEl', listEl);
const items = [...listEl.querySelectorAll(':scope > li')].filter((liEl) => {
liEl.querySelectorAll('script', 'style').forEach((d) => d.remove());
return liEl.textContent.replaceAll('\n', '').trim().length > 0;
});

let x = null;
try {
x = JSON.parse(listEl.closest('div')?.getAttribute('data-hlx-imp-rect')).x;
} catch (err) {
console.error('error', err);
}

console.log('items', items.length, acc?.children.length, x, bodyWidth, listEl);

if (
items.length > 1
&& (!acc || items.length > acc.children.length)
&& (!bodyWidth || (typeof x === 'number' && x < bodyWidth / 2))
) {
console.log('found', listEl);
return listEl;
}
return acc;
},
null,
),
parseFn: (e, targetEl) => {
// cleanup
const elsToDelete = e.querySelectorAll(':scope > :not(li)');
elsToDelete.forEach((d) => d.remove());

targetEl.append(e);
return true;
},
},
];

function getNavigation(rootEl, document, { bodyWidth }) {
const navEl = document.createElement('div');
const menuEl = [...el.querySelectorAll('ol,ul')].filter((f) => f.parentElement.closest('ol,ul') === null).reduce(
(acc, listEl) => {
const items = [...listEl.querySelectorAll('li')].filter((liEl) => {
liEl.querySelectorAll('script', 'style', '[data-hlx-imp-hidden-div]').forEach((e) => e.remove());
return liEl.textContent.replaceAll('\n', '').trim().length > 0;
});

let x = null;
navMapping.some((m) => {
const el = m.checkFn(rootEl, { bodyWidth });
if (el) {
console.log('nav', el);
let x = 0;
try {
x = JSON.parse(listEl.closest('div')?.getAttribute('data-hlx-imp-rect')).x;
x = JSON.parse(el.closest('div')?.getAttribute('data-hlx-imp-rect')).x;
} catch (e) {
console.error('error', e);
}

console.log('items', items.length, acc?.children.length, x, bodyWidth, listEl);
return m.parseFn(el, navEl, bodyWidth, x);
}
return false;
});

return navEl;
}

if (
items.length > 1
&& (!acc || items.length > acc.children.length)
&& (!bodyWidth || (x && x < bodyWidth / 2))
) {
return listEl;
}
return acc;
},
null,
);
if (menuEl) {
navEl.append(menuEl);
}
function cleanup(el) {
el.querySelectorAll('script', 'style').forEach((e) => e.remove());

el.querySelectorAll('a').forEach((a) => {
if (a.textContent.replaceAll('\n', '').trim().toLowerCase() === 'skip to content') {
a.remove();
}
});
return el;
}

export default function headerParser(el, { document, params, allMappings }) {
const containerEl = document.createElement('div');

const bodyWidth = allMappings.sections[0]?.blocks[0]?.width;
const originURL = new URL(params.originalURL).origin;

// get brand logo
const brandEl = getBrandLogo(el, document, { bodyWidth, originURL });

const listEl = el.querySelector('ol,ul');
if (listEl) {
navEl.append(listEl);
// get navigation content
const navEl = getNavigation(el, document, { bodyWidth });

// get remaining hidden elements
const hiddenEls = document.createElement('div');
while (el.querySelector('[data-hlx-imp-hidden-div]')) {
hiddenEls.append(el.querySelector('[data-hlx-imp-hidden-div]'));
}

// get remaining content as tools
const toolsEl = document.createElement('div');
toolsEl.append(...el.children);

let hiddenEl;
while (hiddenEl = toolsEl.querySelector('[data-hlx-imp-hidden-div]')) {
hiddenEl.remove();
}

containerEl.append(brandEl);
containerEl.append(document.createElement('hr'));
containerEl.append(navEl);
containerEl.append(document.createElement('hr'));
containerEl.append(toolsEl);

// put hidden elements in a "hidden" section
if (hiddenEls.children.length > 0 && hiddenEls.textContent.replaceAll('\n', '').trim().length > 0) {
containerEl.append(document.createElement('hr'));
containerEl.append(hiddenEls);
containerEl.append(WebImporter.DOMUtils.createTable([
['section-metadata'],
['style', 'hidden'],
], document));
}

cleanup(containerEl);

return containerEl;
}

0 comments on commit 207bed5

Please sign in to comment.