Bug 870452 - Migrate feed button to new API, r=mconley

This commit is contained in:
Gijs Kruitbosch 2013-06-03 20:59:31 +02:00
Родитель c1c3d1e43c
Коммит e43023925b
10 изменённых файлов: 110 добавлений и 67 удалений

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

@ -8,66 +8,50 @@
* and shows UI when they are discovered. * and shows UI when they are discovered.
*/ */
var FeedHandler = { var FeedHandler = {
/** /** Called when the user clicks on the Subscribe to This Page... menu item,
* The click handler for the Feed icon in the toolbar. Opens the * or when the user clicks the feed button when the page contains multiple
* subscription page if user is not given a choice of feeds. * feeds.
* (Otherwise the list of available feeds will be presented to the
* user in a popup menu.)
*/
onFeedButtonClick: function(event) {
event.stopPropagation();
let feeds = gBrowser.selectedBrowser.feeds || [];
// If there are multiple feeds, the menu will open, so no need to do
// anything. If there are no feeds, nothing to do either.
if (feeds.length != 1)
return;
if (event.eventPhase == Event.AT_TARGET &&
(event.button == 0 || event.button == 1)) {
this.subscribeToFeed(feeds[0].href, event);
}
},
/** Called when the user clicks on the Subscribe to This Page... menu item.
* Builds a menu of unique feeds associated with the page, and if there * Builds a menu of unique feeds associated with the page, and if there
* is only one, shows the feed inline in the browser window. * is only one, shows the feed inline in the browser window.
* @param menuPopup * @param container
* The feed list menupopup to be populated. * The feed list container (menupopup or subview) to be populated.
* @returns true if the menu should be shown, false if there was only * @param isSubview
* Whether we're creating a subview (true) or menu (false/undefined)
* @returns true if the menu/subview should be shown, false if there was only
* one feed and the feed should be shown inline in the browser * one feed and the feed should be shown inline in the browser
* window (do not show the menupopup). * window (do not show the menupopup/subview).
*/ */
buildFeedList: function(menuPopup) { buildFeedList: function(container, isSubview) {
var feeds = gBrowser.selectedBrowser.feeds; var feeds = gBrowser.selectedBrowser.feeds;
if (feeds == null) { if (!isSubview && feeds == null) {
// XXX hack -- menu opening depends on setting of an "open" // XXX hack -- menu opening depends on setting of an "open"
// attribute, and the menu refuses to open if that attribute is // attribute, and the menu refuses to open if that attribute is
// set (because it thinks it's already open). onpopupshowing gets // set (because it thinks it's already open). onpopupshowing gets
// called after the attribute is unset, and it doesn't get unset // called after the attribute is unset, and it doesn't get unset
// if we return false. so we unset it here; otherwise, the menu // if we return false. so we unset it here; otherwise, the menu
// refuses to work past this point. // refuses to work past this point.
menuPopup.parentNode.removeAttribute("open"); container.parentNode.removeAttribute("open");
return false; return false;
} }
while (menuPopup.firstChild) while (container.firstChild)
menuPopup.removeChild(menuPopup.firstChild); container.removeChild(container.firstChild);
if (feeds.length <= 1) if (!feeds || feeds.length <= 1)
return false; return false;
// Build the menu showing the available feed choices for viewing. // Build the menu showing the available feed choices for viewing.
var itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
for (let feedInfo of feeds) { for (let feedInfo of feeds) {
var menuItem = document.createElement("menuitem"); var item = document.createElement(itemNodeType);
var baseTitle = feedInfo.title || feedInfo.href; var baseTitle = feedInfo.title || feedInfo.href;
var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]); var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
menuItem.setAttribute("class", "feed-menuitem"); item.setAttribute("class", "feed-" + itemNodeType);
menuItem.setAttribute("label", labelStr); item.setAttribute("label", labelStr);
menuItem.setAttribute("feed", feedInfo.href); item.setAttribute("feed", feedInfo.href);
menuItem.setAttribute("tooltiptext", feedInfo.href); item.setAttribute("tooltiptext", feedInfo.href);
menuItem.setAttribute("crop", "center"); item.setAttribute("crop", "center");
menuPopup.appendChild(menuItem); container.appendChild(item);
} }
return true; return true;
}, },
@ -76,7 +60,7 @@ var FeedHandler = {
* Subscribe to a given feed. Called when * Subscribe to a given feed. Called when
* 1. Page has a single feed and user clicks feed icon in location bar * 1. Page has a single feed and user clicks feed icon in location bar
* 2. Page has a single feed and user selects Subscribe menu item * 2. Page has a single feed and user selects Subscribe menu item
* 3. Page has multiple feeds and user selects from feed icon popup * 3. Page has multiple feeds and user selects from feed icon popup (or subview)
* 4. Page has multiple feeds and user selects from Subscribe submenu * 4. Page has multiple feeds and user selects from Subscribe submenu
* @param href * @param href
* The feed to subscribe to. May be null, in which case the * The feed to subscribe to. May be null, in which case the

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

@ -183,11 +183,7 @@ toolbar[overflowable]:not([overflowing]) > .overflow-button {
visibility: collapse; visibility: collapse;
} }
#feed-button > .toolbarbutton-menu-dropmarker { #PanelUI-feeds > .feed-toolbarbutton:-moz-locale-dir(rtl) {
display: none;
}
#feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
direction: rtl; direction: rtl;
} }

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

