chore: 整理 third-party Dark Reader 目录并移除本地说明文件跟踪
This commit is contained in:
@@ -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');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user