diff --git a/jslib b/jslib index 21d011554c..8aa2f0fb18 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 21d011554c1c7d5e497241965bc775cfc1001d16 +Subproject commit 8aa2f0fb183ad8f30a9fb5396b63e6fff5b87e12 diff --git a/src/background/main.background.ts b/src/background/main.background.ts index 7fd358a168..c96d39c74b 100644 --- a/src/background/main.background.ts +++ b/src/background/main.background.ts @@ -22,6 +22,7 @@ import { import { ExportService } from 'jslib/services/export.service'; import { NotificationsService } from 'jslib/services/notifications.service'; import { SearchService } from 'jslib/services/search.service'; +import { SystemService } from 'jslib/services/system.service'; import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service'; import { @@ -48,6 +49,7 @@ import { import { ExportService as ExportServiceAbstraction } from 'jslib/abstractions/export.service'; import { NotificationsService as NotificationsServiceAbstraction } from 'jslib/abstractions/notifications.service'; import { SearchService as SearchServiceAbstraction } from 'jslib/abstractions/search.service'; +import { SystemService as SystemServiceAbstraction } from 'jslib/abstractions/system.service'; import { Analytics } from 'jslib/misc'; import { Utils } from 'jslib/misc/utils'; @@ -97,6 +99,7 @@ export default class MainBackground { exportService: ExportServiceAbstraction; searchService: SearchServiceAbstraction; notificationsService: NotificationsServiceAbstraction; + systemService: SystemServiceAbstraction; analytics: Analytics; onUpdatedRan: boolean; @@ -121,7 +124,12 @@ export default class MainBackground { constructor() { // Services this.messagingService = new BrowserMessagingService(); - this.platformUtilsService = new BrowserPlatformUtilsService(this.messagingService); + this.platformUtilsService = new BrowserPlatformUtilsService(this.messagingService, + (clipboardValue, clearMs) => { + if (this.systemService != null) { + this.systemService.clearClipboard(clipboardValue, clearMs); + } + }); this.storageService = new BrowserStorageService(this.platformUtilsService, false); this.secureStorageService = new BrowserStorageService(this.platformUtilsService, true); this.i18nService = new I18nService(BrowserApi.getUILanguage(window), @@ -149,10 +157,9 @@ export default class MainBackground { } await this.setIcon(); await this.refreshBadgeAndMenu(true); - this.lockService.startLockReload(); - }, () => { - window.location.reload(true); - return Promise.resolve(); + if (this.systemService != null) { + this.systemService.startProcessReload(); + } }); this.syncService = new SyncService(this.userService, this.apiService, this.settingsService, this.folderService, this.cipherService, this.cryptoService, this.collectionService, @@ -169,6 +176,11 @@ export default class MainBackground { this.notificationsService); this.analytics = new Analytics(window, () => BrowserApi.gaFilter(), this.platformUtilsService, this.storageService, this.appIdService); + this.systemService = new SystemService(this.storageService, this.lockService, + this.messagingService, this.platformUtilsService, () => { + window.location.reload(true); + return Promise.resolve(); + }); // Other fields this.isSafari = this.platformUtilsService.isSafari(); @@ -178,7 +190,7 @@ export default class MainBackground { // Background this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService, this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService, - this.analytics, this.notificationsService, this.lockService); + this.analytics, this.notificationsService, this.systemService); this.tabsBackground = new TabsBackground(this, this.platformUtilsService); this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService, this.platformUtilsService, this.analytics); @@ -288,7 +300,7 @@ export default class MainBackground { await this.refreshBadgeAndMenu(); await this.reseedStorage(); this.notificationsService.updateConnection(false); - this.lockService.startLockReload(); + this.systemService.startProcessReload(); } collectPageDetailsForContentScript(tab: any, sender: string, frameId: number = null) { diff --git a/src/background/runtime.background.ts b/src/background/runtime.background.ts index 588df0f397..a899c5ecb8 100644 --- a/src/background/runtime.background.ts +++ b/src/background/runtime.background.ts @@ -12,9 +12,9 @@ import { Analytics } from 'jslib/misc'; import { CipherService, - LockService, StorageService, } from 'jslib/abstractions'; +import { SystemService } from 'jslib/abstractions/system.service'; import { BrowserApi } from '../browser/browserApi'; @@ -38,7 +38,7 @@ export default class RuntimeBackground { private cipherService: CipherService, private platformUtilsService: BrowserPlatformUtilsService, private storageService: StorageService, private i18nService: I18nService, private analytics: Analytics, private notificationsService: NotificationsService, - private lockService: LockService) { + private systemService: SystemService) { this.isSafari = this.platformUtilsService.isSafari(); this.runtime = this.isSafari ? safari.application : chrome.runtime; @@ -86,7 +86,7 @@ export default class RuntimeBackground { await this.main.setIcon(); await this.main.refreshBadgeAndMenu(false); this.notificationsService.updateConnection(msg.command === 'unlocked'); - this.lockService.cancelLockReload(); + this.systemService.cancelProcessReload(); break; case 'logout': await this.main.logout(msg.expired); diff --git a/src/services/browserPlatformUtils.service.spec.ts b/src/services/browserPlatformUtils.service.spec.ts index 2d5911af36..07bbe9c061 100644 --- a/src/services/browserPlatformUtils.service.spec.ts +++ b/src/services/browserPlatformUtils.service.spec.ts @@ -27,7 +27,7 @@ describe('Browser Utils Service', () => { value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' }); - const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); + const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.ChromeExtension); }); @@ -37,7 +37,7 @@ describe('Browser Utils Service', () => { value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0' }); - const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); + const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.FirefoxExtension); }); @@ -52,7 +52,7 @@ describe('Browser Utils Service', () => { value: {} }); - const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); + const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.OperaExtension); }); @@ -62,7 +62,7 @@ describe('Browser Utils Service', () => { value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ServiceUI 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063' }); - const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); + const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.EdgeExtension); }); @@ -77,7 +77,7 @@ describe('Browser Utils Service', () => { value: {} }); - const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); + const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.SafariExtension); }); @@ -87,7 +87,7 @@ describe('Browser Utils Service', () => { value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.97 Safari/537.36 Vivaldi/1.94.1008.40' }); - const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); + const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.VivaldiExtension); }); }); diff --git a/src/services/browserPlatformUtils.service.ts b/src/services/browserPlatformUtils.service.ts index b272a05758..9ae66fd114 100644 --- a/src/services/browserPlatformUtils.service.ts +++ b/src/services/browserPlatformUtils.service.ts @@ -16,7 +16,8 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService private deviceCache: DeviceType = null; private analyticsIdCache: string = null; - constructor(private messagingService: MessagingService) { } + constructor(private messagingService: MessagingService, + private clipboardWriteCallback: (clipboardValue: string, clearMs: number) => void) { } getDevice(): DeviceType { if (this.deviceCache) { @@ -185,14 +186,22 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService } else if (options && options.doc) { doc = options.doc; } + const clearMs: number = options && options.clearMs ? options.clearMs : null; if (this.isFirefox() && (win as any).navigator.clipboard && (win as any).navigator.clipboard.writeText) { - (win as any).navigator.clipboard.writeText(text); + (win as any).navigator.clipboard.writeText(text).then(() => { + if (this.clipboardWriteCallback != null) { + this.clipboardWriteCallback(text, clearMs); + } + }); } else if ((win as any).clipboardData && (win as any).clipboardData.setData) { // IE specific code path to prevent textarea being shown while dialog is visible. (win as any).clipboardData.setData('Text', text); + if (this.clipboardWriteCallback != null) { + this.clipboardWriteCallback(text, clearMs); + } } else if (doc.queryCommandSupported && doc.queryCommandSupported('copy')) { const textarea = doc.createElement('textarea'); - textarea.textContent = text; + textarea.textContent = text == null || text === '' ? ' ' : text; // Prevent scrolling to bottom of page in MS Edge. textarea.style.position = 'fixed'; doc.body.appendChild(textarea); @@ -200,7 +209,9 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService try { // Security exception may be thrown by some browsers. - doc.execCommand('copy'); + if (doc.execCommand('copy') && this.clipboardWriteCallback != null) { + this.clipboardWriteCallback(text, clearMs); + } } catch (e) { // tslint:disable-next-line console.warn('Copy to clipboard failed.', e);