UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

221 lines (203 loc) 7.53 kB
'use strict'; var TinyHtml = require('../TinyHtml.cjs'); var TinyHtmlTemplate = require('./TinyHtmlTemplate.cjs'); /** * TinyHtmlAnchor is a helper class for managing <a> elements. * It provides strongly-typed getters and setters for attributes like href, * target, rel, hreflang, referrerpolicy, and more. * * @example * const link = new TinyHtmlAnchor({ * href: 'https://example.com', * label: 'Visit Example', * target: '_blank', * rel: 'noopener noreferrer' * }); * * @extends TinyHtmlTemplate<HTMLAnchorElement> */ class TinyHtmlAnchor extends TinyHtmlTemplate { /** * Creates a new TinyHtmlAnchor instance. * @param {Object} config - Configuration object. * @param {string} config.href - Link URL (required). * @param {string|Element|TinyHtml<any>} [config.label] - Link text or HTML. * @param {string} [config.target] - Target attribute. * @param {string} [config.rel] - Relationship of the linked resource. * @param {string} [config.hreflang] - Language of the linked resource. * @param {string|string[]} [config.ping] - URLs to send pings to. * @param {'no-referrer'|'no-referrer-when-downgrade'|'origin'|'origin-when-cross-origin'|'same-origin'|'strict-origin'|'strict-origin-when-cross-origin'|'unsafe-url'} [config.referrerpolicy] - Referrer policy. * @param {string} [config.type] - MIME type of the linked resource. * @param {boolean|string|string[]} [config.attributionsrc] - Enables Attribution Reporting. * @param {string|boolean} [config.download] - Download filename (or boolean to enable). * @param {boolean} [config.allowHtml=false] - Whether to allow HTML inside the link. * @param {string|string[]|Set<string>} [config.tags=[]] - Initial CSS classes. * @param {string} [config.mainClass=''] - Main CSS class. * @throws {TypeError} If any attribute is invalid. */ constructor({ href, label, target, rel, hreflang, ping, referrerpolicy, type, attributionsrc, download, allowHtml = false, tags = [], mainClass = '', }) { super(document.createElement('a'), tags, mainClass); if (typeof href !== 'string' || !href.trim()) throw new TypeError('TinyHtmlAnchor: "href" must be a non-empty string.'); this.href = href; if (target !== undefined) this.target = target; if (rel !== undefined) this.rel = rel; if (hreflang !== undefined) this.hreflang = hreflang; if (ping !== undefined) this.ping = ping; if (referrerpolicy !== undefined) this.referrerpolicy = referrerpolicy; if (type !== undefined) this.type = type; if (attributionsrc !== undefined) this.attributionsrc = attributionsrc; if (download !== undefined) this.download = download; if (typeof allowHtml !== 'boolean') throw new TypeError('TinyHtmlAnchor: "allowHtml" must be a boolean.'); if (label !== undefined) this.setLabel(label, allowHtml); } /** @param {string} href */ set href(href) { if (typeof href !== 'string' || !href.trim()) throw new TypeError('TinyHtmlAnchor: "href" must be a non-empty string.'); this.setAttr('href', href); } /** @returns {string|null} */ get href() { return this.attrString('href'); } /** @param {string} target */ set target(target) { if (typeof target !== 'string') throw new TypeError('TinyHtmlAnchor: "target" must be a string.'); this.setAttr('target', target); } /** @returns {string|null} */ get target() { return this.attrString('target'); } /** @param {string} rel */ set rel(rel) { if (typeof rel !== 'string') throw new TypeError('TinyHtmlAnchor: "rel" must be a string.'); this.setAttr('rel', rel); } /** @returns {string|null} */ get rel() { return this.attrString('rel'); } /** @param {string} hreflang */ set hreflang(hreflang) { if (typeof hreflang !== 'string') throw new TypeError('TinyHtmlAnchor: "hreflang" must be a string.'); this.setAttr('hreflang', hreflang); } /** @returns {string|null} */ get hreflang() { return this.attrString('hreflang'); } /** @param {string|string[]} ping */ set ping(ping) { if (Array.isArray(ping)) ping = ping.join(' '); if (typeof ping !== 'string') throw new TypeError('TinyHtmlAnchor: "ping" must be a string or string[].'); this.setAttr('ping', ping); } /** @returns {string|null} */ get ping() { return this.attrString('ping'); } /** @param {'no-referrer'|'no-referrer-when-downgrade'|'origin'|'origin-when-cross-origin'|'same-origin'|'strict-origin'|'strict-origin-when-cross-origin'|'unsafe-url'} referrerpolicy */ set referrerpolicy(referrerpolicy) { const valid = [ 'no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'same-origin', 'strict-origin', 'strict-origin-when-cross-origin', 'unsafe-url', ]; if (!valid.includes(referrerpolicy)) throw new TypeError(`TinyHtmlAnchor: "referrerpolicy" must be one of: ${valid.join(', ')}`); this.setAttr('referrerpolicy', referrerpolicy); } /** @returns {string|null} */ get referrerpolicy() { return this.attrString('referrerpolicy'); } /** @param {string} type */ set type(type) { if (typeof type !== 'string') throw new TypeError('TinyHtmlAnchor: "type" must be a string (MIME type).'); this.setAttr('type', type); } /** @returns {string|null} */ get type() { return this.attrString('type'); } /** @param {boolean|string|string[]} attributionsrc */ set attributionsrc(attributionsrc) { if (attributionsrc === true) { this.addProp('attributionsrc'); } else if (typeof attributionsrc === 'string') { this.setAttr('attributionsrc', attributionsrc); } else if (Array.isArray(attributionsrc)) { this.setAttr('attributionsrc', attributionsrc.join(' ')); } else { throw new TypeError( 'TinyHtmlAnchor: "attributionsrc" must be a boolean, string, or string[].', ); } } /** @returns {string|null} */ get attributionsrc() { return this.attrString('attributionsrc'); } /** @param {string|boolean} download */ set download(download) { if (typeof download !== 'string' && typeof download !== 'boolean') throw new TypeError('TinyHtmlAnchor: "download" must be a string or boolean.'); if (typeof download === 'string') this.setAttr('download', download); else if (download) this.addProp('download'); else this.removeProp('download'); } /** @returns {string|boolean|null} */ get download() { if (this.hasProp('download')) { return true; } return this.attrString('download'); } /** * Updates the link label with text, HTML, or an element. * * @param {string|Element|TinyHtml<any>} label - The new label to set. * @param {boolean} [allowHtml=false] - Whether to allow raw HTML or DOM elements instead of plain text. * @returns {this} */ setLabel(label, allowHtml = false) { if (typeof label === 'string') { if (!allowHtml) this.setText(label); else this.setHtml(label); } else if (label instanceof Element || label instanceof TinyHtml) { if (!allowHtml) throw new Error('setLabel: Passing an Element/TinyHtml requires allowHtml=true.'); this.empty().append(label); } else { throw new TypeError("setLabel: 'label' must be a string, Element, or TinyHtml instance."); } return this; } } module.exports = TinyHtmlAnchor;