diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/background/commands.js | 2 | ||||
| -rw-r--r-- | src/background/index.js | 72 | ||||
| -rw-r--r-- | src/background/key-queue.js | 1 | ||||
| -rw-r--r-- | src/background/tabs.js | 49 | ||||
| -rw-r--r-- | src/background/zooms.js | 6 | ||||
| -rw-r--r-- | src/console/console-frame.js | 10 | ||||
| -rw-r--r-- | src/console/console.js | 14 | ||||
| -rw-r--r-- | src/content/index.js | 40 | ||||
| -rw-r--r-- | src/shared/actions.js | 2 | 
9 files changed, 132 insertions, 64 deletions
| diff --git a/src/background/commands.js b/src/background/commands.js deleted file mode 100644 index 8bd52e5..0000000 --- a/src/background/commands.js +++ /dev/null @@ -1,2 +0,0 @@ -export const OPEN = 'open'; -export const TABOPEN = 'tabopen'; diff --git a/src/background/index.js b/src/background/index.js index 7618384..15c8ab0 100644 --- a/src/background/index.js +++ b/src/background/index.js @@ -1,54 +1,50 @@  import * as actions from '../shared/actions';  import * as tabs from './tabs'; -import * as commands from './commands';  import * as zooms from './zooms';  import KeyQueue from './key-queue';  const queue = new KeyQueue(); -const keyPressHandle = (request, sender, sendResponse) => { +const keyPressHandle = (request, sender) => {    let action = queue.push({      code: request.code,      ctrl: request.ctrl    });    if (!action) { -    return; +    return Promise.resolve();    }    if (actions.isBackgroundAction(action[0])) { -    doBackgroundAction(sender, action); +    return doBackgroundAction(sender, action);    } else if (actions.isContentAction(action[0])) { -    sendResponse(action); +    return Promise.resolve({ +      type: 'response.action', +      action: action +    });    } +  return Promise.resolve();  };  const doBackgroundAction = (sender, action) => {    switch(action[0]) {    case actions.TABS_CLOSE: -    tabs.closeTab(sender.tab.id); -    break; +    return tabs.closeTab(sender.tab.id);    case actions.TABS_REOPEN: -    tabs.reopenTab(); -    break; +    return tabs.reopenTab();    case actions.TABS_PREV: -    tabs.selectPrevTab(sender.tab.index, actions[1] || 1); -    break; +    return tabs.selectPrevTab(sender.tab.index, actions[1] || 1);    case actions.TABS_NEXT: -    tabs.selectNextTab(sender.tab.index, actions[1] || 1); -    break; +    return tabs.selectNextTab(sender.tab.index, actions[1] || 1);    case actions.TABS_RELOAD: -    tabs.reload(sender.tab, actions[1] || false); -    break; +    return tabs.reload(sender.tab, actions[1] || false);    case actions.ZOOM_IN: -    zooms.zoomIn(); -    break; +    return zooms.zoomIn();    case actions.ZOOM_OUT: -    zooms.zoomOut(); -    break; +    return zooms.zoomOut();    case actions.ZOOM_NEUTRAL: -    zooms.neutral(); -    break; +    return zooms.neutral();    } +  return Promise.resolve();  }  const normalizeUrl = (string) => { @@ -59,28 +55,38 @@ const normalizeUrl = (string) => {    }  } +const cmdBuffer = (arg) => { +  if (isNaN(arg)) { +    return tabs.selectByKeyword(arg); +  } else { +    let index = parseInt(arg, 10) - 1; +    return tabs.selectAt(index); +  } +} +  const cmdEnterHandle = (request, sender) => {    let words = request.text.split(' ').filter((s) => s.length > 0);    switch (words[0]) { -  case commands.OPEN: -    browser.tabs.update(sender.tab.id, { url: normalizeUrl(words[1]) }); -    return; -  case commands.TABOPEN: -    browser.tabs.create({ url: normalizeUrl(words[1]) }); -    return; +  case 'open': +    return browser.tabs.update(sender.tab.id, { url: normalizeUrl(words[1]) }); +  case 'tabopen': +    return browser.tabs.create({ url: normalizeUrl(words[1]) }); +  case 'b': +  case 'buffer': +    return cmdBuffer(words[1]);    } +  throw new Error(words[0] + ' command is not defined');  }; -browser.runtime.onMessage.addListener((request, sender, sendResponse) => { +browser.runtime.onMessage.addListener((request, sender) => {    switch (request.type) {    case 'event.keypress': -    keyPressHandle(request, sender, sendResponse); -    break; +    return keyPressHandle(request, sender);    case 'event.cmd.enter': -    cmdEnterHandle(request, sender, sendResponse); -    break; +    return cmdEnterHandle(request, sender);    case 'event.cmd.suggest': -    // TODO make suggestion and return via sendResponse +    // TODO make suggestion and return      break;    } +  return Promise.resolve();  }); diff --git a/src/background/key-queue.js b/src/background/key-queue.js index 3805305..d7f0984 100644 --- a/src/background/key-queue.js +++ b/src/background/key-queue.js @@ -4,6 +4,7 @@ const DEFAULT_KEYMAP = {    ':': [ actions.CMD_OPEN ],    'o': [ actions.CMD_TABS_OPEN, false ],    'O': [ actions.CMD_TABS_OPEN, true ], +  'b': [ actions.CMD_BUFFER ],    'k': [ actions.SCROLL_LINES, -1 ],    'j': [ actions.SCROLL_LINES, 1 ],    '<C-E>': [ actions.SCROLL_LINES, -1 ], diff --git a/src/background/tabs.js b/src/background/tabs.js index 56f86eb..efecdc4 100644 --- a/src/background/tabs.js +++ b/src/background/tabs.js @@ -1,9 +1,9 @@  const closeTab = (id) => { -  browser.tabs.remove(id); +  return browser.tabs.remove(id);  };  const reopenTab = () => { -  browser.sessions.getRecentlyClosed({ +  return browser.sessions.getRecentlyClosed({      maxResults: 1    }).then((sessions) => {      if (sessions.length === 0) { @@ -11,40 +11,69 @@ const reopenTab = () => {      }      let session = sessions[0];      if (session.tab) { -      browser.sessions.restore(session.tab.sessionId); +      return browser.sessions.restore(session.tab.sessionId);      } else { -      browser.sessions.restore(session.window.sessionId); +      return browser.sessions.restore(session.window.sessionId);      }    });  }; +const selectAt = (index) => { +  return browser.tabs.query({ currentWindow: true }, (tabs) => { +    if (tabs.length < 2) { +      return; +    } +    if (index < 0 || tabs.length <= index) { +      throw new RangeError(`tab ${index} does not exist`) +    } +    let id = tabs[index].id; +    return browser.tabs.update(id, { active: true }) +  }); +}; + +const selectByKeyword = (keyword) => { +  return browser.tabs.query({ currentWindow: true }).then((tabs) => { +    let matched = tabs.filter((t) => { +      return t.url.includes(keyword) || t.title.includes(keyword) +    }) + +    if (matched.length == 0) { +      throw new RangeError('No matching buffer for ' + keyword); +    } else if (matched.length >= 2) { +      throw new RangeError('More than one match for ' + keyword); +    } + +    return browser.tabs.update(matched[0].id, { active: true }); +  }); +} +  const selectPrevTab = (current, count) => { -  chrome.tabs.query({ currentWindow: true }, (tabs) => { +  return browser.tabs.query({ currentWindow: true }, (tabs) => {      if (tabs.length < 2) {        return;      }      let select = (current - count) % tabs.length      let id = tabs[select].id; -    chrome.tabs.update(id, { active: true }) +    return browser.tabs.update(id, { active: true })    });  };  const selectNextTab = (current, count) => { -  chrome.tabs.query({ currentWindow: true }, (tabs) => { +  return browser.tabs.query({ currentWindow: true }, (tabs) => {      if (tabs.length < 2) {        return;      }      let select = (current + count + tabs.length) % tabs.length      let id = tabs[select].id; -    chrome.tabs.update(id, { active: true }) +    return browser.tabs.update(id, { active: true })    });  };  const reload = (current, cache) => { -  browser.tabs.reload( +  return browser.tabs.reload(      current.id,      { bypassCache: cache }    );  }; -export { closeTab, reopenTab, selectNextTab, selectPrevTab, reload }; +export { closeTab, reopenTab, selectAt, selectByKeyword, selectNextTab, selectPrevTab, reload }; diff --git a/src/background/zooms.js b/src/background/zooms.js index bb65030..e3e2aa6 100644 --- a/src/background/zooms.js +++ b/src/background/zooms.js @@ -10,7 +10,7 @@ const ZOOM_SETTINGS = [  ];  const zoomIn = (tabId = undefined) => { -  browser.tabs.getZoom(tabId).then((factor) => { +  return browser.tabs.getZoom(tabId).then((factor) => {      for (let f of ZOOM_SETTINGS) {        if (f > factor) {          browser.tabs.setZoom(tabId, f); @@ -21,7 +21,7 @@ const zoomIn = (tabId = undefined) => {  };  const zoomOut = (tabId = undefined) => { -  browser.tabs.getZoom(tabId).then((factor) => { +  return browser.tabs.getZoom(tabId).then((factor) => {      for (let f of [].concat(ZOOM_SETTINGS).reverse()) {        if (f < factor) {          browser.tabs.setZoom(tabId, f); @@ -32,7 +32,7 @@ const zoomOut = (tabId = undefined) => {  };  const neutral = (tabId = undefined) => { -  browser.tabs.setZoom(tabId, 1); +  return browser.tabs.setZoom(tabId, 1);  };  export { zoomIn, zoomOut, neutral }; diff --git a/src/console/console-frame.js b/src/console/console-frame.js index aabb96a..ea9f523 100644 --- a/src/console/console-frame.js +++ b/src/console/console-frame.js @@ -10,6 +10,8 @@ export default class ConsoleFrame {      this.element = element; +    this.errorShown = true; +      this.hide();    } @@ -21,6 +23,7 @@ export default class ConsoleFrame {        text: text      };      messages.send(this.element.contentWindow, message); +    this.errorShown = false;    }    showError(text) { @@ -31,6 +34,8 @@ export default class ConsoleFrame {        text: text      };      messages.send(this.element.contentWindow, message); +    this.errorShown = true; +    this.element.blur();    }    showFrame() { @@ -40,5 +45,10 @@ export default class ConsoleFrame {    hide() {      this.element.style.display = 'none';      this.element.blur(); +    this.errorShown = false; +  } + +  isErrorShown() { +    return this.element.style.display === 'block' && this.errorShown;    }  } diff --git a/src/console/console.js b/src/console/console.js index a171ecc..e0227aa 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -8,20 +8,20 @@ var prevValue = "";  const blurMessage = () => {    return { -    type: 'vimvixen.commandline.blur' +    type: 'vimvixen.command.blur'    };  };  const keydownMessage = (input) => {    return { -    type: 'vimvixen.commandline.enter', +    type: 'vimvixen.command.enter',      value: input.value    };  };  const keyupMessage = (input) => {    return { -    type: 'vimvixen.commandline.change', +    type: 'vimvixen.command.change',      value: input.value    };  }; @@ -57,15 +57,15 @@ window.addEventListener('load', () => {  });  const showCommand = (text) => { -  let input = window.document.querySelector('#vimvixen-console-command-input'); -  input.value = text; -  input.focus(); -    let command = window.document.querySelector('#vimvixen-console-command');    command.style.display = 'block';    let error = window.document.querySelector('#vimvixen-console-error');    error.style.display = 'none'; + +  let input = window.document.querySelector('#vimvixen-console-command-input'); +  input.value = text; +  input.focus();  }  const showError = (text) => { diff --git a/src/content/index.js b/src/content/index.js index 66b1121..8b3eb58 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -7,7 +7,7 @@ import Follow from './follow';  let vvConsole = new ConsoleFrame(window); -const invokeEvent = (action) => { +const doAction = (action) => {    if (typeof action === 'undefined' || action === null) {      return;    } @@ -24,6 +24,9 @@ const invokeEvent = (action) => {        vvConsole.showCommand('open ');      }      break; +  case actions.CMD_BUFFER: +    vvConsole.showCommand('buffer '); +    break;    case actions.SCROLL_LINES:      scrolls.scrollLines(window, action[1]);      break; @@ -54,6 +57,18 @@ const invokeEvent = (action) => {    }  } +const handleResponse = (response) => { +  if (!response) { +    return; +  } + +  switch(response.type) { +  case 'response.action': +    doAction(response.action); +    break; +  } +}; +  window.addEventListener("keypress", (e) => {    if (e.target instanceof HTMLInputElement) {      return; @@ -66,27 +81,34 @@ window.addEventListener("keypress", (e) => {    }    browser.runtime.sendMessage(request) -    .then(invokeEvent, -      (err) => { -        console.log(`Vim Vixen: ${err}`); -      }); +    .then(handleResponse) +    .catch((err) => { +      vvConsole.showError(err.message); +      console.log(`Vim Vixen: ${err}`); +    });  });  messages.receive(window, (message) => {    switch (message.type) { -  case 'vimvixen.commandline.blur': -    vvConsole.hide(); +  case 'vimvixen.command.blur': +    if (!vvConsole.isErrorShown()) { +      vvConsole.hide(); +    }      break; -  case 'vimvixen.commandline.enter': +  case 'vimvixen.command.enter':      browser.runtime.sendMessage({        type: 'event.cmd.enter',        text: message.value +    }).catch((e) => { +      vvConsole.showError(e.message);      });      break; -  case 'vimvixen.commandline.change': +  case 'vimvixen.command.change':      browser.runtime.sendMessage({        type: 'event.cmd.suggest',        text: message.value +    }).catch((e) => { +      vvConsole.showError(e.message);      });      break;    default: diff --git a/src/shared/actions.js b/src/shared/actions.js index cd740c2..7151dd1 100644 --- a/src/shared/actions.js +++ b/src/shared/actions.js @@ -1,5 +1,6 @@  export const CMD_OPEN = 'cmd.open';  export const CMD_TABS_OPEN = 'cmd.tabs.open'; +export const CMD_BUFFER = 'cmd.buffer';  export const TABS_CLOSE = 'tabs.close';  export const TABS_REOPEN = 'tabs.reopen';  export const TABS_PREV = 'tabs.prev'; @@ -32,6 +33,7 @@ const BACKGROUND_ACTION_SET = new Set([  const CONTENT_ACTION_SET = new Set([    CMD_OPEN,    CMD_TABS_OPEN, +  CMD_BUFFER,    SCROLL_LINES,    SCROLL_PAGES,    SCROLL_TOP, | 
