canvas
element almost by chance. I'd noticed, during my initial, failed attempts, that attempting to drag a tab in Firefox creates a tiny thumbnail showing the contents of that tab (you can try that right now, if you've never noticed it). So, I decided to look into the browser's main javascript file : chrome://browser/content/browser.js
, which is where I came across the canvas
element for the first time. It was only after that, that we could actually start working on View Tab.As I said at the end of the last post, we are done with creating a preview canvas, and all that's left to do is make sure it shows up at the right place. For this, first we create a
popup
element.//Create a Tooltip to show the canvas prevTooltip = document.createElement("popup"); prevTooltip.id="viewTabTooltip"; prevTooltip.position="after_pointer"; prevTooltip.appendChild(prevCanvas); prevTooltip.setAttribute("style","margin:21px 0px; -moz-box-shadow:10px 10px 2px black; text-rendering:geometricPrecision !important;");
The popup element is, as the name suggests, a popup, which is not shown in the document, and has to be attached to another element in one of three ways, to cause it to show on clicking, right-clicking and hovering the mouse over the element. More on popups here.
The popup, called
prevTooltip
, is given the id "viewTabTooltip"
and its position
is set to "after_pointer"
, which ensures it shows up below the mouse pointer, when it is invoked. Then, the canvas, containing the preview is appended to prevTooltip
, and the popup is styled.Finally, the popup is appended to the browser's
mainPopupSet
, and attached to aTab
using it's tooltip
attribute.//Attach the tooltip to aTab document.getElementById("mainPopupSet") .appendChild(prevTooltip); aTab.setAttribute("tooltip","viewTabTooltip"); } }
With this the function
viewTab.createPreview()
is complete, and will do the job of showing the PT if called when the mouse pointer is moved over a tab.Next, the function to remove the
popup
is defined./* Function to End Preview */ viewTab.endPreview = function(aTab,firsttab){ if(firsttab) aTab=gBrowser.tabContainer. getElementsByClassName("tabbrowser-tab")[0];
The first line of code in the function, again, as I mentioned in the first post, is included to avoid a specific error.
if(document.getElementById("viewTabTooltip")){ document.getElementById("mainPopupSet"). removeChild(document.getElementById ("viewTabTooltip")); aTab.removeAttribute("tooltip"); }}
If the document contains an element with the id
"viewTabTooltip"
, which is the popup that contains the preview canvas, then it is removed, and the tooltip
attribute of aTab
is also removed. This completes viewTab.endPreview()
.Next, a function to set the
onmouseover
and onmouseout
attributes of tabs, so that the functions defined earlier are invoked when they are needed, is defined. The function is pretty straightforward, an array of/* Function to set the onmouseover property of the tabs*/ viewTab.init = function (){ tabs = gBrowser.tabContainer. getElementsByClassName("tabbrowser-tab"); for(var i=0;iif (i!=0){ tabs[i].setAttribute("onmouseover", "viewTab.createPreview(tabs["+i+"]);"); tabs[i].setAttribute("onmouseout", "viewTab.endPreview(tabs["+i+"]);"); } else { tabs[0].setAttribute("onmouseover", "if(tabs[0] !=gBrowser.selectedTab) viewTab.createPreview(tabs[0],true);"); tabs[0].setAttribute("onmouseout", "viewTab.endPreview(tabs[0],true);"); } } }
tabs
is created and their respective onmouseover
and onmouseout
attributes are set to invoke viewTab.createPreview()
and viewTab.endPreview()
. The portion under else
is required because, as mentioned earlier, the first tab causes some trouble, and needs to be dealt with separately.Finally, event handlers are added to the
gBrowser
, the primary tabbrowser
element, to invoke viewTab.init()
whenever any change is made to the tabs.//Add the event handlers to listen for new tabs gBrowser.addEventListener ("load",viewTab.init,false); gBrowser.addEventListener ("TabSelect",viewTab.init,false); gBrowser.addEventListener ("TabClose",viewTab.init,false); gBrowser.addEventListener ("TabMove",viewTab.init,false);
I'd initially assumed it would be enough to listen just for the
"TabOpen"
event (which I ultimately removed!), which is supposedly fired whenever a new tab
is opened. But apparently it wasn't enough, so I tried listening for just the "load"
event, (which is fired in more places than "TabOpen"
), but it wasn't enough either,and so, after a experimenting for a while with possible ways of manipulating tabs, I was finally able to come up with this almost exhaustive list of events to listen for, so that the PT's always show up. Including "TabSelect"
has an added advantage: even if something's gone wrong and PT's aren't showing up, selecting a different tab invokes viewTab.init
and that puts things back in place.With that, the implementation of View Tab is complete! Hope it was useful.