fix slot with context overflow + without let (#4862)

pull/4874/head
Tan Li Hau 4 years ago committed by GitHub
parent 185706f7d0
commit 7834ca3c5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -172,10 +172,7 @@ export default class SlotWrapper extends Wrapper {
const slot_update = b`
if (${slot}.p && ${renderer.dirty(dynamic_dependencies)}) {
${slot}.p(
@get_slot_context(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}),
@get_slot_changes(${slot_definition}, ${renderer.reference('$$scope')}, #dirty, ${get_slot_changes_fn})
);
@update_slot(${slot}, ${slot_definition}, #ctx, ${renderer.reference('$$scope')}, #dirty, ${get_slot_changes_fn}, ${get_slot_context_fn});
}
`;
const fallback_update = has_fallback && fallback_dynamic_dependencies.length > 0 && b`

@ -103,6 +103,14 @@ export function get_slot_changes(definition, $$scope, dirty, fn) {
return $$scope.dirty;
}
export function update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {
const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);
if (slot_changes) {
const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);
slot.p(slot_context, slot_changes);
}
}
export function exclude_internal_props(props) {
const result = {};
for (const k in props) if (k[0] !== '$') result[k] = props[k];

@ -0,0 +1,15 @@
<script>
let open = false;
function toggle() {
open = !open;
}
</script>
<div on:click={toggle}>
<slot name="target" {open}></slot>
<!-- This actually isn't necessary to reproduce. -->
{#if open}
<slot name="content"></slot>
{/if}
</div>

@ -0,0 +1,32 @@
// overflow bitmask + slot missing `let:`
export default {
html: `
<div>
<button slot="target">Toggle inside 1</button>
</div>
<button>Toggle outside</button>
`,
async test({ assert, component, target, window }) {
const button = target.querySelectorAll('button')[1];
const div = target.querySelector('div');
await div.dispatchEvent(new window.MouseEvent('click'));
assert.htmlEqual(target.innerHTML, `
<div>
<button slot="target">Toggle inside 1</button>
<div slot="content">Open</div>
</div>
<button>Toggle outside</button>
`);
await button.dispatchEvent(new window.MouseEvent('click'));
assert.htmlEqual(target.innerHTML, `
<div>
<button slot="target">Toggle inside 2</button>
<div slot="content">Open</div>
</div>
<button>Toggle outside</button>
`);
}
};

@ -0,0 +1,23 @@
<script>
import Slotted from './Slotted.svelte';
let lotsOfNumbers = Array.from({length: 50}, () => 1);
let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af, ag, ah] = lotsOfNumbers;
let last = 1;
function toggle () {
last = 2;
}
</script>
<Slotted>
<button slot="target">
Toggle inside {last}
</button>
<div slot="content">
Open
</div>
</Slotted>
<button on:click={toggle}>Toggle outside</button>
Loading…
Cancel
Save