我正在尝试将chrome扩展从清单版本2重写为清单版本3。
该扩展的作用是使用选定的文本创建一个特定的URL。它会根据选定的文本在Chrome浏览器的contextMenu中添加一个项目,当用户单击该项目时,URL将在一个新窗口中打开。
我使用一个content_script和一个document事件侦听器,在每次所选文本发生变化时(在选择文本时经常发生),向backgroundscript发送一条消息。
这就是我的content_script.js。从清单2到清单3,我没有做任何更改。
//Add event listener: checks for selectionchanges by user
document.addEventListener('selectionchange', function() {
var selection = window.getSelection().toString().trim();
chrome.runtime.sendMessage({
request: 'updateContextMenu',
selection: selection
});
});
在我的后台脚本中,我为这些消息添加了一个侦听器。它检查菜单项是否存在。如果存在,它将更新该项,如果不存在,它将创建该项。
在清单版本2中,我是这样做的:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.request === 'updateContextMenu') {
var type = msg.selection;
if (type == '') {
// Remove the context menu entry
if (cmid != null) {
chrome.contextMenus.remove(cmid);
cmid = null; // Invalidate entry now to avoid race conditions
} // else: No contextmenu ID, so nothing to remove
} else {
var options = {
title: "Open '%s' in Service-Now",
contexts: ["selection"],
onclick: cm_clickHandler
};
if (cmid != null) {
chrome.contextMenus.update(cmid, options);
} else {
// Create new menu, and remember the ID
cmid = chrome.contextMenus.create(options);
}
}
}
});
但是对于manifest版本3,我需要做一些改变。我在onclick属性上得到了一个错误,所以我把它改成了一个事件侦听器。(显然我不能window.open从service_worker调用www.example.com,所以我也必须改变它,但这不是我的问题。
chrome.contextMenus.onClicked.addListener(function(clickData, tab) {
var sn_url = get_servicenow_url(clickData.selectionText);
console.log("debug: open URL " + sn_url);
Clients.openWindow(sn_url, '_blank');
//window.open(sn_url, '_blank');
});
除此之外,我还有一个错误:
事件处理程序出错:TypeError:调用contextMenus时出错。update([integer|字符串] id,对象updateProperties,可选函数回调):参数“updateProperties”处出错:意外属性:请输入您的密码://////
根据chrome文档contextMenus.update应该接受与contextMenus. create相同的参数。但是它并不接受,因为这是文档对contextMenu. update的声明。注意ID是单独提到的。
PARAMETERS id(字符串|number)-要更新的项目的ID。
updateProperties(object)-要更新的属性。接受与contextMenus.create函数相同的值。
其中contextMenus.create id定义为可能的createProperties之一
createProperties(object)id(字符串可选)-分配给此项目的唯一ID。对于事件页面是必需的。不能与此扩展的另一个ID相同。
我不能留下ID,因为创建需要它,我不能把ID放在我的数组中,因为对于更新,它需要是命令中单独的第一件事。
https://developer.chrome.com/docs/extensions/reference/contextMenus/#method-update\
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.request === 'updateContextMenu') {
var type = msg.selection;
if (type == '') {
// Remove the context menu entry
if (cmid != null) {
chrome.contextMenus.remove(cmid);
cmid = null; // Invalidate entry now
} // else: No contextmenu ID, so nothing to remove
} else {
var options = {
id: "OpenSnow", //mandatory for createMenu
title: "Open '%s' in Service-Now",
contexts: ["selection"]
};
if (cmid != null) {
chrome.contextMenus.update(options);
} else {
// Create new menu, and remember the ID
cmid = chrome.contextMenus.create(options);
console.log("debug: first time creation" + );
}
}
}
});
当我尝试运行此代码块时,出现以下错误:
事件处理程序出错:TypeError:调用contextMenus时出错。update([integer|字符串] id,对象updateProperties,可选函数回调):没有匹配的签名。在chrome-扩展名://adpocbbofaopmokkheddloekfodplnnk/background.js:110:37
也就是这一行代码:
chrome.contextMenus.update(options);
但将该行更改为调用id:
chrome.contextMenus.update(cmid, options);
或
chrome.contextMenus.update(id: "OpenSnow", options);
两者又给予我不同的错误。
如果有人能帮我找出清单版本3代码中的错误,那将非常有帮助。或者如果有一个更好的方法来做这件事,在更新选定的文本时没有那么多的消息发送,那也会工作,我愿意接受建议。
2条答案
按热度按时间idfiyjo81#
事实证明,它比我以前的解决方案简单得多。我不再需要内容脚本了。在service_worker中,我创建了一个菜单项,使用%s来显示所选文本,它只在有选择时显示,并且在安装扩展时创建一次。
然后,我创建了一个侦听器,用于在单击上下文菜单项时运行必要的代码。
t2a7ltrp2#
如果选取的文字出现在页面上,则会将它传递给***onClickData.selectionText***中***各种***内容类型的侦听程式。
更多信息:https://developer.chrome.com/docs/extensions/reference/contextMenus/
您可以使用下列程式码来使用不同类型的快显功能表:
清单.json:
背景.js: