Browse Source

LibWeb: Add a document observer for visibility state changes

Timothy Flynn 8 months ago
parent
commit
9e10010c54

+ 5 - 1
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -2729,7 +2729,11 @@ void Document::update_the_visibility_state(HTML::VisibilityState visibility_stat
     // 2. Set document's visibility state to visibilityState.
     m_visibility_state = visibility_state;
 
-    // FIXME: 3. Run any page visibility change steps which may be defined in other specifications, with visibility state and document.
+    // 3. Run any page visibility change steps which may be defined in other specifications, with visibility state and document.
+    for (auto document_observer : m_document_observers) {
+        if (document_observer->document_visibility_state_observer())
+            document_observer->document_visibility_state_observer()->function()(m_visibility_state);
+    }
 
     // 4. Fire an event named visibilitychange at document, with its bubbles attribute initialized to true.
     auto event = DOM::Event::create(realm(), HTML::EventNames::visibilitychange);

+ 1 - 0
Userland/Libraries/LibWeb/DOM/Document.h

@@ -430,6 +430,7 @@ public:
 
     bool hidden() const;
     StringView visibility_state() const;
+    HTML::VisibilityState visibility_state_value() const { return m_visibility_state; }
 
     // https://html.spec.whatwg.org/multipage/interaction.html#update-the-visibility-state
     void update_the_visibility_state(HTML::VisibilityState);

+ 9 - 0
Userland/Libraries/LibWeb/DOM/DocumentObserver.cpp

@@ -26,6 +26,7 @@ void DocumentObserver::visit_edges(Cell::Visitor& visitor)
     visitor.visit(m_document_became_inactive);
     visitor.visit(m_document_completely_loaded);
     visitor.visit(m_document_readiness_observer);
+    visitor.visit(m_document_visibility_state_observer);
 }
 
 void DocumentObserver::finalize()
@@ -58,4 +59,12 @@ void DocumentObserver::set_document_readiness_observer(Function<void(HTML::Docum
         m_document_readiness_observer = nullptr;
 }
 
+void DocumentObserver::set_document_visibility_state_observer(Function<void(HTML::VisibilityState)> callback)
+{
+    if (callback)
+        m_document_visibility_state_observer = JS::create_heap_function(vm().heap(), move(callback));
+    else
+        m_document_visibility_state_observer = nullptr;
+}
+
 }

+ 5 - 0
Userland/Libraries/LibWeb/DOM/DocumentObserver.h

@@ -12,6 +12,7 @@
 #include <LibWeb/Bindings/PlatformObject.h>
 #include <LibWeb/Forward.h>
 #include <LibWeb/HTML/DocumentReadyState.h>
+#include <LibWeb/HTML/VisibilityState.h>
 
 namespace Web::DOM {
 
@@ -29,6 +30,9 @@ public:
     [[nodiscard]] JS::GCPtr<JS::HeapFunction<void(HTML::DocumentReadyState)>> document_readiness_observer() const { return m_document_readiness_observer; }
     void set_document_readiness_observer(Function<void(HTML::DocumentReadyState)>);
 
+    [[nodiscard]] JS::GCPtr<JS::HeapFunction<void(HTML::VisibilityState)>> document_visibility_state_observer() const { return m_document_visibility_state_observer; }
+    void set_document_visibility_state_observer(Function<void(HTML::VisibilityState)>);
+
 private:
     explicit DocumentObserver(JS::Realm&, DOM::Document&);
 
@@ -39,6 +43,7 @@ private:
     JS::GCPtr<JS::HeapFunction<void()>> m_document_became_inactive;
     JS::GCPtr<JS::HeapFunction<void()>> m_document_completely_loaded;
     JS::GCPtr<JS::HeapFunction<void(HTML::DocumentReadyState)>> m_document_readiness_observer;
+    JS::GCPtr<JS::HeapFunction<void(HTML::VisibilityState)>> m_document_visibility_state_observer;
 };
 
 }