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.
Related
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.
I have an extension, functional on Chrome, that monitors the active Tab for URL changes.
Specifically, I need to detect when the URL changes, but there is no new page load or navigation. Some sites do this (e.g. when you click to view another video on YouTube).
On Chrome, I accomplished this with:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo && changeInfo.status == "complete") {
//do stuff here
}
});
How do I detect such changes in a Firefox add-on?
I've been told to use: Listening to events on all tabs, but I couldn't put it together. One of the problems was that gBrowser was not defined in the extension.
What am I doing wrong?
Is there a simpler way?
Use ProgressListener to be notified about location changes.
To install a listener, convert SDK tab to its raw (old) representation using viewFor.
Backward conversion is possible with modelFor and getTabForContentWindow.
const tabs = require("sdk/tabs");
const {viewFor} = require('sdk/view/core');
const {modelFor} = require('sdk/model/core');
const {getBrowserForTab, getTabForContentWindow} = require("sdk/tabs/utils");
const {Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
var progressListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
onLocationChange: function(aProgress, aRequest, aURI) {
var highLevel= modelFor(getTabForContentWindow(aProgress.DOMWindow));
console.log("onLocationChange ", highLevel.url);
}
};
tabs.on('open', function(newTab) {
var lowLevel = viewFor(newTab);
var browser = getBrowserForTab(lowLevel);
browser.addProgressListener(progressListener);
});
Don't forget to remove listeners on extension unload. Tab listeners are removed automagically, but ProgressListeners won't be.
Inspired by
Converting to chrome windows
If you're using the add-on SDK, you're looking at the wrong docs. Here are the tab docs.
As stated there, you create a listener like so:
var tabs = require("sdk/tabs");
// Listen for tab openings.
tabs.on('open', function onOpen(tab) {
myOpenTabs.push(tab);
});
// Listen for tab content loads.
tabs.on('ready', function(tab) {
console.log('tab is loaded', tab.title, tab.url);
});
All the docs you look at should be a subset of developer.mozilla.org/en-US/Add-ons/SDK.
I find that the activate and pageshow events, between the two of them, cover all changes in URL that I can conjure up between switching tabs, opening pages in a new tab, closing tabs, refreshing pages, and typing in new URL's.
var updateURL = function (tab) {
var oldURL = url;
var url = tab.url;
console.log(url);
};
tabs.on("activate", updateURL);
tabs.on("pageshow", updateURL);
I have SAPUI5 application where I am using Shell. I have different views in my Shell and I am able to navigate from one view to another. The problem is that I don't know how can I create or change URL adress to each view. I need to set URL adresses to be able to use "back" button in a browser. I want to add unique URL adress to each view inside my Shell to use "back" and "forward" buttons.
Thanks!
Take a look at this simple sap.ui.core.routing.Router example it shows how to easily set up and use routes and a hash changer with an app Shell container.
sap.ui.core.routing is a javascript routes utilty, it handles URL changes and dispatches control based on pattern logic to views and event handlers, part of routing is HashChanger and History functionality.
if you are using the desktop shell this routing example with sap.ui.ux3.Shell
A lot of examples use jQuery.sap.history.js IMO it doesn't properly support bookmarks and has limited features which means you have to use it with other techniques
Unfortunately, History API presents in modern browsers only. For IE6+ I recommend you to use "hashchange" event of window:
function router(){
var sViewName = window.location.hash.slice(1),
oView = sap.ui.getCore().byId(sViewName) || new sap.ui.view.XMLView({id : sViewName, viewName : sViewName});
sap.ui.getCore().byId("uxShell").setContent(oView);
return false;
}
if("onhashchange" in window){
if(window.attachEvent){ //IE8
attachEvent('onhashchange', router);
} else if(window.addEventListener){ //IE9+, Chrome, Opera, Firefox
addEventListener('hashchange', router);
}
} else { //IE6-7
var oldHref = window.location.hash;
setInterval(function(){
var newHref = window.location.hash;
if(oldHref !== newHref){
oldHref = newHref;
router();
}
}, 100);
}
But to make it work you need to set href property to navigation items like this: #catalog.viewName
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.
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.