Bookmarks Data API

From MozillaWiki
Jump to: navigation, search

The goal of this is to create a Bookmarks Data API that can support all the various sorts of things we want to be able to do with bookmarks (smart bookmarks, live bookmarks, remote bookmarks, shared bookmarks, live imported bookmarks, etc etc etc). The implementations of these bits aren't relevant to this API, however the API should make it possible to do all of those.

To use regular bookmarks and live bookmarks as an example: there would be a provider with a type of "simple" for regular bookmarks, and a provider with a type of "rss" for live bookmarks.

The simple provider's bmIBookmarkItem implementation wouldn't have much other than just the URI and the name. It would return true for all canBeContainedBy queries. The bmIBookmarkContainer would also be straightforward, and would return true for all canContain queries. For serialization, the container would just ask each child to serialize itself, chain these together, add some data (such as its own name and id), and return.

The live bookmarks provider would have its own implementation of bmIBookmarkContainer and bmIBookmarkItem; the container would reference a particular URL (which is what it would serialize, along with maybe information about items that have been visited), and it would create a bunch of bmIBookmarkItems (bmRSSBookmarkItem?) that would have URIs for the individual entries. bmLivemark would be a bmIBookmarkContainer with readOnly = false and containerReadOnly = true. Because these are read-only, the canContain/canBeContainedBy values don't really matter.

There is a Bookmarks Use Cases page if you would like to describe and discuss user-level Bookmark behaviours and use cases.

VladVukicevic 20:26, 6 Jul 2005 (PDT): Updated API incorporating comments, and expanding in-IDL documentation. All bmI* became mozI*. Removed the forwarded nsIMutableArray methods from mozIBookmarkContainer, and just required all mozIBookmarkContainer implementations to also implement nsIMutableArray. All mozIBookmarkNode implementations also must implement nsIWritablePropertyBag. Removed serialization/deserialization -- the property bag for each node should contain the entire state of that node, and will be serialized/deserialized automatically if the node is serialized.

/*
 * The Provider is responsible for creating new bookmark nodes.
 * It is used as a service; one provider must exist per bookmark
 * node type.
 */

[scriptable, uuid(230e3f93-ce0b-48e1-ad40-e51cb6b8b814)]
interface mozIBookmarkProvider : nsISupports {
  /**
   * The name of this provider's bookmark types, as displayed in the UI.
   * Should be localized!
   */
  readonly attribute AUTF8String name;

  /**
   * The overlay that should be added to the properties dialog box
   * when a node from this provider is edited.
   */
  readonly attribute nsIURI propertiesOverlayURI;

  /**
   * Whether this provider can create items.
   */
  readonly attribute boolean canCreateItems;

  /**
   * Whether this provider can create containers.
   */
  readonly attribute boolean canCreateContainers;

  /**
   * Create a new bookmark item from this provider.  This item should
   * be initialized to some sane defaults; however, it is possile that
   * immediately after createItem() the node's property bag will
   * be filled in with properties read from storage to recreate a
   * bookmark item that was written to disk.
   *
   * @returns a new mozIBookmarkItem instance for this provider.
   */
  mozIBookmarkItem createItem();

  /**
   * Create a new bookmark container from this provider.  This item
   * should be initialized to some sane defaults; however, it is
   * possile that immediately after createItem() the node's property
   * bag will be filled in with properties read from storage to
   * recreate a bookmark item that was written to disk.
   *
   * @returns a new mozIBookmarkItem instance for this provider.
   */
  mozIBookmarkContainer createContainer();
};

/*
 * The service is the main entrypoint for bookmark users; it provides
 * some convenience functions for creating bookmarks (that avoid the
 * caller having to use getService for the right provider), as well
 * as provides access to well-known bookmarks.
 */

[scriptable, uuid(5ee39c0f-74f1-48ed-990f-fd68f28028e0)]
interface mozIBookmarkService  : nsISupports {
  /* convenience to avoid having to call getKnownBookmark(BookmarksRoot) */
  attribute mozIBookmarkContainer bookmarksRoot;

