sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.75k stars 4.13k forks source link

Binded volume parameter returning undefined #8006

Open Layendan opened 1 year ago

Layendan commented 1 year ago

Describe the bug

When using bind:volume on video (did not test on audio track), it returns undefined instead of a number from 0-1.

Reproduction

REPL for reproduction based on media element bindings tutorial REPL: https://svelte.dev/repl/d4acb0c4bf3e42efbc41d289f33ee359?version=3.52.0 ^ Click on video and check console, you can keep clicking to see that it only returns undefined. Tutorial: https://svelte.dev/tutorial/media-elements

Logs

No response

System Info

System:
    OS: macOS 13.0
    CPU: (8) arm64 Apple M1
    Memory: 687.88 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.0.0 - /usr/local/bin/node
    Yarn: 1.22.19 - ~/.yarn/bin/yarn
    npm: 8.6.0 - /usr/local/bin/npm
  Browsers:
    Chrome: 107.0.5304.110
    Safari: 16.1
  npmPackages:
    svelte: ^3.52.0 => 3.52.0

Severity

annoyance

brunnerh commented 1 year ago

The volume binding is provided by the volumechange event. If the user does not interact with the volume controls, this event will never fire.

Maybe code could be generated that reads the value once, if the bound variable is undefined. As a workaround, just initialize the variable yourself.

Conduitry commented 1 year ago

The .volume prop is set on the DOM element right away though, I'm not sure why we're not running the code once upon creation that would grab that volume even before the event has fired once, like we're doing for the other types of bindings.

Layendan commented 1 year ago

Can confirm that initializing it fixes the problem. However, I feel like that's counter-intuitive as all other bindings do not need initialization.

Maybe we could just do one of these:

brunnerh commented 1 year ago

@Conduitry Can you give an example for where that happens? I assumed that it might happen on input elements, but to my surprise that does not seem to be the case.

<script>
    let value;
    let checked;
</script>

<input type=text bind:value />
<input type=checkbox bind:checked />

<p>{value}</p>
<p>{checked}</p>

REPL

Both value and checked are undefined until user interaction.


@Layendan It should not be initialized to 1 but simply the value of the DOM property as @Conduitry suggested. You cannot assume 1 because user agents may use different defaults.

You can easily read the value yourself with an action, by the way:

<script>
    let volume;
    const action = (node, callback) => callback(node);
</script>

<!-- svelte-ignore a11y-media-has-caption -->
<video src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
    use:action={v => volume = v.volume}
    bind:volume
    controls />

<div>Volume: {volume}</div>

REPL

RaiVaibhav commented 1 year ago

@Conduitry I would like to work on this issue, there is few things here I noticed.

like we're doing for the other types of bindings. what do you mean here? the initial value of the state inside the instance is same as the value provided.

RaiVaibhav commented 5 months ago

Replying very late :( , but I would like to pick to this up @Rich-Harris

RaiVaibhav commented 5 months ago

Btw this is not reproducible in the latest version of svelte.