chore: 整理 third-party Dark Reader 目录并移除本地说明文件跟踪
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
import {DEFAULT_THEME} from '../../../src/defaults';
|
||||
import {createOrUpdateDynamicTheme, removeDynamicTheme} from '../../../src/inject/dynamic-theme';
|
||||
import {resetChromeRuntimeMessageStub, stubBackgroundFetchResponse, stubChromeRuntimeMessage} from '../support/background-stub';
|
||||
import {getCSSEchoURL} from '../support/echo-client';
|
||||
import {multiline, timeout, waitForEvent} from '../support/test-utils';
|
||||
|
||||
const theme = {
|
||||
...DEFAULT_THEME,
|
||||
darkSchemeBackgroundColor: 'black',
|
||||
darkSchemeTextColor: 'white',
|
||||
};
|
||||
let container: HTMLElement;
|
||||
const links: HTMLLinkElement[] = [];
|
||||
|
||||
function createStyleLink(href: string | null) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.classList.add('testcase--link');
|
||||
if (href) {
|
||||
link.href = href;
|
||||
}
|
||||
document.head.append(link);
|
||||
links.push(link);
|
||||
return link;
|
||||
}
|
||||
|
||||
function selectTestStyleLink() {
|
||||
return document.querySelector('.testcase--link')! as HTMLLinkElement;
|
||||
}
|
||||
|
||||
function createCorsLink(content: string) {
|
||||
const url = getCSSEchoURL(content);
|
||||
stubBackgroundFetchResponse(url, content);
|
||||
return createStyleLink(url);
|
||||
}
|
||||
|
||||
async function waitForLinkLoading(link: HTMLLinkElement) {
|
||||
return new Promise((resolve, reject) => {
|
||||
link.addEventListener('load', resolve, {once: true});
|
||||
link.addEventListener('error', reject, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
container = document.body;
|
||||
container.innerHTML = '';
|
||||
stubChromeRuntimeMessage();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
removeDynamicTheme();
|
||||
container.innerHTML = '';
|
||||
links.forEach((l) => l.remove());
|
||||
links.splice(0);
|
||||
resetChromeRuntimeMessageStub();
|
||||
});
|
||||
|
||||
describe('LINK STYLES', () => {
|
||||
it('should override same-origin link', async () => {
|
||||
createStyleLink(`data:text/css;utf8,${encodeURIComponent(multiline(
|
||||
'h1 { background: gray; }',
|
||||
'h1 strong { color: red; }',
|
||||
))}`);
|
||||
container.innerHTML = multiline(
|
||||
'<h1>Link <strong>override</strong>!</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
|
||||
await timeout(50);
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(255, 255, 255)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 26, 26)');
|
||||
});
|
||||
|
||||
it('should override cross-origin link', async () => {
|
||||
createCorsLink(multiline(
|
||||
'h1 { background: gray; }',
|
||||
'h1 strong { color: red; }',
|
||||
));
|
||||
container.innerHTML = multiline(
|
||||
'<h1><strong>Cross-origin</strong> link override</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
|
||||
await waitForEvent('__darkreader__test__dynamicUpdateComplete');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(255, 255, 255)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 26, 26)');
|
||||
});
|
||||
|
||||
it('should override cross-origin imports in linked CSS', async () => {
|
||||
const importedCSS = 'h1 { background: gray; }';
|
||||
const importedURL = getCSSEchoURL(importedCSS);
|
||||
stubBackgroundFetchResponse(importedURL, importedCSS);
|
||||
createCorsLink(multiline(
|
||||
`@import "${importedURL}";`,
|
||||
'h1 strong { color: red; }',
|
||||
));
|
||||
container.innerHTML = multiline(
|
||||
'<h1><strong>Cross-origin import</strong> link override</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
|
||||
await waitForEvent('__darkreader__test__dynamicUpdateComplete');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(255, 255, 255)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 26, 26)');
|
||||
});
|
||||
|
||||
it('should override cross-origin imports in linked CSS with capital @import', async () => {
|
||||
const importedCSS = 'h1 { background: gray; }';
|
||||
const importedURL = getCSSEchoURL(importedCSS);
|
||||
stubBackgroundFetchResponse(importedURL, importedCSS);
|
||||
createCorsLink(multiline(
|
||||
`@IMPORT "${importedURL}";`,
|
||||
'h1 strong { color: red; }',
|
||||
));
|
||||
container.innerHTML = multiline(
|
||||
'<h1><strong>Cross-origin import</strong> link override</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
await waitForEvent('__darkreader__test__dynamicUpdateComplete');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(255, 255, 255)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 26, 26)');
|
||||
});
|
||||
|
||||
it('should override cross-origin link that has already been loaded', async () => {
|
||||
createCorsLink(multiline(
|
||||
'h1 { background: gray; }',
|
||||
'h1 strong { color: red; }',
|
||||
));
|
||||
container.innerHTML = multiline(
|
||||
'<h1>Loaded <strong>cross-origin</strong> link override</h1>',
|
||||
);
|
||||
|
||||
await waitForLinkLoading(selectTestStyleLink());
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(128, 128, 128)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(0, 0, 0)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 0, 0)');
|
||||
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
await waitForEvent('__darkreader__test__dynamicUpdateComplete');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(255, 255, 255)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 26, 26)');
|
||||
});
|
||||
|
||||
it('should remove manager from disabled link', async () => {
|
||||
const link = createStyleLink(`data:text/css;utf8,${encodeURIComponent(multiline(
|
||||
'h1 { background: gray; }',
|
||||
'h1 strong { color: red; }',
|
||||
))}`);
|
||||
container.innerHTML = multiline(
|
||||
'<h1>Link <strong>disabled</strong>!</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
|
||||
await timeout(50);
|
||||
expect(selectTestStyleLink().nextElementSibling!.classList.contains('darkreader--sync')).toBe(true);
|
||||
link.disabled = true;
|
||||
await timeout(0);
|
||||
expect(selectTestStyleLink().nextElementSibling!.classList.contains('darkreader--sync')).toBe(false);
|
||||
});
|
||||
it("Shouldn't wait on link that won't be loaded", async () => {
|
||||
const link = createStyleLink(null);
|
||||
link.setAttribute('data-href', `data:text/css;utf8,${encodeURIComponent(multiline(
|
||||
'h1 { background: green !important; }',
|
||||
'h1 strong { color: orange !important; }',
|
||||
))}`);
|
||||
container.innerHTML = multiline(
|
||||
'<style>',
|
||||
' h1 { background: gray; }',
|
||||
'</style>',
|
||||
'<h1>Link <strong>loading with non-href attribute</strong>!</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
|
||||
await timeout(50);
|
||||
const h1 = document.querySelector('h1')!;
|
||||
expect(getComputedStyle(h1).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(document.querySelector('.darkreader--fallback')!.textContent).toBe('');
|
||||
});
|
||||
|
||||
it('should handle styles with @import "..." screen;', async () => {
|
||||
const importedCSS = 'h1 { background: gray; }';
|
||||
const importedURL = getCSSEchoURL(importedCSS);
|
||||
stubBackgroundFetchResponse(importedURL, importedCSS);
|
||||
createCorsLink(multiline(
|
||||
`@import "${importedURL}" screen;`,
|
||||
'h1 strong { color: red; }',
|
||||
));
|
||||
container.innerHTML = multiline(
|
||||
'<h1><strong>Cross-origin import</strong> link override</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
|
||||
await waitForEvent('__darkreader__test__dynamicUpdateComplete');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(255, 255, 255)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 26, 26)');
|
||||
});
|
||||
|
||||
it('should handle styles with invalid url(...)', async () => {
|
||||
const importedCSS = 'h1 { background-image: url("freecookies:3https://example.com"); background-color: gray; }';
|
||||
const importedURL = getCSSEchoURL(importedCSS);
|
||||
stubBackgroundFetchResponse(importedURL, importedCSS);
|
||||
stubBackgroundFetchResponse('freecookies:3https://example.com', '');
|
||||
createCorsLink(multiline(
|
||||
`@import "${importedURL}" screen;`,
|
||||
'h1 strong { color: red; }',
|
||||
));
|
||||
container.innerHTML = multiline(
|
||||
'<h1><strong>Cross-origin import</strong> link override</h1>',
|
||||
);
|
||||
createOrUpdateDynamicTheme(theme, null, false);
|
||||
|
||||
await waitForEvent('__darkreader__test__dynamicUpdateComplete');
|
||||
await timeout(1000);
|
||||
expect(getComputedStyle(container.querySelector('h1')!).backgroundColor).toBe('rgb(102, 102, 102)');
|
||||
expect(getComputedStyle(container.querySelector('h1')!).color).toBe('rgb(255, 255, 255)');
|
||||
expect(getComputedStyle(container.querySelector('h1 strong')!).color).toBe('rgb(255, 26, 26)');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user