Skip to content

Commit

Permalink
fix slot data for cancelled transition
Browse files Browse the repository at this point in the history
  • Loading branch information
tanhauhau committed Jun 22, 2021
1 parent 1741699 commit ba67654
Show file tree
Hide file tree
Showing 16 changed files with 370 additions and 7 deletions.
8 changes: 3 additions & 5 deletions src/compiler/compile/render_dom/wrappers/Slot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export default class SlotWrapper extends Wrapper {
if (spread_dynamic_dependencies.size) {
get_slot_spread_changes_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_spread_changes`);
renderer.blocks.push(b`
const ${get_slot_spread_changes_fn} = #dirty => ${renderer.dirty(Array.from(spread_dynamic_dependencies))} > 0 ? -1 : 0;
const ${get_slot_spread_changes_fn} = #dirty => ${renderer.dirty(Array.from(spread_dynamic_dependencies))};
`);
}
} else {
Expand Down Expand Up @@ -165,12 +165,10 @@ export default class SlotWrapper extends Wrapper {
: [];

let condition = renderer.dirty(dynamic_dependencies);
if (block.has_outros) {
condition = x`!#current || ${condition}`;
}
let dirty = x`#dirty`;
if (block.has_outros) {
dirty = x`!#current ? ${renderer.get_initial_dirty()} : ${dirty}`;
condition = x`!#current || ${condition}`;
dirty = x`!#current || ${dirty}`;
}

const slot_update = get_slot_spread_changes_fn ? b`
Expand Down
16 changes: 14 additions & 2 deletions src/runtime/internal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,33 @@ export function get_slot_changes(definition, $$scope, dirty, fn) {
}

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);
const slot_changes = dirty === true ? get_all_dirty($$scope) : 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 update_slot_spread(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_spread_changes_fn, get_slot_context_fn) {
const slot_changes = get_slot_spread_changes_fn(dirty) | get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);
const slot_changes = dirty === true || get_slot_spread_changes_fn(dirty) ? get_all_dirty($$scope) : 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);
}
}

function get_all_dirty($$scope) {
if ($$scope.ctx.length > 32) {
const dirty = [];
const length = $$scope.ctx.length / 32;
for (let i = 0; i < length; i++) {
dirty[i] = -1;
}
return dirty;
}
return -1;
}

export function exclude_internal_props(props) {
const result = {};
for (const k in props) if (k[0] !== '$') result[k] = props[k];
Expand Down
1 change: 1 addition & 0 deletions test/runtime/samples/transition-js-slot-2/_config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// cancelled the transition halfway
export default {
html: `
<div>Foo</div>
Expand Down
19 changes: 19 additions & 0 deletions test/runtime/samples/transition-js-slot-4-cancelled/Nested.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
export let visible;
export let slotProps;
function fade(node) {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
}
</script>

{#if visible}
<div transition:fade>
<slot {slotProps}></slot>
</div>
{/if}
35 changes: 35 additions & 0 deletions test/runtime/samples/transition-js-slot-4-cancelled/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// updated props in the middle of transitions
// and cancelled the transition halfway
export default {
html: `
<div>outside Foo Foo Foo</div>
<div>inside Foo Foo Foo</div>
`,
props: {
props: 'Foo'
},

async test({ assert, component, target, window, raf }) {
await component.hide();
const [, div] = target.querySelectorAll('div');

raf.tick(50);
assert.equal(div.foo, 0.5);

component.props = 'Bar';
assert.htmlEqual(target.innerHTML, `
<div>outside Bar Bar Bar</div>
<div>inside Foo Foo Foo</div>
`);

await component.show();

assert.htmlEqual(target.innerHTML, `
<div>outside Bar Bar Bar</div>
<div>inside Bar Bar Bar</div>
`);

raf.tick(100);
assert.equal(div.foo, 1);
}
};
22 changes: 22 additions & 0 deletions test/runtime/samples/transition-js-slot-4-cancelled/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script>
import Nested from './Nested.svelte';
let visible = true;
let state = 'Foo';
let slotProps = 'Foo';
export let props;
export function show() {
visible = true;
}
export function hide() {
visible = false;
state = 'Bar';
slotProps = 'Bar';
}
</script>

<div>outside {state} {props} {slotProps}</div>
<Nested {visible} {slotProps} let:slotProps>
inside {state} {props} {slotProps}
</Nested>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
export let visible;
export let slotProps;
function fade(node) {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
}
</script>

{#if visible}
<div transition:fade>
<slot {slotProps}></slot>
</div>
{/if}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// updated props in the middle of transitions
// and cancelled the transition halfway
// + spreaded props + overflow context

export default {
html: `
<div>outside Foo Foo Foo</div>
<div>inside Foo Foo Foo</div>
0
`,
props: {
props: 'Foo'
},

async test({ assert, component, target, window, raf }) {
await component.hide();
const [, div] = target.querySelectorAll('div');

raf.tick(50);
assert.equal(div.foo, 0.5);

component.props = 'Bar';
assert.htmlEqual(target.innerHTML, `
<div>outside Bar Bar Bar</div>
<div>inside Foo Foo Foo</div>
0
`);

await component.show();

assert.htmlEqual(target.innerHTML, `
<div>outside Bar Bar Bar</div>
<div>inside Bar Bar Bar</div>
0
`);

raf.tick(100);
assert.equal(div.foo, 1);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script>
import Nested from './Nested.svelte';
export let a1=0,a2=0,a3=0,a4=0,a5=0,a6=0,a7=0,a8=0,a9=0,a10=0,a11=0, a12=0,a13=0,a14=0,a15=0,a16=0,a17=0,a18=0,a19=0,a20=0,a21=0, a22=0,a23=0,a24=0,a25=0,a26=0,a27=0,a28=0,a29=0,a30=0,a31=0,a32=0,a33=0;
let visible = true;
let state = 'Foo';
let slotProps = 'Foo';
export let props;
export function show() {
visible = true;
}
export function hide() {
visible = false;
state = 'Bar';
slotProps = 'Bar';
}
</script>

<div>outside {state} {props} {slotProps}</div>

<Nested {visible} {slotProps} let:slotProps>
inside {state} {props} {slotProps}
</Nested>

{a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16+a17+a18+a19+a20+a21+a22+a23+a24+a25+a26+a27+a28+a29+a30+a31+a32+a33}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
export let visible;
export let slotProps;
function fade(node) {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
}
</script>

{#if visible}
<div transition:fade>
<slot {...slotProps}></slot>
</div>
{/if}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
export let visible;
let slotProps = { slotProps: 'XXX' };
function fade(node) {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
}
</script>

{#if visible}
<div transition:fade>
<slot {...slotProps}></slot>
</div>
{/if}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// updated props in the middle of transitions
// and cancelled the transition halfway
// with spreaded props

export default {
html: `
<div>outside Foo Foo Foo</div>
<div>inside Foo Foo Foo</div>
<div>inside Foo Foo XXX</div>
`,
props: {
props: 'Foo'
},

async test({ assert, component, target, window, raf }) {
await component.hide();
const [, div] = target.querySelectorAll('div');

raf.tick(50);
assert.equal(div.foo, 0.5);

component.props = 'Bar';
assert.htmlEqual(target.innerHTML, `
<div>outside Bar Bar Bar</div>
<div>inside Foo Foo Foo</div>
<div>inside Foo Foo XXX</div>
`);

await component.show();

assert.htmlEqual(target.innerHTML, `
<div>outside Bar Bar Bar</div>
<div>inside Bar Bar Bar</div>
<div>inside Bar Bar XXX</div>
`);

raf.tick(100);
assert.equal(div.foo, 1);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script>
import Nested from './Nested.svelte';
import Nested2 from './Nested2.svelte';
let visible = true;
let state = 'Foo';
let slotProps = { slotProps: 'Foo' };
export let props;
export function show() {
visible = true;
}
export function hide() {
visible = false;
state = 'Bar';
slotProps = { slotProps: 'Bar' };
}
</script>

<div>outside {state} {props} {slotProps.slotProps}</div>
<Nested {visible} {slotProps} let:slotProps>
inside {state} {props} {slotProps}
</Nested>
<Nested2 {visible} let:slotProps>
inside {state} {props} {slotProps}
</Nested2>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
export let visible;
export let slotProps;
function fade(node) {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
}
</script>

{#if visible}
<div transition:fade>
<slot {...slotProps}></slot>
</div>
{/if}
Loading

0 comments on commit ba67654

Please sign in to comment.