Skip to content

Commit 90eb82c

Browse files
committed
Bug 1707584 - part2 : implement :seeking pseudo class. r=media-playback-reviewers,firefox-style-system-reviewers,emilio,chunmin
Per spec [1], :seeking should be set once `seeking attribute is true`, so the state needs to be setup in HTMLMediaElement::Seek() immediatley, so that the script can see the state applied right after updating the media's current time. [1] https://html.spec.whatwg.org/multipage/semantics-other.html#selector-seeking Differential Revision: https://phabricator.services.mozilla.com/D281038
1 parent 7edf28d commit 90eb82c

File tree

9 files changed

+17
-17
lines changed

9 files changed

+17
-17
lines changed

dom/base/rust/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use bitflags::bitflags;
88
use malloc_size_of::malloc_size_of_is_0;
99

10-
pub const HEADING_LEVEL_OFFSET: usize = 53;
10+
pub const HEADING_LEVEL_OFFSET: usize = 54;
1111

1212
bitflags! {
1313
/// Event-based element states.
@@ -146,6 +146,8 @@ bitflags! {
146146
const SUPPRESS_FOR_PRINT_SELECTION = 1u64 << 51;
147147
/// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-paused
148148
const PAUSED = 1u64 << 52;
149+
/// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-seeking
150+
const SEEKING = 1u64 << 53;
149151
/// https://drafts.csswg.org/selectors-5/#headings
150152
/// These 4 bits are used to pack the elements heading level into the element state
151153
/// Heading levels can be from 1-9 so 4 bits allows us to express the full range.

dom/media/mediaelement/HTMLMediaElement.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,6 +2474,11 @@ void HTMLMediaElement::AbortExistingLoads() {
24742474

24752475
if (mDecoder) {
24762476
fireTimeUpdate = mDecoder->GetCurrentTime() != 0.0;
2477+
// When aborting during seeking, remove the seeking state since the decoder
2478+
// won't call SeekCompleted() or SeekAborted() after being shut down.
2479+
if (Seeking()) {
2480+
RemoveStates(ElementState::SEEKING);
2481+
}
24772482
ShutdownDecoder();
24782483
}
24792484
if (mSrcStream) {
@@ -3555,6 +3560,7 @@ void HTMLMediaElement::Seek(double aTime, SeekTarget::Type aSeekType,
35553560
// The media backend is responsible for dispatching the timeupdate
35563561
// event if it changes the playback position as a result of the seek.
35573562
LOG(LogLevel::Debug, ("%p SetCurrentTime(%f) starting seek", this, aTime));
3563+
AddStates(ElementState::SEEKING);
35583564
mDecoder->Seek(aTime, aSeekType);
35593565

35603566
// We changed whether we're seeking so we need to AddRemoveSelfReference.
@@ -6182,6 +6188,7 @@ void HTMLMediaElement::SeekCompleted() {
61826188
// (Step 16)
61836189
// TODO (bug 1688131): run these steps in a stable state.
61846190
FireTimeUpdate(TimeupdateType::eMandatory);
6191+
RemoveStates(ElementState::SEEKING);
61856192
QueueEvent(u"seeked"_ns);
61866193
// We changed whether we're seeking so we need to AddRemoveSelfReference
61876194
AddRemoveSelfReference();
@@ -6199,6 +6206,7 @@ void HTMLMediaElement::SeekCompleted() {
61996206
}
62006207

62016208
void HTMLMediaElement::SeekAborted() {
6209+
RemoveStates(ElementState::SEEKING);
62026210
if (mSeekDOMPromise) {
62036211
AbstractMainThread()->Dispatch(NS_NewRunnableFunction(
62046212
__func__, [promise = std::move(mSeekDOMPromise)] {

servo/components/style/gecko/non_ts_pseudo_class_list.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ macro_rules! apply_non_ts_list {
9595
// Media element pseudo classes
9696
("paused", Paused, PAUSED, _),
9797
("playing", Playing, PAUSED, _),
98+
("seeking", Seeking, SEEKING, _),
9899

99100

100101
// NOTE(emilio): Pseudo-classes below only depend on document state, and thus

servo/components/style/gecko/selector_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl NonTSPseudoClass {
227227
if matches!(*self, Self::Heading(..)) {
228228
return static_prefs::pref!("layout.css.heading-selector.enabled");
229229
}
230-
if matches!(*self, Self::Playing | Self::Paused) {
230+
if matches!(*self, Self::Playing | Self::Paused | Self::Seeking) {
231231
return static_prefs::pref!("dom.media.pseudo-classes.enabled");
232232
}
233233
!self.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME)

servo/components/style/gecko/wrapper.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2085,7 +2085,8 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
20852085
| NonTSPseudoClass::MozRevealed
20862086
| NonTSPseudoClass::ActiveViewTransition
20872087
| NonTSPseudoClass::MozValueEmpty
2088-
| NonTSPseudoClass::MozSuppressForPrintSelection => {
2088+
| NonTSPseudoClass::MozSuppressForPrintSelection
2089+
| NonTSPseudoClass::Seeking => {
20892090
self.state().intersects(pseudo_class.state_flag())
20902091
},
20912092
NonTSPseudoClass::Paused => self.is_html_media_element() && self.state().intersects(ElementState::PAUSED),
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
[media-pseudo-classes-in-has.html]
22
prefs: [dom.media.pseudo-classes.enabled:true]
3-
[Test :seeking pseudo-class]
4-
expected: FAIL
5-
63
[Test :muted pseudo-class]
74
expected: FAIL

testing/web-platform/meta/css/selectors/media/media-playback-state-timing.html.ini

Lines changed: 0 additions & 3 deletions
This file was deleted.

testing/web-platform/meta/css/selectors/media/media-playback-state.html.ini

Lines changed: 0 additions & 6 deletions
This file was deleted.

testing/web-platform/tests/css/selectors/media/media-playback-state.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
}, "Test :seeking pseudo-class");
7676

7777
test((t) => {
78-
const pseudoClasses = [":playing", ":paused"];
78+
const pseudoClasses = [":playing", ":paused", ":seeking"];
7979
const div = document.createElement("div");
8080
document.body.appendChild(div);
8181
t.add_cleanup(() => div.remove());
@@ -84,6 +84,6 @@
8484
assert_false(div.matches(pseudo));
8585
assert_true(div.matches(`:not(${pseudo})`));
8686
}
87-
}, "Test that non-media elements do not match :playing or :paused");
87+
}, "Test that non-media elements do not match :playing, :paused, or :seeking");
8888
</script>
8989
</body>

0 commit comments

Comments
 (0)