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