I have a small test extension that works with opera and chrome. I have troubles with sending message from the backgroud script to the content script.
The manifest file is
{
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [ {
"js": [ "content2.js" ],
"matches": [ "\u003Call_urls>" ]
} ],
"description": "test",
"manifest_version": 3,
"name": "test",
"optional_permissions": [ ],
"permissions": ["contextMenus", "activeTab", "clipboardRead", "clipboardWrite" ],
"version": "0.0.1"
}
The background script is
function buildContextMenu () {
let fcb =[ {fcb_context: "fcb_copy", title: "copy", context: ["selection", "link"]},
{fcb_context:"fcb_paste", context:["editable"], title:"paste"}];
for (let i=0; i< fcb.length; i++) {
let menu = fcb[i];
chrome.contextMenus.create({
//title: "Look up: %s",
title: menu.title,
id: menu.fcb_context,
contexts: menu.context,
});
} // for i
} //buildContextMenu
function log(msg, force=false) {
var debug = true;
if (force || debug){console.log(msg);}
}//Log
//icon in child menu not possible
//http://stackoverflow.com/questions/6772074/add-icon-to-child-context-menu
chrome.runtime.onInstalled.addListener( function () {
log("onInstalled called");
chrome.contextMenus.removeAll();
buildContextMenu();
}); //add listener
chrome.contextMenus.onClicked.addListener(function(info, tabs){
let data, sel, fcb_context;
let id = info.menuItemId;
//data = skim.regex[id];
log(" id: " + id ) ;
sel = info.selectionText;
fcb_context = info.parentMenuItemId;
/*
chrome.tabs.query({currentWindow: true, active: true},
function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {data: "go", context: fcb_context, sel: sel}, function(){} );
});
*/
( async () =>{
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
const response = await chrome.tabs.sendMessage( tab.id, {data: "go", context: fcb_context, sel: sel}, function(){} );
log(response);
})();
}); //onClickedadd
chrome.runtime.onStartup.addListener(function() {
log("onStartup called");
chrome.contextMenus.removeAll();
buildContextMenu();
}); //addListerner
The content script content2.js:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log("received in cs: " + JSON.stringify(request));
//var val;
navigator.clipboard.readText().then((clipText)=>
{
let field = document.activeElement;
console.log("active element name: " + field.name);
let val = "Clipboard content : " + clipText;
insertTextAtCursor(field, val);
return val;
}
).then((val) =>
{
console.log("val: " + val);
navigator.clipboard.writeText(val).then(()=> {
console.log("Set " + val + " to the clipboard");
})
}
);
//let field = document.activeElement;
//let val = paste();
//field.focus();
//insertTextAtCursor(field, "Clipboard contenttt : " + val);
sendResponse();
}
);
function insertTextAtCursor(el, text) {
console.log("insertTextAtCursor: " + text)
//if (! el) { el = document.activeElement; }
console.log("el name: " + el.name);
let val = el.value;
let endIndex;
let range;
let doc = el.ownerDocument;
if (typeof el.selectionStart === 'number' &&
typeof el.selectionEnd === 'number') {
endIndex = el.selectionEnd;
el.value = val.slice(0, endIndex) + text + val.slice(endIndex);
el.selectionStart = el.selectionEnd = endIndex + text.length;
// && doc.selection.createRange)
} else if (doc.selection !== 'undefined' && doc.selection.createRange) {
el.focus();
range = doc.selection.createRange();
range.collapse(false);
range.text = text;
range.select();
}
}//insertTextAtCursor
My problem is that most of the time a page loaded when the extension runs does not react to the past command which appears when the cursor is in a textarea. What am I doing wrong here ?
Tanks
François