@sveltejs/vite-plugin-svelte 6.2.4 → 7.0.0-next.1
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 +5 -7
- package/src/index.js +2 -2
- package/src/plugins/configure.js +0 -15
- package/src/plugins/inspector/index.js +123 -0
- package/src/plugins/inspector/options.js +65 -0
- package/src/plugins/inspector/runtime/Inspector.svelte +411 -0
- package/src/plugins/inspector/runtime/load-inspector.js +14 -0
- package/src/plugins/setup-optimizer.js +16 -87
- package/src/preprocess.js +1 -34
- package/src/public.d.ts +78 -24
- package/src/types/plugin-api.d.ts +0 -5
- package/src/utils/compile.js +0 -3
- package/src/utils/constants.js +3 -2
- package/src/utils/options.js +51 -23
- package/types/index.d.ts +76 -24
- package/types/index.d.ts.map +2 -1
- package/src/utils/hash.js +0 -43
- package/src/utils/preprocess.js +0 -89
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/vite-plugin-svelte",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0-next.1",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"author": "dominikg",
|
|
6
5
|
"files": [
|
|
7
6
|
"src",
|
|
8
7
|
"types"
|
|
@@ -34,21 +33,20 @@
|
|
|
34
33
|
},
|
|
35
34
|
"homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme",
|
|
36
35
|
"dependencies": {
|
|
37
|
-
"@sveltejs/vite-plugin-svelte-inspector": "^5.0.0",
|
|
38
36
|
"deepmerge": "^4.3.1",
|
|
39
37
|
"magic-string": "^0.30.21",
|
|
40
38
|
"obug": "^2.1.0",
|
|
41
|
-
"vitefu": "^1.1.
|
|
39
|
+
"vitefu": "^1.1.2"
|
|
42
40
|
},
|
|
43
41
|
"peerDependencies": {
|
|
44
|
-
"svelte": "^5.
|
|
45
|
-
"vite": "^
|
|
42
|
+
"svelte": "^5.46.4",
|
|
43
|
+
"vite": "^8.0.0-beta.7 || ^8.0.0"
|
|
46
44
|
},
|
|
47
45
|
"devDependencies": {
|
|
48
46
|
"@types/debug": "^4.1.12",
|
|
49
47
|
"sass": "^1.94.2",
|
|
50
48
|
"svelte": "^5.45.4",
|
|
51
|
-
"vite": "^
|
|
49
|
+
"vite": "^8.0.0-beta.7"
|
|
52
50
|
},
|
|
53
51
|
"scripts": {
|
|
54
52
|
"check:publint": "publint --strict",
|
package/src/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { compile } from './plugins/compile.js';
|
|
|
6
6
|
import { loadCompiledCss } from './plugins/load-compiled-css.js';
|
|
7
7
|
import { setupOptimizer } from './plugins/setup-optimizer.js';
|
|
8
8
|
import { compileModule } from './plugins/compile-module.js';
|
|
9
|
-
import { svelteInspector } from '
|
|
9
|
+
import { svelteInspector } from './plugins/inspector/index.js';
|
|
10
10
|
import { loadCustom } from './plugins/load-custom.js';
|
|
11
11
|
import { hotUpdate } from './plugins/hot-update.js';
|
|
12
12
|
|
|
@@ -34,7 +34,7 @@ export function svelte(inlineOptions) {
|
|
|
34
34
|
compile(api),
|
|
35
35
|
compileModule(api),
|
|
36
36
|
hotUpdate(api),
|
|
37
|
-
svelteInspector()
|
|
37
|
+
svelteInspector(api)
|
|
38
38
|
];
|
|
39
39
|
}
|
|
40
40
|
|
package/src/plugins/configure.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
import { isDebugNamespaceEnabled, log } from '../utils/log.js';
|
|
3
|
-
import * as vite from 'vite';
|
|
4
3
|
import { VitePluginSvelteStats } from '../utils/vite-plugin-svelte-stats.js';
|
|
5
4
|
import {
|
|
6
5
|
buildExtraViteConfig,
|
|
@@ -13,25 +12,12 @@ import {
|
|
|
13
12
|
import { buildIdFilter, buildIdParser } from '../utils/id.js';
|
|
14
13
|
import { createCompileSvelte } from '../utils/compile.js';
|
|
15
14
|
|
|
16
|
-
// @ts-ignore rolldownVersion
|
|
17
|
-
const { version: viteVersion, rolldownVersion } = vite;
|
|
18
|
-
|
|
19
15
|
/**
|
|
20
16
|
* @param {Partial<import('../public.d.ts').Options>} [inlineOptions]
|
|
21
17
|
* @param {import('../types/plugin-api.d.ts').PluginAPI} api
|
|
22
18
|
* @returns {import('vite').Plugin}
|
|
23
19
|
*/
|
|
24
20
|
export function configure(api, inlineOptions) {
|
|
25
|
-
if (rolldownVersion) {
|
|
26
|
-
log.warn.once(
|
|
27
|
-
`!!! Support for vite 8 beta in vite-plugin-svelte is experimental (rolldown: ${rolldownVersion}, vite: ${viteVersion}) !!!
|
|
28
|
-
See https://github.com/sveltejs/vite-plugin-svelte/issues/1143 for a list of known issues and to report feedback.`.replace(
|
|
29
|
-
/\t+/g,
|
|
30
|
-
'\t'
|
|
31
|
-
)
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
21
|
validateInlineOptions(inlineOptions);
|
|
36
22
|
|
|
37
23
|
/**
|
|
@@ -72,7 +58,6 @@ export function configure(api, inlineOptions) {
|
|
|
72
58
|
}
|
|
73
59
|
|
|
74
60
|
api.filter = buildIdFilter(options);
|
|
75
|
-
api.idFilter = api.filter;
|
|
76
61
|
api.idParser = buildIdParser(options);
|
|
77
62
|
api.compileSvelte = createCompileSvelte();
|
|
78
63
|
log.debug('resolved options', api.options, 'config');
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { normalizePath } from 'vite';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { defaultInspectorOptions, parseEnvironmentOptions } from './options.js';
|
|
6
|
+
import { log } from '../../utils/log.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {string} url
|
|
10
|
+
* @returns {string} url without query params or hash
|
|
11
|
+
*/
|
|
12
|
+
function cleanUrl(url) {
|
|
13
|
+
return url.replace(/[?#].*$/s, '');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getInspectorPath() {
|
|
17
|
+
const pluginPath = normalizePath(path.dirname(fileURLToPath(import.meta.url)));
|
|
18
|
+
return pluginPath.replace(
|
|
19
|
+
/\/vite-plugin-svelte\/src\/plugins\/inspector$/,
|
|
20
|
+
'/vite-plugin-svelte/src/plugins/inspector/runtime/'
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {import('../../types/plugin-api.d.ts').PluginAPI} api
|
|
26
|
+
* @returns {import('vite').Plugin}
|
|
27
|
+
*/
|
|
28
|
+
export function svelteInspector(api) {
|
|
29
|
+
const inspectorPath = getInspectorPath();
|
|
30
|
+
log.debug(`svelte inspector path: ${inspectorPath}`, null, 'inspector');
|
|
31
|
+
|
|
32
|
+
/** @type {import('../../public.d.ts').InspectorOptions} */
|
|
33
|
+
let inspectorOptions;
|
|
34
|
+
let disabled = false;
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
name: 'vite-plugin-svelte-inspector',
|
|
38
|
+
apply: 'serve',
|
|
39
|
+
enforce: 'pre',
|
|
40
|
+
|
|
41
|
+
applyToEnvironment(env) {
|
|
42
|
+
return !disabled && env.config.consumer === 'client';
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
configResolved(config) {
|
|
46
|
+
const environmentOptions = parseEnvironmentOptions(config);
|
|
47
|
+
if (environmentOptions === false) {
|
|
48
|
+
log.debug('environment options set to false, inspector disabled', null, 'inspector');
|
|
49
|
+
disabled = true;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const configFileOptions = api.options?.inspector;
|
|
53
|
+
|
|
54
|
+
if (!configFileOptions && !environmentOptions) {
|
|
55
|
+
log.debug('no inspector options found, inspector disabled', null, 'inspector');
|
|
56
|
+
disabled = true;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (environmentOptions === true) {
|
|
61
|
+
inspectorOptions = defaultInspectorOptions;
|
|
62
|
+
} else {
|
|
63
|
+
inspectorOptions = {
|
|
64
|
+
...defaultInspectorOptions,
|
|
65
|
+
...(typeof configFileOptions === 'object' ? configFileOptions : {}),
|
|
66
|
+
...(environmentOptions || {})
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
inspectorOptions.__internal = {
|
|
71
|
+
base: config.base?.replace(/\/$/, '') || ''
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
resolveId: {
|
|
75
|
+
filter: {
|
|
76
|
+
id: /^virtual:svelte-inspector-/
|
|
77
|
+
},
|
|
78
|
+
async handler(id) {
|
|
79
|
+
if (disabled) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (id === 'virtual:svelte-inspector-options') {
|
|
83
|
+
return id;
|
|
84
|
+
} else if (id.startsWith('virtual:svelte-inspector-path:') && !id.includes('..')) {
|
|
85
|
+
return id.replace('virtual:svelte-inspector-path:', inspectorPath);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
load: {
|
|
90
|
+
filter: {
|
|
91
|
+
id: {
|
|
92
|
+
include: [`${inspectorPath}/**`, /^virtual:svelte-inspector-options$/],
|
|
93
|
+
exclude: [/style&lang\.css$/]
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
async handler(id) {
|
|
97
|
+
if (disabled) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (id === 'virtual:svelte-inspector-options') {
|
|
101
|
+
return `export default ${JSON.stringify(inspectorOptions ?? {})}`;
|
|
102
|
+
} else if (id.startsWith(inspectorPath)) {
|
|
103
|
+
// read file ourselves to avoid getting shut out by vites fs.allow check
|
|
104
|
+
const file = cleanUrl(id);
|
|
105
|
+
if (fs.existsSync(file)) {
|
|
106
|
+
return await fs.promises.readFile(file, 'utf-8');
|
|
107
|
+
} else {
|
|
108
|
+
log.error(`failed to find svelte-inspector: ${id}`, null, 'inspector');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
transform: {
|
|
114
|
+
filter: { id: /vite\/dist\/client\/client\.mjs(?:\?|$)/ },
|
|
115
|
+
handler(code) {
|
|
116
|
+
if (disabled) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
return { code: `${code}\nimport('virtual:svelte-inspector-path:load-inspector.js')` };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import { loadEnv } from 'vite';
|
|
3
|
+
import { log } from '../../utils/log.js';
|
|
4
|
+
|
|
5
|
+
/** @type {import('../../public.d.ts').InspectorOptions} */
|
|
6
|
+
export const defaultInspectorOptions = {
|
|
7
|
+
toggleKeyCombo: 'alt-x',
|
|
8
|
+
navKeys: { parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' },
|
|
9
|
+
escapeKeys: ['Backspace', 'Escape'],
|
|
10
|
+
openKey: 'Enter',
|
|
11
|
+
holdMode: true,
|
|
12
|
+
showToggleButton: 'active',
|
|
13
|
+
toggleButtonPos: 'top-right',
|
|
14
|
+
customStyles: true
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {import('vite').ResolvedConfig} config
|
|
19
|
+
* @returns {Partial<import('../../public.d.ts').InspectorOptions> | boolean | void}
|
|
20
|
+
*/
|
|
21
|
+
export function parseEnvironmentOptions(config) {
|
|
22
|
+
const env = loadEnv(config.mode, config.envDir ?? process.cwd(), 'SVELTE_INSPECTOR');
|
|
23
|
+
const options = env?.SVELTE_INSPECTOR_OPTIONS;
|
|
24
|
+
const toggle = env?.SVELTE_INSPECTOR_TOGGLE;
|
|
25
|
+
if (options) {
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(options);
|
|
28
|
+
const parsedType = typeof parsed;
|
|
29
|
+
if (parsedType === 'boolean') {
|
|
30
|
+
return parsed;
|
|
31
|
+
} else if (parsedType === 'object') {
|
|
32
|
+
if (Array.isArray(parsed)) {
|
|
33
|
+
throw new Error('invalid type, expected object map but got array');
|
|
34
|
+
}
|
|
35
|
+
const parsedKeys = Object.keys(parsed);
|
|
36
|
+
const defaultKeys = Object.keys(defaultInspectorOptions);
|
|
37
|
+
const unknownKeys = parsedKeys.filter((k) => !defaultKeys.includes(k));
|
|
38
|
+
if (unknownKeys.length) {
|
|
39
|
+
log.warn(
|
|
40
|
+
`[vite-plugin-svelte-inspector] ignoring unknown options in environment SVELTE_INSPECTOR_OPTIONS: ${unknownKeys.join(
|
|
41
|
+
', '
|
|
42
|
+
)}`,
|
|
43
|
+
null,
|
|
44
|
+
'inspector'
|
|
45
|
+
);
|
|
46
|
+
for (const key of unknownKeys) {
|
|
47
|
+
delete parsed[key];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
log.debug('loaded environment config', parsed, 'inspector');
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {
|
|
54
|
+
config.logger.error(
|
|
55
|
+
`[vite-plugin-svelte-inspector] failed to parse inspector options from environment SVELTE_INSPECTOR_OPTIONS="${options}"\n${e}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
} else if (toggle) {
|
|
59
|
+
const keyConfig = {
|
|
60
|
+
toggleKeyCombo: toggle
|
|
61
|
+
};
|
|
62
|
+
log.debug('loaded environment config', keyConfig, 'inspector');
|
|
63
|
+
return keyConfig;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
<svelte:options runes={true} />
|
|
2
|
+
|
|
3
|
+
<script>
|
|
4
|
+
// do not use TS here so that this component works in non-ts projects too
|
|
5
|
+
import { onMount } from 'svelte';
|
|
6
|
+
|
|
7
|
+
import options from 'virtual:svelte-inspector-options';
|
|
8
|
+
const toggle_combo = options.toggleKeyCombo?.toLowerCase().split('-');
|
|
9
|
+
const escape_keys = options.escapeKeys?.map((k) => k.toLowerCase());
|
|
10
|
+
const nav_keys = Object.values(options.navKeys).map((k) => k?.toLowerCase());
|
|
11
|
+
const open_key = options.openKey?.toLowerCase();
|
|
12
|
+
|
|
13
|
+
let enabled = $state(false);
|
|
14
|
+
let has_opened = $state(false);
|
|
15
|
+
|
|
16
|
+
const icon = `data:image/svg+xml;base64,${btoa(
|
|
17
|
+
`
|
|
18
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="25" viewBox="0 0 107 128">
|
|
19
|
+
<title>svelte-inspector-logo</title>
|
|
20
|
+
<path d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" style="fill:#ff3e00"/><path d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287" style="fill:#fff"/>
|
|
21
|
+
<polygon points="0,0 15,40 40,20" stroke="#ff3e00" fill="#ff3e00"></polygon>
|
|
22
|
+
</svg>
|
|
23
|
+
`
|
|
24
|
+
.replace(/[\n\r\t\s]+/g, ' ')
|
|
25
|
+
.trim()
|
|
26
|
+
)}`;
|
|
27
|
+
|
|
28
|
+
// location of code in file
|
|
29
|
+
let file_loc = $state();
|
|
30
|
+
// cursor pos and width for file_loc overlay positioning
|
|
31
|
+
let x = $state(),
|
|
32
|
+
y = $state(),
|
|
33
|
+
w = $state();
|
|
34
|
+
|
|
35
|
+
let active_el = $state();
|
|
36
|
+
|
|
37
|
+
let hold_start_ts = $state();
|
|
38
|
+
|
|
39
|
+
let show_toggle = $derived(
|
|
40
|
+
options.showToggleButton === 'always' || (options.showToggleButton === 'active' && enabled)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
function mousemove(e) {
|
|
44
|
+
x = e.x;
|
|
45
|
+
y = e.y;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function find_selectable_parent(el, include_self = false) {
|
|
49
|
+
if (!include_self) {
|
|
50
|
+
el = el.parentNode;
|
|
51
|
+
}
|
|
52
|
+
while (el) {
|
|
53
|
+
if (is_selectable(el)) {
|
|
54
|
+
return el;
|
|
55
|
+
}
|
|
56
|
+
el = el.parentNode;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function find_selectable_child(el) {
|
|
61
|
+
return [...el.querySelectorAll('*')].find(is_selectable);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function find_selectable_sibling(el, prev = false) {
|
|
65
|
+
do {
|
|
66
|
+
el = prev ? el.previousElementSibling : el.nextElementSibling;
|
|
67
|
+
if (is_selectable(el)) {
|
|
68
|
+
return el;
|
|
69
|
+
}
|
|
70
|
+
} while (el);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function find_selectable_for_nav(key) {
|
|
74
|
+
const el = active_el;
|
|
75
|
+
if (!el) {
|
|
76
|
+
return find_selectable_child(document?.body);
|
|
77
|
+
}
|
|
78
|
+
switch (key) {
|
|
79
|
+
case options.navKeys.parent:
|
|
80
|
+
return find_selectable_parent(el);
|
|
81
|
+
case options.navKeys.child:
|
|
82
|
+
return find_selectable_child(el);
|
|
83
|
+
case options.navKeys.next:
|
|
84
|
+
return find_selectable_sibling(el) || find_selectable_parent(el);
|
|
85
|
+
case options.navKeys.prev:
|
|
86
|
+
return find_selectable_sibling(el, true) || find_selectable_parent(el);
|
|
87
|
+
default:
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function is_selectable(el) {
|
|
93
|
+
const file = el?.__svelte_meta?.loc?.file;
|
|
94
|
+
if (!file || file.includes('node_modules/')) {
|
|
95
|
+
return false; // no file or 3rd party
|
|
96
|
+
}
|
|
97
|
+
const id = el.getAttribute('id');
|
|
98
|
+
if (id === 'svelte-announcer' || id?.startsWith('svelte-inspector-')) {
|
|
99
|
+
return false; // ignore some elements by id that would be selectable from keyboard nav otherwise
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function mouseover({ target }) {
|
|
105
|
+
const el = find_selectable_parent(target, true);
|
|
106
|
+
activate(el, false);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function activate(el, set_bubble_pos = true) {
|
|
110
|
+
if (options.customStyles && el !== active_el) {
|
|
111
|
+
if (active_el) {
|
|
112
|
+
active_el.classList.remove('svelte-inspector-active-target');
|
|
113
|
+
}
|
|
114
|
+
if (el) {
|
|
115
|
+
el.classList.add('svelte-inspector-active-target');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (el) {
|
|
119
|
+
const { file, line, column } = el.__svelte_meta.loc;
|
|
120
|
+
file_loc = `${file}:${line + 1}:${column + 1}`;
|
|
121
|
+
} else {
|
|
122
|
+
file_loc = null;
|
|
123
|
+
}
|
|
124
|
+
active_el = el;
|
|
125
|
+
if (set_bubble_pos) {
|
|
126
|
+
const pos = el.getBoundingClientRect();
|
|
127
|
+
x = Math.ceil(pos.left);
|
|
128
|
+
y = Math.ceil(pos.bottom - 20);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function open_editor(e) {
|
|
133
|
+
if (file_loc) {
|
|
134
|
+
stop(e);
|
|
135
|
+
fetch(`${options.__internal.base}/__open-in-editor?file=${encodeURIComponent(file_loc)}`);
|
|
136
|
+
has_opened = true;
|
|
137
|
+
if (options.holdMode && is_holding()) {
|
|
138
|
+
disable();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function is_active(key, e) {
|
|
144
|
+
switch (key) {
|
|
145
|
+
case 'shift':
|
|
146
|
+
case 'control':
|
|
147
|
+
case 'alt':
|
|
148
|
+
case 'meta':
|
|
149
|
+
return e.getModifierState(key.charAt(0).toUpperCase() + key.slice(1));
|
|
150
|
+
default:
|
|
151
|
+
return key === e.code.replace(/^Key/, '').toLowerCase() || key === e.key.toLowerCase();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function is_combo(e) {
|
|
156
|
+
return toggle_combo?.every((k) => is_active(k, e));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function is_escape(e) {
|
|
160
|
+
return escape_keys?.some((k) => is_active(k, e));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function is_toggle(e) {
|
|
164
|
+
return toggle_combo?.some((k) => is_active(k, e));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function is_nav(e) {
|
|
168
|
+
return nav_keys?.some((k) => is_active(k, e));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function is_open(e) {
|
|
172
|
+
return open_key && is_active(open_key, e);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function is_holding() {
|
|
176
|
+
return hold_start_ts && Date.now() - hold_start_ts > 250;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function stop(e) {
|
|
180
|
+
e.preventDefault();
|
|
181
|
+
e.stopPropagation();
|
|
182
|
+
e.stopImmediatePropagation();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function keydown(e) {
|
|
186
|
+
if (e.repeat || e.key == null || (!enabled && !is_toggle(e))) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (is_combo(e)) {
|
|
190
|
+
toggle();
|
|
191
|
+
if (options.holdMode && enabled) {
|
|
192
|
+
hold_start_ts = Date.now();
|
|
193
|
+
}
|
|
194
|
+
} else if (enabled) {
|
|
195
|
+
if (is_nav(e)) {
|
|
196
|
+
const el = find_selectable_for_nav(e.key);
|
|
197
|
+
if (el) {
|
|
198
|
+
activate(el);
|
|
199
|
+
stop(e);
|
|
200
|
+
}
|
|
201
|
+
} else if (is_open(e)) {
|
|
202
|
+
open_editor(e);
|
|
203
|
+
} else if (is_holding() || is_escape(e)) {
|
|
204
|
+
// is_holding() checks for unhandled additional key pressed
|
|
205
|
+
// while holding the toggle keys, which is possibly another
|
|
206
|
+
// shortcut (e.g. 'meta-shift-x'), so disable again.
|
|
207
|
+
|
|
208
|
+
disable();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function keyup(e) {
|
|
214
|
+
if (e.repeat || e.key == null || !enabled) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (is_toggle(e)) {
|
|
218
|
+
if (is_holding()) {
|
|
219
|
+
disable();
|
|
220
|
+
} else {
|
|
221
|
+
hold_start_ts = null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function toggle() {
|
|
227
|
+
if (enabled) {
|
|
228
|
+
disable();
|
|
229
|
+
} else {
|
|
230
|
+
enable();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function listeners(body, enabled) {
|
|
235
|
+
const l = enabled ? body.addEventListener : body.removeEventListener;
|
|
236
|
+
l('mousemove', mousemove);
|
|
237
|
+
l('mouseover', mouseover);
|
|
238
|
+
l('click', open_editor, true);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function enable() {
|
|
242
|
+
enabled = true;
|
|
243
|
+
const b = document.body;
|
|
244
|
+
if (options.customStyles) {
|
|
245
|
+
b.classList.add('svelte-inspector-enabled');
|
|
246
|
+
}
|
|
247
|
+
listeners(b, enabled);
|
|
248
|
+
activate_initial_el();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function activate_initial_el() {
|
|
252
|
+
const hov = innermost_hover_el();
|
|
253
|
+
let el = find_selectable_parent(hov, true);
|
|
254
|
+
if (!el) {
|
|
255
|
+
const act = document.activeElement;
|
|
256
|
+
el = find_selectable_parent(act, true);
|
|
257
|
+
}
|
|
258
|
+
if (!el) {
|
|
259
|
+
el = find_selectable_child(document.body);
|
|
260
|
+
}
|
|
261
|
+
if (el) {
|
|
262
|
+
activate(el);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function innermost_hover_el() {
|
|
267
|
+
let e = document.body.querySelector(':hover');
|
|
268
|
+
let result;
|
|
269
|
+
while (e) {
|
|
270
|
+
result = e;
|
|
271
|
+
e = e.querySelector(':hover');
|
|
272
|
+
}
|
|
273
|
+
return result;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function disable() {
|
|
277
|
+
enabled = false;
|
|
278
|
+
has_opened = false;
|
|
279
|
+
hold_start_ts = null;
|
|
280
|
+
const b = document.body;
|
|
281
|
+
listeners(b, enabled);
|
|
282
|
+
if (options.customStyles) {
|
|
283
|
+
b.classList.remove('svelte-inspector-enabled');
|
|
284
|
+
active_el?.classList.remove('svelte-inspector-active-target');
|
|
285
|
+
}
|
|
286
|
+
active_el = null;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function visibilityChange() {
|
|
290
|
+
if (document.visibilityState === 'hidden') {
|
|
291
|
+
onLeave();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function onLeave() {
|
|
296
|
+
// disable if a file has been opened or combo is held
|
|
297
|
+
if (enabled && (has_opened || hold_start_ts)) {
|
|
298
|
+
disable();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
onMount(() => {
|
|
303
|
+
const s = document.createElement('style');
|
|
304
|
+
s.setAttribute('type', 'text/css');
|
|
305
|
+
s.setAttribute('id', 'svelte-inspector-style');
|
|
306
|
+
s.textContent = `:root { --svelte-inspector-icon: url(${icon})};`;
|
|
307
|
+
document.head.append(s);
|
|
308
|
+
if (toggle_combo) {
|
|
309
|
+
document.body.addEventListener('keydown', keydown);
|
|
310
|
+
if (options.holdMode) {
|
|
311
|
+
document.body.addEventListener('keyup', keyup);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
document.addEventListener('visibilitychange', visibilityChange);
|
|
315
|
+
document.documentElement.addEventListener('mouseleave', onLeave);
|
|
316
|
+
return () => {
|
|
317
|
+
// make sure we get rid of everything
|
|
318
|
+
disable();
|
|
319
|
+
const s = document.head.querySelector('#svelte-inspector-style');
|
|
320
|
+
if (s) {
|
|
321
|
+
document.head.removeChild(s);
|
|
322
|
+
}
|
|
323
|
+
if (toggle_combo) {
|
|
324
|
+
document.body.removeEventListener('keydown', keydown);
|
|
325
|
+
if (options.holdMode) {
|
|
326
|
+
document.body.removeEventListener('keyup', keyup);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
document.removeEventListener('visibilitychange', visibilityChange);
|
|
330
|
+
document.documentElement.removeEventListener('mouseleave', onLeave);
|
|
331
|
+
};
|
|
332
|
+
});
|
|
333
|
+
</script>
|
|
334
|
+
|
|
335
|
+
{#if show_toggle}
|
|
336
|
+
<button
|
|
337
|
+
id="svelte-inspector-toggle"
|
|
338
|
+
class:enabled
|
|
339
|
+
style={`background-image: var(--svelte-inspector-icon);${options.toggleButtonPos
|
|
340
|
+
.split('-')
|
|
341
|
+
.map((p) => `${p}: 8px;`)
|
|
342
|
+
.join('')}`}
|
|
343
|
+
onclick={() => toggle()}
|
|
344
|
+
aria-label={`${enabled ? 'disable' : 'enable'} svelte-inspector`}
|
|
345
|
+
></button>
|
|
346
|
+
{/if}
|
|
347
|
+
{#if enabled && active_el && file_loc}
|
|
348
|
+
{@const loc = active_el.__svelte_meta.loc}
|
|
349
|
+
<div
|
|
350
|
+
id="svelte-inspector-overlay"
|
|
351
|
+
style:left="{Math.min(x + 3, document.documentElement.clientWidth - w - 10)}px"
|
|
352
|
+
style:top="{document.documentElement.clientHeight < y + 50 ? y - 30 : y + 30}px"
|
|
353
|
+
bind:offsetWidth={w}
|
|
354
|
+
>
|
|
355
|
+
<{active_el.tagName.toLowerCase()}> {file_loc}
|
|
356
|
+
</div>
|
|
357
|
+
<div id="svelte-inspector-announcer" aria-live="assertive" aria-atomic="true">
|
|
358
|
+
{active_el.tagName.toLowerCase()} in file {loc.file} on line {loc.line} column {loc.column}
|
|
359
|
+
</div>
|
|
360
|
+
{/if}
|
|
361
|
+
|
|
362
|
+
<style>
|
|
363
|
+
:global(body.svelte-inspector-enabled *) {
|
|
364
|
+
cursor: var(--svelte-inspector-icon), crosshair !important;
|
|
365
|
+
}
|
|
366
|
+
:global(.svelte-inspector-active-target) {
|
|
367
|
+
outline: 2px dashed #ff3e00 !important;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
#svelte-inspector-overlay {
|
|
371
|
+
position: fixed;
|
|
372
|
+
background-color: rgba(0, 0, 0, 0.8);
|
|
373
|
+
color: #fff;
|
|
374
|
+
padding: 2px 4px;
|
|
375
|
+
border-radius: 5px;
|
|
376
|
+
z-index: 999999;
|
|
377
|
+
pointer-events: none;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
#svelte-inspector-toggle {
|
|
381
|
+
all: unset;
|
|
382
|
+
border: 1px solid #ff3e00;
|
|
383
|
+
border-radius: 8px;
|
|
384
|
+
position: fixed;
|
|
385
|
+
height: 32px;
|
|
386
|
+
width: 32px;
|
|
387
|
+
background-color: white;
|
|
388
|
+
background-position: center;
|
|
389
|
+
background-repeat: no-repeat;
|
|
390
|
+
cursor: pointer;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
#svelte-inspector-announcer {
|
|
394
|
+
position: absolute;
|
|
395
|
+
left: 0px;
|
|
396
|
+
top: 0px;
|
|
397
|
+
clip: rect(0px, 0px, 0px, 0px);
|
|
398
|
+
clip-path: inset(50%);
|
|
399
|
+
overflow: hidden;
|
|
400
|
+
white-space: nowrap;
|
|
401
|
+
width: 1px;
|
|
402
|
+
height: 1px;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
#svelte-inspector-toggle:not(.enabled) {
|
|
406
|
+
filter: grayscale(1);
|
|
407
|
+
}
|
|
408
|
+
#svelte-inspector-toggle:hover {
|
|
409
|
+
background-color: #facece;
|
|
410
|
+
}
|
|
411
|
+
</style>
|