简体   繁体   English

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

[英]Chrome Extension: Changing html of a chrome popup window

I have made a Chrome extension to generate a summary of any document.I added the feature of opening the popup using the browser action icon, and now I want to add the same functionality using a context menu right-click action. 我做了一个Chrome扩展程序来生成任何文档的摘要。我添加了使用浏览器操作图标打开弹出窗口的功能,现在我想使用上下文菜单右键单击操作来添加相同的功能。

Now, when the popup2.html is opened using windows.create() , the window opens as it is and no message is sent to the popup.js script and in turn the innerHtml of the popup window which I opened in the background.js script is not modified. 现在,当使用windows.create()打开popup2.html时,该窗口将按原样打开,并且没有消息发送到popup.js脚本,并且依次发送我在background.js中打开的弹出窗口的innerHtml 。脚本未修改。

I tried to use the chrome.tabs.sendMessage method to send a message to the popup window but am not able to change its html there. 我尝试使用chrome.tabs.sendMessage方法将消息发送到弹出窗口,但无法在此处更改其html。

background.js 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 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 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.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 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 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 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>

You have two problems: 您有两个问题:

First problem 第一个问题

You are using tabs.sendMessage() when attempting to communicate with the script which is in the popup you have opened. 尝试与已打开的弹出窗口中的脚本进行通信时,正在使用tabs.sendMessage() As an HTML page contained within your extension, the scripts in that page run in the background context. 作为扩展中包含的HTML页面,该页面中的脚本在后台上下文中运行。 Thus, tabs.sendMessage() will not work to communicate to that script. 因此, tabs.sendMessage()将无法与该脚本进行通信。 If you are wanting to send messages of that type, you need to use runtime.sendMessage() . 如果要发送该类型的消息,则需要使用runtime.sendMessage() There are multiple ways you can communicate between scripts in the background context. 您可以通过多种方式在后台上下文中的脚本之间进行通信。 For a more detailed discussion, please see Communicate between scripts in the background context (background script, browser action, page action, options page, etc.) 有关更详细的讨论,请参阅在后台上下文中的脚本之间进行通信(后台脚本,浏览器操作,页面操作,选项页面等)。

Second problem 第二个问题

You are trying to send a message to the popup.js script in the window you just opened immediately within the callback of windows.create() . 您正在尝试在windows.create()回调中立即打开的窗口中将消息发送到popup.js脚本。 At the time that callback is run, the window has begun to be created and a windowId has been assigned, but the content of the window does not yet exist (ie the DOM has not been built and the code in popup.js has not yet been run). 在运行回调时,已经开始创建窗口并分配了windowId ,但是该窗口的内容尚不存在(即尚未构建DOM且popup.js中的代码尚未建立)已运行)。 Thus, there is no listener active, which results in the message not being received. 因此,没有侦听器处于活动状态,这导致未接收到消息。

Solutions 解决方案

The easy ways to solve these issues are: 解决这些问题的简单方法是:

  1. Store the data in storage.local prior to the call to windows.open() and let the popup.js code get it from storage.local when it first runs, or 在调用windows.open()之前将数据storage.localstorage.local中,并让popup.js代码在首次运行时从storage.local获取它,或者
  2. Initiate the transfer of the data from popup.js by sending a message from the popup.js code to your background.js (using runtime.sendMessage() ) requesting the data. 通过从popup.js代码向您的background.js发送一条消息(使用runtime.sendMessage() )来请求数据, 从而开始从popup.js传输数据。 Your background.js can then send the data back using the sendResponse function provided by runtime.onMessage() . 然后,您的background.js可以使用runtime.onMessage()提供的sendResponse函数将数据发送回去。
  3. Store the data in a variable in your background.js which is accessible from it's global scope. 将数据存储在background.js中的变量中,该变量可从全局范围访问。 Your popup.js code can then directly access the variable in that scope after obtaining the background's window object with chrome.extension.getBackgroundPage() . 在使用chrome.extension.getBackgroundPage()获得背景的window对象之后,您的popup.js代码即可直接访问该范围内的变量。

It's also possible to wait to send the message from background.js until after popup.js has run, but that is any of: A) more complex, B) effectively the same as having the runtime.sendMessage() initiated from the popup, or C) not guranteed to actually be after the popup.js runs (eg just using a setTimeout() ). 也可以等待从background.js发送消息,直到popup.js运行之后,但这可以是:A)更复杂,B)与从弹出窗口启动runtime.sendMessage()有效地相同,或C)不保证实际运行popup.js之后(例如,仅使用setTimeout() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM