3 function escapeXml(s
) {
4 if (typeof s
=== 'number') {
6 } else if (typeof s
!== 'string') {
10 .replace(/&/g
, '&')
11 .replace(/</g
, '<')
12 .replace(/>/g
, '>')
13 .replace(/"/g, '"')
14 .replace(/'/g, ''');
25 fontFamily: 'DejaVu Sans,Verdana,Geneva,sans-serif',
29 function fixedRound(n, p = 2) {
30 return Number(n.toFixed(p));
35 * image/svg+xml;charset=utf-8 formatted badge with subscriber count for a topic
36 * @param {Object} ctx - badge-specific context (not request context)
37 * @param {String} label
38 * @param {String} message
39 * @param {String} accessibleText
42 module.exports = (ctx, label, message, accessibleText) => {
44 ctx = Object.assign({}, ctxDefaults, ctx, {
49 ctx.verticalMargin = fixedRound(ctx.height * 0.69);
50 ctx.labelWidth = fixedRound(ctx.label.length * ctx.charWidth);
51 ctx.messageWidth = fixedRound(ctx.message.length * ctx.charWidth);
52 ctx.width = ctx.labelWidth + ctx.messageWidth;
53 ctx.halfCharWidth = fixedRound(ctx.charWidth * 0.5);
56 * This SVG content mostly replicates the output of the 'Plastic' badge
57 * renderer from https://github.com/badges/shields/tree/master/badge-maker which
58 * is under the http://creativecommons.org/publicdomain/zero/1.0/ license.
60 return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${ctx.width}" height="${ctx.height}" role="img" aria-label="${escapeXml(ctx.accessibleText)}">
61 <title
>${escapeXml(ctx.accessibleText)}
</title
>
62 <linearGradient id
="s" x2
="0" y2
="100%">
63 <stop offset
="0" stop
-color
="#fff" stop
-opacity
=".7"/>
64 <stop offset
=".1" stop
-color
="#aaa" stop
-opacity
=".1"/>
65 <stop offset
=".9" stop
-color
="#000" stop
-opacity
=".3"/>
66 <stop offset
="1" stop
-color
="#000" stop
-opacity
=".5"/>
69 <rect width
="${ctx.width}" height
="${ctx.height}" rx
="4" fill
="#fff"/>
71 <g clip
-path
="url(#r)">
72 <rect width
="${ctx.labelWidth}" height
="${ctx.height}" fill
="${ctx.labelColor}"/>
73 <rect x
="${ctx.labelWidth}" width
="${ctx.messageWidth}" height
="${ctx.height}" fill
="${ctx.messageColor}"/>
74 <rect width
="${ctx.width}" height
="${ctx.height}" fill
="url(#s)"/>
76 <g fill
="${ctx.color}" text
-anchor
="left" font
-family
="${ctx.fontFamily}" text
-rendering
="geometricPrecision" font
-size
="11" font
-weight
="bold">
77 <text x
="${ctx.halfCharWidth}" y
="${ctx.verticalMargin}">${escapeXml(ctx.label)}
</text
>
78 <text x
="${fixedRound(ctx.halfCharWidth + ctx.labelWidth)}" y
="${ctx.verticalMargin}">${escapeXml(ctx.message)}
</text
>