aboutsummaryrefslogtreecommitdiff
path: root/src/background
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2018-07-28 10:42:32 +0900
committerShin'ya Ueoka <ueokande@i-beam.org>2018-07-28 10:42:32 +0900
commit66c23423f931bb66c59cd29cf9279a5de5d56535 (patch)
tree5c2b37cea2e93aa949d88bf12ac97c294aff2335 /src/background
parentab29706348ec9091d1d75c0418f24dfab849a2e5 (diff)
Background operation as Clean Architecture
Diffstat (limited to 'src/background')
-rw-r--r--src/background/components/operation.js3
-rw-r--r--src/background/controllers/operation.js65
-rw-r--r--src/background/infrastructures/content-message-listener.js8
-rw-r--r--src/background/presenters/bookmark.js0
-rw-r--r--src/background/presenters/console.js20
-rw-r--r--src/background/presenters/tab.js35
-rw-r--r--src/background/usecases/operation.js190
7 files changed, 318 insertions, 3 deletions
diff --git a/src/background/components/operation.js b/src/background/components/operation.js
index ce93270..57b2497 100644
--- a/src/background/components/operation.js
+++ b/src/background/components/operation.js
@@ -22,9 +22,6 @@ export default class BackgroundComponent {
onMessage(message, sender) {
switch (message.type) {
- case messages.BACKGROUND_OPERATION:
- return this.store.dispatch(
- this.exec(message.operation, sender.tab));
}
}
diff --git a/src/background/controllers/operation.js b/src/background/controllers/operation.js
new file mode 100644
index 0000000..1339006
--- /dev/null
+++ b/src/background/controllers/operation.js
@@ -0,0 +1,65 @@
+import operations from '../../shared/operations';
+import OperationInteractor from '../usecases/operation';
+
+export default class OperationController {
+ constructor() {
+ this.operationInteractor = new OperationInteractor();
+ }
+
+ // eslint-disable-next-line complexity, max-lines-per-function
+ exec(operation) {
+ switch (operation.type) {
+ case operations.TAB_CLOSE:
+ return this.operationInteractor.close(false);
+ case operations.TAB_CLOSE_FORCE:
+ return this.operationInteractor.close(true);
+ case operations.TAB_REOPEN:
+ return this.operationInteractor.reopen();
+ case operations.TAB_PREV:
+ return this.operationInteractor.selectPrev(1);
+ case operations.TAB_NEXT:
+ return this.operationInteractor.selectNext(1);
+ case operations.TAB_FIRST:
+ return this.operationInteractor.selectFirst();
+ case operations.TAB_LAST:
+ return this.operationInteractor.selectLast();
+ case operations.TAB_PREV_SEL:
+ return this.operationInteractor.selectPrevSelected();
+ case operations.TAB_RELOAD:
+ return this.operationInteractor.reload(operation.cache);
+ case operations.TAB_PIN:
+ return this.operationInteractor.setPinned(true);
+ case operations.TAB_UNPIN:
+ return this.operationInteractor.setPinned(false);
+ case operations.TAB_TOGGLE_PINNED:
+ return this.operationInteractor.togglePinned();
+ case operations.TAB_DUPLICATE:
+ return this.operationInteractor.duplicate();
+ case operations.PAGE_SOURCE:
+ return this.operationInteractor.openPageSource();
+ case operations.ZOOM_IN:
+ return this.operationInteractor.zoomIn();
+ case operations.ZOOM_OUT:
+ return this.operationInteractor.zoomOut();
+ case operations.ZOOM_NEUTRAL:
+ return this.operationInteractor.zoomNutoral();
+ case operations.COMMAND_SHOW:
+ return this.operationInteractor.showCommand();
+ case operations.COMMAND_SHOW_OPEN:
+ return this.operationInteractor.showOpenCommand(operation.alter);
+ case operations.COMMAND_SHOW_TABOPEN:
+ return this.operationInteractor.showTabopenCommand(operation.alter);
+ case operations.COMMAND_SHOW_WINOPEN:
+ return this.operationInteractor.showWinopenCommand(operation.alter);
+ case operations.COMMAND_SHOW_BUFFER:
+ return this.operationInteractor.showBufferCommand();
+ case operations.COMMAND_SHOW_ADDBOOKMARK:
+ return this.operationInteractor.showAddbookmarkCommand(operation.alter);
+ case operations.FIND_START:
+ return this.operationInteractor.findStart();
+ case operations.CANCEL:
+ return this.operationInteractor.hideConsole();
+ }
+ }
+}
+
diff --git a/src/background/infrastructures/content-message-listener.js b/src/background/infrastructures/content-message-listener.js
index 2e84fcc..277d108 100644
--- a/src/background/infrastructures/content-message-listener.js
+++ b/src/background/infrastructures/content-message-listener.js
@@ -4,6 +4,7 @@ import SettingController from '../controllers/setting';
import FindController from '../controllers/find';
import AddonEnabledController from '../controllers/addon-enabled';
import LinkController from '../controllers/link';
+import OperationController from '../controllers/operation';
export default class ContentMessageListener {
constructor() {
@@ -12,6 +13,7 @@ export default class ContentMessageListener {
this.findController = new FindController();
this.addonEnabledController = new AddonEnabledController();
this.linkController = new LinkController();
+ this.backgroundOperationController = new OperationController();
}
run() {
@@ -46,6 +48,8 @@ export default class ContentMessageListener {
case messages.OPEN_URL:
return this.onOpenUrl(
message.newTab, message.url, sender.tab.id, message.background);
+ case messages.BACKGROUND_OPERATION:
+ return this.onBackgroundOperation(message.operation);
}
}
@@ -85,4 +89,8 @@ export default class ContentMessageListener {
}
return this.linkController.openToTab(url, openerId);
}
+
+ onBackgroundOperation(operation) {
+ return this.backgroundOperationController.exec(operation);
+ }
}
diff --git a/src/background/presenters/bookmark.js b/src/background/presenters/bookmark.js
deleted file mode 100644
index e69de29..0000000
--- a/src/background/presenters/bookmark.js
+++ /dev/null
diff --git a/src/background/presenters/console.js b/src/background/presenters/console.js
index f7d3777..8259238 100644
--- a/src/background/presenters/console.js
+++ b/src/background/presenters/console.js
@@ -1,16 +1,36 @@
import messages from '../../shared/messages';
export default class ConsolePresenter {
+ showCommand(tabId, command) {
+ return browser.tabs.sendMessage(tabId, {
+ type: messages.CONSOLE_SHOW_COMMAND,
+ command,
+ });
+ }
+
+ showFind(tabId) {
+ return browser.tabs.sendMessage(tabId, {
+ type: messages.CONSOLE_SHOW_FIND
+ });
+ }
+
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,
});
}
+
+ hide(tabId) {
+ return browser.tabs.sendMessage(tabId, {
+ type: messages.CONSOLE_HIDE,
+ });
+ }
}
diff --git a/src/background/presenters/tab.js b/src/background/presenters/tab.js
index be6955a..2a06a5a 100644
--- a/src/background/presenters/tab.js
+++ b/src/background/presenters/tab.js
@@ -48,6 +48,41 @@ export default class TabPresenter {
return browser.tabs.remove(ids);
}
+ async reopen() {
+ let window = await browser.windows.getCurrent();
+ let sessions = await browser.sessions.getRecentlyClosed();
+ let session = sessions.find((s) => {
+ return s.tab && s.tab.windowId === window.id;
+ });
+ if (!session) {
+ return;
+ }
+ if (session.tab) {
+ return browser.sessions.restore(session.tab.sessionId);
+ }
+ return browser.sessions.restore(session.window.sessionId);
+ }
+
+ reload(tabId, cache) {
+ return browser.tabs.reload(tabId, { bypassCache: cache });
+ }
+
+ setPinned(tabId, pinned) {
+ return browser.tabs.update(tabId, { pinned });
+ }
+
+ duplicate(id) {
+ return browser.tabs.duplicate(id);
+ }
+
+ getZoom(tabId) {
+ return browser.tabs.getZoom(tabId);
+ }
+
+ setZoom(tabId, factor) {
+ return browser.tabs.setZoom(tabId, factor);
+ }
+
async createAdjacent(url, { openerTabId, active }) {
let tabs = await browser.tabs.query({
active: true, currentWindow: true
diff --git a/src/background/usecases/operation.js b/src/background/usecases/operation.js
new file mode 100644
index 0000000..f19c632
--- /dev/null
+++ b/src/background/usecases/operation.js
@@ -0,0 +1,190 @@
+import MemoryStorage from '../infrastructures/memory-storage';
+import TabPresenter from '../presenters/tab';
+import ConsolePresenter from '../presenters/console';
+
+const CURRENT_SELECTED_KEY = 'tabs.current.selected';
+const LAST_SELECTED_KEY = 'tabs.last.selected';
+
+const ZOOM_SETTINGS = [
+ 0.33, 0.50, 0.66, 0.75, 0.80, 0.90, 1.00,
+ 1.10, 1.25, 1.50, 1.75, 2.00, 2.50, 3.00
+];
+
+export default class OperationInteractor {
+ constructor() {
+ this.tabPresenter = new TabPresenter();
+ this.tabPresenter.onSelected(info => this.onTabSelected(info.tabId));
+
+ this.consolePresenter = new ConsolePresenter();
+
+ this.cache = new MemoryStorage();
+ }
+
+ async close(force) {
+ let tab = await this.tabPresenter.getCurrent();
+ if (!force && tab.pinned) {
+ return;
+ }
+ return this.tabPresenter.remove([tab.id]);
+ }
+
+ reopen() {
+ return this.tabPresenter.reopen();
+ }
+
+ async selectPrev(count) {
+ let tabs = await this.tabPresenter.getAll();
+ if (tabs.length < 2) {
+ return;
+ }
+ let tab = tabs.find(t => t.active);
+ if (!tab) {
+ return;
+ }
+ let select = (tab.index - count + tabs.length) % tabs.length;
+ return this.tabPresenter.select(tabs[select].id);
+ }
+
+ async selectNext(count) {
+ let tabs = await this.tabPresenter.getAll();
+ if (tabs.length < 2) {
+ return;
+ }
+ let tab = tabs.find(t => t.active);
+ if (!tab) {
+ return;
+ }
+ let select = (tab.index + count) % tabs.length;
+ return this.tabPresenter.select(tabs[select].id);
+ }
+
+ async selectFirst() {
+ let tabs = await this.tabPresenter.getAll();
+ return this.tabPresenter.select(tabs[0].id);
+ }
+
+ async selectLast() {
+ let tabs = await this.tabPresenter.getAll();
+ return this.tabPresenter.select(tabs[tabs.length - 1].id);
+ }
+
+ async selectPrevSelected() {
+ let tabId = await this.cache.get(LAST_SELECTED_KEY);
+ if (tabId === null || typeof tabId === 'undefined') {
+ return;
+ }
+ this.tabPresenter.select(tabId);
+ }
+
+ async reload(cache) {
+ let tab = await this.tabPresenter.getCurrent();
+ return this.tabPresenter.reload(tab.id, cache);
+ }
+
+ async setPinned(pinned) {
+ let tab = await this.tabPresenter.getCurrent();
+ return this.tabPresenter.setPinned(tab.id, pinned);
+ }
+
+ async togglePinned() {
+ let tab = await this.tabPresenter.getCurrent();
+ return this.tabPresenter.setPinned(tab.id, !tab.pinned);
+ }
+
+ async duplicate() {
+ let tab = await this.tabPresenter.getCurrent();
+ return this.tabPresenter.duplicate(tab.id);
+ }
+
+ async openPageSource() {
+ let tab = await this.tabPresenter.getCurrent();
+ let url = 'view-source:' + tab.url;
+ return this.tabPresenter.create(url);
+ }
+
+ async zoomIn(tabId) {
+ let tab = await this.tabPresenter.getCurrent();
+ let current = await this.tabPresenter.getZoom(tab.id);
+ let factor = ZOOM_SETTINGS.find(f => f > current);
+ if (factor) {
+ return this.tabPresenter.setZoom(tabId, factor);
+ }
+ }
+
+ async zoomOut(tabId) {
+ let tab = await this.tabPresenter.getCurrent();
+ let current = await this.tabPresenter.getZoom(tab.id);
+ let factor = [].concat(ZOOM_SETTINGS).reverse().find(f => f < current);
+ if (factor) {
+ return this.tabPresenter.setZoom(tabId, factor);
+ }
+ }
+
+ zoomNutoral(tabId) {
+ return this.tabPresenter.setZoom(tabId, 1);
+ }
+
+ async showCommand() {
+ let tab = await this.tabPresenter.getCurrent();
+ this.consolePresenter.showCommand(tab.id, '');
+ }
+
+ async showOpenCommand(alter) {
+ let tab = await this.tabPresenter.getCurrent();
+ let command = 'open ';
+ if (alter) {
+ command += tab.url;
+ }
+ return this.consolePresenter.showCommand(tab.id, command);
+ }
+
+ async showTabopenCommand(alter) {
+ let tab = await this.tabPresenter.getCurrent();
+ let command = 'tabopen ';
+ if (alter) {
+ command += tab.url;
+ }
+ return this.consolePresenter.showCommand(tab.id, command);
+ }
+
+ async showWinopenCommand(alter) {
+ let tab = await this.tabPresenter.getCurrent();
+ let command = 'winopen ';
+ if (alter) {
+ command += tab.url;
+ }
+ return this.consolePresenter.showCommand(tab.id, command);
+ }
+
+ async showBufferCommand() {
+ let tab = await this.tabPresenter.getCurrent();
+ let command = 'buffer ';
+ return this.consolePresenter.showCommand(tab.id, command);
+ }
+
+ async showAddbookmarkCommand(alter) {
+ let tab = await this.tabPresenter.getCurrent();
+ let command = 'addbookmark ';
+ if (alter) {
+ command += tab.title;
+ }
+ return this.consolePresenter.showCommand(tab.id, command);
+ }
+
+ async findStart() {
+ let tab = await this.tabPresenter.getCurrent();
+ this.consolePresenter.showFind(tab.id);
+ }
+
+ async hideConsole() {
+ let tab = await this.tabPresenter.getCurrent();
+ this.consolePresenter.hide(tab.id);
+ }
+
+ onTabSelected(tabId) {
+ let lastId = this.cache.get(CURRENT_SELECTED_KEY);
+ this.cache.set(LAST_SELECTED_KEY, lastId);
+ this.cache.set(CURRENT_SELECTED_KEY, tabId);
+ }
+}
+