Skip to content

Commit

Permalink
feat: simplify block creation #350 (#351)
Browse files Browse the repository at this point in the history
- add `createBlock` function
- move metadata object creation to `getMetadata` function
  • Loading branch information
arumsey committed May 22, 2024
1 parent a37d2cd commit b766954
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 112 deletions.
80 changes: 1 addition & 79 deletions src/importer/defaults/rules/createMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,86 +12,8 @@

import Blocks from '../../../utils/Blocks.js';

function getMetadata(name, document) {
const attr = name && name.includes(':') ? 'property' : 'name';
const meta = [...document.head.querySelectorAll(`meta[${attr}="${name}"]`)]
.map((m) => m.content)
.join(', ');
return meta || '';
}

export default function createMetadata(main, document) {
const meta = {};

const title = document.querySelector('title');
if (title) {
meta.Title = title.textContent.replace(/[\n\t]/gm, '');
}

const desc = getMetadata('description', document);
if (desc) {
meta.Description = desc;
}

const img = getMetadata('og:image', document);
if (img) {
const el = document.createElement('img');
el.src = img;
meta.Image = el;

const imgAlt = getMetadata('og:image:alt', document);
if (imgAlt) {
el.alt = imgAlt;
}
}

const ogtitle = getMetadata('og:title', document);
if (ogtitle && ogtitle !== meta.Title) {
if (meta.Title) {
meta['og:title'] = ogtitle;
} else {
meta.Title = ogtitle;
}
}

const ogdesc = getMetadata('og:description', document);
if (ogdesc && ogdesc !== meta.Description) {
if (meta.Description) {
meta['og:description'] = ogdesc;
} else {
meta.Description = ogdesc;
}
}

const ttitle = getMetadata('twitter:title', document);
if (ttitle && ttitle !== meta.Title) {
if (meta.Title) {
meta['twitter:title'] = ttitle;
} else {
meta.Title = ttitle;
}
}

const tdesc = getMetadata('twitter:description', document);
if (tdesc && tdesc !== meta.Description) {
if (meta.Description) {
meta['twitter:description'] = tdesc;
} else {
meta.Description = tdesc;
}
}

const timg = getMetadata('twitter:image', document);
if (timg && timg !== img) {
const el = document.createElement('img');
el.src = timg;
meta['twitter:image'] = el;

const imgAlt = getMetadata('twitter:image:alt', document);
if (imgAlt) {
el.alt = imgAlt;
}
}
const meta = Blocks.getMetadata(document);

if (Object.keys(meta).length > 0) {
const block = Blocks.getMetadataBlock(document, meta);
Expand Down
130 changes: 100 additions & 30 deletions src/utils/Blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,117 @@
*/
import DOMUtils from './DOMUtils.js';

const DEFAULT_COLSPAN = 2;
function getDocumentMetadata(name, document) {
const attr = name && name.includes(':') ? 'property' : 'name';
const meta = [...document.head.querySelectorAll(`meta[${attr}="${name}"]`)]
.map((m) => m.content)
.join(', ');
return meta || '';
}

export default class Blocks {
static getMetadataBlock(document, metadata) {
const table = document.createElement('table');

let row = document.createElement('tr');
table.append(row);

const hCell = document.createElement('th');
row.append(hCell);

hCell.innerHTML = 'Metadata';
hCell.setAttribute('colspan', DEFAULT_COLSPAN);

// eslint-disable-next-line no-restricted-syntax, guard-for-in
for (const key in metadata) {
row = document.createElement('tr');
table.append(row);
const keyCell = document.createElement('td');
row.append(keyCell);
keyCell.textContent = key;
const valueCell = document.createElement('td');
row.append(valueCell);
const value = metadata[key];
if (value) {
static createBlock(document, { name, variants = [], cells: data }) {
const headerRow = variants.length ? [`${Blocks.computeBlockName(name)} (${variants.join(', ')})`] : [Blocks.computeBlockName(name)];
let blockRows = data;
if (!Array.isArray(data)) {
blockRows = Object.entries(data).map(([key, value]) => {
let colItems = [];
if (Array.isArray(value)) {
value.forEach((v) => {
colItems = value.map((v) => {
const p = document.createElement('p');
p.innerHTML = v;
valueCell.append(p);
return p;
});
} else if (typeof value === 'string') {
valueCell.textContent = value;
} else {
valueCell.append(value);
colItems = [value];
}
return [key, colItems];
});
}
return DOMUtils.createTable([headerRow, ...blockRows], document);
}

static getMetadataBlock(document, metadata) {
return Blocks.createBlock(document, {
name: 'Metadata',
cells: metadata,
});
}

static getMetadata(document) {
const meta = {};

const title = document.querySelector('title');
if (title) {
meta.Title = title.textContent.replace(/[\n\t]/gm, '');
}

const desc = getDocumentMetadata('description', document);
if (desc) {
meta.Description = desc;
}

const img = getDocumentMetadata('og:image', document);
if (img) {
const el = document.createElement('img');
el.src = img;
meta.Image = el;

const imgAlt = getDocumentMetadata('og:image:alt', document);
if (imgAlt) {
el.alt = imgAlt;
}
}

const ogtitle = getDocumentMetadata('og:title', document);
if (ogtitle && ogtitle !== meta.Title) {
if (meta.Title) {
meta['og:title'] = ogtitle;
} else {
meta.Title = ogtitle;
}
}

const ogdesc = getDocumentMetadata('og:description', document);
if (ogdesc && ogdesc !== meta.Description) {
if (meta.Description) {
meta['og:description'] = ogdesc;
} else {
meta.Description = ogdesc;
}
}

const ttitle = getDocumentMetadata('twitter:title', document);
if (ttitle && ttitle !== meta.Title) {
if (meta.Title) {
meta['twitter:title'] = ttitle;
} else {
meta.Title = ttitle;
}
}

const tdesc = getDocumentMetadata('twitter:description', document);
if (tdesc && tdesc !== meta.Description) {
if (meta.Description) {
meta['twitter:description'] = tdesc;
} else {
meta.Description = tdesc;
}
}

const timg = getDocumentMetadata('twitter:image', document);
if (timg && timg !== img) {
const el = document.createElement('img');
el.src = timg;
meta['twitter:image'] = el;

const imgAlt = getDocumentMetadata('twitter:image:alt', document);
if (imgAlt) {
el.alt = imgAlt;
}
}

return table;
return meta;
}

static computeBlockName(str) {
Expand Down
4 changes: 1 addition & 3 deletions src/utils/DOMUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,7 @@ export default class DOMUtils {
if (typeof cell === 'string') {
t.innerHTML = cell;
} else if (Array.isArray(cell)) {
cell.forEach((c) => {
t.append(c);
});
t.append(...cell);
} else {
t.append(cell);
}
Expand Down
31 changes: 31 additions & 0 deletions test/utils/Blocks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,34 @@ describe('Blocks#getMetadataBlock tests', () => {
test({ title: 'Some title', Tags: ['Creative', 'Experience Cloud', 'Photography'] }, '<table><tr><th colspan="2">Metadata</th></tr><tr><td>title</td><td>Some title</td></tr><tr><td>Tags</td><td><p>Creative</p><p>Experience Cloud</p><p>Photography</p></td></tr></table>');
});
});

describe('Blocks#createBlock tests', () => {
const test = (name, variants = [], cells = [], expected = '') => {
const { document } = (new JSDOM()).window;
const table = Blocks.createBlock(document, { name, variants, cells });
strictEqual(trim(table.outerHTML), trim(expected));
};

it('createBlock empty block', () => {
test('test block', [], [], '<table><tr><th>Test Block</th></tr></table>');
test('Test Block', [], [], '<table><tr><th>Test Block</th></tr></table>');
});

it('createBlock with variants', () => {
test('test block', ['variant-1'], [], '<table><tr><th>Test Block (variant-1)</th></tr></table>');
test('test block', ['variant-1', 'variant-2'], [], '<table><tr><th>Test Block (variant-1, variant-2)</th></tr></table>');
});

it('createBlock block config', () => {
test('Test Block', [], { title: 'Some title' }, '<table><tr><th colspan="2">Test Block</th></tr><tr><td>title</td><td>Some title</td></tr></table>');
test('Test Block', [], { Author: 'Name of the author', 'Creation Date': '2022/01/01' }, '<table><tr><th colspan="2">Test Block</th></tr><tr><td>Author</td><td>Name of the author</td></tr><tr><td>Creation Date</td><td>2022/01/01</td></tr></table>');
});

it('createBlock cell array', () => {
const cells = [
['Row 1 - Col 1', 'Row 1 - Col 2'],
['Row 2 - Col 1', 'Row 2 - Col 2'],
];
test('Test Block', [], cells, '<table><tr><th colspan="2">Test Block</th></tr><tr><td>Row 1 - Col 1</td><td>Row 1 - Col 2</td></tr><tr><td>Row 2 - Col 1</td><td>Row 2 - Col 2</td></tr></table>');
});
});

0 comments on commit b766954

Please sign in to comment.