-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathcore.js
108 lines (101 loc) · 2.95 KB
/
core.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
import { highlight } from './highlight.js';
import { send } from './runtime.js';
import { index as v4 } from './svelte-4.js';
import { serialize } from './utils.js';
// @ts-ignore - https://developer.chrome.com/docs/extensions/how-to/devtools/extend-devtools#selected-element
window['#SvelteDevTools'] = {
/**
* @param {string} id
* @param {string[]} keys
* @param {any} value
*/
inject(id, keys, value) {
const { detail: component } = v4.map.get(id) || {};
if (component) {
const [prop, ...rest] = keys;
const original = component.$capture_state()[prop];
if (typeof original === 'object') {
let ref = original;
for (let i = 0; i < rest.length - 1; i += 1) {
ref = ref[rest[i]];
}
ref[rest[rest.length - 1]] = value;
component.$inject_state({ [prop]: original });
} else {
component.$inject_state({ [prop]: value });
}
}
},
};
const previous = {
/** @type {HTMLElement | null} */
target: null,
style: {
cursor: '',
background: '',
outline: '',
},
clear() {
if (this.target) {
for (const key in this.style) {
// @ts-expect-error - trust me TS
this.target.style[key] = this.style[key];
}
}
this.target = null;
},
};
const inspect = {
/** @param {MouseEvent} event */
handle({ target }) {
const same = previous.target && previous.target === target;
const html = target instanceof HTMLElement;
if (same || !html) return;
if (previous.target) previous.clear();
previous.target = target;
previous.style = {
cursor: target.style.cursor,
background: target.style.background,
outline: target.style.outline,
};
target.style.cursor = 'pointer';
target.style.background = 'rgba(0, 136, 204, 0.2)';
target.style.outline = '1px dashed rgb(0, 136, 204)';
},
/** @param {MouseEvent} event */
click(event) {
event.preventDefault();
document.removeEventListener('mousemove', inspect.handle, true);
const node = v4.map.get(/** @type {Node} */ (event.target));
if (node) send('bridge::ext/inspect', { node: serialize(node) });
previous.clear();
},
};
window.addEventListener('message', ({ data, source }) => {
// only accept messages from our application or script
if (source !== window || data?.source !== 'svelte-devtools') return;
if (data.type === 'bridge::ext/select') {
const node = v4.map.get(data.payload);
// @ts-expect-error - saved for `devtools.inspect()`
if (node) window.$n = node.detail;
} else if (data.type === 'bridge::ext/highlight') {
const node = v4.map.get(data.payload);
return highlight(node);
} else if (data.type === 'bridge::ext/inspect') {
switch (data.payload) {
case 'start': {
document.addEventListener('mousemove', inspect.handle, true);
document.addEventListener('click', inspect.click, {
capture: true,
once: true,
});
break;
}
default: {
document.removeEventListener('mousemove', inspect.handle, true);
document.removeEventListener('click', inspect.click, true);
previous.clear();
}
}
}
});