diff --git a/index.html b/index.html index c07670f..549341c 100644 --- a/index.html +++ b/index.html @@ -12,6 +12,7 @@ + Test

Hello, world

diff --git a/packages/banners/src/index.js b/packages/banners/src/index.js index 4d30d62..4099fb9 100644 --- a/packages/banners/src/index.js +++ b/packages/banners/src/index.js @@ -1,2 +1,97 @@ -// eslint-disable-next-line no-console -console.log('Hello world from the package!'); +/** + * @typedef {import('./index.js').BannerObject} BannerObject + */ +import getLocalLayout from './layouts.js'; + +/** + * @param {Readonly} string - The string to be converted. + * @param {Document} document - The document API to be used. + * @returns {HTMLElement} - The DOM of the string. + */ +function stringToHtml(string, document) { + const tmp = document.createElement('template'); + tmp.innerHTML = string; + /** @type {HTMLElement} */ + const dom = tmp.children[0]; + return dom; +} + +/** + * @param {HTMLElement} element - The element to be converted to string. + * @param {Document} document - The document API to be used. + * @returns {string} - The resulting string. + */ +function htmlToString(element, document) { + const tmp = document.createElement('template'); + tmp.appendChild(element); + return tmp.innerHTML; +} +/** + * @typedef {{ + * modify(query: string, callback: (el: Element | null) => T) => T + * }} DOMHelper + * @param {HTMLElement} element - The element to be manipulated. + * @returns {DOMHelper} + */ +function domHelper(element) { + return { + /** + * @template T + * @param {string} query - The query selector to find the element. + * @param {(el: Element | null) => T} callback - Callback to modify the element. + * @returns {T} - The return value of the callback. + * @throws {Error} - Throws if the element is not found. + */ + modify(query, callback) { + const el = element.querySelector(query); + + return callback(el); + }, + }; +} + +/** + * @param {BannerObject} object - The Banner Object to be generated from. + * @returns {Promise} - The SVG of the banner. + */ +async function banner(object) { + /** @type {Document} */ + // @ts-expect-error because Document is not compatible with Readonly + const doc = object.lib?.document ?? globalThis.document; + /** @type {Readonly} */ + const svg = await getLocalLayout('vertical'); + + const dom = stringToHtml(svg, doc); + const helper = domHelper(dom); + + helper.modify('[data-banner-class="title"] > tspan', (el) => { + if (!el) return; + + el.innerHTML = object.title; + }); + helper.modify('[data-banner-class="subtitle"] > tspan', (el) => { + if (!el) return; + el.innerHTML = object.subtitle ?? ''; + }); + return htmlToString(dom, doc); +} +/** + * Test function. + */ +async function test() { + const testBanner = await banner({ + lib: { + // @ts-expect-error because Document is not DeepReadonly + document: new Document(), + fetch, + }, + title: 'Hello, world', + }); + + const body = globalThis.document.getElementsByTagName('body')[0]; + body.innerHTML = testBanner; +} +await test(); + +export default banner; + diff --git a/packages/banners/src/layouts.js b/packages/banners/src/layouts.js new file mode 100644 index 0000000..ed9f92e --- /dev/null +++ b/packages/banners/src/layouts.js @@ -0,0 +1,27 @@ + +/** + * Imports a local layout from the static folder. + * + * @param {import('./types.d.ts').BuiltinLayouts} layout - The banner layout. + * @param {boolean} [rtl] - Is the layout right-to-left? + * @returns {Promise} - The SVG string of the layout file. + */ +async function getLocalLayout(layout, rtl = false) { + let layoutFile; + /* eslint-disable import/no-relative-parent-imports */ + switch (layout) { + case 'vertical': { + layoutFile = await import('../static/vertical.svg.js'); + break; + } + default: { + if (rtl) + layoutFile = await import('../static/horizontal-rtl.svg.js'); + layoutFile = await import('../static/horizontal.svg.js'); + } + } + /* eslint-enable */ + + return layoutFile.default; +} +export default getLocalLayout; diff --git a/packages/banners/test.html b/packages/banners/test.html new file mode 100644 index 0000000..014bc7c --- /dev/null +++ b/packages/banners/test.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + +