mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 1011392 - Make Social API's panel handling generic so that Loop can use it as well, enabling Loop to function properly in the Application menu. r=mhammond
This commit is contained in:
parent
a9360e4878
commit
c0c094e7c7
@ -7,6 +7,7 @@ let LoopUI;
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "injectLoopAPI", "resource:///modules/loop/MozLoopAPI.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MozLoopService", "resource:///modules/loop/MozLoopService.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/PanelFrame.jsm");
|
||||
|
||||
|
||||
(function() {
|
||||
@ -19,41 +20,24 @@ XPCOMUtils.defineLazyModuleGetter(this, "MozLoopService", "resource:///modules/l
|
||||
* the panel to the button which triggers it.
|
||||
*/
|
||||
openCallPanel: function(event) {
|
||||
let panel = document.getElementById("loop-panel");
|
||||
let anchor = event.target;
|
||||
let iframe = document.getElementById("loop-panel-frame");
|
||||
let callback = iframe => {
|
||||
iframe.addEventListener("DOMContentLoaded", function documentDOMLoaded() {
|
||||
iframe.removeEventListener("DOMContentLoaded", documentDOMLoaded, true);
|
||||
injectLoopAPI(iframe.contentWindow);
|
||||
|
||||
if (!iframe) {
|
||||
// XXX This should be using SharedFrame (bug 1011392 may do this).
|
||||
iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("id", "loop-panel-frame");
|
||||
iframe.setAttribute("type", "content");
|
||||
iframe.setAttribute("class", "loop-frame social-panel-frame");
|
||||
iframe.setAttribute("flex", "1");
|
||||
panel.appendChild(iframe);
|
||||
}
|
||||
// We use loopPanelInitialized so that we know we've finished localising before
|
||||
// sizing the panel.
|
||||
iframe.contentWindow.addEventListener("loopPanelInitialized",
|
||||
function documentLoaded() {
|
||||
iframe.contentWindow.removeEventListener("loopPanelInitialized",
|
||||
documentLoaded, true);
|
||||
}, true);
|
||||
|
||||
// We inject in DOMContentLoaded as that is before any scripts have tun.
|
||||
iframe.addEventListener("DOMContentLoaded", function documentDOMLoaded() {
|
||||
iframe.removeEventListener("DOMContentLoaded", documentDOMLoaded, true);
|
||||
injectLoopAPI(iframe.contentWindow);
|
||||
}, true);
|
||||
};
|
||||
|
||||
// We use loopPanelInitialized so that we know we've finished localising before
|
||||
// sizing the panel.
|
||||
iframe.contentWindow.addEventListener("loopPanelInitialized",
|
||||
function documentLoaded() {
|
||||
iframe.contentWindow.removeEventListener("loopPanelInitialized",
|
||||
documentLoaded, true);
|
||||
// XXX We end up with the wrong size here, so this
|
||||
// needs further investigation (bug 1011394).
|
||||
sizeSocialPanelToContent(panel, iframe);
|
||||
}, true);
|
||||
|
||||
}, true);
|
||||
|
||||
iframe.setAttribute("src", "about:looppanel");
|
||||
panel.hidden = false;
|
||||
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
PanelFrame.showPopup(window, PanelUI, event.target, "loop", null,
|
||||
"about:looppanel", null, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -63,6 +47,5 @@ XPCOMUtils.defineLazyModuleGetter(this, "MozLoopService", "resource:///modules/l
|
||||
initialize: function() {
|
||||
MozLoopService.initialize();
|
||||
},
|
||||
|
||||
};
|
||||
})();
|
||||
|
@ -12,13 +12,12 @@ let SocialUI,
|
||||
|
||||
(function() {
|
||||
|
||||
// The minimum sizes for the auto-resize panel code.
|
||||
const PANEL_MIN_HEIGHT = 100;
|
||||
const PANEL_MIN_WIDTH = 330;
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame",
|
||||
"resource:///modules/SharedFrame.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame",
|
||||
"resource:///modules/PanelFrame.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "OpenGraphBuilder", function() {
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/Social.jsm", tmp);
|
||||
@ -1145,66 +1144,6 @@ SocialStatus = {
|
||||
return this._toolbarHelper;
|
||||
},
|
||||
|
||||
get _dynamicResizer() {
|
||||
delete this._dynamicResizer;
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
return this._dynamicResizer;
|
||||
},
|
||||
|
||||
// status panels are one-per button per-process, we swap the docshells between
|
||||
// windows when necessary
|
||||
_attachNotificatonPanel: function(aParent, aButton, provider) {
|
||||
aParent.hidden = !SocialUI.enabled;
|
||||
let notificationFrameId = "social-status-" + provider.origin;
|
||||
let frame = document.getElementById(notificationFrameId);
|
||||
|
||||
// If the button was customized to a new location, we we'll destroy the
|
||||
// iframe and start fresh.
|
||||
if (frame && frame.parentNode != aParent) {
|
||||
SharedFrame.forgetGroup(frame.id);
|
||||
frame.parentNode.removeChild(frame);
|
||||
frame = null;
|
||||
}
|
||||
|
||||
if (!frame) {
|
||||
let size = provider.getPageSize("status");
|
||||
let {width, height} = size ? size : {width: PANEL_MIN_WIDTH, height: PANEL_MIN_HEIGHT};
|
||||
|
||||
frame = SharedFrame.createFrame(
|
||||
notificationFrameId, /* frame name */
|
||||
aParent, /* parent */
|
||||
{
|
||||
"type": "content",
|
||||
"mozbrowser": "true",
|
||||
"class": "social-panel-frame",
|
||||
"id": notificationFrameId,
|
||||
"tooltip": "aHTMLTooltip",
|
||||
"context": "contentAreaContextMenu",
|
||||
"flex": "1",
|
||||
|
||||
// work around bug 793057 - by making the panel roughly the final size
|
||||
// we are more likely to have the anchor in the correct position.
|
||||
"style": "width: " + width + "px; height: " + height + "px;",
|
||||
"dynamicresizer": !size,
|
||||
|
||||
"origin": provider.origin,
|
||||
"src": provider.statusURL
|
||||
}
|
||||
);
|
||||
|
||||
if (frame.socialErrorListener)
|
||||
frame.socialErrorListener.remove();
|
||||
if (frame.docShell) {
|
||||
frame.docShell.isActive = false;
|
||||
Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
|
||||
}
|
||||
} else {
|
||||
frame.setAttribute("origin", provider.origin);
|
||||
SharedFrame.updateURL(notificationFrameId, provider.statusURL);
|
||||
}
|
||||
aButton.setAttribute("notificationFrameId", notificationFrameId);
|
||||
},
|
||||
|
||||
updateButton: function(origin) {
|
||||
let id = this._toolbarHelper.idFromOrigin(origin);
|
||||
let widget = CustomizableUI.getWidget(id);
|
||||
@ -1249,96 +1188,8 @@ SocialStatus = {
|
||||
let origin = aToolbarButton.getAttribute("origin");
|
||||
let provider = Social._getProviderFromOrigin(origin);
|
||||
|
||||
// if we're a slice in the hamburger, use that panel instead
|
||||
let widgetGroup = CustomizableUI.getWidget(aToolbarButton.getAttribute("id"));
|
||||
let widget = widgetGroup.forWindow(window);
|
||||
let panel, showingEvent, hidingEvent;
|
||||
let inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
|
||||
if (inMenuPanel) {
|
||||
panel = document.getElementById("PanelUI-socialapi");
|
||||
this._attachNotificatonPanel(panel, aToolbarButton, provider);
|
||||
widget.node.setAttribute("closemenu", "none");
|
||||
showingEvent = "ViewShowing";
|
||||
hidingEvent = "ViewHiding";
|
||||
} else {
|
||||
panel = document.getElementById("social-notification-panel");
|
||||
this._attachNotificatonPanel(panel, aToolbarButton, provider);
|
||||
showingEvent = "popupshown";
|
||||
hidingEvent = "popuphidden";
|
||||
}
|
||||
let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
|
||||
let notificationFrame = document.getElementById(notificationFrameId);
|
||||
|
||||
let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
|
||||
SharedFrame.setOwner(notificationFrameId, notificationFrame);
|
||||
|
||||
// Clear dimensions on all browsers so the panel size will
|
||||
// only use the selected browser.
|
||||
let frameIter = panel.firstElementChild;
|
||||
while (frameIter) {
|
||||
frameIter.collapsed = (frameIter != notificationFrame);
|
||||
frameIter = frameIter.nextElementSibling;
|
||||
}
|
||||
|
||||
function dispatchPanelEvent(name) {
|
||||
let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
|
||||
evt.initCustomEvent(name, true, true, {});
|
||||
notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
// we only use a dynamic resizer when we're located the toolbar.
|
||||
let dynamicResizer;
|
||||
if (!inMenuPanel && notificationFrame.getAttribute("dynamicresizer") == "true") {
|
||||
dynamicResizer = this._dynamicResizer;
|
||||
}
|
||||
panel.addEventListener(hidingEvent, function onpopuphiding() {
|
||||
panel.removeEventListener(hidingEvent, onpopuphiding);
|
||||
aToolbarButton.removeAttribute("open");
|
||||
if (dynamicResizer)
|
||||
dynamicResizer.stop();
|
||||
notificationFrame.docShell.isActive = false;
|
||||
dispatchPanelEvent("socialFrameHide");
|
||||
});
|
||||
|
||||
panel.addEventListener(showingEvent, function onpopupshown() {
|
||||
panel.removeEventListener(showingEvent, onpopupshown);
|
||||
// This attribute is needed on both the button and the
|
||||
// containing toolbaritem since the buttons on OS X have
|
||||
// moz-appearance:none, while their container gets
|
||||
// moz-appearance:toolbarbutton due to the way that toolbar buttons
|
||||
// get combined on OS X.
|
||||
let initFrameShow = () => {
|
||||
notificationFrame.docShell.isActive = true;
|
||||
notificationFrame.docShell.isAppTab = true;
|
||||
if (dynamicResizer)
|
||||
dynamicResizer.start(panel, notificationFrame);
|
||||
dispatchPanelEvent("socialFrameShow");
|
||||
};
|
||||
if (!inMenuPanel)
|
||||
aToolbarButton.setAttribute("open", "true");
|
||||
if (notificationFrame.contentDocument &&
|
||||
notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
|
||||
initFrameShow();
|
||||
} else {
|
||||
// first time load, wait for load and dispatch after load
|
||||
notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
|
||||
notificationFrame.removeEventListener("load", panelBrowserOnload, true);
|
||||
initFrameShow();
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
|
||||
if (inMenuPanel) {
|
||||
PanelUI.showSubView("PanelUI-socialapi", widget.node,
|
||||
CustomizableUI.AREA_PANEL);
|
||||
} else {
|
||||
let anchor = document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
|
||||
// Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
|
||||
// handling from preventing it being opened in some cases.
|
||||
setTimeout(function() {
|
||||
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
}, 0);
|
||||
}
|
||||
PanelFrame.showPopup(window, PanelUI, aToolbarButton, "social", origin,
|
||||
provider.statusURL, provider.getPageSize("status"));
|
||||
},
|
||||
|
||||
setPanelErrorMessage: function(aNotificationFrame) {
|
||||
|
@ -268,6 +268,12 @@
|
||||
position="topcenter topright"/>
|
||||
|
||||
#ifdef MOZ_LOOP
|
||||
<panel id="loop-notification-panel"
|
||||
class="loop-panel social-panel"
|
||||
type="arrow"
|
||||
hidden="true"
|
||||
noautofocus="true"/>
|
||||
|
||||
<panel id="loop-panel"
|
||||
class="loop-panel social-panel"
|
||||
type="arrow"
|
||||
@ -782,9 +788,13 @@
|
||||
|
||||
#ifdef MOZ_LOOP
|
||||
<!-- XXX Bug 1013989 will provide a label for the button -->
|
||||
<!-- This uses badged to be compatible with the social api code it shares.
|
||||
We may also want it to be badged in the future, for notification
|
||||
purposes. -->
|
||||
<toolbarbutton id="loop-call-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
persist="class"
|
||||
type="badged"
|
||||
removable="true"
|
||||
tooltiptext="&loopCallButton.tooltip;"
|
||||
oncommand="LoopUI.openCallPanel(event);"
|
||||
|
@ -141,6 +141,10 @@
|
||||
|
||||
<panelview id="PanelUI-socialapi" flex="1"/>
|
||||
|
||||
#ifdef MOZ_LOOP
|
||||
<panelview id="PanelUI-loopapi" flex="1"/>
|
||||
#endif
|
||||
|
||||
<panelview id="PanelUI-feeds" flex="1" oncommand="FeedHandler.subscribeToFeed(null, event);">
|
||||
<label value="&feedsMenu.label;" class="panel-subview-header"/>
|
||||
</panelview>
|
||||
|
209
browser/modules/PanelFrame.jsm
Normal file
209
browser/modules/PanelFrame.jsm
Normal file
@ -0,0 +1,209 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
// A module for working with panels with iframes shared across windows.
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["PanelFrame"];
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame", "resource:///modules/SharedFrame.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DynamicResizeWatcher", "resource:///modules/Social.jsm");
|
||||
|
||||
// The minimum sizes for the auto-resize panel code.
|
||||
const PANEL_MIN_HEIGHT = 100;
|
||||
const PANEL_MIN_WIDTH = 330;
|
||||
|
||||
let PanelFrameInternal = {
|
||||
/**
|
||||
* Helper function to get and hold a single instance of a DynamicResizeWatcher.
|
||||
*/
|
||||
get _dynamicResizer() {
|
||||
delete this._dynamicResizer;
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
return this._dynamicResizer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Status panels are one-per button per-process, we swap the docshells between
|
||||
* windows when necessary.
|
||||
*
|
||||
* @param {DOMWindow} aWindow The window in which to show the popup.
|
||||
* @param {PanelUI} aPanelUI The panel UI object that represents the application menu.
|
||||
* @param {DOMElement} aButton The button element that is pressed to show the popup.
|
||||
* @param {String} aType The type of panel this is, e.g. "social" or "loop".
|
||||
* @param {String} aOrigin Optional, the origin to use for the iframe.
|
||||
* @param {String} aSrc The url to load into the iframe.
|
||||
* @param {String} aSize The initial size of the panel (width and height are the same
|
||||
* if specified).
|
||||
*/
|
||||
_attachNotificatonPanel: function(aWindow, aParent, aButton, aType, aOrigin, aSrc, aSize) {
|
||||
aParent.hidden = false;
|
||||
let notificationFrameId = aOrigin ? aType + "-status-" + aOrigin : aType;
|
||||
let frame = aWindow.document.getElementById(notificationFrameId);
|
||||
|
||||
// If the button was customized to a new location, we we'll destroy the
|
||||
// iframe and start fresh.
|
||||
if (frame && frame.parentNode != aParent) {
|
||||
SharedFrame.forgetGroup(frame.id);
|
||||
frame.parentNode.removeChild(frame);
|
||||
frame = null;
|
||||
}
|
||||
|
||||
if (!frame) {
|
||||
let {width, height} = aSize ? aSize : {width: PANEL_MIN_WIDTH, height: PANEL_MIN_HEIGHT};
|
||||
|
||||
frame = SharedFrame.createFrame(
|
||||
notificationFrameId, /* frame name */
|
||||
aParent, /* parent */
|
||||
{
|
||||
"type": "content",
|
||||
"mozbrowser": "true",
|
||||
// All frames use social-panel-frame as the class.
|
||||
"class": "social-panel-frame",
|
||||
"id": notificationFrameId,
|
||||
"tooltip": "aHTMLTooltip",
|
||||
"context": "contentAreaContextMenu",
|
||||
"flex": "1",
|
||||
|
||||
// work around bug 793057 - by making the panel roughly the final size
|
||||
// we are more likely to have the anchor in the correct position.
|
||||
"style": "width: " + width + "px; height: " + height + "px;",
|
||||
"dynamicresizer": !aSize,
|
||||
|
||||
"origin": aOrigin,
|
||||
"src": aSrc
|
||||
}
|
||||
);
|
||||
} else {
|
||||
frame.setAttribute("origin", aOrigin);
|
||||
SharedFrame.updateURL(notificationFrameId, aSrc);
|
||||
}
|
||||
aButton.setAttribute("notificationFrameId", notificationFrameId);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The exported PanelFrame object
|
||||
*/
|
||||
let PanelFrame = {
|
||||
/**
|
||||
* Shows a popup in a pop-up panel, or in a sliding panel view in the application menu.
|
||||
* It will move the iframe to different DOM locations depending on where it needs to be
|
||||
* shown, enabling one iframe to be used for the entire session.
|
||||
*
|
||||
* @param {DOMWindow} aWindow The window in which to show the popup.
|
||||
* @param {PanelUI} aPanelUI The panel UI object that represents the application menu.
|
||||
* @param {DOMElement} aToolbarButton The button element that is pressed to show the popup.
|
||||
* @param {String} aType The type of panel this is, e.g. "social" or "loop".
|
||||
* @param {String} aOrigin Optional, the origin to use for the iframe.
|
||||
* @param {String} aSrc The url to load into the iframe.
|
||||
* @param {String} aSize The initial size of the panel (width and height are the same
|
||||
* if specified).
|
||||
* @param {Function} aCallback Optional, callback to be called with the iframe when it is
|
||||
* set up.
|
||||
*/
|
||||
showPopup: function(aWindow, aPanelUI, aToolbarButton, aType, aOrigin, aSrc, aSize, aCallback) {
|
||||
// if we're a slice in the hamburger, use that panel instead
|
||||
let widgetGroup = CustomizableUI.getWidget(aToolbarButton.getAttribute("id"));
|
||||
let widget = widgetGroup.forWindow(aWindow);
|
||||
let panel, showingEvent, hidingEvent;
|
||||
let inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
|
||||
if (inMenuPanel) {
|
||||
panel = aWindow.document.getElementById("PanelUI-" + aType + "api");
|
||||
PanelFrameInternal._attachNotificatonPanel(aWindow, panel, aToolbarButton, aType, aOrigin, aSrc, aSize);
|
||||
widget.node.setAttribute("closemenu", "none");
|
||||
showingEvent = "ViewShowing";
|
||||
hidingEvent = "ViewHiding";
|
||||
} else {
|
||||
panel = aWindow.document.getElementById(aType + "-notification-panel");
|
||||
PanelFrameInternal._attachNotificatonPanel(aWindow, panel, aToolbarButton, aType, aOrigin, aSrc, aSize);
|
||||
showingEvent = "popupshown";
|
||||
hidingEvent = "popuphidden";
|
||||
}
|
||||
let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
|
||||
let notificationFrame = aWindow.document.getElementById(notificationFrameId);
|
||||
|
||||
let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
|
||||
SharedFrame.setOwner(notificationFrameId, notificationFrame);
|
||||
|
||||
// Clear dimensions on all browsers so the panel size will
|
||||
// only use the selected browser.
|
||||
let frameIter = panel.firstElementChild;
|
||||
while (frameIter) {
|
||||
frameIter.collapsed = (frameIter != notificationFrame);
|
||||
frameIter = frameIter.nextElementSibling;
|
||||
}
|
||||
|
||||
function dispatchPanelEvent(name) {
|
||||
let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
|
||||
evt.initCustomEvent(name, true, true, {});
|
||||
notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
// we only use a dynamic resizer when we're located the toolbar.
|
||||
let dynamicResizer;
|
||||
if (!inMenuPanel && notificationFrame.getAttribute("dynamicresizer") == "true") {
|
||||
dynamicResizer = PanelFrameInternal._dynamicResizer;
|
||||
}
|
||||
panel.addEventListener(hidingEvent, function onpopuphiding() {
|
||||
panel.removeEventListener(hidingEvent, onpopuphiding);
|
||||
aToolbarButton.removeAttribute("open");
|
||||
if (dynamicResizer)
|
||||
dynamicResizer.stop();
|
||||
notificationFrame.docShell.isActive = false;
|
||||
dispatchPanelEvent(aType + "FrameHide");
|
||||
});
|
||||
|
||||
panel.addEventListener(showingEvent, function onpopupshown() {
|
||||
panel.removeEventListener(showingEvent, onpopupshown);
|
||||
// This attribute is needed on both the button and the
|
||||
// containing toolbaritem since the buttons on OS X have
|
||||
// moz-appearance:none, while their container gets
|
||||
// moz-appearance:toolbarbutton due to the way that toolbar buttons
|
||||
// get combined on OS X.
|
||||
let initFrameShow = () => {
|
||||
notificationFrame.docShell.isActive = true;
|
||||
notificationFrame.docShell.isAppTab = true;
|
||||
if (dynamicResizer)
|
||||
dynamicResizer.start(panel, notificationFrame);
|
||||
dispatchPanelEvent(aType + "FrameShow");
|
||||
};
|
||||
if (!inMenuPanel)
|
||||
aToolbarButton.setAttribute("open", "true");
|
||||
if (notificationFrame.contentDocument &&
|
||||
notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
|
||||
initFrameShow();
|
||||
} else {
|
||||
// first time load, wait for load and dispatch after load
|
||||
notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
|
||||
notificationFrame.removeEventListener("load", panelBrowserOnload, true);
|
||||
initFrameShow();
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
|
||||
if (inMenuPanel) {
|
||||
aPanelUI.showSubView("PanelUI-" + aType + "api", widget.node,
|
||||
CustomizableUI.AREA_PANEL);
|
||||
} else {
|
||||
let anchor = aWindow.document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
|
||||
// Bug 849216 - open the popup asynchronously so we avoid the auto-rollup
|
||||
// handling from preventing it being opened in some cases.
|
||||
Services.tm.mainThread.dispatch(function() {
|
||||
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
if (aCallback)
|
||||
aCallback(notificationFrame);
|
||||
}
|
||||
};
|
@ -17,6 +17,7 @@ EXTRA_JS_MODULES += [
|
||||
'Feeds.jsm',
|
||||
'NetworkPrioritizer.jsm',
|
||||
'offlineAppCache.jsm',
|
||||
'PanelFrame.jsm',
|
||||
'RemotePrompt.jsm',
|
||||
'SharedFrame.jsm',
|
||||
'SitePermissions.jsm',
|
||||
|
Loading…
Reference in New Issue
Block a user