diff --git a/types/navigator-permissions/index.d.ts b/types/navigator-permissions/index.d.ts index a62c7f77ef..ba66b4cb46 100644 --- a/types/navigator-permissions/index.d.ts +++ b/types/navigator-permissions/index.d.ts @@ -21,9 +21,9 @@ declare namespace NavigatorPermissions { * Permission state values. */ type PermissionState = - 'granted' | - 'denied' | - 'prompt'; + 'granted' | + 'denied' | + 'prompt'; /** * The `PermissionStatus` interface of the Permissions API provides the state @@ -54,22 +54,22 @@ declare namespace NavigatorPermissions { * Permission name options. */ type PermissionName = - 'accelerometer' | - 'accessibility-events' | - 'ambient-light-sensor' | - 'background-sync' | - 'camera' | - 'clipboard-read' | - 'clipboard-write' | - 'geolocation' | - 'gyroscope' | - 'magnetometer' | - 'microphone' | - 'midi' | - 'notifications' | - 'payment-handler' | - 'persistent-storage' | - 'push'; + 'accelerometer' | + 'accessibility-events' | + 'ambient-light-sensor' | + 'background-sync' | + 'camera' | + 'clipboard-read' | + 'clipboard-write' | + 'geolocation' | + 'gyroscope' | + 'magnetometer' | + 'microphone' | + 'midi' | + 'notifications' | + 'payment-handler' | + 'persistent-storage' | + 'push'; /** * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query} @@ -103,31 +103,38 @@ declare namespace NavigatorPermissions { } // Map permission names to correctly typed descriptors. - interface NameDescriptorMap { - // ??? Question ???: - // Is there a better way to handle this case and remove repeated code, - // something like - // > { - // [n in N]: D; // this line to cover all basic cases - // // and the custom permission descriptors for midi and push - // } - 'accelerometer': PermissionDescriptor<'accelerometer'>; - 'accessibility-events': PermissionDescriptor<'accessibility-events'>; - 'ambient-light-sensor': PermissionDescriptor<'ambient-light-sensor'>; - 'background-sync': PermissionDescriptor<'background-sync'>; - 'camera': PermissionDescriptor<'camera'>; - 'clipboard-read': PermissionDescriptor<'clipboard-read'>; - 'clipboard-write': PermissionDescriptor<'clipboard-write'>; - 'geolocation': PermissionDescriptor<'geolocation'>; - 'gyroscope': PermissionDescriptor<'gyroscope'>; - 'magnetometer': PermissionDescriptor<'magnetometer'>; - 'microphone': PermissionDescriptor<'microphone'>; - 'notifications': PermissionDescriptor<'notifications'>; - 'payment-handler': PermissionDescriptor<'payment-handler'>; - 'persistent-storage': PermissionDescriptor<'persistent-storage'>; - // These permission descriptors support extra properties - 'midi': MidiPermissionDescriptor; - 'push': PushPermissionDescriptor; + interface QueryNameDescriptorMap { + // ??? Question ???: + // Is there a better way to handle this case and remove repeated code, + // something like + // > { + // [n in N]: D; // this line to cover all basic cases + // // and the custom permission descriptors for midi and push + // } + 'accelerometer': PermissionDescriptor<'accelerometer'>; + 'accessibility-events': PermissionDescriptor<'accessibility-events'>; + 'ambient-light-sensor': PermissionDescriptor<'ambient-light-sensor'>; + 'background-sync': PermissionDescriptor<'background-sync'>; + 'camera': PermissionDescriptor<'camera'>; + 'clipboard-read': PermissionDescriptor<'clipboard-read'>; + 'clipboard-write': PermissionDescriptor<'clipboard-write'>; + 'geolocation': PermissionDescriptor<'geolocation'>; + 'gyroscope': PermissionDescriptor<'gyroscope'>; + 'magnetometer': PermissionDescriptor<'magnetometer'>; + 'microphone': PermissionDescriptor<'microphone'>; + 'notifications': PermissionDescriptor<'notifications'>; + 'payment-handler': PermissionDescriptor<'payment-handler'>; + 'persistent-storage': PermissionDescriptor<'persistent-storage'>; + // These permission descriptors support extra properties + 'midi': MidiPermissionDescriptor; + 'push': PushPermissionDescriptor; + } + + interface RevokeNameDescriptorMap { + 'geolocation': PermissionDescriptor<'geolocation'>; + 'notifications': PermissionDescriptor<'notifications'>; + 'midi': MidiPermissionDescriptor; + 'push': PushPermissionDescriptor; } /** @@ -153,14 +160,14 @@ declare namespace NavigatorPermissions { * unsupported (e.g. `midi`, or `push` with `userVisibleOnly`). * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query} */ - query(permissionDescriptor: NameDescriptorMap[keyof NameDescriptorMap]): Promise; + query(permissionDescriptor: QueryNameDescriptorMap[keyof QueryNameDescriptorMap]): Promise; /** * The `Permissions.revoke()` method of the `Permissions` interface reverts a * currently set permission back to its default state, which is usually `prompt`. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Permissions/revoke} */ - revoke(permissionDescriptor: NameDescriptorMap[keyof NameDescriptorMap]): Promise; + revoke(permissionDescriptor: RevokeNameDescriptorMap[keyof RevokeNameDescriptorMap]): Promise; } /** diff --git a/types/navigator-permissions/navigator-permissions-tests.ts b/types/navigator-permissions/navigator-permissions-tests.ts index 918726b23d..e8722d72f0 100644 --- a/types/navigator-permissions/navigator-permissions-tests.ts +++ b/types/navigator-permissions/navigator-permissions-tests.ts @@ -43,3 +43,49 @@ function exampleIgnoreUndefinedCheck() { // Using the ! after permissions will let you bypass the undefined-check nav.permissions!.query({ name: 'microphone' }); } + +function exampleRevokeDoesNotSupportTheSameDescriptorsAsQuery() { + const cameraQueryPromise: Promise = nav.permissions!.query({ name: 'camera' }); + // Revoke only supports a subset of descriptors + // nav.permissions!.revoke({ name: 'camera' }); + // For example name: 'notifications' + const notificationRevocalPromise: Promise = nav.permissions!.revoke({ name: 'notifications' }); +} + +function exampleFromMdnForQueryMethod() { + if (nav.permissions === undefined) { + console.error('Permissions API not supported'); + return; + } + + function showLocalNewsWithGeolocation() { /* Not implemented */ } + function showButtonToEnableLocalNews() { /* Not implemented */ } + // Using .then instead of async-await + nav.permissions.query({ name: 'geolocation' }).then((result) => { + if (result.state === 'granted') { + showLocalNewsWithGeolocation(); + } else if (result.state === 'prompt') { + showButtonToEnableLocalNews(); + } + // Don't do anything if the permission was denied. + }); +} + +function exampleFromMdnForRevokeMethod() { + // Just an example report function I made up + function report(state: NavigatorPermissions.PermissionState) { + switch (state) { + case 'denied': console.error('State: DENIED'); break; + case 'granted': console.log('State: GRANTED'); break; + case 'prompt': console.info('State: PROMPT'); break; + // Using a string that's an invalid state would result in an error from TypeScript + // case 'invalid': console.warn('Type "invalid" is not comparable to type "PermissionState".'); + } + } + // This is a slightly modified example from the MDN revoke method documentation + // https://developer.mozilla.org/en-US/docs/Web/API/Permissions/revoke#Example + // Using .then instead of async-await + nav.permissions!.revoke({ name: 'geolocation' }).then((result) => { + report(result.state); + }); +}