Bug 1011598 fix marks and status buttons for toolbar overflow menu, r=Gijs

This commit is contained in:
Shane Caraveo 2014-06-27 08:58:13 -07:00
Родитель 5a3aeea72e
Коммит 1c1e53ed43
3 изменённых файлов: 67 добавлений и 63 удалений

Просмотреть файл

@ -1182,7 +1182,6 @@ SocialStatus = {
let button = widget.forWindow(window).node; let button = widget.forWindow(window).node;
if (button) { if (button) {
// we only grab the first notification, ignore all others // we only grab the first notification, ignore all others
let place = CustomizableUI.getPlaceForItem(button);
let provider = Social._getProviderFromOrigin(origin); let provider = Social._getProviderFromOrigin(origin);
let icons = provider.ambientNotificationIcons; let icons = provider.ambientNotificationIcons;
let iconNames = Object.keys(icons); let iconNames = Object.keys(icons);
@ -1192,7 +1191,7 @@ SocialStatus = {
// ambient notification and profile changes. // ambient notification and profile changes.
let iconURL = provider.icon32URL || provider.iconURL; let iconURL = provider.icon32URL || provider.iconURL;
let tooltiptext; let tooltiptext;
if (!notif || place == "palette") { if (!notif || !widget.areaType) {
button.style.listStyleImage = "url(" + iconURL + ")"; button.style.listStyleImage = "url(" + iconURL + ")";
button.setAttribute("badge", ""); button.setAttribute("badge", "");
button.setAttribute("aria-label", ""); button.setAttribute("aria-label", "");
@ -1249,8 +1248,12 @@ SocialMarks = {
update: function() { update: function() {
// signal each button to update itself // signal each button to update itself
let currentButtons = document.querySelectorAll('toolbarbutton[type="socialmark"]'); let currentButtons = document.querySelectorAll('toolbarbutton[type="socialmark"]');
for (let elt of currentButtons) for (let elt of currentButtons) {
elt.update(); // make sure we can call update since the xbl is not completely bound if
// the button is in overflow, until the button becomes visible.
if (elt.update)
elt.update();
}
}, },
updatePanelButtons: function() { updatePanelButtons: function() {
@ -1263,7 +1266,9 @@ SocialMarks = {
if (!widget) if (!widget)
continue; continue;
let node = widget.forWindow(window).node; let node = widget.forWindow(window).node;
if (node) // xbl binding is not complete on startup when buttons are not in toolbar,
// verify update is available
if (node && node.update)
node.update(); node.update();
} }
}, },

Просмотреть файл

@ -17,18 +17,27 @@
xbl:inherits="xbl:text=label,accesskey,wrap"/> xbl:inherits="xbl:text=label,accesskey,wrap"/>
</content> </content>
<implementation implements="nsIDOMEventListener, nsIObserver"> <implementation implements="nsIDOMEventListener, nsIObserver">
<field name="_useDynamicResizer">false</field> <constructor>
<field name="inMenuPanel">false</field> // if we overflow, we have to reset the button. unfortunately we cannot
// use a widget listener because we need to do this *after* the node is
// moved, and the event happens before the node is moved.
this.update();
</constructor>
<property name="_anchor">
<getter>
let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id"));
return widgetGroup.forWindow(window).anchor;
</getter>
</property>
<property name="_useDynamicResizer">
<getter>
let provider = Social._getProviderFromOrigin(this.getAttribute("origin"));
return !provider.getPageSize("marks");
</getter>
</property>
<property name="panel"> <property name="panel">
<getter> <getter>
let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id"));
let widget = widgetGroup.forWindow(window);
this.inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
if (this.inMenuPanel) {
widget.node.setAttribute("closemenu", "none");
return document.getElementById("PanelUI-socialapi");
}
return document.getAnonymousElementByAttribute(this, "anonid", "panel"); return document.getAnonymousElementByAttribute(this, "anonid", "panel");
</getter> </getter>
</property> </property>
@ -41,7 +50,6 @@
let provider = Social._getProviderFromOrigin(this.getAttribute("origin")); let provider = Social._getProviderFromOrigin(this.getAttribute("origin"));
let size = provider.getPageSize("marks"); let size = provider.getPageSize("marks");
let {width, height} = size ? size : {width: 330, height: 100}; let {width, height} = size ? size : {width: 330, height: 100};
this._useDynamicResizer = !size;
this._frame = SharedFrame.createFrame( this._frame = SharedFrame.createFrame(
notificationFrameId, /* frame name */ notificationFrameId, /* frame name */
@ -89,8 +97,8 @@
let provider = this.provider; let provider = this.provider;
// we cannot size the image when we apply it via listStyleImage, so // we cannot size the image when we apply it via listStyleImage, so
// use the toolbar image // use the toolbar image
let place = CustomizableUI.getPlaceForItem(this); let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id"));
val = val && place != "palette"; val = val && !!widgetGroup.areaType;
let icon = val ? provider.markedIcon : provider.unmarkedIcon; let icon = val ? provider.markedIcon : provider.unmarkedIcon;
let iconURL = icon || provider.icon32URL || provider.iconURL; let iconURL = icon || provider.icon32URL || provider.iconURL;
this.setAttribute("image", iconURL); this.setAttribute("image", iconURL);
@ -112,24 +120,26 @@
// do we have a savable page loaded? // do we have a savable page loaded?
let aURI = gBrowser.currentURI; let aURI = gBrowser.currentURI;
this.disabled = !aURI || !(aURI.schemeIs('http') || aURI.schemeIs('https')); let disabled = !aURI || !(aURI.schemeIs('http') || aURI.schemeIs('https'));
if (this.disabled) { // when overflowed in toolbar, we must have the attribute set
if (disabled) {
this.setAttribute("disabled", "true");
this.isMarked = false; this.isMarked = false;
} else { } else {
this.removeAttribute("disabled");
Social.isURIMarked(provider.origin, aURI, (isMarked) => { Social.isURIMarked(provider.origin, aURI, (isMarked) => {
this.isMarked = isMarked; this.isMarked = isMarked;
}); });
} }
this.content.setAttribute("origin", provider.origin); this.content.setAttribute("origin", provider.origin);
if (!this.inMenuPanel) {
let panel = this.panel; let panel = this.panel;
// if customization is currently happening, we may not have a panel // if customization is currently happening, we may not have a panel
// that we can hide // that we can hide
if (panel.hidePopup) { if (panel.hidePopup) {
panel.hidePopup(); panel.hidePopup();
panel.hidden = true; panel.hidden = true;
}
} }
this.pageData = null; this.pageData = null;
]]></body> ]]></body>
@ -157,7 +167,7 @@
this._loading = false; this._loading = false;
this.content.removeEventListener("DOMContentLoaded", DOMContentLoaded, true); this.content.removeEventListener("DOMContentLoaded", DOMContentLoaded, true);
// add our resizer after the dom is ready // add our resizer after the dom is ready
if (!this.inMenuPanel && this._useDynamicResizer) { if (this._useDynamicResizer) {
let DynamicResizeWatcher = Cu.import("resource:///modules/Social.jsm", {}).DynamicResizeWatcher; let DynamicResizeWatcher = Cu.import("resource:///modules/Social.jsm", {}).DynamicResizeWatcher;
this._dynamicResizer = new DynamicResizeWatcher(); this._dynamicResizer = new DynamicResizeWatcher();
this._dynamicResizer.start(this.panel, this.content); this._dynamicResizer.start(this.panel, this.content);
@ -213,27 +223,13 @@
frameIter = frameIter.nextElementSibling; frameIter = frameIter.nextElementSibling;
} }
// if we're a slice in the hambuger, use that panel instead let anchor = document.getAnonymousElementByAttribute(this._anchor, "class", "toolbarbutton-icon");
let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id")); // Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
let widget = widgetGroup.forWindow(window); // handling from preventing it being opened in some cases.
let inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL; setTimeout(() => {
if (inMenuPanel) {
PanelUI.showSubView("PanelUI-socialapi", widget.node,
CustomizableUI.AREA_PANEL);
} else {
let anchor = document.getAnonymousElementByAttribute(this, "class", "toolbarbutton-icon");
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false); panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
this.setAttribute("open", "true"); }, 0);
} ]]></body>
if (aResetOnClose) {
let evName = inMenuPanel ? "ViewHiding": "popuphidden";
let _hidden = () => {
panel.removeEventListener(evName, _hidden);
this.update();
};
panel.addEventListener(evName, _hidden, false);
}
]]></body>
</method> </method>
<method name="markCurrentPage"> <method name="markCurrentPage">
@ -241,8 +237,7 @@
<body><![CDATA[ <body><![CDATA[
// we always set the src on click if it has not been set for this tab, // we always set the src on click if it has not been set for this tab,
// but we only want to open the panel if it was previously annotated. // but we only want to open the panel if it was previously annotated.
let openPanel = this.isMarked || aOpenPanel || let openPanel = this.isMarked || aOpenPanel || !this.provider.haveLoggedInUser();
this.inMenuPanel || !this.provider.haveLoggedInUser();
let src = this.content.getAttribute("src"); let src = this.content.getAttribute("src");
if (!src || src == "about:blank") { if (!src || src == "about:blank") {
this.loadPanel(); this.loadPanel();
@ -287,13 +282,13 @@
if (!this._loading && this.contentDocument && if (!this._loading && this.contentDocument &&
this.contentDocument.readyState == "complete") { this.contentDocument.readyState == "complete") {
this.dispatchPanelEvent("socialFrameShow"); this.dispatchPanelEvent("socialFrameShow");
if (!this.inMenuPanel && this._useDynamicResizer) if (this._useDynamicResizer)
sizeSocialPanelToContent(this.panel, this.content); sizeSocialPanelToContent(this.panel, this.content);
} else { } else {
let panelBrowserOnload = (e) => { let panelBrowserOnload = (e) => {
this.content.removeEventListener("load", panelBrowserOnload, true); this.content.removeEventListener("load", panelBrowserOnload, true);
this.dispatchPanelEvent("socialFrameShow"); this.dispatchPanelEvent("socialFrameShow");
if (!this.inMenuPanel && this._useDynamicResizer) if (this._useDynamicResizer)
sizeSocialPanelToContent(this.panel, this.content); sizeSocialPanelToContent(this.panel, this.content);
}; };
this.content.addEventListener("load", panelBrowserOnload, true); this.content.addEventListener("load", panelBrowserOnload, true);
@ -328,24 +323,22 @@
this.setAttribute("image", uri.spec); this.setAttribute("image", uri.spec);
} }
break; break;
case "ViewShowing":
this.onShown();
break;
case "ViewHiding":
this.dispatchPanelEvent("socialFrameHide");
break;
} }
]]></body> ]]></body>
</method> </method>
</implementation> </implementation>
<handlers> <handlers>
<handler event="popupshowing"><![CDATA[
this._anchor.setAttribute("open", "true");
]]></handler>
<handler event="popupshown"><![CDATA[ <handler event="popupshown"><![CDATA[
this.onShown(); this.onShown();
]]></handler> ]]></handler>
<handler event="popuphidden"><![CDATA[ <handler event="popuphidden"><![CDATA[
this.dispatchPanelEvent("socialFrameHide"); this.dispatchPanelEvent("socialFrameHide");
this.removeAttribute("open"); this._anchor.removeAttribute("open");
this.update();
]]></handler> ]]></handler>
<handler event="command"><![CDATA[ <handler event="command"><![CDATA[
this.markCurrentPage(); this.markCurrentPage();

Просмотреть файл

@ -112,9 +112,12 @@ let PanelFrame = {
* set up. * set up.
*/ */
showPopup: function(aWindow, aPanelUI, aToolbarButton, aType, aOrigin, aSrc, aSize, aCallback) { showPopup: function(aWindow, aPanelUI, aToolbarButton, aType, aOrigin, aSrc, aSize, aCallback) {
// if we're a slice in the hamburger, use that panel instead // if we're overflowed, our anchor needs to be the overflow button
let widgetGroup = CustomizableUI.getWidget(aToolbarButton.getAttribute("id")); let widgetGroup = CustomizableUI.getWidget(aToolbarButton.getAttribute("id"));
let widget = widgetGroup.forWindow(aWindow); let widget = widgetGroup.forWindow(aWindow);
let anchorBtn = widget.anchor;
// if we're a slice in the hamburger, use that panel instead
let panel, showingEvent, hidingEvent; let panel, showingEvent, hidingEvent;
let inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL; let inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
if (inMenuPanel) { if (inMenuPanel) {
@ -156,7 +159,8 @@ let PanelFrame = {
} }
panel.addEventListener(hidingEvent, function onpopuphiding() { panel.addEventListener(hidingEvent, function onpopuphiding() {
panel.removeEventListener(hidingEvent, onpopuphiding); panel.removeEventListener(hidingEvent, onpopuphiding);
aToolbarButton.removeAttribute("open"); if (!inMenuPanel)
anchorBtn.removeAttribute("open");
if (dynamicResizer) if (dynamicResizer)
dynamicResizer.stop(); dynamicResizer.stop();
notificationFrame.docShell.isActive = false; notificationFrame.docShell.isActive = false;
@ -178,7 +182,7 @@ let PanelFrame = {
dispatchPanelEvent(aType + "FrameShow"); dispatchPanelEvent(aType + "FrameShow");
}; };
if (!inMenuPanel) if (!inMenuPanel)
aToolbarButton.setAttribute("open", "true"); anchorBtn.setAttribute("open", "true");
if (notificationFrame.contentDocument && if (notificationFrame.contentDocument &&
notificationFrame.contentDocument.readyState == "complete" && wasAlive) { notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
initFrameShow(); initFrameShow();
@ -195,7 +199,9 @@ let PanelFrame = {
aPanelUI.showSubView("PanelUI-" + aType + "api", widget.node, aPanelUI.showSubView("PanelUI-" + aType + "api", widget.node,
CustomizableUI.AREA_PANEL); CustomizableUI.AREA_PANEL);
} else { } else {
let anchor = aWindow.document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container"); // in overflow, the anchor is a normal toolbarbutton, in toolbar it is a badge button
let anchor = aWindow.document.getAnonymousElementByAttribute(anchorBtn, "class", "toolbarbutton-badge-container") ||
aWindow.document.getAnonymousElementByAttribute(anchorBtn, "class", "toolbarbutton-icon");
// Bug 849216 - open the popup asynchronously so we avoid the auto-rollup // Bug 849216 - open the popup asynchronously so we avoid the auto-rollup
// handling from preventing it being opened in some cases. // handling from preventing it being opened in some cases.
Services.tm.mainThread.dispatch(function() { Services.tm.mainThread.dispatch(function() {