How to get tab in TabOpen event with Firefox FUEL? - firefox

I'm writing a firefox extension and really need to listen on TabOpen events and get some details about tab that was opened. But I can't figure out how do I get an actual tab from event object that my callback receives. Is it somewhere in event.data? Is there a way to inspect this object?
Some code that I have tried so far but it doesn't work:
Application.activeWindow.events.addListener("TabOpen",
function(event) {
Application.console.log("TabOpen");
var tab = event.data.target;
Application.console.log(tab.uri);
}
);

In your code, event.data will give you a BrowserTab object. If you want the current URI of the tab, you'd want tab.uri.spec for the string version, or just tab.uri if you want an nsIURI object.

here is an example from the MDC but without using FUEL:
// add event listener
var container = gBrowser.mPanelContainer;
container.addEventListener("DOMNodeInserted", exampleTabAdded, false);
function exampleTabAdded(event)
{ // listening for new tabs
if (event.relatedNode != gBrowser.mPanelContainer)
return; //Could be anywhere in the DOM (unless bubbling is caught at the interface?)
var browser;
browser = event.target.childNodes[1];
// browser is the XUL element of the browser that's been added
}

I've added some new content to MDC that should help with this; information on how to pull the tab object out of the TabOpen event is now available in the example here:
https://developer.mozilla.org/En/FUEL/Window
Also did some other cleaning up while I was at it. Hopefully this will help (especially once the search index refreshes).

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

Sending data from listener (of httpRequestObserver) to addon panel (iframe)

I am trying to create a fire-bug like extension for firefox which is actually dev-tool extension. I have registered httpRequestObserver to observe http-on-examine-response event. I have a listener with below method implemented.
onDataAvailable: function(request, context, inputStream, offset, count) {
//I get the request URL using request.name
var responseData = getResponseData(); // gets data from inputStream
// Now I need to render this responseData into panel's iframe
}
I have created the above script as a module and included it in main.js. I could not find out how the data from this script could be sent to the script included in panel's HTML.
I read about Content Script and port.emit & port.on but I think Content Script won't come into picture since I don't want to touch the actual page's DOM. Want I want to do is intercept the HTTP response and log it into devtool panel.
Thanks in advance.
Take the response string received and make a data url out of it. Then with your content script do a document.write(dataurl) or do window.location = dataurl.
How to make dataurl:
var responseData = getResponseData();
var dataurl = 'data:text/html,' + encodeURIComponent(responseData);
I hear that widgets in sdk have a content option where you can specify this data url:
'content' option in panel, which would enable you to specify HTML content directly, as you can with a widget, as a result of which I've raised bug 692675.
Can also be done like this:
var HTML = '<html><p>Hi there</p></html>';
var panel = require('panel').Panel({
contentURL: "data:text/html, " + encodeURIComponent(HTML)
});
panel.show();

Scriptaculous Autocomplete list closes on scroll bar click

I have a really annoying issue with Autocomplete with Prototype 1.6. I set up and dialog-style div with a form, which contains an Autocomplete. Everything works fine until I click the scroll bar, or drag it; it closes the list of suggestions. I checked this solution but now I got an javascript error
event.srcElement is undefined
I was checking the controls.js and tried to catch the event object inside the onBlur event, but it travels empty. Printed the offsetX property and is undefined. Looks like the event doesn't exist anymore. either way, it prevents that the list closes but, If I click outside the area, the list now doesn't close. And that's kinda of issue too
Anyone with this same issue? Any idea?
Thanks in advance
I was having the exact issue yesterday, but after doing some r&d I got a pretty handy fix for this.
By default this script was hiding the result div (Suggestion List) on the blur event on the search text box so as soon as we click on result div's scroll bar focus gets lost from input element & result div closes. So I did a small edit in controls.js to change the behavior of script, so now result div close method doesn't invoke on blur (focus out) from input element but triggered on the click on the document except the text input element.
For your convenience I've put the edited controls.js here.
If you like to know what has changed in JS file, here it is;
Added a event listener to the document. Just below this line
"Event.observe(this.update, "keypress", this.onKeyPress.bindAsEventListener(this));"
Event.observe($(document), "mouseup", this.onMouseup.bindAsEventListener(this));
Added a new onMouseup method.
onMouseup: function(event) {
if(!this.hasFocus) {
this.hideTimeout = setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
this.active = false;
}
},
Modify the onBlur method (Comment out two line in block)
onBlur: function(event) {
//this.hideTimeout = setTimeout(this.hide.bind(this), 250);
//this.active = false;
this.hasFocus = false;
}
I hope this will solve your issue.
Thanks
Vinod Kumar

Mozilla Extension - tracking data per opened tab

In a firefox extension I'm temporarily saving data in javascript to show in a sidebar. When a tab is selected, I want to change the text in the sidebar to the right data. What is the best object to use as the "Identifier" for each tab? I'm trying to use the tab object. However, I'm stuck then on how to associate the data to the tab. Currently, I get a load event on the document in a tab. Then I process the data in the document. AFter showing the new data in the tab, I want to save it into a map with the tab as the key so that I can retrieve it on a SelectTab event. However, I'm not sure how to find the tab from the documentin the load event.
So please either tell me how to get the tab object from the document object, or a better thing to use as the key.
The following is one way I've found, but I'm sure there is something more elegant.
getTabForDocument : function (document) {
var wm = Components.classes["#mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
for (var found = false, index = 0, tabbrowser = wm.getEnumerator('navigator:browser').getNext().gBrowser;
index < tabbrowser.tabContainer.childNodes.length && !found;
index++) {
// Get the next tab
var currentTab = tabbrowser.tabContainer.childNodes[index];
if (currentTab.linkedBrowser.contentWindow.document == document)
{
return currentTab;
}
}
return null;
},
Thanks...
Take a look at: https://developer.mozilla.org/en/Code_snippets/Tabbed_browser, especially the gBrowser.selectedBrowser section and https://developer.mozilla.org/En/Listening_to_events_on_all_tabs
To associate data with a tab you can use the setUserData method on the browser.
To get the browser for a document use the getBrowserForDocument method on the gBrowser global object.

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