diff --git a/README.md b/README.md
index 003a71c..3fdeccc 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,6 @@
-
Svelte DevTools
+# Svelte DevTools
-
+[![Chrome Web Store](https://img.shields.io/chrome-web-store/users/ckolcbmkjpjmangdbmnkpjigpkddpogn?color=blue&label=Chrome)](https://chrome.google.com/webstore/detail/svelte-devtools/ckolcbmkjpjmangdbmnkpjigpkddpogn) [![Mozilla Add-on](https://img.shields.io/amo/users/svelte-devtools?color=orange&label=Firefox)](https://addons.mozilla.org/en-US/firefox/addon/svelte-devtools)
Svelte DevTools is a Chrome extension for the [Svelte](https://svelte.dev/) framework. It allows you to inspect the Svelte state and component hierarchies in the Developer Tools.
@@ -23,7 +16,7 @@ This extensions officially supports Svelte 4.0 and above.
## Development
-Clone this repository and run the package script.
+Clone this repository, setup and run the build script
```sh
git clone https://github.com/sveltejs/svelte-devtools.git
diff --git a/rollup.config.js b/rollup.config.js
index 636f123..82f9b54 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -9,42 +9,9 @@ export default defineConfig([
},
{
input: 'src/client/index.js',
- output: {
- file: 'build/courier.js',
- format: 'iife',
- banner: `if (!window.tag) {
- window.tag = document.createElement('script')
- window.tag.text = \``,
- footer: `\`
- if (window.sessionStorage.SvelteDevToolsProfilerEnabled === "true") window.tag.text = window.tag.text.replace('let profilerEnabled = false;', '\$&\\nstartProfiler();')
- document.children[0].append(window.tag)
- const sendMessage = chrome.runtime.sendMessage
- const postMessage = window.postMessage.bind(window)
- chrome.runtime.onMessage.addListener((message, sender) => {
- const fromBackground = sender && sender.id === chrome.runtime.id
- if (!fromBackground) {
- console.error('Message from unexpected sender', sender, message)
- return
- }
- switch (message.type) {
- case 'startProfiler':
- window.sessionStorage.SvelteDevToolsProfilerEnabled = "true"
- break
- case 'stopProfiler':
- // fallthrough
- case 'clear':
- delete window.sessionStorage.SvelteDevToolsProfilerEnabled
- break
- }
- postMessage(message)
- })
- window.addEventListener(
- 'message',
- e => e.source == window && sendMessage(e.data),
- false
- )
- window.addEventListener('unload', () => sendMessage({ type: 'clear' }))
-}`,
- },
+ output: [
+ { file: 'static/courier.js', format: 'iife' },
+ { file: 'build/courier.js', format: 'iife' },
+ ],
},
]);
diff --git a/src/client/index.js b/src/client/index.js
index 5623683..1b018f6 100644
--- a/src/client/index.js
+++ b/src/client/index.js
@@ -108,7 +108,7 @@ function serializeNode(node) {
const attributes = Array.from(node.detail.attributes || []);
/** @type {NonNullable} */
- const listeners = res.detail.__listeners || [];
+ const listeners = node.detail.__listeners || [];
res.detail = {
attributes: attributes.map(({ name: key, value }) => ({ key, value })),
diff --git a/src/client/svelte.js b/src/client/svelte.js
index 625670a..045d3c5 100644
--- a/src/client/svelte.js
+++ b/src/client/svelte.js
@@ -123,8 +123,8 @@ document.addEventListener('SvelteRegisterBlock', ({ detail }) => {
}
Promise.resolve().then(() => {
- const invalidate = node.detail.$$?.invalidate || {};
- Object.keys(invalidate.length).length && listeners.update(node);
+ const invalidate = node.detail.$$?.bound || {};
+ Object.keys(invalidate).length && listeners.update(node);
});
break;
}
diff --git a/static/background.js b/static/background.js
index 8b0739d..bf84629 100644
--- a/static/background.js
+++ b/static/background.js
@@ -7,18 +7,21 @@ chrome.runtime.onConnect.addListener((port) => {
return port.disconnect();
}
- port.onMessage.addListener((msg, sender) => {
- if (msg.type === 'init') {
- return setup(msg.tabId, sender, msg.profilerEnabled);
- } else if (msg.type === 'reload') {
- return chrome.tabs.reload(msg.tabId, { bypassCache: true });
+ // messages are from the devtools page and not content script (courier.js)
+ port.onMessage.addListener((message, sender) => {
+ if (message.type === 'init') {
+ return setup(message.tabId, sender);
+ } else if (message.type === 'reload') {
+ return chrome.tabs.reload(message.tabId, { bypassCache: true });
}
- return chrome.tabs.sendMessage(msg.tabId, msg);
+ // relay messages from devtools page to `chrome.scripting`
+ return chrome.tabs.sendMessage(message.tabId, message);
});
});
-// relay messages from content scripts to devtools page
+// relay messages from `chrome.scripting` to devtools page
chrome.runtime.onMessage.addListener((msg, sender) => {
+ if (sender.id !== chrome.runtime.id) return; // unexpected sender
const port = sender.tab?.id && ports.get(sender.tab.id);
if (port) port.postMessage(msg);
});
@@ -27,29 +30,57 @@ chrome.runtime.onMessage.addListener((msg, sender) => {
function attach(tabId, changed) {
if (!ports.has(tabId) || changed.status !== 'loading') return;
- chrome.tabs.executeScript(tabId, {
- file: '/courier.js',
- runAt: 'document_start',
+ chrome.scripting.executeScript({
+ target: { tabId },
+
+ // no lexical context, `func` is serialized and deserialized.
+ // a limbo world where both `chrome` and `window` are defined
+ // with many unexpected and out of the ordinary behaviors, do
+ // minimal work here and delegate to `courier.js` in the page.
+ func: () => {
+ const source = chrome.runtime.getURL('/courier.js');
+ if (document.querySelector(`script[src="${source}"]`)) return;
+
+ // attach script manually instead of declaring through `files`
+ // because `detail` in the dispatched custom events is `null`
+ const script = document.createElement('script');
+ script.setAttribute('src', source);
+ document.body.appendChild(script);
+
+ chrome.runtime.onMessage.addListener((message, sender) => {
+ if (sender.id !== chrome.runtime.id) return; // unexpected sender
+ window.postMessage(message); // relay to content script (courier.js)
+ });
+
+ window.addEventListener('message', ({ source, data }) => {
+ // only accept messages from our application or script
+ if (source === window && data?.source === 'svelte-devtools') {
+ chrome.runtime.sendMessage(data);
+ }
+ });
+
+ window.addEventListener('unload', () => {
+ chrome.runtime.sendMessage({ type: 'ext/clear' });
+ });
+ },
});
}
/**
- *
* @param {number} tabId
- * @param {chrome.runtime.Port} port
- * @param {boolean} profilerEnabled
+ * @param {chrome.runtime.Port} sender
*/
-function setup(tabId, port, profilerEnabled) {
- chrome.tabs.executeScript(tabId, {
- code: profilerEnabled
- ? `window.sessionStorage.SvelteDevToolsProfilerEnabled = "true"`
- : 'delete window.sessionStorage.SvelteDevToolsProfilerEnabled',
- runAt: 'document_start',
- });
+function setup(tabId, sender) {
+ // chrome.tabs.executeScript(tabId, {
+ // code: profilerEnabled
+ // ? `window.sessionStorage.SvelteDevToolsProfilerEnabled = "true"`
+ // : 'delete window.sessionStorage.SvelteDevToolsProfilerEnabled',
+ // runAt: 'document_start',
+ // });
- ports.set(tabId, port);
+ ports.set(tabId, sender);
- port.onDisconnect.addListener(() => {
+ sender.onDisconnect.addListener(() => {
ports.delete(tabId);
chrome.tabs.onUpdated.removeListener(attach);
diff --git a/static/manifest.json b/static/manifest.json
index a27298e..b3c1ab9 100644
--- a/static/manifest.json
+++ b/static/manifest.json
@@ -1,7 +1,7 @@
{
- "manifest_version": 2,
- "name": "Svelte Devtools",
- "version": "1.3.0",
+ "manifest_version": 3,
+ "name": "Svelte DevTools",
+ "version": "2.0.0",
"description": "Browser devtools extension for debugging Svelte applications.",
"icons": {
"16": "icons/16.png",
@@ -12,9 +12,15 @@
},
"background": {
- "scripts": ["background.js"]
+ "service_worker": "background.js"
},
- "devtools_page": "devtools/index.html",
- "permissions": ["tabs", ""],
- "web_accessible_resources": ["courier.js"]
+ "devtools_page": "register.html",
+ "host_permissions": ["*://*/*"],
+ "permissions": ["activeTab", "scripting"],
+ "web_accessible_resources": [
+ {
+ "resources": ["courier.js"],
+ "matches": ["*://*/*"]
+ }
+ ]
}
diff --git a/static/register.html b/static/register.html
index f8cef97..6689014 100644
--- a/static/register.html
+++ b/static/register.html
@@ -1,8 +1,4 @@
-
-
-
-
-
+
diff --git a/static/register.js b/static/register.js
index 0f60516..cbb761a 100644
--- a/static/register.js
+++ b/static/register.js
@@ -1,6 +1,6 @@
chrome.devtools.panels.create(
'Svelte',
- chrome.devtools.panels.themeName == 'dark'
+ chrome.devtools.panels.themeName === 'dark'
? '/icons/svelte-logo-dark.svg'
: '/icons/svelte-logo-light.svg',
'/index.html',