Skip to content

Make muted content attribute affect muted IDL attribute only once#12473

Open
foolip wants to merge 1 commit into
mainfrom
foolip/muted-once
Open

Make muted content attribute affect muted IDL attribute only once#12473
foolip wants to merge 1 commit into
mainfrom
foolip/muted-once

Conversation

@foolip
Copy link
Copy Markdown
Member

@foolip foolip commented May 21, 2026

The purpose of this is to limit the cases where the muted IDL attribute
can change without a volumechange event firing.

The notion that user agents may remember volume and muted is removed as
it would require additional muted states to handle correctly, but could
be reinstated if there is implementer interest.

  • At least two implementers are interested (and none opposed):
  • Tests are written and can be reviewed and commented upon at:
  • Implementation bugs are filed:
    • Chromium: …
    • Gecko: …
    • WebKit: …
    • Deno (only for timers, structured clone, base64 utils, channel messaging, module resolution, web workers, and web storage): …
    • Node.js (only for timers, structured clone, base64 utils, channel messaging, and module resolution): …
  • Corresponding HTML AAM & ARIA in HTML issues & PRs:
  • MDN issue is filed: …
  • The top of this comment includes a clear commit message to use.

(See WHATWG Working Mode: Changes for more details.)


/media.html ( diff )

@annevk
Copy link
Copy Markdown
Member

annevk commented May 21, 2026

What do implementations do today? I'm pretty sure WebKit doesn't have a "set once" special case.

@foolip
Copy link
Copy Markdown
Member Author

foolip commented May 21, 2026

Chromium reacts to muted content attribute changes but only for AttributeModificationReason::kByParser which can only happen once in HTMLMediaElement::ParseAttribute().

Gecko seems to look at the muted content attribute in two places: in HTMLMediaElement::DoneCreatingElement() and in HTMLMediaElement::CopyInnerTo(), which maybe is for cloning, not sure.

WebKit has a tri-state optional bool m_implicitlyMuted and a boolean m_explicitlyMuted. I'm not sure about m_implicitlyMuted, but m_explicitlyMuted is used as a once-only state bit when setting m_muted from the attribute in two places: in MediaElement::postConnectionSteps() and in MediaElement::loadResource().

@foolip
Copy link
Copy Markdown
Member Author

foolip commented May 21, 2026

For Gecko, the MutedReasons is also interesting and confirms that playbackRate can mute in Gecko. Seems like that doesn't fire a "volumechange" event.

@foolip
Copy link
Copy Markdown
Member Author

foolip commented May 21, 2026

cc @whatwg/media for opinions on this. In short, the topic is how/when the muted content attribute affects the muted IDL attribute, and which changes in the muted IDL attribute should fire a volumechange event.

Recent changes here are #12389 and #12428.

@annevk
Copy link
Copy Markdown
Member

annevk commented May 24, 2026

I see, perhaps observing the muted content attribute in the post-connection steps is a good alternative to the fictional "creation time". As that is a well-defined point in time.

That would require changing the :muted tests again I suspect.

@foolip foolip force-pushed the foolip/muted-once branch from 249e5dc to f6b7b0e Compare May 25, 2026 21:16
The purpose of this is to limit the cases where the muted IDL attribute
can change without a volumechange event firing.

The notion that user agents may remember volume and muted is removed as
it would require additional muted states to handle correctly, but could
be reinstated if there is implementer interest.
@foolip foolip force-pushed the foolip/muted-once branch from f6b7b0e to 295bb37 Compare May 25, 2026 21:19
@foolip
Copy link
Copy Markdown
Member Author

foolip commented May 25, 2026

@annevk that works for me, I've updated this PR and tests in https://crrev.com/c/7857861 to match.

@foolip foolip added the agenda+ To be discussed at a triage meeting label May 26, 2026
Copy link
Copy Markdown
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the WebKit case of taking the muted content attribute into account when loading a new media resource?

Comment thread source
data-x="">default</code>". User agents may <span>set the muted state</span> of a <span>media
element</span> to true or false (e.g., remembering the last set value across sessions, on a
per-site basis or otherwise).</p>
state</dfn>, which is either true, false, or unset; it is initially unset.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not keep "default" here? We don't really have precedence for "unset" as a standalone value.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also wondering why we'd remove the allowance for user agents changing this state on behalf of the user. Isn't that needed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could keep it since it's not observable, any third state would do. But it doesn't line up defaultMuted any longer, in fact muted takes on the value of defaultMuted only when muted state is longer "default". How about "initial"?

I removed the allowance because I think no browser implements this and it would need a "remembered unmuted" state to prevent the muted content attribute from affecting .muted on insertion. But I can put it back and implementations can add whatever additional state they need to make it work.

Comment thread source
<p>A <span>media element</span> has a <dfn data-x="concept-media-volume">playback volume</dfn>, which is a fraction in the range 0.0 (silent) to 1.0 (loudest).
Initially, the volume should be 1.0, but user agents may remember the last set value across
sessions, on a per-site basis or otherwise, so the volume may start at other values.</p>
Initially, the volume should be 1.0.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why lose the language on letting it be configurable?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect it's spec fiction, but will put it back.

Comment thread source
<li>
<p>If <var>insertedNode</var> has a <code data-x="attr-media-muted">muted</code> attribute,
then set <var>insertedNode</var>'s <span data-x="concept-media-muted-state">muted state</span>
to true.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we only set it to true if it's "default"?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, this is essential for the "only once" part. I think it's also what WebKit does, so I'd like to change this to match.

I'll just note that there's also the option of always setting the muted state on insertion if muted state is "default", so that after the first insertion it's always true or false. The difference would be when inserting an element, adding the muted content attributes, and then inserting the element somewhere else. I'm not sure there's any point in having the muted content attribute have an effect on that second insertion, so maybe we change "default" to "initial" and it only stays in that state until the first insertion? It's effectively a "has ever been inserted" flag. WDYT?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In https://crrev.com/c/7857861 I have gone the route of always updating the muted state is post-insertion steps if muted was unset. I'll do that in the spec.

Comment thread source
data-x="dom-media-muted">muted</code> IDL attribute has changed. Fired after the relevant
attribute's setter has returned. The event is not fired in response to changes to <code
data-x="dom-media-playbackRate">playbackRate</code> or when inserting the element, even if
the <code data-x="dom-media-muted">muted</code> IDL attribute changes in response.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is non-normative I'm not sure we should elaborate on all the ins and outs. That might make people think these are the actual requirements.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert.

Comment thread source
<li>
<p>If <var>insertedNode</var> has a <code data-x="attr-media-muted">muted</code> attribute,
then set <var>insertedNode</var>'s <span data-x="concept-media-muted-state">muted state</span>
to true.</p>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this all mean with audio which works somewhat fine whether or not it is ever connected.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The muted content attribute would have no effect on such an audio element. That's the same as the current behavior, AFAICT no browser would mute in this situation:

var a = document.createElement('audio')`;
a.setAttribute('muted', '');
a.src = '...';
a.play();

If such code exists, it's silly but would continue to work.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if you create the audio element using innerHTML (on a disconnected element) and it has muted attribute, both Firefox and Chrome keep it muted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agenda+ To be discussed at a triage meeting topic: media

Development

Successfully merging this pull request may close these issues.

3 participants