https://developer.chrome.com/extensions/overview

# 0X00 chrome extension基础

chrome插件本质就是一堆HTML,CSS,JavaScript和一些配置文件的集合,可以拓展用户的浏览器体验

chrome://extensions

  • Manifest

Json格式的文件,声明基本的版本,权限,图标,browser action或page action,background脚本

{
    "name": "Getting Started Example",
    "version": "1.0",
    "description": "Build an Extension!",
    "permissions": ["activeTab", "declarativeContent", "storage"],
    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },
    "page_action": {
        "default_popup": "popup.html",
        "default_icon": {
            "16": "images/get_started16.png",
            "32": "images/get_started32.png",
            "48": "images/get_started48.png",
            "128": "images/get_started128.png"
        }
    },
    "icons": {
        "16": "images/get_started16.png",
        "32": "images/get_started32.png",
        "48": "images/get_started48.png",
        "128": "images/get_started128.png"
    },
    "options_page": "options.html",
    "manifest_version": 2
  }
  • Background Script

插件的事件处理器,基本包括browser listener,比如插件安装事件,页面变化事件,快捷键监听事件

background.js:
chrome.runtime.onInstalled.addListener(function() {
  chrome.storage.sync.set({color: '#3aa757'}, function() {
    console.log("The color is green.");
  });
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    chrome.declarativeContent.onPageChanged.addRules([{
      conditions: [new chrome.declarativeContent.PageStateMatcher({
        pageUrl: {hostEquals: 'developer.chrome.com'},
      })
      ],
          actions: [new chrome.declarativeContent.ShowPageAction()]
    }]);
  });
});
  • UI Elements

插件的用户界面,通常插件都有browser action或page action,不过也可以有其他形式的用户界面,比如context menu菜单,omnibox,甚至可以没有用户界面,比如只用快捷键keyboard shortcut; 通常默认界面我们叫popup.html,一般包含普通的html,插件也可以调用tabs.create或window.open()显示额外的更丰富的用户界面; 默认我们是在manifest里面通过browser action或page action定义好popup.html,除此之外,我们还允许通过 chrome.declarativeContent API来做更多自定义rules控制

popup.html:
<body>
    <button id="changeColor"></button>
    <script src="popup.js"></script>
  </body>
  • Content Script

插件读写操作web页面dom就是利用这个content script,这个脚本就是将javascript装载到web页面的上下文中运行,可见content script和上面的其他script上下文是不同的,他们可以交互吗?可以,就是通过chrome.storage API

popup.js
chrome.tabs.executeScript(targetTabID, {
      file: '/scripts/content_script.js',
      allFrames: true
    });
  • Option Page

这个是额外选项,默认安装的extension只有一个background的view可以inpsect,这个是额外的选项可以让用户直接做相应的设置,比如让用户选择需要的功能,这个需要在manifest中定义好options_page; 当然从前面的popup页面中也可以设置,只不过这里提供了另外一种方式;

还需要注意chromeAPI基本都是异步的,所以如果你的代码逻辑有依赖,需要放到callback里面

# 0X01 我遇到的问题

首先我想加入一个快捷键功能,不用鼠标点来点去,很简单,manifest加入 "commands": { "your-command-name": { "suggested_key": { "default": "Ctrl+X"

  },
  "description": ""

}

}, 然后background.js: chrome.commands.onCommand.addListener(function(command) { if(command === "your-command-name") { //to implement

....

另外我更改的开源的插件都只能在该tab页面打开一个poppup窗口,

我老婆之前用的比较好的一个插件是可以开启新tab操作别的tab窗口内容,我自己试了下

Cannot access contents of url "chrome-extension://l". Extension manifest must request permission to access this host. 原来操作tabs还是要加权限的 但是我不太明白新开tab之后如何在之前的tab也就是target页面上加载执行脚本,所以参考了下别人的插件,开发者模式下chrome这里有个很好的debug功能,可以直接点击inspect,设置脚本断点,当然默认是minified一行脚本,可以点击{}格式化一下:

参考主要逻辑如下: 默认popup页面加载:

拿到你想要操作的tab即targetTab

var tabId=targetTab.id; chrome.storage.sync.set({'targetTabID': tabId}, function() { chrome.tabs.create({ url: chrome.extension.getURL("你的新tab页面") }, function(a) { targetTab(a); }); 新tab页面加载:

chrome.storage.sync.get(['targetTabID'], function(result) { chrome.tabs.executeScript(result.targetTabID, { file: '/scripts/', allFrames: true

});

});