Firefox extension open an HTML options page - javascript

I have an options page for my extension that is made with HTML and javascript tio be activated when options are selected. The extension is a window that hovers over the web page, and it has an "Options" button in it already.
I need to have the options page be opened in a separate tab in the browser when the button is clicked.
What I have so far is:
mainPanel.port.on("options", function () {
currentUser=null;
mainPanel.hide();
var url = serverURL+"/options.html";
tabs.open(url);
});
options.html is stored in the main file for the extension, and serverURL refers to the main server that the extension contacts for information.

In this case you need to use Port.on()/Port.emit() to send a controll option from options.html, like click on setting button.
options.html
var panelIsOpen = 0;
$('#settings').click(function() {
self.port.emit("statusoptions", {optionsIsOpen:1});
});
popup.html
Panel.port.on("statusoptions", function (panda) {
if(panda.optionsIsOpen === 1){
Panel.hide();
tabs.open({
url: "options.html",
onReady: function onReady(tab) {
Panel.hide();
},
contentScriptFile: [
data.url("js/jquery-2.0.0.min.js"),
data.url("js/options.js")],
});
}
});

Related

How to access to the tab object from popup script

I'm new to javascript and I want to code a firefox web extension.
I have a browser action button with a popup. but I didn't define the popup in the manifest, i set it in javascript code, because the click event won't be fired when the popup is defined. So here is the important part of my background script:
browser.browserAction.onClicked.addListener((tab) => {
var tabUrl = tab.url;
browser.browserAction.setPopup({ popup: "/popup/popup.html" });
browser.browserAction.openPopup();
browser.browserAction.setPopup({ popup: "" });
});
In this event the tab object is passed, so I can use the url.
This file is in the /background_scripts folder.
The popup is in the /popup folder. It's a html file with 2 menuitems.
In the popup.js I have an event to get the click:
document.addEventListener("click", (e) => {
if(e.target.id == menuItem1)
{
...
//here i want to use the url of the current tab
});
How I can get the tab object or the url in my popup code?
The tabs.tab.getCurrent() method doesn't work as I understand according to this:
tabs.getCurrent() result is undefined?
and this
How do I include a JavaScript file in another JavaScript file?
doesn't work too.

Store data when popup loses focus

I'm developing a Chrome extension and I would like to preserve user input data when user closes the extension's popup. Is there any reliable way to do this using local storage when the extension popup loses focus?
I managed to figure that one out. When I was calling store functions directly from popup unload callback (detecting lost focus) it didn't work. Managed to do that when I was doing the storage in background page. Sample code below:
Background script:
function storeFormDataLocally(someData) {
if (someData != null) {
chrome.storage.local.set({
'someDataKey': someData
}, function() {
console.log("data saved: " + someData)
});
}
}
Popup:
addEventListener("unload", function(event) {
var background = chrome.extension.getBackgroundPage();
var someData = "My data to store";
background.storeFormDataLocally(someData);
}, true);

Programmatically (or optionally) override Chrome's New Tab page

I've written a Chrome extension that overrides the New Tab page:
manifest.json:
"chrome_url_overrides": {
"newtab": "new-tab.html"
},
Is there a way to make this override optional? That is, I'd like to enable the user to uncheck a checkbox in the options page and disable the New Tab override. This must be possible because when I open a new tab for the first time, there's a popup informing of an extension changing the New Tab settings and asking whether to keep changes or restore settings:
I couldn't find any API for controlling overrides. The New Tab Redirect project doesn't have an option to display the native New Tab.
Google made a Star Wars new tab replacement which allows you to view the default new tab page. The url it uses is chrome-search://local-ntp/local-ntp.html.
Example:
options.html:
<input type="checkbox"> Use default new tab page
options.js:
var checkbox = document.querySelector("input[type=checkbox]")
checkbox.addEventListener("click", function() {
chrome.storage.sync.set({ defaultnewtab: checkbox.checked })
})
newtab.js:
chrome.storage.sync.get("defaultnewtab", function(storage) {
if(storage.defaultnewtab) {
chrome.tabs.update({ url: "chrome-search://local-ntp/local-ntp.html" })
}
})
Instead of using the chrome_url_override you could write a listener that listens for when tabs update using the chrome.tabs.onUpdated.addListener(), then check if the url is chrome://newtab/ and if it is and the check box is ticked, then using chrome.tabs.update() relocate them to another page.
Using the Star Wars method as described #Daniel Herr, I did this, which is working well. Although feels a little hack-y.
I have an option being set in the popup.html whether the Extension is "on" or not.
First off, set the default new tab page using the Chrome defined method:
manifest.json
"chrome_url_overrides": {
"newtab": "newtab.html"
},
Then in your Extension's newtab.html call a new JavaScript file, newtab.js (or whatever).
I am also using jQuery, so my code uses that, but you can do this natively using DOMContentLoaded.
newtab.js
$(document).ready(function(){
// It takes a moment for the Chrome query/update so sometimes there is a flash of content
// Hiding the Body makes it look blank/white until either redirected or shown
$('body').hide();
var background = chrome.extension.getBackgroundPage();
var _app = background._app;
// App is OFF, show Default New Tab
if(!_app._on){
// Get the current Tab
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
var active = tabs[0].id;
// Set the URL to the Local-NTP (New Tab Page)
chrome.tabs.update(active, { url: "chrome-search://local-ntp/local-ntp.html" }, function() { });
});
// App is ON, show custom content
} else {
$('body').show();
}
});
Basically, the methodology is to update the Tab so that it is redirected to chrome-search://local-ntp/local-ntp.html which is the hard URL to the default Chrome NTP.
Since this is a Chrome internal URL -- the URL field still appears blank.

