зеркало из https://github.com/mozilla/pjs.git
Bug 382877 - dynamic containers implementation, part 1. r=dietrich.
This commit is contained in:
Родитель
494a5292e6
Коммит
23788fbf9c
|
@ -230,7 +230,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode is a Bookmark folder or not.
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is a Bookmark folder, false otherwise
|
||||
*/
|
||||
nodeIsFolder: function PU_nodeIsFolder(aNode) {
|
||||
|
@ -241,7 +241,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode represents a bookmarked URI.
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node represents a bookmarked URI, false otherwise
|
||||
*/
|
||||
nodeIsBookmark: function PU_nodeIsBookmark(aNode) {
|
||||
|
@ -253,7 +253,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode is a Bookmark separator.
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is a Bookmark separator, false otherwise
|
||||
*/
|
||||
nodeIsSeparator: function PU_nodeIsSeparator(aNode) {
|
||||
|
@ -265,7 +265,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode is a visit item or not
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is a visit item, false otherwise
|
||||
*/
|
||||
nodeIsVisit: function PU_nodeIsVisit(aNode) {
|
||||
|
@ -280,7 +280,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode is a URL item or not
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is a URL item, false otherwise
|
||||
*/
|
||||
nodeIsURI: function PU_nodeIsURI(aNode) {
|
||||
|
@ -296,7 +296,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode is a Query item or not
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is a Query item, false otherwise
|
||||
*/
|
||||
nodeIsQuery: function PU_nodeIsQuery(aNode) {
|
||||
|
@ -309,7 +309,7 @@ var PlacesUtils = {
|
|||
* Determines if a node is read only (children cannot be inserted, sometimes
|
||||
* they cannot be removed depending on the circumstance)
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is readonly, false otherwise
|
||||
*/
|
||||
nodeIsReadOnly: function PU_nodeIsReadOnly(aNode) {
|
||||
|
@ -325,7 +325,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode is a host folder or not
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is a host item, false otherwise
|
||||
*/
|
||||
nodeIsHost: function PU_nodeIsHost(aNode) {
|
||||
|
@ -337,7 +337,7 @@ var PlacesUtils = {
|
|||
/**
|
||||
* Determines whether or not a ResultNode is a container item or not
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* A result node
|
||||
* @returns true if the node is a container item, false otherwise
|
||||
*/
|
||||
nodeIsContainer: function PU_nodeIsContainer(aNode) {
|
||||
|
@ -349,31 +349,22 @@ var PlacesUtils = {
|
|||
type == NHRN.RESULT_TYPE_QUERY ||
|
||||
type == NHRN.RESULT_TYPE_FOLDER ||
|
||||
type == NHRN.RESULT_TYPE_DAY ||
|
||||
type == NHRN.RESULT_TYPE_REMOTE_CONTAINER;
|
||||
type == NHRN.RESULT_TYPE_DYNAMIC_CONTAINER;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether or not a ResultNode is a remotecontainer item.
|
||||
* ResultNote may be either a remote container result type or a bookmark folder
|
||||
* with a nonempty remoteContainerType. The remote container result node
|
||||
* type is for dynamically created remote containers (i.e., for the file
|
||||
* browser service where you get your folders in bookmark menus). Bookmark
|
||||
* folders are marked as remote containers when some other component is
|
||||
* registered as interested in them and providing some operations, in which
|
||||
* case their remoteContainerType indicates which component is thus registered.
|
||||
* For exmaple, the livemark service uses this mechanism.
|
||||
* Determines whether or not a result-node is a dynamic-container item.
|
||||
* The dynamic container result node type is for dynamically created
|
||||
* containers (e.g. for the file browser service where you get your folders
|
||||
* in bookmark menus).
|
||||
* @param aNode
|
||||
* A NavHistoryResultNode
|
||||
* @returns true if the node is a container item, false otherwise
|
||||
* A result node
|
||||
* @returns true if the node is a dynamic container item, false otherwise
|
||||
*/
|
||||
nodeIsRemoteContainer: function PU_nodeIsRemoteContainer(aNode) {
|
||||
nodeIsDynamicContainer: function PU_nodeIsDynamicContainer(aNode) {
|
||||
NS_ASSERT(aNode, "null node");
|
||||
|
||||
const NHRN = Ci.nsINavHistoryResultNode;
|
||||
if (aNode.type == NHRN.RESULT_TYPE_REMOTE_CONTAINER)
|
||||
if (aNode.type == NHRN.RESULT_TYPE_DYNAMIC_CONTAINER)
|
||||
return true;
|
||||
if (this.nodeIsFolder(aNode))
|
||||
return asContainer(aNode).remoteContainerType != "";
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -385,9 +376,8 @@ var PlacesUtils = {
|
|||
* @returns true if the node is a livemark container item
|
||||
*/
|
||||
nodeIsLivemarkContainer: function PU_nodeIsLivemarkContainer(aNode) {
|
||||
return (this.nodeIsRemoteContainer(aNode) &&
|
||||
asContainer(aNode).remoteContainerType ==
|
||||
"@mozilla.org/browser/livemark-service;2");
|
||||
return this.nodeIsFolder(aNode) &&
|
||||
this.annotations.itemHasAnnotation(aNode.itemId, "livemark/feedURI");
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -2399,7 +2399,7 @@ nsPlacesImportExportService::ExportHTMLToFile(nsILocalFile* aBookmarksFile)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// get root (folder) node
|
||||
nsCOMPtr<nsINavHistoryQueryResultNode> rootNode;
|
||||
nsCOMPtr<nsINavHistoryContainerResultNode> rootNode;
|
||||
rv = result->GetRoot(getter_AddRefs(rootNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ XPIDLSRCS = \
|
|||
nsINavHistoryService.idl \
|
||||
nsINavBookmarksService.idl \
|
||||
nsILivemarkService.idl \
|
||||
nsIRemoteContainer.idl \
|
||||
nsIDynamicContainer.idl \
|
||||
nsITaggingService.idl \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Annie Sullivan <annie.sullivan@gmail.com> (original author)
|
||||
* Asaf Romano <mano@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsINavHistoryContainerResultNode;
|
||||
interface nsINavHistoryQueryOptions;
|
||||
|
||||
/**
|
||||
* The dynamic container interface provides a base class for services that want
|
||||
* to provide containers for temporary contents.
|
||||
*
|
||||
* The service can fill result nodes directly into the container when it is
|
||||
* being opened. It can use the property bag on every result node to store data
|
||||
* associated with each item, such as full path on disk. It would create
|
||||
* additional containers for each container, registered to its service.
|
||||
*
|
||||
* See also createDynamicContainer in nsINavBookmarksService.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(7e85d97b-4109-4ea7-afd8-bc2cd3840d70)]
|
||||
interface nsIDynamicContainer : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called when the given container node is about to be populated so that the
|
||||
* service can populate the container if necessary.
|
||||
*
|
||||
* @param aContainer
|
||||
* The container node for the container being opened. Note that all
|
||||
* result nodes implement a property bag if you need to store state.
|
||||
* @param aOptions
|
||||
* The options used to generate this query. Containers should follow
|
||||
* these when possible, for example, whether to expand queries, etc.
|
||||
* Implementations should use this when possible if adding query and
|
||||
* folder nodes to the container. DO NOT MODIFY THIS VALUE.
|
||||
*/
|
||||
void onContainerNodeOpening(in nsINavHistoryContainerResultNode aContainer,
|
||||
in nsINavHistoryQueryOptions aOptions);
|
||||
|
||||
/**
|
||||
* Called when the given container has just been collapsed so that the
|
||||
* service can do any necessary cleanup. This is NOT guaranteed to get
|
||||
* called. In particular, if the query just goes away, you will not get this
|
||||
* call. This only happens when the container itself goes from the open state
|
||||
* to the closed state. A service with large numbers of dynamically populated
|
||||
* items might use this to do some cleanup so those items don't hang around
|
||||
*
|
||||
* @param aContainer
|
||||
* The container node of the container being closed. The service need
|
||||
* not worry about removing any created nodes, they will be
|
||||
* automatically removed when this call completes.
|
||||
*/
|
||||
void onContainerNodeClosed(in nsINavHistoryContainerResultNode aContainer);
|
||||
|
||||
/**
|
||||
* Called when the given container is about to be deleted from the bookmarks
|
||||
* table, so that the service can do any necessary cleanup.
|
||||
* Called BEFORE the container is deleted, so that the service
|
||||
* can still reference it.
|
||||
* @param aItemId
|
||||
* The item-id of the container item.
|
||||
*/
|
||||
void onContainerRemoving(in long long aItemId);
|
||||
|
||||
/**
|
||||
* Called when the given container has just been moved, in case
|
||||
* the service needs to do any bookkeeping.
|
||||
* Called AFTER the container has been moved.
|
||||
* @param aItemId
|
||||
* The item-id of the container item.
|
||||
* @param aNewParent
|
||||
* The item of the new parent folder for the container.
|
||||
* @param aNewIndex
|
||||
* The index the container will be inserted at, or -1 for append.
|
||||
*/
|
||||
void onContainerMoved(in long long aItemId,
|
||||
in long long aNewParent, in long aNewIndex);
|
||||
};
|
|
@ -38,13 +38,12 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIRemoteContainer.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsINavBookmarksService;
|
||||
|
||||
[scriptable, uuid(86f0be08-7b7f-4ec6-97ff-ecace917b852)]
|
||||
interface nsILivemarkService : nsIRemoteContainer
|
||||
[scriptable, uuid(602e3a71-2d10-4d8f-80c2-6db302b5c89d)]
|
||||
interface nsILivemarkService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Creates a new livemark
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
* Contributor(s):
|
||||
* Brian Ryner <bryner@brianryner.com> (original author)
|
||||
* Joe Hughes <joe@retrovirus.com>
|
||||
* Dietrich Ayala <dietrich@mozilla.com>
|
||||
* Asaf Romano <mano@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -161,7 +163,7 @@ interface nsINavBookmarkObserver : nsISupports
|
|||
* folders. A URI in history can be contained in one or more such folders.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(630dcd21-402c-44cd-8336-78bff3efc5f3)]
|
||||
[scriptable, uuid(117e4d4c-8c10-4c50-b588-848942b55b6e)]
|
||||
interface nsINavBookmarksService : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -197,6 +199,7 @@ interface nsINavBookmarksService : nsISupports
|
|||
const unsigned short TYPE_BOOKMARK = 1;
|
||||
const unsigned short TYPE_FOLDER = 2;
|
||||
const unsigned short TYPE_SEPARATOR = 3;
|
||||
const unsigned short TYPE_DYNAMIC_CONTAINER = 4;
|
||||
|
||||
/**
|
||||
* Inserts a child bookmark into the given folder. If this item already exists in
|
||||
|
@ -235,22 +238,22 @@ interface nsINavBookmarksService : nsISupports
|
|||
in long index);
|
||||
|
||||
/**
|
||||
* Wrapper for container services. Creates a folder under the given
|
||||
* parent and sets the container type. Containers are wrappers around
|
||||
* read-only folders, with a specific type.
|
||||
* Creates a dynamic container under the given parent folder.
|
||||
*
|
||||
* @param aParentFolder
|
||||
* The id of the parent folder
|
||||
* @param aName
|
||||
* The name of the new folder
|
||||
* @param aType
|
||||
* The type of container to insert
|
||||
* @param aContractId
|
||||
* The contract id of the service which is to manipulate this
|
||||
* container.
|
||||
* @param aIndex
|
||||
* The index to insert at, or -1 to append
|
||||
*
|
||||
* @returns the ID of the newly-inserted folder
|
||||
*/
|
||||
long long createContainer(in long long aParentFolder, in AString aName,
|
||||
in AString aType, in long aIndex);
|
||||
long long createDynamicContainer(in long long aParentFolder, in AString aName,
|
||||
in AString aContractId, in long aIndex);
|
||||
|
||||
/**
|
||||
* Removes a folder from the bookmarks tree.
|
||||
|
@ -434,13 +437,23 @@ interface nsINavBookmarksService : nsISupports
|
|||
unsigned short getItemType(in long long aItemId);
|
||||
|
||||
/**
|
||||
* Checks whether a folder has read-only children. This property is
|
||||
* defined by the nsIBookmarsContainer for the folder, if one exists.
|
||||
* Checks whether a folder is marked as read-only.
|
||||
* If this is set to true, UI should not allow the user to add, remove,
|
||||
* or reorder children in this folder. The default for all folders is false.
|
||||
* or reorder children in this folder. The default for all folders is false.
|
||||
* @param aFolder
|
||||
* the item-id of the folder.
|
||||
*/
|
||||
boolean getFolderReadonly(in long long aFolder);
|
||||
|
||||
/**
|
||||
* Sets or unsets the readonly flag from a folder
|
||||
* @param aFolder
|
||||
* the item-id of the folder.
|
||||
* @param aReadOnly
|
||||
* the read-only state (boolean).
|
||||
*/
|
||||
void setFolderReadonly(in long long aFolder, in boolean aReadOnly);
|
||||
|
||||
/**
|
||||
* Returns true if the given URI is in any bookmark folder. If you want the
|
||||
* results to be redirect-aware, use getBookmarkedURIFor()
|
||||
|
@ -537,4 +550,3 @@ interface nsINavBookmarksService : nsISupports
|
|||
void runInBatchMode(in nsINavHistoryBatchCallback aCallback,
|
||||
in nsISupports aUserData);
|
||||
};
|
||||
|
||||
|
|
|
@ -69,21 +69,17 @@ interface nsINavHistoryResultNode : nsISupports
|
|||
|
||||
/**
|
||||
* Identifies the type of this node. This node can then be QI-ed to the
|
||||
* corresponding specialized result node interface. The remote_container one
|
||||
* is a little weird, it is a temporary folder generated by the remote
|
||||
* container API. Note that bookmark folders can also be filled by the
|
||||
* remote container API (these are the entrypoints for the API) and may
|
||||
* have a remote container type as well.
|
||||
* corresponding specialized result node interface.
|
||||
*/
|
||||
const unsigned long RESULT_TYPE_URI = 0; // nsINavHistoryResultNode
|
||||
const unsigned long RESULT_TYPE_VISIT = 1; // nsINavHistoryVisitResultNode
|
||||
const unsigned long RESULT_TYPE_FULL_VISIT = 2; // nsINavHistoryFullVisitResultNode
|
||||
const unsigned long RESULT_TYPE_HOST = 3; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_REMOTE_CONTAINER = 4; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_QUERY = 5; // nsINavHistoryQueryResultNode
|
||||
const unsigned long RESULT_TYPE_FOLDER = 6; // nsINavHistoryQueryResultNode
|
||||
const unsigned long RESULT_TYPE_SEPARATOR = 7; // nsINavHistoryResultNode
|
||||
const unsigned long RESULT_TYPE_DAY = 8; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_URI = 0; // nsINavHistoryResultNode
|
||||
const unsigned long RESULT_TYPE_VISIT = 1; // nsINavHistoryVisitResultNode
|
||||
const unsigned long RESULT_TYPE_FULL_VISIT = 2; // nsINavHistoryFullVisitResultNode
|
||||
const unsigned long RESULT_TYPE_HOST = 3; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_DYNAMIC_CONTAINER = 4; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_QUERY = 5; // nsINavHistoryQueryResultNode
|
||||
const unsigned long RESULT_TYPE_FOLDER = 6; // nsINavHistoryQueryResultNode
|
||||
const unsigned long RESULT_TYPE_SEPARATOR = 7; // nsINavHistoryResultNode
|
||||
const unsigned long RESULT_TYPE_DAY = 8; // nsINavHistoryContainerResultNode
|
||||
readonly attribute unsigned long type;
|
||||
|
||||
/**
|
||||
|
@ -227,7 +223,7 @@ interface nsINavHistoryFullVisitResultNode : nsINavHistoryVisitResultNode
|
|||
* Bookmark folders and places queries will be QueryResultNodes which extends
|
||||
* these items.
|
||||
*/
|
||||
[scriptable, uuid(957065fd-76e7-4c24-9284-c31b5decbaaa)]
|
||||
[scriptable, uuid(f9c8e1c1-e701-44ad-893c-8504c3956929)]
|
||||
interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
||||
{
|
||||
|
||||
|
@ -269,41 +265,34 @@ interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
|||
* (adding or removing children, or reordering children), or true if
|
||||
* the UI should not allow the list of children to be modified.
|
||||
* This is false for bookmark folder nodes unless setFolderReadOnly() has
|
||||
* been called to override it, and true for non-folder nodes. If this
|
||||
* container is a remote container this flag may be redefined by the
|
||||
* remote container provider.
|
||||
* been called to override it, and true for non-folder nodes.
|
||||
*/
|
||||
readonly attribute boolean childrenReadOnly;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Remote container
|
||||
// Dynamic container
|
||||
|
||||
/**
|
||||
* This is a string representing the remote container API service that is
|
||||
* responsible for this container. It is empty if there is none. The
|
||||
* container may be a RESULT_TYPE_REMOTE_CONTAINER node that has been
|
||||
* dynamically generated by the remote container API. It may also be a
|
||||
* bookmark folder (RESULT_TYPE_FOLDER) for which some service (such as
|
||||
* livemarks) has registered to provide certain operations.
|
||||
* This is a string representing the dynamic container API service that is
|
||||
* responsible for this container. This throws if if the node is not a dynamic
|
||||
* container.
|
||||
*/
|
||||
readonly attribute AUTF8String remoteContainerType;
|
||||
readonly attribute AUTF8String dynamicContainerType;
|
||||
|
||||
/**
|
||||
* Appends a full visit node to this container and returns it. For the remote
|
||||
* container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening()
|
||||
* Appends a full visit node to this container and returns it. For the dynamic
|
||||
* container API. TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening()
|
||||
* ONLY, and only for non-bookmark-folder containers.
|
||||
*
|
||||
* @see nsINavHistoryURIResultNode for parameters.
|
||||
*
|
||||
* UNTESTED: Container API functions are commented out until we can test
|
||||
*/
|
||||
/*nsINavHistoryResultNode appendURINode(
|
||||
nsINavHistoryResultNode appendURINode(
|
||||
in AUTF8String aURI, in AUTF8String aTitle, in PRUint32 aAccessCount,
|
||||
in PRTime aTime, in AUTF8String aIconURI);*/
|
||||
in PRTime aTime, in AUTF8String aIconURI);
|
||||
|
||||
/**
|
||||
* Appends a full visit node to this container and returns it. For the remote
|
||||
* container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening()
|
||||
* Appends a full visit node to this container and returns it. For the dynamic
|
||||
* container API. TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening()
|
||||
* ONLY, and only for non-bookmark-folder containers.
|
||||
*
|
||||
* @see nsINavHistoryVisitResultNode for parameters.
|
||||
|
@ -315,8 +304,8 @@ interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
|||
in PRTime aTime, in AUTF8String aIconURI, in PRInt64 aSession);*/
|
||||
|
||||
/**
|
||||
* Appends a full visit node to this container and returns it. For the remote
|
||||
* container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening()
|
||||
* Appends a full visit node to this container and returns it. For the dynamic
|
||||
* container API. TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening()
|
||||
* ONLY, and only for non-bookmark-folder containers.
|
||||
*
|
||||
* @see nsINavHistoryFullVisitResultNode for parameters.
|
||||
|
@ -330,13 +319,13 @@ interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
|||
in PRInt32 aTransitionType);*/
|
||||
|
||||
/**
|
||||
* Appends a container node to this container and returns it. For the remote
|
||||
* container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening()
|
||||
* Appends a container node to this container and returns it. For the dynamic
|
||||
* container API. TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening()
|
||||
* ONLY, and only for non-bookmark-folder containers.
|
||||
*
|
||||
* aContainerType should be either RESULT_TYPE_HOST or
|
||||
* RESULT_TYPE_REMOTE_CONTAINER. When type is remote container you must
|
||||
* specify a remote container type, otherwise, the remote container type must
|
||||
* RESULT_TYPE_DYNAMIC_CONTAINER. When type is dynamic container you must
|
||||
* specify a dynamic container type, otherwise, the dynamic container type must
|
||||
* be null. Use appendQueryNode and appendFolderNode for the other container
|
||||
* types.
|
||||
*
|
||||
|
@ -344,11 +333,11 @@ interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
|||
*/
|
||||
/*nsINavHistoryContainerResultNode appendContainerNode(
|
||||
in AUTF8String aTitle, in AUTF8String aIconURI, in PRUint32 aContainerType,
|
||||
in AUTF8String aRemoteContainerType);*/
|
||||
in AUTF8String aDynamicContainerType);*/
|
||||
|
||||
/**
|
||||
* Appends a query node to this container and returns it. For the remote
|
||||
* container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening()
|
||||
* Appends a query node to this container and returns it. For the dynamic
|
||||
* container API. TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening()
|
||||
* ONLY, and only for non-bookmark-folder containers.
|
||||
*
|
||||
* Normally you should supply an empty string for IconURI and it will take
|
||||
|
@ -361,20 +350,18 @@ interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
|||
|
||||
/**
|
||||
* Appends a bookmark folder node to this container and returns it. For the
|
||||
* remote container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening()
|
||||
* dynamic container API. TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening()
|
||||
* ONLY, and only for non-bookmark-folder containers.
|
||||
*
|
||||
* All container attributes will come from the boomkarks service for this
|
||||
* folder.
|
||||
*
|
||||
* UNTESTED: Container API functions are commented out until we can test
|
||||
*/
|
||||
/*nsINavHistoryFolderResultNode appendFolderNode(in PRInt64 aFolderId);*/
|
||||
nsINavHistoryContainerResultNode appendFolderNode(in PRInt64 aFolderId);
|
||||
|
||||
/**
|
||||
* Clears all children of this container. For the remote container API.
|
||||
* TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening and
|
||||
* nsIRemoteContainer::OnContainerClosed ONLY, and valid only for
|
||||
* Clears all children of this container. For the dynamic container API.
|
||||
* TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening and
|
||||
* nsIDynamicContainer::OnContainerClosed ONLY, and valid only for
|
||||
* non-bookmark-folder containers.
|
||||
*
|
||||
* UNTESTED: Container API functions are commented out until we can test
|
||||
|
@ -669,7 +656,7 @@ interface nsINavHistoryResultTreeViewer : nsINavHistoryResultViewer
|
|||
* through the nsINavHistoryResultViewObserver interface.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(6cfcb46f-9b70-4efa-b02a-c2ce85d75e00)]
|
||||
[scriptable, uuid(d1562f6f-8d5a-4042-8524-72f747a51b18)]
|
||||
interface nsINavHistoryResult : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -699,7 +686,7 @@ interface nsINavHistoryResult : nsISupports
|
|||
* This is the root of the results. Remember that you need to open all
|
||||
* containers for their contents to be valid.
|
||||
*/
|
||||
readonly attribute nsINavHistoryQueryResultNode root;
|
||||
readonly attribute nsINavHistoryContainerResultNode root;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -144,6 +144,8 @@ function LivemarkService() {
|
|||
);
|
||||
this._pushLivemark(livemarks[i], feedURI);
|
||||
}
|
||||
|
||||
this._bms.addObserver(this, false);
|
||||
}
|
||||
|
||||
LivemarkService.prototype = {
|
||||
|
@ -277,7 +279,8 @@ LivemarkService.prototype = {
|
|||
|
||||
_createFolder:
|
||||
function LS__createFolder(bms, folder, name, siteURI, feedURI, index) {
|
||||
var livemarkID = bms.createContainer(folder, name, LS_CONTRACTID, index);
|
||||
var livemarkID = bms.createFolder(folder, name, index);
|
||||
this._bms.setFolderReadonly(livemarkID, true);
|
||||
|
||||
// Add an annotation to map the folder URI to the livemark feed URI
|
||||
this._ans.setItemAnnotation(livemarkID, LMANNO_FEEDURI, feedURI.spec, 0,
|
||||
|
@ -380,9 +383,22 @@ LivemarkService.prototype = {
|
|||
this._updateLivemarkChildren(livemarkIndex, true);
|
||||
},
|
||||
|
||||
// nsIRemoteContainer
|
||||
onContainerRemoving: function LS_onContainerRemoving(container) {
|
||||
var livemarkIndex = this._getLivemarkIndex(container);
|
||||
// nsINavBookmarkObserver
|
||||
onBeginUpdateBatch: function() { },
|
||||
onEndUpdateBatch: function() { },
|
||||
onItemAdded: function() { },
|
||||
onItemChanged: function() { },
|
||||
onItemVisited: function() { },
|
||||
onItemMoved: function() { },
|
||||
|
||||
onItemRemoved: function(aItemId, aParentFolder, aIndex) {
|
||||
try {
|
||||
var livemarkIndex = this._getLivemarkIndex(aItemId);
|
||||
}
|
||||
catch(ex) {
|
||||
// not a livemark
|
||||
return;
|
||||
}
|
||||
var livemark = this._livemarks[livemarkIndex];
|
||||
|
||||
var stillInUse = false;
|
||||
|
@ -398,14 +414,8 @@ LivemarkService.prototype = {
|
|||
if (livemark.loadGroup)
|
||||
livemark.loadGroup.cancel(Cr.NS_BINDING_ABORTED);
|
||||
this._livemarks.splice(livemarkIndex, 1);
|
||||
this.deleteLivemarkChildren(container);
|
||||
},
|
||||
|
||||
onContainerMoved:
|
||||
function LS_onContainerMoved(container, newFolder, newIndex) { },
|
||||
|
||||
childrenReadOnly: true,
|
||||
|
||||
createInstance: function LS_createInstance(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
|
@ -414,12 +424,12 @@ LivemarkService.prototype = {
|
|||
|
||||
QueryInterface: function LS_QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsILivemarkService) ||
|
||||
iid.equals(Ci.nsIRemoteContainer) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsINavBookmarkObserver) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
function LivemarkLoadListener(livemark) {
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "mozStorageHelper.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIRemoteContainer.h"
|
||||
#include "nsIDynamicContainer.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsFaviconService.h"
|
||||
#include "nsAnnotationService.h"
|
||||
|
@ -71,7 +71,7 @@ const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_Position = 3;
|
|||
const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_PlaceID = 4;
|
||||
const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_Parent = 5;
|
||||
const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_Type = 6;
|
||||
const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_FolderType = 7;
|
||||
const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_ServiceContractId = 7;
|
||||
const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_DateAdded = 8;
|
||||
const PRInt32 nsNavBookmarks::kGetItemPropertiesIndex_LastModified = 9;
|
||||
|
||||
|
@ -80,6 +80,7 @@ nsNavBookmarks* nsNavBookmarks::sInstance = nsnull;
|
|||
#define BOOKMARKS_ANNO_PREFIX "bookmarks/"
|
||||
#define BOOKMARKS_TOOLBAR_FOLDER_ANNO NS_LITERAL_CSTRING(BOOKMARKS_ANNO_PREFIX "toolbarFolder")
|
||||
#define GUID_ANNO NS_LITERAL_CSTRING("placesInternal/GUID")
|
||||
#define READ_ONLY_ANNO NS_LITERAL_CSTRING("placesInternal/READ_ONLY")
|
||||
|
||||
nsNavBookmarks::nsNavBookmarks()
|
||||
: mRoot(0), mBookmarksRoot(0), mTagRoot(0), mToolbarFolder(0), mBatchLevel(0),
|
||||
|
@ -1065,27 +1066,63 @@ NS_IMETHODIMP
|
|||
nsNavBookmarks::CreateFolder(PRInt64 aParent, const nsAString &aName,
|
||||
PRInt32 aIndex, PRInt64 *aNewFolder)
|
||||
{
|
||||
// CreateFolderWithID returns the index of the new folder, but that's not
|
||||
// CreateContainerWithID returns the index of the new folder, but that's not
|
||||
// used here. To avoid any risk of corrupting data should this function
|
||||
// be changed, we'll use a local variable to hold it. The PR_TRUE argument
|
||||
// will cause notifications to be sent to bookmark observers.
|
||||
PRInt32 localIndex = aIndex;
|
||||
return CreateFolderWithID(-1, aParent, aName, PR_TRUE, &localIndex, aNewFolder);
|
||||
return CreateContainerWithID(-1, aParent, aName, EmptyString(), PR_TRUE,
|
||||
&localIndex, aNewFolder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::CreateContainer(PRInt64 aParent, const nsAString &aName,
|
||||
const nsAString &aType, PRInt32 aIndex,
|
||||
PRInt64 *aNewFolder)
|
||||
nsNavBookmarks::CreateDynamicContainer(PRInt64 aParent, const nsAString &aName,
|
||||
const nsAString &aContractId,
|
||||
PRInt32 aIndex,
|
||||
PRInt64 *aNewFolder)
|
||||
{
|
||||
return CreateContainerWithID(-1, aParent, aName, aType, aIndex, aNewFolder);
|
||||
if (aContractId.IsEmpty())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
PRInt32 index = aIndex;
|
||||
return CreateContainerWithID(-1, aParent, aName, aContractId, PR_FALSE,
|
||||
&aIndex, aNewFolder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetFolderReadonly(PRInt64 aFolder, PRBool *aResult)
|
||||
{
|
||||
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
|
||||
NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY);
|
||||
return annosvc->ItemHasAnnotation(aFolder, READ_ONLY_ANNO, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::SetFolderReadonly(PRInt64 aFolder, PRBool aReadOnly)
|
||||
{
|
||||
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
|
||||
NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY);
|
||||
if (aReadOnly) {
|
||||
return annosvc->SetItemAnnotationInt32(aFolder, READ_ONLY_ANNO, 1,
|
||||
0,
|
||||
nsAnnotationService::EXPIRE_NEVER);
|
||||
}
|
||||
else {
|
||||
PRBool hasAnno;
|
||||
nsresult rv = annosvc->ItemHasAnnotation(aFolder, READ_ONLY_ANNO, &hasAnno);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasAnno)
|
||||
return annosvc->RemoveItemAnnotation(aFolder, READ_ONLY_ANNO);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::CreateFolderWithID(PRInt64 aFolder, PRInt64 aParent,
|
||||
const nsAString& aName,
|
||||
PRBool aSendNotifications,
|
||||
PRInt32* aIndex, PRInt64* aNewFolder)
|
||||
nsNavBookmarks::CreateContainerWithID(PRInt64 aItemId, PRInt64 aParent,
|
||||
const nsAString& aName,
|
||||
const nsAString& aContractId,
|
||||
PRBool aIsBookmarkFolder,
|
||||
PRInt32* aIndex, PRInt64* aNewFolder)
|
||||
{
|
||||
// You can pass -1 to indicate append, but no other negative number is allowed
|
||||
if (*aIndex < -1)
|
||||
|
@ -1100,29 +1137,35 @@ nsNavBookmarks::CreateFolderWithID(PRInt64 aFolder, PRInt64 aParent,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
if (aFolder == -1) {
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks (title, type, parent, position, folder_type, dateAdded) VALUES (?1, ?2, ?3, ?4, null, ?5)"),
|
||||
if (aItemId == -1) {
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks (title, type, parent, position, folder_type, dateAdded) VALUES (?1, ?2, ?3, ?4, ?5, ?6)"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks (id, title, type, parent, position, folder_type, dateAdded) VALUES (?6, ?1, ?2, ?3, ?4, null, ?5)"),
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks (id, title, type, parent, position, folder_type, dateAdded) VALUES (?7, ?1, ?2, ?3, ?4, ?5, ?6)"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->BindInt64Parameter(5, aFolder);
|
||||
rv = statement->BindInt64Parameter(6, aItemId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = statement->BindStringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindInt32Parameter(1, TYPE_FOLDER);
|
||||
|
||||
PRInt32 containerType =
|
||||
aIsBookmarkFolder ? TYPE_FOLDER : TYPE_DYNAMIC_CONTAINER;
|
||||
|
||||
rv = statement->BindInt32Parameter(1, containerType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindInt64Parameter(2, aParent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindInt32Parameter(3, index);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindInt64Parameter(4, PR_Now());
|
||||
rv = statement->BindStringParameter(4, aContractId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindInt64Parameter(5, PR_Now());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->Execute();
|
||||
|
@ -1138,54 +1181,14 @@ nsNavBookmarks::CreateFolderWithID(PRInt64 aFolder, PRInt64 aParent,
|
|||
rv = transaction.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// When creating a livemark container, we need to delay sending notifications
|
||||
// until the container type has been set. In that case, they'll be sent by
|
||||
// CreateContainerWithID rather than here.
|
||||
if (aSendNotifications) {
|
||||
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
|
||||
OnItemAdded(id, aParent, index))
|
||||
}
|
||||
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
|
||||
OnItemAdded(id, aParent, index))
|
||||
|
||||
*aIndex = index;
|
||||
*aNewFolder = id;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::CreateContainerWithID(PRInt64 aFolder, PRInt64 aParent,
|
||||
const nsAString &aName, const nsAString &aType,
|
||||
PRInt32 aIndex, PRInt64 *aNewFolder)
|
||||
{
|
||||
// Containers are wrappers around read-only folders, with a specific type.
|
||||
// CreateFolderWithID will return the index of the newly created folder,
|
||||
// which we will need later on in order to send notifications. The PR_FALSE
|
||||
// argument disables sending notifications, since we need to defer that until
|
||||
// the folder type has been set.
|
||||
PRInt32 localIndex = aIndex;
|
||||
nsresult rv = CreateFolderWithID(aFolder, aParent, aName, PR_FALSE, &localIndex, aNewFolder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set the type.
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_bookmarks SET folder_type = ?2 WHERE id = ?1"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->BindInt64Parameter(0, *aNewFolder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindStringParameter(1, aType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Send notifications after folder type has been set.
|
||||
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
|
||||
OnItemAdded(*aNewFolder, aParent, localIndex))
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::InsertSeparator(PRInt64 aParent, PRInt32 aIndex,
|
||||
PRInt64* aNewItemId)
|
||||
|
@ -1334,14 +1337,14 @@ nsNavBookmarks::RemoveFolder(PRInt64 aFolder)
|
|||
|
||||
parent = mDBGetItemProperties->AsInt64(kGetItemPropertiesIndex_Parent);
|
||||
index = mDBGetItemProperties->AsInt32(kGetItemPropertiesIndex_Position);
|
||||
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_FolderType, folderType);
|
||||
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_ServiceContractId, folderType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// If this is a container bookmark, try to notify its service.
|
||||
if (folderType.Length() > 0) {
|
||||
// There is a type associated with this folder; it's a livemark.
|
||||
nsCOMPtr<nsIRemoteContainer> bmcServ = do_GetService(folderType.get());
|
||||
nsCOMPtr<nsIDynamicContainer> bmcServ = do_GetService(folderType.get());
|
||||
if (bmcServ) {
|
||||
rv = bmcServ->OnContainerRemoving(aFolder);
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -1403,7 +1406,7 @@ nsNavBookmarks::GetRemoveFolderTransaction(PRInt64 aFolder, nsITransaction** aRe
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RemoveFolderTransaction* rft =
|
||||
new RemoveFolderTransaction(aFolder, parent, title, index, type);
|
||||
new RemoveFolderTransaction(aFolder, parent, title, index, NS_ConvertUTF8toUTF16(type));
|
||||
if (!rft)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -1496,7 +1499,7 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId, PRInt64 aNewParent, PRInt32 aIndex)
|
|||
oldIndex = mDBGetItemProperties->AsInt32(kGetItemPropertiesIndex_Position);
|
||||
itemType = mDBGetItemProperties->AsInt32(kGetItemPropertiesIndex_Type);
|
||||
if (itemType == TYPE_FOLDER) {
|
||||
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_FolderType,
|
||||
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_ServiceContractId,
|
||||
folderType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
@ -1608,9 +1611,9 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId, PRInt64 aNewParent, PRInt32 aIndex)
|
|||
OnItemMoved(aItemId, oldParent, oldIndex, aNewParent,
|
||||
newIndex))
|
||||
|
||||
// notify remote container provider if there is one
|
||||
// notify dynamic container provider if there is one
|
||||
if (!folderType.IsEmpty()) {
|
||||
nsCOMPtr<nsIRemoteContainer> container =
|
||||
nsCOMPtr<nsIDynamicContainer> container =
|
||||
do_GetService(folderType.get(), &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = container->OnContainerMoved(aItemId, aNewParent, newIndex);
|
||||
|
@ -1910,13 +1913,13 @@ nsNavBookmarks::GetFolderType(PRInt64 aFolder, nsACString &aType)
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_FolderType, aType);
|
||||
return mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_ServiceContractId, aType);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::ResultNodeForFolder(PRInt64 aID,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
nsNavHistoryResultNode **aNode)
|
||||
nsNavBookmarks::ResultNodeForContainer(PRInt64 aID,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
nsNavHistoryResultNode **aNode)
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBGetItemProperties);
|
||||
mDBGetItemProperties->BindInt64Parameter(0, aID);
|
||||
|
@ -1924,18 +1927,29 @@ nsNavBookmarks::ResultNodeForFolder(PRInt64 aID,
|
|||
PRBool results;
|
||||
nsresult rv = mDBGetItemProperties->ExecuteStep(&results);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(results, "ResultNodeForFolder expects a valid folder id");
|
||||
NS_ASSERTION(results, "ResultNodeForContainer expects a valid item id");
|
||||
|
||||
// type
|
||||
nsCAutoString folderType;
|
||||
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_FolderType, folderType);
|
||||
// contract id
|
||||
nsCAutoString contractId;
|
||||
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_ServiceContractId,
|
||||
contractId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// title
|
||||
nsCAutoString title;
|
||||
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_Title, title);
|
||||
|
||||
*aNode = new nsNavHistoryFolderResultNode(title, aOptions, aID, folderType);
|
||||
PRInt32 itemType = mDBGetItemProperties->AsInt32(kGetItemPropertiesIndex_Type);
|
||||
if (itemType == TYPE_DYNAMIC_CONTAINER) {
|
||||
*aNode = new nsNavHistoryContainerResultNode(EmptyCString(), title, EmptyCString(),
|
||||
nsINavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER,
|
||||
PR_TRUE,
|
||||
contractId,
|
||||
aOptions);
|
||||
(*aNode)->mItemId = aID;
|
||||
} else { // TYPE_FOLDER
|
||||
*aNode = new nsNavHistoryFolderResultNode(title, aOptions, aID, contractId);
|
||||
}
|
||||
if (!*aNode)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -1966,27 +1980,6 @@ nsNavBookmarks::GetFolderURI(PRInt64 aFolder, nsIURI **aURI)
|
|||
return NS_NewURI(aURI, spec);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetFolderReadonly(PRInt64 aFolder, PRBool *aResult)
|
||||
{
|
||||
// Ask the folder's nsIRemoteContainer for the readonly property.
|
||||
*aResult = PR_FALSE;
|
||||
nsCAutoString type;
|
||||
nsresult rv = GetFolderType(aFolder, type);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!type.IsEmpty()) {
|
||||
nsCOMPtr<nsIRemoteContainer> container =
|
||||
do_GetService(type.get(), &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = container->GetChildrenReadOnly(aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::QueryFolderChildren(PRInt64 aFolderId,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
|
@ -2015,12 +2008,12 @@ nsNavBookmarks::QueryFolderChildren(PRInt64 aFolderId,
|
|||
// it will start counting at 0 the first time through the loop.
|
||||
index ++;
|
||||
|
||||
PRBool isFolder = mDBGetChildren->AsInt32(kGetChildrenIndex_Type) == TYPE_FOLDER;
|
||||
PRInt32 itemType = mDBGetChildren->AsInt32(kGetChildrenIndex_Type);
|
||||
PRInt64 id = mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_ItemId);
|
||||
nsCOMPtr<nsNavHistoryResultNode> node;
|
||||
if (isFolder) {
|
||||
|
||||
if (options->ExcludeReadOnlyFolders()) {
|
||||
if (itemType == TYPE_FOLDER || itemType == TYPE_DYNAMIC_CONTAINER) {
|
||||
if (itemType == TYPE_DYNAMIC_CONTAINER ||
|
||||
(itemType == TYPE_FOLDER && options->ExcludeReadOnlyFolders())) {
|
||||
// see if it's read only and skip it
|
||||
PRBool readOnly = PR_FALSE;
|
||||
GetFolderReadonly(id, &readOnly);
|
||||
|
@ -2028,7 +2021,7 @@ nsNavBookmarks::QueryFolderChildren(PRInt64 aFolderId,
|
|||
continue; // skip
|
||||
}
|
||||
|
||||
rv = ResultNodeForFolder(id, aOptions, getter_AddRefs(node));
|
||||
rv = ResultNodeForContainer(id, aOptions, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
} else if (mDBGetChildren->AsInt32(kGetChildrenIndex_Type) == TYPE_SEPARATOR) {
|
||||
|
|
|
@ -77,8 +77,8 @@ public:
|
|||
|
||||
nsresult AddBookmarkToHash(PRInt64 aBookmarkId, PRTime aMinTime);
|
||||
|
||||
nsresult ResultNodeForFolder(PRInt64 aID, nsNavHistoryQueryOptions *aOptions,
|
||||
nsNavHistoryResultNode **aNode);
|
||||
nsresult ResultNodeForContainer(PRInt64 aID, nsNavHistoryQueryOptions *aOptions,
|
||||
nsNavHistoryResultNode **aNode);
|
||||
|
||||
// Find all the children of a folder, using the given query and options.
|
||||
// For each child, a ResultNode is created and added to |children|.
|
||||
|
@ -89,20 +89,13 @@ public:
|
|||
|
||||
// If aFolder is -1, uses the autoincrement id for folder index. Returns
|
||||
// the index of the new folder in aIndex, whether it was passed in or
|
||||
// generated by autoincrement. If aSendNotifications is true, sends
|
||||
// OnFolderAdded notifications to bookmark observers.
|
||||
nsresult CreateFolderWithID(PRInt64 aFolder, PRInt64 aParent,
|
||||
const nsAString& title,
|
||||
PRBool aSendNotifications,
|
||||
PRInt32 *aIndex, PRInt64* aNewFolder);
|
||||
|
||||
// Creates a new container of the given type. If aFolder is -1, uses the
|
||||
// autoincrement id for folder index. Sends OnFolderAdded notifications
|
||||
// to all observers after the folder has been created and its type has
|
||||
// been set.
|
||||
nsresult CreateContainerWithID(PRInt64 aFolder, PRInt64 aParent,
|
||||
const nsAString& title, const nsAString& type,
|
||||
PRInt32 aIndex, PRInt64* aNewFolder);
|
||||
// generated by autoincrement.
|
||||
nsresult CreateContainerWithID(PRInt64 aId, PRInt64 aParent,
|
||||
const nsAString& aName,
|
||||
const nsAString& aContractId,
|
||||
PRBool aIsBookmarkFolder,
|
||||
PRInt32* aIndex,
|
||||
PRInt64* aNewFolder);
|
||||
|
||||
// Called by History service when quitting.
|
||||
nsresult OnQuit();
|
||||
|
@ -200,7 +193,7 @@ private:
|
|||
static const PRInt32 kGetItemPropertiesIndex_PlaceID;
|
||||
static const PRInt32 kGetItemPropertiesIndex_Parent;
|
||||
static const PRInt32 kGetItemPropertiesIndex_Type;
|
||||
static const PRInt32 kGetItemPropertiesIndex_FolderType;
|
||||
static const PRInt32 kGetItemPropertiesIndex_ServiceContractId;
|
||||
static const PRInt32 kGetItemPropertiesIndex_DateAdded;
|
||||
static const PRInt32 kGetItemPropertiesIndex_LastModified;
|
||||
|
||||
|
@ -219,7 +212,7 @@ private:
|
|||
public:
|
||||
RemoveFolderTransaction(PRInt64 aID, PRInt64 aParent,
|
||||
const nsAString& aTitle, PRInt32 aIndex,
|
||||
const nsACString& aType)
|
||||
const nsAString& aType)
|
||||
: mID(aID),
|
||||
mParent(aParent),
|
||||
mIndex(aIndex){
|
||||
|
@ -237,12 +230,8 @@ private:
|
|||
NS_IMETHOD UndoTransaction() {
|
||||
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
|
||||
PRInt64 newFolder;
|
||||
// If the transaction has no specific type, default to a folder, and send notifications
|
||||
// to all bookmark observers (controlled by the PR_TRUE argument to CreateFolderWithID).
|
||||
if (mType.IsEmpty())
|
||||
return bookmarks->CreateFolderWithID(mID, mParent, mTitle, PR_TRUE, &mIndex, &newFolder);
|
||||
nsAutoString type; type.AssignWithConversion(mType);
|
||||
return bookmarks->CreateContainerWithID(mID, mParent, mTitle, type, mIndex, &newFolder);
|
||||
return bookmarks->CreateContainerWithID(mID, mParent, mTitle, mType, PR_TRUE,
|
||||
&mIndex, &newFolder);
|
||||
}
|
||||
|
||||
NS_IMETHOD RedoTransaction() {
|
||||
|
@ -263,7 +252,7 @@ private:
|
|||
PRInt64 mID;
|
||||
PRInt64 mParent;
|
||||
nsString mTitle;
|
||||
nsCString mType;
|
||||
nsString mType;
|
||||
PRInt32 mIndex;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2012,8 +2012,8 @@ nsNavHistory::ExecuteQueries(nsINavHistoryQuery** aQueries, PRUint32 aQueryCount
|
|||
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
|
||||
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsCOMPtr<nsNavHistoryResultNode> tempRootNode;
|
||||
rv = bookmarks->ResultNodeForFolder(folderId, options,
|
||||
getter_AddRefs(tempRootNode));
|
||||
rv = bookmarks->ResultNodeForContainer(folderId, options,
|
||||
getter_AddRefs(tempRootNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rootNode = tempRootNode->GetAsContainer();
|
||||
} else {
|
||||
|
@ -3911,7 +3911,8 @@ nsNavHistory::GroupByDay(nsNavHistoryQueryResultNode *aResultNode,
|
|||
EmptyCString(),
|
||||
nsNavHistoryResultNode::RESULT_TYPE_DAY,
|
||||
PR_TRUE,
|
||||
EmptyCString());
|
||||
EmptyCString(),
|
||||
nsnull);
|
||||
|
||||
if (!dates[ageInDays])
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -3989,7 +3990,7 @@ nsNavHistory::GroupByHost(nsNavHistoryQueryResultNode *aResultNode,
|
|||
|
||||
curTopGroup = new nsNavHistoryContainerResultNode(urn, title,
|
||||
EmptyCString(), nsNavHistoryResultNode::RESULT_TYPE_HOST, PR_TRUE,
|
||||
EmptyCString());
|
||||
EmptyCString(), nsnull);
|
||||
if (! curTopGroup)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -4326,7 +4327,7 @@ nsNavHistory::QueryRowToResult(const nsACString& aURI, const nsACString& aTitle,
|
|||
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// this addrefs for us
|
||||
rv = bookmarks->ResultNodeForFolder(folderId, options, aNode);
|
||||
rv = bookmarks->ResultNodeForContainer(folderId, options, aNode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
// regular query
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#include "nsILocale.h"
|
||||
#include "nsILocaleService.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIRemoteContainer.h"
|
||||
#include "nsIDynamicContainer.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsITreeColumns.h"
|
||||
|
@ -203,11 +203,9 @@ nsNavHistoryResultNode::GetGeneratingOptions()
|
|||
// When we have no parent, it either means we haven't built the tree yet,
|
||||
// in which case calling this function is a bug, or this node is the root
|
||||
// of the tree. When we are the root of the tree, our own options are the
|
||||
// generating options, and we know we are either a query of a folder node.
|
||||
if (IsFolder())
|
||||
return GetAsFolder()->mOptions;
|
||||
else if (IsQuery())
|
||||
return GetAsQuery()->mOptions;
|
||||
// generating options.
|
||||
if (IsContainer())
|
||||
return GetAsContainer()->mOptions;
|
||||
NS_NOTREACHED("Can't find a generating node for this container, perhaps FillStats has not been called on this tree yet?");
|
||||
return nsnull;
|
||||
}
|
||||
|
@ -272,13 +270,14 @@ NS_INTERFACE_MAP_END_INHERITING(nsNavHistoryResultNode)
|
|||
nsNavHistoryContainerResultNode::nsNavHistoryContainerResultNode(
|
||||
const nsACString& aURI, const nsACString& aTitle,
|
||||
const nsACString& aIconURI, PRUint32 aContainerType, PRBool aReadOnly,
|
||||
const nsACString& aRemoteContainerType) :
|
||||
const nsACString& aDynamicContainerType, nsNavHistoryQueryOptions* aOptions) :
|
||||
nsNavHistoryResultNode(aURI, aTitle, 0, 0, aIconURI),
|
||||
mResult(nsnull),
|
||||
mContainerType(aContainerType),
|
||||
mExpanded(PR_FALSE),
|
||||
mChildrenReadOnly(aReadOnly),
|
||||
mRemoteContainerType(aRemoteContainerType)
|
||||
mDynamicContainerType(aDynamicContainerType),
|
||||
mOptions(aOptions)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -360,22 +359,20 @@ nsNavHistoryContainerResultNode::OpenContainer()
|
|||
NS_ASSERTION(! mExpanded, "Container must be expanded to close it");
|
||||
mExpanded = PR_TRUE;
|
||||
|
||||
/* Untested container API functions
|
||||
if (! mRemoteContainerType.IsEmpty()) {
|
||||
// remote container API may want to fill us
|
||||
if (IsDynamicContainer()) {
|
||||
// dynamic container API may want to fill us
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIRemoteContainer> remote = do_GetService(mRemoteContainerType.get(), &rv);
|
||||
nsCOMPtr<nsIDynamicContainer> svc = do_GetService(mDynamicContainerType.get(), &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
remote->OnContainerOpening(this, GetGeneratingOptions());
|
||||
svc->OnContainerNodeOpening(this, GetGeneratingOptions());
|
||||
} else {
|
||||
NS_WARNING("Unable to get remote container for ");
|
||||
NS_WARNING(mRemoteContainerType.get());
|
||||
NS_WARNING("Unable to get dynamic container for ");
|
||||
NS_WARNING(mDynamicContainerType.get());
|
||||
}
|
||||
PRInt32 oldAccessCount = mAccessCount;
|
||||
FillStats();
|
||||
ReverseUpdateStats(mAccessCount - oldAccessCount);
|
||||
}
|
||||
*/
|
||||
|
||||
nsNavHistoryResult* result = GetResult();
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
|
@ -405,15 +402,13 @@ nsNavHistoryContainerResultNode::CloseContainer(PRBool aUpdateView)
|
|||
|
||||
mExpanded = PR_FALSE;
|
||||
|
||||
/* Untested remote container functions
|
||||
nsresult rv;
|
||||
if (! mRemoteContainerType.IsEmpty()) {
|
||||
// notify remote containers that we are closing
|
||||
nsCOMPtr<nsIRemoteContainer> remote = do_GetService(mRemoteContainerType.get(), &rv);
|
||||
if (IsDynamicContainer()) {
|
||||
// notify dynamic containers that we are closing
|
||||
nsCOMPtr<nsIDynamicContainer> svc = do_GetService(mDynamicContainerType.get(), &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
remote->OnContainerClosed(this);
|
||||
svc->OnContainerNodeClosed(this);
|
||||
}
|
||||
*/
|
||||
|
||||
if (aUpdateView) {
|
||||
nsNavHistoryResult* result = GetResult();
|
||||
|
@ -1378,20 +1373,6 @@ nsNavHistoryContainerResultNode::RemoveChildAt(PRInt32 aIndex,
|
|||
}
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::CanRemoteContainersChange
|
||||
//
|
||||
// Returns true if remote containers can manipulate the contents of this
|
||||
// container. This is false for folders and queries, true for everything
|
||||
// else.
|
||||
|
||||
PRBool
|
||||
nsNavHistoryContainerResultNode::CanRemoteContainersChange()
|
||||
{
|
||||
return (mContainerType != nsNavHistoryResultNode::RESULT_TYPE_FOLDER &&
|
||||
mContainerType != nsNavHistoryResultNode::RESULT_TYPE_QUERY);
|
||||
}
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::RecursiveFindURIs
|
||||
//
|
||||
// This function searches for matches for the given URI.
|
||||
|
@ -1621,40 +1602,39 @@ nsNavHistoryContainerResultNode::GetChildrenReadOnly(PRBool *aChildrenReadOnly)
|
|||
}
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::GetRemoteContainerType
|
||||
// nsNavHistoryContainerResultNode::GetDynamicContainerType
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryContainerResultNode::GetRemoteContainerType(
|
||||
nsACString& aRemoteContainerType)
|
||||
nsNavHistoryContainerResultNode::GetDynamicContainerType(
|
||||
nsACString& aDynamicContainerType)
|
||||
{
|
||||
aRemoteContainerType = mRemoteContainerType;
|
||||
aDynamicContainerType = mDynamicContainerType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::AppendURINode
|
||||
|
||||
#if 0 // UNTESTED, commented out until it can be tested
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryContainerResultNode::AppendURINode(
|
||||
const nsACString& aURI, const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI, nsINavHistoryResultNode** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a remote container
|
||||
if (!IsDynamicContainer())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a dynamic container
|
||||
|
||||
nsRefPtr<nsNavHistoryResultNode> result =
|
||||
new nsNavHistoryResultNode(aURI, aTitle, aAccessCount, aTime, aIconURI);
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// append to our list
|
||||
if (! mChildren.AppendObject(result))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsresult rv = InsertChildAt(result, mChildren.Count());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*_retval = result);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::AppendVisitNode
|
||||
|
@ -1667,8 +1647,8 @@ nsNavHistoryContainerResultNode::AppendVisitNode(
|
|||
nsINavHistoryVisitResultNode** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a remote container
|
||||
if (!IsDynamicContainer())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a dynamic container
|
||||
|
||||
nsRefPtr<nsNavHistoryVisitResultNode> result =
|
||||
new nsNavHistoryVisitResultNode(aURI, aTitle, aAccessCount, aTime,
|
||||
|
@ -1681,12 +1661,10 @@ nsNavHistoryContainerResultNode::AppendVisitNode(
|
|||
NS_ADDREF(*_retval = result);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::AppendFullVisitNode
|
||||
|
||||
#if 0 // UNTESTED, commented out until it can be tested
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryContainerResultNode::AppendFullVisitNode(
|
||||
const nsACString& aURI, const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
|
@ -1695,8 +1673,8 @@ nsNavHistoryContainerResultNode::AppendFullVisitNode(
|
|||
nsINavHistoryFullVisitResultNode** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a remote container
|
||||
if (!IsDynamicContainer())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a dynamic container
|
||||
|
||||
nsRefPtr<nsNavHistoryFullVisitResultNode> result =
|
||||
new nsNavHistoryFullVisitResultNode(aURI, aTitle, aAccessCount, aTime,
|
||||
|
@ -1710,35 +1688,33 @@ nsNavHistoryContainerResultNode::AppendFullVisitNode(
|
|||
NS_ADDREF(*_retval = result);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::AppendContainerNode
|
||||
|
||||
#if 0 // UNTESTED, commented out until it can be tested
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryContainerResultNode::AppendContainerNode(
|
||||
const nsACString& aTitle, const nsACString& aIconURI,
|
||||
PRUint32 aContainerType, const nsACString& aRemoteContainerType,
|
||||
PRUint32 aContainerType, const nsACString& aDynamicContainerType,
|
||||
nsINavHistoryContainerResultNode** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a remote container
|
||||
if (!IsDynamicContainer())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a dynamic container
|
||||
if (! IsTypeContainer(aContainerType) || IsTypeFolder(aContainerType) ||
|
||||
IsTypeQuery(aContainerType))
|
||||
return NS_ERROR_INVALID_ARG; // not proper container type
|
||||
if (aContainerType == nsNavHistoryResultNode::RESULT_TYPE_REMOTE_CONTAINER &&
|
||||
if (aContainerType == nsNavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER &&
|
||||
aRemoteContainerType.IsEmpty())
|
||||
return NS_ERROR_INVALID_ARG; // remote containers must have r.c. type
|
||||
if (aContainerType != nsNavHistoryResultNode::RESULT_TYPE_REMOTE_CONTAINER &&
|
||||
! aRemoteContainerType.IsEmpty())
|
||||
return NS_ERROR_INVALID_ARG; // non-remote containers must NOT have r.c. type
|
||||
return NS_ERROR_INVALID_ARG; // dynamic containers must have d.c. type
|
||||
if (aContainerType != nsNavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER &&
|
||||
! aDynamicContainerType.IsEmpty())
|
||||
return NS_ERROR_INVALID_ARG; // non-dynamic containers must NOT have d.c. type
|
||||
|
||||
nsRefPtr<nsNavHistoryContainerResultNode> result =
|
||||
new nsNavHistoryContainerResultNode(EmptyCString(), aTitle, aIconURI,
|
||||
aContainerType, PR_TRUE,
|
||||
aRemoteContainerType);
|
||||
aDynamicContainerType);
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// append to our list
|
||||
|
@ -1757,8 +1733,8 @@ nsNavHistoryContainerResultNode::AppendQueryNode(
|
|||
const nsACString& aIconURI, nsINavHistoryQueryResultNode** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a remote container
|
||||
if (!IsDynamicContainer())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a dynamic container
|
||||
|
||||
nsRefPtr<nsNavHistoryQueryResultNode> result =
|
||||
new nsNavHistoryQueryResultNode(aQueryURI, aTitle, aIconURI);
|
||||
|
@ -1772,47 +1748,45 @@ nsNavHistoryContainerResultNode::AppendQueryNode(
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::AppendFolderNode
|
||||
|
||||
#if 0 // UNTESTED, commented out until it can be tested
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryContainerResultNode::AppendFolderNode(
|
||||
PRInt64 aFolderId, nsINavHistoryFolderResultNode** _retval)
|
||||
PRInt64 aFolderId, nsINavHistoryContainerResultNode** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a remote container
|
||||
if (!IsDynamicContainer())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a dynamic container
|
||||
|
||||
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
|
||||
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// create the node, it will be addrefed for us
|
||||
nsRefPtr<nsNavHistoryResultNode> result;
|
||||
nsresult rv = bookmarks->ResultNodeForFolder(aFolderId,
|
||||
GetGeneratingOptions(),
|
||||
getter_AddRefs(result));
|
||||
nsresult rv = bookmarks->ResultNodeForContainer(aFolderId,
|
||||
GetGeneratingOptions(),
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// append to our list
|
||||
if (! mChildren.AppendObject(result))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*_retval = result->GetAsFolder());
|
||||
rv = InsertChildAt(result, mChildren.Count());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*_retval = result->GetAsContainer());
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode::ClearContents
|
||||
//
|
||||
// Used by the remote container API to clear this container
|
||||
// Used by the dynamic container API to clear this container
|
||||
|
||||
#if 0 // UNTESTED, commented out until it can be tested
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryContainerResultNode::ClearContents()
|
||||
{
|
||||
if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a remote container
|
||||
if (!IsDynamicContainer())
|
||||
return NS_ERROR_INVALID_ARG; // we must be a dynamic container
|
||||
|
||||
// we know if CanRemoteContainersChange() then we are a regular container
|
||||
// and not a query or folder, so clearing doesn't need anything else to
|
||||
|
@ -1828,7 +1802,6 @@ nsNavHistoryContainerResultNode::ClearContents()
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
// nsNavHistoryQueryResultNode *************************************************
|
||||
//
|
||||
// HOW QUERY UPDATING WORKS
|
||||
|
@ -1857,7 +1830,7 @@ nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode(
|
|||
const nsACString& aQueryURI) :
|
||||
nsNavHistoryContainerResultNode(aQueryURI, aTitle, aIconURI,
|
||||
nsNavHistoryResultNode::RESULT_TYPE_QUERY,
|
||||
PR_TRUE, EmptyCString()),
|
||||
PR_TRUE, EmptyCString(), nsnull),
|
||||
mHasSearchTerms(PR_FALSE),
|
||||
mContentsValid(PR_FALSE),
|
||||
mBatchInProgress(PR_FALSE)
|
||||
|
@ -1873,9 +1846,8 @@ nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode(
|
|||
nsNavHistoryQueryOptions* aOptions) :
|
||||
nsNavHistoryContainerResultNode(EmptyCString(), aTitle, aIconURI,
|
||||
nsNavHistoryResultNode::RESULT_TYPE_QUERY,
|
||||
PR_TRUE, EmptyCString()),
|
||||
PR_TRUE, EmptyCString(), aOptions),
|
||||
mQueries(aQueries),
|
||||
mOptions(aOptions),
|
||||
mContentsValid(PR_FALSE),
|
||||
mBatchInProgress(PR_FALSE)
|
||||
{
|
||||
|
@ -2649,12 +2621,11 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsNavHistoryFolderResultNode,
|
|||
|
||||
nsNavHistoryFolderResultNode::nsNavHistoryFolderResultNode(
|
||||
const nsACString& aTitle, nsNavHistoryQueryOptions* aOptions,
|
||||
PRInt64 aFolderId, const nsACString& aRemoteContainerType) :
|
||||
PRInt64 aFolderId, const nsACString& aDynamicContainerType) :
|
||||
nsNavHistoryContainerResultNode(EmptyCString(), aTitle, EmptyCString(),
|
||||
nsNavHistoryResultNode::RESULT_TYPE_FOLDER,
|
||||
PR_FALSE, aRemoteContainerType),
|
||||
mContentsValid(PR_FALSE),
|
||||
mOptions(aOptions)
|
||||
PR_FALSE, aDynamicContainerType, aOptions),
|
||||
mContentsValid(PR_FALSE)
|
||||
{
|
||||
mItemId = aFolderId;
|
||||
|
||||
|
@ -2714,25 +2685,23 @@ nsNavHistoryFolderResultNode::OpenContainer()
|
|||
NS_ASSERTION(! mExpanded, "Container must be expanded to close it");
|
||||
nsresult rv;
|
||||
|
||||
/* Untested container API functions
|
||||
if (! mRemoteContainerType.IsEmpty()) {
|
||||
// remote container API may want to change the bookmarks for this folder.
|
||||
nsCOMPtr<nsIRemoteContainer> remote = do_GetService(mRemoteContainerType.get(), &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
remote->OnContainerOpening(static_cast<nsINavHistoryFolderResultNode*>(this),
|
||||
mOptions);
|
||||
} else {
|
||||
NS_WARNING("Unable to get remote container for ");
|
||||
NS_WARNING(mRemoteContainerType.get());
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (! mContentsValid) {
|
||||
rv = FillChildren();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (IsDynamicContainer()) {
|
||||
// dynamic container API may want to change the bookmarks for this folder.
|
||||
nsCOMPtr<nsIDynamicContainer> svc = do_GetService(mDynamicContainerType.get(), &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
svc->OnContainerNodeOpening(
|
||||
static_cast<nsNavHistoryContainerResultNode*>(this), mOptions);
|
||||
} else {
|
||||
NS_WARNING("Unable to get dynamic container for ");
|
||||
NS_WARNING(mDynamicContainerType.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
mExpanded = PR_TRUE;
|
||||
|
||||
nsNavHistoryResult* result = GetResult();
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
if (result->GetView())
|
||||
|
@ -3093,7 +3062,7 @@ nsNavHistoryFolderResultNode::OnItemAdded(PRInt64 aItemId,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (itemType == nsINavBookmarksService::TYPE_FOLDER) {
|
||||
rv = bookmarks->ResultNodeForFolder(aItemId, mOptions, &node);
|
||||
rv = bookmarks->ResultNodeForContainer(aItemId, mOptions, &node);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (itemType == nsINavBookmarksService::TYPE_SEPARATOR) {
|
||||
|
@ -3690,19 +3659,15 @@ nsNavHistoryResult::SetViewer(nsINavHistoryResultViewer* aViewer)
|
|||
|
||||
// nsNavHistoryResult::GetRoot (nsINavHistoryResult)
|
||||
//
|
||||
// We have a pointer to a container, but it will either be a folder or
|
||||
// query node, both of which QI to QueryResultNode (even though folder
|
||||
// does not inherit from a concrete query).
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryResult::GetRoot(nsINavHistoryQueryResultNode** aRoot)
|
||||
nsNavHistoryResult::GetRoot(nsINavHistoryContainerResultNode** aRoot)
|
||||
{
|
||||
if (! mRootNode) {
|
||||
NS_NOTREACHED("Root is null");
|
||||
*aRoot = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return mRootNode->QueryInterface(NS_GET_IID(nsINavHistoryQueryResultNode),
|
||||
return mRootNode->QueryInterface(NS_GET_IID(nsINavHistoryContainerResultNode),
|
||||
reinterpret_cast<void**>(aRoot));
|
||||
}
|
||||
|
||||
|
|
|
@ -292,7 +292,7 @@ public:
|
|||
// Note that GetType() already has a vtable slot because its on the iface.
|
||||
PRBool IsTypeContainer(PRUint32 type) {
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_HOST ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_REMOTE_CONTAINER ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_QUERY ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_DAY);
|
||||
|
@ -302,6 +302,11 @@ public:
|
|||
GetType(&type);
|
||||
return IsTypeContainer(type);
|
||||
}
|
||||
PRBool IsDynamicContainer() {
|
||||
PRUint32 type;
|
||||
GetType(&type);
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER);
|
||||
}
|
||||
static PRBool IsTypeQuerySubcontainer(PRUint32 type) {
|
||||
// Tests containers that are inside queries that really belong to the query
|
||||
// itself, and is used when recursively updating a query. This currently
|
||||
|
@ -476,11 +481,13 @@ public:
|
|||
{ return nsNavHistoryContainerResultNode::GetChildCount(aChildCount); } \
|
||||
NS_IMETHOD GetChild(PRUint32 index, nsINavHistoryResultNode **_retval) \
|
||||
{ return nsNavHistoryContainerResultNode::GetChild(index, _retval); } \
|
||||
NS_IMETHOD GetRemoteContainerType(nsACString& aRemoteContainerType) \
|
||||
{ return nsNavHistoryContainerResultNode::GetRemoteContainerType(aRemoteContainerType); }
|
||||
/* Untested container API functions
|
||||
NS_IMETHOD GetDynamicContainerType(nsACString& aDynamicContainerType) \
|
||||
{ return nsNavHistoryContainerResultNode::GetDynamicContainerType(aDynamicContainerType); } \
|
||||
NS_IMETHOD AppendURINode(const nsACString& aURI, const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, const nsACString& aIconURI, nsINavHistoryResultNode **_retval) \
|
||||
{ return nsNavHistoryContainerResultNode::AppendURINode(aURI, aTitle, aAccessCount, aTime, aIconURI, _retval); } \
|
||||
NS_IMETHOD AppendFolderNode(PRInt64 aFolderId, nsINavHistoryContainerResultNode **_retval) \
|
||||
{ return nsNavHistoryContainerResultNode::AppendFolderNode(aFolderId, _retval); }
|
||||
/* Untested container API functions
|
||||
NS_IMETHOD AppendVisitNode(const nsACString& aURI, const nsACString & aTitle, PRUint32 aAccessCount, PRTime aTime, const nsACString & aIconURI, PRInt64 aSession, nsINavHistoryVisitResultNode **_retval) \
|
||||
{ return nsNavHistoryContainerResultNode::AppendVisitNode(aURI, aTitle, aAccessCount, aTime, aIconURI, aSession, _retval); } \
|
||||
NS_IMETHOD AppendFullVisitNode(const nsACString& aURI, const nsACString & aTitle, PRUint32 aAccessCount, PRTime aTime, const nsACString & aIconURI, PRInt64 aSession, PRInt64 aVisitId, PRInt64 aReferringVisitId, PRInt32 aTransitionType, nsINavHistoryFullVisitResultNode **_retval) \
|
||||
|
@ -489,8 +496,6 @@ public:
|
|||
{ return nsNavHistoryContainerResultNode::AppendContainerNode(aTitle, aIconURI, aContainerType, aRemoteContainerType, _retval); } \
|
||||
NS_IMETHOD AppendQueryNode(const nsACString& aQueryURI, const nsACString & aTitle, const nsACString & aIconURI, nsINavHistoryQueryResultNode **_retval) \
|
||||
{ return nsNavHistoryContainerResultNode::AppendQueryNode(aQueryURI, aTitle, aIconURI, _retval); } \
|
||||
NS_IMETHOD AppendFolderNode(PRInt64 aFolderId, nsINavHistoryFolderResultNode **_retval) \
|
||||
{ return nsNavHistoryContainerResultNode::AppendFolderNode(aFolderId, _retval); } \
|
||||
NS_IMETHOD ClearContents() \
|
||||
{ return nsNavHistoryContainerResultNode::ClearContents(); }
|
||||
*/
|
||||
|
@ -505,7 +510,8 @@ public:
|
|||
nsNavHistoryContainerResultNode(
|
||||
const nsACString& aURI, const nsACString& aTitle,
|
||||
const nsACString& aIconURI, PRUint32 aContainerType,
|
||||
PRBool aReadOnly, const nsACString& aRemoteContainerType);
|
||||
PRBool aReadOnly, const nsACString& aDynamicContainerType,
|
||||
nsNavHistoryQueryOptions* aOptions);
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYCONTAINERRESULTNODE_IID)
|
||||
|
||||
|
@ -546,10 +552,10 @@ public:
|
|||
|
||||
PRBool mChildrenReadOnly;
|
||||
|
||||
// ID of a remote container interface that we can use GetService to get.
|
||||
// This is empty to indicate there is no remote container service for this
|
||||
// container (the common case).
|
||||
nsCString mRemoteContainerType;
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
|
||||
|
||||
// ID of a dynamic container interface that we can use GetService to get.
|
||||
nsCString mDynamicContainerType;
|
||||
|
||||
void FillStats();
|
||||
void ReverseUpdateStats(PRInt32 aAccessCountChange);
|
||||
|
@ -630,8 +636,6 @@ public:
|
|||
nsresult ReplaceChildURIAt(PRUint32 aIndex, nsNavHistoryResultNode* aNode);
|
||||
nsresult RemoveChildAt(PRInt32 aIndex, PRBool aIsTemporary = PR_FALSE);
|
||||
|
||||
PRBool CanRemoteContainersChange();
|
||||
|
||||
void RecursiveFindURIs(PRBool aOnlyOne,
|
||||
nsNavHistoryContainerResultNode* aContainer,
|
||||
const nsCString& aSpec,
|
||||
|
@ -691,7 +695,6 @@ public:
|
|||
// these may be constructed lazily from mURI, call VerifyQueriesParsed
|
||||
// either this or mURI should be valid
|
||||
nsCOMArray<nsNavHistoryQuery> mQueries;
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
|
||||
PRUint32 mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h
|
||||
PRBool mHasSearchTerms;
|
||||
nsresult VerifyQueriesParsed();
|
||||
|
@ -723,7 +726,7 @@ public:
|
|||
nsNavHistoryFolderResultNode(const nsACString& aTitle,
|
||||
nsNavHistoryQueryOptions* options,
|
||||
PRInt64 aFolderId,
|
||||
const nsACString& aRemoteContainerType);
|
||||
const nsACString& aDynamicContainerType);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_COMMON_RESULTNODE_TO_BASE
|
||||
|
@ -750,8 +753,6 @@ public:
|
|||
// after the container is closed until a notification comes in
|
||||
PRBool mContentsValid;
|
||||
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
|
||||
|
||||
nsresult FillChildren();
|
||||
void ClearChildren(PRBool aUnregister);
|
||||
nsresult Refresh();
|
||||
|
|
|
@ -63,18 +63,10 @@ function run_test() {
|
|||
uri("http://example.com/"),
|
||||
uri("http://example.com/rss.xml"), -1);
|
||||
|
||||
|
||||
try {
|
||||
lmsvc.QueryInterface(Ci.nsIRemoteContainer);
|
||||
} catch(ex) {
|
||||
do_throw("Failed to QueryInterface livemark-service to nsIRemoteContainer");
|
||||
}
|
||||
|
||||
do_check_true(lmsvc.childrenReadOnly);
|
||||
|
||||
do_check_true(lmsvc.isLivemark(livemarkId));
|
||||
do_check_true(lmsvc.getSiteURI(livemarkId).spec == "http://example.com/");
|
||||
do_check_true(lmsvc.getFeedURI(livemarkId).spec == "http://example.com/rss.xml");
|
||||
do_check_true(bmsvc.getFolderReadonly(livemarkId));
|
||||
|
||||
lmsvc.setSiteURI(livemarkId, uri("http://foo.example.com/"));
|
||||
do_check_true(lmsvc.getSiteURI(livemarkId).spec == "http://foo.example.com/");
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License
|
||||
* at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* The Original Code is Places Dynamic Containers unit test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Asaf Romano <mano@mozilla.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of either the GNU General Public License Version 2 or later
|
||||
* (the "GPL"), or the GNU Lesser General Public License Version 2.1
|
||||
* or later (the "LGPL"), in which case the provisions of the GPL or
|
||||
* the LGPL are applicable instead of those above. If you wish to
|
||||
* allow use of your version of this file only under the terms of
|
||||
* either the GPL or the LGPL, and not to allow others to use your
|
||||
* version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the
|
||||
* notice and other provisions required by the GPL or the LGPL. If you
|
||||
* do not delete the provisions above, a recipient may use your
|
||||
* version of this file under the terms of any one of the MPL, the GPL
|
||||
* or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function RemoteContainerSampleService() {
|
||||
}
|
||||
|
||||
RemoteContainerSampleService.prototype = {
|
||||
|
||||
get bms() {
|
||||
if (!this._bms)
|
||||
this._bms = Cc[BMS_CONTRACTID].getService(Ci.nsINavBookmarksService);
|
||||
return this._bms;
|
||||
},
|
||||
|
||||
get history() {
|
||||
if (!this._history)
|
||||
this._history = Cc[NH_CONTRACTID].getService(Ci.nsINavHistoryService);
|
||||
return this._history;
|
||||
},
|
||||
|
||||
// IO Service
|
||||
get ios() {
|
||||
if (!this._ios)
|
||||
this._ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
return this._ios;
|
||||
},
|
||||
|
||||
// nsIDynamicContainer
|
||||
onContainerRemoving: function(container) { },
|
||||
|
||||
onContainerMoved: function() { },
|
||||
|
||||
onContainerNodeOpening: function(container, options) {
|
||||
container.appendURINode("http://foo.tld/", "uri 1", 0, 0, null);
|
||||
|
||||
var folder = Cc["@mozilla.org/browser/annotation-service;1"].
|
||||
getService(Ci.nsIAnnotationService).
|
||||
getItemAnnotation(container.itemId, "exposedFolder");
|
||||
|
||||
container.appendFolderNode(folder);
|
||||
},
|
||||
|
||||
onContainerNodeClosed: function() { },
|
||||
|
||||
createInstance: function LS_createInstance(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
classDescription: "Remote Container Sample Service",
|
||||
contractID: "@mozilla.org/browser/remote-container-sample;1",
|
||||
classID: Components.ID("{0d42adc5-f07a-4da2-b8da-3e2ef114cb67}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDynamicContainer]),
|
||||
};
|
||||
|
||||
function NSGetModule(compMgr, fileSpec) {
|
||||
return XPCOMUtils.generateModule([RemoteContainerSampleService]);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places Dynamic Containers unit test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Asaf Romano <mano@mozilla.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var annosvc = Cc["@mozilla.org/browser/annotation-service;1"].
|
||||
getService(Ci.nsIAnnotationService);
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
// load our dynamic-container sample service
|
||||
do_load_module("/toolkit/components/places/tests/unit/nsDynamicContainerServiceSample.js");
|
||||
var testRoot = bmsvc.createFolder(bmsvc.placesRoot, "test root", bmsvc.DEFAULT_INDEX);
|
||||
var exposedFolder = bmsvc.createFolder(testRoot, "exposed folder", bmsvc.DEFAULT_INDEX);
|
||||
var efId1 = bmsvc.insertBookmark(exposedFolder, uri("http://uri1.tld"), bmsvc.DEFAULT_INDEX, "");
|
||||
|
||||
// create our dynamic container
|
||||
var remoteContainer =
|
||||
bmsvc.createDynamicContainer(testRoot, "remote container sample",
|
||||
"@mozilla.org/browser/remote-container-sample;1",
|
||||
bmsvc.DEFAULT_INDEX);
|
||||
|
||||
// the service will read this annotation and append a folder node for
|
||||
// |exposedFolder| to |remoteContainer|
|
||||
annosvc.setItemAnnotation(remoteContainer, "exposedFolder",
|
||||
exposedFolder, 0, 0);
|
||||
|
||||
// query |remoteContainer|
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
var query = histsvc.getNewQuery();
|
||||
query.setFolders([remoteContainer], 1);
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var rootNode = result.root;
|
||||
|
||||
// two nodes should be at the top lop of this container after opening it,
|
||||
// the first is an arbitrary uri node ("http://foo.tld/"), the second is a
|
||||
// folder node representing |exposedFolder|.
|
||||
rootNode.containerOpen = true;
|
||||
do_check_eq(rootNode.childCount, 2);
|
||||
|
||||
do_check_eq(rootNode.getChild(0).uri, "http://foo.tld/");
|
||||
var folder = rootNode.getChild(1).QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(folder.itemId, exposedFolder);
|
||||
folder.containerOpen = true;
|
||||
do_check_eq(folder.childCount, 1);
|
||||
|
||||
// check live update of a folder exposed within a remote container
|
||||
bmsvc.insertBookmark(exposedFolder, uri("http://uri2.tld"), bmsvc.DEFAULT_INDEX, "");
|
||||
do_check_eq(folder.childCount, 2);
|
||||
}
|
Загрузка…
Ссылка в новой задаче