fix: Explicitly handle null attribute values (#1157)

* fix: Explicitly handle removed attributes

The attribute `value` can be null when a mutation observer triggers due to a removed attribute. This is currently not reflected by types and code.

* Apply formatting changes

* fix

* add changeset
This commit is contained in:
Francesco Novy
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 7dca0f37c4
commit 8b55751a40
7 changed files with 256 additions and 15 deletions

View File

@@ -223,33 +223,36 @@ export function transformAttribute(
doc: Document,
tagName: string,
name: string,
value: string,
): string {
value: string | null,
): string | null {
if (!value) {
return value;
}
// relative path in attribute
if (
name === 'src' ||
(name === 'href' && value && !(tagName === 'use' && value[0] === '#'))
(name === 'href' && !(tagName === 'use' && value[0] === '#'))
) {
// href starts with a # is an id pointer for svg
return absoluteToDoc(doc, value);
} else if (name === 'xlink:href' && value && value[0] !== '#') {
} else if (name === 'xlink:href' && value[0] !== '#') {
// xlink:href starts with # is an id pointer
return absoluteToDoc(doc, value);
} else if (
name === 'background' &&
value &&
(tagName === 'table' || tagName === 'td' || tagName === 'th')
) {
return absoluteToDoc(doc, value);
} else if (name === 'srcset' && value) {
} else if (name === 'srcset') {
return getAbsoluteSrcsetString(doc, value);
} else if (name === 'style' && value) {
} else if (name === 'style') {
return absoluteToStylesheet(value, getHref());
} else if (tagName === 'object' && name === 'data' && value) {
} else if (tagName === 'object' && name === 'data') {
return absoluteToDoc(doc, value);
} else {
return value;
}
return value;
}
export function _isBlockedElement(
@@ -794,8 +797,10 @@ function serializeElementNode(
};
}
function lowerIfExists(maybeAttr: string | number | boolean): string {
if (maybeAttr === undefined) {
function lowerIfExists(
maybeAttr: string | number | boolean | undefined | null,
): string {
if (maybeAttr === undefined || maybeAttr === null) {
return '';
} else {
return (maybeAttr as string).toLowerCase();