@templatical/types
Advanced tools
+5
-3
@@ -1080,5 +1080,7 @@ //#region src/blocks.d.ts | ||
| * Handles double-quoted, single-quoted and unquoted values, and matches the | ||
| * attribute name case-insensitively, as HTML does. Attribute values are not | ||
| * entity-decoded — callers compare them against configured merge-tag tokens, | ||
| * which are stored the same way. | ||
| * attribute name case-insensitively, as HTML does. The value is | ||
| * entity-decoded, because that is what the attribute means: the editor | ||
| * serializes a tag value of `<% $email %>` as | ||
| * `data-merge-tag="<% $email %>"`, and every caller compares the result | ||
| * against a configured merge-tag token written in raw characters. | ||
| */ | ||
@@ -1085,0 +1087,0 @@ declare function getTagAttrValue(attrs: string, name: string): string | null; |
+37
-5
@@ -554,3 +554,33 @@ //#region src/blocks.ts | ||
| } | ||
| const NAMED_ENTITIES = { | ||
| amp: "&", | ||
| lt: "<", | ||
| gt: ">", | ||
| quot: "\"", | ||
| apos: "'", | ||
| nbsp: "\xA0" | ||
| }; | ||
| /** | ||
| * Decode the character references an HTML serializer writes into an attribute | ||
| * value, so callers get the characters the author wrote. | ||
| * | ||
| * Deliberately small: the named set a serializer actually emits, plus numeric | ||
| * references. An unknown or malformed reference is left as literal text, which | ||
| * is what a browser does. Single-pass — `&lt;` decodes to the text `<` | ||
| * and stops, never to `<`, so an escaped entity inside a consumer's tag value | ||
| * survives as itself. | ||
| */ | ||
| function decodeAttrEntities(value) { | ||
| if (!value.includes("&")) return value; | ||
| return value.replace(/&(#[0-9]+|#[xX][0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (match, ref) => { | ||
| if (ref[0] === "#") { | ||
| const code = ref[1] === "x" || ref[1] === "X" ? Number.parseInt(ref.slice(2), 16) : Number.parseInt(ref.slice(1), 10); | ||
| if (!Number.isFinite(code) || code < 1 || code > 1114111) return match; | ||
| if (code >= 55296 && code <= 57343) return match; | ||
| return String.fromCodePoint(code); | ||
| } | ||
| return NAMED_ENTITIES[ref.toLowerCase()] ?? match; | ||
| }); | ||
| } | ||
| /** | ||
| * The value of the `name` attribute within an open tag's attribute string (the | ||
@@ -561,5 +591,7 @@ * text between the tag name and its closing `>`), or `null` when the attribute | ||
| * Handles double-quoted, single-quoted and unquoted values, and matches the | ||
| * attribute name case-insensitively, as HTML does. Attribute values are not | ||
| * entity-decoded — callers compare them against configured merge-tag tokens, | ||
| * which are stored the same way. | ||
| * attribute name case-insensitively, as HTML does. The value is | ||
| * entity-decoded, because that is what the attribute means: the editor | ||
| * serializes a tag value of `<% $email %>` as | ||
| * `data-merge-tag="<% $email %>"`, and every caller compares the result | ||
| * against a configured merge-tag token written in raw characters. | ||
| */ | ||
@@ -588,3 +620,3 @@ function getTagAttrValue(attrs, name) { | ||
| if (valueEnd === -1) return null; | ||
| if (attrName === target) return attrs.substring(valueStart, valueEnd); | ||
| if (attrName === target) return decodeAttrEntities(attrs.substring(valueStart, valueEnd)); | ||
| i = valueEnd + 1; | ||
@@ -595,3 +627,3 @@ continue; | ||
| while (i < attrs.length && !isWhitespace(attrs[i]) && attrs[i] !== ">") i++; | ||
| if (attrName === target) return attrs.substring(valueStart, i); | ||
| if (attrName === target) return decodeAttrEntities(attrs.substring(valueStart, i)); | ||
| } | ||
@@ -598,0 +630,0 @@ return null; |
+2
-2
| { | ||
| "name": "@templatical/types", | ||
| "description": "Shared TypeScript types, block factory functions, and event emitter for Templatical email editor", | ||
| "version": "0.26.1", | ||
| "version": "0.26.2", | ||
| "bugs": "https://github.com/templatical/sdk/issues", | ||
@@ -9,3 +9,3 @@ "devDependencies": { | ||
| "vitest": "^4.1.10", | ||
| "@templatical/media-library": "0.26.1" | ||
| "@templatical/media-library": "0.26.2" | ||
| }, | ||
@@ -12,0 +12,0 @@ "exports": { |
Sorry, the diff of this file is too big to display
185268
1.98%2348
1.47%