@sveltejs/vite-plugin-svelte 1.0.5 → 1.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/vite-plugin-svelte",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
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.14.12"
49
+ "svelte-hmr": "^0.15.0"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "diff-match-patch": "^1.0.5",
@@ -62,11 +62,11 @@
62
62
  "@types/debug": "^4.1.7",
63
63
  "@types/diff-match-patch": "^1.0.32",
64
64
  "diff-match-patch": "^1.0.5",
65
- "esbuild": "^0.15.7",
65
+ "esbuild": "^0.15.8",
66
66
  "rollup": "^2.79.0",
67
- "svelte": "^3.50.0",
67
+ "svelte": "^3.50.1",
68
68
  "tsup": "^6.2.3",
69
- "vite": "^3.1.0"
69
+ "vite": "^3.1.2"
70
70
  },
71
71
  "scripts": {
72
72
  "dev": "pnpm build:ci --sourcemap --watch src",
@@ -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(
@@ -25,7 +25,6 @@
25
25
  let x, y, w;
26
26
 
27
27
  let active_el;
28
- let toggle_el;
29
28
 
30
29
  let enabled_ts;
31
30
 
@@ -37,18 +36,65 @@
37
36
  y = event.y;
38
37
  }
39
38
 
40
- function findMetaEl(el) {
41
- while (el) {
42
- const file = el.__svelte_meta?.loc?.file;
43
- if (el !== toggle_el && file && !file.includes('node_modules/')) {
39
+ function find_selectable_parent(el) {
40
+ do {
41
+ el = el.parentNode;
42
+ if (is_selectable(el)) {
44
43
  return el;
45
44
  }
46
- el = el.parentNode;
45
+ } while (el);
46
+ }
47
+
48
+ function find_selectable_child(el) {
49
+ return [...el.querySelectorAll('*')].find(is_selectable);
50
+ }
51
+
52
+ function find_selectable_sibling(el, prev = false) {
53
+ do {
54
+ el = prev ? el.previousElementSibling : el.nextElementSibling;
55
+ if (is_selectable(el)) {
56
+ return el;
57
+ }
58
+ } while (el);
59
+ }
60
+
61
+ function find_selectable_for_nav(key) {
62
+ const el = active_el;
63
+ if (!el) {
64
+ return find_selectable_child(document?.body);
47
65
  }
66
+ switch (key) {
67
+ case options.navKeys.parent:
68
+ return find_selectable_parent(el);
69
+ case options.navKeys.child:
70
+ return find_selectable_child(el);
71
+ case options.navKeys.next:
72
+ return find_selectable_sibling(el) || find_selectable_parent(el);
73
+ case options.navKeys.prev:
74
+ return find_selectable_sibling(el, true) || find_selectable_parent(el);
75
+ default:
76
+ return;
77
+ }
78
+ }
79
+
80
+ function is_selectable(el) {
81
+ const file = el?.__svelte_meta?.loc?.file;
82
+ if (!file || file.includes('node_modules/')) {
83
+ return false; // no file or 3rd party
84
+ }
85
+ const id = el.getAttribute('id');
86
+ if (id === 'svelte-announcer' || id?.startsWith('svelte-inspector-')) {
87
+ return false; // ignore some elements by id that would be selectable from keyboard nav otherwise
88
+ }
89
+ return true;
48
90
  }
49
91
 
50
92
  function mouseover(event) {
51
- const el = findMetaEl(event.target);
93
+ const el = find_selectable_parent(event.target);
94
+ activate(el, false);
95
+ }
96
+
97
+ function activate(el, set_bubble_pos = true) {
52
98
  if (options.customStyles && el !== active_el) {
53
99
  if (active_el) {
54
100
  active_el.classList.remove('svelte-inspector-active-target');
@@ -64,13 +110,16 @@
64
110
  file_loc = null;
65
111
  }
66
112
  active_el = el;
113
+ if (set_bubble_pos) {
114
+ const pos = el.getBoundingClientRect();
115
+ x = Math.ceil(pos.left);
116
+ y = Math.ceil(pos.bottom - 20);
117
+ }
67
118
  }
68
119
 
69
- function click(event) {
120
+ function open_editor(event) {
70
121
  if (file_loc) {
71
- event.preventDefault();
72
- event.stopPropagation();
73
- event.stopImmediatePropagation();
122
+ stop(event);
74
123
  fetch(`/__open-in-editor?file=${encodeURIComponent(file_loc)}`);
75
124
  if (options.holdMode && is_holding()) {
76
125
  disable();
@@ -94,10 +143,24 @@
94
143
  return toggle_combo?.every((key) => is_key_active(key, event));
95
144
  }
96
145
 
146
+ function is_nav(event) {
147
+ return nav_keys?.some((key) => is_key_active(key, event));
148
+ }
149
+
150
+ function is_open(event) {
151
+ return options.openKey && options.openKey.toLowerCase() === event.key.toLowerCase();
152
+ }
153
+
97
154
  function is_holding() {
98
155
  return enabled_ts && Date.now() - enabled_ts > 250;
99
156
  }
100
157
 
158
+ function stop(event) {
159
+ event.preventDefault();
160
+ event.stopPropagation();
161
+ event.stopImmediatePropagation();
162
+ }
163
+
101
164
  function keydown(event) {
102
165
  if (event.repeat || event.key == null) {
103
166
  return;
@@ -108,6 +171,14 @@
108
171
  if (options.holdMode && enabled) {
109
172
  enabled_ts = Date.now();
110
173
  }
174
+ } else if (is_nav(event)) {
175
+ const el = find_selectable_for_nav(event.key);
176
+ if (el) {
177
+ activate(el);
178
+ stop(event);
179
+ }
180
+ } else if (is_open(event)) {
181
+ open_editor(event);
111
182
  }
112
183
  }
113
184
 
@@ -131,7 +202,7 @@
131
202
  const l = enabled ? body.addEventListener : body.removeEventListener;
132
203
  l('mousemove', mousemove);
133
204
  l('mouseover', mouseover);
134
- l('click', click, true);
205
+ l('click', open_editor, true);
135
206
  }
136
207
 
137
208
  function enable() {
@@ -141,6 +212,32 @@
141
212
  b.classList.add('svelte-inspector-enabled');
142
213
  }
143
214
  listeners(b, enabled);
215
+ activate_initial_el();
216
+ }
217
+
218
+ function activate_initial_el() {
219
+ const hov = innermost_hover_el();
220
+ let el = is_selectable(hov) ? hov : find_selectable_parent(hov);
221
+ if (!el) {
222
+ const act = document.activeElement;
223
+ el = is_selectable(act) ? act : find_selectable_parent(act);
224
+ }
225
+ if (!el) {
226
+ el = find_selectable_child(document.body);
227
+ }
228
+ if (el) {
229
+ activate(el);
230
+ }
231
+ }
232
+
233
+ function innermost_hover_el() {
234
+ let e = document.body.querySelector(':hover');
235
+ let result;
236
+ while (e) {
237
+ result = e;
238
+ e = e.querySelector(':hover');
239
+ }
240
+ return result;
144
241
  }
145
242
 
146
243
  function disable() {
@@ -185,25 +282,29 @@
185
282
  </script>
186
283
 
187
284
  {#if show_toggle}
188
- <div
189
- class="svelte-inspector-toggle"
285
+ <button
286
+ id="svelte-inspector-toggle"
190
287
  class:enabled
191
288
  style={`background-image: var(--svelte-inspector-icon);${options.toggleButtonPos
192
289
  .split('-')
193
290
  .map((p) => `${p}: 8px;`)
194
291
  .join('')}`}
195
292
  on:click={() => toggle()}
196
- bind:this={toggle_el}
293
+ aria-label={`${enabled ? 'disable' : 'enable'} svelte-inspector`}
197
294
  />
198
295
  {/if}
199
- {#if enabled && file_loc}
296
+ {#if enabled && active_el && file_loc}
297
+ {@const loc = active_el.__svelte_meta.loc}
200
298
  <div
201
- class="svelte-inspector-overlay"
202
- style:left="{Math.min(x + 3, document.body.clientWidth - w - 10)}px"
203
- style:top="{y + 30}px"
299
+ id="svelte-inspector-overlay"
300
+ style:left="{Math.min(x + 3, document.documentElement.clientWidth - w - 10)}px"
301
+ style:top="{document.documentElement.clientHeight < y + 50 ? y - 30 : y + 30}px"
204
302
  bind:offsetWidth={w}
205
303
  >
206
- {file_loc}
304
+ &lt;{active_el.tagName.toLowerCase()}&gt;&nbsp;{file_loc}
305
+ </div>
306
+ <div id="svelte-inspector-announcer" aria-live="assertive" aria-atomic="true">
307
+ {active_el.tagName.toLowerCase()} in file {loc.file} on line {loc.line} column {loc.column}
207
308
  </div>
208
309
  {/if}
209
310
 
@@ -215,16 +316,18 @@
215
316
  outline: 2px dashed #ff3e00 !important;
216
317
  }
217
318
 
218
- .svelte-inspector-overlay {
319
+ #svelte-inspector-overlay {
219
320
  position: fixed;
220
321
  background-color: rgba(0, 0, 0, 0.8);
221
322
  color: #fff;
222
323
  padding: 2px 4px;
223
324
  border-radius: 5px;
224
325
  z-index: 999999;
326
+ pointer-events: none;
225
327
  }
226
328
 
227
- .svelte-inspector-toggle {
329
+ #svelte-inspector-toggle {
330
+ all: unset;
228
331
  border: 1px solid #ff3e00;
229
332
  border-radius: 8px;
230
333
  position: fixed;
@@ -236,10 +339,22 @@
236
339
  cursor: pointer;
237
340
  }
238
341
 
239
- .svelte-inspector-toggle:not(.enabled) {
342
+ #svelte-inspector-announcer {
343
+ position: absolute;
344
+ left: 0px;
345
+ top: 0px;
346
+ clip: rect(0px, 0px, 0px, 0px);
347
+ clip-path: inset(50%);
348
+ overflow: hidden;
349
+ white-space: nowrap;
350
+ width: 1px;
351
+ height: 1px;
352
+ }
353
+
354
+ #svelte-inspector-toggle:not(.enabled) {
240
355
  filter: grayscale(1);
241
356
  }
242
- .svelte-inspector-toggle:hover {
357
+ #svelte-inspector-toggle:hover {
243
358
  background-color: #facece;
244
359
  }
245
360
  </style>
@@ -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',
@@ -170,7 +170,12 @@ export function resolveOptions(
170
170
  viteConfig: ResolvedConfig
171
171
  ): ResolvedOptions {
172
172
  const defaultOptions: Partial<Options> = {
173
- hot: viteConfig.isProduction ? false : { injectCss: !preResolveOptions.emitCss },
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