---
title: 'Microsoft edgeの拡張機能を作ってみる'
url: 'https://automationse.net/creating-microsoft-edge-extension'
markdown: 'https://automationse.net/creating-microsoft-edge-extension.md'
date: '2024-01-31'
description: 'Microsoft Edgeの拡張機能を作成するには、まず基本的な構成ファイル（manifest.json）を準備し、JavaScriptを使用して拡張機能のロジックを記述する必要があります。ここでは、設定ページで指定した文字列を含むURLを検索結果から除外する拡張機能の基本的なアイデアとサンプルコードを提供します。 Step 1: manifest.…'
taxonomy:
  category:
    - IT関連
  tag:
    - アプリ
---

# Microsoft edgeの拡張機能を作ってみる

## [Microsoft edgeの拡張機能を作ってみる](https://automationse.net/creating-microsoft-edge-extension)

  公開日 2024.01.31 更新日 2024.01.31  [アプリ](https://automationse.net/tag:%E3%82%A2%E3%83%97%E3%83%AA#body-wrapper)  

 Microsoft Edgeの拡張機能を作成するには、まず基本的な構成ファイル（`manifest.json`）を準備し、JavaScriptを使用して拡張機能のロジックを記述する必要があります。ここでは、設定ページで指定した文字列を含むURLを検索結果から除外する拡張機能の基本的なアイデアとサンプルコードを提供します。

### Step 1: `manifest.json`を作成する

```
{
  "manifest_version": 3,
  "name": "URL Blocker",
  "version": "1.0",
  "description": "Block specified URLs from search results",
  "permissions": ["storage", "activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "images/icon16.png",
      "48": "images/icon48.png",
      "128": "images/icon128.png"
    }
  },
  "options_page": "options.html",
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["*://*.google.com/*", "*://*.bing.com/*", "*://*.yahoo.com/*"],
      "js": ["content.js"]
    }
  ]
}
```

### Step 2: `content.js`を作成する

```
chrome.storage.sync.get('blockedUrls', function(data) {
    const blockedUrls = data.blockedUrls || [];

    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            if (mutation.addedNodes.length) {
                filterSearchResults();
            }
        });
    });

    const config = { childList: true, subtree: true };
    observer.observe(document.body, config);

    function filterSearchResults() {
        // 現在のURLを取得
        const currentUrl = window.location.href;

        // Google、Bing、YahooのURLに基づいて処理を分岐
        if (currentUrl.includes("google.com")) {
            blockLinksOnGoogle();
        } else if (currentUrl.includes("bing.com")) {
            blockLinksOnBing();
        } else if (currentUrl.includes("yahoo.com")) {
            blockLinksOnYahoo();
        }
    }

    function blockLinksOnGoogle() {
        document.querySelectorAll('a').forEach(link => {
            blockedUrls.forEach(blockedUrl => {
                if (link.href.includes(blockedUrl)) {
                    let element = link.closest('.g');
                    if (element) {
                        element.style.display = 'none';
                    }
                }
            });
        });
        // 要素をすべて選択
        var elementsG = document.getElementsByClassName('uVMCKf');
        // 取得した要素をループして非表示にする
        for (var i = 0; i < elementsG.length; i++) {
            elementsG[i].style.display = 'none';
        }
    }

    function blockLinksOnBing() {
        document.querySelectorAll('a').forEach(elem => {
            elem.querySelectorAll('cite').forEach(link => {
                blockedUrls.forEach(blockedUrl => {
                    if (link.textContent.includes(blockedUrl)) {
                        elem.style.display = 'none';
                    }
                });
            });
        });
    }

    function blockLinksOnYahoo() {
        // Yahoo検索結果に対する処理（必要に応じて追加）
    }

    // 初期ロード時にもフィルターを適用
    filterSearchResults();
});
```

上記のコードでは、Googleの検索結果を対象としていますが、他の検索エンジンについては、適切なセレクターに変更する必要があります。

### Step 3: `background.js`の作成（オプション）

拡張機能のバックグラウンドスクリプトです。この例では特に必要な機能は実装していませんが、将来的な機能拡張や設定の保存などに利用できます。

### Step 4: アイコンとポップアップ（オプション）

```

<html>
<head>
  <title>拡張機能のポップアップ</title>

<!-- Google Tag Manager (managed by Grav Google Tools) -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer',"GTM-T7C4GV5");</script>
<meta name="google-adsense-account" content="ca-pub-8538204815849426">
<!-- Google AdSense (managed by Grav Google Tools) --><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8538204815849426" crossorigin="anonymous"></script>
</head>
<body>
<!-- Google Tag Manager (noscript) --><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-T7C4GV5" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <h1>URL Blocker</h1>
  <p>オプションページでURLを設定してください。</p>

<!-- Conversion events (managed by Grav Google Tools) -->
<script>
(function(cfg){
  function emit(name, params){
    params = params || {};
    if (cfg.mode === 'direct') {
      if (typeof window.gtag === 'function') window.gtag('event', name, params);
      return;
    }
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push(Object.assign({event: name}, params));
  }
  function textOf(el){ return ((el && el.textContent) || '').trim().slice(0, 120); }

  var path = window.location.pathname || '/';
  (cfg.events.paths || []).forEach(function(rule){
    var matched = rule.match === 'exact' ? path === rule.path :
      rule.match === 'prefix' ? path.indexOf(rule.path) === 0 : path.indexOf(rule.path) !== -1;
    if (!matched) return;
    var params = {page_path: path};
    if (rule.send_to) params.send_to = rule.send_to;
    emit(rule.event_name, params);
  });

  document.addEventListener('click', function(ev){
    var target = ev.target && ev.target.closest ? ev.target : null;
    if (!target) return;

    (cfg.events.clicks || []).forEach(function(rule){
      try {
        var matched = target.closest(rule.selector);
        if (!matched) return;
        var params = {element_text: textOf(matched)};
        if (matched.href) params.link_url = matched.href;
        if (rule.send_to) params.send_to = rule.send_to;
        if (typeof rule.value === 'number') params.value = rule.value;
        if (rule.currency) params.currency = rule.currency;
        emit(rule.event_name, params);
      } catch (e) {}
    });

    var link = target.closest('a[href]');
    if (!link) return;
    var url;
    try { url = new URL(link.href || '', window.location.href); } catch (e) { return; }

    if (cfg.events.download && cfg.events.download.enabled) {
      var pathname = (url.pathname || '').toLowerCase();
      var ext = pathname.indexOf('.') !== -1 ? pathname.split('.').pop() : '';
      if ((cfg.events.download.extensions || []).indexOf(ext) !== -1) {
        emit(cfg.events.download.event_name, {link_url: url.href, link_text: textOf(link), file_extension: ext});
      }
    }

    if (cfg.events.outbound && cfg.events.outbound.enabled && /^https?:$/.test(url.protocol) && url.hostname !== window.location.hostname) {
      emit(cfg.events.outbound.event_name, {link_url: url.href, link_domain: url.hostname, link_text: textOf(link)});
    }
  }, true);
})({"mode":"gtm","events":{"download":{"enabled":true,"event_name":"file_download","extensions":["apk","zip","pdf","doc","docx","xls","xlsx","ppt","pptx"]},"outbound":{"enabled":true,"event_name":"outbound_click"},"clicks":[],"paths":[]}});
</script>
</body>
</html>
```

拡張機能のアイコン(`icon.png`)とポップアップ用のHTML(`popup.html`)を追加します。これらはユーザーが拡張機能を操作するためのUIを提供します。

### Step 4: 設定ページを作成（オプション）

今回は設定ページにCSVファイルを読み込ませてデータを追加、もしくは手動でデータを追加し、設定ページのローカルストレージにデータを保存する仕組みを作成しました。

```

<html>
<head>
    <title>拡張機能の設定</title>
</head>
<body>
    <h1>設定</h1>
    <input type="file" id="fileInput" accept=".csv">
    <button id="importCsv">CSVからインポート</button>

    <form id="urlForm">
        <input type="text" id="newUrl" placeholder="URLを追加">
        <button type="submit">追加</button>
    </form>
    <table id="urlTable">
        <thead>
            <tr>
                <th>URL</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <!-- URLリストがここに表示される -->
        </tbody>
    </table>

    <button id="exportCsv">CSVでエクスポート</button>
    <script src="options.js"></script>
</body>
</html>
```

```
document.getElementById('urlForm').addEventListener('submit', function(e) {
    e.preventDefault();
    var newUrl = document.getElementById('newUrl').value;
    if (newUrl) {
        addUrlToTable(newUrl);
        saveUrls();
    }
});

function addUrlToTable(url) {
    var table = document.getElementById('urlTable').getElementsByTagName('tbody')[0];
    var row = table.insertRow();
    var urlCell = row.insertCell(0);
    var deleteCell = row.insertCell(1);

    urlCell.textContent = url;
    var deleteButton = document.createElement('button');
    deleteButton.textContent = '削除';
    deleteButton.addEventListener('click', function() {
        row.remove();
        saveUrls();
    });
    deleteCell.appendChild(deleteButton);
}

function saveUrls() {
    var urls = [];
    var table = document.getElementById('urlTable').getElementsByTagName('tbody')[0];
    Array.from(table.rows).forEach(row => {
        urls.push(row.cells[0].textContent);
    });
    chrome.storage.sync.set({ 'blockedUrls': urls });
}

// ページロード時に保存されたURLをテーブルに表示
document.addEventListener('DOMContentLoaded', function() {
    chrome.storage.sync.get('blockedUrls', function(data) {
        if (data.blockedUrls) {
            data.blockedUrls.forEach(url => addUrlToTable(url));
        }
    });
});

// options.js

document.getElementById('exportCsv').addEventListener('click', function() {
    // ストレージからデータを取得
    chrome.storage.sync.get('blockedUrls', function(data) {
        const blockedUrls = data.blockedUrls || [];

        // CSV形式に変換
        let csvContent = "data:text/csv;charset=utf-8,";
        blockedUrls.forEach(function(row) {
            csvContent += row + "rn";
        });

        // Blobを作成し、ダウンロードリンクを生成
        var encodedUri = encodeURI(csvContent);
        var link = document.createElement("a");
        link.setAttribute("href", encodedUri);
        link.setAttribute("download", "blocked_urls.csv");
        document.body.appendChild(link); // Firefoxで動作するために必要

        // リンクをクリックしてダウンロード
        link.click();
        document.body.removeChild(link); // リンクを削除
    });
});

// options.js

document.getElementById('importCsv').addEventListener('click', function() {
    var fileInput = document.getElementById('fileInput');
    var file = fileInput.files[0];
    var reader = new FileReader();

    reader.onload = function(e) {
        var text = e.target.result;
        var rows = text.split("n");

        var urls = rows.map(function(row) {
            return row.trim();
        });

        // 空の行を削除
        urls = urls.filter(function(url) {
            return url.length > 0;
        });

        // ストレージに保存
        chrome.storage.sync.set({ 'blockedUrls': urls }, function() {
            console.log('URLs are imported!');
            // データが保存された後、ページをリロードする
            window.location.reload();
        });
    };

    reader.readAsText(file);
});
```

### Step 5: 拡張機能のテスト

- Edgeブラウザで`edge://extensions/`にアクセスします。
- 右上の「デベロッパーモード」を有効にします。
- 「展開してパッケージ化されていない拡張機能を読み込む」をクリックし、拡張機能のフォルダを選択します。

これで、指定した条件に基づいて検索結果が除外されるはずです。検索結果の構造は検索エンジンによって異なるため、各検索エンジンのDOM構造に合わせて`content.js`のセレクターを調整する必要があります。

 [ Previous Post](https://automationse.net/powershell-file-monitoring-notification-system) [Next Post ](https://automationse.net/powershell-multi-file-monitoring-script-explanation)

---

## Navigation

- Parent: [WordPress Import](https://automationse.net/wordpress-import.md)
- Previous: [PowerShellによる複数ファイルの監視スクリプトの解説](https://automationse.net/powershell-multi-file-monitoring-script-explanation.md)
- Next: [PowerShellを活用したファイル監視と通知システムの構築](https://automationse.net/powershell-file-monitoring-notification-system.md)
