mount and render after a tick

pull/8457/head
Simon Holthausen 3 years ago
parent 62e6d0654d
commit 868fb234ed

@ -132,10 +132,6 @@ export default class SlotWrapper extends Wrapper {
const ${slot_definition} = ${renderer.reference('#slots')}.${slot_name};
const ${slot} = @create_slot(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn});
${has_fallback ? b`const ${slot_or_fallback} = ${slot} || ${this.fallback.name}(#ctx);` : null}
${has_fallback && this.renderer.options.customElement && this.renderer.component.component_options.tag
// This ensures that fallback content is rendered into the <slot> element given by the custom element wrapper
? b`if (${slot_or_fallback}.$$c_e) { ${slot_or_fallback}.$$c_e = ${this.fallback.name}(#ctx); }`
: null}
`);
block.chunks.create.push(

@ -1,4 +1,4 @@
import { add_render_callback, flush, flush_render_callbacks, schedule_update, dirty_components, tick } from './scheduler';
import { add_render_callback, flush, flush_render_callbacks, schedule_update, dirty_components } from './scheduler';
import { current_component, set_current_component } from './lifecycle';
import { blank_object, is_empty, is_function, run, run_all, noop } from './utils';
import { children, detach, start_hydrating, end_hydrating, get_custom_elements_slots, insert } from './dom';
@ -169,10 +169,17 @@ if (typeof HTMLElement === 'function') {
super.addEventListener(type, listener, options);
}
connectedCallback() {
async connectedCallback() {
this.$$connected = true;
if (!this.$$component) {
function create_slot(name: string, $$c_e = false) {
// We wait one tick to let possible child slot elements be created/mounted
await Promise.resolve();
if (!this.$$connected) {
return;
}
function create_slot(name: string) {
return () => {
let node: HTMLSlotElement;
const obj = {
@ -181,25 +188,15 @@ if (typeof HTMLElement === 'function') {
if (name !== 'default') {
node.setAttribute('name', name);
}
if (typeof obj.$$c_e === 'object') {
(obj.$$c_e as any).c()
}
},
m: function mount(target: HTMLElement, anchor?: HTMLElement) {
insert(target, node, anchor);
if (typeof obj.$$c_e === 'object') {
(obj.$$c_e as any).m(node, anchor)
}
},
d: function destroy(detaching: boolean) {
if (detaching) {
if (typeof obj.$$c_e === 'object') {
(obj.$$c_e as any).d(detaching)
}
detach(node);
}
},
$$c_e
}
};
return obj;
};
@ -213,15 +210,6 @@ if (typeof HTMLElement === 'function') {
}
}
if (!Object.keys($$slots).length && this.$$slots.length) {
// There are potentially slots, but we didn't find any. This could be due to Svelte adding the child nodes
// only after the component is created (in the mount phase). In this case, pass in placeholder slots.
// The drawback is that all $$slots properties will be `true`, even if the component doesn't use them.
for (const name of this.$$slots) {
$$slots[name] = [create_slot(name, true)];
}
}
for (const attribute of this.attributes) {
// this.$$data takes precedence over this.attributes
const name = this.$$get_prop_name(attribute.name);
@ -256,7 +244,7 @@ if (typeof HTMLElement === 'function') {
disconnectedCallback() {
this.$$connected = false;
// In a microtask, because this could be a move within the DOM
tick().then(() => {
Promise.resolve().then(() => {
if (!this.$$connected) {
this.$$component!.$destroy();
this.$$component = undefined;

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element name="world" answer="42" test="svelte"></custom-element>';
await tick();
const el = target.querySelector('custom-element');
assert.htmlEqual(el.shadowRoot.innerHTML, `

