我正在开发一个在Zendesk中使用的chrome扩展,该扩展的功能之一是收集给定票证的两种不同格式的字符串,并将其打印回摘要或";时间线";总体安排我有这个功能,但有一些错误我无法解决。
我希望在chrome扩展中选择自定义上下文菜单选项时,该函数只运行一次当前它将运行几次,相当于用户在选择上下文菜单选项之前单击鼠标右键的次数消息从内容脚本(在页面上下文中运行)发送到后台脚本。该消息初始化上下文菜单选项的onClicked侦听器,然后将更新发送回内容脚本以运行该函数。
我试着用相反的方式来做这件事,看看它是否能解决这个问题,但由于内容脚本在页面上下文中运行以访问pages ckeditor实例,我不知道如何用这种方式来做。在我看来,每次用户单击鼠标右键时,消息都会排队,然后一旦按下上下文菜单项,队列就会清空。
script.js(内容脚本)
function generateTimeline(editingArea)
{
chrome.runtime.sendMessage("nmkeddobbgmklaojjmkimpaffccencgn", {operation : "UPD" }, function(response) {
if(response === "UPDATED")
{
const editorInstance = editingArea.ckeditorInstance;
const eventContainer = getEventContainer(editingArea);
let dateTimeRecords = getInternalCommentTextNodes(eventContainer);
dateTimeRecords.sort(dateComparator);
duplicateChecker(dateTimeRecords);
editorInstance.model.change(writer => {
for(record of dateTimeRecords)
{
const paragraph = writer.createElement('paragraph');
writer.append(paragraph, editorInstance.model.document.getRoot());
const textNode = writer.createText(record.tag + ' ' + record.comment);
writer.append(textNode, paragraph);
}
});
}
});
}
document.addEventListener('mouseup', function(e) {
if(this.activeElement.getAttribute("role") === "textbox" && this.activeElement.getAttribute("aria-label") === "Rich Text Editor. Editing area: main")
{
const editingArea = singletonEventListener(this.activeElement);
// left click
if(e.button === 0)
{
createKeyPressListener(editingArea);
}
//right click
if(e.button === 2)
{
generateTimeline(editingArea);
}
}
});
background.js
const timeLineGenerator = {
"id": "timeLineGenerator",
"title": "Generate Timeline",
"contexts":["editable"]
};
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create(timeLineGenerator);
});
function manageMenuListener(request, sender, sendResponse)
{
if(request.operation === "UPD")
{
if(chrome.contextMenus.onClicked.hasListener)
{
chrome.contextMenus.onClicked.removeListener();
console.log("listener removed");
}
chrome.contextMenus.onClicked.addListener(() => {
return sendResponse("UPDATED");
});
}
}
chrome.runtime.onMessageExternal.addListener(manageMenuListener);
manifest.json
{
"manifest_version": 3,
"name": "Zendesk Date Time Tool",
"description": "Inserts a date time string when a user defined key is pressed",
"permissions":[
"scripting",
"contextMenus",
"activeTab",
"tabs"
],
"host_permissions":["<all_urls>"],
"version": "1.0",
"icons":{
"16":"/icons/icon16.png",
"48":"/icons/icon48.png",
"128":"/icons/icon128.png"
},
"action": {
"default_popup": "/src/index.html",
"default_icon": "/icons/icon128.png"
},
"background":{
"service_worker":"/src/background.js"
},
"content_scripts":[{
"world": "MAIN",
"matches":["https://.zendesk.com/*"],
"js":["/src/script.js"],
"run_at":"document_end"
}],
"externally_connectable": {
"matches": ["https://.zendesk.com/*"]
}
}
编辑:
因此,我将返回sendResponse("UPDATED")移动到;行到一个名为timelineTrigger的函数并返回它
事件处理程序中出错:TypeError:sendResponse不是函数在triggerTimeline
这是更改后的背景.js代码
const timeLineGenerator = {
"id": "timeLineGenerator",
"title": "Generate Timeline",
"contexts":["editable"]
};
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create(timeLineGenerator);
});
function triggerTimeline(request, sender, sendResponse)
{
return sendResponse("UPDATED");
}
chrome.runtime.onMessageExternal.addListener(function(request, sender, sendResponse){
if(request.operation === "UPD")
{
if(chrome.contextMenus.onClicked.hasListener(triggerTimeline))
{
chrome.contextMenus.onClicked.removeListener(triggerTimeline);
console.log("listener removed");
}
chrome.contextMenus.onClicked.addListener(triggerTimeline);
}
});
EDIT 2:全局函数变量
const timeLineGenerator = {
"id": "timeLineGenerator",
"title": "Generate Timeline",
"contexts":["editable"]
};
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create(timeLineGenerator);
});
let triggerTimeline;
chrome.runtime.onMessageExternal.addListener(function(request, sender, sendResponse){
triggerTimeline = function()
{
return sendResponse("UPDATED");
}
if(request.operation === "UPD")
{
if(chrome.contextMenus.onClicked.hasListener(triggerTimeline))
{
chrome.contextMenus.onClicked.removeListener(triggerTimeline);
console.log("listener removed");
}
chrome.contextMenus.onClicked.addListener(triggerTimeline);
}
});
第3版:修复问题的更改。然而,现在它并不总是着火。
const timeLineGenerator = {
"id": "timeLineGenerator",
"title": "Generate Timeline",
"contexts":["editable"]
};
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create(timeLineGenerator);
});
let triggerTimeline;
chrome.runtime.onMessageExternal.addListener(function(request, sender, sendResponse){
if(!triggerTimeline)
{
triggerTimeline = function()
{
return sendResponse("UPDATED");
}
}
if(request.operation === "UPD")
{
if(chrome.contextMenus.onClicked.hasListener(triggerTimeline))
{
chrome.contextMenus.onClicked.removeListener(triggerTimeline);
console.log("listener removed");
}
chrome.contextMenus.onClicked.addListener(triggerTimeline);
}
});
@wOxxOm 的回答
const timeLineGenerator = {
"id": "timeLineGenerator",
"title": "Generate Timeline",
"contexts":["editable"]
};
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create(timeLineGenerator);
});
let triggerTimeline;
chrome.runtime.onMessageExternal.addListener(function(request, sender, sendResponse){
if(!triggerTimeline)
{
triggerTimeline = function()
{
return sendResponse("UPDATED");
}
}
if(request.operation === "UPD")
{
if(chrome.contextMenus.onClicked.hasListener(triggerTimeline))
{
chrome.contextMenus.onClicked.removeListener(triggerTimeline);
console.log("listener removed");
}
chrome.contextMenus.onClicked.addListener(triggerTimeline);
}
});