extension-create 4.0.1 → 4.0.2-canary.local-d776e4d9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/package-manager.d.ts +1 -0
- package/dist/module.cjs +62 -8
- package/dist/steps/install-internal-deps.d.ts +0 -14
- package/package.json +1 -1
- package/dist/test-template-javascript/README.md +0 -41
- package/dist/test-template-javascript/extension.config.js +0 -19
- package/dist/test-template-javascript/package.json +0 -27
- package/dist/test-template-javascript/public/screenshot.png +0 -0
- package/dist/test-template-javascript/src/background.js +0 -44
- package/dist/test-template-javascript/src/content/ContentApp.js +0 -42
- package/dist/test-template-javascript/src/content/scripts.js +0 -38
- package/dist/test-template-javascript/src/content/styles.css +0 -45
- package/dist/test-template-javascript/src/images/icon.png +0 -0
- package/dist/test-template-javascript/src/manifest.json +0 -63
- package/dist/test-template-javascript/src/sidebar/SidebarApp.js +0 -30
- package/dist/test-template-javascript/src/sidebar/index.html +0 -13
- package/dist/test-template-javascript/src/sidebar/scripts.js +0 -3
- package/dist/test-template-javascript/src/sidebar/styles.css +0 -60
package/dist/module.cjs
CHANGED
|
@@ -43,10 +43,12 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
43
43
|
extensionCreate: ()=>extensionCreate
|
|
44
44
|
});
|
|
45
45
|
const external_path_namespaceObject = require("path");
|
|
46
|
-
const external_fs_namespaceObject = require("fs");
|
|
47
46
|
const external_pintor_namespaceObject = require("pintor");
|
|
48
47
|
var external_pintor_default = /*#__PURE__*/ __webpack_require__.n(external_pintor_namespaceObject);
|
|
49
48
|
const external_prefers_yarn_namespaceObject = require("prefers-yarn");
|
|
49
|
+
function isDenoRuntime() {
|
|
50
|
+
return void 0 !== globalThis.Deno || Boolean(process.versions?.deno);
|
|
51
|
+
}
|
|
50
52
|
const statusPrefix = external_pintor_default().brightBlue('⏵⏵⏵');
|
|
51
53
|
function destinationNotWriteable(workingDir) {
|
|
52
54
|
const workingDirFolder = external_path_namespaceObject.basename(workingDir);
|
|
@@ -55,10 +57,7 @@ function destinationNotWriteable(workingDir) {
|
|
|
55
57
|
async function directoryHasConflicts(projectPath, conflictingFiles) {
|
|
56
58
|
const projectName = external_path_namespaceObject.basename(projectPath);
|
|
57
59
|
let message = `Conflicting files found in ${external_pintor_default().blue(projectName)}.\n\n`;
|
|
58
|
-
for (const file of conflictingFiles){
|
|
59
|
-
const stats = await external_fs_namespaceObject.promises.lstat(external_path_namespaceObject.join(projectPath, file));
|
|
60
|
-
message += stats.isDirectory() ? ` ${external_pintor_default().yellow('-')} ${external_pintor_default().yellow(file)}\n` : ` ${external_pintor_default().yellow('-')} ${external_pintor_default().yellow(file)}\n`;
|
|
61
|
-
}
|
|
60
|
+
for (const file of conflictingFiles)message += ` ${external_pintor_default().yellow('-')} ${external_pintor_default().yellow(file)}\n`;
|
|
62
61
|
message += `\n${external_pintor_default().red('Next step: remove or rename the files above, or choose a different directory name.')}\n\nPath: ${external_pintor_default().underline(projectPath)}`;
|
|
63
62
|
return message;
|
|
64
63
|
}
|
|
@@ -73,7 +72,10 @@ async function successfullInstall(projectPath, projectName, depsInstalled) {
|
|
|
73
72
|
const pm = (0, external_prefers_yarn_namespaceObject.detectPackageManagerFromEnv)();
|
|
74
73
|
let command = 'npm run';
|
|
75
74
|
let installCmd = 'npm install';
|
|
76
|
-
|
|
75
|
+
if (isDenoRuntime()) {
|
|
76
|
+
command = 'deno task dev';
|
|
77
|
+
installCmd = 'deno install';
|
|
78
|
+
} else switch(pm){
|
|
77
79
|
case 'yarn':
|
|
78
80
|
command = 'yarn dev';
|
|
79
81
|
installCmd = 'yarn';
|
|
@@ -82,6 +84,10 @@ async function successfullInstall(projectPath, projectName, depsInstalled) {
|
|
|
82
84
|
command = 'pnpm dev';
|
|
83
85
|
installCmd = 'pnpm install';
|
|
84
86
|
break;
|
|
87
|
+
case 'bun':
|
|
88
|
+
command = 'bun dev';
|
|
89
|
+
installCmd = 'bun install';
|
|
90
|
+
break;
|
|
85
91
|
default:
|
|
86
92
|
command = 'npm run dev';
|
|
87
93
|
installCmd = 'npm install';
|
|
@@ -137,7 +143,7 @@ function installingProjectIntegrations(integrations) {
|
|
|
137
143
|
if (2 === items.length) return `${items[0]} and ${items[1]}`;
|
|
138
144
|
return `${items.slice(0, -1).join(', ')}, and ${items[items.length - 1]}`;
|
|
139
145
|
};
|
|
140
|
-
const tools =
|
|
146
|
+
const tools = formatList(integrations.map((name)=>external_pintor_default().yellow(name)));
|
|
141
147
|
return `${statusPrefix} Installing specialized dependencies for ${tools}... ${external_pintor_default().gray('(This may take a moment)')}`;
|
|
142
148
|
}
|
|
143
149
|
function installingDependenciesFailed(gitCommand, gitArgs, code) {
|
|
@@ -288,6 +294,7 @@ async function createDirectory(projectPath, projectName, logger) {
|
|
|
288
294
|
throw new Error(createDirectoryError(projectName, error));
|
|
289
295
|
}
|
|
290
296
|
}
|
|
297
|
+
const external_fs_namespaceObject = require("fs");
|
|
291
298
|
const external_os_namespaceObject = require("os");
|
|
292
299
|
const external_axios_namespaceObject = require("axios");
|
|
293
300
|
var external_axios_default = /*#__PURE__*/ __webpack_require__.n(external_axios_namespaceObject);
|
|
@@ -466,6 +473,19 @@ function getTemplateAwareScripts(template, extensionBinary) {
|
|
|
466
473
|
}
|
|
467
474
|
return extensionJsPackageJsonScripts(extensionBinary);
|
|
468
475
|
}
|
|
476
|
+
const BUILD_NOOP_DEPENDENCIES = [
|
|
477
|
+
'less'
|
|
478
|
+
];
|
|
479
|
+
const ML_NATIVE_BUILD_DEPENDENCIES = [
|
|
480
|
+
'onnxruntime-node',
|
|
481
|
+
'sharp',
|
|
482
|
+
'protobufjs'
|
|
483
|
+
];
|
|
484
|
+
const ML_DEP_TRIGGERS = [
|
|
485
|
+
'@huggingface/transformers',
|
|
486
|
+
'@xenova/transformers'
|
|
487
|
+
];
|
|
488
|
+
const uniq = (values)=>Array.from(new Set(values.filter(Boolean)));
|
|
469
489
|
function resolveExtensionDevDependencyVersion(cliVersion) {
|
|
470
490
|
if (!cliVersion) return 'latest';
|
|
471
491
|
return cliVersion.includes('-') ? cliVersion : `^${cliVersion}`;
|
|
@@ -493,6 +513,25 @@ async function overridePackageJson(projectPath, projectName, { template = "javas
|
|
|
493
513
|
extension: 'development' === process.env.EXTENSION_ENV ? '*' : resolveExtensionDevDependencyVersion(cliVersion)
|
|
494
514
|
};
|
|
495
515
|
const packageManagerSpec = packageJson.packageManager || (0, external_prefers_yarn_namespaceObject.getPackageManagerSpec)();
|
|
516
|
+
const declaredDeps = {
|
|
517
|
+
...packageJson.dependencies || {},
|
|
518
|
+
...packageJson.devDependencies || {}
|
|
519
|
+
};
|
|
520
|
+
const usesMlNativeDeps = ML_DEP_TRIGGERS.some((dep)=>declaredDeps[dep]);
|
|
521
|
+
const nativeBuildDeps = usesMlNativeDeps ? ML_NATIVE_BUILD_DEPENDENCIES : [];
|
|
522
|
+
const existingPnpm = packageJson.pnpm && 'object' == typeof packageJson.pnpm ? packageJson.pnpm : {};
|
|
523
|
+
const ignoredBuilt = uniq([
|
|
524
|
+
...existingPnpm.ignoredBuiltDependencies || [],
|
|
525
|
+
...BUILD_NOOP_DEPENDENCIES
|
|
526
|
+
]);
|
|
527
|
+
const onlyBuilt = uniq([
|
|
528
|
+
...existingPnpm.onlyBuiltDependencies || [],
|
|
529
|
+
...nativeBuildDeps
|
|
530
|
+
]);
|
|
531
|
+
const trustedDeps = uniq([
|
|
532
|
+
...packageJson.trustedDependencies || [],
|
|
533
|
+
...nativeBuildDeps
|
|
534
|
+
]);
|
|
496
535
|
const packageMetadata = {
|
|
497
536
|
...packageJson,
|
|
498
537
|
name: external_path_namespaceObject.basename(projectPath),
|
|
@@ -506,6 +545,18 @@ async function overridePackageJson(projectPath, projectName, { template = "javas
|
|
|
506
545
|
},
|
|
507
546
|
dependencies: packageJson.dependencies,
|
|
508
547
|
devDependencies: packageJson.devDependencies,
|
|
548
|
+
pnpm: {
|
|
549
|
+
...existingPnpm,
|
|
550
|
+
...ignoredBuilt.length ? {
|
|
551
|
+
ignoredBuiltDependencies: ignoredBuilt
|
|
552
|
+
} : {},
|
|
553
|
+
...onlyBuilt.length ? {
|
|
554
|
+
onlyBuiltDependencies: onlyBuilt
|
|
555
|
+
} : {}
|
|
556
|
+
},
|
|
557
|
+
...trustedDeps.length ? {
|
|
558
|
+
trustedDependencies: trustedDeps
|
|
559
|
+
} : {},
|
|
509
560
|
author: {
|
|
510
561
|
name: 'Your Name',
|
|
511
562
|
email: 'your@email.com',
|
|
@@ -699,6 +750,9 @@ async function pathExists(target) {
|
|
|
699
750
|
}
|
|
700
751
|
async function writeReadmeFile(projectPath, projectName, logger) {
|
|
701
752
|
const installCommand = await getInstallCommand();
|
|
753
|
+
const deno = isDenoRuntime();
|
|
754
|
+
const runPrefix = deno ? 'deno task' : `${installCommand} run`;
|
|
755
|
+
const argSeparator = deno ? '' : ' --';
|
|
702
756
|
const manifestJsonPath = await findManifestJsonPath(projectPath);
|
|
703
757
|
const manifestJson = JSON.parse(await promises_namespaceObject.readFile(manifestJsonPath, 'utf-8'));
|
|
704
758
|
const description = String(manifestJson.description || '').trim();
|
|
@@ -706,7 +760,7 @@ async function writeReadmeFile(projectPath, projectName, logger) {
|
|
|
706
760
|
const hasScreenshot = await pathExists(screenshotPath);
|
|
707
761
|
const screenshotEmbed = hasScreenshot ? `\n\n` : '';
|
|
708
762
|
const blockquote = description ? `> ${description}\n\n` : '';
|
|
709
|
-
const readme = `<a href="https://extension.js.org" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/Powered%20by%20%7C%20Extension.js-0971fe" alt="Powered by Extension.js" align="right" /></a>\n\n# ${projectName}\n\n` + blockquote + `${screenshotEmbed}` + `## Commands\n` + `\n` + `### dev\n` + `\n` + "Run the extension in development mode. Target a browser with `--browser`:\n" + `\n` + "```bash\n" + `${
|
|
763
|
+
const readme = `<a href="https://extension.js.org" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/Powered%20by%20%7C%20Extension.js-0971fe" alt="Powered by Extension.js" align="right" /></a>\n\n# ${projectName}\n\n` + blockquote + `${screenshotEmbed}` + `## Commands\n` + `\n` + `### dev\n` + `\n` + "Run the extension in development mode. Target a browser with `--browser`:\n" + `\n` + "```bash\n" + `${runPrefix} dev\n` + `${runPrefix} dev${argSeparator} --browser=firefox\n` + `${runPrefix} dev${argSeparator} --browser=edge\n` + "```\n" + `\n` + `### build\n` + `\n` + `Build for production. Convenience scripts target each browser:\n` + `\n` + "```bash\n" + `${runPrefix} build # Chrome (default)\n` + `${runPrefix} build:firefox\n` + `${runPrefix} build:edge\n` + "```\n" + `\n` + `### preview\n` + `\n` + `Preview the production build in the browser:\n` + `\n` + "```bash\n" + `${runPrefix} preview\n` + "```\n" + `\n` + `## Learn more\n` + `\n` + `[Extension.js docs](https://extension.js.org).\n`;
|
|
710
764
|
try {
|
|
711
765
|
logger.log(writingReadmeMetaData());
|
|
712
766
|
await promises_namespaceObject.mkdir(projectPath, {
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
type OptionalDepsPlan = {
|
|
2
|
-
integrations: string[];
|
|
3
|
-
dependencies: string[];
|
|
4
|
-
dependenciesByIntegration: Record<string, string[]>;
|
|
5
|
-
};
|
|
6
|
-
declare function resolveDevelopRoot(projectPath: string): string | null;
|
|
7
|
-
declare function detectOptionalDependencies(projectPath: string): OptionalDepsPlan;
|
|
8
|
-
declare function resolveMissingOptionalDeps(developRoot: string, projectPath: string): OptionalDepsPlan;
|
|
9
1
|
export declare function installInternalDependencies(projectPath: string, logger: {
|
|
10
2
|
log(...args: any[]): void;
|
|
11
3
|
error(...args: any[]): void;
|
|
12
4
|
}): Promise<void>;
|
|
13
|
-
export declare const __testing__: {
|
|
14
|
-
resolveDevelopRoot: typeof resolveDevelopRoot;
|
|
15
|
-
resolveMissingOptionalDeps: typeof resolveMissingOptionalDeps;
|
|
16
|
-
detectOptionalDependencies: typeof detectOptionalDependencies;
|
|
17
|
-
};
|
|
18
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
<a href="https://extension.js.org" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/Powered%20by%20%7C%20Extension.js-0971fe" alt="Powered by Extension.js" align="right" /></a>
|
|
2
|
-
|
|
3
|
-
# test-template-javascript
|
|
4
|
-
|
|
5
|
-
> JavaScript-based extension with a sidebar panel. Adds a sidebar with a simple page.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-

|
|
9
|
-
## Commands
|
|
10
|
-
|
|
11
|
-
### dev
|
|
12
|
-
|
|
13
|
-
Run the extension in development mode. Target a browser with `--browser`:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
pnpm run dev
|
|
17
|
-
pnpm run dev -- --browser=firefox
|
|
18
|
-
pnpm run dev -- --browser=edge
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### build
|
|
22
|
-
|
|
23
|
-
Build for production. Convenience scripts target each browser:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
pnpm run build # Chrome (default)
|
|
27
|
-
pnpm run build:firefox
|
|
28
|
-
pnpm run build:edge
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### preview
|
|
32
|
-
|
|
33
|
-
Preview the production build in the browser:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
pnpm run preview
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Learn more
|
|
40
|
-
|
|
41
|
-
[Extension.js docs](https://extension.js.org).
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/** @type {import('extension').FileConfig} */
|
|
2
|
-
// Extension.js uses a fresh profile on every run.
|
|
3
|
-
// Prefer that default? Remove the profile config below.
|
|
4
|
-
const profile = (name) => `./dist/extension-profile-${name}`
|
|
5
|
-
const ciFlags = process.env.CI ? ['--no-sandbox', '--disable-gpu'] : []
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
browser: {
|
|
9
|
-
chrome: {profile: profile('chrome'), browserFlags: ciFlags},
|
|
10
|
-
chromium: {profile: profile('chromium'), browserFlags: ciFlags},
|
|
11
|
-
edge: {profile: profile('edge'), browserFlags: ciFlags},
|
|
12
|
-
firefox: {profile: profile('firefox')},
|
|
13
|
-
'chromium-based': {
|
|
14
|
-
profile: profile('chromium-based'),
|
|
15
|
-
browserFlags: ciFlags
|
|
16
|
-
},
|
|
17
|
-
'gecko-based': {profile: profile('gecko-based')}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"private": true,
|
|
3
|
-
"name": "test-template-javascript",
|
|
4
|
-
"description": "JavaScript-based extension with a sidebar panel. Adds a sidebar with a simple page.",
|
|
5
|
-
"version": "1.0.0",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"author": {
|
|
9
|
-
"name": "Your Name",
|
|
10
|
-
"email": "your@email.com",
|
|
11
|
-
"url": "https://yourwebsite.com"
|
|
12
|
-
},
|
|
13
|
-
"scripts": {
|
|
14
|
-
"dev": "extension dev",
|
|
15
|
-
"start": "extension start",
|
|
16
|
-
"build": "extension build",
|
|
17
|
-
"preview": "extension preview",
|
|
18
|
-
"build:chrome": "extension build --browser chrome",
|
|
19
|
-
"build:firefox": "extension build --browser firefox",
|
|
20
|
-
"build:edge": "extension build --browser edge"
|
|
21
|
-
},
|
|
22
|
-
"dependencies": {},
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"extension": "latest"
|
|
25
|
-
},
|
|
26
|
-
"packageManager": "pnpm@10.28.0"
|
|
27
|
-
}
|
|
Binary file
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
console.log(
|
|
2
|
-
'[From the background context] Hello from the background worker/script!'
|
|
3
|
-
)
|
|
4
|
-
|
|
5
|
-
const isFirefoxLike =
|
|
6
|
-
import.meta.env.EXTENSION_PUBLIC_BROWSER === 'firefox' ||
|
|
7
|
-
import.meta.env.EXTENSION_PUBLIC_BROWSER === 'gecko-based'
|
|
8
|
-
|
|
9
|
-
if (isFirefoxLike) {
|
|
10
|
-
browser.browserAction.onClicked.addListener(() => {
|
|
11
|
-
browser.sidebarAction.open()
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
browser.runtime.onMessage.addListener((message) => {
|
|
15
|
-
if (!message || message.type !== 'openSidebar') return
|
|
16
|
-
|
|
17
|
-
browser.sidebarAction.open()
|
|
18
|
-
})
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!isFirefoxLike) {
|
|
22
|
-
chrome.action.onClicked.addListener(() => {
|
|
23
|
-
chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true})
|
|
24
|
-
})
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
chrome.runtime.onMessage.addListener((message) => {
|
|
28
|
-
if (!message || message.type !== 'openSidebar') return
|
|
29
|
-
|
|
30
|
-
chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true})
|
|
31
|
-
|
|
32
|
-
if (!chrome.sidePanel.open) return
|
|
33
|
-
|
|
34
|
-
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
|
|
35
|
-
const activeTabId = tabs && tabs[0] && tabs[0].id
|
|
36
|
-
if (!activeTabId) return
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
chrome.sidePanel.open({tabId: activeTabId})
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.error(error)
|
|
42
|
-
}
|
|
43
|
-
})
|
|
44
|
-
})
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import iconUrl from '../images/icon.png'
|
|
2
|
-
const logo = iconUrl
|
|
3
|
-
|
|
4
|
-
export default function createContentApp() {
|
|
5
|
-
const container = document.createElement('div')
|
|
6
|
-
container.className = 'content_script'
|
|
7
|
-
|
|
8
|
-
const pill = document.createElement('button')
|
|
9
|
-
pill.type = 'button'
|
|
10
|
-
pill.className = 'content_pill'
|
|
11
|
-
pill.setAttribute('aria-label', 'Open sidebar')
|
|
12
|
-
pill.addEventListener('click', () => {
|
|
13
|
-
try {
|
|
14
|
-
if (
|
|
15
|
-
import.meta.env.EXTENSION_PUBLIC_BROWSER === 'firefox' ||
|
|
16
|
-
import.meta.env.EXTENSION_PUBLIC_BROWSER === 'gecko-based'
|
|
17
|
-
) {
|
|
18
|
-
browser.runtime.sendMessage({type: 'openSidebar'})
|
|
19
|
-
} else {
|
|
20
|
-
chrome.runtime.sendMessage({type: 'openSidebar'})
|
|
21
|
-
}
|
|
22
|
-
} catch (error) {
|
|
23
|
-
console.error(error)
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const img = document.createElement('img')
|
|
28
|
-
img.className = 'content_pill_logo'
|
|
29
|
-
img.src = logo
|
|
30
|
-
img.alt = ''
|
|
31
|
-
img.setAttribute('aria-hidden', 'true')
|
|
32
|
-
|
|
33
|
-
const text = document.createElement('span')
|
|
34
|
-
text.className = 'content_pill_text'
|
|
35
|
-
text.textContent = 'Open sidebar'
|
|
36
|
-
|
|
37
|
-
pill.appendChild(img)
|
|
38
|
-
pill.appendChild(text)
|
|
39
|
-
container.appendChild(pill)
|
|
40
|
-
|
|
41
|
-
return container
|
|
42
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
console.log('[From the page context] Hello from content_scripts!')
|
|
2
|
-
import createContentApp from './ContentApp.js'
|
|
3
|
-
import './styles.css'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Extension.js content_script entrypoint. The framework calls this on
|
|
7
|
-
* injection and calls the returned function on HMR/teardown to clean up.
|
|
8
|
-
* Do not invoke it yourself.
|
|
9
|
-
*/
|
|
10
|
-
export default function initial() {
|
|
11
|
-
const rootDiv = document.createElement('div')
|
|
12
|
-
rootDiv.setAttribute('data-extension-root', 'true')
|
|
13
|
-
document.body.appendChild(rootDiv)
|
|
14
|
-
|
|
15
|
-
// Injecting content_scripts inside a shadow dom
|
|
16
|
-
// prevents conflicts with the host page's styles.
|
|
17
|
-
// This way, styles from the extension won't leak into the host page.
|
|
18
|
-
const shadowRoot = rootDiv.attachShadow({mode: 'open'})
|
|
19
|
-
|
|
20
|
-
const styleElement = document.createElement('style')
|
|
21
|
-
shadowRoot.appendChild(styleElement)
|
|
22
|
-
fetchCSS().then((response) => (styleElement.textContent = response))
|
|
23
|
-
|
|
24
|
-
// Render ContentApp inside shadow root
|
|
25
|
-
const container = createContentApp()
|
|
26
|
-
shadowRoot.appendChild(container)
|
|
27
|
-
|
|
28
|
-
return () => {
|
|
29
|
-
rootDiv.remove()
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async function fetchCSS() {
|
|
34
|
-
const cssUrl = new URL('./styles.css', import.meta.url)
|
|
35
|
-
const response = await fetch(cssUrl)
|
|
36
|
-
const text = await response.text()
|
|
37
|
-
return response.ok ? text : Promise.reject(text)
|
|
38
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
.content_script {
|
|
2
|
-
position: absolute;
|
|
3
|
-
right: 0.75rem;
|
|
4
|
-
bottom: 0.75rem;
|
|
5
|
-
z-index: 9999;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.content_pill {
|
|
9
|
-
-webkit-font-smoothing: antialiased;
|
|
10
|
-
-moz-osx-font-smoothing: grayscale;
|
|
11
|
-
appearance: none;
|
|
12
|
-
border: none;
|
|
13
|
-
outline: none;
|
|
14
|
-
cursor: pointer;
|
|
15
|
-
display: inline-flex;
|
|
16
|
-
align-items: center;
|
|
17
|
-
gap: 0.5rem;
|
|
18
|
-
background: var(--sidebar-bg, #0a0c10);
|
|
19
|
-
color: var(--sidebar-text, #c9c9c9);
|
|
20
|
-
padding: 0.5rem 1rem 0.5rem 0.5rem;
|
|
21
|
-
border-radius: 9999px;
|
|
22
|
-
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.content_pill:hover {
|
|
26
|
-
background: #11151c;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.content_pill_logo {
|
|
30
|
-
height: 1.5rem;
|
|
31
|
-
border-radius: 9999px;
|
|
32
|
-
background: rgba(255, 255, 255, 0.08);
|
|
33
|
-
object-fit: contain;
|
|
34
|
-
aspect-ratio: 1 / 1;
|
|
35
|
-
padding: 0.125rem;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.content_pill_text {
|
|
39
|
-
font-size: 0.85rem;
|
|
40
|
-
font-weight: 600;
|
|
41
|
-
line-height: 1;
|
|
42
|
-
font-family:
|
|
43
|
-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
|
|
44
|
-
Arial, "Noto Sans", sans-serif;
|
|
45
|
-
}
|
|
Binary file
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/chrome-manifest.json",
|
|
3
|
-
"chromium:manifest_version": 3,
|
|
4
|
-
"firefox:manifest_version": 2,
|
|
5
|
-
"version": "1.0.0",
|
|
6
|
-
"name": "test-template-javascript",
|
|
7
|
-
"description": "JavaScript-based extension with a sidebar panel. Adds a sidebar with a simple page.",
|
|
8
|
-
"icons": {
|
|
9
|
-
"16": "images/icon.png",
|
|
10
|
-
"32": "images/icon.png",
|
|
11
|
-
"48": "images/icon.png",
|
|
12
|
-
"64": "images/icon.png",
|
|
13
|
-
"128": "images/icon.png"
|
|
14
|
-
},
|
|
15
|
-
"chromium:action": {
|
|
16
|
-
"default_icon": {
|
|
17
|
-
"16": "images/icon.png",
|
|
18
|
-
"32": "images/icon.png",
|
|
19
|
-
"48": "images/icon.png",
|
|
20
|
-
"64": "images/icon.png",
|
|
21
|
-
"128": "images/icon.png"
|
|
22
|
-
},
|
|
23
|
-
"default_title": "Open Side Panel"
|
|
24
|
-
},
|
|
25
|
-
"firefox:browser_action": {
|
|
26
|
-
"default_icon": {
|
|
27
|
-
"16": "images/icon.png",
|
|
28
|
-
"32": "images/icon.png",
|
|
29
|
-
"48": "images/icon.png",
|
|
30
|
-
"64": "images/icon.png",
|
|
31
|
-
"128": "images/icon.png"
|
|
32
|
-
},
|
|
33
|
-
"default_title": "Open Side Panel"
|
|
34
|
-
},
|
|
35
|
-
"chromium:side_panel": {
|
|
36
|
-
"default_path": "sidebar/index.html",
|
|
37
|
-
"default_title": "Side Panel Content"
|
|
38
|
-
},
|
|
39
|
-
"firefox:sidebar_action": {
|
|
40
|
-
"default_panel": "sidebar/index.html",
|
|
41
|
-
"default_title": "Side Panel Content"
|
|
42
|
-
},
|
|
43
|
-
"chromium:permissions": [
|
|
44
|
-
"sidePanel"
|
|
45
|
-
],
|
|
46
|
-
"background": {
|
|
47
|
-
"chromium:service_worker": "background.js",
|
|
48
|
-
"firefox:scripts": [
|
|
49
|
-
"background.js"
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
"content_scripts": [
|
|
53
|
-
{
|
|
54
|
-
"matches": [
|
|
55
|
-
"<all_urls>"
|
|
56
|
-
],
|
|
57
|
-
"js": [
|
|
58
|
-
"content/scripts.js"
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
],
|
|
62
|
-
"author": "Your Name"
|
|
63
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import './styles.css'
|
|
2
|
-
import iconUrl from '../images/icon.png'
|
|
3
|
-
|
|
4
|
-
const javascriptLogo = iconUrl
|
|
5
|
-
|
|
6
|
-
function SidebarApp() {
|
|
7
|
-
const root = document.getElementById('root')
|
|
8
|
-
if (!root) return
|
|
9
|
-
|
|
10
|
-
root.innerHTML = `
|
|
11
|
-
<div class="sidebar_app">
|
|
12
|
-
<img
|
|
13
|
-
class="sidebar_logo"
|
|
14
|
-
src="${javascriptLogo}"
|
|
15
|
-
alt="The JavaScript logo"
|
|
16
|
-
/>
|
|
17
|
-
<h1 class="sidebar_title">Sidebar Panel</h1>
|
|
18
|
-
<p class="sidebar_description">
|
|
19
|
-
Learn more in the
|
|
20
|
-
<a
|
|
21
|
-
href="https://extension.js.org"
|
|
22
|
-
target="_blank" rel="noopener noreferrer"
|
|
23
|
-
>Extension.js docs</a>
|
|
24
|
-
.
|
|
25
|
-
</p>
|
|
26
|
-
</div>
|
|
27
|
-
`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
SidebarApp()
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>JavaScript Sidebar</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<noscript>You need to enable JavaScript to run this extension.</noscript>
|
|
10
|
-
<div id="root"></div>
|
|
11
|
-
</body>
|
|
12
|
-
<script src="./scripts.js"></script>
|
|
13
|
-
</html>
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/* @import 'sakura.css'; */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--sidebar-margin: 1rem;
|
|
5
|
-
--sidebar-bg: #0a0c10;
|
|
6
|
-
--sidebar-text: #c9c9c9;
|
|
7
|
-
--sidebar-link: #e5e7eb;
|
|
8
|
-
--sidebar-border: #c9c9c9;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
body {
|
|
12
|
-
background-color: var(--sidebar-bg);
|
|
13
|
-
color: var(--sidebar-text);
|
|
14
|
-
height: 100vh;
|
|
15
|
-
margin: var(--sidebar-margin);
|
|
16
|
-
border-radius: 6px;
|
|
17
|
-
display: flex;
|
|
18
|
-
justify-content: center;
|
|
19
|
-
align-items: center;
|
|
20
|
-
overflow: hidden;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.sidebar_app {
|
|
24
|
-
display: flex;
|
|
25
|
-
flex-direction: column;
|
|
26
|
-
align-items: center;
|
|
27
|
-
padding: 0 1rem;
|
|
28
|
-
text-align: center;
|
|
29
|
-
max-height: 100vh;
|
|
30
|
-
overflow-y: auto;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.sidebar_logo {
|
|
34
|
-
width: 72px;
|
|
35
|
-
margin: 0 auto 1rem;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.sidebar_title {
|
|
39
|
-
font-size: 1.85em;
|
|
40
|
-
line-height: 1.1;
|
|
41
|
-
font-family:
|
|
42
|
-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
|
|
43
|
-
Arial, "Noto Sans", sans-serif;
|
|
44
|
-
font-weight: 700;
|
|
45
|
-
margin: 0;
|
|
46
|
-
text-align: center;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.sidebar_description {
|
|
50
|
-
font-size: small;
|
|
51
|
-
margin: 0.5rem 0 0;
|
|
52
|
-
text-align: center;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.sidebar_description a {
|
|
56
|
-
text-decoration: none;
|
|
57
|
-
border-bottom: 2px solid var(--sidebar-border);
|
|
58
|
-
color: var(--sidebar-link);
|
|
59
|
-
margin: 0;
|
|
60
|
-
}
|