mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-07-01 11:53:55 +00:00
fix: match root for CSS currentColor and skip unreferenced defs tones
This commit is contained in:
parent
ef93643a16
commit
166ca58919
2 changed files with 41 additions and 1 deletions
|
|
@ -178,6 +178,12 @@ describe('isMonochromeSvg', () => {
|
|||
'<svg viewBox="0 0 24 24"><defs><path id="glyph" d="M6 6h12v12H6z" /></defs><rect x="0" y="0" width="8" height="8" fill="#fff" /><use href="#glyph" /></svg>';
|
||||
expect(isMonochromeSvg(svg)).toBe(false);
|
||||
});
|
||||
|
||||
it('ignores an unreferenced colored template in defs', () => {
|
||||
const svg =
|
||||
'<svg viewBox="0 0 24 24"><defs><symbol id="unused"><path fill="#f00" d="M0 0h4v4H0z" /></symbol></defs><path fill="#333" d="M6 6h12v12H6z" /></svg>';
|
||||
expect(isMonochromeSvg(svg)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('currentColor resolved against a fixed color', () => {
|
||||
|
|
@ -240,6 +246,12 @@ describe('isMonochromeSvg', () => {
|
|||
'<svg viewBox="0 0 24 24"><style>svg{fill:#f00}</style><path d="M4 4h16v16H4z" /></svg>';
|
||||
expect(isMonochromeSvg(svg)).toBe(false);
|
||||
});
|
||||
|
||||
it('preserves a root CSS currentColor fill fixed by the root color', () => {
|
||||
const svg =
|
||||
'<svg viewBox="0 0 24 24" color="#e00"><style>svg{fill:currentColor}</style><path d="M4 4h16v16H4z" /></svg>';
|
||||
expect(isMonochromeSvg(svg)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('default fills alongside <style> rules', () => {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ const FUNCTIONAL_CONTAINERS = new Set(['clippath', 'mask', 'marker', 'pattern'])
|
|||
*/
|
||||
const DEFERRED_CONTAINERS = new Set(['clippath', 'mask', 'marker', 'pattern', 'defs', 'symbol']);
|
||||
|
||||
/** Containers whose content renders only when referenced (e.g. through `<use>`). */
|
||||
const TEMPLATE_CONTAINERS = new Set(['defs', 'symbol']);
|
||||
|
||||
/** Paint properties whose corresponding opacity makes them invisible at zero. */
|
||||
const PAINT_OPACITY = new Map([
|
||||
['fill', 'fill-opacity'],
|
||||
|
|
@ -290,6 +293,9 @@ function resolveCssCurrentColor(root: Element, selector: string, rules: StyleRul
|
|||
let matched: Element[];
|
||||
try {
|
||||
matched = Array.from(root.querySelectorAll(selector));
|
||||
if (root.matches(selector)) {
|
||||
matched = [root, ...matched];
|
||||
}
|
||||
} catch {
|
||||
return [CURRENT_COLOR];
|
||||
}
|
||||
|
|
@ -373,13 +379,35 @@ function resolveCurrentColor(el: Element, root: Element, rules: StyleRule[]): st
|
|||
return CURRENT_COLOR;
|
||||
}
|
||||
|
||||
/** Elements rendered through a visible `<use>` (target subtrees), so their
|
||||
* template paint counts even though they live in a deferred container. */
|
||||
function referencedElements(root: Element, rules: StyleRule[]): Set<Element> {
|
||||
const referenced = new Set<Element>();
|
||||
for (const use of Array.from(root.querySelectorAll('use'))) {
|
||||
if (isHidden(use, root, rules) || isInside(use, root, DEFERRED_CONTAINERS)) {
|
||||
continue;
|
||||
}
|
||||
const target = referencedTarget(use, root);
|
||||
if (target == null) {
|
||||
continue;
|
||||
}
|
||||
referenced.add(target);
|
||||
for (const el of Array.from(target.querySelectorAll('*'))) {
|
||||
referenced.add(el);
|
||||
}
|
||||
}
|
||||
return referenced;
|
||||
}
|
||||
|
||||
function collectColors(root: Element, rules: StyleRule[]): string[] {
|
||||
const colors: string[] = [];
|
||||
const referenced = referencedElements(root, rules);
|
||||
for (const el of [root, ...Array.from(root.querySelectorAll('*'))]) {
|
||||
if (
|
||||
el.nodeName.toLowerCase() === 'style' ||
|
||||
isInside(el, root, FUNCTIONAL_CONTAINERS) ||
|
||||
isHidden(el, root, rules)
|
||||
isHidden(el, root, rules) ||
|
||||
(isInside(el, root, TEMPLATE_CONTAINERS) && !referenced.has(el))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue