Firefox Extension - New Tab - How To Override Preferences? - firefox

I am new to Firefox extension, that is why I use the Add On SDK.
I want to create an extension that shows a specific site every time the user opens up a new tab. This is my code so far:
var self = require("sdk/self");
var tabs = require("sdk/tabs");
// Listen for tab openings.
tabs.on('open', function onOpen(tab) {
getActiveTab();
});
function getActiveTab(){
tabs.on('activate', function (tab) {
tab.url = "http://www.example.com";
});
}
This works. But before it loads the specified domain it loads the Firefox default newtab page. Now is there an API reference to access the newtab setting and change to example.com?
Thanks,
Gerd

It was possible to change about:newtab URL using SDK:
require('sdk/preferences/service').set('browser.newtab.url', 'http://www.stackoverflow.com');
but it becomes obsolete with FF41, as there isn't a browser.newtab.url preference any more.
If you still plan on using it, you might also consider adding this to your code:
var { when: unload } = require('sdk/system/unload');
var reason;
unload( function ( reason ) {
require('sdk/preferences/service').set('browser.newtab.url', 'about:newtab');
});
so that the preference change gets undone after add-on unload. You can also pass one of unload reasons to the function: 'uninstall', 'disable', 'shutdown', 'upgrade', or 'downgrade', or not provide reason argument at all / leave it undefined.

Since the browser.newtab.url preference has been removed, this is the new way to do this: https://github.com/sblask/firefox-open-tabs-next-to-current/blob/master/lib/helpers.js#L50 The code of the module can be found here: https://dxr.mozilla.org/mozilla-central/source/browser/modules/NewTabURL.jsm
If you also want to replace the homepage, you have to change the browser.startup.homepage preference.

Related

How to get the current tab's history in a Web Extension in Firefox?

Is there an API that makes it possible to get the current tab's history in a Web Extension in Firefox? Just like when clicking and holding on the Back button, a dropdown will appear to show the current tab's history.
No. You cannot ask for the list for a certain tab by default.
You can, however, listen for the tab events onUpdated, onCreated etc. Using the tabId which stays the same, you can keep a list of URLs in a background script (background.js) which is always running if the addon is enabled.
You would do it like this:
let arr=[]; // At the top of background.js
browser.tabs.onCreated.addListener(handleCreated); // Somewhere in background.js
function handleCreated(tab) {
let tabId = tab.id;
if(arr[tabId]==null) arr[tabId] = [];
arr[tabId].push(url);
}
function getHistoryForCurrentTab(){
function currentTabs(tabs) {
// browser.tabs.query returns an array, lets assume the first one (it's safe to assume)
let tab = tabs[0];
// tab.url requires the `tabs` permission (manifest.json)
// We will now log the tab history to the console.
for(let url of arr[tab.id]){
console.log(url);
}
}
function onError(error) {
console.log(`This should not happen: ${error}`);
}
browser.tabs.query({currentWindow: true, active: true}).then(currentTabs, onError);
}
The above code is a proof of concept. Some improvements you will need to consider: implement onClosed which resets the tab history for that id (arr[tabId] = null), implement onUpdated (will be needed for sure, same logic as in handleCreated).
Links:
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs

LightSwitch Tabbed screen in Browse template

