mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-07-01 20:01:35 +00:00
fix: skip transparent svg use references
This commit is contained in:
parent
d168091f1f
commit
1d4da287ea
2 changed files with 45 additions and 6 deletions
|
|
@ -209,6 +209,24 @@ describe('isMonochromeSvg', () => {
|
|||
expect(isMonochromeSvg(svg)).toBe(true);
|
||||
});
|
||||
|
||||
it('ignores a referenced color rendered only through an opacity-zero use', () => {
|
||||
const svg =
|
||||
'<svg viewBox="0 0 24 24"><defs><path id="red" fill="#f00" d="M6 6h12v12H6z" /></defs><path fill="#333" d="M0 0h4v4H0z" /><use href="#red" opacity="0" /></svg>';
|
||||
expect(isMonochromeSvg(svg)).toBe(true);
|
||||
});
|
||||
|
||||
it('ignores a nested referenced color hidden by an opacity-zero use', () => {
|
||||
const svg =
|
||||
'<svg viewBox="0 0 24 24"><defs><symbol id="s"><use href="#red" opacity="0" /></symbol><path id="red" fill="#f00" d="M6 6h12v12H6z" /></defs><path fill="#333" d="M0 0h4v4H0z" /><use href="#s" /></svg>';
|
||||
expect(isMonochromeSvg(svg)).toBe(true);
|
||||
});
|
||||
|
||||
it('ignores a default-black use hidden with opacity zero', () => {
|
||||
const svg =
|
||||
'<svg viewBox="0 0 24 24"><defs><path id="g" d="M6 6h12v12H6z" /></defs><path fill="#fff" d="M0 0h4v4H0z" /><use href="#g" opacity="0" /></svg>';
|
||||
expect(isMonochromeSvg(svg)).toBe(true);
|
||||
});
|
||||
|
||||
it('tints a referenced glyph whose own fill overrides the use fill', () => {
|
||||
const svg =
|
||||
'<svg viewBox="0 0 24 24"><defs><path id="p" fill="#333" d="M4 4h16v16H4z" /></defs><use href="#p" fill="#000" /></svg>';
|
||||
|
|
|
|||
|
|
@ -342,8 +342,8 @@ function currentColorTones(
|
|||
* instantiating `<use>` elements, so its template paint counts even though it
|
||||
* lives in a deferred container, and `currentColor` can resolve against the
|
||||
* instance's inherited `color`. Nested `<use>` inside a referenced template are
|
||||
* followed too (a symbol may reference another template). Hidden uses render
|
||||
* nothing and are skipped; a `seen` set guards against reference cycles.
|
||||
* followed too (a symbol may reference another template). Hidden or opacity-zero
|
||||
* uses render nothing and are skipped; a `seen` set guards against reference cycles.
|
||||
*/
|
||||
function referenceMap(root: Element, rules: StyleRule[]): Map<Element, Element[]> {
|
||||
const map = new Map<Element, Element[]>();
|
||||
|
|
@ -365,7 +365,7 @@ function referenceMap(root: Element, rules: StyleRule[]): Map<Element, Element[]
|
|||
link(el, use);
|
||||
}
|
||||
for (const nested of Array.from(target.querySelectorAll('use'))) {
|
||||
if (isHidden(nested, root, rules)) {
|
||||
if (instanceInvisible(nested, root, rules)) {
|
||||
continue;
|
||||
}
|
||||
const nestedTarget = referencedTarget(nested, root);
|
||||
|
|
@ -375,7 +375,7 @@ function referenceMap(root: Element, rules: StyleRule[]): Map<Element, Element[]
|
|||
}
|
||||
};
|
||||
for (const use of Array.from(root.querySelectorAll('use'))) {
|
||||
if (isHidden(use, root, rules) || isInside(use, root, DEFERRED_CONTAINERS)) {
|
||||
if (instanceInvisible(use, root, rules) || isInside(use, root, DEFERRED_CONTAINERS)) {
|
||||
continue;
|
||||
}
|
||||
const target = referencedTarget(use, root);
|
||||
|
|
@ -593,6 +593,24 @@ function isHidden(el: Element, root: Element, rules: StyleRule[]): boolean {
|
|||
return false;
|
||||
}
|
||||
|
||||
function hasZeroOpacity(el: Element, root: Element, rules: StyleRule[]): boolean {
|
||||
let current: Element | null = el;
|
||||
while (current != null) {
|
||||
if (styleNumber(current, rules, 'opacity') === 0) {
|
||||
return true;
|
||||
}
|
||||
if (current === root) {
|
||||
break;
|
||||
}
|
||||
current = current.parentElement;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function instanceInvisible(el: Element, root: Element, rules: StyleRule[]): boolean {
|
||||
return isHidden(el, root, rules) || hasZeroOpacity(el, root, rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* True when a paint is fully transparent through opacity: the element or any
|
||||
* ancestor group has `opacity:0` (group opacity is not inherited and composites
|
||||
|
|
@ -776,7 +794,10 @@ function targetInheritsPaint(
|
|||
}
|
||||
}
|
||||
for (const nested of Array.from(target.querySelectorAll('use'))) {
|
||||
if (isHidden(nested, root, rules) || resolvePaint(nested, target, rules, property) != null) {
|
||||
if (
|
||||
instanceInvisible(nested, root, rules) ||
|
||||
resolvePaint(nested, target, rules, property) != null
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const nestedTarget = referencedTarget(nested, root);
|
||||
|
|
@ -811,7 +832,7 @@ function instanceContributesPaint(
|
|||
function hasDefaultBlackUse(root: Element, rules: StyleRule[]): boolean {
|
||||
for (const use of Array.from(root.querySelectorAll('use'))) {
|
||||
if (
|
||||
isHidden(use, root, rules) ||
|
||||
instanceInvisible(use, root, rules) ||
|
||||
isInside(use, root, DEFERRED_CONTAINERS) ||
|
||||
fillIsResolved(use, root, rules)
|
||||
) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue