From c60d0e7392fc708e961614d6b756a045de74f458 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Tue, 30 Apr 2019 14:00:07 +0900 Subject: Rename .js/.jsx to .ts/.tsx --- .../controllers/AddonEnabledController.js | 11 -- .../controllers/AddonEnabledController.ts | 11 ++ src/background/controllers/CommandController.js | 99 ---------- src/background/controllers/CommandController.ts | 99 ++++++++++ src/background/controllers/FindController.js | 15 -- src/background/controllers/FindController.ts | 15 ++ src/background/controllers/LinkController.js | 15 -- src/background/controllers/LinkController.ts | 15 ++ src/background/controllers/MarkController.js | 15 -- src/background/controllers/MarkController.ts | 15 ++ src/background/controllers/OperationController.js | 77 -------- src/background/controllers/OperationController.ts | 77 ++++++++ src/background/controllers/SettingController.js | 18 -- src/background/controllers/SettingController.ts | 18 ++ src/background/controllers/VersionController.js | 11 -- src/background/controllers/VersionController.ts | 11 ++ src/background/controllers/version.js | 13 -- src/background/controllers/version.ts | 13 ++ src/background/domains/CommandDocs.js | 12 -- src/background/domains/CommandDocs.ts | 12 ++ src/background/domains/CompletionGroup.js | 14 -- src/background/domains/CompletionGroup.ts | 14 ++ src/background/domains/CompletionItem.js | 24 --- src/background/domains/CompletionItem.ts | 24 +++ src/background/domains/Completions.js | 27 --- src/background/domains/Completions.ts | 27 +++ src/background/domains/GlobalMark.js | 24 --- src/background/domains/GlobalMark.ts | 24 +++ src/background/domains/Setting.js | 51 ----- src/background/domains/Setting.ts | 51 +++++ src/background/index.js | 23 --- src/background/index.ts | 23 +++ src/background/infrastructures/ConsoleClient.js | 37 ---- src/background/infrastructures/ConsoleClient.ts | 37 ++++ .../infrastructures/ContentMessageClient.js | 36 ---- .../infrastructures/ContentMessageClient.ts | 36 ++++ .../infrastructures/ContentMessageListener.js | 135 -------------- .../infrastructures/ContentMessageListener.ts | 135 ++++++++++++++ src/background/infrastructures/MemoryStorage.js | 19 -- src/background/infrastructures/MemoryStorage.ts | 19 ++ src/background/presenters/IndicatorPresenter.js | 12 -- src/background/presenters/IndicatorPresenter.ts | 12 ++ src/background/presenters/NotifyPresenter.js | 23 --- src/background/presenters/NotifyPresenter.ts | 23 +++ src/background/presenters/TabPresenter.js | 102 ---------- src/background/presenters/TabPresenter.ts | 102 ++++++++++ src/background/presenters/WindowPresenter.js | 5 - src/background/presenters/WindowPresenter.ts | 5 + src/background/repositories/BookmarkRepository.js | 13 -- src/background/repositories/BookmarkRepository.ts | 13 ++ .../repositories/BrowserSettingRepository.js | 8 - .../repositories/BrowserSettingRepository.ts | 8 + .../repositories/CompletionsRepository.js | 31 ---- .../repositories/CompletionsRepository.ts | 31 ++++ src/background/repositories/FindRepository.js | 19 -- src/background/repositories/FindRepository.ts | 19 ++ src/background/repositories/MarkRepository.js | 33 ---- src/background/repositories/MarkRepository.ts | 33 ++++ .../repositories/PersistentSettingRepository.js | 12 -- .../repositories/PersistentSettingRepository.ts | 12 ++ src/background/repositories/SettingRepository.js | 23 --- src/background/repositories/SettingRepository.ts | 23 +++ src/background/repositories/VersionRepository.js | 10 - src/background/repositories/VersionRepository.ts | 10 + src/background/usecases/AddonEnabledUseCase.js | 29 --- src/background/usecases/AddonEnabledUseCase.ts | 29 +++ src/background/usecases/CommandUseCase.js | 125 ------------- src/background/usecases/CommandUseCase.ts | 125 +++++++++++++ src/background/usecases/CompletionsUseCase.js | 205 --------------------- src/background/usecases/CompletionsUseCase.ts | 205 +++++++++++++++++++++ src/background/usecases/ConsoleUseCase.js | 61 ------ src/background/usecases/ConsoleUseCase.ts | 61 ++++++ src/background/usecases/FindUseCase.js | 24 --- src/background/usecases/FindUseCase.ts | 24 +++ src/background/usecases/LinkUseCase.js | 19 -- src/background/usecases/LinkUseCase.ts | 19 ++ src/background/usecases/MarkUseCase.js | 39 ---- src/background/usecases/MarkUseCase.ts | 39 ++++ src/background/usecases/SettingUseCase.js | 28 --- src/background/usecases/SettingUseCase.ts | 28 +++ src/background/usecases/TabSelectUseCase.js | 51 ----- src/background/usecases/TabSelectUseCase.ts | 51 +++++ src/background/usecases/TabUseCase.js | 77 -------- src/background/usecases/TabUseCase.ts | 77 ++++++++ src/background/usecases/VersionUseCase.js | 26 --- src/background/usecases/VersionUseCase.ts | 26 +++ src/background/usecases/ZoomUseCase.js | 35 ---- src/background/usecases/ZoomUseCase.ts | 35 ++++ src/background/usecases/filters.js | 72 -------- src/background/usecases/filters.ts | 72 ++++++++ src/background/usecases/parsers.js | 31 ---- src/background/usecases/parsers.ts | 31 ++++ 92 files changed, 1789 insertions(+), 1789 deletions(-) delete mode 100644 src/background/controllers/AddonEnabledController.js create mode 100644 src/background/controllers/AddonEnabledController.ts delete mode 100644 src/background/controllers/CommandController.js create mode 100644 src/background/controllers/CommandController.ts delete mode 100644 src/background/controllers/FindController.js create mode 100644 src/background/controllers/FindController.ts delete mode 100644 src/background/controllers/LinkController.js create mode 100644 src/background/controllers/LinkController.ts delete mode 100644 src/background/controllers/MarkController.js create mode 100644 src/background/controllers/MarkController.ts delete mode 100644 src/background/controllers/OperationController.js create mode 100644 src/background/controllers/OperationController.ts delete mode 100644 src/background/controllers/SettingController.js create mode 100644 src/background/controllers/SettingController.ts delete mode 100644 src/background/controllers/VersionController.js create mode 100644 src/background/controllers/VersionController.ts delete mode 100644 src/background/controllers/version.js create mode 100644 src/background/controllers/version.ts delete mode 100644 src/background/domains/CommandDocs.js create mode 100644 src/background/domains/CommandDocs.ts delete mode 100644 src/background/domains/CompletionGroup.js create mode 100644 src/background/domains/CompletionGroup.ts delete mode 100644 src/background/domains/CompletionItem.js create mode 100644 src/background/domains/CompletionItem.ts delete mode 100644 src/background/domains/Completions.js create mode 100644 src/background/domains/Completions.ts delete mode 100644 src/background/domains/GlobalMark.js create mode 100644 src/background/domains/GlobalMark.ts delete mode 100644 src/background/domains/Setting.js create mode 100644 src/background/domains/Setting.ts delete mode 100644 src/background/index.js create mode 100644 src/background/index.ts delete mode 100644 src/background/infrastructures/ConsoleClient.js create mode 100644 src/background/infrastructures/ConsoleClient.ts delete mode 100644 src/background/infrastructures/ContentMessageClient.js create mode 100644 src/background/infrastructures/ContentMessageClient.ts delete mode 100644 src/background/infrastructures/ContentMessageListener.js create mode 100644 src/background/infrastructures/ContentMessageListener.ts delete mode 100644 src/background/infrastructures/MemoryStorage.js create mode 100644 src/background/infrastructures/MemoryStorage.ts delete mode 100644 src/background/presenters/IndicatorPresenter.js create mode 100644 src/background/presenters/IndicatorPresenter.ts delete mode 100644 src/background/presenters/NotifyPresenter.js create mode 100644 src/background/presenters/NotifyPresenter.ts delete mode 100644 src/background/presenters/TabPresenter.js create mode 100644 src/background/presenters/TabPresenter.ts delete mode 100644 src/background/presenters/WindowPresenter.js create mode 100644 src/background/presenters/WindowPresenter.ts delete mode 100644 src/background/repositories/BookmarkRepository.js create mode 100644 src/background/repositories/BookmarkRepository.ts delete mode 100644 src/background/repositories/BrowserSettingRepository.js create mode 100644 src/background/repositories/BrowserSettingRepository.ts delete mode 100644 src/background/repositories/CompletionsRepository.js create mode 100644 src/background/repositories/CompletionsRepository.ts delete mode 100644 src/background/repositories/FindRepository.js create mode 100644 src/background/repositories/FindRepository.ts delete mode 100644 src/background/repositories/MarkRepository.js create mode 100644 src/background/repositories/MarkRepository.ts delete mode 100644 src/background/repositories/PersistentSettingRepository.js create mode 100644 src/background/repositories/PersistentSettingRepository.ts delete mode 100644 src/background/repositories/SettingRepository.js create mode 100644 src/background/repositories/SettingRepository.ts delete mode 100644 src/background/repositories/VersionRepository.js create mode 100644 src/background/repositories/VersionRepository.ts delete mode 100644 src/background/usecases/AddonEnabledUseCase.js create mode 100644 src/background/usecases/AddonEnabledUseCase.ts delete mode 100644 src/background/usecases/CommandUseCase.js create mode 100644 src/background/usecases/CommandUseCase.ts delete mode 100644 src/background/usecases/CompletionsUseCase.js create mode 100644 src/background/usecases/CompletionsUseCase.ts delete mode 100644 src/background/usecases/ConsoleUseCase.js create mode 100644 src/background/usecases/ConsoleUseCase.ts delete mode 100644 src/background/usecases/FindUseCase.js create mode 100644 src/background/usecases/FindUseCase.ts delete mode 100644 src/background/usecases/LinkUseCase.js create mode 100644 src/background/usecases/LinkUseCase.ts delete mode 100644 src/background/usecases/MarkUseCase.js create mode 100644 src/background/usecases/MarkUseCase.ts delete mode 100644 src/background/usecases/SettingUseCase.js create mode 100644 src/background/usecases/SettingUseCase.ts delete mode 100644 src/background/usecases/TabSelectUseCase.js create mode 100644 src/background/usecases/TabSelectUseCase.ts delete mode 100644 src/background/usecases/TabUseCase.js create mode 100644 src/background/usecases/TabUseCase.ts delete mode 100644 src/background/usecases/VersionUseCase.js create mode 100644 src/background/usecases/VersionUseCase.ts delete mode 100644 src/background/usecases/ZoomUseCase.js create mode 100644 src/background/usecases/ZoomUseCase.ts delete mode 100644 src/background/usecases/filters.js create mode 100644 src/background/usecases/filters.ts delete mode 100644 src/background/usecases/parsers.js create mode 100644 src/background/usecases/parsers.ts (limited to 'src/background') diff --git a/src/background/controllers/AddonEnabledController.js b/src/background/controllers/AddonEnabledController.js deleted file mode 100644 index 9a3a521..0000000 --- a/src/background/controllers/AddonEnabledController.js +++ /dev/null @@ -1,11 +0,0 @@ -import AddonEnabledUseCase from '../usecases/AddonEnabledUseCase'; - -export default class AddonEnabledController { - constructor() { - this.addonEnabledUseCase = new AddonEnabledUseCase(); - } - - indicate(enabled) { - return this.addonEnabledUseCase.indicate(enabled); - } -} diff --git a/src/background/controllers/AddonEnabledController.ts b/src/background/controllers/AddonEnabledController.ts new file mode 100644 index 0000000..9a3a521 --- /dev/null +++ b/src/background/controllers/AddonEnabledController.ts @@ -0,0 +1,11 @@ +import AddonEnabledUseCase from '../usecases/AddonEnabledUseCase'; + +export default class AddonEnabledController { + constructor() { + this.addonEnabledUseCase = new AddonEnabledUseCase(); + } + + indicate(enabled) { + return this.addonEnabledUseCase.indicate(enabled); + } +} diff --git a/src/background/controllers/CommandController.js b/src/background/controllers/CommandController.js deleted file mode 100644 index b113709..0000000 --- a/src/background/controllers/CommandController.js +++ /dev/null @@ -1,99 +0,0 @@ -import CompletionsUseCase from '../usecases/CompletionsUseCase'; -import CommandUseCase from '../usecases/CommandUseCase'; -import Completions from '../domains/Completions'; - -const trimStart = (str) => { - // NOTE String.trimStart is available on Firefox 61 - return str.replace(/^\s+/, ''); -}; - -export default class CommandController { - constructor() { - this.completionsUseCase = new CompletionsUseCase(); - this.commandIndicator = new CommandUseCase(); - } - - getCompletions(line) { - let trimmed = trimStart(line); - let words = trimmed.split(/ +/); - let name = words[0]; - if (words.length === 1) { - return this.completionsUseCase.queryConsoleCommand(name); - } - let keywords = trimStart(trimmed.slice(name.length)); - switch (words[0]) { - case 'o': - case 'open': - case 't': - case 'tabopen': - case 'w': - case 'winopen': - return this.completionsUseCase.queryOpen(name, keywords); - case 'b': - case 'buffer': - return this.completionsUseCase.queryBuffer(name, keywords); - case 'bd': - case 'bdel': - case 'bdelete': - case 'bdeletes': - return this.completionsUseCase.queryBdelete(name, keywords); - case 'bd!': - case 'bdel!': - case 'bdelete!': - case 'bdeletes!': - return this.completionsUseCase.queryBdeleteForce(name, keywords); - case 'set': - return this.completionsUseCase.querySet(name, keywords); - } - return Promise.resolve(Completions.empty()); - } - - // eslint-disable-next-line complexity - exec(line) { - let trimmed = trimStart(line); - let words = trimmed.split(/ +/); - let name = words[0]; - if (words[0].length === 0) { - return Promise.resolve(); - } - - let keywords = trimStart(trimmed.slice(name.length)); - 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); - } - throw new Error(words[0] + ' command is not defined'); - } -} diff --git a/src/background/controllers/CommandController.ts b/src/background/controllers/CommandController.ts new file mode 100644 index 0000000..b113709 --- /dev/null +++ b/src/background/controllers/CommandController.ts @@ -0,0 +1,99 @@ +import CompletionsUseCase from '../usecases/CompletionsUseCase'; +import CommandUseCase from '../usecases/CommandUseCase'; +import Completions from '../domains/Completions'; + +const trimStart = (str) => { + // NOTE String.trimStart is available on Firefox 61 + return str.replace(/^\s+/, ''); +}; + +export default class CommandController { + constructor() { + this.completionsUseCase = new CompletionsUseCase(); + this.commandIndicator = new CommandUseCase(); + } + + getCompletions(line) { + let trimmed = trimStart(line); + let words = trimmed.split(/ +/); + let name = words[0]; + if (words.length === 1) { + return this.completionsUseCase.queryConsoleCommand(name); + } + let keywords = trimStart(trimmed.slice(name.length)); + switch (words[0]) { + case 'o': + case 'open': + case 't': + case 'tabopen': + case 'w': + case 'winopen': + return this.completionsUseCase.queryOpen(name, keywords); + case 'b': + case 'buffer': + return this.completionsUseCase.queryBuffer(name, keywords); + case 'bd': + case 'bdel': + case 'bdelete': + case 'bdeletes': + return this.completionsUseCase.queryBdelete(name, keywords); + case 'bd!': + case 'bdel!': + case 'bdelete!': + case 'bdeletes!': + return this.completionsUseCase.queryBdeleteForce(name, keywords); + case 'set': + return this.completionsUseCase.querySet(name, keywords); + } + return Promise.resolve(Completions.empty()); + } + + // eslint-disable-next-line complexity + exec(line) { + let trimmed = trimStart(line); + let words = trimmed.split(/ +/); + let name = words[0]; + if (words[0].length === 0) { + return Promise.resolve(); + } + + let keywords = trimStart(trimmed.slice(name.length)); + 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); + } + throw new Error(words[0] + ' command is not defined'); + } +} diff --git a/src/background/controllers/FindController.js b/src/background/controllers/FindController.js deleted file mode 100644 index caeff98..0000000 --- a/src/background/controllers/FindController.js +++ /dev/null @@ -1,15 +0,0 @@ -import FindUseCase from '../usecases/FindUseCase'; - -export default class FindController { - constructor() { - this.findUseCase = new FindUseCase(); - } - - getKeyword() { - return this.findUseCase.getKeyword(); - } - - setKeyword(keyword) { - return this.findUseCase.setKeyword(keyword); - } -} diff --git a/src/background/controllers/FindController.ts b/src/background/controllers/FindController.ts new file mode 100644 index 0000000..caeff98 --- /dev/null +++ b/src/background/controllers/FindController.ts @@ -0,0 +1,15 @@ +import FindUseCase from '../usecases/FindUseCase'; + +export default class FindController { + constructor() { + this.findUseCase = new FindUseCase(); + } + + getKeyword() { + return this.findUseCase.getKeyword(); + } + + setKeyword(keyword) { + return this.findUseCase.setKeyword(keyword); + } +} diff --git a/src/background/controllers/LinkController.js b/src/background/controllers/LinkController.js deleted file mode 100644 index 7e395b1..0000000 --- a/src/background/controllers/LinkController.js +++ /dev/null @@ -1,15 +0,0 @@ -import LinkUseCase from '../usecases/LinkUseCase'; - -export default class LinkController { - constructor() { - this.linkUseCase = new LinkUseCase(); - } - - openToTab(url, tabId) { - this.linkUseCase.openToTab(url, tabId); - } - - openNewTab(url, openerId, background) { - this.linkUseCase.openNewTab(url, openerId, background); - } -} diff --git a/src/background/controllers/LinkController.ts b/src/background/controllers/LinkController.ts new file mode 100644 index 0000000..7e395b1 --- /dev/null +++ b/src/background/controllers/LinkController.ts @@ -0,0 +1,15 @@ +import LinkUseCase from '../usecases/LinkUseCase'; + +export default class LinkController { + constructor() { + this.linkUseCase = new LinkUseCase(); + } + + openToTab(url, tabId) { + this.linkUseCase.openToTab(url, tabId); + } + + openNewTab(url, openerId, background) { + this.linkUseCase.openNewTab(url, openerId, background); + } +} diff --git a/src/background/controllers/MarkController.js b/src/background/controllers/MarkController.js deleted file mode 100644 index 0478369..0000000 --- a/src/background/controllers/MarkController.js +++ /dev/null @@ -1,15 +0,0 @@ -import MarkUseCase from '../usecases/MarkUseCase'; - -export default class MarkController { - constructor() { - this.markUseCase = new MarkUseCase(); - } - - setGlobal(key, x, y) { - this.markUseCase.setGlobal(key, x, y); - } - - jumpGlobal(key) { - this.markUseCase.jumpGlobal(key); - } -} diff --git a/src/background/controllers/MarkController.ts b/src/background/controllers/MarkController.ts new file mode 100644 index 0000000..0478369 --- /dev/null +++ b/src/background/controllers/MarkController.ts @@ -0,0 +1,15 @@ +import MarkUseCase from '../usecases/MarkUseCase'; + +export default class MarkController { + constructor() { + this.markUseCase = new MarkUseCase(); + } + + setGlobal(key, x, y) { + this.markUseCase.setGlobal(key, x, y); + } + + jumpGlobal(key) { + this.markUseCase.jumpGlobal(key); + } +} diff --git a/src/background/controllers/OperationController.js b/src/background/controllers/OperationController.js deleted file mode 100644 index 416aa9c..0000000 --- a/src/background/controllers/OperationController.js +++ /dev/null @@ -1,77 +0,0 @@ -import operations from '../../shared/operations'; -import FindUseCase from '../usecases/FindUseCase'; -import ConsoleUseCase from '../usecases/ConsoleUseCase'; -import TabUseCase from '../usecases/TabUseCase'; -import TabSelectUseCase from '../usecases/TabSelectUseCase'; -import ZoomUseCase from '../usecases/ZoomUseCase'; - -export default class OperationController { - constructor() { - this.findUseCase = new FindUseCase(); - this.consoleUseCase = new ConsoleUseCase(); - this.tabUseCase = new TabUseCase(); - this.tabSelectUseCase = new TabSelectUseCase(); - this.zoomUseCase = new ZoomUseCase(); - } - - // eslint-disable-next-line complexity, max-lines-per-function - exec(operation) { - switch (operation.type) { - case operations.TAB_CLOSE: - return this.tabUseCase.close(false); - case operations.TAB_CLOSE_RIGHT: - return this.tabUseCase.closeRight(); - case operations.TAB_CLOSE_FORCE: - return this.tabUseCase.close(true); - case operations.TAB_REOPEN: - return this.tabUseCase.reopen(); - case operations.TAB_PREV: - return this.tabSelectUseCase.selectPrev(1); - case operations.TAB_NEXT: - return this.tabSelectUseCase.selectNext(1); - case operations.TAB_FIRST: - return this.tabSelectUseCase.selectFirst(); - case operations.TAB_LAST: - return this.tabSelectUseCase.selectLast(); - case operations.TAB_PREV_SEL: - return this.tabSelectUseCase.selectPrevSelected(); - case operations.TAB_RELOAD: - return this.tabUseCase.reload(operation.cache); - case operations.TAB_PIN: - return this.tabUseCase.setPinned(true); - case operations.TAB_UNPIN: - return this.tabUseCase.setPinned(false); - case operations.TAB_TOGGLE_PINNED: - return this.tabUseCase.togglePinned(); - case operations.TAB_DUPLICATE: - return this.tabUseCase.duplicate(); - case operations.PAGE_SOURCE: - return this.tabUseCase.openPageSource(); - case operations.PAGE_HOME: - return this.tabUseCase.openHome(operation.newTab); - case operations.ZOOM_IN: - return this.zoomUseCase.zoomIn(); - case operations.ZOOM_OUT: - return this.zoomUseCase.zoomOut(); - case operations.ZOOM_NEUTRAL: - return this.zoomUseCase.zoomNutoral(); - case operations.COMMAND_SHOW: - return this.consoleUseCase.showCommand(); - case operations.COMMAND_SHOW_OPEN: - return this.consoleUseCase.showOpenCommand(operation.alter); - case operations.COMMAND_SHOW_TABOPEN: - return this.consoleUseCase.showTabopenCommand(operation.alter); - case operations.COMMAND_SHOW_WINOPEN: - return this.consoleUseCase.showWinopenCommand(operation.alter); - case operations.COMMAND_SHOW_BUFFER: - return this.consoleUseCase.showBufferCommand(); - case operations.COMMAND_SHOW_ADDBOOKMARK: - return this.consoleUseCase.showAddbookmarkCommand(operation.alter); - case operations.FIND_START: - return this.findUseCase.findStart(); - case operations.CANCEL: - return this.consoleUseCase.hideConsole(); - } - } -} - diff --git a/src/background/controllers/OperationController.ts b/src/background/controllers/OperationController.ts new file mode 100644 index 0000000..416aa9c --- /dev/null +++ b/src/background/controllers/OperationController.ts @@ -0,0 +1,77 @@ +import operations from '../../shared/operations'; +import FindUseCase from '../usecases/FindUseCase'; +import ConsoleUseCase from '../usecases/ConsoleUseCase'; +import TabUseCase from '../usecases/TabUseCase'; +import TabSelectUseCase from '../usecases/TabSelectUseCase'; +import ZoomUseCase from '../usecases/ZoomUseCase'; + +export default class OperationController { + constructor() { + this.findUseCase = new FindUseCase(); + this.consoleUseCase = new ConsoleUseCase(); + this.tabUseCase = new TabUseCase(); + this.tabSelectUseCase = new TabSelectUseCase(); + this.zoomUseCase = new ZoomUseCase(); + } + + // eslint-disable-next-line complexity, max-lines-per-function + exec(operation) { + switch (operation.type) { + case operations.TAB_CLOSE: + return this.tabUseCase.close(false); + case operations.TAB_CLOSE_RIGHT: + return this.tabUseCase.closeRight(); + case operations.TAB_CLOSE_FORCE: + return this.tabUseCase.close(true); + case operations.TAB_REOPEN: + return this.tabUseCase.reopen(); + case operations.TAB_PREV: + return this.tabSelectUseCase.selectPrev(1); + case operations.TAB_NEXT: + return this.tabSelectUseCase.selectNext(1); + case operations.TAB_FIRST: + return this.tabSelectUseCase.selectFirst(); + case operations.TAB_LAST: + return this.tabSelectUseCase.selectLast(); + case operations.TAB_PREV_SEL: + return this.tabSelectUseCase.selectPrevSelected(); + case operations.TAB_RELOAD: + return this.tabUseCase.reload(operation.cache); + case operations.TAB_PIN: + return this.tabUseCase.setPinned(true); + case operations.TAB_UNPIN: + return this.tabUseCase.setPinned(false); + case operations.TAB_TOGGLE_PINNED: + return this.tabUseCase.togglePinned(); + case operations.TAB_DUPLICATE: + return this.tabUseCase.duplicate(); + case operations.PAGE_SOURCE: + return this.tabUseCase.openPageSource(); + case operations.PAGE_HOME: + return this.tabUseCase.openHome(operation.newTab); + case operations.ZOOM_IN: + return this.zoomUseCase.zoomIn(); + case operations.ZOOM_OUT: + return this.zoomUseCase.zoomOut(); + case operations.ZOOM_NEUTRAL: + return this.zoomUseCase.zoomNutoral(); + case operations.COMMAND_SHOW: + return this.consoleUseCase.showCommand(); + case operations.COMMAND_SHOW_OPEN: + return this.consoleUseCase.showOpenCommand(operation.alter); + case operations.COMMAND_SHOW_TABOPEN: + return this.consoleUseCase.showTabopenCommand(operation.alter); + case operations.COMMAND_SHOW_WINOPEN: + return this.consoleUseCase.showWinopenCommand(operation.alter); + case operations.COMMAND_SHOW_BUFFER: + return this.consoleUseCase.showBufferCommand(); + case operations.COMMAND_SHOW_ADDBOOKMARK: + return this.consoleUseCase.showAddbookmarkCommand(operation.alter); + case operations.FIND_START: + return this.findUseCase.findStart(); + case operations.CANCEL: + return this.consoleUseCase.hideConsole(); + } + } +} + diff --git a/src/background/controllers/SettingController.js b/src/background/controllers/SettingController.js deleted file mode 100644 index e895d72..0000000 --- a/src/background/controllers/SettingController.js +++ /dev/null @@ -1,18 +0,0 @@ -import SettingUseCase from '../usecases/SettingUseCase'; -import ContentMessageClient from '../infrastructures/ContentMessageClient'; - -export default class SettingController { - constructor() { - this.settingUseCase = new SettingUseCase(); - this.contentMessageClient = new ContentMessageClient(); - } - - getSetting() { - return this.settingUseCase.get(); - } - - async reload() { - await this.settingUseCase.reload(); - this.contentMessageClient.broadcastSettingsChanged(); - } -} diff --git a/src/background/controllers/SettingController.ts b/src/background/controllers/SettingController.ts new file mode 100644 index 0000000..e895d72 --- /dev/null +++ b/src/background/controllers/SettingController.ts @@ -0,0 +1,18 @@ +import SettingUseCase from '../usecases/SettingUseCase'; +import ContentMessageClient from '../infrastructures/ContentMessageClient'; + +export default class SettingController { + constructor() { + this.settingUseCase = new SettingUseCase(); + this.contentMessageClient = new ContentMessageClient(); + } + + getSetting() { + return this.settingUseCase.get(); + } + + async reload() { + await this.settingUseCase.reload(); + this.contentMessageClient.broadcastSettingsChanged(); + } +} diff --git a/src/background/controllers/VersionController.js b/src/background/controllers/VersionController.js deleted file mode 100644 index c596f9b..0000000 --- a/src/background/controllers/VersionController.js +++ /dev/null @@ -1,11 +0,0 @@ -import VersionUseCase from '../usecases/VersionUseCase'; - -export default class VersionController { - constructor() { - this.versionUseCase = new VersionUseCase(); - } - - notify() { - this.versionUseCase.notify(); - } -} diff --git a/src/background/controllers/VersionController.ts b/src/background/controllers/VersionController.ts new file mode 100644 index 0000000..c596f9b --- /dev/null +++ b/src/background/controllers/VersionController.ts @@ -0,0 +1,11 @@ +import VersionUseCase from '../usecases/VersionUseCase'; + +export default class VersionController { + constructor() { + this.versionUseCase = new VersionUseCase(); + } + + notify() { + this.versionUseCase.notify(); + } +} diff --git a/src/background/controllers/version.js b/src/background/controllers/version.js deleted file mode 100644 index ec0f634..0000000 --- a/src/background/controllers/version.js +++ /dev/null @@ -1,13 +0,0 @@ -import VersionInteractor from '../usecases/version'; - -export default class VersionController { - constructor() { - this.versionInteractor = new VersionInteractor(); - } - - notifyIfUpdated() { - browser.runtime.onInstalled.addListener(() => { - return this.versionInteractor.notify(); - }); - } -} diff --git a/src/background/controllers/version.ts b/src/background/controllers/version.ts new file mode 100644 index 0000000..ec0f634 --- /dev/null +++ b/src/background/controllers/version.ts @@ -0,0 +1,13 @@ +import VersionInteractor from '../usecases/version'; + +export default class VersionController { + constructor() { + this.versionInteractor = new VersionInteractor(); + } + + notifyIfUpdated() { + browser.runtime.onInstalled.addListener(() => { + return this.versionInteractor.notify(); + }); + } +} diff --git a/src/background/domains/CommandDocs.js b/src/background/domains/CommandDocs.js deleted file mode 100644 index 734c68e..0000000 --- a/src/background/domains/CommandDocs.js +++ /dev/null @@ -1,12 +0,0 @@ -export default { - set: 'Set a value of the property', - open: 'Open a URL or search by keywords in current tab', - tabopen: 'Open a URL or search by keywords in new tab', - winopen: 'Open a URL or search by keywords in new window', - buffer: 'Select tabs by matched keywords', - bdelete: 'Close a certain tab matched by keywords', - bdeletes: 'Close all tabs matched by keywords', - quit: 'Close the current tab', - quitall: 'Close all tabs', -}; - diff --git a/src/background/domains/CommandDocs.ts b/src/background/domains/CommandDocs.ts new file mode 100644 index 0000000..734c68e --- /dev/null +++ b/src/background/domains/CommandDocs.ts @@ -0,0 +1,12 @@ +export default { + set: 'Set a value of the property', + open: 'Open a URL or search by keywords in current tab', + tabopen: 'Open a URL or search by keywords in new tab', + winopen: 'Open a URL or search by keywords in new window', + buffer: 'Select tabs by matched keywords', + bdelete: 'Close a certain tab matched by keywords', + bdeletes: 'Close all tabs matched by keywords', + quit: 'Close the current tab', + quitall: 'Close all tabs', +}; + diff --git a/src/background/domains/CompletionGroup.js b/src/background/domains/CompletionGroup.js deleted file mode 100644 index 1749d72..0000000 --- a/src/background/domains/CompletionGroup.js +++ /dev/null @@ -1,14 +0,0 @@ -export default class CompletionGroup { - constructor(name, items) { - this.name0 = name; - this.items0 = items; - } - - get name() { - return this.name0; - } - - get items() { - return this.items0; - } -} diff --git a/src/background/domains/CompletionGroup.ts b/src/background/domains/CompletionGroup.ts new file mode 100644 index 0000000..1749d72 --- /dev/null +++ b/src/background/domains/CompletionGroup.ts @@ -0,0 +1,14 @@ +export default class CompletionGroup { + constructor(name, items) { + this.name0 = name; + this.items0 = items; + } + + get name() { + return this.name0; + } + + get items() { + return this.items0; + } +} diff --git a/src/background/domains/CompletionItem.js b/src/background/domains/CompletionItem.js deleted file mode 100644 index c7ad8a1..0000000 --- a/src/background/domains/CompletionItem.js +++ /dev/null @@ -1,24 +0,0 @@ -export default class CompletionItem { - constructor({ caption, content, url, icon }) { - this.caption0 = caption; - this.content0 = content; - this.url0 = url; - this.icon0 = icon; - } - - get caption() { - return this.caption0; - } - - get content() { - return this.content0; - } - - get url() { - return this.url0; - } - - get icon() { - return this.icon0; - } -} diff --git a/src/background/domains/CompletionItem.ts b/src/background/domains/CompletionItem.ts new file mode 100644 index 0000000..c7ad8a1 --- /dev/null +++ b/src/background/domains/CompletionItem.ts @@ -0,0 +1,24 @@ +export default class CompletionItem { + constructor({ caption, content, url, icon }) { + this.caption0 = caption; + this.content0 = content; + this.url0 = url; + this.icon0 = icon; + } + + get caption() { + return this.caption0; + } + + get content() { + return this.content0; + } + + get url() { + return this.url0; + } + + get icon() { + return this.icon0; + } +} diff --git a/src/background/domains/Completions.js b/src/background/domains/Completions.js deleted file mode 100644 index f399743..0000000 --- a/src/background/domains/Completions.js +++ /dev/null @@ -1,27 +0,0 @@ -export default class Completions { - constructor(groups) { - this.g = groups; - } - - get groups() { - return this.g; - } - - serialize() { - return this.groups.map(group => ({ - name: group.name, - items: group.items.map(item => ({ - caption: item.caption, - content: item.content, - url: item.url, - icon: item.icon, - })), - })); - } - - static empty() { - return EMPTY_COMPLETIONS; - } -} - -let EMPTY_COMPLETIONS = new Completions([]); diff --git a/src/background/domains/Completions.ts b/src/background/domains/Completions.ts new file mode 100644 index 0000000..f399743 --- /dev/null +++ b/src/background/domains/Completions.ts @@ -0,0 +1,27 @@ +export default class Completions { + constructor(groups) { + this.g = groups; + } + + get groups() { + return this.g; + } + + serialize() { + return this.groups.map(group => ({ + name: group.name, + items: group.items.map(item => ({ + caption: item.caption, + content: item.content, + url: item.url, + icon: item.icon, + })), + })); + } + + static empty() { + return EMPTY_COMPLETIONS; + } +} + +let EMPTY_COMPLETIONS = new Completions([]); diff --git a/src/background/domains/GlobalMark.js b/src/background/domains/GlobalMark.js deleted file mode 100644 index f0586f1..0000000 --- a/src/background/domains/GlobalMark.js +++ /dev/null @@ -1,24 +0,0 @@ -export default class GlobalMark { - constructor(tabId, url, x, y) { - this.tabId0 = tabId; - this.url0 = url; - this.x0 = x; - this.y0 = y; - } - - get tabId() { - return this.tabId0; - } - - get url() { - return this.url0; - } - - get x() { - return this.x0; - } - - get y() { - return this.y0; - } -} diff --git a/src/background/domains/GlobalMark.ts b/src/background/domains/GlobalMark.ts new file mode 100644 index 0000000..f0586f1 --- /dev/null +++ b/src/background/domains/GlobalMark.ts @@ -0,0 +1,24 @@ +export default class GlobalMark { + constructor(tabId, url, x, y) { + this.tabId0 = tabId; + this.url0 = url; + this.x0 = x; + this.y0 = y; + } + + get tabId() { + return this.tabId0; + } + + get url() { + return this.url0; + } + + get x() { + return this.x0; + } + + get y() { + return this.y0; + } +} diff --git a/src/background/domains/Setting.js b/src/background/domains/Setting.js deleted file mode 100644 index 106ec0f..0000000 --- a/src/background/domains/Setting.js +++ /dev/null @@ -1,51 +0,0 @@ -import DefaultSettings from '../../shared/settings/default'; -import * as settingsValues from '../../shared/settings/values'; - -export default class Setting { - constructor({ source, json, form }) { - this.obj = { - source, json, form - }; - } - - get source() { - return this.obj.source; - } - - get json() { - return this.obj.json; - } - - get form() { - return this.obj.form; - } - - value() { - let value = JSON.parse(DefaultSettings.json); - if (this.obj.source === 'json') { - value = settingsValues.valueFromJson(this.obj.json); - } else if (this.obj.source === 'form') { - value = settingsValues.valueFromForm(this.obj.form); - } - if (!value.properties) { - value.properties = {}; - } - return { ...settingsValues.valueFromJson(DefaultSettings.json), ...value }; - } - - serialize() { - return this.obj; - } - - static deserialize(obj) { - return new Setting({ source: obj.source, json: obj.json, form: obj.form }); - } - - static defaultSettings() { - return new Setting({ - source: DefaultSettings.source, - json: DefaultSettings.json, - form: {}, - }); - } -} diff --git a/src/background/domains/Setting.ts b/src/background/domains/Setting.ts new file mode 100644 index 0000000..106ec0f --- /dev/null +++ b/src/background/domains/Setting.ts @@ -0,0 +1,51 @@ +import DefaultSettings from '../../shared/settings/default'; +import * as settingsValues from '../../shared/settings/values'; + +export default class Setting { + constructor({ source, json, form }) { + this.obj = { + source, json, form + }; + } + + get source() { + return this.obj.source; + } + + get json() { + return this.obj.json; + } + + get form() { + return this.obj.form; + } + + value() { + let value = JSON.parse(DefaultSettings.json); + if (this.obj.source === 'json') { + value = settingsValues.valueFromJson(this.obj.json); + } else if (this.obj.source === 'form') { + value = settingsValues.valueFromForm(this.obj.form); + } + if (!value.properties) { + value.properties = {}; + } + return { ...settingsValues.valueFromJson(DefaultSettings.json), ...value }; + } + + serialize() { + return this.obj; + } + + static deserialize(obj) { + return new Setting({ source: obj.source, json: obj.json, form: obj.form }); + } + + static defaultSettings() { + return new Setting({ + source: DefaultSettings.source, + json: DefaultSettings.json, + form: {}, + }); + } +} diff --git a/src/background/index.js b/src/background/index.js deleted file mode 100644 index f9efd4d..0000000 --- a/src/background/index.js +++ /dev/null @@ -1,23 +0,0 @@ -import ContentMessageListener from './infrastructures/ContentMessageListener'; -import SettingController from './controllers/SettingController'; -import VersionController from './controllers/VersionController'; - -let settingController = new SettingController(); -settingController.reload(); - -browser.runtime.onInstalled.addListener((details) => { - if (details.reason !== 'install' && details.reason !== 'update') { - return; - } - new VersionController().notify(); -}); - -new ContentMessageListener().run(); -browser.storage.onChanged.addListener((changes, area) => { - if (area !== 'local') { - return; - } - if (changes.settings) { - settingController.reload(); - } -}); diff --git a/src/background/index.ts b/src/background/index.ts new file mode 100644 index 0000000..f9efd4d --- /dev/null +++ b/src/background/index.ts @@ -0,0 +1,23 @@ +import ContentMessageListener from './infrastructures/ContentMessageListener'; +import SettingController from './controllers/SettingController'; +import VersionController from './controllers/VersionController'; + +let settingController = new SettingController(); +settingController.reload(); + +browser.runtime.onInstalled.addListener((details) => { + if (details.reason !== 'install' && details.reason !== 'update') { + return; + } + new VersionController().notify(); +}); + +new ContentMessageListener().run(); +browser.storage.onChanged.addListener((changes, area) => { + if (area !== 'local') { + return; + } + if (changes.settings) { + settingController.reload(); + } +}); diff --git a/src/background/infrastructures/ConsoleClient.js b/src/background/infrastructures/ConsoleClient.js deleted file mode 100644 index f691515..0000000 --- a/src/background/infrastructures/ConsoleClient.js +++ /dev/null @@ -1,37 +0,0 @@ -import messages from '../../shared/messages'; - -export default class ConsoleClient { - 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/infrastructures/ConsoleClient.ts b/src/background/infrastructures/ConsoleClient.ts new file mode 100644 index 0000000..f691515 --- /dev/null +++ b/src/background/infrastructures/ConsoleClient.ts @@ -0,0 +1,37 @@ +import messages from '../../shared/messages'; + +export default class ConsoleClient { + 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/infrastructures/ContentMessageClient.js b/src/background/infrastructures/ContentMessageClient.js deleted file mode 100644 index 0fab5a3..0000000 --- a/src/background/infrastructures/ContentMessageClient.js +++ /dev/null @@ -1,36 +0,0 @@ -import messages from '../../shared/messages'; - -export default class ContentMessageClient { - async broadcastSettingsChanged() { - let tabs = await browser.tabs.query({}); - for (let tab of tabs) { - if (tab.url.startsWith('about:')) { - continue; - } - browser.tabs.sendMessage(tab.id, { - type: messages.SETTINGS_CHANGED, - }); - } - } - - async getAddonEnabled(tabId) { - let { enabled } = await browser.tabs.sendMessage(tabId, { - type: messages.ADDON_ENABLED_QUERY, - }); - return enabled; - } - - toggleAddonEnabled(tabId) { - return browser.tabs.sendMessage(tabId, { - type: messages.ADDON_TOGGLE_ENABLED, - }); - } - - scrollTo(tabId, x, y) { - return browser.tabs.sendMessage(tabId, { - type: messages.TAB_SCROLL_TO, - x, - y, - }); - } -} diff --git a/src/background/infrastructures/ContentMessageClient.ts b/src/background/infrastructures/ContentMessageClient.ts new file mode 100644 index 0000000..0fab5a3 --- /dev/null +++ b/src/background/infrastructures/ContentMessageClient.ts @@ -0,0 +1,36 @@ +import messages from '../../shared/messages'; + +export default class ContentMessageClient { + async broadcastSettingsChanged() { + let tabs = await browser.tabs.query({}); + for (let tab of tabs) { + if (tab.url.startsWith('about:')) { + continue; + } + browser.tabs.sendMessage(tab.id, { + type: messages.SETTINGS_CHANGED, + }); + } + } + + async getAddonEnabled(tabId) { + let { enabled } = await browser.tabs.sendMessage(tabId, { + type: messages.ADDON_ENABLED_QUERY, + }); + return enabled; + } + + toggleAddonEnabled(tabId) { + return browser.tabs.sendMessage(tabId, { + type: messages.ADDON_TOGGLE_ENABLED, + }); + } + + scrollTo(tabId, x, y) { + return browser.tabs.sendMessage(tabId, { + type: messages.TAB_SCROLL_TO, + x, + y, + }); + } +} diff --git a/src/background/infrastructures/ContentMessageListener.js b/src/background/infrastructures/ContentMessageListener.js deleted file mode 100644 index 5b0f62e..0000000 --- a/src/background/infrastructures/ContentMessageListener.js +++ /dev/null @@ -1,135 +0,0 @@ -import messages from '../../shared/messages'; -import CommandController from '../controllers/CommandController'; -import SettingController from '../controllers/SettingController'; -import FindController from '../controllers/FindController'; -import AddonEnabledController from '../controllers/AddonEnabledController'; -import LinkController from '../controllers/LinkController'; -import OperationController from '../controllers/OperationController'; -import MarkController from '../controllers/MarkController'; - -export default class ContentMessageListener { - constructor() { - this.settingController = new SettingController(); - this.commandController = new CommandController(); - this.findController = new FindController(); - this.addonEnabledController = new AddonEnabledController(); - this.linkController = new LinkController(); - this.backgroundOperationController = new OperationController(); - this.markController = new MarkController(); - - this.consolePorts = {}; - } - - run() { - browser.runtime.onMessage.addListener((message, sender) => { - try { - let ret = this.onMessage(message, sender); - if (!(ret instanceof Promise)) { - return {}; - } - return ret.catch((e) => { - return browser.tabs.sendMessage(sender.tab.id, { - type: messages.CONSOLE_SHOW_ERROR, - text: e.message, - }); - }); - } catch (e) { - return browser.tabs.sendMessage(sender.tab.id, { - type: messages.CONSOLE_SHOW_ERROR, - text: e.message, - }); - } - }); - browser.runtime.onConnect.addListener(this.onConnected.bind(this)); - } - - onMessage(message, sender) { - switch (message.type) { - case messages.CONSOLE_QUERY_COMPLETIONS: - return this.onConsoleQueryCompletions(message.text); - case messages.CONSOLE_ENTER_COMMAND: - return this.onConsoleEnterCommand(message.text); - case messages.SETTINGS_QUERY: - return this.onSettingsQuery(); - case messages.FIND_GET_KEYWORD: - return this.onFindGetKeyword(); - case messages.FIND_SET_KEYWORD: - return this.onFindSetKeyword(message.keyword); - case messages.ADDON_ENABLED_RESPONSE: - return this.onAddonEnabledResponse(message.enabled); - 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); - case messages.MARK_SET_GLOBAL: - return this.onMarkSetGlobal(message.key, message.x, message.y); - case messages.MARK_JUMP_GLOBAL: - return this.onMarkJumpGlobal(message.key); - case messages.CONSOLE_FRAME_MESSAGE: - return this.onConsoleFrameMessage(sender.tab.id, message.message); - } - } - - async onConsoleQueryCompletions(line) { - let completions = await this.commandController.getCompletions(line); - return Promise.resolve(completions.serialize()); - } - - onConsoleEnterCommand(text) { - return this.commandController.exec(text); - } - - - onSettingsQuery() { - return this.settingController.getSetting(); - } - - onFindGetKeyword() { - return this.findController.getKeyword(); - } - - onFindSetKeyword(keyword) { - return this.findController.setKeyword(keyword); - } - - onAddonEnabledResponse(enabled) { - return this.addonEnabledController.indicate(enabled); - } - - onOpenUrl(newTab, url, openerId, background) { - if (newTab) { - return this.linkController.openNewTab(url, openerId, background); - } - return this.linkController.openToTab(url, openerId); - } - - onBackgroundOperation(operation) { - return this.backgroundOperationController.exec(operation); - } - - onMarkSetGlobal(key, x, y) { - return this.markController.setGlobal(key, x, y); - } - - onMarkJumpGlobal(key) { - return this.markController.jumpGlobal(key); - } - - onConsoleFrameMessage(tabId, message) { - let port = this.consolePorts[tabId]; - if (!port) { - return; - } - port.postMessage(message); - } - - onConnected(port) { - if (port.name !== 'vimvixen-console') { - return; - } - - let id = port.sender.tab.id; - this.consolePorts[id] = port; - } -} diff --git a/src/background/infrastructures/ContentMessageListener.ts b/src/background/infrastructures/ContentMessageListener.ts new file mode 100644 index 0000000..5b0f62e --- /dev/null +++ b/src/background/infrastructures/ContentMessageListener.ts @@ -0,0 +1,135 @@ +import messages from '../../shared/messages'; +import CommandController from '../controllers/CommandController'; +import SettingController from '../controllers/SettingController'; +import FindController from '../controllers/FindController'; +import AddonEnabledController from '../controllers/AddonEnabledController'; +import LinkController from '../controllers/LinkController'; +import OperationController from '../controllers/OperationController'; +import MarkController from '../controllers/MarkController'; + +export default class ContentMessageListener { + constructor() { + this.settingController = new SettingController(); + this.commandController = new CommandController(); + this.findController = new FindController(); + this.addonEnabledController = new AddonEnabledController(); + this.linkController = new LinkController(); + this.backgroundOperationController = new OperationController(); + this.markController = new MarkController(); + + this.consolePorts = {}; + } + + run() { + browser.runtime.onMessage.addListener((message, sender) => { + try { + let ret = this.onMessage(message, sender); + if (!(ret instanceof Promise)) { + return {}; + } + return ret.catch((e) => { + return browser.tabs.sendMessage(sender.tab.id, { + type: messages.CONSOLE_SHOW_ERROR, + text: e.message, + }); + }); + } catch (e) { + return browser.tabs.sendMessage(sender.tab.id, { + type: messages.CONSOLE_SHOW_ERROR, + text: e.message, + }); + } + }); + browser.runtime.onConnect.addListener(this.onConnected.bind(this)); + } + + onMessage(message, sender) { + switch (message.type) { + case messages.CONSOLE_QUERY_COMPLETIONS: + return this.onConsoleQueryCompletions(message.text); + case messages.CONSOLE_ENTER_COMMAND: + return this.onConsoleEnterCommand(message.text); + case messages.SETTINGS_QUERY: + return this.onSettingsQuery(); + case messages.FIND_GET_KEYWORD: + return this.onFindGetKeyword(); + case messages.FIND_SET_KEYWORD: + return this.onFindSetKeyword(message.keyword); + case messages.ADDON_ENABLED_RESPONSE: + return this.onAddonEnabledResponse(message.enabled); + 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); + case messages.MARK_SET_GLOBAL: + return this.onMarkSetGlobal(message.key, message.x, message.y); + case messages.MARK_JUMP_GLOBAL: + return this.onMarkJumpGlobal(message.key); + case messages.CONSOLE_FRAME_MESSAGE: + return this.onConsoleFrameMessage(sender.tab.id, message.message); + } + } + + async onConsoleQueryCompletions(line) { + let completions = await this.commandController.getCompletions(line); + return Promise.resolve(completions.serialize()); + } + + onConsoleEnterCommand(text) { + return this.commandController.exec(text); + } + + + onSettingsQuery() { + return this.settingController.getSetting(); + } + + onFindGetKeyword() { + return this.findController.getKeyword(); + } + + onFindSetKeyword(keyword) { + return this.findController.setKeyword(keyword); + } + + onAddonEnabledResponse(enabled) { + return this.addonEnabledController.indicate(enabled); + } + + onOpenUrl(newTab, url, openerId, background) { + if (newTab) { + return this.linkController.openNewTab(url, openerId, background); + } + return this.linkController.openToTab(url, openerId); + } + + onBackgroundOperation(operation) { + return this.backgroundOperationController.exec(operation); + } + + onMarkSetGlobal(key, x, y) { + return this.markController.setGlobal(key, x, y); + } + + onMarkJumpGlobal(key) { + return this.markController.jumpGlobal(key); + } + + onConsoleFrameMessage(tabId, message) { + let port = this.consolePorts[tabId]; + if (!port) { + return; + } + port.postMessage(message); + } + + onConnected(port) { + if (port.name !== 'vimvixen-console') { + return; + } + + let id = port.sender.tab.id; + this.consolePorts[id] = port; + } +} diff --git a/src/background/infrastructures/MemoryStorage.js b/src/background/infrastructures/MemoryStorage.js deleted file mode 100644 index 3a7e4f2..0000000 --- a/src/background/infrastructures/MemoryStorage.js +++ /dev/null @@ -1,19 +0,0 @@ -const db = {}; - -export default class MemoryStorage { - set(name, value) { - let data = JSON.stringify(value); - if (typeof data === 'undefined') { - throw new Error('value is not serializable'); - } - db[name] = data; - } - - get(name) { - let data = db[name]; - if (!data) { - return undefined; - } - return JSON.parse(data); - } -} diff --git a/src/background/infrastructures/MemoryStorage.ts b/src/background/infrastructures/MemoryStorage.ts new file mode 100644 index 0000000..3a7e4f2 --- /dev/null +++ b/src/background/infrastructures/MemoryStorage.ts @@ -0,0 +1,19 @@ +const db = {}; + +export default class MemoryStorage { + set(name, value) { + let data = JSON.stringify(value); + if (typeof data === 'undefined') { + throw new Error('value is not serializable'); + } + db[name] = data; + } + + get(name) { + let data = db[name]; + if (!data) { + return undefined; + } + return JSON.parse(data); + } +} diff --git a/src/background/presenters/IndicatorPresenter.js b/src/background/presenters/IndicatorPresenter.js deleted file mode 100644 index 5737519..0000000 --- a/src/background/presenters/IndicatorPresenter.js +++ /dev/null @@ -1,12 +0,0 @@ -export default class IndicatorPresenter { - indicate(enabled) { - let path = enabled - ? 'resources/enabled_32x32.png' - : 'resources/disabled_32x32.png'; - return browser.browserAction.setIcon({ path }); - } - - onClick(listener) { - browser.browserAction.onClicked.addListener(listener); - } -} diff --git a/src/background/presenters/IndicatorPresenter.ts b/src/background/presenters/IndicatorPresenter.ts new file mode 100644 index 0000000..5737519 --- /dev/null +++ b/src/background/presenters/IndicatorPresenter.ts @@ -0,0 +1,12 @@ +export default class IndicatorPresenter { + indicate(enabled) { + let path = enabled + ? 'resources/enabled_32x32.png' + : 'resources/disabled_32x32.png'; + return browser.browserAction.setIcon({ path }); + } + + onClick(listener) { + browser.browserAction.onClicked.addListener(listener); + } +} diff --git a/src/background/presenters/NotifyPresenter.js b/src/background/presenters/NotifyPresenter.js deleted file mode 100644 index a81f227..0000000 --- a/src/background/presenters/NotifyPresenter.js +++ /dev/null @@ -1,23 +0,0 @@ -const NOTIFICATION_ID = 'vimvixen-update'; - -export default class NotifyPresenter { - notify(title, message, onclick) { - const listener = (id) => { - if (id !== NOTIFICATION_ID) { - return; - } - - onclick(); - - browser.notifications.onClicked.removeListener(listener); - }; - browser.notifications.onClicked.addListener(listener); - - return browser.notifications.create(NOTIFICATION_ID, { - 'type': 'basic', - 'iconUrl': browser.extension.getURL('resources/icon_48x48.png'), - title, - message, - }); - } -} diff --git a/src/background/presenters/NotifyPresenter.ts b/src/background/presenters/NotifyPresenter.ts new file mode 100644 index 0000000..a81f227 --- /dev/null +++ b/src/background/presenters/NotifyPresenter.ts @@ -0,0 +1,23 @@ +const NOTIFICATION_ID = 'vimvixen-update'; + +export default class NotifyPresenter { + notify(title, message, onclick) { + const listener = (id) => { + if (id !== NOTIFICATION_ID) { + return; + } + + onclick(); + + browser.notifications.onClicked.removeListener(listener); + }; + browser.notifications.onClicked.addListener(listener); + + return browser.notifications.create(NOTIFICATION_ID, { + 'type': 'basic', + 'iconUrl': browser.extension.getURL('resources/icon_48x48.png'), + title, + message, + }); + } +} diff --git a/src/background/presenters/TabPresenter.js b/src/background/presenters/TabPresenter.js deleted file mode 100644 index 744be39..0000000 --- a/src/background/presenters/TabPresenter.js +++ /dev/null @@ -1,102 +0,0 @@ -import MemoryStorage from '../infrastructures/MemoryStorage'; - -const CURRENT_SELECTED_KEY = 'tabs.current.selected'; -const LAST_SELECTED_KEY = 'tabs.last.selected'; - -export default class TabPresenter { - open(url, tabId) { - return browser.tabs.update(tabId, { url }); - } - - create(url, opts) { - return browser.tabs.create({ url, ...opts }); - } - - async getCurrent() { - let tabs = await browser.tabs.query({ - active: true, currentWindow: true - }); - return tabs[0]; - } - - getAll() { - return browser.tabs.query({ currentWindow: true }); - } - - async getLastSelectedId() { - let cache = new MemoryStorage(); - let tabId = await cache.get(LAST_SELECTED_KEY); - if (tabId === null || typeof tabId === 'undefined') { - return; - } - return tabId; - } - - async getByKeyword(keyword, excludePinned = false) { - let tabs = await browser.tabs.query({ currentWindow: true }); - return tabs.filter((t) => { - return t.url.toLowerCase().includes(keyword.toLowerCase()) || - t.title && t.title.toLowerCase().includes(keyword.toLowerCase()); - }).filter((t) => { - return !(excludePinned && t.pinned); - }); - } - - select(tabId) { - return browser.tabs.update(tabId, { active: true }); - } - - remove(ids) { - 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); - } - - onSelected(listener) { - browser.tabs.onActivated.addListener(listener); - } -} - -let tabPresenter = new TabPresenter(); -tabPresenter.onSelected((tab) => { - let cache = new MemoryStorage(); - - let lastId = cache.get(CURRENT_SELECTED_KEY); - if (lastId) { - cache.set(LAST_SELECTED_KEY, lastId); - } - cache.set(CURRENT_SELECTED_KEY, tab.tabId); -}); diff --git a/src/background/presenters/TabPresenter.ts b/src/background/presenters/TabPresenter.ts new file mode 100644 index 0000000..744be39 --- /dev/null +++ b/src/background/presenters/TabPresenter.ts @@ -0,0 +1,102 @@ +import MemoryStorage from '../infrastructures/MemoryStorage'; + +const CURRENT_SELECTED_KEY = 'tabs.current.selected'; +const LAST_SELECTED_KEY = 'tabs.last.selected'; + +export default class TabPresenter { + open(url, tabId) { + return browser.tabs.update(tabId, { url }); + } + + create(url, opts) { + return browser.tabs.create({ url, ...opts }); + } + + async getCurrent() { + let tabs = await browser.tabs.query({ + active: true, currentWindow: true + }); + return tabs[0]; + } + + getAll() { + return browser.tabs.query({ currentWindow: true }); + } + + async getLastSelectedId() { + let cache = new MemoryStorage(); + let tabId = await cache.get(LAST_SELECTED_KEY); + if (tabId === null || typeof tabId === 'undefined') { + return; + } + return tabId; + } + + async getByKeyword(keyword, excludePinned = false) { + let tabs = await browser.tabs.query({ currentWindow: true }); + return tabs.filter((t) => { + return t.url.toLowerCase().includes(keyword.toLowerCase()) || + t.title && t.title.toLowerCase().includes(keyword.toLowerCase()); + }).filter((t) => { + return !(excludePinned && t.pinned); + }); + } + + select(tabId) { + return browser.tabs.update(tabId, { active: true }); + } + + remove(ids) { + 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); + } + + onSelected(listener) { + browser.tabs.onActivated.addListener(listener); + } +} + +let tabPresenter = new TabPresenter(); +tabPresenter.onSelected((tab) => { + let cache = new MemoryStorage(); + + let lastId = cache.get(CURRENT_SELECTED_KEY); + if (lastId) { + cache.set(LAST_SELECTED_KEY, lastId); + } + cache.set(CURRENT_SELECTED_KEY, tab.tabId); +}); diff --git a/src/background/presenters/WindowPresenter.js b/src/background/presenters/WindowPresenter.js deleted file mode 100644 index a82c4a2..0000000 --- a/src/background/presenters/WindowPresenter.js +++ /dev/null @@ -1,5 +0,0 @@ -export default class WindowPresenter { - create(url) { - return browser.windows.create({ url }); - } -} diff --git a/src/background/presenters/WindowPresenter.ts b/src/background/presenters/WindowPresenter.ts new file mode 100644 index 0000000..a82c4a2 --- /dev/null +++ b/src/background/presenters/WindowPresenter.ts @@ -0,0 +1,5 @@ +export default class WindowPresenter { + create(url) { + return browser.windows.create({ url }); + } +} diff --git a/src/background/repositories/BookmarkRepository.js b/src/background/repositories/BookmarkRepository.js deleted file mode 100644 index 99f7ec4..0000000 --- a/src/background/repositories/BookmarkRepository.js +++ /dev/null @@ -1,13 +0,0 @@ -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; - } -} diff --git a/src/background/repositories/BookmarkRepository.ts b/src/background/repositories/BookmarkRepository.ts new file mode 100644 index 0000000..99f7ec4 --- /dev/null +++ b/src/background/repositories/BookmarkRepository.ts @@ -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; + } +} diff --git a/src/background/repositories/BrowserSettingRepository.js b/src/background/repositories/BrowserSettingRepository.js deleted file mode 100644 index a9d2c06..0000000 --- a/src/background/repositories/BrowserSettingRepository.js +++ /dev/null @@ -1,8 +0,0 @@ -import * as urls from '../../shared/urls'; - -export default class BrowserSettingRepository { - async getHomepageUrls() { - let { value } = await browser.browserSettings.homepageOverride.get({}); - return value.split('|').map(urls.normalizeUrl); - } -} diff --git a/src/background/repositories/BrowserSettingRepository.ts b/src/background/repositories/BrowserSettingRepository.ts new file mode 100644 index 0000000..a9d2c06 --- /dev/null +++ b/src/background/repositories/BrowserSettingRepository.ts @@ -0,0 +1,8 @@ +import * as urls from '../../shared/urls'; + +export default class BrowserSettingRepository { + async getHomepageUrls() { + let { value } = await browser.browserSettings.homepageOverride.get({}); + return value.split('|').map(urls.normalizeUrl); + } +} diff --git a/src/background/repositories/CompletionsRepository.js b/src/background/repositories/CompletionsRepository.js deleted file mode 100644 index 1318d36..0000000 --- a/src/background/repositories/CompletionsRepository.js +++ /dev/null @@ -1,31 +0,0 @@ -export default class CompletionsRepository { - async queryBookmarks(keywords) { - let items = await browser.bookmarks.search({ query: keywords }); - return items.filter((item) => { - let url = undefined; - try { - url = new URL(item.url); - } catch (e) { - return false; - } - return item.type === 'bookmark' && url.protocol !== 'place:'; - }); - } - - queryHistories(keywords) { - return browser.history.search({ - text: keywords, - startTime: 0, - }); - } - - async queryTabs(keywords, excludePinned) { - let tabs = await browser.tabs.query({ currentWindow: true }); - return tabs.filter((t) => { - return t.url.toLowerCase().includes(keywords.toLowerCase()) || - t.title && t.title.toLowerCase().includes(keywords.toLowerCase()); - }).filter((t) => { - return !(excludePinned && t.pinned); - }); - } -} diff --git a/src/background/repositories/CompletionsRepository.ts b/src/background/repositories/CompletionsRepository.ts new file mode 100644 index 0000000..1318d36 --- /dev/null +++ b/src/background/repositories/CompletionsRepository.ts @@ -0,0 +1,31 @@ +export default class CompletionsRepository { + async queryBookmarks(keywords) { + let items = await browser.bookmarks.search({ query: keywords }); + return items.filter((item) => { + let url = undefined; + try { + url = new URL(item.url); + } catch (e) { + return false; + } + return item.type === 'bookmark' && url.protocol !== 'place:'; + }); + } + + queryHistories(keywords) { + return browser.history.search({ + text: keywords, + startTime: 0, + }); + } + + async queryTabs(keywords, excludePinned) { + let tabs = await browser.tabs.query({ currentWindow: true }); + return tabs.filter((t) => { + return t.url.toLowerCase().includes(keywords.toLowerCase()) || + t.title && t.title.toLowerCase().includes(keywords.toLowerCase()); + }).filter((t) => { + return !(excludePinned && t.pinned); + }); + } +} diff --git a/src/background/repositories/FindRepository.js b/src/background/repositories/FindRepository.js deleted file mode 100644 index 74ec914..0000000 --- a/src/background/repositories/FindRepository.js +++ /dev/null @@ -1,19 +0,0 @@ -import MemoryStorage from '../infrastructures/MemoryStorage'; - -const FIND_KEYWORD_KEY = 'find-keyword'; - -export default class FindRepository { - constructor() { - this.cache = new MemoryStorage(); - } - - getKeyword() { - return Promise.resolve(this.cache.get(FIND_KEYWORD_KEY)); - } - - setKeyword(keyword) { - this.cache.set(FIND_KEYWORD_KEY, keyword); - return Promise.resolve(); - } -} - diff --git a/src/background/repositories/FindRepository.ts b/src/background/repositories/FindRepository.ts new file mode 100644 index 0000000..74ec914 --- /dev/null +++ b/src/background/repositories/FindRepository.ts @@ -0,0 +1,19 @@ +import MemoryStorage from '../infrastructures/MemoryStorage'; + +const FIND_KEYWORD_KEY = 'find-keyword'; + +export default class FindRepository { + constructor() { + this.cache = new MemoryStorage(); + } + + getKeyword() { + return Promise.resolve(this.cache.get(FIND_KEYWORD_KEY)); + } + + setKeyword(keyword) { + this.cache.set(FIND_KEYWORD_KEY, keyword); + return Promise.resolve(); + } +} + diff --git a/src/background/repositories/MarkRepository.js b/src/background/repositories/MarkRepository.js deleted file mode 100644 index 282c712..0000000 --- a/src/background/repositories/MarkRepository.js +++ /dev/null @@ -1,33 +0,0 @@ -import MemoryStorage from '../infrastructures/MemoryStorage'; -import GlobalMark from '../domains/GlobalMark'; - -const MARK_KEY = 'mark'; - -export default class MarkRepository { - constructor() { - this.cache = new MemoryStorage(); - } - - getMark(key) { - let marks = this.getOrEmptyMarks(); - let data = marks[key]; - if (!data) { - return Promise.resolve(undefined); - } - let mark = new GlobalMark(data.tabId, data.url, data.x, data.y); - return Promise.resolve(mark); - } - - setMark(key, mark) { - let marks = this.getOrEmptyMarks(); - marks[key] = { tabId: mark.tabId, url: mark.url, x: mark.x, y: mark.y }; - this.cache.set(MARK_KEY, marks); - - return Promise.resolve(); - } - - getOrEmptyMarks() { - return this.cache.get(MARK_KEY) || {}; - } -} - diff --git a/src/background/repositories/MarkRepository.ts b/src/background/repositories/MarkRepository.ts new file mode 100644 index 0000000..282c712 --- /dev/null +++ b/src/background/repositories/MarkRepository.ts @@ -0,0 +1,33 @@ +import MemoryStorage from '../infrastructures/MemoryStorage'; +import GlobalMark from '../domains/GlobalMark'; + +const MARK_KEY = 'mark'; + +export default class MarkRepository { + constructor() { + this.cache = new MemoryStorage(); + } + + getMark(key) { + let marks = this.getOrEmptyMarks(); + let data = marks[key]; + if (!data) { + return Promise.resolve(undefined); + } + let mark = new GlobalMark(data.tabId, data.url, data.x, data.y); + return Promise.resolve(mark); + } + + setMark(key, mark) { + let marks = this.getOrEmptyMarks(); + marks[key] = { tabId: mark.tabId, url: mark.url, x: mark.x, y: mark.y }; + this.cache.set(MARK_KEY, marks); + + return Promise.resolve(); + } + + getOrEmptyMarks() { + return this.cache.get(MARK_KEY) || {}; + } +} + diff --git a/src/background/repositories/PersistentSettingRepository.js b/src/background/repositories/PersistentSettingRepository.js deleted file mode 100644 index 4cab107..0000000 --- a/src/background/repositories/PersistentSettingRepository.js +++ /dev/null @@ -1,12 +0,0 @@ -import Setting from '../domains/Setting'; - -export default class SettingRepository { - async load() { - let { settings } = await browser.storage.local.get('settings'); - if (!settings) { - return null; - } - return Setting.deserialize(settings); - } -} - diff --git a/src/background/repositories/PersistentSettingRepository.ts b/src/background/repositories/PersistentSettingRepository.ts new file mode 100644 index 0000000..4cab107 --- /dev/null +++ b/src/background/repositories/PersistentSettingRepository.ts @@ -0,0 +1,12 @@ +import Setting from '../domains/Setting'; + +export default class SettingRepository { + async load() { + let { settings } = await browser.storage.local.get('settings'); + if (!settings) { + return null; + } + return Setting.deserialize(settings); + } +} + diff --git a/src/background/repositories/SettingRepository.js b/src/background/repositories/SettingRepository.js deleted file mode 100644 index c4667a9..0000000 --- a/src/background/repositories/SettingRepository.js +++ /dev/null @@ -1,23 +0,0 @@ -import MemoryStorage from '../infrastructures/MemoryStorage'; - -const CACHED_SETTING_KEY = 'setting'; - -export default class SettingRepository { - constructor() { - this.cache = new MemoryStorage(); - } - - get() { - return Promise.resolve(this.cache.get(CACHED_SETTING_KEY)); - } - - update(value) { - return this.cache.set(CACHED_SETTING_KEY, value); - } - - async setProperty(name, value) { - let current = await this.get(); - current.properties[name] = value; - return this.update(current); - } -} diff --git a/src/background/repositories/SettingRepository.ts b/src/background/repositories/SettingRepository.ts new file mode 100644 index 0000000..c4667a9 --- /dev/null +++ b/src/background/repositories/SettingRepository.ts @@ -0,0 +1,23 @@ +import MemoryStorage from '../infrastructures/MemoryStorage'; + +const CACHED_SETTING_KEY = 'setting'; + +export default class SettingRepository { + constructor() { + this.cache = new MemoryStorage(); + } + + get() { + return Promise.resolve(this.cache.get(CACHED_SETTING_KEY)); + } + + update(value) { + return this.cache.set(CACHED_SETTING_KEY, value); + } + + async setProperty(name, value) { + let current = await this.get(); + current.properties[name] = value; + return this.update(current); + } +} diff --git a/src/background/repositories/VersionRepository.js b/src/background/repositories/VersionRepository.js deleted file mode 100644 index 4c71d05..0000000 --- a/src/background/repositories/VersionRepository.js +++ /dev/null @@ -1,10 +0,0 @@ -export default class VersionRepository { - async get() { - let { version } = await browser.storage.local.get('version'); - return version; - } - - update(version) { - return browser.storage.local.set({ version }); - } -} diff --git a/src/background/repositories/VersionRepository.ts b/src/background/repositories/VersionRepository.ts new file mode 100644 index 0000000..4c71d05 --- /dev/null +++ b/src/background/repositories/VersionRepository.ts @@ -0,0 +1,10 @@ +export default class VersionRepository { + async get() { + let { version } = await browser.storage.local.get('version'); + return version; + } + + update(version) { + return browser.storage.local.set({ version }); + } +} diff --git a/src/background/usecases/AddonEnabledUseCase.js b/src/background/usecases/AddonEnabledUseCase.js deleted file mode 100644 index bb2c347..0000000 --- a/src/background/usecases/AddonEnabledUseCase.js +++ /dev/null @@ -1,29 +0,0 @@ -import IndicatorPresenter from '../presenters/IndicatorPresenter'; -import TabPresenter from '../presenters/TabPresenter'; -import ContentMessageClient from '../infrastructures/ContentMessageClient'; - -export default class AddonEnabledUseCase { - constructor() { - this.indicatorPresentor = new IndicatorPresenter(); - - this.indicatorPresentor.onClick(tab => this.onIndicatorClick(tab.id)); - - this.tabPresenter = new TabPresenter(); - this.tabPresenter.onSelected(info => this.onTabSelected(info.tabId)); - - this.contentMessageClient = new ContentMessageClient(); - } - - indicate(enabled) { - return this.indicatorPresentor.indicate(enabled); - } - - onIndicatorClick(tabId) { - return this.contentMessageClient.toggleAddonEnabled(tabId); - } - - async onTabSelected(tabId) { - let enabled = await this.contentMessageClient.getAddonEnabled(tabId); - return this.indicatorPresentor.indicate(enabled); - } -} diff --git a/src/background/usecases/AddonEnabledUseCase.ts b/src/background/usecases/AddonEnabledUseCase.ts new file mode 100644 index 0000000..bb2c347 --- /dev/null +++ b/src/background/usecases/AddonEnabledUseCase.ts @@ -0,0 +1,29 @@ +import IndicatorPresenter from '../presenters/IndicatorPresenter'; +import TabPresenter from '../presenters/TabPresenter'; +import ContentMessageClient from '../infrastructures/ContentMessageClient'; + +export default class AddonEnabledUseCase { + constructor() { + this.indicatorPresentor = new IndicatorPresenter(); + + this.indicatorPresentor.onClick(tab => this.onIndicatorClick(tab.id)); + + this.tabPresenter = new TabPresenter(); + this.tabPresenter.onSelected(info => this.onTabSelected(info.tabId)); + + this.contentMessageClient = new ContentMessageClient(); + } + + indicate(enabled) { + return this.indicatorPresentor.indicate(enabled); + } + + onIndicatorClick(tabId) { + return this.contentMessageClient.toggleAddonEnabled(tabId); + } + + async onTabSelected(tabId) { + let enabled = await this.contentMessageClient.getAddonEnabled(tabId); + return this.indicatorPresentor.indicate(enabled); + } +} diff --git a/src/background/usecases/CommandUseCase.js b/src/background/usecases/CommandUseCase.js deleted file mode 100644 index 9ec46fe..0000000 --- a/src/background/usecases/CommandUseCase.js +++ /dev/null @@ -1,125 +0,0 @@ -import * as parsers from './parsers'; -import * as urls from '../../shared/urls'; -import TabPresenter from '../presenters/TabPresenter'; -import WindowPresenter from '../presenters/WindowPresenter'; -import SettingRepository from '../repositories/SettingRepository'; -import BookmarkRepository from '../repositories/BookmarkRepository'; -import ConsoleClient from '../infrastructures/ConsoleClient'; -import ContentMessageClient from '../infrastructures/ContentMessageClient'; -import * as properties from 'shared/settings/properties'; - -export default class CommandIndicator { - constructor() { - this.tabPresenter = new TabPresenter(); - this.windowPresenter = new WindowPresenter(); - this.settingRepository = new SettingRepository(); - this.bookmarkRepository = new BookmarkRepository(); - this.consoleClient = new ConsoleClient(); - - this.contentMessageClient = new ContentMessageClient(); - } - - 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); - } - - // eslint-disable-next-line max-statements - async buffer(keywords) { - if (keywords.length === 0) { - return; - } - - if (!isNaN(keywords)) { - let tabs = await this.tabPresenter.getAll(); - let index = parseInt(keywords, 10) - 1; - if (index < 0 || tabs.length <= index) { - throw new RangeError(`tab ${index + 1} does not exist`); - } - return this.tabPresenter.select(tabs[index].id); - } else if (keywords.trim() === '%') { - // Select current window - return; - } else if (keywords.trim() === '#') { - // Select last selected window - let lastId = await this.tabPresenter.getLastSelectedId(); - if (typeof lastId === 'undefined' || lastId === null) { - throw new Error('No last selected tab'); - } - return this.tabPresenter.select(lastId); - } - - 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.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.consoleClient.showInfo(tab.id, message); - } - - async set(keywords) { - if (keywords.length === 0) { - return; - } - let [name, value] = parsers.parseSetOption(keywords, properties.types); - await this.settingRepository.setProperty(name, value); - - return this.contentMessageClient.broadcastSettingsChanged(); - } - - async urlOrSearch(keywords) { - let settings = await this.settingRepository.get(); - return urls.searchUrl(keywords, settings.search); - } -} diff --git a/src/background/usecases/CommandUseCase.ts b/src/background/usecases/CommandUseCase.ts new file mode 100644 index 0000000..9ec46fe --- /dev/null +++ b/src/background/usecases/CommandUseCase.ts @@ -0,0 +1,125 @@ +import * as parsers from './parsers'; +import * as urls from '../../shared/urls'; +import TabPresenter from '../presenters/TabPresenter'; +import WindowPresenter from '../presenters/WindowPresenter'; +import SettingRepository from '../repositories/SettingRepository'; +import BookmarkRepository from '../repositories/BookmarkRepository'; +import ConsoleClient from '../infrastructures/ConsoleClient'; +import ContentMessageClient from '../infrastructures/ContentMessageClient'; +import * as properties from 'shared/settings/properties'; + +export default class CommandIndicator { + constructor() { + this.tabPresenter = new TabPresenter(); + this.windowPresenter = new WindowPresenter(); + this.settingRepository = new SettingRepository(); + this.bookmarkRepository = new BookmarkRepository(); + this.consoleClient = new ConsoleClient(); + + this.contentMessageClient = new ContentMessageClient(); + } + + 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); + } + + // eslint-disable-next-line max-statements + async buffer(keywords) { + if (keywords.length === 0) { + return; + } + + if (!isNaN(keywords)) { + let tabs = await this.tabPresenter.getAll(); + let index = parseInt(keywords, 10) - 1; + if (index < 0 || tabs.length <= index) { + throw new RangeError(`tab ${index + 1} does not exist`); + } + return this.tabPresenter.select(tabs[index].id); + } else if (keywords.trim() === '%') { + // Select current window + return; + } else if (keywords.trim() === '#') { + // Select last selected window + let lastId = await this.tabPresenter.getLastSelectedId(); + if (typeof lastId === 'undefined' || lastId === null) { + throw new Error('No last selected tab'); + } + return this.tabPresenter.select(lastId); + } + + 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.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.consoleClient.showInfo(tab.id, message); + } + + async set(keywords) { + if (keywords.length === 0) { + return; + } + let [name, value] = parsers.parseSetOption(keywords, properties.types); + await this.settingRepository.setProperty(name, value); + + return this.contentMessageClient.broadcastSettingsChanged(); + } + + async urlOrSearch(keywords) { + let settings = await this.settingRepository.get(); + return urls.searchUrl(keywords, settings.search); + } +} diff --git a/src/background/usecases/CompletionsUseCase.js b/src/background/usecases/CompletionsUseCase.js deleted file mode 100644 index 7dc30ac..0000000 --- a/src/background/usecases/CompletionsUseCase.js +++ /dev/null @@ -1,205 +0,0 @@ -import CompletionItem from '../domains/CompletionItem'; -import CompletionGroup from '../domains/CompletionGroup'; -import Completions from '../domains/Completions'; -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 properties from '../../shared/settings/properties'; - -const COMPLETION_ITEM_LIMIT = 10; - -export default class CompletionsUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - this.completionsRepository = new CompletionsRepository(); - this.settingRepository = new SettingRepository(); - } - - queryConsoleCommand(prefix) { - 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(Completions.empty()); - } - return Promise.resolve( - new Completions([new CompletionGroup('Console Command', items)]) - ); - } - - async queryOpen(name, keywords) { - let settings = await this.settingRepository.get(); - let groups = []; - - let complete = settings.properties.complete || properties.defaults.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(new CompletionGroup('Search Engines', 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(new CompletionGroup('History', 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(new CompletionGroup('Bookmarks', bookmarks)); - } - } - } - return new Completions(groups); - } - - // eslint-disable-next-line max-statements - async queryBuffer(name, keywords) { - let lastId = await this.tabPresenter.getLastSelectedId(); - let trimmed = keywords.trim(); - let tabs = []; - if (trimmed.length > 0 && !isNaN(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); - 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); - tabs = [tab]; - } - } else { - tabs = await this.completionsRepository.queryTabs(keywords, false); - } - const flag = (tab) => { - if (tab.active) { - return '%'; - } else if (tab.id === lastId) { - return '#'; - } - return ' '; - }; - let items = tabs.map(tab => new CompletionItem({ - 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(Completions.empty()); - } - return new Completions([new CompletionGroup('Buffers', items)]); - } - - queryBdelete(name, keywords) { - return this.queryTabs(name, true, keywords); - } - - queryBdeleteForce(name, keywords) { - return this.queryTabs(name, false, keywords); - } - - querySet(name, keywords) { - let items = Object.keys(properties.docs).map((key) => { - if (properties.types[key] === 'boolean') { - return [ - new CompletionItem({ - caption: key, - content: name + ' ' + key, - url: 'Enable ' + properties.docs[key], - }), - new CompletionItem({ - caption: 'no' + key, - content: name + ' no' + key, - url: 'Disable ' + properties.docs[key], - }), - ]; - } - return [ - new CompletionItem({ - caption: key, - content: name + ' ' + key, - url: 'Set ' + properties.docs[key], - }) - ]; - }); - items = items.reduce((acc, val) => acc.concat(val), []); - items = items.filter((item) => { - return item.caption.startsWith(keywords); - }); - if (items.length === 0) { - return Promise.resolve(Completions.empty()); - } - return Promise.resolve( - new Completions([new CompletionGroup('Properties', items)]) - ); - } - - async queryTabs(name, excludePinned, args) { - let tabs = await this.completionsRepository.queryTabs(args, excludePinned); - let items = tabs.map(tab => new CompletionItem({ - caption: tab.title, - content: name + ' ' + tab.title, - url: tab.url, - icon: tab.favIconUrl - })); - if (items.length === 0) { - return Promise.resolve(Completions.empty()); - } - return new Completions([new CompletionGroup('Buffers', items)]); - } - - async querySearchEngineItems(name, keywords) { - let settings = await this.settingRepository.get(); - let engines = Object.keys(settings.search.engines) - .filter(key => key.startsWith(keywords)); - return engines.map(key => new CompletionItem({ - caption: key, - content: name + ' ' + key, - })); - } - - async queryHistoryItems(name, keywords) { - 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, y) => x.visitCount < y.visitCount) - .slice(0, COMPLETION_ITEM_LIMIT); - return histories.map(page => new CompletionItem({ - caption: page.title, - content: name + ' ' + page.url, - url: page.url - })); - } - - async queryBookmarkItems(name, keywords) { - let bookmarks = await this.completionsRepository.queryBookmarks(keywords); - return bookmarks.slice(0, COMPLETION_ITEM_LIMIT) - .map(page => new CompletionItem({ - caption: page.title, - content: name + ' ' + page.url, - url: page.url - })); - } -} diff --git a/src/background/usecases/CompletionsUseCase.ts b/src/background/usecases/CompletionsUseCase.ts new file mode 100644 index 0000000..7dc30ac --- /dev/null +++ b/src/background/usecases/CompletionsUseCase.ts @@ -0,0 +1,205 @@ +import CompletionItem from '../domains/CompletionItem'; +import CompletionGroup from '../domains/CompletionGroup'; +import Completions from '../domains/Completions'; +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 properties from '../../shared/settings/properties'; + +const COMPLETION_ITEM_LIMIT = 10; + +export default class CompletionsUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + this.completionsRepository = new CompletionsRepository(); + this.settingRepository = new SettingRepository(); + } + + queryConsoleCommand(prefix) { + 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(Completions.empty()); + } + return Promise.resolve( + new Completions([new CompletionGroup('Console Command', items)]) + ); + } + + async queryOpen(name, keywords) { + let settings = await this.settingRepository.get(); + let groups = []; + + let complete = settings.properties.complete || properties.defaults.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(new CompletionGroup('Search Engines', 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(new CompletionGroup('History', 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(new CompletionGroup('Bookmarks', bookmarks)); + } + } + } + return new Completions(groups); + } + + // eslint-disable-next-line max-statements + async queryBuffer(name, keywords) { + let lastId = await this.tabPresenter.getLastSelectedId(); + let trimmed = keywords.trim(); + let tabs = []; + if (trimmed.length > 0 && !isNaN(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); + 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); + tabs = [tab]; + } + } else { + tabs = await this.completionsRepository.queryTabs(keywords, false); + } + const flag = (tab) => { + if (tab.active) { + return '%'; + } else if (tab.id === lastId) { + return '#'; + } + return ' '; + }; + let items = tabs.map(tab => new CompletionItem({ + 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(Completions.empty()); + } + return new Completions([new CompletionGroup('Buffers', items)]); + } + + queryBdelete(name, keywords) { + return this.queryTabs(name, true, keywords); + } + + queryBdeleteForce(name, keywords) { + return this.queryTabs(name, false, keywords); + } + + querySet(name, keywords) { + let items = Object.keys(properties.docs).map((key) => { + if (properties.types[key] === 'boolean') { + return [ + new CompletionItem({ + caption: key, + content: name + ' ' + key, + url: 'Enable ' + properties.docs[key], + }), + new CompletionItem({ + caption: 'no' + key, + content: name + ' no' + key, + url: 'Disable ' + properties.docs[key], + }), + ]; + } + return [ + new CompletionItem({ + caption: key, + content: name + ' ' + key, + url: 'Set ' + properties.docs[key], + }) + ]; + }); + items = items.reduce((acc, val) => acc.concat(val), []); + items = items.filter((item) => { + return item.caption.startsWith(keywords); + }); + if (items.length === 0) { + return Promise.resolve(Completions.empty()); + } + return Promise.resolve( + new Completions([new CompletionGroup('Properties', items)]) + ); + } + + async queryTabs(name, excludePinned, args) { + let tabs = await this.completionsRepository.queryTabs(args, excludePinned); + let items = tabs.map(tab => new CompletionItem({ + caption: tab.title, + content: name + ' ' + tab.title, + url: tab.url, + icon: tab.favIconUrl + })); + if (items.length === 0) { + return Promise.resolve(Completions.empty()); + } + return new Completions([new CompletionGroup('Buffers', items)]); + } + + async querySearchEngineItems(name, keywords) { + let settings = await this.settingRepository.get(); + let engines = Object.keys(settings.search.engines) + .filter(key => key.startsWith(keywords)); + return engines.map(key => new CompletionItem({ + caption: key, + content: name + ' ' + key, + })); + } + + async queryHistoryItems(name, keywords) { + 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, y) => x.visitCount < y.visitCount) + .slice(0, COMPLETION_ITEM_LIMIT); + return histories.map(page => new CompletionItem({ + caption: page.title, + content: name + ' ' + page.url, + url: page.url + })); + } + + async queryBookmarkItems(name, keywords) { + let bookmarks = await this.completionsRepository.queryBookmarks(keywords); + return bookmarks.slice(0, COMPLETION_ITEM_LIMIT) + .map(page => new CompletionItem({ + caption: page.title, + content: name + ' ' + page.url, + url: page.url + })); + } +} diff --git a/src/background/usecases/ConsoleUseCase.js b/src/background/usecases/ConsoleUseCase.js deleted file mode 100644 index e8e5d4a..0000000 --- a/src/background/usecases/ConsoleUseCase.js +++ /dev/null @@ -1,61 +0,0 @@ -import TabPresenter from '../presenters/TabPresenter'; -import ConsoleClient from '../infrastructures/ConsoleClient'; - -export default class ConsoleUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - this.consoleClient = new ConsoleClient(); - } - - async showCommand() { - let tab = await this.tabPresenter.getCurrent(); - return this.consoleClient.showCommand(tab.id, ''); - } - - async showOpenCommand(alter) { - let tab = await this.tabPresenter.getCurrent(); - let command = 'open '; - if (alter) { - command += tab.url; - } - return this.consoleClient.showCommand(tab.id, command); - } - - async showTabopenCommand(alter) { - let tab = await this.tabPresenter.getCurrent(); - let command = 'tabopen '; - if (alter) { - command += tab.url; - } - return this.consoleClient.showCommand(tab.id, command); - } - - async showWinopenCommand(alter) { - let tab = await this.tabPresenter.getCurrent(); - let command = 'winopen '; - if (alter) { - command += tab.url; - } - return this.consoleClient.showCommand(tab.id, command); - } - - async showBufferCommand() { - let tab = await this.tabPresenter.getCurrent(); - let command = 'buffer '; - return this.consoleClient.showCommand(tab.id, command); - } - - async showAddbookmarkCommand(alter) { - let tab = await this.tabPresenter.getCurrent(); - let command = 'addbookmark '; - if (alter) { - command += tab.title; - } - return this.consoleClient.showCommand(tab.id, command); - } - - async hideConsole() { - let tab = await this.tabPresenter.getCurrent(); - return this.consoleClient.hide(tab.id); - } -} diff --git a/src/background/usecases/ConsoleUseCase.ts b/src/background/usecases/ConsoleUseCase.ts new file mode 100644 index 0000000..e8e5d4a --- /dev/null +++ b/src/background/usecases/ConsoleUseCase.ts @@ -0,0 +1,61 @@ +import TabPresenter from '../presenters/TabPresenter'; +import ConsoleClient from '../infrastructures/ConsoleClient'; + +export default class ConsoleUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + this.consoleClient = new ConsoleClient(); + } + + async showCommand() { + let tab = await this.tabPresenter.getCurrent(); + return this.consoleClient.showCommand(tab.id, ''); + } + + async showOpenCommand(alter) { + let tab = await this.tabPresenter.getCurrent(); + let command = 'open '; + if (alter) { + command += tab.url; + } + return this.consoleClient.showCommand(tab.id, command); + } + + async showTabopenCommand(alter) { + let tab = await this.tabPresenter.getCurrent(); + let command = 'tabopen '; + if (alter) { + command += tab.url; + } + return this.consoleClient.showCommand(tab.id, command); + } + + async showWinopenCommand(alter) { + let tab = await this.tabPresenter.getCurrent(); + let command = 'winopen '; + if (alter) { + command += tab.url; + } + return this.consoleClient.showCommand(tab.id, command); + } + + async showBufferCommand() { + let tab = await this.tabPresenter.getCurrent(); + let command = 'buffer '; + return this.consoleClient.showCommand(tab.id, command); + } + + async showAddbookmarkCommand(alter) { + let tab = await this.tabPresenter.getCurrent(); + let command = 'addbookmark '; + if (alter) { + command += tab.title; + } + return this.consoleClient.showCommand(tab.id, command); + } + + async hideConsole() { + let tab = await this.tabPresenter.getCurrent(); + return this.consoleClient.hide(tab.id); + } +} diff --git a/src/background/usecases/FindUseCase.js b/src/background/usecases/FindUseCase.js deleted file mode 100644 index 224e4a9..0000000 --- a/src/background/usecases/FindUseCase.js +++ /dev/null @@ -1,24 +0,0 @@ -import FindRepository from '../repositories/FindRepository'; -import TabPresenter from '../presenters/TabPresenter'; -import ConsoleClient from '../infrastructures/ConsoleClient'; - -export default class FindUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - this.findRepository = new FindRepository(); - this.consoleClient = new ConsoleClient(); - } - - getKeyword() { - return this.findRepository.getKeyword(); - } - - setKeyword(keyword) { - return this.findRepository.setKeyword(keyword); - } - - async findStart() { - let tab = await this.tabPresenter.getCurrent(); - return this.consoleClient.showFind(tab.id); - } -} diff --git a/src/background/usecases/FindUseCase.ts b/src/background/usecases/FindUseCase.ts new file mode 100644 index 0000000..224e4a9 --- /dev/null +++ b/src/background/usecases/FindUseCase.ts @@ -0,0 +1,24 @@ +import FindRepository from '../repositories/FindRepository'; +import TabPresenter from '../presenters/TabPresenter'; +import ConsoleClient from '../infrastructures/ConsoleClient'; + +export default class FindUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + this.findRepository = new FindRepository(); + this.consoleClient = new ConsoleClient(); + } + + getKeyword() { + return this.findRepository.getKeyword(); + } + + setKeyword(keyword) { + return this.findRepository.setKeyword(keyword); + } + + async findStart() { + let tab = await this.tabPresenter.getCurrent(); + return this.consoleClient.showFind(tab.id); + } +} diff --git a/src/background/usecases/LinkUseCase.js b/src/background/usecases/LinkUseCase.js deleted file mode 100644 index 89412c5..0000000 --- a/src/background/usecases/LinkUseCase.js +++ /dev/null @@ -1,19 +0,0 @@ -import SettingRepository from '../repositories/SettingRepository'; -import TabPresenter from '../presenters/TabPresenter'; - -export default class LinkUseCase { - constructor() { - this.settingRepository = new SettingRepository(); - this.tabPresenter = new TabPresenter(); - } - - openToTab(url, tabId) { - return this.tabPresenter.open(url, tabId); - } - - openNewTab(url, openerId, background) { - return this.tabPresenter.create(url, { - openerTabId: openerId, active: !background - }); - } -} diff --git a/src/background/usecases/LinkUseCase.ts b/src/background/usecases/LinkUseCase.ts new file mode 100644 index 0000000..89412c5 --- /dev/null +++ b/src/background/usecases/LinkUseCase.ts @@ -0,0 +1,19 @@ +import SettingRepository from '../repositories/SettingRepository'; +import TabPresenter from '../presenters/TabPresenter'; + +export default class LinkUseCase { + constructor() { + this.settingRepository = new SettingRepository(); + this.tabPresenter = new TabPresenter(); + } + + openToTab(url, tabId) { + return this.tabPresenter.open(url, tabId); + } + + openNewTab(url, openerId, background) { + return this.tabPresenter.create(url, { + openerTabId: openerId, active: !background + }); + } +} diff --git a/src/background/usecases/MarkUseCase.js b/src/background/usecases/MarkUseCase.js deleted file mode 100644 index 39c796b..0000000 --- a/src/background/usecases/MarkUseCase.js +++ /dev/null @@ -1,39 +0,0 @@ -import GlobalMark from '../domains/GlobalMark'; -import TabPresenter from '../presenters/TabPresenter'; -import MarkRepository from '../repositories/MarkRepository'; -import ConsoleClient from '../infrastructures/ConsoleClient'; -import ContentMessageClient from '../infrastructures/ContentMessageClient'; - -export default class MarkUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - this.markRepository = new MarkRepository(); - this.consoleClient = new ConsoleClient(); - this.contentMessageClient = new ContentMessageClient(); - } - - async setGlobal(key, x, y) { - let tab = await this.tabPresenter.getCurrent(); - let mark = new GlobalMark(tab.id, tab.url, x, y); - return this.markRepository.setMark(key, mark); - } - - async jumpGlobal(key) { - let current = await this.tabPresenter.getCurrent(); - - let mark = await this.markRepository.getMark(key); - if (!mark) { - return this.consoleClient.showError(current.id, 'Mark is not set'); - } - - return this.contentMessageClient.scrollTo( - mark.tabId, mark.x, mark.y - ).then(() => { - return this.tabPresenter.select(mark.tabId); - }).catch(async() => { - let tab = await this.tabPresenter.create(mark.url); - let mark2 = new GlobalMark(tab.id, mark.url, mark.x, mark.y); - return this.markRepository.setMark(key, mark2); - }); - } -} diff --git a/src/background/usecases/MarkUseCase.ts b/src/background/usecases/MarkUseCase.ts new file mode 100644 index 0000000..39c796b --- /dev/null +++ b/src/background/usecases/MarkUseCase.ts @@ -0,0 +1,39 @@ +import GlobalMark from '../domains/GlobalMark'; +import TabPresenter from '../presenters/TabPresenter'; +import MarkRepository from '../repositories/MarkRepository'; +import ConsoleClient from '../infrastructures/ConsoleClient'; +import ContentMessageClient from '../infrastructures/ContentMessageClient'; + +export default class MarkUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + this.markRepository = new MarkRepository(); + this.consoleClient = new ConsoleClient(); + this.contentMessageClient = new ContentMessageClient(); + } + + async setGlobal(key, x, y) { + let tab = await this.tabPresenter.getCurrent(); + let mark = new GlobalMark(tab.id, tab.url, x, y); + return this.markRepository.setMark(key, mark); + } + + async jumpGlobal(key) { + let current = await this.tabPresenter.getCurrent(); + + let mark = await this.markRepository.getMark(key); + if (!mark) { + return this.consoleClient.showError(current.id, 'Mark is not set'); + } + + return this.contentMessageClient.scrollTo( + mark.tabId, mark.x, mark.y + ).then(() => { + return this.tabPresenter.select(mark.tabId); + }).catch(async() => { + let tab = await this.tabPresenter.create(mark.url); + let mark2 = new GlobalMark(tab.id, mark.url, mark.x, mark.y); + return this.markRepository.setMark(key, mark2); + }); + } +} diff --git a/src/background/usecases/SettingUseCase.js b/src/background/usecases/SettingUseCase.js deleted file mode 100644 index 9e17408..0000000 --- a/src/background/usecases/SettingUseCase.js +++ /dev/null @@ -1,28 +0,0 @@ -import Setting from '../domains/Setting'; -// eslint-disable-next-line max-len -import PersistentSettingRepository from '../repositories/PersistentSettingRepository'; -import SettingRepository from '../repositories/SettingRepository'; - -export default class SettingUseCase { - constructor() { - this.persistentSettingRepository = new PersistentSettingRepository(); - this.settingRepository = new SettingRepository(); - } - - get() { - return this.settingRepository.get(); - } - - async reload() { - let settings = await this.persistentSettingRepository.load(); - if (!settings) { - settings = Setting.defaultSettings(); - } - - let value = settings.value(); - - this.settingRepository.update(value); - - return value; - } -} diff --git a/src/background/usecases/SettingUseCase.ts b/src/background/usecases/SettingUseCase.ts new file mode 100644 index 0000000..9e17408 --- /dev/null +++ b/src/background/usecases/SettingUseCase.ts @@ -0,0 +1,28 @@ +import Setting from '../domains/Setting'; +// eslint-disable-next-line max-len +import PersistentSettingRepository from '../repositories/PersistentSettingRepository'; +import SettingRepository from '../repositories/SettingRepository'; + +export default class SettingUseCase { + constructor() { + this.persistentSettingRepository = new PersistentSettingRepository(); + this.settingRepository = new SettingRepository(); + } + + get() { + return this.settingRepository.get(); + } + + async reload() { + let settings = await this.persistentSettingRepository.load(); + if (!settings) { + settings = Setting.defaultSettings(); + } + + let value = settings.value(); + + this.settingRepository.update(value); + + return value; + } +} diff --git a/src/background/usecases/TabSelectUseCase.js b/src/background/usecases/TabSelectUseCase.js deleted file mode 100644 index 16b3e14..0000000 --- a/src/background/usecases/TabSelectUseCase.js +++ /dev/null @@ -1,51 +0,0 @@ -import TabPresenter from '../presenters/TabPresenter'; - -export default class TabSelectUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - } - - 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.tabPresenter.getLastSelectedId(); - if (tabId === null || typeof tabId === 'undefined') { - return; - } - this.tabPresenter.select(tabId); - } -} diff --git a/src/background/usecases/TabSelectUseCase.ts b/src/background/usecases/TabSelectUseCase.ts new file mode 100644 index 0000000..16b3e14 --- /dev/null +++ b/src/background/usecases/TabSelectUseCase.ts @@ -0,0 +1,51 @@ +import TabPresenter from '../presenters/TabPresenter'; + +export default class TabSelectUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + } + + 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.tabPresenter.getLastSelectedId(); + if (tabId === null || typeof tabId === 'undefined') { + return; + } + this.tabPresenter.select(tabId); + } +} diff --git a/src/background/usecases/TabUseCase.js b/src/background/usecases/TabUseCase.js deleted file mode 100644 index d930842..0000000 --- a/src/background/usecases/TabUseCase.js +++ /dev/null @@ -1,77 +0,0 @@ -import TabPresenter from '../presenters/TabPresenter'; -import BrowserSettingRepository from '../repositories/BrowserSettingRepository'; - -export default class TabUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - this.browserSettingRepository = new BrowserSettingRepository(); - } - - async close(force) { - let tab = await this.tabPresenter.getCurrent(); - if (!force && tab.pinned) { - return; - } - return this.tabPresenter.remove([tab.id]); - } - - async closeRight() { - let tabs = await this.tabPresenter.getAll(); - tabs.sort((t1, t2) => t1.index - t2.index); - let index = tabs.findIndex(t => t.active); - if (index < 0) { - return; - } - for (let i = index + 1; i < tabs.length; ++i) { - let tab = tabs[i]; - if (!tab.pinned) { - this.tabPresenter.remove(tab.id); - } - } - } - - reopen() { - return this.tabPresenter.reopen(); - } - - 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 openHome(newTab) { - let tab = await this.tabPresenter.getCurrent(); - let urls = await this.browserSettingRepository.getHomepageUrls(); - if (urls.length === 1 && urls[0] === 'about:home') { - // eslint-disable-next-line max-len - throw new Error('Cannot open Firefox Home (about:home) by WebExtensions, set your custom URLs'); - } - if (urls.length === 1 && !newTab) { - return this.tabPresenter.open(urls[0], tab.id); - } - for (let url of urls) { - this.tabPresenter.create(url); - } - } -} diff --git a/src/background/usecases/TabUseCase.ts b/src/background/usecases/TabUseCase.ts new file mode 100644 index 0000000..d930842 --- /dev/null +++ b/src/background/usecases/TabUseCase.ts @@ -0,0 +1,77 @@ +import TabPresenter from '../presenters/TabPresenter'; +import BrowserSettingRepository from '../repositories/BrowserSettingRepository'; + +export default class TabUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + this.browserSettingRepository = new BrowserSettingRepository(); + } + + async close(force) { + let tab = await this.tabPresenter.getCurrent(); + if (!force && tab.pinned) { + return; + } + return this.tabPresenter.remove([tab.id]); + } + + async closeRight() { + let tabs = await this.tabPresenter.getAll(); + tabs.sort((t1, t2) => t1.index - t2.index); + let index = tabs.findIndex(t => t.active); + if (index < 0) { + return; + } + for (let i = index + 1; i < tabs.length; ++i) { + let tab = tabs[i]; + if (!tab.pinned) { + this.tabPresenter.remove(tab.id); + } + } + } + + reopen() { + return this.tabPresenter.reopen(); + } + + 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 openHome(newTab) { + let tab = await this.tabPresenter.getCurrent(); + let urls = await this.browserSettingRepository.getHomepageUrls(); + if (urls.length === 1 && urls[0] === 'about:home') { + // eslint-disable-next-line max-len + throw new Error('Cannot open Firefox Home (about:home) by WebExtensions, set your custom URLs'); + } + if (urls.length === 1 && !newTab) { + return this.tabPresenter.open(urls[0], tab.id); + } + for (let url of urls) { + this.tabPresenter.create(url); + } + } +} diff --git a/src/background/usecases/VersionUseCase.js b/src/background/usecases/VersionUseCase.js deleted file mode 100644 index ed5112b..0000000 --- a/src/background/usecases/VersionUseCase.js +++ /dev/null @@ -1,26 +0,0 @@ -import manifest from '../../../manifest.json'; -import TabPresenter from '../presenters/TabPresenter'; -import NotifyPresenter from '../presenters/NotifyPresenter'; - -export default class VersionUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - this.notifyPresenter = new NotifyPresenter(); - } - - notify() { - let title = `Vim Vixen ${manifest.version} has been installed`; - let message = 'Click here to see release notes'; - let url = this.releaseNoteUrl(manifest.version); - this.notifyPresenter.notify(title, message, () => { - this.tabPresenter.create(url); - }); - } - - releaseNoteUrl(version) { - if (version) { - return `https://github.com/ueokande/vim-vixen/releases/tag/${version}`; - } - return 'https://github.com/ueokande/vim-vixen/releases/'; - } -} diff --git a/src/background/usecases/VersionUseCase.ts b/src/background/usecases/VersionUseCase.ts new file mode 100644 index 0000000..ed5112b --- /dev/null +++ b/src/background/usecases/VersionUseCase.ts @@ -0,0 +1,26 @@ +import manifest from '../../../manifest.json'; +import TabPresenter from '../presenters/TabPresenter'; +import NotifyPresenter from '../presenters/NotifyPresenter'; + +export default class VersionUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + this.notifyPresenter = new NotifyPresenter(); + } + + notify() { + let title = `Vim Vixen ${manifest.version} has been installed`; + let message = 'Click here to see release notes'; + let url = this.releaseNoteUrl(manifest.version); + this.notifyPresenter.notify(title, message, () => { + this.tabPresenter.create(url); + }); + } + + releaseNoteUrl(version) { + if (version) { + return `https://github.com/ueokande/vim-vixen/releases/tag/${version}`; + } + return 'https://github.com/ueokande/vim-vixen/releases/'; + } +} diff --git a/src/background/usecases/ZoomUseCase.js b/src/background/usecases/ZoomUseCase.js deleted file mode 100644 index 692d6d9..0000000 --- a/src/background/usecases/ZoomUseCase.js +++ /dev/null @@ -1,35 +0,0 @@ -import TabPresenter from '../presenters/TabPresenter'; - -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 ZoomUseCase { - constructor() { - this.tabPresenter = new TabPresenter(); - } - - 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); - } - -} diff --git a/src/background/usecases/ZoomUseCase.ts b/src/background/usecases/ZoomUseCase.ts new file mode 100644 index 0000000..692d6d9 --- /dev/null +++ b/src/background/usecases/ZoomUseCase.ts @@ -0,0 +1,35 @@ +import TabPresenter from '../presenters/TabPresenter'; + +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 ZoomUseCase { + constructor() { + this.tabPresenter = new TabPresenter(); + } + + 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); + } + +} diff --git a/src/background/usecases/filters.js b/src/background/usecases/filters.js deleted file mode 100644 index d057dca..0000000 --- a/src/background/usecases/filters.js +++ /dev/null @@ -1,72 +0,0 @@ -const filterHttp = (items) => { - let httpsHosts = items.map(x => new URL(x.url)) - .filter(x => x.protocol === 'https:') - .map(x => x.host); - httpsHosts = new Set(httpsHosts); - - return items.filter((item) => { - let url = new URL(item.url); - return url.protocol === 'https:' || !httpsHosts.has(url.host); - }); -}; - -const filterBlankTitle = (items) => { - return items.filter(item => item.title && item.title !== ''); -}; - -const filterByTailingSlash = (items) => { - let urls = items.map(item => new URL(item.url)); - let simplePaths = urls - .filter(url => url.hash === '' && url.search === '') - .map(url => url.origin + url.pathname); - simplePaths = new Set(simplePaths); - - return items.filter((item) => { - let url = new URL(item.url); - if (url.hash !== '' || url.search !== '' || - url.pathname.slice(-1) !== '/') { - return true; - } - return !simplePaths.has(url.origin + url.pathname.slice(0, -1)); - }); -}; - -const filterByPathname = (items, min) => { - let hash = {}; - for (let item of items) { - let url = new URL(item.url); - let pathname = url.origin + url.pathname; - if (!hash[pathname]) { - hash[pathname] = item; - } else if (hash[pathname].url.length > item.url.length) { - hash[pathname] = item; - } - } - let filtered = Object.values(hash); - if (filtered.length < min) { - return items; - } - return filtered; -}; - -const filterByOrigin = (items, min) => { - let hash = {}; - for (let item of items) { - let origin = new URL(item.url).origin; - if (!hash[origin]) { - hash[origin] = item; - } else if (hash[origin].url.length > item.url.length) { - hash[origin] = item; - } - } - let filtered = Object.values(hash); - if (filtered.length < min) { - return items; - } - return filtered; -}; - -export { - filterHttp, filterBlankTitle, filterByTailingSlash, - filterByPathname, filterByOrigin -}; diff --git a/src/background/usecases/filters.ts b/src/background/usecases/filters.ts new file mode 100644 index 0000000..d057dca --- /dev/null +++ b/src/background/usecases/filters.ts @@ -0,0 +1,72 @@ +const filterHttp = (items) => { + let httpsHosts = items.map(x => new URL(x.url)) + .filter(x => x.protocol === 'https:') + .map(x => x.host); + httpsHosts = new Set(httpsHosts); + + return items.filter((item) => { + let url = new URL(item.url); + return url.protocol === 'https:' || !httpsHosts.has(url.host); + }); +}; + +const filterBlankTitle = (items) => { + return items.filter(item => item.title && item.title !== ''); +}; + +const filterByTailingSlash = (items) => { + let urls = items.map(item => new URL(item.url)); + let simplePaths = urls + .filter(url => url.hash === '' && url.search === '') + .map(url => url.origin + url.pathname); + simplePaths = new Set(simplePaths); + + return items.filter((item) => { + let url = new URL(item.url); + if (url.hash !== '' || url.search !== '' || + url.pathname.slice(-1) !== '/') { + return true; + } + return !simplePaths.has(url.origin + url.pathname.slice(0, -1)); + }); +}; + +const filterByPathname = (items, min) => { + let hash = {}; + for (let item of items) { + let url = new URL(item.url); + let pathname = url.origin + url.pathname; + if (!hash[pathname]) { + hash[pathname] = item; + } else if (hash[pathname].url.length > item.url.length) { + hash[pathname] = item; + } + } + let filtered = Object.values(hash); + if (filtered.length < min) { + return items; + } + return filtered; +}; + +const filterByOrigin = (items, min) => { + let hash = {}; + for (let item of items) { + let origin = new URL(item.url).origin; + if (!hash[origin]) { + hash[origin] = item; + } else if (hash[origin].url.length > item.url.length) { + hash[origin] = item; + } + } + let filtered = Object.values(hash); + if (filtered.length < min) { + return items; + } + return filtered; +}; + +export { + filterHttp, filterBlankTitle, filterByTailingSlash, + filterByPathname, filterByOrigin +}; diff --git a/src/background/usecases/parsers.js b/src/background/usecases/parsers.js deleted file mode 100644 index 43c8177..0000000 --- a/src/background/usecases/parsers.js +++ /dev/null @@ -1,31 +0,0 @@ -const mustNumber = (v) => { - let num = Number(v); - if (isNaN(num)) { - throw new Error('Not number: ' + v); - } - return num; -}; - -const parseSetOption = (word, types) => { - let [key, value] = word.split('='); - if (value === undefined) { - value = !key.startsWith('no'); - key = value ? key : key.slice(2); - } - let type = types[key]; - if (!type) { - throw new Error('Unknown property: ' + key); - } - if (type === 'boolean' && typeof value !== 'boolean' || - type !== 'boolean' && typeof value === 'boolean') { - throw new Error('Invalid argument: ' + word); - } - - switch (type) { - case 'string': return [key, value]; - case 'number': return [key, mustNumber(value)]; - case 'boolean': return [key, value]; - } -}; - -export { parseSetOption }; diff --git a/src/background/usecases/parsers.ts b/src/background/usecases/parsers.ts new file mode 100644 index 0000000..43c8177 --- /dev/null +++ b/src/background/usecases/parsers.ts @@ -0,0 +1,31 @@ +const mustNumber = (v) => { + let num = Number(v); + if (isNaN(num)) { + throw new Error('Not number: ' + v); + } + return num; +}; + +const parseSetOption = (word, types) => { + let [key, value] = word.split('='); + if (value === undefined) { + value = !key.startsWith('no'); + key = value ? key : key.slice(2); + } + let type = types[key]; + if (!type) { + throw new Error('Unknown property: ' + key); + } + if (type === 'boolean' && typeof value !== 'boolean' || + type !== 'boolean' && typeof value === 'boolean') { + throw new Error('Invalid argument: ' + word); + } + + switch (type) { + case 'string': return [key, value]; + case 'number': return [key, mustNumber(value)]; + case 'boolean': return [key, value]; + } +}; + +export { parseSetOption }; -- cgit v1.2.3