Skip to content

Commit 1ebb604

Browse files
authored
fix devtools class scope (#156)
1 parent 1dc37e9 commit 1ebb604

File tree

1 file changed

+135
-136
lines changed

1 file changed

+135
-136
lines changed

packages/shell-chrome/src/backend.js

Lines changed: 135 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -26,172 +26,171 @@ function serializeDataProperty(value) {
2626
}
2727
}
2828

29-
class AlpineDevtoolsBackend {
30-
constructor() {
31-
this.components = []
32-
this.uuid = 1
33-
this.hoverElement = null
34-
this.observer = null
35-
this._stopMutationObserver = false
36-
}
37-
38-
runWithMutationPaused(cb) {
39-
this._stopMutationObserver = true
40-
cb()
41-
setTimeout(() => {
29+
function init() {
30+
class AlpineDevtoolsBackend {
31+
constructor() {
32+
this.components = []
33+
this.uuid = 1
34+
this.hoverElement = null
35+
this.observer = null
4236
this._stopMutationObserver = false
43-
}, 10)
44-
}
37+
}
4538

46-
start() {
47-
this.getAlpineVersion()
48-
this.discoverComponents()
39+
runWithMutationPaused(cb) {
40+
this._stopMutationObserver = true
41+
cb()
42+
setTimeout(() => {
43+
this._stopMutationObserver = false
44+
}, 10)
45+
}
4946

50-
// Watch on the body for injected components. This is lightweight
51-
// as work is only done if there are components added/removed
52-
this.observeNode(document.querySelector('body'))
53-
}
47+
start() {
48+
this.getAlpineVersion()
49+
this.discoverComponents()
5450

55-
shutdown() {
56-
this.cleanupHoverElement()
57-
this.disconnectObserver()
58-
}
51+
// Watch on the body for injected components. This is lightweight
52+
// as work is only done if there are components added/removed
53+
this.observeNode(document.querySelector('body'))
54+
}
5955

60-
discoverComponents() {
61-
const rootEls = document.querySelectorAll('[x-data]')
62-
// Exit early if no components have been added or removed
63-
const allComponentsInitialized = Object.values(rootEls).every((e) => e.__alpineDevtool)
64-
if (this.components.length === rootEls.length && allComponentsInitialized) {
65-
return false
56+
shutdown() {
57+
this.cleanupHoverElement()
58+
this.disconnectObserver()
6659
}
6760

68-
this.components = []
61+
discoverComponents() {
62+
const rootEls = document.querySelectorAll('[x-data]')
63+
// Exit early if no components have been added or removed
64+
const allComponentsInitialized = Object.values(rootEls).every((e) => e.__alpineDevtool)
65+
if (this.components.length === rootEls.length && allComponentsInitialized) {
66+
return false
67+
}
6968

70-
rootEls.forEach((rootEl, index) => {
71-
Alpine.initializeComponent(rootEl)
69+
this.components = []
7270

73-
if (!rootEl.__alpineDevtool) {
74-
rootEl.__alpineDevtool = {}
75-
}
71+
rootEls.forEach((rootEl, index) => {
72+
Alpine.initializeComponent(rootEl)
7673

77-
if (!rootEl.__alpineDevtool.id) {
78-
rootEl.__alpineDevtool.id = this.uuid++
79-
window[`$x${rootEl.__alpineDevtool.id - 1}`] = rootEl.__x
80-
}
74+
if (!rootEl.__alpineDevtool) {
75+
rootEl.__alpineDevtool = {}
76+
}
8177

82-
let depth = 0
78+
if (!rootEl.__alpineDevtool.id) {
79+
rootEl.__alpineDevtool.id = this.uuid++
80+
window[`$x${rootEl.__alpineDevtool.id - 1}`] = rootEl.__x
81+
}
8382

84-
if (index != 0) {
85-
rootEls.forEach((innerElement, innerIndex) => {
86-
if (index == innerIndex) {
87-
return false
88-
}
83+
let depth = 0
8984

90-
if (innerElement.contains(rootEl)) {
91-
depth = depth + 1
92-
}
93-
})
94-
}
85+
if (index != 0) {
86+
rootEls.forEach((innerElement, innerIndex) => {
87+
if (index == innerIndex) {
88+
return false
89+
}
9590

96-
const data = Object.entries(rootEl.__x.getUnobservedData()).reduce((acc, [key, value]) => {
97-
acc[key] = serializeDataProperty(value)
91+
if (innerElement.contains(rootEl)) {
92+
depth = depth + 1
93+
}
94+
})
95+
}
9896

99-
return acc
100-
}, {})
97+
const data = Object.entries(rootEl.__x.getUnobservedData()).reduce((acc, [key, value]) => {
98+
acc[key] = serializeDataProperty(value)
10199

102-
this.components.push({
103-
name: getComponentName(rootEl),
104-
depth: depth,
105-
data: data,
106-
index: index,
107-
id: rootEl.__alpineDevtool.id,
100+
return acc
101+
}, {})
102+
103+
this.components.push({
104+
name: getComponentName(rootEl),
105+
depth: depth,
106+
data: data,
107+
index: index,
108+
id: rootEl.__alpineDevtool.id,
109+
})
108110
})
109-
})
110-
111-
window.postMessage(
112-
{
113-
source: 'alpine-devtools-backend',
114-
payload: {
115-
// stringify to unfurl proxies
116-
// there's no way to detect proxies but
117-
// we need to get rid of them
118-
// this avoids `DataCloneError: The object could not be cloned.`
119-
// see https://github.com/Te7a-Houdini/alpinejs-devtools/issues/17
120-
components: JSON.stringify(this.components),
121-
type: 'render-components',
122-
},
123-
},
124-
'*',
125-
)
126-
}
127111

128-
getAlpineVersion() {
129-
window.postMessage(
130-
{
131-
source: 'alpine-devtools-backend',
132-
payload: {
133-
version: window.Alpine.version,
134-
type: 'set-version',
112+
window.postMessage(
113+
{
114+
source: 'alpine-devtools-backend',
115+
payload: {
116+
// stringify to unfurl proxies
117+
// there's no way to detect proxies but
118+
// we need to get rid of them
119+
// this avoids `DataCloneError: The object could not be cloned.`
120+
// see https://github.com/Te7a-Houdini/alpinejs-devtools/issues/17
121+
components: JSON.stringify(this.components),
122+
type: 'render-components',
123+
},
135124
},
136-
},
137-
'*',
138-
)
139-
}
125+
'*',
126+
)
127+
}
140128

141-
observeNode(node) {
142-
const observerOptions = {
143-
childList: true,
144-
attributes: true,
145-
subtree: true,
129+
getAlpineVersion() {
130+
window.postMessage(
131+
{
132+
source: 'alpine-devtools-backend',
133+
payload: {
134+
version: window.Alpine.version,
135+
type: 'set-version',
136+
},
137+
},
138+
'*',
139+
)
146140
}
147141

148-
this.observer = new MutationObserver((_mutations) => {
149-
if (!this._stopMutationObserver) {
150-
this.discoverComponents()
142+
observeNode(node) {
143+
const observerOptions = {
144+
childList: true,
145+
attributes: true,
146+
subtree: true,
151147
}
152-
})
153148

154-
this.observer.observe(node, observerOptions)
155-
}
149+
this.observer = new MutationObserver((_mutations) => {
150+
if (!this._stopMutationObserver) {
151+
this.discoverComponents()
152+
}
153+
})
156154

157-
disconnectObserver() {
158-
if (this.observer) {
159-
this.observer.disconnect()
160-
this.observer = null
155+
this.observer.observe(node, observerOptions)
161156
}
162-
}
163157

164-
addHoverElement(target) {
165-
this.cleanupHoverElement()
166-
167-
let hoverElement = document.createElement('div')
168-
let bounds = target.getBoundingClientRect()
169-
170-
Object.assign(hoverElement.style, {
171-
position: 'absolute',
172-
top: `${bounds.top}px`,
173-
left: `${bounds.left}px`,
174-
width: `${bounds.width}px`,
175-
height: `${bounds.height}px`,
176-
backgroundColor: 'rgba(104, 182, 255, 0.35)',
177-
borderRadius: '4px',
178-
zIndex: 9999,
179-
})
180-
hoverElement.dataset.testid = 'hover-element'
181-
182-
this.hoverElement = hoverElement
183-
document.body.appendChild(this.hoverElement)
184-
}
158+
disconnectObserver() {
159+
if (this.observer) {
160+
this.observer.disconnect()
161+
this.observer = null
162+
}
163+
}
185164

186-
cleanupHoverElement() {
187-
if (this.hoverElement) {
188-
this.hoverElement.remove()
189-
this.hoverElement = null
165+
addHoverElement(target) {
166+
this.cleanupHoverElement()
167+
168+
let hoverElement = document.createElement('div')
169+
let bounds = target.getBoundingClientRect()
170+
171+
Object.assign(hoverElement.style, {
172+
position: 'absolute',
173+
top: `${bounds.top}px`,
174+
left: `${bounds.left}px`,
175+
width: `${bounds.width}px`,
176+
height: `${bounds.height}px`,
177+
backgroundColor: 'rgba(104, 182, 255, 0.35)',
178+
borderRadius: '4px',
179+
zIndex: 9999,
180+
})
181+
hoverElement.dataset.testid = 'hover-element'
182+
183+
this.hoverElement = hoverElement
184+
document.body.appendChild(this.hoverElement)
190185
}
191-
}
192-
}
193186

194-
function init() {
187+
cleanupHoverElement() {
188+
if (this.hoverElement) {
189+
this.hoverElement.remove()
190+
this.hoverElement = null
191+
}
192+
}
193+
}
195194
// using a function scope to avoid running into issues on re-injection
196195
const devtoolsBackend = new AlpineDevtoolsBackend()
197196
window.addEventListener('message', handshake)

0 commit comments

Comments
 (0)