From 7d0d04f177999d9eea69d018659eec681245840a Mon Sep 17 00:00:00 2001 From: valkyrie_pilot Date: Thu, 3 Oct 2024 19:32:40 -0600 Subject: [PATCH] Add option for IDs to have a prefix --- badge-maker/lib/badge-renderers.js | 27 +++++++++++++++------------ badge-maker/lib/index.js | 7 +++++++ badge-maker/lib/make-badge.js | 3 +++ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/badge-maker/lib/badge-renderers.js b/badge-maker/lib/badge-renderers.js index af726101e0819..681acdea9ed4a 100644 --- a/badge-maker/lib/badge-renderers.js +++ b/badge-maker/lib/badge-renderers.js @@ -128,6 +128,7 @@ class Badge { logoPadding, color = '#4c1', labelColor, + idPrefix = '', }) { const horizPadding = 5 const hasLogo = !!logo @@ -178,6 +179,7 @@ class Badge { this.label = label this.message = message this.accessibleText = accessibleText + this.idPrefix = idPrefix this.logoElement = getLogoElement({ logo, @@ -286,7 +288,7 @@ class Badge { }, }), ], - attrs: { id: 'r' }, + attrs: { id: `${this.idPrefix}r` }, }) } @@ -313,7 +315,7 @@ class Badge { attrs: { width: this.width, height: this.constructor.height, - fill: 'url(#s)', + fill: `url(#${this.idPrefix}s)`, }, }) const content = withGradient @@ -379,14 +381,14 @@ class Plastic extends Badge { attrs: { offset: 1, 'stop-color': '#000', 'stop-opacity': '.5' }, }), ], - attrs: { id: 's', x2: 0, y2: '100%' }, + attrs: { id: `${this.idPrefix}s`, x2: 0, y2: '100%' }, }) const clipPath = this.getClipPathElement(4) const backgroundGroup = this.getBackgroundGroupElement({ withGradient: true, - attrs: { 'clip-path': 'url(#r)' }, + attrs: { 'clip-path': `url(#${this.idPrefix}r)` }, }) return renderBadge( @@ -428,14 +430,14 @@ class Flat extends Badge { attrs: { offset: 1, 'stop-opacity': '.1' }, }), ], - attrs: { id: 's', x2: 0, y2: '100%' }, + attrs: { id: `${this.idPrefix}s`, x2: 0, y2: '100%' }, }) const clipPath = this.getClipPathElement(3) const backgroundGroup = this.getBackgroundGroupElement({ withGradient: true, - attrs: { 'clip-path': 'url(#r)' }, + attrs: { 'clip-path': `url(#${this.idPrefix}r)` }, }) return renderBadge( @@ -492,6 +494,7 @@ function social({ logoPadding, color = '#4c1', labelColor = '#555', + idPrefix = '', }) { // Social label is styled with a leading capital. Convert to caps here so // width can be measured using the correct characters. @@ -565,9 +568,9 @@ function social({ const rect = new XmlElement({ name: 'rect', attrs: { - id: 'llink', + id: `${idPrefix}llink`, stroke: '#d5d5d5', - fill: 'url(#a)', + fill: `url(#${idPrefix}a)`, x: '.5', y: '.5', width: labelRectWidth, @@ -640,7 +643,7 @@ function social({ name: 'text', content: [message], attrs: { - id: 'rlink', + id: `${idPrefix}rlink`, x: messageTextX, y: 140, transform: FONT_SCALE_DOWN_VALUE, @@ -660,7 +663,7 @@ function social({ const style = new XmlElement({ name: 'style', content: [ - 'a:hover #llink{fill:url(#b);stroke:#ccc}a:hover #rlink{fill:#4183c4}', + `a:hover #${idPrefix}llink{fill:url(#${idPrefix}b);stroke:#ccc}a:hover #${idPrefix}rlink{fill:#4183c4}`, ], }) const gradients = new ElementList({ @@ -681,7 +684,7 @@ function social({ attrs: { offset: 1, 'stop-opacity': '.1' }, }), ], - attrs: { id: 'a', x2: 0, y2: '100%' }, + attrs: { id: `${idPrefix}a`, x2: 0, y2: '100%' }, }), new XmlElement({ name: 'linearGradient', @@ -695,7 +698,7 @@ function social({ attrs: { offset: 1, 'stop-opacity': '.1' }, }), ], - attrs: { id: 'b', x2: 0, y2: '100%' }, + attrs: { id: `${idPrefix}b`, x2: 0, y2: '100%' }, }), ], }) diff --git a/badge-maker/lib/index.js b/badge-maker/lib/index.js index fa9caec94bf75..a0e8926f9a74b 100644 --- a/badge-maker/lib/index.js +++ b/badge-maker/lib/index.js @@ -52,6 +52,11 @@ function _validate(format) { `Field \`style\` must be one of (${styleValues.toString()})`, ) } + if ('idPrefix' in format && /^[a-zA-Z0-9\-_]+$/.test(format.idPrefix)) { + throw new ValidationError( + 'field `idPrefix` must contain only numbers, letters, -, and _', + ) + } } function _clean(format) { @@ -63,6 +68,7 @@ function _clean(format) { 'style', 'logoBase64', 'links', + 'idPrefix', ] const cleaned = {} @@ -95,6 +101,7 @@ function _clean(format) { * @param {string} format.style (Optional) Visual style (e.g: 'flat') * @param {string} format.logoBase64 (Optional) Logo data URL * @param {Array} format.links (Optional) Links array (e.g: ['https://example.com', 'https://example.com']) + * @param {string} format.idPrefix (Optional) Prefix for IDs, e.g. 1, 2, and 3 for three invocations that will be used on the same page. * @returns {string} Badge in SVG format * @see https://github.com/badges/shields/tree/master/badge-maker/README.md */ diff --git a/badge-maker/lib/make-badge.js b/badge-maker/lib/make-badge.js index 0556427f8f21f..c84c58cc36327 100644 --- a/badge-maker/lib/make-badge.js +++ b/badge-maker/lib/make-badge.js @@ -20,6 +20,7 @@ module.exports = function makeBadge({ logoSize, logoWidth, links = ['', ''], + idPrefix, }) { // String coercion and whitespace removal. label = `${label}`.trim() @@ -38,6 +39,7 @@ module.exports = function makeBadge({ link: links, name: label, value: message, + idPrefix, }) } @@ -59,6 +61,7 @@ module.exports = function makeBadge({ logoPadding: logo && label.length ? 3 : 0, color: toSvgColor(color), labelColor: toSvgColor(labelColor), + idPrefix, }), ) }