clear clipboard timeout implemented

This commit is contained in:
Kyle Spearrin 2019-02-27 09:28:16 -05:00
parent d2a736ed71
commit 5b088b2b3c
5 changed files with 44 additions and 21 deletions

2
jslib

@ -1 +1 @@
Subproject commit 21d011554c1c7d5e497241965bc775cfc1001d16 Subproject commit 8aa2f0fb183ad8f30a9fb5396b63e6fff5b87e12

View File

@ -22,6 +22,7 @@ import {
import { ExportService } from 'jslib/services/export.service'; import { ExportService } from 'jslib/services/export.service';
import { NotificationsService } from 'jslib/services/notifications.service'; import { NotificationsService } from 'jslib/services/notifications.service';
import { SearchService } from 'jslib/services/search.service'; import { SearchService } from 'jslib/services/search.service';
import { SystemService } from 'jslib/services/system.service';
import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service'; import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service';
import { import {
@ -48,6 +49,7 @@ import {
import { ExportService as ExportServiceAbstraction } from 'jslib/abstractions/export.service'; import { ExportService as ExportServiceAbstraction } from 'jslib/abstractions/export.service';
import { NotificationsService as NotificationsServiceAbstraction } from 'jslib/abstractions/notifications.service'; import { NotificationsService as NotificationsServiceAbstraction } from 'jslib/abstractions/notifications.service';
import { SearchService as SearchServiceAbstraction } from 'jslib/abstractions/search.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 { Analytics } from 'jslib/misc';
import { Utils } from 'jslib/misc/utils'; import { Utils } from 'jslib/misc/utils';
@ -97,6 +99,7 @@ export default class MainBackground {
exportService: ExportServiceAbstraction; exportService: ExportServiceAbstraction;
searchService: SearchServiceAbstraction; searchService: SearchServiceAbstraction;
notificationsService: NotificationsServiceAbstraction; notificationsService: NotificationsServiceAbstraction;
systemService: SystemServiceAbstraction;
analytics: Analytics; analytics: Analytics;
onUpdatedRan: boolean; onUpdatedRan: boolean;
@ -121,7 +124,12 @@ export default class MainBackground {
constructor() { constructor() {
// Services // Services
this.messagingService = new BrowserMessagingService(); 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.storageService = new BrowserStorageService(this.platformUtilsService, false);
this.secureStorageService = new BrowserStorageService(this.platformUtilsService, true); this.secureStorageService = new BrowserStorageService(this.platformUtilsService, true);
this.i18nService = new I18nService(BrowserApi.getUILanguage(window), this.i18nService = new I18nService(BrowserApi.getUILanguage(window),
@ -149,10 +157,9 @@ export default class MainBackground {
} }
await this.setIcon(); await this.setIcon();
await this.refreshBadgeAndMenu(true); await this.refreshBadgeAndMenu(true);
this.lockService.startLockReload(); if (this.systemService != null) {
}, () => { this.systemService.startProcessReload();
window.location.reload(true); }
return Promise.resolve();
}); });
this.syncService = new SyncService(this.userService, this.apiService, this.settingsService, this.syncService = new SyncService(this.userService, this.apiService, this.settingsService,
this.folderService, this.cipherService, this.cryptoService, this.collectionService, this.folderService, this.cipherService, this.cryptoService, this.collectionService,
@ -169,6 +176,11 @@ export default class MainBackground {
this.notificationsService); this.notificationsService);
this.analytics = new Analytics(window, () => BrowserApi.gaFilter(), this.platformUtilsService, this.analytics = new Analytics(window, () => BrowserApi.gaFilter(), this.platformUtilsService,
this.storageService, this.appIdService); 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 // Other fields
this.isSafari = this.platformUtilsService.isSafari(); this.isSafari = this.platformUtilsService.isSafari();
@ -178,7 +190,7 @@ export default class MainBackground {
// Background // Background
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService, this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService,
this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService, 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.tabsBackground = new TabsBackground(this, this.platformUtilsService);
this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService, this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService,
this.platformUtilsService, this.analytics); this.platformUtilsService, this.analytics);
@ -288,7 +300,7 @@ export default class MainBackground {
await this.refreshBadgeAndMenu(); await this.refreshBadgeAndMenu();
await this.reseedStorage(); await this.reseedStorage();
this.notificationsService.updateConnection(false); this.notificationsService.updateConnection(false);
this.lockService.startLockReload(); this.systemService.startProcessReload();
} }
collectPageDetailsForContentScript(tab: any, sender: string, frameId: number = null) { collectPageDetailsForContentScript(tab: any, sender: string, frameId: number = null) {

View File

@ -12,9 +12,9 @@ import { Analytics } from 'jslib/misc';
import { import {
CipherService, CipherService,
LockService,
StorageService, StorageService,
} from 'jslib/abstractions'; } from 'jslib/abstractions';
import { SystemService } from 'jslib/abstractions/system.service';
import { BrowserApi } from '../browser/browserApi'; import { BrowserApi } from '../browser/browserApi';
@ -38,7 +38,7 @@ export default class RuntimeBackground {
private cipherService: CipherService, private platformUtilsService: BrowserPlatformUtilsService, private cipherService: CipherService, private platformUtilsService: BrowserPlatformUtilsService,
private storageService: StorageService, private i18nService: I18nService, private storageService: StorageService, private i18nService: I18nService,
private analytics: Analytics, private notificationsService: NotificationsService, private analytics: Analytics, private notificationsService: NotificationsService,
private lockService: LockService) { private systemService: SystemService) {
this.isSafari = this.platformUtilsService.isSafari(); this.isSafari = this.platformUtilsService.isSafari();
this.runtime = this.isSafari ? safari.application : chrome.runtime; this.runtime = this.isSafari ? safari.application : chrome.runtime;
@ -86,7 +86,7 @@ export default class RuntimeBackground {
await this.main.setIcon(); await this.main.setIcon();
await this.main.refreshBadgeAndMenu(false); await this.main.refreshBadgeAndMenu(false);
this.notificationsService.updateConnection(msg.command === 'unlocked'); this.notificationsService.updateConnection(msg.command === 'unlocked');
this.lockService.cancelLockReload(); this.systemService.cancelProcessReload();
break; break;
case 'logout': case 'logout':
await this.main.logout(msg.expired); await this.main.logout(msg.expired);

View File

@ -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' 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); 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' 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); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.FirefoxExtension);
}); });
@ -52,7 +52,7 @@ describe('Browser Utils Service', () => {
value: {} value: {}
}); });
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.OperaExtension); 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' 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); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.EdgeExtension);
}); });
@ -77,7 +77,7 @@ describe('Browser Utils Service', () => {
value: {} value: {}
}); });
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null); const browserPlatformUtilsService = new BrowserPlatformUtilsService(null, null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.SafariExtension); 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' 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); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.VivaldiExtension);
}); });
}); });

