Chrome扩展程序:更改Chrome弹出窗口的html

时间:2017-06-26 07:32:23

标签: javascript google-chrome google-chrome-extension

我制作了Chrome扩展程序以生成任何文档的摘要。我添加了使用浏览器操作图标打开弹出窗口的功能,现在我想使用上下文菜单右键单击操作添加相同的功能。 / p>

现在,当使用windows.create()打开popup2.html时,窗口将按原样打开,并且不会向popup.js脚本发送任何消息,而是弹出窗口的innerHtml我在 background.js 脚本中打开时未修改。

我尝试使用chrome.tabs.sendMessage方法向弹出窗口发送消息,但无法在其中更改其html。

background.js

chrome.runtime.onInstalled.addListener(function() {
  var context = "selection";
  var title = "See the Gist";
  var id = chrome.contextMenus.create({"title": title, "contexts":[context],"id": "context_selection"});  
});

var open_window_ids=[]

function getSummary(selected) {

    var jsonData;

    $.ajax({
        url: 'http://127.0.0.1:5000/api/summarize',
        type: 'POST',
        data: JSON.stringify(selected),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        async: false,
        success: function(data) {
            jsonData = data;
        }
    });

    return jsonData;
}

console.log("Booting");

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {

    var activeTab = tabs[0];
    chrome.tabs.sendMessage(activeTab.id, {"message": "get_selected_text"}, function(response) {
        console.log('From button');
        if (response.selected_text == "") {
            document.body.innerHTML += "<h3 style='text-align: center'>No text selected! Select text and try again.</h3>";
        }
        else {
            var apiResponse = getSummary(response);
            console.log(apiResponse);
            if (!apiResponse)
            {
                document.getElementById("header").innerHTML += "<h3 class='heading'>API response unavailable.</h3>";
            }
            var summary_final = apiResponse.sentences;
            if (summary_final.length == 0) {
                document.getElementById("header").innerHTML += "<h3 class='heading'>Not enough text selected to generate summary. Select larger block of text and try again.</h3>";
                document.getElementById("footer").innerHTML += "<div style='padding:15px;'>Powered by <a href='http://zippybots.com' target='_blank'><span id='link'>Zippybots</span></a></div>";
            }
            else{
                document.getElementById("header").innerHTML += "<h1 class='heading'>The Gist is.....</h1>";
                var para = "";
                for (var i = 0;i<summary_final.length;i++)
                {
                    para += summary_final[i]+" ";
                    if( i % 3 == 2) 
                    {
                        document.getElementById("summary").innerHTML += "<p class='point'>"+para+"</p>";    
                        para = "";
                    }
                }
                if (para) document.getElementById("summary").innerHTML += "<p class='point'>"+para+"</p>";
                document.getElementById("footer").innerHTML += "<div style='padding:15px;'>Powered by <a href='http://zippybots.com' target='_blank'><span id='link'>Zippybots</span></a></div>";
            }
        }
    });
});


chrome.contextMenus.onClicked.addListener(function(info, tab){
    if (info.menuItemId == "context_selection") {
        for (var i = open_window_ids.length - 1; i >= 0; i--) {
            chrome.windows.remove(open_window_ids[i],function(){});
            open_window_ids.pop();
        }   
            // window.document.body.innerHTML += doc;
        var activeTab;
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            activeTab = tabs[0];
            chrome.windows.create({url: 'popup2.html',focused:true,type:'popup'},function(win){
                open_window_ids.push(win.id);
                displayCurrent(open_window_ids[0],activeTab.id,win);
            });
        });
    }
});

function displayCurrent(id,activeTabId,popupwindow){
    console.log("Got selection tab id :"+activeTabId);
    var popupTabId = popupwindow.tabs[0].id;
    console.log("Got popup tab id :"+popupTabId);

    chrome.tabs.sendMessage(activeTabId, {"message": "get_selected_text"}, function(response) {

        console.log("Resp:"+response.selected_text);
        if (response.selected_text == "") {
            console.log("Selected text is null");
            chrome.tabs.sendMessage(popupTabId,{"message":"no_text_selected"},function (response){});
        }
        else {
            var apiResponse = getSummary(response);
            if (!apiResponse)
            {
                document.getElementById("header").innerHTML += "<h3 class='heading'>API response unavailable.</h3>";
            }
            var summary_final = apiResponse.sentences;
            if (summary_final.length == 0) {
                console.log("Summary length 0");
                chrome.tabs.sendMessage(popupTabId,{"message":"not_enough_text"},function (response){});
            }
            else {
                console.log("Summary there");
                chrome.tabs.sendMessage(popupTabId,{"message":"summary","data":summary_final},function (response){});   
            }
        }   
    });
}

