Skip to content

Commit bd18aab

Browse files
committed
First commit
0 parents  commit bd18aab

30 files changed

+450
-0
lines changed

.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
vite.config.js.timestamp*
10+
pnpm-lock.yaml
11+
package-lock.json
12+
13+
playground
14+
node_modules
15+
dist
16+
dist-ssr
17+
*.local
18+
19+
# Editor directories and files
20+
.vscode/*
21+
!.vscode/launch.json
22+
!.vscode/extensions.json
23+
.idea
24+
.DS_Store
25+
*.suo
26+
*.ntvs*
27+
*.njsproj
28+
*.sln
29+
*.sw?
30+
31+
# Config files
32+
.webextrc
33+
.webextrc.*

.vscode/launch.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Todo: Add a configuration that loads options, popup, etc. via the "url" property
3+
*/
4+
{
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "chrome",
9+
"request": "launch",
10+
"name": "Launch Chrome",
11+
"url": "https://www.svelte.dev/",
12+
"runtimeArgs": ["--load-extension=${workspaceFolder}/dist", "--auto-open-devtools-for-tabs"],
13+
"resolveSourceMapLocations": [
14+
"${workspaceFolder}/dist/**",
15+
"!**/node_modules/**"
16+
],
17+
//"smartStep": true,
18+
},
19+
{
20+
/**
21+
* Requires Debugger for Firefox Extension
22+
* Todo: Autoload extension like chrome does via runetimeArgs
23+
*/
24+
"type": "firefox",
25+
"request": "launch",
26+
"name": "Launch Firefox",
27+
"url": "https://svelte.dev/",
28+
"addonPath": "${workspaceFolder}/dist",
29+
"firefoxArgs": ["--devtools"],
30+
}
31+
]
32+
}

jsconfig.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"typeAcquisition": {
3+
"include": ["chrome"]
4+
},
5+
"compilerOptions": {
6+
"moduleResolution": "Node",
7+
"target": "ESNext",
8+
"module": "ESNext",
9+
/**
10+
* svelte-preprocess cannot figure out whether you have
11+
* a value or a type, so tell TypeScript to enforce using
12+
* `import type` instead of `import` for Types.
13+
*/
14+
"verbatimModuleSyntax": "error",
15+
"isolatedModules": true,
16+
"resolveJsonModule": true,
17+
/**
18+
* To have warnings / errors of the Svelte compiler at the
19+
* correct position, enable source maps by default.
20+
*/
21+
"sourceMap": true,
22+
"esModuleInterop": true,
23+
"skipLibCheck": true,
24+
"forceConsistentCasingInFileNames": true,
25+
/**
26+
* Typecheck JS in `.svelte` and `.js` files by default.
27+
* Disable this if you'd like to use dynamic types.
28+
*/
29+
"checkJs": true
30+
},
31+
/**
32+
* Use global.d.ts instead of compilerOptions.types
33+
* to avoid limiting type declarations.
34+
*/
35+
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
36+
}

manifest.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"{{chrome}}.manifest_version": 3,
3+
"permissions": [
4+
"sidePanel",
5+
"storage"
6+
],
7+
"{{chrome}}.action": {
8+
"default_popup": "src/popups/app.html"
9+
},
10+
"{{chrome}}.side_panel": {
11+
"default_path": "src/side-panels/app.html"
12+
},
13+
"{{chrome}}.content_scripts": [
14+
{
15+
"matches": [
16+
"https://*/*",
17+
"http://*/*"
18+
],
19+
"js": ["src/content-scripts/app.js"]
20+
}
21+
],
22+
"web_accessible_resources": [
23+
{
24+
"resources": ["*.js.map"],
25+
"matches": ["https://*/*","http://*/*"]
26+
}
27+
]
28+
}

nodemon.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"watch": ["./src/**", "./public/**"],
3+
"ext": "json,css,html,svelte"
4+
}

package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "debuggable-svelte-chrome-extension",
3+
"version": "1.0.0",
4+
"description": "A minimal svelte chrome extension boilerplate with everything that's needed to debug in Chrome already added.",
5+
"type": "module",
6+
"author": {
7+
"name": "Bradley Tollett",
8+
"email": "[email protected]"
9+
},
10+
"scripts": {
11+
"watch": "nodemon --watch './src/**' --watch './public/**' --exec 'vite build' -e json,css,html,svelte",
12+
"dev": "vite",
13+
"build": "vite build"
14+
},
15+
"devDependencies": {
16+
"@sveltejs/vite-plugin-svelte": "^2.5.2",
17+
"nodemon": "^3.0.1",
18+
"svelte": "^3.59.2",
19+
"vite": "^4.5.0",
20+
"vite-plugin-web-extension": "^3.2.0",
21+
"webextension-polyfill": "^0.10.0"
22+
},
23+
"dependencies": {
24+
"svelte-chrome-storage": "^0.1.8"
25+
}
26+
}

public/icon-with-shadow.svg

Lines changed: 29 additions & 0 deletions
Loading

public/icon/128.png

12.4 KB
Loading

public/icon/16.png

698 Bytes
Loading

public/icon/32.png

1.59 KB
Loading

public/icon/48.png

2.87 KB
Loading

public/icon/96.png

7.89 KB
Loading

