Merge pull request #31944 from vargavince91/master

navigator-permissions: accept only subset of permission descriptor names for revoke method
This commit is contained in:
Ron Buckton
2019-01-22 09:39:40 -08:00
committed by GitHub
2 changed files with 99 additions and 46 deletions
+53 -46
View File
@@ -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 extends PermissionName, D extends PermissionDescriptor<N>> {
// [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 extends PermissionName, D extends PermissionDescriptor<N>> {
// [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<PermissionStatus>;
query(permissionDescriptor: QueryNameDescriptorMap[keyof QueryNameDescriptorMap]): Promise<PermissionStatus>;
/**
* 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<PermissionStatus>;
revoke(permissionDescriptor: RevokeNameDescriptorMap[keyof RevokeNameDescriptorMap]): Promise<PermissionStatus>;
}
/**
@@ -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<NavigatorPermissions.PermissionStatus> = nav.permissions!.query({ name: 'camera' });
// Revoke only supports a subset of descriptors
// nav.permissions!.revoke({ name: 'camera' });
// For example name: 'notifications'
const notificationRevocalPromise: Promise<NavigatorPermissions.PermissionStatus> = 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);
});
}