popup2.html

<html>
    <head>
        <meta charset="utf-8">
        <link href="bootstrap.min.css" rel="stylesheet">
        <script src="jquery-3.1.1.min.js"></script>
        <script src="bootstrap.min.js"></script>
        <!-- <script src="api-keys.js"/></script> -->
        <link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
        <script type="text/javascript" src="popup.js"></script>
        <script type="text/javascript" src="background.js"></script>
        <style>
            body{
                min-width: 750px;
                font-family: 'Ubuntu', sans-serif;
                background: #f1f1f1;
                /*background: #2c001e;*/
            }
            #header{
                /*background: #dd4814;*/
                background: #2c001e;
                /*color: #dd4814;*/
                color: #fff;
                text-align: center;
                padding: 1px;
            }
            #footer{
                /*background: #dd4814;*/
                background: #2c001e;
                color: #fff;
                text-align: right;
                min-height: 50px; 
            }
            #link{
                /*color: #fff;              */
                color: #dd4814;
            }
            .point{
                color: #333;                
                /*background: #2c001e;*/
                background: #f1f1f1;
                text-align: justify;
                padding: 5px;
            }
            #summary{
                background: #f1f1f1;
                /*background: #2c001e;*/
                max-width: 720px;
                font-weight: 300;   
                font-size:15px;
                font-family: Ubuntu, Arial, "libra sans", sans-serif;
                padding-left: 30px;
            }
            .heading{
                margin-top: 10px;
                margin-bottom: 10px;
            }
        </style>
    </head>
    <body>
            <div id="header"></div>
            <!-- This will be populated when extension button is clicked -->
            <div id="summary"><br></div>
            <div id="footer">

            </div>
    </body>
</html>

content.js

console.log("Content file loaded");
chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) {
    if (request.message == "get_selected_text") {
        var selectedText = document.getSelection().toString();
        sendResponse({selected_text: selectedText});
        return true;
    }
});

的manifest.json

{
  "manifest_version": 2,
  "name": "Selection Summarizer",
  "description": "A chrome extension that allows users to get a summary of a news article or large block of text.",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],

      "js": ["jquery-3.1.1.min.js", "content.js","popup.js"]

    }
  ],

  "background": {
        "scripts": ["background.js"],
        "persistent" :false
    },


  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html",
    "default_title": "Summarize!"
  },

  "icons": { "16": "icons/icon16.png",
           "48": "icons/icon48.png",
          "128": "icons/icon128.png" },

  "permissions": ["activeTab", "tabs","contextMenus",
    "http://127.0.0.1:5000/*","https://en.wikipedia.org/*"]
}

popup.js

chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) {
    if (request.message == "no_text_selected") {
        console.log("no_text_selected");
        document.body.innerHTML += "<h3 style='text-align: center'>No text selected! Select text and try again.</h3>";
    }

    else if (request.message == "not_enough_text") {
        console.log("not enough text");
        document.getElementById("header").innerHTML += "<h3 class='heading'>Not enough text selected to generate summary. Select larger block of text and try again.</h3>";
        document.getElementById("footer").innerHTML += "<div style='padding:15px;'>Powered by <a href='http://zippybots.com' target='_blank'><span id='link'>Zippybots</span></a></div>";
    }

    else if (request.message == "summary") {
        console.log("Summary printing");
        var summary_final = request.data;
        console.log(summary_final);
        document.getElementById("header").innerHTML += "<h1 class='heading'>Summary</h1>";
        var para = "";
        for (var i = 0;i<summary_final.length;i++)
        {
            para += summary_final[i]+" ";
            if( i % 3 == 2) 
            {
                document.getElementById("summary").innerHTML += "<p class='point'>"+para+"</p>";    
                para = "";
            }
        }
        if (para) document.getElementById("summary").innerHTML += "<p class='point'>"+para+"</p>";
        document.getElementById("footer").innerHTML += "<div style='padding:15px;'>Powered by <a href='http://zippybots.com' target='_blank'><span id='link'>Zippybots</span></a></div>";
    }
    return true;
});