View File

@ -16,7 +16,8 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
private deviceCache: DeviceType = null; private deviceCache: DeviceType = null;
private analyticsIdCache: string = null; private analyticsIdCache: string = null;
constructor(private messagingService: MessagingService) { } constructor(private messagingService: MessagingService,
private clipboardWriteCallback: (clipboardValue: string, clearMs: number) => void) { }
getDevice(): DeviceType { getDevice(): DeviceType {
if (this.deviceCache) { if (this.deviceCache) {
@ -185,14 +186,22 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
} else if (options && options.doc) { } else if (options && options.doc) {
doc = 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) { 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) { } else if ((win as any).clipboardData && (win as any).clipboardData.setData) {
// IE specific code path to prevent textarea being shown while dialog is visible. // IE specific code path to prevent textarea being shown while dialog is visible.
(win as any).clipboardData.setData('Text', text); (win as any).clipboardData.setData('Text', text);
if (this.clipboardWriteCallback != null) {
this.clipboardWriteCallback(text, clearMs);
}
} else if (doc.queryCommandSupported && doc.queryCommandSupported('copy')) { } else if (doc.queryCommandSupported && doc.queryCommandSupported('copy')) {
const textarea = doc.createElement('textarea'); const textarea = doc.createElement('textarea');
textarea.textContent = text; textarea.textContent = text == null || text === '' ? ' ' : text;
// Prevent scrolling to bottom of page in MS Edge. // Prevent scrolling to bottom of page in MS Edge.
textarea.style.position = 'fixed'; textarea.style.position = 'fixed';
doc.body.appendChild(textarea); doc.body.appendChild(textarea);
@ -200,7 +209,9 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
try { try {
// Security exception may be thrown by some browsers. // Security exception may be thrown by some browsers.
doc.execCommand('copy'); if (doc.execCommand('copy') && this.clipboardWriteCallback != null) {
this.clipboardWriteCallback(text, clearMs);
}
} catch (e) { } catch (e) {
// tslint:disable-next-line // tslint:disable-next-line
console.warn('Copy to clipboard failed.', e); console.warn('Copy to clipboard failed.', e);