@ -998,20 +998,6 @@
label="&fullScreenCmd.label;" label="&fullScreenCmd.label;"
tooltiptext="&fullScreenButton.tooltip;"/> tooltiptext="&fullScreenButton.tooltip;"/>
<toolbarbutton id="feed-button"
type="menu"
class="toolbarbutton-1 chromeclass-toolbar-additional"
disabled="true"
label="&feedButton.label;"
tooltiptext="&feedButton.tooltip;"
onclick="return FeedHandler.onFeedButtonClick(event);">
<menupopup position="after_end"
id="feed-menu"
onpopupshowing="return FeedHandler.buildFeedList(this);"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"/>
</toolbarbutton>
#ifdef MOZ_SERVICES_SYNC #ifdef MOZ_SERVICES_SYNC
<toolbarbutton id="sync-button" <toolbarbutton id="sync-button"
class="toolbarbutton-1 chromeclass-toolbar-additional" class="toolbarbutton-1 chromeclass-toolbar-additional"

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

@ -40,6 +40,8 @@
onclick="PlacesCommandHook.showPlacesOrganizer('History'); PanelUI.hide();"/> onclick="PlacesCommandHook.showPlacesOrganizer('History'); PanelUI.hide();"/>
</panelview> </panelview>
<panelview id="PanelUI-feeds" flex="1" oncommand="FeedHandler.subscribeToFeed(null, event);"></panelview>
<panelview id="PanelUI-help" flex="1"> <panelview id="PanelUI-help" flex="1">
<label value="&helpMenu.label;"/> <label value="&helpMenu.label;"/>
<vbox id="PanelUI-helpItems"/> <vbox id="PanelUI-helpItems"/>

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

