@sveltejs/vite-plugin-svelte 1.0.4 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/vite-plugin-svelte",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "license": "MIT",
5
5
  "author": "dominikg",
6
6
  "files": [
@@ -45,13 +45,13 @@
45
45
  "debug": "^4.3.4",
46
46
  "deepmerge": "^4.2.2",
47
47
  "kleur": "^4.1.5",
48
- "magic-string": "^0.26.2",
49
- "svelte-hmr": "^0.14.12"
48
+ "magic-string": "^0.26.3",
49
+ "svelte-hmr": "^0.15.0"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "diff-match-patch": "^1.0.5",
53
53
  "svelte": "^3.44.0",
54
- "vite": "^3.0.0 || ^3.1.0-beta.1"
54
+ "vite": "^3.0.0"
55
55
  },
56
56
  "peerDependenciesMeta": {
57
57
  "diff-match-patch": {
@@ -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.5",
66
- "rollup": "^2.78.1",
67
- "svelte": "^3.49.0",
65
+ "esbuild": "^0.15.7",
66
+ "rollup": "^2.79.0",
67
+ "svelte": "^3.50.0",
68
68
  "tsup": "^6.2.3",
69
- "vite": "^3.1.0-beta.1"
69
+ "vite": "^3.1.0"
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(
@@ -37,18 +37,67 @@
37
37
  y = event.y;
38
38
  }
39
39
 
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/')) {
40
+ function find_selectable_parent(el) {
41
+ do {
42
+ el = el.parentNode;
43
+ if (is_selectable(el)) {
44
44
  return el;
45
45
  }
46
- el = el.parentNode;
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 = findMetaEl(event.target);
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 click(event) {
123
+ function open_editor(event) {
70
124
  if (file_loc) {
71
- event.preventDefault();
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', click, true);
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
- <div
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.body.clientWidth - w - 10)}px"
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
+ &lt;{active_el.tagName.toLowerCase()}&gt;&nbsp;{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',
@@ -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