content.js

console.log("Content file loaded");
chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) {
    if (request.message == "get_selected_text") {
        var selectedText = document.getSelection().toString();
        sendResponse({selected_text: selectedText});
        return true;
    }
});

popup.html

<html>
    <head>
        <meta charset="utf-8">
        <link href="bootstrap.min.css" rel="stylesheet">
        <script src="jquery-3.1.1.min.js"></script>
        <script src="bootstrap.min.js"></script>
        <!-- <script src="api-keys.js"/></script> -->
        <link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
        <script type="text/javascript" src="content.js"></script>
        <script type="text/javascript" src="background.js"></script>
        <style>
            body{
                min-width: 550px;
                font-family: 'Ubuntu', sans-serif;
                background: #f1f1f1;
                /*background: #2c001e;*/
            }
            #header{
                /*background: #dd4814;*/
                background: #2c001e;
                /*color: #dd4814;*/
                color: #fff;
                text-align: center;
                padding: 1px;
            }
            #footer{
                /*background: #dd4814;*/
                background: #2c001e;
                color: #fff;
                text-align: right;
                min-height: 50px; 
            }
            #link{
                /*color: #fff;              */
                color: #dd4814;
            }
            .point{
                color: #333;                
                /*background: #2c001e;*/
                background: #f1f1f1;
                text-align: justify;
                padding: 5px;
            }
            #summary{
                background: #f1f1f1;
                /*background: #2c001e;*/
                max-width: 720px;
                font-weight: 300;   
                font-size:15px;
                font-family: Ubuntu, Arial, "libra sans", sans-serif;
                padding-left: 30px;
            }
            .heading{
                margin-top: 10px;
                margin-bottom: 10px;
            }
        </style>
    </head>
    <body>
            <div id="header"></div>
            <!-- This will be populated when extension button is clicked -->
            <div id="summary"><br></div>
            <div id="footer">

            </div>
    </body>
</html>

1 个答案:

答案 0 :(得分:3)

你有两个问题:

第一个问题

在尝试与您打开的弹出窗口中的脚本进行通信时,您正在使用tabs.sendMessage()。作为扩展中包含的HTML页面,该页面中的脚本在后台上下文中运行。因此,tabs.sendMessage()将无法与该脚本进行通信。如果您要发送该类型的邮件,则需要使用runtime.sendMessage()。您可以通过多种方式在后台上下文中的脚本之间进行通信。有关更详细的讨论,请参阅Communicate between scripts in the background context (background script, browser action, page action, options page, etc.)

第二个问题

您正尝试在windows.create()的回调中立即打开的窗口中向 popup.js 脚本发送消息。在运行回调时,窗口已经开始创建,并且已经分配了windowId,但窗口的内容尚不存在(即尚未构建DOM并且 popup.js 尚未运行)。因此,没有监听器处于活动状态,这导致消息未被接收。

解决方案

解决这些问题的简便方法是:

  1. 在调用storage.local之前将数据存储在windows.open()中,并让 popup.js 代码在首次运行时从storage.local获取,或者
  2. 通过从 popup.js 代码向 background.js 发送消息,启动从 popup.js 传输数据(使用runtime.sendMessage())请求数据。然后,您的 background.js 可以使用sendResponse提供的runtime.onMessage()功能发回数据。
  3. 将数据存储在 background.js 中的变量中,该变量可从其全局范围访问。然后,在使用chrome.extension.getBackgroundPage()获取背景的window对象后,您的 popup.js 代码可以直接访问该范围内的变量。
  4. popup.js 运行之后,还可以等待从 background.js 发送消息,但这是以下任何一种情况:A)更复杂,B)实际上与从弹出窗口启动的runtime.sendMessage()相同,或者C)实际上不在 popup.js 之后运行(例如只使用{{1} }})。