chore: 整理 third-party Dark Reader 目录并移除本地说明文件跟踪

This commit is contained in:
2026-08-08 17:38:08 +08:00
parent 202ab537d1
commit 0bb552b026
1004 changed files with 115066 additions and 20081 deletions
+270
View File
@@ -0,0 +1,270 @@
import type {DynamicThemeFix} from '../../../src/definitions';
import {findRelevantFix, combineFixes} from '../../../src/inject/dynamic-theme/fixes';
import {multiline} from '../../support/test-utils';
describe('Select fixes via findRelevantFix()', () => {
const emptyFix: DynamicThemeFix = {
url: [],
css: '',
invert: [],
ignoreImageAnalysis: [],
ignoreInlineStyle: [],
ignoreCSSUrl: [],
disableStyleSheetsProxy: false,
disableCustomElementRegistryProxy: false,
};
it('If fix list is empty or invalid, findRelevantFix() returns null', () => {
expect(findRelevantFix('https://example.com', [])).toBe(null);
expect(findRelevantFix('https://example.com', 1 as any)).toBe(null);
expect(findRelevantFix('https://example.com', 'a' as any)).toBe(null);
expect(findRelevantFix('https://example.com', {} as any)).toBe(null);
});
it('If no matching URL found, findRelevantFix() returns null', () => {
expect(findRelevantFix('https://example.com', [
{
...emptyFix,
url: ['*'],
},
])).toBe(null);
expect(findRelevantFix('https://example.com', [
{
...emptyFix,
url: ['*'],
},
{
...emptyFix,
url: [
'other.com',
'some.net',
],
},
])).toBe(null);
expect(findRelevantFix('https://example.com', [
{
...emptyFix,
url: ['*'],
},
{
...emptyFix,
url: [
'example.com/sub',
],
},
])).toBe(null);
});
it('If multiple matching URL patterns found, select the most specific one', () => {
expect(findRelevantFix('https://example.com/sub', [
{
...emptyFix,
url: ['*'],
},
{
...emptyFix,
url: [
'example.com',
'example.net',
],
},
{
...emptyFix,
url: [
'example.com/sub',
'some.net',
],
},
])).toBe(2);
expect(findRelevantFix('https://example.com/1/2/3', [
{
...emptyFix,
url: ['*'],
},
{
...emptyFix,
url: [
'example.com/1',
'example.net',
],
},
{
...emptyFix,
url: [
'example.com/1/2',
'example.net',
],
},
{
...emptyFix,
url: [
'example.com/1/2/3',
'some.net',
],
},
{
...emptyFix,
url: [
'example.com/1/2/3/4',
'some.net',
],
},
])).toBe(3);
});
it('BUG COMPATIBILITY: If multiple matching URL patterns found, the most specific fix is determined by the length of first pattern', () => {
expect(findRelevantFix('https://example.com/exact/match', [
{
...emptyFix,
url: ['*'],
},
{
...emptyFix,
url: [
'other.net',
'example.com/exact/match',
],
},
{
...emptyFix,
url: [
'other.net/this/fix/is/selected',
'example.com',
],
},
{
...emptyFix,
url: [
'other.net',
'example.com/exact/match',
],
},
])).toBe(2);
});
it('BUG COMPATIBILITY: If multiple matching URL patterns of the same length are found, select the first one', () => {
expect(findRelevantFix('https://example.com/exact/match', [
{
...emptyFix,
url: ['*'],
},
{
...emptyFix,
url: [
'example.com/exact/match',
],
},
{
...emptyFix,
url: [
'example.com/exact/match',
],
},
])).toBe(1);
});
});
describe('Construct single fix via combineFixes()', () => {
const emptyFix: DynamicThemeFix = {
url: [],
css: '',
invert: [],
ignoreImageAnalysis: [],
ignoreInlineStyle: [],
ignoreCSSUrl: [],
disableStyleSheetsProxy: false,
disableCustomElementRegistryProxy: false,
};
it('Merges CSS', () => {
expect(combineFixes([
{
...emptyFix,
url: ['*'],
css: 'body { background: blue; }',
},
{
...emptyFix,
url: ['example.com'],
css: 'h1 { color: yellow; }\n',
},
])!.css).toBe(multiline(
'body { background: blue; }',
'h1 { color: yellow; }',
));
});
it('Merges invert', () => {
expect(combineFixes([
{
...emptyFix,
url: ['*'],
invert: ['img'],
},
{
...emptyFix,
invert: ['svg'],
},
])!.invert).toStrictEqual(['img', 'svg']);
});
it('Merges ignoreImageAnalysis', () => {
expect(combineFixes([
{
...emptyFix,
url: ['*'],
ignoreImageAnalysis: ['img'],
},
{
...emptyFix,
ignoreImageAnalysis: ['svg'],
},
])!.ignoreImageAnalysis).toStrictEqual(['img', 'svg']);
});
it('Merges ignoreInlineStyle', () => {
expect(combineFixes([
{
...emptyFix,
url: ['*'],
ignoreInlineStyle: ['img'],
},
{
...emptyFix,
ignoreInlineStyle: ['svg'],
},
])!.ignoreInlineStyle).toStrictEqual(['img', 'svg']);
});
it('disableStyleSheetsProxy is true if it is true in at least one fix', () => {
expect(combineFixes([
{
...emptyFix,
url: ['*'],
disableStyleSheetsProxy: false,
},
{
...emptyFix,
},
])!.disableStyleSheetsProxy).toBe(false);
expect(combineFixes([
{
...emptyFix,
url: ['*'],
disableStyleSheetsProxy: false,
},
{
...emptyFix,
disableStyleSheetsProxy: true,
},
{
...emptyFix,
disableStyleSheetsProxy: false,
},
])!.disableStyleSheetsProxy).toBe(true);
});
});
@@ -0,0 +1,77 @@
import {isSelectorWithin, makeSelectorEmpty} from '../../../src/inject/dynamic-theme/selectors';
describe('Check if a selector is within another selector', () => {
it('Treats identical selector as within', () => {
expect(isSelectorWithin('.a', '.a')).toBe(true);
expect(isSelectorWithin('.a:hover', '.a:hover')).toBe(true);
});
it('Returns false when sub does not start with parent', () => {
expect(isSelectorWithin('.b', '.a')).toBe(false);
expect(isSelectorWithin('.a', '.a .b')).toBe(false);
});
it('Returns false when sub continues the same token', () => {
expect(isSelectorWithin('.ab', '.a')).toBe(false);
expect(isSelectorWithin('dividend', 'div')).toBe(false);
});
it('Treats same-element extensions as within', () => {
expect(isSelectorWithin('.a.b', '.a')).toBe(true);
expect(isSelectorWithin('.a:hover', '.a')).toBe(true);
expect(isSelectorWithin('.a::before', '.a')).toBe(true);
expect(isSelectorWithin('.a::after', '.a')).toBe(true);
expect(isSelectorWithin('.a:not(.x)', '.a')).toBe(true);
expect(isSelectorWithin('.a#id', '.a')).toBe(true);
expect(isSelectorWithin('.a[x]', '.a')).toBe(true);
expect(isSelectorWithin('.a[x="y"]', '.a')).toBe(true);
});
it('Treats descendants as within', () => {
expect(isSelectorWithin('.a .b', '.a')).toBe(true);
expect(isSelectorWithin('.a .b .c', '.a')).toBe(true);
});
it('Treats immediate child as within', () => {
expect(isSelectorWithin('.a > .b', '.a')).toBe(true);
expect(isSelectorWithin('.a>.b', '.a')).toBe(true);
expect(isSelectorWithin('.a >.b', '.a')).toBe(true);
expect(isSelectorWithin('.a> .b', '.a')).toBe(true);
});
it('Treats siblings as not within', () => {
expect(isSelectorWithin('.a + .b', '.a')).toBe(false);
expect(isSelectorWithin('.a+.b', '.a')).toBe(false);
expect(isSelectorWithin('.a ~ .b', '.a')).toBe(false);
expect(isSelectorWithin('.a~.b', '.a')).toBe(false);
});
it('Handle complex selectors', () => {
expect(isSelectorWithin('.a:hover .b', '.a')).toBe(true);
expect(isSelectorWithin('.a .b > .c', '.a')).toBe(true);
expect(isSelectorWithin('.a + .b .c', '.a')).toBe(false);
});
});
describe('Make selector empty', () => {
it('Should append :empty', () => {
expect(makeSelectorEmpty('.a')).toBe('.a:empty');
expect(makeSelectorEmpty('div.a')).toBe('div.a:empty');
expect(makeSelectorEmpty('.a .b')).toBe('.a .b:empty');
});
it('Should ignore already :empty selectors', () => {
expect(makeSelectorEmpty('.a:empty')).toBe('.a:empty');
});
it('Should treat :before and :after as empty', () => {
expect(makeSelectorEmpty('.a:before')).toBe('.a:before');
expect(makeSelectorEmpty('.a:after')).toBe('.a:after');
expect(makeSelectorEmpty('.a::before')).toBe('.a::before');
expect(makeSelectorEmpty('.a::after')).toBe('.a::after');
});
it('Should trim selectors', () => {
expect(makeSelectorEmpty(' .a ')).toBe('.a:empty');
});
});