Brett Zamir
Brett Zamir

Reputation: 14345

Addon SDK way to make a dialog

What is the proper way to use the SDK to make a dialog (which is not anchored to the add-on bar, etc. but shows centered on screen)? It doesn't seem like there is any API for this important capability. I do see windows/utils has open but I have two problems with that:

  1. The dialog opening seems to require "chrome" privs to get it to be centered on the screen (and I'd be expectant of add-on reviewers complaining of chrome privs, and even if not, I'd like to try to stick to the SDK way).
  2. While I can get the DOM window reference of the new window/utils' open() dialog, I'm not sure how to attach a content script so I can respond to user interaction in a way that prompts (and can respond to) privileged behavior ala postMessage or port.emit (without again, directly working with chrome privs).

Upvotes: 2

Views: 934

Answers (3)

Andrew Zitnay
Andrew Zitnay

Reputation: 1

Simply adding ",screenX=0,screenY=0" (or any values, the zeroes seem to be meaningless) to the features screen seems to fix centerscreen.

Upvotes: 0

Brett Zamir
Brett Zamir

Reputation: 14345

Ok, this answer should have been pretty obvious for anyone with a little experience with the SDK. I realized I can just use a panel. In my defense, the name "panel" is not as clear as "dialog" in conjuring up this idea, and I am so used to using panels with widgets, that it hadn't occurred to me that I could use it independently!

Edit

Unfortunately, as per Bug 595040, these dialogs are not persistent, meaning if the panel loses focus, the "dialog" is gone... So panel looks like it is not a suitable candidate after all... :(

Edit 2

I've since moved on and have gotten things working mostly to my satisfaction with sdk/window/utils and openDialog on whose returned window I add a load listener and then call tabs.activeTab.on('ready', and then set tabs.activeTab.url to my add-on local HTML file so the ready event will get a tab to which I can attach a worker. There is still the problem with chrome privs I suppose, but at least the main communications are using SDK processes.

Update to Edit 2:

Code sample provided by request:

var data = require('sdk/self').data,
    tabs = require('sdk/tabs');
var win = require('sdk/window/utils').openDialog({
    // No "url" supplied here in this case as we add it below (in order to have a ready listener in place before load which can give us access to the tab worker)
    // For more, see https://developer.mozilla.org/en-US/docs/Web/API/window.open#Position_and_size_features
    features: Object.keys({
        chrome: true, // Needed for centerscreen per docs
        centerscreen: true, // Doesn't seem to be working for some reason (even though it does work when calling via XPCOM)
        resizable: true,
        scrollbars: true
    }).join() + ',width=850,height=650',
    name: "My window name"
    // parent: 
    // args: 
});
win.addEventListener('load', function () {
    tabs.activeTab.on('ready', function (tab) {
        var worker = tab.attach({
            contentScriptFile: ....
            // ...
        });
        // Use worker.port.on, worker.port.emit, etc...
    });
    tabs.activeTab.url = data.url('myHTMLFile.html');
});

Upvotes: 5

willlma
willlma

Reputation: 7533

if the panel loses focus, the "dialog" is gone...

It doesn't get destroyed, just hides, right? If so, depending on why it's getting hidden, you can just call show() on it again.

You'd want to make sure it's not being hidden for a good reason before calling show again. If there's a specific situation in which it's losing focus where you don't want it to, create a listener for that situation, then call if (!panel.isShown) panel.show();

For example, if it's losing focus because a user clicks outside the box, then that's probably the expected behaviour and nothing should be done. If it's losing focus when the browser/tab loses focus, just register a tab.on('activate', aboveFunction)

Upvotes: 2

Related Questions