diff options
| -rw-r--r-- | src/background/presenters/tab.js | 37 | ||||
| -rw-r--r-- | src/background/usecases/command.js | 18 | ||||
| -rw-r--r-- | src/background/usecases/completions.js | 46 | ||||
| -rw-r--r-- | src/background/usecases/operation.js | 18 | ||||
| -rw-r--r-- | src/console/site.scss | 2 | 
5 files changed, 88 insertions, 33 deletions
| diff --git a/src/background/presenters/tab.js b/src/background/presenters/tab.js index 2a06a5a..bacb644 100644 --- a/src/background/presenters/tab.js +++ b/src/background/presenters/tab.js @@ -1,3 +1,8 @@ +import MemoryStorage from '../infrastructures/memory-storage'; + +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 }); @@ -18,6 +23,15 @@ export default class TabPresenter {      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) => { @@ -32,18 +46,6 @@ export default class TabPresenter {      return browser.tabs.update(tabId, { active: true });    } -  async selectAt(index) { -    let tabs = await browser.tabs.query({ currentWindow: true }); -    if (tabs.length < 2) { -      return; -    } -    if (index < 0 || tabs.length <= index) { -      throw new RangeError(`tab ${index + 1} does not exist`); -    } -    let id = tabs[index].id; -    return browser.tabs.update(id, { active: true }); -  } -    remove(ids) {      return browser.tabs.remove(ids);    } @@ -99,3 +101,14 @@ export default class TabPresenter {      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/usecases/command.js b/src/background/usecases/command.js index 7fd2e57..f6ade43 100644 --- a/src/background/usecases/command.js +++ b/src/background/usecases/command.js @@ -34,13 +34,29 @@ export default class CommandIndicator {      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; -      return tabs.selectAt(index); +      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(); diff --git a/src/background/usecases/completions.js b/src/background/usecases/completions.js index 2bf5b3b..af7aaf2 100644 --- a/src/background/usecases/completions.js +++ b/src/background/usecases/completions.js @@ -5,12 +5,14 @@ import CommandDocs from '../domains/command-docs';  import CompletionRepository from '../repositories/completions';  import * as filters from './filters';  import SettingRepository from '../repositories/setting'; +import TabPresenter from '../presenters/tab';  import * as properties from '../../shared/settings/properties';  const COMPLETION_ITEM_LIMIT = 10;  export default class CompletionsInteractor {    constructor() { +    this.tabPresenter = new TabPresenter();      this.completionRepository = new CompletionRepository();      this.settingRepository = new SettingRepository();    } @@ -50,8 +52,48 @@ export default class CompletionsInteractor {      return new Completions(groups);    } -  queryBuffer(name, keywords) { -    return this.queryTabs(name, false, keywords); +  // 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.completionRepository.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) { diff --git a/src/background/usecases/operation.js b/src/background/usecases/operation.js index 7bf93e4..74ea830 100644 --- a/src/background/usecases/operation.js +++ b/src/background/usecases/operation.js @@ -1,10 +1,6 @@ -import MemoryStorage from '../infrastructures/memory-storage';  import TabPresenter from '../presenters/tab';  import ConsolePresenter from '../presenters/console'; -const CURRENT_SELECTED_KEY = 'tabs.current.selected'; -const LAST_SELECTED_KEY = 'tabs.last.selected'; -  const ZOOM_SETTINGS = [    0.33, 0.50, 0.66, 0.75, 0.80, 0.90, 1.00,    1.10, 1.25, 1.50, 1.75, 2.00, 2.50, 3.00 @@ -13,11 +9,7 @@ const ZOOM_SETTINGS = [  export default class OperationInteractor {    constructor() {      this.tabPresenter = new TabPresenter(); -    this.tabPresenter.onSelected(info => this.onTabSelected(info.tabId)); -      this.consolePresenter = new ConsolePresenter(); - -    this.cache = new MemoryStorage();    }    async close(force) { @@ -69,7 +61,7 @@ export default class OperationInteractor {    }    async selectPrevSelected() { -    let tabId = await this.cache.get(LAST_SELECTED_KEY); +    let tabId = await this.tabPresenter.getLastSelectedId();      if (tabId === null || typeof tabId === 'undefined') {        return;      } @@ -180,13 +172,5 @@ export default class OperationInteractor {      let tab = await this.tabPresenter.getCurrent();      return this.consolePresenter.hide(tab.id);    } - -  onTabSelected(tabId) { -    let lastId = this.cache.get(CURRENT_SELECTED_KEY); -    if (lastId) { -      this.cache.set(LAST_SELECTED_KEY, lastId); -    } -    this.cache.set(CURRENT_SELECTED_KEY, tabId); -  }  } diff --git a/src/console/site.scss b/src/console/site.scss index cb89e50..b9b1016 100644 --- a/src/console/site.scss +++ b/src/console/site.scss @@ -44,7 +44,7 @@ body {        background-position: 0 center;        background-size: contain;        background-repeat: no-repeat; -      white-space: nowrap; +      white-space: pre;        &.vimvixen-completion-selected {          background-color: yellow; | 