@ -162,6 +162,9 @@ const PanelUI = {
let evt = document.createEvent("CustomEvent"); let evt = document.createEvent("CustomEvent");
evt.initCustomEvent("ViewShowing", true, true, viewNode); evt.initCustomEvent("ViewShowing", true, true, viewNode);
viewNode.dispatchEvent(evt); viewNode.dispatchEvent(evt);
if (evt.defaultPrevented) {
return;
}
let tempPanel = document.createElement("panel"); let tempPanel = document.createElement("panel");
tempPanel.setAttribute("type", "arrow"); tempPanel.setAttribute("type", "arrow");

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

@ -191,6 +191,9 @@
let evt = document.createEvent("CustomEvent"); let evt = document.createEvent("CustomEvent");
evt.initCustomEvent("ViewShowing", true, true, viewNode); evt.initCustomEvent("ViewShowing", true, true, viewNode);
viewNode.dispatchEvent(evt); viewNode.dispatchEvent(evt);
if (evt.defaultPrevented) {
return;
}
this._currentSubView = viewNode; this._currentSubView = viewNode;

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

@ -768,8 +768,10 @@ let CustomizableUIInternal = {
} }
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional"); node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
let handler = this.handleWidgetClick.bind(this, aWidget, node); let commandHandler = this.handleWidgetCommand.bind(this, aWidget, node);
node.addEventListener("command", handler, false); node.addEventListener("command", commandHandler, false);
let clickHandler = this.handleWidgetClick.bind(this, aWidget, node);
node.addEventListener("click", clickHandler, false);
// If the widget has a view, and has view showing / hiding listeners, // If the widget has a view, and has view showing / hiding listeners,
// hook those up to this widget. // hook those up to this widget.
@ -796,6 +798,10 @@ let CustomizableUIInternal = {
LOG("Widget " + aWidget.id + " showing and hiding event handlers set."); LOG("Widget " + aWidget.id + " showing and hiding event handlers set.");
} }
if (aWidget.onCreated) {
aWidget.onCreated(node);
}
} }
aWidget.instances.set(aDocument, node); aWidget.instances.set(aDocument, node);
@ -826,8 +832,8 @@ let CustomizableUIInternal = {
return def; return def;
}, },
handleWidgetClick: function(aWidget, aNode, aEvent) { handleWidgetCommand: function(aWidget, aNode, aEvent) {
LOG("handleWidgetClick"); LOG("handleWidgetCommand");
if (aWidget.type == "button") { if (aWidget.type == "button") {
this.maybeAutoHidePanel(aEvent); this.maybeAutoHidePanel(aEvent);
@ -841,7 +847,7 @@ let CustomizableUIInternal = {
} else { } else {
//XXXunf Need to think this through more, and formalize. //XXXunf Need to think this through more, and formalize.
Services.obs.notifyObservers(aNode, Services.obs.notifyObservers(aNode,
"customizedui-widget-click", "customizedui-widget-command",
aWidget.id); aWidget.id);
} }
} else if (aWidget.type == "view") { } else if (aWidget.type == "view") {
@ -851,6 +857,24 @@ let CustomizableUIInternal = {
} }
}, },
handleWidgetClick: function(aWidget, aNode, aEvent) {
LOG("handleWidgetClick");
if (aWidget.type == "button") {
this.maybeAutoHidePanel(aEvent);
}
if (aWidget.onClick) {
try {
aWidget.onClick.call(null, aEvent);
} catch(e) {
Cu.reportError(e);
}
} else {
//XXXunf Need to think this through more, and formalize.
Services.obs.notifyObservers(aNode, "customizedui-widget-click", aWidget.id);
}
},
maybeAutoHidePanel: function(aEvent) { maybeAutoHidePanel: function(aEvent) {
if (aEvent.type == "keypress" && if (aEvent.type == "keypress" &&
!(aEvent.keyCode == aEvent.DOM_VK_ENTER || !(aEvent.keyCode == aEvent.DOM_VK_ENTER ||
@ -1361,6 +1385,10 @@ let CustomizableUIInternal = {
} }
} }
widget.onClick = typeof aData.onClick == "function" ? aData.onClick : null;
widget.onCreated = typeof aData.onCreated == "function" ? aData.onCreated : null;
if (widget.type == "button") { if (widget.type == "button") {
widget.onCommand = typeof aData.onCommand == "function" ? widget.onCommand = typeof aData.onCommand == "function" ?
aData.onCommand : aData.onCommand :

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

@ -450,4 +450,45 @@ const CustomizableWidgets = [{
return node; return node;
} }
},
{
id: "feed-button",
type: "view",
viewId: "PanelUI-feeds",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL, CustomizableUI.AREA_NAVBAR],
onClick: function(aEvent) {
let win = aEvent.target.ownerDocument.defaultView;
let feeds = win.gBrowser.selectedBrowser.feeds;
// Here, we only care about the case where we have exactly 1 feed and the
// user clicked...
let isClick = (aEvent.button == 0 || aEvent.button == 1);
if (feeds && feeds.length == 1 && isClick) {
aEvent.preventDefault();
aEvent.stopPropagation();
win.FeedHandler.subscribeToFeed(feeds[0].href, aEvent);
}
},
onViewShowing: function(aEvent) {
let doc = aEvent.detail.ownerDocument;
let container = doc.getElementById("PanelUI-feeds");
let gotView = doc.defaultView.FeedHandler.buildFeedList(container, true);
// For no feeds or only a single one, don't show the panel.
if (!gotView) {
aEvent.preventDefault();
aEvent.stopPropagation();
return;
}
},
onCreated: function(node) {
let win = node.ownerDocument.defaultView;
let selectedBrowser = win.gBrowser.selectedBrowser;
let feeds = selectedBrowser && selectedBrowser.feeds;
if (!feeds || !feeds.length) {
node.setAttribute("disabled", "true");
}
}
}]; }];

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

@ -166,9 +166,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY tabGroupsButton.label "Tab Groups"> <!ENTITY tabGroupsButton.label "Tab Groups">
<!ENTITY tabGroupsButton.tooltip "Group your tabs"> <!ENTITY tabGroupsButton.tooltip "Group your tabs">
<!ENTITY feedButton.label "Subscribe">
<!ENTITY feedButton.tooltip "Subscribe to this page…">
<!ENTITY bookmarksButton.label "Bookmarks"> <!ENTITY bookmarksButton.label "Bookmarks">
<!ENTITY bookmarksCmd.commandkey "b"> <!ENTITY bookmarksCmd.commandkey "b">

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

@ -62,3 +62,6 @@ copy-button.tooltiptext = Copy
paste-button.label = Paste paste-button.label = Paste
paste-button.tooltiptext = Paste paste-button.tooltiptext = Paste
feed-button.label = Subscribe
feed-button.tooltiptext = Subscribe to this page…