parent
0846587baf
commit
c4afd7237b
10 changed files with 291 additions and 49 deletions
@ -0,0 +1,89 @@ |
|||||||
|
import CompletionsInteractor from '../usecases/completions'; |
||||||
|
import CommandInteractor from '../usecases/command'; |
||||||
|
import Completions from '../domains/completions'; |
||||||
|
|
||||||
|
export default class CommandController { |
||||||
|
constructor() { |
||||||
|
this.completionsInteractor = new CompletionsInteractor(); |
||||||
|
this.commandIndicator = new CommandInteractor(); |
||||||
|
} |
||||||
|
|
||||||
|
getCompletions(line) { |
||||||
|
let trimmed = line.trimStart(); |
||||||
|
let words = trimmed.split(/ +/); |
||||||
|
let name = words[0]; |
||||||
|
if (words.length === 1) { |
||||||
|
return this.completionsInteractor.queryConsoleCommand(name); |
||||||
|
} |
||||||
|
let keywords = trimmed.slice(name.length).trimStart(); |
||||||
|
switch (words[0]) { |
||||||
|
case 'o': |
||||||
|
case 'open': |
||||||
|
case 't': |
||||||
|
case 'tabopen': |
||||||
|
case 'w': |
||||||
|
case 'winopen': |
||||||
|
return this.completionsInteractor.queryOpen(name, keywords); |
||||||
|
case 'b': |
||||||
|
case 'buffer': |
||||||
|
return this.completionsInteractor.queryBuffer(name, keywords); |
||||||
|
case 'bd': |
||||||
|
case 'bdel': |
||||||
|
case 'bdelete': |
||||||
|
case 'bdeletes': |
||||||
|
return this.completionsInteractor.queryBdelete(name, keywords); |
||||||
|
case 'bd!': |
||||||
|
case 'bdel!': |
||||||
|
case 'bdelete!': |
||||||
|
case 'bdeletes!': |
||||||
|
return this.completionsInteractor.queryBdeleteForce(name, keywords); |
||||||
|
case 'set': |
||||||
|
return this.completionsInteractor.querySet(name, keywords); |
||||||
|
} |
||||||
|
return Promise.resolve(Completions.empty()); |
||||||
|
} |
||||||
|
|
||||||
|
// eslint-disable-next-line complexity
|
||||||
|
exec(line) { |
||||||
|
let trimmed = line.trimStart(); |
||||||
|
let words = trimmed.split(/ +/); |
||||||
|
let name = words[0]; |
||||||
|
let keywords = trimmed.slice(name.length).trimStart(); |
||||||
|
switch (words[0]) { |
||||||
|
case 'o': |
||||||
|
case 'open': |
||||||
|
return this.commandIndicator.open(keywords); |
||||||
|
case 't': |
||||||
|
case 'tabopen': |
||||||
|
return this.commandIndicator.tabopen(keywords); |
||||||
|
case 'w': |
||||||
|
case 'winopen': |
||||||
|
return this.commandIndicator.winopen(keywords); |
||||||
|
case 'b': |
||||||
|
case 'buffer': |
||||||
|
return this.commandIndicator.buffer(keywords); |
||||||
|
case 'bd': |
||||||
|
case 'bdel': |
||||||
|
case 'bdelete': |
||||||
|
return this.commandIndicator.bdelete(false, keywords); |
||||||
|
case 'bd!': |
||||||
|
case 'bdel!': |
||||||
|
case 'bdelete!': |
||||||
|
return this.commandIndicator.bdelete(true, keywords); |
||||||
|
case 'bdeletes': |
||||||
|
return this.commandIndicator.bdeletes(false, keywords); |
||||||
|
case 'bdeletes!': |
||||||
|
return this.commandIndicator.bdeletes(true, keywords); |
||||||
|
case 'addbookmark': |
||||||
|
return this.commandIndicator.addbookmark(keywords); |
||||||
|
case 'q': |
||||||
|
case 'quit': |
||||||
|
return this.commandIndicator.quit(); |
||||||
|
case 'qa': |
||||||
|
case 'quitall': |
||||||
|
return this.commandIndicator.quitAll(); |
||||||
|
case 'set': |
||||||
|
return this.commandIndicator.set(keywords); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,43 +0,0 @@ |
|||||||
import CompletionsInteractor from '../usecases/completions'; |
|
||||||
import Completions from '../domains/completions'; |
|
||||||
|
|
||||||
export default class ContentMessageController { |
|
||||||
constructor() { |
|
||||||
this.completionsInteractor = new CompletionsInteractor(); |
|
||||||
} |
|
||||||
|
|
||||||
getCompletions(line) { |
|
||||||
let trimmed = line.trimStart(); |
|
||||||
let words = trimmed.split(/ +/); |
|
||||||
let name = words[0]; |
|
||||||
if (words.length === 1) { |
|
||||||
return this.completionsInteractor.queryConsoleCommand(name); |
|
||||||
} |
|
||||||
let keywords = trimmed.slice(name.length).trimStart(); |
|
||||||
switch (words[0]) { |
|
||||||
case 'o': |
|
||||||
case 'open': |
|
||||||
case 't': |
|
||||||
case 'tabopen': |
|
||||||
case 'w': |
|
||||||
case 'winopen': |
|
||||||
return this.completionsInteractor.queryOpen(name, keywords); |
|
||||||
case 'b': |
|
||||||
case 'buffer': |
|
||||||
return this.completionsInteractor.queryBuffer(name, keywords); |
|
||||||
case 'bd': |
|
||||||
case 'bdel': |
|
||||||
case 'bdelete': |
|
||||||
case 'bdeletes': |
|
||||||
return this.completionsInteractor.queryBdelete(name, keywords); |
|
||||||
case 'bd!': |
|
||||||
case 'bdel!': |
|
||||||
case 'bdelete!': |
|
||||||
case 'bdeletes!': |
|
||||||
return this.completionsInteractor.queryBdeleteForce(name, keywords); |
|
||||||
case 'set': |
|
||||||
return this.completionsInteractor.querySet(name, keywords); |
|
||||||
} |
|
||||||
return Promise.resolve(Completions.empty()); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,16 @@ |
|||||||
|
import messages from '../../shared/messages'; |
||||||
|
|
||||||
|
export default class ConsolePresenter { |
||||||
|
showInfo(tabId, message) { |
||||||
|
return browser.tabs.sendMessage(tabId, { |
||||||
|
type: messages.CONSOLE_SHOW_INFO, |
||||||
|
text: message, |
||||||
|
}); |
||||||
|
} |
||||||
|
showError(tabId, message) { |
||||||
|
return browser.tabs.sendMessage(tabId, { |
||||||
|
type: messages.CONSOLE_SHOW_ERROR, |
||||||
|
text: message, |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
export default class WindowPresenter { |
||||||
|
create(url) { |
||||||
|
return browser.windows.create({ url }); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
export default class BookmarkRepository { |
||||||
|
async create(title, url) { |
||||||
|
let item = await browser.bookmarks.create({ |
||||||
|
type: 'bookmark', |
||||||
|
title, |
||||||
|
url, |
||||||
|
}); |
||||||
|
if (!item) { |
||||||
|
throw new Error('Could not create a bookmark'); |
||||||
|
} |
||||||
|
return item; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
import TabPresenter from '../presenters/tab'; |
||||||
|
import WindowPresenter from '../presenters/window'; |
||||||
|
import SettingRepository from '../repositories/setting'; |
||||||
|
import BookmarkRepository from '../repositories/bookmark'; |
||||||
|
import ConsolePresenter from '../presenters/console'; |
||||||
|
|
||||||
|
export default class CommandIndicator { |
||||||
|
constructor() { |
||||||
|
this.tabPresenter = new TabPresenter(); |
||||||
|
this.windowPresenter = new WindowPresenter(); |
||||||
|
this.settingRepository = new SettingRepository(); |
||||||
|
this.bookmarkRepository = new BookmarkRepository(); |
||||||
|
this.consolePresenter = new ConsolePresenter(); |
||||||
|
} |
||||||
|
|
||||||
|
async open(keywords) { |
||||||
|
let url = await this.urlOrSearch(keywords); |
||||||
|
return this.tabPresenter.open(url); |
||||||
|
} |
||||||
|
|
||||||
|
async tabopen(keywords) { |
||||||
|
let url = await this.urlOrSearch(keywords); |
||||||
|
return this.tabPresenter.create(url); |
||||||
|
} |
||||||
|
|
||||||
|
async winopen(keywords) { |
||||||
|
let url = await this.urlOrSearch(keywords); |
||||||
|
return this.windowPresenter.create(url); |
||||||
|
} |
||||||
|
|
||||||
|
async buffer(keywords) { |
||||||
|
if (keywords.length === 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!isNaN(keywords)) { |
||||||
|
let index = parseInt(keywords, 10) - 1; |
||||||
|
return tabs.selectAt(index); |
||||||
|
} |
||||||
|
|
||||||
|
let current = await this.tabPresenter.getCurrent(); |
||||||
|
let tabs = await this.tabPresenter.getByKeyword(keywords); |
||||||
|
if (tabs.length === 0) { |
||||||
|
throw new RangeError('No matching buffer for ' + keywords); |
||||||
|
} |
||||||
|
for (let tab of tabs) { |
||||||
|
if (tab.index > current.index) { |
||||||
|
return this.tabPresenter.select(tab.id); |
||||||
|
} |
||||||
|
} |
||||||
|
return this.tabPresenter.select(tabs[0].id); |
||||||
|
} |
||||||
|
|
||||||
|
async bdelete(force, keywords) { |
||||||
|
let excludePinned = !force; |
||||||
|
let tabs = await this.tabPresenter.getByKeyword(keywords, excludePinned); |
||||||
|
if (tabs.length === 0) { |
||||||
|
throw new Error('No matching buffer for ' + keywords); |
||||||
|
} else if (tabs.length > 1) { |
||||||
|
throw new Error('More than one match for ' + keywords); |
||||||
|
} |
||||||
|
return this.tabPresenter.remove([tabs[0].id]); |
||||||
|
} |
||||||
|
|
||||||
|
async bdeletes(force, keywords) { |
||||||
|
let excludePinned = !force; |
||||||
|
let tabs = await this.tabPresenter.getByKeyword(keywords, excludePinned); |
||||||
|
let ids = tabs.map(tab => tab.id); |
||||||
|
return this.tabPresenter.remove(ids); |
||||||
|
} |
||||||
|
|
||||||
|
async quit() { |
||||||
|
let tab = await this.tabPresenter.getCurrent(); |
||||||
|
return this.tabPresenter.remove([tab.id]); |
||||||
|
} |
||||||
|
|
||||||
|
async quitall() { |
||||||
|
let tabs = await this.tabPresenter.getAll(); |
||||||
|
let ids = tabs.map(tab => tab.id); |
||||||
|
this.tabPresenter.tabPresenter.remove(ids); |
||||||
|
} |
||||||
|
|
||||||
|
async addbookmark(title) { |
||||||
|
let tab = await this.tabPresenter.getCurrent(); |
||||||
|
let item = await this.bookmarkRepository.create(title, tab.url); |
||||||
|
let message = 'Saved current page: ' + item.url; |
||||||
|
return this.consolePresenter.showInfo(tab.id, message); |
||||||
|
} |
||||||
|
|
||||||
|
set(keywords) { |
||||||
|
// TODO implement set command
|
||||||
|
} |
||||||
|
|
||||||
|
async urlOrSearch(keywords) { |
||||||
|
try { |
||||||
|
return new URL(keywords).href; |
||||||
|
} catch (e) { |
||||||
|
if (keywords.includes('.') && !keywords.includes(' ')) { |
||||||
|
return 'http://' + keywords; |
||||||
|
} |
||||||
|
let settings = await this.settingRepository.get(); |
||||||
|
let engines = settings.search.engines; |
||||||
|
|
||||||
|
let template = engines[settings.search.default]; |
||||||
|
let query = keywords; |
||||||
|
|
||||||
|
let first = keywords.trimStart().split(' ')[0]; |
||||||
|
if (Object.keys(engines).includes(first)) { |
||||||
|
template = engines[first]; |
||||||
|
query = keywords.trimStart().slice(first.length).trimStart(); |
||||||
|
} |
||||||
|
return template.replace('{}', encodeURIComponent(query)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Reference in new issue