pull/4923/head
pushkine 5 years ago
parent f46b38a308
commit a34ac31558

@ -486,7 +486,7 @@ export default class Block {
`); `);
this.chunks.destroy.push( this.chunks.destroy.push(
b`@run_all(${dispose});` b`${dispose}.forEach((#v) => #v());`
); );
} }
} }

@ -72,32 +72,48 @@ export default function dom(
const uses_props = component.var_lookup.has('$$props'); const uses_props = component.var_lookup.has('$$props');
const uses_rest = component.var_lookup.has('$$restProps'); const uses_rest = component.var_lookup.has('$$restProps');
const $$props = uses_props || uses_rest ? `$$new_props` : `$$props`; const uses_$$ = uses_props || uses_rest;
const $$props = uses_$$ ? `$$new_props` : `$$props`;
const props = component.vars.filter(variable => !variable.module && variable.export_name); const props = component.vars.filter(variable => !variable.module && variable.export_name);
const writable_props = props.filter(variable => variable.writable); const writable_props = props.filter(variable => variable.writable);
const omit_props_names = component.get_unique_name('omit_props_names'); const omit_props_names = component.get_unique_name('omit_props_names');
const compute_rest = x`@compute_rest_props($$props, ${omit_props_names.name})`;
const rest = uses_rest ? b` const rest = uses_rest ? b`
const ${omit_props_names.name} = [${props.map(prop => `"${prop.export_name}"`).join(',')}]; const ${omit_props_names.name} = [${props.map(prop => `"${prop.export_name}"`)}];
let $$restProps = ${compute_rest}; const $$restProps = {};
for (#k in $$props) {
if (!#keys.has(#k) && #k[0] !== '$') {
$$restProps[#k] = $$props[#k];
}
}
` : null; ` : null;
const set = (uses_props || uses_rest || writable_props.length > 0 || component.slots.size > 0) const process_new_$$ = b`
? x` for (#k in $$new_props) {
${$$props} => { if (#k[0] !== '$') {
${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`)} ${uses_rest ? b`
${uses_rest && !uses_props && x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`} if (!#keys.has(#k)) {
${uses_rest && renderer.invalidate('$$restProps', x`$$restProps = ${compute_rest}`)} $$props[#k] = ($$restProps[#k] = $$new_props[#k]);
${writable_props.map(prop => } else {
b`if ('${prop.export_name}' in ${$$props}) ${renderer.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.export_name}`)};` $$props[#k] = $$new_props[#k];
)} }`
${component.slots.size > 0 && : b`$$props[#k] = $$new_props[#k];`}
b`if ('$$scope' in ${$$props}) ${renderer.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`}
} }
` }
: null; ${uses_props && renderer.invalidate("$$props")}
${uses_rest && renderer.invalidate("$$restProps")}
`
const set = (uses_$$ || writable_props.length > 0 || component.slots.size > 0)
? x`${$$props} => {
${uses_$$ ? process_new_$$ : null}
${writable_props.map(prop => b`if ('${prop.export_name}' in ${$$props}) ${renderer.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.export_name}`)};`)}
${component.slots.size > 0 && b`if ('$$scope' in ${$$props}) ${renderer.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`}
}`
: null;
const k = set ? b`let #k;` : null
const accessors = []; const accessors = [];
const not_equal = component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`; const not_equal = component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`;
@ -188,7 +204,7 @@ export default function dom(
if (uses_props || injectable_vars.length > 0) { if (uses_props || injectable_vars.length > 0) {
inject_state = x` inject_state = x`
${$$props} => { ${$$props} => {
${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)} ${uses_props && renderer.invalidate('$$props', x`$$props = { ...$$props, ...$$new_props }`)}
${injectable_vars.map( ${injectable_vars.map(
v => b`if ('${v.name}' in $$props) ${renderer.invalidate(v.name, x`${v.name} = ${$$props}.${v.name}`)};` v => b`if ('${v.name}' in $$props) ${renderer.invalidate(v.name, x`${v.name} = ${$$props}.${v.name}`)};`
)} )}
@ -251,7 +267,7 @@ export default function dom(
const insert = (reassigned || export_name) const insert = (reassigned || export_name)
? b`${`$$subscribe_${name}`}()` ? b`${`$$subscribe_${name}`}()`
: b`@component_subscribe($$self, ${name}, #value => $$invalidate(${i}, ${value} = #value))`; : b`$$self.$$.on_destroy.push(@subscribe(${name}, #value => {$$invalidate(${i}, (${value} = #value));})`;
if (component.compile_options.dev) { if (component.compile_options.dev) {
return b`@validate_store(${name}, '${name}'); ${insert}`; return b`@validate_store(${name}, '${name}'); ${insert}`;
@ -335,7 +351,9 @@ export default function dom(
}) })
.map(({ name }) => b` .map(({ name }) => b`
${component.compile_options.dev && b`@validate_store(${name.slice(1)}, '${name.slice(1)}');`} ${component.compile_options.dev && b`@validate_store(${name.slice(1)}, '${name.slice(1)}');`}
@component_subscribe($$self, ${name.slice(1)}, $$value => $$invalidate(${renderer.context_lookup.get(name).index}, ${name} = $$value)); $$self.$$.on_destroy.push(@subscribe(${name.slice(1)}, #value => {
$$invalidate(${renderer.context_lookup.get(name).index}, (${name} = #value));
}));
`); `);
const resubscribable_reactive_store_unsubscribers = reactive_stores const resubscribable_reactive_store_unsubscribers = reactive_stores
@ -386,7 +404,14 @@ export default function dom(
const subscribe = `$$subscribe_${name}`; const subscribe = `$$subscribe_${name}`;
const i = renderer.context_lookup.get($name).index; const i = renderer.context_lookup.get($name).index;
return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => $$invalidate(${i}, ${$name} = $$value)), ${name})`; return b`
let ${$name},
${unsubscribe} = @noop,
${subscribe} = () => {
${unsubscribe}();
${unsubscribe} = @subscribe(${name}, (#value) => { $$invalidate(${i}, (${$name} = #value)); });
return ${name};
};`;
} }
return b`let ${$name};`; return b`let ${$name};`;
@ -412,6 +437,8 @@ export default function dom(
body.push(b` body.push(b`
function ${definition}(${args}) { function ${definition}(${args}) {
${k}
${rest} ${rest}
${reactive_store_declarations} ${reactive_store_declarations}
@ -449,7 +476,7 @@ export default function dom(
${fixed_reactive_declarations} ${fixed_reactive_declarations}
${uses_props && b`$$props = @exclude_internal_props($$props);`} ${uses_props && b`for (#k in $$props) if (#k[0] === '$') delete $$props[#k];`}
return ${return_value}; return ${return_value};
} }

@ -604,6 +604,9 @@ export default class EachBlockWrapper extends Wrapper {
`); `);
} }
block.chunks.destroy.push(b`@destroy_each(${iterations}, detaching);`); block.chunks.destroy.push(b`
for (let #i = 0; #i < ${iterations}.length; #i += 1) {
if (${iterations}[#i]) ${iterations}[#i].d(detaching);
}`);
} }
} }

