Skip to content

Commit 3d24ecb

Browse files
committed
Use different SVG mask ids for each generated badge
Within a single Python session anybadge will use different SVG mask IDs. This is an attempt to fix the issue where SVG files displayed in the same HTML will re-use the same mask, and therefore appear with the same dimensions. Uses a singleton on the class to maintain a sequence of mask ids. Includes unittests to ensure new ID is used for each badge.
1 parent a4b20c6 commit 3d24ecb

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

anybadge.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
NUM_PADDING_CHARS = 0.5
2424
DEFAULT_COLOR = '#4c1'
2525
DEFAULT_TEXT_COLOR = '#fff'
26+
MASK_ID_PREFIX = 'anybadge_'
2627

2728
# Dictionary for looking up approx pixel widths of
2829
# supported fonts and font sizes.
@@ -51,10 +52,10 @@
5152
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
5253
<stop offset="1" stop-opacity=".1"/>
5354
</linearGradient>
54-
<mask id="a">
55+
<mask id="{{ mask id }}">
5556
<rect width="{{ badge width }}" height="20" rx="3" fill="#fff"/>
5657
</mask>
57-
<g mask="url(#a)">
58+
<g mask="url(#{{ mask id }})">
5859
<path fill="#555" d="M0 0h{{ color split x }}v20H0z"/>
5960
<path fill="{{ color }}" d="M{{ color split x }} 0h{{ value width }}v20H{{ color split x }}z"/>
6061
<path fill="url(#b)" d="M0 0h{{ badge width }}v20H0z"/>
@@ -207,6 +208,7 @@ def __init__(self, label, value, font_name=None, font_size=None,
207208
self.value_text_color = text_colors[1]
208209

209210
self.use_max_when_value_exceeds = use_max_when_value_exceeds
211+
self.mask_id = self.__class__._get_next_mask_id()
210212

211213
def __repr__(self):
212214
"""Return a representation of the Badge object instance.
@@ -259,6 +261,19 @@ def __repr__(self):
259261
optional_args
260262
)
261263

264+
@classmethod
265+
def _get_next_mask_id(cls):
266+
"""Return a new mask ID from a singleton sequence maintained on the class.
267+
268+
Returns: str
269+
"""
270+
if not hasattr(cls, 'mask_id'):
271+
cls.mask_id = 0
272+
273+
cls.mask_id += 1
274+
275+
return MASK_ID_PREFIX + str(cls.mask_id)
276+
262277
@property
263278
def value_is_float(self):
264279
"""Identify whether the value text is a float.
@@ -412,7 +427,8 @@ def badge_svg_text(self):
412427
.replace('{{ label text color }}', self.label_text_color) \
413428
.replace('{{ value text color }}', self.value_text_color) \
414429
.replace('{{ color split x }}', str(self.color_split_position)) \
415-
.replace('{{ value width }}', str(self.badge_width - self.color_split_position))
430+
.replace('{{ value width }}', str(self.badge_width - self.color_split_position))\
431+
.replace('{{ mask id }}', self.mask_id)
416432

417433
def __str__(self):
418434
"""Return string representation of badge.

tests/test_anybadge.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,20 @@ def test_badge_with_text_color(self):
103103
text_color='#010101,#101010')
104104

105105
badge.write_badge('test_badge_9.svg', overwrite=True)
106+
107+
def test_multiple_badges_in_one_session(self):
108+
109+
badges = [
110+
Badge('something', value='100', value_suffix='%', num_padding_chars=0),
111+
Badge('coverage', value='1234567890'),
112+
]
113+
114+
self.assertNotEqual(badges[0].badge_width, badges[1].badge_width)
115+
116+
def test_multiple_badges_get_different_mask_id(self):
117+
badges = [
118+
Badge('something', value='100', value_suffix='%', num_padding_chars=0),
119+
Badge('coverage', value='1234567890'),
120+
]
121+
122+
self.assertNotEqual(badges[0].mask_id, badges[1].mask_id)

0 commit comments

Comments
 (0)