The difference between event page and background page - javascript

After I read the documentation about Event Page I didn't got the advantage of using Event Page instead of Background Page .
Suppose I have the follow simple case -
manifest.json
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
content.js
chrome.runtime.sendMessage("Hi Background")
background.js
chrome.runtime.onMessage.addListener(messageListener);
function messageListener (request, sender, sendResponse) {
alert(request);
}
In this case , whether persistent is "persistent": false or "persistent": true the listener in the background.js always should be awake in order to get the messages from the content.js and therefore the the background.js couldn't go to suspend mode .
So what is the benefit of the Event Page ("persistent": true) in such cases and in general ? Please provide an example.

The main advantage of the event pages is to release RAM and CPU resources by unloading background script when it is not used.
...background.js couldn't go to suspend mode.
It can. Even if your event page uses message listener it still will be unloaded after some time. Chrome remembers that the page has set the listener, so the browser will awake the page when a message will be sent.
You can try this experiment:
add this extension
manifest.json
{
"manifest_version": 2,
"name": "Test",
"version": "0.0.1",
"description": "",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_popup": "popup.html"
}
}
background.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
sendResponse({
msg: "it's alive!"
});
}
);
popup.html
<html>
<body>
<div id="text"></div>
<script src="popup.js"></script>
</body>
</html>
popup.js
chrome.runtime.sendMessage('hello',
function (response) {
document.getElementById('text').textContent = response.msg;
}
);
Open Chrome's Task manager and wait few seconds until Test extension disappears (unloads). If you do not see it (it already unloaded), you can reload extension.
Click to the extension's browser action and you will see message inside the window which came from the event page. Also, you can see two processes in the task manager for the Test extension: one is a popup and the second is the event page.
After popup will be closed, the event page unloads again in a few seconds.

Related

Chrome extension - Document.getelementbyId(...) evaluating to null?

In console I can input document.getElementById('...') and get a value back. Or even .textContent and get the string I want.
Once I pop this into my chrome extension and run it, it evaluates document.getElementById('...') as null. What's up?
Manifest.json:
{
"name": "CSUF RMP",
"version": "0.1",
"manifest_version" : 2,
"description": "Displays professor ratings on icon click",
"background" : {
"scripts" : ["background.js"]
},
"browser_action": {
"default_icon": "icon16.png"
},
"content_scripts": [
{
"matches": ["https://mycsuf.fullerton.edu/*"],
"js": ["script.js"]
}
],
"permissions": ["<all_urls>", "*://*/*", "http://*/*", "https://*/*"]
}
Background.js:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "script.js"});
});
My script.js is literally what I posted at the top. The script is supposed to have access to the web page's DOM (thus I need a content script) and run it on click of the icon (hence the background.js)
I can get the page to run and show an alert or something, but that line isn't evaluating the page's dom, just null.
I think I know what is the problem here,
you are executing script.js just like a normal script, and a normal script can't interact with the page DOM, you can think about it as just runing a script from a file- it don't have the content script's privileges that way.
What you can do is open a new tab (with the url of the content script), and then pass to the content script at that new tab a message which tells him to run a specific function there.
You can test it without using message sending by setting the onload of the content script to something like: onload=alert(document.getElementById('...')); and than open a new tab from the background page: chrome.tabs.create({"url":"https://mycsuf.fullerton.edu"});
tell me how it goes :)
Edit: forgot to mention that you need the 'tabs' permission in your manifest file in order to open new tabs and test the thing out.

Do not display popup when clicking Chrome Extension browser action button

