[英]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: 您有两个问题:
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.)
有关更详细的讨论,请参阅在后台上下文中的脚本之间进行通信(后台脚本,浏览器操作,页面操作,选项页面等)。
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. 因此,没有侦听器处于活动状态,这导致未接收到消息。
The easy ways to solve these issues are: 解决这些问题的简单方法是:
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.local
在storage.local
中,并让popup.js代码在首次运行时从storage.local
获取它,或者 runtime.sendMessage()
) requesting the data. runtime.sendMessage()
)来请求数据, 从而开始从popup.js传输数据。 Your background.js can then send the data back using the sendResponse
function provided by runtime.onMessage()
. runtime.onMessage()
提供的sendResponse
函数将数据发送回去。 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.