Separating classes in a chrome extension - google-chrome-extension

I'm writing my first chrome extension and I can't seem to find any way to pull in functionality in a RequireJS type way..
I just want to be able to write a class in 1 JS file and pull its functionality in to my background.js file and use it, to keep things tidy.
I've googled about and can't find anything! What am I missing?
Thanks!

1
If you want to pull class.js functionality in to background.js, you can just append it to scripts array in manifest.json.
Like this,
{
"name": "My extension",
...
"background": {
"scripts": ["class.js","background.js"]
},
...
}
This means background.js will load after class.js is loaded. So that you can use all functioanality of class.js in background.js.
2
If you want to do this in require.js way, you should use background.html instead of background.js.
Like this,
manifest.json
{
"background": {
"page": "background.html"
},
"description": "Background example",
"name": "Background example",
"version": "0.0.1",
"manifest_version": 2,
"web_accessible_resources": [
"scripts/require-jquery.js",
"scripts/main.js"
],
}
As you see you must add script files that you will use to web_accesible_resource array.
background.html
<!DOCTYPE html>
<html>
<head>
<title>jQuery+RequireJS Sample Page</title>
<!-- This is a special version of jQuery with RequireJS built-in -->
<script data-main="scripts/main" src="scripts/require-jquery.js"></script>
</head>
<body>
</body>
</html>

Related

Why is chrome.browserAction.onClicked undefined (in the background script)? [duplicate]

I'm writing a Chrome extension that will redirect me to a URL when clicking on the browser action icon.
I'm trying to use:
chrome.browserAction.onClicked.addListener
but I get
Uncaught TypeError: Cannot read property 'onClicked' of undefined
This is my manifest file:
{
"name": "first extension",
"version": "2.2.12",
"description": "redirct to a link icon",
"browser_action": {
"default_icon": "icontest.png",
"default_title": "Do action"
},
"permissions": ["tabs", "http://*/*"],
"content_scripts": [{
"matches": ["http://*.twitter.com/*", "https://*.twitter.com/*"],
"js": ["twterland.js"]
}],
"icons": {
"16": "icontest.png",
"48": "icontest.png",
"128": "icontest.png"
}
}
This is my js file:
chrome.browserAction.onClicked.addListener(function(tab) { alert("hi"); });
ManifestV3
manifest.json: use action not browser_action, see also the migration guide.
"action": {},
"background": {"service_worker": "background.js"},
background.js: use chrome.action not chrome.browserAction.
Classic ManifestV2
For those who already have added something like
"background": {
"scripts": ["background.js"]
}
and still gets Cannot read property 'onClicked' of undefined - just add
"browser_action": {}
into your manifest.json
It seems like the code is in your twterland.js file, which is your content script. browserAction can only be used in extension pages, so you can not use it in content scripts.
Document: https://developer.chrome.com/extensions/content_scripts
However, content scripts have some limitations. They cannot:
- Use chrome.* APIs (except for parts of chrome.extension)
- Use variables or functions defined by their extension's pages
- Use variables or functions defined by web pages or by other content scripts
Put it on the background page instead.
If you do not have a "browser_action" property defined in your manifest.json then this error may occur. #Kirill's answer works but you also have to add a blank icon.png file else chrome will throw an error that it cannot find such a file.
Adding this to the manifest.json file should suppress this is error:
"browser_action": {}
Be sure to read the documentation for further reference on how to use the "browser_action" setting.
The same problem may appear if you are using manifest_version 3.
In this case
"background.scripts" should be replaced with "background.service_worker"
"browser_action" should be replaced with "action"
in js code chrome.browserAction should be replaced with chrome.action
detailed information could be found here: Manifest version 3 migration documentation
I was also getting this, adding
"persistent": true
to my background declaration in manifest.json solved it.
Please notice that you can heave only one of app, browser_action, page_actions present in your manifest‎.json file.
For example, to use the chrome.browserAction.setBadgeText you should have the browser_action field in your manifest‎.json.
Make sure we don't have jquery.js before background.js in the scripts array of background in manifest.json.
"background": {
"scripts": ["background.js","jquery.js"]
}

chrome.runtime.onInstalled SOMETIMES not defined in event page

When running in test (reloading an unpacked extension), about 1 out of 5 times my event page's chrome.runtime object does not (yet) have the 'onInstalled' property.
// Cannot read property 'addListener' of undefined
chrome.runtime.onInstalled.addListener(...)
Feels like a race condition on startup within the extension container?
When the error throws, chrome.runtime only has the following:
{OnInstalledReason, OnRestartRequiredReason, PlatformArch,
PlatformNaclArch, PlatformOs, RequestUpdateCheckStatus, connect, sendMessage}
Try moving the event listener to a background script if they are in a content script. Content scripts have limited access to Chrome API. You can define it in the manifest. Then, if needed, you can send it from the background to a content script.
{
"manifest_version": 2,
"name": "someName",
"version": "0.0",
"description": ":D",
"content_scripts": [
{
"matches": ["https://*/*", "http://*/*"],
"js": ["content.js"]
}
],
"background":{
"scripts":["background.js"]
}
}
According to the linked Issue 601559, this was a bug in Chrome that was fixed in Chrome 51 (May 2016).

Multiple background scripts in a Google Chrome extension?

