Is my chrome extension idea a content script or background script? - google-chrome

I'm looking to create a chrome extension that will mute/unmute certain tabs after a action is executed (like opening a new tab that autoplays audio). This would be my first chrome extension, so I'm curious as to if this would be a background script of a content script, thanks in advance!

I played with playing sounds in different tabs with chrome extensions, and it does require background scripts for the sounds.

To use most of APIs in chrome namespace you need a background script.
To mute a tab use chrome.tabs.update.
To detect a change in the tab's audible/muted state use chrome.tabs.onUpdated listener.
chrome.tabs.onUpdated.addListener((tabId, change, tab) => {
const { audible, mutedInfo } = change;
if (audible || mutedInfo && !mutedInfo.muted) {
chrome.tabs.update(tabId, {muted: true});
}
});

Related

JS Userscript: accessing DOM of new tab

I'm writing a Chrome userscript to open a new tab, then click on some DOM elements. But how can I access the DOM of the new tab?
/* background script */
chrome.browserAction.onClicked.addListener(() => {
chrome.tabs.create({"url": MY_URL, (tab) => {
// What ought I to do?
});
});
You will need to have at least one content script file loaded in your tab (with the right permissions to allow the content script to be loaded).
In the content script, you will have to leverage the Messaging API to communicate with the background page.
If your logic is simple enough, you could even run all logic directly inside content script, as they have access to be same set of chrome API as the background page.

Background scripts vs Content Scripts

I am trying to develop a chrome extension which saves the url of webpages opened in all tabs and then load them whenever needed. Now I know content scripts, background scripts and popup.js. Content scripts mainly deal with the content of the loaded webpage and they have less chrome api interactions, background scripts are executed in an isolated environment and we can use all chrome api methods, popup.js is simply javascript that runs in context of popup.html.
Now here is my problem, I have a button in popup.html named "save" and on click of that button I want to save all the webpage urls opened in multiple tabs under one window. How can I do that?
Should I write a content or a background script?
Sorry for my noobish question. I am new to chrome api. Any help/suggestions?
Neither content script or background page is needed. You could do that just in popup.js, since popup page actually runs in the same context with extension.
In your popup.js, just call chrome.tabs.query to get tab info, including url (you would need to declare tabs permissions in manifest.json). If you want to specify window id, either use WINDOW_ID_CURRENT or retrieve it through other ways (depends on your logic)
chrome.tabs.query({ windowId: YOUR_WINDOW_ID }, (tabs) => {
tabs.forEach((tab) => console.log(tab.url));
});

Google Chrome Extension - background script

After messing around with Chrome Extension I noticed that when you are on the chrome://extensions page a background script initiated in the manifest file will run where as if you are just browsing the internet or on another other page besides the extension page the background script will not run.
Here is what I mean:
In my Manifest file:
"background": {
"scripts": ["jquery-latest.js","background.js"]
},
Now in the background.js file:
$(document).ready(function(){
alert("working");
});
I use a simple alert function to see if this will work and found out that alert("working"); only gets displayed when I am on the chrome://extension directory. If I go to google.com or something of that sort, no cigar.
My question lies in, why does this happen? How do I change it so it does alert no matter what.
The background script should be viewed as "running in the background of the Chrome browser".
Your desired effect (running a script for every page) is actually a task for content scripts.
To learn more, read https://developer.chrome.com/extensions/overview.html#arch.
It is because you are using the background page .. use the event page instead by slightly modifying the manifest.json..
Try adding this:
"background": {
"scripts": ["jquery-latest.js","background.js"],
"persistent": false
},
for more details on event pages check this : https://developer.chrome.com/extensions/event_pages
The effect is produced because whenever you load chrome://extensions it forces the extensions to reload, the same behavior can be reproduced using CTRL+R. So every time, the background page got a fresh reload, which doesn't happen in case of other pages.
The background script is a script running in the background to handle majority of chrome events that content scripts cannot. Content scripts are purely the content of the each page. Both cannot speak to each other, however, you can give the scripts listeners (e.g. chrome.browserAction.addListener(myFunction) plays the function when the button in the top right of your screen for the extension is clicked) order to find out whether a button has been pressed or even send a message from the background script into the page's console.
https://youtu.be/ew9ut7ixIlI
This video was a great introduction for me about background scripts, however, the part where he begins to talk about the listeners and such is 6:30.

registering browser google chrome extension for resize event

I'm new to google chrome extension development. i want to register my extension javascript to listen for the browser resize event. How can i do this ?
Currently
window.addEventListener("load",myfunction,false);
in the extension javascript was able to execute myfunction when i launch the browser
but
window.addEventListener("resize",customfunction,false);
doesnt execute customfunction on browser window resize..
How can we fix this problem ?
One thing you can try is using the following in a content script:
window.onresize = function(event) {
console.log("Resized");
};
This will log "Resized" to your console every time you resize the window. With that in mind, you can look into Message Passing, which you could use to send a message to your popup.js (or other background script) anytime the window has been resized, and then you can handle it accordingly. Also, apparently adding this functionality by way of chrome.windows.onResize is still an in-progress bug.

How can I open my extension's pop-up with JavaScript?

I am trying to write a JavaScript function that will open my extension like when the extension icon is clicked. I know how to open my extension in a new tab:
var url = "chrome-extension://kelodmiboakdjlbcdfoceeiafckgojel/login.html";
window.open(url);
But I want to open a pop-up in the upper right corner of the browser, like when the extension icon is clicked.
The Chromium dev team has explicitly said they will not enable this functionality. See Feature request: open extension popup bubble programmatically :
The philosophy for browser and page action popups is that they must be triggered by user action. Our suggestion is to use the new html notifications feature...
Desktop notifications can be used progammatically to present the user with a small HTML page much like your popup. It's not a perfect substitution, but it might provide the type of functionality you need.
Chrome team did create a method to open the popup programmatically, but it's only enabled as a private API, and plans to make it generally available have stalled due to security concerns.
So, as of March 2018 as of now, you still can't do it.
Short answer is that you cannot open browserAction programmatically. But you can create a dialog with your content script which emulates your browserAction and display that isntead (programmatically). However you won't be able to access your extension's background page from this popup directly as you can from your popup.html. You will have to pass message instead to your extension.
As mentioned there is no public API for this.
One workaround I have come up with is launching the extension as an iframe inside a content script with a button click. Whereby the background script emits the extension URL to the content script to be set as the iframe's src, something like below.
background.js
browser.runtime.onMessage.addListener((request) => {
if (request.open) {
return new Promise(resolve => {
chrome.browserAction.getPopup({}, (popup) => {
return resolve(popup)
})
})
}
})
content-scipt.js
const i = document.createElement('iframe')
const b = document.createElement('button')
const p = document.getElementById('some-id')
b.innerHTML = 'Open'
b.addEventListener('click', (evt) => {
evt.preventDefault()
chrome.runtime.sendMessage({ open: true }, (response) => {
i.src = response
p.appendChild(i)
})
})
p.appendChild(b)
This opens the extension in the DOM of the page the script is running on. You will also need to add the below to the manifest.
manifest.json
....
"web_accessible_resources": [
"popup.html"
]
....
You could emulate the popup by displaying a fixed html element on the page in the same location the popup would be and style it to look like the popup.
I had the same requirement: When the user clicks on the extension icon a small popup should open. In my case, I was writing an extension which will give updates on selective stocks whenever the icon is clicked. This is how my popup looked.
If you were having the same requirement then please read the answer below.
This is how my manifest.json file looked.
All the heavy lifting was handled by manifest.json file only. There is a section browser_action inside which there is a key called default_popup, just put the name of the HTML file that you want the popup to display.
I wanted my extension to work on all the pages that's why I added the attribute matches under content_scripts. I really didn't need to put the jquery file jquery-3.2.1.js inside the js array but the extension manager was not allowing me to keep that array empty.
Hope this helps, do comment if you have any doubt regarding the answer.