I have a screen where we have 4 tabs, each tab should be displayed as per the login priority.
Ex:Department,Role,Employee,Screen are the tabs.
Each tab is having buttons to add,edit,remove the data.
by default when i log with any user its going to the first tab, but not all the users are having the first tab as their requirement.
how can i resolve this to do it dynamically in html client application
As covered towards the end of the following LightSwitch Team blog post, you can programmatically change the tab by using the screen.showTab method:
Creating a wizard-like experience for HTML client (Andy Kung)
However, in order to use this showTab API command when your screen is loading, its use needs to be delayed until the screen has fully displayed. This can be achieved in your screen's created method by using a combination of the jQuery mobile pagechange event (as the LightSwitch HTML Client uses jQuery mobile) and a setTimeout with a zero timeout (to delay the showTab until the loading screen is rendered).
The following shows a brief example of how you can use this approach to dynamically set the initial screen tab:
myapp.BrowseScreen.created = function (screen) {
var initialTabName = localStorage.getItem("Rolename") + "Tab";
$(window).one("pagechange", function (e, data) {
setTimeout(function () {
screen.showTab(initialTabName);
});
});
};
Based on your earlier post it appears that you're using LocalStorage to track your logged in user and their role.
On this basis, the above example assumes that the user's role will be the factor dictating the tab they are shown when the screen loads (the screen is named BrowseScreen in the above example).
It also assumes that your tabs are named after each employee role (suffixed with the text 'Tab') e.g. a user who is assigned the role 'DepartmentManager' would be directed to a tab called 'DepartmentManagerTab'.
Whilst slightly more involved, if you'd prefer to avoid the pagechange and setTimeout it's possible to customise the LightSwitch library to introduce a new navigationComplete screen event. This new event is ideal for executing any operations dependent upon the screen having fully rendered (such as navigating to a different tab using the showTab function).
If you'd like to introduce this additional event, you'll need to reference the un-minified version of the LightSwitch library by making the following change in your HTML client's default.htm file (to remove the .min from the end of the library script reference):
<!--<script type="text/javascript" src="Scripts/msls-?.?.?.min.js"></script>-->
<script type="text/javascript" src="Scripts/msls-?.?.?.js"></script>
The question marks in the line above will relate to the version of LightSwitch you're using.
You'll then need to locate the section of code in your Scripts/msls-?.?.?.js file that declares the completeNavigation function and change it as follows:
function completeNavigation(targetUnit) {
msls_notify(msls_shell_NavigationComplete, { navigationUnit: targetUnit });
var screen = targetUnit.screen;
var intialNavigation = !screen.activeTab;
var selectedTab = targetUnit.__pageName;
if (screen.activeTab !== selectedTab) {
callNavigationUnitScreenFunction(targetUnit, "navigationComplete", [intialNavigation, selectedTab]);
screen.activeTab = selectedTab; // Set at the end of the process to allow the previous selection to be referenced (activeTab)
}
}
function callNavigationUnitScreenFunction(navigationUnit, functionName, additionalParameters) {
var screenObject = navigationUnit.screen;
var constructorName = "constructor";
var _ScreenType = screenObject[constructorName];
if (!!_ScreenType) {
var fn = _ScreenType[functionName];
if (!!fn) {
return fn.apply(null, [screenObject, navigationUnit].concat(additionalParameters));
}
}
}
You can then use this new event in your screens as follows:
myapp.BrowseScreen.navigationComplete = function (screen, navigationUnit, intialNavigation, selectedTab) {
if (intialNavigation) {
var initialTabName = localStorage.getItem("Rolename") + "Tab";
screen.showTab(initialTabName);
}
};
This event fires whenever a navigation event completes (including a change of tab) with the initialNavigation parameter being set to true upon the initial load of the screen and the selectedTab parameter reflecting the selected tab.
Although modification to the LightSwitch library aren't uncommon with some of the more seasoned LightSwitch developers, if you decide to go down this path you'll need to thoroughly test the change for any adverse side effects. Also, if you upgrade your version of LightSwitch, you'll need to repeat the library modification in the new version.

firexfox extension toggle on off on icon click

I develop my first firefox extension. My usecase (already sucessfully implemented as a chrome extension):
Inject CSS of a specific page
Default load: contentscript-on.js
On Click icon (icon-on.png / icon-off.png) switch from contentscript-on.js to contentscript-off.js and backward
The contentscript-on.js already works on page load. I´ve searched a lot to find help or an example for my usecase. Any ideas?
Thank you very much!
main.js
var pageMod = require("sdk/page-mod");
var self = require("sdk/self");
pageMod.PageMod({
include: "https://app.example.de/dashboard",
contentScriptFile: [self.data.url("jquery-1.11.0.min.js"), self.data.url("contentscript-on.js")]
});
In my chrome extension, I use a background.js to toggle on / off and switch between the scripts
//toggle = true, because the contenscript-on.js is already loaded on initial loading of the page
var toggle = true;
chrome.browserAction.onClicked.addListener(function(tab) {
toggle = !toggle;
if(toggle){
//change the icon after pushed the icon to On
chrome.browserAction.setIcon({path: "icon-on.png", tabId:tab.id});
//start the content script to hide dashboard
chrome.tabs.executeScript({file:"contentscript-on.js"});
}
else{
//change the icon after pushed the icon to Off
chrome.browserAction.setIcon({path: "icon-off.png", tabId:tab.id});
//start the content script to hide dashboard
chrome.tabs.executeScript({file:"contentscript-off.js"});
}
});
Is there a similar way to this in firefox extensions?
The PageMod constructor has an optional onAttach property which passes a content worker to your function. This worker can be destroyed to remove the scripts from the page
var contentWorker; // Global (or greater scope) variable
// …
onAttach: function(worker) {
contentWorker = worker;
}
Then, in your click listener
var tab = contentWorker.tab;
contentWorker.destroy();
contentWorker = tab.attach( {
contentScriptFile: [self.data.url("jquery-1.11.0.min.js"), self.data.url("contentscript-off.js")]
});
Frankly, it would probably be easier just to attach both and toggle them somehow from within the content script code
As a side note, there's a new toggle button that you can can use that will have an activated/deactivated look that sounds like it would be good for your scenario.

