aboutsummaryrefslogtreecommitdiff
path: root/src/background/usecases/CompletionsUseCase.ts
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2019-05-07 21:16:47 +0900
committerGitHub <noreply@github.com>2019-05-07 21:16:47 +0900
commit05ef6a8ca35aaa801c11eb6b4896caa3690058af (patch)
tree2c7708ca91ac2b462cc86aa28612e3d3943496f3 /src/background/usecases/CompletionsUseCase.ts
parent457d954e08923b4accd28a919c72d0b61db1bb98 (diff)
parent27d0a7f37d24a0ad68a8ccb7dee18fc1d00eea58 (diff)
Merge pull request #578 from ueokande/move-to-typescript
Move to TypeScript
Diffstat (limited to 'src/background/usecases/CompletionsUseCase.ts')
-rw-r--r--src/background/usecases/CompletionsUseCase.ts218
1 files changed, 218 insertions, 0 deletions
diff --git a/src/background/usecases/CompletionsUseCase.ts b/src/background/usecases/CompletionsUseCase.ts
new file mode 100644
index 0000000..ae1ceed
--- /dev/null
+++ b/src/background/usecases/CompletionsUseCase.ts
@@ -0,0 +1,218 @@
+import CompletionGroup from '../domains/CompletionGroup';
+import CommandDocs from '../domains/CommandDocs';
+import CompletionsRepository from '../repositories/CompletionsRepository';
+import * as filters from './filters';
+import SettingRepository from '../repositories/SettingRepository';
+import TabPresenter from '../presenters/TabPresenter';
+import * as PropertyDefs from '../../shared/property-defs';
+
+const COMPLETION_ITEM_LIMIT = 10;
+
+type Tab = browser.tabs.Tab;
+type HistoryItem = browser.history.HistoryItem;
+
+export default class CompletionsUseCase {
+ private tabPresenter: TabPresenter;
+
+ private completionsRepository: CompletionsRepository;
+
+ private settingRepository: SettingRepository;
+
+ constructor() {
+ this.tabPresenter = new TabPresenter();
+ this.completionsRepository = new CompletionsRepository();
+ this.settingRepository = new SettingRepository();
+ }
+
+ queryConsoleCommand(prefix: string): Promise<CompletionGroup[]> {
+ let keys = Object.keys(CommandDocs);
+ let items = keys
+ .filter(name => name.startsWith(prefix))
+ .map(name => ({
+ caption: name,
+ content: name,
+ url: CommandDocs[name],
+ }));
+
+ if (items.length === 0) {
+ return Promise.resolve([]);
+ }
+ return Promise.resolve([{ name: 'Console Command', items }]);
+ }
+
+ async queryOpen(name: string, keywords: string): Promise<CompletionGroup[]> {
+ let settings = await this.settingRepository.get();
+ let groups: CompletionGroup[] = [];
+
+ let complete = settings.properties.complete;
+ for (let c of complete) {
+ if (c === 's') {
+ // eslint-disable-next-line no-await-in-loop
+ let engines = await this.querySearchEngineItems(name, keywords);
+ if (engines.length > 0) {
+ groups.push({ name: 'Search Engines', items: engines });
+ }
+ } else if (c === 'h') {
+ // eslint-disable-next-line no-await-in-loop
+ let histories = await this.queryHistoryItems(name, keywords);
+ if (histories.length > 0) {
+ groups.push({ name: 'History', items: histories });
+ }
+ } else if (c === 'b') {
+ // eslint-disable-next-line no-await-in-loop
+ let bookmarks = await this.queryBookmarkItems(name, keywords);
+ if (bookmarks.length > 0) {
+ groups.push({ name: 'Bookmarks', items: bookmarks });
+ }
+ }
+ }
+ return groups;
+ }
+
+ // eslint-disable-next-line max-statements
+ async queryBuffer(
+ name: string,
+ keywords: string,
+ ): Promise<CompletionGroup[]> {
+ let lastId = await this.tabPresenter.getLastSelectedId();
+ let trimmed = keywords.trim();
+ let tabs: Tab[] = [];
+ if (trimmed.length > 0 && !isNaN(Number(trimmed))) {
+ let all = await this.tabPresenter.getAll();
+ let index = parseInt(trimmed, 10) - 1;
+ if (index >= 0 && index < all.length) {
+ tabs = [all[index]];
+ }
+ } else if (trimmed === '%') {
+ let all = await this.tabPresenter.getAll();
+ let tab = all.find(t => t.active) as Tab;
+ tabs = [tab];
+ } else if (trimmed === '#') {
+ if (typeof lastId !== 'undefined' && lastId !== null) {
+ let all = await this.tabPresenter.getAll();
+ let tab = all.find(t => t.id === lastId) as Tab;
+ tabs = [tab];
+ }
+ } else {
+ tabs = await this.completionsRepository.queryTabs(keywords, false);
+ }
+ const flag = (tab: Tab) => {
+ if (tab.active) {
+ return '%';
+ } else if (tab.id === lastId) {
+ return '#';
+ }
+ return ' ';
+ };
+ let items = tabs.map(tab => ({
+ caption: tab.index + 1 + ': ' + flag(tab) + ' ' + tab.title,
+ content: name + ' ' + tab.title,
+ url: tab.url,
+ icon: tab.favIconUrl,
+ }));
+ if (items.length === 0) {
+ return Promise.resolve([]);
+ }
+ return [{ name: 'Buffers', items }];
+ }
+
+ queryBdelete(name: string, keywords: string): Promise<CompletionGroup[]> {
+ return this.queryTabs(name, true, keywords);
+ }
+
+ queryBdeleteForce(
+ name: string, keywords: string,
+ ): Promise<CompletionGroup[]> {
+ return this.queryTabs(name, false, keywords);
+ }
+
+ querySet(name: string, keywords: string): Promise<CompletionGroup[]> {
+ let items = PropertyDefs.defs.map((def) => {
+ if (def.type === 'boolean') {
+ return [
+ {
+ caption: def.name,
+ content: name + ' ' + def.name,
+ url: 'Enable ' + def.description,
+ }, {
+ caption: 'no' + def.name,
+ content: name + ' no' + def.name,
+ url: 'Disable ' + def.description
+ }
+ ];
+ }
+ return [
+ {
+ caption: def.name,
+ content: name + ' ' + def.name,
+ url: 'Set ' + def.description,
+ }
+ ];
+ });
+ let flatten = items.reduce((acc, val) => acc.concat(val), []);
+ flatten = flatten.filter((item) => {
+ return item.caption.startsWith(keywords);
+ });
+ if (flatten.length === 0) {
+ return Promise.resolve([]);
+ }
+ return Promise.resolve(
+ [{ name: 'Properties', items: flatten }],
+ );
+ }
+
+ async queryTabs(
+ name: string, excludePinned: boolean, args: string,
+ ): Promise<CompletionGroup[]> {
+ let tabs = await this.completionsRepository.queryTabs(args, excludePinned);
+ let items = tabs.map(tab => ({
+ caption: tab.title,
+ content: name + ' ' + tab.title,
+ url: tab.url,
+ icon: tab.favIconUrl
+ }));
+ if (items.length === 0) {
+ return Promise.resolve([]);
+ }
+ return [{ name: 'Buffers', items }];
+ }
+
+ async querySearchEngineItems(name: string, keywords: string) {
+ let settings = await this.settingRepository.get();
+ let engines = Object.keys(settings.search.engines)
+ .filter(key => key.startsWith(keywords));
+ return engines.map(key => ({
+ caption: key,
+ content: name + ' ' + key,
+ }));
+ }
+
+ async queryHistoryItems(name: string, keywords: string) {
+ let histories = await this.completionsRepository.queryHistories(keywords);
+ histories = [histories]
+ .map(filters.filterBlankTitle)
+ .map(filters.filterHttp)
+ .map(filters.filterByTailingSlash)
+ .map(pages => filters.filterByPathname(pages, COMPLETION_ITEM_LIMIT))
+ .map(pages => filters.filterByOrigin(pages, COMPLETION_ITEM_LIMIT))[0]
+ .sort((x: HistoryItem, y: HistoryItem): number => {
+ return Number(x.visitCount) - Number(y.visitCount);
+ })
+ .slice(0, COMPLETION_ITEM_LIMIT);
+ return histories.map(page => ({
+ caption: page.title,
+ content: name + ' ' + page.url,
+ url: page.url
+ }));
+ }
+
+ async queryBookmarkItems(name: string, keywords: string) {
+ let bookmarks = await this.completionsRepository.queryBookmarks(keywords);
+ return bookmarks.slice(0, COMPLETION_ITEM_LIMIT)
+ .map(page => ({
+ caption: page.title,
+ content: name + ' ' + page.url,
+ url: page.url
+ }));
+ }
+}