Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/injecting scripts from popup #579

Merged
merged 10 commits into from
Jul 20, 2024
3 changes: 2 additions & 1 deletion chrome-extension/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const manifest = deepmerge(
name: '__MSG_extensionName__',
version: packageJson.version,
description: '__MSG_extensionDescription__',
permissions: ['storage'],
host_permissions: ['<all_urls>'],
permissions: ['storage', 'scripting'],
options_page: 'options/index.html',
background: {
service_worker: 'background.iife.js',
Expand Down
9 changes: 9 additions & 0 deletions pages/content-runtime/lib/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useEffect } from 'react';

export default function App() {
useEffect(() => {
console.log('runtime content view loaded');
}, []);

return <div className="runtime-content-view-text">runtime content view</div>;
}
3 changes: 3 additions & 0 deletions pages/content-runtime/lib/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.runtime-content-view-text {
font-size: 20px;
}
11 changes: 11 additions & 0 deletions pages/content-runtime/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* DO NOT USE import someModule from '...';
*
* @issue-url https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/issues/160
*
* Chrome extensions don't support modules in content scripts.
* If you want to use other modules in content scripts, you need to import them via these files.
*
*/
import('@lib/root');
console.log('runtime script loaded');
38 changes: 38 additions & 0 deletions pages/content-runtime/lib/root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createRoot } from 'react-dom/client';
import App from '@lib/app';
// eslint-disable-next-line
// @ts-ignore
import injectedStyle from '@lib/index.css?inline';

const root = document.createElement('div');
root.id = 'chrome-extension-boilerplate-react-vite-runtime-content-view-root';

document.body.append(root);

const rootIntoShadow = document.createElement('div');
rootIntoShadow.id = 'shadow-root';

const shadowRoot = root.attachShadow({ mode: 'open' });
shadowRoot.appendChild(rootIntoShadow);

/** Inject styles into shadow dom */
const globalStyleSheet = new CSSStyleSheet();
globalStyleSheet.replaceSync(injectedStyle);
shadowRoot.adoptedStyleSheets = [globalStyleSheet];
shadowRoot.appendChild(rootIntoShadow);
/**
* In the firefox environment, the adoptedStyleSheets bug may prevent style from being applied properly.
*
* @url https://bugzilla.mozilla.org/show_bug.cgi?id=1770592
* @url https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/pull/174
*
* Please refer to the links above and try the following code if you encounter the issue.
*
* ```ts
* const styleElement = document.createElement('style');
* styleElement.innerHTML = injectedStyle;
* shadowRoot.appendChild(styleElement);
* ```
*/

createRoot(rootIntoShadow).render(<App />);
27 changes: 27 additions & 0 deletions pages/content-runtime/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@chrome-extension-boilerplate/content-runtime-script",
"version": "0.0.1",
"description": "chrome extension content runtime script",
"private": true,
"sideEffects": true,
"files": [
"dist/**"
],
"scripts": {
"clean": "rimraf ./dist",
"build": "pnpm run clean && pnpm type-check && vite build",
"build:watch": "cross-env __DEV__=true vite build -w --mode development",
"dev": "pnpm build:watch",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "pnpm lint --fix",
"prettier": "prettier . --write --ignore-path ../../.prettierignore",
"type-check": "tsc --noEmit"
},
"dependencies": {
},
"devDependencies": {
"@chrome-extension-boilerplate/tsconfig": "workspace:*",
"@chrome-extension-boilerplate/hmr": "workspace:*",
"@chrome-extension-boilerplate/vite-config": "workspace:*"
}
}
11 changes: 11 additions & 0 deletions pages/content-runtime/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@chrome-extension-boilerplate/tsconfig/base",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@lib/*": ["lib/*"]
},
"types": ["chrome"]
},
"include": ["lib"]
}
23 changes: 23 additions & 0 deletions pages/content-runtime/vite.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { resolve } from 'path';
import { withPageConfig } from '@chrome-extension-boilerplate/vite-config';

const rootDir = resolve(__dirname);
const libDir = resolve(rootDir, 'lib');

export default withPageConfig({
resolve: {
alias: {
'@lib': libDir,
},
},
publicDir: resolve(rootDir, 'public'),
build: {
lib: {
formats: ['iife'],
entry: resolve(__dirname, 'lib/index.ts'),
name: 'ContentRuntimeScript',
fileName: 'index',
},
outDir: resolve(rootDir, '..', '..', 'dist', 'content-runtime'),
},
});
15 changes: 14 additions & 1 deletion pages/content-ui/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,21 @@ shadowRoot.appendChild(rootIntoShadow);
/** Inject styles into shadow dom */
const globalStyleSheet = new CSSStyleSheet();
globalStyleSheet.replaceSync(tailwindcssOutput);

