Merge branch 'main' into onoutroend-twice

pull/18498/head
JY Wey 2 weeks ago committed by GitHub
commit 74f54502fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: avoid declaration tag warning in event handlers

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: chain preprocessor sourcemaps with an empty `sources[0]` instead of dropping them

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: don't treat declaration tags as parts inside each blocks

@ -18,7 +18,9 @@ export function visit_function(node, context) {
context.next({
...context.state,
function_depth: context.state.function_depth + 1,
// we generally want to use scope.function_depth unless we specifically increased
// that in state.function_depth (e.g. a derived)
function_depth: Math.max(context.state.scope.function_depth, context.state.function_depth) + 1,
expression: null
});
}

@ -8,7 +8,7 @@ import { sanitize_template_string } from '../../../../../utils/sanitize_template
import { regex_is_valid_identifier } from '../../../../patterns.js';
import is_reference from 'is-reference';
import { dev, is_ignored, locator, component_name } from '../../../../../state.js';
import { build_getter } from '../../utils.js';
import { build_getter, is_state_source } from '../../utils.js';
import { ExpressionMetadata } from '../../../../nodes.js';
/**
@ -272,6 +272,10 @@ export function build_bind_this(expression, value, { state, visit }) {
const binding = state.scope.get(node.name);
if (!binding) return;
// if it is a state or a derived it means is a declaration tag...in that case we don't want to pass the
// value but the signal itself or assignment will break
if (is_state_source(binding, state.analysis) || binding.kind === 'derived') return;
for (const [owner, scope] of state.scopes) {
if (owner.type === 'EachBlock' && scope === binding.scope) {
ids.push(node);

@ -311,6 +311,13 @@ function apply_preprocessor_sourcemap(filename, svelte_map, preprocessor_map_inp
typeof preprocessor_map_input === 'string'
? JSON.parse(preprocessor_map_input)
: preprocessor_map_input;
// A preprocessor map with a missing/empty `sources[0]` (e.g. from a MagicString transform
// created without a `source` option) can't be matched against `filename` during combination,
// which silently drops the chain instead of erroring. Normalize it to `filename` first, the
// same way Vite treats an empty `sources[0]` as referring to the file being transformed.
if (preprocessor_map.sources?.length === 1 && !preprocessor_map.sources[0]) {
preprocessor_map.sources = [filename];
}
const result_map = combine_sourcemaps(filename, [svelte_map, preprocessor_map]);
// Svelte expects a SourceMap which includes toUrl and toString. Instead of wrapping our output in a class,
// we just tack on the extra properties.

@ -0,0 +1,10 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ target, assert }) {
const [btn1, btn2] = target.querySelectorAll('button');
flushSync(() => btn2.click());
assert.equal(btn1.textContent, '1');
}
});

@ -0,0 +1,6 @@
{#each Array(1)}
{let ref = $state()}
{let count = $state(0)}
<button onclick={()=>count++} bind:this={ref}>{count}</button>
<button onclick={()=>ref.click()}></button>
{/each}

@ -0,0 +1,29 @@
import * as fs from 'node:fs';
import MagicString from 'magic-string';
import { test } from '../../test';
// Simulates a bundler plugin (e.g. a Vite plugin using `magic-string`) that transforms
// the Svelte source *before* it reaches `compile()`, and hands its own sourcemap to
// `compileOptions.sourcemap` — the documented way to let svelte chain an upstream map
// into its own output map. Crucially, the upstream map is generated *without* a `source`
// option, exactly like `new MagicString(code).generateMap()` — this yields a sourcemap
// whose `sources` is `['']`, which previously broke the chain entirely (see #18491)
// instead of being treated as "this file", causing every mapping through it to resolve
// to `{ source: null, line: null, column: null }`.
const input = fs.readFileSync(new URL('./input.svelte', import.meta.url), 'utf-8');
const src = new MagicString(input);
src.overwrite(
src.original.indexOf('count * 2'),
src.original.indexOf('count * 2') + 'count * 2'.length,
'count * 2',
{
storeName: false
}
);
export default test({
compileOptions: {
sourcemap: src.generateMap({ hires: true })
},
client: [{ str: 'let doubled' }]
});

@ -0,0 +1,6 @@
<script>
let count = 0;
let doubled = count * 2;
</script>
<button>clicks: {count}</button>

@ -7,3 +7,7 @@
{let e = $state(0), f = e}
{a}{b}{c}{d}{e}{f}
<button onclick={() => {
console.log(a);
}}>a</button>
Loading…
Cancel
Save