I want my Chrome extension to behave such that when a user clicks on the extension button, it sends a message and then closes the popup. I have nothing I want to display in the popup and ideally don't want it to even appear in the first place.
Half the time, my code works. The other half of the time, that little empty white bubble remains even after the message has been sent. Why is this non-determinism occurring? Is there a way to simply send a message on clicking the extension button and bypassing the pointless popup appearing?
Here is my popup.js:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
// Go immediately to background script.
// This popup's thread of execution will get killed as soon as we move to another tab.
chrome.extension.sendRequest({
tab: tabs[0],
message: "Button was clicked"
});
window.close();
});
which is included in the following popup.html:
<head>
<script src="popup.js"></script>
</head>
<body>
</body>
My manifest.json (with irrelevant fields removed) is:
{
"name": "My Extension",
"description": "This is my extension",
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["content.js"]
}
],
"background": { "scripts": ["background.js"] },
"browser_action": {
"default_popup": "popup.html"
},
"permissions": [
"http://*/*",
"https://*/*",
"tabs"
],
}
You just declared default_popup in manifest.json, that means once browser action is clicked, the popup.html will show up. If you don't want that, just remove that field and listen to chrome.browserAction.onClicked in background.js.
manifest.json
{
...
"browser_action": {},
...
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.runtime.sendMessage({tab: tab, message: "Button was clicked"});
});

Chrome extension to load the script without clicking on icon

Hello all i want to load the script whether or not user clicks on my extension icon
This is my extension it works great but i want it to work without making the user click on the icon to load the scripts ..
Here is the code .
{
"name": "Injecta",
"version": "0.0.1",
"manifest_version": 2,
"description": "Injecting stuff",
"background":
{
"scripts": ["jquery.js","background.js"]
},
"browser_action": {
"default_title": "Inject!"
},
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
]
}
This is my background.js
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.executeScript({
file: 'jquery.js'
});
chrome.tabs.executeScript({
file: 'inject.js'
});
});
i just want the extension to load all the scripts with the page load. currently user has to click on the icon to load the scripts..
What executeScript does is basically creating a Content Script dynamically. This is called Programmatic Injection.
An alternative method of working with content scripts is specifying them in the manifest. This achieves exactly what you're asking: content scripts are executed automatically when the page is loaded.
"content_scripts" : [
{
"js": ["jquery.js", "inject.js"],
"matches": ["*://*/*"]
}
],
Adjust the matches parameter to only include match patterns for pages you want it to run on.
Make sure to check out the documentation of run_at parameter if you need to fine-tune when injection happens.
if (typeof jQuery === 'undefined') {}

Run the script only onclick on chrome extension

Whenever my chrome extension icon is clicked, I want to run a script that would make certain changes to the current webpage.
I have tried using content_scripts in my manifest and it worked but the problem is , the script runs even if I did not clicked on the icon.
I have found that, I need to use background script.In my background.js file I have added
chrome.browserAction.onClicked.addListener(function(tab) {
alert();
});
and it is not working.
Here is my manifest file.
{
"manifest_version": 2,
"name": "Reveal Password",
"description": "Reveals password in password input field",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
}
}
Plus I want to execute the script that I made that manipulates the current web page too.
Use chrome.tabs.executeScript() to execute code in a tab like this:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({
code: 'alert("Hello")'
});
});
Instead of code, you could also use a file which contains the code :
chrome.tabs.executeScript(null, {file: "content_script.js"});
NOTE : You need activeTab permissions to execute code in an active tab
"permissions": [
"activeTab"
]

How to have background script and something similar to a default popup?

So, I understand that you cannot have background scripts and a default popup together. If this is so, how can I have something similar to a default popup (where there is some simple HTML that appears when you clicked the extension's icon) and have the background script modify the contents of that popup?
Here's the manifest.json
"browser_action": {
"default_title": "Mark this position!",
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": ["content.js"]
}
],
You absolutely can have both a popup (i.e. default_popup set) and a background page. The background page will have its own lifecycle (with "persistent": false it's an Event page) and the popup will exist as long as it's open.
I guess your confusion stems from the fact that you cannot have a popup and a chrome.browserAction.onClicked listener at the same time.
This is true, but there are other ways to tell your background page that the popup has opened.
You can message the background page from the popup:
// popup.js, should be included in the popup
chrome.runtime.sendMessage({popupOpen: true}, function(response) {
/* process response */
});
// background.js
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if(message.popupOpen) {
/* do stuff */
sendResponse(response);
}
});
If you put the above popup code on the top level, then the background will be informed as soon as the popup opens.
While you can directly access the popup's window from the background (see chrome.extension.getViews), it's recommended that you move the UI logic into the popup itself and communicate with the background using Messaging as above and shared chrome.storage.

Categories