@ -215,7 +215,7 @@ export default class AttributeWrapper {
if (scoped_css && rendered.length === 2) { if (scoped_css && rendered.length === 2) {
// we have a situation like class={possiblyUndefined} // we have a situation like class={possiblyUndefined}
rendered[0] = x`@null_to_empty(${rendered[0]})`; rendered[0] = x`null != ${rendered[0]} ? ${rendered[0]} : ""`;
} }
return rendered.reduce((lhs, rhs) => x`${lhs} + ${rhs}`); return rendered.reduce((lhs, rhs) => x`${lhs} + ${rhs}`);

@ -31,7 +31,7 @@ export default class EventHandlerWrapper {
if (this.node.reassigned) { if (this.node.reassigned) {
block.maintain_context = true; block.maintain_context = true;
return x`function () { if (@is_function(${snippet})) ${snippet}.apply(this, arguments); }`; return x`function () { if ("function" === typeof (${snippet})) ${snippet}.apply(this, arguments); }`;
} }
return snippet; return snippet;
} }

@ -690,11 +690,10 @@ export default class ElementWrapper extends Wrapper {
}); });
block.chunks.init.push(b` block.chunks.init.push(b`
let ${levels} = [${initial_props}]; const ${levels} = [${initial_props}];
let ${data} = ${levels}[0] || {};
let ${data} = {}; for (let i = 1; i < ${levels}.length; i++) {
for (let #i = 0; #i < ${levels}.length; #i += 1) { ${data} = { ...${data}, ...${levels}[i] };
${data} = @assign(${data}, ${levels}[#i]);
} }
`); `);

@ -36,7 +36,7 @@ export default class HeadWrapper extends Wrapper {
let nodes; let nodes;
if (this.renderer.options.hydratable && this.fragment.nodes.length) { if (this.renderer.options.hydratable && this.fragment.nodes.length) {
nodes = block.get_unique_name('head_nodes'); nodes = block.get_unique_name('head_nodes');
block.chunks.claim.push(b`const ${nodes} = @query_selector_all('[data-svelte="${this.node.id}"]', @_document.head);`); block.chunks.claim.push(b`const ${nodes} = Array.from(( @_document.head || @_document.body ).querySelectorAll('[data-svelte="${this.node.id}"]'));`);
} }
this.fragment.render(block, x`@_document.head` as unknown as Identifier, nodes); this.fragment.render(block, x`@_document.head` as unknown as Identifier, nodes);

@ -241,7 +241,7 @@ export default class InlineComponentWrapper extends Wrapper {
let value_object = value; let value_object = value;
if (attr.expression.node.type !== 'ObjectExpression') { if (attr.expression.node.type !== 'ObjectExpression') {
value_object = x`@get_spread_object(${value})`; value_object = x`typeof (#buffer = ${value}) === 'object' && #buffer !== null ? #buffer : {}`
} }
change_object = value_object; change_object = value_object;
} else { } else {
@ -265,16 +265,13 @@ export default class InlineComponentWrapper extends Wrapper {
]; ];
`); `);
statements.push(b` statements.push(b`${props} = @_Object.assign(${props}, ...${levels});`);
for (let #i = 0; #i < ${levels}.length; #i += 1) {
${props} = @assign(${props}, ${levels}[#i]);
}
`);
if (all_dependencies.size) { if (all_dependencies.size) {
const condition = renderer.dirty(Array.from(all_dependencies)); const condition = renderer.dirty(Array.from(all_dependencies));
updates.push(b` updates.push(b`
let #buffer;
const ${name_changes} = ${condition} ? @get_spread_update(${levels}, [ const ${name_changes} = ${condition} ? @get_spread_update(${levels}, [
${changes} ${changes}
]) : {} ]) : {}
@ -424,7 +421,7 @@ export default class InlineComponentWrapper extends Wrapper {
`); `);
block.chunks.create.push( block.chunks.create.push(
b`if (${name}) @create_component(${name}.$$.fragment);` b`if (${name} && ${name}.$$.fragment) ${name}.$$.fragment.c();`
); );
if (parent_nodes && this.renderer.options.hydratable) { if (parent_nodes && this.renderer.options.hydratable) {
@ -465,7 +462,7 @@ export default class InlineComponentWrapper extends Wrapper {
${munged_bindings} ${munged_bindings}
${munged_handlers} ${munged_handlers}
@create_component(${name}.$$.fragment); if(${name}.$$.fragment) ${name}.$$.fragment.c();
@transition_in(${name}.$$.fragment, 1); @transition_in(${name}.$$.fragment, 1);
@mount_component(${name}, ${update_mount_node}, ${anchor}); @mount_component(${name}, ${update_mount_node}, ${anchor});
} else { } else {
@ -500,11 +497,11 @@ export default class InlineComponentWrapper extends Wrapper {
${munged_handlers} ${munged_handlers}
`); `);
block.chunks.create.push(b`@create_component(${name}.$$.fragment);`); block.chunks.create.push(b`if(${name}.$$.fragment) ${name}.$$.fragment.c();`);
if (parent_nodes && this.renderer.options.hydratable) { if (parent_nodes && this.renderer.options.hydratable) {
block.chunks.claim.push( block.chunks.claim.push(
b`@claim_component(${name}.$$.fragment, ${parent_nodes});` b`if(${name}.$$.fragment) ${name}.$$.fragment.l(${parent_nodes});`
); );
} }

@ -126,10 +126,15 @@ export default class SlotWrapper extends Wrapper {
const slot = block.get_unique_name(`${sanitize(slot_name)}_slot`); const slot = block.get_unique_name(`${sanitize(slot_name)}_slot`);
const slot_definition = block.get_unique_name(`${sanitize(slot_name)}_slot_template`); const slot_definition = block.get_unique_name(`${sanitize(slot_name)}_slot_template`);
const slot_or_fallback = has_fallback ? block.get_unique_name(`${sanitize(slot_name)}_slot_or_fallback`) : slot; const slot_or_fallback = has_fallback ? block.get_unique_name(`${sanitize(slot_name)}_slot_or_fallback`) : slot;
const $$scope = renderer.reference('$$scope');
const context = x`
${slot_definition}[1] && ${get_slot_context_fn}
? @_Object.assign(${$$scope}.ctx.slice(), ${slot_definition}[1](${get_slot_context_fn}(#ctx)))
: ${$$scope}.ctx`;
block.chunks.init.push(b` block.chunks.init.push(b`
const ${slot_definition} = ${renderer.reference('$$slots')}.${slot_name}; const ${slot_definition} = ${renderer.reference('$$slots')}.${slot_name};
const ${slot} = @create_slot(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}); const ${slot} = ${slot_definition} && ${slot_definition}[0](${context});
${has_fallback ? b`const ${slot_or_fallback} = ${slot} || ${this.fallback.name}(#ctx);` : null} ${has_fallback ? b`const ${slot_or_fallback} = ${slot} || ${this.fallback.name}(#ctx);` : null}
`); `);
@ -172,7 +177,8 @@ export default class SlotWrapper extends Wrapper {
const slot_update = b` const slot_update = b`
if (${slot}.p && ${renderer.dirty(dynamic_dependencies)}) { if (${slot}.p && ${renderer.dirty(dynamic_dependencies)}) {
@update_slot(${slot}, ${slot_definition}, #ctx, ${renderer.reference('$$scope')}, #dirty, ${get_slot_changes_fn}, ${get_slot_context_fn}); const #changes = @get_slot_changes(${slot_definition}, ${$$scope}, #dirty, ${get_slot_changes_fn})
if (#changes) ${slot}.p(${context}, #changes);
} }
`; `;
const fallback_update = has_fallback && fallback_dynamic_dependencies.length > 0 && b` const fallback_update = has_fallback && fallback_dynamic_dependencies.length > 0 && b`

@ -29,11 +29,11 @@ export function add_action(block: Block, target: string, action: Action) {
const fn = block.renderer.reference(action.name); const fn = block.renderer.reference(action.name);
block.event_listeners.push( block.event_listeners.push(
x`@action_destroyer(${id} = ${fn}.call(null, ${target}, ${snippet}))` x`(${id} = ${fn}.call(null, ${target}, ${snippet})) && 'function' === typeof ${id}.destroy ? ${id}.destroy : @noop`
); );
if (dependencies && dependencies.length > 0) { if (dependencies && dependencies.length > 0) {
let condition = x`${id} && @is_function(${id}.update)`; let condition = x`${id} && "function" === typeof ${id}.update`;
if (dependencies.length > 0) { if (dependencies.length > 0) {
condition = x`${condition} && ${block.renderer.dirty(dependencies)}`; condition = x`${condition} && ${block.renderer.dirty(dependencies)}`;

@ -13,7 +13,7 @@ export default function(node: AwaitBlock, renderer: Renderer, options: RenderOpt
renderer.add_expression(x` renderer.add_expression(x`
function(__value) { function(__value) {
if (@is_promise(__value)) return ${pending}; if (__value && typeof __value === 'object' && typeof __value.then === 'function') return ${pending};
return (function(${node.then_node ? node.then_node : ''}) { return ${then}; }(__value)); return (function(${node.then_node ? node.then_node : ''}) { return ${then}; }(__value));
}(${node.expression.node}) }(${node.expression.node})
`); `);

@ -9,7 +9,7 @@ export function get_class_attribute_value(attribute: Attribute): ESTreeExpressio
// handle special case — `class={possiblyUndefined}` with scoped CSS // handle special case — `class={possiblyUndefined}` with scoped CSS
if (attribute.chunks.length === 2 && (attribute.chunks[1] as Text).synthetic) { if (attribute.chunks.length === 2 && (attribute.chunks[1] as Text).synthetic) {
const value = (attribute.chunks[0] as Expression).node; const value = (attribute.chunks[0] as Expression).node;
return x`@escape(@null_to_empty(${value})) + "${(attribute.chunks[1] as Text).data}"`; return x`(${x`${value} != null ? @escape(${value}) : ""`}) + "${(attribute.chunks[1] as Text).data}"`;
} }
return get_attribute_value(attribute); return get_attribute_value(attribute);

@ -32,8 +32,14 @@ export default function ssr(
component.stylesheet.render(options.filename, true); component.stylesheet.render(options.filename, true);
const uses_rest = component.var_lookup.has('$$restProps'); const uses_rest = component.var_lookup.has('$$restProps');
const props = component.vars.filter(variable => !variable.module && variable.export_name); const props = component.vars.filter((variable => !variable.module && variable.export_name));
const rest = uses_rest ? b`let $$restProps = @compute_rest_props($$props, [${props.map(prop => `"${prop.export_name}"`).join(',')}]);` : null; const rest = uses_rest
? b`
let #k;
const #keys = new Set([${props.map(prop => `"${prop.export_name}"`)}]);
let $$restProps = {};
for (#k in $$props){ if (!#keys.has(#k) && #k[0] !== '$'){ $$restProps[#k] = $$props[#k];}}`
: null;
const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$'); const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$');
const reactive_store_values = reactive_stores const reactive_store_values = reactive_stores
@ -42,7 +48,7 @@ export default function ssr(
const store = component.var_lookup.get(store_name); const store = component.var_lookup.get(store_name);
if (store && store.hoistable) return null; if (store && store.hoistable) return null;
const assignment = b`${name} = @get_store_value(${store_name});`; const assignment = b`@subscribe(${store_name}, (#v) => { ${name} = #v; })();`;
return component.compile_options.dev return component.compile_options.dev
? b`@validate_store(${store_name}, '${store_name}'); ${assignment}` ? b`@validate_store(${store_name}, '${store_name}'); ${assignment}`
@ -50,16 +56,12 @@ export default function ssr(
}) })
.filter(Boolean); .filter(Boolean);
component.rewrite_props(({ name }) => { component.rewrite_props(
const value = `$${name}`; ({ name }) =>
b`
let insert = b`${value} = @get_store_value(${name})`; ${component.compile_options.dev && b`@validate_store_dev(${name}, '${name}');`}
if (component.compile_options.dev) { @subscribe(${name}, (#v) => { ${`$${name}`} = #v; })();`
insert = b`@validate_store(${name}, '${name}'); ${insert}`; );
}
return insert;
});
const instance_javascript = component.extract_javascript(component.ast.instance); const instance_javascript = component.extract_javascript(component.ast.instance);
@ -138,10 +140,9 @@ export default function ssr(
...reactive_stores.map(({ name }) => { ...reactive_stores.map(({ name }) => {
const store_name = name.slice(1); const store_name = name.slice(1);
const store = component.var_lookup.get(store_name); const store = component.var_lookup.get(store_name);
if (store && store.hoistable) { return b`
return b`let ${name} = @get_store_value(${store_name});`; let ${name};
} ${store && store.hoistable && b`@subscribe(${store_name},(#v) => { ${name}=#v; })();`}`;
return b`let ${name};`;
}), }),
instance_javascript, instance_javascript,

@ -1,5 +1,4 @@
import { cubicOut } from 'svelte/easing'; import { cubicOut } from 'svelte/easing';
import { is_function } from 'svelte/internal';
// todo: same as Transition, should it be shared? // todo: same as Transition, should it be shared?
export interface AnimationConfig { export interface AnimationConfig {
@ -35,7 +34,7 @@ export function flip(node: Element, animation: { from: DOMRect; to: DOMRect }, p
return { return {
delay, delay,
duration: is_function(duration) ? duration(d) : duration, duration: typeof duration === "function" ? duration(d) : duration,
easing, easing,
css: (_t, u) => `transform: ${transform} translate(${u * dx}px, ${u * dy}px);` css: (_t, u) => `transform: ${transform} translate(${u * dx}px, ${u * dy}px);`
}; };

@ -1,6 +1,6 @@
import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler'; import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler';
import { current_component, set_current_component } from './lifecycle'; import { current_component, set_current_component } from './lifecycle';
import { blank_object, is_function, run, run_all, noop } from './utils'; import { noop } from './utils';
import { children, detach } from './dom'; import { children, detach } from './dom';
import { transition_in } from './transitions'; import { transition_in } from './transitions';
@ -59,13 +59,13 @@ export function mount_component(component, target, anchor) {
// onMount happens before the initial afterUpdate // onMount happens before the initial afterUpdate
add_render_callback(() => { add_render_callback(() => {
const new_on_destroy = on_mount.map(run).filter(is_function); const new_on_destroy = on_mount.map(v => v()).filter(v => typeof v === "function");
if (on_destroy) { if (on_destroy) {
on_destroy.push(...new_on_destroy); on_destroy.push(...new_on_destroy);
} else { } else {
// Edge case - component was destroyed immediately, // Edge case - component was destroyed immediately,
// most likely as a result of a binding initialising // most likely as a result of a binding initialising
run_all(new_on_destroy); new_on_destroy.forEach(v => v());
} }
component.$$.on_mount = []; component.$$.on_mount = [];
}); });
@ -76,7 +76,7 @@ export function mount_component(component, target, anchor) {
export function destroy_component(component, detaching) { export function destroy_component(component, detaching) {
const $$ = component.$$; const $$ = component.$$;
if ($$.fragment !== null) { if ($$.fragment !== null) {
run_all($$.on_destroy); $$.on_destroy.forEach(v => v());
$$.fragment && $$.fragment.d(detaching); $$.fragment && $$.fragment.d(detaching);
@ -110,7 +110,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
props, props,
update: noop, update: noop,
not_equal, not_equal,
bound: blank_object(), bound: Object.create(null),
// lifecycle // lifecycle
on_mount: [], on_mount: [],
@ -120,7 +120,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
context: new Map(parent_component ? parent_component.$$.context : []), context: new Map(parent_component ? parent_component.$$.context : []),
// everything else // everything else
callbacks: blank_object(), callbacks: Object.create(null),
dirty dirty
}; };
@ -139,7 +139,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
$$.update(); $$.update();
ready = true; ready = true;
run_all($$.before_update); $$.before_update.forEach(v => v());
// `false` as a special case of no DOM component // `false` as a special case of no DOM component
$$.fragment = create_fragment ? create_fragment($$.ctx) : false; $$.fragment = create_fragment ? create_fragment($$.ctx) : false;

@ -1,4 +1,3 @@
import { is_promise } from './utils';
import { check_outros, group_outros, transition_in, transition_out } from './transitions'; import { check_outros, group_outros, transition_in, transition_out } from './transitions';
import { flush } from './scheduler'; import { flush } from './scheduler';
import { get_current_component, set_current_component } from './lifecycle'; import { get_current_component, set_current_component } from './lifecycle';
@ -52,7 +51,7 @@ export function handle_promise(promise, info) {
} }
} }
if (is_promise(promise)) { if (promise && typeof promise === 'object' && typeof promise.then === 'function') {
const current_component = get_current_component(); const current_component = get_current_component();
promise.then(value => { promise.then(value => {
set_current_component(current_component); set_current_component(current_component);

@ -1,6 +1,12 @@
import { custom_event, append, insert, detach, listen, attr } from './dom'; import { custom_event, append, insert, detach, listen, attr } from './dom';
import { SvelteComponent } from './Component'; import { SvelteComponent } from './Component';
export function add_location(element, file, line, column, char) {
element.__svelte_meta = {
loc: { file, line, column, char }
};
}
export function dispatch_dev<T=any>(type: string, detail?: T) { export function dispatch_dev<T=any>(type: string, detail?: T) {
document.dispatchEvent(custom_event(type, { version: '__VERSION__', ...detail })); document.dispatchEvent(custom_event(type, { version: '__VERSION__', ...detail }));
} }
@ -79,6 +85,15 @@ export function set_data_dev(text, data) {
text.data = data; text.data = data;
} }
export function validate_component(component, name) {
if (!component || !component.$$render) {
if (name === 'svelte:component') name += ' this={...}';
throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);
}
return component;
}
export function validate_each_argument(arg) { export function validate_each_argument(arg) {
if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) { if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {
let msg = '{#each} only iterates over array-like objects.'; let msg = '{#each} only iterates over array-like objects.';
@ -97,6 +112,24 @@ export function validate_slots(name, slot, keys) {
} }
} }
export function validate_store(store, name) {
if (store != null && typeof store.subscribe !== 'function') {
throw new Error(`'${name}' is not a store with a 'subscribe' method`);
}
}
export function validate_each_keys(ctx, list, get_context, get_key) {
const keys = new Set();
for (let i = 0; i < list.length; i++) {
const key = get_key(get_context(ctx, list, i));
if (keys.has(key)) {
throw new Error(`Cannot have duplicate keys in a keyed each`);
}
keys.add(key);
}
}
type Props = Record<string, any>; type Props = Record<string, any>;
export interface SvelteComponentDev { export interface SvelteComponentDev {
$set(props?: Props): void; $set(props?: Props): void;

@ -1,5 +1,3 @@
import { has_prop } from "./utils";
export function append(target: Node, node: Node) { export function append(target: Node, node: Node) {
target.appendChild(node); target.appendChild(node);
} }
@ -26,18 +24,10 @@ export function element_is<K extends keyof HTMLElementTagNameMap>(name: K, is: s
return document.createElement<K>(name, { is }); return document.createElement<K>(name, { is });
} }
export function object_without_properties<T, K extends keyof T>(obj: T, exclude: K[]) { export function object_without_properties<T, K extends string[]>(obj: T, excluded: K) {
const target = {} as Pick<T, Exclude<keyof T, K>>; const target = {} as Pick<T, Exclude<keyof T, keyof K>>;
for (const k in obj) { let key;
if ( for (key in obj) if (!~excluded.indexOf(key)) target[key] = obj[key];
has_prop(obj, k)
// @ts-ignore
&& exclude.indexOf(k) === -1
) {
// @ts-ignore
target[k] = obj[k];
}
}
return target; return target;
} }
@ -85,6 +75,15 @@ export function self(fn) {
}; };
} }
export function once(fn) {
let ran = false;
return function(this: any, ...args) {
if (ran) return;
ran = true;
fn.call(this, ...args);
};
}
export function attr(node: Element, attribute: string, value?: string) { export function attr(node: Element, attribute: string, value?: string) {
if (value == null) node.removeAttribute(attribute); if (value == null) node.removeAttribute(attribute);
else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value); else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value);
@ -309,10 +308,6 @@ export function custom_event<T=any>(type: string, detail?: T) {
return e; return e;
} }
export function query_selector_all(selector: string, parent: HTMLElement = document.body) {
return Array.from(parent.querySelectorAll(selector));
}
export class HtmlTag { export class HtmlTag {
e: HTMLElement; e: HTMLElement;
n: ChildNode[]; n: ChildNode[];

@ -106,15 +106,4 @@ export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list
while (n) insert(new_blocks[n - 1]); while (n) insert(new_blocks[n - 1]);
return new_blocks; return new_blocks;
} }
export function validate_each_keys(ctx, list, get_context, get_key) {
const keys = new Set();
for (let i = 0; i < list.length; i++) {
const key = get_key(get_context(ctx, list, i));
if (keys.has(key)) {
throw new Error(`Cannot have duplicate keys in a keyed each`);
}
keys.add(key);
}
}

@ -1,4 +1,3 @@
import { run_all } from './utils';
import { set_current_component } from './lifecycle'; import { set_current_component } from './lifecycle';
export const dirty_components = []; export const dirty_components = [];
@ -43,7 +42,15 @@ export function flush() {
for (let i = 0; i < dirty_components.length; i += 1) { for (let i = 0; i < dirty_components.length; i += 1) {
const component = dirty_components[i]; const component = dirty_components[i];
set_current_component(component); set_current_component(component);
update(component.$$); const { $$ } = component
if ($$.fragment !== null) {
$$.update();
$$.before_update.forEach(v => v());
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);
$$.after_update.forEach(add_render_callback);
}
} }
dirty_components.length = 0; dirty_components.length = 0;
@ -74,16 +81,4 @@ export function flush() {
update_scheduled = false; update_scheduled = false;
flushing = false; flushing = false;
seen_callbacks.clear(); seen_callbacks.clear();
} }
function update($$) {
if ($$.fragment !== null) {
$$.update();
run_all($$.before_update);
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);
$$.after_update.forEach(add_render_callback);
}
}

@ -34,8 +34,4 @@ export function get_spread_update(levels, updates) {
} }
return update; return update;
}
export function get_spread_object(spread_props) {
return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};
} }

@ -1,5 +1,4 @@
import { set_current_component, current_component } from './lifecycle'; import { set_current_component, current_component } from './lifecycle';
import { run_all, blank_object } from './utils';
import { boolean_attributes } from '../../compiler/compile/render_ssr/handlers/shared/boolean_attributes'; import { boolean_attributes } from '../../compiler/compile/render_ssr/handlers/shared/boolean_attributes';
export const invalid_attribute_name_character = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u; export const invalid_attribute_name_character = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
@ -56,15 +55,6 @@ export const missing_component = {
$$render: () => '' $$render: () => ''
}; };
export function validate_component(component, name) {
if (!component || !component.$$render) {
if (name === 'svelte:component') name += ' this={...}';
throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);
}
return component;
}
export function debug(file, line, column, values) { export function debug(file, line, column, values) {
console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console
console.log(values); // eslint-disable-line no-console console.log(values); // eslint-disable-line no-console
@ -85,7 +75,7 @@ export function create_ssr_component(fn) {
on_mount: [], on_mount: [],
before_update: [], before_update: [],
after_update: [], after_update: [],
callbacks: blank_object() callbacks: Object.create(null)
}; };
set_current_component({ $$ }); set_current_component({ $$ });
@ -111,7 +101,7 @@ export function create_ssr_component(fn) {
const html = $$render(result, props, {}, options); const html = $$render(result, props, {}, options);
run_all(on_destroy); on_destroy.forEach(v => v());
return { return {
html, html,

@ -1,4 +1,4 @@
import { identity as linear, is_function, noop, run_all } from './utils'; import { identity as linear, noop } from './utils';
import { now } from "./environment"; import { now } from "./environment";
import { loop } from './loop'; import { loop } from './loop';
import { create_rule, delete_rule } from './style_manager'; import { create_rule, delete_rule } from './style_manager';
@ -36,7 +36,7 @@ export function group_outros() {
export function check_outros() { export function check_outros() {
if (!outros.r) { if (!outros.r) {
run_all(outros.c); outros.c.forEach(v => v());
} }
outros = outros.p; outros = outros.p;
} }
@ -129,7 +129,8 @@ export function create_in_transition(node: Element & ElementCSSInlineStyle, fn:
delete_rule(node); delete_rule(node);
if (is_function(config)) { if (typeof config === "function") {
//@ts-ignore
config = config(); config = config();
wait().then(go); wait().then(go);
} else { } else {
@ -185,7 +186,7 @@ export function create_out_transition(node: Element & ElementCSSInlineStyle, fn:
if (!--group.r) { if (!--group.r) {
// this will result in `end()` being called, // this will result in `end()` being called,
// so we don't need to clean up here // so we don't need to clean up here
run_all(group.c); group.c.forEach(v => v());
} }
return false; return false;
@ -201,7 +202,7 @@ export function create_out_transition(node: Element & ElementCSSInlineStyle, fn:
}); });
} }
if (is_function(config)) { if (typeof config === "function") {
wait().then(() => { wait().then(() => {
// @ts-ignore // @ts-ignore
config = config(); config = config();
@ -313,7 +314,7 @@ export function create_bidirectional_transition(node: Element & ElementCSSInline
clear_animation(); clear_animation();
} else { } else {
// outro — needs to be coordinated // outro — needs to be coordinated
if (!--running_program.group.r) run_all(running_program.group.c); if (!--running_program.group.r) running_program.group.c.forEach(v => v());
} }
} }
@ -334,7 +335,7 @@ export function create_bidirectional_transition(node: Element & ElementCSSInline
return { return {
run(b) { run(b) {
if (is_function(config)) { if (typeof config === "function") {
wait().then(() => { wait().then(() => {
// @ts-ignore // @ts-ignore
config = config(); config = config();

@ -2,38 +2,6 @@ export function noop() {}
export const identity = x => x; export const identity = x => x;
export function assign<T, S>(tar: T, src: S): T & S {
// @ts-ignore
for (const k in src) tar[k] = src[k];
return tar as T & S;
}
export function is_promise<T = any>(value: any): value is PromiseLike<T> {
return value && typeof value === 'object' && typeof value.then === 'function';
}
export function add_location(element, file, line, column, char) {
element.__svelte_meta = {
loc: { file, line, column, char }
};
}
export function run(fn) {
return fn();
}
export function blank_object() {
return Object.create(null);
}
export function run_all(fns) {
fns.forEach(run);
}
export function is_function(thing: any): thing is Function {
return typeof thing === 'function';
}
export function safe_not_equal(a, b) { export function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
} }
@ -42,10 +10,15 @@ export function not_equal(a, b) {
return a != a ? b == b : a !== b; return a != a ? b == b : a !== b;
} }
export function validate_store(store, name) { export function get_slot_changes(definition, $$scope, dirty, fn) {
if (store != null && typeof store.subscribe !== 'function') { if (!definition[2] || !fn) return $$scope.dirty;
throw new Error(`'${name}' is not a store with a 'subscribe' method`); const lets = definition[2](fn(dirty));
} if ($$scope.dirty === void 0) return lets;
else if (typeof lets === 'object') {
const merged = new Array(Math.max($$scope.dirty.length, lets.length));
for (let i = 0; i < merged.length; i += 1) merged[i] = $$scope.dirty[i] | lets[i];
return merged;
} else return $$scope.dirty | lets;
} }
export function subscribe(store, ...callbacks) { export function subscribe(store, ...callbacks) {
@ -56,94 +29,7 @@ export function subscribe(store, ...callbacks) {
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
} }
export function get_store_value(store) {
let value;
subscribe(store, _ => value = _)();
return value;
}
export function component_subscribe(component, store, callback) {
component.$$.on_destroy.push(subscribe(store, callback));
}
export function create_slot(definition, ctx, $$scope, fn) {
if (definition) {
const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);
return definition[0](slot_ctx);
}
}
export function get_slot_context(definition, ctx, $$scope, fn) {
return definition[1] && fn
? assign($$scope.ctx.slice(), definition[1](fn(ctx)))
: $$scope.ctx;
}
export function get_slot_changes(definition, $$scope, dirty, fn) {
if (definition[2] && fn) {
const lets = definition[2](fn(dirty));
if ($$scope.dirty === undefined) {
return lets;
}
if (typeof lets === 'object') {
const merged = [];
const len = Math.max($$scope.dirty.length, lets.length);
for (let i = 0; i < len; i += 1) {
merged[i] = $$scope.dirty[i] | lets[i];
}
return merged;
}
return $$scope.dirty | lets;
}
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];
return result;
}
export function compute_rest_props(props, keys) {
const rest = {};
keys = new Set(keys);
for (const k in props) if (!keys.has(k) && k[0] !== '$') rest[k] = props[k];
return rest;
}
export function once(fn) {
let ran = false;
return function(this: any, ...args) {
if (ran) return;
ran = true;
fn.call(this, ...args);
};
}
export function null_to_empty(value) {
return value == null ? '' : value;
}
export function set_store_value(store, ret, value = ret) { export function set_store_value(store, ret, value = ret) {
store.set(value); store.set(value);
return ret; return ret;
}
export const has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
export function action_destroyer(action_result) {
return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;
} }

@ -1,5 +1,5 @@
import { Readable, writable } from 'svelte/store'; import { Readable, writable } from 'svelte/store';
import { assign, loop, now, Task } from 'svelte/internal'; import { loop, now, Task } from 'svelte/internal';
import { linear } from 'svelte/easing'; import { linear } from 'svelte/easing';
import { is_date } from './utils'; import { is_date } from './utils';
@ -91,7 +91,7 @@ export function tweened<T>(value?: T, defaults: Options<T> = {}): Tweened<T> {
duration = 400, duration = 400,
easing = linear, easing = linear,
interpolate = get_interpolator interpolate = get_interpolator
} = assign(assign({}, defaults), opts); } = { ...defaults, ...opts };
if (duration === 0) { if (duration === 0) {
if (previous_task) { if (previous_task) {

@ -1,4 +1,4 @@
import { run_all, subscribe, noop, safe_not_equal, is_function, get_store_value } from 'svelte/internal'; import { subscribe, noop, safe_not_equal } from 'svelte/internal';
/** Callback to inform of a value updates. */ /** Callback to inform of a value updates. */
type Subscriber<T> = (value: T) => void; type Subscriber<T> = (value: T) => void;
@ -169,7 +169,7 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
if (auto) { if (auto) {
set(result as T); set(result as T);
} else { } else {
cleanup = is_function(result) ? result as Unsubscriber : noop; cleanup = "function" === typeof result ? result as Unsubscriber : noop;
} }
}; };
@ -191,7 +191,7 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
sync(); sync();
return function stop() { return function stop() {
run_all(unsubscribers); unsubscribers.forEach(v => v());
cleanup(); cleanup();
}; };
}); });
@ -201,4 +201,8 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
* Get the current value from a store by subscribing and immediately unsubscribing. * Get the current value from a store by subscribing and immediately unsubscribing.
* @param store readable * @param store readable
*/ */
export { get_store_value as get }; export function get(store) {
let value;
subscribe(store, _ => value = _)();
return value;
}

@ -1,5 +1,4 @@
import { cubicOut, cubicInOut, linear } from 'svelte/easing'; import { cubicOut, cubicInOut, linear } from 'svelte/easing';
import { assign, is_function } from 'svelte/internal';
type EasingFunction = (t: number) => number; type EasingFunction = (t: number) => number;
@ -217,7 +216,8 @@ export function crossfade({ fallback, ...defaults }: CrossfadeParams & {
delay = 0, delay = 0,
duration = d => Math.sqrt(d) * 30, duration = d => Math.sqrt(d) * 30,
easing = cubicOut easing = cubicOut
} = assign(assign({}, defaults), params); //@ts-ignore
} = {...defaults, params};
const to = node.getBoundingClientRect(); const to = node.getBoundingClientRect();
const dx = from.left - to.left; const dx = from.left - to.left;
@ -232,7 +232,7 @@ export function crossfade({ fallback, ...defaults }: CrossfadeParams & {
return { return {
delay, delay,
duration: is_function(duration) ? duration(d) : duration, duration: typeof duration === "function" ? duration(d) : duration,
easing, easing,
css: (t, u) => ` css: (t, u) => `
opacity: ${t * opacity}; opacity: ${t * opacity};

Loading…
Cancel
Save