aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/background/completion/OpenCompletionUseCase.ts (renamed from src/background/completion/CompletionUseCase.ts)2
-rw-r--r--src/background/completion/TabCompletionUseCase.ts34
-rw-r--r--src/background/completion/TabItem.ts11
-rw-r--r--src/background/completion/TabRepository.ts12
-rw-r--r--src/background/completion/impl/TabRepositoryImpl.ts27
-rw-r--r--src/background/controllers/CompletionController.ts15
-rw-r--r--src/background/di.ts4
-rw-r--r--src/background/infrastructures/ContentMessageListener.ts2
-rw-r--r--src/background/presenters/TabPresenter.ts65
-rw-r--r--src/background/usecases/AddonEnabledUseCase.ts4
-rw-r--r--src/background/usecases/CommandUseCase.ts4
-rw-r--r--src/background/usecases/CompletionsUseCase.ts6
-rw-r--r--src/background/usecases/ConsoleUseCase.ts4
-rw-r--r--src/background/usecases/FindUseCase.ts4
-rw-r--r--src/background/usecases/LinkUseCase.ts4
-rw-r--r--src/background/usecases/MarkUseCase.ts4
-rw-r--r--src/background/usecases/NavigateUseCase.ts4
-rw-r--r--src/background/usecases/TabSelectUseCase.ts4
-rw-r--r--src/background/usecases/TabUseCase.ts4
-rw-r--r--src/background/usecases/VersionUseCase.ts2
-rw-r--r--src/background/usecases/ZoomUseCase.ts4
-rw-r--r--src/console/actions/console.ts27
-rw-r--r--src/console/clients/CompletionClient.ts20
-rw-r--r--src/console/components/Console.tsx15
-rw-r--r--src/shared/TabFlag.ts7
-rw-r--r--src/shared/messages.ts17
26 files changed, 258 insertions, 48 deletions
diff --git a/src/background/completion/CompletionUseCase.ts b/src/background/completion/OpenCompletionUseCase.ts
index f7531e7..1b63e7c 100644
--- a/src/background/completion/CompletionUseCase.ts
+++ b/src/background/completion/OpenCompletionUseCase.ts
@@ -15,7 +15,7 @@ export type HistoryItem = {
}
@injectable()
-export default class CompletionUseCase {
+export default class OpenCompletionUseCase {
constructor(
@inject('BookmarkRepository') private bookmarkRepository: BookmarkRepository,
@inject('HistoryRepository') private historyRepository: HistoryRepository,
diff --git a/src/background/completion/TabCompletionUseCase.ts b/src/background/completion/TabCompletionUseCase.ts
new file mode 100644
index 0000000..7e6dce3
--- /dev/null
+++ b/src/background/completion/TabCompletionUseCase.ts
@@ -0,0 +1,34 @@
+import { inject, injectable } from "tsyringe";
+import TabItem from "./TabItem";
+import TabRepository from "./TabRepository";
+import TabPresenter from "../presenters/TabPresenter";
+import TabFlag from "../../shared/TabFlag";
+
+@injectable()
+export default class TabCompletionUseCase {
+ constructor(
+ @inject('TabRepository') private tabRepository: TabRepository,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
+ ) {
+ }
+
+ async queryTabs(query: string, excludePinned: boolean): Promise<TabItem[]> {
+ const lastTabId = await this.tabPresenter.getLastSelectedId();
+ const tabs = await this.tabRepository.queryTabs(query, excludePinned);
+ return tabs.map(tab => {
+ let flag = TabFlag.None;
+ if (tab.active) {
+ flag = TabFlag.CurrentTab
+ } else if (tab.id == lastTabId) {
+ flag = TabFlag.LastTab
+ }
+ return {
+ index: tab.index + 1,
+ flag: flag,
+ title: tab.title,
+ url: tab.url,
+ faviconUrl : tab.faviconUrl
+ }
+ });
+ }
+}
diff --git a/src/background/completion/TabItem.ts b/src/background/completion/TabItem.ts
new file mode 100644
index 0000000..630855a
--- /dev/null
+++ b/src/background/completion/TabItem.ts
@@ -0,0 +1,11 @@
+import TabFlag from "../../shared/TabFlag";
+
+type TabItem = {
+ index: number
+ flag: TabFlag
+ title: string
+ url: string
+ faviconUrl?: string
+}
+
+export default TabItem; \ No newline at end of file
diff --git a/src/background/completion/TabRepository.ts b/src/background/completion/TabRepository.ts
new file mode 100644
index 0000000..61fac3b
--- /dev/null
+++ b/src/background/completion/TabRepository.ts
@@ -0,0 +1,12 @@
+export type Tab = {
+ id: number
+ index: number
+ active: boolean
+ title: string
+ url: string
+ faviconUrl?: string
+}
+
+export default interface TabRepository {
+ queryTabs(query: string, excludePinned: boolean): Promise<Tab[]>;
+}
diff --git a/src/background/completion/impl/TabRepositoryImpl.ts b/src/background/completion/impl/TabRepositoryImpl.ts
new file mode 100644
index 0000000..6692b27
--- /dev/null
+++ b/src/background/completion/impl/TabRepositoryImpl.ts
@@ -0,0 +1,27 @@
+import TabRepository, { Tab } from "../TabRepository";
+
+const COMPLETION_ITEM_LIMIT = 10;
+
+export default class TabRepositoryImpl implements TabRepository {
+ async queryTabs(query: string, excludePinned: boolean): Promise<Tab[]> {
+ const tabs = await browser.tabs.query({ currentWindow: true });
+ return tabs
+ .filter((t) => {
+ return t.url && t.url.toLowerCase().includes(query.toLowerCase()) ||
+ t.title && t.title.toLowerCase().includes(query.toLowerCase());
+ })
+ .filter((t) => {
+ return !(excludePinned && t.pinned);
+ })
+ .filter(item => item.id && item.title && item.url)
+ .slice(0, COMPLETION_ITEM_LIMIT)
+ .map(item => ({
+ id: item.id!!,
+ url: item.url!!,
+ active: item.active,
+ title: item.title!!,
+ faviconUrl: item.favIconUrl,
+ index: item.index,
+ }))
+ }
+} \ No newline at end of file
diff --git a/src/background/controllers/CompletionController.ts b/src/background/controllers/CompletionController.ts
index 313f38b..a268d15 100644
--- a/src/background/controllers/CompletionController.ts
+++ b/src/background/controllers/CompletionController.ts
@@ -1,14 +1,19 @@
import {
ConsoleGetCompletionTypesResponse,
- ConsoleRequestBookmarksResponse, ConsoleRequestHistoryResponse, ConsoleRequestSearchEnginesResponse
+ ConsoleRequestBookmarksResponse,
+ ConsoleRequestHistoryResponse,
+ ConsoleRequestSearchEnginesResponse,
+ ConsoleRequesttabsResponse
} from "../../shared/messages";
import { injectable } from "tsyringe";
-import CompletionUseCase from "../completion/CompletionUseCase";
+import OpenCompletionUseCase from "../completion/OpenCompletionUseCase";
+import TabCompletionUseCase from "../completion/TabCompletionUseCase";
@injectable()
export default class CompletionController {
constructor(
- private completionUseCase: CompletionUseCase,
+ private completionUseCase: OpenCompletionUseCase,
+ private tabCompletionUseCase: TabCompletionUseCase,
) {
}
@@ -28,4 +33,8 @@ export default class CompletionController {
async requestHistory(query: string): Promise<ConsoleRequestHistoryResponse> {
return this.completionUseCase.requestHistory(query);
}
+
+ async queryTabs(query: string, excludePinned: boolean): Promise<ConsoleRequesttabsResponse> {
+ return this.tabCompletionUseCase.queryTabs(query, excludePinned);
+ }
} \ No newline at end of file
diff --git a/src/background/di.ts b/src/background/di.ts
index 0b52e0b..c186262 100644
--- a/src/background/di.ts
+++ b/src/background/di.ts
@@ -6,6 +6,8 @@ import { CachedSettingRepositoryImpl } from "./repositories/CachedSettingReposit
import { container } from 'tsyringe';
import HistoryRepositoryImpl from "./completion/impl/HistoryRepositoryImpl";
import BookmarkRepositoryImpl from "./completion/impl/BookmarkRepositoryImpl";
+import TabRepositoryImpl from "./completion/impl/TabRepositoryImpl";
+import {TabPresenterImpl} from "./presenters/TabPresenter";
container.register('LocalSettingRepository', { useValue: LocalSettingRepository });
container.register('SyncSettingRepository', { useClass: SyncSettingRepository });
@@ -13,3 +15,5 @@ container.register('CachedSettingRepository', { useClass: CachedSettingRepositor
container.register('Notifier', { useClass: NotifierImpl });
container.register('HistoryRepository', { useClass: HistoryRepositoryImpl });
container.register('BookmarkRepository', { useClass: BookmarkRepositoryImpl });
+container.register('TabRepository', { useClass: TabRepositoryImpl });
+container.register('TabPresenter', { useClass: TabPresenterImpl });
diff --git a/src/background/infrastructures/ContentMessageListener.ts b/src/background/infrastructures/ContentMessageListener.ts
index 62cd49f..13aa763 100644
--- a/src/background/infrastructures/ContentMessageListener.ts
+++ b/src/background/infrastructures/ContentMessageListener.ts
@@ -73,6 +73,8 @@ export default class ContentMessageListener {
return this.completionController.requestBookmarks(message.query);
case messages.CONSOLE_REQUEST_HISTORY:
return this.completionController.requestHistory(message.query);
+ case messages.CONSOLE_REQUEST_TABS:
+ return this.completionController.queryTabs(message.query, message.excludePinned);
case messages.CONSOLE_ENTER_COMMAND:
return this.onConsoleEnterCommand(message.text);
case messages.SETTINGS_QUERY:
diff --git a/src/background/presenters/TabPresenter.ts b/src/background/presenters/TabPresenter.ts
index 33d8bea..bded5a2 100644
--- a/src/background/presenters/TabPresenter.ts
+++ b/src/background/presenters/TabPresenter.ts
@@ -1,4 +1,3 @@
-import { injectable } from 'tsyringe';
import MemoryStorage from '../infrastructures/MemoryStorage';
const CURRENT_SELECTED_KEY = 'tabs.current.selected';
@@ -6,8 +5,41 @@ const LAST_SELECTED_KEY = 'tabs.last.selected';
type Tab = browser.tabs.Tab;
-@injectable()
-export default class TabPresenter {
+export default interface TabPresenter {
+ open(url: string, tabId?: number): Promise<Tab>;
+
+ create(url: string, opts?: object): Promise<Tab>;
+
+ getCurrent(): Promise<Tab>;
+
+ getAll(): Promise<Tab[]>;
+
+ getLastSelectedId(): Promise<number | undefined>;
+
+ getByKeyword(keyword: string, excludePinned: boolean): Promise<Tab[]>;
+
+ select(tabId: number): Promise<void>;
+
+ remove(ids: number[]): Promise<void>;
+
+ reopen(): Promise<void>;
+
+ reload(tabId: number, cache: boolean): Promise<void>;
+
+ setPinned(tabId: number, pinned: boolean): Promise<void>;
+
+ duplicate(id: number): Promise<Tab>;
+
+ getZoom(tabId: number): Promise<number>;
+
+ setZoom(tabId: number, factor: number): Promise<void>;
+
+ onSelected(
+ listener: (arg: { tabId: number, windowId: number}) => void,
+ ): void;
+}
+
+export class TabPresenterImpl implements TabPresenter {
open(url: string, tabId?: number): Promise<Tab> {
return browser.tabs.update(tabId, { url });
}
@@ -48,15 +80,15 @@ export default class TabPresenter {
});
}
- select(tabId: number): Promise<Tab> {
- return browser.tabs.update(tabId, { active: true });
+ async select(tabId: number): Promise<void> {
+ await browser.tabs.update(tabId, { active: true });
}
- remove(ids: number[]): Promise<void> {
- return browser.tabs.remove(ids);
+ async remove(ids: number[]): Promise<void> {
+ await browser.tabs.remove(ids);
}
- async reopen(): Promise<any> {
+ async reopen(): Promise<void> {
const window = await browser.windows.getCurrent();
const sessions = await browser.sessions.getRecentlyClosed();
const session = sessions.find((s) => {
@@ -66,19 +98,18 @@ export default class TabPresenter {
return;
}
if (session.tab && session.tab.sessionId) {
- return browser.sessions.restore(session.tab.sessionId);
- }
- if (session.window && session.window.sessionId) {
- return browser.sessions.restore(session.window.sessionId);
+ await browser.sessions.restore(session.tab.sessionId);
+ } else if (session.window && session.window.sessionId) {
+ await browser.sessions.restore(session.window.sessionId);
}
}
- reload(tabId: number, cache: boolean): Promise<void> {
- return browser.tabs.reload(tabId, { bypassCache: cache });
+ async reload(tabId: number, cache: boolean): Promise<void> {
+ await browser.tabs.reload(tabId, { bypassCache: cache });
}
- setPinned(tabId: number, pinned: boolean): Promise<Tab> {
- return browser.tabs.update(tabId, { pinned });
+ async setPinned(tabId: number, pinned: boolean): Promise<void> {
+ await browser.tabs.update(tabId, { pinned });
}
duplicate(id: number): Promise<Tab> {
@@ -100,7 +131,7 @@ export default class TabPresenter {
}
}
-const tabPresenter = new TabPresenter();
+const tabPresenter = new TabPresenterImpl();
tabPresenter.onSelected((tab: any) => {
const cache = new MemoryStorage();
diff --git a/src/background/usecases/AddonEnabledUseCase.ts b/src/background/usecases/AddonEnabledUseCase.ts
index 9abd3dc..51f02e1 100644
--- a/src/background/usecases/AddonEnabledUseCase.ts
+++ b/src/background/usecases/AddonEnabledUseCase.ts
@@ -1,4 +1,4 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import IndicatorPresenter from '../presenters/IndicatorPresenter';
import TabPresenter from '../presenters/TabPresenter';
import ContentMessageClient from '../infrastructures/ContentMessageClient';
@@ -7,7 +7,7 @@ import ContentMessageClient from '../infrastructures/ContentMessageClient';
export default class AddonEnabledUseCase {
constructor(
private indicatorPresentor: IndicatorPresenter,
- private tabPresenter: TabPresenter,
+ @inject("TabPresenter") private tabPresenter: TabPresenter,
private contentMessageClient: ContentMessageClient,
) {
this.indicatorPresentor.onClick((tab) => {
diff --git a/src/background/usecases/CommandUseCase.ts b/src/background/usecases/CommandUseCase.ts
index 7dba664..d2d707e 100644
--- a/src/background/usecases/CommandUseCase.ts
+++ b/src/background/usecases/CommandUseCase.ts
@@ -14,7 +14,7 @@ import RepeatUseCase from '../usecases/RepeatUseCase';
@injectable()
export default class CommandIndicator {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
private windowPresenter: WindowPresenter,
private helpPresenter: HelpPresenter,
@inject("CachedSettingRepository") private cachedSettingRepository: CachedSettingRepository,
@@ -80,7 +80,7 @@ export default class CommandIndicator {
}
const current = await this.tabPresenter.getCurrent();
- const tabs = await this.tabPresenter.getByKeyword(keywords);
+ const tabs = await this.tabPresenter.getByKeyword(keywords, false);
if (tabs.length === 0) {
throw new RangeError('No matching buffer for ' + keywords);
}
diff --git a/src/background/usecases/CompletionsUseCase.ts b/src/background/usecases/CompletionsUseCase.ts
index b75b635..439c81a 100644
--- a/src/background/usecases/CompletionsUseCase.ts
+++ b/src/background/usecases/CompletionsUseCase.ts
@@ -5,17 +5,17 @@ import CompletionsRepository from '../repositories/CompletionsRepository';
import CachedSettingRepository from '../repositories/CachedSettingRepository';
import TabPresenter from '../presenters/TabPresenter';
import Properties from '../../shared/settings/Properties';
-import CompletionUseCase from "../completion/CompletionUseCase";
+import OpenCompletionUseCase from "../completion/OpenCompletionUseCase";
type Tab = browser.tabs.Tab;
@injectable()
export default class CompletionsUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
private completionsRepository: CompletionsRepository,
@inject("CachedSettingRepository") private cachedSettingRepository: CachedSettingRepository,
- private completionUseCase: CompletionUseCase
+ private completionUseCase: OpenCompletionUseCase
) {
}
diff --git a/src/background/usecases/ConsoleUseCase.ts b/src/background/usecases/ConsoleUseCase.ts
index 775a1e0..2de5bc1 100644
--- a/src/background/usecases/ConsoleUseCase.ts
+++ b/src/background/usecases/ConsoleUseCase.ts
@@ -1,4 +1,4 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import TabPresenter from '../presenters/TabPresenter';
import ConsoleClient from '../infrastructures/ConsoleClient';
@@ -6,7 +6,7 @@ import ConsoleClient from '../infrastructures/ConsoleClient';
export default class ConsoleUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
private consoleClient: ConsoleClient,
) {
}
diff --git a/src/background/usecases/FindUseCase.ts b/src/background/usecases/FindUseCase.ts
index b8593c6..cb41cd5 100644
--- a/src/background/usecases/FindUseCase.ts
+++ b/src/background/usecases/FindUseCase.ts
@@ -1,4 +1,4 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import FindRepository from '../repositories/FindRepository';
import TabPresenter from '../presenters/TabPresenter';
import ConsoleClient from '../infrastructures/ConsoleClient';
@@ -6,7 +6,7 @@ import ConsoleClient from '../infrastructures/ConsoleClient';
@injectable()
export default class FindUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
private findRepository: FindRepository,
private consoleClient: ConsoleClient,
) {
diff --git a/src/background/usecases/LinkUseCase.ts b/src/background/usecases/LinkUseCase.ts
index 9c0eab5..be076c7 100644
--- a/src/background/usecases/LinkUseCase.ts
+++ b/src/background/usecases/LinkUseCase.ts
@@ -1,10 +1,10 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import TabPresenter from '../presenters/TabPresenter';
@injectable()
export default class LinkUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
) {
}
diff --git a/src/background/usecases/MarkUseCase.ts b/src/background/usecases/MarkUseCase.ts
index eeac40f..2c0bc13 100644
--- a/src/background/usecases/MarkUseCase.ts
+++ b/src/background/usecases/MarkUseCase.ts
@@ -1,4 +1,4 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import TabPresenter from '../presenters/TabPresenter';
import MarkRepository from '../repositories/MarkRepository';
import ConsoleClient from '../infrastructures/ConsoleClient';
@@ -7,7 +7,7 @@ import ContentMessageClient from '../infrastructures/ContentMessageClient';
@injectable()
export default class MarkUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
private markRepository: MarkRepository,
private consoleClient: ConsoleClient,
private contentMessageClient: ContentMessageClient,
diff --git a/src/background/usecases/NavigateUseCase.ts b/src/background/usecases/NavigateUseCase.ts
index 25e7f20..3aa1ed6 100644
--- a/src/background/usecases/NavigateUseCase.ts
+++ b/src/background/usecases/NavigateUseCase.ts
@@ -1,11 +1,11 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import NavigateClient from '../clients/NavigateClient';
import TabPresenter from '../presenters/TabPresenter';
@injectable()
export default class NavigateUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
private navigateClient: NavigateClient,
) {
}
diff --git a/src/background/usecases/TabSelectUseCase.ts b/src/background/usecases/TabSelectUseCase.ts
index 62098de..271bb6c 100644
--- a/src/background/usecases/TabSelectUseCase.ts
+++ b/src/background/usecases/TabSelectUseCase.ts
@@ -1,10 +1,10 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import TabPresenter from '../presenters/TabPresenter';
@injectable()
export default class TabSelectUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
) {
}
diff --git a/src/background/usecases/TabUseCase.ts b/src/background/usecases/TabUseCase.ts
index 66f8573..418dde5 100644
--- a/src/background/usecases/TabUseCase.ts
+++ b/src/background/usecases/TabUseCase.ts
@@ -1,4 +1,4 @@
-import { injectable } from 'tsyringe';
+import {inject, injectable} from 'tsyringe';
import TabPresenter from '../presenters/TabPresenter';
import WindowPresenter from '../presenters/WindowPresenter';
import BrowserSettingRepository from '../repositories/BrowserSettingRepository';
@@ -6,7 +6,7 @@ import BrowserSettingRepository from '../repositories/BrowserSettingRepository';
@injectable()
export default class TabUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
private windowPresenter: WindowPresenter,
private browserSettingRepository: BrowserSettingRepository,
) {
diff --git a/src/background/usecases/VersionUseCase.ts b/src/background/usecases/VersionUseCase.ts
index 9ea8af9..21a5e2c 100644
--- a/src/background/usecases/VersionUseCase.ts
+++ b/src/background/usecases/VersionUseCase.ts
@@ -5,7 +5,7 @@ import Notifier from '../presenters/Notifier';
@injectable()
export default class VersionUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
@inject("Notifier") private notifier: Notifier,
) {
}
diff --git a/src/background/usecases/ZoomUseCase.ts b/src/background/usecases/ZoomUseCase.ts
index f598871..ca1368d 100644
--- a/src/background/usecases/ZoomUseCase.ts
+++ b/src/background/usecases/ZoomUseCase.ts
@@ -1,4 +1,4 @@
-import { injectable } from 'tsyringe';
+import { inject, injectable } from 'tsyringe';
import TabPresenter from '../presenters/TabPresenter';
const ZOOM_SETTINGS: number[] = [
@@ -9,7 +9,7 @@ const ZOOM_SETTINGS: number[] = [
@injectable()
export default class ZoomUseCase {
constructor(
- private tabPresenter: TabPresenter,
+ @inject('TabPresenter') private tabPresenter: TabPresenter,
) {
}
diff --git a/src/console/actions/console.ts b/src/console/actions/console.ts
index f1db941..603a98d 100644
--- a/src/console/actions/console.ts
+++ b/src/console/actions/console.ts
@@ -1,9 +1,10 @@
import * as messages from '../../shared/messages';
import * as actions from './index';
-import { Command } from "../../shared/Command";
+import {Command} from "../../shared/Command";
import CompletionClient from "../clients/CompletionClient";
import CompletionType from "../../shared/CompletionType";
import Completions from "../Completions";
+import TabFlag from "../../shared/TabFlag";
const completionClient = new CompletionClient();
@@ -155,6 +156,28 @@ const getOpenCompletions = async(
};
};
+const getTabCompletions = async (
+ original: string, command: Command, query: string, excludePinned: boolean,
+): Promise<actions.SetCompletionsAction> => {
+ const items = await completionClient.requestTabs(query, excludePinned);
+ const completions = [{
+ name: 'Buffers',
+ items: items.map(item => ({
+ content: command + ' ' + item.url,
+ caption: `${item.index}: ${item.flag != TabFlag.None ? item.flag : ' ' } ${item.title}`,
+ url: item.url,
+ icon: item.faviconUrl,
+ })),
+ }];
+ return {
+ type: actions.CONSOLE_SET_COMPLETIONS,
+ completions,
+ completionSource: original,
+ }
+};
+
+
+
const getCompletions = async(text: string): Promise<actions.SetCompletionsAction> => {
const completions = await browser.runtime.sendMessage({
type: messages.CONSOLE_QUERY_COMPLETIONS,
@@ -181,6 +204,6 @@ const completionPrev = (): actions.CompletionPrevAction => {
export {
hide, showCommand, showFind, showError, showInfo, hideCommand, setConsoleText, enterCommand, enterFind,
- getCompletions, getCommandCompletions, getOpenCompletions,
+ getCompletions, getCommandCompletions, getOpenCompletions, getTabCompletions,
completionNext, completionPrev,
};
diff --git a/src/console/clients/CompletionClient.ts b/src/console/clients/CompletionClient.ts
index d5f9b01..19b4d99 100644
--- a/src/console/clients/CompletionClient.ts
+++ b/src/console/clients/CompletionClient.ts
@@ -2,9 +2,10 @@ import * as messages from "../../shared/messages";
import {
ConsoleGetCompletionTypesResponse,
ConsoleRequestBookmarksResponse,
- ConsoleRequestHistoryResponse, ConsoleRequestSearchEnginesResponse
+ ConsoleRequestHistoryResponse, ConsoleRequestSearchEnginesResponse, ConsoleRequesttabsResponse
} from "../../shared/messages";
import CompletionType from "../../shared/CompletionType";
+import TabFlag from "../../shared/TabFlag";
export type SearchEngines = {
title: string
@@ -20,6 +21,14 @@ export type HistoryItem = {
url: string
}
+export type TabItem = {
+ index: number
+ flag: TabFlag
+ title: string
+ url: string
+ faviconUrl?: string
+}
+
export default class CompletionClient {
async getCompletionTypes(): Promise<CompletionType[]> {
const resp = await browser.runtime.sendMessage({
@@ -51,4 +60,13 @@ export default class CompletionClient {
}) as ConsoleRequestHistoryResponse;
return resp;
}
+
+ async requestTabs(query: string, excludePinned: boolean): Promise<TabItem[]> {
+ const resp = await browser.runtime.sendMessage({
+ type: messages.CONSOLE_REQUEST_TABS,
+ query,
+ excludePinned,
+ }) as ConsoleRequesttabsResponse;
+ return resp;
+ }
}
diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx
index 7be073e..c1709cd 100644
--- a/src/console/components/Console.tsx
+++ b/src/console/components/Console.tsx
@@ -171,6 +171,21 @@ class Console extends React.Component<Props> {
case Command.WindowOpen:
this.props.dispatch(consoleActions.getOpenCompletions(this.props.completionTypes, text, cmd.command, cmd.args));
break;
+ case Command.Buffer:
+ this.props.dispatch(consoleActions.getTabCompletions(text, cmd.command, cmd.args, false));
+ break;
+ case Command.BufferDelete:
+ this.props.dispatch(consoleActions.getTabCompletions(text, cmd.command, cmd.args, true));
+ break;
+ case Command.BufferDeleteForce:
+ this.props.dispatch(consoleActions.getTabCompletions(text, cmd.command, cmd.args, false));
+ break;
+ case Command.BuffersDelete:
+ this.props.dispatch(consoleActions.getTabCompletions(text, cmd.command, cmd.args, true));
+ break;
+ case Command.BuffersDeleteForce:
+ this.props.dispatch(consoleActions.getTabCompletions(text, cmd.command, cmd.args, false));
+ break;
default:
this.props.dispatch(consoleActions.getCompletions(text));
}
diff --git a/src/shared/TabFlag.ts b/src/shared/TabFlag.ts
new file mode 100644
index 0000000..b10d5c6
--- /dev/null
+++ b/src/shared/TabFlag.ts
@@ -0,0 +1,7 @@
+enum TabFlag {
+ CurrentTab = '%',
+ LastTab = '#',
+ None = '',
+}
+
+export default TabFlag \ No newline at end of file
diff --git a/src/shared/messages.ts b/src/shared/messages.ts
index be6a2e1..3f6b7bf 100644
--- a/src/shared/messages.ts
+++ b/src/shared/messages.ts
@@ -1,5 +1,6 @@
import * as operations from './operations';
import CompletionType from "./CompletionType";
+import TabFlag from "./TabFlag";
export const BACKGROUND_OPERATION = 'background.operation';
@@ -16,6 +17,7 @@ export const CONSOLE_GET_COMPLETION_TYPES = 'console.get.completion.types'
export const CONSOLE_REQUEST_SEARCH_ENGINES_MESSAGE = 'console.qresut.searchEngines';
export const CONSOLE_REQUEST_BOOKMARKS = 'console.request.bookmarks';
export const CONSOLE_REQUEST_HISTORY = 'console.request.history';
+export const CONSOLE_REQUEST_TABS = 'console.request.tabs';
export const FOLLOW_START = 'follow.start';
export const FOLLOW_REQUEST_COUNT_TARGETS = 'follow.request.count.targets';
@@ -119,6 +121,20 @@ export interface ConsoleRequestHistoryMessage {
query: string;
}
+export interface ConsoleRequestTabsMessage {
+ type: typeof CONSOLE_REQUEST_TABS;
+ query: string;
+ excludePinned: boolean;
+}
+
+export type ConsoleRequesttabsResponse = {
+ index: number
+ flag: TabFlag
+ title: string
+ url: string
+ faviconUrl?: string
+}[]
+
export type ConsoleGetCompletionTypesResponse = CompletionType[];
export type ConsoleRequestSearchEnginesResponse = {
@@ -279,6 +295,7 @@ export type Message =
ConsoleHideMessage |
ConsoleRequestBookmarksMessage |
ConsoleRequestHistoryMessage |
+ ConsoleRequestTabsMessage |
ConsoleGetCompletionTypesMessage |
ConsoleRequestSearchEnginesMessage |
FollowStartMessage |