@@ -99,6 +99,8 @@ void Page::visit_edges(JS::Cell::Visitor& visitor)
9999 visitor.visit (m_window_rect_observer);
100100 visitor.visit (m_on_pending_dialog_closed);
101101 visitor.visit (m_pending_clipboard_requests);
102+ for (auto const & request : m_pending_geolocation_requests)
103+ visitor.visit (request.value .callback );
102104 m_pending_fullscreen_operations.for_each ([&](auto const & operation) {
103105 operation.visit ([&](PendingFullscreenEnter const & enter_operation) {
104106 visitor.visit (enter_operation.element );
@@ -677,6 +679,86 @@ void Page::retrieved_clipboard_entries(u64 request_id, Vector<Clipboard::SystemC
677679 (*request)->function ()(move (items));
678680}
679681
682+ u64 Page::request_geolocation_position (GeolocationPositionCallback callback, GeolocationRequestType type)
683+ {
684+ // AD-HOC: This is the browser-process bridge for the Geolocation spec's "try to acquire position data from the
685+ // underlying system" step.
686+ auto request_id = m_next_geolocation_request_id++;
687+ m_pending_geolocation_requests.set (request_id, PendingGeolocationRequest {
688+ .callback = callback,
689+ .type = type,
690+ });
691+
692+ if (type == GeolocationRequestType::Watch) {
693+ client ().page_did_start_geolocation_position_watch (request_id);
694+ return request_id;
695+ }
696+
697+ if (!m_active_geolocation_request_id.has_value ()) {
698+ m_active_geolocation_request_id = request_id;
699+ client ().page_did_request_geolocation_position (request_id);
700+ }
701+
702+ return request_id;
703+ }
704+
705+ void Page::cancel_geolocation_position_request (u64 request_id)
706+ {
707+ auto request = m_pending_geolocation_requests.take (request_id);
708+ if (!request.has_value ())
709+ return ;
710+
711+ if (request->type == GeolocationRequestType::Watch) {
712+ client ().page_did_stop_geolocation_position_watch (request_id);
713+ return ;
714+ }
715+
716+ if (m_active_geolocation_request_id != request_id)
717+ return ;
718+
719+ m_active_geolocation_request_id = {};
720+ for (auto const & entry : m_pending_geolocation_requests) {
721+ if (entry.value .type == GeolocationRequestType::OneShot) {
722+ m_active_geolocation_request_id = entry.key ;
723+ client ().page_did_request_geolocation_position (entry.key );
724+ return ;
725+ }
726+ }
727+ }
728+
729+ void Page::receive_geolocation_position (u64 request_id, Optional<Geolocation::CoordinatesData> coordinates, Optional<Geolocation::GeolocationPositionError::ErrorCode> error)
730+ {
731+ auto request = m_pending_geolocation_requests.get (request_id);
732+ if (!request.has_value ())
733+ return ;
734+
735+ if (request->type == GeolocationRequestType::Watch) {
736+ auto callback = request->callback ;
737+ callback->function ()(coordinates, error);
738+ return ;
739+ }
740+
741+ if (m_active_geolocation_request_id != request_id)
742+ return ;
743+
744+ m_active_geolocation_request_id = {};
745+
746+ Vector<GeolocationPositionCallback> callbacks;
747+ Vector<u64 > completed_request_ids;
748+ for (auto const & entry : m_pending_geolocation_requests) {
749+ if (entry.value .type != GeolocationRequestType::OneShot)
750+ continue ;
751+ callbacks.append (entry.value .callback );
752+ completed_request_ids.append (entry.key );
753+ }
754+
755+ for (auto completed_request_id : completed_request_ids)
756+ m_pending_geolocation_requests.remove (completed_request_id);
757+
758+ for (auto const & callback : callbacks)
759+ callback->function ()(coordinates, error);
760+ }
761+
680762void Page::register_media_element (Badge<HTML ::HTMLMediaElement>, UniqueNodeID media_id)
681763{
682764 m_media_elements.append (media_id);
0 commit comments