more simplification

pull/1934/head
Richard Harris 7 years ago
parent 49db9e7524
commit e0eaf24522

@ -28,6 +28,7 @@ export default class BindingWrapper {
};
snippet: string;
initialUpdate: string;
isReadOnly: boolean;
needsLock: boolean;
constructor(block: Block, node: Binding, parent: ElementWrapper) {
@ -66,14 +67,17 @@ export default class BindingWrapper {
this.snippet = this.node.expression.render();
const isReadOnly = (
const type = parent.node.getStaticAttributeValue('type');
this.isReadOnly = (
dimensions.test(this.node.name) ||
(parent.node.isMediaNode() && readOnlyMediaAttributes.has(this.node.name)) ||
dimensions.test(this.node.name)
(parent.node.name === 'input' && type === 'file') // TODO others?
);
this.needsLock = !isReadOnly && (
parent.node.name !== 'input' ||
!/radio|checkbox|range|color/.test(parent.node.getStaticAttributeValue('type'))
this.needsLock = !this.isReadOnly && (
// TODO others?
parent.node.name !== 'input'
);
}
@ -97,45 +101,47 @@ export default class BindingWrapper {
}
render(block: Block, lock: string) {
// bind:offsetWidth and bind:offsetHeight — readonly
if (dimensions.test(this.node.name)) return;
if (this.isReadOnly) return;
const { parent } = this;
const { renderer } = parent;
let updateConditions: string[] = this.needsLock ? [`!${lock}`] : [];
// model to view
let updateDom = getDomUpdater(parent, this);
let initialUpdate = updateDom;
// special cases
if (this.node.name === 'group') {
const bindingGroup = getBindingGroup(renderer, this.node.expression.node);
block.builders.hydrate.addLine(
`(#component.$$.binding_groups[${bindingGroup}] || (#component.$$.binding_groups[${bindingGroup}] = [])).push(${parent.var});`
);
block.builders.destroy.addLine(
`#component.$$.binding_groups[${bindingGroup}].splice(#component.$$.binding_groups[${bindingGroup}].indexOf(${parent.var}), 1);`
);
}
if (this.node.name === 'currentTime' || this.node.name === 'volume') {
updateConditions.push(`!isNaN(${this.snippet})`);
if (this.node.name === 'currentTime') initialUpdate = null;
}
if (this.node.name === 'paused') {
// this is necessary to prevent audio restarting by itself
const last = block.getUniqueName(`${parent.var}_is_paused`);
block.addVariable(last, 'true');
updateConditions.push(`${last} !== (${last} = ${this.snippet})`);
updateDom = `${parent.var}[${last} ? "pause" : "play"]();`;
initialUpdate = null;
switch (this.node.name) {
case 'group':
const bindingGroup = getBindingGroup(parent.renderer, this.node.expression.node);
block.builders.hydrate.addLine(
`(#component.$$.binding_groups[${bindingGroup}] || (#component.$$.binding_groups[${bindingGroup}] = [])).push(${parent.var});`
);
block.builders.destroy.addLine(
`#component.$$.binding_groups[${bindingGroup}].splice(#component.$$.binding_groups[${bindingGroup}].indexOf(${parent.var}), 1);`
);
break;
case 'currentTime':
case 'volume':
updateConditions.push(`!isNaN(${this.snippet})`);
break;
case 'paused':
// this is necessary to prevent audio restarting by itself
const last = block.getUniqueName(`${parent.var}_is_paused`);
block.addVariable(last, 'true');
updateConditions.push(`${last} !== (${last} = ${this.snippet})`);
updateDom = `${parent.var}[${last} ? "pause" : "play"]();`;
break;
case 'value':
if (parent.getStaticAttributeValue('type') === 'file') {
updateDom = null;
}
}
const dependencyArray = [...this.node.expression.dynamic_dependencies]
@ -154,8 +160,8 @@ export default class BindingWrapper {
);
}
if (initialUpdate) {
block.builders.mount.addBlock(initialUpdate);
if (!/(currentTime|paused)/.test(this.node.name)) {
block.builders.mount.addBlock(updateDom);
}
}
}

@ -370,13 +370,7 @@ export default class ElementWrapper extends Wrapper {
renderer.component.has_reactive_assignments = true;
const needsLock = this.node.name !== 'input' || !/radio|checkbox|range|color/.test(this.getStaticAttributeValue('type'));
// TODO munge in constructor
// const mungedBindings = this.bindings.map(binding => binding.munge(block));
const mungedBindings = this.bindings;
const lock = mungedBindings.some(binding => binding.needsLock) ?
const lock = this.bindings.some(binding => binding.needsLock) ?
block.getUniqueName(`${this.var}_updating`) :
null;
@ -385,7 +379,7 @@ export default class ElementWrapper extends Wrapper {
const groups = events
.map(event => ({
events: event.eventNames,
bindings: mungedBindings
bindings: this.bindings
.filter(binding => binding.node.name !== 'this')
.filter(binding => event.filter(this.node, binding.node.name))
}))
@ -411,8 +405,6 @@ export default class ElementWrapper extends Wrapper {
binding.render(block, lock);
});
const mutations = group.bindings.map(binding => binding.handler.mutation).filter(Boolean).join('\n');
// media bindings — awkward special case. The native timeupdate events
// fire too infrequently, so we need to take matters into our
// own hands
@ -422,47 +414,35 @@ export default class ElementWrapper extends Wrapper {
block.addVariable(animation_frame);
}
const has_local_function = contextual_dependencies.size > 0 || needsLock || animation_frame;
let callee;
// TODO dry this out — similar code for event handlers and component bindings
if (contextual_dependencies.size > 0) {
const deps = Array.from(contextual_dependencies);
if (has_local_function) {
// need to create a block-local function that calls an instance-level function
block.builders.init.addBlock(deindent`
function ${handler}() {
ctx.${handler}.call(this, ctx);
}
`);
this.renderer.component.partly_hoisted.push(deindent`
function ${handler}({ ${deps.join(', ')} }) {
${
animation_frame && deindent`
cancelAnimationFrame(${animation_frame});
if (!${this.var}.paused) ${animation_frame} = requestAnimationFrame(${handler});`
}
${mutations.length > 0 && mutations}
${Array.from(dependencies).map(dep => `$$invalidate('${dep}', ${dep});`)}
${animation_frame && deindent`
cancelAnimationFrame(${animation_frame});
if (!${this.var}.paused) ${animation_frame} = requestAnimationFrame(${handler});`}
${needsLock && `${lock} = true;`}
ctx.${handler}.call(${this.var}${contextual_dependencies.size > 0 ? ', ctx' : ''});
}
`);
callee = handler;
} else {
this.renderer.component.partly_hoisted.push(deindent`
function ${handler}() {
${
animation_frame && deindent`
cancelAnimationFrame(${animation_frame});
if (!${this.var}.paused) ${animation_frame} = requestAnimationFrame(${handler});`
}
${mutations.length > 0 && mutations}
${Array.from(dependencies).map(dep => `$$invalidate('${dep}', ${dep});`)}
}
`);
callee = `ctx.${handler}`;
}
this.renderer.component.partly_hoisted.push(deindent`
function ${handler}(${contextual_dependencies.size > 0 ? `{ ${[...contextual_dependencies].join(', ')} }` : ``}) {
${group.bindings.map(b => b.handler.mutation)}
${Array.from(dependencies).map(dep => `$$invalidate('${dep}', ${dep});`)}
}
`);
group.events.forEach(name => {
if (name === 'resize') {
// special case
@ -488,8 +468,9 @@ export default class ElementWrapper extends Wrapper {
.join(' || ');
if (this.node.name === 'select' || group.bindings.find(binding => binding.node.name === 'indeterminate' || binding.isReadOnlyMediaAttribute())) {
const callback = has_local_function ? handler : `() => ${callee}.call(${this.var})`;
block.builders.hydrate.addLine(
`if (${someInitialStateIsUndefined}) @add_render_callback(() => ${callee}.call(${this.var}));`
`if (${someInitialStateIsUndefined}) @add_render_callback(${callback});`
);
}
@ -500,6 +481,10 @@ export default class ElementWrapper extends Wrapper {
}
});
if (lock) {
block.builders.update.addLine(`${lock} = false;`);
}
const this_binding = this.bindings.find(b => b.node.name === 'this');
if (this_binding) {
const name = renderer.component.getUniqueName(`${this.var}_binding`);

@ -1,8 +1,8 @@
/* generated by Svelte vX.Y.Z */
import { SvelteComponent as SvelteComponent_1, addListener, createElement, detachNode, flush, init, insert, run, safe_not_equal, setAttribute } from "svelte/internal";
import { SvelteComponent as SvelteComponent_1, addListener, createElement, detachNode, flush, init, insert, noop, run, safe_not_equal, setAttribute } from "svelte/internal";
function create_fragment(component, ctx) {
var input, input_updating = false, current, dispose;
var input, current, dispose;
return {
c() {
@ -14,15 +14,10 @@ function create_fragment(component, ctx) {
m(target, anchor) {
insert(target, input, anchor);
input.files = ctx.files;
current = true;
},
p(changed, ctx) {
if (!input_updating && changed.files) input.files = ctx.files;
},
p: noop,
i(target, anchor) {
if (current) return;

@ -2,55 +2,40 @@
import { SvelteComponent as SvelteComponent_1, addListener, add_render_callback, createElement, detachNode, flush, init, insert, run, run_all, safe_not_equal, timeRangesToArray } from "svelte/internal";
function create_fragment(component, ctx) {
var audio, audio_is_paused = true, audio_updating = false, audio_animationframe, current, dispose;
var audio, audio_updating = false, audio_animationframe, audio_is_paused = true, current, dispose;
function audio_timeupdate_handler() {
cancelAnimationFrame(audio_animationframe);
if (!audio.paused) audio_animationframe = requestAnimationFrame(audio_timeupdate_handler);
audio_updating = true;
ctx.audio_timeupdate_handler(audio);
}
function audio_durationchange_handler() {
audio_updating = true;
ctx.audio_durationchange_handler(audio);
ctx.audio_timeupdate_handler.call(audio);
}
function audio_play_pause_handler() {
audio_updating = true;
ctx.audio_durationchange_handler(audio);
}
function audio_progress_handler() {
audio_updating = true;
ctx.audio_progress_handler(audio);
}
function audio_loadedmetadata_handler() {
audio_updating = true;
ctx.audio_loadedmetadata_handler(audio);
ctx.audio_play_pause_handler.call(audio);
}
function audio_volumechange_handler() {
audio_updating = true;
ctx.audio_volumechange_handler(audio);
ctx.audio_volumechange_handler.call(audio);
}
return {
c() {
audio = createElement("audio");
if (ctx.played === void 0 || ctx.currentTime === void 0) add_render_callback(audio_timeupdate_handler);
if (ctx.duration === void 0) add_render_callback(audio_durationchange_handler);
if (ctx.buffered === void 0) add_render_callback(audio_progress_handler);
if (ctx.buffered === void 0 || ctx.seekable === void 0) add_render_callback(audio_loadedmetadata_handler);
if (ctx.duration === void 0) add_render_callback(() => ctx.audio_durationchange_handler.call(audio));
if (ctx.buffered === void 0) add_render_callback(() => ctx.audio_progress_handler.call(audio));
if (ctx.buffered === void 0 || ctx.seekable === void 0) add_render_callback(() => ctx.audio_loadedmetadata_handler.call(audio));
dispose = [
addListener(audio, "timeupdate", audio_timeupdate_handler),
addListener(audio, "durationchange", audio_durationchange_handler),
addListener(audio, "durationchange", ctx.audio_durationchange_handler),
addListener(audio, "play", audio_play_pause_handler),
addListener(audio, "pause", audio_play_pause_handler),
addListener(audio, "progress", audio_progress_handler),
addListener(audio, "loadedmetadata", audio_loadedmetadata_handler),
addListener(audio, "progress", ctx.audio_progress_handler),
addListener(audio, "loadedmetadata", ctx.audio_loadedmetadata_handler),
addListener(audio, "volumechange", audio_volumechange_handler)
];
},
@ -67,7 +52,6 @@ function create_fragment(component, ctx) {
if (!audio_updating && !isNaN(ctx.currentTime) && changed.currentTime) audio.currentTime = ctx.currentTime;
if (!audio_updating && audio_is_paused !== (audio_is_paused = ctx.paused) && changed.paused) audio[audio_is_paused ? "pause" : "play"]();
if (!audio_updating && !isNaN(ctx.volume) && changed.volume) audio.volume = ctx.volume;
audio_updating = false;
},
@ -91,30 +75,38 @@ function create_fragment(component, ctx) {
function instance($$self, $$props, $$invalidate) {
let { buffered, seekable, played, currentTime, duration, paused, volume } = $$props;
function audio_timeupdate_handler(audio) {
$$invalidate('played', played = timeRangesToArray(audio.played));
$$invalidate('currentTime', currentTime = audio.currentTime);
function audio_timeupdate_handler() {
played = timeRangesToArray(this.played);
currentTime = this.currentTime;
$$invalidate('played', played);
$$invalidate('currentTime', currentTime);
}
function audio_durationchange_handler(audio) {
$$invalidate('duration', duration = audio.duration);
function audio_durationchange_handler() {
duration = this.duration;
$$invalidate('duration', duration);
}
function audio_play_pause_handler(audio) {
$$invalidate('paused', paused = audio.paused);
function audio_play_pause_handler() {
paused = this.paused;
$$invalidate('paused', paused);
}
function audio_progress_handler(audio) {
$$invalidate('buffered', buffered = timeRangesToArray(audio.buffered));
function audio_progress_handler() {
buffered = timeRangesToArray(this.buffered);
$$invalidate('buffered', buffered);
}
function audio_loadedmetadata_handler(audio) {
$$invalidate('buffered', buffered = timeRangesToArray(audio.buffered));
$$invalidate('seekable', seekable = timeRangesToArray(audio.seekable));
function audio_loadedmetadata_handler() {
buffered = timeRangesToArray(this.buffered);
seekable = timeRangesToArray(this.seekable);
$$invalidate('buffered', buffered);
$$invalidate('seekable', seekable);
}
function audio_volumechange_handler(audio) {
$$invalidate('volume', volume = audio.volume);
function audio_volumechange_handler() {
volume = this.volume;
$$invalidate('volume', volume);
}
$$self.$set = $$props => {

Loading…
Cancel
Save