  /* well-known bookmark node identifiers
   * XXX - how do we actually set the BookmarksToolbarFolder?
   */
  const unsigned long BookmarksRoot = 0;
  const unsigned long BookmarksToolbarFolder = 1;

  /**
   * Get a bookmark with the well-known type bmtype, which is
   * one of the constants defined in bookmarks.idl.
   *
   * @param bmtype well-known bookmark id
   *
   * @returns mozIBookmarkNode for the given bookmark id, or null
   * if that well-known bookmark type isn't present in the current
   * bookmarks hierarchy.
   *
   * @throws NS_ERROR_INVALID_ARG if bmtype is invalid.
   */
  mozIBookmarkNode getKnownBookmark(in string bmtype);

  /**
   * Get a bookmark by string id, which is mozIBookmarkNode.id.
   *
   * @param bmid the bookmark node's id which to return.
   *
   * @returns mozIBookmarkNode for the given id, or null
   * if bmid can't be found.
   */
  mozIBookmarkNode getBookmarkById(in string bmid);

  /**
   * Get an array of bookmarks by property name and value.
   *
   * @param propName The property name to search for.
   * @param propValue The property value to search for.
   *
   * @returns An array of mozIBookmarkNodes.
   */
  void getBookmarksByProperty(in string propName, in nsIVariant propValue,
			      out PRUint32 retCount,
			      [retval,array,size_is(retCount)] out mozIBookmarkNode retNodes);

  /**
   * Create a bookmark with the given type.  This is a convenience
   * function, which will call getService to obtain a mozIBookmarkProvider
   * for that type, and call its createBookmark function.
   *
   * @param type the type of bookmark to be created
   *
   * @returns a new bookmark of the given type.
   *
   * @see mozIBookmarkProvider::createBookmark
   */
  mozIBookmarkNode createBookmark(in string type);

  /**
   * Add a new bookmark observer to be notified of changes.
   *
   * @param obs the observer to add.
   */
  void addObserver(in mozIBookmarkObserver obs);

  /**
   * Remove an observer.
   *
   * @param obs the observer to remove.
   *
   * @throws NS_ERROR_INVALID_ARG if the observer isn't found.
   */
  void removeObserver(in mozIBookmarkObserver obs);
};

/**
 * An observer for changes on all bookmarks in a given service's hierarchy.
 */
[scriptable, uuid(75c53908-7aa0-45ee-a68a-f2db90374742)]
interface mozIBookmarkObserver : nsISupports {
  /**
   * Notify this observer that the bookmark was added.
   * Called after the actual add took place.
   *
   * @param bmrk The bookmark node that was added.
   */
  void onBookmarkAdded (in mozIBookmarkNode bmrk);

  /**
   * Notify this observer that the bookmark was removed.
   * Called before the actual remove takes place.
   *
   * @param bmrk The bookmark that will be removed.
   */
  void onBookmarkRemoved (in mozIBookmarkNode bmrk);

  /**
   * Notify this observer that the bookmark's position in the given
   * container has changed.  The old index of the bookmark within the
   * container is passed in, as well as the new index.  Note that the
   * new index is relative to the container without the old bookmark,
   * and indicates that the bookmark was inserted at that position and
   * any elements present there are pushed forward.
   *
   * @param container The bookmark container in which the bookmark moved.
   * @param bmrk The bookmark which moved.
   * @param oldIndex The bookmark's old index in the container.
   * @param newIndex The bookmark's new index in the container.
   */

  void onBookmarkMoved (in mozIBookmarkContainer container,
			in mozIBookmarkNode bmrk,
			in unsigned long oldIndex,
			in unsigned long newIndex);

  /**
   * Notify this observer that a bookmark's information has changed.  This
   * will be called whenever any attributes like "name" are changed,
   * or whenever any properties on the property bag are modified.
   *
   * @param bmrk The bookmark which changed.
   */
  void onBookmarkChanged (in mozIBookmarkNode bmrk);
};