@ -1,19 +1,22 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import Component from './main.svelte';
export default function (target) {
export default async function (target) {
const component = new Component({ target, props: { name: 'slot' } });
await tick();
await tick();
const ce = target.querySelector('my-widget');
assert.htmlEqual(ce.shadowRoot.innerHTML, `
<slot>fallback</slot>
<slot name=\"named\"><p>named fallback</p></slot>
<slot></slot>
<p>named fallback</p>
`);
component.name = 'slot2';
assert.htmlEqual(ce.shadowRoot.innerHTML, `
<slot>fallback</slot>
<slot name=\"named\"><p>named fallback</p></slot>
<slot></slot>
<p>named fallback</p>
`);
}

@ -1,11 +1,13 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = `
<custom-element><span slot="a">hello world</span><span>bye</span><span>world</span></custom-element>
<custom-element><span slot="a">hello world</span><span slot="b">hello world</span><span>bye world</span></custom-element>
`;
await tick();
const [a, b] = target.querySelectorAll('custom-element');

@ -1,9 +1,10 @@
import { tick } from 'svelte';
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default async function (target) {
target.innerHTML = '<custom-element name="foo"></custom-element>';
await tick();
const el = target.querySelector('custom-element');
const events = el.events; // need to get the array reference, else it's gone when destroyed
assert.deepEqual(events, ['foo']);

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element camel-case="world" an-array="[1,2]"></custom-element>';
await tick();
const el = target.querySelector('custom-element');
assert.equal(el.shadowRoot.innerHTML, '<h1>Hello world!</h1> <p>1</p><p>2</p>');

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element name="world"></custom-element>';
await tick();
const el = target.querySelector('custom-element');
const h1 = el.shadowRoot.querySelector('h1');

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default async function (target) {
target.innerHTML = '<custom-element></custom-element>';
await tick();
const el = target.querySelector('custom-element');
await el.updateFoo(42);

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element></custom-element>';
await tick();
const icon = target.querySelector('custom-element').shadowRoot.querySelector('.icon');
const before = getComputedStyle(icon, '::before');

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element></custom-element>';
await tick();
const el = target.querySelector('custom-element');
const events = [];

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element></custom-element>';
await tick();
assert.equal(target.innerHTML, '<custom-element></custom-element>');
const el = target.querySelector('custom-element');

@ -1,11 +1,13 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = `
<custom-element>
<strong>slotted</strong>
</custom-element>`;
await tick();
const el = target.querySelector('custom-element');

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element name="world"></custom-element>';
await tick();
const el = target.querySelector('custom-element');
assert.equal(el.name, 'world');

@ -1,8 +1,10 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default async function (target) {
target.innerHTML = '<my-app/>';
await tick();
const el = target.querySelector('my-app');
const button = el.shadowRoot.querySelector('button');
const span = el.shadowRoot.querySelector('span');

@ -1,9 +1,11 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<p>unstyled</p>';
target.appendChild(document.createElement('custom-element'));
await tick();
const unstyled = target.querySelector('p');
const styled = target.querySelector('custom-element').shadowRoot.querySelector('p');

@ -1,7 +1,8 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
const warnings = [];
const warn = console.warn;
@ -10,6 +11,7 @@ export default function (target) {
};
target.innerHTML = '<my-app foo=yes />';
await tick();
assert.deepEqual(warnings, [
"<my-app> was created without expected prop 'bar'"

@ -1,10 +1,12 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import CustomElement from './main.svelte';
import { create_custom_element } from 'svelte/internal';
export default function (target) {
export default async function (target) {
customElements.define('no-tag', create_custom_element(CustomElement, {name: {}}, [], []));
target.innerHTML = '<no-tag name="world"></no-tag>';
await tick();
const el = target.querySelector('no-tag');
const h1 = el.shadowRoot.querySelector('h1');

@ -1,10 +1,12 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import CustomElement from './main.svelte';
import { create_custom_element } from 'svelte/internal';
export default function (target) {
export default async function (target) {
customElements.define('no-tag', create_custom_element(CustomElement, { name: {}}, [], []));
target.innerHTML = '<no-tag name="world"></no-tag>';
await tick();
const el = target.querySelector('no-tag');
const h1 = el.shadowRoot.querySelector('h1');

@ -1,10 +1,12 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import CustomElement from './main.svelte';
import { create_custom_element } from 'svelte/internal';
export default function (target) {
export default async function (target) {
customElements.define('no-tag', create_custom_element(CustomElement, { name: {} }, [], []));
target.innerHTML = '<no-tag name="world"></no-tag>';
await tick();
const el = target.querySelector('no-tag');
const h1 = el.shadowRoot.querySelector('h1');

@ -4,6 +4,7 @@ import './main.svelte';
export default async function (target) {
target.innerHTML = '<my-app prop/>';
await tick();
const el = target.querySelector('my-app');
await tick();

@ -4,6 +4,7 @@ import './main.svelte';
export default async function (target) {
target.innerHTML = '<my-app/>';
await tick();
const el = target.querySelector('my-app');
target.removeChild(el);

@ -1,8 +1,11 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element></custom-element>';
await tick();
await tick();
assert.equal(target.innerHTML, '<custom-element></custom-element>');
@ -10,6 +13,7 @@ export default function (target) {
const widget = el.shadowRoot.querySelector('my-widget');
const [p1, p2, p3, p4] = widget.shadowRoot.querySelectorAll('p');
console.log('goooo', !!p1, !!p2, !!p3, !!p4)
assert.equal(p1.textContent, '3 items');
assert.equal(p2.textContent, 'a, b, c');

@ -1,8 +1,11 @@
import * as assert from 'assert';
import { tick } from 'svelte';
import './main.svelte';
export default function (target) {
export default async function (target) {
target.innerHTML = '<custom-element red white></custom-element>';
await tick();
await tick();
const ceRoot = target.querySelector('custom-element').shadowRoot;
const div = ceRoot.querySelector('div');
const p = ceRoot.querySelector('p');

Loading…
Cancel
Save