diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/content/actions/operation.ts | 12 | ||||
-rw-r--r-- | src/content/client/TabsClient.ts | 18 | ||||
-rw-r--r-- | src/content/repositories/ClipboardRepository.ts | 46 | ||||
-rw-r--r-- | src/content/urls.ts | 41 | ||||
-rw-r--r-- | src/content/usecases/ClipboardUseCase.ts | 44 | ||||
-rw-r--r-- | src/shared/urls.ts | 10 |
6 files changed, 119 insertions, 52 deletions
diff --git a/src/content/actions/operation.ts b/src/content/actions/operation.ts index b264e36..28192d7 100644 --- a/src/content/actions/operation.ts +++ b/src/content/actions/operation.ts @@ -3,15 +3,15 @@ import * as actions from './index'; import * as messages from '../../shared/messages'; import * as navigates from '../navigates'; import * as focuses from '../focuses'; -import * as urls from '../urls'; -import * as consoleFrames from '../console-frames'; import * as markActions from './mark'; import AddonEnabledUseCase from '../usecases/AddonEnabledUseCase'; +import ClipboardUseCase from '../usecases/ClipboardUseCase'; import { SettingRepositoryImpl } from '../repositories/SettingRepository'; import { ScrollPresenterImpl } from '../presenters/ScrollPresenter'; let addonEnabledUseCase = new AddonEnabledUseCase(); +let clipbaordUseCase = new ClipboardUseCase(); let settingRepository = new SettingRepositoryImpl(); let scrollPresenter = new ScrollPresenterImpl(); @@ -95,13 +95,11 @@ const exec = async( focuses.focusInput(); break; case operations.URLS_YANK: - urls.yank(window); - consoleFrames.postInfo('Yanked ' + window.location.href); + await clipbaordUseCase.yankCurrentURL(); break; case operations.URLS_PASTE: - urls.paste( - window, operation.newTab ? operation.newTab : false, - settings.search, + await clipbaordUseCase.openOrSearch( + operation.newTab ? operation.newTab : false, ); break; default: diff --git a/src/content/client/TabsClient.ts b/src/content/client/TabsClient.ts new file mode 100644 index 0000000..fe72e11 --- /dev/null +++ b/src/content/client/TabsClient.ts @@ -0,0 +1,18 @@ +import * as messages from '../../shared/messages'; + +export default interface TabsClient { + openUrl(url: string, newTab: boolean): Promise<void>; + + // eslint-disable-next-line semi +} + +export class TabsClientImpl { + async openUrl(url: string, newTab: boolean): Promise<void> { + await browser.runtime.sendMessage({ + type: messages.OPEN_URL, + url, + newTab, + }); + } +} + diff --git a/src/content/repositories/ClipboardRepository.ts b/src/content/repositories/ClipboardRepository.ts new file mode 100644 index 0000000..747ae6a --- /dev/null +++ b/src/content/repositories/ClipboardRepository.ts @@ -0,0 +1,46 @@ +export default interface ClipboardRepository { + read(): string; + + write(text: string): void; + + // eslint-disable-next-line semi +} + +export class ClipboardRepositoryImpl { + read(): string { + let textarea = window.document.createElement('textarea'); + window.document.body.append(textarea); + + textarea.style.position = 'fixed'; + textarea.style.top = '-100px'; + textarea.contentEditable = 'true'; + textarea.focus(); + + let ok = window.document.execCommand('paste'); + let value = textarea.textContent!!; + textarea.remove(); + + if (!ok) { + throw new Error('failed to access clipbaord'); + } + + return value; + } + + write(text: string): void { + let input = window.document.createElement('input'); + window.document.body.append(input); + + input.style.position = 'fixed'; + input.style.top = '-100px'; + input.value = text; + input.select(); + + let ok = window.document.execCommand('copy'); + input.remove(); + + if (!ok) { + throw new Error('failed to access clipbaord'); + } + } +} diff --git a/src/content/urls.ts b/src/content/urls.ts deleted file mode 100644 index 035b9bb..0000000 --- a/src/content/urls.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as messages from '../shared/messages'; -import * as urls from '../shared/urls'; -import { Search } from '../shared/Settings'; - -const yank = (win: Window) => { - let input = win.document.createElement('input'); - win.document.body.append(input); - - input.style.position = 'fixed'; - input.style.top = '-100px'; - input.value = win.location.href; - input.select(); - - win.document.execCommand('copy'); - - input.remove(); -}; - -const paste = (win: Window, newTab: boolean, search: Search) => { - let textarea = win.document.createElement('textarea'); - win.document.body.append(textarea); - - textarea.style.position = 'fixed'; - textarea.style.top = '-100px'; - textarea.contentEditable = 'true'; - textarea.focus(); - - if (win.document.execCommand('paste')) { - let value = textarea.textContent as string; - let url = urls.searchUrl(value, search); - browser.runtime.sendMessage({ - type: messages.OPEN_URL, - url, - newTab, - }); - } - - textarea.remove(); -}; - -export { yank, paste }; diff --git a/src/content/usecases/ClipboardUseCase.ts b/src/content/usecases/ClipboardUseCase.ts new file mode 100644 index 0000000..b2ece2f --- /dev/null +++ b/src/content/usecases/ClipboardUseCase.ts @@ -0,0 +1,44 @@ +import * as urls from '../../shared/urls'; +import ClipboardRepository, { ClipboardRepositoryImpl } + from '../repositories/ClipboardRepository'; +import SettingRepository, { SettingRepositoryImpl } + from '../repositories/SettingRepository'; +import TabsClient, { TabsClientImpl } + from '../client/TabsClient'; +import ConsoleClient, { ConsoleClientImpl } from '../client/ConsoleClient'; + +export default class ClipboardUseCase { + private repository: ClipboardRepository; + + private settingRepository: SettingRepository; + + private client: TabsClient; + + private consoleClient: ConsoleClient; + + constructor({ + repository = new ClipboardRepositoryImpl(), + settingRepository = new SettingRepositoryImpl(), + client = new TabsClientImpl(), + consoleClient = new ConsoleClientImpl(), + } = {}) { + this.repository = repository; + this.settingRepository = settingRepository; + this.client = client; + this.consoleClient = consoleClient; + } + + async yankCurrentURL(): Promise<string> { + let url = window.location.href; + this.repository.write(url); + await this.consoleClient.info('Yanked ' + url); + return Promise.resolve(url); + } + + async openOrSearch(newTab: boolean): Promise<void> { + let search = this.settingRepository.get().search; + let text = this.repository.read(); + let url = urls.searchUrl(text, search); + await this.client.openUrl(url, newTab); + } +} diff --git a/src/shared/urls.ts b/src/shared/urls.ts index 18349c8..bbdb1ea 100644 --- a/src/shared/urls.ts +++ b/src/shared/urls.ts @@ -1,3 +1,5 @@ +import { Search } from './Settings'; + const trimStart = (str: string): string => { // NOTE String.trimStart is available on Firefox 61 return str.replace(/^\s+/, ''); @@ -5,7 +7,7 @@ const trimStart = (str: string): string => { const SUPPORTED_PROTOCOLS = ['http:', 'https:', 'ftp:', 'mailto:', 'about:']; -const searchUrl = (keywords: string, searchSettings: any): string => { +const searchUrl = (keywords: string, search: Search): string => { try { let u = new URL(keywords); if (SUPPORTED_PROTOCOLS.includes(u.protocol.toLowerCase())) { @@ -17,12 +19,12 @@ const searchUrl = (keywords: string, searchSettings: any): string => { if (keywords.includes('.') && !keywords.includes(' ')) { return 'http://' + keywords; } - let template = searchSettings.engines[searchSettings.default]; + let template = search.engines[search.default]; let query = keywords; let first = trimStart(keywords).split(' ')[0]; - if (Object.keys(searchSettings.engines).includes(first)) { - template = searchSettings.engines[first]; + if (Object.keys(search.engines).includes(first)) { + template = search.engines[first]; query = trimStart(trimStart(keywords).slice(first.length)); } return template.replace('{}', encodeURIComponent(query)); |