/**
 * A Node in the bookmarks tree.  Providers may derive their own Node
 * implementations from this interface, if they wish to expose
 * additional functionality.
 *
 * A mozIBookmarkNode must also implement a nsIWritablePropertyBag for
 * storing arbitrary data along with the bookmark.
 */

[scriptable, uuid(be2823f2-79b4-4835-8a27-68efe378659f)]
interface mozIBookmarkNode : nsISupports {
  /**
   * UUID for this node
   */
  readonly attribute string id;

  /**
   * The provider type; part of the provider's contractid
   */
  readonly attribute string providerType;

  /**
   * Whether this node is read-only; in other whether, the
   * name or any other properties can be changed.
   */
  readonly attribute boolean readOnly;

  /**
   * The name of this node.  This is the "title" of the bookmark
   * in the UI.
   */
  attribute AUTF8String name;

  /**
   * The icon that should be displayed along with this bookmark.
   * The icon will be visible in the bookmarks menu, toolbar, manager,
   * and possibly other places.
   */
  attribute AUTF8String iconUrl;

  /**
   * The UTC time when this bookmark was created.
   */
  attribute PRTime creationTime;

  /**
   * true if this bookmark node has been modified since the last
   * time it was flushed to disk.
   */
  readonly attribute boolean dirty;

  /**
   * Tests whether this node can be contained by the given container.
   * Both the container and the node have a chance to reject a parent-child
   * relationship (via canBeContainedBy and canContain).
   *
   * @param bmcontainer The container to test.
   *
   * @returns a boolean indicating whether this node can be contained
   * by the given container.
   */
  boolean canBeContainedBy(in mozIBookmarkContainer bmcontainer);

  /**
   * Return a clone of this node, using some node type that has no
   * restrictions (e.g. that it can be contained by a simple container
   * -- in most cases, this would just use the simple item/container
   * types).  This would be used to copy an otherwise read-only child,
   * e.g. to save a RSS feed item into another folder.
   */
  mozIBookmarkNode cloneSimple();
};

/**
 * A generic non-container bookmark item, with a URI.
 */
[scriptable, uuid(47e221fd-b4c3-4dc0-99da-8109c2730981)]
interface mozIBookmarkItem : mozIBookmarkNode {
  /**
   * The URI for this item.
   */
  attribute nsIURI uri;

  /**
   * the last visited time for this bookmark.
   */
  attribute PRTime lastVisitedTime;
};

/**
 * A generic bookmark container, holding one or more child nodes.
 *
 * Implementors of mozIBookmarkContainer MUST also implement
 * nsIMutableArray, which will be used to actually modify
 * the bookmark contents.
 */
[scriptable, uuid(3c82858d-9a17-45b7-87ef-173c70b1067e)]
interface mozIBookmarkContainer : mozIBookmarkNode {
  /**
   * If the container contents are read only.  If
   * readOnly == false, but containerReadOnly == true,
   * then the container's name may be changed, but
   * its children cannot be modified (e.g. can't add
   * or remove a child).
   *
   * Note that a readOnly node implies a read-only
   * container.
   */
  readonly attribute boolean containerReadOnly;

  /**
   * The number of children this container has.
   */
  readonly attribute unsigned long numChildren;

  /**
   * Returns whether this container can contain a given node.
   *
   * @param bmrk The bookmark node to be tested.
   *
   * @returns a boolean indicating whether this container can
   * contain the given node or not.
   */
  boolean canContain(in mozIBookmarkNode bmrk);

  /**
   * Convenience function to avoid having to deal with an
   * enumerator in JavaScript.
   *
   * @returns an array of mozIBookmarkNodes in the current container.
   */
  void getBookmarks(out unsigned long count,
		    [retval,array,size_is(count)] out mozIBookmarkNode bookmarks);
};