Fixes to toolbar and menu to work with new history backend.

r=brettw sr=ben bug=209804
This commit is contained in:
annie.sullivan%gmail.com 2006-01-27 18:30:51 +00:00
parent 6267d722fe
commit 104b4f993a
6 changed files with 121 additions and 122 deletions

View File

@ -52,12 +52,22 @@ PlacesBrowserShim.init = function PBS_init() {
this._lms =
Cc["@mozilla.org/browser/livemark-service;1"].
getService(Ci.nsILivemarkService);
this._hist =
Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
// Override the old addLivemark function
BookmarksUtils.addLivemark = function(a,b,c,d) {PlacesBrowserShim.addLivemark(a,b,c,d);};
var newMenuPopup = document.getElementById("bookmarksMenuPopup");
newMenuPopup.folderId = this._bms.bookmarksRoot;
var query = this._hist.getNewQuery();
query.setFolders([this._bms.bookmarksRoot], 1);
var options = this._hist.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
var result = this._hist.executeQuery(query, options);
newMenuPopup._result = result;
newMenuPopup._resultNode = result.root;
};
PlacesBrowserShim.addBookmark = function PBS_addBookmark() {

View File

@ -432,7 +432,22 @@ var PlacesController = {
* @returns true if the node is a container item, false otherwise
*/
nodeIsContainer: function PC_nodeIsContainer(node) {
return node.folderType != "";
const NHRN = Ci.nsINavHistoryResultNode;
return node.type == NHRN.RESULT_TYPE_HOST ||
node.type == NHRN.RESULT_TYPE_QUERY ||
node.type == NHRN.RESULT_TYPE_FOLDER ||
node.type == NHRN.RESULT_TYPE_REMOTE_CONTAINER;
},
/**
* Determines whether or not a ResultNode is a remotecontainer item or not
* @param node
* A NavHistoryResultNode
* @returns true if the node is a container item, false otherwise
*/
nodeIsRemoteContainer: function PC_nodeIsRemoteContainer(node) {
const NHRN = Ci.nsINavHistoryResultNode;
return node.type == NHRN.RESULT_TYPE_REMOTE_CONTAINER;
},
/**
@ -495,7 +510,7 @@ var PlacesController = {
* is-mutable "mutable"
* is-removable "removable"
* is-multiselect"multiselect"
* is-container "container"
* is-container "remotecontainer"
* @returns an object with each of the properties above set if the selection
* matches that rule.
*/
@ -509,8 +524,8 @@ var PlacesController = {
var selectedNode = this._activeView.selectedNode;
if (this.nodeIsFolder(selectedNode))
metadata["folder"] = true;
if (this.nodeIsContainer(selectedNode))
metadata["container"] = true;
if (this.nodeIsRemoteContainer(selectedNode))
metadata["remotecontainer"] = true;
}
var foundNonLeaf = false;
@ -519,7 +534,8 @@ var PlacesController = {
var node = nodes[i];
if (node.type != Ci.nsINavHistoryResultNode.RESULT_TYPE_URI)
foundNonLeaf = true;
if (!node.readonly && node.folderType == "")
if (!node.readonly &&
node.type != Ci.nsINavHistoryResultNode.RESULT_TYPE_REMOTE_CONTAINER)
metadata["mutable"] = true;
}
if (this._activeView.getAttribute("seltype") != "single")
@ -655,15 +671,13 @@ var PlacesController = {
openLinksInTabs: function PC_openLinksInTabs() {
var node = this._activeView.selectedNode;
if (this._activeView.hasSingleSelection && this.nodeIsFolder(node)) {
var queries = node.getQueries({});
var kids = this._hist.executeQueries(queries, queries.length,
node.queryOptions);
var cc = kids.childCount;
node.QueryInterface(Ci.nsINavHistoryFolderResultNode);
var cc = node.childCount;
for (var i = 0; i < cc; ++i) {
var node = kids.getChild(i);
if (this.nodeIsURI(node))
var childNode = node.getChild(i);
if (this.nodeIsURI(childNode))
this._activeView.browserWindow.openNewTabWith(
node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri,
childNode.QueryInterface(Ci.nsINavHistoryURIResultNode).uri,
null, null);
}
}
@ -773,14 +787,15 @@ var PlacesController = {
var node = nodes[i];
var index = this.getIndexOfNode(node);
if (this.nodeIsFolder(node)) {
txns.push(new PlacesRemoveFolderTransaction(node.folderId,
node.parent.folderId,
// TODO -- node.parent might be a query and not a folder. See bug 324948
txns.push(new PlacesRemoveFolderTransaction(node.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId,
node.parent.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId,
index));
}
else if (this.nodeIsFolder(node.parent)) {
// this item is in a bookmark folder
txns.push(new PlacesRemoveItemTransaction(this._uri(node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri),
node.parent.folderId,
node.parent.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId,
index));
}
else {
@ -815,10 +830,10 @@ var PlacesController = {
*/
getIndexOfNode: function PC_getIndexOfNode(node) {
var parent = node.parent;
if (!parent)
if (!parent || !this.nodeIsContainer(parent))
return -1;
var cc = parent.childCount;
for (var i = 0; i < cc && parent.getChild(i) != node; ++i);
var cc = parent.QueryInterface(Ci.nsINavHistoryContainerResultNode).childCount;
for (var i = 0; i < cc && parent.QueryInterface(Ci.nsINavHistoryContainerResultNode).getChild(i) != node; ++i);
return i < cc ? i : -1;
},
@ -835,7 +850,24 @@ var PlacesController = {
switch (type) {
case TYPE_X_MOZ_PLACE_CONTAINER:
case TYPE_X_MOZ_PLACE:
return node.folderId + "\n" + node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri + "\n" + node.parent.folderId + "\n" + this.getIndexOfNode(node);
var wrapped = "";
if (this.nodeIsFolder(node))
wrapped += node.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId + "\n";
else
wrapped += "0\n";
if (this.nodeIsURI(node))
wrapped += node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri + "\n";
else
wrapped += "\n";
if (this.nodeIsFolder(node.parent))
wrapped += node.parent.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId + "\n";
else
wrapped += "0\n";
wrapped += this.getIndexOfNode(node);
return wrapped;
case TYPE_X_MOZ_URL:
return node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri + "\n" + node.title;
case TYPE_HTML:
@ -863,9 +895,9 @@ var PlacesController = {
case TYPE_X_MOZ_PLACE_CONTAINER:
case TYPE_X_MOZ_PLACE:
nodes.push({ folderId: parseInt(parts[i++]),
uri: parts[i] ? this._uri(parts[i++]) : null,
parent: parseInt(parts[i++]),
index: parseInt(parts[i]) });
uri: parts[i] ? this._uri(parts[i]) : null,
parent: parseInt(parts[++i]),
index: parseInt(parts[++i]) });
break;
case TYPE_X_MOZ_URL:
nodes.push({ uri: this._uri(parts[i++]),

View File

@ -9,34 +9,18 @@
<binding id="places-menupopup"
extends="chrome://global/content/bindings/popup.xml#popup">
<implementation>
<constructor><![CDATA[
this._places =
Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
this._bms =
Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
this._bms.addObserver(this._observer, false);
<constructor><![CDATA[
]]></constructor>
<destructor><![CDATA[
this._bms.removeObserver(this._observer);
<destructor><![CDATA[
]]></destructor>
<property name="folderId"
onget="return parseInt(this.getAttribute('folderId'));"
onset="this.setAttribute('folderId', val); return val;"/>
<method name="onPopupShowing">
<body><![CDATA[
var query = this._places.getNewQuery();
query.setFolders([this.folderId], 1);
var options = this._places.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
// options.setExpandPlaces(); ?
this._result = this._places.executeQuery(query, options);
if (PlacesController.nodeIsContainer(this._resultNode)) {
this._resultNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
this._resultNode.containerOpen = true;
}
this._rebuild();
if (this.popupShowingCallback)
this.popupShowingCallback();
@ -46,6 +30,16 @@
<field name="_selection">null</field>
<field name="_result">null</field>
<filed name="_resultNode">null</filed>
<method name="setResultAndNode">
<parameter name="result"/>
<parameter name="resultNode"/>
<body><![CDATA[
this._result = result;
this._resultNode = resultNode;
this._rebuild();
]]></body>
</method>
<method name="getResult">
<body><![CDATA[
return this._result;
@ -84,20 +78,24 @@
<body><![CDATA[
this._cleanMenu();
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var cc = this._result.root.childCount;
if (PlacesController.nodeIsContainer(this._resultNode))
this._resultNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
else
return; // Nothing to do if this menu isn't a container.
var cc = this._resultNode.childCount;
if (cc > 0) {
for (var i = 0; i < cc; ++i) {
var child = this._result.root.getChild(i);
var child = this._resultNode.getChild(i);
var element = null;
if (PlacesController.nodeIsURI(child)) {
element = document.createElementNS(XULNS, "menuitem");
element.setAttribute("label", child.title);
element.setAttribute("url", child.QueryInterface(nsINavHistoryURIResultNode).uri);
element.setAttribute("url", child.QueryInterface(Ci.nsINavHistoryURIResultNode).uri);
element.setAttribute("statustext", child.url);
element.setAttribute("image", child.icon.spec);
element.className = "menuitem-iconic bookmark-item";
}
else if (PlacesController.nodeIsFolder(child)) {
else if (PlacesController.nodeIsContainer(child)) {
element = document.createElementNS(XULNS, "menu");
element.setAttribute("type", "menu");
element.setAttribute("container", "true");
@ -108,7 +106,8 @@
// The context menu is set here instead of in the xbl constructor
// because it doesn't get initialized properly if set in the constructor.
popup.setAttribute("context", "placesContext");
popup.folderId = child.folderId;
popup._result = this._result;
popup._resultNode = child;
element.className = "menu-iconic bookmark-item";
}
// else if (nodeIsQuery) ... add menu to build kids
@ -129,16 +128,6 @@
]]></body>
</method>
<method name="load">
<parameter name="queries"/>
<parameter name="options"/>
<body><![CDATA[
this._result = this._places.executeQueries(queries, queries.length,
options);
this._rebuild();
]]></body>
</method>
<property name="isBookmarks">
<getter><![CDATA[
return PlacesController.nodeIsFolder(this.getResult());
@ -186,17 +175,20 @@
<getter><![CDATA[
// By default, the insertion point is at the top level, at the end.
var index = -1;
var folderId = this._result.folderId;
var folderId = 0;
if(PlacesController.nodeIsFolder(this._resultNode))
folderId = this._resultNode.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
if (this.hasSelection) {
if(PlacesController.nodeIsFolder(this.selectedNode))
if(PlacesController.nodeIsFolder(this.selectedNode)) {
// If there is a folder selected, the insertion point is the
// end of the folder.
folderId = this.selectedNode.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
else
} else {
// If there is another type of node selected, the insertion point
// is after that node.
index = PlacesController.getIndexOfNode(this.selectedNode)
}
}
return new InsertionPoint(folderId, index);
]]></getter>
@ -218,49 +210,6 @@
]]></body>
</method>
<!-- nsINavBookmarkObserver -->
<field name="_observer"><![CDATA[({
_numBatches: 0,
_self: this,
onBeginUpdateBatch: function TB_O_onBeginUpdateBatch() {
++this._numBatches;
},
onEndUpdateBatch: function TB_O_onEndUpdateBatch() {
if (!--this._numBatches) ;
//this._self.init();
},
onItemAdded: function TB_O_onItemAdded(bookmark, folder, index) {
//this._self.init();
},
onItemRemoved: function TB_O_onItemRemoved(bookmark, folder, index) {
//this._self.init();
},
onItemMoved: function TB_O_onItemMoved(bookmark, folder, oldIndex, newIndex) {
//this._self.init();
},
onItemChanged: function TB_O_onItemChanged(bookmark, property, value) {
//this._self.init();
},
onItemVisited: function TB_0_onItemVisited(bookmark, visitId, time) {
//this._self.init();
},
onItemReplaced: function TB_0_onItemReplaced(filder, item, newItem) {
// this._self.init();
},
onFolderAdded: function TB_O_onFolderAdded(folder, parent, index) {
//this._self.init();
},
onFolderRemoved: function TB_O_onFolderRemoved(folder, parent, index) {
//this._self.init();
},
onFolderMoved: function TB_O_onFolderMoved(folder, oldParent, oldIndex, newParent, newIndex) {
//this._self.init();
},
onFolderChanged: function TB_O_onFolderChanged(folder, property) {
//this._self.init();
},
})]]></field>
<method name="saveSelection">
<body><![CDATA[
]]></body>
@ -278,11 +227,9 @@
</handler>
<handler event="popuphidden">
if (event.target == this) {
// If this is a container, notify the service.
if (PlacesController.nodeIsContainer(this._result)) {
var serv = Cc[this._result.folderType]
.getService(Ci.nsIBookmarksContainer);
serv.onContainerClosed(this._result.folderId);
if (PlacesController.nodeIsContainer(this._resultNode)) {
this._resultNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
this._resultNode.containerOpen = false;
}
}
</handler>

View File

@ -287,7 +287,7 @@ var PlacesPage = {
search: function PP_applyFilter(filterString) {
switch (PlacesSearchBox.filterCollection) {
case "collection":
var folder = this._content.getResult().folderId;
var folder = this._content.getResult().root.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
this._content.applyFilter(filterString, true, folder);
this._setHeader("results", filterString);
break;

View File

@ -74,7 +74,8 @@
// it doesn't get initialized properly in the constructor.
popup.setAttribute("context", "placesContext");
button.appendChild(popup);
popup.folderId = child.folderId;
popup._result = this._result;
popup._resultNode = child;
}
button.className = "menuitem-iconic bookmark-item";
button.node = child;
@ -97,7 +98,8 @@
// This is set here and not in the XBL constructor for the menu because
// it doesn't get initialized properly in the constructor.
popup.setAttribute("context", "placesContext");
popup.folderId = this._result.root.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
popup._result = this._result;
popup._resultNode = this._result.root;
var t = this;
popup.popupShowingCallback = function() {t.chevronPopupShowing();};
this._chevron.appendChild(popup);
@ -214,18 +216,22 @@
<getter><![CDATA[
// By default, the insertion point is at the top level, at the end.
var index = -1;
var folderId = this._result.root.QueryInterface(nsINavHistoryFolderResultNode).folderId;
var folderId = this._result.root.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
if (this.hasSelection) {
if(PlacesController.nodeIsFolder(this.selectedNode))
if(PlacesController.nodeIsFolder(this.selectedNode)) {
// If there is a folder selected, the insertion point is the
// end of the folder.
folderId = this.selectedNode.folderId;
else
dump("Selected node is folder. ");
folderId = this.selectedNode.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
} else {
// If there is another type of node selected, the insertion point
// is after that node.
dump("Selected node is node. ");
index = PlacesController.getIndexOfNode(this.selectedNode)
}
}
dump("setting insertion point to index " + index + " folderId " + folderId + "\n");
return new InsertionPoint(folderId, index);
]]></getter>
</property>
@ -313,11 +319,15 @@
},
onDrop: function TBV_DO_onDrop(event, dropData, session) {
var result = this._self.getResult();
var destContainer = result.folderId;
if (!PlacesController.nodeIsFolder(result.root))
return;
result.root.QueryInterface(Ci.nsINavHistoryFolderResultNode);
var destContainer = result.root.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
var destIndex = -1;
var orientation = 1;
if (event.target.localName == "toolbarbutton") {
if (PlacesController.nodeIsFolder(event.target.node)) {
event.target.node.QueryInterface(Ci.nsINavHistoryFolderResultNode);
destContainer = event.target.node.folderId;
destIndex = -1;
orientation = 0;
@ -359,7 +369,7 @@
if (event.target.localName == "toolbarbutton")
this._selection = event.target.node;
else
this._selection = this.getResult();
this._selection = this.getResult().root;
PlacesController.activeView = this;
document.commandDispatcher.updateCommands("mousedown");
]]></handler>

View File

@ -2791,7 +2791,7 @@ NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnFolderAdded(PRInt64 aFolder, PRInt64 aParent,
PRInt32 aIndex)
{
NS_ASSERTION(aFolder == mFolderId, "Got wrong bookmark update");
NS_ASSERTION(aParent == mFolderId, "Got wrong bookmark update");
if (! StartIncrementalUpdate())
return NS_OK;