Advertisement
miozn

WebExtensionsで「選択範囲のリンクを新しいタブで開く」

Jan 8th, 2018
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // common --------------------------------------------------------------------
  2.  
  3. const MenuItem = {
  4.     'MENU_OPEN_SELECTED_LINKS': 'menu.openSelectedLinks'
  5. };
  6.  
  7. const Request = {
  8.     'REQUEST_GET_SELECTED_LINKS': 'request.getSelectedLinks',
  9.     'REQUEST_OPEN_LINKS_IN_NEW_TAB': 'request.openLinksInNewTab'
  10. };
  11.  
  12. // background ----------------------------------------------------------------
  13.  
  14. class TabManager {
  15.     // ⑤URLを指定して新しいタブを開く
  16.     static async openNewUrls(urls) {
  17.         for (const url of urls) {
  18.             await browser.tabs.create({
  19.                 'active': false,
  20.                 'url': url
  21.             });
  22.         }
  23.     }
  24. }
  25.  
  26. // ①コンテキストメニュー生成
  27. browser.menus.create({
  28.     'id': MenuItem.MENU_OPEN_SELECTED_LINKS,
  29.     'type': 'normal',
  30.     'contexts': ['selection'],
  31.     'title': "選択範囲のリンクを新しいタブで開く"
  32. });
  33.  
  34. // ②コンテキストメニュー項目クリックイベントハンドラ
  35. browser.menus.onClicked.addListener((info, tab) => {
  36.     switch (info.menuItemId) {
  37.         case MenuItem.MENU_OPEN_SELECTED_LINKS:
  38.             // content(タブ)に選択範囲のリンクを取得させる
  39.             browser.tabs.sendMessage(tab.id, {
  40.                 'type': 'request',
  41.                 'subtype': Request.REQUEST_GET_SELECTED_LINKS,
  42.                 'param': null
  43.             });
  44.             break;
  45.     }
  46. });
  47.  
  48. // ④メッセージ受信イベントハンドラ
  49. browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
  50.     if (request.type === 'request') {
  51.         if (request.subtype === Request.REQUEST_OPEN_LINKS_IN_NEW_TAB) {
  52.             // URLをタブを開く
  53.             TabManager.openNewUrls(request.param.urls);
  54.         }
  55.  
  56.         return;
  57.     }
  58. });
  59.  
  60. // content -------------------------------------------------------------------
  61.  
  62. // ③メッセージ受信イベントハンドラ
  63. browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
  64.     if (request.type === 'request') {
  65.         if (request.subtype === Request.REQUEST_GET_SELECTED_LINKS) {
  66.             // 選択範囲のリンクからURLを収集
  67.             const urls = [];
  68.             const sel = window.getSelection();
  69.             for (let i=0; i<sel.rangeCount; i++) {
  70.                 sel.getRangeAt(i).cloneContents().querySelectorAll('a').forEach(node => {
  71.                     urls.push(node.href);
  72.                 });
  73.             }
  74.  
  75.             // URLがあった場合はbackgroundにタブを開かせる
  76.             if (urls.length !== 0) {
  77.                 browser.runtime.sendMessage({
  78.                     'type': 'request',
  79.                     'subtype': Request.REQUEST_OPEN_LINKS_IN_NEW_TAB,
  80.                     'param': {
  81.                         'urls': urls
  82.                     }
  83.                 });
  84.             }
  85.         }
  86.  
  87.         return;
  88.     }
  89. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement