@sveltejs/vite-plugin-svelte 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +12 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +30 -0
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/ui/inspector/Inspector.svelte +135 -17
- package/src/ui/inspector/plugin.ts +2 -0
- package/src/utils/options.ts +44 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/vite-plugin-svelte",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "dominikg",
|
|
6
6
|
"files": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"deepmerge": "^4.2.2",
|
|
47
47
|
"kleur": "^4.1.5",
|
|
48
48
|
"magic-string": "^0.26.3",
|
|
49
|
-
"svelte-hmr": "^0.
|
|
49
|
+
"svelte-hmr": "^0.15.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"diff-match-patch": "^1.0.5",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// eslint-disable-next-line node/no-missing-import
|
|
5
5
|
import options from 'virtual:svelte-inspector-options';
|
|
6
6
|
const toggle_combo = options.toggleKeyCombo?.toLowerCase().split('-');
|
|
7
|
-
|
|
7
|
+
const nav_keys = Object.values(options.navKeys).map((k) => k.toLowerCase());
|
|
8
8
|
let enabled = false;
|
|
9
9
|
|
|
10
10
|
const icon = `data:image/svg+xml;base64,${btoa(
|
|
@@ -37,18 +37,67 @@
|
|
|
37
37
|
y = event.y;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (el
|
|
40
|
+
function find_selectable_parent(el) {
|
|
41
|
+
do {
|
|
42
|
+
el = el.parentNode;
|
|
43
|
+
if (is_selectable(el)) {
|
|
44
44
|
return el;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
} while (el);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function find_selectable_child(el) {
|
|
50
|
+
return [...el.querySelectorAll('*')].find(is_selectable);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function find_selectable_sibling(el, prev = false) {
|
|
54
|
+
do {
|
|
55
|
+
el = prev ? el.previousElementSibling : el.nextElementSibling;
|
|
56
|
+
if (is_selectable(el)) {
|
|
57
|
+
return el;
|
|
58
|
+
}
|
|
59
|
+
} while (el);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function find_selectable_for_nav(key) {
|
|
63
|
+
const el = active_el;
|
|
64
|
+
if (!el) {
|
|
65
|
+
return find_selectable_child(document?.body);
|
|
66
|
+
}
|
|
67
|
+
switch (key) {
|
|
68
|
+
case options.navKeys.parent:
|
|
69
|
+
return find_selectable_parent(el);
|
|
70
|
+
case options.navKeys.child:
|
|
71
|
+
return find_selectable_child(el);
|
|
72
|
+
case options.navKeys.next:
|
|
73
|
+
return find_selectable_sibling(el) || find_selectable_parent(el);
|
|
74
|
+
case options.navKeys.prev:
|
|
75
|
+
return find_selectable_sibling(el, true) || find_selectable_parent(el);
|
|
76
|
+
default:
|
|
77
|
+
return;
|
|
47
78
|
}
|
|
48
79
|
}
|
|
49
80
|
|
|
81
|
+
function is_selectable(el) {
|
|
82
|
+
if (el === toggle_el) {
|
|
83
|
+
return false; // toggle is our own
|
|
84
|
+
}
|
|
85
|
+
const file = el?.__svelte_meta?.loc?.file;
|
|
86
|
+
if (!file || file.includes('node_modules/')) {
|
|
87
|
+
return false; // no file or 3rd party
|
|
88
|
+
}
|
|
89
|
+
if (['svelte-announcer', 'svelte-inspector-announcer'].includes(el.getAttribute('id'))) {
|
|
90
|
+
return false; // ignore some elements by id that would be selectable from keyboard nav otherwise
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
50
95
|
function mouseover(event) {
|
|
51
|
-
const el =
|
|
96
|
+
const el = find_selectable_parent(event.target);
|
|
97
|
+
activate(el, false);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function activate(el, set_bubble_pos = true) {
|
|
52
101
|
if (options.customStyles && el !== active_el) {
|
|
53
102
|
if (active_el) {
|
|
54
103
|
active_el.classList.remove('svelte-inspector-active-target');
|
|
@@ -64,13 +113,16 @@
|
|
|
64
113
|
file_loc = null;
|
|
65
114
|
}
|
|
66
115
|
active_el = el;
|
|
116
|
+
if (set_bubble_pos) {
|
|
117
|
+
const pos = el.getBoundingClientRect();
|
|
118
|
+
x = Math.ceil(pos.left);
|
|
119
|
+
y = Math.ceil(pos.bottom - 20);
|
|
120
|
+
}
|
|
67
121
|
}
|
|
68
122
|
|
|
69
|
-
function
|
|
123
|
+
function open_editor(event) {
|
|
70
124
|
if (file_loc) {
|
|
71
|
-
event
|
|
72
|
-
event.stopPropagation();
|
|
73
|
-
event.stopImmediatePropagation();
|
|
125
|
+
stop(event);
|
|
74
126
|
fetch(`/__open-in-editor?file=${encodeURIComponent(file_loc)}`);
|
|
75
127
|
if (options.holdMode && is_holding()) {
|
|
76
128
|
disable();
|
|
@@ -94,10 +146,24 @@
|
|
|
94
146
|
return toggle_combo?.every((key) => is_key_active(key, event));
|
|
95
147
|
}
|
|
96
148
|
|
|
149
|
+
function is_nav(event) {
|
|
150
|
+
return nav_keys?.some((key) => is_key_active(key, event));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function is_open(event) {
|
|
154
|
+
return options.openKey && options.openKey.toLowerCase() === event.key.toLowerCase();
|
|
155
|
+
}
|
|
156
|
+
|
|
97
157
|
function is_holding() {
|
|
98
158
|
return enabled_ts && Date.now() - enabled_ts > 250;
|
|
99
159
|
}
|
|
100
160
|
|
|
161
|
+
function stop(event) {
|
|
162
|
+
event.preventDefault();
|
|
163
|
+
event.stopPropagation();
|
|
164
|
+
event.stopImmediatePropagation();
|
|
165
|
+
}
|
|
166
|
+
|
|
101
167
|
function keydown(event) {
|
|
102
168
|
if (event.repeat || event.key == null) {
|
|
103
169
|
return;
|
|
@@ -108,6 +174,14 @@
|
|
|
108
174
|
if (options.holdMode && enabled) {
|
|
109
175
|
enabled_ts = Date.now();
|
|
110
176
|
}
|
|
177
|
+
} else if (is_nav(event)) {
|
|
178
|
+
const el = find_selectable_for_nav(event.key);
|
|
179
|
+
if (el) {
|
|
180
|
+
activate(el);
|
|
181
|
+
stop(event);
|
|
182
|
+
}
|
|
183
|
+
} else if (is_open(event)) {
|
|
184
|
+
open_editor(event);
|
|
111
185
|
}
|
|
112
186
|
}
|
|
113
187
|
|
|
@@ -131,7 +205,7 @@
|
|
|
131
205
|
const l = enabled ? body.addEventListener : body.removeEventListener;
|
|
132
206
|
l('mousemove', mousemove);
|
|
133
207
|
l('mouseover', mouseover);
|
|
134
|
-
l('click',
|
|
208
|
+
l('click', open_editor, true);
|
|
135
209
|
}
|
|
136
210
|
|
|
137
211
|
function enable() {
|
|
@@ -141,6 +215,32 @@
|
|
|
141
215
|
b.classList.add('svelte-inspector-enabled');
|
|
142
216
|
}
|
|
143
217
|
listeners(b, enabled);
|
|
218
|
+
activate_initial_el();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function activate_initial_el() {
|
|
222
|
+
const hov = innermost_hover_el();
|
|
223
|
+
let el = is_selectable(hov) ? hov : find_selectable_parent(hov);
|
|
224
|
+
if (!el) {
|
|
225
|
+
const act = document.activeElement;
|
|
226
|
+
el = is_selectable(act) ? act : find_selectable_parent(act);
|
|
227
|
+
}
|
|
228
|
+
if (!el) {
|
|
229
|
+
el = find_selectable_child(document.body);
|
|
230
|
+
}
|
|
231
|
+
if (el) {
|
|
232
|
+
activate(el);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function innermost_hover_el() {
|
|
237
|
+
let e = document.body.querySelector(':hover');
|
|
238
|
+
let result;
|
|
239
|
+
while (e) {
|
|
240
|
+
result = e;
|
|
241
|
+
e = e.querySelector(':hover');
|
|
242
|
+
}
|
|
243
|
+
return result;
|
|
144
244
|
}
|
|
145
245
|
|
|
146
246
|
function disable() {
|
|
@@ -185,7 +285,7 @@
|
|
|
185
285
|
</script>
|
|
186
286
|
|
|
187
287
|
{#if show_toggle}
|
|
188
|
-
<
|
|
288
|
+
<button
|
|
189
289
|
class="svelte-inspector-toggle"
|
|
190
290
|
class:enabled
|
|
191
291
|
style={`background-image: var(--svelte-inspector-icon);${options.toggleButtonPos
|
|
@@ -194,16 +294,21 @@
|
|
|
194
294
|
.join('')}`}
|
|
195
295
|
on:click={() => toggle()}
|
|
196
296
|
bind:this={toggle_el}
|
|
297
|
+
aria-label={`${enabled ? 'disable' : 'enable'} svelte-inspector`}
|
|
197
298
|
/>
|
|
198
299
|
{/if}
|
|
199
|
-
{#if enabled && file_loc}
|
|
300
|
+
{#if enabled && active_el && file_loc}
|
|
301
|
+
{@const loc = active_el.__svelte_meta.loc}
|
|
200
302
|
<div
|
|
201
303
|
class="svelte-inspector-overlay"
|
|
202
|
-
style:left="{Math.min(x + 3, document.
|
|
203
|
-
style:top="{y + 30}px"
|
|
304
|
+
style:left="{Math.min(x + 3, document.documentElement.clientWidth - w - 10)}px"
|
|
305
|
+
style:top="{document.documentElement.clientHeight < y + 50 ? y - 30 : y + 30}px"
|
|
204
306
|
bind:offsetWidth={w}
|
|
205
307
|
>
|
|
206
|
-
{file_loc}
|
|
308
|
+
<{active_el.tagName.toLowerCase()}> {file_loc}
|
|
309
|
+
</div>
|
|
310
|
+
<div id="svelte-inspector-announcer" aria-live="assertive" aria-atomic="true">
|
|
311
|
+
{active_el.tagName.toLowerCase()} in file {loc.file} on line {loc.line} column {loc.column}
|
|
207
312
|
</div>
|
|
208
313
|
{/if}
|
|
209
314
|
|
|
@@ -225,6 +330,7 @@
|
|
|
225
330
|
}
|
|
226
331
|
|
|
227
332
|
.svelte-inspector-toggle {
|
|
333
|
+
all: unset;
|
|
228
334
|
border: 1px solid #ff3e00;
|
|
229
335
|
border-radius: 8px;
|
|
230
336
|
position: fixed;
|
|
@@ -236,6 +342,18 @@
|
|
|
236
342
|
cursor: pointer;
|
|
237
343
|
}
|
|
238
344
|
|
|
345
|
+
#svelte-inspector-announcer {
|
|
346
|
+
position: absolute;
|
|
347
|
+
left: 0px;
|
|
348
|
+
top: 0px;
|
|
349
|
+
clip: rect(0px, 0px, 0px, 0px);
|
|
350
|
+
clip-path: inset(50%);
|
|
351
|
+
overflow: hidden;
|
|
352
|
+
white-space: nowrap;
|
|
353
|
+
width: 1px;
|
|
354
|
+
height: 1px;
|
|
355
|
+
}
|
|
356
|
+
|
|
239
357
|
.svelte-inspector-toggle:not(.enabled) {
|
|
240
358
|
filter: grayscale(1);
|
|
241
359
|
}
|
|
@@ -8,6 +8,8 @@ import { idToFile } from './utils';
|
|
|
8
8
|
|
|
9
9
|
const defaultInspectorOptions: InspectorOptions = {
|
|
10
10
|
toggleKeyCombo: process.platform === 'win32' ? 'control-shift' : 'meta-shift',
|
|
11
|
+
navKeys: { parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' },
|
|
12
|
+
openKey: 'Enter',
|
|
11
13
|
holdMode: false,
|
|
12
14
|
showToggleButton: 'active',
|
|
13
15
|
toggleButtonPos: 'top-right',
|
package/src/utils/options.ts
CHANGED
|
@@ -170,7 +170,12 @@ export function resolveOptions(
|
|
|
170
170
|
viteConfig: ResolvedConfig
|
|
171
171
|
): ResolvedOptions {
|
|
172
172
|
const defaultOptions: Partial<Options> = {
|
|
173
|
-
hot: viteConfig.isProduction
|
|
173
|
+
hot: viteConfig.isProduction
|
|
174
|
+
? false
|
|
175
|
+
: {
|
|
176
|
+
injectCss: !preResolveOptions.emitCss,
|
|
177
|
+
partialAccept: !!viteConfig.experimental?.hmrPartialAccept
|
|
178
|
+
},
|
|
174
179
|
compilerOptions: {
|
|
175
180
|
css: !preResolveOptions.emitCss,
|
|
176
181
|
dev: !viteConfig.isProduction
|
|
@@ -331,6 +336,17 @@ export function buildExtraViteConfig(
|
|
|
331
336
|
// @ts-ignore
|
|
332
337
|
extraViteConfig.ssr = buildSSROptionsForSvelte(svelteDeps, options, config, extraViteConfig);
|
|
333
338
|
|
|
339
|
+
// enable hmrPartialAccept if not explicitly disabled
|
|
340
|
+
if (
|
|
341
|
+
(options.hot == null ||
|
|
342
|
+
options.hot === true ||
|
|
343
|
+
(options.hot && options.hot.partialAccept !== false)) && // deviate from svelte-hmr, default to true
|
|
344
|
+
config.experimental?.hmrPartialAccept !== false
|
|
345
|
+
) {
|
|
346
|
+
log.debug('enabling "experimental.hmrPartialAccept" in vite config');
|
|
347
|
+
extraViteConfig.experimental = { hmrPartialAccept: true };
|
|
348
|
+
}
|
|
349
|
+
|
|
334
350
|
return extraViteConfig;
|
|
335
351
|
}
|
|
336
352
|
|
|
@@ -500,7 +516,7 @@ export interface PluginOptions {
|
|
|
500
516
|
* @see https://github.com/rixo/svelte-hmr#options
|
|
501
517
|
* @default true for development, always false for production
|
|
502
518
|
*/
|
|
503
|
-
hot?: boolean | { injectCss?: boolean; [key: string]: any };
|
|
519
|
+
hot?: boolean | { injectCss?: boolean; partialAccept?: boolean; [key: string]: any };
|
|
504
520
|
|
|
505
521
|
/**
|
|
506
522
|
* Some Vite plugins can contribute additional preprocessors by defining `api.sveltePreprocess`.
|
|
@@ -643,6 +659,32 @@ export interface InspectorOptions {
|
|
|
643
659
|
*/
|
|
644
660
|
toggleKeyCombo?: string;
|
|
645
661
|
|
|
662
|
+
/**
|
|
663
|
+
* define keys to select elements with via keyboard
|
|
664
|
+
* @default {parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' }
|
|
665
|
+
*
|
|
666
|
+
* improves accessibility and also helps when you want to select elements that do not have a hoverable surface area
|
|
667
|
+
* due to tight wrapping
|
|
668
|
+
*
|
|
669
|
+
* A note for users of screen-readers:
|
|
670
|
+
* If you are using arrow keys to navigate the page itself, change the navKeys to avoid conflicts.
|
|
671
|
+
* e.g. navKeys: {parent: 'w', prev: 'a', child: 's', next: 'd'}
|
|
672
|
+
*
|
|
673
|
+
*
|
|
674
|
+
* parent: select closest parent
|
|
675
|
+
* child: select first child (or grandchild)
|
|
676
|
+
* next: next sibling (or parent if no next sibling exists)
|
|
677
|
+
* prev: previous sibling (or parent if no prev sibling exists)
|
|
678
|
+
*/
|
|
679
|
+
navKeys?: { parent: string; child: string; next: string; prev: string };
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* define key to open the editor for the currently selected dom node
|
|
683
|
+
*
|
|
684
|
+
* @default 'Enter'
|
|
685
|
+
*/
|
|
686
|
+
openKey?: string;
|
|
687
|
+
|
|
646
688
|
/**
|
|
647
689
|
* inspector is automatically disabled when releasing toggleKeyCombo after holding it for a longpress
|
|
648
690
|
* @default false
|