readme.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Debuggable Svelte Chrome Extension
2+
3+
A minimal Svelte Chrome extension boilerplate that's preconfigured for debugging with source maps.
4+
5+
## Directions
6+
7+
To start debugging, set you breakpoints and then run:
8+
9+
```
10+
npm install
11+
npm watch
12+
```
13+
14+
Go to the VSCode Run view
15+
16+
Make sure Launch Chrome is seleteced from the dropdown menu
17+
18+
Click the play button
19+
20+
A new Chrome instance should launch with your plugin installed and DevTools should automatically open
21+
22+
At that point, you can debug like you would any other app.

src/components/ContentScript.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
console.log('ContentScript loaded');
3+
</script>
4+
<!-- Content Script Widgets -->
5+
<style>
6+
7+
</style>

src/components/Options.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
console.log("Options loaded");
3+
</script>
4+
<div>
5+
<img src="/icon-with-shadow.svg" alt="" />
6+
<h1>Options Page</h1>
7+
<p>
8+
Template: <code>svelte-js</code>
9+
</p>
10+
</div>
11+
<style>
12+
13+
</style>

src/components/PopUp.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
console.log("PopUp loaded");
3+
</script>
4+
<div>
5+
<img src="/icon-with-shadow.svg" alt="" />
6+
<h1>Popup Page</h1>
7+
<p>
8+
Template: <code>svelte-js</code>
9+
</p>
10+
</div>
11+
<style>
12+
13+
</style>

src/components/SidePanel.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
console.log("SidePanel loaded");
3+
</script>
4+
<div>
5+
<img src="/icon-with-shadow.svg" alt="" />
6+
<h1>Popup Page</h1>
7+
<p>
8+
Template: <code>svelte-js</code>
9+
</p>
10+
</div>
11+
<style>
12+
13+
</style>

src/content-scripts/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import ContentScript from '../components/ContentScript.svelte'
2+
new ContentScript({ target: document.body });

src/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<link rel="stylesheet" href="./style.css" />
8+
<title>Option</title>
9+
</head>
10+
11+
<body></body>
12+
13+
<script type="module" src="./options.js"></script>
14+
</html>

src/library/hot-reload.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Hot reloads the chrome-extension so you don't have to reload it manually each time.
3+
* Doesn't work at the moment, see Todo: that was added below.
4+
*/
5+
const filesInDirectory = dir => new Promise (resolve =>
6+
dir.createReader ().readEntries (entries =>
7+
Promise.all (entries.filter (e => e.name[0] !== '.').map (e =>
8+
e.isDirectory
9+
? filesInDirectory (e)
10+
: new Promise (resolve => e.file (resolve))
11+
))
12+
.then (files => [].concat (...files))
13+
.then (resolve)
14+
)
15+
)
16+
17+
const timestampForFilesInDirectory = dir =>
18+
filesInDirectory (dir).then (files =>
19+
files.map (f => f.name + f.lastModifiedDate).join ())
20+
21+
const watchChanges = (dir, lastTimestamp) => {
22+
timestampForFilesInDirectory (dir).then (timestamp => {
23+
if (!lastTimestamp || (lastTimestamp === timestamp)) {
24+
setTimeout (() => watchChanges (dir, timestamp), 1000) // retry after 1s
25+
} else {
26+
chrome.runtime.reload ()
27+
}
28+
})
29+
}
30+
31+
chrome.management.getSelf (self => {
32+
if (self.installType === 'development') {
33+
/**
34+
* Todo: getPackageDirectoryEntry does not work in background on manifest v3.
35+
* Not a big deal when using the launch.json config since it's reinstalled each time
36+
* Relevant Links:
37+
* https://developer.chrome.com/docs/extensions/reference/runtime/#method-getPackageDirectoryEntry
38+
* https://stackoverflow.com/questions/71377847/cant-use-chrome-runtime-getpackagedirectoryentry-in-service-work-with-the-manif
39+
*/
40+
chrome.runtime.getPackageDirectoryEntry(dir => watchChanges (dir))
41+
chrome.tabs.query ({ active: true, lastFocusedWindow: true }, tabs => { // NB: see https://github.com/xpl/crx-hotreload/issues/5
42+
if (tabs[0]) {
43+
chrome.tabs.reload (tabs[0].id)
44+
}
45+
})
46+
}
47+
})

src/options/app.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Options</title>
8+
</head>
9+
<body></body>
10+
<script type="module" src="./options.js"></script>
11+
</html>

src/options/options.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Options from '../components/Options.svelte';
2+
new Options({ target: document.body });

src/popups/app.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<link rel="stylesheet" href="./style.css" />
8+
<title>Popup</title>
9+
</head>
10+
11+
<body></body>
12+
13+
<script type="module" src="./popup.js"></script>
14+
</html>

src/popups/popup.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Popup from '../components/PopUp.svelte'
2+
new Popup({ target: document.body });

src/side-panels/app.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<link rel="stylesheet" href="./style.css" />
8+
<title>Popup</title>
9+
</head>
10+
11+
<body></body>
12+
13+
<script type="module" src="./side-panel.js"></script>
14+
</html>

src/side-panels/side-panel.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import SidePanel from '../components/SidePanel.svelte'
2+
new SidePanel({ target: document.body });

0 commit comments

Comments
 (0)