From dca94e14dca789ef35b16d7c79b6786038c8657a Mon Sep 17 00:00:00 2001 From: anotherminh Date: Mon, 8 Jan 2024 14:52:58 -0500 Subject: [PATCH 1/4] Fix event target compatibilty in Safari < 14 --- src/event-target.ts | 87 +++++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/src/event-target.ts b/src/event-target.ts index dcede70b..bc320e2c 100644 --- a/src/event-target.ts +++ b/src/event-target.ts @@ -1,29 +1,64 @@ -/** - * Extend EventTarget to include the Transcend toStringTag - */ -export class TranscendEventTarget extends EventTarget { - #stringTag = 'Transcend'; +/* eslint-disable max-classes-per-file */ + +export const { userAgent } = navigator as { + /** user agent information */ + userAgent: string +}; +export const IS_EDGEHTML = userAgent.includes('Edge/'); +export const SAFARI_VERSION = + userAgent.includes('Safari/') && + !userAgent.includes('Chrome/') && + userAgent.match(/Version\/(\d+)/)?.[1]; - /** - * Add Transcend to the string tag - * - * @returns string - */ - get [Symbol.toStringTag](): string { - return this.#stringTag; - } +export const brand = (object: T, brand: string): T => + Object.defineProperty(object, Symbol.toStringTag, { + value: brand, + enumerable: true, + configurable: false, + writable: false, + }); - /** - * Allow airgap.js code to overwrite [Symbol.toStringTag] - */ - set [Symbol.toStringTag](updatedStringTag: string) { - this.#stringTag = updatedStringTag; - } +const STRING_TAG = 'Transcend'; - /** - * @param args - EventTarget constructor parameters - */ - constructor(...args: ConstructorParameters) { - super(...args); - } -} +/** + * EventTarget shim + */ +export const EventTargetShim = Object.freeze( + IS_EDGEHTML || (SAFARI_VERSION && +SAFARI_VERSION < 14) + ? /** + * EventTarget shim for EdgeHTML and Safari <14 + * + * Note that this shim performs worse than a full polyfill, + * but it results in a much smaller build size and maintains + * native compatibility with EventTarget.prototype. + */ + class { + /** + * EventTarget constructor shim + */ + constructor() { + // This is one of the lightest real-EventTarget-inheriting + // structures instantiable in EdgeHTML and Safari <14. + // const target = call(nativeCreateDocument, domImplementation, '', ''); + const target = document.implementation.createDocument('', ''); + // eslint-disable-next-line no-constructor-return + return brand(target, STRING_TAG); + } + } + : /** + * airgap.js-branded native EventTarget subclass + */ + class extends EventTarget { + /** + * Branding applicator constructor + * + * @param args - EventTarget constructor arguments + */ + constructor(...args: ConstructorParameters) { + super(...args); + brand(this, STRING_TAG); + } + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any +) as any as typeof EventTarget; +/* eslint-enable max-classes-per-file */ From 9b14e4aefbdd445fc593759697f78aa64bb9eb74 Mon Sep 17 00:00:00 2001 From: anotherminh Date: Mon, 8 Jan 2024 14:57:44 -0500 Subject: [PATCH 2/4] fix export class --- src/event-target.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event-target.ts b/src/event-target.ts index bc320e2c..9946a2fa 100644 --- a/src/event-target.ts +++ b/src/event-target.ts @@ -23,7 +23,7 @@ const STRING_TAG = 'Transcend'; /** * EventTarget shim */ -export const EventTargetShim = Object.freeze( +export const TranscendEventTarget = Object.freeze( IS_EDGEHTML || (SAFARI_VERSION && +SAFARI_VERSION < 14) ? /** * EventTarget shim for EdgeHTML and Safari <14 From 37db70658c52b06f4100ddf2a98bad7be39bf65d Mon Sep 17 00:00:00 2001 From: anotherminh Date: Mon, 8 Jan 2024 14:58:25 -0500 Subject: [PATCH 3/4] bump --- package.json | 2 +- src/event-target.ts | 48 ++++++++++++++++++++++----------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index a2aefdb3..16841aa9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/transcend-io/consent-manager-ui.git" }, "homepage": "https://github.com/transcend-io/consent-manager-ui", - "version": "4.12.0", + "version": "4.13.0", "license": "MIT", "main": "build/ui", "files": [ diff --git a/src/event-target.ts b/src/event-target.ts index 9946a2fa..27653239 100644 --- a/src/event-target.ts +++ b/src/event-target.ts @@ -2,7 +2,7 @@ export const { userAgent } = navigator as { /** user agent information */ - userAgent: string + userAgent: string; }; export const IS_EDGEHTML = userAgent.includes('Edge/'); export const SAFARI_VERSION = @@ -32,33 +32,33 @@ export const TranscendEventTarget = Object.freeze( * but it results in a much smaller build size and maintains * native compatibility with EventTarget.prototype. */ - class { - /** - * EventTarget constructor shim - */ - constructor() { - // This is one of the lightest real-EventTarget-inheriting - // structures instantiable in EdgeHTML and Safari <14. - // const target = call(nativeCreateDocument, domImplementation, '', ''); - const target = document.implementation.createDocument('', ''); - // eslint-disable-next-line no-constructor-return - return brand(target, STRING_TAG); + class { + /** + * EventTarget constructor shim + */ + constructor() { + // This is one of the lightest real-EventTarget-inheriting + // structures instantiable in EdgeHTML and Safari <14. + // const target = call(nativeCreateDocument, domImplementation, '', ''); + const target = document.implementation.createDocument('', ''); + // eslint-disable-next-line no-constructor-return + return brand(target, STRING_TAG); + } } - } : /** * airgap.js-branded native EventTarget subclass */ - class extends EventTarget { - /** - * Branding applicator constructor - * - * @param args - EventTarget constructor arguments - */ - constructor(...args: ConstructorParameters) { - super(...args); - brand(this, STRING_TAG); - } - }, + class extends EventTarget { + /** + * Branding applicator constructor + * + * @param args - EventTarget constructor arguments + */ + constructor(...args: ConstructorParameters) { + super(...args); + brand(this, STRING_TAG); + } + }, // eslint-disable-next-line @typescript-eslint/no-explicit-any ) as any as typeof EventTarget; /* eslint-enable max-classes-per-file */ From 43c7584af889a6f611ff4d628b0782f610436fa7 Mon Sep 17 00:00:00 2001 From: anotherminh Date: Mon, 8 Jan 2024 14:59:01 -0500 Subject: [PATCH 4/4] rename constant --- src/event-target.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/event-target.ts b/src/event-target.ts index 27653239..434188e8 100644 --- a/src/event-target.ts +++ b/src/event-target.ts @@ -18,7 +18,7 @@ export const brand = (object: T, brand: string): T => writable: false, }); -const STRING_TAG = 'Transcend'; +const TO_STRING_TAG = 'Transcend'; /** * EventTarget shim @@ -42,7 +42,7 @@ export const TranscendEventTarget = Object.freeze( // const target = call(nativeCreateDocument, domImplementation, '', ''); const target = document.implementation.createDocument('', ''); // eslint-disable-next-line no-constructor-return - return brand(target, STRING_TAG); + return brand(target, TO_STRING_TAG); } } : /** @@ -56,7 +56,7 @@ export const TranscendEventTarget = Object.freeze( */ constructor(...args: ConstructorParameters) { super(...args); - brand(this, STRING_TAG); + brand(this, TO_STRING_TAG); } }, // eslint-disable-next-line @typescript-eslint/no-explicit-any