Skip to content

Commit

Permalink
refactor: migrate to manifest v3 (#2136)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akryum committed Feb 4, 2024
1 parent e275579 commit faae234
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 134 deletions.
37 changes: 25 additions & 12 deletions packages/shell-chrome/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"version": "6.5.1",
"version_name": "6.5.1",
"description": "Browser DevTools extension for debugging Vue.js applications.",
"manifest_version": 2,
"manifest_version": 3,
"icons": {
"16": "icons/16.png",
"48": "icons/48.png",
"128": "icons/128.png"
},
"browser_action": {
"action": {
"default_icon": {
"16": "icons/16-gray.png",
"48": "icons/48-gray.png",
Expand All @@ -19,20 +19,31 @@
"default_popup": "popups/not-found.html"
},
"web_accessible_resources": [
"devtools.html",
"devtools-background.html",
"build/backend.js"
{
"resources": [
"devtools.html",
"devtools-background.html",
"build/backend.js",
"build/proxy.js",
"build/hook-exec.js",
"build/detector-exec.js"
],
"matches": [
"<all_urls>"
],
"extension_ids": []
}
],
"devtools_page": "devtools-background.html",
"background": {
"scripts": [
"build/background.js"
],
"persistent": true
"service_worker": "build/service-worker.js"
},
"permissions": [
"<all_urls>",
"storage"
"storage",
"scripting"
],
"host_permissions": [
"<all_urls>"
],
"content_scripts": [
{
Expand All @@ -54,5 +65,7 @@
"run_at": "document_idle"
}
],
"content_security_policy": "script-src 'self'; object-src 'self'"
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
}
}
85 changes: 85 additions & 0 deletions packages/shell-chrome/src/detector-exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { installToast } from '@back/toast'

function sendMessage (message) {
window.postMessage({
key: '_vue-devtools-send-message',
message,
})
}

function detect () {
let delay = 1000
let detectRemainingTries = 10

function runDetect () {
// Method 1: Check Nuxt.js
const nuxtDetected = !!(window.__NUXT__ || window.$nuxt)

if (nuxtDetected) {
let Vue

if (window.$nuxt) {
Vue = window.$nuxt.$root && window.$nuxt.$root.constructor
}

sendMessage({
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) {
sendMessage({
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
}
sendMessage({
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) {
detect()
installToast()
}
105 changes: 9 additions & 96 deletions packages/shell-chrome/src/detector.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,12 @@
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
}
window.addEventListener('message', function (event) {
if (event.data.key === '_vue-devtools-send-message') {
chrome.runtime.sendMessage(event.data.message)
}
}, false)

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)
}
const script = document.createElement('script')
script.src = chrome.runtime.getURL('build/detector-exec.js')
script.onload = () => {
script.remove()
}
;(document.head || document.documentElement).appendChild(script)
3 changes: 3 additions & 0 deletions packages/shell-chrome/src/hook-exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { installHook } from '@back/hook'

installHook(window)
22 changes: 5 additions & 17 deletions packages/shell-chrome/src/hook.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
// This script is injected into every page.
import { installHook } from '@back/hook'
import { isFirefox } from '@vue-devtools/shared-utils'

// inject the hook
if (document instanceof HTMLDocument) {
const source = ';(' + installHook.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)
}
const script = document.createElement('script')
script.src = chrome.runtime.getURL('build/hook-exec.js')
script.onload = () => {
script.remove()
}
;(document.head || document.documentElement).appendChild(script)
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ function isNumeric (str) {
}

function installProxy (tabId) {
chrome.tabs.executeScript(tabId, {
file: '/build/proxy.js',
chrome.scripting.executeScript({
target: { tabId },
files: ['build/proxy.js'],
}, function (res) {
if (!res) {
ports[tabId].devtools.postMessage('proxy-fail')
Expand Down Expand Up @@ -95,17 +96,21 @@ chrome.runtime.onMessage.addListener((req, sender) => {
if (sender.tab && req.vueDetected) {
const suffix = req.nuxtDetected ? '.nuxt' : ''

chrome.browserAction.setIcon({
chrome.action.setIcon({
tabId: sender.tab.id,
path: {
16: `icons/16${suffix}.png`,
48: `icons/48${suffix}.png`,
128: `icons/128${suffix}.png`,
16: chrome.runtime.getURL(`icons/16${suffix}.png`),
48: chrome.runtime.getURL(`icons/48${suffix}.png`),
128: chrome.runtime.getURL(`icons/128${suffix}.png`),
},
}, () => {
// noop
})
chrome.browserAction.setPopup({
chrome.action.setPopup({
tabId: sender.tab.id,
popup: req.devtoolsEnabled ? `popups/enabled${suffix}.html` : `popups/disabled${suffix}.html`,
popup: chrome.runtime.getURL(req.devtoolsEnabled ? `popups/enabled${suffix}.html` : `popups/disabled${suffix}.html`),
}, () => {
// noop
})
}

Expand Down
4 changes: 3 additions & 1 deletion packages/shell-chrome/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ const { createConfig } = require('@vue-devtools/build-tools')
module.exports = createConfig({
entry: {
hook: './src/hook.js',
'hook-exec': './src/hook-exec.js',
devtools: './src/devtools.js',
background: './src/background.js',
'service-worker': './src/service-worker.js',
'devtools-background': './src/devtools-background.js',
backend: './src/backend.js',
proxy: './src/proxy.js',
detector: './src/detector.js',
'detector-exec': './src/detector-exec.js',
},
output: {
path: path.join(__dirname, 'build'),
Expand Down

0 comments on commit faae234

Please sign in to comment.