-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
Copy pathdevtools-background.js
135 lines (113 loc) · 3.21 KB
/
devtools-background.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// This is the devtools script, which is called when the user opens the
// Chrome devtool on a page. We check to see if we global hook has detected
// Vue presence on the page. If yes, create the Vue panel; otherwise poll
// for 10 seconds.
let panelLoaded = false
let panelShown = false
let pendingAction
let created = false
let checkCount = 0
chrome.devtools.network.onNavigated.addListener(createPanelIfHasVue)
const checkVueInterval = setInterval(createPanelIfHasVue, 1000)
createPanelIfHasVue()
function createPanelIfHasVue () {
if (created || checkCount++ > 10) {
clearInterval(checkVueInterval)
return
}
panelLoaded = false
panelShown = false
chrome.devtools.inspectedWindow.eval(
'!!(window.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue)',
function (hasVue) {
if (!hasVue || created) {
return
}
clearInterval(checkVueInterval)
created = true
chrome.devtools.panels.create(
'Vue', 'icons/128.png', 'devtools.html',
panel => {
// panel loaded
panel.onShown.addListener(onPanelShown)
panel.onHidden.addListener(onPanelHidden)
}
)
}
)
}
// Runtime messages
chrome.runtime.onMessage.addListener(request => {
if (request === 'vue-panel-load') {
onPanelLoad()
} else if (request.vueToast) {
toast(request.vueToast)
} else if (request.vueContextMenu) {
onContextMenu(request.vueContextMenu)
}
})
// Page context menu entry
function onContextMenu ({ id }) {
if (id === 'vue-inspect-instance') {
const src = `window.__VUE_DEVTOOLS_CONTEXT_MENU_HAS_TARGET__`
chrome.devtools.inspectedWindow.eval(src, function (res, err) {
if (err) {
console.log(err)
}
if (typeof res !== 'undefined' && res) {
panelAction(() => {
chrome.runtime.sendMessage('vue-get-context-menu-target')
}, 'open-devtools')
} else {
pendingAction = null
toast('component-not-found')
}
})
}
}
// Action that may execute immediatly
// or later when the Vue panel is ready
function panelAction (cb, message = null) {
if (created && panelLoaded && panelShown) {
cb()
} else {
pendingAction = cb
message && toast(message)
}
}
function executePendingAction () {
pendingAction && pendingAction()
pendingAction = null
}
// Execute pending action when Vue panel is ready
function onPanelLoad () {
executePendingAction()
panelLoaded = true
}
// Manage panel visibility
function onPanelShown () {
chrome.runtime.sendMessage('vue-panel-shown')
panelShown = true
panelLoaded && executePendingAction()
}
function onPanelHidden () {
chrome.runtime.sendMessage('vue-panel-hidden')
panelShown = false
}
// Toasts
const toastMessages = {
'open-devtools': { message: 'Open Vue devtools to see component details', type: 'normal' },
'component-not-found': { message: 'No Vue component was found', type: 'warn' }
}
function toast (id) {
if (!Object.keys(toastMessages).includes(id)) return
const { message, type } = toastMessages[id]
const src = `(function() {
__VUE_DEVTOOLS_TOAST__(\`${message}\`, '${type}');
})()`
chrome.devtools.inspectedWindow.eval(src, function (res, err) {
if (err) {
console.log(err)
}
})
}