javascript - Chrome 扩展程序 : Changing html of a chrome popup window

标签 javascript google-chrome google-chrome-extension

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

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

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

背景.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;
    }
});

ma​​nifest.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>

最佳答案

您有两个问题:

第一个问题

您正在使用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. 在调用 windows.open() 之前将数据存储在 storage.local 中,并让 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 代码可以直接访问该范围内的变量。 .

也可以等到 popup.js 运行后才从 background.js 发送消息,但这是以下任何一种:A) 更复杂,B) )实际上与从弹出窗口启动 runtime.sendMessage() 相同,或者 C) 不能保证实际上是在 popup.js 运行之后(例如,仅使用setTimeout())。

关于javascript - Chrome 扩展程序 : Changing html of a chrome popup window,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44754868/

相关文章:

javascript - chrome.tabs.executeScript 在 chrome.tabs.create 回调中不起作用

javascript - Lodash 帮助使用搜索词和多个属性名称进行过滤

javascript - Firebase Web update() 删除所有其他子节点

java - 在 Android Native App 之前获取本地存储项目

google-chrome - console.info() 的 (i) 图标发生了什么变化?

javascript - 如果未安装 Chromecast 扩展程序或使用隐身模式,Google Chromecast 发件人错误

Javascript 神经网络不收敛

google-chrome - 在我的 chrome 浏览器中访问 localhost 时出现 Fiddler Echo Service 错误

python - 在Python中通过selenium执行测试时,ChromeDriver应该放在哪里?

google-chrome - Chrome 不信任 M70 for Aliexpress