在上下文菜单中,Chrome如何知道文字是否为网址?

时间:2013-08-15 23:43:27

标签: javascript google-chrome-extension

我正在制作Chrome扩展程序,在上下文菜单中添加“缩短网址”按钮。这是我第一次做任何相关的代码,但我做得很好。

当你突出显示文字时,我的按钮就会出现(使用selectionText)。如果文本是“文本”URL(即纯文本是URL,而不是链接),我想要它只是出现。

我知道这是可能的,因为Google会这样做。如果您突出显示并右键单击文本,则会出现“搜索Google ”按钮,但如果您突出显示并右键单击纯文本网址,则“转到”按钮出现了。

如何在我的扩展程序中执行此操作?

谢谢。

修改

我已经尝试使用TimothéeBoucher的建议在我的扩展中使用它,但我一定做错了(请参阅下面的评论)。

这是我到目前为止所得到的:

background.js

function shortenurl1(info) {
    var searchstring = info.pageUrl;
    chrome.tabs.create({
        url: "http://is.gd/create.php?url=" + searchstring
    })
}

chrome.contextMenus.create({
    title: "Shorten URL (with is.gd)",
    contexts: ["page"],
    onclick: shortenurl1
});

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        if (request.action === 'addContextMenu') {
            function shortenurl2(info) {
                var searchstring = info.selectionText;
                chrome.tabs.create({
                    url: "http://is.gd/create.php?url=" + searchstring
                })
            }

            chrome.contextMenus.create({
                title: "Shorten URL (with is.gd)",
                contexts: ["selection"],
                onclick: shortenurl2
            })
        } else if (request.action === 'removeContextMenu') {
            chrome.contextMenus.remove({
                title: "Shorten URL (with is.gd)"
            })
        }
    }
);

function shortenurl3(info) {
    var searchstring = info.linkUrl;
    chrome.tabs.create({
        url: "http://is.gd/create.php?url=" + searchstring
    })
}

chrome.contextMenus.create({
    title: "Shorten URL (with is.gd)",
    contexts: ["link"],
    onclick: shortenurl3
});

contentscript.js

document.onmouseup = function() {
    var selectedText = window.getSelection().toString();
    // this regex should work for very basic cases but doesn't follow the
    // RFC strictly for what constitutes a URL. Full regex left as exercise ;-)
    if (/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-    ;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:    [\w]*))?)/.test(selectedText)) {
        // send a message to the background page to add the context menu
        chrome.extension.sendMessage({action: 'addContextMenu', url: selectedText});
    } else {
        // send a message to the background page to remove the context menu
        chrome.extension.sendMessage({action: 'removeContextMenu'});
    }
};

的manifest.json

{
    "background": {
        "scripts": ["background.js"]
    },
    "content_scripts": [{
        "run_at": "document_idle",
        "js": ["contentscript.js"],
        "matches": ["<all_urls>"]
    }],
    "description": "Shortens URLs using is.gd.",
    "icons": {
        "16": "icon16.png",
        "48": "icon48.png"
    },
    "name": "is.gd context menu",
    "permissions": ["contextMenus", "tabs", "clipboardWrite"],
    "version": "1.0",
    "manifest_version": 2
}

1 个答案:

答案 0 :(得分:0)

据我所知,当您为此目的提前创建上下文菜单时(例如加载扩展程序时),它将是/或。这意味着您将获得所有选定文本或根本不获取。因此,您必须动态添加和删除它。

您可以执行以下操作:

  1. 在内容脚本中,在document.onmouseup上添加一个侦听器。
  2. 调用时,请检查当前所选文本的内容。
  3. 如果它与URL的正则表达式匹配,请让后台页面添加上下文菜单,否则删除上下文菜单。
  4. 没有第4步。
  5. 因此,在您的内容脚本中,您可以拥有类似的内容:

    document.onmouseup = function() {
        var selectedText = window.getSelection().toString();
        // this regex should work for very basic cases but doesn't follow the
        // RFC strictly for what constitutes a URL. Full regex left as exercise ;-)
        if (/^\s*https?:\/\/[a-zA-Z0-9$-_.+!*'(),]+\s*$/.test(selectedText)) {
            // send a message to the background page to add the context menu
            chrome.extension.sendMessage({action: 'addContextMenu', url: selectedText});
        } else {
            // send a message to the background page to remove the context menu
            chrome.extension.sendMessage({action: 'removeContextMenu'});
        }
    };
    

    在后台脚本中,相应地收听消息和create以及remove上下文菜单。

    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            if (request.action === 'addContextMenu') {
                // code to add the context menu
                // You can access the URL in 'request.url'
            } else if (request.action === 'removeContextMenu') {
                // Remove the context menu
            }
        }
    );
    

    有关消息传递的信息,请参阅this page

    注意:您可以从内容脚本创建菜单,但我还没有尝试过。