Skip to content

Commit 125825a

Browse files
Release build 12.3.0 [ci release]
1 parent 63ce8ef commit 125825a

35 files changed

+2325
-32
lines changed

CHANGELOG.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Add Web Notifications support (#2067)
2+
- History: Stub out support for theming (#2066)

build/android/adsjsContentScope.js

Lines changed: 179 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,24 @@
673673
return Reflect.get(target, prop, receiver);
674674
};
675675
}
676+
function wrapFunction(functionValue, realTarget) {
677+
return new Proxy(realTarget, {
678+
get(target, prop, receiver) {
679+
if (prop === "toString") {
680+
const method = Reflect.get(target, prop, receiver).bind(target);
681+
Object.defineProperty(method, "toString", {
682+
value: functionToString.bind(functionToString),
683+
enumerable: false
684+
});
685+
return method;
686+
}
687+
return Reflect.get(target, prop, receiver);
688+
},
689+
apply(_2, thisArg, argumentsList) {
690+
return Reflect.apply(functionValue, thisArg, argumentsList);
691+
}
692+
});
693+
}
676694
function wrapProperty(object, propertyName, descriptor, definePropertyFn) {
677695
if (!object) {
678696
return;
@@ -4020,14 +4038,16 @@
40204038
}
40214039
return dataToSend;
40224040
}
4023-
var _activeShareRequest, _activeScreenLockRequest;
4041+
var _activeShareRequest, _activeScreenLockRequest, _webNotifications;
40244042
var WebCompat = class extends ContentFeature {
40254043
constructor() {
40264044
super(...arguments);
40274045
/** @type {Promise<any> | null} */
40284046
__privateAdd(this, _activeShareRequest, null);
40294047
/** @type {Promise<any> | null} */
40304048
__privateAdd(this, _activeScreenLockRequest, null);
4049+
/** @type {Map<string, object>} */
4050+
__privateAdd(this, _webNotifications, /* @__PURE__ */ new Map());
40314051
// Opt in to receive configuration updates from initial ping responses
40324052
__publicField(this, "listenForConfigUpdates", true);
40334053
}
@@ -4047,6 +4067,9 @@
40474067
if (this.getFeatureSettingEnabled("notification")) {
40484068
this.notificationFix();
40494069
}
4070+
if (this.getFeatureSettingEnabled("webNotifications")) {
4071+
this.webNotificationsFix();
4072+
}
40504073
if (this.getFeatureSettingEnabled("permissions")) {
40514074
const settings = this.getFeatureSetting("permissions");
40524075
this.permissionsFix(settings);
@@ -4181,6 +4204,160 @@
41814204
enumerable: true
41824205
});
41834206
}
4207+
/**
4208+
* Web Notifications polyfill that communicates with native code for permission
4209+
* management and notification display.
4210+
*/
4211+
webNotificationsFix() {
4212+
var _id;
4213+
if (!globalThis.isSecureContext) {
4214+
return;
4215+
}
4216+
const feature = this;
4217+
const settings = this.getFeatureSetting("webNotifications") || {};
4218+
const nativeEnabled = settings.nativeEnabled !== false;
4219+
const nativeNotify = nativeEnabled ? (name, data) => feature.notify(name, data) : () => {
4220+
};
4221+
const nativeRequest = nativeEnabled ? (name, data) => feature.request(name, data) : () => Promise.resolve({ permission: "denied" });
4222+
const nativeSubscribe = nativeEnabled ? (name, cb) => feature.subscribe(name, cb) : () => () => {
4223+
};
4224+
let permission = nativeEnabled ? "default" : "denied";
4225+
class NotificationPolyfill {
4226+
/**
4227+
* @param {string} title
4228+
* @param {NotificationOptions} [options]
4229+
*/
4230+
constructor(title, options = {}) {
4231+
/** @type {string} */
4232+
__privateAdd(this, _id);
4233+
/** @type {string} */
4234+
__publicField(this, "title");
4235+
/** @type {string} */
4236+
__publicField(this, "body");
4237+
/** @type {string} */
4238+
__publicField(this, "icon");
4239+
/** @type {string} */
4240+
__publicField(this, "tag");
4241+
/** @type {any} */
4242+
__publicField(this, "data");
4243+
// Event handlers
4244+
/** @type {((this: Notification, ev: Event) => any) | null} */
4245+
__publicField(this, "onclick", null);
4246+
/** @type {((this: Notification, ev: Event) => any) | null} */
4247+
__publicField(this, "onclose", null);
4248+
/** @type {((this: Notification, ev: Event) => any) | null} */
4249+
__publicField(this, "onerror", null);
4250+
/** @type {((this: Notification, ev: Event) => any) | null} */
4251+
__publicField(this, "onshow", null);
4252+
__privateSet(this, _id, crypto.randomUUID());
4253+
this.title = String(title);
4254+
this.body = options.body ? String(options.body) : "";
4255+
this.icon = options.icon ? String(options.icon) : "";
4256+
this.tag = options.tag ? String(options.tag) : "";
4257+
this.data = options.data;
4258+
__privateGet(feature, _webNotifications).set(__privateGet(this, _id), this);
4259+
nativeNotify("showNotification", {
4260+
id: __privateGet(this, _id),
4261+
title: this.title,
4262+
body: this.body,
4263+
icon: this.icon,
4264+
tag: this.tag
4265+
});
4266+
}
4267+
/**
4268+
* @returns {'default' | 'denied' | 'granted'}
4269+
*/
4270+
static get permission() {
4271+
return permission;
4272+
}
4273+
/**
4274+
* @param {NotificationPermissionCallback} [deprecatedCallback]
4275+
* @returns {Promise<NotificationPermission>}
4276+
*/
4277+
static async requestPermission(deprecatedCallback) {
4278+
try {
4279+
const result = await nativeRequest("requestPermission", {});
4280+
const resultPermission = (
4281+
/** @type {NotificationPermission} */
4282+
result?.permission || "denied"
4283+
);
4284+
permission = resultPermission;
4285+
if (deprecatedCallback) {
4286+
deprecatedCallback(resultPermission);
4287+
}
4288+
return resultPermission;
4289+
} catch (e) {
4290+
permission = "denied";
4291+
if (deprecatedCallback) {
4292+
deprecatedCallback("denied");
4293+
}
4294+
return "denied";
4295+
}
4296+
}
4297+
/**
4298+
* @returns {number}
4299+
*/
4300+
static get maxActions() {
4301+
return 2;
4302+
}
4303+
close() {
4304+
if (!__privateGet(feature, _webNotifications).has(__privateGet(this, _id))) {
4305+
return;
4306+
}
4307+
nativeNotify("closeNotification", { id: __privateGet(this, _id) });
4308+
__privateGet(feature, _webNotifications).delete(__privateGet(this, _id));
4309+
if (typeof this.onclose === "function") {
4310+
try {
4311+
this.onclose(new Event("close"));
4312+
} catch (e) {
4313+
}
4314+
}
4315+
}
4316+
}
4317+
_id = new WeakMap();
4318+
const wrappedNotification = wrapFunction(NotificationPolyfill, NotificationPolyfill);
4319+
const wrappedRequestPermission = wrapToString(
4320+
NotificationPolyfill.requestPermission.bind(NotificationPolyfill),
4321+
NotificationPolyfill.requestPermission,
4322+
"function requestPermission() { [native code] }"
4323+
);
4324+
nativeSubscribe("notificationEvent", (data) => {
4325+
const notification = __privateGet(this, _webNotifications).get(data.id);
4326+
if (!notification) return;
4327+
const eventName = `on${data.event}`;
4328+
if (typeof notification[eventName] === "function") {
4329+
try {
4330+
notification[eventName](new Event(data.event));
4331+
} catch (e) {
4332+
}
4333+
}
4334+
if (data.event === "close") {
4335+
__privateGet(this, _webNotifications).delete(data.id);
4336+
}
4337+
});
4338+
this.defineProperty(globalThis, "Notification", {
4339+
value: wrappedNotification,
4340+
writable: true,
4341+
configurable: true,
4342+
enumerable: false
4343+
});
4344+
this.defineProperty(globalThis.Notification, "permission", {
4345+
get: () => permission,
4346+
configurable: true,
4347+
enumerable: true
4348+
});
4349+
this.defineProperty(globalThis.Notification, "maxActions", {
4350+
get: () => 2,
4351+
configurable: true,
4352+
enumerable: true
4353+
});
4354+
this.defineProperty(globalThis.Notification, "requestPermission", {
4355+
value: wrappedRequestPermission,
4356+
writable: true,
4357+
configurable: true,
4358+
enumerable: true
4359+
});
4360+
}
41844361
cleanIframeValue() {
41854362
function cleanValueData(val) {
41864363
const clone = Object.assign({}, val);
@@ -4746,6 +4923,7 @@
47464923
};
47474924
_activeShareRequest = new WeakMap();
47484925
_activeScreenLockRequest = new WeakMap();
4926+
_webNotifications = new WeakMap();
47494927
var web_compat_default = WebCompat;
47504928

47514929
// src/features/fingerprinting-hardware.js

0 commit comments

Comments
 (0)