Skip to content

Commit

Permalink
Fix turn off issue by using style tag instead of inject css
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaiyoKung committed Feb 28, 2024
1 parent 19e6144 commit b5ddf55
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 104 deletions.
8 changes: 7 additions & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@
"32": "images/icon32.png",
"48": "images/icon48.png",
"128": "images/icon128.png"
}
},
"content_scripts": [
{
"matches": ["https://www.netflix.com/watch/*"],
"js": ["assets/content-scripts/netflix.js"]
}
]
}
51 changes: 28 additions & 23 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Button, ColorPicker, InputLabel, Stack, Switch } from '@mantine/core';
import { useCallback, useEffect } from 'react';
import { useCallback } from 'react';
import { IoRefresh } from 'react-icons/io5';
import { useChromeSyncStorageState } from './hooks';
import {
Style,
defaultStyle,
applyStyle,
styleStorageKey,
isOnStorageKey,
defaultIsOn,
IsOn,
removeStyle,
sendChangeStyleMessage,
} from './modules';

const mantinePaddingMd: number = 16;
Expand All @@ -24,36 +23,42 @@ export function App() {

const handleChangeOnOff = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setIsOn(e.currentTarget.checked);
setIsOn(() => {
const checked = e.target.checked;
sendChangeStyleMessage(checked, style);
return checked;
});
},
[setIsOn]
[setIsOn, style]
);

const handleChangeTextColor = useCallback(
(value: string) => {
setStyle((prev) => ({ ...prev, textColor: value }));
const handleChangeColor = useCallback(
(property: keyof Style, value: string) => {
setStyle((prev) => {
const style = { ...prev, [property]: value };
sendChangeStyleMessage(isOn, style);
return style;
});
},
[setStyle]
[isOn, setStyle]
);

const handleChangeTextColor = useCallback(
(value: string) => handleChangeColor('textColor', value),
[handleChangeColor]
);

const handleChangeBgColor = useCallback(
(value: string) => {
setStyle((prev) => ({ ...prev, backgroundColor: value }));
},
[setStyle]
(value: string) => handleChangeColor('backgroundColor', value),
[handleChangeColor]
);

const handleClickReset = useCallback(() => {
setStyle(defaultStyle);
}, [setStyle]);

useEffect(() => {
if (isOn) {
applyStyle(style);
} else {
removeStyle(style);
}
}, [isOn, style]);
setStyle(() => {
sendChangeStyleMessage(isOn, defaultStyle);
return defaultStyle;
});
}, [isOn, setStyle]);

return (
<Stack miw={containerMinWidth} p="md">
Expand Down
69 changes: 69 additions & 0 deletions src/content-scripts/netflix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const isOnStorageKey: string = 'isOn';

interface Style {
textColor: string;
backgroundColor: string;
}

const styleStorageKey: string = 'style';

const defaultStyle: Style = {
textColor: 'rgba(255, 255, 255, 1)',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
};

function applyStyle(style: Style) {
const css = `
.player-timedtext > .player-timedtext-text-container > span > span {
color: ${style.textColor} !important;
background-color: ${style.backgroundColor} !important;
}
`;

const currentStyleTag = document.querySelector('style#sub-stylist-style') as HTMLStyleElement | null;
if (currentStyleTag) {
currentStyleTag.textContent = css;
return;
}

const styleTag = document.createElement('style');
styleTag.id = 'sub-stylist-style';
styleTag.textContent = css;
document.head.appendChild(styleTag);
}

function removeStyle() {
const currentStyleTag = document.querySelector('style#sub-stylist-style') as HTMLStyleElement | null;
if (currentStyleTag) {
currentStyleTag.remove();
}
}

async function loadAndApplyStyle() {
const states = await chrome.storage.sync.get([isOnStorageKey, styleStorageKey]);
const isOn = states[isOnStorageKey] as boolean | undefined;
if (!isOn) {
return;
}

const style = states[styleStorageKey] as Style | undefined;
if (style !== undefined) {
applyStyle(style);
} else {
applyStyle(defaultStyle);
}
}

chrome.runtime.onMessage.addListener((message) => {
if (message.action === 'changeStyle') {
const isOn = message.payload.isOn as boolean;
if (isOn) {
const style = message.payload.style as Style;
applyStyle(style);
} else {
removeStyle();
}
}
});

loadAndApplyStyle();
62 changes: 3 additions & 59 deletions src/modules/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,70 +15,14 @@ export const defaultStyle: Style = {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
};

export function getPlatformOverrideCss(url: string, style: Style) {
//
// Netflix
//
if (url.startsWith('https://www.netflix.com/watch/')) {
return `
.player-timedtext > .player-timedtext-text-container > span > span {
color: ${style.textColor} !important;
background-color: ${style.backgroundColor} !important;
}
`;
}

//
// Other will append below
//
}

export async function applyStyle(style: Style) {
export async function sendChangeStyleMessage(isOn: boolean, style: Style) {
console.log('send "changeStyle" message');
const activeTab = await getActiveTab();

if (!activeTab.id) {
console.error("don't have active tab id");
return;
}

if (!activeTab.url) {
console.error("don't have active tab url");
return;
}

const css = getPlatformOverrideCss(activeTab.url, style);
if (!css) {
console.error('this platform not support');
return;
}

await chrome.scripting.insertCSS({
target: { tabId: activeTab.id },
css: css,
});
}

export async function removeStyle(style: Style) {
const activeTab = await getActiveTab();

if (!activeTab.id) {
console.error("don't have active tab id");
return;
}

if (!activeTab.url) {
console.error("don't have active tab url");
return;
}

const css = getPlatformOverrideCss(activeTab.url, style);
if (!css) {
console.error('this platform not support');
return;
}

await chrome.scripting.removeCSS({
target: { tabId: activeTab.id },
css: css,
});
await chrome.tabs.sendMessage(activeTab.id, { action: 'changeStyle', payload: { isOn, style } });
}
21 changes: 0 additions & 21 deletions src/service-worker.ts
Original file line number Diff line number Diff line change
@@ -1,21 +0,0 @@
import { applyStyle, defaultStyle, isOnSchema, isOnStorageKey, styleSchema, styleStorageKey } from './modules';

async function loadAndApplyStyle() {
const states = await chrome.storage.sync.get([isOnStorageKey, styleStorageKey]);
const isOn = isOnSchema.optional().parse(states[isOnStorageKey]);
if (!isOn) {
console.warn('now off');
return;
}

const style = styleSchema.optional().parse(states[styleStorageKey]);
if (style !== undefined) {
await applyStyle(style);
} else {
await applyStyle(defaultStyle);
}
}

chrome.tabs.onUpdated.addListener(() => {
loadAndApplyStyle();
});
1 change: 1 addition & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default defineConfig({
input: {
popup: 'popup.html',
'service-worker': './src/service-worker.ts',
'content-scripts/netflix': './src/content-scripts/netflix.ts',
},

// build without hash
Expand Down

0 comments on commit b5ddf55

Please sign in to comment.