I developed a google chrome extension that works good with Windows OS. but the problem that does not work with mac, I tried to check the problem, I found that function
chrome.tabs.executeScript
does not work on mac, this is the completely code that worked good with windows not mac.
// The onClicked callback function.
function onClickHandler(info, tab) {
// the problem in injecting code
chrome.tabs.executeScript
( null,{code:"var activeElm = document.activeElement; var inp_text = activeElm.value; console.log(activeElm.value);"});
};
chrome.contextMenus.onClicked.addListener(onClickHandler);
// Set up context menu tree at install time.
chrome.runtime.onInstalled.addListener(function() {
// Intentionally create an invalid item, to show off error checking in the
// create callback.
console.log("About to try creating an invalid item - an error about " +
"duplicate item child1 should show up");
chrome.contextMenus.create({"title": "consoleMe", "id": "child523", "contexts":["selection"]}, function() {
if (chrome.extension.lastError) {
console.log("Got expected error: " + chrome.extension.lastError.message);
}
});
});
Hint:
I use content_scripts injection files in the manifest file, but it seems did not activated on Google chrome on Mac.
"content_scripts": [
{
"matches": ["http://*/*","https://*/*"],
"js" : ["jquery.min.js","fix.js","injscript.js"],
"all_frames": false
}
],
OS : Mac 10.8 Mountain lion --
Google Chrome V 32
There should be no difference between Windows and Mac. It's likely that something else is different between your two setups.
It's not clear to me whether the javascript snippet above is a background script or an injected content script. Can you provide the full manifest and indicate which file the snippet belongs to?
If it's a background script, chrome.tabs.executeScript with null tabId will apply to the background page, which is not what you expect. Instead, pass tab.id for the tabId.
If it's a content script, the contextMenus API calls won't work because content scripts are not allowed to use chrome APIs (see https://developer.chrome.com/extensions/content_scripts.html).
Related
In Chrome Manifest V2 I was able to easily capture the desktop. Attempting this in Manifest version 3 I have had no luck. I feel I may be missing something here in attempting this in Manifest V3.
I have been using this as a reference. https://developer.chrome.com/docs/extensions/reference/desktopCapture/
My manifest has these permissions granted to it
"permissions": [
"idle",
"tabs",
"storage",
"notifications",
"alarms",
"desktopCapture"
],
This is the sample code I have been testing just to see if I can get the screen selector to come up. I have not included the tabs.tab as this is labeled as optional and I wanted to see if I could have the plugin trigger the screen recording feature on its own.
chrome.desktopCapture.chooseDesktopMedia(["screen"], (streamID, options) => {console.log(id)});
I have been attempting to have this run in my background.js file.
Each time it runs chrome crashes completely with no errors given.
Reviewing the crash dump I can see the following information.
Exception Code: 0xC0000005
Exception Information: The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
I solve it this way for Manifest v3.
It was giving me errors too. When I checked the documentation, chooseDesktopMedia it wanted three parameters.
DesktopCaptureSourceType[]
Tab
Callback Function
I see in your question your have put 1 and 3. I did the same it was giving me errors. So I made sure I get the active tab first before calling chrome.desktopCapture.chooseDesktopMedia in the background script.
So the code looks like this
chrome.tabs.query({ active: true }, (tabs) => {
if (tabs.length) {
const tab = tabs[0];
var pending = chrome.desktopCapture.chooseDesktopMedia(["window"], tab, (streamId) => {
//console.log(streamId, tab);
});
}
return false;
})
And it worked. I hope this helps
I am currently making a chrome extension using the following Chrome tutorial:
https://developer.chrome.com/docs/extensions/mv3/getstarted/
I ran into some issues with my own code initially so now I'm just using their code as a basis for my own thing.
In popup.js, the tutorial has a function that changes the background color on click.
function setPageBackgroundColor() {
chrome.storage.sync.get("color", ({ color }) => {
document.body.style.backgroundColor = color;
});
I replaced the line in the code instead to what I wanted it to do.
document.getElementById(xyz).miscfunction(arg1, arg2);
The getting started extension works as intended (obviously). When I run my line of code in the console in Chrome, it works exactly as intended. However, when I run the line using the extension, it gives me the following error:
Uncaught TypeError: document.getElementById(...).miscfunction is not a function
I have tested and found out that getElementById is indeed getting the element I want because when I try to run this on a tab that does not have said element, it gives me an error saying that the element is null. It does not do so for the tab that actually does have the element.
What is preventing my extension from being able to access the miscfunction? When I was last trying to debug this months ago, I recall having some issues with injection and the content security policy but I do not remember what I did to get to that point. Any help would be appreciated.
EDIT:
I have since updated the popup to call a script js file instead of calling a function, and then put the function in a separate file.
To access the document element of the page you are viewing, you need to paste the required code in the content script.
You first need to add content script and it's scope in manifest.json
"content_scripts" : [{
"matches" : ["https://<website-you-are-working-on>"]
"js" : ["script.js"] //file containing the code you need to execute
}]
The pop up script now needs to send message to content script to do what you want to do.
popup.js
chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
const activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {
"action" : "change-background"
"payload": {
//required info
}
})});
Now listen for the message in the content script and do the required task.
script.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if(message.action == "change-background"){
//your code here
}
})
I'd like to write an extension for Thunderbird that modifies the message display (e.g. insert/replace text/markup/image).
Unfortunately, the documentation is lacking (due to recent changes?).
https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_extensions
is outdated
https://developer.thunderbird.net/
does not have useful examples (yet)
https://thunderbird-webextensions.readthedocs.io/
no examples either
Some examples can be found at
https://github.com/thundernest/sample-extensions
Building on https://github.com/thundernest/sample-extensions/tree/master/messageDisplay
I've modified background.js
browser.messageDisplay.onMessageDisplayed.addListener((tabId, message) => {
console.log(`Message displayed in tab ${tabId}: ${message.subject}`);
console.log(message.id);
browser.messages.getFull(message.id).then((messagepart) => {
console.log(messagepart);
body = messagepart['parts'][0]['parts'][0]['body'];
console.log(body);
body += "modified!";
console.log(body);
});
browser.windows.getCurrent().then((window)=>{
console.log(window.type);
});
browser.tabs.getCurrent().then((tab)=>{
console.log("tab",tab);
});
});
which gives me the message body (using magic indexes) but expectedly, the change is not reflected in the message display.
The window type returned is normal, not messageDisplay.
The tab is undefined despite adding permissions
"permissions": [
"messagesRead",
"activeTab",
"tabs",
"tabHide"
],
but I assume that's because the script is running as background.
So I'd need a script running on the content / access to the tab and then some hints on how to modify the displayed message content (I do not want to modify the message).
Where would I find the equivalent documentation to
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts
specific to Thunderbird?
Specifying content_scripts in manifest.json causes "Error: Error reloading addon messageDisplay#sample.extensions.thunderbird.net: undefined".
executeScript() from background does not seem to work either, even with tabId specified.
This was not possible to do when you wrote your question, the API for modifying displayed messages was missing.
As of this writing (September 2020), the browser.messageDisplayScripts API landed a few days ago, see bug 1504475 and related patch for examples. It works as follows: You can register your content script (to modify the displayed messages) like this
let myPromise = browser.messageDisplayScripts.register({
css: [{
file: "/style.css",
}],
js: [{
file: "/content_script.js",
}],
});
And you can later unregister with
myPromise.then((script) => { script.unregister(); });
You need to register the script just once for all messages (you do not need a listener that would load it each time a message is displayed).
Note that your manifest.json needs to include the messagesModify permission for this to work.
The new API will be in Thunderbird version 82, so if I understand the release process correctly it should be in stable version 88 (unless it is backported before that). You can try it already (v82 is the current EarlyBird).
Documentation https://thunderbird-webextensions.readthedocs.io/en/68/tabs.html#getcurrent
says:
May be undefined if called from a non-tab context (for example: a background page or popup view).
Since the background.js is not called from a tab context the tab is undefined.
I am trying to change the background of about:newtab in Firefox using the new WebExtensions API. At the moment, I don't understand why I receive the following error message in the debug console:
Unchecked lastError value: Error: No window matching {"matchesHost":[]}
The code for my add-on is as follows:
manifest.json
{
"background": {
"scripts": ["background.js"]
},
"description": "Yourdomain description.",
"homepage_url": "https://yourdomain.com",
"icons": {
"64": "icons/icon-64.png"
},
"manifest_version": 2,
"name": "yourDomain",
"permissions": [
"tabs",
"activeTab"
],
"version": "2.0"
}
background.js:
var tabId;
function changeBackground() {
chrome.tabs.insertCSS( tabId, {
code: "body { border: 20px dotted pink; }"
});
}
function handleCreated(tab) {
if (tab.url == "about:newtab") {
console.log(tab);
tabId = tab.id;
changeBackground();
}
}
chrome.tabs.onCreated.addListener(handleCreated);
Currently no way for WebExtensions add-ons to change about:newtab
That is the error you receive when the page into which you are attempting to inject does not match the match pattern, or can not be expressed as a match pattern (i.e. the URL must be able to be expressed as a match pattern, even if you didn't supply a match pattern). Match patterns must have a scheme that is one of http, https, file, ftp, or app. The error you are seeing is a result of not checking the runtime.lastError value in the callback function in tabs.insertCSS() when the error is the one expected when you attempt to inject code or CSS into an about:* page.
The MDN documentation is quite specific about not being able to use tabs.insertCSS() with any of the about:* pages (emphasis mine):
You can only inject CSS into pages whose URL can be expressed using a match pattern: meaning, its scheme must be one of "http", "https", "file", "ftp". This means that you can't inject CSS into any of the browser's built-in pages, such as about:debugging, about:addons, or the page that opens when you open a new empty tab [about:newtab].
Future:
Chrome has the manifest.json key chrome_url_overrides which allows overriding any of: bookmarks, history, or newtab. It appears that Firefox support for this manifest.json key is a "maybe".
Alternatives:
It is possible to override the newtab page with other types of Firefox add-ons.
You can use WebExtensions to detect that a tab has changed its URL to about:newtab and redirect the tab to a page of your choice.
Using tabs.insertCSS() or tabs.executeScript() for tabs, generally
If you are using tabs.insertCSS() or tabs.executeScript() in a situation where the tab normally contains a regular URL, but might be an about*: (or chrome:* scheme on Chrome) (e.g. a browser_action button), you could handle the error with the following code (tested and working in both Firefox WebExtensions and Chrome):
function handleExecuteScriptAndInsertCSSErrors(tabId){
if(chrome.runtime.lastError){
let message = chrome.runtime.lastError.message;
let isFirefox = window.InstallTrigger?true:false;
let extraMessage = tabId ? 'in tab ' + tabId + '.' : 'on this page.';
if((!isFirefox && message.indexOf('Cannot access a chrome:') > -1) //Chrome
||(isFirefox && message.indexOf('No window matching') > -1) //Firefox
){
//The current tab is one into which we are not allowed to inject scripts.
// You should consider alternatives for informing the user that your extension
// does not work on a particular page/URL/tab.
// For example: For browser_actions, you should listen to chrome.tabs events
// and use use browserAction.disable()/enable() when the URL of the
// active tab is, or is not, one for which your add-on can operate.
// Alternately, you could use a page_action button.
//In other words, using a console.log() here in a released add-on is not a good
// idea, but works for examples/testing.
console.log('This extension, ' + chrome.runtime.id
+ ', does not work ' + extraMessage);
} else {
// Report the error
if(isFirefox){
//In Firefox, runtime.lastError is an Error Object including a stack trace.
console.error(chrome.runtime.lastError);
}else{
console.error(message);
}
}
}
}
You could then change your changeBackground() code to:
function changeBackground(tabId) {
chrome.tabs.insertCSS( tabId, {
code: "body { border: 20px dotted pink; }"
}, handleExecuteScriptAndInsertCSSErrors.bind(null,tabId));
}
Obviously, changing your code like that won't actually allow you to change the background on the about:newtab page.
I'm making add-on modules for several browsers, including Chrome and Firefox.
I just did what I want with Chrome : overriding new tab url to load a HTML file with the manifest.json. Pretty simple. (Now I'm able to copy paste again :)) :
...
"chrome_url_overrides" : {
"newtab": "override.html"
},
...
When the user create a new blank tab, it overrides the default page and loads the file I want : override.html, with the same behavior (no URL in the address bar).
But now, I want to do the same thing with Firefox using Add-on SDK. I tried using browser.newtab.url :
var { get, set } = require("sdk/preferences/service");
var { when: unload } = require("sdk/system/unload");
var oldValue = get("browser.newtab.url");
set("browser.newtab.url", 'http://www.example.com');
// Restore old setting when unload
unload(function() {
set("browser.urlbar.autoFill", oldValue);
});
It works, but I really would be able to load an HTML file instead giving it a new URL (the code would be more maintainable) and keep a clean address bar.
Any ideas ?