Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I display text over toolbar button for a firefox addon?

I'm trying to display a small text (new messages count) over icon in toolbar button, something like Chrome and Opera extensions have with badge over the toolbar icons. Text should not cover the whole icon, it should be at the bottom so the user can still see main part of the icon and recognize what extension it is. How can I do this?

You can see what I want on this example image from Chrome:

toolbar button text overlay on chrome


I tried with description, span and div inside stack element but I couldn't get none of them to position at the bottom. Description and div always display text at the center, while span displays it on the right side of the icon making the entire button wider.

<toolbarpalette id="BrowserToolbarPalette">
    <toolbarbutton class="toolbarbutton-1">
        <stack>
            <image></image>
            <description right="0" bottom="0" value="4"></description>
            <!-- <html:div right="0" bottom="0">5</html:div> -->
        </stack>
    </toolbarbutton>
</toolbarpalette>
like image 720
Igor Jerosimić Avatar asked Jun 09 '11 09:06

Igor Jerosimić


People also ask

What is the bar at the top of Firefox called?

Show the Menu bar (If the Alt key doesn't work, press the AltGr key.) To always show the Menu bar: Right-click the top of the Firefox window and click Menu bar.


3 Answers

I had some time to waste while waiting for rain to stop in Formula 1, so I made this work with canvas:

UPDATED: Previous method was flawed when user would remove the icon from the toolbar, updated method is more robust and with less code.


XUL

<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml">
    <hbox hidden="true">
        <html:canvas id="toolbar_button_canvas" width="24" height="24"></html:canvas>
    </hbox>
    <toolbarpalette id="BrowserToolbarPalette">
        <toolbarbutton id="toolbar_button" class="toolbarbutton-1" />
    </toolbarpalette>
</overlay>


CSS

#toolbar_button {
    list-style-image:url("chrome://your_extension/skin/icon_024.png");
}

toolbar[iconsize="small"] #toolbar_button {
    list-style-image:url("chrome://your_extension/skin/icon_016.png");
}


JavaScript

show_status: function(display_text)
{
    var btn = document.getElementById("toolbar_button");
    var canvas = document.getElementById("toolbar_button_canvas");
    var img_src = window.getComputedStyle(btn).listStyleImage.replace(/^url\("(chrome:\/\/your_extension\/skin\/icon_0\d{2}.png)"\)$/, "$1");   // get image path
    var csize = img_src.replace(/^chrome:\/\/your_extension\/skin\/icon_0(\d{2})\.png$/, "$1"); // get image size

    canvas.setAttribute("width", csize);
    canvas.setAttribute("height", csize);
    var ctx = canvas.getContext("2d");

    var img = new Image();
    img.onload = function()
    {
        ctx.textBaseline = "top";
        ctx.font = "bold 9px sans-serif";       // has to go before measureText

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img, 0, 0);

        if (display_text !== "")
        {
            var w = ctx.measureText(display_text).width;
            var h = 7;                  // 9 = font height

            var rp = ((canvas.width - 4) > w) ? 2 : 1;  // right padding = 2, or 1 if text is wider
            var x = canvas.width - w - rp;
            var y = canvas.height - h - 1;          // 1 = bottom padding

            ctx.fillStyle = "#f00";             // background color
            ctx.fillRect(x-rp, y-1, w+rp+rp, h+2);
            ctx.fillStyle = "#fff";             // text color
            ctx.fillText(display_text, x, y);
            //ctx.strokeText(display_text, x, y);
        }
        btn.image = canvas.toDataURL("image/png", "");  // set new toolbar image
    };
    img.src = img_src;
}
like image 131
Igor Jerosimić Avatar answered Nov 15 '22 11:11

Igor Jerosimić


my variant with html:div

P.S. you can also try play with z-index

How it's looks http://f3.s.qip.ru/fTUvr2Cj.jpg

XUL

<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml">
    <toolbar id="nav-bar">
    <hbox>
    <html:div style="color: #000000;
        font-size: 10px;
        font-weight: bold;
        margin-right: 10px;
        margin-top: 16px;
        position: fixed;
        right: 0;">5</html:div>
    <toolbarbutton  insertafter="search-container" type="menu">
    <menupopup>
    <menuitem   class="menuitem-iconic" label="&count;"></menuitem>

    <menuitem   class="menuitem-iconic" label="&size;"></menuitem>

    <menuitem  class="menuitem-iconic" label="&time;"></menuitem>
    <menuseparator></menuseparator>
    <menuitem  class="menuitem-iconic" label="&settings;"></menuitem>
    </menupopup>
    </toolbarbutton>
    </hbox>
    </toolbar>
</overlay>
like image 39
webkiller Avatar answered Nov 15 '22 10:11

webkiller


I just used the libraries from browser-action-jplib

And it worked fine on my simple addons

If you use the library, you may got some problems with AMO-review

It can be solved by the issue

like image 25
vanduc1102 Avatar answered Nov 15 '22 10:11

vanduc1102