@thunderid/browser 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3633,6 +3633,23 @@ const AVATAR_PALETTES = [
3633
3633
  * without needing the actual palette values.
3634
3634
  */
3635
3635
  const AVATAR_GRADIENT_COUNT = AVATAR_PALETTES.length;
3636
+ const XML_ESCAPES = {
3637
+ "\"": """,
3638
+ "&": "&",
3639
+ "'": "'",
3640
+ "<": "&lt;",
3641
+ ">": "&gt;"
3642
+ };
3643
+ /**
3644
+ * Escapes a caller-supplied value for interpolation into SVG text.
3645
+ */
3646
+ const escapeXml = (value) => value.replace(/["&'<>]/g, (ch) => XML_ESCAPES[ch]);
3647
+ /**
3648
+ * Encodes an SVG document as a data URI. Lone UTF-16 surrogates are replaced with U+FFFD
3649
+ * first, since `encodeURIComponent` throws a `URIError` on them. `Array.from` iterates by
3650
+ * code point, so a surrogate it yields on its own is unpaired.
3651
+ */
3652
+ const toSvgDataUri = (svg) => `data:image/svg+xml,${encodeURIComponent(Array.from(svg, (ch) => ch.length === 1 && ch >= "\ud800" && ch <= "\udfff" ? "�" : ch).join(""))}`;
3636
3653
  /**
3637
3654
  * Fills in `params.content` when the spec itself didn't carry one, deriving it from a raw
3638
3655
  * seed name (e.g. an app or user display name) — extracting initials for letter variants,
@@ -3683,11 +3700,10 @@ const generateGradientAvatar = ({ shape, variant, content, colors, bg }) => {
3683
3700
  let text = "";
3684
3701
  if (variant !== "blank") {
3685
3702
  const letterCount = variant === "one_letter" ? 1 : 2;
3686
- const initials = (content || "A").toUpperCase().slice(0, letterCount);
3703
+ const initials = escapeXml(Array.from((content || "A").toUpperCase()).slice(0, letterCount).join(""));
3687
3704
  text = `<text x="50" y="64" font-family="Helvetica,Arial,sans-serif" font-weight="700" font-size="${letterCount === 1 ? 46 : 34}" text-anchor="middle" fill="#fff">${initials}</text>`;
3688
3705
  }
3689
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${defs}${shapeMarkup(shape, background)}${text}</svg>`;
3690
- return `data:image/svg+xml,${encodeURIComponent(svg)}`;
3706
+ return toSvgDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${defs}${shapeMarkup(shape, background)}${text}</svg>`);
3691
3707
  };
3692
3708
  /**
3693
3709
  * Renders one of the curated anonymous-animal icons, applying the requested background
@@ -3699,8 +3715,7 @@ const generateAnonymousAnimalAvatar = ({ shape, content, bg }) => {
3699
3715
  const icon = ANONYMOUS_ANIMAL_ICONS[Object.prototype.hasOwnProperty.call(ANONYMOUS_ANIMAL_ICONS, content) ? content : pickAnonymousAvatarName_default()];
3700
3716
  const color = bg ?? icon.color;
3701
3717
  const markup = icon.markup.replaceAll("%COLOR%", color);
3702
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${shapeMarkup(shape, color)}${markup}</svg>`;
3703
- return `data:image/svg+xml,${encodeURIComponent(svg)}`;
3718
+ return toSvgDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${shapeMarkup(shape, color)}${markup}</svg>`);
3704
3719
  };
3705
3720
  /**
3706
3721
  * Renders one of the curated anonymous-entity icons (application/organization/resource-server
@@ -3712,8 +3727,7 @@ const generateAnonymousEntityAvatar = ({ shape, content, bg }) => {
3712
3727
  const icon = ANONYMOUS_ENTITY_ICONS[Object.prototype.hasOwnProperty.call(ANONYMOUS_ENTITY_ICONS, content) ? content : pickAnonymousEntityName_default()];
3713
3728
  const color = bg ?? icon.color;
3714
3729
  const markup = icon.markup.replaceAll("%COLOR%", color);
3715
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${shapeMarkup(shape, color)}${markup}</svg>`;
3716
- return `data:image/svg+xml,${encodeURIComponent(svg)}`;
3730
+ return toSvgDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${shapeMarkup(shape, color)}${markup}</svg>`);
3717
3731
  };
3718
3732
  /**
3719
3733
  * Generates an avatar image as an `svg+xml` data URI from a fully-resolved {@link AvatarParams}.