parent
c6288f19d9
commit
8cef5981b8
7 changed files with 195 additions and 52 deletions
@ -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, |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -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'); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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 }; |
|
@ -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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
import ClipboardRepository from '../../../src/content/repositories/ClipboardRepository'; |
||||||
|
import TabsClient from '../../../src/content/client/TabsClient'; |
||||||
|
import MockConsoleClient from '../mock/MockConsoleClient'; |
||||||
|
import ClipboardUseCase from '../../../src/content/usecases/ClipboardUseCase'; |
||||||
|
import { expect } from 'chai'; |
||||||
|
|
||||||
|
class MockClipboardRepository implements ClipboardRepository { |
||||||
|
public clipboard: string; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.clipboard = ''; |
||||||
|
} |
||||||
|
|
||||||
|
read(): string { |
||||||
|
return this.clipboard; |
||||||
|
} |
||||||
|
|
||||||
|
write(text: string): void { |
||||||
|
this.clipboard = text; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class MockTabsClient implements TabsClient { |
||||||
|
public last: string; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.last = ''; |
||||||
|
} |
||||||
|
|
||||||
|
openUrl(url: string, _newTab: boolean): Promise<void> { |
||||||
|
this.last = url; |
||||||
|
return Promise.resolve(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
describe('ClipboardUseCase', () => { |
||||||
|
let repository: MockClipboardRepository; |
||||||
|
let client: MockTabsClient; |
||||||
|
let consoleClient: MockConsoleClient; |
||||||
|
let sut: ClipboardUseCase; |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
repository = new MockClipboardRepository(); |
||||||
|
client = new MockTabsClient(); |
||||||
|
consoleClient = new MockConsoleClient(); |
||||||
|
sut = new ClipboardUseCase({ repository, client: client, consoleClient }); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#yankCurrentURL', () => { |
||||||
|
it('yanks current url', async () => { |
||||||
|
let yanked = await sut.yankCurrentURL(); |
||||||
|
|
||||||
|
expect(yanked).to.equal(window.location.href); |
||||||
|
expect(repository.clipboard).to.equal(yanked); |
||||||
|
expect(consoleClient.text).to.equal('Yanked ' + yanked); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#openOrSearch', () => { |
||||||
|
it('opens url from the clipboard', async () => { |
||||||
|
let url = 'https://github.com/ueokande/vim-vixen' |
||||||
|
repository.clipboard = url; |
||||||
|
await sut.openOrSearch(true); |
||||||
|
|
||||||
|
expect(client.last).to.equal(url); |
||||||
|
}); |
||||||
|
|
||||||
|
it('opens search results from the clipboard', async () => { |
||||||
|
repository.clipboard = 'banana'; |
||||||
|
await sut.openOrSearch(true); |
||||||
|
|
||||||
|
expect(client.last).to.equal('https://google.com/search?q=banana'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
Reference in new issue