在contextMenu chrome (manifest version 3)中使用选定文本



我正试图重写一个chrome扩展从清单版本2到清单版本3。

扩展所做的是使用选定的文本来创建特定的URL。它根据所选文本在Chrome浏览器的contextMenu中添加一个项目,当用户单击该项目时,该URL将在新窗口中打开。

我使用一个带有文档事件监听器的content_script向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
});
});

在后台脚本中,我为这些消息添加了一个侦听器。这将检查菜单项是否存在。如果存在,则更新项,如果不存在,则创建项。

在manifest版本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);
}
}
}
});

但是要显示版本3,我需要改变一些东西。我在onclick属性上得到了一个错误,所以我把它改成了一个事件监听器。我不能叫窗口。显然是从service_worker打开的,所以我也必须改变它,但这不是我的问题所在。

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|string] id,对象updateProperties,可选回调函数):参数'updateProperties'出错:意外属性:'id'。在chrome扩展://adpocbbofaopmokkheddloekfodplnnk/background.js: 117:37

根据chrome文档的上下文菜单。update也应该接受相同的参数。但它没有,因为这是文档中对contextMenu.update的说明。注意ID是单独提到的。

参数id (string | number) -要更新的项的id。

updateProperties (object) -要更新的属性。接受与contextMenus相同的值。创建函数。

Where for contextMenus。create id被定义为一个可能的createProperties

createProperties(对象)id(字符串可选)-分配给该项的唯一id。事件页面必选。不能与此扩展名的其他ID相同。

我不能留下ID,因为create需要它,我不能把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|string] id,对象updateProperties,可选回调函数):无匹配签名。在chrome扩展://adpocbbofaopmokkheddloekfodplnnk/background.js: 110:37

是这行代码:

chrome.contextMenus.update(options);

但是将这一行改为调用id:

chrome.contextMenus.update(cmid, options);

chrome.contextMenus.update(id: "OpenSnow", options);

两个都给我不同的错误。

如果有人能帮我找出我的Manifest版本3代码中的错误,那将是非常有帮助的。或者,如果有一个更好的方法来做到这一点,没有那么多的消息发送,同时更新选定的文本,这也会工作,我是开放的建议。

这比我以前的解决方案要简单得多。我不再需要内容脚本了。在service_worker中,我创建了一个菜单项,使用%s来显示选中的文本,该文本仅在有选择时显示,并在安装扩展时创建一次。

然后创建一个侦听器,用于在单击上下文菜单项时运行所需的代码。

//define contextMenuItem
var contextMenuItem = {
"id": "OpenSN",
"title": "Open %s in ServiceNow",
"contexts": ["selection"]
};
//on installation of chrome extension: create contextMenuItem
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "OpenSN",
title: "Open %s in Service-Now",
contexts: ["selection"]
});
});

//add listener for click on self defined menu item
chrome.contextMenus.onClicked.addListener(function(clickData){
if (clickData.menuItemId == "OpenSN" && clickData.selectionText) {
//run code here
}
})

如果选定的文本存在于页面上,则将其传递给onClickData.selectionText中的侦听器。对各种上下文类型。

更多信息:https://developer.chrome.com/docs/extensions/reference/contextMenus/

您可以使用以下代码来使用不同类型的上下文菜单:

manifest.json:

"background": {
"service_worker": "background.js"
},
...
"permissions": [
"contextMenus"
],

background.js:

const types = [
"all",
"page",
"frame",
"selection",
"link",
"editable",
"image",
"video",
"audio",
"browser_action",
"page_action",
"action"
];
chrome.runtime.onInstalled.addListener(reason => {
types.forEach(type => {
console.log(type, reason);
chrome.contextMenus.create({
id: `${type}_TYPE_MENUITEM_ID`,
title: `Add ${type} with “%s“ to my service`,
contexts: [type],
visible: true
});
chrome.contextMenus.onClicked.addListener((clickData) => {
if (clickData.menuItemId === `${type}_TYPE_MENUITEM_ID`) {
console.log(`Clicked as: ${type}`);
console.log(clickData);
}
});
});
});

相关内容

最新更新