I've been tasked with creating a Google Chrome extension. So far, everything works fine. However, I would like to be able to use multiple background scripts (what I mean is
"background" : {"scripts" : ["background.js"]}, if what I'm talking about is unclear) rather than creating multiple extensions. Is this possible?
Regards,
According to the documentation:
A background page will be generated by the extension system that includes each of the files listed in the scripts property.
So yes, it should work. Simply declare multiple scripts:
...
"background": {
"scripts": [
"background.js",
"backgroundone.js",
"backgroundtwo.js"
]
},
...
All of these scripts would work as if loaded into the same page; they will all share the same context.
In manifest version3:
---------manifest.json
"background": {
"service_worker": "bg-wrapper.js"
}
---------bg-wrapper.js
try {
importScripts('background.js');
} catch (error) {
console.error(error);
}

chrome.experimental.processes.onExited.addListener not working

I am trying to write a Chrome extension which detects process crashes.
First i went to about:flags page of Chrome and enabled "Experimental Extension APIs".
This is the extension I wrote:
manifest.json:
{
"manifest_version": 2,
"name": "CrashDetect",
"description": "Detects crashes in processes.",
"version": "1.0",
"permissions": [
"experimental","tabs"
],
"background": {
"scripts": ["background.js"]
}
}
backround.js:
chrome.experimental.processes.onExited.addListener(function(integer processId, integer exitType, integerexitCode) {
chrome.tabs.getCurrent(function(Tab tab) {
chrome.tabs.update(tab.id, {url:"http:\\127.0.0.1\""});
};)
});
Then I visited about://crash page of Chrome. But onExited listener does not execute.
Have I done anything wrong in manifest.json or background.js?
There a couple errors in your code. First you have the types of the parameters in the function declaration, change it to:
function(processId, exitType, integerexitCode){
Second, you put };) instead of });. Try inspecting the background page to see syntax errors.
Alright, after playing around with it some as I was unfamiliar with this particular API, I found that none of the events fired if I didn't include a handler for onUpdated. I really doubt that this is the intended behavior and I will check to see if there is a bug report on it. For now just do something like this to get it working:
chrome.experimental.processes.onUpdated.addListener(function(process){});
chrome.experimental.processes.onExited.addListener(function(processId, exitType, integerexitCode){
chrome.tabs.query({active:true, currentWindow:true},function(tabs){
chrome.tabs.update(tabs[0].id, {url:"http:\\127.0.0.1"});
});
});
Notice that I did swap out your getCurrent for a chrome.tabs.query as the former would have given you an error. This does lead to the behavior of if you close a tab, the next tab will be redirected. Perhaps you could try to filter by exitType and not include normal exits.

Inject a JavaScript to predefined pages and use page action

Well I have a list of domains (about 10) which my chrome extension is going to interact with.
As I studied the chrome extensions documentation this needs to use content_scripts
I have included these lines in the manifest.json
"content_scripts": [ {
"all_frames": true,
"js": [ "js/main.js" ],
"matches": [ "http://domain1.com/*",
"http://domain2.com/*",
"http://domain3.com/*",
"http://domain4.com/*",
"http://domain5.com/*",
"http://domain6.com/*",
"http://domain7.com/*",
"http://domain8.com/*",
"http://domain9.com/*",
"http://domain10.com/*"
],
"run_at": "document_start"
}],
This means that during loading every page that the url matches the defined url's in the manifest file, then the main.js will be injected to the page. Am I right? yes.
So I want to do some UI when the script is injected through page action
I included these lines to the manifest:
"page_action": {
"default_icon": "images/pa.png",
"default_title": "This in one of that 10 domains, that is why I showed up!"
},
It seems that it is not enough. and I have to manually trigger the page action.
but where ?
I realized that for this purpose I would need a background.html file.
but Why I can not include the trigger at the same main.js file?
answer:
However, content scripts have some limitations. They **cannot**:
- Use chrome.* APIs (except for parts of chrome.extension)
- Use variables or functions defined by their extension's pages
- Use variables or functions defined by web pages or by other content scripts
So included it in the manifest:
"background_page": "background.html"
and this is the content:
<html>
<head>
<script>
function check (tab_id , data , tab){
//test just one domain to be simple
if (tab.url.indexOf('domain1.com') > -1){
chrome.pageAction.show(tab_id);
};
};
chrome.tabs.onUpdated.addListener(check);
</script>
</head>
</html>
Fair enough until here,
What I want and I don't know is how to add the ability of toggle on/off the extension.
User clicks on the page action icon -> the icon changes and turns off/on (the main.js would act different)
Instead of adding the content script through the manifest, you can also use the chrome.tabs.onUpdated in conjunction with chrome.tabs.executeScript:
// Example:
var url_pattern = /^http:\/\/(domain1|domain2|domain3|etc)\//i;
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (url_pattern.test(tab.url)) {
if (changeInfo.status === 'complete') { // Or 'loading'
chrome.tabs.executeScript(tabId, {'file':'main.js'});
chrome.pageAction.show(tabId);
}
} else {
chrome.pageAction.hide(tabId);
}
});
Do not forget to check for the value changeInfo.status, because otherwise, the content script will be executed twice.
In one of these if-statements, you can incorporate a check whether the extension is active or not, and act upon it:
if (changeInfo.status === 'complete' && am_I_active_questionmark) ...
Side not: Instead of using background_page, you can also use "background": {"scripts":["bg.js"]}, and place the background script in bg.js.

Resources