shadowRoot.adoptedStyleSheets = [globalStyleSheet];
shadowRoot.appendChild(rootIntoShadow);
/**
* In the firefox environment, the adoptedStyleSheets bug may prevent style from being applied properly.
*
* @url https://bugzilla.mozilla.org/show_bug.cgi?id=1770592
* @url https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/pull/174
*
* Please refer to the links above and try the following code if you encounter the issue.
*

* const styleElement = document.createElement('style');
* styleElement.innerHTML = tailwindcssOutput;
* shadowRoot.appendChild(styleElement);
* ```
*/

createRoot(rootIntoShadow).render(<App />);
18 changes: 7 additions & 11 deletions pages/content-ui/src/tailwind-output.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@ html,
-moz-tab-size: 4;
/* 3 */
-o-tab-size: 4;
tab-size: 4;
tab-size: 4;
/* 3 */
font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
/* 4 */
font-feature-settings: normal;
/* 5 */
Expand Down Expand Up @@ -90,7 +89,7 @@ Add the correct text decoration in Chrome, Edge, and Safari.

abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
text-decoration: underline dotted;
}

/*
Expand Down Expand Up @@ -136,7 +135,7 @@ code,
kbd,
samp,
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
/* 1 */
font-feature-settings: normal;
/* 2 */
Expand Down Expand Up @@ -379,8 +378,7 @@ textarea {
2. Set the default placeholder color to the user's configured gray 400 color.
*/

input::-moz-placeholder,
textarea::-moz-placeholder {
input::-moz-placeholder, textarea::-moz-placeholder {
opacity: 1;
/* 1 */
color: #9ca3af;
Expand All @@ -400,7 +398,7 @@ Set the default cursor for buttons.
*/

button,
[role='button'] {
[role="button"] {
cursor: pointer;
}

Expand Down Expand Up @@ -448,9 +446,7 @@ video {
display: none;
}

*,
::before,
::after {
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
Expand Down
4 changes: 3 additions & 1 deletion pages/popup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
},
"dependencies": {
"@chrome-extension-boilerplate/shared": "workspace:*",
"@chrome-extension-boilerplate/storage": "workspace:*"
"@chrome-extension-boilerplate/storage": "workspace:*",
"@chrome-extension-boilerplate/content-runtime-script": "workspace:*",
"@types/node": "^20.14.10"
},
"devDependencies": {
"@chrome-extension-boilerplate/tailwindcss-config": "workspace:*",
Expand Down
19 changes: 18 additions & 1 deletion pages/popup/src/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,30 @@ const Popup = () => {
const isLight = theme === 'light';
const logo = isLight ? 'popup/logo_vertical.svg' : 'popup/logo_vertical_dark.svg';

const injectContentScript = async () => {
const [tab] = await chrome.tabs.query({ currentWindow: true, active: true });

await chrome.scripting.executeScript({
target: { tabId: tab.id! },
files: ['content-runtime/index.iife.js'],
});
};

return (
<div className={`App ${isLight ? 'bg-slate-50' : 'bg-gray-800'}`}>
<header className={`App-header ${isLight ? 'text-gray-900' : 'text-gray-100'}`}>
<img src={chrome.runtime.getURL(logo)} className="App-logo" alt="logo" />
<p>
Edit <code>pages/popup/src/Popup.tsx</code>
</p>
<button
className={
'font-bold mt-4 py-1 px-4 rounded shadow hover:scale-105 ' +
(isLight ? 'bg-blue-200 text-black' : 'bg-gray-700 text-white')
}
onClick={injectContentScript}>
Click to inject Content Script
</button>
<ToggleButton>Toggle theme</ToggleButton>
</header>
</div>
Expand All @@ -29,7 +46,7 @@ const ToggleButton = (props: ComponentPropsWithoutRef<'button'>) => {
props.className +
' ' +
'font-bold mt-4 py-1 px-4 rounded shadow hover:scale-105 ' +
(theme === 'light' ? 'bg-white text-black' : 'bg-black text-white')
(theme === 'light' ? 'bg-white text-black shadow-black' : 'bg-black text-white')
}
onClick={exampleThemeStorage.toggle}>
{props.children}
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.