Skip to content

Commit 40e9683

Browse files
Notification: Add toString and make permission/requestPermission set values (#1934)
* Initial PoC changes for testing * Address comments * Add toString attempt * Try using full constructor instead of arrow function * Fix notification toString * Avoid proxy descriptor mismatch in wrapToString * Remove rando copilot edit * Try recursively shimming toString * Try again to fix toString2 error * Match Chrome's inheritance instead of supplying toString * Fix constructor toString * Debug toString2 * Debug toString2 some more * Add current state * Fix writable value * Get tests to pass * Make notification.permission use value over get * Fix writable value * Remove this scope changes * Zap dangling comment * Zap another comment * Zap rando file addition * Make suggested changes --------- Co-authored-by: Jonathan Kingston <[email protected]>
1 parent 4678800 commit 40e9683

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

injected/integration-test/web-compat.spec.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,26 @@ test.describe('Ensure Notification interface is injected', () => {
130130
return window.Notification.maxActions;
131131
});
132132
expect(maxActionsPropDenied).toEqual(2);
133+
134+
const notificationToString = await page.evaluate(() => {
135+
return window.Notification.toString();
136+
});
137+
expect(notificationToString).toEqual('function Notification() { [native code] }');
138+
139+
const requestPermissionToString = await page.evaluate(() => {
140+
return window.Notification.requestPermission.toString();
141+
});
142+
expect(requestPermissionToString).toEqual('function requestPermission() { [native code] }');
143+
144+
const notificationToStringToString = await page.evaluate(() => {
145+
return window.Notification.toString.toString();
146+
});
147+
expect(notificationToStringToString).toEqual('function toString() { [native code] }');
148+
149+
const requestPermissionToStringToString = await page.evaluate(() => {
150+
return window.Notification.requestPermission.toString.toString();
151+
});
152+
expect(requestPermissionToStringToString).toEqual('function toString() { [native code] }');
133153
});
134154
});
135155

injected/src/features/web-compat.js

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import ContentFeature from '../content-feature.js';
22
// eslint-disable-next-line no-redeclare
33
import { URL } from '../captured-globals.js';
44
import { DDGProxy, DDGReflect } from '../utils';
5+
import { wrapToString } from '../wrapper-utils.js';
56
/**
67
* Fixes incorrect sizing value for outerHeight and outerWidth
78
*/
@@ -216,33 +217,52 @@ export class WebCompat extends ContentFeature {
216217
if (window.Notification) {
217218
return;
218219
}
220+
219221
// Expose the API
222+
// window.Notification polyfill is intentionally incompatible with DOM lib types
223+
const NotificationConstructor = function Notification() {
224+
throw new TypeError("Failed to construct 'Notification': Illegal constructor");
225+
};
226+
227+
const wrappedNotification = wrapToString(
228+
NotificationConstructor,
229+
NotificationConstructor,
230+
'function Notification() { [native code] }',
231+
);
232+
220233
this.defineProperty(window, 'Notification', {
221-
value: () => {
222-
// noop
223-
},
234+
value: wrappedNotification,
224235
writable: true,
225236
configurable: true,
226237
enumerable: false,
227238
});
228239

229-
this.defineProperty(window.Notification, 'requestPermission', {
230-
value: () => {
231-
return Promise.resolve('denied');
232-
},
233-
writable: true,
240+
this.defineProperty(window.Notification, 'permission', {
241+
value: 'denied',
242+
writable: false,
234243
configurable: true,
235244
enumerable: true,
236245
});
237246

238-
this.defineProperty(window.Notification, 'permission', {
239-
get: () => 'denied',
247+
this.defineProperty(window.Notification, 'maxActions', {
248+
get: () => 2,
240249
configurable: true,
241-
enumerable: false,
250+
enumerable: true,
242251
});
243252

244-
this.defineProperty(window.Notification, 'maxActions', {
245-
get: () => 2,
253+
const requestPermissionFunc = function requestPermission() {
254+
return Promise.resolve('denied');
255+
};
256+
257+
const wrappedRequestPermission = wrapToString(
258+
requestPermissionFunc,
259+
requestPermissionFunc,
260+
'function requestPermission() { [native code] }',
261+
);
262+
263+
this.defineProperty(window.Notification, 'requestPermission', {
264+
value: wrappedRequestPermission,
265+
writable: true,
246266
configurable: true,
247267
enumerable: true,
248268
});

0 commit comments

Comments
 (0)