How can I change the state of the check box? [duplicate] - html

I am here asking how is it possible for my chrome extension to be able to "survive" throughout the user refreshing the page and changing page after selecting a feature.
For an example let's use a rather generic background color changing setting which changes the background color of a desired site. Once ticking the enable box and having the background changed to the option selected, it does not stay persistent after changing page or refreshing. I am here asking if someone could possibly help me with some sort of helpful resources which are more helpful than the developer.chrome site.
EDIT: for much better example of my question which is my bad. If anyone of you are aware of such extensions like "BetterTTV" for Twitch, it has a menu of options. One of these options is the "night" option which mentioned prior turns the entire site to "night colors" such as whites to black and black text to light. This option once enabled is seen through the entire site and even once Chrome is closed is still enabled to be producing changes next time opened. If i am correct in understanding what has been said, using Chrome storage will preserve such actions enabled by the user to be produced on the page till disabled.
Thank you.

A content script can survive for the same time that a webpage remains in the tab (i.e. not through refresh, or navigating to a new page). You can not make this longer. A background script can exist for the time that Chrome is running from starting Chrome through exiting. If you want to save settings, you can use chrome.storage, or store the setting in the background page. You can then read the settings, or get them from the background page, when your content script starts again when the page is refreshed, or the user navigates to a new page. Using chrome.storage will allow you to persist the option until turned off. Using chrome.storage, even if Chrome is exited and restarted later, the option information will still be available. If you just store the data in a variable in the background page, it will not persist through exiting and restarting Chrome.
If you are changing a setting in a content script it will live only as long as the content script unless you get the information somewhere will it will persist longer. That means chrome.storage or messaging the information to a background script. Either way, if you want to have the setting active when the content script next runs (refresh, navigating) you will have to get the setting back (e.g. reading from chrome.storage or receiving a message from a background script).
In general, changing options in the content script is, probably, not a good idea. It is uncommon for such to be done in the content script. On the other hand, depending on what you are doing, changing some of your extension's options in a content script may be the most appropriate.
How best to organize this depends on what you are doing. To go further really requires more information from you (e.g. code that shows what you are doing). There are many examples around of having settings persist, although usually not changed from a content script. Settings are mostly changed from options pages, popups, etc.
If your function is as simple as "ticking the enable box and having the background changed to the option selected", having the selection take place in the content script is not a good idea. In that case, you should have a browser_action button which is either a toggle, or that brings up a popup where a checkbox could be ticked (if you have multiple options). The background script would then inject the content script using chrome.tabs.executeScript() only when the feature was enabled.
Update:
Based on the new information you have added to your question, it sounds like you should use a popup which will allow you to have multiple options, or a list of sites on which your add-on is enabled. If you are looking for an example, you can take a look at the Chrome developer options page example. You can have that as a popup with a `browser_action button in addition to being an options page by adding the following to your manifest.json
"browser_action": {
"default_icon": {
"48": "myIcon.png"
},
"default_title": "Show panel",
"default_popup": "options.html"
},
If interested, my answer to this question shows using a single page as both an options page and popup. It shows how to get the data from the options page into chrome.storage and read it back. It is a bit more complicated than potentially desired as it shows four slightly different methods of communicating the information from the popup to a background page. It is tested and working in both Chrome and Firefox.
Here is an example of reading data (useDirect and emailAddress) from chrome.storage and placing the information in the DOM (to show the current value on an options page/popup):
// Restores select box and input using the preferences
// stored in chrome.storage.
function useStoredOptionsForDisplayInDOM() {
chrome.storage.local.get({
useDirect: 0,
emailAddress: '',
enabled: false
}, function(items) {
//Store retrieved options as the selected values in the DOM
document.getElementById('useDirect').value = items.useDirect;
document.getElementById('email').value = items.emailAddress;
document.getElementById('enabled').checked = items.enabled;
});
}
This is how those same values are stored in chrome.storage:
function saveOptions() {
let useDirectValue = document.getElementById('useDirect').value;
useDirectValue = +useDirectValue; //Force to number, not a string
let email = document.getElementById('email').value;
let functionEnabled = document.getElementById('enabled').checked;
chrome.storage.local.set({
useDirect: useDirectValue,
emailAddress: email,
enabled: functionEnabled
});
}
And the <body> of the HTML:
<body>
<div id="optionsArea">
Use direct method:
<select id="useDirect">
<option value="0">Option 0</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">option 3</option>
</select>
<div>Email:
<input id="email"></input>
</div>
<label>
<input type="checkbox" id="enabled">
Enable functionality.
</label>
</div>
<script src="options.js"></script>
</body>

Related

How to programmatically make a tab become the active tab?

I am using BroadcastChannel to remotely control the contents shown in another browser window (on the same PC) displayed on a projector. (Basically, the projected window is an extended desktop display.) It has worked nicely so far on both Chrome and Edge, with a short JS script each in the remote controlling page and the controlled page.
However, the projected browser contents are in three different tabs. Currently, I have to switch focus to that projected window and deftly use Ctrl-Tab to get the tab I want to control to become the active tab.
How do I programmatically select which tab to become active? If there's no generic method, I am happy to have a solution just for Chrome or Edge.
If the tabs are opened with window.open, you can switch between them using focus(). The sample code is like below:
<input type="button" onclick="window1.focus()" value="switch to window1" />
<input type="button" onclick="window2.focus()" value="switch to window2" />
<script>
var window1 = window.open("https://samplesite.com/window1");
var window2 = window.open("https://samplesite.com/window2");
</script>
If not, it's impossible to switch between the tabs due to security reasons. If it were possible, it would be a risk that attackers would find a way to gain access to information about the other tabs a user has opened.
Besides, if you're making a browser extension, you can switch between tabs using chrome.tabs API. For more information and sample code, you can refer to this answer.

Is there a certain page I should be fetching my API data from within my Chrome Extension Project?

I am making a chrome extension that fetched JSON data from CoinMarketCap.com API and currently I have it running in the background script. I'm not 100% sure what the purpose of the page is really. I was wondering if I could simply fetch the data from the popup script after I click a button within my popup?
Each button represents a different coin. I basically want to get the price of a chosen coin and display it on whatever page the user is on when they double click the coin in a text article. Eventually I want to make it so you can double click any coin and have it show a live price conversion while you're on the web-page.
The point of a background page is to be always available (running if persistent: true, woken up / recreated for registered events if persistent: false).
A popup's lifetime is determined by its visibility. The moment the user clicks away and closes it, the page is closed (as if the tab with it was closed), so it can no longer process any events and its state is lost.
As long as:
The data you need fetched is to be received/processed while the popup is open
Any state you need to persist between popups being shown can be stored in chrome.storage
Then you don't need the background page to do the fetching. Popup page has the same level of access to Chrome APIs.
However, consider this scenario: suppose you want the data to be ready as soon as popup is opened (at least, you want it to be fresher than "since last time"). You may want to do periodic updates even while the popup is closed to refresh the data. You can only do that reliably with a background page (and, say, chrome.alarms API). Then you can cache the latest available data in chrome.storage and use that in the popup.
Background pages have their uses as some code that can run periodically regardless of user actions, and to be able to always react to events.
According to Changes to Cross-Origin Requests in Chrome Extension Content Scripts now you have to do your fetches in Background Script. Not in Content Script.

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 page or event page?

I'm building a Google Chrome extension at the moment and I have a question about when to use an event page.
A quick look at the Chrome extension docs shows that Google really want its developers to use event pages, if possible.
My extension currently uses a background page, but I was wondering if I should switch to an event page?
This is what my extension does:
When matched with a particular website, it injects a script that adds buttons for the user to access extra functionality.
Most of this extra functionality consists of doing fairly computationally expensive operations on user-entered data - this is all done in the background page (it is all it does).
When a user wants to run these operations on their data they press a button and this passes a message, from the injected script to the background page, which then passes a message back containing the results of its operations.
Essentially, all the background page is doing is waiting for message passing from an injected script in one particular website and then running some operations. Since it doesn't need to be active all the time, this suggests that I should be using an event page.
Can anyone confirm if this would be a good idea for me? Or are there reasons why I should stick to a background page?
Allowing the background page to suspend (chrome.runtime.onSusend) is great, because it will free up system resources. The page will automatically be launched when a matching event happens (chrome.tab.onUpdated etc). I can't think of any compelling reason to use a persistent background page. You can always store any long term state in chrome.storage.local or indexedDb, etc.

Duplicate a tab in Chrome without Reloading the Page?

Is there any way to completely duplicate the state of a current tab in Google Chrome? I want an exact copy of the current state of the page without having to reload the page in another tab.
An example use case:
While browsing a "slideshow" on a news website, I want to preserve the current slide that I'm on, but create a duplicate so that I can continue viewing the next slide. If I simply Right-Click and "Duplicate" the tab, the new page will completely Reload, reprocessing all of the Javascript and running the pre-slideshow advertisement again.
In short "NO" you can't.
I am not expert on this
but a similar behavior can be achieved in some ways i know :
Dump the whole DOM
Never tried this though. You can convert the DOM to a string, pass it to the new window and then parse it as a document. This will let you lose your DOM events and State manipulation javascript. (But that's good for your case)
var dtab = window.open('about:blank', 'duplicate_a_tab');
dtab.document.open();
dtab.document.write("... yout html string ..");
dtab.document.close();
Develop an extension
Let the users continue on the current tab with the current state, your extension should be able to capture the screenshot of that area and open that screenshot in new tab. There are plenty of screenshot taking extensions are available in the market.
If that website is your own
You can develop your services that uses state locally like progressive web apps. Give a link separately to 'duplicate' which will eventually open the same URL in different tab with the same local state and with the flag do-not-sync.
This will not work when the user uses browser inbuilt duplicate
feature.