Bug 419544 - "places menupopups options ("open all in tabs", "open <feed website>") do not update correctly" [p=mak77@supereva.it (Marco Bonardo [mak77]) r=Mano a=blocking-firefox3+]

This commit is contained in:
2008-03-12 04:08:08 -07:00
parent 8d2f3315fd
commit 8d467372c6
4 changed files with 150 additions and 129 deletions

View File

@@ -637,69 +637,86 @@ var BookmarksEventHandler = {
*/
onPopupShowing: function BM_onPopupShowing(event) {
var target = event.originalTarget;
if (target.localName == "menupopup" &&
target.id != "bookmarksMenuPopup" &&
target.getAttribute("anonid") != "chevronPopup") {
// Add the "Open All in Tabs" menuitem if there are
// at least two menuitems with places result nodes.
// Add the "Open (Feed Name)" menuitem if it's a livemark with a siteURI.
var numNodes = 0;
var hasMultipleEntries = false;
var currentChild = target.firstChild;
while (currentChild) {
if (currentChild.localName == "menuitem" && currentChild.node)
numNodes++;
if (!target.hasAttribute("placespopup"))
return;
// If the menuitem already exists, do nothing.
if (currentChild.getAttribute("openInTabs") == "true")
return;
if (currentChild.hasAttribute("siteURI"))
return;
currentChild = currentChild.nextSibling;
}
if (numNodes > 1)
hasMultipleEntries = true;
var itemId = target._resultNode.itemId;
var siteURIString = "";
if (itemId != -1 && PlacesUtils.livemarks.isLivemark(itemId)) {
var siteURI = PlacesUtils.livemarks.getSiteURI(itemId);
if (siteURI)
siteURIString = siteURI.spec;
}
if (hasMultipleEntries || siteURIString) {
var separator = document.createElement("menuseparator");
target.appendChild(separator);
if (siteURIString) {
var openHomePage = document.createElement("menuitem");
openHomePage.setAttribute("siteURI", siteURIString);
openHomePage.setAttribute("oncommand",
"openUILink(this.getAttribute('siteURI'), event);");
// If a user middle-clicks this item we serve the oncommand event
// We are using checkForMiddleClick because of Bug 246720
// Note: stopPropagation is needed to avoid serving middle-click
// with BT_onClick that would open all items in tabs
openHomePage.setAttribute("onclick",
"checkForMiddleClick(this, event); event.stopPropagation();");
openHomePage.setAttribute("label",
PlacesUtils.getFormattedString("menuOpenLivemarkOrigin.label",
[target.parentNode.getAttribute("label")]));
target.appendChild(openHomePage);
}
if (hasMultipleEntries) {
var openInTabs = document.createElement("menuitem");
openInTabs.setAttribute("openInTabs", "true");
openInTabs.setAttribute("oncommand",
"PlacesUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);");
openInTabs.setAttribute("label",
gNavigatorBundle.getString("menuOpenAllInTabs.label"));
target.appendChild(openInTabs);
// Check if the popup contains at least 2 menuitems with places nodes
var numNodes = 0;
var hasMultipleURIs = false;
var currentChild = target.firstChild;
while (currentChild) {
if (currentChild.localName == "menuitem" && currentChild.node) {
if (++numNodes == 2) {
hasMultipleURIs = true;
break;
}
}
currentChild = currentChild.nextSibling;
}
var itemId = target._resultNode.itemId;
var siteURIString = "";
if (itemId != -1 && PlacesUtils.livemarks.isLivemark(itemId)) {
var siteURI = PlacesUtils.livemarks.getSiteURI(itemId);
if (siteURI)
siteURIString = siteURI.spec;
}
if (!siteURIString && target._endOptOpenSiteURI) {
target.removeChild(target._endOptOpenSiteURI);
target._endOptOpenSiteURI = null;
}
if (!hasMultipleURIs && target._endOptOpenAllInTabs) {
target.removeChild(target._endOptOpenAllInTabs);
target._endOptOpenAllInTabs = null;
}
if (!(hasMultipleURIs || siteURIString)) {
// we don't have to show any option
if (target._endOptSeparator) {
target.removeChild(target._endOptSeparator);
target._endOptSeparator = null;
target._endMarker = -1;
}
return;
}
if (!target._endOptSeparator) {
// create a separator before options
target._endOptSeparator = document.createElement("menuseparator");
target._endOptSeparator.setAttribute("builder", "end");
target._endMarker = target.childNodes.length;
target.appendChild(target._endOptSeparator);
}
if (siteURIString && !target._endOptOpenSiteURI) {
// Add "Open (Feed Name)" menuitem if it's a livemark with a siteURI
target._endOptOpenSiteURI = document.createElement("menuitem");
target._endOptOpenSiteURI.setAttribute("siteURI", siteURIString);
target._endOptOpenSiteURI.setAttribute("oncommand",
"openUILink(this.getAttribute('siteURI'), event);");
// If a user middle-clicks this item we serve the oncommand event
// We are using checkForMiddleClick because of Bug 246720
// Note: stopPropagation is needed to avoid serving middle-click
// with BT_onClick that would open all items in tabs
target._endOptOpenSiteURI.setAttribute("onclick",
"checkForMiddleClick(this, event); event.stopPropagation();");
target._endOptOpenSiteURI.setAttribute("label",
PlacesUtils.getFormattedString("menuOpenLivemarkOrigin.label",
[target.parentNode.getAttribute("label")]));
target.appendChild(target._endOptOpenSiteURI);
}
if (hasMultipleURIs && !target._endOptOpenAllInTabs) {
// Add the "Open All in Tabs" menuitem if there are
// at least two menuitems with places result nodes.
target._endOptOpenAllInTabs = document.createElement("menuitem");
target._endOptOpenAllInTabs.setAttribute("oncommand",
"PlacesUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);");
target._endOptOpenAllInTabs.setAttribute("label",
gNavigatorBundle.getString("menuOpenAllInTabs.label"));
target.appendChild(target._endOptOpenAllInTabs);
}
},

View File

@@ -78,6 +78,8 @@
<!-- This is the view that manage the popup -->
<field name="_rootView">PlacesUtils.getViewForNode(this);</field>
<field name="_built">false</field>
<method name="onDragOver">
<parameter name="aEvent"/>
<parameter name="aFlavour"/>
@@ -231,14 +233,14 @@
// draw the drop indicator outside of them
var betweenMarkers = true;
if (this._startMarker != -1 &&
target.boxObject.y < this.childNodes[this._startMarker].boxObject.y)
target.boxObject.y <= this.childNodes[this._startMarker].boxObject.y)
betweenMarkers = false;
if (this._endMarker != -1 &&
target.boxObject.y > this.childNodes[this._endMarker].boxObject.y)
target.boxObject.y >= this.childNodes[this._endMarker].boxObject.y)
betweenMarkers = false;
// hide the dropmarker if current node is not a places bookmark item
return !(target && betweenMarkers && this.canDrop());
return !(target && target.node && betweenMarkers && this.canDrop());
]]></body>
</method>
@@ -494,14 +496,13 @@
readonly="true"
onget="return this._controller;"/>
<field name="_built">false</field>
<method name="onPopupShowing">
<parameter name="aEvent"/>
<body><![CDATA[
var popup = aEvent.target;
var resultNode = popup._resultNode;
resultNode.containerOpen = true;
if (!resultNode.containerOpen)
resultNode.containerOpen = true;
if (!popup._built)
this._rebuild(popup);
]]></body>
@@ -522,58 +523,6 @@
]]></body>
</method>
<method name="_cleanMenu">
<parameter name="aPopup"/>
<body><![CDATA[
// Find static menuitems that should go at the start
// and end of the menu, marked by builder="start" and
// builder="end" attributes, and keep track of their indices.
// All of the items between the start and end should be removed.
var items = [];
aPopup._startMarker = -1;
aPopup._endMarker = -1;
for (var i = 0; i < aPopup.childNodes.length; ++i) {
var item = aPopup.childNodes[i];
if (item.getAttribute("builder") == "start") {
aPopup._startMarker = i;
continue;
}
if (item.getAttribute("builder") == "end") {
aPopup._endMarker = i;
continue;
}
if ((aPopup._startMarker != -1) && (aPopup._endMarker == -1))
items.push(item);
}
// If static items at the beginning were found, remove all items between
// them and the static content at the end.
for (var i = 0; i < items.length; ++i) {
// skip the empty menu item
if (aPopup._emptyMenuItem != items[i]) {
aPopup.removeChild(items[i]);
if (this._endMarker > 0)
--this._endMarker;
}
}
// If no static items were found at the beginning, remove all items before
// the static items at the end.
if (aPopup._startMarker == -1) {
var end = aPopup._endMarker == -1 ?
aPopup.childNodes.length - 1 : aPopup._endMarker - 1;
for (var i = end; i >=0; i--) {
// skip the empty menu item
if (aPopup._emptyMenuItem != aPopup.childNodes[i]) {
aPopup.removeChild(aPopup.childNodes[i]);
if (aPopup._endMarker > 0)
--aPopup._endMarker;
}
}
}
]]></body>
</method>
<method name="removeItem">
<parameter name="child"/>
<body><![CDATA[
@@ -637,7 +586,7 @@
<method name="_rebuild">
<parameter name="aPopup"/>
<body><![CDATA[
this._cleanMenu(aPopup);
PlacesUtils.cleanPlacesPopup(aPopup);
var cc = aPopup._resultNode.childCount;
if (cc > 0) {

View File

@@ -983,10 +983,20 @@
<body><![CDATA[
var element =
PlacesUtils.createMenuItemForNode(aChild, this._containerNodesMap);
if (aBefore)
aParentPopup.insertBefore(element, aBefore);
else
aParentPopup.appendChild(element);
else {
// Add the new element to the menu. If there is static content at
// the end of the menu, add the element before that. Otherwise,
// just add to the end.
if (aParentPopup._endMarker != -1) {
aParentPopup.insertBefore(element,
aParentPopup.childNodes[aParentPopup._endMarker++]);
}
else
aParentPopup.appendChild(element);
}
]]></body>
</method>
@@ -996,12 +1006,7 @@
if (aPopup._built)
return;
// remove previous menu items
while (aPopup.hasChildNodes())
aPopup.removeChild(aPopup.firstChild);
// restore the empty-menu item if has been created already
if (aPopup._emptyMenuItem)
aPopup.appendChild(aPopup._emptyMenuItem);
PlacesUtils.cleanPlacesPopup(aPopup);
var resultNode = aPopup._resultNode;
if (!resultNode.containerOpen)
@@ -1018,8 +1023,10 @@
}
}
else {
// add element to show it is empty.
this._showEmptyMenuItem(aPopup);
// This menu is empty. If there is no static content, add
// an element to show it is empty.
if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
this._showEmptyMenuItem(aPopup);
}
aPopup._built = true;
]]></body>

View File

@@ -1896,6 +1896,54 @@ var PlacesUtils = {
return element;
},
cleanPlacesPopup: function PU_cleanPlacesPopup(aPopup) {
// Find static menuitems at the start and at the end of the menupopup,
// marked by builder="start" and builder="end" attributes, and set
// markers to keep track of their indices.
var items = [];
aPopup._startMarker = -1;
aPopup._endMarker = -1;
for (var i = 0; i < aPopup.childNodes.length; ++i) {
var item = aPopup.childNodes[i];
if (item.getAttribute("builder") == "start") {
aPopup._startMarker = i;
continue;
}
if (item.getAttribute("builder") == "end") {
aPopup._endMarker = i;
continue;
}
if ((aPopup._startMarker != -1) && (aPopup._endMarker == -1))
items.push(item);
}
// If static items at the beginning were found, remove all items between
// them and the static content at the end.
for (var i = 0; i < items.length; ++i) {
// skip the empty menu item
if (aPopup._emptyMenuItem != items[i]) {
aPopup.removeChild(items[i]);
if (this._endMarker > 0)
--this._endMarker;
}
}
// If no static items were found at the beginning, remove all items before
// the static items at the end.
if (aPopup._startMarker == -1) {
var end = aPopup._endMarker == -1 ?
aPopup.childNodes.length - 1 : aPopup._endMarker - 1;
for (var i = end; i >= 0; i--) {
// skip the empty menu item
if (aPopup._emptyMenuItem != aPopup.childNodes[i]) {
aPopup.removeChild(aPopup.childNodes[i]);
if (aPopup._endMarker > 0)
--aPopup._endMarker;
}
}
}
},
getBestTitle: function PU_getBestTitle(aNode) {
var title;
if (!aNode.title && this.uriTypes.indexOf(aNode.type) != -1) {