ソースを参照

LibWeb: Implement the `:seeking` pseudo-class

This matches while a media element is seeking.
Sam Atkins 2 年 前
コミット
7b4ae43b91

+ 2 - 0
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -503,6 +503,8 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Paused);
         if (pseudo_name.equals_ignoring_ascii_case("root"sv))
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Root);
+        if (pseudo_name.equals_ignoring_ascii_case("seeking"sv))
+            return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Seeking);
         if (pseudo_name.equals_ignoring_ascii_case("host"sv))
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Host);
         if (pseudo_name.equals_ignoring_ascii_case("visited"sv))

+ 1 - 0
Userland/Libraries/LibWeb/CSS/Selector.cpp

@@ -233,6 +233,7 @@ ErrorOr<String> Selector::SimpleSelector::serialize() const
         case Selector::SimpleSelector::PseudoClass::Type::Defined:
         case Selector::SimpleSelector::PseudoClass::Type::Playing:
         case Selector::SimpleSelector::PseudoClass::Type::Paused:
+        case Selector::SimpleSelector::PseudoClass::Type::Seeking:
             // If the pseudo-class does not accept arguments append ":" (U+003A), followed by the name of the pseudo-class, to s.
             TRY(s.try_append(':'));
             TRY(s.try_append(pseudo_class_name(pseudo_class.type)));

+ 3 - 0
Userland/Libraries/LibWeb/CSS/Selector.h

@@ -117,6 +117,7 @@ public:
                 Defined,
                 Playing,
                 Paused,
+                Seeking,
             };
             Type type;
 
@@ -310,6 +311,8 @@ constexpr StringView pseudo_class_name(Selector::SimpleSelector::PseudoClass::Ty
         return "playing"sv;
     case Selector::SimpleSelector::PseudoClass::Type::Paused:
         return "paused"sv;
+    case Selector::SimpleSelector::PseudoClass::Type::Seeking:
+        return "seeking"sv;
     }
     VERIFY_NOT_REACHED();
 }

+ 6 - 0
Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp

@@ -389,6 +389,12 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
         auto const& media_element = static_cast<HTML::HTMLMediaElement const&>(element);
         return media_element.paused();
     }
+    case CSS::Selector::SimpleSelector::PseudoClass::Type::Seeking: {
+        if (!is<HTML::HTMLMediaElement>(element))
+            return false;
+        auto const& media_element = static_cast<HTML::HTMLMediaElement const&>(element);
+        return media_element.seeking();
+    }
     }
 
     return false;

+ 3 - 0
Userland/Libraries/LibWeb/Dump.cpp

@@ -548,6 +548,9 @@ void dump_selector(StringBuilder& builder, CSS::Selector const& selector)
                 case CSS::Selector::SimpleSelector::PseudoClass::Type::Paused:
                     pseudo_class_description = "Paused";
                     break;
+                case CSS::Selector::SimpleSelector::PseudoClass::Type::Seeking:
+                    pseudo_class_description = "Seeking";
+                    break;
                 }
 
                 builder.appendff(" pseudo_class={}", pseudo_class_description);

+ 12 - 3
Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp

@@ -212,6 +212,14 @@ WebIDL::ExceptionOr<Bindings::CanPlayTypeResult> HTMLMediaElement::can_play_type
     return Bindings::CanPlayTypeResult::Empty;
 }
 
+void HTMLMediaElement::set_seeking(bool seeking)
+{
+    if (m_seeking == seeking)
+        return;
+    m_seeking = seeking;
+    set_needs_style_update(true);
+}
+
 // https://html.spec.whatwg.org/multipage/media.html#dom-media-load
 WebIDL::ExceptionOr<void> HTMLMediaElement::load()
 {
@@ -505,7 +513,8 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::load_element()
         }
 
         // 7. If seeking is true, set it to false.
-        m_seeking = false;
+        if (seeking())
+            set_seeking(false);
 
         // 8. Set the current playback position to 0.
         m_current_playback_position = 0;
@@ -1490,7 +1499,7 @@ void HTMLMediaElement::seek_element(double playback_position, MediaSeekMode seek
     }
 
     // 4. Set the seeking IDL attribute to true.
-    m_seeking = true;
+    set_seeking(true);
 
     // FIXME: 5. If the seek was in response to a DOM method call or setting of an IDL attribute, then continue the script. The
     //           remainder of these steps must be run in parallel. With the exception of the steps marked with ⌛, they could be
@@ -1534,7 +1543,7 @@ void HTMLMediaElement::seek_element(double playback_position, MediaSeekMode seek
     //            synchronous section are marked with ⌛.)
 
     // 14. ⌛ Set the seeking IDL attribute to false.
-    m_seeking = false;
+    set_seeking(false);
 
     // 15. ⌛ Run the time marches on steps.
     time_marches_on(TimeMarchesOnReason::Other);

+ 1 - 0
Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h

@@ -70,6 +70,7 @@ public:
     ReadyState ready_state() const { return m_ready_state; }
 
     bool seeking() const { return m_seeking; }
+    void set_seeking(bool);
 
     WebIDL::ExceptionOr<void> load();