Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1172 from ZER0/australis-widget/903002
Browse files Browse the repository at this point in the history
Bug 903002 - Display properly the widget with panel attached, in Australis r=@Gozala
  • Loading branch information
ZER0 committed Jan 7, 2014
2 parents 843dd48 + 232171d commit 6a8d60d
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 4 deletions.
23 changes: 21 additions & 2 deletions lib/sdk/widget.js
Expand Up @@ -443,11 +443,30 @@ const WidgetViewTrait = LightTrait.compose(EventEmitterTrait, LightTrait({

// Special case for click events: if the widget doesn't have a click
// handler, but it does have a panel, display the panel.
if ("click" == type && !this._listeners("click").length && this.panel)
if ("click" == type && !this._listeners("click").length && this.panel) {
// In Australis, widgets may be positioned in an overflow panel or the
// menu panel.
// In such cases clicking this widget will hide the overflow/menu panel,
// and the widget's panel will show instead.

let anchor = domNode;
let { CustomizableUI, window } = domNode.ownerDocument.defaultView;

if (CustomizableUI) {
({anchor}) = CustomizableUI.getWidget(domNode.id).forWindow(window);

// if `anchor` is not the `domNode` itself, it means the widget is
// positioned in a panel, therefore we have to hide it before show
// the widget's panel in the same anchor
if (anchor !== domNode)
CustomizableUI.hidePanelForNode(domNode);
}

// This kind of ugly workaround, instead we should implement
// `getNodeView` for the `Widget` class itself, but that's kind of
// hard without cleaning things up.
this.panel.show(null, getNodeView.implement({}, function() domNode));
this.panel.show(null, getNodeView.implement({}, () => anchor));
}
},

_isInWindow: function WidgetView__isInWindow(window) {
Expand Down
65 changes: 63 additions & 2 deletions test/test-widget.js
Expand Up @@ -10,7 +10,7 @@ module.metadata = {
};

const widgets = require("sdk/widget");
const { Cc, Ci } = require("chrome");
const { Cc, Ci, Cu } = require("chrome");
const { Loader } = require('sdk/test/loader');
const url = require("sdk/url");
const timer = require("sdk/timers");
Expand Down Expand Up @@ -711,7 +711,7 @@ exports.testWidgetWithValidPanel = function(assert, done) {
const widgets = require("sdk/widget");

let widget1 = widgets.Widget({
id: "panel1",
id: "testWidgetWithValidPanel",
label: "panel widget 1",
content: "<div id='me'>foo</div>",
contentScript: "var evt = new MouseEvent('click', {button: 0});" +
Expand Down Expand Up @@ -776,6 +776,67 @@ exports.testPanelWidget3 = function testPanelWidget3(assert, done) {
});
};

exports.testWidgetWithPanelInMenuPanel = function(assert, done) {
let CustomizableUI;

try {
({CustomizableUI}) = Cu.import("resource:///modules/CustomizableUI.jsm", {});
}
catch (e) {
assert.pass("Test skipped: no CustomizableUI object found.");
done();
return;
}

const widgets = require("sdk/widget");

let widget1 = widgets.Widget({
id: "panel1",
label: "panel widget 1",
content: "<div id='me'>foo</div>",
contentScript: "new " + function() {
self.port.on('click', () => {
let evt = new MouseEvent('click', {button: 0});
document.body.dispatchEvent(evt);
});
},
contentScriptWhen: "end",
panel: require("sdk/panel").Panel({
contentURL: "data:text/html;charset=utf-8,<body>Look ma, a panel!</body>",
onShow: function() {
let { document } = getMostRecentBrowserWindow();
let { anchorNode } = document.getElementById('mainPopupSet').lastChild;
let panelButtonNode = document.getElementById("PanelUI-menu-button");

assert.strictEqual(anchorNode, panelButtonNode,
'the panel is anchored to the panel menu button instead of widget');

widget1.destroy();
done();
}
})
});

let widgetId = "widget:" + jetpackID + "-" + widget1.id;

CustomizableUI.addListener({
onWidgetAdded: function(id) {
if (id !== widgetId) return;

let { document, PanelUI } = getMostRecentBrowserWindow();

PanelUI.panel.addEventListener('popupshowing', function onshow({type}) {
this.removeEventListener(type, onshow);
widget1.port.emit('click');
});

document.getElementById("PanelUI-menu-button").click()
}
});

CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_PANEL);
};

exports.testWidgetMessaging = function testWidgetMessaging(assert, done) {
let origMessage = "foo";
const widgets = require("sdk/widget");
Expand Down

0 comments on commit 6a8d60d

Please sign in to comment.