文件目录

image

  1. icon.png 在谷歌状态栏显示的图标
  2. manifest.json 关于插件的一些配置文件
  3. popup.html 点击插件图标后显示内容 和标准的html结构也一致
  4. popup.js 页面的事件

manifest.json

{
  "manifest_version": 2,
  "name": "Getting started example",
  "description": "This extension allows the user to change the background color of the current page.",
  "version": "1.0",

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html",
    "default_title": "点击他!"
  },
  "permissions": [
    "activeTab",
    "storage"
  ]
}

每一个扩展都有一个manifest.json文件,里面配置了关于插件的一些信息。

{
  // 必须的字段
  "manifest_version": 2,
  "name": "My Extension",
  "version": "versionString",

  // 建议提供的字段
  "default_locale": "en",
  "description": "A plain text description",
  "icons": {...},

  // 多选一,或者都不提供
  "browser_action": {...},
  "page_action": {...},

  // 根据需要提供
  "action": ...,
  "author": ...,
  "automation": ...,
  "background": {
    // Recommended
    "persistent": false
  },
  "background_page": ...,
  "chrome_settings_overrides": {...},
  "chrome_ui_overrides": {
    "bookmarks_ui": {
      "remove_bookmark_shortcut": true,
      "remove_button": true
    }
  },
  "chrome_url_overrides": {...},
  "commands": {...},
  "content_capabilities": ...,
  "content_scripts": [{...}],
  "content_security_policy": "policyString",
  "converted_from_user_script": ...,
  "current_locale": ...,
  "declarative_net_request": ...,
  "devtools_page": "devtools.html",
  "event_rules": [{...}],
  "externally_connectable": {
    "matches": ["*://*.example.com/*"]
  },
  "file_browser_handlers": [...],
  "file_system_provider_capabilities": {
    "configurable": true,
    "multiple_mounts": true,
    "source": "network"
  },
  "homepage_url": "http://path/to/homepage",
  "import": [{"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}],
  "incognito": "spanning, split, or not_allowed",
  "input_components": ...,
  "key": "publicKey",
  "minimum_chrome_version": "versionString",
  "nacl_modules": [...],
  "oauth2": ...,
  "offline_enabled": true,
  "omnibox": {
    "keyword": "aString"
  },
  "optional_permissions": ["tabs"],
  "options_page": "options.html",
  "options_ui": {
    "chrome_style": true,
    "page": "options.html"
  },
  "permissions": ["tabs"],
  "platforms": ...,
  "requirements": {...},
  "sandbox": [...],
  "short_name": "Short Name",
  "signature": ...,
  "spellcheck": ...,
  "storage": {
    "managed_schema": "schema.json"
  },
  "system_indicator": ...,
  "tts_engine": {...},
  "update_url": "http://path/to/updateInfo.xml",
  "version_name": "aString",
  "web_accessible_resources": [...]
}

具体含义解析
中文
英文原版(需要科学上网)

popup.html

<!doctype html>
<!--
这个页面展示了当扩展按钮被点击后展示的页面,在 manifest.json 中需要配置
 -->
<html>
<head>
    <meta charset="UTF-8">
    <title>改变背景</title>
    <style type="text/css">
        body {
            margin: 10px;
            white-space: nowrap;
        }

        h1 {
            font-size: 15px;
        }

        #container {
            align-items: center;
            display: flex;
            justify-content: space-between;
        }
    </style>

    <!--
      - JavaScript和HTML必须放在单独的文件中。
      - 可以通过下面的链接查看解释(需科学访问)
      -
      - [1]: https://developer.chrome.com/extensions/contentSecurityPolicy
    -->
    <script src="popup.js"></script>
</head>

<body>
    <h1>背景颜色更改</h1>
    <div id="container">
        <span>选择一个你喜欢的颜色</span>
        <select id="dropdown">
            <option selected disabled hidden value=''></option>
            <option value="white">White</option>
            <option value="pink">Pink</option>
            <option value="green">Green</option>
            <option value="yellow">Yellow</option>
        </select>
    </div>
</body>
</html>

popup.js

/**
 * 获取URL
 */
function getCurrentTabUrl(callback) {
  // queryInfo就是随query的一个配置
  let queryInfo = {
    active: true,
    currentWindow: true
  };

  chrome.tabs.query(queryInfo, (tabs) => {
    //原文这里的大致意思就是 只要能点击这个按钮 肯定是存在一个tab 所有tabs不会为空。
    let tab = tabs[0];

    // tab包含的选项卡的一些信息。
    // See https://developer.chrome.com/extensions/tabs#type-Tab
    let url = tab.url;
    console.assert(typeof url === 'string', 'tab.url should be a string');
    callback(url);
  });

  //大多数的chrome API 都是异步的  所以不能向下面这样写
  // let url;
  // chrome.tabs.query(queryInfo, (tabs) => {
  //   url = tabs[0].url;
  // });
  // alert(url); // Shows "undefined", because chrome.tabs.query is async.
}

/**
 *改变当前页面的背景颜色。
 *
 * @param {string} color The new background color.
 */
function changeBackgroundColor(color) {
  let script = 'document.body.style.backgroundColor="' + color + '";';
  // See https://developer.chrome.com/extensions/tabs#method-executeScript.
  // 向页面注入JavaScript代码.
  chrome.tabs.executeScript({
    code: script
  });
}

/**
 * 取出保存的页面背景颜色 如果用户曾经用插件改变过这个页面的背景颜色。
 *
 * @param {string} url URL whose background color is to be retrieved.
 * @param {function(string)} callback called with the saved background color for
 *     the given url on success, or a falsy value if no color is retrieved.
 */
function getSavedBackgroundColor(url, callback) {
  // See https://developer.chrome.com/apps/storage#type-StorageArea. We check
  // for chrome.runtime.lastError to ensure correctness even when the API call
  // fails.
  chrome.storage.sync.get(url, (items) => {
    callback(chrome.runtime.lastError ? null : items[url]);
  });
}

/**
 * 用来保存用户选择的背景颜色的函数
 *
 * @param {string} url URL for which background color is to be saved.
 * @param {string} color The background color to be saved.
 */
function saveBackgroundColor(url, color) {
  let items = {};
  items[url] = color;
  // See https://developer.chrome.com/apps/storage#type-StorageArea. We omit the
  // optional callback since we don't need to perform any action once the
  // background color is saved.
  chrome.storage.sync.set(items);
}

// 插件会先加载用户上次选择的颜色,如果存在的话。

document.addEventListener('DOMContentLoaded', () => {
  getCurrentTabUrl((url) => {
    let dropdown = document.getElementById('dropdown');

    // Load the saved background color for this page and modify the dropdown
    // value, if needed.
    getSavedBackgroundColor(url, (savedColor) => {
      if (savedColor) {
        changeBackgroundColor(savedColor);
        dropdown.value = savedColor;
      }
    });

    // 用户选择新的颜色  保存。
    dropdown.addEventListener('change', () => {
      changeBackgroundColor(dropdown.value);
      saveBackgroundColor(url, dropdown.value);
    });
  });
});