Chrome content script run in all pages in a given tab

I have a Chrome extension (content script) with a popup window. When the user clicks a "Start" button in the popup window, I'd like a new tab to open to a url (say www.test.com), and for the content script to be injected into that tab. Not just executed once, but injected so that it will work on (www.test.com/*) on that same tab. Not in other tabs - just that one.
Here's what I have now:
chrome.tabs.create({
'url': 'http://test.com/shop/new'
}, function(tab) {
chrome.tabs.executeScript(tab.id, {
'file': 'script.js'
});
});
But, chrome.tabs.executeScript is being used, which only executes the script once. The script redirects the page to 'http://test.com/shop/new/xxx', but since the script is only executed once, it stops working when the page changes. Again - how can I make it so that the script is injected into all 'http://test.com/shop/*' pages in that tab?
A good idea is to make a script that is always injected into http://test.com/shop/* (via manifest):
"content_scripts" : [
{
matches: ["http://test.com/shop/*"],
js: ["script.js"]
}
],
Then, in the script, ask the background page if it should be active for this ID:
// script.js
chrome.runtime.sendMessage({shouldIRun : true}, function(response){
if(response) {
// Actually do stuff
}
});
And in the background script, keep a record of tabs that you want it to apply to:
// Background script
var activeTabs = {}; // Slightly more difficult with event pages
// At some point when you enable it, e.g. in a browserAction.onClicked listener
activeTabs[tabId] = true;
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if(message.shouldIRun) {
// Double negation to ensure true/false
sendResponse(!!activeTabs[sender.tab.id]);
}
});
// It's a good idea to clear the stray entries
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
delete activeTabs[tabId];
});
// Sometimes this can also happen
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
if(!!activeTabs[removedTabId]) activeTabs[addedTabId] = true;
delete activeTabs[removedTabId];
});

How to send data from popup script to background.js in crossrider?

I am developing a browser extension using crossrider. I have some resource pages like popup.html and popup.js. In popup.html, there is a form and when user submit the form I want to send the data to my server, which is straight forward. But I also want to send the active tab url along with the form data. But we can get the active tab url in background.js only.
To do this I need to send the form data to background.js and then post them to my server.
So my question is how to send data from popup.js (popup window) to background.js ?
In answer to your direct question, you can send data from the popup scope to the background scope using appAPI.message.toBackground.
However, I think it would be more efficient to get the active tab's URL when the popup is opened so that it's available in the popup when the form is submitted. You can achieve this by requesting the active tab's URL directly from the active tab and saving the response in a var in the popup scope, as follows:
popup.html:
function crossriderMain($) {
// var to store active tab's URL
var activeTabUrl = null;
// Message listener for response from active tab
appAPI.message.addListener(function(msg) {
if (msg.type === 'active-tab-url') activeTabUrl = msg.url;
});
// Request URL from active tab
appAPI.message.toActiveTab({type: 'active-tab-url'});
// THE REST OF YOUR CODE
}
extension.js:
appAPI.ready(function($) {
// Message listener
appAPI.message.addListener(function(msg) {
if (msg.type === 'active-tab-url')
// Send active tab's URL to popup
appAPI.message.toPopup({
type: 'active-tab-url',
url:encodeURIComponent(location.href)
});
});
// THE REST OF YOUR CODE
});
[Disclaimer: I am a Crossrider employee]

Categories