-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: separate firefox shell with manifest v2
- Loading branch information
Showing
14 changed files
with
608 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
icons/ | ||
popups/ | ||
*.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/bash | ||
|
||
rm -rf icons | ||
|
||
cp -r ../shell-chrome/icons . | ||
cp -r ../shell-chrome/popups . | ||
cp ../shell-chrome/*.html . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"name": "Vue.js devtools", | ||
"version": "6.5.1", | ||
"version_name": "6.5.1", | ||
"description": "Browser DevTools extension for debugging Vue.js applications.", | ||
"manifest_version": 2, | ||
"icons": { | ||
"16": "icons/16.png", | ||
"48": "icons/48.png", | ||
"128": "icons/128.png" | ||
}, | ||
"browser_action": { | ||
"default_icon": { | ||
"16": "icons/16-gray.png", | ||
"48": "icons/48-gray.png", | ||
"128": "icons/128-gray.png" | ||
}, | ||
"default_title": "Vue Devtools", | ||
"default_popup": "popups/not-found.html" | ||
}, | ||
"web_accessible_resources": [ | ||
"devtools.html", | ||
"devtools-background.html", | ||
"build/backend.js" | ||
], | ||
"devtools_page": "devtools-background.html", | ||
"background": { | ||
"scripts": [ | ||
"build/background.js" | ||
], | ||
"persistent": true | ||
}, | ||
"permissions": [ | ||
"<all_urls>", | ||
"storage" | ||
], | ||
"content_scripts": [ | ||
{ | ||
"matches": [ | ||
"<all_urls>" | ||
], | ||
"js": [ | ||
"build/hook.js" | ||
], | ||
"run_at": "document_start" | ||
}, | ||
{ | ||
"matches": [ | ||
"<all_urls>" | ||
], | ||
"js": [ | ||
"build/detector.js" | ||
], | ||
"run_at": "document_idle" | ||
} | ||
], | ||
"content_security_policy": "script-src 'self'; object-src 'self'" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "@vue-devtools/shell-firefox", | ||
"version": "0.0.0", | ||
"scripts": { | ||
"build": "rimraf ./build && ./copy.sh && cross-env NODE_ENV=production webpack --progress" | ||
}, | ||
"dependencies": { | ||
"@vue-devtools/app-backend-core": "^0.0.0", | ||
"@vue-devtools/app-frontend": "^0.0.0", | ||
"@vue-devtools/shared-utils": "^0.0.0" | ||
}, | ||
"devDependencies": { | ||
"@vue-devtools/build-tools": "^0.0.0", | ||
"rimraf": "^3.0.2", | ||
"webpack": "^5.35.1", | ||
"webpack-cli": "^4.6.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// this is injected to the app page when the panel is activated. | ||
|
||
import { initBackend } from '@back' | ||
import { Bridge } from '@vue-devtools/shared-utils' | ||
|
||
window.addEventListener('message', handshake) | ||
|
||
function sendListening() { | ||
window.postMessage({ | ||
source: 'vue-devtools-backend-injection', | ||
payload: 'listening', | ||
}, '*') | ||
} | ||
sendListening() | ||
|
||
function handshake(e) { | ||
if (e.data.source === 'vue-devtools-proxy' && e.data.payload === 'init') { | ||
window.removeEventListener('message', handshake) | ||
|
||
let listeners = [] | ||
const bridge = new Bridge({ | ||
listen(fn) { | ||
const listener = (evt) => { | ||
if (evt.data.source === 'vue-devtools-proxy' && evt.data.payload) { | ||
fn(evt.data.payload) | ||
} | ||
} | ||
window.addEventListener('message', listener) | ||
listeners.push(listener) | ||
}, | ||
send(data) { | ||
// if (process.env.NODE_ENV !== 'production') { | ||
// console.log('[chrome] backend -> devtools', data) | ||
// } | ||
window.postMessage({ | ||
source: 'vue-devtools-backend', | ||
payload: data, | ||
}, '*') | ||
}, | ||
}) | ||
|
||
bridge.on('shutdown', () => { | ||
listeners.forEach((l) => { | ||
window.removeEventListener('message', l) | ||
}) | ||
listeners = [] | ||
window.addEventListener('message', handshake) | ||
}) | ||
|
||
initBackend(bridge) | ||
} | ||
else { | ||
sendListening() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
// the background script runs all the time and serves as a central message | ||
// hub for each vue devtools (panel + proxy + backend) instance. | ||
|
||
const ports = {} | ||
|
||
chrome.runtime.onConnect.addListener((port) => { | ||
let tab | ||
let name | ||
if (isNumeric(port.name)) { | ||
tab = port.name | ||
name = 'devtools' | ||
installProxy(+port.name) | ||
} | ||
else { | ||
tab = port.sender.tab.id | ||
name = 'backend' | ||
} | ||
|
||
if (!ports[tab]) { | ||
ports[tab] = { | ||
devtools: null, | ||
backend: null, | ||
} | ||
} | ||
ports[tab][name] = port | ||
|
||
if (ports[tab].devtools && ports[tab].backend) { | ||
doublePipe(tab, ports[tab].devtools, ports[tab].backend) | ||
} | ||
}) | ||
|
||
function isNumeric(str) { | ||
return `${+str}` === str | ||
} | ||
|
||
function installProxy(tabId) { | ||
chrome.tabs.executeScript(tabId, { | ||
file: '/build/proxy.js', | ||
}, (res) => { | ||
if (!res) { | ||
ports[tabId].devtools.postMessage('proxy-fail') | ||
} | ||
else { | ||
if (process.env.NODE_ENV !== 'production') { | ||
// eslint-disable-next-line no-console | ||
console.log(`injected proxy to tab ${tabId}`) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
function doublePipe(id, one, two) { | ||
one.onMessage.addListener(lOne) | ||
function lOne(message) { | ||
if (message.event === 'log') { | ||
// eslint-disable-next-line no-console | ||
return console.log(`tab ${id}`, message.payload) | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
// eslint-disable-next-line no-console | ||
console.log('%cdevtools -> backend', 'color:#888;', message) | ||
} | ||
two.postMessage(message) | ||
} | ||
two.onMessage.addListener(lTwo) | ||
function lTwo(message) { | ||
if (message.event === 'log') { | ||
// eslint-disable-next-line no-console | ||
return console.log(`tab ${id}`, message.payload) | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
// eslint-disable-next-line no-console | ||
console.log('%cbackend -> devtools', 'color:#888;', message) | ||
} | ||
one.postMessage(message) | ||
} | ||
function shutdown() { | ||
if (process.env.NODE_ENV !== 'production') { | ||
// eslint-disable-next-line no-console | ||
console.log(`tab ${id} disconnected.`) | ||
} | ||
one.onMessage.removeListener(lOne) | ||
two.onMessage.removeListener(lTwo) | ||
one.disconnect() | ||
two.disconnect() | ||
ports[id] = null | ||
} | ||
one.onDisconnect.addListener(shutdown) | ||
two.onDisconnect.addListener(shutdown) | ||
if (process.env.NODE_ENV !== 'production') { | ||
// eslint-disable-next-line no-console | ||
console.log(`tab ${id} connected.`) | ||
} | ||
} | ||
|
||
chrome.runtime.onMessage.addListener((req, sender) => { | ||
if (sender.tab && req.vueDetected) { | ||
const suffix = req.nuxtDetected ? '.nuxt' : '' | ||
|
||
chrome.browserAction.setIcon({ | ||
tabId: sender.tab.id, | ||
path: { | ||
16: `icons/16${suffix}.png`, | ||
48: `icons/48${suffix}.png`, | ||
128: `icons/128${suffix}.png`, | ||
}, | ||
}) | ||
chrome.browserAction.setPopup({ | ||
tabId: sender.tab.id, | ||
popup: req.devtoolsEnabled ? `popups/enabled${suffix}.html` : `popups/disabled${suffix}.html`, | ||
}) | ||
} | ||
|
||
if (req.action === 'vue-take-screenshot' && sender.envType === 'devtools_child') { | ||
browser.tabs.captureVisibleTab({ | ||
format: 'png', | ||
}).then((dataUrl) => { | ||
browser.runtime.sendMessage({ | ||
action: 'vue-screenshot-result', | ||
id: req.id, | ||
dataUrl, | ||
}) | ||
}) | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { installToast } from '@back/toast' | ||
import { isFirefox } from '@vue-devtools/shared-utils' | ||
|
||
window.addEventListener('message', (e) => { | ||
if (e.source === window && e.data.vueDetected) { | ||
chrome.runtime.sendMessage(e.data) | ||
} | ||
}) | ||
|
||
function detect(win) { | ||
let delay = 1000 | ||
let detectRemainingTries = 10 | ||
|
||
function runDetect() { | ||
// Method 1: Check Nuxt | ||
const nuxtDetected = !!(window.__NUXT__ || window.$nuxt) | ||
|
||
if (nuxtDetected) { | ||
let Vue | ||
|
||
if (window.$nuxt) { | ||
Vue = window.$nuxt.$root && window.$nuxt.$root.constructor | ||
} | ||
|
||
win.postMessage({ | ||
devtoolsEnabled: (/* Vue 2 */ Vue && Vue.config.devtools) | ||
|| (/* Vue 3.2.14+ */ window.__VUE_DEVTOOLS_GLOBAL_HOOK__ && window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled), | ||
vueDetected: true, | ||
nuxtDetected: true, | ||
}, '*') | ||
|
||
return | ||
} | ||
|
||
// Method 2: Check Vue 3 | ||
const vueDetected = !!(window.__VUE__) | ||
if (vueDetected) { | ||
win.postMessage({ | ||
devtoolsEnabled: /* Vue 3.2.14+ */ window.__VUE_DEVTOOLS_GLOBAL_HOOK__ && window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled, | ||
vueDetected: true, | ||
}, '*') | ||
|
||
return | ||
} | ||
|
||
// Method 3: Scan all elements inside document | ||
const all = document.querySelectorAll('*') | ||
let el | ||
for (let i = 0; i < all.length; i++) { | ||
if (all[i].__vue__) { | ||
el = all[i] | ||
break | ||
} | ||
} | ||
if (el) { | ||
let Vue = Object.getPrototypeOf(el.__vue__).constructor | ||
while (Vue.super) { | ||
Vue = Vue.super | ||
} | ||
win.postMessage({ | ||
devtoolsEnabled: Vue.config.devtools, | ||
vueDetected: true, | ||
}, '*') | ||
return | ||
} | ||
|
||
if (detectRemainingTries > 0) { | ||
detectRemainingTries-- | ||
setTimeout(() => { | ||
runDetect() | ||
}, delay) | ||
delay *= 5 | ||
} | ||
} | ||
|
||
setTimeout(() => { | ||
runDetect() | ||
}, 100) | ||
} | ||
|
||
// inject the hook | ||
if (document instanceof HTMLDocument) { | ||
installScript(detect) | ||
installScript(installToast) | ||
} | ||
|
||
function installScript(fn) { | ||
const source = `;(${fn.toString()})(window)` | ||
|
||
if (isFirefox) { | ||
// eslint-disable-next-line no-eval | ||
window.eval(source) // in Firefox, this evaluates on the content window | ||
} | ||
else { | ||
const script = document.createElement('script') | ||
script.textContent = source | ||
document.documentElement.appendChild(script) | ||
script.parentNode.removeChild(script) | ||
} | ||
} |
Oops, something went wrong.