Secondly, the API for nsIBookmarksService falls short of what I need to
provide true bookmarks functionality to an embedding application.
Firstly, I need the ability to remove a bookmark. Then, I need the
ability to export the bookmarks to an in-memory data structure,
hopefully some kind of tree.
Is anyone working on the nsIBookmarksService API?
Ed
Sent via Deja.com http://www.deja.com/
Before you buy.
Can you use the RDF APIs to get the bookmarks access you crave?
Mike
--
599804.46 570301.28
Still, no-one has replied to this.
> Secondly, the API for nsIBookmarksService falls short of what I need
> to
> provide true bookmarks functionality to an embedding application.
> Firstly, I need the ability to remove a bookmark. Then, I need the
> ability to export the bookmarks to an in-memory data structure,
> hopefully some kind of tree.
Mike Shaver's last words to me, before he left the project, were, "look
ye into the RDF service for what you seek".
I did, and it looks like I can indeed get what I need.
I tried running mozilla in the debugger, setting breakpoints in
nsBookmarksService.cpp to see how nsBookmarksService is used as an
RDFDataSource, but didn't get very far.
It seems I need to call ArcLabelsOut() to get an enumeration of the
items, but in order to do that, I need an nsIRDFResource instance.
Basically, I want to be able to programmatically traverse the bookmarks
store. Chris Waterson, can you please help me with this?
I've read some of the documents on mozilla.org about RDF, but I'm
looking for something more concise.
Here's what I have so far:
<CODE>
nsresult rv;
NS_WITH_SERVICE(nsIBookmarksService, bookmarksService,
kBookmarksServiceCID, &rv);
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Can't get
bookmarks Service from browser");
return;
}
printf("debug: edburns: got bookmarks\n");
nsCOMPtr<nsIRDFDataSource> rdfDataSource;
rv = bookmarksService->QueryInterface(NS_GET_IID(nsIRDFDataSource),
getter_AddRefs
(rdfDataSource));
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Can't get
RDFDataSource from BookmarksService");
return;
}
</CODE>
So I successfully have the bookmarksService as an nsIRDFDataSource.
How do I go from there to traverse the bookmarks store?
Thanks,
> I tried running mozilla in the debugger, setting breakpoints in
> nsBookmarksService.cpp to see how nsBookmarksService is used as an
> RDFDataSource, but didn't get very far.
>
> It seems I need to call ArcLabelsOut() to get an enumeration of the
> items, but in order to do that, I need an nsIRDFResource instance.
> Basically, I want to be able to programmatically traverse the bookmarks
> store. Chris Waterson, can you please help me with this?
Hmm. What are you trying to do here?
If you want to programatically traverse all of the bookmarks, RDF is
certainly one way to do it. I'd recommend this approach if you're
working on some sort of generic "data viewer" app.
But if you just want a down-and-nasty-get-me-to-the-bookmarks-baby API,
then let's extend nsIBookmarksService to include what you need. This
seems like a sensible part of a browser embedding API to me...
chris
> Yes, I am working on a generic data-viewer app. Namely, creating a
> javax.swing.tree.TreeModel interface to the bookmarks. So, I think I
> need to know how to use RDF.
Ok, didn't mean to be pedantic, just wanted to make sure I wasn't
selling you the wrong thing! :-)
> I spent three hours running the BookmarksParser class in the debugger to
> try to understand how the graph is getting built,
Oh, I pity you!
> Please take a look at this code and tell me what I'm doing wrong.
> Basically, I'd like to be able to traverse the graph and pull out the
> data. Will nsIRDFDataSource.GetAllResources() do the trick? Is there a
> better way?
Yes. Here's a JS snippet that should do what you want. Of course, you
can do the same thing in C++ with a bit more typing.
// The RDF service
var RDF = Components.
classes['component://netscape/rdf/rdf-service'].
getService(Components.interfaces.nsIRDFService);
// The RDF component utilities
var RDFC = Components.
classes['component://netscape/rdf/container-utils'].
getService(Components.interfaces.nsIRDFContainerUtils);
// The bookmarks service
var Bookmarks = Components.
classes['component://netscape/browser/bookmarks-service'].
getService(Components.interfaces.nsIRDFDataSource);
var kNC_BookmarksRoot = RDF.GetResource("NC:BookmarksRoot");
var kNC_Name =
RDF.GetResource("http://home.netscape.com/NC-rdf#Name");
var kNC_URL = RDF.GetResource("http://home.netscape.com/NC-rdf#URL");
function walk(node)
{
if (RDFC.IsContainer(Bookmarks, node)) {
// It's a folder
var name = Bookmarks.GetTarget(node, kNC_Name, true);
if (name) {
dump("folder title = " +
name.QueryInterface(Components.interfaces.nsIRDFLiteral).Value
+ "\n");
}
var container = Components.
classes['component://netscape/rdf/container'].
createInstance(Components.interfaces.nsIRDFContainer);
container.Init(Bookmarks, node);
var contents = container.GetElements();
while (contents.HasMoreElements()) {
var child = contents.GetNext().
QueryInterface(Components.interfaces.nsIRDFResource);
// recur!
walk(child);
}
}
else {
// It's just a bookmark.
dump("url = " + Bookmarks.GetTarget(node, kNC_URL, true).
QueryInterface(Components.interfaces.nsIRDFLiteral).Value
+ "\n");
dump("title = " + Bookmarks.GetTarget(node, kNC_Name, true).
QueryInterface(Components.interfaces.nsIRDFLiteral).Value
+ "\n");
}
}
// dump the tree
walk(kNC_BookmarksRoot);
I haven't tested the code, but it should do the right thing. Heh heh.
chris