diff --git a/Libraries/LibWeb/Geolocation/Geolocation.cpp b/Libraries/LibWeb/Geolocation/Geolocation.cpp index 4dcf2e541f..f0aa0a4aba 100644 --- a/Libraries/LibWeb/Geolocation/Geolocation.cpp +++ b/Libraries/LibWeb/Geolocation/Geolocation.cpp @@ -7,14 +7,17 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -324,15 +327,17 @@ void Geolocation::request_a_position(GC::Ref success_callb // 2. Continue to the next steps below. // AD-HOC: This is implemented by run_in_parallel_when_document_is_visible(). - // FIXME: 6. Let descriptor be a new PermissionDescriptor whose name is "geolocation". + // 6. Let descriptor be a new PermissionDescriptor whose name is "geolocation". + auto descriptor = Bindings::PermissionDescriptor { "geolocation"_string }; // 7. In parallel: // AD-HOC: run_in_parallel_when_document_is_visible() already runs this in parallel. { - // FIXME: 1. Set permission to request permission to use descriptor. + // 1. Set permission to request permission to use descriptor. + auto permission = Web::PermissionsAPI::request_permission(descriptor); - // FIXME: 2. If permission is "denied", then: - if (false) { + // 2. If permission is "denied", then: + if (permission == Bindings::PermissionState::Denied) { // 1. If watchId was passed, remove watchId from watchIDs. if (watch_id.has_value()) m_watch_ids.remove(watch_id.value()); @@ -371,7 +376,11 @@ void Geolocation::run_in_parallel_when_document_is_visible(DOM::Document& docume { // Run callback in parallel if the document is already visible. if (document.visibility_state_value() == HTML::VisibilityState::Visible) { - Platform::EventLoopPlugin::the().deferred_invoke(callback); + auto callback_with_context = GC::create_function(heap(), [this, callback] { + HTML::TemporaryExecutionContext execution_context { realm() }; + callback->function()(); + }); + Platform::EventLoopPlugin::the().deferred_invoke(callback_with_context); return; } @@ -389,9 +398,10 @@ void Geolocation::run_in_parallel_when_document_is_visible(DOM::Document& docume clear_observer_and_timer(); }); - document_observer->set_document_visibility_state_observer([clear_observer_and_timer, callback](HTML::VisibilityState state) { + document_observer->set_document_visibility_state_observer([this, clear_observer_and_timer, callback](HTML::VisibilityState state) { if (state == HTML::VisibilityState::Visible) { clear_observer_and_timer(); + HTML::TemporaryExecutionContext execution_context { realm() }; callback->function()(); } }); diff --git a/Libraries/LibWeb/PermissionsAPI/Permissions.cpp b/Libraries/LibWeb/PermissionsAPI/Permissions.cpp index 79564069dc..325114ac3d 100644 --- a/Libraries/LibWeb/PermissionsAPI/Permissions.cpp +++ b/Libraries/LibWeb/PermissionsAPI/Permissions.cpp @@ -20,12 +20,50 @@ namespace Web::PermissionsAPI { -bool is_permission_supported(String const&) +bool is_permission_supported(String const& name) { - // FIXME: Actually support permissions + if (name == "geolocation") { + return true; + } return false; } +// https://w3c.github.io/permissions/#dfn-request-permission-to-use +Bindings::PermissionState request_permission(Bindings::PermissionDescriptor const& descriptor) +{ + // 1. Let current state be the descriptor's permission state. + auto current_state = permission_state(descriptor); + + // 2. If current state is not "prompt", return current state and abort these steps. + if (current_state != Bindings::PermissionState::Prompt) + return current_state; + + // FIXME: 3. Ask the user for express permission for the calling algorithm to use the powerful feature described by descriptor. + + // 4. If the user gives express permission to use the powerful feature, set current state to "granted"; otherwise to "denied". + // The user's interaction may provide new information about the user's intent for the origin. + if (false) { + current_state = Bindings::PermissionState::Granted; + } else { + current_state = Bindings::PermissionState::Denied; + } + + // 5. Let settings be the current settings object. + auto& settings = HTML::current_settings_object(); + + // 6. Let key be the result of generating a permission key for descriptor with settings's top-level origin and settings's origin. + VERIFY(settings.top_level_origin.has_value()); + auto key = permission_key_generation_algorithm(settings.top_level_origin.value(), settings.origin()); + + // 7. Queue a task on the current settings object's responsible event loop to set a permission store entry with descriptor, key, and current state. + HTML::queue_global_task(HTML::Task::Source::Permissions, settings.global_object(), GC::create_function(settings.realm().heap(), [descriptor, key, current_state] { + PermissionStore::the().set_permission_store_entry(descriptor, key, current_state); + })); + + // 8. Return current state. + return current_state; +} + // https://w3c.github.io/permissions/#dfn-permission-state Bindings::PermissionState permission_state(Bindings::PermissionDescriptor descriptor, Optional settings) { diff --git a/Libraries/LibWeb/PermissionsAPI/Permissions.h b/Libraries/LibWeb/PermissionsAPI/Permissions.h index 1c28d3e9d9..7890efebe0 100644 --- a/Libraries/LibWeb/PermissionsAPI/Permissions.h +++ b/Libraries/LibWeb/PermissionsAPI/Permissions.h @@ -20,6 +20,8 @@ Bindings::PermissionState permission_state(Bindings::PermissionDescriptor descri Bindings::PermissionState get_current_permission_state(String const& name, Optional settings = {}); +Bindings::PermissionState request_permission(Bindings::PermissionDescriptor const& descriptor); + class WEB_API Permissions : public Bindings::PlatformObject { WEB_PLATFORM_OBJECT(Permissions, Bindings::PlatformObject); GC_DECLARE_ALLOCATOR(Permissions); diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 63ef842f98..5dd33f313c 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -353,6 +353,8 @@ PerformanceObserverEntryList PerformanceResourceTiming PerformanceTiming PeriodicWave +PermissionStatus +Permissions Plugin PluginArray PointerEvent diff --git a/Tests/LibWeb/Text/expected/wpt-import/permissions/all-permissions.txt b/Tests/LibWeb/Text/expected/wpt-import/permissions/all-permissions.txt new file mode 100644 index 0000000000..151a0b193c --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/permissions/all-permissions.txt @@ -0,0 +1,25 @@ +Harness status: OK + +Found 19 tests + +1 Pass +18 Fail +Fail Query "camera" permission +Pass Query "geolocation" permission +Fail Query "microphone" permission +Fail Query "notifications" permission +Fail Query "persistent-storage" permission +Fail Query "push" permission +Fail Query "accelerometer" permission +Fail Query "ambient-light-sensor" permission +Fail Query "background-fetch" permission +Fail Query "background-sync" permission +Fail Query "bluetooth" permission +Fail Query "gyroscope" permission +Fail Query "magnetometer" permission +Fail Query "midi" permission +Fail Query "nfc" permission +Fail Query "screen-wake-lock" permission +Fail Query "display-capture" permission +Fail Query "speaker-selection" permission +Fail Query "xr-spatial-tracking" permission \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/permissions/permissionsstatus-name.txt b/Tests/LibWeb/Text/expected/wpt-import/permissions/permissionsstatus-name.txt new file mode 100644 index 0000000000..5cdc172611 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/permissions/permissionsstatus-name.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Test PermissionStatus's name attribute. \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/permissions/all-permissions.html b/Tests/LibWeb/Text/input/wpt-import/permissions/all-permissions.html new file mode 100644 index 0000000000..bde6c0d089 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/permissions/all-permissions.html @@ -0,0 +1,43 @@ + + +Test all known permissions support + + +
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/permissions/permissionsstatus-name.html b/Tests/LibWeb/Text/input/wpt-import/permissions/permissionsstatus-name.html new file mode 100644 index 0000000000..7499e884c8 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/permissions/permissionsstatus-name.html @@ -0,0 +1,15 @@ + + +Test PermissionStatus's name attribute. + + +
+ + \ No newline at end of file