[PM-1829] Allow Safari popup to be full height in Safari >= 16.1 (#5226)
* Logic for calculating if we should apply height fix for safari * Revert safari height fix for safari >= 16.1 * Deprecate static isBrowser funcions, using them directly is incorrect * Changes based on feedback * Update CSS to use & selector --------- Co-authored-by: Hinton <hinton@users.noreply.github.com>
This commit is contained in:
parent
c763415edf
commit
1b9c4a9c11
|
@ -1,10 +1,18 @@
|
|||
import { enableProdMode } from "@angular/core";
|
||||
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
|
||||
|
||||
import BrowserPlatformUtilsService from "../services/browserPlatformUtils.service";
|
||||
|
||||
require("./scss/popup.scss");
|
||||
|
||||
import { AppModule } from "./app.module";
|
||||
|
||||
// We put this first to minimize the delay in window changing.
|
||||
// Should be removed once we deprecate support for Safari 16.0 and older. See Jira ticket [PM-1861]
|
||||
if (BrowserPlatformUtilsService.shouldApplySafariHeightFix(window)) {
|
||||
document.documentElement.classList.add("safari_height_fix");
|
||||
}
|
||||
|
||||
if (process.env.ENV === "production") {
|
||||
enableProdMode();
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
@import "variables.scss";
|
||||
|
||||
html.browser_safari {
|
||||
body {
|
||||
height: 360px !important;
|
||||
&.safari_height_fix {
|
||||
body {
|
||||
height: 360px !important;
|
||||
|
||||
&.body-xs {
|
||||
height: 300px !important;
|
||||
}
|
||||
&.body-xs {
|
||||
height: 300px !important;
|
||||
}
|
||||
|
||||
&.body-full {
|
||||
height: 100% !important;
|
||||
&.body-full {
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ describe("Browser Utils Service", () => {
|
|||
afterEach(() => {
|
||||
window.matchMedia = undefined;
|
||||
(window as any).chrome = undefined;
|
||||
(BrowserPlatformUtilsService as any).deviceCache = null;
|
||||
});
|
||||
|
||||
it("should detect chrome", () => {
|
||||
|
@ -86,3 +87,73 @@ describe("Browser Utils Service", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Safari Height Fix", () => {
|
||||
const originalUserAgent = navigator.userAgent;
|
||||
|
||||
// Reset the userAgent.
|
||||
afterAll(() => {
|
||||
Object.defineProperty(navigator, "userAgent", {
|
||||
value: originalUserAgent,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
(BrowserPlatformUtilsService as any).deviceCache = null;
|
||||
});
|
||||
|
||||
test.each([
|
||||
[
|
||||
"safari 15.6.1",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15",
|
||||
true,
|
||||
],
|
||||
[
|
||||
"safari 16.0",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15",
|
||||
true,
|
||||
],
|
||||
|
||||
[
|
||||
"safari 16.1",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"safari 16.4",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"safari 17.0 (future release)",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"chrome",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"firefox",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"opera",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3175.3 Safari/537.36 OPR/49.0.2695.0 (Edition developer)",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"edge",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.74 Safari/537.36 Edg/79.0.309.43",
|
||||
false,
|
||||
],
|
||||
])("Apply fix for %s", (name, userAgent, expected) => {
|
||||
Object.defineProperty(navigator, "userAgent", {
|
||||
configurable: true,
|
||||
value: userAgent,
|
||||
});
|
||||
expect(BrowserPlatformUtilsService.shouldApplySafariHeightFix(window)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
number,
|
||||
{ tryResolve: (canceled: boolean, password: string) => Promise<boolean>; date: Date }
|
||||
>();
|
||||
private deviceCache: DeviceType = null;
|
||||
private static deviceCache: DeviceType = null;
|
||||
|
||||
constructor(
|
||||
private messagingService: MessagingService,
|
||||
|
@ -22,28 +22,32 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
private win: Window & typeof globalThis
|
||||
) {}
|
||||
|
||||
getDevice(): DeviceType {
|
||||
static getDevice(win: Window & typeof globalThis): DeviceType {
|
||||
if (this.deviceCache) {
|
||||
return this.deviceCache;
|
||||
}
|
||||
|
||||
if (BrowserPlatformUtilsService.isFirefox()) {
|
||||
this.deviceCache = DeviceType.FirefoxExtension;
|
||||
} else if (BrowserPlatformUtilsService.isOpera(this.win)) {
|
||||
} else if (BrowserPlatformUtilsService.isOpera(win)) {
|
||||
this.deviceCache = DeviceType.OperaExtension;
|
||||
} else if (BrowserPlatformUtilsService.isEdge()) {
|
||||
this.deviceCache = DeviceType.EdgeExtension;
|
||||
} else if (BrowserPlatformUtilsService.isVivaldi()) {
|
||||
this.deviceCache = DeviceType.VivaldiExtension;
|
||||
} else if (BrowserPlatformUtilsService.isChrome(this.win)) {
|
||||
} else if (BrowserPlatformUtilsService.isChrome(win)) {
|
||||
this.deviceCache = DeviceType.ChromeExtension;
|
||||
} else if (BrowserPlatformUtilsService.isSafari(this.win)) {
|
||||
} else if (BrowserPlatformUtilsService.isSafari(win)) {
|
||||
this.deviceCache = DeviceType.SafariExtension;
|
||||
}
|
||||
|
||||
return this.deviceCache;
|
||||
}
|
||||
|
||||
getDevice(): DeviceType {
|
||||
return BrowserPlatformUtilsService.getDevice(this.win);
|
||||
}
|
||||
|
||||
getDeviceString(): string {
|
||||
const device = DeviceType[this.getDevice()].toLowerCase();
|
||||
return device.replace("extension", "");
|
||||
|
@ -53,6 +57,9 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
return ClientType.Browser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do not call this directly, use getDevice() instead
|
||||
*/
|
||||
static isFirefox(): boolean {
|
||||
return (
|
||||
navigator.userAgent.indexOf(" Firefox/") !== -1 ||
|
||||
|
@ -64,7 +71,10 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
return this.getDevice() === DeviceType.FirefoxExtension;
|
||||
}
|
||||
|
||||
static isChrome(win: Window & typeof globalThis): boolean {
|
||||
/**
|
||||
* @deprecated Do not call this directly, use getDevice() instead
|
||||
*/
|
||||
private static isChrome(win: Window & typeof globalThis): boolean {
|
||||
return win.chrome && navigator.userAgent.indexOf(" Chrome/") !== -1;
|
||||
}
|
||||
|
||||
|
@ -72,7 +82,10 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
return this.getDevice() === DeviceType.ChromeExtension;
|
||||
}
|
||||
|
||||
static isEdge(): boolean {
|
||||
/**
|
||||
* @deprecated Do not call this directly, use getDevice() instead
|
||||
*/
|
||||
private static isEdge(): boolean {
|
||||
return navigator.userAgent.indexOf(" Edg/") !== -1;
|
||||
}
|
||||
|
||||
|
@ -80,7 +93,10 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
return this.getDevice() === DeviceType.EdgeExtension;
|
||||
}
|
||||
|
||||
static isOpera(win: Window & typeof globalThis): boolean {
|
||||
/**
|
||||
* @deprecated Do not call this directly, use getDevice() instead
|
||||
*/
|
||||
private static isOpera(win: Window & typeof globalThis): boolean {
|
||||
return (
|
||||
(!!win.opr && !!win.opr.addons) || !!win.opera || navigator.userAgent.indexOf(" OPR/") >= 0
|
||||
);
|
||||
|
@ -90,7 +106,10 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
return this.getDevice() === DeviceType.OperaExtension;
|
||||
}
|
||||
|
||||
static isVivaldi(): boolean {
|
||||
/**
|
||||
* @deprecated Do not call this directly, use getDevice() instead
|
||||
*/
|
||||
private static isVivaldi(): boolean {
|
||||
return navigator.userAgent.indexOf(" Vivaldi/") !== -1;
|
||||
}
|
||||
|
||||
|
@ -98,6 +117,9 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
return this.getDevice() === DeviceType.VivaldiExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do not call this directly, use getDevice() instead
|
||||
*/
|
||||
static isSafari(win: Window & typeof globalThis): boolean {
|
||||
// Opera masquerades as Safari, so make sure we're not there first
|
||||
return (
|
||||
|
@ -105,6 +127,24 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
|||
);
|
||||
}
|
||||
|
||||
private static safariVersion(): string {
|
||||
return navigator.userAgent.match("Version/([0-9.]*)")?.[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Safari previous to version 16.1 had a bug which caused artifacts on hover in large extension popups.
|
||||
* https://bugs.webkit.org/show_bug.cgi?id=218704
|
||||
*/
|
||||
static shouldApplySafariHeightFix(win: Window & typeof globalThis): boolean {
|
||||
if (BrowserPlatformUtilsService.getDevice(win) !== DeviceType.SafariExtension) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const version = BrowserPlatformUtilsService.safariVersion();
|
||||
const parts = version?.split(".")?.map((v) => Number(v));
|
||||
return parts?.[0] < 16 || (parts?.[0] === 16 && parts?.[1] === 0);
|
||||
}
|
||||
|
||||
isSafari(): boolean {
|
||||
return this.getDevice() === DeviceType.SafariExtension;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue