diff --git a/src/page/utils/BrowserSupportsPush.ts b/src/page/utils/BrowserSupportsPush.ts index bc0fb155f..f42a45104 100644 --- a/src/page/utils/BrowserSupportsPush.ts +++ b/src/page/utils/BrowserSupportsPush.ts @@ -1,3 +1,5 @@ +// Light weight JS to detect browsers push notification capabilities +// // This is used by the OneSignalSDK.page.js shim // DO NOT add other imports since it is an ES5 target and dead code imports can't be clean up. @@ -7,15 +9,17 @@ export function isPushNotificationsSupported() { return supportsVapidPush() || supportsSafariPush(); } +// Fallback detection for Safari on macOS in an iframe context +// - window.safari is undefined in this context export function isMacOSSafariInIframe(): boolean { - // Fallback detection for Safari on macOS in an iframe context return ( window.top !== window && // isContextIframe - navigator.vendor === 'Apple Computer, Inc.' && // isSafari + isSafariBrowser() && navigator.platform === 'MacIntel' ); // isMacOS } +// Does the browser support legacy Safari push? (only available on macOS) export function supportsSafariPush(): boolean { return ( (window.safari && typeof window.safari.pushNotification !== 'undefined') || @@ -32,6 +36,19 @@ export function supportsVapidPush(): boolean { ); } +// Is Safari on iOS or iPadOS +export function isIosSafari(): boolean { + // Safari's "Request Desktop Website" (default for iPad) masks the + // userAgent as macOS. So we are using maxTouchPoints to assume it is + // iOS, since there are no touch screen Macs. + return isSafariBrowser() && navigator.maxTouchPoints > 0; +} + +// Is any Safari browser, includes macOS and iOS. +function isSafariBrowser(): boolean { + return navigator.vendor === 'Apple Computer, Inc.'; +} + /* Notes on browser results which lead the logic of the functions above */ // Safari // macOS - typeof safari.pushNotification == "object" @@ -43,4 +60,3 @@ export function supportsVapidPush(): boolean { // Firefox // Normal - typeof PushSubscriptionOptions == "function" // HTTP & HTTPS - typeof PushSubscriptionOptions == "function" -// ESR - typeof PushSubscriptionOptions == "undefined" diff --git a/src/page/utils/OneSignalShimLoader.ts b/src/page/utils/OneSignalShimLoader.ts index c4fa48730..39d8391e2 100644 --- a/src/page/utils/OneSignalShimLoader.ts +++ b/src/page/utils/OneSignalShimLoader.ts @@ -1,4 +1,7 @@ -import { isPushNotificationsSupported } from './BrowserSupportsPush'; +import { + isIosSafari, + isPushNotificationsSupported, +} from './BrowserSupportsPush'; // NOTE: Careful if adding imports, ES5 targets can't clean up functions never called. // See sdk.ts for what entry points this handles @@ -55,7 +58,16 @@ export class OneSignalShimLoader { if (isPushNotificationsSupported()) { OneSignalShimLoader.loadFullPageSDK(); } else { - console.log('OneSignal: SDK is not compatible with this browser.'); + this.printEnvironmentNotSupported(); } } + + private static printEnvironmentNotSupported() { + let logMessage = 'OneSignal: SDK is not compatible with this browser.'; + if (isIosSafari()) { + logMessage += + ' To support iOS please install as a Web App. See the OneSignal guide https://documentation.onesignal.com/docs/safari-web-push-for-ios'; + } + console.log(logMessage); + } }