firefox addon page-mod - when url doesn't match

I want to be able to activate a widget if a url matches some pattern, but the problem is I also want to disable the widget when page-mod rule doesn't match the url.
So if I have few tabs open and if I switch between them I should be able to somehow disable the widget if an active tab's url doesn't match the rule, or in other case activate it. The state of widget(on/off) should be changed on loading pages and switching through tabs.
I've been struggling with this for a while and still haven't found a solution.
This is where I'm at right now:
// Activates on matching one of the site domains, but I also want to deactivate
// it when it does not match
var pageMod = require("page-mod");
pageMod.PageMod({
include: ["*.site1.com","*.site2.com"],
onAttach: function() {
alert("Widget activated!");
});
});
Thank you for any help!
If I understand correctly what you are trying to do then page-mod is the wrong solution - you simply want to listen to the active tab. Use tabs module for that, listen to ready (new URL loaded) and activate (active tab changed) events:
var tabs = require("tabs");
tabs.on("ready", function(tab)
{
if (tab == tabs.activeTab)
updateActiveTab(tab);
});
tabs.on("activate", function(tab)
{
updateActiveTab(tab);
});
Your updateActiveTab() function would need to check tab.url and activate or deactivate the widget then. If you want to use patterns for that like the ones you specify for page-mod then you need to use the internal match-pattern module, like this:
var {MatchPattern} = require("match-pattern");
var patterns = [
new MatchPattern("*.site1.com"),
new MatchPattern("*.site2.com")
];
function updateActiveTab(tab)
{
var matches = false;
for (var i = 0; i < patterns.length; i++)
if (patterns[i].test(tab.url))
matches = true;
if (matches)
activateWidget();
else
deactivateWidget();
}
But of course you can just use a regular expression or something like this to test tab.url, you don't have to use the match-pattern module.
Disclaimer: The code examples are only there to make the approach easier to understand, they haven't been tested.

Limit a firefox extension to a specific domain

I would like to write a firefox extension. This extension is not a generic extension but work specifically for a domain where I need to highlight specific html components.
How should I do that? I just want the js loaded when the user is browsing a specific domain.
My current overaly.js is basically empty (generated by the Extension Wizard):
var myextension = {
onLoad: function() {
// initialization code
this.initialized = true;
this.strings = document.getElementById("myextension-strings");
},
onMenuItemCommand: function(e) {
var promptService = Components.classes["#mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
promptService.alert(window, this.strings.getString("helloMessageTitle"),
this.strings.getString("helloMessage"));
},
onToolbarButtonCommand: function(e) {
// just reuse the function above. you can change this, obviously!
myextension.onMenuItemCommand(e);
}
};
window.addEventListener("load", myextension.onLoad, false);
And my ff-overlay.xul is:
myextension.onFirefoxLoad = function(event) {
document.getElementById("contentAreaContextMenu")
.addEventListener("popupshowing", function (e){ myextension.showFirefoxContextMenu(e); }, false);
};
myextension.showFirefoxContextMenu = function(event) {
// show or hide the menuitem based on what the context menu is on
document.getElementById("context-myextension").hidden = gContextMenu.onImage;
};
window.addEventListener("load", myextension.onFirefoxLoad, false);
I was thinking to go neanderthal and do a check inside myextension.onFirefoxLoad to see if the currentpage is the one I want but that requires the user to click the proper item on the context menu.
I'm not totally following what you have because both of those look like JS files, not XUL files. But what you probably want to do is listen for the load event coming from the web pages that are loaded. Then, in your event loader, just look at each page that loads and see whether it's coming from the specific domain you want.
A great (though not always quite as easy as it sounds) way to find out how to do something in a Firefox addon is to find another addon that does something similar. DOM Inspector and Inspect Context are your friends! The first such addon that comes to mind in this case is WikiTrust so you could try looking at that one to see if it gives you any inspiration.

Resources