我可以允许分机用户选择匹配的网域吗? [英] Can I allow the extension user to choose matching domains?

查看:111
本文介绍了我可以允许分机用户选择匹配的网域吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以允许我的扩展程序的域匹配为用户可配置吗?
我想让我的用户在扩展运行时选择。

解决方案

要实现可自定义的匹配模式对于内容脚本,内容脚本需要在后台页面中使用 chrome.tabs.executeScript 方法(使用 chrome.tabs.onUpdated 事件监听器)。



因为匹配模式检查没有公开在任何API中,您都必须自己创建方法。它在 url_pattern.cc ,该规范可在匹配模式中找到。



下面是一个解析器的例子:

  * @param字符串输入匹配模式
*如果输入无效,则返回null
* @returns要传递给RegExp构造函数的字符串* /
函数parse_match_pattern(输入){
if(typeof input!=='string')return null;
var match_pattern ='(?:^'
,regEscape = function(s){return s.replace(/ [[^ $。|?* +(){} \\] / g,'\\ $&');}
,result = / ^(\ * | https?| file | ftp | chrome-extension):\ / \ //。exec输入);

//解析方案
if(!result)返回null;
input = input.substr(result [0] .length);
match_pattern + = result [1] ==='*'?'https?://':result [1] +'://';

//如果scheme不是`file `
if(result [1]!=='file'){
if(!(result = /^(?:\*|(\*\.)?([^ \ / *] +))(?= \ /)/ .exec(input)))return null;
input = input.substr(result [0] .length);
if结果[0] ==='*'){//主机是'*'
match_pattern + ='[^ /] +';
} else {
if(result [1 ]){//子域通配符存在
match_pattern + ='(?:[^ /] + \\。)?';
}
//追加主机(转义特殊的正则表达式字符)
match_pattern + = regEscape(result [2]);

$ b $ //添加余数(路径)
match_pattern + = input.split('*')。map(regEscape).join('。*');
match_pattern + ='$)';
返回match_pattern;
}



示例:在匹配模式的页面上运行内容脚本



在下面的例子中,数组是硬编码的。实际上,您可以使用 localStorage chrome.storage

//示例:解析匹配模式列表:
var patterns = ['*: // * / *','* exampleofinvalid *','file:// *'];

//解析列表和过滤器(排除)无效匹配模式
var parsed = patterns.map(parse_match_pattern)
.filter(function(pattern){return pattern!==空值});
//创建用于验证的模式:
var pattern = new RegExp(parsed.join('|'));

//过滤示例:
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,tab){
if(changeInfo.status ==='complete' ){
var url = tab.url.split('#')[0]; //排除URL片段
if(pattern.test(url)){
chrome.tabs。 executeScript(tabId,{
file:'contentscript.js'
//或:code:'< JavaScript code here>'
//其他有效选项:allFrames,runAt
});
}
}
});

为了实现这个目标,您需要请求以下清单文件中的许可


  • tabs - 启用必要的标签 API。 < all_urls> - 能够使用 chrome.tabs.executeScript 在特定页面执行内容脚本。



固定权限列表



如果一组匹配模式是固定的(即用户不能定义新模式,只有切换模式),< all_urls>可以用这个替换一组权限。您甚至可以使用可选的权限来减少所请求权限的初始数量(在 chrome.permissions 的文档)。


Can I allow the domain matching for my extension to be user configurable? I'd like to let my users choose when the extension runs.

解决方案

To implement customizable "match patterns" for content scripts, the Content script need to be executed in by the background page using the chrome.tabs.executeScript method (after detecting a page load using the chrome.tabs.onUpdated event listener).

Because the match pattern check is not exposed in any API, you have to create the method yourself. It is implemented in url_pattern.cc, and the specification is available at match patterns.

Here's an example of a parser:

/**
  * @param String input  A match pattern
  * @returns  null if input is invalid
  * @returns  String to be passed to the RegExp constructor */
function parse_match_pattern(input) {
    if (typeof input !== 'string') return null;
    var match_pattern = '(?:^'
      , regEscape = function(s) {return s.replace(/[[^$.|?*+(){}\\]/g, '\\$&');}
      , result = /^(\*|https?|file|ftp|chrome-extension):\/\//.exec(input);

    // Parse scheme
    if (!result) return null;
    input = input.substr(result[0].length);
    match_pattern += result[1] === '*' ? 'https?://' : result[1] + '://';

    // Parse host if scheme is not `file`
    if (result[1] !== 'file') {
        if (!(result = /^(?:\*|(\*\.)?([^\/*]+))(?=\/)/.exec(input))) return null;
        input = input.substr(result[0].length);
        if (result[0] === '*') {    // host is '*'
            match_pattern += '[^/]+';
        } else {
            if (result[1]) {         // Subdomain wildcard exists
                match_pattern += '(?:[^/]+\\.)?';
            }
            // Append host (escape special regex characters)
            match_pattern += regEscape(result[2]);
        }
    }
    // Add remainder (path)
    match_pattern += input.split('*').map(regEscape).join('.*');
    match_pattern += '$)';
    return match_pattern;
}

Example: Run content script on pages which match the pattern

In the example below, the array is hard-coded. In practice, you would store the match patterns in an array using localStorage or chrome.storage.

// Example: Parse a list of match patterns:
var patterns = ['*://*/*', '*exampleofinvalid*', 'file://*'];

// Parse list and filter(exclude) invalid match patterns
var parsed = patterns.map(parse_match_pattern)
                     .filter(function(pattern){return pattern !== null});
// Create pattern for validation:
var pattern = new RegExp(parsed.join('|'));

// Example of filtering:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if (changeInfo.status === 'complete') {
        var url = tab.url.split('#')[0]; // Exclude URL fragments
        if (pattern.test(url)) {
            chrome.tabs.executeScript(tabId, {
                file: 'contentscript.js'
                // or: code: '<JavaScript code here>'
                // Other valid options: allFrames, runAt
            });
        }
    }
});

To get this to work, you need to request the following permissions in the manifest file:

  • "tabs" - To enable the necessary tabs API.
  • "<all_urls>" - To be able to use chrome.tabs.executeScript to execute a content script in a specific page.

A fixed list of permissions

If the set of match patterns is fixed (ie. the user cannot define new ones, only toggle patterns), "<all_urls>" can be replaced with this set of permissions. You may even use optional permissions to reduce the initial number of requested permissions (clearly explained in the documentation of chrome.permissions).

这篇关于我可以允许分机用户选择匹配的网域吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