Compare commits

..

31 Commits

Author SHA1 Message Date
gordon%netscape.com
f06d4f2264 The files have been replaced by nsDiskCacheBinding.*
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95453 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 23:02:39 +00:00
gordon%netscape.com
168ba7fac5 Use approximation of last fetch time for eviction rank.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95437 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 22:26:38 +00:00
gordon%netscape.com
544dab6d92 Change mGeneration to PRUint8.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95411 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 20:57:40 +00:00
darin%netscape.com
3e4ab67de4 changes resulting from review
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95405 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 20:12:31 +00:00
gordon%netscape.com
1d221aa7dd Fixed accounting bugs for total size and entry count.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95386 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 08:02:18 +00:00
darin%netscape.com
344240b9f6 removed unnecessary stuff
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95368 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 04:42:51 +00:00
darin%netscape.com
643bedea5c fixed byte ordering for little endian
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95349 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 00:46:15 +00:00
gordon%netscape.com
ab1f74bc51 Minor fix.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95344 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 00:24:50 +00:00
gordon%netscape.com
0c75de57d4 Minor fixes.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95343 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 00:22:29 +00:00
gordon%netscape.com
7f31a3499d Fixed more bugs.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95341 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-18 00:08:32 +00:00
darin%netscape.com
75f4a226fa make it compile on windows
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95302 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-17 20:50:05 +00:00
gordon%netscape.com
c4f4404360 Update for tip.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95279 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-17 18:50:55 +00:00
gordon%netscape.com
1307eaca6a Implement clear disk cache, and fix bugs.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95278 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-17 18:48:27 +00:00
darin%netscape.com
79730cfa63 make it build on windows
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95179 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-17 01:19:36 +00:00
gordon%netscape.com
f3628c7bd5 Updating for linux.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95149 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-16 22:29:41 +00:00
gordon%netscape.com
e87d348d54 Change for new files in DISKCACHE2_BRANCH.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95148 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-16 22:29:07 +00:00
gordon%netscape.com
606cb60b1f Level 2 nearly done. Eviction still needs to be hooked back up.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@95099 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-16 04:06:21 +00:00
gordon%netscape.com
e6669e5d3a Sync with tip.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94898 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-14 21:31:47 +00:00
gordon%netscape.com
8e855ab4ed Back out non-essential change.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94897 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-14 21:29:11 +00:00
gordon%netscape.com
184791f5ea Add nsDiskCacheBindData.cpp and nsDiskCacheBlockFile.cpp to build.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94896 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-14 21:14:03 +00:00
gordon%netscape.com
fdd7e77c2d Joining change from tip.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94895 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-14 21:12:13 +00:00
gordon%netscape.com
f8cf79b055 Fixes for a few bugs caught by linux.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94894 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-14 20:23:17 +00:00
gordon%netscape.com
8a22ddce2f Additional refactoring of disk cache.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94893 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-14 20:04:53 +00:00
gordon%netscape.com
826ed51db3 Renaming nsDiskCacheEntry -> nsDiskCacheBindInfo, and reorganize files.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94555 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-11 01:38:03 +00:00
gordon%netscape.com
cc6d193bae updating branch for recent trunk changes
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94413 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-09 22:46:14 +00:00
(no author)
9e5b5201e6 This commit was manufactured by cvs2svn to create branch
'DISKCACHE2_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@94030 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-05 05:33:39 +00:00
gordon%netscape.com
ce35aa80bc updating from trunk.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@93323 18797224-902f-48f8-a5cc-f745e15eee43
2001-04-27 23:23:53 +00:00
gordon%netscape.com
908e3bc997 Begin refactoring for nsDiskCacheBlockFile integration. (flat files for metadata).
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@92513 18797224-902f-48f8-a5cc-f745e15eee43
2001-04-17 04:10:54 +00:00
gordon%netscape.com
0ee6b398ae Implement deviceID attribute for nsICacheEntryInfo. Implement nsCacheSession::EvictEntries().
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@92057 18797224-902f-48f8-a5cc-f745e15eee43
2001-04-12 02:44:10 +00:00
gordon%netscape.com
ccc56f1b74 Added attribute to nsICacheEntryInfo to get deviceID for entry.
git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@92056 18797224-902f-48f8-a5cc-f745e15eee43
2001-04-12 02:42:26 +00:00
(no author)
0893647797 This commit was manufactured by cvs2svn to create branch
'DISKCACHE2_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/DISKCACHE2_BRANCH@91529 18797224-902f-48f8-a5cc-f745e15eee43
2001-04-06 00:33:20 +00:00
100 changed files with 11067 additions and 20896 deletions

6
mozilla/netwerk/cache/public/MANIFEST vendored Normal file
View File

@@ -0,0 +1,6 @@
nsICachedNetData.idl
nsINetDataCache.idl
nsINetDataCacheManager.idl
nsINetDataCacheRecord.idl
nsINetDataDiskCache.idl
nsIStreamAsFile.idl

View File

@@ -24,9 +24,37 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = nkcache
XPIDL_MODULE = necko_cache
include $(DEPTH)/config/autoconf.mk
DIRS = public src resources
XPIDLSRCS = $(NULL)
ifdef OLD_CACHE
XPIDLSRCS += \
nsICachedNetData.idl \
nsINetDataCacheManager.idl \
nsINetDataCache.idl \
nsINetDataCacheRecord.idl \
nsINetDataDiskCache.idl \
nsIStreamAsFile.idl \
$(NULL)
endif
ifdef MOZ_NEW_CACHE
XPIDLSRCS += \
nsICache.idl \
nsICacheEntryDescriptor.idl \
nsICacheListener.idl \
nsICacheService.idl \
nsICacheSession.idl \
nsICacheVisitor.idl \
$(NULL)
endif
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk

View File

@@ -1,4 +1,4 @@
#!nmake
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
@@ -19,40 +19,35 @@
#
# Contributor(s):
DEPTH=..\..\..\..
MODULE=bookmarks
REQUIRES = xpcom \
string \
rdf \
appshell \
widget \
necko \
nkcache \
uconv \
pref \
dom \
intl \
webshell \
windowwatcher \
unicharutil \
$(NULL)
MODULE = necko
XPIDL_MODULE = necko_cache
CPP_OBJS= \
.\$(OBJDIR)\nsBookmarksService.obj \
$(NULL)
DEPTH = ..\..\..
include <$(DEPTH)/config/config.mak>
LIBRARY_NAME=bookmarks_s
LCFLAGS = \
$(LCFLAGS) \
$(DEFINES) \
EXPORTS = \
$(NULL)
include <$(DEPTH)\config\rules.mak>
XPIDLSRCS = \
!ifdef MOZ_OLD_CACHE
.\nsICachedNetData.idl \
.\nsINetDataCacheManager.idl \
.\nsINetDataCache.idl \
.\nsINetDataCacheRecord.idl \
.\nsINetDataDiskCache.idl \
.\nsIStreamAsFile.idl \
!endif
!ifdef MOZ_NEW_CACHE
.\nsICache.idl \
.\nsICacheEntryDescriptor.idl \
.\nsICacheListener.idl \
.\nsICacheService.idl \
.\nsICacheSession.idl \
.\nsICacheVisitor.idl \
!endif
$(NULL)
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
include <$(DEPTH)/config/rules.mak>
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,170 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsICache.idl, released February 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsISupports.idl"
typedef long nsCacheStoragePolicy;
typedef long nsCacheAccessMode;
/**
* nsICache is a namespace for various cache constants. It does not represent
* an actual object.
*/
[scriptable, uuid(ec1c0063-197d-44bb-84ba-7525d50fc937)]
interface nsICache
{
/**
* Access Modes
*
*
* Mode Requested | Not Cached | Cached
* ------------------------------------------------------------------------
* READ | KEY_NOT_FOUND | NS_OK
* | Mode = NONE | Mode = READ
* | No Descriptor | Descriptor
* ------------------------------------------------------------------------
* WRITE | NS_OK | NS_OK (Cache service
* | Mode = WRITE | Mode = WRITE dooms existing
* | Descriptor | Descriptor cache entry)
* ------------------------------------------------------------------------
* READ_WRITE | NS_OK | NS_OK
* (1st req.) | Mode = WRITE | Mode = READ_WRITE
* | Descriptor | Descriptor
* ------------------------------------------------------------------------
* READ_WRITE | N/A | NS_OK
* (Nth req.) | | Mode = READ
* | | Descriptor
* ------------------------------------------------------------------------
*
*
* Access Requested:
*
* READ - I only want to READ, if there isn't an entry just fail
* WRITE - I have something new I want to write into the cache, make
* me a new entry and doom the old one, if any.
* READ_WRITE - I want to READ, but I'm willing to update an existing
* entry if necessary, or create a new one if none exists.
*
*
* Access Granted:
*
* NONE - No descriptor is provided. You get zilch. Nada. Nothing.
* READ - You can READ from this descriptor.
* WRITE - You must WRITE to this descriptor because the cache entry
* was just created for you.
* READ_WRITE - You can READ the descriptor to determine if it's valid,
* you may WRITE if it needs updating.
*
*
* Comments:
*
* If you think that you might need to modify cached data or meta data,
* then you must open a cache entry requesting WRITE access. Only one
* cache entry descriptor, per cache entry, will be granted WRITE access.
*
* Usually, you will request READ_WRITE access in order to first test the
* meta data and informational fields to determine if a write (ie. going
* to the net) may actually be necessary. If you determine that it is
* not, then you would mark the cache entry as valid (using MarkValid) and
* then simply read the data from the cache.
*
* A descriptor granted WRITE access has exclusive access to the cache
* entry up to the point at which it marks it as valid. Once the cache
* entry has been "validated", other descriptors with READ access may be
* opened to the cache entry.
*
* If you make a request for READ_WRITE access to a cache entry, the cache
* service will downgrade your access to READ if there is already a
* cache entry descriptor open with WRITE access.
*
* If you make a request for only WRITE access to a cache entry and another
* descriptor with WRITE access is currently open, then the existing cache
* entry will be 'doomed', and you will be given a descriptor (with WRITE
* access only) to a new cache entry.
*
*/
const nsCacheAccessMode ACCESS_NONE = 0;
const nsCacheAccessMode ACCESS_READ = 1;
const nsCacheAccessMode ACCESS_WRITE = 2;
const nsCacheAccessMode ACCESS_READ_WRITE = 3;
/**
* Storage Policy
*
* The storage policy of a cache entry determines the device(s) to which
* it belongs. See nsICacheSession and nsICacheEntryDescriptor for more
* details.
*
* STORE_ANYWHERE - Allows the cache entry to be stored in any device.
* The cache service decides which cache device to use
* based on "some resource management calculation."
* STORE_IN_MEMORY - Requires the cache entry to reside in non-persistent
* storage (ie. typically in system RAM).
* STORE_ON_DISK - Requires the cache entry to reside in persistent
* storage (ie. typically on a system's hard disk).
* STORE_ON_DISK_AS_DISK - Requires the cache entry to reside in persistent
* storage, and in a specific file.
*/
const nsCacheStoragePolicy STORE_ANYWHERE = 0;
const nsCacheStoragePolicy STORE_IN_MEMORY = 1;
const nsCacheStoragePolicy STORE_ON_DISK = 2;
const nsCacheStoragePolicy STORE_ON_DISK_AS_FILE = 3;
/**
* All entries for a cache session are stored as streams of data or
* as objects. These constant my be used to specify the type of entries
* when calling nsICacheService::CreateSession().
*/
const long NOT_STREAM_BASED = 0;
const long STREAM_BASED = 1;
/**
* The synchronous OpenCacheEntry() may be blocking or non-blocking. If a cache entry is
* waiting to be validated by another cache descriptor (so no new cache descriptors for that
* key can be created, OpenCacheEntry() will return NS_ERROR_CACHE_WAIT_FOR_VALIDATION in
* non-blocking mode. In blocking mode, it will wait until the cache entry for the key has
* been validated or doomed. If the cache entry is validated, then a descriptor for that
* entry will be created and returned. If the cache entry was doomed, then a descriptor
* will be created for a new cache entry for the key.
*/
const long NON_BLOCKING = 0;
const long BLOCKING = 1;
};
%{C++
/**
* Cache specific nsresult error codes
*/
#define NS_ERROR_CACHE_KEY_NOT_FOUND NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 61)
#define NS_ERROR_CACHE_DATA_IS_STREAM NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 62)
#define NS_ERROR_CACHE_DATA_IS_NOT_STREAM NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 63)
#define NS_ERROR_CACHE_WAIT_FOR_VALIDATION NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 64)
#define NS_ERROR_CACHE_ENTRY_DOOMED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 65)
#define NS_ERROR_CACHE_READ_ACCESS_DENIED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 66)
#define NS_ERROR_CACHE_WRITE_ACCESS_DENIED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 67)
%}

View File

@@ -0,0 +1,137 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsICacheEntryDescriptor.idl, released
* February 10, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsICacheVisitor.idl"
#include "nsICache.idl"
interface nsISimpleEnumerator;
interface nsICacheListener;
interface nsITransport;
interface nsIFile;
interface nsICacheMetaDataVisitor;
[scriptable, uuid(49c1a11d-f5d2-4f09-8262-551e64908ada)]
interface nsICacheEntryDescriptor : nsICacheEntryInfo
{
/**
* Set the time at which the cache entry should be considered invalid (in
* seconds since the Epoch).
*/
void setExpirationTime(in PRUint32 expirationTime);
/**
* Set the cache entry data size. This will fail if the cache entry
* IS stream based.
*/
void setDataSize(in unsigned long size);
/**
* Get a transport to the cache data. This will fail if the cache entry
* IS NOT stream based.
*/
readonly attribute nsITransport transport;
/**
* Get/set the cache data element. This will fail if the cache entry
* IS stream based. The cache entry holds a strong reference to this
* object. The object will be released when the cache entry is destroyed.
*/
attribute nsISupports cacheElement;
/**
* Get the access granted to this descriptor. See nsICache.idl for the
* definitions of the access modes and a thorough description of their
* corresponding meanings.
*/
readonly attribute nsCacheAccessMode accessGranted;
/**
* Get/set the storage policy of the cache entry. See nsICache.idl for
* the definitions of the storage policies.
*/
attribute nsCacheStoragePolicy storagePolicy;
/**
* Get the disk file associated with the cache entry.
*/
readonly attribute nsIFile file;
/**
* Get/set security info on the cache entry for this descriptor. This fails
* if the storage policy is not STORE_IN_MEMORY.
*/
attribute nsISupports securityInfo;
/**
* Doom the cache entry this descriptor references in order to slate it for
* removal. Once doomed a cache entry cannot be undoomed.
*
* A descriptor with WRITE access can doom the cache entry and choose to
* fail pending requests. This means that pending requests will not get
* a cache descriptor. This is meant as a tool for clients that wish to
* instruct pending requests to skip the cache.
*/
void doom();
void doomAndFailPendingRequests(in nsresult status);
/**
* A writer must validate this cache object before any readers are given
* a descriptor to the object.
*/
void markValid();
/**
* Explicitly close the descriptor (optional).
*/
void close();
/**
* Methods for accessing meta data. Meta data is a table of key/value
* string pairs. The strings do not have to conform to any particular
* charset, but they must be null terminated.
*/
string getMetaDataElement(in string key);
void setMetaDataElement(in string key, in string value);
/**
* Visitor will be called with key/value pair for each meta data element.
*/
void visitMetaData(in nsICacheMetaDataVisitor visitor);
};
[scriptable, uuid(22f9a49c-3cf8-4c23-8006-54efb11ac562)]
interface nsICacheMetaDataVisitor : nsISupports
{
/**
* Called for each key/value pair in the meta data for a cache entry
*/
boolean visitMetaDataElement(in string key,
in string value);
};

View File

@@ -0,0 +1,44 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsICacheListener.idl, released January 19, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsISupports.idl"
#include "nsICache.idl"
interface nsICacheEntryDescriptor;
[scriptable, uuid(638c3848-778b-4851-8ff3-9400f65b8773)]
interface nsICacheListener : nsISupports
{
/**
* Called when the requested access (or appropriate subset) is
* acquired. The status parameter equals NS_OK on success.
* See nsICacheService.idl for accessGranted values.
*/
void onCacheEntryAvailable(in nsICacheEntryDescriptor descriptor,
in nsCacheAccessMode accessGranted,
in nsresult status);
};

View File

@@ -0,0 +1,80 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsICacheService.idl, released February 10, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsISupports.idl"
#include "nsICache.idl"
interface nsISimpleEnumerator;
interface nsICacheListener;
interface nsICacheSession;
interface nsICacheVisitor;
[scriptable, uuid(0ebec4c7-742f-4f27-8e7b-7c8a0cc76348)]
interface nsICacheService : nsISupports
{
/**
* Initialize the cache service.
*/
void init();
/**
* Shutdown the cache service.
*/
void shutdown();
/**
* Create a cache session
*
* A cache session represents a client's access into the cache. The cache
* session is not "owned" by the cache service. Hence, it is possible to
* create duplicate cache sessions. Entries created by a cache session
* are invisible to other cache sessions, unless the cache sessions are
* equivalent.
*
* @param clientID - Specifies the name of the client using the cache.
* @param storagePolicy - Limits the storage policy for all entries
* accessed via the returned session. As a result, devices excluded
* by the storage policy will not be searched when opening entries
* from the returned session.
* @param streamBased - Indicates whether or not the data being cached
* can be represented as a stream. The storagePolicy must be
* consistent with the value of this field. For example, a non-stream-
* based cache entry can only have a storage policy of STORE_IN_MEMORY.
* @return new cache session.
*/
nsICacheSession createSession(in string clientID,
in nsCacheStoragePolicy storagePolicy,
in boolean streamBased);
/**
* Visit entries stored in the cache. Used to implement about:cache.
*/
void visitEntries(in nsICacheVisitor visitor);
/**
* Evicts all entries in all devices implied by the storage policy.
*/
void evictEntries(in nsCacheStoragePolicy storagePolicy);
};

View File

@@ -0,0 +1,72 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsICacheSession.idl, released February 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsISupports.idl"
#include "nsICache.idl"
interface nsICacheEntryDescriptor;
interface nsICacheListener;
[scriptable, uuid(b4b419ad-28b7-4d25-9988-20fa98505a19)]
interface nsICacheSession : nsISupports
{
/**
* Expired entries will be doomed or evicted if this attribute is set to
* true. If false, expired entries will be returned (useful for offline-
* mode and clients, such as HTTP, that can update the valid lifetime of
* cached content). This attribute defaults to true.
*/
attribute PRBool doomEntriesIfExpired;
/**
* A cache session can only give out one descriptor with WRITE access
* to a given cache entry at a time. Until the client calls MarkValid on
* its descriptor, other attempts to open the same cache entry will block.
*/
/**
* Synchronous cache access. This returns a unique descriptor each
* time it is called, even if the same key is specified. When
* called by multiple threads for write access, only one writable
* descriptor will be granted. If 'blocking' is set to false,
*/
nsICacheEntryDescriptor openCacheEntry(in string key,
in nsCacheAccessMode accessRequested,
in boolean blockingMode);
/**
* Asynchronous cache access. Does not block the calling thread.
* Instead, the listener will be notified when the descriptor is
* available.
*/
void asyncOpenCacheEntry(in string key,
in nsCacheAccessMode accessRequested,
in nsICacheListener listener);
/**
* Evict all entries for this session's clientID according to its storagePolicy.
*/
void evictEntries();
};

View File

@@ -0,0 +1,142 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsICacheVisitor.idl, released February 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsISupports.idl"
/* XXX we should define device and entry info as well (stats, etc) */
interface nsICacheDeviceInfo;
interface nsICacheEntryInfo;
[scriptable, uuid(f8c08c4b-d778-49d1-a59b-866fdc500d95)]
interface nsICacheVisitor : nsISupports
{
/**
* Called to provide information about a cache device.
*
* @param deviceID - specifies the device being visited.
* @param deviceInfo - specifies information about this device.
*
* @return true to start visiting all entries for this device.
* @return false to advance to the next device.
*/
boolean visitDevice(in string deviceID,
in nsICacheDeviceInfo deviceInfo);
/**
* Called to provide information about a cache entry.
*
* @param deviceID - specifies the device being visited.
* @param entryInfo - specifies information about this entry.
*
* @return true to visit the next entry on the current device, or if the
* end of the device has been reached, advance to the next device.
* @return false to advance to the next device.
*/
boolean visitEntry(in string deviceID,
in nsICacheEntryInfo entryInfo);
};
[scriptable, uuid(31d1c294-1dd2-11b2-be3a-c79230dca297)]
interface nsICacheDeviceInfo : nsISupports
{
/**
* Get a human readable description of the cache device.
*/
readonly attribute string description;
/**
* Get a usage report, statistics, miscellaneous data about
* the cache device.
*/
readonly attribute string usageReport;
/**
* Get the number of stored cache entries.
*/
readonly attribute unsigned long entryCount;
/**
* Get the total size of the stored cache entries.
*/
readonly attribute unsigned long totalSize;
/**
* Get the upper limit of the size of the data the cache can store.
*/
readonly attribute unsigned long maximumSize;
};
[scriptable, uuid(72c64022-1dd2-11b2-b3a5-b8b859e0a1b2)]
interface nsICacheEntryInfo : nsISupports
{
/**
* Get the client id associated with this cache entry.
*/
readonly attribute string clientID;
/**
* Get the id for the device that stores this cache entry.
*/
readonly attribute string deviceID;
/**
* Get the key identifying the cache entry.
*/
readonly attribute string key;
/**
* Get the number of times the cache entry has been opened.
*/
readonly attribute long fetchCount;
/**
* Get the last time the cache entry was opened (in seconds since the Epoch).
*/
readonly attribute PRUint32 lastFetched;
/**
* Get the last time the cache entry was modified (in seconds since the Epoch).
*/
readonly attribute PRUint32 lastModified;
/**
* Get the expiration time of the cache entry (in seconds since the Epoch).
*/
readonly attribute PRUint32 expirationTime;
/**
* Get the cache entry data size.
*/
readonly attribute unsigned long dataSize;
/**
* Find out whether or not the cache entry is stream based.
*/
boolean isStreamBased();
};

View File

@@ -0,0 +1,240 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsrootidl.idl"
#include "nsISupports.idl"
interface nsIURI;
interface nsIObserver;
interface nsIChannel;
interface nsINetDataCache;
interface nsINetDataCacheRecord;
interface nsILoadGroup;
interface nsIStreamListener;
/**
* The nsICachedNetData interface represents a single entry in a database that
* caches data retrieved from the network. This interface is implemented by the
* cache manager on top of the low-level nsINetDataCacheRecord and
* nsINetDataCache interfaces that are implemented by the database.
*
* Each cache record may contain both content and metadata. The content may
* be, for example, GIF image data or HTML, and it is accessed through
* nsIChannel's streaming API. The opaque metadata, which may contain HTTP
* headers among other things, is stored as a byte array. Each entry in the
* cache is indexed by two different keys: a record id number and a key created
* by combining the URI with a "secondary key", e.g. HTTP post data.
*
* @See nsINetDataCacheRecord
* @See nsINetDataCache
* @See nsINetDataDiskCache
* @See nsINetDataCacheManager
*/
[scriptable, uuid(6aeb2a40-6d43-11d3-90c8-000064657374)]
interface nsICachedNetData : nsISupports
{
/**
* String form of the URI provided as an argument to the call to
* nsINetDataCacheManager::GetCachedNetData() that created this record.
*/
readonly attribute string uriSpec;
/**
* Getter for the opaque secondary database key provided as an argument to
* the call to nsINetDataCacheManager::GetCachedNetData() that created this
* record.
*/
void getSecondaryKey(out unsigned long length,
[retval, size_is(length)] out string secondaryKey);
/**
* This flag may be set by a protocol handler to indicate that it supports
* partial fetching of data. In that case, the cache manager is permitted
* to truncate the entry's content to accommodate incoming data for other
* cache entries rather than deleting it wholesale.
*/
attribute boolean allowPartial;
/**
* This flag indicates that the write stream supplying content data for the
* cache did not complete normally and, therefore, the content may be
* truncated.
*/
readonly attribute boolean partialFlag;
/**
* This flag can be set and cleared by a protocol handler as a form of
* self-notification, so as to avoid race conditions in which a protocol
* handler issues two identical network requests to fill the same cache
* entry. The cache manager itself largely ignores this flag.
*/
attribute boolean updateInProgress;
/**
* inUse is set if any existing channels are associated with this cache
* entry or if the updateInProgess flag is set. This can be used to
* prevent writing to a cache entry by a protocol handler if it's being
* read or written elsewhere.
*/
readonly attribute boolean inUse;
/**
* Date/time that the document was last stored on the origin server, as
* supplied by the protocol handler. This value is used as input to the
* cache replacement policy, i.e. it is not used for validation. If the
* protocol can't supply a last-modified time, this attribute should remain
* unset. When unset, the value of this attribute is zero.
*
* FIXME: Should use nsIDateTime interface, once it's created
* instead of PRTime, for improved scriptability ?
*/
attribute PRTime lastModifiedTime;
/**
* Supplied by the protocol handler, the expirationTime attribute specifies
* the time until which the document is guaranteed fresh, i.e. the document
* does not have to be validated with the server and, therefore, any data
* in cache is definitely usable. The value of this attribute serves as a
* hint to the cache replacement policy. Only one of either staleTime or
* expirationTime may be set for a single cache record. When unset, the
* value of this attribute is zero.
*/
attribute PRTime expirationTime;
/**
* Date/time supplied by the protocol handler, at which point the content
* is *likely* to be stale, i.e. the data in the cache may be out-of-date
* with respect to the data on the server. This heuristic date does not
* necessarily correspond to the HTTP Expires header, as it does not
* determine when cached network data must be validated with the origin
* server, but only serves as a hint to the cache replacement policy. Only
* one of either staleTime or expirationTime may be set for a single cache
* record. When unset, the value of this attribute is zero.
*/
attribute PRTime staleTime;
/**
* Date/time of last access of the data in this cache record, as determined
* by the cache manager.
*/
readonly attribute PRTime lastAccessTime;
readonly attribute PRTime lastUpdateTime;
/**
* Number of times this record has been accessed since it was first stored.
*/
readonly attribute PRUint16 numberAccesses;
/**
* Accessor methods for opaque meta-data which can be read and updated
* independently of the content data.
*
* The aTag argument can be used to accommodate multiple clients of the
* cache API, each of which wants to store its own private meta-data into
* the cache. For example, there could be a "headers" tag that the HTTP
* protocol handler uses to store http response headers and a "image size"
* tag used to store the image dimensions of a GIF file. The aData
* argument refers to an opaque blob of arbitrary bytes.
*
* IMPORTANT: If aData does not contain byte-oriented data, i.e. it's not a
* string, the contents of aData must be byte-swapped by the,
* caller, so as to make the cache files endian-independent.
*/
void getAnnotation(in string aTag,
out PRUint32 aLength, [size_is(aLength), retval] out string aData);
void setAnnotation(in string aTag,
in PRUint32 aLength, [size_is(aLength)] in string aData);
/**
* As a getter, return the number of content bytes stored in the cache,
* i.e. via the nsIChannel streaming APIs. This may be less than the
* complete content length if a partial cache fill occurred. The cached
* content can be truncated by setting the value of this attribute. The
* value of the attribute represents a logical, not a physical, length. If
* compression has been used, the content may consume less storage than
* indicated by this attribute.
*
* When this attribute is set to zero the associated cache disk file, if
* any, should be deleted.
*/
attribute PRUint32 storedContentLength;
/**
* Length of stored content, which may be less than storage consumed if
* compression is used
*/
readonly attribute PRUint32 logicalLength;
/**
* Opaque security info associated with the cache entry; it can't be serialized
* to disk, so it'll only make sense with memory cache
*/
attribute nsISupports securityInfo;
/**
* Notify any observers associated with this cache entry of the deletion
* request. If all observers drop their reference to the cache entry,
* proceed to delete the underlying cache database record and associated
* content storage.
*/
void delete();
/**
* Flush any changes in this entry's data to the cache database. This
* method will automatically be called when the last reference to the cache
* is dropped, but it can also be called explicitly for a synchronous
* effect.
*/
void commit();
/**
* Parent container cache for this entry.
*/
readonly attribute nsINetDataCache cache;
/**
* Create a channel for reading or writing a stream of content into the
* entry. It is expected that many of the nsIChannel methods return
* NS_NOT_IMPLEMENTED, including:
*
* + GetURI()
* + GetContentType()
* + GetContentLength()
*
* Though nsIChannel provides for both async and synchronous I/O APIs, both
* may not be implemented. Only AsyncRead() and OpenOutputStream() is
* required.
*/
nsIChannel newChannel(in nsILoadGroup aLoadGroup);
/**
* This method can be used by a caching protocol handler to store data in
* the cache by forking an asynchronous read stream so that it is
* simultaneously sent to a requester and written into the cache. This
* method implicitly sets the updateInProgress flag, if it has not already
* been set.
*/
nsIStreamListener interceptAsyncRead(in nsIStreamListener aOriginalListener,
in PRUint32 aStartOffset);
};

View File

@@ -0,0 +1,142 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIURI;
interface nsINetDataCacheRecord;
interface nsISimpleEnumerator;
/**
* The nsINetDataCache defines the low-level API for a network-data
* cache, used to cache the responses to network retrieval commands.
* This interface, along with nsINetDataCacheRecord, is implemented by
* the memory cache, the file cache and, optionally, by some extension
* caches. This interface is essentially a pseudo-private API for the
* cache manager. Other clients should never use this interface.
*
* Each cache entry may contain both content, e.g. GIF image data, and
* associated metadata, e.g. HTTP headers. Each entry is indexed by two
* different keys: a record id number and a key created by combining the URI
* with a "secondary key", e.g. HTTP post data.
*
* The nsINetDataCache interface is agnostic as to where the data is
* stored and whether the storage is volatile or persistent. The
* memory cache, any disk caches and any extension caches must all
* implement this interface.
*
*/
[scriptable, uuid(ccfc58c0-6dde-11d3-90c8-000064657374)]
interface nsINetDataCache : nsISupports
{
/**
* Human-readable description of the cache module, e.g. "Disk Cache"
*/
readonly attribute wstring description;
/**
* Returns true if cached data is available for the given opaque key,
* even if only partial data is stored.
*/
boolean contains([size_is(length)] in string key, in PRUint32 length);
/**
* Fetch the cache entry record for the given opaque key. If one does not
* exist, create a new, empty record.
*/
nsINetDataCacheRecord getCachedNetData([size_is(length)] in string key,
in PRUint32 length);
/**
* Fetch the cache entry record for the given URI using the record ID as a key.
*/
nsINetDataCacheRecord getCachedNetDataByID(in PRInt32 RecordID);
/**
* False indicates that this cache is entirely bypassed.
*/
attribute boolean enabled;
/**
* Constants for flags attribute, below
*/
// Used for extension caches, e.g. a CD-ROM cache
const long READ_ONLY = 1 << 0;
// One of these bits must be set
const long MEMORY_CACHE = 1 << 1;
const long FLAT_FILE_CACHE = 1 << 2;
const long FILE_PER_URL_CACHE = 1 << 3;
/**
* See constants defined above.
*/
readonly attribute PRUint32 flags;
/**
* Total number of URI entries stored in the cache.
*/
readonly attribute PRUint32 numEntries;
/**
* Maximum number of URI entries that may be stored in the cache.
*/
readonly attribute PRUint32 maxEntries;
/**
* Enumerate the URI entries stored in the cache.
*/
nsISimpleEnumerator newCacheEntryIterator();
/**
* Contains a reference to the next cache in search order. For the memory
* cache, this attribute always references the disk cache. For the disk
* cache, it contains a reference to the first extension cache.
*/
attribute nsINetDataCache nextCache;
/**
* An estimate of the amount of storage occupied by the cache, in kB.
* Actual use may be slightly higher than reported due to cache overhead
* and heap fragmentation (in the memory cache) or block quantization (in
* the disk cache).
*/
readonly attribute PRUint32 storageInUse;
/**
* Remove all entries from a writable cache. This could be used, for
* example, after a guest ends a browser session. This is equivalent to
* setting the cache's Capacity to zero, except that all cache entries,
* even those in active use, will be deleted. Also, any global cache
* database files will be deleted.
*/
void removeAll();
};
%{ C++
// ContractID prefix for Components that implement this interface
#define NS_NETWORK_CACHE_CONTRACTID "@mozilla.org/network/cache;1"
#define NS_NETWORK_MEMORY_CACHE_CONTRACTID NS_NETWORK_CACHE_CONTRACTID "?name=memory-cache"
#define NS_NETWORK_FLAT_CACHE_CONTRACTID NS_NETWORK_CACHE_CONTRACTID "?name=flat-cache"
#define NS_NETWORK_FILE_CACHE_CONTRACTID NS_NETWORK_CACHE_CONTRACTID "?name=file-cache"
%}

View File

@@ -0,0 +1,169 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsINetDataCache.idl"
interface nsISimpleEnumerator;
interface nsICachedNetData;
interface nsINetDataDiskCache;
interface nsIURI;
/**
* The network-response cache manager is partly responsible for the caching of
* content and associated metadata that has been retrieved via the network.
* (The remaining responsibility for caching lies with individual network
* protocol handlers.)
*
* The cache manager supervises the actions of individual cache components,
* such as the memory cache, the disk cache and any extension caches, e.g. a
* read-only CD-ROM cache.
*
* @See nsINetDataCache
* @See nsICachedNetData
*/
[scriptable, uuid(71c8ab00-6d5c-11d3-90c8-000064657374)]
interface nsINetDataCacheManager : nsISupports
{
/**
* Flag for the GetCachedNetData() method: If set, the memory cache is
* neither searched nor will any data be stored into it. This might be
* appropriate, for example, with images, because they have their own
* cache for storing *decoded* images.
*/
const unsigned long BYPASS_MEMORY_CACHE = 1 << 0;
/**
* Flag for the GetCachedNetData() method: If set, the disk cache
* is neither searched nor will any be data stored into it.
* However, read-only extension caches may be searched. This
* might be used to avoid leaving persistent records of secure
* data.
*/
const unsigned long BYPASS_PERSISTENT_CACHE = 1 << 1;
/**
* Flag for the GetCachedNetData() method: If set, any stream
* content is stored in the cache as a single disk file. Content
* will not be cached in the memory cache nor is it cached in a
* flat-file cache database. This is used to implement the jar
* protocol handler and to provide the stream-as-file semantics
* required by the classic bowser plugin API.
*/
const unsigned long CACHE_AS_FILE = 1 << 2;
/**
These enum's are used for the ClearCache calls.
*/
const unsigned long ALL_CACHES = 1;
const unsigned long MEM_CACHE = 1<<1;
const unsigned long FILE_CACHE = 1<<2;
const unsigned long FLAT_CACHE = 1<<3;
/**
* Fetch the cache entry record for the given URI. If one does not exist,
* create a new, empty record. The normal search order for caches is:
* + Memory cache
* + Disk cache
* + File cache (stream-as-file cache)
* + All extension caches
*
* When writing, data is typically stored in both the memory cache and the
* disk cache. Both the search order and this write policy can be modified by
* setting one or more of the flag argument bits, as defined above.
*
* The optionally-NULL secondaryKey argument can be used, e.g. for form
* post data or for HTTP headers in the case of HTTP.
*/
nsICachedNetData getCachedNetData(in string uri,
[size_is(secondaryKeyLength)] in string secondaryKey,
in PRUint32 secondaryKeyLength,
in PRUint32 flags);
/**
* Returns true if cached content is available for the given URI, even if
* only partial data is stored. The flags argument behaves the same as for
* the GetCachedNetData() method, above.
*/
boolean contains(in string uri,
[size_is(secondaryKeyLength)] in string secondaryKey,
in PRUint32 secondaryKeyLength,
in PRUint32 flags);
/**
* Total number of unexpired URI entries stored in all caches. This number
* does not take into account duplicate URIs, e.g. because the memory cache
* and the disk cache might each contain an entry for the same URI.
*/
readonly attribute PRUint32 numEntries;
/**
* Enumerate the unexpired URI entries stored in all caches. Some URIs may
* be enumerated more than once, e.g. because the the memory cache and the
* disk cache might each contain an entry for the same URI.
*/
nsISimpleEnumerator newCacheEntryIterator();
/*
* Enumerate all the loaded nsINetDataCache-implementing cache modules.
* The first module enumerated will be the memory cache, the second will be
* the disk cache, then the file cache, followed by all the extension
* caches, in search order.
*/
nsISimpleEnumerator newCacheModuleIterator();
/**
* Remove all entries from all writable caches. This could be used, for
* example, after a guest ends a browser session. This is equivalent to
* setting the DiskCacheCapacity to zero, except that all cache entries,
* even those in active use, will be deleted. Also, any global cache
* database files will be deleted.
*/
void removeAll();
/**
* Clears the specified cache
*/
void clear( in PRUint32 aCacheToClear );
/**
* The disk cache is made up of the file cache (for stream-as-file
* requests) and a (possibly independent) persistent cache that handles all
* other cache requests. This attribute sets/gets the combined capacity of
* these caches, measured in KBytes. Setting the capacity lower than the
* current amount of space currently in use may cause cache entries to be
* evicted from the cache to accomodate the requested capacity.
*/
attribute PRUint32 diskCacheCapacity;
/**
* This attribute sets/gets the capacity of the memory cache, measured in
* KBytes. Setting the capacity lower than the current amount of space
* currently in use may cause cache entries to be evicted from the cache to
* accomodate the requested capacity.
*/
attribute PRUint32 memCacheCapacity;
};
%{ C++
// ContractID prefix for Components that implement this interface
#define NS_NETWORK_CACHE_MANAGER_CONTRACTID NS_NETWORK_CACHE_CONTRACTID "?name=manager"
%}

View File

@@ -0,0 +1,131 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsrootidl.idl"
interface nsIFile;
interface nsIChannel;
interface nsINetDataCache;
/**
* The nsINetDataCacheRecord represents a single entry in a database that
* caches data retrieved from the network. On top of this low-level interface
* to the raw record data, the cache manager implements a higher-level record
* interface, nsICachedNetData. Each instance of nsINetDataCacheRecord is
* (internally) associated with a parent database, an instance of the
* nsINetDataCache interface. This interface is essentially a pseudo-private
* API for the cache manager. Other clients should never use this interface.
*
* Each cache record may contain both content and metadata. The content may
* be, for example, GIF image data or HTML, and it is accessed through
* nsIChannel's streaming API. The opaque metadata, which may contain HTTP
* headers among other things, is accessed as a contiguous byte array. Each
* entry in the cache is indexed by two different keys: a unique record id
* number, generated by the cache, and an opaque string. The latter contains
* the URI and other secondary key information, e.g. HTTP form post key/value
* pairs.
*
* The nsINetDataCacheRecord interface is agnostic as to where the data is
* stored and whether the storage is volatile or persistent. The memory cache,
* the disk cache, a flat-file cache and any read-only extension caches must
* all implement this interface.
*
* @See nsICachedNetData
* @See nsINetDataCache
* @See nsINetDataDiskCache
* @See nsINetDataCacheManager
*/
interface nsILoadGroup;
[scriptable, uuid(fdcdd6a0-7461-11d3-90ca-0040056a906e)]
interface nsINetDataCacheRecord : nsISupports
{
/**
* As far as the nsINetDataCacheRecord implementation is concerned, the
* cache entry database key is an opaque blob, but it's intended to contain
* both the URI and any secondary keys, such as HTTP post data.
*/
void getKey(out unsigned long length, [size_is(length), retval] out string key);
/**
* A persistent record number assigned by the cache which must be unique
* among all entries stored within the same cache. The record ID serves as
* an alternate key to the cache record. Providing that they satisfy the
* afforementioned uniqueness requirement, record IDs can be assigned any
* value by the database except that they may never be zero.
*/
readonly attribute PRInt32 recordID;
/**
* Opaque data which can be updated for each cache entry independently of
* the content data. This data is a combination of protocol-independent
* data provided by the cache manager and protocol-specific meta-data,
* e.g. HTTP headers.
*/
void getMetaData(out PRUint32 length, [size_is(length), retval] out string metaData);
void setMetaData(in PRUint32 length, [size_is(length)] in string data);
/**
* Number of content bytes stored in the cache, i.e. via the nsIChannel
* streaming APIs. This may be less than the complete content length if a
* partial cache fill occurred. Additionally, the cached content can be
* truncated by reducing the value of this attribute. When this attribute
* is set to zero the associated cache disk file, if any, should be
* deleted.
*/
attribute PRUint32 storedContentLength;
/**
* Opaque security info associated with the cache entry; it can't be serialized
* to disk, so it'll only make sense with memory cache
*/
attribute nsISupports securityInfo;
/**
* Delete this cache entry and its associated content.
*/
void delete();
/**
* Create a channel for reading or writing a stream of content into the
* entry. However, many of the nsIChannel methods may return
* NS_NOT_IMPLEMENTED, including:
*
* + GetURI()
* + GetContentType()
* + GetContentLength()
*/
nsIChannel newChannel(in nsILoadGroup loadGroup);
/**
* If a cache is implemented such that it stores each URI's content in an
* individual disk file, this method will identify the file corresponding
* to this record. This may be used to implement the "stream-as-file"
* semantics required by some plugins and by the 'jar:' protocol handler.
* However, not all cache implementations are *required* to store the data
* from each URI in an individual file, so it is acceptable for an
* implementation of this method to signal NS_NOT_IMPLEMENTED.
*/
readonly attribute nsIFile file;
};

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
@@ -20,7 +20,22 @@
* Contributor(s):
*/
/* Defining the following causes NS_APPSHELL to be defined as NS_EXPORT. */
#define _IMPL_NS_APPSHELL
#include "nsINetDataCache.idl"
interface nsIFile;
/**
* A network-data disk cache is used to persistently cache the responses to
* network retrieval commands. Each cache entry may contain both content,
* e.g. GIF image data, and associated metadata, e.g. HTTP headers.
*/
[scriptable, uuid(6408e390-6f13-11d3-90c8-000064657374)]
interface nsINetDataDiskCache : nsINetDataCache
{
/**
* This attribute must be set before calling any other methods of this
* interface.
*/
attribute nsIFile diskCacheFolder;
};
#include "MacSharedPrefix.h"

View File

@@ -0,0 +1,106 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Scott Furman, fur@netscape.com
*/
#include "nsrootidl.idl"
#include "nsISupports.idl"
interface nsIFile;
interface nsIStreamAsFileObserver;
/**
* In addition to enhancing effective network response time via caching, the
* cache manager serves a second purpose by providing the stream-as-file
* service required by traditional browser plugins and the jar: protocol
* handler. The interface below provides a means for a client to determine the
* filename associated with a stream and to detect modification/deletion of
* that file.
*/
[scriptable, uuid(0eedbbf0-92d9-11d3-90d3-0040056a906e)]
interface nsIStreamAsFile : nsISupports
{
/**
* Filename containing stream-as-file
*/
readonly attribute nsIFile file;
/**
* Add an observer for this cache record. When the cache wants to delete
* or truncate a record, so as to make space for another cache entry's
* content data, it will call <code>aObserver</code>'s Observe() method,
* passing the nsIStreamAsFile instance as the <code>aSubject</code>
* argument and an appropriate message. If the observer does not wish to
* inhibit deletion/truncation, it should Release() any references it has to the
* cache record.
*
* @See nsIStreamAsFileObserver
*/
void addObserver(in nsIStreamAsFileObserver aObserver);
/**
* Delete an observer that was added by the AddObserver() method.
*/
void removeObserver(in nsIStreamAsFileObserver aObserver);
};
/**
* This interface can be implemented by a client to receive notifications of
* either modification or deletion of a file created by the cache manager using
* the stream-as-file semantics.
*/
[scriptable, uuid(a26e27c0-92da-11d3-90d3-0040056a906e)]
interface nsIStreamAsFileObserver : nsISupports
{
/**
* Flag bits for argument to observeStreamAsFile() method.
*/
const long NOTIFY_AVAILABLE = 1 << 0; // Stream-as-file now available for reading
const long NOTIFY_ERROR = 1 << 1; // Error while loading stream / creating file
const long REQUEST_DELETION = 1 << 2; // Cache manager wishes to delete/truncate file
const long INVALIDATE = 1 << 3; // File is out-of-date
// Convenience value
const long MAKE_UNAVAILABLE = REQUEST_DELETION | INVALIDATE;
/**
* Receive either a notification or a request concerning a file that has
* been opened using stream-as-file. The aMessage and aError arguments
* have varying values depending on the nature of the notification.
* aMessage is set to NOTIFY_AVAILABLE when a complete stream has been read
* and stored on disk in a file. At that point, and no sooner, may the
* filename attribute of the associated nsIStreamAsFile be accessed via the
* associated nsIStreamAsFile interface. If the aMessage argument is
* NOTIFY_ERROR, the aError argument contains the relevant error code. If
* the aMessage argument is either REQUEST_DELETION or REQUEST_TRUNCATION,
* the callee should immediately Release() all references to the
* nsIStreamAsFile (and any references to its associated nsICachedNetData
* instances), unless it wishes to inhibit the requested file modification.
* If the aMessage argument is INVALIDATE, the cache manager is replacing
* the file with a more recent version. If a client wants to continue
* using the (now out-of-date) file, it must delete it when it has finished,
* as the cache manager will effectively relinquished ownership of the
* file.
*/
void observeStreamAsFile(in nsIStreamAsFile aStreamAsFile,
in PRUint32 aMessage,
in nsresult aError);
};

View File

@@ -13,42 +13,56 @@
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = appcomps
LIBRARY_NAME = bookmarks_s
REQUIRES = xpcom \
string \
rdf \
appshell \
widget \
necko \
nkcache \
uconv \
pref \
dom \
intl \
webshell \
windowwatcher \
unicharutil \
$(NULL)
MODULE = nkcache
LIBRARY_NAME = nkcache
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
REQUIRES = xpcom string necko pref
EXPORTS = \
nsCacheService.h \
$(NULL)
CPPSRCS = \
nsCache.cpp \
nsCacheEntry.cpp \
nsCacheEntryDescriptor.cpp \
nsCacheMetaData.cpp \
nsCacheModule.cpp \
nsCacheService.cpp \
nsCacheSession.cpp \
nsDiskCacheBinding.cpp \
nsDiskCacheBlockFile.cpp \
nsDiskCacheDevice.cpp \
nsDiskCacheEntry.cpp \
nsDiskCacheMap.cpp \
nsMemoryCacheDevice.cpp \
$(NULL)
include $(topsrcdir)/config/config.mk
EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS)
#EXTRA_LIBS = $(NSPR_LIBS)
CPPSRCS = nsBookmarksService.cpp
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1
#override NO_SHARED_LIB=1
#override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

69
mozilla/netwerk/cache/src/makefile.win vendored Executable file
View File

@@ -0,0 +1,69 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = nkcache
DLLNAME=nkcache
DLL=.\$(OBJDIR)\$(DLLNAME).dll
MAKE_OBJ_TYPE=DLL
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
EXPORTS = \
nsCacheService.h \
$(NULL)
CPP_OBJS = \
.\$(OBJDIR)\nsCache.obj \
.\$(OBJDIR)\nsCacheEntry.obj \
.\$(OBJDIR)\nsCacheEntryDescriptor.obj \
.\$(OBJDIR)\nsCacheMetaData.obj \
.\$(OBJDIR)\nsCacheModule.obj \
.\$(OBJDIR)\nsCacheService.obj \
.\$(OBJDIR)\nsCacheSession.obj \
.\$(OBJDIR)\nsDiskCacheBinding.obj \
.\$(OBJDIR)\nsDiskCacheBlockFile.obj \
.\$(OBJDIR)\nsDiskCacheDevice.obj \
.\$(OBJDIR)\nsDiskCacheEntry.obj \
.\$(OBJDIR)\nsDiskCacheMap.obj \
.\$(OBJDIR)\nsMemoryCacheDevice.obj \
$(NULL)
LLIBS = \
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(NULL)
include <$(DEPTH)/config/rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
clobber::
$(RM) $(DIST)\bin\components\$(DLLNAME).dll
$(RM) $(DIST)\lib\$(DLLNAME).lib

View File

@@ -0,0 +1,388 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsANSIFileStreams.cpp, released March 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Patrick C. Beard <beard@netscape.com>
*/
#include "nsANSIFileStreams.h"
NS_IMPL_ISUPPORTS2(nsANSIInputStream, nsIInputStream, nsISeekableStream);
nsANSIInputStream::nsANSIInputStream() : mFile(nsnull), mSize(0)
{
NS_INIT_ISUPPORTS();
}
nsANSIInputStream::~nsANSIInputStream()
{
Close();
}
nsresult nsANSIInputStream::Open(nsILocalFile* file)
{
nsresult rv;
rv = file->OpenANSIFileDesc("rb", &mFile);
if (NS_FAILED(rv)) return rv;
if (::fseek(mFile, 0, SEEK_END) != 0) return NS_ERROR_FAILURE;
mSize = ::ftell(mFile);
::fseek(mFile, 0, SEEK_SET);
rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
NS_IMETHODIMP nsANSIInputStream::Close()
{
if (mFile) {
::fclose(mFile);
mFile = nsnull;
return NS_OK;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIInputStream::Available(PRUint32 * result)
{
if (mFile) {
*result = (mSize - ::ftell(mFile));
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIInputStream::Read(char * buf, PRUint32 count, PRUint32 *result)
{
if (mFile) {
*result = ::fread(buf, 1, count, mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIInputStream::GetNonBlocking(PRBool *aNonBlocking)
{
*aNonBlocking = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsANSIInputStream::GetObserver(nsIInputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIInputStream::SetObserver(nsIInputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIInputStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mFile) {
::fseek(mFile, offset, whence);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIInputStream::Tell(PRUint32 * result)
{
if (mFile) {
*result = ::ftell(mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMPL_ISUPPORTS2(nsANSIOutputStream, nsIOutputStream, nsISeekableStream);
nsANSIOutputStream::nsANSIOutputStream() : mFile(nsnull)
{
NS_INIT_ISUPPORTS();
}
nsANSIOutputStream::~nsANSIOutputStream()
{
Close();
}
nsresult nsANSIOutputStream::Open(nsILocalFile* file)
{
nsresult rv = file->OpenANSIFileDesc("wb", &mFile);
return rv;
}
NS_IMETHODIMP nsANSIOutputStream::Close()
{
if (mFile) {
::fclose(mFile);
mFile = nsnull;
return NS_OK;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIOutputStream::Flush()
{
if (mFile) {
::fflush(mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIOutputStream::Write(const char *buffer, PRUint32 count, PRUint32 *result)
{
if (mFile) {
*result = ::fwrite(buffer, 1, count, mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIOutputStream::WriteFrom(nsIInputStream *input, PRUint32 count, PRUint32 *actualCount)
{
nsresult rv;
char buffer[BUFSIZ];
PRUint32 totalCount = count;
*actualCount = 0;
while (totalCount > 0) {
count = (totalCount < BUFSIZ ? totalCount : BUFSIZ);
rv = input->Read(buffer, count, &count);
if (NS_FAILED(rv)) break;
rv = Write(buffer, count, &count);
if (NS_FAILED(rv)) break;
totalCount -= count;
*actualCount += count;
}
return rv;
}
NS_IMETHODIMP nsANSIOutputStream::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIOutputStream::GetNonBlocking(PRBool *aNonBlocking)
{
*aNonBlocking = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsANSIOutputStream::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIOutputStream::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIOutputStream::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIOutputStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mFile) {
::fseek(mFile, offset, whence);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIOutputStream::Tell(PRUint32 * result)
{
if (mFile) {
*result = ::ftell(mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
///////
NS_IMPL_ISUPPORTS3(nsANSIFileStream, nsIInputStream, nsIOutputStream, nsISeekableStream);
nsANSIFileStream::nsANSIFileStream() : mFile(nsnull), mSize(0)
{
NS_INIT_ISUPPORTS();
}
nsANSIFileStream::~nsANSIFileStream()
{
Close();
}
NS_IMETHODIMP nsANSIFileStream::Open(nsILocalFile* file)
{
nsresult rv;
rv = file->OpenANSIFileDesc("rb+", &mFile);
if (NS_FAILED(rv)) {
rv = rv = file->OpenANSIFileDesc("wb+", &mFile);
if (NS_FAILED(rv)) return rv;
}
// compute size of file.
if (::fseek(mFile, 0, SEEK_END) != 0) return NS_ERROR_FAILURE;
mSize = ::ftell(mFile);
::fseek(mFile, 0, SEEK_SET);
rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
NS_IMETHODIMP nsANSIFileStream::Close()
{
if (mFile) {
::fclose(mFile);
mFile = nsnull;
return NS_OK;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIFileStream::Available(PRUint32 * result)
{
if (mFile) {
*result = (mSize - ::ftell(mFile));
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIFileStream::Read(char * buf, PRUint32 count, PRUint32 *result)
{
if (mFile) {
*result = ::fread(buf, 1, count, mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIFileStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIFileStream::GetNonBlocking(PRBool *aNonBlocking)
{
*aNonBlocking = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsANSIFileStream::GetObserver(nsIInputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIFileStream::SetObserver(nsIInputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIFileStream::Flush()
{
if (mFile) {
::fflush(mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIFileStream::Write(const char *buffer, PRUint32 count, PRUint32 *result)
{
if (mFile) {
*result = ::fwrite(buffer, 1, count, mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIFileStream::WriteFrom(nsIInputStream *input, PRUint32 count, PRUint32 *actualCount)
{
char buffer[BUFSIZ];
PRUint32 totalCount = count;
*actualCount = 0;
while (totalCount > 0) {
count = (totalCount < BUFSIZ ? totalCount : BUFSIZ);
nsresult rv = input->Read(buffer, count, &count);
if (NS_FAILED(rv)) return rv;
rv = Write(buffer, count, &count);
totalCount -= count;
*actualCount += count;
}
return NS_OK;
}
NS_IMETHODIMP nsANSIFileStream::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIFileStream::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIFileStream::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIFileStream::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsANSIFileStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mFile) {
::fseek(mFile, offset, whence);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}
NS_IMETHODIMP nsANSIFileStream::Tell(PRUint32 * result)
{
if (mFile) {
*result = ::ftell(mFile);
nsresult rv = (ferror(mFile) ? NS_ERROR_FAILURE : NS_OK);
return rv;
}
return NS_BASE_STREAM_CLOSED;
}

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsANSIFileStreams.h, released March 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Patrick C. Beard <beard@netscape.com>
*/
#ifndef _nsANSIFileStreams_h_
#define _nsANSIFileStreams_h_
#include <stdio.h>
#include "nsIFileStreams.h"
class nsANSIInputStream : public nsIInputStream, public nsISeekableStream {
FILE* mFile;
PRUint32 mSize;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSISEEKABLESTREAM
nsANSIInputStream();
virtual ~nsANSIInputStream();
nsresult Open(nsILocalFile* file);
};
class nsANSIOutputStream : public nsIOutputStream, public nsISeekableStream {
FILE* mFile;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSISEEKABLESTREAM
nsANSIOutputStream();
virtual ~nsANSIOutputStream();
nsresult Open(nsILocalFile* file);
};
class nsANSIFileStream : public nsIInputStream, public nsIOutputStream, public nsISeekableStream {
FILE* mFile;
PRUint32 mSize;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
// NS_DECL_NSIOUTPUTSTREAM
// XXX must only declare additional methods introduced by nsIOutputStream.
NS_IMETHOD Flush(void);
NS_IMETHOD Write(const char *buf, PRUint32 count, PRUint32 *_retval);
NS_IMETHOD WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval);
NS_IMETHOD WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval);
NS_IMETHOD SetNonBlocking(PRBool aNonBlocking);
NS_IMETHOD GetObserver(nsIOutputStreamObserver * *aObserver);
NS_IMETHOD SetObserver(nsIOutputStreamObserver * aObserver);
NS_DECL_NSISEEKABLESTREAM
NS_EXPORT nsANSIFileStream();
virtual ~nsANSIFileStream();
NS_IMETHOD Open(nsILocalFile* file);
};
#endif // _nsANSIFileStreams_h_

119
mozilla/netwerk/cache/src/nsCache.cpp vendored Normal file
View File

@@ -0,0 +1,119 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCache.cpp, released March 18, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsCache.h"
#include "nsReadableUtils.h"
/**
* Cache Service Utility Functions
*/
#if defined(PR_LOGGING)
PRLogModuleInfo * gCacheLog = nsnull;
void
CacheLogInit()
{
if (gCacheLog) return;
gCacheLog = PR_NewLogModule("cache");
NS_ASSERTION(gCacheLog, "\n### failed to allocate cache log.\n");
}
#endif
PRUint32
SecondsFromPRTime(PRTime prTime)
{
PRInt64 microSecondsPerSecond, intermediateResult;
PRUint32 seconds;
LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
LL_DIV(intermediateResult, prTime, microSecondsPerSecond);
LL_L2UI(seconds, intermediateResult);
return seconds;
}
PRTime
PRTimeFromSeconds(PRUint32 seconds)
{
PRInt64 microSecondsPerSecond, intermediateResult;
PRTime prTime;
LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
LL_UI2L(intermediateResult, seconds);
LL_MUL(prTime, intermediateResult, microSecondsPerSecond);
return prTime;
}
nsresult
ClientIDFromCacheKey(const nsAReadableCString& key, char ** result)
{
nsresult rv = NS_OK;
*result = nsnull;
nsReadingIterator<char> colon;
key.BeginReading(colon);
nsReadingIterator<char> start;
key.BeginReading(start);
nsReadingIterator<char> end;
key.EndReading(end);
if (FindCharInReadable(':', colon, end)) {
*result = ToNewCString( Substring(start, colon));
if (!*result) rv = NS_ERROR_OUT_OF_MEMORY;
} else {
NS_ASSERTION(PR_FALSE, "FindCharInRead failed to find ':'");
rv = NS_ERROR_UNEXPECTED;
}
return rv;
}
nsresult
ClientKeyFromCacheKey(const nsAReadableCString& key, char ** result)
{
nsresult rv = NS_OK;
*result = nsnull;
nsReadingIterator<char> start;
key.BeginReading(start);
nsReadingIterator<char> end;
key.EndReading(end);
if (FindCharInReadable(':', start, end)) {
++start; // advance past clientID ':' delimiter
*result = ToNewCString( Substring(start, end));
if (!*result) rv = NS_ERROR_OUT_OF_MEMORY;
} else {
NS_ASSERTION(PR_FALSE, "FindCharInRead failed to find ':'");
rv = NS_ERROR_UNEXPECTED;
}
return rv;
}

63
mozilla/netwerk/cache/src/nsCache.h vendored Normal file
View File

@@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCache.h, released March 18, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
/**
* Cache Service Utility Functions
*/
#ifndef _nsCache_h_
#define _nsCache_h_
#include "nsAReadableString.h"
#include "prtime.h"
#include "nsError.h"
#include "prlog.h"
// PR_LOG args = "format string", arg, arg, ...
#if defined(PR_LOGGING)
extern PRLogModuleInfo * gCacheLog;
void CacheLogInit();
#define CACHE_LOG_INIT() CacheLogInit()
#define CACHE_LOG_ALWAYS(args) PR_LOG(gCacheLog, PR_LOG_ALWAYS, args)
#define CACHE_LOG_ERROR(args) PR_LOG(gCacheLog, PR_LOG_ERROR, args)
#define CACHE_LOG_WARNING(args) PR_LOG(gCacheLog, PR_LOG_WARNING, args)
#define CACHE_LOG_DEBUG(args) PR_LOG(gCacheLog, PR_LOG_DEBUG, args)
#else
#define CACHE_LOG_INIT() {}
#define CACHE_LOG_ALWAYS(args) {}
#define CACHE_LOG_ERROR(args) {}
#define CACHE_LOG_WARNING(args) {}
#define CACHE_LOG_DEBUG(args) {}
#endif
extern PRUint32 SecondsFromPRTime(PRTime prTime);
extern PRTime PRTimeFromSeconds(PRUint32 seconds);
extern nsresult ClientIDFromCacheKey(const nsAReadableCString& key, char ** result);
extern nsresult ClientKeyFromCacheKey(const nsAReadableCString& key, char ** result);
#endif // _nsCache_h

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheDevice.h, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#ifndef _nsCacheDevice_h_
#define _nsCacheDevice_h_
#include "nspr.h"
#include "nsError.h"
#include "nsICache.h"
class nsIFile;
class nsCString;
class nsCacheEntry;
class nsICacheVisitor;
class nsITransport;
/******************************************************************************
* nsCacheDevice
*******************************************************************************/
class nsCacheDevice {
public:
virtual ~nsCacheDevice() {}
virtual nsresult Init() = 0;
virtual nsresult Shutdown() = 0;
virtual const char * GetDeviceID(void) = 0;
virtual nsCacheEntry * FindEntry( nsCString * key ) = 0;
virtual nsresult DeactivateEntry( nsCacheEntry * entry ) = 0;
virtual nsresult BindEntry( nsCacheEntry * entry ) = 0;
virtual void DoomEntry( nsCacheEntry * entry ) = 0;
virtual nsresult GetTransportForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport **result ) = 0;
virtual nsresult GetFileForEntry( nsCacheEntry * entry,
nsIFile ** result ) = 0;
virtual nsresult OnDataSizeChange( nsCacheEntry * entry, PRInt32 deltaSize ) = 0;
virtual nsresult Visit(nsICacheVisitor * visitor) = 0;
/**
* Device must evict entries associated with clientID. If clientID == nsnull, all
* entries must be evicted. Active entries must be doomed, rather than evicted.
*/
virtual nsresult EvictEntries(const char * clientID) = 0;
};
#endif // _nsCacheDevice_h_

View File

@@ -0,0 +1,663 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheEntry.cpp, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#include "nspr.h"
#include "nsCacheEntry.h"
#include "nsCacheEntryDescriptor.h"
#include "nsCacheMetaData.h"
#include "nsCacheRequest.h"
#include "nsError.h"
#include "nsICacheService.h"
#include "nsCache.h"
#include "nsCacheDevice.h"
nsCacheEntry::nsCacheEntry(nsCString * key,
PRBool streamBased,
nsCacheStoragePolicy storagePolicy)
: mKey(key),
mFetchCount(0),
mLastFetched(0),
mExpirationTime(0),
mFlags(0),
mDataSize(0),
mMetaSize(0),
mCacheDevice(nsnull),
mData(nsnull),
mMetaData(nsnull)
{
PR_INIT_CLIST(this);
PR_INIT_CLIST(&mRequestQ);
PR_INIT_CLIST(&mDescriptorQ);
if (streamBased) MarkStreamBased();
SetStoragePolicy(storagePolicy);
}
static void* PR_CALLBACK
CacheElementReleaseEventHandler(PLEvent *self)
{
nsISupports * element = (nsISupports *)PL_GetEventOwner(self);
NS_RELEASE(element);
return 0;
}
static void PR_CALLBACK
CacheElementReleaseDestroyHandler(PLEvent *self)
{
delete self;
}
nsCacheEntry::~nsCacheEntry()
{
delete mKey;
delete mMetaData;
if (IsStreamData()) return;
// proxy release of of memory cache nsISupports objects
if (!mData) {
NS_ASSERTION(!mEventQ, "### ~nsCacheEntry: mEventQ but no mData");
return;
}
if (!mEventQ) {
NS_ASSERTION(!mData, "### ~nsCacheEntry: mData, but no eventQ");
return;
}
PLEvent * event = new PLEvent;
if (!event) {
// XXX warning
return;
}
nsISupports * data = mData;
NS_ADDREF(data); // this reference will be owned by the event
mData = nsnull; // release our reference before switching threads
PL_InitEvent(event,
data,
CacheElementReleaseEventHandler,
CacheElementReleaseDestroyHandler);
mEventQ->PostEvent(event);
}
nsresult
nsCacheEntry::Create( const char * key,
PRBool streamBased,
nsCacheStoragePolicy storagePolicy,
nsCacheDevice * device,
nsCacheEntry ** result)
{
nsCString* newKey = new nsCString(key);
if (!newKey) return NS_ERROR_OUT_OF_MEMORY;
nsCacheEntry* entry = new nsCacheEntry(newKey, streamBased, storagePolicy);
if (!entry) { delete newKey; return NS_ERROR_OUT_OF_MEMORY; }
entry->SetCacheDevice(device);
*result = entry;
return NS_OK;
}
void
nsCacheEntry::Fetched()
{
mLastFetched = SecondsFromPRTime(PR_Now());
++mFetchCount;
MarkEntryDirty();
}
const char *
nsCacheEntry::GetDeviceID()
{
if (mCacheDevice) return mCacheDevice->GetDeviceID();
return nsnull;
}
nsresult
nsCacheEntry::GetData(nsISupports **result)
{
NS_ENSURE_ARG_POINTER(result);
NS_IF_ADDREF(*result = mData);
return NS_OK;
}
void
nsCacheEntry::TouchData()
{
mLastModified = SecondsFromPRTime(PR_Now());
MarkDataDirty();
}
nsresult
nsCacheEntry::GetMetaDataElement( const nsAReadableCString& key,
nsAReadableCString ** value)
{
*value = mMetaData ? mMetaData->GetElement(&key) : nsnull;
return NS_OK;
}
nsresult
nsCacheEntry::SetMetaDataElement( const nsAReadableCString& key,
const nsAReadableCString& value)
{
if (!mMetaData) {
mMetaData = nsCacheMetaData::Create();
if (!mMetaData)
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv = mMetaData->SetElement(key, value);
if (NS_FAILED(rv))
return rv;
mMetaSize = mMetaData->Size(); // calc new meta data size
return rv;
}
nsresult
nsCacheEntry::VisitMetaDataElements( nsICacheMetaDataVisitor * visitor)
{
NS_ENSURE_ARG_POINTER(visitor);
if (mMetaData)
mMetaData->VisitElements(visitor);
return NS_OK;
}
nsresult
nsCacheEntry::FlattenMetaData(char ** data, PRUint32 * size)
{
NS_ENSURE_ARG_POINTER(size);
if (mMetaData)
return mMetaData->FlattenMetaData(data, size);
if (data) *data = nsnull;
*size = 0;
return NS_OK;
}
nsresult
nsCacheEntry::UnflattenMetaData(char * data, PRUint32 size)
{
delete mMetaData;
mMetaData = nsCacheMetaData::Create();
if (!mMetaData)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = mMetaData->UnflattenMetaData(data, size);
if (NS_SUCCEEDED(rv))
mMetaSize = mMetaData->Size();
return rv;
}
void
nsCacheEntry::TouchMetaData()
{
mLastModified = SecondsFromPRTime(PR_Now());
MarkMetaDataDirty();
}
#if 0
nsresult
nsCacheEntry::GetKeyValueArray(nsCacheMetaDataKeyValuePair ** array,
PRUint32 * count)
{
if (!array || !count) return NS_ERROR_NULL_POINTER;
if (!mMetaData) {
*array = nsnull;
*count = 0;
return NS_OK;
}
return mMetaData->GetKeyValueArray(array, count);
}
#endif
nsresult
nsCacheEntry::GetSecurityInfo( nsISupports ** result)
{
NS_ENSURE_ARG_POINTER(result);
NS_IF_ADDREF(*result = mSecurityInfo);
return NS_OK;
}
/**
* cache entry states
* 0 descriptors (new entry)
* 0 descriptors (existing, bound entry)
* n descriptors (existing, bound entry) valid
* n descriptors (existing, bound entry) not valid (wait until valid or doomed)
*/
nsresult
nsCacheEntry::RequestAccess(nsCacheRequest * request, nsCacheAccessMode *accessGranted)
{
nsresult rv = NS_OK;
if (!IsInitialized()) {
// brand new, unbound entry
request->mKey = nsnull; // steal ownership of the key string
if (request->IsStreamBased()) MarkStreamBased();
MarkInitialized();
*accessGranted = request->AccessRequested() & nsICache::ACCESS_WRITE;
NS_ASSERTION(*accessGranted, "new cache entry for READ-ONLY request");
PR_APPEND_LINK(request, &mRequestQ);
return rv;
}
if (IsDoomed()) return NS_ERROR_CACHE_ENTRY_DOOMED;
if (IsStreamData() != request->IsStreamBased()) {
*accessGranted = nsICache::ACCESS_NONE;
return request->IsStreamBased() ?
NS_ERROR_CACHE_DATA_IS_NOT_STREAM : NS_ERROR_CACHE_DATA_IS_STREAM;
}
if (PR_CLIST_IS_EMPTY(&mDescriptorQ)) {
// 1st descriptor for existing bound entry
*accessGranted = request->AccessRequested();
if (*accessGranted & nsICache::ACCESS_WRITE) {
MarkInvalid();
} else {
MarkValid();
}
} else {
// nth request for existing, bound entry
*accessGranted = request->AccessRequested() & ~nsICache::ACCESS_WRITE;
if (!IsValid())
rv = NS_ERROR_CACHE_WAIT_FOR_VALIDATION;
}
PR_APPEND_LINK(request,&mRequestQ);
return rv;
}
nsresult
nsCacheEntry::CreateDescriptor(nsCacheRequest * request,
nsCacheAccessMode accessGranted,
nsICacheEntryDescriptor ** result)
{
NS_ENSURE_ARG_POINTER(request && result);
nsCacheEntryDescriptor * descriptor =
new nsCacheEntryDescriptor(this, accessGranted);
// XXX check request is on q
PR_REMOVE_AND_INIT_LINK(request); // remove request regardless of success
if (descriptor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
PR_APPEND_LINK(descriptor, &mDescriptorQ);
NS_ADDREF(*result = descriptor);
return NS_OK;
}
PRBool
nsCacheEntry::RemoveRequest(nsCacheRequest * request)
{
// XXX if debug: verify this request belongs to this entry
PR_REMOVE_AND_INIT_LINK(request);
// return true if this entry should stay active
return !((PR_CLIST_IS_EMPTY(&mRequestQ)) &&
(PR_CLIST_IS_EMPTY(&mDescriptorQ)));
}
PRBool
nsCacheEntry::RemoveDescriptor(nsCacheEntryDescriptor * descriptor)
{
// XXX if debug: verify this descriptor belongs to this entry
PR_REMOVE_AND_INIT_LINK(descriptor);
if (!PR_CLIST_IS_EMPTY(&mDescriptorQ))
return PR_TRUE; // stay active if we still have open descriptors
if (PR_CLIST_IS_EMPTY(&mRequestQ))
return PR_FALSE; // no descriptors or requests, we can deactivate
return PR_TRUE; // find next best request to give a descriptor to
}
void
nsCacheEntry::DetachDescriptors(void)
{
nsCacheEntryDescriptor * descriptor =
(nsCacheEntryDescriptor *)PR_LIST_HEAD(&mDescriptorQ);
while (descriptor != &mDescriptorQ) {
nsCacheEntryDescriptor * nextDescriptor =
(nsCacheEntryDescriptor *)PR_NEXT_LINK(descriptor);
descriptor->ClearCacheEntry();
PR_REMOVE_AND_INIT_LINK(descriptor);
descriptor = nextDescriptor;
}
}
/******************************************************************************
* nsCacheEntryInfo - for implementing about:cache
*****************************************************************************/
NS_IMPL_ISUPPORTS1(nsCacheEntryInfo, nsICacheEntryInfo);
NS_IMETHODIMP
nsCacheEntryInfo::GetClientID(char ** clientID)
{
NS_ENSURE_ARG_POINTER(clientID);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return ClientIDFromCacheKey(*mCacheEntry->Key(), clientID);
}
NS_IMETHODIMP
nsCacheEntryInfo::GetDeviceID(char ** deviceID)
{
NS_ENSURE_ARG_POINTER(deviceID);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*deviceID = nsCRT::strdup(mCacheEntry->GetDeviceID());
return *deviceID ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsCacheEntryInfo::GetKey(char ** key)
{
NS_ENSURE_ARG_POINTER(key);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return ClientKeyFromCacheKey(*mCacheEntry->Key(), key);
}
NS_IMETHODIMP
nsCacheEntryInfo::GetFetchCount(PRInt32 * fetchCount)
{
NS_ENSURE_ARG_POINTER(fetchCount);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*fetchCount = mCacheEntry->FetchCount();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryInfo::GetLastFetched(PRUint32 * lastFetched)
{
NS_ENSURE_ARG_POINTER(lastFetched);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*lastFetched = mCacheEntry->LastFetched();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryInfo::GetLastModified(PRUint32 * lastModified)
{
NS_ENSURE_ARG_POINTER(lastModified);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*lastModified = mCacheEntry->LastModified();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryInfo::GetExpirationTime(PRUint32 * expirationTime)
{
NS_ENSURE_ARG_POINTER(expirationTime);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*expirationTime = mCacheEntry->ExpirationTime();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryInfo::GetDataSize(PRUint32 * dataSize)
{
NS_ENSURE_ARG_POINTER(dataSize);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*dataSize = mCacheEntry->DataSize();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryInfo::IsStreamBased(PRBool * result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->IsStreamData();
return NS_OK;
}
/******************************************************************************
* nsCacheEntryHashTable
*****************************************************************************/
PLDHashTableOps
nsCacheEntryHashTable::ops =
{
PL_DHashAllocTable,
PL_DHashFreeTable,
GetKey,
HashKey,
MatchEntry,
MoveEntry,
ClearEntry,
PL_DHashFinalizeStub
};
nsCacheEntryHashTable::nsCacheEntryHashTable()
: initialized(PR_FALSE)
{
}
nsCacheEntryHashTable::~nsCacheEntryHashTable()
{
if (initialized)
Shutdown();
}
nsresult
nsCacheEntryHashTable::Init()
{
nsresult rv = NS_OK;
initialized = PL_DHashTableInit(&table, &ops, nsnull,
sizeof(nsCacheEntryHashTableEntry), 512);
if (!initialized) rv = NS_ERROR_OUT_OF_MEMORY;
return rv;
}
void
nsCacheEntryHashTable::Shutdown()
{
if (initialized) {
PL_DHashTableFinish(&table);
initialized = PR_FALSE;
}
}
nsCacheEntry *
nsCacheEntryHashTable::GetEntry( const nsCString * key)
{
PLDHashEntryHdr *hashEntry;
nsCacheEntry *result = nsnull;
NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized");
if (!initialized) return nsnull;
hashEntry = PL_DHashTableOperate(&table, key, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_BUSY(hashEntry)) {
result = ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry;
}
return result;
}
nsresult
nsCacheEntryHashTable::AddEntry( nsCacheEntry *cacheEntry)
{
PLDHashEntryHdr *hashEntry;
NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized");
if (!initialized) return NS_ERROR_NOT_INITIALIZED;
if (!cacheEntry) return NS_ERROR_NULL_POINTER;
hashEntry = PL_DHashTableOperate(&table, cacheEntry->mKey, PL_DHASH_ADD);
#ifndef DEBUG_dougt
NS_ASSERTION(((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry == 0,
"### nsCacheEntryHashTable::AddEntry - entry already used");
#endif
((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry = cacheEntry;
return NS_OK;
}
void
nsCacheEntryHashTable::RemoveEntry( nsCacheEntry *cacheEntry)
{
NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized");
NS_ASSERTION(cacheEntry, "### cacheEntry == nsnull");
if (!initialized) return; // NS_ERROR_NOT_INITIALIZED
#if DEBUG
// XXX debug code to make sure we have the entry we're trying to remove
nsCacheEntry *check = GetEntry(cacheEntry->mKey);
NS_ASSERTION(check == cacheEntry, "### Attempting to remove unknown cache entry!!!");
#endif
(void) PL_DHashTableOperate(&table, cacheEntry->mKey, PL_DHASH_REMOVE);
}
void
nsCacheEntryHashTable::VisitEntries( nsCacheEntryHashTable::Visitor *visitor)
{
NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized");
if (!initialized) return; // NS_ERROR_NOT_INITIALIZED
PL_DHashTableEnumerate(&table, VisitEntry, visitor);
}
PLDHashOperator PR_CALLBACK
nsCacheEntryHashTable::VisitEntry(PLDHashTable *table,
PLDHashEntryHdr *hashEntry,
PRUint32 number,
void *arg)
{
nsCacheEntry *cacheEntry = ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry;
nsCacheEntryHashTable::Visitor *visitor = (nsCacheEntryHashTable::Visitor*) arg;
return (visitor->VisitEntry(cacheEntry) ? PL_DHASH_NEXT : PL_DHASH_STOP);
}
/**
* hash table operation callback functions
*/
const void * PR_CALLBACK
nsCacheEntryHashTable::GetKey( PLDHashTable * /*table*/, PLDHashEntryHdr *hashEntry)
{
nsCacheEntry *cacheEntry = ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry;
return cacheEntry->mKey;
}
PLDHashNumber PR_CALLBACK
nsCacheEntryHashTable::HashKey( PLDHashTable *table, const void *key)
{
return PL_DHashStringKey(table,((nsCString *)key)->get());
}
PRBool PR_CALLBACK
nsCacheEntryHashTable::MatchEntry(PLDHashTable * /* table */,
const PLDHashEntryHdr * hashEntry,
const void * key)
{
NS_ASSERTION(key != nsnull, "### nsCacheEntryHashTable::MatchEntry : null key");
nsCacheEntry *cacheEntry = ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry;
return nsStr::StrCompare(*cacheEntry->mKey, *(nsCString *)key, -1, PR_FALSE) == 0;
}
void PR_CALLBACK
nsCacheEntryHashTable::MoveEntry(PLDHashTable * /* table */,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to)
{
((nsCacheEntryHashTableEntry *)to)->cacheEntry =
((nsCacheEntryHashTableEntry *)from)->cacheEntry;
}
void PR_CALLBACK
nsCacheEntryHashTable::ClearEntry(PLDHashTable * /* table */,
PLDHashEntryHdr * hashEntry)
{
((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry = 0;
}

330
mozilla/netwerk/cache/src/nsCacheEntry.h vendored Normal file
View File

@@ -0,0 +1,330 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheEntry.h, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#ifndef _nsCacheEntry_h_
#define _nsCacheEntry_h_
#include "nsICache.h"
#include "nsICacheEntryDescriptor.h"
#include "nsCacheMetaData.h"
#include "nspr.h"
#include "pldhash.h"
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsAReadableString.h"
#include "nsIEventQueue.h"
class nsCacheDevice;
class nsCacheMetaData;
class nsCacheRequest;
class nsCacheEntryDescriptor;
/******************************************************************************
* nsCacheEntry
*******************************************************************************/
class nsCacheEntry : public PRCList
{
public:
nsCacheEntry(nsCString * key,
PRBool streamBased,
nsCacheStoragePolicy storagePolicy);
~nsCacheEntry();
static nsresult Create( const char * key,
PRBool streamBased,
nsCacheStoragePolicy storagePolicy,
nsCacheDevice * device,
nsCacheEntry ** result);
nsCString * Key() { return mKey; }
PRInt32 FetchCount() { return mFetchCount;}
void SetFetchCount( PRInt32 count) { mFetchCount = count;}
void Fetched();
PRUint32 LastFetched() { return mLastFetched;}
void SetLastFetched( PRUint32 lastFetched) { mLastFetched = lastFetched;}
PRUint32 LastModified() { return mLastModified;}
void SetLastModified( PRUint32 lastModified) { mLastModified = lastModified;}
PRUint32 ExpirationTime() { return mExpirationTime;}
void SetExpirationTime( PRUint32 expires) { mExpirationTime = expires;}
PRUint32 Size() { return mDataSize + mMetaSize; }
nsCacheDevice * CacheDevice() { return mCacheDevice;}
void SetCacheDevice( nsCacheDevice * device) { mCacheDevice = device;}
const char * GetDeviceID();
/**
* Data accessors
*/
nsresult GetData( nsISupports ** result);
void SetData( nsISupports * data) { mData = data;}
PRUint32 DataSize() { return mDataSize;}
void SetDataSize( PRUint32 size) { mDataSize = size;}
void TouchData();
nsIEventQueue * GetEventQ() { return mEventQ;}
void SetEventQ(nsIEventQueue * eventQ) { mEventQ = dont_AddRef(eventQ);}
/**
* Meta data accessors
*/
nsresult GetMetaDataElement( const nsAReadableCString& key,
nsAReadableCString ** value);
nsresult SetMetaDataElement( const nsAReadableCString& key,
const nsAReadableCString& value);
nsresult VisitMetaDataElements( nsICacheMetaDataVisitor * visitor);
nsresult FlattenMetaData( char ** data, PRUint32 * size);
nsresult UnflattenMetaData( char * data, PRUint32 size);
PRUint32 MetaDataSize() { return mMetaSize;}
void TouchMetaData();
/**
* Security Info accessors
*/
nsresult GetSecurityInfo( nsISupports ** result);
void SetSecurityInfo( nsISupports * info) { mSecurityInfo = info; }
// XXX enumerate MetaData method
enum CacheEntryFlags {
eStoragePolicyMask = 0x000000FF,
eDoomedMask = 0x00000100,
eEntryDirtyMask = 0x00000200,
eDataDirtyMask = 0x00000400,
eMetaDataDirtyMask = 0x00000800,
eStreamDataMask = 0x00001000,
eActiveMask = 0x00002000,
eInitializedMask = 0x00004000,
eValidMask = 0x00008000,
eBindingMask = 0x00010000
};
void MarkBinding() { mFlags |= eBindingMask; }
void ClearBinding() { mFlags &= ~eBindingMask; }
PRBool IsBinding() { return (mFlags & eBindingMask) != 0; }
void MarkEntryDirty() { mFlags |= eEntryDirtyMask; }
void MarkEntryClean() { mFlags &= ~eEntryDirtyMask; }
void MarkDataDirty() { mFlags |= eDataDirtyMask; }
void MarkDataClean() { mFlags &= ~eDataDirtyMask; }
void MarkMetaDataDirty() { mFlags |= eMetaDataDirtyMask; }
void MarkMetaDataClean() { mFlags &= ~eMetaDataDirtyMask; }
void MarkStreamData() { mFlags |= eStreamDataMask; }
void MarkValid() { mFlags |= eValidMask; }
void MarkInvalid() { mFlags &= ~eValidMask; }
// void MarkAllowedInMemory() { mFlags |= eAllowedInMemoryMask; }
// void MarkAllowedOnDisk() { mFlags |= eAllowedOnDiskMask; }
PRBool IsDoomed() { return (mFlags & eDoomedMask) != 0; }
PRBool IsEntryDirty() { return (mFlags & eEntryDirtyMask) != 0; }
PRBool IsDataDirty() { return (mFlags & eDataDirtyMask) != 0; }
PRBool IsMetaDataDirty() { return (mFlags & eMetaDataDirtyMask) != 0; }
PRBool IsStreamData() { return (mFlags & eStreamDataMask) != 0; }
PRBool IsActive() { return (mFlags & eActiveMask) != 0; }
PRBool IsInitialized() { return (mFlags & eInitializedMask) != 0; }
PRBool IsValid() { return (mFlags & eValidMask) != 0; }
PRBool IsInvalid() { return (mFlags & eValidMask) == 0; }
PRBool IsInUse() { return !(PR_CLIST_IS_EMPTY(&mRequestQ) &&
PR_CLIST_IS_EMPTY(&mDescriptorQ)); }
PRBool IsNotInUse() { return (PR_CLIST_IS_EMPTY(&mRequestQ) &&
PR_CLIST_IS_EMPTY(&mDescriptorQ)); }
PRBool IsAllowedInMemory()
{
return (StoragePolicy() == nsICache::STORE_ANYWHERE) ||
(StoragePolicy() == nsICache::STORE_IN_MEMORY);
}
PRBool IsAllowedOnDisk()
{
return (StoragePolicy() == nsICache::STORE_ANYWHERE) ||
(StoragePolicy() == nsICache::STORE_ON_DISK) ||
(StoragePolicy() == nsICache::STORE_ON_DISK_AS_FILE);
}
nsCacheStoragePolicy StoragePolicy()
{
return (nsCacheStoragePolicy)(mFlags & eStoragePolicyMask);
}
void SetStoragePolicy(nsCacheStoragePolicy policy)
{
NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy");
mFlags &= ~eStoragePolicyMask; // clear storage policy bits
mFlags |= policy;
}
// methods for nsCacheService
nsresult RequestAccess( nsCacheRequest * request, nsCacheAccessMode *accessGranted);
nsresult CreateDescriptor( nsCacheRequest * request,
nsCacheAccessMode accessGranted,
nsICacheEntryDescriptor ** result);
// nsresult Open(nsCacheRequest *request, nsICacheEntryDescriptor ** result);
// nsresult AsyncOpen(nsCacheRequest *request);
PRBool RemoveRequest( nsCacheRequest * request);
PRBool RemoveDescriptor( nsCacheEntryDescriptor * descriptor);
private:
friend class nsCacheEntryHashTable;
friend class nsCacheService;
void DetachDescriptors(void);
// internal methods
void MarkDoomed() { mFlags |= eDoomedMask; }
void MarkStreamBased() { mFlags |= eStreamDataMask; }
void MarkInitialized() { mFlags |= eInitializedMask; }
void MarkActive() { mFlags |= eActiveMask; }
void MarkInactive() { mFlags &= ~eActiveMask; }
nsCString * mKey; // 4 // XXX ask scc about const'ness
PRUint32 mFetchCount; // 4
PRUint32 mLastFetched; // 4
PRUint32 mLastModified; // 4
PRUint32 mLastValidated; // 4
PRUint32 mExpirationTime; // 4
PRUint32 mFlags; // 4
PRUint32 mDataSize; // 4
PRUint32 mMetaSize; // 4
nsCacheDevice * mCacheDevice; // 4
nsCOMPtr<nsISupports> mSecurityInfo; //
nsCOMPtr<nsISupports> mData; //
nsCOMPtr<nsIEventQueue> mEventQ; // event queue for mData (for mem object cache)
nsCacheMetaData * mMetaData; // 4
PRCList mRequestQ; // 8
PRCList mDescriptorQ; // 8
};
/******************************************************************************
* nsCacheEntryInfo
*******************************************************************************/
class nsCacheEntryInfo : public nsICacheEntryInfo {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICACHEENTRYINFO
nsCacheEntryInfo(nsCacheEntry* entry)
: mCacheEntry(entry)
{
NS_INIT_ISUPPORTS();
}
virtual ~nsCacheEntryInfo() {}
void DetachEntry() { mCacheEntry = nsnull; }
private:
nsCacheEntry * mCacheEntry;
};
/******************************************************************************
* nsCacheEntryHashTable
*******************************************************************************/
typedef struct {
PLDHashNumber keyHash;
nsCacheEntry *cacheEntry;
} nsCacheEntryHashTableEntry;
class nsCacheEntryHashTable
{
public:
nsCacheEntryHashTable();
~nsCacheEntryHashTable();
nsresult Init();
void Shutdown();
nsCacheEntry *GetEntry( const nsCString * key);
nsresult AddEntry( nsCacheEntry *entry);
void RemoveEntry( nsCacheEntry *entry);
// XXX enumerate entries?
class Visitor {
public:
virtual PRBool VisitEntry( nsCacheEntry *entry) = 0;
};
void VisitEntries( Visitor *visitor);
private:
friend class nsCacheService; // XXX redefine interface so this isn't necessary
// PLDHashTable operation callbacks
static const void * PR_CALLBACK GetKey( PLDHashTable *table, PLDHashEntryHdr *entry);
static PLDHashNumber PR_CALLBACK HashKey( PLDHashTable *table, const void *key);
static PRBool PR_CALLBACK MatchEntry( PLDHashTable * table,
const PLDHashEntryHdr * entry,
const void * key);
static void PR_CALLBACK MoveEntry( PLDHashTable *table,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to);
static void PR_CALLBACK ClearEntry( PLDHashTable *table, PLDHashEntryHdr *entry);
static void PR_CALLBACK Finalize( PLDHashTable *table);
static
PLDHashOperator PR_CALLBACK FreeCacheEntries(PLDHashTable * table,
PLDHashEntryHdr * hdr,
PRUint32 number,
void * arg);
static
PLDHashOperator PR_CALLBACK VisitEntry(PLDHashTable * table,
PLDHashEntryHdr * hdr,
PRUint32 number,
void * arg);
// member variables
static PLDHashTableOps ops;
PLDHashTable table;
PRBool initialized;
};
#endif // _nsCacheEntry_h_

View File

@@ -0,0 +1,647 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheEntryDescriptor.cpp, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#include "nsICache.h"
#include "nsCache.h"
#include "nsCacheService.h"
#include "nsCacheEntryDescriptor.h"
#include "nsCacheEntry.h"
#include "nsReadableUtils.h"
#include "nsIOutputStream.h"
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor, nsICacheEntryDescriptor)
nsCacheEntryDescriptor::nsCacheEntryDescriptor(nsCacheEntry * entry,
nsCacheAccessMode accessGranted)
: mCacheEntry(entry),
mAccessGranted(accessGranted)
{
NS_INIT_ISUPPORTS();
PR_INIT_CLIST(this);
}
nsCacheEntryDescriptor::~nsCacheEntryDescriptor()
{
if (mCacheEntry)
Close();
}
nsresult
nsCacheEntryDescriptor::Create(nsCacheEntry * entry, nsCacheAccessMode accessGranted,
nsICacheEntryDescriptor ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsresult rv = nsnull;
nsCacheEntryDescriptor * descriptor =
new nsCacheEntryDescriptor(entry, accessGranted);
if (descriptor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(descriptor);
rv = descriptor->QueryInterface(NS_GET_IID(nsICacheEntryDescriptor), (void**)result);
NS_RELEASE(descriptor);
return rv;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetClientID(char ** result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return ClientIDFromCacheKey(*(mCacheEntry->Key()), result);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetDeviceID(char ** result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = nsCRT::strdup(mCacheEntry->GetDeviceID());
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetKey(char ** result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return ClientKeyFromCacheKey(*(mCacheEntry->Key()), result);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetFetchCount(PRInt32 *result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->FetchCount();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetLastFetched(PRUint32 *result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->LastFetched();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetLastModified(PRUint32 *result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->LastModified();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetExpirationTime(PRUint32 *result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->ExpirationTime();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::SetExpirationTime(PRUint32 expirationTime)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
mCacheEntry->SetExpirationTime(expirationTime);
mCacheEntry->MarkEntryDirty();
return NS_OK;
}
NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(PRBool *result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->IsStreamData(); // XXX which name is better?
return NS_OK;
}
NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->DataSize();
return NS_OK;
}
nsresult
nsCacheEntryDescriptor::RequestDataSizeChange(PRInt32 deltaSize)
{
nsresult rv;
rv = nsCacheService::GlobalInstance()->OnDataSizeChange(mCacheEntry, deltaSize);
if (NS_SUCCEEDED(rv)) {
// XXX review for signed/unsigned math errors
PRUint32 newDataSize = mCacheEntry->DataSize() + deltaSize;
mCacheEntry->SetDataSize(newDataSize);
mCacheEntry->TouchData();
}
return rv;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::SetDataSize(PRUint32 dataSize)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
// XXX review for signed/unsigned math errors
PRInt32 deltaSize = dataSize - mCacheEntry->DataSize();
// this had better be NS_OK, this call instance is advisory
nsresult rv = RequestDataSizeChange(deltaSize);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed SetDataSize() on memory cache object!");
return rv;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetTransport(nsITransport ** result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;
NS_ADDREF(*result = &mTransportWrapper);
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
return mCacheEntry->GetData(result);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::SetCacheElement(nsISupports * cacheElement)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
mCacheEntry->SetData(cacheElement);
mCacheEntry->TouchData();
return nsCacheService::GlobalInstance()->SetCacheElement(mCacheEntry, cacheElement);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetAccessGranted(nsCacheAccessMode *result)
{
NS_ENSURE_ARG_POINTER(result);
*result = mAccessGranted;
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return mCacheEntry->StoragePolicy();
}
NS_IMETHODIMP
nsCacheEntryDescriptor::SetStoragePolicy(nsCacheStoragePolicy policy)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
// XXX validate policy against session?
mCacheEntry->SetStoragePolicy(policy);
mCacheEntry->MarkEntryDirty();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetFile(nsIFile ** result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return nsCacheService::GlobalInstance()->GetFileForEntry(mCacheEntry, result);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result)
{
NS_ENSURE_ARG_POINTER(result);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return mCacheEntry->GetSecurityInfo(result);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
mCacheEntry->SetSecurityInfo(securityInfo);
mCacheEntry->MarkEntryDirty();
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::Doom()
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return nsCacheService::GlobalInstance()->DoomEntry(mCacheEntry);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::MarkValid()
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
nsresult rv;
rv = nsCacheService::GlobalInstance()->ValidateEntry(mCacheEntry);
return rv;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::Close()
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
// tell nsCacheService we're going away
nsCacheService::GlobalInstance()->CloseDescriptor(this);
mCacheEntry = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char ** result)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!key | !result) return NS_ERROR_NULL_POINTER;
nsAReadableCString *value;
*result = nsnull;
// XXX not thread safe
nsresult rv = mCacheEntry->GetMetaDataElement(nsLiteralCString(key), &value);
if (NS_FAILED(rv)) return rv;
if (!value) return NS_ERROR_NOT_AVAILABLE;
*result = ToNewCString(*value);
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value)
{
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!key) return NS_ERROR_NULL_POINTER;
// XXX not thread safe
// XXX allow null value, for clearing key?
nsresult rv = mCacheEntry->SetMetaDataElement(nsLiteralCString(key),
nsLiteralCString(value));
if (NS_SUCCEEDED(rv))
mCacheEntry->TouchMetaData();
return rv;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::VisitMetaData(nsICacheMetaDataVisitor * visitor)
{
NS_ENSURE_ARG_POINTER(visitor);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return mCacheEntry->VisitMetaDataElements(visitor);
}
/******************************************************************************
* nsCacheTransportWrapper
******************************************************************************/
// XXX NS_IMPL_ISUPPORTS1(nsCacheEntryDescriptor::nsTransportWrapper, nsITransport);
NS_IMPL_QUERY_INTERFACE1(nsCacheEntryDescriptor::nsTransportWrapper, nsITransport)
// special AddRef and Release, because we are part of the descriptor
#define GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(_this) \
((nsCacheEntryDescriptor*)((char*)(_this) - \
offsetof(nsCacheEntryDescriptor, mTransportWrapper)))
NS_IMETHODIMP_(nsrefcnt) nsCacheEntryDescriptor::
nsTransportWrapper::AddRef(void)
{
return GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this)->AddRef();
}
NS_IMETHODIMP_(nsrefcnt) nsCacheEntryDescriptor::
nsTransportWrapper::Release(void)
{
return GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this)->Release();
}
nsresult nsCacheEntryDescriptor::
nsTransportWrapper::EnsureTransportWithAccess(nsCacheAccessMode mode)
{
nsresult rv = NS_OK;
nsCacheEntryDescriptor * descriptor = GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this);
if (!descriptor->mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!descriptor->mAccessGranted & mode) {
rv = (mode == nsICache::ACCESS_READ) ?
NS_ERROR_CACHE_READ_ACCESS_DENIED : NS_ERROR_CACHE_WRITE_ACCESS_DENIED;
return rv;
}
if (!mTransport) {
rv = nsCacheService::GlobalInstance()->
GetTransportForEntry(descriptor->mCacheEntry,
descriptor->mAccessGranted,
getter_AddRefs(mTransport));
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}
nsresult
nsCacheEntryDescriptor::NewOutputStreamWrapper(nsIOutputStream ** result,
nsCacheEntryDescriptor * descriptor,
nsIOutputStream * output)
{
nsOutputStreamWrapper* cacheOutput =
new nsOutputStreamWrapper(descriptor, output);
if (!cacheOutput) return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsISupports> ref(cacheOutput);
nsresult rv = cacheOutput->Init();
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*result = cacheOutput);
return NS_OK;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::GetSecurityInfo(nsISupports ** securityInfo)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::GetNotificationCallbacks(nsIInterfaceRequestor ** result)
{
NS_ENSURE_ARG_POINTER(result);
// if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::SetNotificationCallbacks(nsIInterfaceRequestor * requestor,
PRUint32 flags)
{
// if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::OpenInputStream(PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIInputStream ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_READ);
if (NS_FAILED(rv)) return rv;
return mTransport->OpenInputStream(offset, count, flags, result);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::OpenOutputStream(PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIOutputStream ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_WRITE);
if (NS_FAILED(rv)) return rv;
// XXX allow more than one output stream at a time on a descriptor? Why?
// Create the underlying output stream using the wrapped transport.
nsCOMPtr<nsIOutputStream> output;
rv = mTransport->OpenOutputStream(offset, count, flags, getter_AddRefs(output));
if (NS_FAILED(rv)) return rv;
// Wrap this output stream with a stream that monitors how much data gets written,
// maintains the cache entry's size, and informs the cache device.
// This mechanism provides a way for the cache device to enforce space limits,
// and to drive cache entry eviction.
nsCacheEntryDescriptor * descriptor = GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this);
// reset datasize of entry based on offset so OnWrite calculates delta changes correctly.
rv = descriptor->SetDataSize(offset);
if (NS_FAILED(rv)) return rv;
return NewOutputStreamWrapper(result, descriptor, output);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::AsyncRead(nsIStreamListener * listener,
nsISupports * ctxt,
PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIRequest ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_READ);
if (NS_FAILED(rv)) return rv;
return mTransport->AsyncRead(listener, ctxt, offset, count, flags, result);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::AsyncWrite(nsIStreamProvider * provider,
nsISupports * ctxt,
PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIRequest ** result)
{
// we're not planning on implementing this
return NS_ERROR_NOT_IMPLEMENTED;
#if 0
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_WRITE);
if (NS_FAILED(rv)) return rv;
return mTransport->AsyncWrite(provider, ctxt, offset, count, flags, result);
#endif
}
/******************************************************************************
* nsCacheOutputStream - a wrapper for nsIOutputstream to track the amount of
* data written to a cache entry.
******************************************************************************/
NS_IMPL_ISUPPORTS1(nsCacheEntryDescriptor::nsOutputStreamWrapper, nsIOutputStream);
nsresult nsCacheEntryDescriptor::
nsOutputStreamWrapper::Init()
{
nsCacheAccessMode mode;
nsresult rv = mDescriptor->GetAccessGranted(&mode);
if (NS_FAILED(rv)) return rv;
if (mode == nsICache::ACCESS_WRITE) {
nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;
nsCacheDevice* device = cacheEntry->CacheDevice();
if (!device) return NS_ERROR_NOT_AVAILABLE;
// the entry has been truncated to zero bytes, inform the device.
PRInt32 delta = -cacheEntry->DataSize();
rv = device->OnDataSizeChange(cacheEntry, delta);
cacheEntry->SetDataSize(0);
}
return rv;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::Write(const char * buf,
PRUint32 count,
PRUint32 * result)
{
nsresult rv = OnWrite(count);
if (NS_FAILED(rv)) return rv;
return mOutput->Write(buf, count, result);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::WriteFrom(nsIInputStream * inStr,
PRUint32 count,
PRUint32 * result)
{
nsresult rv = OnWrite(count);
if (NS_FAILED(rv)) return rv;
return mOutput->WriteFrom(inStr, count, result);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::WriteSegments(nsReadSegmentFun reader,
void * closure,
PRUint32 count,
PRUint32 * result)
{
nsresult rv = OnWrite(count);
if (NS_FAILED(rv)) return rv;
return mOutput->WriteSegments(reader, closure, count, result);
}
nsresult nsCacheEntryDescriptor::
nsOutputStreamWrapper::OnWrite(PRUint32 count)
{
// XXX if count > 2^31 error_write_too_big
return mDescriptor->RequestDataSizeChange((PRInt32)count);
}

View File

@@ -0,0 +1,167 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheEntryDescriptor.h, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#ifndef _nsCacheEntryDescriptor_h_
#define _nsCacheEntryDescriptor_h_
#include "nsICacheEntryDescriptor.h"
#include "nsCacheEntry.h"
#include "nsIOutputStream.h"
#include "nsITransport.h"
/******************************************************************************
* nsCacheEntryDescriptor
*******************************************************************************/
class nsCacheEntryDescriptor :
public PRCList,
public nsICacheEntryDescriptor
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICACHEENTRYDESCRIPTOR
NS_DECL_NSICACHEENTRYINFO
nsCacheEntryDescriptor(nsCacheEntry * entry, nsCacheAccessMode mode);
virtual ~nsCacheEntryDescriptor();
static nsresult Create(nsCacheEntry * entry, nsCacheAccessMode accessGranted,
nsICacheEntryDescriptor ** result);
/**
* utility method to attempt changing data size of associated entry
*/
nsresult RequestDataSizeChange(PRInt32 deltaSize);
/**
* methods callbacks for nsCacheService
*/
nsCacheEntry * CacheEntry(void) { return mCacheEntry; }
void ClearCacheEntry(void) { mCacheEntry = nsnull; }
private:
/*************************************************************************
* transport wrapper class -
*
* we want the transport wrapper to have the same lifetime as the
* descriptor, but since they each need to reference the other, we have the
* descriptor include the transport wrapper as a member, rather than just
* pointing to it, which avoids circular AddRefs.
*************************************************************************/
class nsTransportWrapper : public nsITransport
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSITRANSPORT
nsTransportWrapper() : mTransport(nsnull) {}
virtual ~nsTransportWrapper() {}
nsresult EnsureTransportWithAccess(nsCacheAccessMode mode);
nsCOMPtr<nsITransport> mTransport;
}; // end of class nsTransportWrapper
friend class nsTransportWrapper;
/*************************************************************************
* output stream wrapper class -
*
* The output stream wrapper references the descriptor, but the descriptor
* doesn't need any references to the stream wrapper, so we don't need the
* same kind of tricks that we're using for the transport wrapper.
*************************************************************************/
class nsOutputStreamWrapper : public nsIOutputStream {
private:
nsCacheEntryDescriptor * mDescriptor;
nsCOMPtr<nsIOutputStream> mOutput;
public:
NS_DECL_ISUPPORTS
// NS_DECL_NSIOUTPUTSTREAM
NS_IMETHOD Close(void) { return mOutput->Close(); }
NS_IMETHOD Flush(void) { return mOutput->Flush(); }
NS_IMETHOD Write(const char * buf,
PRUint32 count,
PRUint32 * result);
NS_IMETHOD WriteFrom(nsIInputStream * inStr,
PRUint32 count,
PRUint32 * result);
NS_IMETHOD WriteSegments(nsReadSegmentFun reader,
void * closure,
PRUint32 count,
PRUint32 * result);
NS_IMETHOD GetNonBlocking(PRBool * nonBlocking)
{ return mOutput->GetNonBlocking(nonBlocking); }
NS_IMETHOD SetNonBlocking(PRBool nonBlocking)
{ return mOutput->SetNonBlocking(nonBlocking); }
NS_IMETHOD GetObserver(nsIOutputStreamObserver ** observer)
{ return mOutput->GetObserver(observer); }
NS_IMETHOD SetObserver(nsIOutputStreamObserver * observer)
{ return mOutput->SetObserver(observer); }
nsOutputStreamWrapper(nsCacheEntryDescriptor * descriptor,
nsIOutputStream * output)
: mDescriptor(nsnull), mOutput(output)
{
NS_INIT_ISUPPORTS();
NS_ADDREF(mDescriptor = descriptor);
}
virtual ~nsOutputStreamWrapper()
{
NS_RELEASE(mDescriptor);
}
nsresult Init();
private:
nsresult OnWrite(PRUint32 count);
}; // end of class nsOutputStreamWrapper
friend class nsOutputStreamWrapper;
static nsresult NewOutputStreamWrapper(nsIOutputStream ** result,
nsCacheEntryDescriptor * descriptor,
nsIOutputStream * output);
private:
/**
* nsCacheEntryDescriptor data members
*/
nsCacheEntry * mCacheEntry; // we are a child of the entry
nsCacheAccessMode mAccessGranted;
nsTransportWrapper mTransportWrapper;
};
#endif // _nsCacheEntryDescriptor_h_

View File

@@ -0,0 +1,327 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheMetaData.cpp, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#include "nsCacheMetaData.h"
#include "nsString.h"
#include "nsICacheEntryDescriptor.h"
/*
* nsCacheClientHashTable
*/
PLDHashTableOps
nsCacheMetaData::ops =
{
PL_DHashAllocTable,
PL_DHashFreeTable,
GetKey,
HashKey,
MatchEntry,
MoveEntry,
ClearEntry,
Finalize
};
nsCacheMetaData::nsCacheMetaData()
: initialized(PR_FALSE)
{
}
nsCacheMetaData::~nsCacheMetaData()
{
if (initialized)
PL_DHashTableFinish(&table);
}
nsresult
nsCacheMetaData::Init()
{
nsresult rv = NS_OK;
initialized = PL_DHashTableInit(&table, &ops, nsnull,
sizeof(nsCacheMetaDataHashTableEntry), 16);
if (!initialized) rv = NS_ERROR_OUT_OF_MEMORY;
return rv;
}
nsCacheMetaData *
nsCacheMetaData::Create()
{
nsCacheMetaData * metaData = new nsCacheMetaData();
if (!metaData)
return nsnull;
nsresult rv = metaData->Init();
if (NS_FAILED(rv)) {
delete metaData;
return nsnull;
}
return metaData;
}
nsAReadableCString *
nsCacheMetaData::GetElement(const nsAReadableCString * key)
{
PLDHashEntryHdr * hashEntry;
nsCString * result = nsnull;
// XXX need to copy string until we have scc's new flat string abstract class
// XXX see nsCacheMetaData::HashKey below (bug 70075)
nsCString * tempKey = new nsCString(*key);
if (!tempKey) return result;
NS_ASSERTION(initialized, "nsCacheMetaDataHashTable not initialized");
hashEntry = PL_DHashTableOperate(&table, tempKey, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_BUSY(hashEntry)) {
result = ((nsCacheMetaDataHashTableEntry *)hashEntry)->value;
}
delete tempKey;
return result;
}
nsresult
nsCacheMetaData::SetElement(const nsAReadableCString& key,
const nsAReadableCString& value)
{
nsCacheMetaDataHashTableEntry * metaEntry;
nsresult rv = NS_ERROR_OUT_OF_MEMORY; // presume the worst
NS_ASSERTION(initialized, "nsCacheMetaDataHashTable not initialized");
// XXX need to copy string until we have scc's new flat string abstract class
// XXX see nsCacheMetaData::HashKey below (bug 70075)
nsCString * tempKey = new nsCString(key);
if (!tempKey) return rv;
// XXX should empty value remove the key?
metaEntry = (nsCacheMetaDataHashTableEntry *)
PL_DHashTableOperate(&table, tempKey, PL_DHASH_ADD);
if (!metaEntry) goto error_exit;
if (metaEntry->key == nsnull) {
metaEntry->key = new nsCString(key);
if (metaEntry->key == nsnull) {
goto error_exit;
}
}
if (metaEntry->value != nsnull)
delete metaEntry->value; // clear the old value
metaEntry->value = new nsCString(value);
if (metaEntry->value == nsnull) {
// XXX remove key?
goto error_exit;
}
rv = NS_OK;
error_exit:
delete tempKey;
return rv;
}
PRUint32
nsCacheMetaData::Size(void)
{
PRUint32 size = 0;
(void) PL_DHashTableEnumerate(&table, CalculateSize, &size);
return size;
}
nsresult
nsCacheMetaData::FlattenMetaData(char ** data, PRUint32 * size)
{
*size = 0;
if (PL_DHashTableEnumerate(&table, CalculateSize, size) != 0 && data) {
*data = new char[*size];
if (*data == nsnull) return NS_ERROR_OUT_OF_MEMORY;
char* state = *data;
PL_DHashTableEnumerate(&table, AccumulateElement, &state);
}
return NS_OK;
}
nsresult
nsCacheMetaData::UnflattenMetaData(char * data, PRUint32 size)
{
nsresult rv = NS_ERROR_UNEXPECTED;
char* limit = data + size;
while (data < limit) {
const char* name = data;
PRUint32 nameSize = nsCRT::strlen(name);
data += 1 + nameSize;
if (data < limit) {
const char* value = data;
PRUint32 valueSize = nsCRT::strlen(value);
data += 1 + valueSize;
rv = SetElement(nsLocalCString(name, nameSize),
nsLocalCString(value, valueSize));
if (NS_FAILED(rv)) break;
}
}
return rv;
}
nsresult
nsCacheMetaData::VisitElements(nsICacheMetaDataVisitor * visitor)
{
(void) PL_DHashTableEnumerate(&table, VisitElement, visitor);
return NS_OK;
}
/*
* hash table operation callback functions
*/
const void * PR_CALLBACK
nsCacheMetaData::GetKey( PLDHashTable * /* table */, PLDHashEntryHdr *hashEntry)
{
return ((nsCacheMetaDataHashTableEntry *)hashEntry)->key;
}
PLDHashNumber PR_CALLBACK
nsCacheMetaData::HashKey( PLDHashTable * table, const void *key)
{
// XXX need scc's new flat string abstract class here (bug 70075)
return PL_DHashStringKey(table, ((nsCString *)key)->get());
}
PRBool PR_CALLBACK
nsCacheMetaData::MatchEntry(PLDHashTable * /* table */,
const PLDHashEntryHdr * hashEntry,
const void * key)
{
NS_ASSERTION(key != nsnull, "### nsCacheMetaDataHashTable::MatchEntry : null key");
nsCString * entryKey = ((nsCacheMetaDataHashTableEntry *)hashEntry)->key;
NS_ASSERTION(entryKey, "### hashEntry->key == nsnull");
return entryKey->Equals(*NS_STATIC_CAST(const nsAReadableCString*,key));
}
void PR_CALLBACK
nsCacheMetaData::MoveEntry(PLDHashTable * /* table */,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to)
{
((nsCacheMetaDataHashTableEntry *)to)->key =
((nsCacheMetaDataHashTableEntry *)from)->key;
((nsCacheMetaDataHashTableEntry *)to)->value =
((nsCacheMetaDataHashTableEntry *)from)->value;
}
void PR_CALLBACK
nsCacheMetaData::ClearEntry(PLDHashTable * /* table */,
PLDHashEntryHdr * hashEntry)
{
((nsCacheMetaDataHashTableEntry *)hashEntry)->key = 0;
((nsCacheMetaDataHashTableEntry *)hashEntry)->value = 0;
}
void PR_CALLBACK
nsCacheMetaData::Finalize(PLDHashTable * table)
{
(void) PL_DHashTableEnumerate(table, FreeElement, nsnull);
}
/**
* hash table enumeration callback functions
*/
PLDHashOperator PR_CALLBACK
nsCacheMetaData::CalculateSize(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg)
{
nsCacheMetaDataHashTableEntry* hashEntry = (nsCacheMetaDataHashTableEntry *)hdr;
*(PRUint32*)arg += (2 + hashEntry->key->Length() + hashEntry->value->Length());
return PL_DHASH_NEXT;
}
PLDHashOperator PR_CALLBACK
nsCacheMetaData::AccumulateElement(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg)
{
char** bufferPtr = (char**) arg;
nsCacheMetaDataHashTableEntry* hashEntry = (nsCacheMetaDataHashTableEntry *)hdr;
PRUint32 size = 1 + hashEntry->key->Length();
nsCRT::memcpy(*bufferPtr, hashEntry->key->get(), size);
*bufferPtr += size;
size = 1 + hashEntry->value->Length();
nsCRT::memcpy(*bufferPtr, hashEntry->value->get(), size);
*bufferPtr += size;
return PL_DHASH_NEXT;
}
PLDHashOperator PR_CALLBACK
nsCacheMetaData::FreeElement(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg)
{
nsCacheMetaDataHashTableEntry *entry = (nsCacheMetaDataHashTableEntry *)hdr;
delete entry->key;
delete entry->value;
return PL_DHASH_NEXT;
}
PLDHashOperator PR_CALLBACK
nsCacheMetaData::VisitElement(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg)
{
nsCacheMetaDataHashTableEntry *entry = (nsCacheMetaDataHashTableEntry *)hdr;
nsICacheMetaDataVisitor *visitor = (nsICacheMetaDataVisitor *)arg;
const char * key = entry->key ? entry->key->get() : nsnull;
const char * value = entry->value ? entry->value->get() : nsnull;
PRBool keepGoing;
nsresult rv = visitor->VisitMetaDataElement(key, value, &keepGoing);
return NS_SUCCEEDED(rv) && keepGoing ? PL_DHASH_NEXT : PL_DHASH_STOP;
}

View File

@@ -0,0 +1,119 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheMetaData.h, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#ifndef _nsCacheMetaData_h_
#define _nsCacheMetaData_h_
#include "nspr.h"
#include "pldhash.h"
#include "nscore.h"
// #include "nsCOMPtr.h"
#include "nsString.h"
// #include "nsAReadableString.h"
class nsICacheMetaDataVisitor;
typedef struct {
nsCString * key;
nsCString * value;
} nsCacheMetaDataKeyValuePair;
typedef struct {
PLDHashNumber keyHash;
nsCString * key;
nsCString * value;
} nsCacheMetaDataHashTableEntry;
class nsCacheMetaData {
public:
nsCacheMetaData();
~nsCacheMetaData();
static
nsCacheMetaData * Create(void);
nsresult Init(void);
nsAReadableCString * GetElement(const nsAReadableCString * key);
nsresult SetElement(const nsAReadableCString& key,
const nsAReadableCString& value);
PRUint32 Size(void);
nsresult FlattenMetaData(char ** data, PRUint32 * size);
nsresult UnflattenMetaData(char * data, PRUint32 size);
nsresult VisitElements(nsICacheMetaDataVisitor * visitor);
private:
// PLDHashTable operation callbacks
static const void * PR_CALLBACK GetKey( PLDHashTable *table, PLDHashEntryHdr *entry);
static PLDHashNumber PR_CALLBACK HashKey( PLDHashTable *table, const void *key);
static PRBool PR_CALLBACK MatchEntry( PLDHashTable * table,
const PLDHashEntryHdr * entry,
const void * key);
static void PR_CALLBACK MoveEntry( PLDHashTable *table,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to);
static void PR_CALLBACK ClearEntry( PLDHashTable *table, PLDHashEntryHdr *entry);
static void PR_CALLBACK Finalize( PLDHashTable *table);
static
PLDHashOperator PR_CALLBACK CalculateSize(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg);
static
PLDHashOperator PR_CALLBACK AccumulateElement(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg);
static
PLDHashOperator PR_CALLBACK FreeElement(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg);
static
PLDHashOperator PR_CALLBACK VisitElement(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg);
// member variables
static PLDHashTableOps ops;
PLDHashTable table;
PRBool initialized;
};
#endif // _nsCacheMetaData_h

View File

@@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheModule.cpp, released February 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Patrick C. Beard <beard@netscape.com>
* Gordon Sheridan <gordon@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsCacheService.h"
#include "nsNetCID.h"
// nsCacheService
//
static nsModuleComponentInfo gResComponents[] = {
{
NS_CACHESERVICE_CLASSNAME,
NS_CACHESERVICE_CID,
NS_CACHESERVICE_CONTRACTID,
nsCacheService::Create
}
};
NS_IMPL_NSGETMODULE(cacheservice, gResComponents)

View File

@@ -0,0 +1,178 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheRequest.h, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*/
#ifndef _nsCacheRequest_h_
#define _nsCacheRequest_h_
#include "nspr.h"
#include "nsCOMPtr.h"
#include "nsICache.h"
#include "nsICacheListener.h"
#include "nsIEventQueue.h"
#include "nsCacheSession.h"
class nsCacheRequest : public PRCList
{
private:
friend class nsCacheService;
friend class nsCacheEntry;
nsCacheRequest( nsCString * key,
nsICacheListener * listener,
nsCacheAccessMode accessRequested,
PRBool blockingMode,
nsCacheSession * session)
: mKey(key),
mInfo(0),
mListener(listener),
mEventQ(nsnull),
mLock(nsnull),
mCondVar(nsnull)
{
PR_INIT_CLIST(this);
SetAccessRequested(accessRequested);
SetStoragePolicy(session->StoragePolicy());
if (session->IsStreamBased()) MarkStreamBased();
if (session->WillDoomEntriesIfExpired()) MarkDoomEntriesIfExpired();
if (blockingMode == nsICache::BLOCKING) MarkBlockingMode();
MarkWaitingForValidation();
}
~nsCacheRequest()
{
delete mKey;
if (mLock) PR_DestroyLock(mLock);
if (mCondVar) PR_DestroyCondVar(mCondVar);
NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list");
}
/**
* Simple Accessors
*/
enum CacheRequestInfo {
eStoragePolicyMask = 0x000000FF,
eStreamBasedMask = 0x00000100,
eDoomEntriesIfExpiredMask = 0x00001000,
eBlockingModeMask = 0x00010000,
eWaitingForValidationMask = 0x00100000,
eAccessRequestedMask = 0xFF000000
};
void SetAccessRequested(nsCacheAccessMode mode)
{
NS_ASSERTION(mode <= 0xFF, "too many bits in nsCacheAccessMode");
mInfo &= ~eAccessRequestedMask;
mInfo |= mode << 24;
}
nsCacheAccessMode AccessRequested()
{
return (nsCacheAccessMode)((mInfo >> 24) & 0xFF);
}
void MarkStreamBased() { mInfo |= eStreamBasedMask; }
PRBool IsStreamBased() { return (mInfo & eStreamBasedMask) != 0; }
void MarkDoomEntriesIfExpired() { mInfo |= eDoomEntriesIfExpiredMask; }
PRBool WillDoomEntriesIfExpired() { return (mInfo & eDoomEntriesIfExpiredMask); }
void MarkBlockingMode() { mInfo |= eBlockingModeMask; }
PRBool IsBlocking() { return (mInfo & eBlockingModeMask); }
PRBool IsNonBlocking() { return !(mInfo & eBlockingModeMask); }
void SetStoragePolicy(nsCacheStoragePolicy policy)
{
NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy");
mInfo &= ~eStoragePolicyMask; // clear storage policy bits
mInfo |= policy; // or in new bits
}
nsCacheStoragePolicy StoragePolicy()
{
return (nsCacheStoragePolicy)(mInfo & 0xFF);
}
void MarkWaitingForValidation() { mInfo |= eWaitingForValidationMask; }
void DoneWaitingForValidation() { mInfo &= ~eWaitingForValidationMask; }
PRBool WaitingForValidation()
{
return (mInfo & eWaitingForValidationMask) != 0;
}
nsresult
WaitForValidation(void)
{
if (!WaitingForValidation()) { // flag already cleared
MarkWaitingForValidation(); // set up for next time
return NS_OK; // early exit;
}
if (!mLock) {
mLock = PR_NewLock();
if (!mLock) return NS_ERROR_OUT_OF_MEMORY;
NS_ASSERTION(!mCondVar,"we have mCondVar, but didn't have mLock?");
mCondVar = PR_NewCondVar(mLock);
if (!mCondVar) {
PR_DestroyLock(mLock);
return NS_ERROR_OUT_OF_MEMORY;
}
}
PRStatus status = PR_SUCCESS;
PR_Lock(mLock);
while (WaitingForValidation() && (status == PR_SUCCESS) ) {
status = PR_WaitCondVar(mCondVar, PR_INTERVAL_NO_TIMEOUT);
}
MarkWaitingForValidation(); // set up for next time
PR_Unlock(mLock);
NS_ASSERTION(status == PR_SUCCESS, "PR_WaitCondVar() returned PR_FAILURE?");
if (status == PR_FAILURE)
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
void WakeUp(void) {
DoneWaitingForValidation();
if (mLock) {
PR_Lock(mLock);
PR_NotifyCondVar(mCondVar);
PR_Unlock(mLock);
}
}
/**
* Data members
*/
nsCString * mKey;
PRUint32 mInfo;
nsCOMPtr<nsICacheListener> mListener;
nsCOMPtr<nsIEventQueue> mEventQ;
PRLock * mLock;
PRCondVar * mCondVar;
};
#endif // _nsCacheRequest_h_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheService.h, released February 10, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#ifndef _nsCacheService_h_
#define _nsCacheService_h_
#include "nsICacheService.h"
#include "nsCacheSession.h"
#include "nsCacheDevice.h"
#include "nsCacheEntry.h"
#include "nspr.h"
#include "nsIObserver.h"
#include "nsString.h"
#include "nsIEventQueueService.h"
#include "nsProxiedService.h"
class nsCacheRequest;
/******************************************************************************
* nsCacheService
******************************************************************************/
class nsCacheService : public nsICacheService, public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICACHESERVICE
NS_DECL_NSIOBSERVER
nsCacheService();
virtual ~nsCacheService();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* outer, const nsIID& iid, void* *result);
/**
* Methods called by nsCacheSession
*/
nsresult OpenCacheEntry(nsCacheSession * session,
const char * key,
nsCacheAccessMode accessRequested,
PRBool blockingMode,
nsICacheListener * listener,
nsICacheEntryDescriptor ** result);
nsresult EvictEntriesForSession(nsCacheSession * session);
nsresult EvictEntriesForClient(const char * clientID,
nsCacheStoragePolicy storagePolicy);
/**
* Methods called by nsCacheEntryDescriptor
*/
nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element);
nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize);
nsresult ValidateEntry(nsCacheEntry * entry);
nsresult GetTransportForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** result);
void CloseDescriptor(nsCacheEntryDescriptor * descriptor);
nsresult GetFileForEntry(nsCacheEntry * entry,
nsIFile ** result);
/**
* Methods called by any cache classes
*/
static
nsCacheService * GlobalInstance(void) { return gService; };
nsresult DoomEntry(nsCacheEntry * entry);
nsresult DoomEntry_Locked(nsCacheEntry * entry);
/**
* Methods called by nsCachePrefObserver
*/
void SetCacheDevicesEnabled(PRBool disk, PRBool memory);
private:
/**
* Internal Methods
*/
nsresult CreateDiskDevice();
nsresult CreateMemoryDevice();
nsresult CreateRequest(nsCacheSession * session,
const char * clientKey,
nsCacheAccessMode accessRequested,
PRBool blockingMode,
nsICacheListener * listener,
nsCacheRequest ** request);
nsresult NotifyListener(nsCacheRequest * request,
nsICacheEntryDescriptor * descriptor,
nsCacheAccessMode accessGranted,
nsresult error);
nsresult ActivateEntry(nsCacheRequest * request, nsCacheEntry ** entry);
nsCacheDevice * EnsureEntryHasDevice(nsCacheEntry * entry);
nsCacheEntry * SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy);
void DeactivateEntry(nsCacheEntry * entry);
nsresult ProcessRequest(nsCacheRequest * request,
PRBool calledFromOpenCacheEntry,
nsICacheEntryDescriptor ** result);
nsresult ProcessPendingRequests(nsCacheEntry * entry);
void ClearPendingRequests(nsCacheEntry * entry);
void ClearDoomList(void);
void ClearActiveEntries(void);
static
PLDHashOperator PR_CALLBACK DeactivateAndClearEntry(PLDHashTable * table,
PLDHashEntryHdr * hdr,
PRUint32 number,
void * arg);
#if defined(PR_LOGGING)
void LogCacheStatistics();
#endif
/**
* Data Members
*/
static nsCacheService * gService; // there can be only one...
nsCOMPtr<nsIEventQueueService> mEventQService;
nsCOMPtr<nsIProxyObjectManager> mProxyObjectManager;
PRLock* mCacheServiceLock;
PRBool mEnableMemoryDevice;
PRBool mEnableDiskDevice;
nsCacheDevice * mMemoryDevice;
nsCacheDevice * mDiskDevice;
nsCacheEntryHashTable mActiveEntries;
PRCList mDoomedEntries;
// stats
PRUint32 mTotalEntries;
PRUint32 mCacheHits;
PRUint32 mCacheMisses;
PRUint32 mMaxKeyLength;
PRUint32 mMaxDataSize;
PRUint32 mMaxMetaSize;
// Unexpected error totals
PRUint32 mDeactivateFailures;
PRUint32 mDeactivatedUnboundEntries;
};
#endif // _nsCacheService_h_

View File

@@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheSession.h, released February 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#include "nsCacheSession.h"
#include "nsCacheService.h"
NS_IMPL_ISUPPORTS1(nsCacheSession, nsICacheSession)
nsCacheSession::nsCacheSession(const char * clientID,
nsCacheStoragePolicy storagePolicy,
PRBool streamBased)
: mClientID(clientID),
mInfo(0)
{
NS_INIT_ISUPPORTS();
SetStoragePolicy(storagePolicy);
if (streamBased) MarkStreamBased();
else SetStoragePolicy(nsICache::STORE_IN_MEMORY);
}
nsCacheSession::~nsCacheSession()
{
/* destructor code */
// notify service we are going away?
}
NS_IMETHODIMP nsCacheSession::GetDoomEntriesIfExpired(PRBool *result)
{
NS_ENSURE_ARG_POINTER(result);
*result = WillDoomEntriesIfExpired();
return NS_OK;
}
NS_IMETHODIMP nsCacheSession::SetDoomEntriesIfExpired(PRBool doomEntriesIfExpired)
{
if (doomEntriesIfExpired) MarkDoomEntriesIfExpired();
else ClearDoomEntriesIfExpired();
return NS_OK;
}
NS_IMETHODIMP
nsCacheSession::OpenCacheEntry(const char * key,
nsCacheAccessMode accessRequested,
PRBool blockingMode,
nsICacheEntryDescriptor ** result)
{
nsresult rv;
rv = nsCacheService::GlobalInstance()->OpenCacheEntry(this,
key,
accessRequested,
blockingMode,
nsnull, // no listener
result);
return rv;
}
NS_IMETHODIMP nsCacheSession::AsyncOpenCacheEntry(const char *key,
nsCacheAccessMode accessRequested,
nsICacheListener *listener)
{
nsresult rv;
rv = nsCacheService::GlobalInstance()->OpenCacheEntry(this,
key,
accessRequested,
nsICache::BLOCKING,
listener,
nsnull); // no result
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) rv = NS_OK;
return rv;
}
NS_IMETHODIMP nsCacheSession::EvictEntries()
{
return nsCacheService::GlobalInstance()->EvictEntriesForSession(this);
}

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheSession.h, released February 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick Beard <beard@netscape.com>
* Darin Fisher <darin@netscape.com>
*/
#ifndef _nsCacheSession_h_
#define _nsCacheSession_h_
#include "nspr.h"
#include "nsError.h"
#include "nsICacheSession.h"
#include "nsString.h"
class nsCacheSession : public nsICacheSession
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICACHESESSION
nsCacheSession(const char * clientID, nsCacheStoragePolicy storagePolicy, PRBool streamBased);
virtual ~nsCacheSession();
nsCString * ClientID() { return &mClientID; }
enum SessionInfo {
eStoragePolicyMask = 0x000000FF,
eStreamBasedMask = 0x00000100,
eDoomEntriesIfExpiredMask = 0x00001000
};
void MarkStreamBased() { mInfo |= eStreamBasedMask; }
void ClearStreamBased() { mInfo &= ~eStreamBasedMask; }
PRBool IsStreamBased() { return (mInfo & eStreamBasedMask) != 0; }
void MarkDoomEntriesIfExpired() { mInfo |= eDoomEntriesIfExpiredMask; }
void ClearDoomEntriesIfExpired() { mInfo &= ~eDoomEntriesIfExpiredMask; }
PRBool WillDoomEntriesIfExpired() { return (mInfo & eDoomEntriesIfExpiredMask); }
nsCacheStoragePolicy StoragePolicy()
{
return (nsCacheStoragePolicy)(mInfo & eStoragePolicyMask);
}
void SetStoragePolicy(nsCacheStoragePolicy policy)
{
NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy");
mInfo &= ~eStoragePolicyMask; // clear storage policy bits
mInfo |= policy;
}
private:
nsCString mClientID;
PRUint32 mInfo;
};
#endif // _nsCacheSession_h_

43
mozilla/netwerk/cache/src/nsDiskCache.h vendored Normal file
View File

@@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsCacheDevice.h, released March 9, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Patrick Beard <beard@netscape.com>
* Gordon Sheridan <gordon@netscape.com>
*/
#ifndef _nsDiskCache_h_
#define _nsDiskCache_h_
#include "nsCacheEntry.h"
class nsDiskCache {
public:
enum {
kCurrentVersion = 0x00010003 // XXX whats the format?
};
enum { kData, kMetaData };
static PLDHashNumber Hash(const char* key);
};
#endif // _nsDiskCache_h_

View File

@@ -0,0 +1,348 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheBinding.cpp, released May 10, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Patrick C. Beard <beard@netscape.com>
* Gordon Sheridan <gordon@netscape.com>
*/
#include <limits.h>
#include "nsDiskCacheBinding.h"
/******************************************************************************
* static hash table callback functions
*
*****************************************************************************/
#ifdef XP_MAC
#pragma mark -
#pragma mark HASHTABLE CALLBACKS
#endif
struct HashTableEntry : PLDHashEntryHdr {
nsDiskCacheBinding * mBinding;
};
static const void * PR_CALLBACK
GetKey(PLDHashTable * /*table*/, PLDHashEntryHdr * header)
{
return (void*) ((HashTableEntry *)header)->mBinding->mRecord.HashNumber();
}
static PLDHashNumber PR_CALLBACK
HashKey( PLDHashTable *table, const void *key)
{
return (PLDHashNumber) key;
}
static PRBool PR_CALLBACK
MatchEntry(PLDHashTable * /* table */,
const PLDHashEntryHdr * header,
const void * key)
{
HashTableEntry * hashEntry = (HashTableEntry *) header;
return (hashEntry->mBinding->mRecord.HashNumber() == (PLDHashNumber) key);
}
static void PR_CALLBACK
MoveEntry(PLDHashTable * /* table */,
const PLDHashEntryHdr * src,
PLDHashEntryHdr * dst)
{
((HashTableEntry *)dst)->mBinding = ((HashTableEntry *)src)->mBinding;
}
static void PR_CALLBACK
ClearEntry(PLDHashTable * /* table */,
PLDHashEntryHdr * header)
{
((HashTableEntry *)header)->mBinding = nsnull;
}
/******************************************************************************
* Utility Functions
*****************************************************************************/
#ifdef XP_MAC
#pragma mark -
#pragma mark DISK CACHE BINDERY
#endif
nsDiskCacheBinding *
GetCacheEntryBinding(nsCacheEntry * entry)
{
nsCOMPtr<nsISupports> data;
nsresult rv = entry->GetData(getter_AddRefs(data));
if (NS_FAILED(rv)) return nsnull;
return (nsDiskCacheBinding *)data.get();
}
/******************************************************************************
* nsDiskCacheBinding
*****************************************************************************/
NS_IMPL_THREADSAFE_ISUPPORTS0(nsDiskCacheBinding);
nsDiskCacheBinding::nsDiskCacheBinding(nsCacheEntry* entry, nsDiskCacheRecord * record)
: mCacheEntry(entry)
{
NS_ASSERTION(record->ValidRecord(), "bad record");
NS_INIT_ISUPPORTS();
PR_INIT_CLIST(this);
mRecord = *record;
mDoomed = entry->IsDoomed();
mGeneration = record->Generation(); // 0 == uninitialized, or data & meta using block files
}
nsDiskCacheBinding::~nsDiskCacheBinding()
{
NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "binding deleted while still on list");
if (!PR_CLIST_IS_EMPTY(this))
PR_REMOVE_LINK(this); // XXX why are we still on a list?
}
/******************************************************************************
* nsDiskCacheBindery
*
* Keeps track of bound disk cache entries to detect for collisions.
*
*****************************************************************************/
PLDHashTableOps nsDiskCacheBindery::ops =
{
PL_DHashAllocTable,
PL_DHashFreeTable,
GetKey,
HashKey,
MatchEntry,
MoveEntry,
ClearEntry,
PL_DHashFinalizeStub
};
nsDiskCacheBindery::nsDiskCacheBindery()
: initialized(PR_FALSE)
{
}
nsDiskCacheBindery::~nsDiskCacheBindery()
{
if (initialized)
PL_DHashTableFinish(&table);
}
nsresult
nsDiskCacheBindery::Init()
{
nsresult rv = NS_OK;
initialized = PL_DHashTableInit(&table, &ops, nsnull, sizeof(HashTableEntry), 0);
if (!initialized) rv = NS_ERROR_OUT_OF_MEMORY;
return rv;
}
nsDiskCacheBinding *
nsDiskCacheBindery::CreateBinding(nsCacheEntry * entry,
nsDiskCacheRecord * record)
{
NS_ASSERTION(initialized, "nsDiskCacheBindery not initialized");
nsCOMPtr<nsISupports> data;
nsresult rv = entry->GetData(getter_AddRefs(data));
if (NS_FAILED(rv) || data) {
NS_ASSERTION(!data, "cache entry already has bind data");
return nsnull;
}
nsDiskCacheBinding * binding = new nsDiskCacheBinding(entry, record);
if (!binding) return nsnull;
// give ownership of the binding to the entry
entry->SetData(binding);
// add binding to collision detection system
rv = AddBinding(binding);
if (NS_FAILED(rv)) {
entry->SetData(nsnull);
return nsnull;
}
return binding;
}
/**
* FindActiveEntry : to find active colliding entry so we can doom it
*/
nsDiskCacheBinding *
nsDiskCacheBindery::FindActiveBinding(PRUint32 hashNumber)
{
NS_ASSERTION(initialized, "nsDiskCacheBindery not initialized");
// find hash entry for key
HashTableEntry * hashEntry;
hashEntry = (HashTableEntry *) PL_DHashTableOperate(&table, (void*) hashNumber, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_FREE(hashEntry)) return nsnull;
// walk list looking for active entry
NS_ASSERTION(hashEntry->mBinding, "hash entry left with no binding");
nsDiskCacheBinding * binding = hashEntry->mBinding;
while (binding->mCacheEntry->IsDoomed()) {
binding = (nsDiskCacheBinding *)PR_NEXT_LINK(binding);
if (binding == hashEntry->mBinding) return nsnull;
}
return binding;
}
/**
* FindBinding : to identify whether a record is 'in use' so we don't evict it
*/
nsDiskCacheBinding *
nsDiskCacheBindery::FindBinding(nsDiskCacheRecord * record)
{
NS_ASSERTION(initialized, "nsDiskCacheBindery not initialized");
// find hash entry for key
HashTableEntry * hashEntry;
hashEntry = (HashTableEntry *) PL_DHashTableOperate(&table, (void*) record->HashNumber(), PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_FREE(hashEntry)) return nsnull;
// walk list looking for matching record (match on MetaLocation)
NS_ASSERTION(hashEntry->mBinding, "hash entry left with no binding");
nsDiskCacheBinding * binding = hashEntry->mBinding;
while (binding->mRecord.MetaLocation() != record->MetaLocation()) {
binding = (nsDiskCacheBinding *)PR_NEXT_LINK(binding);
if (binding == hashEntry->mBinding) return nsnull;
}
return binding;
}
/**
* AddBinding
*
* Called from FindEntry() if we read an entry off of disk
* - it may already have a generation number
* - a generation number conflict is an error
*
* Called from BindEntry()
* - a generation number needs to be assigned
*/
nsresult
nsDiskCacheBindery::AddBinding(nsDiskCacheBinding * binding)
{
NS_ENSURE_ARG_POINTER(binding);
NS_ASSERTION(initialized, "nsDiskCacheBindery not initialized");
// find hash entry for key
HashTableEntry * hashEntry;
hashEntry = (HashTableEntry *) PL_DHashTableOperate(&table,
(void*) binding->mRecord.HashNumber(),
PL_DHASH_ADD);
if (!hashEntry) return NS_ERROR_OUT_OF_MEMORY;
if (hashEntry->mBinding == nsnull) {
hashEntry->mBinding = binding;
if (binding->mGeneration == 0)
binding->mGeneration = 1; // if generation uninitialized, set it to 1
return NS_OK;
}
// insert binding in generation order
nsDiskCacheBinding * p = hashEntry->mBinding;
PRBool calcGeneration = (binding->mGeneration == 0); // do we need to calculate generation?
if (calcGeneration) binding->mGeneration = 1; // initialize to 1 if uninitialized
while (1) {
if (binding->mGeneration < p->mGeneration) {
// here we are
PR_INSERT_BEFORE(binding, p);
if (hashEntry->mBinding == p)
hashEntry->mBinding = binding;
}
if (binding->mGeneration == p->mGeneration) {
if (calcGeneration) ++binding->mGeneration; // try the next generation
else {
NS_ASSERTION(binding->mGeneration != p->mGeneration, "generations collide!");
return NS_ERROR_UNEXPECTED;
}
}
p = (nsDiskCacheBinding *)PR_NEXT_LINK(p);
if (p == hashEntry->mBinding) {
// end of line: insert here or die
p = (nsDiskCacheBinding *)PR_PREV_LINK(p); // back up and check generation
if (p->mGeneration == 255) {
NS_ASSERTION(p->mGeneration < 255, "generation capacity at full, the engines canna take it cap'n");
return NS_ERROR_UNEXPECTED;
}
PR_INSERT_BEFORE(binding, hashEntry->mBinding);
}
}
return NS_OK;
}
/**
* RemoveBinding : remove binding from collision detection on deactivation
*/
void
nsDiskCacheBindery::RemoveBinding(nsDiskCacheBinding * binding)
{
NS_ASSERTION(initialized, "nsDiskCacheBindery not initialized");
if (!initialized) return;
HashTableEntry * hashEntry;
void * key = (void *)binding->mRecord.HashNumber();
hashEntry = (HashTableEntry*) PL_DHashTableOperate(&table, (void*) key, PL_DHASH_LOOKUP);
if (!PL_DHASH_ENTRY_IS_BUSY(hashEntry)) {
NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(hashEntry), "binding not in disk cache hashtable!");
return;
}
if (binding == hashEntry->mBinding) {
if (PR_CLIST_IS_EMPTY(binding)) {
// remove this hash entry
(void) PL_DHashTableOperate(&table, (void*) binding->mRecord.HashNumber(), PL_DHASH_REMOVE);
return;
} else {
// promote next binding to head, and unlink this binding
hashEntry->mBinding = (nsDiskCacheBinding *)PR_NEXT_LINK(binding);
}
}
PR_REMOVE_AND_INIT_LINK(binding);
}

View File

@@ -0,0 +1,143 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheBinding.h, released May 10, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
*/
#ifndef _nsDiskCacheBinding_h_
#define _nsDiskCacheBinding_h_
#include "nspr.h"
#include "pldhash.h"
#include "nsISupports.h"
#include "nsCacheEntry.h"
#ifdef MOZ_NEW_CACHE_REUSE_TRANSPORTS
#include "nsITransport.h"
#endif
#include "nsDiskCacheMap.h"
/******************************************************************************
* nsDiskCacheBinding
*
* Created for disk cache specific data and stored in nsCacheEntry.mData as
* an nsISupports. Also stored in nsDiskCacheHashTable, with collisions
* linked by the PRCList.
*
*****************************************************************************/
class nsDiskCacheBinding : public nsISupports, public PRCList {
public:
NS_DECL_ISUPPORTS
nsDiskCacheBinding(nsCacheEntry* entry, nsDiskCacheRecord * record);
virtual ~nsDiskCacheBinding();
#ifdef MOZ_NEW_CACHE_REUSE_TRANSPORTS
/**
* Maps a cache access mode to a cached nsITransport for that access
* mode. We keep these cached to avoid repeated trips to the
* file transport service.
*/
nsCOMPtr<nsITransport>& getTransport(nsCacheAccessMode mode)
{
return mTransports[mode - 1];
}
#endif
// XXX make friends
public:
nsCacheEntry* mCacheEntry; // back pointer to parent nsCacheEntry
nsDiskCacheRecord mRecord;
PRBool mDoomed; // record is not stored in cache map
PRUint8 mGeneration; // possibly just reservation
private:
#ifdef MOZ_NEW_CACHE_REUSE_TRANSPORTS
nsCOMPtr<nsITransport> mTransports[3];
#endif
};
/******************************************************************************
* Utility Functions
*****************************************************************************/
nsDiskCacheBinding * GetCacheEntryBinding(nsCacheEntry * entry);
/******************************************************************************
* nsDiskCacheBindery
*
* Used to keep track of nsDiskCacheBinding associated with active/bound (and
* possibly doomed) entries. Lookups on 4 byte disk hash to find collisions
* (which need to be doomed, instead of just evicted. Collisions are linked
* using a PRCList to keep track of current generation number.
*
* Used to detect hash number collisions, and find available generation numbers.
*
* Not all nsDiskCacheBinding have a generation number.
*
* Generation numbers may be aquired late, or lost (when data fits in block file)
*
* Collisions can occur:
* BindEntry() - hashnumbers collide (possibly different keys)
*
* Generation number required:
* DeactivateEntry() - metadata written to disk, may require file
* GetFileForEntry() - force data to require file
* writing to stream - data size may require file
*
* Binding can be kept in PRCList in order of generation numbers.
* Binding with no generation number can be Appended to PRCList (last).
*
*****************************************************************************/
class nsDiskCacheBindery {
public:
nsDiskCacheBindery();
~nsDiskCacheBindery();
nsresult Init();
nsDiskCacheBinding * CreateBinding(nsCacheEntry * entry,
nsDiskCacheRecord * record);
nsDiskCacheBinding * FindActiveBinding(PRUint32 hashNumber);
nsDiskCacheBinding * FindBinding(nsDiskCacheRecord * record);
nsresult AddBinding(nsDiskCacheBinding * binding);
void RemoveBinding(nsDiskCacheBinding * binding);
private:
// member variables
static PLDHashTableOps ops;
PLDHashTable table;
PRBool initialized;
};
#endif /* _nsDiskCacheBinding_h_ */

View File

@@ -0,0 +1,422 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheBlockFile.cpp, released April 12, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
*/
#include "nsCRT.h"
#include "nsDiskCacheBlockFile.h"
/******************************************************************************
* nsDiskCacheBlockFile -
*****************************************************************************/
/******************************************************************************
* Open
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::Open( nsILocalFile * blockFile, PRUint32 blockSize)
{
PRStatus err = PR_SUCCESS;
PRInt32 fileSize;
mBlockSize = blockSize;
// open the file
nsresult rv = blockFile->OpenNSPRFileDesc(PR_RDWR | PR_CREATE_FILE, 00666, &mFD);
if (NS_FAILED(rv)) return rv; // unable to open or create file
// allocate bit map buffer
mBitMap = new PRUint8[kBitMapBytes];
if (!mBitMap) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto error_exit;
}
// check if we just creating the file
fileSize = PR_Available(mFD);
if (fileSize < 0) {
// XXX an error occurred. We could call PR_GetError(), but how would that help?
rv = NS_ERROR_UNEXPECTED;
goto error_exit;
}
mEndOfFile = fileSize;
if (mEndOfFile == 0) {
// initialize bit map and write it
nsCRT::zero(mBitMap, kBitMapBytes);
PRInt32 bytesWritten = PR_Write(mFD, mBitMap, kBitMapBytes);
if (bytesWritten < kBitMapBytes) goto error_exit;
mEndOfFile = kBitMapBytes;
} else if (mEndOfFile < kBitMapBytes) {
rv = NS_ERROR_UNEXPECTED; // XXX NS_ERROR_CACHE_INVALID;
goto error_exit;
} else {
// read the bit map
PRInt32 bytesRead = PR_Read(mFD, mBitMap, kBitMapBytes);
if (bytesRead < kBitMapBytes) {
rv = NS_ERROR_UNEXPECTED;
goto error_exit;
}
// validate block file
rv = ValidateFile();
if (NS_FAILED(rv)) goto error_exit;
}
return NS_OK;
error_exit:
if (mFD) {
(void) PR_Close(mFD);
mFD = nsnull;
}
if (mBitMap) {
delete [] mBitMap;
mBitMap = nsnull;
}
return rv;
}
/******************************************************************************
* Close
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::Close()
{
if (!mFD) return NS_OK;
nsresult rv = FlushBitMap();
PRStatus err = PR_Close(mFD);
mFD = nsnull;
if (mBitMap) {
delete [] mBitMap;
mBitMap = nsnull;
}
if (NS_SUCCEEDED(rv) && (err != PR_SUCCESS))
rv = NS_ERROR_UNEXPECTED;
return rv;
}
/******************************************************************************
* Trim
*
* Truncate the block file to the end of the last allocated block.
*
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::Trim()
{
return NS_OK;
}
/******************************************************************************
* AllocateBlocks
*
* Allocates 1-4 blocks, using a first fit strategy,
* so that no group of blocks spans a quad block boundary.
*
* Returns block number of first block allocated or -1 on failure.
*
*****************************************************************************/
PRInt32
nsDiskCacheBlockFile::AllocateBlocks(PRInt32 numBlocks)
{
if (!mFD) return -1; // NS_ERROR_NOT_AVAILABLE;
// return -1 if unable to allocate blocks
// PRUint8 mask = (0x01 << numBlocks) - 1;
int i = 0;
PRUint8 mapByte;
PRUint8 mask;
// presume allocation will succeed
PRBool oldValue = mBitMapDirty;
mBitMapDirty = PR_TRUE;
while ((mBitMap[i] == 0xFF) && (i < kBitMapBytes)) ++i; // find first block with a free bit
if (numBlocks == 1) {
if (i < kBitMapBytes) {
// don't need a while loop, because we know there's at least 1 free bit in this byte
mapByte = ~mBitMap[i]; // flip bits so free bits are 1
/*
* // Linear search for first free bit in byte
* mask = 0x01;
* for (int j=0; j<8; ++j, mask <<= 1)
* if (mask & mapByte) {mBitMap[i] |= mask; return (i * 8 + j); }
*/
// Binary search for first free bit in byte
PRUint8 bit = 0;
if ((mapByte & 0x0F) == 0) { bit |= 4; mapByte >>= 4; }
if ((mapByte & 0x03) == 0) { bit |= 2; mapByte >>= 2; }
if ((mapByte & 0x01) == 0) { bit |= 1; mapByte >>= 1; }
mBitMap[i] |= (PRUint8)1 << bit;
return i * 8 + bit;
}
} else if (numBlocks == 2) {
while (i < kBitMapBytes) {
mapByte = ~mBitMap[i]; // flip bits so free bits are 1
mask = 0x03;
// check for fit in lower quad bits
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8); } mask <<= 1;
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 1); } mask <<= 1;
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 2); } mask <<= 2;
// check for fit in upper quad bits
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 4); } mask <<= 1;
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 5); } mask <<= 1;
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 6); }
++i;
}
} else if (numBlocks == 3) {
while (i < kBitMapBytes) {
mapByte = ~mBitMap[i]; // flip bits so free bits are 1
mask = 0x07;
// check for fit in lower quad bits
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8); } mask <<= 1;
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 1); } mask <<= 3;
// check for fit in upper quad bits
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 4); } mask <<= 1;
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 5); }
++i;
}
} else if (numBlocks == 4) {
while (i < kBitMapBytes) {
mapByte = ~mBitMap[i]; // flip bits so free bits are 1
mask = 0x0F;
// check for fit in lower quad bits
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8); } mask <<= 4;
// check for fit in upper quad bits
if ((mask & mapByte) == mask) { mBitMap[i] |= mask; return (i * 8 + 4); }
++i;
}
}
mBitMapDirty = oldValue;
return -1;
}
/******************************************************************************
* DeallocateBlocks
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::DeallocateBlocks( PRInt32 startBlock, PRInt32 numBlocks)
{
if (!mFD) return NS_ERROR_NOT_AVAILABLE;
if ((startBlock < 0) || (startBlock > kBitMapBytes * 8 - 1) ||
(numBlocks < 1) || (numBlocks > 4))
return NS_ERROR_ILLEGAL_VALUE;
PRInt32 startByte = startBlock / 8;
PRUint8 startBit = startBlock % 8;
// make sure requested deallocation doesn't span a byte boundary
if ((startBlock + numBlocks - 1) / 8 != startByte) return NS_ERROR_UNEXPECTED;
PRUint8 mask = ((0x01 << numBlocks) - 1) << startBit;
PRUint8 mapByte = ~mBitMap[startByte]; // flip so allocated bits are zero
// make sure requested deallocation is currently allocated
if (mapByte & mask) return NS_ERROR_ABORT;
mBitMap[startByte] ^= mask; // flips the bits off;
mBitMapDirty = PR_TRUE;
// XXX rv = FlushBitMap(); // coherency vs. performance
return NS_OK;
}
/******************************************************************************
* WriteBlocks
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::WriteBlocks( void * buffer,
PRInt32 startBlock,
PRInt32 numBlocks)
{
// presume buffer != nsnull
if (!mFD) return NS_ERROR_NOT_AVAILABLE;
nsresult rv = VerifyAllocation(startBlock, numBlocks);
if (NS_FAILED(rv)) return rv;
// seek to block position
PRInt32 blockPos = kBitMapBytes + startBlock * mBlockSize;
PRInt32 filePos = PR_Seek(mFD, blockPos, PR_SEEK_SET);
if (filePos != blockPos) return NS_ERROR_UNEXPECTED;
if (mEndOfFile < (blockPos + numBlocks * mBlockSize))
mEndOfFile = (blockPos + numBlocks * mBlockSize);
// write the blocks
PRInt32 bytesToWrite = numBlocks * mBlockSize;
PRInt32 bytesWritten = PR_Write(mFD, buffer, bytesToWrite);
if (bytesWritten < bytesToWrite) return NS_ERROR_UNEXPECTED;
// write the bit map and flush the file
// XXX rv = FlushBitMap();
return rv;
}
/******************************************************************************
* ReadBlocks
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::ReadBlocks( void * buffer,
PRInt32 startBlock,
PRInt32 numBlocks)
{
// presume buffer != nsnull
if (!mFD) return NS_ERROR_NOT_AVAILABLE;
nsresult rv = VerifyAllocation(startBlock, numBlocks);
if (NS_FAILED(rv)) return rv;
// seek to block position
PRInt32 blockPos = kBitMapBytes + startBlock * mBlockSize;
PRInt32 filePos = PR_Seek(mFD, blockPos, PR_SEEK_SET);
if (filePos != blockPos) return NS_ERROR_UNEXPECTED;
// read the blocks
PRInt32 bytesToRead = numBlocks * mBlockSize;
PRInt32 bytesRead = PR_Read(mFD, buffer, bytesToRead);
if (bytesRead < bytesToRead) return NS_ERROR_UNEXPECTED;
return rv;
}
/******************************************************************************
* FlushBitMap
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::FlushBitMap()
{
if (!mBitMapDirty) return NS_OK;
// seek to bitmap
PRInt32 filePos = PR_Seek(mFD, 0, PR_SEEK_SET);
if (filePos != 0) return NS_ERROR_UNEXPECTED;
// write bitmap
PRInt32 bytesWritten = PR_Write(mFD, mBitMap, kBitMapBytes);
if (bytesWritten < kBitMapBytes) return NS_ERROR_UNEXPECTED;
PRStatus err = PR_Sync(mFD);
if (err != PR_SUCCESS) return NS_ERROR_UNEXPECTED;
mBitMapDirty = PR_FALSE;
return NS_OK;
}
/******************************************************************************
* ValidateFile
*
* Check size of file against last bit allocated for mBlockSize.
*
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::ValidateFile()
{
PRInt32 estimatedSize = kBitMapBytes;
PRInt32 lastBlock = LastBlock();
if (lastBlock >= 0)
estimatedSize += (lastBlock + 1) * mBlockSize;
// seek to beginning
PRInt32 filePos = PR_Seek(mFD, 0, PR_SEEK_SET);
if (filePos != 0) return NS_ERROR_UNEXPECTED;
PRInt32 fileSize = PR_Available(mFD);
if (estimatedSize > fileSize)
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
/******************************************************************************
* VerfiyAllocation
*
* Return values:
* NS_OK if all bits are marked allocated
* NS_ERROR_ILLEGAL_VALUE if parameters don't obey constraints
* NS_ERROR_FAILURE if some or all the bits are marked unallocated
*
*****************************************************************************/
nsresult
nsDiskCacheBlockFile::VerifyAllocation( PRInt32 startBlock, PRInt32 numBlocks)
{
if ((startBlock < 0) || (startBlock > kBitMapBytes * 8 - 1) ||
(numBlocks < 1) || (numBlocks > 4))
return NS_ERROR_ILLEGAL_VALUE;
PRInt32 startByte = startBlock / 8;
PRUint8 startBit = startBlock % 8;
// make sure requested deallocation doesn't span a byte boundary
if ((startBlock + numBlocks - 1) / 8 != startByte) return NS_ERROR_ILLEGAL_VALUE;
PRUint8 mask = ((0x01 << numBlocks) - 1) << startBit;
// check if all specified blocks are currently allocated
if ((mBitMap[startByte] & mask) != mask) return NS_ERROR_FAILURE;
return NS_OK;
}
/******************************************************************************
* LastBlock
*
* Return last block allocated or -1 if no blocks are allocated.
*
*****************************************************************************/
PRInt32
nsDiskCacheBlockFile::LastBlock()
{
// search for last byte in mBitMap with allocated bits
PRInt32 i = kBitMapBytes;
while (--i >= 0) {
if (mBitMap[i]) break;
}
if (i >= 0) {
// binary search to find last allocated bit in byte
PRUint8 mapByte = mBitMap[i];
PRUint8 lastBit = 7;
if ((mapByte & 0xF0) == 0) { lastBit ^= 4; mapByte <<= 4; }
if ((mapByte & 0xC0) == 0) { lastBit ^= 2; mapByte <<= 2; }
if ((mapByte & 0x80) == 0) { lastBit ^= 1; mapByte <<= 1; }
return i * 8 + lastBit;
}
return -1;
}

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheBlockFile.h, released April 12, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
*/
#ifndef _nsDiskCacheBlockFile_h_
#define _nsDiskCacheBlockFile_h_
#include "nsILocalFile.h"
#include "nspr.h"
enum { kBitMapBytes = 4096 };
/******************************************************************************
* nsDiskCacheBlockFile
*
* The structure of a cache block file is a 4096 bytes bit map, followed by
* some number of blocks of mBlockSize. The creator of a
* nsDiskCacheBlockFile object must provide the block size for a given file.
*
*****************************************************************************/
class nsDiskCacheBlockFile {
public:
nsDiskCacheBlockFile()
: mFD(nsnull)
, mBlockSize(0)
, mEndOfFile(0)
, mBitMap(nsnull)
, mBitMapDirty(PR_FALSE)
{}
~nsDiskCacheBlockFile() { (void) Close(); }
nsresult Open( nsILocalFile * blockFile, PRUint32 blockSize);
nsresult Close();
nsresult Trim();
PRInt32 AllocateBlocks( PRInt32 numBlocks);
nsresult DeallocateBlocks( PRInt32 startBlock, PRInt32 numBlocks);
nsresult WriteBlocks( void * buffer, PRInt32 startBlock, PRInt32 numBlocks);
nsresult ReadBlocks( void * buffer, PRInt32 startBlock, PRInt32 numBlocks);
private:
nsresult FlushBitMap();
nsresult ValidateFile(); // called by Open()
nsresult VerifyAllocation( PRInt32 startBlock, PRInt32 numBLocks);
PRInt32 LastBlock();
/**
* Data members
*/
PRFileDesc * mFD;
PRUint32 mBlockSize;
PRUint32 mEndOfFile;
PRUint8 * mBitMap; // XXX future: array of bit map blocks
PRBool mBitMapDirty;
};
#endif // _nsDiskCacheBlockFile_h_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheDevice.h, released February 20, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
*/
#ifndef _nsDiskCacheDevice_h_
#define _nsDiskCacheDevice_h_
#include "nsCacheDevice.h"
#include "nsDiskCacheBinding.h"
#include "nsDiskCacheBlockFile.h"
#include "nsDiskCacheEntry.h"
#include "nsILocalFile.h"
#include "nsIObserver.h"
class nsDiskCacheMap;
class nsDiskCacheDevice : public nsCacheDevice {
public:
nsDiskCacheDevice();
virtual ~nsDiskCacheDevice();
static nsresult Create(nsCacheDevice **result);
virtual nsresult Init();
virtual nsresult Shutdown();
virtual const char * GetDeviceID(void);
virtual nsCacheEntry * FindEntry(nsCString * key);
virtual nsresult DeactivateEntry(nsCacheEntry * entry);
virtual nsresult BindEntry(nsCacheEntry * entry);
virtual void DoomEntry( nsCacheEntry * entry );
virtual nsresult GetTransportForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** result);
virtual nsresult GetFileForEntry(nsCacheEntry * entry,
nsIFile ** result);
virtual nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize);
virtual nsresult Visit(nsICacheVisitor * visitor);
virtual nsresult EvictEntries(const char * clientID);
/* private: */
void setPrefsObserver(nsIObserver * observer);
void getPrefsObserver(nsIObserver ** result);
void setCacheDirectory(nsILocalFile * directory);
void getCacheDirectory(nsILocalFile ** result);
void setCacheCapacity(PRUint32 capacity);
PRUint32 getCacheCapacity();
PRUint32 getCacheSize();
PRUint32 getEntryCount();
private:
/**
* Private methods
*/
nsresult InitializeCacheDirectory();
nsresult GetCacheTrashDirectory(nsIFile ** result);
nsresult EvictDiskCacheEntries();
/**
* Member variables
*/
PRBool mInitialized;
nsCOMPtr<nsIObserver> mPrefsObserver; // XXX ?
nsCOMPtr<nsILocalFile> mCacheDirectory;
nsDiskCacheBindery mBindery;
PRUint32 mCacheCapacity; // XXX need soft/hard limits, currentTotal
nsDiskCacheMap * mCacheMap;
};
#endif // _nsDiskCacheDevice_h_

View File

@@ -0,0 +1,211 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheEntry.cpp, released May 10, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
*/
#include "nsDiskCache.h"
#include "nsDiskCacheEntry.h"
#include "nsDiskCacheBinding.h"
#include "nsDiskCacheMap.h"
#include "nsCache.h"
/******************************************************************************
* nsDiskCacheEntry
*****************************************************************************/
/**
* CreateCacheEntry()
*
* Creates an nsCacheEntry and sets all fields except for the binding.
*/
nsCacheEntry *
nsDiskCacheEntry::CreateCacheEntry(nsCacheDevice * device)
{
nsCacheEntry * entry = nsnull;
nsresult rv = nsCacheEntry::Create(mKeyStart,
nsICache::STREAM_BASED,
nsICache::STORE_ON_DISK,
device,
&entry);
if (NS_FAILED(rv) || !entry) return nsnull;
entry->SetFetchCount(mFetchCount);
entry->SetLastFetched(mLastFetched);
entry->SetLastModified(mLastModified);
entry->SetExpirationTime(mExpirationTime);
entry->SetCacheDevice(device);
// XXX why does nsCacheService have to fill out device in BindEntry()?
entry->SetDataSize(mDataSize);
rv = entry->UnflattenMetaData(&mKeyStart[mKeySize], mMetaDataSize);
if (NS_FAILED(rv)) {
delete entry;
return nsnull;
}
return entry;
}
/**
* CheckConsistency()
*
* Perform a few simple checks to verify the data looks reasonable.
*/
PRBool
nsDiskCacheEntry::CheckConsistency(PRUint32 size)
{
if ((mHeaderVersion != nsDiskCache::kCurrentVersion) ||
(Size() > size) ||
(mKeySize == 0) ||
(mKeyStart[mKeySize - 1] != 0)) // key is null terminated
return PR_FALSE;
return PR_TRUE;
}
/**
* CreateDiskCacheEntry(nsCacheEntry * entry)
*
* Prepare an nsCacheEntry for writing to disk
*/
nsDiskCacheEntry *
CreateDiskCacheEntry(nsDiskCacheBinding * binding)
{
nsCacheEntry * entry = binding->mCacheEntry;
if (!entry) return nsnull;
PRUint32 keySize = entry->Key()->Length() + 1;
PRUint32 size = sizeof(nsDiskCacheEntry) +
keySize + entry->MetaDataSize();
// pad size so we can write to block files without overrunning buffer
PRInt32 pad = size;
if (pad < 1024) pad = 1024;
else if (pad < 4096) pad = 4096;
else if (pad < 16384) pad = 16384;
// XXX be more precise
nsDiskCacheEntry * diskEntry = (nsDiskCacheEntry *)new char[pad];
if (!diskEntry) return nsnull;
diskEntry->mHeaderVersion = nsDiskCache::kCurrentVersion;
diskEntry->mMetaLocation = binding->mRecord.MetaLocation();
diskEntry->mFetchCount = entry->FetchCount();
diskEntry->mLastFetched = entry->LastFetched();
diskEntry->mLastModified = entry->LastModified();
diskEntry->mExpirationTime = entry->ExpirationTime();
diskEntry->mDataSize = entry->DataSize();
diskEntry->mKeySize = keySize;
diskEntry->mMetaDataSize = entry->MetaDataSize();
nsCRT::memcpy(diskEntry->mKeyStart, entry->Key()->get(),keySize);
// XXX FIXME FlattenMetaData should not allocate a buffer
char * metaData = nsnull;
PRUint32 metaSize = 0;
nsresult rv = entry->FlattenMetaData(&metaData, &metaSize);
if (NS_FAILED(rv)) {
delete diskEntry;
return nsnull;
}
diskEntry->mMetaDataSize = metaSize;
if (metaSize)
nsCRT::memcpy(&diskEntry->mKeyStart[keySize], metaData, metaSize);
delete metaData;
return diskEntry;
}
/******************************************************************************
* nsDiskCacheEntryInfo
*****************************************************************************/
NS_IMPL_ISUPPORTS1(nsDiskCacheEntryInfo, nsICacheEntryInfo);
NS_IMETHODIMP nsDiskCacheEntryInfo::GetClientID(char ** clientID)
{
NS_ENSURE_ARG_POINTER(clientID);
return ClientIDFromCacheKey(nsLiteralCString(mDiskEntry->mKeyStart), clientID);
}
extern const char DISK_CACHE_DEVICE_ID[];
NS_IMETHODIMP nsDiskCacheEntryInfo::GetDeviceID(char ** deviceID)
{
NS_ENSURE_ARG_POINTER(deviceID);
*deviceID = nsCRT::strdup(mDeviceID);
return *deviceID ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP nsDiskCacheEntryInfo::GetKey(char ** clientKey)
{
NS_ENSURE_ARG_POINTER(clientKey);
return ClientKeyFromCacheKey(nsLiteralCString(mDiskEntry->mKeyStart), clientKey);
}
NS_IMETHODIMP nsDiskCacheEntryInfo::GetFetchCount(PRInt32 *aFetchCount)
{
NS_ENSURE_ARG_POINTER(aFetchCount);
*aFetchCount = mDiskEntry->mFetchCount;
return NS_OK;
}
NS_IMETHODIMP nsDiskCacheEntryInfo::GetLastFetched(PRUint32 *aLastFetched)
{
NS_ENSURE_ARG_POINTER(aLastFetched);
*aLastFetched = mDiskEntry->mLastFetched;
return NS_OK;
}
NS_IMETHODIMP nsDiskCacheEntryInfo::GetLastModified(PRUint32 *aLastModified)
{
NS_ENSURE_ARG_POINTER(aLastModified);
*aLastModified = mDiskEntry->mLastModified;
return NS_OK;
}
NS_IMETHODIMP nsDiskCacheEntryInfo::GetExpirationTime(PRUint32 *aExpirationTime)
{
NS_ENSURE_ARG_POINTER(aExpirationTime);
*aExpirationTime = mDiskEntry->mExpirationTime;
return NS_OK;
}
NS_IMETHODIMP nsDiskCacheEntryInfo::IsStreamBased(PRBool *aStreamBased)
{
NS_ENSURE_ARG_POINTER(aStreamBased);
*aStreamBased = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP nsDiskCacheEntryInfo::GetDataSize(PRUint32 *aDataSize)
{
NS_ENSURE_ARG_POINTER(aDataSize);
*aDataSize = mDiskEntry->mDataSize;
return NS_OK;
}

View File

@@ -0,0 +1,126 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsMemoryCacheDevice.cpp, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
*/
#ifndef _nsDiskCacheEntry_h_
#define _nsDiskCacheEntry_h_
#include "nsDiskCacheMap.h"
#include "nsCacheEntry.h"
#include "nsICacheVisitor.h"
#include "nspr.h"
#include "nscore.h"
#include "nsError.h"
/******************************************************************************
* nsDiskCacheEntry
*****************************************************************************/
struct nsDiskCacheEntry {
PRUint32 mHeaderVersion; // useful for stand-alone metadata files
PRUint32 mMetaLocation; // for verification
PRInt32 mFetchCount;
PRUint32 mLastFetched;
PRUint32 mLastModified;
PRUint32 mExpirationTime;
PRUint32 mDataSize;
PRUint32 mKeySize; // includes terminating null byte
PRUint32 mMetaDataSize; // includes terminating null byte
char mKeyStart[1]; // start of key data
// mMetaDataStart = mKeyStart[mKeySize];
PRUint32 Size() { return sizeof(nsDiskCacheEntry)
- sizeof(char) // subtract default key size
+ mKeySize // plus actual key size
+ mMetaDataSize;
}
nsCacheEntry * CreateCacheEntry(nsCacheDevice * device);
PRBool CheckConsistency(PRUint32 size);
void Swap() // host to network (memory to disk)
{
#if defined(IS_LITTLE_ENDIAN)
mHeaderVersion = ::PR_htonl(mHeaderVersion);
mMetaLocation = ::PR_htonl(mMetaLocation);
mFetchCount = ::PR_htonl(mFetchCount);
mLastFetched = ::PR_htonl(mLastFetched);
mLastModified = ::PR_htonl(mLastModified);
mExpirationTime = ::PR_htonl(mExpirationTime);
mDataSize = ::PR_htonl(mDataSize);
mKeySize = ::PR_htonl(mKeySize);
mMetaDataSize = ::PR_htonl(mMetaDataSize);
#endif
}
void Unswap() // network to host (disk to memory)
{
#if defined(IS_LITTLE_ENDIAN)
mHeaderVersion = ::PR_ntohl(mHeaderVersion);
mMetaLocation = ::PR_ntohl(mMetaLocation);
mFetchCount = ::PR_ntohl(mFetchCount);
mLastFetched = ::PR_ntohl(mLastFetched);
mLastModified = ::PR_ntohl(mLastModified);
mExpirationTime = ::PR_ntohl(mExpirationTime);
mDataSize = ::PR_ntohl(mDataSize);
mKeySize = ::PR_ntohl(mKeySize);
mMetaDataSize = ::PR_ntohl(mMetaDataSize);
#endif
}
};
nsDiskCacheEntry * CreateDiskCacheEntry(nsDiskCacheBinding * binding);
/******************************************************************************
* nsDiskCacheEntryInfo
*****************************************************************************/
class nsDiskCacheEntryInfo : public nsICacheEntryInfo {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICACHEENTRYINFO
nsDiskCacheEntryInfo(const char * deviceID, nsDiskCacheEntry * diskEntry)
: mDeviceID(deviceID)
, mDiskEntry(diskEntry)
{
NS_INIT_ISUPPORTS();
}
virtual ~nsDiskCacheEntryInfo() {}
const char* Key() { return mDiskEntry->mKeyStart; }
private:
const char * mDeviceID;
nsDiskCacheEntry * mDiskEntry;
};
#endif /* _nsDiskCacheEntry_h_ */

View File

@@ -0,0 +1,836 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheMap.cpp, released March 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Patrick C. Beard <beard@netscape.com>
* Gordon Sheridan <gordon@netscape.com>
*/
#include "nsDiskCacheMap.h"
#include "nsDiskCacheBinding.h"
#include "nsDiskCacheEntry.h"
#include "nsCache.h"
#include "nsCRT.h"
#include <string.h>
/******************************************************************************
* nsDiskCacheBucket
*****************************************************************************/
void
nsDiskCacheBucket::Swap()
{
nsDiskCacheRecord * record = &mRecords[0];
for (int i = 0; i < kRecordsPerBucket; ++i) {
if (record->HashNumber() == 0)
break;
record->Swap();
}
}
void
nsDiskCacheBucket::Unswap()
{
nsDiskCacheRecord * record = &mRecords[0];
for (int i = 0; i < kRecordsPerBucket; ++i) {
if (record->HashNumber() == 0)
break;
record->Unswap();
}
}
PRUint32
nsDiskCacheBucket::CountRecords()
{
if (mRecords[0].HashNumber() == 0) return 0;
PRUint32 i = kRecordsPerBucket >> 1;
PRUint32 offset = kRecordsPerBucket >> 2;
while (offset > 0) {
if (mRecords[i].HashNumber()) i += offset;
else i -= offset;
offset >>= 1;
}
if (mRecords[i].HashNumber() != 0)
++i;
return i;
}
PRUint32
nsDiskCacheBucket::EvictionRank()
{
PRUint32 rank = 0;
for (int i = CountRecords() - 1; i >= 0; --i) {
if (rank < mRecords[i].EvictionRank())
rank = mRecords[i].EvictionRank();
}
return rank;
}
PRInt32
nsDiskCacheBucket::VisitEachRecord(nsDiskCacheRecordVisitor * visitor,
PRUint32 evictionRank,
PRUint32 * result)
{
PRUint32 recordsDeleted = 0;
PRInt32 rv = kVisitNextRecord;
PRInt32 last = CountRecords() - 1;
// call visitor for each entry (equal or greater than evictionRank)
for (int i = last; i >= 0; i--) {
if (evictionRank > mRecords[i].EvictionRank()) continue;
rv = visitor->VisitRecord(&mRecords[i]);
if (rv == kVisitNextRecord) continue;
if (rv == kDeleteRecordAndContinue) {
mRecords[i] = mRecords[last];
mRecords[last].SetHashNumber(0);
--last;
++recordsDeleted;
continue;
}
*result = recordsDeleted;
return kStopVisitingRecords; // rv == kStopVisitingRecords
}
*result = recordsDeleted;
return rv;
}
/******************************************************************************
* nsDiskCacheMap
*****************************************************************************/
/**
* File operations
*/
nsresult
nsDiskCacheMap::Open(nsILocalFile * cacheDirectory)
{
NS_ENSURE_ARG_POINTER(cacheDirectory);
if (mMapFD) return NS_ERROR_ALREADY_INITIALIZED;
mCacheDirectory = cacheDirectory; // save a reference for ourselves
// create nsILocalFile for _CACHE_MAP_
nsresult rv;
nsCOMPtr<nsIFile> file;
rv = cacheDirectory->Clone(getter_AddRefs(file));
nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file, &rv));
if (NS_FAILED(rv)) return rv;
rv = localFile->Append("_CACHE_MAP_");
if (NS_FAILED(rv)) return rv;
// open the file
rv = localFile->OpenNSPRFileDesc(PR_RDWR | PR_CREATE_FILE, 00666, &mMapFD);
if (NS_FAILED(rv)) return rv; // unable to open or create file
// check size of map file
PRUint32 mapSize = PR_Available(mMapFD);
if (mapSize < 0) {
rv = NS_ERROR_UNEXPECTED;
goto error_exit;
}
if (mapSize == 0) {
// create the file - initialize in memory
mHeader.mVersion = nsDiskCache::kCurrentVersion;
mHeader.mDataSize = 0;
mHeader.mEntryCount = 0;
mHeader.mIsDirty = PR_TRUE;
for (int i = 0; i < kBucketsPerTable; ++i) {
mHeader.mEvictionRank[i] = 0;
}
nsCRT::zero(mHeader.reserved, nsDiskCacheHeader::kReservedBytes);
nsCRT::zero(mBuckets, sizeof(nsDiskCacheBucket) * kBucketsPerTable);
} else if (mapSize == kCacheMapSize) {
// read it in
PRUint32 bytesRead = PR_Read(mMapFD, &mHeader, kCacheMapSize);
if (kCacheMapSize != bytesRead) {
rv = NS_ERROR_UNEXPECTED;
goto error_exit;
}
mHeader.Unswap();
if (mHeader.mIsDirty || mHeader.mVersion != nsDiskCache::kCurrentVersion) {
rv = NS_ERROR_FILE_CORRUPTED;
goto error_exit;
}
// Unswap each bucket
for (PRUint32 i = 0; i < kBucketsPerTable; ++i) {
mBuckets[i].Unswap();
}
// XXX verify entry count, check size(?)
} else {
rv = NS_ERROR_FILE_CORRUPTED;
goto error_exit;
}
rv = OpenBlockFiles();
if (NS_FAILED(rv)) goto error_exit;
// set dirty bit and flush header
mHeader.mIsDirty = PR_TRUE;
rv = FlushHeader();
if (NS_FAILED(rv)) goto error_exit;
return NS_OK;
error_exit:
(void) CloseBlockFiles();
if (mMapFD) {
(void) PR_Close(mMapFD);
mMapFD = nsnull;
}
return rv;
}
nsresult
nsDiskCacheMap::Close()
{
if (!mMapFD) return NS_OK;
// close block files
nsresult rv = CloseBlockFiles();
if (NS_FAILED(rv)) goto exit; // this is going to be a mess...
// write map record buckets
rv = FlushBuckets(PR_FALSE); // don't bother swapping buckets back
if (NS_FAILED(rv)) goto exit;
// clear dirty bit
mHeader.mIsDirty = PR_FALSE;
rv = FlushHeader();
exit:
PRStatus err = PR_Close(mMapFD);
mMapFD = nsnull;
if (NS_FAILED(rv)) return rv;
return err == PR_SUCCESS ? NS_OK : NS_ERROR_UNEXPECTED;
}
nsresult
nsDiskCacheMap::FlushHeader()
{
if (!mMapFD) return NS_ERROR_NOT_AVAILABLE;
// seek to beginning of cache map
PRInt32 filePos = PR_Seek(mMapFD, 0, PR_SEEK_SET);
if (filePos != 0) return NS_ERROR_UNEXPECTED;
// write the header
mHeader.Swap();
PRInt32 bytesWritten = PR_Write(mMapFD, &mHeader, sizeof(nsDiskCacheHeader));
mHeader.Unswap();
if (sizeof(nsDiskCacheHeader) != bytesWritten) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
nsresult
nsDiskCacheMap::FlushBuckets(PRBool unswap)
{
if (!mMapFD) return NS_ERROR_NOT_AVAILABLE;
// seek to beginning of buckets
PRInt32 filePos = PR_Seek(mMapFD, sizeof(nsDiskCacheHeader), PR_SEEK_SET);
if (filePos != sizeof(nsDiskCacheHeader)) return NS_ERROR_UNEXPECTED;
// Swap each bucket
for (PRUint32 i = 0; i < kBucketsPerTable; ++i) {
mBuckets[i].Swap();
}
PRInt32 bytesWritten = PR_Write(mMapFD, &mBuckets, sizeof(nsDiskCacheBucket) * kBucketsPerTable);
if (unswap) {
// Unswap each bucket
for (PRUint32 i = 0; i < kBucketsPerTable; ++i) {
mBuckets[i].Unswap();
}
}
if ( sizeof(nsDiskCacheBucket) * kBucketsPerTable != bytesWritten) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
/**
* Record operations
*/
nsresult
nsDiskCacheMap::AddRecord( nsDiskCacheRecord * mapRecord,
nsDiskCacheRecord * oldRecord)
{
nsresult rv;
PRUint32 hashNumber = mapRecord->HashNumber();
nsDiskCacheBucket * bucket;
PRUint32 bucketIndex = GetBucketIndex(hashNumber);
int i;
oldRecord->SetHashNumber(0); // signify no record
rv = GetBucketForHashNumber(hashNumber, &bucket);
if (NS_FAILED(rv)) return rv;
nsDiskCacheRecord * mostEvictable = &bucket->mRecords[0];
for (i = 0; i < kRecordsPerBucket; ++i) {
if (bucket->mRecords[i].HashNumber() == 0) {
// stick the new record here
bucket->mRecords[i] = *mapRecord;
++mHeader.mEntryCount;
// update eviction rank in header if necessary
if (mHeader.mEvictionRank[bucketIndex] < mapRecord->EvictionRank())
mHeader.mEvictionRank[bucketIndex] = mapRecord->EvictionRank();
NS_ASSERTION(mHeader.mEvictionRank[bucketIndex] == bucket->EvictionRank(), "whao!");
return NS_OK;
}
if (bucket->mRecords[i].EvictionRank() > mostEvictable->EvictionRank())
mostEvictable = &bucket->mRecords[i];
}
*oldRecord = *mostEvictable; // i == kRecordsPerBucket, so evict the mostEvictable
*mostEvictable = *mapRecord; // replace it with the new record
// check if we need to update mostEvictable entry in header
if ((oldRecord->HashNumber() != 0) ||
(mapRecord->EvictionRank() > mHeader.mEvictionRank[bucketIndex])) {
mHeader.mEvictionRank[bucketIndex] = bucket->EvictionRank();
}
NS_ASSERTION(mHeader.mEvictionRank[bucketIndex] == bucket->EvictionRank(), "whao!");
return NS_OK;
}
nsresult
nsDiskCacheMap::UpdateRecord( nsDiskCacheRecord * mapRecord)
{
PRUint32 hashNumber = mapRecord->HashNumber();
nsDiskCacheBucket * bucket;
nsresult rv = GetBucketForHashNumber(hashNumber, &bucket);
if (NS_FAILED(rv)) return rv;
for (int i = 0; i < kRecordsPerBucket; ++i) {
if (bucket->mRecords[i].HashNumber() == mapRecord->HashNumber()) {
PRUint32 oldRank = bucket->mRecords[i].EvictionRank();
// stick the new record here
bucket->mRecords[i] = *mapRecord;
// update eviction rank in header if necessary
PRUint32 bucketIndex = GetBucketIndex(mapRecord->HashNumber());
if (mHeader.mEvictionRank[bucketIndex] < mapRecord->EvictionRank())
mHeader.mEvictionRank[bucketIndex] = mapRecord->EvictionRank();
else if (mHeader.mEvictionRank[bucketIndex] == oldRank)
mHeader.mEvictionRank[bucketIndex] = bucket->EvictionRank();
NS_ASSERTION(mHeader.mEvictionRank[bucketIndex] == bucket->EvictionRank(), "whao!");
return NS_OK;
}
}
return NS_ERROR_UNEXPECTED;
}
nsresult
nsDiskCacheMap::FindRecord( PRUint32 hashNumber, nsDiskCacheRecord * result)
{
nsDiskCacheBucket * bucket;
nsresult rv = GetBucketForHashNumber(hashNumber, &bucket);
if (NS_FAILED(rv)) return rv;
for (int i = 0; i < kRecordsPerBucket; ++i) {
if (bucket->mRecords[i].HashNumber() == 0) break;
if (bucket->mRecords[i].HashNumber() == hashNumber) {
*result = bucket->mRecords[i]; // copy the record
NS_ASSERTION(result->ValidRecord(), "bad cache map record");
return NS_OK;
}
}
return NS_ERROR_CACHE_KEY_NOT_FOUND;
}
nsresult
nsDiskCacheMap::DeleteRecord( nsDiskCacheRecord * mapRecord)
{
nsDiskCacheBucket * bucket;
nsresult rv = GetBucketForHashNumber(mapRecord->HashNumber(), &bucket);
if (NS_FAILED(rv)) return rv;
PRUint32 count = bucket->CountRecords();
for (PRUint32 i = 0; i < count; ++i) {
if (bucket->mRecords[i].HashNumber() == mapRecord->HashNumber()) {
// found it, now delete it.
PRUint32 evictionRank = bucket->mRecords[i].EvictionRank();
NS_ASSERTION(evictionRank == mapRecord->EvictionRank(), "evictionRank out of sync");
if (i != (count - 1)) { // if not the last record, shift last record into opening
bucket->mRecords[i] = bucket->mRecords[count - 1];
}
bucket->mRecords[count - 1].SetHashNumber(0); // clear last record
mHeader.mEntryCount--;
// update eviction rank
PRUint32 bucketIndex = GetBucketIndex(mapRecord->HashNumber());
if (mHeader.mEvictionRank[bucketIndex] <= evictionRank) {
mHeader.mEvictionRank[bucketIndex] = bucket->EvictionRank();
}
NS_ASSERTION(mHeader.mEvictionRank[bucketIndex] == bucket->EvictionRank(), "whao!");
return NS_OK;
}
}
return NS_ERROR_UNEXPECTED;
}
/**
* VisitRecords
*
* Visit every record in cache map in the most convenient order
*/
nsresult
nsDiskCacheMap::VisitRecords( nsDiskCacheRecordVisitor * visitor)
{
for (PRUint32 i = 0; i < kBucketsPerTable; ++i) {
// get bucket
PRUint32 recordsDeleted;
PRBool continueFlag = mBuckets[i].VisitEachRecord(visitor, 0, &recordsDeleted);
if (recordsDeleted) {
// recalc eviction rank
mHeader.mEvictionRank[i] = mBuckets[i].EvictionRank();
mHeader.mEntryCount -= recordsDeleted;
// XXX write bucket
}
NS_ASSERTION(mHeader.mEvictionRank[i] == mBuckets[i].EvictionRank(), "whao!");
if (!continueFlag) break;
}
return NS_OK;
}
/**
* EvictRecords
*
* Just like VisitRecords, but visits the records in order of their eviction rank
*/
nsresult
nsDiskCacheMap::EvictRecords( nsDiskCacheRecordVisitor * visitor)
{
while (1) {
// find bucket with highest eviction rank
PRUint32 rank = 0;
PRUint32 index = 0;
for (int i = 0; i < kBucketsPerTable; ++i) {
if (rank < mHeader.mEvictionRank[i]) {
rank = mHeader.mEvictionRank[i];
index = i;
}
}
NS_ASSERTION(mHeader.mEvictionRank[index] == mBuckets[index].EvictionRank(),
"header eviction rank out of sync");
// visit records in bucket with eviction ranks >= target eviction rank
PRUint32 recordsDeleted;
PRBool continueFlag = mBuckets[index].VisitEachRecord(visitor, rank, &recordsDeleted);
if (recordsDeleted) {
// recalc eviction rank
mHeader.mEvictionRank[index] = mBuckets[index].EvictionRank();
mHeader.mEntryCount -= recordsDeleted;
// XXX write bucket
}
if (!continueFlag) break;
// break if visitor returned stop
}
return NS_OK;
}
nsresult
nsDiskCacheMap::OpenBlockFiles()
{
// create nsILocalFile for block file
nsCOMPtr<nsILocalFile> blockFile;
nsresult rv;
for (int i = 0; i < 3; ++i) {
rv = GetBlockFileForIndex(i, getter_AddRefs(blockFile));
if (NS_FAILED(rv)) goto error_exit;
PRUint32 blockSize = GetBlockSizeForIndex(i);
rv = mBlockFile[i].Open(blockFile, blockSize);
if (NS_FAILED(rv)) goto error_exit;
}
return NS_OK;
error_exit:
(void)CloseBlockFiles(); // we already have an error to report
return rv;
}
nsresult
nsDiskCacheMap::CloseBlockFiles()
{
nsresult rv, rv2 = NS_OK;
for (int i=0; i < 3; ++i) {
rv = mBlockFile[i].Close();
if (NS_FAILED(rv)) rv2 = rv; // if one or more errors, report at least one
}
return rv2;
}
nsresult
nsDiskCacheMap::ReadDiskCacheEntry(nsDiskCacheRecord * record, nsDiskCacheEntry ** result)
{
nsresult rv;
nsDiskCacheEntry * diskEntry = nsnull;
PRUint32 metaFile = record->MetaFile();
PRFileDesc * fd = nsnull;
*result = nsnull;
if (metaFile == 0) { // entry/metadata stored in separate file
// open and read the file
nsCOMPtr<nsILocalFile> file;
rv = GetLocalFileForDiskCacheRecord(record, nsDiskCache::kMetaData, getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
PRFileDesc * fd = nsnull;
nsresult rv = file->OpenNSPRFileDesc(PR_RDONLY, 00666, &fd);
if (NS_FAILED(rv)) return rv;
PRInt32 fileSize = PR_Available(fd);
if (fileSize < 0) {
// XXX an error occurred. We could call PR_GetError(), but how would that help?
rv = NS_ERROR_UNEXPECTED;
goto exit;
}
diskEntry = (nsDiskCacheEntry *) new char[fileSize];
if (!diskEntry) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto exit;
}
PRInt32 bytesRead = PR_Read(fd, diskEntry, fileSize);
if (bytesRead < fileSize) {
rv = NS_ERROR_UNEXPECTED;
goto exit;
}
} else if (metaFile < 4) { // XXX magic number: use constant
// entry/metadata stored in cache block file
// allocate buffer
PRUint32 blockSize = GetBlockSizeForIndex(metaFile - 1);
PRUint32 blockCount = record->MetaBlockCount();
diskEntry = (nsDiskCacheEntry *) new char[blockSize * blockCount];
// read diskEntry
rv = mBlockFile[metaFile - 1].ReadBlocks((char *)diskEntry,
record->MetaStartBlock(),
blockCount);
if (NS_FAILED(rv)) goto exit;
}
diskEntry->Unswap(); // disk to memory
// pass ownership to caller
*result = diskEntry;
diskEntry = nsnull;
exit:
// XXX auto ptr would be nice
if (fd) (void) PR_Close(fd);
delete diskEntry;
return rv;
}
nsresult
nsDiskCacheMap::WriteDiskCacheEntry(nsDiskCacheBinding * binding)
{
nsresult rv = NS_OK;
nsDiskCacheEntry * diskEntry = CreateDiskCacheEntry(binding);
if (!diskEntry) return NS_ERROR_UNEXPECTED;
binding->mRecord.SetEvictionRank(ULONG_MAX - SecondsFromPRTime(PR_Now()));
PRUint32 size = diskEntry->Size();
PRUint32 fileIndex;
PRUint32 blocks;
if (size < 1024) { // block size 256
fileIndex = 1;
blocks = size / 256 + 1;
} else if (size < 4096) { // block size 1024
fileIndex = 2;
blocks = size / 1024 + 1;
} else if (size < 16384) { // block size 4096
fileIndex = 3;
blocks = size / 4096 + 1;
} else { // separate file
fileIndex = 0;
}
PRUint32 metaFile = binding->mRecord.MetaFile();
// Deallocate old storage if necessary
if (binding->mRecord.MetaLocationInitialized()) {
// we have existing storage
if ((metaFile == 0) && (fileIndex == 0)) { // keeping the separate file
// just decrement total
// XXX if bindRecord.MetaFileSize == USHRT_MAX, stat the file to see how big it is
DecrementTotalSize(binding->mRecord.MetaFileSize() * 1024);
NS_ASSERTION(binding->mRecord.MetaFileGeneration() == binding->mGeneration,
"generations out of sync");
} else {
rv = DeleteStorage(&binding->mRecord, nsDiskCache::kMetaData);
if (NS_FAILED(rv)) return rv;
}
}
if (fileIndex == 0) {
// Write entry data to separate file
PRUint32 metaFileSizeK = ((size + 0x0399) >> 10); // round up to nearest 1k
nsCOMPtr<nsILocalFile> localFile;
// XXX handle metaFileSizeK > USHRT_MAX
binding->mRecord.SetMetaFileGeneration(binding->mGeneration);
binding->mRecord.SetMetaFileSize(metaFileSizeK);
rv = UpdateRecord(&binding->mRecord);
if (NS_FAILED(rv)) goto exit;
rv = GetLocalFileForDiskCacheRecord(&binding->mRecord,
nsDiskCache::kMetaData,
getter_AddRefs(localFile));
if (NS_FAILED(rv)) goto exit;
// open the file
PRFileDesc * fd;
rv = localFile->OpenNSPRFileDesc(PR_RDWR | PR_TRUNCATE | PR_CREATE_FILE, 00666, &fd);
if (NS_FAILED(rv)) goto exit; // unable to open or create file
// write the file
diskEntry->Swap();
PRInt32 bytesWritten = PR_Write(fd, diskEntry, size);
PRStatus err = PR_Close(mMapFD);
if ((bytesWritten != size) || (err != PR_SUCCESS)) {
rv = NS_ERROR_UNEXPECTED;
goto exit;
}
// XXX handle metaFileSizeK == USHRT_MAX
IncrementTotalSize(metaFileSizeK * 1024);
} else {
// write entry data to disk cache block file
PRInt32 startBlock = mBlockFile[fileIndex - 1].AllocateBlocks(blocks);
if (startBlock < 0) {
rv = NS_ERROR_UNEXPECTED;
goto exit;
}
// update binding and cache map record
binding->mRecord.SetMetaBlocks(fileIndex, startBlock, blocks);
rv = UpdateRecord(&binding->mRecord);
if (NS_FAILED(rv)) goto exit;
// XXX we should probably write out bucket ourselves
// write data
diskEntry->Swap();
rv = mBlockFile[fileIndex - 1].WriteBlocks(diskEntry, startBlock, blocks);
if (NS_FAILED(rv)) goto exit;
IncrementTotalSize(blocks * GetBlockSizeForIndex(fileIndex - 1));
}
exit:
return rv;
}
nsresult
nsDiskCacheMap::DoomRecord(nsDiskCacheRecord * record)
{
nsresult rv = DeleteRecord(record);
// XXX future: add record to doomed record journal
return rv;
}
nsresult
nsDiskCacheMap::DeleteStorage(nsDiskCacheRecord * record)
{
nsresult rv1 = DeleteStorage(record, nsDiskCache::kData);
nsresult rv2 = DeleteStorage(record, nsDiskCache::kMetaData);
return NS_FAILED(rv1) ? rv1 : rv2;
}
nsresult
nsDiskCacheMap::DeleteStorage(nsDiskCacheRecord * record, PRBool metaData)
{
nsresult rv;
PRUint32 fileIndex = metaData ? record->MetaFile() : record->DataFile();
nsCOMPtr<nsIFile> file;
if (fileIndex == 0) {
// delete the file
PRUint32 sizeK = metaData ? record->MetaFileSize() : record->DataFileSize();
// XXX if sizeK == USHRT_MAX, stat file for actual size
rv = GetFileForDiskCacheRecord(record, metaData, getter_AddRefs(file));
if (NS_SUCCEEDED(rv)) {
rv = file->Delete(PR_FALSE); // false == non-recursive
}
DecrementTotalSize(sizeK * 1024);
} else if (fileIndex < 4) {
// deallocate blocks
PRInt32 startBlock = metaData ? record->MetaStartBlock() : record->DataStartBlock();
PRInt32 blockCount = metaData ? record->MetaBlockCount() : record->DataBlockCount();
rv = mBlockFile[fileIndex - 1].DeallocateBlocks(startBlock, blockCount);
DecrementTotalSize(blockCount * GetBlockSizeForIndex(fileIndex - 1));
}
return rv;
}
nsresult
nsDiskCacheMap::DeleteRecordAndStorage(nsDiskCacheRecord * record)
{
nsresult rv1 = DeleteStorage(record);
nsresult rv2 = DeleteRecord(record);
return NS_FAILED(rv1) ? rv1 : rv2;
}
nsresult
nsDiskCacheMap::GetFileForDiskCacheRecord(nsDiskCacheRecord * record,
PRBool meta,
nsIFile ** result)
{
if (!mCacheDirectory) return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<nsIFile> file;
nsresult rv = mCacheDirectory->Clone(getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
PRInt16 generation = record->Generation();
char name[32];
::sprintf(name, "%08X%c%02X", record->HashNumber(), (meta ? 'm' : 'd'), generation);
rv = file->Append(name);
if (NS_FAILED(rv)) return rv;
NS_IF_ADDREF(*result = file);
return rv;
}
nsresult
nsDiskCacheMap::GetLocalFileForDiskCacheRecord(nsDiskCacheRecord * record,
PRBool meta,
nsILocalFile ** result)
{
nsCOMPtr<nsIFile> file;
nsresult rv = GetFileForDiskCacheRecord(record, meta, getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv)) return rv;
NS_IF_ADDREF(*result = localFile);
return rv;
}
nsresult
nsDiskCacheMap::GetBlockFileForIndex(PRUint32 index, nsILocalFile ** result)
{
if (!mCacheDirectory) return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<nsIFile> file;
nsresult rv = mCacheDirectory->Clone(getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
char name[32];
::sprintf(name, "_CACHE_%03d_", index + 1);
rv = file->Append(name);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
NS_IF_ADDREF(*result = localFile);
return rv;
}
PRUint32
nsDiskCacheMap::GetBlockSizeForIndex(PRUint32 index)
{
return 256 << (2 * (index)); // XXX magic numbers
}

View File

@@ -0,0 +1,499 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsDiskCacheMap.h, released March 23, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Patrick C. Beard <beard@netscape.com>
* Gordon Sheridan <gordon@netscape.com>
*/
#ifndef _nsDiskCacheMap_h_
#define _nsDiskCacheMap_h_
#include <limits.h>
#include "prtypes.h"
#include "prnetdb.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsILocalFile.h"
#include "nsDiskCache.h"
#include "nsDiskCacheBlockFile.h"
class nsDiskCacheBinding;
class nsDiskCacheEntry;
/******************************************************************************
* nsDiskCacheRecord
*
* Cache Location Format
*
* 1000 0000 0000 0000 0000 0000 0000 0000 : initialized bit
*
* 0011 0000 0000 0000 0000 0000 0000 0000 : File Selector (0 = separate file)
* 0000 0011 0000 0000 0000 0000 0000 0000 : number of extra contiguous blocks 1-4
* 0100 1100 0000 0000 0000 0000 0000 0000 : reserved bits
* 0000 0000 1111 1111 1111 1111 1111 1111 : block# 0-16777216 (2^24)
*
* 0000 0000 1111 1111 1111 1111 0000 0000 : eFileSizeMask (size of file in k: see note)
* 0000 0000 0000 0000 0000 0000 1111 1111 : eFileGenerationMask
*
* File Selector:
* 0 = separate file on disk
* 1 = 256 byte block file
* 2 = 1k block file
* 3 = 4k block file
*
* eFileSizeMask note: Files larger than 64 Mb have zero size stored in the
* location. The file itself must be examined to determine
* its actual size.
*
*****************************************************************************/
class nsDiskCacheRecord {
private:
PRUint32 mHashNumber;
PRUint32 mEvictionRank;
PRUint32 mDataLocation;
PRUint32 mMetaLocation;
enum {
eLocationInitializedMask = 0x80000000,
eLocationSelectorMask = 0x30000000,
eLocationSelectorOffset = 28,
eExtraBlocksMask = 0x03000000,
eExtraBlocksOffset = 24,
eReservedMask = 0x4C000000,
eBlockNumberMask = 0x00FFFFFF,
eFileSizeMask = 0x00FFFF00,
eFileSizeOffset = 8,
eFileGenerationMask = 0x000000FF,
eFileReservedMask = 0x4F000000
};
public:
nsDiskCacheRecord()
: mHashNumber(0), mEvictionRank(0), mDataLocation(0), mMetaLocation(0)
{
}
PRBool ValidRecord()
{
if ((mDataLocation & eReservedMask) || (mMetaLocation & eReservedMask))
return PR_FALSE;
return PR_TRUE;
}
// HashNumber accessors
PRUint32 HashNumber() const { return mHashNumber; }
void SetHashNumber( PRUint32 hashNumber) { mHashNumber = hashNumber; }
// EvictionRank accessors
PRUint32 EvictionRank() const { return mEvictionRank; }
void SetEvictionRank( PRUint32 rank) { mEvictionRank = rank; }
// DataLocation accessors
PRBool DataLocationInitialized() { return mDataLocation & eLocationInitializedMask; }
PRUint32 DataLocation() { return mDataLocation; }
void SetDataLocation( PRUint32 location) { mDataLocation = location; }
PRUint32 DataFile() const
{
return (PRUint32)(mDataLocation & eLocationSelectorMask) >> eLocationSelectorOffset;
}
void SetDataBlocks( PRUint32 index, PRUint32 startBlock, PRUint32 blockCount)
{
// clear everything
mDataLocation = 0;
// set file index
NS_ASSERTION( index < 4,"invalid location index");
NS_ASSERTION( index > 0,"invalid location index");
mDataLocation |= (index << eLocationSelectorOffset) & eLocationSelectorMask;
// set startBlock
NS_ASSERTION(startBlock == (startBlock & eBlockNumberMask), "invalid block number");
mDataLocation |= startBlock & eBlockNumberMask;
// set blockCount
NS_ASSERTION( (blockCount>=1) && (blockCount<=4),"invalid block count");
blockCount = --blockCount;
mDataLocation |= (blockCount << eExtraBlocksOffset) & eExtraBlocksMask;
mDataLocation |= eLocationInitializedMask;
}
PRUint32 DataBlockCount() const
{
return (PRUint32)((mDataLocation & eExtraBlocksMask) >> eExtraBlocksOffset) + 1;
}
PRUint32 DataStartBlock() const
{
return (mDataLocation & eBlockNumberMask);
}
PRUint32 DataFileSize() const { return (mDataLocation & eFileSizeMask) >> eFileSizeOffset; }
void SetDataFileSize(PRUint32 size)
{
NS_ASSERTION((mDataLocation & eFileReservedMask) == 0, "bad location");
mDataLocation &= ~eFileSizeMask; // clear eFileSizeMask
mDataLocation |= (size << eFileSizeOffset) & eFileSizeMask;
}
PRUint16 DataFileGeneration() const
{
return (mDataLocation & eFileGenerationMask);
}
void SetDataFileGeneration( PRUint8 generation)
{
// clear everything, (separate file index = 0)
mDataLocation = 0;
mDataLocation |= generation & eFileGenerationMask;
mDataLocation |= eLocationInitializedMask;
}
// MetaLocation accessors
PRBool MetaLocationInitialized() { return mMetaLocation & eLocationInitializedMask; }
PRUint32 MetaLocation() { return mMetaLocation; }
void SetMetaLocation( PRUint32 location) { mMetaLocation = location; }
PRUint32 MetaFile() const
{
return (PRUint32)(mMetaLocation & eLocationSelectorMask) >> eLocationSelectorOffset;
}
void SetMetaBlocks( PRUint32 index, PRUint32 startBlock, PRUint32 blockCount)
{
// clear everything
mMetaLocation = 0;
// set file index
NS_ASSERTION( index < 4, "invalid location index");
NS_ASSERTION( index > 0, "invalid location index");
mMetaLocation |= (index << eLocationSelectorOffset) & eLocationSelectorMask;
// set startBlock
NS_ASSERTION(startBlock == (startBlock & eBlockNumberMask), "invalid block number");
mMetaLocation |= startBlock & eBlockNumberMask;
// set blockCount
NS_ASSERTION( (blockCount>=1) && (blockCount<=4),"invalid block count");
blockCount = --blockCount;
mMetaLocation |= (blockCount << eExtraBlocksOffset) & eExtraBlocksMask;
mMetaLocation |= eLocationInitializedMask;
}
PRUint32 MetaBlockCount() const
{
return (PRUint32)((mMetaLocation & eExtraBlocksMask) >> eExtraBlocksOffset) + 1;
}
PRUint32 MetaStartBlock() const
{
return (mMetaLocation & eBlockNumberMask);
}
PRUint32 MetaFileSize() const { return (mMetaLocation & eFileSizeMask) >> eFileSizeOffset; }
void SetMetaFileSize(PRUint32 size)
{
mMetaLocation &= ~eFileSizeMask; // clear eFileSizeMask
mMetaLocation |= (size << eFileSizeOffset) & eFileSizeMask;
}
PRUint16 MetaFileGeneration() const
{
return (mMetaLocation & eFileGenerationMask);
}
void SetMetaFileGeneration( PRUint8 generation)
{
// clear everything, (separate file index = 0)
mMetaLocation = 0;
mMetaLocation |= generation & eFileGenerationMask;
mMetaLocation |= eLocationInitializedMask;
}
PRUint8 Generation() const
{
if ((mDataLocation & eLocationInitializedMask) &&
(DataFile() == 0))
return DataFileGeneration();
if ((mMetaLocation & eLocationInitializedMask) &&
(MetaFile() == 0))
return MetaFileGeneration();
return 0; // no generation
}
void Swap()
{
#if defined(IS_LITTLE_ENDIAN)
mHashNumber = ::PR_htonl(mHashNumber);
mEvictionRank = ::PR_htonl(mEvictionRank);
mDataLocation = ::PR_htonl(mDataLocation);
mMetaLocation = ::PR_htonl(mMetaLocation);
#endif
}
void Unswap()
{
#if defined(IS_LITTLE_ENDIAN)
mHashNumber = ::PR_ntohl(mHashNumber);
mEvictionRank = ::PR_ntohl(mEvictionRank);
mDataLocation = ::PR_ntohl(mDataLocation);
mMetaLocation = ::PR_ntohl(mMetaLocation);
#endif
}
};
/******************************************************************************
* nsDiskCacheRecordVisitor
*****************************************************************************/
enum { kDeleteRecordAndContinue = -1,
kStopVisitingRecords = 0,
kVisitNextRecord = 1
};
class nsDiskCacheRecordVisitor {
public:
virtual PRInt32 VisitRecord( nsDiskCacheRecord * mapRecord) = 0;
};
/******************************************************************************
* nsDiskCacheBucket
*****************************************************************************/
enum {
kRecordsPerBucket = 256,
kBucketsPerTable = (1 << 5) // must be a power of 2!
};
struct nsDiskCacheBucket {
nsDiskCacheRecord mRecords[kRecordsPerBucket];
void Swap();
void Unswap();
PRUint32 CountRecords();
PRUint32 EvictionRank(); // return largest rank in bucket
PRInt32 VisitEachRecord( nsDiskCacheRecordVisitor * visitor,
PRUint32 evictionRank,
PRUint32 * recordsDeleted);
};
/******************************************************************************
* nsDiskCacheHeader
*****************************************************************************/
struct nsDiskCacheHeader {
PRUint32 mVersion; // cache version.
PRInt32 mDataSize; // size of cache in bytes.
PRInt32 mEntryCount; // number of entries stored in cache.
PRUint32 mIsDirty; // dirty flag.
PRUint32 mEvictionRank[kBucketsPerTable];
// pad to blocksize
enum { kReservedBytes = sizeof(nsDiskCacheBucket)
- sizeof(PRUint32) * 4 // version, size, count, dirty
- sizeof(PRUint32) * kBucketsPerTable // eviction array
};
PRUint8 reserved[kReservedBytes];
// XXX need a bitmap?
nsDiskCacheHeader()
: mVersion(nsDiskCache::kCurrentVersion)
, mDataSize(0)
, mEntryCount(0)
, mIsDirty(PR_TRUE)
{}
void Swap()
{
#if defined(IS_LITTLE_ENDIAN)
mVersion = ::PR_htonl(mVersion);
mDataSize = ::PR_htonl(mDataSize);
mEntryCount = ::PR_htonl(mEntryCount);
mIsDirty = ::PR_htonl(mIsDirty);
#endif
}
void Unswap()
{
#if defined(IS_LITTLE_ENDIAN)
mVersion = ::PR_ntohl(mVersion);
mDataSize = ::PR_ntohl(mDataSize);
mEntryCount = ::PR_ntohl(mEntryCount);
mIsDirty = ::PR_ntohl(mIsDirty);
#endif
}
};
/******************************************************************************
* nsDiskCacheMap
*****************************************************************************/
// XXX fixed capacity for 8192 entries. Future: make dynamic
enum {
kCacheMapSize = sizeof(nsDiskCacheHeader) +
kBucketsPerTable * sizeof(nsDiskCacheBucket)
};
class nsDiskCacheMap {
public:
nsDiskCacheMap()
: mCacheDirectory(nsnull)
, mMapFD(nsnull)
{
NS_ASSERTION(sizeof(nsDiskCacheHeader) == sizeof(nsDiskCacheBucket), "structure misalignment");
}
~nsDiskCacheMap() { (void) Close(); }
/**
* File Operations
*
* Open
*
* Creates a new cache map file if one doesn't exist.
* Returns error if it detects change in format or cache wasn't closed.
*/
nsresult Open( nsILocalFile * cacheDirectory);
nsresult Close();
// nsresult Flush();
nsresult FlushHeader();
nsresult FlushBuckets( PRBool unswap);
/**
* Record operations
*/
nsresult AddRecord( nsDiskCacheRecord * mapRecord, nsDiskCacheRecord * oldRecord);
nsresult UpdateRecord( nsDiskCacheRecord * mapRecord);
nsresult FindRecord( PRUint32 hashNumber, nsDiskCacheRecord * mapRecord);
nsresult DeleteRecord( nsDiskCacheRecord * mapRecord);
nsresult VisitRecords( nsDiskCacheRecordVisitor * visitor);
nsresult EvictRecords( nsDiskCacheRecordVisitor * visitor);
/**
* Disk Entry operations
*/
nsresult DoomRecord( nsDiskCacheRecord * record);
nsresult DeleteStorage( nsDiskCacheRecord * record);
nsresult DeleteRecordAndStorage( nsDiskCacheRecord * record);
nsresult GetFileForDiskCacheRecord( nsDiskCacheRecord * record,
PRBool meta,
nsIFile ** result);
nsresult GetLocalFileForDiskCacheRecord( nsDiskCacheRecord * record,
PRBool meta,
nsILocalFile ** result);
nsresult ReadDiskCacheEntry( nsDiskCacheRecord * record,
nsDiskCacheEntry ** result);
nsresult WriteDiskCacheEntry( nsDiskCacheBinding * binding);
/**
* Statistical Operations
*/
void IncrementTotalSize( PRInt32 delta)
{
NS_ASSERTION(mHeader.mDataSize >= 0, "disk cache size negative?");
mHeader.mDataSize += delta;
mHeader.mIsDirty = PR_TRUE;
}
void DecrementTotalSize( PRInt32 delta)
{
mHeader.mDataSize -= delta;
mHeader.mIsDirty = PR_TRUE;
NS_ASSERTION(mHeader.mDataSize >= 0, "disk cache size negative?");
}
PRInt32 TotalSize() { return mHeader.mDataSize; }
PRInt32 EntryCount() { return mHeader.mEntryCount; }
private:
/**
* Private methods
*/
nsresult OpenBlockFiles();
nsresult CloseBlockFiles();
nsresult GetBlockFileForIndex( PRUint32 index, nsILocalFile ** result);
PRUint32 GetBlockSizeForIndex( PRUint32 index);
nsresult DeleteStorage( nsDiskCacheRecord * record, PRBool metaData);
nsresult GetBucketForHashNumber( PRUint32 hashNumber, nsDiskCacheBucket ** result)
{
*result = &mBuckets[GetBucketIndex(hashNumber)];
return NS_OK;
}
PRUint32 GetBucketIndex( PRUint32 hashNumber)
{
return (hashNumber & (kBucketsPerTable - 1));
}
/**
* data members
*/
private:
nsCOMPtr<nsILocalFile> mCacheDirectory;
PRFileDesc * mMapFD;
nsDiskCacheBlockFile mBlockFile[3];
nsDiskCacheHeader mHeader;
nsDiskCacheBucket mBuckets[kBucketsPerTable];
};
#endif // _nsDiskCacheMap_h_

View File

@@ -0,0 +1,496 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsMemoryCacheDevice.cpp, released February 22, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, <gordon@netscape.com>
* Patrick C. Beard <beard@netscape.com>
*/
#include "nsMemoryCacheDevice.h"
#include "nsCacheService.h"
#include "nsICacheService.h"
#include "nsIComponentManager.h"
#include "nsNetCID.h"
#include "nsIObserverService.h"
#include "nsIPref.h"
#include "nsICacheVisitor.h"
#include "nsITransport.h"
#include "signal.h"
static NS_DEFINE_CID(kStorageTransportCID, NS_STORAGETRANSPORT_CID);
const char *gMemoryDeviceID = "memory";
const char *gMemoryCacheSizePref = "browser.cache.memory_cache_size";
nsMemoryCacheDevice::nsMemoryCacheDevice()
: mEvictionThreshold(40 * 1024),
mHardLimit(0),
mSoftLimit(0),
mTotalSize(0),
mInactiveSize(0),
mEntryCount(0),
mMaxEntryCount(0)
{
PR_INIT_CLIST(&mEvictionList[mostLikelyToEvict]);
PR_INIT_CLIST(&mEvictionList[leastLikelyToEvict]);
}
nsMemoryCacheDevice::~nsMemoryCacheDevice()
{
#if DEBUG
printf("### starting ~nsMemoryCacheDevice()\n");
#endif
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
prefs->UnregisterCallback(gMemoryCacheSizePref, MemoryCacheSizeChanged, this);
}
Shutdown();
}
int PR_CALLBACK
nsMemoryCacheDevice::MemoryCacheSizeChanged(const char * pref, void * closure)
{
nsresult rv;
PRUint32 softLimit = 0;
nsMemoryCacheDevice * device = (nsMemoryCacheDevice *)closure;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = prefs->GetIntPref(gMemoryCacheSizePref, (PRInt32 *)&softLimit);
if (NS_FAILED(rv)) return rv;
softLimit *= 1024; // convert k into bytes
PRUint32 hardLimit = softLimit + 1024*1024*2; // XXX find better limit than +2Meg
device->AdjustMemoryLimits(softLimit, hardLimit);
return 0; // XXX what are we supposed to return?
}
nsresult
nsMemoryCacheDevice::Init()
{
nsresult rv;
rv = mMemCacheEntries.Init();
// set some default memory limits, in case prefs aren't available
mSoftLimit = 1024 * 1024 * 3;
mHardLimit = mSoftLimit + 1024 *1024 * 2;
// read user prefs for memory cache limits
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = prefs->RegisterCallback(gMemoryCacheSizePref, MemoryCacheSizeChanged, this);
if (NS_FAILED(rv)) return rv;
// Initialize the pref
MemoryCacheSizeChanged(gMemoryCacheSizePref, this);
}
// Register as a memory pressure observer
NS_WITH_SERVICE(nsIObserverService,
observerService,
NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
// XXX rv = observerServcie->AddObserver(this, NS_MEMORY_PRESSURE_TOPIC);
}
// Ignore failure of memory pressure registration
return rv;
}
nsresult
nsMemoryCacheDevice::Shutdown()
{
mMemCacheEntries.Shutdown();
// evict all entries
nsCacheEntry * entry, * next;
for (int i=mostLikelyToEvict; i <= leastLikelyToEvict; ++i) {
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
while (entry != &mEvictionList[i]) {
NS_ASSERTION(entry->IsInUse() == PR_FALSE, "### shutting down with active entries.\n");
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
PR_REMOVE_AND_INIT_LINK(entry);
// update statistics
PRUint32 memoryRecovered = entry->Size();
mTotalSize -= memoryRecovered;
mInactiveSize -= memoryRecovered;
--mEntryCount;
delete entry;
entry = next;
}
}
/*
* we're not factoring in changes to meta data yet...
* NS_ASSERTION(mTotalSize == 0, "### mem cache leaking entries?\n");
*/
NS_ASSERTION(mInactiveSize == 0, "### mem cache leaking entries?\n");
NS_ASSERTION(mEntryCount == 0, "### mem cache leaking entries?\n");
return NS_OK;
}
const char *
nsMemoryCacheDevice::GetDeviceID()
{
return gMemoryDeviceID;
}
nsCacheEntry *
nsMemoryCacheDevice::FindEntry(nsCString * key)
{
nsCacheEntry * entry = mMemCacheEntries.GetEntry(key);
if (!entry) return nsnull;
// move entry to the tail of an eviction list
PR_REMOVE_AND_INIT_LINK(entry);
PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, 0)]);
mInactiveSize -= entry->Size();
return entry;
}
nsresult
nsMemoryCacheDevice::DeactivateEntry(nsCacheEntry * entry)
{
if (entry->IsDoomed()) {
#if debug
// XXX verify we've removed it from mMemCacheEntries & eviction list
#endif
// update statistics
mTotalSize -= entry->Size();
--mEntryCount;
delete entry;
return NS_OK;
}
nsCacheEntry * ourEntry = mMemCacheEntries.GetEntry(entry->Key());
NS_ASSERTION(ourEntry, "DeactivateEntry called for an entry we don't have!");
NS_ASSERTION(entry == ourEntry, "entry doesn't match ourEntry");
if (ourEntry != entry)
return NS_ERROR_INVALID_POINTER;
mInactiveSize += entry->Size();
EvictEntriesIfNecessary();
return NS_OK;
}
nsresult
nsMemoryCacheDevice::BindEntry(nsCacheEntry * entry)
{
NS_ASSERTION(PR_CLIST_IS_EMPTY(entry),"entry is already on a list!");
if (!entry->IsDoomed()) {
// append entry to the eviction list
PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, 0)]);
// add entry to hashtable of mem cache entries
nsresult rv = mMemCacheEntries.AddEntry(entry);
if (NS_FAILED(rv)) {
PR_REMOVE_AND_INIT_LINK(entry);
return rv;
}
}
// add size of entry to memory totals
++mEntryCount;
if (mMaxEntryCount < mEntryCount) mMaxEntryCount = mEntryCount;
mTotalSize += entry->Size();
EvictEntriesIfNecessary();
return NS_OK;
}
void
nsMemoryCacheDevice::DoomEntry(nsCacheEntry * entry)
{
// XXX debug code to verify we have entry
mMemCacheEntries.RemoveEntry(entry);
// remove entry from our eviction list
PR_REMOVE_AND_INIT_LINK(entry);
}
nsresult
nsMemoryCacheDevice::GetTransportForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** transport )
{
NS_ENSURE_ARG_POINTER(entry);
NS_ENSURE_ARG_POINTER(transport);
nsCOMPtr<nsISupports> data;
nsresult rv = entry->GetData(getter_AddRefs(data));
if (NS_FAILED(rv))
return rv;
if (data)
return CallQueryInterface(data, transport);
else {
// create a new transport for this entry
rv = nsComponentManager::CreateInstance(kStorageTransportCID,
nsnull,
NS_GET_IID(nsITransport),
(void **) transport);
if (NS_FAILED(rv)) return rv;
entry->SetData(*transport);
return NS_OK;
}
}
nsresult
nsMemoryCacheDevice::GetFileForEntry( nsCacheEntry * entry,
nsIFile ** result )
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsMemoryCacheDevice::OnDataSizeChange( nsCacheEntry * entry, PRInt32 deltaSize)
{
if (entry->IsStreamData()) {
// we have the right to refuse or pre-evict
}
// adjust our totals
mTotalSize += deltaSize;
if (!entry->IsDoomed()) {
// move entry to the tail of the appropriate eviction list
PR_REMOVE_AND_INIT_LINK(entry);
PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, deltaSize)]);
}
EvictEntriesIfNecessary();
return NS_OK;
}
void
nsMemoryCacheDevice::AdjustMemoryLimits(PRUint32 softLimit, PRUint32 hardLimit)
{
mSoftLimit = softLimit;
mHardLimit = hardLimit;
EvictEntriesIfNecessary();
}
void
nsMemoryCacheDevice::EvictEntry(nsCacheEntry * entry)
{
// remove entry from our hashtable
mMemCacheEntries.RemoveEntry(entry);
// remove entry from the eviction list
PR_REMOVE_AND_INIT_LINK(entry);
// update statistics
PRUint32 memoryRecovered = entry->Size();
mTotalSize -= memoryRecovered;
mInactiveSize -= memoryRecovered;
--mEntryCount;
delete entry;
}
void
nsMemoryCacheDevice::EvictEntriesIfNecessary(void)
{
nsCacheEntry * entry, * next;
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
return;
for (int i=mostLikelyToEvict; i<=leastLikelyToEvict; ++i) {
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
while (entry != &mEvictionList[i]) {
if (entry->IsInUse()) {
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
continue;
}
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
EvictEntry(entry);
entry = next;
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
return;
}
}
}
int
nsMemoryCacheDevice::EvictionList(nsCacheEntry * entry, PRUint32 deltaSize)
{
PRUint32 size = entry->Size() + deltaSize;
if ((size > mEvictionThreshold) || (entry->ExpirationTime() != 0))
return mostLikelyToEvict;
return leastLikelyToEvict;
}
nsresult
nsMemoryCacheDevice::Visit(nsICacheVisitor * visitor)
{
nsMemoryCacheDeviceInfo * deviceInfo = new nsMemoryCacheDeviceInfo(this);
nsCOMPtr<nsICacheDeviceInfo> deviceRef(deviceInfo);
if (!deviceInfo) return NS_ERROR_OUT_OF_MEMORY;
PRBool keepGoing;
nsresult rv = visitor->VisitDevice(gMemoryDeviceID, deviceInfo, &keepGoing);
if (NS_FAILED(rv)) return rv;
if (!keepGoing)
return NS_OK;
nsCacheEntry * entry;
nsCOMPtr<nsICacheEntryInfo> entryRef;
for (int i=mostLikelyToEvict; i <= leastLikelyToEvict; ++i) {
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
while (entry != &mEvictionList[i]) {
nsCacheEntryInfo * entryInfo = new nsCacheEntryInfo(entry);
if (!entryInfo) return NS_ERROR_OUT_OF_MEMORY;
entryRef = entryInfo;
rv = visitor->VisitEntry(gMemoryDeviceID, entryInfo, &keepGoing);
entryInfo->DetachEntry();
if (NS_FAILED(rv)) return rv;
if (!keepGoing) break;
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
}
}
return NS_OK;
}
nsresult
nsMemoryCacheDevice::EvictEntries(const char * clientID)
{
nsCacheEntry * entry;
PRUint32 prefixLength = (clientID ? nsCRT::strlen(clientID) : 0);
for (int i=mostLikelyToEvict; i<=leastLikelyToEvict; ++i) {
PRCList * elem = PR_LIST_HEAD(&mEvictionList[i]);
while (elem != &mEvictionList[i]) {
entry = (nsCacheEntry *)elem;
elem = PR_NEXT_LINK(elem);
const char * key = entry->Key()->get();
if (clientID && nsCRT::strncmp(clientID, key, prefixLength) != 0)
continue;
if (entry->IsInUse()) {
nsresult rv = nsCacheService::GlobalInstance()->DoomEntry_Locked(entry);
if (NS_FAILED(rv)) return rv;
} else {
EvictEntry(entry);
}
}
}
return NS_OK;
}
/******************************************************************************
* nsMemoryCacheDeviceInfo - for implementing about:cache
*****************************************************************************/
NS_IMPL_ISUPPORTS1(nsMemoryCacheDeviceInfo, nsICacheDeviceInfo);
NS_IMETHODIMP
nsMemoryCacheDeviceInfo::GetDescription(char ** result)
{
NS_ENSURE_ARG_POINTER(result);
*result = nsCRT::strdup("Memory cache device");
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsMemoryCacheDeviceInfo::GetUsageReport(char ** result)
{
NS_ENSURE_ARG_POINTER(result);
*result = nsCRT::strdup("Memory cache usage report:");
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsMemoryCacheDeviceInfo::GetEntryCount(PRUint32 * result)
{
NS_ENSURE_ARG_POINTER(result);
// XXX compare calculated count vs. mEntryCount
*result = mDevice->mEntryCount;
return NS_OK;
}
NS_IMETHODIMP
nsMemoryCacheDeviceInfo::GetTotalSize(PRUint32 * result)
{
NS_ENSURE_ARG_POINTER(result);
*result = mDevice->mTotalSize;
return NS_OK;
}
NS_IMETHODIMP
nsMemoryCacheDeviceInfo::GetMaximumSize(PRUint32 * result)
{
NS_ENSURE_ARG_POINTER(result);
*result = mDevice->mHardLimit;
return NS_OK;
}

View File

@@ -0,0 +1,119 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 nsMemoryCacheDevice.h, released February 20, 2001.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 20-February-2001
*/
#ifndef _nsMemoryCacheDevice_h_
#define _nsMemoryCacheDevice_h_
#include "nsCacheDevice.h"
#include "pldhash.h"
#include "nsCacheEntry.h"
class nsMemoryCacheDeviceInfo;
/******************************************************************************
* nsMemoryCacheDevice
******************************************************************************/
class nsMemoryCacheDevice : public nsCacheDevice
{
public:
nsMemoryCacheDevice();
virtual ~nsMemoryCacheDevice();
virtual nsresult Init();
virtual nsresult Shutdown();
virtual const char * GetDeviceID(void);
virtual nsresult BindEntry( nsCacheEntry * entry );
virtual nsCacheEntry * FindEntry( nsCString * key );
virtual void DoomEntry( nsCacheEntry * entry );
virtual nsresult DeactivateEntry( nsCacheEntry * entry );
virtual nsresult GetTransportForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport **transport );
virtual nsresult GetFileForEntry( nsCacheEntry * entry,
nsIFile ** result );
virtual nsresult OnDataSizeChange( nsCacheEntry * entry, PRInt32 deltaSize );
virtual nsresult Visit( nsICacheVisitor * visitor );
virtual nsresult EvictEntries(const char * clientID);
static int PR_CALLBACK MemoryCacheSizeChanged(const char * pref, void * closure);
private:
friend class nsMemoryCacheDeviceInfo;
void AdjustMemoryLimits( PRUint32 softLimit, PRUint32 hardLimit);
void EvictEntry( nsCacheEntry * entry );
void EvictEntriesIfNecessary();
int EvictionList(nsCacheEntry * entry, PRUint32 deltaSize);
/*
* Data members
*/
nsCacheEntryHashTable mMemCacheEntries;
enum { mostLikelyToEvict = 0, leastLikelyToEvict = 1 }; // constants to differentiate eviction lists
PRCList mEvictionList[2];
PRUint32 mEvictionThreshold;
PRUint32 mHardLimit;
PRUint32 mSoftLimit;
PRUint32 mTotalSize;
PRUint32 mInactiveSize;
PRUint32 mEntryCount;
PRUint32 mMaxEntryCount;
// XXX what other stats do we want to keep?
};
/******************************************************************************
* nsMemoryCacheDeviceInfo - used to call nsIVisitor for about:cache
******************************************************************************/
class nsMemoryCacheDeviceInfo : public nsICacheDeviceInfo {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICACHEDEVICEINFO
nsMemoryCacheDeviceInfo(nsMemoryCacheDevice* device)
: mDevice(device)
{
NS_INIT_ISUPPORTS();
}
virtual ~nsMemoryCacheDeviceInfo() {}
private:
nsMemoryCacheDevice* mDevice;
};
#endif // _nsMemoryCacheDevice_h_

231
mozilla/netwerk/cache/src/win32.order vendored Normal file
View File

@@ -0,0 +1,231 @@
?AddRef@nsCacheEntryDescriptor@@UAGKXZ ; 35743
?HashKey@nsCacheEntryHashTable@@CAIPAUPLDHashTable@@PBX@Z ; 29743
?Release@nsCacheEntryDescriptor@@UAGKXZ ; 21199
??_EnsCString@@UAEPAXI@Z ; 19905
?AddRef@nsCacheSession@@UAGKXZ ; 17435
?GetEntry@nsCacheEntryHashTable@@QAEPAVnsCacheEntry@@PBVnsCString@@@Z ; 17433
?SecondsFromPRTime@@YAI_J@Z ; 14263
?CalculateSize@nsCacheMetaData@@CA?AW4PLDHashOperator@@PAUPLDHashTable@@PAUPLDHashEntryHdr@@IPAX@Z ; 14243
?Release@nsCacheEntryInfo@@UAGKXZ ; 10964
?GetLastModified@nsDiskCacheEntryInfo@@UAGIPAI@Z ; 9800
?Release@nsANSIOutputStream@@UAGKXZ ; 9758
?MatchEntry@nsCacheEntryHashTable@@CAHPAUPLDHashTable@@PBUPLDHashEntryHdr@@PBX@Z ; 9663
?QueryInterface@nsCacheEntryInfo@@UAGIABUnsID@@PAPAX@Z ; 8638
??Rdo_QueryElementAt@@UBEIABUnsID@@PAPAX@Z ; 8638
?assign_assuming_AddRef@nsCOMPtr_base@@IAEXPAVnsISupports@@@Z ; 8259
??0nsDiskCacheRecord@@QAE@XZ ; 8192
?EnsureEntryHasDevice@nsCacheService@@AAEPAVnsCacheDevice@@PAVnsCacheEntry@@@Z ; 7918
?MoveEntry@nsCacheEntryHashTable@@CAXPAUPLDHashTable@@PBUPLDHashEntryHdr@@PAU3@@Z ; 7653
?GetKey@nsCacheEntryHashTable@@CAPBXPAUPLDHashTable@@PAUPLDHashEntryHdr@@@Z ; 7653
?Close@nsANSIOutputStream@@UAGIXZ ; 7092
?Write@nsANSIOutputStream@@UAGIPBDIPAI@Z ; 7067
?AccumulateElements@nsCacheMetaData@@CA?AW4PLDHashOperator@@PAUPLDHashTable@@PAUPLDHashEntryHdr@@IPAX@Z ; 7063
?Release@nsDiskCacheDeviceInfo@@UAGKXZ ; 6471
?CreateRequest@nsCacheService@@AAEIPAVnsCacheSession@@PBDHPAVnsICacheListener@@PAPAVnsCacheRequest@@@Z ; 6468
?ActivateEntry@nsCacheService@@AAEIPAVnsCacheRequest@@PAPAVnsCacheEntry@@@Z ; 6468
?ProcessRequest@nsCacheService@@AAEIPAVnsCacheRequest@@PAPAVnsICacheEntryDescriptor@@@Z ; 6468
??1nsCacheRequest@@AAE@XZ ; 6468
?OpenCacheEntry@nsCacheService@@QAEIPAVnsCacheSession@@PBDHPAVnsICacheListener@@PAPAVnsICacheEntryDescriptor@@@Z ; 6468
??0nsCacheRequest@@AAE@PAVnsCString@@PAVnsICacheListener@@HPAVnsCacheSession@@@Z ; 6468
?Hash@nsDiskCacheEntry@@SAIPBD@Z ; 6166
?HashKey@nsDiskCacheEntryHashTable@@CAIPAUPLDHashTable@@PBX@Z ; 6037
?EvictEntriesIfNecessary@nsMemoryCacheDevice@@AAEXXZ ; 5780
?TouchData@nsCacheEntry@@QAEXXZ ; 5503
?OpenCacheEntry@nsCacheSession@@UAGIPBDHPAPAVnsICacheEntryDescriptor@@@Z ; 5165
?RequestAccess@nsCacheEntry@@QAEIPAVnsCacheRequest@@PAH@Z ; 5099
?Fetched@nsCacheEntry@@QAEXXZ ; 5094
??0nsTransportWrapper@nsCacheEntryDescriptor@@QAE@XZ ; 5092
?CreateDescriptor@nsCacheEntry@@QAEIPAVnsCacheRequest@@HPAPAVnsICacheEntryDescriptor@@@Z ; 5092
??0nsCacheEntryDescriptor@@QAE@PAVnsCacheEntry@@H@Z ; 5092
?RemoveDescriptor@nsCacheEntry@@QAEHPAVnsCacheEntryDescriptor@@@Z ; 5090
?CloseDescriptor@nsCacheService@@QAEXPAVnsCacheEntryDescriptor@@@Z ; 5090
?Close@nsCacheEntryDescriptor@@UAGIXZ ; 5090
??_GnsCacheEntryDescriptor@@UAEPAXI@Z ; 5090
??1nsCacheEntryDescriptor@@UAE@XZ ; 5090
?SearchCacheDevices@nsCacheService@@AAEPAVnsCacheEntry@@PAVnsCString@@H@Z ; 4993
?AddEntry@nsCacheEntryHashTable@@QAEIPAVnsCacheEntry@@@Z ; 4993
?FindEntry@nsMemoryCacheDevice@@UAEPAVnsCacheEntry@@PAVnsCString@@@Z ; 4993
?ClearEntry@nsCacheEntryHashTable@@CAXPAUPLDHashTable@@PAUPLDHashEntryHdr@@@Z ; 4993
?RemoveEntry@nsCacheEntryHashTable@@QAEXPAVnsCacheEntry@@@Z ; 4921
?GetData@nsCacheEntry@@QAEIPAPAVnsISupports@@@Z ; 4811
?Release@nsDiskCacheEntry@@UAGKXZ ; 4784
?RequestDataSizeChange@nsCacheEntryDescriptor@@QAEIH@Z ; 4127
?OnDataSizeChange@nsCacheService@@QAEIPAVnsCacheEntry@@H@Z ; 4127
?SetElement@nsCacheMetaData@@QAEIABVnsACString@@0@Z ; 3682
?ClearEntry@nsCacheMetaData@@CAXPAUPLDHashTable@@PAUPLDHashEntryHdr@@@Z ; 3681
?FreeElements@nsCacheMetaData@@CA?AW4PLDHashOperator@@PAUPLDHashTable@@PAUPLDHashEntryHdr@@IPAX@Z ; 3681
?GetEntry@nsDiskCacheEntryHashTable@@QAEPAVnsDiskCacheEntry@@PBD@Z ; 3651
?GetRecord@nsDiskCacheMap@@QAEPAVnsDiskCacheRecord@@I@Z ; 3650
?Size@nsCacheMetaData@@QAEIXZ ; 3628
?DeactivateEntry@nsCacheService@@AAEXPAVnsCacheEntry@@@Z ; 3619
?TouchMetaData@nsCacheEntry@@QAEXXZ ; 3601
?SetMetaDataElement@nsCacheEntryDescriptor@@UAGIPBD0@Z ; 3601
?SetMetaDataElement@nsCacheEntry@@QAEIABVnsACString@@0@Z ; 3601
?getFileForHashNumber@nsDiskCacheDevice@@QAEIIHIPAPAVnsIFile@@@Z ; 3587
?Read@nsANSIInputStream@@UAGIPADIPAI@Z ; 3570
?getFileForDiskCacheEntry@nsDiskCacheDevice@@QAEIPAVnsDiskCacheEntry@@HPAPAVnsIFile@@@Z ; 3560
?Unswap@MetaDataHeader@@QAEXXZ ; 3545
??1MetaDataFile@@QAE@XZ ; 3545
?OnDataSizeChange@nsDiskCacheDevice@@UAEIPAVnsCacheEntry@@H@Z ; 3210
?ProcessPendingRequests@nsCacheService@@AAEIPAVnsCacheEntry@@@Z ; 2800
??0nsCacheEntry@@QAE@PAVnsCString@@HH@Z ; 2673
??1nsCacheEntry@@QAE@XZ ; 2673
?MarkValid@nsCacheEntryDescriptor@@UAGIXZ ; 2592
?ValidateEntry@nsCacheService@@QAEIPAVnsCacheEntry@@@Z ; 2592
?GetCacheElement@nsCacheEntryDescriptor@@UAGIPAPAVnsISupports@@@Z ; 2413
?MatchEntry@nsDiskCacheEntryHashTable@@CAHPAUPLDHashTable@@PBUPLDHashEntryHdr@@PBX@Z ; 2383
?Release@nsANSIInputStream@@UAGKXZ ; 2380
?AddRef@nsANSIInputStream@@UAGKXZ ; 2380
?MatchEntry@nsCacheMetaData@@CAHPAUPLDHashTable@@PBUPLDHashEntryHdr@@PBX@Z ; 2365
?GetMetaDataElement@nsCacheEntry@@QAEIABVnsACString@@PAPBV2@@Z ; 2365
?GetElement@nsCacheMetaData@@QAEPBVnsACString@@PBV2@@Z ; 2365
?GetMetaDataElement@nsCacheEntryDescriptor@@UAGIPBDPAPAD@Z ; 2365
?openOutputStream@nsDiskCacheDevice@@SAIPAVnsIFile@@PAPAVnsIOutputStream@@@Z ; 2356
?updateDiskCacheEntry@nsDiskCacheDevice@@QAEIPAVnsDiskCacheEntry@@@Z ; 2356
??0nsANSIOutputStream@@QAE@PAU_iobuf@@@Z ; 2356
??_EnsANSIOutputStream@@UAEPAXI@Z ; 2356
??1nsANSIOutputStream@@UAE@XZ ; 2356
?Swap@MetaDataHeader@@QAEXXZ ; 2355
?FlattenMetaData@nsCacheMetaData@@QAEIPAPADPAI@Z ; 2355
?Init@MetaDataFile@@QAEIPAVnsCacheEntry@@@Z ; 2355
?updateCacheMap@nsDiskCacheDevice@@QAEIPAVnsDiskCacheEntry@@@Z ; 2355
??0MetaDataHeader@@QAE@PAVnsCacheEntry@@@Z ; 2355
?Write@MetaDataFile@@QAEIPAVnsIOutputStream@@@Z ; 2355
?FlattenMetaData@nsCacheEntry@@QAEIPAPADPAI@Z ; 2355
?DeactivateEntry@nsMemoryCacheDevice@@UAEIPAVnsCacheEntry@@@Z ; 2322
?SetExpirationTime@nsCacheEntryDescriptor@@UAGII@Z ; 2259
?QueryInterface@nsCacheEntryDescriptor@@UAGIABUnsID@@PAPAX@Z ; 2186
?GetDataSize@nsCacheEntryDescriptor@@UAGIPAI@Z ; 2107
?OnDataSizeChange@nsMemoryCacheDevice@@UAEIPAVnsCacheEntry@@H@Z ; 2082
?SetDataSize@nsCacheEntryDescriptor@@UAGII@Z ; 2082
?Write@nsOutputStreamWrapper@nsCacheEntryDescriptor@@UAGIPBDIPAI@Z ; 2045
?OnWrite@nsOutputStreamWrapper@nsCacheEntryDescriptor@@AAEII@Z ; 2045
?GetNonBlocking@nsOutputStreamWrapper@nsCacheEntryDescriptor@@UAGIPAH@Z ; 1550
?SetCacheElement@nsCacheEntryDescriptor@@UAGIPAVnsISupports@@@Z ; 1376
?BindEntry@nsMemoryCacheDevice@@UAEIPAVnsCacheEntry@@@Z ; 1376
?AsyncOpenCacheEntry@nsCacheSession@@UAGIPBDHPAVnsICacheListener@@@Z ; 1303
?NotifyListener@nsCacheService@@AAEIPAVnsCacheRequest@@PAVnsICacheEntryDescriptor@@HI@Z ; 1303
??0nsCacheMetaData@@QAE@XZ ; 1298
??1nsCacheMetaData@@QAE@XZ ; 1298
?FindEntry@nsDiskCacheDevice@@UAEPAVnsCacheEntry@@PAVnsCString@@@Z ; 1295
?Init@nsCacheMetaData@@QAEIXZ ; 1295
?Finalize@nsCacheMetaData@@CAXPAUPLDHashTable@@@Z ; 1295
?Create@nsCacheMetaData@@SAPAV1@XZ ; 1295
?getTransportForFile@nsDiskCacheDevice@@SAIPAVnsIFile@@HPAPAVnsITransport@@@Z ; 1199
?GetTransportForEntry@nsDiskCacheDevice@@UAEIPAVnsCacheEntry@@HPAPAVnsITransport@@@Z ; 1198
?AddRef@nsTransportWrapper@nsCacheEntryDescriptor@@UAGKXZ ; 1198
?EnsureTransportWithAccess@nsTransportWrapper@nsCacheEntryDescriptor@@QAEIH@Z ; 1198
?GetTransport@nsCacheEntryDescriptor@@UAGIPAPAVnsITransport@@@Z ; 1198
?GetTransportForEntry@nsCacheService@@QAEIPAVnsCacheEntry@@HPAPAVnsITransport@@@Z ; 1198
?Release@nsTransportWrapper@nsCacheEntryDescriptor@@UAGKXZ ; 1198
?GetSecurityInfo@nsCacheEntryDescriptor@@UAGIPAPAVnsISupports@@@Z ; 1195
?GetSecurityInfo@nsCacheEntry@@QAEIPAPAVnsISupports@@@Z ; 1195
??1nsDiskCacheEntry@@UAE@XZ ; 1193
??0nsDiskCacheEntry@@QAE@PAVnsCacheEntry@@@Z ; 1193
??_EnsDiskCacheEntry@@UAEPAXI@Z ; 1193
?DeactivateEntry@nsDiskCacheDevice@@UAEIPAVnsCacheEntry@@@Z ; 1193
?AddEntry@nsDiskCacheEntryHashTable@@QAEIPAVnsDiskCacheEntry@@@Z ; 1193
?ClearEntry@nsDiskCacheEntryHashTable@@CAXPAUPLDHashTable@@PAUPLDHashEntryHdr@@@Z ; 1193
?RemoveEntry@nsDiskCacheEntryHashTable@@QAEXPAVnsDiskCacheEntry@@@Z ; 1193
?openInputStream@nsDiskCacheDevice@@SAIPAVnsIFile@@PAPAVnsIInputStream@@@Z ; 1191
??1nsANSIInputStream@@UAE@XZ ; 1190
?Read@MetaDataFile@@QAEIPAVnsIInputStream@@@Z ; 1190
??0nsANSIInputStream@@QAE@PAU_iobuf@@@Z ; 1190
??_EnsANSIInputStream@@UAEPAXI@Z ; 1190
??0MetaDataHeader@@QAE@XZ ; 1190
?OpenOutputStream@nsTransportWrapper@nsCacheEntryDescriptor@@UAGIIIIPAPAVnsIOutputStream@@@Z ; 1166
?BindEntry@nsDiskCacheDevice@@UAEIPAVnsCacheEntry@@@Z ; 1166
?IsAllowedOnDisk@nsCacheEntry@@QAEHXZ ; 1166
??1nsOutputStreamWrapper@nsCacheEntryDescriptor@@UAE@XZ ; 1165
?NewOutputStreamWrapper@nsCacheEntryDescriptor@@CAIPAPAVnsIOutputStream@@PAV1@PAV2@@Z ; 1165
?GetAccessGranted@nsCacheEntryDescriptor@@UAGIPAH@Z ; 1165
??0nsOutputStreamWrapper@nsCacheEntryDescriptor@@QAE@PAV1@PAVnsIOutputStream@@@Z ; 1165
?Init@nsOutputStreamWrapper@nsCacheEntryDescriptor@@QAEIXZ ; 1165
??_GnsOutputStreamWrapper@nsCacheEntryDescriptor@@UAEPAXI@Z ; 1165
??0MetaDataFile@@QAE@XZ ; 1163
?GetDataSize@nsDiskCacheEntryInfo@@UAGIPAI@Z ; 1163
??_GnsDiskCacheEntryInfo@@UAEPAXI@Z ; 1163
?Swap@nsDiskCacheRecord@@QAEXXZ ; 1123
?Unswap@nsDiskCacheRecord@@QAEXXZ ; 1123
?GetExpirationTime@nsCacheEntryDescriptor@@UAGIPAI@Z ; 1118
?GetKey@nsDiskCacheEntryHashTable@@CAPBXPAUPLDHashTable@@PAUPLDHashEntryHdr@@@Z ; 395
?MoveEntry@nsDiskCacheEntryHashTable@@CAXPAUPLDHashTable@@PBUPLDHashEntryHdr@@PAU3@@Z ; 395
?DoomEntry_Locked@nsCacheService@@QAEIPAVnsCacheEntry@@@Z ; 106
?DoomEntry@nsCacheService@@QAEIPAVnsCacheEntry@@@Z ; 104
?Doom@nsCacheEntryDescriptor@@UAGIXZ ; 104
?FreeCacheEntries@nsCacheEntryHashTable@@CA?AW4PLDHashOperator@@PAUPLDHashTable@@PAUPLDHashEntryHdr@@IPAX@Z ; 72
?AsyncRead@nsTransportWrapper@nsCacheEntryDescriptor@@UAGIPAVnsIStreamListener@@PAVnsISupports@@IIIPAPAVnsIRequest@@@Z ; 32
??_H@YGXPAXIHP6EX0@Z@Z ; 32
?getFileForKey@nsDiskCacheDevice@@QAEIPBDHIPAPAVnsIFile@@@Z ; 27
?UnflattenMetaData@nsCacheMetaData@@QAEIPADI@Z ; 27
?UnflattenMetaData@nsCacheEntry@@QAEIPADI@Z ; 27
?readDiskCacheEntry@nsDiskCacheDevice@@QAEIPBDPAPAVnsDiskCacheEntry@@@Z ; 27
?GetLastModified@nsCacheEntryDescriptor@@UAGIPAI@Z ; 25
?AddRef@nsDiskCacheObserver@@UAGKXZ ; 12
?Release@nsDiskCacheObserver@@UAGKXZ ; 12
?AddRef@nsCacheService@@UAGKXZ ; 9
?Release@nsCacheService@@UAGKXZ ; 9
?QueryInterface@nsDiskCacheObserver@@UAGIABUnsID@@PAPAX@Z ; 6
?QueryInterface@nsCacheService@@UAGIABUnsID@@PAPAX@Z ; 6
?do_GetService@@YA?BVnsGetServiceByContractID@@PBDPAI@Z ; 5
?DeleteRecord@nsDiskCacheMap@@QAEXI@Z ; 3
??0nsCacheSession@@QAE@PBDHH@Z ; 3
??1nsCacheSession@@UAE@XZ ; 3
??_EnsCacheSession@@UAEPAXI@Z ; 3
?deleteDiskCacheEntry@nsDiskCacheDevice@@QAEIPAVnsDiskCacheEntry@@@Z ; 3
?DoomEntry@nsDiskCacheDevice@@UAEXPAVnsCacheEntry@@@Z ; 3
?CreateSession@nsCacheService@@UAGIPBDHHPAPAVnsICacheSession@@@Z ; 3
?setPrefsObserver@nsDiskCacheDevice@@QAEXPAVnsIObserver@@@Z ; 2
?VisitEntries@nsDiskCacheEntryHashTable@@QAEXPAVVisitor@1@@Z ; 2
?DetachDescriptors@nsCacheEntry@@AAEXXZ ; 2
?ClearPendingRequests@nsCacheService@@AAEXPAVnsCacheEntry@@@Z ; 2
?SetDoomEntriesIfExpired@nsCacheSession@@UAGIH@Z ; 2
?Finalize@nsCacheEntryHashTable@@CAXPAUPLDHashTable@@@Z ; 2
?DeactivateAndClearEntry@nsCacheService@@CA?AW4PLDHashOperator@@PAUPLDHashTable@@PAUPLDHashEntryHdr@@IPAX@Z ; 2
?Init@nsCacheEntryHashTable@@QAEIXZ ; 2
?updateDiskCacheEntries@nsDiskCacheDevice@@QAEIXZ ; 2
?scanDiskCacheEntries@nsDiskCacheDevice@@QAEIPAPAVnsISupportsArray@@@Z ; 2
?AdjustMemoryLimits@nsMemoryCacheDevice@@AAEXII@Z ; 1
_NSGetModule ; 1
?Finalize@nsDiskCacheEntryHashTable@@CAXPAUPLDHashTable@@@Z ; 1
??0nsMemoryCacheDevice@@QAE@XZ ; 1
?evictDiskCacheEntries@nsDiskCacheDevice@@QAEIXZ ; 1
??0nsDiskCacheMap@@QAE@XZ ; 1
?ClearActiveEntries@nsCacheService@@AAEXXZ ; 1
?setCacheCapacity@nsDiskCacheDevice@@QAEXI@Z ; 1
?Init@nsDiskCacheEntryHashTable@@QAEIXZ ; 1
?DoomEntry@nsMemoryCacheDevice@@UAEXPAVnsCacheEntry@@@Z ; 1
?getPrefsObserver@nsDiskCacheDevice@@QAEXPAPAVnsIObserver@@@Z ; 1
??_EnsMemoryCacheDevice@@UAEPAXI@Z ; 1
?setCacheDirectory@nsDiskCacheDevice@@QAEXPAVnsILocalFile@@@Z ; 1
?Shutdown@nsCacheService@@UAGIXZ ; 1
??_GnsCacheService@@UAEPAXI@Z ; 1
?ClearDoomList@nsCacheService@@AAEXXZ ; 1
?QueryInterface@nsANSIOutputStream@@UAGIABUnsID@@PAPAX@Z ; 1
?Init@nsCacheService@@UAGIXZ ; 1
??0nsDiskCacheDevice@@QAE@XZ ; 1
?Swap@nsDiskCacheHeader@@QAEXXZ ; 1
?GetFileForEntry@nsCacheService@@QAEIPAVnsCacheEntry@@PAPAVnsIFile@@@Z ; 1
??_GnsDiskCacheDevice@@UAEPAXI@Z ; 1
??1nsCacheService@@UAE@XZ ; 1
?GetFileForEntry@nsDiskCacheDevice@@UAEIPAVnsCacheEntry@@PAPAVnsIFile@@@Z ; 1
?Init@nsMemoryCacheDevice@@UAEIXZ ; 1
?GetFile@nsCacheEntryDescriptor@@UAGIPAPAVnsIFile@@@Z ; 1
?Seek@nsANSIOutputStream@@UAGIHH@Z ; 1
?MemoryCacheSizeChanged@nsMemoryCacheDevice@@SAHPBDPAX@Z ; 1
?SetStoragePolicy@nsCacheEntryDescriptor@@UAGIH@Z ; 1
??0nsCacheService@@QAE@XZ ; 1
?Observe@nsCacheService@@UAGIPAVnsISupports@@PBG1@Z ; 1
?writeCacheMap@nsDiskCacheDevice@@QAEIXZ ; 1
?Init@nsDiskCacheDevice@@UAEIXZ ; 1
?Create@nsCacheService@@SGIPAVnsISupports@@ABUnsID@@PAPAX@Z ; 1
?NS_GetSpecialDirectory@@YAIPBDPAPAVnsIFile@@@Z ; 1
??1nsDiskCacheDevice@@UAE@XZ ; 1
?readCacheMap@nsDiskCacheDevice@@QAEIXZ ; 1
??1nsDiskCacheMap@@QAE@XZ ; 1
??_EnsDiskCacheObserver@@UAEPAXI@Z ; 1
?Unswap@nsDiskCacheHeader@@QAEXXZ ; 1
?CreateDiskDevice@nsCacheService@@AAEIXZ ; 1
??1nsMemoryCacheDevice@@UAE@XZ ; 1
?Shutdown@nsDiskCacheDevice@@UAEIXZ ; 1
?Write@nsDiskCacheMap@@QAEIPAVnsIOutputStream@@@Z ; 1

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* Defining the following causes NS_APPSHELL to be defined as NS_EXPORT. */
#define _IMPL_NS_APPSHELL
#include "MacSharedPrefix_debug.h"

View File

@@ -1,26 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
DIRS=public src resources
include <$(DEPTH)\config\rules.mak>

View File

@@ -1 +0,0 @@
nsIBookmarksService.idl

View File

@@ -1,35 +0,0 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = appcomps
XPIDL_MODULE = bookmarks
XPIDLSRCS = nsIBookmarksService.idl
include $(topsrcdir)/config/rules.mk

View File

@@ -1,31 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..\..
MODULE=bookmarks
XPIDLSRCS = \
.\nsIBookmarksService.idl \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,95 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* The Browser Bookmarks service
*/
#include "nsISupports.idl"
interface nsIRDFResource;
[scriptable, uuid(a82e9300-e4af-11d2-8fdf-0008c70adc7b)]
interface nsIBookmarksService : nsISupports
{
const unsigned long BOOKMARK_DEFAULT_TYPE = 0;
const unsigned long BOOKMARK_SEARCH_TYPE = 1;
const unsigned long BOOKMARK_FIND_TYPE = 2;
boolean ReadBookmarks();
boolean IsBookmarked(in string aURI);
void addBookmarkImmediately(in string aURI, in wstring aTitle, in long bmType, in wstring docCharset);
nsIRDFResource createFolder(in wstring aName, in nsIRDFResource aParentFolder);
nsIRDFResource createFolderWithDetails(in wstring aName, in nsIRDFResource aParentFolder,
in long aIndex);
nsIRDFResource createGroup(in wstring aName, in nsIRDFResource aParentFolder);
nsIRDFResource createGroupWithDetails(in wstring aName, in nsIRDFResource aParentFolder,
in long aIndex);
nsIRDFResource createBookmark(in wstring aName, in string aURL, in nsIRDFResource aParentFolder);
nsIRDFResource createBookmarkWithDetails(in wstring aName, in string aURI, in wstring docCharSet,
in nsIRDFResource aFolder, in long aIndex);
void updateBookmarkIcon(in string aURL, in wstring iconURL);
void removeBookmarkIcon(in string aURL, in wstring iconURL);
void updateLastVisitedDate(in string aURL, in wstring docCharset);
string resolveKeyword(in wstring aName);
wstring getLastCharset(in string aURI);
void importSystemBookmarks(in nsIRDFResource aParentFolder);
};
%{C++
// {E638D760-8687-11d2-B530-000000000000}
#define NS_BOOKMARKS_SERVICE_CID \
{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
#define NS_BOOKMARKS_SERVICE_CONTRACTID \
"@mozilla.org/browser/bookmarks-service;1"
#define NS_BOOKMARKS_DATASOURCE_CONTRACTID \
"@mozilla.org/rdf/datasource;1?name=bookmarks"
%}

View File

@@ -1,9 +0,0 @@
bm-find.js
bm-find.xul
bm-panel.js
bm-panel.xul
bm-props.js
bm-props.xul
bookmarks.js
bookmarksDD.js
bookmarks.xul

View File

@@ -1,30 +0,0 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk

View File

@@ -1,348 +0,0 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Add Bookmark Dialog.
* ====================
*
* This is a generic bookmark dialog that allows for bookmark addition
* and folder selection. It can be opened with various parameters that
* result in appearance/purpose differences and initial state.
*
* Use: Open with 'openDialog', with the flags
* 'centerscreen,chrome,dialog=no,resizable=yes'
*
* Parameters:
* Apart from the standard openDialog parameters, this dialog can
* be passed additional information, which gets mapped to the
* window.arguments array:
*
* window.arguments[0]: Bookmark Name. The value to be prefilled
* into the "Name: " field (if visible).
* window.arguments[1]: Bookmark URL: The location of the bookmark.
* The value to be filled in the "Location: "
* field (if visible).
* window.arguments[2]: Bookmark Folder. The RDF Resource URI of the
* folder that this bookmark should be created in.
* window.arguments[3]: Bookmark Charset. The charset that should be
* used when adding a bookmark to the specified
* URL. (Usually the charset of the current
* document when launching this window).
* window.arguments[4]: The mode of operation. See notes for details.
* window.arguments[5]: If the mode is "addGroup", this is an array
* of objects with name, URL and charset
* properties, one for each group member.
*
* Mode of Operation Notes:
* ------------------------
* This dialog can be opened in four different ways by using a parameter
* passed through the call to openDialog. The 'mode' of operation
* of the window is expressed in window.arguments[4]. The valid modes are:
*
* 1) <default> (no fifth open parameter).
* Opens this dialog with the bookmark Name, URL and folder selection
* components visible.
* 2) "newBookmark" (fifth open parameter = String("newBookmark"))
* Opens the dialog as in (1) above except the folder selection tree
* is hidden. This type of mode is useful when the creation folder
* is pre-determined.
* 3) "selectFolder" (fifth open parameter = String("selectFolder"))
* Opens the dialog as in (1) above except the Name/Location section
* is hidden, and the dialog takes on the utility of a Folder chooser.
* Used when the user must select a Folder for some purpose.
* 4) "addGroup" (fifth open parameter = String("addGroup"))
* Opens the dialog like <default>, with a checkbox to select between
* filing a single bookmark or a group. For the single bookmark the
* values are taken from the name, URL and charset arguments.
* For the group, the values are taken from the sixth argument.
* This parameter can also be String("addGroup,group") where "group"
* specifies that the dialog starts in filing as a group.
*/
var gFld_Name = null;
var gFld_URL = null;
var gFolderTree = null;
var gCB_AddGroup = null;
var gBookmarkCharset = null;
const kRDFSContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFSIID = Components.interfaces.nsIRDFService;
const kRDF = Components.classes[kRDFSContractID].getService(kRDFSIID);
var gSelectItemObserver = null;
var gCreateInFolder = "NC:NewBookmarkFolder";
function Startup()
{
gFld_Name = document.getElementById("name");
gFld_URL = document.getElementById("url");
gCB_AddGroup = document.getElementById("addgroup");
var bookmarkView = document.getElementById("bookmarks-view");
var shouldSetOKButton = true;
var dialogElement = document.documentElement;
if ("arguments" in window) {
var ind;
var folderItem = null;
var arg;
if (window.arguments.length < 5)
arg = null;
else
arg = window.arguments[4];
switch (arg) {
case "selectFolder":
// If we're being opened as a folder selection window
document.getElementById("bookmarknamegrid").setAttribute("hidden", "true");
document.getElementById("createinseparator").setAttribute("hidden", "true");
document.getElementById("nameseparator").setAttribute("hidden", "true");
sizeToContent();
dialogElement.setAttribute("title", dialogElement.getAttribute("title-selectFolder"));
shouldSetOKButton = false;
if (window.arguments[2])
folderItem = bookmarkView.rdf.GetResource(window.arguments[2]);
if (folderItem) {
ind = bookmarkView.treeBuilder.getIndexOfResource(folderItem);
bookmarkView.treeBoxObject.selection.select(ind);
}
break;
case "newBookmark":
setupFields();
if (window.arguments[2])
gCreateInFolder = window.arguments[2];
document.getElementById("folderbox").setAttribute("hidden", "true");
sizeToFit();
break;
case "addGroup":
document.getElementById("showaddgroup").setAttribute("hidden", "false");
setupFields();
sizeToFit();
break;
case "addGroup,group":
document.getElementById("showaddgroup").setAttribute("hidden", "false");
gCB_AddGroup.setAttribute("checked", "true");
setupFields();
toggleGroup();
sizeToFit();
break;
default:
// Regular Add Bookmark
setupFields();
if (window.arguments[2]) {
gCreateInFolder = window.arguments[2];
folderItem = bookmarkView.rdf.GetResource(gCreateInFolder);
if (folderItem) {
ind = bookmarkView.treeBuilder.getIndexOfResource(folderItem);
bookmarkView.treeBoxObject.selection.select(ind);
}
}
}
}
if (shouldSetOKButton)
onFieldInput();
if (document.getElementById("bookmarknamegrid").hasAttribute("hidden")) {
bookmarkView.tree.focus();
if (bookmarkView.currentIndex == -1)
bookmarkView.treeBoxObject.selection.select(0);
}
else {
gFld_Name.select();
gFld_Name.focus();
}
}
function sizeToFit()
{
var dialogElement = document.documentElement;
dialogElement.removeAttribute("persist");
dialogElement.removeAttribute("height");
dialogElement.removeAttribute("width");
dialogElement.setAttribute("style", dialogElement.getAttribute("style"));
sizeToContent();
}
function setupFields()
{
// New bookmark in predetermined folder.
gFld_Name.value = window.arguments[0] || "";
gFld_URL.value = window.arguments[1] || "";
onFieldInput();
gFld_Name.select();
gFld_Name.focus();
gBookmarkCharset = window.arguments[3] || null;
}
function onFieldInput()
{
const ok = document.documentElement.getButton("accept");
ok.disabled = gFld_URL.value == "" && !addingGroup() ||
gFld_Name.value == "";
}
function onOK()
{
if (!document.getElementById("folderbox").hasAttribute("hidden")) {
var bookmarkView = document.getElementById("bookmarks-view");
var currentIndex = bookmarkView.currentIndex;
if (currentIndex != -1)
gCreateInFolder = bookmarkView.treeBuilder.getResourceAtIndex(currentIndex).Value;
}
// In Select Folder Mode, do nothing but tell our caller what
// folder was selected.
if (window.arguments.length > 4 && window.arguments[4] == "selectFolder")
window.arguments[5].selectedFolder = gCreateInFolder;
else {
// Otherwise add a bookmark to the selected folder.
const kBMDS = kRDF.GetDataSource("rdf:bookmarks");
const kBMSContractID = "@mozilla.org/browser/bookmarks-service;1";
const kBMSIID = Components.interfaces.nsIBookmarksService;
const kBMS = Components.classes[kBMSContractID].getService(kBMSIID);
var rFolder = kRDF.GetResource(gCreateInFolder, true);
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFIID = Components.interfaces.nsIRDFContainer;
const kRDFC = Components.classes[kRDFCContractID].getService(kRDFIID);
try {
kRDFC.Init(kBMDS, rFolder);
}
catch (e) {
// No "NC:NewBookmarkFolder" exists, just append to the root.
rFolder = kRDF.GetResource("NC:BookmarksRoot", true);
kRDFC.Init(kBMDS, rFolder);
}
// if no URL was provided and we're not filing as a group, do nothing
if (!gFld_URL.value && !addingGroup())
return;
var url;
if (addingGroup()) {
const group = kBMS.createGroup(gFld_Name.value, rFolder);
const groups = window.arguments[5];
for (var i = 0; i < groups.length; ++i) {
url = getNormalizedURL(groups[i].url);
kBMS.createBookmarkWithDetails(groups[i].name, url,
groups[i].charset, group, -1);
}
} else {
url = getNormalizedURL(gFld_URL.value);
var newBookmark = kBMS.createBookmarkWithDetails(gFld_Name.value, url, gBookmarkCharset, rFolder, -1);
if (window.arguments.length > 4 && window.arguments[4] == "newBookmark") {
window.arguments[5].newBookmark = newBookmark;
}
}
}
}
function getNormalizedURL(url)
{
// Check to see if the item is a local directory path, and if so, convert
// to a file URL so that aggregation with rdf:files works
try {
const kLF = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
kLF.initWithPath(url);
if (kLF.exists()) {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.classes.nsIIOService);
url = ioService.getURLSpecFromFile(kLF);
}
}
catch (e) {
}
return url;
}
var gBookmarksShell = null;
function createNewFolder ()
{
var bookmarksView = document.getElementById("bookmarks-view");
bookmarksView.createNewFolder();
}
function useDefaultFolder ()
{
const kBMDS = kRDF.GetDataSource("rdf:bookmarks");
var bookmarkView = document.getElementById("bookmarks-view");
var sources = kBMDS.GetSources(bookmarkView.rdf.GetResource(NC_NS + "FolderType"), bookmarkView.rdf.GetResource("NC:NewBookmarkFolder"), true);
var folder = null;
if (sources.hasMoreElements()) {
folder = sources.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
}
var ind = bookmarkView.treeBuilder.getIndexOfResource(folder);
if (ind != -1) {
bookmarkView.tree.focus();
bookmarkView.treeBoxObject.selection.select(ind);
gCreateInFolder = folder.Value;
}
else {
bookmarkView.treeBoxObject.selection.clearSelection();
gCreateInFolder = "NC:BookmarksRoot";
}
}
var gOldNameValue = "";
var gOldURLValue = "";
function toggleGroup()
{
// swap between single bookmark and group name
var temp = gOldNameValue;
gOldNameValue = gFld_Name.value;
gFld_Name.value = temp;
// swap between single bookmark and group url
temp = gOldURLValue;
gOldURLValue = gFld_URL.value;
gFld_URL.value = temp;
gFld_URL.disabled = gCB_AddGroup.getAttribute("checked") == "true";
gFld_Name.select();
gFld_Name.focus();
onFieldInput();
}
function addingGroup()
{
const showAddGroup = document.getElementById("showaddgroup");
return showAddGroup.getAttribute("hidden") != "true" && gCB_AddGroup.getAttribute("checked") == "true";
}

View File

@@ -1,118 +0,0 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape 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/NPL/
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 mozilla.org code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Ben Goodger <ben@netscape.com> (Original Author)
-->
<?xml-stylesheet href="chrome://communicator/skin/"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarks.css"?>
<?xml-stylesheet href="chrome://communicator/content/bookmarks/bookmarks.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
%brandDTD;
<!ENTITY % addBookmarkDTD SYSTEM "chrome://communicator/locale/bookmarks/addBookmark.dtd">
%addBookmarkDTD;
]>
<dialog id="newBookmarkDialog" style="width: 36em;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
ondialogaccept="return onOK(event)"
title="&newBookmark.title;" title-selectFolder="&selectFolder.label;"
onload="Startup();"
persist="screenX screenY width height"
screenX="24" screenY="24">
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksTree.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/addBookmark.js"/>
<stringbundle id="bookmarksbundle"
src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
<broadcaster id="showaddgroup" hidden="true"/>
<separator id="nameseparator" class="thin"/>
<grid id="bookmarknamegrid">
<columns>
<column/>
<column flex="5"/>
<column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&name.label;" accesskey="&name.accesskey;" control="name"/>
<textbox id="name" oninput="onFieldInput();"/>
<spacer/>
</row>
<row>
<separator class="thin"/>
<separator class="thin"/>
<spacer/>
</row>
<row align="center">
<label value="&url.label;" accesskey="&url.accesskey;" control="url"/>
<textbox id="url" oninput="onFieldInput();"/>
<spacer/>
</row>
<row observes="showaddgroup">
<separator class="thin"/>
<separator class="thin"/>
<spacer/>
</row>
<row observes="showaddgroup">
<spacer/>
<hbox pack="start">
<checkbox id="addgroup" label="&addGroup.label;"
accesskey="&addGroup.accesskey;" oncommand="toggleGroup();"/>
</hbox>
<spacer/>
</row>
</rows>
</grid>
<separator id="createinseparator"/>
<vbox id="folderbox" flex="1">
<separator/>
<hbox flex="1">
<label id="createinlabel" value="&createin.label;"/>
<hbox flex="1">
<bookmarks-tree id="bookmarks-view" flex="1" type="folders"/>
<vbox>
<button label="&button.newfolder.label;" accesskey="&button.newfolder.accesskey;"
oncommand="createNewFolder();"/>
<button label="&button.defaultfolder.label;"
accesskey="&button.defaultfolder.accesskey;"
oncommand="useDefaultFolder();"/>
</vbox>
</hbox>
</hbox>
</vbox>
<separator/>
</dialog>

View File

@@ -1,87 +0,0 @@
<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape 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/NPL/
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 mozilla.org code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Ben Goodger <ben@netscape.com> (Original Author, v2.0)
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/sidebar/sidebarListView.css" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarksWindow.css" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/content/bookmarks/bookmarks.css" type="text/css"?>
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/tasksOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://communicator/locale/bookmarks/bookmarks.dtd">
<page id="bookmarksPanel"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Startup();" elementtofocus="bookmarks-view">
<!-- XXX - would like to cut this dependency out -->
<script type="application/x-javascript" src="chrome://global/content/strres.js"/>
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
<!-- Bookmarks Shell -->
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksPanel.js"/>
<!-- Drag and Drop -->
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksDD.js"/>
<!-- context menu, tooltips, etc -->
<popupset id="bookmarksPopupset"/>
<!-- bookmarks string bundle -->
<stringbundleset id="stringbundleset"/>
<!-- bookmarks & edit commands -->
<commands id="commands">
<commandset id="CommandUpdate_Bookmarks"
commandupdater="true"
events="click,focus"
oncommandupdate="document.getElementById('bookmarks-view').onCommandUpdate();">
</commandset>
<commandset id="bookmarksItems"/>
</commands>
<hbox id="panel-bar" class="toolbar">
<toolbarbutton id="btnAddBookmark" label="&command.addBookmark.label;"
oncommand="addBookmark();"/>
<toolbarbutton id="btnManageBookmarks" label="&command.manageBookmarks.label;"
oncommand="manageBookmarks();"/>
<spacer flex="1"/>
<toolbarseparator/>
<toolbarbutton id="btnFindBookmarks" label="&command.findBookmarks.label;"
oncommand="document.getElementById('bookmarks-view').openFindDialog();"/>
</hbox>
<bookmarks-tree id="bookmarks-view" class="sidebar" type="single-column" flex="1"/>
</page>

View File

@@ -1,387 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var NC_NAMESPACE_URI = "http://home.netscape.com/NC-rdf#";
// XXX MAKE SURE that the "url" field is LAST!
// This is important for what happens if/when the URL itself is changed.
// Ask rjc@netscape.com if you want to know why exactly this is.
// This is the set of fields that are visible in the window.
var gFields = ["name", "shortcut", "description", "url"];
// ...and this is a parallel array that contains the RDF properties
// that they are associated with.
var gProperties = [NC_NAMESPACE_URI + "Name",
NC_NAMESPACE_URI + "ShortcutURL",
NC_NAMESPACE_URI + "Description",
NC_NAMESPACE_URI + "URL"];
var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]
.getService(Components.interfaces.nsIRDFService);
var RDFC = Components.classes["@mozilla.org/rdf/container-utils;1"]
.getService(Components.interfaces.nsIRDFContainerUtils);
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
var gBookmarkURL = "";
function Init()
{
var x;
gBookmarkURL = window.arguments[0];
// Initialize the properties panel by copying the values from the
// RDF graph into the fields on screen.
for (var i = 0; i < gFields.length; ++i) {
var field = document.getElementById(gFields[i]);
var value = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
RDF.GetResource(gProperties[i]),
true);
if (value)
value = value.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
if (value) //make sure were aren't stuffing null into any fields
field.value = value;
}
var propsWindow = document.getElementById("bmPropsWindow");
var nameNode = document.getElementById("name");
var title = propsWindow.getAttribute("title");
title = title.replace(/\*\*bm_title\*\*/gi, nameNode.value);
propsWindow.setAttribute("title", title);
// check bookmark schedule
value = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
RDF.GetResource("http://home.netscape.com/WEB-rdf#Schedule"),
true);
if (value) {
value = value.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
if (value) {
var values = value.split("|");
if (values.length == 4) {
// get day range
var days = values[0];
var dayNode = document.getElementById("dayRange");
var dayItems = dayNode.childNodes[0].childNodes;
for (x=0; x < dayItems.length; ++x) {
if (dayItems[x].getAttribute("value") == days) {
dayNode.selectedItem = dayItems[x];
break;
}
}
// get hour range
var hours = values[1].split("-");
var startHour = "";
var endHour = "";
if (hours.length == 2) {
startHour = hours[0];
endHour = hours[1];
}
// set start hour
var startHourNode = document.getElementById("startHourRange");
var startHourItems = startHourNode.childNodes[0].childNodes;
for (x=0; x < startHourItems.length; ++x) {
if (startHourItems[x].getAttribute("value") == startHour) {
startHourNode.selectedItem = startHourItems[x];
break;
}
}
// set end hour
var endHourNode = document.getElementById("endHourRange");
var endHourItems = endHourNode.childNodes[0].childNodes;
for (x=0; x < endHourItems.length; ++x) {
if (endHourItems[x].getAttribute("value") == endHour) {
endHourNode.selectedItem = endHourItems[x];
break;
}
}
// get duration
var duration = values[2];
var durationNode = document.getElementById("duration");
durationNode.value = duration;
// get notification method
var method = values[3];
if (method.indexOf("icon") >= 0)
document.getElementById("bookmarkIcon").checked = true;
if (method.indexOf("sound") >= 0)
document.getElementById("playSound").checked = true;
if (method.indexOf("alert") >= 0)
document.getElementById("showAlert").checked = true;
if (method.indexOf("open") >= 0)
document.getElementById("openWindow").checked = true;
}
}
}
// if its a container, disable some things
var isContainerFlag = RDFC.IsContainer(Bookmarks, RDF.GetResource(gBookmarkURL));
if (!isContainerFlag) {
// XXX To do: the "RDFC.IsContainer" call above only works for RDF sequences;
// if its not a RDF sequence, we should to more checking to see if
// the item in question is really a container of not. A good example
// of this is the "File System" container.
}
if (isContainerFlag) {
// If it is a folder, it has no URL or Keyword
document.getElementById("locationrow").setAttribute("hidden", "true");
document.getElementById("shortcutrow").setAttribute("hidden", "true");
}
if (gBookmarkURL.substr(0, 7).toLowerCase() != "http://" &&
gBookmarkURL.substr(0, 8).toLowerCase() != "https://") {
// only allow scheduling of http/https URLs
document.getElementById("ScheduleTab").setAttribute("hidden", "true");
document.getElementById("NotifyTab").setAttribute("hidden", "true");
}
sizeToContent();
// Set up the enabled of controls on the scheduling panels
dayRangeChange(document.getElementById("dayRange"));
// set initial focus
var name = document.getElementById("name");
name.focus();
name.select();
}
function Commit()
{
var changed = false;
// Grovel through the fields to see if any of the values have
// changed. If so, update the RDF graph and force them to be saved
// to disk.
for (var i = 0; i < gFields.length; ++i) {
var field = document.getElementById(gFields[i]);
if (field) {
// Get the new value as a literal, using 'null' if the value is empty.
var newvalue = field.value;
var oldvalue = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
RDF.GetResource(gProperties[i]),
true);
if (oldvalue)
oldvalue = oldvalue.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (newvalue && gProperties[i] == (NC_NAMESPACE_URI + "ShortcutURL")) {
// shortcuts are always lowercased internally
newvalue = newvalue.toLowerCase();
}
else if (newvalue && gProperties[i] == (NC_NAMESPACE_URI + "URL")) {
// we're dealing with the URL attribute;
// if a scheme isn't specified, use "http://"
if (newvalue.indexOf(":") < 0)
newvalue = "http://" + newvalue;
}
if (newvalue)
newvalue = RDF.GetLiteral(newvalue);
if (updateAttribute(gProperties[i], oldvalue, newvalue)) {
// Update gBookmarkURL if the url changed
if (newvalue && gProperties[i] == NC_NAMESPACE_URI + "URL")
gBookmarkURL = newvalue.Value;
changed = true;
}
}
}
// Update bookmark schedule if necessary;
// if the tab was removed, just skip it
var scheduleTab = document.getElementById("ScheduleTab");
if (scheduleTab) {
var scheduleRes = "http://home.netscape.com/WEB-rdf#Schedule";
oldvalue = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
RDF.GetResource(scheduleRes), true);
newvalue = "";
var dayRangeNode = document.getElementById("dayRange");
var dayRange = dayRangeNode.selectedItem.getAttribute("value");
if (dayRange) {
var startHourRangeNode = document.getElementById("startHourRange");
var startHourRange = startHourRangeNode.selectedItem.getAttribute("value");
var endHourRangeNode = document.getElementById("endHourRange");
var endHourRange = endHourRangeNode.selectedItem.getAttribute("value");
if (parseInt(startHourRange) > parseInt(endHourRange)) {
var temp = startHourRange;
startHourRange = endHourRange;
endHourRange = temp;
}
var bookmarkBundle;
var duration = document.getElementById("duration").value;
if (!duration) {
bookmarkBundle = document.getElementById("bundle_bookmark");
alert (bookmarkBundle.getString("pleaseEnterADuration"));
return false;
}
var methods = [];
if (document.getElementById("bookmarkIcon").checked)
methods.push("icon");
if (document.getElementById("playSound").checked)
methods.push("sound");
if (document.getElementById("showAlert").checked)
methods.push("alert");
if (document.getElementById("openWindow").checked)
methods.push("open");
if (methods.length == 0) {
bookmarkBundle = document.getElementById("bundle_bookmark");
alert (bookmarkBundle.getString("pleaseSelectANotification"));
return false;
}
var method = methods.join(); // join string in array with ","
newvalue = dayRange + "|" + startHourRange + "-" + endHourRange + "|" + duration + "|" + method;
}
if (newvalue)
newvalue = RDF.GetLiteral(newvalue);
if (updateAttribute(scheduleRes, oldvalue, newvalue))
changed = true;
}
if (changed) {
var remote = Bookmarks.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
if (remote)
remote.Flush();
}
window.close();
return true;
}
function updateAttribute(prop, oldvalue, newvalue)
{
var changed = false;
if (prop && (oldvalue || newvalue) && oldvalue != newvalue) {
if (oldvalue && !newvalue) {
Bookmarks.Unassert(RDF.GetResource(gBookmarkURL),
RDF.GetResource(prop),
oldvalue);
}
else if (!oldvalue && newvalue) {
Bookmarks.Assert(RDF.GetResource(gBookmarkURL),
RDF.GetResource(prop),
newvalue,
true);
}
else /* if (oldvalue && newvalue) */ {
Bookmarks.Change(RDF.GetResource(gBookmarkURL),
RDF.GetResource(prop),
oldvalue,
newvalue);
}
changed = true;
}
return changed;
}
function setEndHourRange()
{
// Get the values of the start-time and end-time as ints
var startHourRangeNode = document.getElementById("startHourRange");
var startHourRange = startHourRangeNode.selectedItem.getAttribute("value");
var startHourRangeInt = parseInt(startHourRange);
var endHourRangeNode = document.getElementById("endHourRange");
var endHourRange = endHourRangeNode.selectedItem.getAttribute("value");
var endHourRangeInt = parseInt(endHourRange);
var endHourItemNode = endHourRangeNode.firstChild.firstChild;
var index = 0;
// disable all those end-times before the start-time
for (; index < startHourRangeInt; ++index) {
endHourItemNode.setAttribute("disabled", "true");
endHourItemNode = endHourItemNode.nextSibling;
}
// update the selected value if it's out of the allowed range
if (startHourRangeInt >= endHourRangeInt)
endHourRangeNode.selectedItem = endHourItemNode;
// make sure all the end-times after the start-time are enabled
for (; index < 24; ++index) {
endHourItemNode.removeAttribute("disabled");
endHourItemNode = endHourItemNode.nextSibling;
}
}
function dayRangeChange (aMenuList)
{
var controls = ["startHourRange", "endHourRange", "duration", "bookmarkIcon",
"showAlert", "openWindow", "playSound", "durationSubLabel",
"durationLabel", "startHourRangeLabel", "endHourRangeLabel"];
for (var i = 0; i < controls.length; ++i)
document.getElementById(controls[i]).disabled = !aMenuList.value;
}

View File

@@ -1,235 +0,0 @@
<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape 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/NPL/
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 mozilla.org code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarks.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
%brandDTD;
<!ENTITY % bmpropsDTD SYSTEM "chrome://communicator/locale/bookmarks/bm-props.dtd">
%bmpropsDTD;
]>
<dialog id="bmPropsWindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&bookmarks.windowtitle.label;"
onload="Init()" style="width: 30em;"
ondialogaccept="return Commit();">
<stringbundle id="bundle_bookmark" src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bm-props.js"/>
<keyset id="keyset"/>
<tabbox>
<tabs>
<tab label="&generalInfo.label;" accesskey="&generalInfo.accesskey;"/>
<tab id="ScheduleTab" label="&schedule.label;" accesskey="&schedule.accesskey;"/>
<tab id="NotifyTab" label="&notification.label;" accesskey="&notification.accesskey;"/>
</tabs>
<tabpanels>
<vbox>
<separator class="thin"/>
<hbox align="start">
<image class="message-icon"/>
<separator class="thin" orient="vertical"/>
<description flex="1">&generaldesc.label;</description>
</hbox>
<separator class="thin"/>
<vbox class="box-padded">
<grid>
<columns>
<column />
<column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&bookmarks.name.label;" control="name"/>
<textbox id="name"/>
</row>
<row id="locationrow" align="center">
<label value="&bookmarks.location.label;" control="url"/>
<textbox id="url" />
</row>
<row id="shortcutrow" align="center">
<label value="&bookmarks.shortcut.label;" control="shortcut"/>
<textbox id="shortcut" />
</row>
<row>
<label value="&bookmarks.description.label;" control="description"/>
<textbox multiline="true" wrap="virtual" id="description" flex="1"/>
</row>
</rows>
</grid>
<separator/>
</vbox>
</vbox>
<vbox>
<separator class="thin"/>
<hbox align="center">
<image id="schedule-icon"/>
<separator class="thin" orient="vertical"/>
<description flex="1">&schedule.description;</description>
</hbox>
<separator class="thin"/>
<hbox class="box-padded">
<spacer flex="1"/>
<groupbox>
<caption label="&checkforupdates.legend.label;"/>
<grid flex="1">
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&when.label;" control="dayRange"/>
<hbox>
<menulist id="dayRange" oncommand="dayRangeChange(this);">
<menupopup>
<menuitem value="" label="&checknever.label;"/>
<menuseparator />
<menuitem value="0123456" label="&checkeveryday.label;"/>
<menuitem value="12345" label="&checkweekdays.label;"/>
<menuitem value="06" label="&checkweekends.label;"/>
<menuitem value="1" label="&checkmondays.label;"/>
<menuitem value="2" label="&checktuesdays.label;"/>
<menuitem value="3" label="&checkwednesdays.label;"/>
<menuitem value="4" label="&checkthursdays.label;"/>
<menuitem value="5" label="&checkfridays.label;"/>
<menuitem value="6" label="&checksaturdays.label;"/>
<menuitem value="0" label="&checksundays.label;"/>
</menupopup>
</menulist>
</hbox>
</row>
<row align="center">
<label id="startHourRangeLabel"
value="&from.label;" control="startHourRange"/>
<hbox align="center">
<menulist id="startHourRange" oncommand="setEndHourRange()">
<menupopup>
<menuitem value="0" label="&midnight.label;"/>
<menuitem value="1" label="&AMone.label;"/>
<menuitem value="2" label="&AMtwo.label;"/>
<menuitem value="3" label="&AMthree.label;"/>
<menuitem value="4" label="&AMfour.label;"/>
<menuitem value="5" label="&AMfive.label;"/>
<menuitem value="6" label="&AMsix.label;"/>
<menuitem value="7" label="&AMseven.label;"/>
<menuitem value="8" label="&AMeight.label;"/>
<menuitem value="9" label="&AMnine.label;"/>
<menuitem value="10" label="&AMten.label;"/>
<menuitem value="11" label="&AMeleven.label;"/>
<menuitem value="12" label="&noon.label;"/>
<menuitem value="13" label="&PMone.label;"/>
<menuitem value="14" label="&PMtwo.label;"/>
<menuitem value="15" label="&PMthree.label;"/>
<menuitem value="16" label="&PMfour.label;"/>
<menuitem value="17" label="&PMfive.label;"/>
<menuitem value="18" label="&PMsix.label;"/>
<menuitem value="19" label="&PMseven.label;"/>
<menuitem value="20" label="&PMeight.label;"/>
<menuitem value="21" label="&PMnine.label;"/>
<menuitem value="22" label="&PMten.label;"/>
<menuitem value="23" label="&PMeleven.label;"/>
</menupopup>
</menulist>
<label id="endHourRangeLabel"
value="&to.label;" control="endHourRange"/>
<menulist id="endHourRange">
<menupopup onpopupshowing="setEndHourRange()">
<menuitem value="1" label="&AMone.label;"/>
<menuitem value="2" label="&AMtwo.label;"/>
<menuitem value="3" label="&AMthree.label;"/>
<menuitem value="4" label="&AMfour.label;"/>
<menuitem value="5" label="&AMfive.label;"/>
<menuitem value="6" label="&AMsix.label;"/>
<menuitem value="7" label="&AMseven.label;"/>
<menuitem value="8" label="&AMeight.label;"/>
<menuitem value="9" label="&AMnine.label;"/>
<menuitem value="10" label="&AMten.label;"/>
<menuitem value="11" label="&AMeleven.label;"/>
<menuitem value="12" label="&noon.label;"/>
<menuitem value="13" label="&PMone.label;"/>
<menuitem value="14" label="&PMtwo.label;"/>
<menuitem value="15" label="&PMthree.label;"/>
<menuitem value="16" label="&PMfour.label;"/>
<menuitem value="17" label="&PMfive.label;"/>
<menuitem value="18" label="&PMsix.label;"/>
<menuitem value="19" label="&PMseven.label;"/>
<menuitem value="20" label="&PMeight.label;"/>
<menuitem value="21" label="&PMnine.label;"/>
<menuitem value="22" label="&PMten.label;"/>
<menuitem value="23" label="&PMeleven.label;"/>
<menuitem value="24" label="&midnight.label;"/>
</menupopup>
</menulist>
</hbox>
</row>
<row align="center">
<label id="durationLabel"
value="&every.label;" control="duration"/>
<hbox align="center">
<textbox id="duration" size="4" value="60" />
<label id="durationSubLabel" value="&minutes.label;" />
</hbox>
</row>
</rows>
</grid>
<separator class="thin"/>
</groupbox>
<spacer flex="1"/>
</hbox>
</vbox>
<vbox>
<separator class="thin"/>
<hbox align="start">
<image id="notification-icon"/>
<separator class="thin" orient="vertical"/>
<description flex="1">&notification.description;</description>
</hbox>
<separator class="thin"/>
<hbox class="box-padded">
<spacer flex="1"/>
<groupbox>
<caption label="&notifications.legend.label;" />
<vbox align="start">
<checkbox id="bookmarkIcon" label="&notification.icon.label;" />
<checkbox id="showAlert" label="&notification.alert.label;" />
<checkbox id="openWindow" label="&notification.window.label;" />
<checkbox id="playSound" label="&notification.sound.label;" />
</vbox>
</groupbox>
<spacer flex="1"/>
</hbox>
</vbox>
</tabpanels>
</tabbox>
</dialog>

View File

@@ -1,854 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
This is the old bookmarks code, included here for the sake of the bookmarks sidebar panel,
which will be fixed to use my new code in .9. In the mean time, this file provides a
life line to various functionality.
*/
var NC_NS = "http://home.netscape.com/NC-rdf#";
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
function Init() {
var tree = document.getElementById("bookmarksTree");
tree.controllers.appendController(BookmarksController);
var children = document.getElementById('treechildren-bookmarks');
tree.selectItem(children.firstChild);
tree.focus();
RefreshSort();
}
var BookmarksController = {
supportsCommand: function(command)
{
switch(command)
{
case "cmd_undo":
case "cmd_redo":
return false;
case "cmd_cut":
case "cmd_copy":
case "cmd_paste":
case "cmd_delete":
case "cmd_selectAll":
return true;
default:
return false;
}
},
isCommandEnabled: function(command)
{
switch(command)
{
case "cmd_undo":
case "cmd_redo":
return false;
case "cmd_cut":
case "cmd_copy":
case "cmd_paste":
case "cmd_delete":
case "cmd_selectAll":
return true;
default:
return false;
}
},
doCommand: function(command)
{
switch(command)
{
case "cmd_undo":
case "cmd_redo":
break;
case "cmd_cut":
doCut();
break;
case "cmd_copy":
doCopy();
break;
case "cmd_paste":
doPaste();
break;
case "cmd_delete":
doDelete();
break;
case "cmd_selectAll":
doSelectAll();
break;
}
},
onEvent: function(event)
{
// On blur events set the menu item texts back to the normal values
/*if (event == 'blur' )
{
goSetMenuValue('cmd_undo', 'valueDefault');
goSetMenuValue('cmd_redo', 'valueDefault');
}*/
}
};
function CommandUpdate_Bookmarks()
{
//goUpdateCommand('button_delete');
// get selection info from dir pane
/*
var oneAddressBookSelected = false;
if ( dirTree && dirTree.selectedItems && (dirTree.selectedItems.length == 1) )
oneAddressBookSelected = true;
// get selection info from results pane
var selectedCards = GetSelectedAddresses();
var oneOrMoreCardsSelected = false;
if ( selectedCards )
oneOrMoreCardsSelected = true;
*/
// set commands to enabled / disabled
//goSetCommandEnabled('cmd_PrintCard', oneAddressBookSelected);
goSetCommandEnabled('bm_cmd_find', true/*oneAddressBookSelected*/);
}
function copySelectionToClipboard()
{
var treeNode = document.getElementById("bookmarksTree");
if (!treeNode) return false;
var select_list = treeNode.selectedItems;
if (!select_list) return false;
if (select_list.length < 1) return false;
var rdf_uri = "@mozilla.org/rdf/rdf-service;1"
var RDF = Components.classes[rdf_uri].getService();
RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
if (!RDF) return false;
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
if (!Bookmarks) return false;
var nameRes = RDF.GetResource(NC_NS + "Name");
if (!nameRes) return false;
// Build a url that encodes all the select nodes
// as well as their parent nodes
var url = "";
var text = "";
var html = "";
for (var nodeIndex = 0; nodeIndex < select_list.length; nodeIndex++)
{
var node = select_list[nodeIndex];
if (!node) continue;
var ID = getAbsoluteID("bookmarksTree", node);
if (!ID) continue;
var IDRes = RDF.GetResource(ID);
if (!IDRes) continue;
var nameNode = Bookmarks.GetTarget(IDRes, nameRes, true);
var theName = "";
if (nameNode)
nameNode =
nameNode.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (nameNode) theName = nameNode.Value;
url += "ID:{" + ID + "};";
url += "NAME:{" + theName + "};";
if (node.getAttribute("container") == "true")
{
var type = node.getAttribute("type");
if (type == NC_NS + "BookmarkSeparator")
{
// Note: can't encode separators in text, just html
html += "<hr><p>";
}
else
{
text += ID + "\r";
html += "<a href='" + ID + "'>";
if (theName != "")
{
html += theName;
}
html += "</a><p>";
}
}
}
if (url == "") return false;
// get some useful components
var trans_uri = "@mozilla.org/widget/transferable;1";
var trans = Components.classes[trans_uri].createInstance();
if (trans) trans = trans.QueryInterface(Components.interfaces.nsITransferable);
if (!trans) return false;
var clip_uri = "@mozilla.org/widget/clipboard;1";
var clip = Components.classes[clip_uri].getService();
if (clip) clip = clip.QueryInterface(Components.interfaces.nsIClipboard);
if (!clip) return false;
clip.emptyClipboard(Components.interfaces.nsIClipboard.kGlobalClipboard);
// save bookmark's ID
trans.addDataFlavor("moz/bookmarkclipboarditem");
var data_uri = "@mozilla.org/supports-wstring;1";
var data = Components.classes[data_uri].createInstance();
if (data) {
data = data.QueryInterface(Components.interfaces.nsISupportsWString);
}
if (!data) return false;
data.data = url;
// double byte data
trans.setTransferData("moz/bookmarkclipboarditem", data, url.length*2);
if (text != "")
{
trans.addDataFlavor("text/unicode");
var textData_uri = "@mozilla.org/supports-wstring;1";
var textData = Components.classes[textData_uri].createInstance();
if (textData) textData = textData.QueryInterface(Components.interfaces.nsISupportsWString);
if (!textData) return false;
textData.data = text;
// double byte data
trans.setTransferData("text/unicode", textData, text.length*2);
}
if (html != "")
{
trans.addDataFlavor("text/html");
var wstring_uri = "@mozilla.org/supports-wstring;1";
var htmlData = Components.classes[wstring_uri].createInstance();
if (htmlData) {
var wstring_interface = Components.interfaces.nsISupportsWString;
htmlData = htmlData.QueryInterface(wstring_interface);
}
if (!htmlData) return false;
htmlData.data = html;
// double byte data
trans.setTransferData("text/html", htmlData, html.length*2);
}
clip.setData(trans, null,
Components.interfaces.nsIClipboard.kGlobalClipboard);
return true;
}
function doCut()
{
if (copySelectionToClipboard() == true) {
doDelete(false);
}
return true;
}
function doCopy()
{
copySelectionToClipboard();
return true;
}
function doPaste()
{
var treeNode = document.getElementById("bookmarksTree");
if (!treeNode) return false;
var select_list = treeNode.selectedItems;
if (!select_list) return false;
if (select_list.length != 1) return false;
var pasteNodeID = select_list[0].getAttribute("id");
var isContainerFlag = (select_list[0].getAttribute("container") == "true");
var clip_uri = "@mozilla.org/widget/clipboard;1";
var clip = Components.classes[clip_uri].getService();
if (clip) clip = clip.QueryInterface(Components.interfaces.nsIClipboard);
if (!clip) return false;
var trans_uri = "@mozilla.org/widget/transferable;1";
var trans = Components.classes[trans_uri].createInstance();
if (trans) {
trans = trans.QueryInterface(Components.interfaces.nsITransferable);
}
if (!trans) return false;
trans.addDataFlavor("moz/bookmarkclipboarditem");
clip.getData(trans, Components.interfaces.nsIClipboard.kGlobalClipboard);
var data = new Object();
var dataLen = new Object();
trans.getTransferData("moz/bookmarkclipboarditem", data, dataLen);
if (data) {
var data_interface = Components.interfaces.nsISupportsWString
data = data.value.QueryInterface(data_interface);
}
var url = null;
// double byte data
if (data) url = data.data.substring(0, dataLen.value / 2);
if (!url) return false;
var strings = url.split(";");
if (!strings) return false;
var rdf_uri = "@mozilla.org/rdf/rdf-service;1";
var RDF = Components.classes[rdf_uri].getService();
RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
if (!RDF) return false;
var rdfc_uri = "@mozilla.org/rdf/container;1";
var RDFC = Components.classes[rdfc_uri].getService();
RDFC = RDFC.QueryInterface(Components.interfaces.nsIRDFContainer);
if (!RDFC) return false;
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
if (!Bookmarks) return false;
var nameRes = RDF.GetResource(NC_NS + "Name");
if (!nameRes) return false;
pasteNodeRes = RDF.GetResource(pasteNodeID);
if (!pasteNodeRes) return false;
var pasteContainerRes = null;
var pasteNodeIndex = -1;
if (isContainerFlag == true)
{
pasteContainerRes = pasteNodeRes;
}
else
{
var parID = select_list[0].parentNode.parentNode.getAttribute("ref");
if (!parID) {
parID = select_list[0].parentNode.parentNode.getAttribute("id");
}
if (!parID) return false;
pasteContainerRes = RDF.GetResource(parID);
if (!pasteContainerRes) return false;
}
RDFC.Init(Bookmarks, pasteContainerRes);
if (isContainerFlag == false)
{
pasteNodeIndex = RDFC.IndexOf(pasteNodeRes);
if (pasteNodeIndex < 0) return false; // how did that happen?
}
var typeRes = RDF.GetResource(RDF_NS + "type");
if (!typeRes) return false;
var bmTypeRes = RDF.GetResource(NC_NS + "Bookmark");
if (!bmTypeRes) return false;
var dirty = false;
for (var x=0; x<strings.length; x=x+2)
{
var theID = strings[x];
var theName = strings[x+1];
if ((theID.indexOf("ID:{") == 0) && (theName.indexOf("NAME:{") == 0))
{
theID = theID.substr(4, theID.length-5);
theName = theName.substr(6, theName.length-7);
var IDRes = RDF.GetResource(theID);
if (!IDRes) continue;
if (RDFC.IndexOf(IDRes) > 0)
continue;
if (theName != "")
{
var NameLiteral = RDF.GetLiteral(theName);
if (NameLiteral)
{
Bookmarks.Assert(IDRes, nameRes, NameLiteral, true);
dirty = true;
}
}
if (isContainerFlag == true)
RDFC.AppendElement(IDRes);
else
RDFC.InsertElementAt(IDRes, pasteNodeIndex++, true);
dirty = true;
// make sure appropriate bookmark type is set
var bmTypeNode = Bookmarks.GetTarget( IDRes, typeRes, true );
if (!bmTypeNode)
{
// set default bookmark type
Bookmarks.Assert(IDRes, typeRes, bmTypeRes, true);
}
}
}
if (dirty == true)
{
var rdf_ds_interface = Components.interfaces.nsIRDFRemoteDataSource;
var remote = Bookmarks.QueryInterface(rdf_ds_interface);
if (remote)
remote.Flush();
}
return true;
}
function doDelete(promptFlag)
{
var treeNode = document.getElementById("bookmarksTree");
if (!treeNode) return false;
var select_list = treeNode.selectedItems;
if (!select_list) return false;
if (select_list.length < 1) return false;
if (promptFlag == true)
{
var deleteStr = '';
if (select_list.length == 1) {
deleteStr = get_localized_string("DeleteItem");
} else {
deleteStr = get_localized_string("DeleteItems");
}
var ok = confirm(deleteStr);
if (!ok) return false;
}
var RDF_uri = "@mozilla.org/rdf/rdf-service;1";
var RDF = Components.classes[RDF_uri].getService();
RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
if (!RDF) return false;
var RDFC_uri = "@mozilla.org/rdf/container;1";
var RDFC = Components.classes[RDFC_uri].getService();
RDFC = RDFC.QueryInterface(Components.interfaces.nsIRDFContainer);
if (!RDFC) return false;
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
if (!Bookmarks) return false;
var dirty = false;
// note: backwards delete so that we handle odd deletion cases such as
// deleting a child of a folder as well as the folder itself
for (var nodeIndex=select_list.length-1; nodeIndex>=0; nodeIndex--)
{
var node = select_list[nodeIndex];
if (!node) continue;
var ID = node.getAttribute("id");
if (!ID) continue;
// don't allow deletion of various "special" folders
if ((ID == "NC:BookmarksRoot") || (ID == "NC:IEFavoritesRoot"))
{
continue;
}
var parentID = node.parentNode.parentNode.getAttribute("ref");
if (!parentID) parentID = node.parentNode.parentNode.getAttribute("id");
if (!parentID) continue;
var IDRes = RDF.GetResource(ID);
if (!IDRes) continue;
var parentIDRes = RDF.GetResource(parentID);
if (!parentIDRes) continue;
RDFC.Init(Bookmarks, parentIDRes);
RDFC.RemoveElement(IDRes, true);
dirty = true;
}
if (dirty == true)
{
var remote = Bookmarks.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
if (remote)
remote.Flush();
}
return true;
}
function doSelectAll()
{
var treeNode = document.getElementById("bookmarksTree");
if (!treeNode) return false;
treeNode.selectAll();
return true;
}
function doUnload()
{
// Get the current window position/size.
var x = window.screenX;
var y = window.screenY;
var h = window.outerHeight;
var w = window.outerWidth;
// Store these into the window attributes (for persistence).
var win = document.getElementById("bookmark-window");
win.setAttribute("x", x);
win.setAttribute("y", y);
win.setAttribute("height", h);
win.setAttribute("width", w);
}
function BookmarkProperties()
{
var treeNode = document.getElementById('bookmarksTree');
var select_list = treeNode.selectedItems;
if (select_list.length >= 1) {
// don't bother showing properties on bookmark separators
var type = select_list[0].getAttribute('type');
if (type != NC_NS + "BookmarkSeparator") {
window.openDialog("chrome://communicator/content/bookmarks/bm-props.xul",
"_blank", "centerscreen,chrome,menubar",
select_list[0].getAttribute("id"));
}
}
return true;
}
function OpenBookmarksFind()
{
window.openDialog("chrome://communicator/content/bookmarks/bm-find.xul",
"FindBookmarksWindow",
"dialog=no,close,chrome,resizable", "bookmarks");
return true;
}
function getAbsoluteID(root, node)
{
var url = node.getAttribute("ref");
if ((url == null) || (url == ""))
{
url = node.getAttribute("id");
}
try
{
var rootNode = document.getElementById(root);
var ds = null;
if (rootNode)
{
ds = rootNode.database;
}
// add support for anonymous resources such as Internet Search results,
// IE favorites under Win32, and NetPositive URLs under BeOS
var rdf_uri = "@mozilla.org/rdf/rdf-service;1";
var rdf = Components.classes[rdf_uri].getService();
if (rdf) rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
if (rdf && ds)
{
var src = rdf.GetResource(url, true);
var prop = rdf.GetResource(NC_NS + "URL",
true);
var target = ds.GetTarget(src, prop, true);
if (target) target = target.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (target) target = target.Value;
if (target) url = target;
}
}
catch(ex)
{
}
return url;
}
function OpenURL(event, node, root)
{
if ((event.button != 0) || (event.detail != 2)
|| (node.nodeName != "treeitem"))
return false;
if (node.getAttribute("container") == "true")
return false;
var url = getAbsoluteID(root, node);
// Ignore "NC:" urls.
if (url.substring(0, 3) == "NC:")
return false;
if (event.altKey)
{
BookmarkProperties();
}
else
{
// get right sized window
window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
}
return true;
}
const nsIFilePicker = Components.interfaces.nsIFilePicker;
function doContextCmd(cmdName)
{
// Do some prompting/confirmation for various bookmark
// commands that we know about.
// If we have values to pass it, they are added to the arguments array
var nameVal = "";
var urlVal = "";
var promptStr;
var picker_uri;
var filePicker;
if (cmdName == NC_NS + "command?cmd=newbookmark")
{
while (true)
{
promptStr = get_localized_string("NewBookmarkURLPrompt");
urlVal = prompt(promptStr, "");
if (!urlVal || urlVal=="") return false;
// ensure we get a fully qualified URL (protocol colon address)
var colonOffset = urlVal.indexOf(":");
if (colonOffset > 0) break;
alert(get_localized_string("NeedValidURL"));
}
promptStr = get_localized_string("NewBookmarkNamePrompt");
nameVal = prompt(promptStr, "");
if (!nameVal || nameVal=="") return false;
}
else if (cmdName == NC_NS + "command?cmd=newfolder")
{
promptStr = get_localized_string("NewFolderNamePrompt");
nameVal = prompt(promptStr, "");
if (!nameVal || nameVal=="") return false;
}
else if ((cmdName == NC_NS + "command?cmd=deletebookmark") ||
(cmdName == NC_NS + "command?cmd=deletebookmarkfolder") ||
(cmdName == NC_NS + "command?cmd=deletebookmarkseparator"))
{
return doDelete(true);
//var promptStr = get_localized_string("DeleteItems");
//if (!confirm(promptStr)) return false;
}
else if (cmdName == NC_NS + "command?cmd=import")
{
try
{
picker_uri = "@mozilla.org/filepicker;1";
filePicker = Components.classes[picker_uri].createInstance(nsIFilePicker);
if (!filePicker) return false;
promptStr = get_localized_string("SelectImport");
filePicker.init(window, promptStr, nsIFilePicker.modeOpen);
filePicker.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterAll);
if (filePicker.show() != nsIFilePicker.returnCancel)
var filename = filePicker.fileURL.spec;
if ((!filename) || (filename == "")) return false;
urlVal = filename;
}
catch(ex)
{
return false;
}
}
else if (cmdName == NC_NS + "command?cmd=export")
{
try
{
picker_uri = "@mozilla.org/filepicker;1";
filePicker = Components.classes[picker_uri].createInstance(nsIFilePicker);
if (!filePicker) return false;
promptStr = get_localized_string("EnterExport");
filePicker.init(window, promptStr, nsIFilePicker.modeSave);
filePicker.defaultString = "bookmarks.html";
filePicker.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterAll);
if (filePicker.show() != nsIFilePicker.returnCancel &&
filePicker.fileURL.spec &&
filePicker.fileURL.spec.length > 0) {
urlVal = filePicker.fileURL.spec;
} else {
return false;
}
}
catch(ex)
{
return false;
}
}
var treeNode = document.getElementById("bookmarksTree");
if (!treeNode) return false;
var db = treeNode.database;
if (!db) return false;
var compositeDB = db.QueryInterface(Components.interfaces.nsIRDFDataSource);
if (!compositeDB) return false;
var isupports_uri = "@mozilla.org/rdf/rdf-service;1";
var isupports = Components.classes[isupports_uri].getService();
if (!isupports) return false;
var rdf = isupports.QueryInterface(Components.interfaces.nsIRDFService);
if (!rdf) return false;
// need a resource for the command
var cmdResource = rdf.GetResource(cmdName);
if (!cmdResource) return false;
cmdResource = cmdResource.QueryInterface(Components.interfaces.nsIRDFResource);
if (!cmdResource) return false;
// set up selection nsISupportsArray
var selection_uri = "@mozilla.org/supports-array;1";
var selectionInstance = Components.classes[selection_uri].createInstance();
var selectionArray = selectionInstance.QueryInterface(Components.interfaces.nsISupportsArray);
// set up arguments nsISupportsArray
var arguments_uri = "@mozilla.org/supports-array;1";
var argumentsInstance = Components.classes[arguments_uri].createInstance();
var argumentsArray = argumentsInstance.QueryInterface(Components.interfaces.nsISupportsArray);
// get various arguments (parent, name)
var parentArc = rdf.GetResource(NC_NS + "parent");
if (!parentArc) return false;
var nameArc = rdf.GetResource(NC_NS + "Name");
if (!nameArc) return false;
var urlArc = rdf.GetResource(NC_NS + "URL");
if (!urlArc) return false;
var select_list = treeNode.selectedItems;
var uri;
var rdfNode;
if (select_list.length < 1)
{
// if nothing is selected, default to using the "ref"
// on the root of the tree
uri = treeNode.getAttribute("ref");
if (!uri || uri=="") return false;
rdfNode = rdf.GetResource(uri);
// add node into selection array
if (rdfNode)
{
selectionArray.AppendElement(rdfNode);
}
// add singular arguments into arguments array
if ((nameVal) && (nameVal != ""))
{
var nameLiteral = rdf.GetLiteral(nameVal);
if (!nameLiteral) return false;
argumentsArray.AppendElement(nameArc);
argumentsArray.AppendElement(nameLiteral);
}
if ((urlVal) && (urlVal != ""))
{
var urlLiteral = rdf.GetLiteral(urlVal);
if (!urlLiteral) return false;
argumentsArray.AppendElement(urlArc);
argumentsArray.AppendElement(urlLiteral);
}
}
else for (var nodeIndex=0; nodeIndex<select_list.length; nodeIndex++)
{
var node = select_list[nodeIndex];
if (!node) break;
uri = node.getAttribute("ref");
if ((uri) || (uri == ""))
{
uri = node.getAttribute("id");
}
if (!uri) return false;
rdfNode = rdf.GetResource(uri);
if (!rdfNode) break;
// add node into selection array
selectionArray.AppendElement(rdfNode);
// get the parent's URI
var parentURI = "";
var theParent = node.parentNode.parentNode;
parentURI = theParent.getAttribute("ref");
if ((!parentURI) || (parentURI == ""))
{
parentURI = theParent.getAttribute("id");
}
if (parentURI == "") return false;
var parentNode = rdf.GetResource(parentURI, true);
if (!parentNode) return false;
// add multiple arguments into arguments array
argumentsArray.AppendElement(parentArc);
argumentsArray.AppendElement(parentNode);
if ((nameVal) && (nameVal != ""))
{
var nameLiteral2 = rdf.GetLiteral(nameVal);
if (!nameLiteral2) return false;
argumentsArray.AppendElement(nameArc);
argumentsArray.AppendElement(nameLiteral2);
}
if ((urlVal) && (urlVal != ""))
{
var urlLiteral2 = rdf.GetLiteral(urlVal);
if (!urlLiteral2) return false;
argumentsArray.AppendElement(urlArc);
argumentsArray.AppendElement(urlLiteral2);
}
}
// do the command
compositeDB.DoCommand(selectionArray, cmdResource, argumentsArray);
return true;
}
function bookmarkSelect()
{
var tree = document.getElementById("bookmarksTree");
var status = document.getElementById("statusbar-text");
var val = "";
if (tree.selectedItems.length == 1)
{
val = getAbsoluteID("bookmarksTree", tree.selectedItems[0]);
// Ignore "NC:" urls.
if (val.substring(0, 3) == "NC:")
{
val = "";
}
}
status.label = val;
return true;
}

View File

@@ -1,14 +0,0 @@
bookmarks-tree, bookmarks-tree[type="multi-column"]
{
-moz-binding : url("chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-tree-full");
}
bookmarks-tree[type="single-column"]
{
-moz-binding : url("chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-tree-name");
}
bookmarks-tree[type="folders"]
{
-moz-binding : url("chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-tree-folders");
}

View File

@@ -1,219 +0,0 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.com> (Original Author, v3.0)
*/
////////////////////////////////////////////////////////////////////////////////
// Initialize the command controllers, set focus, tree root,
// window title state, etc.
function Startup()
{
const windowNode = document.getElementById("bookmark-window");
const bookmarksView = document.getElementById("bookmarks-view");
var titleString;
// If we've been opened with a parameter, root the tree on it.
if ("arguments" in window && window.arguments[0]) {
var title;
var uri = window.arguments[0];
bookmarksView.tree.setAttribute("ref", uri);
if (uri.substring(0,5) == "find:") {
title = bookmarksView._bundle.GetStringFromName("search_results_title");
// Update the windowtype so that future searches are directed
// there and the window is not re-used for bookmarks.
windowNode.setAttribute("windowtype", "bookmarks:searchresults");
}
else {
const krNameArc = bookmarksView.rdf.GetResource(NC_NS + "Name");
const krRoot = bookmarksView.rdf.GetResource(window.arguments[0]);
var rName = bookmarksView.db.GetTarget(krRoot, krNameArc, true);
title = rName.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
}
titleString = bookmarksView._bundle.GetStringFromName("window_title");
titleString = titleString.replace(/%folder_name%/gi, title);
windowNode.setAttribute("title", titleString);
}
else {
const kProfileContractID = "@mozilla.org/profile/manager;1";
const kProfileIID = Components.interfaces.nsIProfile;
const kProfile = Components.classes[kProfileContractID].getService(kProfileIID);
var length = {value:0};
var profileList = kProfile.getProfileList(length);
// unset the default BM title if the user has more than one profile
// or if he/she has changed the name of the default one.
// the profile "default" is not localizable.
if (length.value > 1 || kProfile.currentProfile.toLowerCase() != "default") {
titleString = bookmarksView._bundle.GetStringFromName("bookmarks_root");
titleString = titleString.replace(/%user_name%/, kProfile.currentProfile);
windowNode.setAttribute("title", titleString);
}
}
bookmarksView.treeBoxObject.selection.select(0);
bookmarksView.tree.focus();
}
function Shutdown ()
{
// Store current window position and size in window attributes (for persistence).
var win = document.getElementById("bookmark-window");
win.setAttribute("x", screenX);
win.setAttribute("y", screenY);
win.setAttribute("height", outerHeight);
win.setAttribute("width", outerWidth);
var bookmarksView = document.getElementById("bookmarks-view");
bookmarksView.flushBMDatasource();
}
var gConstructedViewMenuSortItems = false;
function fillViewMenu(aEvent)
{
var adjacentElement = document.getElementById("fill-before-this-node");
var popupElement = aEvent.target;
var bookmarksView = document.getElementById("bookmarks-view");
var columns = bookmarksView.columns;
if (!gConstructedViewMenuSortItems) {
for (var i = 0; i < columns.length; ++i) {
var name = columns[i].name;
var accesskey = columns[i].accesskey;
var menuitem = document.createElement("menuitem");
var nameTemplate = bookmarksView._bundle.GetStringFromName("SortMenuItem");
name = nameTemplate.replace(/%NAME%/g, columns[i].label);
menuitem.setAttribute("label", name);
menuitem.setAttribute("accesskey", columns[i].accesskey);
menuitem.setAttribute("resource", columns[i].resource);
menuitem.setAttribute("id", "sortMenuItem:" + columns[i].resource);
menuitem.setAttribute("checked", columns[i].sortActive);
menuitem.setAttribute("name", "sortSet");
menuitem.setAttribute("type", "radio");
popupElement.insertBefore(menuitem, adjacentElement);
}
gConstructedViewMenuSortItems = true;
}
const kPrefSvcContractID = "@mozilla.org/preferences;1";
const kPrefSvcIID = Components.interfaces.nsIPrefService;
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
var bookmarksSortPrefs = prefSvc.getBranch("browser.bookmarks.sort.");
if (gConstructedViewMenuSortItems) {
var resource = bookmarksSortPrefs.getCharPref("resource");
var element = document.getElementById("sortMenuItem:" + resource);
if (element)
element.setAttribute("checked", "true");
}
var sortAscendingMenu = document.getElementById("ascending");
var sortDescendingMenu = document.getElementById("descending");
var noSortMenu = document.getElementById("natural");
sortAscendingMenu.setAttribute("checked", "false");
sortDescendingMenu.setAttribute("checked", "false");
noSortMenu.setAttribute("checked", "false");
var direction = bookmarksSortPrefs.getCharPref("direction");
if (direction == "natural")
sortAscendingMenu.setAttribute("checked", "true");
else if (direction == "ascending")
sortDescendingMenu.setAttribute("checked", "true");
else
noSortMenu.setAttribute("checked", "true");
}
function onViewMenuSortItemSelected(aEvent)
{
var resource = aEvent.target.getAttribute("resource");
const kPrefSvcContractID = "@mozilla.org/preferences;1";
const kPrefSvcIID = Components.interfaces.nsIPrefService;
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
var bookmarksSortPrefs = prefSvc.getBranch("browser.bookmarks.sort.");
switch (resource) {
case "":
break;
case "direction":
var dirn = bookmarksSortPrefs.getCharPref("direction");
if (aEvent.target.id == "ascending")
bookmarksSortPrefs.setCharPref("direction", "natural");
else if (aEvent.target.id == "descending")
bookmarksSortPrefs.setCharPref("direction", "ascending");
else
bookmarksSortPrefs.setCharPref("direction", "descending");
break;
default:
bookmarksSortPrefs.setCharPref("resource", resource);
var direction = bookmarksSortPrefs.getCharPref("direction");
if (direction == "descending")
bookmarksSortPrefs.setCharPref("direction", "natural");
break;
}
aEvent.preventCapture();
}
var gConstructedColumnsMenuItems = false;
function fillColumnsMenu(aEvent)
{
var bookmarksView = document.getElementById("bookmarks-view");
var columns = bookmarksView.columns;
var i;
if (!gConstructedColumnsMenuItems) {
for (i = 0; i < columns.length; ++i) {
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", columns[i].label);
menuitem.setAttribute("resource", columns[i].resource);
menuitem.setAttribute("id", "columnMenuItem:" + columns[i].resource);
menuitem.setAttribute("type", "checkbox");
menuitem.setAttribute("checked", columns[i].hidden != "true");
aEvent.target.appendChild(menuitem);
}
gConstructedColumnsMenuItems = true;
}
else {
for (i = 0; i < columns.length; ++i) {
var element = document.getElementById("columnMenuItem:" + columns[i].resource);
if (element && columns[i].hidden != "true")
element.setAttribute("checked", "true");
}
}
aEvent.preventBubble();
}
function onViewMenuColumnItemSelected(aEvent)
{
var resource = aEvent.target.getAttribute("resource");
if (resource != "") {
var bookmarksView = document.getElementById("bookmarks-view");
bookmarksView.toggleColumnVisibility(resource);
}
aEvent.preventBubble();
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,252 +0,0 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape 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/NPL/
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 mozilla.org code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Ben Goodger <ben@netscape.com>
Blake Ross <blakeross@telocity.com>
Dean Tessman <dean_tessman@hotmail.com>
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarksWindow.css" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/content/bookmarks/bookmarks.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/tasksOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?>
<!DOCTYPE window [
<!ENTITY % utilDTD SYSTEM "chrome://communicator/locale/utilityOverlay.dtd" >
%utilDTD;
<!ENTITY % bmDTD SYSTEM "chrome://communicator/locale/bookmarks/bookmarks.dtd">
%bmDTD;
]>
<window id="bookmark-window" windowtype="bookmarks:manager"
title="&bookmarksWindowTitle.label;"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:web="http://home.netscape.com/WEB-rdf#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="630" height="400" screenX="20" screenY="20"
persist="width height screenX screenY sizemode"
onload="Startup();" onunload="Shutdown();">
<!-- The order of loading of these script files is IMPORTANT -->
<!-- Shared Libraries -->
<script type="application/x-javascript" src="chrome://global/content/strres.js"></script>
<!-- XXX - This should SO become an XBL widget -->
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"></script>
<!-- Shared Bookmarks Utility Library -->
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
<!-- Tree-based Bookmarks UI Utility Library -->
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksTree.js"/>
<!-- Bookmarks Window -->
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarks.js"/>
<!-- Bookmarks Window Drag & Drop -->
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksDD.js"/>
<popupset id="bookmarksPopupset"/>
<commands id="commands">
<commandset id="CommandUpdate_Bookmarks"
commandupdater="true"
events="focus,tree-select"
oncommandupdate="document.getElementById('bookmarks-view').onCommandUpdate();">
</commandset>
<commandset id="tasksCommands"/>
<!-- File Menu -->
<command id="cmd_close" oncommand="close()"/>
<command id="cmd_quit"/>
<!-- Edit Menu -->
<command id="cmd_undo"/>
</commands>
<stringbundleset id="stringbundleset"/>
<keyset id="tasksKeys">
<!-- File Menu -->
<key id="key_close"/>
<key id="key_quit"/>
<!-- Edit Menu -->
<key id="key_undo"/>
<!-- These keybindings do not have a command specified in the overlay,
which is good, but we need to specify it ourselves here -->
<key id="key_cut" command="cmd_bm_cut"/>
<key id="key_copy" command="cmd_bm_copy"/>
<key id="key_paste" command="cmd_bm_paste"/>
<key id="key_selectAll" command="cmd_bm_selectAll"/>
<!-- We need to provide our own delete key binding because the key_delete
handler in platformGlobalOverlay.xul maps command to "cmd_delete" which
is NOT what we want! -->
<key id="key_bm_delete" keycode="VK_DELETE" command="cmd_bm_delete"/>
<key id="bm_key_find"
key="&edit.find.keybinding;"
command="cmd_bm_find" modifiers="accel"/>
<key id="bm_key_properties"
key="&edit.properties.keybinding;"
command="cmd_bm_properties" modifiers="accel"/>
</keyset>
<toolbox id="bookmarks-toolbox">
<menubar id="main-menubar" grippytooltiptext="&menuBar.tooltip;">
<menu id="menu_File">
<menupopup id="menu_FilePopup">
<menu id="menu_New">
<menupopup>
<menuitem label="&menuitem.newBookmark.label;"
accesskey="&command.newBookmark.accesskey;"
observes="cmd_bm_newbookmark"/>
<menuitem label="&menuitem.newFolder.label;"
accesskey="&command.newFolder.accesskey;"
observes="cmd_bm_newfolder"/>
<menuitem label="&menuitem.newSeparator.label;"
accesskey="&command.newSeparator.accesskey;"
observes="cmd_bm_newseparator"/>
</menupopup>
</menu>
<menuitem id="menu_close"/>
</menupopup>
</menu>
<menu id="menu_Edit">
<menupopup>
<menuitem id="menu_undo" disabled="true"/>
<menuseparator/>
<menuitem id="menu_bm_cut"
label="&cutCmd.label;" accesskey="&cutCmd.accesskey;"
key="key_cut" command="cmd_bm_cut"/>
<menuitem id="menu_bm_copy"
label="&copyCmd.label;" accesskey="&copyCmd.accesskey;"
key="key_copy" command="cmd_bm_copy"/>
<menuitem id="menu_bm_paste"
label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;"
key="key_paste" command="cmd_bm_paste"/>
<menuitem id="menu_bm_delete"
label="&deleteCmd.label;" accesskey="&deleteCmd.label;"
key="key_bm_delete" command="cmd_bm_delete"/>
<menuseparator/>
<menuitem id="menu_bm_selectAll"
label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;"
key="key_selectAll" command="cmd_bm_selectAll"/>
<menuseparator/>
<menuitem label="&command.fileBookmark.label;"
accesskey="&command.fileBookmark.accesskey;"
command="cmd_bm_fileBookmark"/>
<menuseparator/>
<menuitem observes="cmd_bm_properties" key="bm_key_properties"
label="&command.properties.label;"
accesskey="&command.properties.accesskey;" />
</menupopup>
</menu>
<menu id="menu_View">
<menupopup onpopupshowing="fillViewMenu(event)"
oncommand="onViewMenuSortItemSelected(event);">
<menuitem id="viewCommandToolbar" type="checkbox" class="menuitem-iconic"
label="&menuitem.view.command.toolbar.label;"
accesskey="&menuitem.view.command.toolbar.accesskey;"
oncommand="goToggleToolbar('command-toolbar', 'viewCommandToolbar'); event.preventBubble();"
persist="checked"/>
<menuseparator id="fill-after-this-node"/>
<menuitem id="natural" label="&menuitem.view.unsorted.label;"
accesskey="&menuitem.view.unsorted.accesskey;"
type="radio"
resource="direction" name="sortSet"/>
<menuseparator id="fill-before-this-node"/>
<menuitem id="ascending" label="&menuitem.view.ascending.label;"
accesskey="&menuitem.view.ascending.accesskey;"
type="radio"
resource="direction" name="sortDirectionSet"/>
<menuitem id="descending" label="&menuitem.view.descending.label;"
accesskey="&menuitem.view.descending.accesskey;"
type="radio"
resource="direction" name="sortDirectionSet"/>
<menuseparator/>
<menu id="descending" label="&menuitem.view.show_columns.label;"
accesskey="&menuitem.view.show_columns.accesskey;">
<menupopup id="columnsPopup" onpopupshowing="fillColumnsMenu(event);"
oncommand="onViewMenuColumnItemSelected(event);"/>
</menu>
<menuseparator/>
<menuitem label="&menuitem.newbookmarkfolder.label;"
command="cmd_bm_setnewbookmarkfolder"
accesskey="&menuitem.newbookmarkfolder.accesskey;"/>
<menuitem label="&menuitem.newinternetsearchfolder.label;"
command="cmd_bm_setnewsearchfolder"
accesskey="&menuitem.newinternetsearchfolder.accesskey;"/>
<menuitem label="&menuitem.personaltoolbarfolder.label;"
command="cmd_bm_setpersonaltoolbarfolder"
accesskey="&menuitem.personaltoolbarfolder.accesskey;"/>
</menupopup>
</menu>
<menu id="tasksMenu">
<menupopup id="taskPopup">
<menuitem command="cmd_bm_find" key="bm_key_find"
label="&menuitem.find.label;"
accesskey="&menuitem.find.accesskey;"/>
<menuitem label="&menuitem.import.label;"
accesskey="&menuitem.import.accesskey;"
observes="cmd_bm_import"/>
<menuitem label="&menuitem.export.label;"
accesskey="&menuitem.export.accesskey;"
observes="cmd_bm_export"/>
<menuseparator/>
</menupopup>
</menu>
<menu id="windowMenu"/>
<menu id="menu_Help"/>
</menubar>
<toolbar id="command-toolbar" tbalign="stretch" grippytooltiptext="&bookmarkToolbar.tooltip;">
<toolbarbutton id="newfolder" label="&button.newFolder.label;"
command="cmd_bm_newfolder"/>
<toolbarbutton id="newseparator" label="&button.newSeparator.label;"
command="cmd_bm_newseparator"/>
<toolbarseparator/>
<toolbarbutton id="fileBookmark" label="&command.fileBookmark.label;"
command="cmd_bm_fileBookmark"/>
<toolbarseparator/>
<toolbarbutton id="properties" label="&command.properties.label;"
command="cmd_bm_properties"/>
<toolbarbutton id="rename" label="&command.rename.label;"
command="cmd_bm_rename"/>
<toolbarbutton id="delete" label="&command.delete.label;"
command="cmd_bm_delete"/>
</toolbar>
</toolbox>
<bookmarks-tree id="bookmarks-view" flex="1"/>
</window>

View File

@@ -1,508 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
This is the old bookmarks code, included here for the sake of the bookmarks sidebar panel,
which will be fixed to use my new code in .9. In the mean time, this file provides a
life line to various functionality.
*/
var NC_NS = "http://home.netscape.com/NC-rdf#";
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
function TopLevelDrag ( event )
{
return(true);
}
function BeginDragTree ( event )
{
//XXX we rely on a capturer to already have determined which item the mouse was over
//XXX and have set an attribute.
// if the click is on the tree proper, ignore it. We only care about clicks on items.
var tree = document.getElementById("bookmarksTree");
if ( event.target == tree || event.target.localName == "treechildren" )
return(true); // continue propagating the event
var childWithDatabase = tree;
if ( ! childWithDatabase )
return(false);
var dragStarted = false;
var trans =
Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
if ( !trans ) return(false);
var genData =
Components.classes["@mozilla.org/supports-wstring;1"].createInstance(Components.interfaces.nsISupportsWString);
if (!genData) return(false);
var genDataURL =
Components.classes["@mozilla.org/supports-wstring;1"].createInstance(Components.interfaces.nsISupportsWString);
if (!genDataURL) return(false);
trans.addDataFlavor("text/unicode");
trans.addDataFlavor("moz/rdfitem");
// ref/id (url) is on the <treeitem> which is two levels above the <treecell> which is
// the target of the event.
var id = event.target.parentNode.parentNode.getAttribute("ref");
if (!id || id=="")
{
id = event.target.parentNode.parentNode.getAttribute("id");
}
var parentID = event.target.parentNode.parentNode.parentNode.parentNode.getAttribute("ref");
if (!parentID || parentID == "")
{
parentID = event.target.parentNode.parentNode.parentNode.parentNode.getAttribute("id");
}
var trueID = id;
if (parentID != null)
{
trueID += "\n" + parentID;
}
genData.data = trueID;
genDataURL.data = id;
var database = childWithDatabase.database;
var rdf =
Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
if ((!rdf) || (!database)) { dump("CAN'T GET DATABASE\n"); return(false); }
// make sure its a bookmark, bookmark separator, or bookmark folder
var src = rdf.GetResource(id, true);
var prop = rdf.GetResource(RDF_NS + "type", true);
var target = database.GetTarget(src, prop, true);
if (target) target = target.QueryInterface(Components.interfaces.nsIRDFResource);
if (target) target = target.Value;
if ((!target) || (target == "")) {dump("BAD\n"); return(false);}
if ((target != NC_NS + "BookmarkSeparator") &&
(target != NC_NS + "Bookmark") &&
(target != NC_NS + "Folder")) return(false);
trans.setTransferData ( "moz/rdfitem", genData, genData.data.length * 2); // double byte data
trans.setTransferData ( "text/unicode", genDataURL, genDataURL.data.length * 2); // double byte data
var transArray =
Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
if ( !transArray ) return(false);
// put it into the transferable as an |nsISupports|
var genTrans = trans.QueryInterface(Components.interfaces.nsISupports);
transArray.AppendElement(genTrans);
var dragService =
Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
if ( !dragService ) return(false);
var nsIDragService = Components.interfaces.nsIDragService;
dragService.invokeDragSession ( event.target, transArray, null, nsIDragService.DRAGDROP_ACTION_COPY +
nsIDragService.DRAGDROP_ACTION_MOVE );
dragStarted = true;
return(!dragStarted);
}
function DragOverTree ( event )
{
var validFlavor = false;
var dragSession = null;
var retVal = true;
var dragService =
Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
if ( !dragService ) return(false);
dragSession = dragService.getCurrentSession();
if ( !dragSession ) return(false);
if ( dragSession.isDataFlavorSupported("moz/rdfitem") ) validFlavor = true;
else if ( dragSession.isDataFlavorSupported("text/unicode") ) validFlavor = true;
//XXX other flavors here...
// touch the attribute on the rowgroup to trigger the repaint with the drop feedback.
if ( validFlavor )
{
var treeRoot = document.getElementById("bookmarksTree");
if (!treeRoot) return(false);
var treeDatabase = treeRoot.database;
if (!treeDatabase) return(false);
//XXX this is really slow and likes to refresh N times per second.
var rowGroup = event.target.parentNode.parentNode;
var sortActive = treeRoot.getAttribute("sortActive");
if (sortActive == "true")
rowGroup.setAttribute ( "dd-triggerrepaintsorted", 0 );
else
rowGroup.setAttribute ( "dd-triggerrepaint", 0 );
dragSession.canDrop = true;
// necessary??
retVal = false;
}
return(retVal);
}
function DropOnTree ( event )
{
var treeRoot = document.getElementById("bookmarksTree");
if (!treeRoot) return(false);
var treeDatabase = treeRoot.database;
if (!treeDatabase) return(false);
// for beta1, don't allow D&D if sorting is active
var sortActive = treeRoot.getAttribute("sortActive");
if (sortActive == "true")
{
dump("Sorry, drag&drop is currently disabled when sorting is active.\n");
return(false);
}
var RDF =
Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
if (!RDF) return(false);
var RDFC =
Components.classes["@mozilla.org/rdf/container;1"].getService(Components.interfaces.nsIRDFContainer);
if (!RDFC) return(false);
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
if (!Bookmarks) return(false);
// target is the <treecell>, and "ref/id" is on the <treeitem> two levels above
var treeItem = event.target.parentNode.parentNode;
if (!treeItem) return(false);
// get drop hint attributes
var dropBefore = treeItem.getAttribute("dd-droplocation");
var dropOn = treeItem.getAttribute("dd-dropon");
// calculate drop action
var dropAction;
if (dropBefore == "true") dropAction = "before";
else if (dropOn == "true") dropAction = "on";
else dropAction = "after";
// calculate parent container node
var containerItem = treeItem;
if (dropAction != "on")
{
containerItem = treeItem.parentNode.parentNode;
}
// magical fix for bug # 33546: handle dropping after open container
if (treeItem.getAttribute("container") == "true")
{
if (treeItem.getAttribute("open") == "true")
{
if (dropAction == "after")
{
dropAction = "before";
containerItem = treeItem;
// find <treechildren>, drop before first child
var treeChildren = treeItem;
treeItem = null;
for (var x = 0; x < treeChildren.childNodes.length; x++)
{
if (treeChildren.childNodes[x].tagName == "treechildren")
{
treeItem = treeChildren.childNodes[x].childNodes[0];
break;
}
}
if (!treeItem)
{
dropAction = "on";
containerItem = treeItem.parentNode.parentNode;
}
}
}
}
var targetID = getAbsoluteID("bookmarksTree", treeItem);
if (!targetID) return(false);
var targetNode = RDF.GetResource(targetID, true);
if (!targetNode) return(false);
var containerID = getAbsoluteID("bookmarksTree", containerItem);
if (!containerID) return(false);
var containerNode = RDF.GetResource(containerID);
if (!containerNode) return(false);
var dragService =
Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
if ( !dragService ) return(false);
var dragSession = dragService.getCurrentSession();
if ( !dragSession ) return(false);
var trans =
Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
if ( !trans ) return(false);
trans.addDataFlavor("moz/rdfitem");
trans.addDataFlavor("text/x-moz-url");
trans.addDataFlavor("text/unicode");
var typeRes = RDF.GetResource(RDF_NS + "type");
if (!typeRes) return false;
var bmTypeRes = RDF.GetResource(NC_NS + "Bookmark");
if (!bmTypeRes) return false;
var dirty = false;
for ( var i = 0; i < dragSession.numDropItems; ++i )
{
dragSession.getData ( trans, i );
var dataObj = new Object();
var bestFlavor = new Object();
var len = new Object();
trans.getAnyTransferData ( bestFlavor, dataObj, len );
if ( dataObj ) dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
if ( !dataObj ) continue;
var sourceID = null;
var parentID = null;
var checkNameHack = false;
var name=null;
if (bestFlavor.value == "moz/rdfitem")
{
// pull the URL out of the data object
var data = dataObj.data.substring(0, len.value / 2);
// moz/rdfitem allows parent ID specified on next line; check for it
var cr = data.indexOf("\n");
if (cr >= 0)
{
sourceID = data.substr(0, cr);
parentID = data.substr(cr+1);
}
else
{
sourceID = data;
}
}
else if (bestFlavor.value == "text/x-moz-url")
{
// pull the URL out of the data object
data = dataObj.data.substring(0, len.value / 2);
sourceID = data;
// we may need to synthesize a name (just use the URL)
checkNameHack = true;
}
else if (bestFlavor.value == "text/unicode")
{
sourceID = dataObj.data;
// we may need to synthesize a name (just use the URL)
checkNameHack = true;
}
else
{
// unknown flavor, skip
continue;
}
// pull the (optional) name out of the URL
var separator = sourceID.indexOf("\n");
if (separator >= 0)
{
name = sourceID.substr(separator+1);
sourceID = sourceID.substr(0, separator);
}
var sourceNode = RDF.GetResource(sourceID, true);
if (!sourceNode) continue;
var parentNode = null;
if (parentID != null)
{
parentNode = RDF.GetResource(parentID, true);
}
// Prevent dropping of a node before, after, or on itself
if (sourceNode == targetNode) continue;
// Prevent dropping of a node onto its parent container
if ((dropAction == "on") && (containerID) && (containerID == parentID)) continue;
RDFC.Init(Bookmarks, containerNode);
// make sure appropriate bookmark type is set
var bmTypeNode = Bookmarks.GetTarget( sourceNode, typeRes, true );
if (!bmTypeNode)
{
// set default bookmark type
Bookmarks.Assert(sourceNode, typeRes, bmTypeRes, true);
}
if ((dropAction == "before") || (dropAction == "after"))
{
// drop before or after
var nodeIndex;
nodeIndex = RDFC.IndexOf(sourceNode);
if (nodeIndex >= 1)
{
// moving a node around inside of the container
// so remove, then re-add the node
RDFC.RemoveElementAt(nodeIndex, true, sourceNode);
}
nodeIndex = RDFC.IndexOf(targetNode);
if (nodeIndex < 1) return(false);
if (dropAction == "after") ++nodeIndex;
RDFC.InsertElementAt(sourceNode, nodeIndex, true);
// select the newly added node
if (parentID)
{
selectDroppedItems(treeRoot, containerID, sourceID);
}
dirty = true;
}
else
{
// drop on
RDFC.AppendElement(sourceNode);
// select the newly added node
if (parentID)
{
selectDroppedItems(treeRoot, containerID, sourceID);
}
dirty = true;
}
if ((checkNameHack == true) || (name != null))
{
var srcArc = RDF.GetResource(sourceID, true);
var propArc = RDF.GetResource(NC_NS + "Name", true);
if (srcArc && propArc && Bookmarks)
{
var targetArc = Bookmarks.GetTarget(srcArc, propArc, true);
if (!targetArc)
{
// if no name, fallback to using the URL as the name
var defaultNameArc = RDF.GetLiteral((name != null && name != "") ? name : sourceID);
if (defaultNameArc)
{
Bookmarks.Assert(srcArc, propArc, defaultNameArc, true);
}
}
}
}
}
// should we move the node? (i.e. take it out of the source container?)
if ((parentNode != null) && (containerNode != parentNode))
{
try
{
RDFC.Init(Bookmarks, parentNode);
nodeIndex = RDFC.IndexOf(sourceNode);
if (nodeIndex >= 1)
{
RDFC.RemoveElementAt(nodeIndex, true, sourceNode);
}
}
catch(ex)
{
}
}
if (dirty == true)
{
var remote = Bookmarks.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
if (remote)
{
remote.Flush();
}
}
return(false);
}
function selectDroppedItems(treeRoot, containerID, targetID)
{
var select_list = treeRoot.getElementsByAttribute("id", targetID);
for (var x=0; x<select_list.length; x++)
{
var node = select_list[x];
if (!node) continue;
var parent = node.parentNode.parentNode;
if (!parent) continue;
var id = parent.getAttribute("ref");
if (!id || id=="")
{
id = parent.getAttribute("id");
}
if (!id || id=="") continue;
if (id == containerID)
{
treeRoot.selectItem(node);
break;
}
}
}

View File

@@ -1,397 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.com> (Original Author, v2.0)
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var NC_NS = "http://home.netscape.com/NC-rdf#";
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
var gSpringLoadTracker = {
timeout: 0,
element: null,
open: function (aRDFNode)
{
if (this.element)
this.element.setAttribute("open", "true");
clearTimeout(this.timeout);
}
};
var bookmarksDNDObserver = {
_RDF: null,
get RDF ()
{
if (!this._RDF) {
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFIID = Components.interfaces.nsIRDFService;
this._RDF = Components.classes[kRDFContractID].getService(kRDFIID);
}
return this._RDF;
},
// XXX I belong somewhere shared.
getResource: function(aString)
{
return this.RDF.GetResource(aString, true);
},
getTarget: function(aDS, aSourceID, aPropertyID)
{
var source = this.getResource(aSourceID);
var property = this.getResource(aPropertyID);
return aDS.GetTarget(source, property, true);
},
onDragStart: function (aEvent, aXferData, aDragAction)
{
var bookmarksTree = document.getElementById("bookmarksTree");
if (aEvent.target == bookmarksTree || aEvent.target.localName == "treechildren" ||
aEvent.target.localName == "splitter" || aEvent.target.localName == "menu")
throw Components.results.NS_OK; // not a draggable item.
if (aEvent.target.parentNode && aEvent.target.parentNode.parentNode &&
aEvent.target.parentNode.parentNode.localName == "treehead")
throw Components.results.NS_OK; // don't drag treehead cells.
if (bookmarksTree.getAttribute("sortActive") == "true")
throw Components.results.NS_OK;
var selItems = null;
if (bookmarksTree.selectedItems.length <= 0)
selItems = [aEvent.target.parentNode.parentNode];
else
selItems = bookmarksTree.selectedItems;
aXferData.data = new TransferDataSet();
for (var i = 0; i < selItems.length; ++i) {
var currItem = selItems[i];
var currURI = NODE_ID(currItem);
var parentItem = currItem.parentNode.parentNode;
var parentURI = NODE_ID(parentItem);
var type = this.getTarget(bookmarksTree.database, currURI, RDF_NS + "type");
type = type.QueryInterface(Components.interfaces.nsIRDFResource).Value;
if (!type || (type != (NC_NS + "BookmarkSeparator") &&
type != (NC_NS + "Bookmark") &&
type != (NC_NS + "Folder")))
throw Components.results.NS_OK;
var name = this.getTarget(bookmarksTree.database, currURI, NC_NS + "Name");
var data = new TransferData();
if (name) {
name = name.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
data.addDataForFlavour("text/x-moz-url", currURI + "\n" + name);
}
else {
data.addDataForFlavour("text/x-moz-url", currURI);
}
data.addDataForFlavour("moz/rdfitem", currURI + "\n" + parentURI);
data.addDataForFlavour("text/unicode", currURI);
aXferData.data.push(data);
}
if (aEvent.ctrlKey) {
const kDSIID = Components.interfaces.nsIDragService;
aDragAction.action = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
}
},
onDragOver: function (aEvent, aFlavour, aDragSession)
{
var bookmarksTree = document.getElementById("bookmarksTree");
var rowGroup = aEvent.target.parentNode.parentNode;
if (rowGroup)
rowGroup.setAttribute("dd-triggerrepaint" +
(bookmarksTree.getAttribute("sortActive") == "true" ? "sorted" : ""), 0);
var rdfNode = gBookmarksShell.findRDFNode(aEvent.target, true);
var rdfParent = rdfNode.parentNode.parentNode;
var isContainer = false;
if (rdfParent && rdfParent.getAttribute("container") == "true") {
var rDragOverContainer = this.RDF.GetResource(NODE_ID(rdfParent));
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
const kRDFCUtilsContractID = "@mozilla.org/rdf/container-utils;1";
const kRDFCUtilsIID = Components.interfaces.nsIRDFContainerUtils;
const kRDFCUtils = Components.classes[kRDFCUtilsContractID].getService(kRDFCUtilsIID);
isContainer = kRDFCUtils.IsContainer(kBMDS, rDragOverContainer);
}
if (!isContainer || rowGroup.id == "headRow") {
// Not a container, or dropping onto something that isn't designed to take drops
// (e.g. the tree header)
aDragSession.canDrop = false;
return;
}
// Springloaded folders.
/* XXX - not yet.
if (rdfNode && rdfNode.getAttribute("container") == "true" &&
rdfNode.getAttribute("open") != "true") {
if (!gSpringLoadTracker.element || gSpringLoadTracker.element.id != rdfNode.id) {
// XXX - this is not good enough. We need to keep track of nesting and close up
// folders after the user has dragged out of them otherwise we end up with
// everything open and a big mess!
if (gSpringLoadTracker.timeout)
clearTimeout(gSpringLoadTracker.timeout);
gSpringLoadTracker.element = rdfNode;
gSpringLoadTracker.timeout = setTimeout("gSpringLoadTracker.open()", 100);
}
}
*/
},
_flavourSet: null,
getSupportedFlavours: function ()
{
if (!this._flavourSet) {
this._flavourSet = new FlavourSet();
this._flavourSet.appendFlavour("moz/rdfitem");
this._flavourSet.appendFlavour("text/x-moz-url");
this._flavourSet.appendFlavour("text/unicode");
}
return this._flavourSet;
},
canHandleMultipleItems: true,
onDrop: function (aEvent, aXferData, aDragSession)
{
var bookmarksTree = document.getElementById("bookmarksTree");
// XXX lame
if (bookmarksTree.getAttribute("sortActive") == "true") return;
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFIID = Components.interfaces.nsIRDFContainer;
var RDFC = Components.classes[kRDFCContractID].getService(kRDFIID);
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
var dropItem = aEvent.target.parentNode.parentNode;
if (aEvent.target.localName == "treechildren")
dropItem = aEvent.target.parentNode; // handle drop on blank space.
// In the default view, the root node is the NC root, and we don't want to append
// to that. Adjust accordingly...
if (NODE_ID(dropItem) == "NC:NavCenter")
dropItem = document.getElementById("treechildren-bookmarks").firstChild;
// Don't allow drops on the header row & prevent catastrophe
if (dropItem.id == "headRow" || !dropItem) return;
// XXX we could probably compute this ourselves, but let the tree do this
// automagically for now.
var dropBefore = dropItem.getAttribute("dd-droplocation");
var dropOn = dropItem.getAttribute("dd-dropon");
var dropAction = dropBefore == "true" ? "before" : dropOn == "true" ? "on" : "after";
if (aEvent.target.localName == "treechildren")
dropAction = "on"; // handle drop on blank space.
var containerItem = dropAction == "on" ? dropItem : dropItem.parentNode.parentNode;
// XXX magical fix for bug # 33546: handle dropping after open container
if (dropItem.getAttribute("container") && dropItem.getAttribute("open") &&
dropAction == "after") {
dropAction = "before";
containerItem = dropItem;
dropItem = null;
for (var i = 0; i < containerItem.childNodes.length; ++i) {
if (containerItem.childNodes[i].localName == "treechildren") {
dropItem = containerItem.childNodes[i].firstChild;
break;
}
}
if (!dropItem) {
dropAction = "on";
dropItem = containerItem.parentNode.parentNode;
}
}
var rTarget = this.getResource(NODE_ID(dropItem));
var rContainer = this.getResource(NODE_ID(containerItem));
const kRDFCUtilsContractID = "@mozilla.org/rdf/container-utils;1";
const kRDFCUtilsIID = Components.interfaces.nsIRDFContainerUtils;
const kRDFCUtils = Components.classes[kRDFCUtilsContractID].getService(kRDFCUtilsIID);
var isContainer = kRDFCUtils.IsContainer(kBMDS, rContainer);
// XXX
var rType = this.getResource(RDF_NS + "type");
var rBookmark = this.getResource(NC_NS + "Bookmark");
var dirty = false;
var additiveFlag = false;
var numObjects = aXferData.dataList.length;
/*
if (numObjects > 1) {
var bo = bookmarksTree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
bo.beginBatch();
}
*/
var sourceID = [], parentID = [], nameRequired = [], name = [];
var flavourData;
for (i = 0; i < numObjects; ++i) {
flavourData = aXferData.dataList[i].first;
nameRequired[i] = false;
name[i] = null;
var data = flavourData.data;
switch (flavourData.flavour.contentType) {
case "moz/rdfitem":
var ix = data.indexOf("\n");
sourceID[i] = ix >= 0 ? (parentID[i] = data.substr(ix+1), data.substr(0, ix)) : data;
break;
case "text/x-moz-url":
ix = data.indexOf("\n");
sourceID[i] = ix >= 0 ? (name[i] = data.substr(ix+1), data.substr(0, ix)) : data;
break;
case "text/unicode":
sourceID[i] = data;
nameRequired[i] = true;
break;
default:
continue;
}
var rSource = this.getResource(sourceID[i]);
var rParent = parentID[i] ? this.getResource(parentID[i]) : null;
// Prevent dropping node on itself, before or after itself, on its parent
// container, or a weird situation when an open container is dropped into
// itself (which results in data loss!).
// Also prevent dropping into a folder that isn't actually a container
// (and is thus probably a pseudo-container from an aggregated datasource,
// see bug 68656 fir details).
if (rSource == rTarget || (dropAction == "on" && rContainer == rParent) ||
rContainer == rSource || !isContainer)
return;
// Prevent dropping node into one of its own subfolders
var dropItem2 = dropItem;
do {
var targetAncestor = NODE_ID(dropItem2);
dropItem2 = dropItem2.parentNode;
} while (targetAncestor != "NC:BookmarksRoot" && targetAncestor != sourceID[i]);
if (targetAncestor == sourceID[i]) {
return;
}
}
for (i = 0; i < numObjects; ++i) {
flavourData = aXferData.dataList[i].first;
rSource = this.getResource(sourceID[i]);
rParent = parentID[i] ? this.getResource(parentID[i]) : null;
// XXX if any of the following fails, the nodes are gone for good!
const kDSIID = Components.interfaces.nsIDragService;
const kCopyAction = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
if (rParent) {
if (!(aDragSession.dragAction & kCopyAction)) {
try {
RDFC.Init(kBMDS, rParent);
ix = RDFC.IndexOf(rSource);
if (ix >= 1)
RDFC.RemoveElementAt(ix, true);
}
catch (ex) { }
}
}
RDFC.Init(kBMDS, rContainer);
// If this item already exists in this container, don't paste, as
// this will result in the creation of multiple copies in the datasource
// but will not result in an update of the UI. (In Short: we don't
// handle multiple bookmarks well)
ix = RDFC.IndexOf(rSource);
if (ix != -1)
continue;
var bmType = this.getTarget(bookmarksTree.database, sourceID[i], RDF_NS + "type");
if (!bmType)
kBMDS.Assert(rSource, rType, rBookmark, true);
if (bmType == NC_NS + "Folder") {
// If we're going to copy a folder type, we need to clone the folder
// rather than just asserting the new node as a child of the drop folder.
if (aDragSession.dragAction & kCopyAction)
rSource = BookmarksUtils.cloneFolder(rSource, rContainer, rTarget);
}
if (dropAction == "before" || dropAction == "after") {
var dropIx = RDFC.IndexOf(rTarget);
RDFC.InsertElementAt(rSource, dropAction == "after" ? ++dropIx : dropIx, true);
}
else
RDFC.AppendElement(rSource); // drop on
dirty = true;
if (rParent) {
gBookmarksShell.selectFolderItem(rContainer.Value, sourceID[i], additiveFlag);
if (!additiveFlag) additiveFlag = true;
}
// If a name is supplied, we want to assert this information into the
// graph. E.g. user drags an internet shortcut to the app, we want to
// preserve not only the URL but the name of the shortcut. The other case
// where we need to assert a name is when the node does not already exist
// in the graph, in this case we'll just use the URL as the name.
if (name[i] || nameRequired[i]) {
var currentName = this.getTarget(bookmarksTree.database, sourceID[i], NC_NS + "Name");
if (!currentName) {
var rDefaultName = this.RDF.GetLiteral(name[i] || sourceID[i]);
if (rDefaultName) {
var rName = this.RDF.GetResource(NC_NS + "Name");
kBMDS.Assert(rSource, rName, rDefaultName, true);
}
}
}
}
/*
if (numObjects > 1) {
var bo = bookmarksTree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
bo.endBatch();
}
*/
if (dirty) {
var remoteDS = kBMDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
remoteDS.Flush();
}
}
}

View File

@@ -1,954 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var NC_NS = "http://home.netscape.com/NC-rdf#";
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
const NC_NS_CMD = NC_NS + "command?cmd=";
/**
* XXX - 04/16/01
* ACK! massive command name collision problems are causing big issues
* in getting this stuff to work in the Navigator window. For sanity's
* sake, we need to rename all the commands to be of the form cmd_bm_*
* otherwise there'll continue to be problems. For now, we're just
* renaming those that affect the personal toolbar (edit operations,
* which were clashing with the textfield controller)
*
* There are also several places that need to be updated if you need
* to change a command name.
* 1) the controller in ALL clients (bookmarksTree.js, personalToolbar.js)
* 2) the command nodes in the overlay
* 3) the command human-readable name key in bookmark.properties
* 4) the function 'getAllCmds' in bookmarksOverlay.js
* 5) the function 'execCommand' in bookmarksOverlay.js
* Yes, this blows crusty dead goats through straws, and I should probably
* create some constants somewhere to bring this number down to 3.
* However, if you fail to do one of these, you WILL break something
* and I WILL come after you with a knife.
*/
function LITERAL (aDB, aElement, aPropertyID)
{
var RDF = BookmarksUIElement.prototype.RDF;
var rSource = RDF.GetResource(aElement.id);
var rProperty = RDF.GetResource(aPropertyID);
var node = aDB.GetTarget(rSource, rProperty, true);
return node ? node.QueryInterface(Components.interfaces.nsIRDFLiteral).Value : "";
}
function BookmarksUIElement () { }
BookmarksUIElement.prototype = {
_rdf: null,
get RDF ()
{
if (!this._rdf) {
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFIID = Components.interfaces.nsIRDFService;
this._rdf = Components.classes[kRDFContractID].getService(kRDFIID);
}
return this._rdf;
},
propertySet: function (sourceID, propertyID, newValue)
{
if (!newValue) return;
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFIID = Components.interfaces.nsIRDFService;
const kRDF = Components.classes[kRDFContractID].getService(kRDFIID);
// need to shuffle this into an API.
const kBMDS = kRDF.GetDataSource("rdf:bookmarks");
const krProperty = kRDF.GetResource(propertyID);
const krItem = kRDF.GetResource(sourceID);
var rCurrValue = kBMDS.GetTarget(krItem, krProperty, true);
const krNewValue = kRDF.GetLiteral(newValue);
if (!rCurrValue)
kBMDS.Assert(krItem, krProperty, krNewValue, true);
else {
rCurrValue = rCurrValue.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (rCurrValue.Value != newValue)
kBMDS.Change(krItem, krProperty, rCurrValue, krNewValue);
}
},
/////////////////////////////////////////////////////////////////////////////
// Fill a context menu popup with menuitems that are appropriate for the current
// selection.
createContextMenu: function (aEvent)
{
var popup = aEvent.target;
// clear out the old context menu contents (if any)
while (popup.hasChildNodes())
popup.removeChild(popup.firstChild);
var popupNode = document.popupNode;
if (!("findRDFNode" in this))
throw "Clients must implement findRDFNode!";
var itemNode = this.findRDFNode(popupNode, true);
if (!itemNode || !itemNode.getAttributeNS(RDF_NS, "type") || itemNode.getAttribute("mode") == "edit") {
aEvent.preventDefault();
return;
}
if (!("getContextSelection" in this))
throw "Clients must implement getContextSelection!";
var selection = this.getContextSelection (itemNode);
var commonCommands = [];
for (var i = 0; i < selection.length; ++i) {
var commands = this.getAllCmds(selection[i].id);
if (!commands) {
aEvent.preventDefault();
return;
}
commands = this.flattenEnumerator(commands);
if (!commonCommands.length) commonCommands = commands;
commonCommands = this.findCommonNodes(commands, commonCommands);
}
if (!commonCommands.length) {
aEvent.preventDefault();
return;
}
// Now that we should have generated a list of commands that is valid
// for the entire selection, build a context menu.
for (i = 0; i < commonCommands.length; ++i) {
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var currCommand = commonCommands[i].QueryInterface(Components.interfaces.nsIRDFResource).Value;
var element = null;
if (currCommand != NC_NS_CMD + "bm_separator") {
var commandName = this.getCommandName(currCommand);
element = this.createMenuItem(commandName, currCommand, itemNode);
}
else if (i != 0 && i < commonCommands.length-1) {
// Never append a separator as the first or last element in a context
// menu.
element = document.createElementNS(kXULNS, "menuseparator");
}
if (element)
popup.appendChild(element);
}
return;
},
/////////////////////////////////////////////////////////////////////////////
// Given two unique arrays, return an array that contains only the elements
// common to both.
findCommonNodes: function (aNewArray, aOldArray)
{
var common = [];
for (var i = 0; i < aNewArray.length; ++i) {
for (var j = 0; j < aOldArray.length; ++j) {
if (common.length > 0 && common[common.length-1] == aNewArray[i])
continue;
if (aNewArray[i] == aOldArray[j])
common.push(aNewArray[i]);
}
}
return common;
},
flattenEnumerator: function (aEnumerator)
{
if ("_index" in aEnumerator)
return aEnumerator._inner;
var temp = [];
while (aEnumerator.hasMoreElements())
temp.push(aEnumerator.getNext());
return temp;
},
/////////////////////////////////////////////////////////////////////////////
// For a given URI (a unique identifier of a resource in the graph) return
// an enumeration of applicable commands for that URI.
getAllCmds: function (aNodeID)
{
var type = this.resolveType(aNodeID);
if (!type) {
if (aNodeID == "NC:PersonalToolbarFolder" || aNodeID == "NC:BookmarksRoot")
type = "http://home.netscape.com/NC-rdf#Folder";
else
return null;
}
var commands = [];
// menu order:
//
// bm_open
// bm_openfolder
// bm_openinnewwindow
// /* bm_openinnewtab not yet supported */
// ---------------------
// /* bm_find removed */
// bm_newfolder
// ---------------------
// bm_cut
// bm_copy
// bm_paste
// bm_fileBookmark
// ---------------------
// bm_delete
// bm_rename
// ---------------------
// bm_properties
switch (type) {
case "http://home.netscape.com/NC-rdf#BookmarkSeparator":
commands = ["bm_newfolder", "bm_separator",
"bm_cut", "bm_copy", "bm_paste", "bm_separator",
"bm_delete"];
break;
case "http://home.netscape.com/NC-rdf#Bookmark":
commands = ["bm_open", "bm_openinnewwindow", /* "bm_openinnewtab", */ "bm_separator",
"bm_newfolder", "bm_separator",
"bm_cut", "bm_copy", "bm_paste", "bm_fileBookmark", "bm_separator",
"bm_delete", "bm_rename", "bm_separator",
"bm_properties"];
break;
case "http://home.netscape.com/NC-rdf#Folder":
commands = ["bm_openfolder", "bm_openinnewwindow", "bm_separator",
"bm_newfolder", "bm_separator",
"bm_cut", "bm_copy", "bm_paste", "bm_fileBookmark", "bm_separator",
"bm_delete", "bm_rename", "bm_separator",
"bm_properties"];
break;
case "http://home.netscape.com/NC-rdf#IEFavoriteFolder":
commands = ["bm_openfolder", "bm_separator",
"bm_delete"];
break;
case "http://home.netscape.com/NC-rdf#IEFavorite":
commands = ["bm_open", "bm_openinnewwindow", /* "bm_openinnewtab", */ "bm_separator",
"bm_copy"];
break;
case "http://home.netscape.com/NC-rdf#FileSystemObject":
commands = ["bm_open", "bm_openinnewwindow", /* "bm_openinnewtab", */ "bm_separator",
"bm_copy"];
break;
default:
var source = this.RDF.GetResource(aNodeID);
return this.db.GetAllCmds(source);
}
return new CommandArrayEnumerator(commands);
},
/////////////////////////////////////////////////////////////////////////////
// Retrieve the human-readable name for a particular command. Used when
// manufacturing a UI to invoke commands.
getCommandName: function (aCommand)
{
var cmdName = aCommand.substring(NC_NS_CMD.length);
try {
// Note: this will succeed only if there's a string in the bookmarks
// string bundle for this command name. Otherwise, <xul:stringbundle/>
// will throw, we'll catch & stifle the error, and look up the command
// name in the datasource.
return this.getLocaleString ("cmd_" + cmdName);
}
catch (e) {
}
// XXX - WORK TO DO HERE! (rjc will cry if we don't fix this)
// need to ask the ds for the commands for this node, however we don't
// have the right params. This is kind of a problem.
dump("*** BAD! EVIL! WICKED! NO! ACK! ARGH! ORGH!\n");
const rName = this.RDF.GetResource(NC_NS + "Name");
const rSource = this.RDF.GetResource(aNodeID);
return this.db.GetTarget(rSource, rName, true).Value;
},
/////////////////////////////////////////////////////////////////////////////
// Perform a command based on a UI event. XXX - work to do here.
preExecCommand: function (aEvent)
{
var commandID = aEvent.target.getAttribute("cmd");
if (!commandID) return;
goDoCommand("cmd_" + commandID.substring(NC_NS_CMD.length));
},
execCommand: function (aCommandID)
{
var args = [];
var selection = this.getSelection ();
if (selection.length >= 1)
var selectedItem = selection[0];
switch (aCommandID) {
case "bm_open":
this.open(null, selectedItem, false);
break;
case "bm_openfolder":
this.commands.openFolder(selectedItem);
break;
case "bm_openinnewwindow":
if (this.resolveType(selectedItem.id) == NC_NS + "Folder")
this.openFolderInNewWindow(selectedItem);
else
this.open(null, selectedItem, true);
break;
case "bm_rename":
// XXX - this is SO going to break if we ever do column re-ordering.
this.commands.editCell(selectedItem, 0);
break;
case "bm_editurl":
this.commands.editCell(selectedItem, 1);
break;
case "bm_setnewbookmarkfolder":
case "bm_setpersonaltoolbarfolder":
case "bm_setnewsearchfolder":
BookmarksUtils.doBookmarksCommand(selectedItem.id, NC_NS_CMD + aCommandID, args);
// XXX - The containing node seems to be closed here and the
// focus/selection is destroyed.
this.selectElement(selectedItem);
break;
case "bm_properties":
this.showPropertiesForNode(selectedItem);
break;
case "bm_find":
this.findInBookmarks();
break;
case "bm_cut":
this.copySelection(selection);
this.deleteSelection(selection);
break;
case "bm_copy":
this.copySelection(selection);
break;
case "bm_paste":
this.paste(selection);
break;
case "bm_delete":
this.deleteSelection(selection);
break;
case "bm_fileBookmark":
var rv = { selectedFolder: null };
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
"centerscreen,chrome,modal=yes,dialog=yes,resizable=yes", null, null, folder, null, "selectFolder", rv);
if (rv.selectedFolder) {
for (var k = 0; k < selection.length; ++k) {
if (selection[k].id == rv.selectedFolder)
return; // Selection contains the target folder. Just fail silently.
}
var additiveFlag = false;
var selectedItems = [].concat(this.getSelection())
for (var i = 0; i < selectedItems.length; ++i) {
var currItem = selectedItems[i];
var currURI = currItem.id;
var parent = gBookmarksShell.findRDFNode(currItem, false);
gBookmarksShell.moveBookmark(currURI, parent.id, rv.selectedFolder);
gBookmarksShell.selectFolderItem(rv.selectedFolder, currURI, additiveFlag);
if (!additiveFlag) additiveFlag = true;
}
gBookmarksShell.flushDataSource();
}
break;
case "bm_newfolder":
var nfseln = this.getBestItem();
this.commands.createBookmarkItem("folder", nfseln);
break;
case "bm_newbookmark":
var folder = this.getSelectedFolder();
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
"centerscreen,chrome,modal=yes,dialog=yes,resizable=no", null, null, folder, null, "newBookmark");
break;
case "bm_newseparator":
nfseln = this.getBestItem();
var parentNode = this.findRDFNode(nfseln, false);
args = [{ property: NC_NS + "parent",
resource: parentNode.id }];
BookmarksUtils.doBookmarksCommand(nfseln.id, NC_NS_CMD + "newseparator", args);
break;
case "bm_import":
case "bm_export":
const isImport = aCommandID == "bm_import";
try {
const kFilePickerContractID = "@mozilla.org/filepicker;1";
const kFilePickerIID = Components.interfaces.nsIFilePicker;
const kFilePicker = Components.classes[kFilePickerContractID].createInstance(kFilePickerIID);
const kTitle = this.getLocaleString(isImport ? "SelectImport": "EnterExport");
kFilePicker.init(window, kTitle, kFilePickerIID[isImport ? "modeOpen" : "modeSave"]);
kFilePicker.appendFilters(kFilePickerIID.filterHTML | kFilePickerIID.filterAll);
if (!isImport) kFilePicker.defaultString = "bookmarks.html";
if (kFilePicker.show() != kFilePickerIID.returnCancel) {
var fileName = kFilePicker.fileURL.spec;
if (!fileName) break;
}
else break;
}
catch (e) {
break;
}
var seln = this.getBestItem();
args = [{ property: NC_NS + "URL", literal: fileName}];
BookmarksUtils.doBookmarksCommand(seln.id, NC_NS_CMD + aCommandID, args);
break;
}
},
openFolderInNewWindow: function (aSelectedItem)
{
openDialog("chrome://communicator/content/bookmarks/bookmarks.xul",
"", "chrome,all,dialog=no", aSelectedItem.id);
},
copySelection: function (aSelection)
{
const kSuppArrayContractID = "@mozilla.org/supports-array;1";
const kSuppArrayIID = Components.interfaces.nsISupportsArray;
var itemArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
const kSuppWStringContractID = "@mozilla.org/supports-wstring;1";
const kSuppWStringIID = Components.interfaces.nsISupportsWString;
var bmstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
var unicodestring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
var htmlstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
var sBookmarkItem = ""; var sTextUnicode = ""; var sTextHTML = "";
for (var i = 0; i < aSelection.length; ++i) {
var url = LITERAL(this.db, aSelection[i], NC_NS + "URL");
var name = LITERAL(this.db, aSelection[i], NC_NS + "Name");
sBookmarkItem += aSelection[i].id + "\n";
sTextUnicode += url + "\n";
sTextHTML += "<A HREF=\"" + url + "\">" + name + "</A>";
}
const kXferableContractID = "@mozilla.org/widget/transferable;1";
const kXferableIID = Components.interfaces.nsITransferable;
var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID);
xferable.addDataFlavor("moz/bookmarkclipboarditem");
bmstring.data = sBookmarkItem;
xferable.setTransferData("moz/bookmarkclipboarditem", bmstring, sBookmarkItem.length*2)
xferable.addDataFlavor("text/html");
htmlstring.data = sTextHTML;
xferable.setTransferData("text/html", htmlstring, sTextHTML.length*2)
xferable.addDataFlavor("text/unicode");
unicodestring.data = sTextUnicode;
xferable.setTransferData("text/unicode", unicodestring, sTextUnicode.length*2)
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
const kClipboardIID = Components.interfaces.nsIClipboard;
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
clipboard.setData(xferable, null, kClipboardIID.kGlobalClipboard);
},
paste: function (aSelection)
{
const kXferableContractID = "@mozilla.org/widget/transferable;1";
const kXferableIID = Components.interfaces.nsITransferable;
var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID);
xferable.addDataFlavor("moz/bookmarkclipboarditem");
xferable.addDataFlavor("text/x-moz-url");
xferable.addDataFlavor("text/unicode");
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
const kClipboardIID = Components.interfaces.nsIClipboard;
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
clipboard.getData(xferable, kClipboardIID.kGlobalClipboard);
var flavour = { };
var data = { };
var length = { };
xferable.getAnyTransferData(flavour, data, length);
var nodes = []; var names = [];
data = data.value.QueryInterface(Components.interfaces.nsISupportsWString).data;
switch (flavour.value) {
case "moz/bookmarkclipboarditem":
nodes = data.split("\n");
break;
case "text/x-moz-url":
var ix = data.indexOf("\n");
nodes.push(data.substring(0, ix != -1 ? ix : data.length));
names.push(data.substring(ix));
break;
default:
return;
}
const lastSelected = aSelection[aSelection.length-1];
const kParentNode = this.resolvePasteFolder(aSelection);
const krParent = this.RDF.GetResource(kParentNode.id);
const krSource = this.RDF.GetResource(lastSelected.id);
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFCIID = Components.interfaces.nsIRDFContainer;
const ksRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
var additiveFlag = false;
for (var i = 0; i < nodes.length; ++i) {
if (!nodes[i]) continue;
var rCurrent = this.RDF.GetResource(nodes[i]);
const krTypeProperty = this.RDF.GetResource(RDF_NS + "type");
var rType = this.db.GetTarget(rCurrent, krTypeProperty, true);
try {
rType = rType.QueryInterface(Components.interfaces.nsIRDFResource);
}
catch (e) {
try {
rType = rType.QueryInterface(Components.interfaces.nsIRDFLiteral);
}
catch (e) {
// OK, no type exists, so node does not exist in the graph.
// (e.g. user pastes url as text)
// Do some housekeeping.
const krName = this.RDF.GetResource(names[i]);
const krNameProperty = this.RDF.GetResource(NC_NS + "Name");
const krBookmark = this.RDF.GetResource(NC_NS + "Bookmark");
kBMDS.Assert(rCurrent, krNameProperty, krName, true);
kBMDS.Assert(rCurrent, krTypeProperty, krBookmark, true);
}
}
// If the node is a folder, then we need to create a new anonymous
// resource and copy all the arcs over.
if (rType && rType.Value == NC_NS + "Folder")
rCurrent = BookmarksUtils.cloneFolder(rCurrent, krParent, krSource);
// If this item already exists in this container, don't paste, as
// this will result in the creation of multiple copies in the datasource
// but will not result in an update of the UI. (In Short: we don't
// handle multiple bookmarks well)
ksRDFC.Init(kBMDS, krParent);
ix = ksRDFC.IndexOf(rCurrent);
if (ix != -1)
continue;
ix = ksRDFC.IndexOf(krSource);
if (ix != -1)
ksRDFC.InsertElementAt(rCurrent, ix+1, true);
else
ksRDFC.AppendElement(rCurrent);
this.selectFolderItem(krSource.Value, rCurrent.Value, additiveFlag);
if (!additiveFlag) additiveFlag = true;
var rds = kBMDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
rds.Flush();
}
},
/////////////////////////////////////////////////////////////////////////////
// For the given selection, determines the element that should form the
// container to paste items into.
resolvePasteFolder: function (aSelection)
{
const lastSelected = aSelection[aSelection.length-1];
if (lastSelected.getAttribute("container") == "true" &&
aSelection.length == 1)
return lastSelected;
return this.findRDFNode(lastSelected, false);
},
canPaste: function ()
{
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
const kClipboardIID = Components.interfaces.nsIClipboard;
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
const kSuppArrayContractID = "@mozilla.org/supports-array;1";
const kSuppArrayIID = Components.interfaces.nsISupportsArray;
var flavourArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
const kSuppStringContractID = "@mozilla.org/supports-string;1";
const kSuppStringIID = Components.interfaces.nsISupportsString;
var flavours = ["moz/bookmarkclipboarditem", "text/x-moz-url"];
for (var i = 0; i < flavours.length; ++i) {
const kSuppString = Components.classes[kSuppStringContractID].createInstance(kSuppStringIID);
kSuppString.data = flavours[i];
flavourArray.AppendElement(kSuppString);
}
var hasFlavours = clipboard.hasDataMatchingFlavors(flavourArray, kClipboardIID.kGlobalClipboard);
return hasFlavours;
},
/////////////////////////////////////////////////////////////////////////////
// aSelection is a mutable array, not a NodeList.
deleteSelection: function (aSelection)
{
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFCIID = Components.interfaces.nsIRDFContainer;
const ksRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
var nextElement;
var count = 0;
var selectionLength = aSelection.length;
while (aSelection.length && aSelection[count]) {
const currParent = this.findRDFNode(aSelection[count], false);
const kSelectionURI = aSelection[count].id;
// Disallow the removal of certain 'special' nodes
if (kSelectionURI == "NC:BookmarksRoot") {
aSelection.splice(count++,1);
continue;
}
// If the current bookmark is the IE Favorites folder, we have a little
// extra work to do - set the pref |browser.bookmarks.import_system_favorites|
// to ensure that we don't re-import next time.
if (aSelection[count].getAttribute("type") == (NC_NS + "IEFavoriteFolder")) {
const kPrefSvcContractID = "@mozilla.org/preferences-service;1";
const kPrefSvcIID = Components.interfaces.nsIPrefBranch;
const kPrefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
kPrefSvc.setBoolPref("browser.bookmarks.import_system_favorites", false);
}
const krParent = this.RDF.GetResource(currParent.id);
const krBookmark = this.RDF.GetResource(kSelectionURI);
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
ksRDFC.Init(kBMDS, krParent);
nextElement = this.getNextElement(aSelection[count]);
ksRDFC.RemoveElement(krBookmark, true);
try {
// XXX - UGH. Template builder is NOT removing the element from the
// tree, and so selection remains non-zero in length and we go into
// an infinite loop here. Tear the node out of the document.
var parent = aSelection[count].parentNode;
parent.removeChild(aSelection[count]);
}
catch (e) {
}
// Manipulate the selection array ourselves.
aSelection.splice(count,1);
}
this.selectElement(nextElement);
},
moveBookmark: function (aBookmarkURI, aFromFolderURI, aToFolderURI)
{
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFCIID = Components.interfaces.nsIRDFContainer;
const kRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
const krSrc = this.RDF.GetResource(aBookmarkURI);
const krOldParent = this.RDF.GetResource(aFromFolderURI);
const krNewParent = this.RDF.GetResource(aToFolderURI);
kRDFC.Init(kBMDS, krNewParent);
kRDFC.AppendElement(krSrc);
kRDFC.Init(kBMDS, krOldParent);
kRDFC.RemoveElement(krSrc, true);
},
open: function (aEvent, aRDFNode, aInNewWindow)
{
var urlValue = LITERAL(this.db, aRDFNode, NC_NS + "URL");
// Ignore "NC:" and empty urls.
if (urlValue.substring(0,3) == "NC:" || !urlValue) return;
if (aEvent && aEvent.altKey)
this.showPropertiesForNode (aRDFNode);
else if (aInNewWindow)
openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", urlValue);
else
openTopWin (urlValue);
if (aEvent)
aEvent.preventBubble();
},
showPropertiesForNode: function (aBookmarkItem)
{
if (aBookmarkItem.getAttribute("type") != NC_NS + "BookmarkSeparator")
openDialog("chrome://communicator/content/bookmarks/bm-props.xul",
"", "centerscreen,chrome,resizable=no", aBookmarkItem.id);
},
findInBookmarks: function ()
{
openDialog("chrome://communicator/content/bookmarks/findBookmark.xul",
"FindBookmarksWindow",
"centerscreen,resizable=no,chrome,dependent");
},
getLocaleString: function (aStringKey)
{
var bundle = document.getElementById("bookmarksbundle");
return bundle.getString (aStringKey);
},
flushDataSource: function ()
{
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
var remoteDS = kBMDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
remoteDS.Flush();
},
/////////////////////////////////////////////////////////////////////////////
// Determine the rdf:type property for the given resource.
resolveType: function (aID)
{
const krType = this.RDF.GetResource(RDF_NS + "type");
const krElement = this.RDF.GetResource(aID);
const type = gBookmarksShell.db.GetTarget(krElement, krType, true);
try {
return type.QueryInterface(Components.interfaces.nsIRDFResource).Value;
}
catch (e) {
try {
return type.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
}
catch (e) {
return null;
}
}
},
/////////////////////////////////////////////////////////////////////////////
// takes a node and adds the appropriate adornments for a bookmark container.
createBookmarkFolderDecorations: function (aNode)
{
aNode.setAttribute("type", "http://home.netscape.com/NC-rdf#Folder");
aNode.setAttribute("container", "true");
return aNode;
}
};
function CommandArrayEnumerator (aCommandArray)
{
this._inner = [];
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFIID = Components.interfaces.nsIRDFService;
const RDF = Components.classes[kRDFContractID].getService(kRDFIID);
for (var i = 0; i < aCommandArray.length; ++i)
this._inner.push(RDF.GetResource(NC_NS_CMD + aCommandArray[i]));
this._index = 0;
}
CommandArrayEnumerator.prototype = {
getNext: function ()
{
return this._inner[this._index];
},
hasMoreElements: function ()
{
return this._index < this._inner.length;
}
};
var BookmarksUtils = {
_rdf: null,
get RDF ()
{
if (!this._rdf) {
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFIID = Components.interfaces.nsIRDFService;
this._rdf = Components.classes[kRDFContractID].getService(kRDFIID);
}
return this._rdf;
},
///////////////////////////////////////////////////////////////////////////
// Execute a command with the given source and arguments
doBookmarksCommand: function (aSourceURI, aCommand, aArgumentsArray)
{
var rCommand = this.RDF.GetResource(aCommand);
var kSuppArrayContractID = "@mozilla.org/supports-array;1";
var kSuppArrayIID = Components.interfaces.nsISupportsArray;
var sourcesArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
if (aSourceURI) {
var rSource = this.RDF.GetResource(aSourceURI);
sourcesArray.AppendElement (rSource);
}
var argsArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
for (var i = 0; i < aArgumentsArray.length; ++i) {
var rArc = this.RDF.GetResource(aArgumentsArray[i].property);
argsArray.AppendElement(rArc);
var rValue = null;
if ("resource" in aArgumentsArray[i]) {
rValue = this.RDF.GetResource(aArgumentsArray[i].resource);
}
else
rValue = this.RDF.GetLiteral(aArgumentsArray[i].literal);
argsArray.AppendElement(rValue);
}
// Exec the command in the Bookmarks datasource.
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
kBMDS.DoCommand(sourcesArray, rCommand, argsArray);
},
cloneFolder: function (aFolder, aParent, aRelativeItem)
{
var BMDS = this.RDF.GetDataSource("rdf:bookmarks");
var nameArc = this.RDF.GetResource(NC_NS + "Name");
var rName = BMDS.GetTarget(aFolder, nameArc, true);
rName = rName.QueryInterface(Components.interfaces.nsIRDFLiteral);
var newFolder = this.createFolderWithID(rName.Value, aRelativeItem, aParent);
// Now need to append kiddies.
try {
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFCIID = Components.interfaces.nsIRDFContainer;
var RDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
const kRDFCUContractID = "@mozilla.org/rdf/container-utils;1";
const kRDFCUIID = Components.interfaces.nsIRDFContainerUtils;
var RDFCU = Components.classes[kRDFCUContractID].getService(kRDFCUIID);
RDFC.Init(BMDS, aFolder);
var elts = RDFC.GetElements();
RDFC.Init(BMDS, newFolder);
while (elts.hasMoreElements()) {
var curr = elts.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
if (RDFCU.IsContainer(BMDS, curr))
BookmarksUtils.cloneFolder(curr, newFolder);
else
RDFC.AppendElement(curr);
}
}
catch (e) {
}
return newFolder;
},
createFolderWithID: function (aTitle, aRelativeItem, aParentFolder)
{
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFCIID = Components.interfaces.nsIRDFContainer;
var RDFC = Components.classes[kRDFCContractID].createInstance(kRDFCIID);
var BMDS = this.RDF.GetDataSource("rdf:bookmarks");
try {
RDFC.Init(BMDS, aParentFolder);
}
catch (e) {
return null;
}
var ix = RDFC.IndexOf(aRelativeItem);
var BMSvc = BMDS.QueryInterface(Components.interfaces.nsIBookmarksService);
return BMSvc.createFolderWithDetails(aTitle, aParentFolder, ix);
},
addBookmarkForTabBrowser: function( aTabBrowser, aSelect )
{
var tabsInfo = [];
var currentTabInfo = { name: "", url: "", charset: null };
const activeBrowser = aTabBrowser.selectedBrowser;
const browsers = aTabBrowser.browsers;
for (var i = 0; i < browsers.length; ++i) {
var webNav = browsers[i].webNavigation;
var url = webNav.currentURI.spec;
var name = "";
var charset;
try {
var doc = webNav.document;
name = doc.title || url;
charset = doc.characterSet;
} catch (e) {
name = url;
}
tabsInfo[i] = { name: name, url: url, charset: charset };
if (browsers[i] == activeBrowser)
currentTabInfo = tabsInfo[i];
}
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
"centerscreen,chrome,dialog=yes,resizable,dependent",
currentTabInfo.name, currentTabInfo.url, null,
currentTabInfo.charset, "addGroup" + (aSelect ? ",group" : ""), tabsInfo);
},
addBookmarkForBrowser: function (aDocShell, aShowDialog)
{
// Bug 52536: We obtain the URL and title from the nsIWebNavigation
// associated with a <browser/> rather than from a DOMWindow.
// This is because when a full page plugin is loaded, there is
// no DOMWindow (?) but information about the loaded document
// may still be obtained from the webNavigation.
var url = aDocShell.currentURI.spec;
var title, docCharset = null;
try {
title = aDocShell.document.title || url;
docCharset = aDocShell.document.characterSet;
}
catch (e) {
title = url;
}
this.addBookmark(url, title, docCharset, aShowDialog);
},
addBookmark: function (aURL, aTitle, aCharset, aShowDialog)
{
if (aCharset === undefined) {
var fw = document.commandDispatcher.focusedWindow;
aCharset = fw.document.characterSet;
}
if (aShowDialog)
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
"centerscreen,chrome,dialog=yes,resizable,dependent", aTitle, aURL, null, aCharset);
else {
// User has elected to override the file dialog and always file bookmarks
// into the default bookmark folder.
const kBMSvcContractID = "@mozilla.org/browser/bookmarks-service;1";
const kBMSvcIID = Components.interfaces.nsIBookmarksService;
const kBMSvc = Components.classes[kBMSvcContractID].getService(kBMSvcIID);
kBMSvc.addBookmarkImmediately(aURL, aTitle, kBMSvcIID.BOOKMARK_DEFAULT_TYPE, aCharset);
}
}
};
var ContentUtils = {
childByLocalName: function (aSelectedItem, aLocalName)
{
var temp = aSelectedItem.firstChild;
while (temp) {
if (temp.localName == aLocalName)
return temp;
temp = temp.nextSibling;
}
return null;
}
};

View File

@@ -1,70 +0,0 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape 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/NPL/
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 mozilla.org code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Ben Goodger <ben@netscape.com> (Original Author)
-->
<!DOCTYPE window SYSTEM "chrome://communicator/locale/bookmarks/bookmarksOverlay.dtd">
<overlay id="bookmarksOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<stringbundleset id="stringbundleset">
<stringbundle id="bookmarksbundle"
src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
</stringbundleset>
<popupset id="bookmarksPopupset">
<popup id="bmContext"
onpopupshowing="gBookmarksShell.createContextMenu(event);"/>
</popupset>
<commands id="commands">
<commandset id="bookmarksItems">
<command id="cmd_bm_open" oncommand="goDoCommand('cmd_bm_open');"/>
<command id="cmd_bm_openfolder" oncommand="goDoCommand('cmd_bm_openfolder');"/>
<command id="cmd_bm_newfolder" oncommand="goDoCommand('cmd_bm_newfolder');"/>
<command id="cmd_bm_newbookmark" oncommand="goDoCommand('cmd_bm_newbookmark');"/>
<command id="cmd_bm_newseparator" oncommand="goDoCommand('cmd_bm_newseparator');"/>
<command id="cmd_bm_find" oncommand="goDoCommand('cmd_bm_find');"/>
<command id="cmd_bm_setnewbookmarkfolder" oncommand="goDoCommand('cmd_bm_setnewbookmarkfolder');"/>
<command id="cmd_bm_setpersonaltoolbarfolder" oncommand="goDoCommand('cmd_bm_setpersonaltoolbarfolder');"/>
<command id="cmd_bm_setnewsearchfolder" oncommand="goDoCommand('cmd_bm_setnewsearchfolder');"/>
<command id="cmd_bm_properties" oncommand="goDoCommand('cmd_bm_properties');"/>
<command id="cmd_bm_rename" oncommand="goDoCommand('cmd_bm_rename');"/>
<command id="cmd_bm_openinnewwindow" oncommand="goDoCommand('cmd_bm_openinnewwindow');"/>
<command id="cmd_bm_import" oncommand="goDoCommand('cmd_bm_import');"/>
<command id="cmd_bm_export" oncommand="goDoCommand('cmd_bm_export');"/>
<command id="cmd_bm_fileBookmark" oncommand="goDoCommand('cmd_bm_fileBookmark');"/>
<command id="cmd_bm_cut" oncommand="goDoCommand('cmd_bm_cut');"/>
<command id="cmd_bm_copy" oncommand="goDoCommand('cmd_bm_copy');"/>
<command id="cmd_bm_paste" oncommand="goDoCommand('cmd_bm_paste');"/>
<command id="cmd_bm_delete" oncommand="goDoCommand('cmd_bm_delete');"/>
<command id="cmd_bm_selectAll" oncommand="goDoCommand('cmd_bm_selectAll');"/>
</commandset>
<commandset id="selectEditMenuItems"/>
<commandset id="globalEditMenuItems"/>
</commands>
</overlay>

View File

@@ -1,64 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
////////////////////////////////////////////////////////////////////////////////
// Get the two bookmarks utility libraries running, attach controllers, focus
// tree widget, etc.
function Startup()
{
var bookmarksView = document.getElementById("bookmarks-view");
bookmarksView.treeBoxObject.selection.select(0);
}
function manageBookmarks() {
openDialog("chrome://communicator/content/bookmarks/bookmarks.xul", "", "chrome,dialog=no,resizable=yes");
}
function addBookmark() {
var contentArea = top.document.getElementById('content');
if (contentArea) {
const browsers = contentArea.browsers;
if (browsers.length > 1)
BookmarksUtils.addBookmarkForTabBrowser(contentArea);
else
BookmarksUtils.addBookmarkForBrowser(contentArea.webNavigation, true);
}
else
BookmarksUtils.addBookmark(null, null, undefined, true);
}

View File

@@ -1,759 +0,0 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var gBookmarksShell = null;
///////////////////////////////////////////////////////////////////////////////
// Tracks the selected item, the cell last clicked on, and the number of clicks
// given to it. Used to activate inline edit mode.
var gSelectionTracker = { currentItem: null, currentCell: null, clickCount: 0 };
///////////////////////////////////////////////////////////////////////////////
// Class which defines methods for a bookmarks UI implementation based around
// a treeview. Subclasses BookmarksBase in bookmarksOverlay.js. Some methods
// are required by the base class, others are for event handling. Window specific
// glue code should go into the BookmarksWindow class in bookmarks.js
function BookmarksTree (aID)
{
this.id = aID;
}
BookmarksTree.prototype = {
__proto__: BookmarksUIElement.prototype,
// XXX - change this to .element and move into base.
get tree ()
{
return document.getElementById(this.id);
},
/////////////////////////////////////////////////////////////////////////////
// This method constructs a menuitem for a context menu for the given command.
// This is implemented by the client so that it can intercept menuitem naming
// as appropriate.
createMenuItem: function (aDisplayName, aCommandName, aItemNode)
{
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var xulElement = document.createElementNS(kXULNS, "menuitem");
xulElement.setAttribute("cmd", aCommandName);
xulElement.setAttribute("command", "cmd_" + aCommandName.substring(NC_NS_CMD.length));
switch (aCommandName) {
case NC_NS_CMD + "open":
xulElement.setAttribute("label", aDisplayName);
xulElement.setAttribute("default", "true");
break;
case NC_NS_CMD + "openfolder":
aDisplayName = aItemNode.getAttribute("open") == "true" ? this.getLocaleString("cmd_openfolder2") : aDisplayName;
xulElement.setAttribute("label", aDisplayName);
xulElement.setAttribute("default", "true");
break;
case NC_NS_CMD + "renamebookmark":
if (!document.popupNode.hasAttribute("type")) {
xulElement.setAttribute("label", this.getLocaleString("cmd_renamebookmark2"));
xulElement.setAttribute("cmd", (NC_NS_CMD + "editurl"));
}
else
xulElement.setAttribute("label", aDisplayName);
break;
default:
xulElement.setAttribute("label", aDisplayName);
break;
}
return xulElement;
},
// XXX - ideally this would be in the base. this.tree needs to change to
// this.element and then we can do just that.
setRoot: function (aRoot)
{
this.tree.setAttribute("ref", aRoot);
},
// Command implementation
commands: {
openFolder: function (aSelectedItem)
{
if (aSelectedItem.getAttribute("open") == "true")
aSelectedItem.removeAttribute("open");
else
aSelectedItem.setAttribute("open", "true");
},
// Things Needed to Satisfy Mac Weenies:
// 1) need to implement timed single click edit. This could be Hard.
// 2) need to implement some other method of key access apart from F2.
// mpt claims that 'Cmd+U' is the excel equivalent.
editCell: function (aSelectedItem, aCell)
{
// XXX throw up properties dialog with name selected so user can rename
// that way, until tree conversion allows us to use IL again.
goDoCommand("cmd_properties");
return; // Disable inline edit for now.
var editCell = aSelectedItem.firstChild.childNodes[aCell];
if (editCell.getAttribute("editable") != "true")
return;
// Cause the inline edit cell binding to be used.
editCell.setAttribute("class", "treecell-indent treecell-editable");
var editColGroup = document.getElementById("theColumns");
var count = 0;
var property = "";
for (var i = 0; i < editColGroup.childNodes.length; ++i) {
var currCol = editColGroup.childNodes[i];
if (currCol.getAttribute("hidden") == "true")
return;
if (count == aCell) {
property = currCol.getAttribute("resource");
break;
}
++count;
// Deal with interleaved column resizer splitters
if (currCol.nextSibling.localName == "splitter") ++i;
}
if (property) {
editCell.setMode("edit");
editCell.addObserver(this.postModifyCallback, "accept",
[editCell, aSelectedItem, property]);
}
},
///////////////////////////////////////////////////////////////////////////
// Called after an inline-edit cell has left inline-edit mode, and data
// needs to be modified in the datasource.
postModifyCallback: function (aParams)
{
var selItemURI = NODE_ID(aParams[1]);
gBookmarksShell.propertySet(selItemURI, aParams[2], aParams[3]);
gBookmarksShell.selectFolderItem(NODE_ID(gBookmarksShell.findRDFNode(aParams[1], false)),
selItemURI, false);
gBookmarksShell.tree.focus();
gSelectionTracker.clickCount = 0;
// Set the cell back to use the standard treecell binding.
var editCell = aParams[0];
editCell.setAttribute("class", "treecell-indent");
},
///////////////////////////////////////////////////////////////////////////
// New Folder Creation
// Strategy: create a dummy row with edit fields to harvest information
// from the user, then destroy these rows and create an item
// in its place.
///////////////////////////////////////////////////////////////////////////
// Edit folder name & update the datasource if name is valid
onEditFolderName: function (aParams, aTopic)
{
var name = aParams[3];
var shell = gBookmarksShell.commands; // suck
var dummyItem = aParams[2];
var relativeNode = aParams[1];
var parentNode = relativeNode ? gBookmarksShell.findRDFNode(relativeNode, false) : gBookmarksShell.tree;
dummyItem.parentNode.removeChild(dummyItem);
if (!shell.validateNameAndTopic(name, aTopic, relativeNode, dummyItem)) {
gBookmarksShell.tree.selectItem(relativeNode);
gBookmarksShell.tree.focus();
return;
}
if (relativeNode) {
// If we're attempting to create a folder as a subfolder of an open folder,
// we need to set the parentFolder to be relativeNode, which will be the
// parent of the new folder, rather than the parent of the relativeNode,
// which will result in the folder being created in an incorrect position
// (adjacent to the relativeNode).
var selKids = ContentUtils.childByLocalName(relativeNode, "treechildren");
if (selKids && selKids.hasChildNodes() && selKids.lastChild == dummyItem)
parentNode = relativeNode;
}
var args = [{ property: NC_NS + "parent",
resource: NODE_ID(parentNode) },
{ property: NC_NS + "Name",
literal: name }];
const kBMDS = gBookmarksShell.RDF.GetDataSource("rdf:bookmarks");
kBMDS.AddObserver(newFolderRDFObserver);
var relId = relativeNode ? NODE_ID(relativeNode) : "NC:BookmarksRoot";
BookmarksUtils.doBookmarksCommand(relId, NC_NS_CMD + "newfolder", args);
kBMDS.RemoveObserver(newFolderRDFObserver);
var newFolderItem = document.getElementById(newFolderRDFObserver._newFolderURI);
gBookmarksShell.tree.focus();
gBookmarksShell.tree.selectItem(newFolderItem);
// Can't use newFolderItem because it may not have been created yet. Hack, huh?
var index = gBookmarksShell.tree.getIndexOfItem(relativeNode);
gBookmarksShell.tree.ensureIndexIsVisible(index+1);
gSelectionTracker.clickCount = 0;
},
///////////////////////////////////////////////////////////////////////////
// Performs simple validation on what the user has entered:
// 1) prevents entering an empty string
// 2) in the case of a canceled operation, remove the dummy item and
// restore selection.
validateNameAndTopic: function (aName, aTopic, aOldSelectedItem, aDummyItem)
{
// Don't allow user to enter an empty string "";
if (!aName) return false;
// If the user hit escape, go no further.
if (aTopic == "reject") {
if (aOldSelectedItem)
gBookmarksShell.tree.selectItem(aOldSelectedItem);
return false;
}
return true;
},
///////////////////////////////////////////////////////////////////////////
// Creates a dummy item that can be placed in edit mode to retrieve data
// to create new bookmarks/folders.
createBookmarkItem: function (aMode, aSelectedItem)
{
/////////////////////////////////////////////////////////////////////////
// HACK HACK HACK HACK HACK
// Disable Inline-Edit for now and just use a dialog.
// XXX - most of this is just copy-pasted from the other two folder
// creation functions. Yes it's ugly, but it'll do the trick for
// now as this is in no way intended to be a long-term solution.
const kPromptSvcContractID = "@mozilla.org/embedcomp/prompt-service;1";
const kPromptSvcIID = Components.interfaces.nsIPromptService;
const kPromptSvc = Components.classes[kPromptSvcContractID].getService(kPromptSvcIID);
var defaultValue = gBookmarksShell.getLocaleString("ile_newfolder");
var dialogTitle = gBookmarksShell.getLocaleString("newfolder_dialog_title");
var dialogMsg = gBookmarksShell.getLocaleString("newfolder_dialog_msg");
var stringValue = { value: defaultValue };
if (kPromptSvc.prompt(window, dialogTitle, dialogMsg, stringValue, null, { value: 0 })) {
var relativeNode = gBookmarksShell.tree;
var parentNode;
if (aSelectedItem && aSelectedItem.localName != "tree") {
// By default, create adjacent to the selected item
relativeNode = aSelectedItem;
if (relativeNode.getAttribute("container") == "true" &&
relativeNode.getAttribute("open") == "true") {
// But if it's an open container, the relative node should be the last child.
var treechildren = ContentUtils.childByLocalName(relativeNode, "treechildren");
if (treechildren && treechildren.hasChildNodes())
relativeNode = treechildren.lastChild; // folder non-empty, set relativeNode
parentNode = aSelectedItem; // no matter what, folder is open, so make it parent
} else {
parentNode = relativeNode ? gBookmarksShell.findRDFNode(relativeNode, false) : gBookmarksShell.tree;
}
}
var args = [{ property: NC_NS + "parent",
resource: NODE_ID(parentNode) },
{ property: NC_NS + "Name",
literal: stringValue.value }];
const kBMDS = gBookmarksShell.RDF.GetDataSource("rdf:bookmarks");
kBMDS.AddObserver(newFolderRDFObserver);
var relId = relativeNode ? NODE_ID(relativeNode) : "NC:BookmarksRoot";
BookmarksUtils.doBookmarksCommand(relId, NC_NS_CMD + "newfolder", args);
kBMDS.RemoveObserver(newFolderRDFObserver);
var newFolderItem = document.getElementById(newFolderRDFObserver._newFolderURI);
gBookmarksShell.tree.focus();
gBookmarksShell.tree.selectItem(newFolderItem);
// Can't use newFolderItem because it may not have been created yet. Hack, huh?
var index = gBookmarksShell.tree.getIndexOfItem(relativeNode);
gBookmarksShell.tree.ensureIndexIsVisible(index+1);
}
return;
// HACK HACK HACK HACK HACK
/////////////////////////////////////////////////////////////////////////
/* Disable inline edit for now
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var dummyItem = document.createElementNS(kXULNS, "treeitem");
dummyItem = gBookmarksShell.createBookmarkFolderDecorations(dummyItem);
dummyItem.setAttribute("class", "bookmark-item");
var dummyRow = document.createElementNS(kXULNS, "treerow");
var dummyCell = document.createElementNS(kXULNS, "treecell");
var dummyCell2 = document.createElementNS(kXULNS, "treecell");
dummyCell.setAttribute("label", gBookmarksShell.getLocaleString("ile_newfolder") + " ");
dummyCell.setAttribute("type", NC_NS + "Folder");
dummyCell.setAttribute("editable", "true");
dummyCell.setAttribute("class", "treecell-indent treecell-editable");
dummyRow.appendChild(dummyCell);
dummyItem.appendChild(dummyRow);
var relativeNode = null;
// If there are selected items, try to create the dummy item relative to the
// best item, and position the bookmark there when created. Otherwise just
// append to the root.
if (aSelectedItem && aSelectedItem.localName != "tree") {
// By default, create adjacent to the selected item
relativeNode = aSelectedItem;
if (relativeNode.getAttribute("container") == "true" &&
relativeNode.getAttribute("open") == "true") {
// But if it's an open container, the relative node should be the last child.
var treechildren = ContentUtils.childByLocalName(relativeNode, "treechildren");
if (treechildren && treechildren.hasChildNodes())
relativeNode = treechildren.lastChild;
}
if (aSelectedItem.getAttribute("container") == "true") {
if (aSelectedItem.getAttribute("open") == "true") {
var treechildren = ContentUtils.childByLocalName(aSelectedItem, "treechildren");
if (!treechildren) {
treechildren = document.createElementNS(kXULNS, "treechildren");
aSelectedItem.appendChild(treechildren);
}
// Insert new item after last item.
treechildren.appendChild(dummyItem);
}
else {
if (aSelectedItem.nextSibling)
aSelectedItem.parentNode.insertBefore(dummyItem, aSelectedItem.nextSibling);
else
aSelectedItem.parentNode.appendChild(dummyItem);
}
var index = gBookmarksShell.tree.getIndexOfItem(dummyItem);
gBookmarksShell.tree.ensureIndexIsVisible(index);
}
else {
if (aSelectedItem.nextSibling)
aSelectedItem.parentNode.insertBefore(dummyItem, aSelectedItem.nextSibling);
else
aSelectedItem.parentNode.appendChild(dummyItem);
}
}
else {
// No items in the tree. Append to the root.
var rootKids = document.getElementById("treechildren-bookmarks");
rootKids.appendChild(dummyItem);
}
dummyCell.setMode("edit");
dummyCell.addObserver(this.onEditFolderName, "accept", [dummyCell, relativeNode, dummyItem]);
dummyCell.addObserver(this.onEditFolderName, "reject", [dummyCell, relativeNode, dummyItem]);
*/
}
},
/////////////////////////////////////////////////////////////////////////////
// Evaluates an event to determine whether or not it affords opening a tree
// item. Typically, this is when the left mouse button is used, and provided
// the click-rate matches that specified by our owning tree class. For example,
// some trees open an item when double clicked (bookmarks/history windows) and
// others on a single click (sidebar panels).
isValidOpenEvent: function (aEvent)
{
return !(aEvent.type == "click" &&
(aEvent.button != 0 || aEvent.detail != this.openClickCount))
},
/////////////////////////////////////////////////////////////////////////////
// For the given selection, selects the best adjacent element. This method is
// useful when an action such as a cut or a deletion is performed on a
// selection, and focus/selection needs to be restored after the operation
// is performed.
getNextElement: function (aElement)
{
if (aElement.nextSibling)
return aElement.nextSibling;
else if (aElement.previousSibling)
return aElement.previousSibling;
else
return aElement.parentNode.parentNode;
},
selectElement: function (aElement)
{
this.tree.selectItem(aElement);
},
//////////////////////////////////////////////////////////////////////////////
// Add the treeitem element specified by aURI to the tree's current selection.
addItemToSelection: function (aURI)
{
var item = document.getElementById(aURI) // XXX flawed for multiple ids
this.tree.addItemToSelection(item);
},
/////////////////////////////////////////////////////////////////////////////
// Return a set of DOM nodes that represent the selection in the tree widget.
// This method is takes a node parameter which is the popupNode for the
// document. If the popupNode is not contained by the selection, the
// popupNode is selected and the new selection returned.
getSelection: function ()
{
// Note that we don't just the selectedItems NodeList here because that
// is a reference to a LIVE DOM NODE LIST. We want to maintain control
// over what is in the selection array ourselves.
return [].concat(this.tree.selectedItems);
},
getBestItem: function ()
{
var seln = this.getSelection ();
if (seln.length < 1) {
var kids = ContentUtils.childByLocalName(this.tree, "treechildren");
return kids.lastChild || this.tree;
}
else
return seln[0];
return this.tree;
},
/////////////////////////////////////////////////////////////////////////////
// Return a set of DOM nodes that represent the selection in the tree widget.
// This method is takes a node parameter which is the popupNode for the
// document. If the popupNode is not contained by the selection, the
// popupNode is selected and the new selection returned.
getContextSelection: function (aItemNode)
{
// How a context-click works:
// if the popup node is contained by the selection, the context menu is
// built for that selection. However, if the popup node is invoked on a
// non-selected node, unless modifiers are pressed**, the previous
// selection is discarded and that node selected.
var selectedItems = this.tree.selectedItems;
for (var i = 0; i < selectedItems.length; ++i) {
if (selectedItems[i] == aItemNode)
return selectedItems;
}
if (aItemNode.localName == "treeitem")
this.tree.selectItem(aItemNode);
return this.tree.selectedItems.length ? this.tree.selectedItems : [this.tree];
},
getSelectedFolder: function ()
{
var selectedItem = this.getBestItem();
if (!selectedItem) return "NC:BookmarksRoot";
while (selectedItem && selectedItem.nodeType == Node.ELEMENT_NODE) {
if (selectedItem.getAttribute("container") == "true" &&
selectedItem.getAttribute("open") == "true")
return NODE_ID(selectedItem);
selectedItem = selectedItem.parentNode.parentNode;
}
return "NC:BookmarksRoot";
},
/////////////////////////////////////////////////////////////////////////////
// For a given start DOM element, find the enclosing DOM element that contains
// the template builder RDF resource decorations (id, ref, etc).
findRDFNode: function (aStartNode, aIncludeStartNodeFlag)
{
var temp = aIncludeStartNodeFlag ? aStartNode : aStartNode.parentNode;
while (temp && temp.localName != "treeitem")
temp = temp.parentNode;
return temp || this.tree;
},
/////////////////////////////////////////////////////////////////////////////
// Tree click events. This handles when to go into inline-edit mode for
// editable cells.
treeClicked: function (aEvent)
{
// We are disabling Inline Edit for now. It's too buggy in the old XUL tree widget.
// A more solid implementation will follow the conversion to tree
/*
if (this.tree.selectedItems.length > 1 || aEvent.detail > 1 || aEvent.button != 0) {
gSelectionTracker.clickCount = 0;
return;
}
if (gSelectionTracker.currentItem == this.tree.currentItem &&
gSelectionTracker.currentCell == aEvent.target)
++gSelectionTracker.clickCount;
else
gSelectionTracker.clickCount = 0;
if (!this.tree.currentItem)
return;
gSelectionTracker.currentItem = this.tree.currentItem;
gSelectionTracker.currentCell = aEvent.target;
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" &&
gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Folder")
return;
var row = gSelectionTracker.currentItem.firstChild;
if (row) {
for (var i = 0; i < row.childNodes.length; ++i) {
if (row.childNodes[i] == gSelectionTracker.currentCell) {
// Don't allow inline-edit of cells other than name for folders.
// XXX - so so skeezy. Change this to look for NC:Name or some such.
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" && i)
return;
// Don't allow editing of the root folder name
if (gSelectionTracker.currentItem.id == "NC:BookmarksRoot")
return;
if (gSelectionTracker.clickCount == 1 && this.openClickCount > 1)
gBookmarksShell.commands.editCell(this.tree.currentItem, i);
break;
}
}
}
*/
},
treeOpen: function (aEvent)
{
if (this.isValidOpenEvent(aEvent)) {
var rdfNode = this.findRDFNode(aEvent.target, true);
if (rdfNode.getAttribute("container") != "true")
this.open(aEvent, rdfNode);
}
},
/////////////////////////////////////////////////////////////////////////////
// Tree key events. This handles when to go into inline-edit mode for editable
// cells, when to load a URL, etc.
treeKeyPress: function (aEvent)
{
if (this.tree.selectedItems.length > 1) return;
/* Disabling Inline Edit
if (aEvent.keyCode == 113 && aEvent.shiftKey) {
const kNodeId = NODE_ID(this.tree.currentItem);
if (this.resolveType(kNodeId) == NC_NS + "Bookmark")
gBookmarksShell.commands.editCell (this.tree.currentItem, 1);
}
else */
if (aEvent.keyCode == 113)
goDoCommand("cmd_rename");
else if (aEvent.keyCode == 13) // && this.tree.currentItem.firstChild.getAttribute("inline-edit") != "true")
goDoCommand(aEvent.altKey ? "cmd_properties" : "cmd_open");
},
selectFolderItem: function (aFolderURI, aItemURI, aAdditiveFlag)
{
var folder = document.getElementById(aFolderURI);
var kids = ContentUtils.childByLocalName(folder, "treechildren");
if (!kids) return;
var item = kids.firstChild;
while (item) {
if (item.id == aItemURI) break;
item = item.nextSibling;
}
if (!item) return;
this.tree[aAdditiveFlag ? "addItemToSelection" : "selectItem"](item);
},
/////////////////////////////////////////////////////////////////////////////
// Command handling & Updating.
controller: {
supportsCommand: function (aCommand)
{
switch(aCommand) {
case "cmd_undo":
case "cmd_redo":
return false;
case "cmd_bm_cut":
case "cmd_bm_copy":
case "cmd_bm_paste":
case "cmd_bm_delete":
case "cmd_bm_selectAll":
return true;
case "cmd_open":
case "cmd_openfolder":
case "cmd_openfolderinnewwindow":
case "cmd_newbookmark":
case "cmd_newfolder":
case "cmd_newseparator":
case "cmd_find":
case "cmd_properties":
case "cmd_rename":
case "cmd_setnewbookmarkfolder":
case "cmd_setpersonaltoolbarfolder":
case "cmd_setnewsearchfolder":
case "cmd_import":
case "cmd_export":
case "cmd_bm_fileBookmark":
return true;
default:
return false;
}
},
isCommandEnabled: function (aCommand)
{
var numSelectedItems = gBookmarksShell.tree.selectedItems.length;
var seln, firstSelected, folderType, bItemCountCorrect;
switch(aCommand) {
case "cmd_undo":
case "cmd_redo":
return false;
case "cmd_bm_paste":
return gBookmarksShell.canPaste();
case "cmd_bm_cut":
case "cmd_bm_copy":
case "cmd_bm_delete":
return numSelectedItems >= 1;
case "cmd_bm_selectAll":
return true;
case "cmd_open":
seln = gBookmarksShell.tree.selectedItems;
return numSelectedItems == 1 && seln[0].getAttribute("type") == NC_NS + "Bookmark";
case "cmd_openfolder":
case "cmd_openfolderinnewwindow":
seln = gBookmarksShell.tree.selectedItems;
return numSelectedItems == 1 && seln[0].getAttribute("type") == NC_NS + "Folder";
case "cmd_find":
case "cmd_newbookmark":
case "cmd_newfolder":
case "cmd_newseparator":
case "cmd_import":
case "cmd_export":
return true;
case "cmd_properties":
case "cmd_rename":
seln = gBookmarksShell.tree.selectedItems;
return numSelectedItems == 1 && seln[0].getAttribute("type") != NC_NS + "BookmarkSeparator";
case "cmd_setnewbookmarkfolder":
seln = gBookmarksShell.tree.selectedItems;
firstSelected = seln.length ? seln[0] : gBookmarksShell.tree;
folderType = firstSelected.getAttribute("type") == (NC_NS + "Folder");
bItemCountCorrect = seln.length ? numSelectedItems == 1 : true;
return bItemCountCorrect && !(NODE_ID(firstSelected) == "NC:NewBookmarkFolder") && folderType;
case "cmd_setpersonaltoolbarfolder":
seln = gBookmarksShell.tree.selectedItems;
firstSelected = seln.length ? seln[0] : gBookmarksShell.tree;
folderType = firstSelected.getAttribute("type") == (NC_NS + "Folder");
bItemCountCorrect = seln.length ? numSelectedItems == 1 : true;
return bItemCountCorrect && !(NODE_ID(firstSelected) == "NC:PersonalToolbarFolder") && folderType;
case "cmd_setnewsearchfolder":
seln = gBookmarksShell.tree.selectedItems;
firstSelected = seln.length ? seln[0] : gBookmarksShell.tree;
folderType = firstSelected.getAttribute("type") == (NC_NS + "Folder");
bItemCountCorrect = seln.length ? numSelectedItems == 1 : true;
return bItemCountCorrect == 1 && !(NODE_ID(firstSelected) == "NC:NewSearchFolder") && folderType;
case "cmd_bm_fileBookmark":
seln = gBookmarksShell.tree.selectedItems;
return seln.length > 0;
default:
return false;
}
},
doCommand: function (aCommand)
{
switch(aCommand) {
case "cmd_undo":
case "cmd_redo":
break;
case "cmd_bm_paste":
case "cmd_bm_copy":
case "cmd_bm_cut":
case "cmd_bm_delete":
case "cmd_newbookmark":
case "cmd_newfolder":
case "cmd_newseparator":
case "cmd_properties":
case "cmd_rename":
case "cmd_open":
case "cmd_openfolder":
case "cmd_openfolderinnewwindow":
case "cmd_setnewbookmarkfolder":
case "cmd_setpersonaltoolbarfolder":
case "cmd_setnewsearchfolder":
case "cmd_find":
case "cmd_import":
case "cmd_export":
case "cmd_bm_fileBookmark":
gBookmarksShell.execCommand(aCommand.substring("cmd_".length));
break;
case "cmd_bm_selectAll":
gBookmarksShell.tree.selectAll();
break;
}
},
onEvent: function (aEvent)
{
switch (aEvent) {
case "tree-select":
this.onCommandUpdate();
break;
}
},
onCommandUpdate: function ()
{
var commands = ["cmd_properties", "cmd_rename", "cmd_bm_copy",
"cmd_bm_paste", "cmd_bm_cut", "cmd_bm_delete",
"cmd_setpersonaltoolbarfolder",
"cmd_setnewbookmarkfolder",
"cmd_setnewsearchfolder", "cmd_bm_fileBookmark",
"cmd_openfolderinnewwindow", "cmd_openfolder"];
for (var i = 0; i < commands.length; ++i)
goUpdateCommand(commands[i]);
}
}
};
var newFolderRDFObserver = {
_newFolderURI: null,
onAssert: function (aDS, aSource, aProperty, aValue)
{
try {
var value = aValue.QueryInterface(Components.interfaces.nsIRDFResource);
if (aDS.URI == "rdf:bookmarks" && aProperty.Value == RDF_NS + "type" &&
value.Value == NC_NS + "Folder")
this._newFolderURI = aSource.Value;
}
catch (e) {
// Failures are OK, the value could be a literal instead of a resource.
}
},
onUnassert: function (aDS, aSource, aProperty, aTarget) { },
onChange: function (aDS, aSource, aProperty, aOldTarget, aNewTarget) { },
onMove: function (aDS, aOldSource, aNewSource, aProperty, aTarget) { },
beginUpdateBatch: function (aDS) { },
endUpdateBatch: function (aDS) { }
};

View File

@@ -1,97 +0,0 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const BMARKS_CONTRACTID = "@mozilla.org/browser/bookmarks-service;1";
const nsIBookmarksService = Components.interfaces.nsIBookmarksService;
var gOKButton;
var gSearchField;
function Startup()
{
var bundle = document.getElementById("bookmarksBundle");
gOKButton = document.documentElement.getButton("accept");
gOKButton.label = bundle.getString("search_button_label");
gOKButton.disabled = true;
gSearchField = document.getElementById("searchField");
gSearchField.focus();
}
var gCreatingNewWindow = false;
function find()
{
// Build up a find URI from the search fields and open a new window
// rooted on the URI.
var match = document.getElementById("matchList");
var method = document.getElementById("methodList");
var searchURI = "find:datasource=rdf:bookmarks"
searchURI += "&match=" + match.selectedItem.value;
searchURI += "&method=" + method.selectedItem.value;
searchURI += "&text=" + escape(gSearchField.value);
var bmWindow = findMostRecentWindow("bookmarks:searchresults", "chrome://communicator/content/bookmarks/bookmarks.xul", searchURI);
// Update the root of the tree if we're using an existing search window.
if (!gCreatingNewWindow)
bmWindow.document.getElementById("bookmarks-view").tree.setAttribute("ref", searchURI);
bmWindow.focus();
if (document.getElementById("saveQuery").checked == true)
{
var bundle = document.getElementById("bookmarksBundle");
var findTitle = bundle.stringBundle.formatStringFromName(
"ShortFindTitle", [gSearchField.value], 1);
var bmks = Components.classes[BMARKS_CONTRACTID].getService(nsIBookmarksService);
bmks.addBookmarkImmediately(searchURI, findTitle, bmks.BOOKMARK_FIND_TYPE, null);
}
return true;
}
function findMostRecentWindow(aType, aURI, aParam)
{
var WM = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
WM = WM.QueryInterface(Components.interfaces.nsIWindowMediator);
var topWindow = WM.getMostRecentWindow(aType);
if (!topWindow) gCreatingNewWindow = true;
return topWindow || openDialog("chrome://communicator/content/bookmarks/bookmarks.xul",
"", "chrome,all,dialog=no", aParam);
}
function doEnabling()
{
gOKButton.disabled = !gSearchField.value;
}

View File

@@ -1,69 +0,0 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape 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/NPL/
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 mozilla.org code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Ben Goodger <ben@netscape.com> (Original Author)
-->
<!--
"Find Bookmarks" window
-->
<?xml-stylesheet href="chrome://communicator/skin/"?>
<!DOCTYPE window SYSTEM "chrome://communicator/locale/bookmarks/findBookmark.dtd">
<dialog id="findBookmarkWindow" style="width: 36em;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&findBookmark.title;"
onload="Startup();"
ondialogaccept="return find();">
<stringbundle id="bookmarksBundle" src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/findBookmark.js"/>
<label value="&search.for.label;"/>
<hbox align="center">
<menulist id="matchList" class="menulist-toolbar">
<menupopup>
<menuitem value="http://home.netscape.com/NC-rdf#Name" label="&search.name.label;"/>
<menuitem value="http://home.netscape.com/NC-rdf#URL" label="&search.url.label;"/>
<menuitem value="http://home.netscape.com/NC-rdf#Description" label="&search.description.label;"/>
<menuitem value="http://home.netscape.com/NC-rdf#ShortcutURL" label="&search.shortcut.label;"/>
</menupopup>
</menulist>
<menulist id="methodList" class="menulist-toolbar">
<menupopup>
<menuitem value="contains" label="&search.contains.label;"/>
<menuitem value="startswith" label="&search.startswith.label;"/>
<menuitem value="endswith" label="&search.endswith.label;"/>
<menuitem value="is" label="&search.is.label;"/>
<menuitem value="isnot" label="&search.isnot.label;"/>
<menuitem value="doesntcontain" label="&search.doesntcontain.label;"/>
</menupopup>
</menulist>
<textbox id="searchField" flex="1" oninput="doEnabling();"/>
</hbox>
<checkbox id="saveQuery" label="&save.query.label;" />
</dialog>

View File

@@ -1,47 +0,0 @@
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
comm.jar:
content/communicator/bookmarks/addBookmark.xul
content/communicator/bookmarks/addBookmark.js
content/communicator/bookmarks/bm-props.js
content/communicator/bookmarks/bm-props.xul
content/communicator/bookmarks/bookmarksDD.js
content/communicator/bookmarks/bookmarks.xul
content/communicator/bookmarks/bookmarks.js
content/communicator/bookmarks/bookmarks.css
content/communicator/bookmarks/bookmarks.xml
content/communicator/bookmarks/bookmarksTree.js
content/communicator/bookmarks/bookmarksOverlay.xul
content/communicator/bookmarks/bookmarksOverlay.js
content/communicator/bookmarks/bm-panel.xul
content/communicator/bookmarks/bookmarksPanel.js
content/communicator/bookmarks/findBookmark.js
content/communicator/bookmarks/findBookmark.xul
content/communicator/bookmarks/pref-bookmarks.xul
content/communicator/bookmarks/oTest.xul
en-US.jar:
locale/en-US/communicator/bookmarks/addBookmark.dtd (locale/en-US/addBookmark.dtd)
locale/en-US/communicator/bookmarks/bm-props.dtd (locale/en-US/bm-props.dtd)
locale/en-US/communicator/bookmarks/bookmarks.dtd (locale/en-US/bookmarks.dtd)
locale/en-US/communicator/bookmarks/bookmark.properties (locale/en-US/bookmark.properties)
locale/en-US/communicator/bookmarks/bookmarksOverlay.dtd (locale/en-US/bookmarksOverlay.dtd)
locale/en-US/communicator/bookmarks/findBookmark.dtd (locale/en-US/findBookmark.dtd)
locale/en-US/communicator/bookmarks/pref-bookmarks.dtd (locale/en-US/pref-bookmarks.dtd)

View File

@@ -1,4 +0,0 @@
en-US:bm-find.dtd
en-US:bm-props.dtd
en-US:bookmarks.dtd
en-US:bookmark.properties

View File

@@ -1,4 +0,0 @@
bm-find.dtd
bm-props.dtd
bookmark.properties
bookmarks.dtd

View File

@@ -1,46 +0,0 @@
<!--
- 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 Mozilla Communicator.
-
- The Initial Developer of the Original Code is Netscape
- Communications Corp. Portions created by Netscape Communications
- Corp. are Copyright (C) 1999 Netscape Communications Corp. All
- Rights Reserved.
-
- Contributor(s):
- Ben Goodger <ben@netscape.com> (Original Author)
-->
<!ENTITY newBookmark.title "Add Bookmark">
<!ENTITY newbookmark.label "&brandShortName; will add a bookmark to this page.">
<!ENTITY name.label "Name:">
<!ENTITY name.accesskey "n">
<!ENTITY url.label "Location:">
<!ENTITY url.accesskey "l">
<!ENTITY button.createin.label "Create In &gt;&gt;">
<!ENTITY button.createin.accesskey "c">
<!ENTITY button.createin2.label "Create In &lt;&lt;">
<!ENTITY createin.label "Create in:">
<!ENTITY createin.accesskey "i">
<!ENTITY button.newfolder.label "New Folder...">
<!ENTITY button.newfolder.accesskey "w">
<!ENTITY alwayscreateinfolder.label "Don't show this dialog again">
<!ENTITY alwayscreateinfolder.accesskey "a">
<!ENTITY dontshowmessage.tooltip "When this option is selected, new Bookmarks will be added using the title provided by the page.">
<!ENTITY button.defaultfolder.label "Use Default">
<!ENTITY button.defaultfolder.accesskey "d">
<!ENTITY selectFolder.label "Choose Folder">
<!ENTITY addGroup.label "Bookmark this group of tabs">
<!ENTITY addGroup.accesskey "B">

View File

@@ -1,92 +0,0 @@
<!--
- 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 Mozilla Communicator.
-
- The Initial Developer of the Original Code is Netscape
- Communications Corp. Portions created by Netscape Communications
- Corp. are Copyright (C) 1999 Netscape Communications Corp. All
- Rights Reserved.
-
- Contributor(s): Stephen Lamm <slamm@netscape.com>
- Robert John Churchill <rjc@netscape.com>
- Ben Goodger <ben@netscape.com>
-->
<!ENTITY bookmarks.windowtitle.label "Properties for &quot;**bm_title**&quot;">
<!ENTITY generalInfo.label "Info">
<!ENTITY generalInfo.accesskey "i">
<!ENTITY generaldesc.label "&brandShortName; can remember the locations of sites on the Internet for you. Enter the site's name and location in the fields below, then select the site from the Bookmarks menu or your Bookmarks Sidebar tab to visit the site.">
<!ENTITY schedule.label "Schedule">
<!ENTITY schedule.accesskey "s">
<!ENTITY schedule.description "&brandShortName; can check this site for updates and notify you when one occurs. Use these settings to customize the schedule for this Bookmark.">
<!ENTITY notification.label "Notify">
<!ENTITY notification.accesskey "n">
<!-- ICK. fix me -->
<!ENTITY notification.description "&brandShortName; will notify you when this site changes. Use these settings to customize notification.">
<!ENTITY bookmarks.information.label "Information:">
<!ENTITY bookmarks.name.label "Name:">
<!ENTITY bookmarks.location.label "Location:">
<!ENTITY bookmarks.shortcut.label "Keyword:">
<!ENTITY bookmarks.description.label "Description:">
<!ENTITY checkforupdates.legend.label "Check this location for updates:">
<!ENTITY when.label "When:">
<!ENTITY from.label "from:">
<!ENTITY to.label "to: ">
<!ENTITY every.label "every">
<!ENTITY minutes.label "minute(s)">
<!ENTITY notifications.legend.label "Notification:">
<!ENTITY checknever.label "Never">
<!ENTITY checkeveryday.label "Every day">
<!ENTITY checkweekdays.label "Weekdays">
<!ENTITY checkweekends.label "Weekends">
<!ENTITY checkmondays.label "Mondays">
<!ENTITY checktuesdays.label "Tuesdays">
<!ENTITY checkwednesdays.label "Wednesdays">
<!ENTITY checkthursdays.label "Thursdays">
<!ENTITY checkfridays.label "Fridays">
<!ENTITY checksaturdays.label "Saturdays">
<!ENTITY checksundays.label "Sundays">
<!ENTITY midnight.label "Midnight">
<!ENTITY AMone.label "1 AM">
<!ENTITY AMtwo.label "2 AM">
<!ENTITY AMthree.label "3 AM">
<!ENTITY AMfour.label "4 AM">
<!ENTITY AMfive.label "5 AM">
<!ENTITY AMsix.label "6 AM">
<!ENTITY AMseven.label "7 AM">
<!ENTITY AMeight.label "8 AM">
<!ENTITY AMnine.label "9 AM">
<!ENTITY AMten.label "10 AM">
<!ENTITY AMeleven.label "11 AM">
<!ENTITY noon.label "Noon">
<!ENTITY PMone.label "1 PM">
<!ENTITY PMtwo.label "2 PM">
<!ENTITY PMthree.label "3 PM">
<!ENTITY PMfour.label "4 PM">
<!ENTITY PMfive.label "5 PM">
<!ENTITY PMsix.label "6 PM">
<!ENTITY PMseven.label "7 PM">
<!ENTITY PMeight.label "8 PM">
<!ENTITY PMnine.label "9 PM">
<!ENTITY PMten.label "10 PM">
<!ENTITY PMeleven.label "11 PM">
<!ENTITY notification.icon.label "Change the bookmark's icon">
<!ENTITY notification.sound.label "Play a sound">
<!ENTITY notification.alert.label "Display an alert">
<!ENTITY notification.window.label "Open web page in a new window">

View File

@@ -1,80 +0,0 @@
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
cmd_bm_open = Open
cmd_bm_openfolder = Expand
cmd_bm_openfolder2 = Collapse
cmd_bm_find = Find a Bookmark...
cmd_bm_cut = Cut
cmd_bm_copy = Copy
cmd_bm_paste = Paste
cmd_bm_delete = Delete
cmd_bm_selectAll = Select All
cmd_bm_rename = Rename...
cmd_bm_renamebookmark2 = Change Location...
cmd_bm_properties = Properties
cmd_bm_fileBookmark = File Bookmark(s)...
cmd_bm_openinnewwindow = Open in New Window
cmd_bm_newfolder = New Folder...
cmd_bm_newbookmark = New Bookmark...
cmd_bm_newseparator = New Separator
cmd_bm_setnewbookmarkfolder = Set as New Bookmark folder
cmd_bm_setpersonaltoolbarfolder = Set as Personal Toolbar folder
cmd_bm_setnewsearchfolder = Set as Saved Search Results folder
ile_newfolder = New Folder
ile_newbookmark = New Bookmark
newfolder_dialog_title = Create New Folder
newfolder_dialog_msg = Create a New Folder named:
window_title = %folder_name% - Bookmarks
search_results_title = Search Results
file_in = File in "%folder_name%"
bookmarks_root = Bookmarks for %user_name%
status_foldercount = %num_items% object(s)
WebPageUpdated = The following web page has been updated:
WebPageTitle = Title:
WebPageURL = URL:
WebPageAskDisplay = Would you like to display it?
WebPageAskStopOption = Stop checking for updates on this web page
pleaseEnterALocation = Please enter a location
pleaseEnterADuration = Please enter a duration.
pleaseSelectANotification = Please enter at least one notification method.
SortMenuItem = Sorted by %NAME%
ShortFindTitle = Find: '%S'
FindTitle = Find: %S %S '%S' in %S
ImportedIEFavorites = Imported IE Favorites
ImportedIEStaticFavorites = Imported IE Favorites
ImportedNetPositiveBookmarks = Imported NetPositive Bookmarks
DefaultPersonalToolbarFolder = Personal Toolbar Folder
SelectImport = Import bookmark file:
EnterExport = Export bookmark file:
search_button_label = Find

View File

@@ -1,87 +0,0 @@
<!--
- 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 Mozilla Communicator.
-
- The Initial Developer of the Original Code is Netscape
- Communications Corp. Portions created by Netscape Communications
- Corp. are Copyright (C) 1999 Netscape Communications Corp. All
- Rights Reserved.
-
- Contributor(s):
- Stephen Lamm <slamm@netscape.com>
- Blake Ross <blakeross@telocity.com>
-->
<!-- extracted from ./bookmarks.xul -->
<!ENTITY menuBar.tooltip "Menu Bar">
<!ENTITY bookmarkToolbar.tooltip "Bookmark Toolbar">
<!ENTITY menuitem.newBookmark.label "Bookmark">
<!ENTITY command.newBookmark.accesskey "B">
<!ENTITY menuitem.newFolder.label "Folder">
<!ENTITY button.newFolder.label "New Folder">
<!ENTITY command.newFolder.accesskey "F">
<!ENTITY menuitem.newSeparator.label "Separator">
<!ENTITY button.newSeparator.label "New Separator">
<!ENTITY command.newSeparator.accesskey "S">
<!ENTITY menuitem.import.label "Import...">
<!ENTITY menuitem.import.accesskey "i">
<!ENTITY menuitem.export.label "Export...">
<!ENTITY menuitem.export.accesskey "e">
<!ENTITY menuitem.find.label "Search Bookmarks...">
<!ENTITY command.findBookmarks.label "Search...">
<!ENTITY menuitem.find.accesskey "S">
<!ENTITY edit.find.keybinding "f">
<!ENTITY command.properties.label "Properties...">
<!ENTITY command.properties.accesskey "r">
<!ENTITY edit.properties.keybinding "i">
<!ENTITY command.rename.label "Rename...">
<!ENTITY command.delete.label "Delete">
<!ENTITY command.fileBookmark.label "File Bookmark(s)...">
<!ENTITY command.fileBookmark.accesskey "l">
<!ENTITY command.addBookmark.label "Add...">
<!ENTITY command.manageBookmarks.label "Manage">
<!ENTITY menuitem.view.command.toolbar.label "Toolbar">
<!ENTITY menuitem.view.command.toolbar.accesskey "t">
<!ENTITY menuitem.view.unsorted.label "Unsorted">
<!ENTITY menuitem.view.unsorted.accesskey "u">
<!ENTITY menuitem.view.ascending.label "A > Z Sort Order">
<!ENTITY menuitem.view.ascending.accesskey "a">
<!ENTITY menuitem.view.descending.label "Z > A Sort Order">
<!ENTITY menuitem.view.descending.accesskey "z">
<!ENTITY menuitem.view.show_columns.label "Show columns">
<!ENTITY menuitem.view.show_columns.accesskey "S">
<!ENTITY menuitem.newbookmarkfolder.label "Set as New Bookmark Folder">
<!ENTITY menuitem.newbookmarkfolder.accesskey "b">
<!ENTITY menuitem.newinternetsearchfolder.label "Set as New Internet Search Folder">
<!ENTITY menuitem.newinternetsearchfolder.accesskey "i">
<!ENTITY menuitem.personaltoolbarfolder.label "Set as Personal Toolbar Folder">
<!ENTITY menuitem.personaltoolbarfolder.accesskey "p">
<!ENTITY treecol.name.label "Name">
<!ENTITY treecol.name.accesskey "n">
<!ENTITY treecol.url.label "Location">
<!ENTITY treecol.url.accesskey "l">
<!ENTITY treecol.shortcut.label "Keyword">
<!ENTITY treecol.shortcut.accesskey "k">
<!ENTITY treecol.addedon.label "Added">
<!ENTITY treecol.addedon.accesskey "a">
<!ENTITY treecol.lastmod.label "Last Modified">
<!ENTITY treecol.lastmod.accesskey "m">
<!ENTITY treecol.lastvisit.label "Last Visited">
<!ENTITY treecol.lastvisit.accesskey "b">
<!ENTITY treecol.description.label "Description">
<!ENTITY treecol.description.accesskey "d">
<!ENTITY bookmarksWindowTitle.label "Bookmark Manager">

View File

@@ -1,22 +0,0 @@
<!ENTITY findABookmark.label "Find a Bookmark...">
<!ENTITY findABookmark.accesskey "f">
<!ENTITY newBookmark.label "New Bookmark...">
<!ENTITY newBookmark.accesskey "n">
<!ENTITY newFolder.label "New Folder...">
<!ENTITY newFolder.accesskey "e">
<!ENTITY newSeparator.label "New Separator">
<!ENTITY newSeparator.accesskey "s">
<!ENTITY setAsNewBookmarkFolder.label "Set as new Bookmark folder">
<!ENTITY setAsNewBookmarkFolder.accesskey "b">
<!ENTITY setAsNewSearchFolder.label "Set as new Search Results folder">
<!ENTITY setAsNewSearchFolder.accesskey "r">
<!ENTITY setAsNewToolbarFolder.label "Set as new Personal Toolbar folder">
<!ENTITY setAsNewToolbarFolder.accesskey "p">
<!ENTITY exportBookmarks.label "Export...">
<!ENTITY exportBookmarks.accesskey "x">
<!ENTITY importBookmarks.label "Import...">
<!ENTITY importBookmarks.accesskey "i">

View File

@@ -1,15 +0,0 @@
<!ENTITY search.name.label "name">
<!ENTITY search.url.label "location">
<!ENTITY search.shortcut.label "keyword">
<!ENTITY search.description.label "description">
<!ENTITY search.startswith.label "starts with">
<!ENTITY search.endswith.label "ends with">
<!ENTITY search.is.label "is">
<!ENTITY search.isnot.label "is not">
<!ENTITY search.contains.label "contains">
<!ENTITY search.doesntcontain.label "doesn't contain">
<!ENTITY save.query.label "Save query in bookmarks">
<!ENTITY search.for.label "Find Bookmarks whose">
<!ENTITY findBookmark.title "Find Bookmarks">

View File

@@ -1,24 +0,0 @@
#!nmake
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Mozilla Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ..\..\..\..\..\..
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,13 +0,0 @@
<!ENTITY lHeader "Bookmarks">
<!ENTITY filingBookmarks.label "Adding Bookmarks">
<!ENTITY autoFile.label "&brandShortName; will ask you to choose a title and folder when adding a new Bookmark.">
<!ENTITY enableAutoFile.label "Automatically set title and destination">
<!ENTITY defaultFolder.label "By default, all new Bookmarks will be added into this folder:">
<!ENTITY chooseDefaultFolder.label "Choose Folder...">
<!ENTITY chooseDefaultFolder.accesskey "c">
<!ENTITY extendedDataViews.label "Extended Data Views">
<!ENTITY extendedDataExplanation.label "&brandShortName; can display some types of special data (e.g. local file folders and ftp directories) in the bookmarks window or menu as folders, rather than as normal links.">
<!ENTITY showExtendedData.label "Show Extended Data as folders in the Bookmarks window and menu">
<!ENTITY showExtendedData.accesskey "x">

View File

@@ -1,27 +0,0 @@
#!nmake
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Mozilla Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ..\..\..\..\..
DIRS = en-US
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,27 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..\..
DIRS= locale
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,29 +0,0 @@
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
packages/core.jar:
communicator/content/bookmarks/bm-find.js
communicator/content/bookmarks/bm-find.xul
communicator/content/bookmarks/bm-panel.js
communicator/content/bookmarks/bm-panel.xul
communicator/content/bookmarks/bm-props.js
communicator/content/bookmarks/bm-props.xul
communicator/content/bookmarks/bookmarks.js
communicator/content/bookmarks/bookmarksDD.js
communicator/content/bookmarks/bookmarks.xul

View File

@@ -1,162 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://communicator/skin/"?>
<?xml-stylesheet href="chrome://communicator/content/bookmarks/oTest.css"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<window id="bookmarksTreeTest" width="640" height="480"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
orient="vertical"
onload="Startup();">
<script>
<![CDATA[
var bookmarksBuilderObserver = {
onToggleOpenState: function (aIndex) {
dump("*** onToggleOpenState(" + aIndex + ");\n");
},
onCycleHeader: function (aColID, aDOMElement) {
dump("*** onCycleHeader(" + aColID + ", " + aDOMElement + ");\n");
},
onCycleCell: function (aIndex, aColID) {
dump("*** onCycleCell(" + aIndex + ", " + aColID + ");\n");
},
onSelectionChanged: function () {
dump("*** onSelectionChanged\n");
},
isEditable: function (aIndex, aColID) {
dump("*** isEditable(" + aIndex + ", " + aColID + ");\n");
return aColID == "NameColumn";
},
onSetCellText: function (aIndex, aColID, aValue) {
dump("*** onSetCellText(" + aIndex + ", " + aColID + ", " + aValue + ");\n");
},
onPerformAction: function (aAction) {
dump("*** onPerformAction(" + aAction + ");\n");
},
onPerformActionOnRow: function (aAction, aIndex) {
dump("*** onPerformActionOnRow(" + aAction + ", " + aIndex + ");\n");
},
onPerformActionOnCell: function (aAction, aIndex, aColID) {
dump("*** onPerformActionOnCell(" + aAction + ", " + aIndex + ", " + aColID + ");\n");
}
};
function Startup()
{
var tree = document.getElementById("tree");
var builder = tree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
builder.addObserver(bookmarksBuilderObserver);
}
function getItemRect(aEvent)
{
var tree = document.getElementById("tree-proper");
var obo = tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
var row = { };
var col = { };
var elt = { };
obo.getCellAt(aEvent.clientX, aEvent.clientY, row, col, elt);
var x = { };
var y = { };
var w = { };
var h = { };
var crp = { };
obo.getCoordsForCellItem(row.value, col.value, elt.value, x, y, w, h, crp);
dump("*** (x,y) = (" + x.value + "," + y.value + "); (w,h) = (" + w.value + "," + h.value + ");\n");
}
const kRDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
function createContextMenu (aEvent)
{
var tree = document.getElementById("tree-proper");
var obo = tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
var row = { };
var col = { };
var elt = { };
obo.getCellAt(aEvent.clientX, aEvent.clientY, row, col, elt);
dump("*** row.value = " + row.value + "\n")
var treeBody = document.getElementById("tree");
var rowResource = treeBody.builder.getResourceAtIndex(row.value);
const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFSvcIID = Components.interfaces.nsIRDFService;
const kRDFSvc = Components.classes[kRDFSvcContractID].getService(kRDFSvcIID);
var database = treeBody.database;
const krType = kRDFSvc.GetResource(kRDF_NS + "type");
var typeNode = kDatabase.GetTarget(rowResource, krType, true);
typeNode = typeNode.QueryInterface(Components.interfaces.nsIRDFResource);
dump("*** typeNode = " + typeNode.Value + "\n");
aEvent.preventBubble();
}
]]>
</script>
<popupset id="contextSet">
<popup id="bookmarkContextMenu" onpopupshowing="createContextMenu(event);"/>
</popupset>
<toolbox>
<toolbar>
<button class="button-toolbar-2" label="Foopy Noopy" oncommand="alert('hi');"/>
</toolbar>
</toolbox>
<stack>
<button label="Foopy Noopy" flex="1"/>
<bulletinboard flex="1">
<textbox value="NerpNerp" left="10" top="50" onblur="this.setAttribute('hidden','true');"/>
</bulletinboard>
</stack>
<tree flex="1" flags="dont-test-empty" id="tree-proper">
<treecols>
<treecol id="NameColumn"
class="treecol-header treecol-inset-header sortDirectionIndicator"
flex="1"
sort="rdf:http://home.netscape.com/NC-rdf#Name"
sortActive="true"
label="Name"
persist="width hidden sortActive sortDirection"
primary="true" />
<splitter class="tree-splitter"/>
<treecol id="URLColumn"
class="treecol-header treecol-inset-header sortDirectionIndicator"
flex="1"
sort="rdf:http://home.netscape.com/NC-rdf#URL"
label="Location"
persist="width hidden sortActive sortDirection" />
</treecols>
<treebody id="tree" datasources="rdf:bookmarks rdf:internetsearch rdf:files" flex="1"
onclick="getItemRect(event);" ref="NC:BookmarksRoot">
<template>
<treerow uri="rdf:*" properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type rdf:http://home.netscape.com/NC-rdf#loading">
<treecell ref="NameColumn"
label="rdf:http://home.netscape.com/NC-rdf#Name" />
<treecell ref="URLColumn"
label="rdf:http://home.netscape.com/NC-rdf#URL" />
</treerow>
</template>
</treebody>
</tree>
</window>

View File

@@ -1,116 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape 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/NPL/
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 Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
%brandDTD;
<!ENTITY % prefBookmarkDTD SYSTEM "chrome://communicator/locale/bookmarks/pref-bookmarks.dtd">
%prefBookmarkDTD;
]>
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="parent.initPanel('chrome://communicator/content/bookmarks/pref-bookmarks.xul');"
headertitle="&lHeader;">
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["enableAutoFile", "showExtendedData"];
var gCreateInFolder = "NC:NewBookmarkFolder";
function Startup ()
{
const kDisplay = document.getElementById("defaultFolder");
const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFSvcIID = Components.interfaces.nsIRDFService;
const kRDFSvc = Components.classes[kRDFSvcContractID].getService(kRDFSvcIID);
const kBMDS = kRDFSvc.GetDataSource("rdf:bookmarks");
const krDefaultFolder = kRDFSvc.GetResource("NC:NewBookmarkFolder");
const krType = kRDFSvc.GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
const krFolder = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#Folder");
const isFolder = kBMDS.HasAssertion(krDefaultFolder, krType, krFolder, true);
const krNameArc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#Name");
if (!isFolder) {
const krRoot = kRDFSvc.GetResource("NC:BookmarksRoot");
gCreateInFolder = "NC:BookmarksRoot";
}
var rName = kBMDS.GetTarget(isFolder ? krDefaultFolder : krRoot, krNameArc, true);
rName = rName.QueryInterface(Components.interfaces.nsIRDFLiteral);
kDisplay.value = rName.Value;
}
function chooseDefaultFolder ()
{
var rv = { selectedFolder: null };
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
"centerscreen,chrome,dialog=no,resizable=no",
null, null, gCreateInFolder, null, "selectFolder", rv);
if (rv && rv.selectedFolder) {
const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFSvcIID = Components.interfaces.nsIRDFService;
const kRDFSvc = Components.classes[kRDFSvcContractID].getService(kRDFSvcIID);
const kBMDS = kRDFSvc.GetDataSource("rdf:bookmarks");
const krDefaultFolder = kRDFSvc.GetResource(rv.selectedFolder);
const krNameArc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#Name");
rName = kBMDS.GetTarget(krDefaultFolder, krNameArc, true);
rName = rName.QueryInterface(Components.interfaces.nsIRDFLiteral);
document.getElementById("defaultFolder").value = rName.Value;
}
}
]]>
</script>
<groupbox>
<caption label="&filingBookmarks.label;"/>
<description flex="1">&autoFile.label;</description>
<hbox align="center">
<checkbox id="enableAutoFile" label="&enableAutoFile.label;"
preftype="bool" prefstring="browser.bookmarks.add_without_dialog"
prefattribute="checked"/>
</hbox>
<separator/>
<description flex="1">&defaultFolder.label;</description>
<hbox align="center">
<textbox readonly="true" id="defaultFolder" crop="right" flex="1"/>
<button label="&chooseDefaultFolder.label;" accesskey="&chooseDefaultFolder.accesskey;"
oncommand="chooseDefaultFolder();"
id="browser.bookmarks.choosefolder" preftype="bool"
prefstring="pref.browser.homepage.disable_button.choose_folder" prefattribute="disabled"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&extendedDataViews.label;"/>
<vbox align="start">
<description>&extendedDataExplanation.label;</description>
<checkbox id="showExtendedData" label="&showExtendedData.label;"
accesskey="&showExtendedData.accesskey;"
preftype="bool" prefstring="browser.bookmarks.show_extended_data"
prefattribute="checked"/>
</vbox>
</groupbox>
</page>

File diff suppressed because it is too large Load Diff

View File

@@ -1,258 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef bookmarksservice___h___
#define bookmarksservice___h___
#include "nsIRDFDataSource.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsIStreamListener.h"
#include "nsIRDFObserver.h"
#include "nsISupportsArray.h"
#include "nsIStringBundle.h"
#include "nsITimer.h"
#include "nsIRDFNode.h"
#include "nsIBookmarksService.h"
#include "nsString.h"
#include "nsIFileSpec.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsIIOService.h"
#include "nsICacheService.h"
#include "nsICacheSession.h"
#include "nsILocalFile.h"
#ifdef DEBUG
#ifdef XP_MAC
#include <Timer.h>
#endif
#endif
class nsBookmarksService : public nsIBookmarksService,
public nsIRDFDataSource,
public nsIRDFRemoteDataSource,
public nsIStreamListener,
public nsIRDFObserver,
public nsIObserver,
public nsSupportsWeakReference
{
protected:
nsIRDFDataSource* mInner;
nsCOMPtr<nsIRDFResource> busyResource;
nsCOMPtr<nsISupportsArray> mObservers;
nsCOMPtr<nsIStringBundle> mBundle;
nsCOMPtr<nsITimer> mTimer;
nsCOMPtr<nsIIOService> mNetService;
nsCOMPtr<nsICacheService> mCacheService;
nsCOMPtr<nsICacheSession> mCacheSession;
PRUint32 htmlSize;
PRInt32 mUpdateBatchNest;
nsString mPersonalToolbarName;
PRBool mBookmarksAvailable;
PRBool mDirty;
PRBool mBrowserIcons;
PRBool busySchedule;
// System Bookmark parsing
#ifdef XP_WIN
// @param aDirectory - Favorites Folder to import from.
// @param aParentResource - Folder into which to place imported
// Favorites.
nsresult ParseFavoritesFolder(nsIFile* aDirectory,
nsIRDFResource* aParentResource);
#elif XP_MAC
PRBool mIEFavoritesAvailable;
nsresult ReadFavorites();
#endif
#if defined(XP_WIN) || defined(XP_MAC)
void HandleSystemBookmarks(nsIRDFNode* aNode);
#endif
static void FireTimer(nsITimer* aTimer, void* aClosure);
nsresult ExamineBookmarkSchedule(nsIRDFResource *theBookmark, PRBool & examineFlag);
nsresult GetBookmarkToPing(nsIRDFResource **theBookmark);
nsresult GetBookmarksFile(nsFileSpec* aResult);
nsresult WriteBookmarks(nsFileSpec *bookmarksFile, nsIRDFDataSource *ds, nsIRDFResource *root);
nsresult WriteBookmarksContainer(nsIRDFDataSource *ds, nsOutputFileStream& strm, nsIRDFResource *container, PRInt32 level, nsISupportsArray *parentArray);
nsresult GetTextForNode(nsIRDFNode* aNode, nsString& aResult);
nsresult GetSynthesizedType(nsIRDFResource *aNode, nsIRDFNode **aType);
nsresult UpdateBookmarkLastModifiedDate(nsIRDFResource *aSource);
nsresult WriteBookmarkProperties(nsIRDFDataSource *ds, nsOutputFileStream& strm, nsIRDFResource *node,
nsIRDFResource *property, const char *htmlAttrib, PRBool isFirst);
PRBool CanAccept(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget);
nsresult getArgumentN(nsISupportsArray *arguments, nsIRDFResource *res, PRInt32 offset, nsIRDFNode **argValue);
nsresult insertBookmarkItem(nsIRDFResource *src, nsISupportsArray *aArguments, nsIRDFResource *objType);
nsresult deleteBookmarkItem(nsIRDFResource *src, nsISupportsArray *aArguments, PRInt32 parentArgIndex, nsIRDFResource *objType);
nsresult setFolderHint(nsIRDFResource *src, nsIRDFResource *objType);
nsresult getFolderViaHint(nsIRDFResource *src, PRBool fallbackFlag, nsIRDFResource **folder);
nsresult importBookmarks(nsISupportsArray *aArguments);
nsresult exportBookmarks(nsISupportsArray *aArguments);
nsresult ProcessCachedBookmarkIcon(nsIRDFResource* aSource, const PRUnichar *iconURL, nsIRDFNode** aTarget);
nsresult getResourceFromLiteralNode(nsIRDFNode *node, nsIRDFResource **res);
void AnnotateBookmarkSchedule(nsIRDFResource* aSource, PRBool scheduleFlag);
nsresult IsBookmarkedInternal(nsIRDFResource *bookmark, PRBool *isBookmarkedFlag);
nsresult ChangeURL(nsIRDFResource* aOldURL,
nsIRDFResource* aNewURL);
nsresult getLocaleString(const char *key, nsString &str);
nsresult CreateFolderWithDetails(const PRUnichar* aName,
nsIRDFResource* aParentFolder, PRInt32 aIndex,
nsIRDFResource** aResult, PRBool aIsGroup);
nsresult LoadBookmarks();
nsresult initDatasource();
// nsIStreamObserver methods:
NS_DECL_NSIREQUESTOBSERVER
// nsIStreamListener methods:
NS_DECL_NSISTREAMLISTENER
// nsIObserver methods:
NS_DECL_NSIOBSERVER
public:
nsBookmarksService();
virtual ~nsBookmarksService();
nsresult Init();
// nsISupports
NS_DECL_ISUPPORTS
// nsIBookmarksService
NS_DECL_NSIBOOKMARKSSERVICE
// nsIRDFDataSource
NS_IMETHOD GetURI(char* *uri);
NS_IMETHOD GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source) {
return mInner->GetSource(property, target, tv, source);
}
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsISimpleEnumerator** sources) {
return mInner->GetSources(property, target, tv, sources);
}
NS_IMETHOD GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFNode** target);
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsISimpleEnumerator** targets) {
return mInner->GetTargets(source, property, tv, targets);
}
NS_IMETHOD Assert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue);
NS_IMETHOD Unassert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget);
NS_IMETHOD Change(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget);
NS_IMETHOD Move(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget);
NS_IMETHOD HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion);
NS_IMETHOD AddObserver(nsIRDFObserver* aObserver);
NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver);
NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, PRBool *_retval);
NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, PRBool *_retval);
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsISimpleEnumerator** labels) {
return mInner->ArcLabelsIn(node, labels);
}
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsISimpleEnumerator** labels);
NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult);
NS_IMETHOD GetAllCommands(nsIRDFResource* source,
nsIEnumerator/*<nsIRDFResource>*/** commands);
NS_IMETHOD GetAllCmds(nsIRDFResource* source,
nsISimpleEnumerator/*<nsIRDFResource>*/** commands);
NS_IMETHOD IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments,
PRBool* aResult);
NS_IMETHOD DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments);
// nsIRDFRemoteDataSource
NS_DECL_NSIRDFREMOTEDATASOURCE
// nsIRDFObserver
NS_DECL_NSIRDFOBSERVER
};
#endif // bookmarksservice___h___

View File

@@ -1,121 +0,0 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = appcomps
LIBRARY_NAME = appcomps
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = application
REQUIRES = xpcom \
string \
content \
rdf \
necko \
necko2 \
nkcache \
intl \
locale \
mork \
widget \
dom \
downloadmanager \
alerts\
uriloader \
mimetype \
webbrowserpersist \
progressDlg \
pref \
docshell \
webshell \
appshell \
history \
$(NULL)
CPPSRCS = nsModule.cpp
ifdef MOZ_LDAP_XPCOM
REQUIRES += mozldap
DEFINES += -DMOZ_LDAP_XPCOM
endif
ifdef MOZ_PERF_METRICS
EXTRA_DSO_LIBS += mozutil_s
endif
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/$(LIB_PREFIX)autocomplete_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)bookmarks_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)directory_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)downloadmanager_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)history_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)appcompintl_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)related_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)search_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)urlbarhistory_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)timebomb_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)windowds_s.$(LIB_SUFFIX) \
$(NULL)
LOCAL_INCLUDES = \
-I$(srcdir)/../autocomplete/src \
-I$(srcdir)/../bookmarks/src \
-I$(srcdir)/../directory \
-I$(srcdir)/../download-manager/src \
-I$(srcdir)/../history/src \
-I$(srcdir)/../related/src \
-I$(srcdir)/../search/src \
-I$(srcdir)/../timebomb \
-I$(srcdir)/../urlbarhistory/src \
-I$(srcdir)/../windowds \
$(NULL)
ifeq ($(OS_ARCH),WINNT)
DEFINES += -DWIN32_LEAN_AND_MEAN
SHARED_LIBRARY_LIBS += \
$(DIST)/lib/$(LIB_PREFIX)urlwidgt_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)winhooks_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)alerts_s.$(LIB_SUFFIX) \
$(NULL)
OS_LIBS += ole32.lib shell32.lib
LOCAL_INCLUDES += \
-I$(srcdir)/../urlwidget \
-I$(srcdir)/../winhooks \
-I$(srcdir)/../alerts/src \
$(NULL)
endif
EXTRA_DSO_LDOPTS = \
$(MOZ_COMPONENT_LIBS) \
$(EXTRA_DSO_LIBS) \
$(MOZ_UNICHARUTIL_LIBS) \
$(MOZ_JS_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,112 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
MODULE=appcomps
LIBRARY_NAME=appcomps
MODULE_NAME=application
REQUIRES = xpcom \
string \
rdf \
necko \
necko2 \
nkcache \
intl \
locale \
mork \
widget \
dom \
pref \
docshell \
downloadmanager \
webshell \
timebomb \
bookmarks \
content \
history \
search \
alerts \
progressDlg \
related \
urlbarhistory \
uriloader \
mimetype \
mozldap \
webbrowserpersist \
appshell \
$(NULL)
LCFLAGS = -DWIN32_LEAN_AND_MEAN
!if !defined(DISABLE_LDAP)
LCFLAGS = $(LCFLAGS) -DMOZ_LDAP_XPCOM
!endif
CPP_OBJS= \
.\$(OBJDIR)\nsModule.obj \
$(NULL)
SUB_LIBRARIES= \
$(DIST)\lib\autocomplete_s.lib \
$(DIST)\lib\bookmarks_s.lib \
$(DIST)\lib\directory_s.lib \
$(DIST)\lib\downloadmanager_s.lib \
$(DIST)\lib\history_s.lib \
$(DIST)\lib\appcompintl_s.lib \
$(DIST)\lib\related_s.lib \
$(DIST)\lib\search_s.lib \
$(DIST)\lib\alerts_s.lib \
$(DIST)\lib\timebomb_s.lib \
$(DIST)\lib\urlbarhistory_s.lib \
$(DIST)\lib\urlwidgt_s.lib \
$(DIST)\lib\windowds_s.lib \
$(DIST)\lib\winhooks_s.lib \
$(NULL)
WIN_LIBS = \
ole32.lib \
shell32.lib \
$(NULL)
LLIBS= \
$(DIST)\lib\js3250.lib \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\unicharutil_s.lib \
$(LIBNSPR) \
$(NULL)
INCS = $(INCS) \
-I$(DEPTH)\xpfe\components\autocomplete\src \
-I$(DEPTH)\xpfe\components\bookmarks\src \
-I$(DEPTH)\xpfe\components\directory \
-I$(DEPTH)\xpfe\components\download-manager\src \
-I$(DEPTH)\xpfe\components\history\src \
-I$(DEPTH)\xpfe\components\related\src \
-I$(DEPTH)\xpfe\components\search\src \
-I$(DEPTH)\xpfe\components\timebomb \
-I$(DEPTH)\xpfe\components\urlbarhistory\src \
-I$(DEPTH)\xpfe\components\urlwidget \
-I$(DEPTH)\xpfe\components\windowds \
-I$(DEPTH)\xpfe\components\winhooks \
-I$(DEPTH)\xpfe\components\alerts\src \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,207 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIGenericFactory.h"
#include "nsICategoryManager.h"
#include "nsAutoComplete.h"
#include "nsBookmarksService.h"
#include "nsDirectoryViewer.h"
#include "nsDownloadManager.h"
#include "nsDownloadProxy.h"
#include "nsGlobalHistory.h"
#include "rdf.h"
#include "nsTimeBomb.h"
#include "nsLocalSearchService.h"
#include "nsInternetSearchService.h"
#include "nsRelatedLinksHandlerImpl.h"
#include "nsUrlbarHistory.h"
#include "nsXPIDLString.h"
#include "nsCharsetMenu.h"
#include "nsFontPackageHandler.h"
#include "nsWindowDataSource.h"
#if defined(XP_WIN)
#include "nsAlertsService.h"
#include "nsUrlWidget.h"
#include "nsWindowsHooks.h"
#endif // Windows
#if defined(MOZ_LDAP_XPCOM)
#include "nsLDAPAutoCompleteSession.h"
#endif
// Factory constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteItem)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteResults)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsBookmarksService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHTTPIndex, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDirectoryViewerFactory)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDownloadManager, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGlobalHistory, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(LocalSearchDataSource, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(InternetSearchDataSource, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(RelatedLinksHandlerImpl, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimeBomb)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlbarHistory)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontPackageHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowDataSource, Init)
#if defined(XP_WIN)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAlertsService)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUrlWidget, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsHooks)
#endif // Windows
#if defined(MOZ_LDAP_XPCOM)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPAutoCompleteSession)
#endif
static NS_METHOD
RegisterProc(nsIComponentManager *aCompMgr,
nsIFile *aPath,
const char *registryLocation,
const char *componentType,
const nsModuleComponentInfo *info)
{
nsresult rv;
nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
// add the MIME types layotu can handle to the handlers category.
// this allows users of layout's viewers (the docshell for example)
// to query the types of viewers layout can create.
nsXPIDLCString previous;
rv = catman->AddCategoryEntry("Gecko-Content-Viewers", "application/http-index-format",
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format",
PR_TRUE,
PR_TRUE,
getter_Copies(previous));
if (NS_FAILED(rv)) return rv;
rv = catman->AddCategoryEntry("Gecko-Content-Viewers", "application/http-index-format; x-view-type=view-source",
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format; x-view-type=view-source",
PR_TRUE,
PR_TRUE,
getter_Copies(previous));
return rv;
}
static NS_METHOD
UnregisterProc(nsIComponentManager *aCompMgr,
nsIFile *aPath,
const char *registryLocation,
const nsModuleComponentInfo *info)
{
nsresult rv;
nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = catman->DeleteCategoryEntry("Gecko-Content-Viewers",
"application/http-index-format", PR_TRUE);
if (NS_FAILED(rv)) return rv;
rv = catman->DeleteCategoryEntry("Gecko-Content-Viewers",
"application/http-index-format; x-view-type=view-source", PR_TRUE);
return rv;
}
static const nsModuleComponentInfo components[] = {
{ "AutoComplete Search Results", NS_AUTOCOMPLETERESULTS_CID, NS_AUTOCOMPLETERESULTS_CONTRACTID,
nsAutoCompleteResultsConstructor},
{ "AutoComplete Search Item", NS_AUTOCOMPLETEITEM_CID, NS_AUTOCOMPLETEITEM_CONTRACTID,
nsAutoCompleteItemConstructor},
{ "Bookmarks", NS_BOOKMARKS_SERVICE_CID, NS_BOOKMARKS_SERVICE_CONTRACTID,
nsBookmarksServiceConstructor },
{ "Bookmarks", NS_BOOKMARKS_SERVICE_CID, NS_BOOKMARKS_DATASOURCE_CONTRACTID,
nsBookmarksServiceConstructor },
{ "Directory Viewer", NS_DIRECTORYVIEWERFACTORY_CID,
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format",
nsDirectoryViewerFactoryConstructor, RegisterProc, UnregisterProc },
{ "Directory Viewer", NS_DIRECTORYVIEWERFACTORY_CID,
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format; x-view-type=view-source",
nsDirectoryViewerFactoryConstructor }, // Let the standard type do the registration
{ "Directory Viewer", NS_HTTPINDEX_SERVICE_CID, NS_HTTPINDEX_SERVICE_CONTRACTID,
nsHTTPIndexConstructor },
{ "Directory Viewer", NS_HTTPINDEX_SERVICE_CID, NS_HTTPINDEX_DATASOURCE_CONTRACTID,
nsHTTPIndexConstructor },
{ "Download Manager", NS_DOWNLOADMANAGER_CID, NS_DOWNLOADMANAGER_CONTRACTID,
nsDownloadManagerConstructor },
{ "Download", NS_DOWNLOAD_CID, NS_DOWNLOAD_CONTRACTID,
nsDownloadProxyConstructor },
{ "Global History", NS_GLOBALHISTORY_CID, NS_GLOBALHISTORY_CONTRACTID,
nsGlobalHistoryConstructor },
{ "Global History", NS_GLOBALHISTORY_CID, NS_GLOBALHISTORY_DATASOURCE_CONTRACTID,
nsGlobalHistoryConstructor },
{ "Global History", NS_GLOBALHISTORY_CID, NS_GLOBALHISTORY_AUTOCOMPLETE_CONTRACTID,
nsGlobalHistoryConstructor },
{ "Local Search", NS_RDFFINDDATASOURCE_CID,
NS_LOCALSEARCH_SERVICE_CONTRACTID, LocalSearchDataSourceConstructor },
{ "Local Search", NS_RDFFINDDATASOURCE_CID,
NS_LOCALSEARCH_DATASOURCE_CONTRACTID, LocalSearchDataSourceConstructor },
{ "Internet Search", NS_RDFSEARCHDATASOURCE_CID,
NS_INTERNETSEARCH_SERVICE_CONTRACTID, InternetSearchDataSourceConstructor },
{ "Internet Search", NS_RDFSEARCHDATASOURCE_CID,
NS_INTERNETSEARCH_DATASOURCE_CONTRACTID, InternetSearchDataSourceConstructor },
{ "Related Links Handler", NS_RELATEDLINKSHANDLER_CID, NS_RELATEDLINKSHANDLER_CONTRACTID,
RelatedLinksHandlerImplConstructor},
{ "Netscape TimeBomb", NS_TIMEBOMB_CID, NS_TIMEBOMB_CONTRACTID, nsTimeBombConstructor},
{ "nsUrlbarHistory", NS_URLBARHISTORY_CID,
NS_URLBARHISTORY_CONTRACTID, nsUrlbarHistoryConstructor },
{ "nsUrlbarHistory", NS_URLBARHISTORY_CID,
NS_URLBARAUTOCOMPLETE_CONTRACTID, nsUrlbarHistoryConstructor },
{ "nsCharsetMenu", NS_CHARSETMENU_CID,
NS_RDF_DATASOURCE_CONTRACTID_PREFIX NS_CHARSETMENU_PID,
NS_NewCharsetMenu },
{ "nsFontPackageHandler", NS_FONTPACKAGEHANDLER_CID,
"@mozilla.org/locale/default-font-package-handler;1",
nsFontPackageHandlerConstructor },
{ "nsWindowDataSource",
NS_WINDOWDATASOURCE_CID,
NS_RDF_DATASOURCE_CONTRACTID_PREFIX "window-mediator",
nsWindowDataSourceConstructor },
#if defined(XP_WIN)
{ NS_IURLWIDGET_CLASSNAME, NS_IURLWIDGET_CID, NS_IURLWIDGET_CONTRACTID,
nsUrlWidgetConstructor },
{ "nsAlertsService", NS_ALERTSSERVICE_CID, NS_ALERTSERVICE_CONTRACTID, nsAlertsServiceConstructor},
{ NS_IWINDOWSHOOKS_CLASSNAME, NS_IWINDOWSHOOKS_CID, NS_IWINDOWSHOOKS_CONTRACTID,
nsWindowsHooksConstructor },
#endif // Windows
#if defined(MOZ_LDAP_XPCOM)
{ "LDAP Autocomplete Session", NS_LDAPAUTOCOMPLETESESSION_CID,
"@mozilla.org/autocompleteSession;1?type=ldap",
nsLDAPAutoCompleteSessionConstructor },
#endif
};
NS_IMPL_NSGETMODULE(application, components)

View File

@@ -1,256 +0,0 @@
?StartAssignment@?$nsMdbPtr@VnsIMdbThumb@@@@QAEPAPAVnsIMdbThumb@@XZ ; 18413
??1?$nsMdbPtr@VnsIMdbRow@@@@QAE@XZ ; 18363
?assign_assuming_AddRef@nsCOMPtr_base@@IAEXPAVnsISupports@@@Z ; 12166
?ExamineBookmarkSchedule@nsBookmarksService@@IAEIPAVnsIRDFResource@@AAH@Z ; 10780
?HasAssertion@nsBookmarksService@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 10016
?HasAssertion@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 9886
?OpenDB@nsGlobalHistory@@IAEIXZ ; 9142
?FindRow@nsGlobalHistory@@IAEIIPBDPAPAVnsIMdbRow@@@Z ; 9142
?IsVisited@nsGlobalHistory@@UAGIPBDPAH@Z ; 8972
?HasAssertion@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 8845
?WriteBookmarkProperties@nsBookmarksService@@IAEIPAVnsIRDFDataSource@@AAVnsOutputFileStream@@PAVnsIRDFResource@@2PBDH@Z ; 2484
?HasAssertion@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 2326
?AddRef@nsBookmarksService@@UAGKXZ ; 1466
?Release@nsBookmarksService@@UAGKXZ ; 1459
?isSearchURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 1154
?isSearchCategoryURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 923
?isSearchCategoryEngineURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 921
?OnAssert@nsBookmarksService@@UAGIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@@Z ; 911
?isEngineURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 686
?GetTextForNode@nsBookmarksService@@IAEIPAVnsIRDFNode@@AAVnsString@@@Z ; 618
?GetData@InternetSearchDataSource@@IAEIPBGPBDI1AAVnsString@@@Z ; 589
?NotifyAssert@nsGlobalHistory@@IAEIPAVnsIRDFResource@@0PAVnsIRDFNode@@@Z ; 570
?updateAtom@BookmarkParser@@IAEIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@PAH@Z ; 536
?GetHostIndex@nsUrlbarHistory@@MAGIPBGPAH@Z ; 505
?GetTarget@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 437
?isSearchCommand@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 437
?QueryInterface@nsBookmarksService@@UAGIABUnsID@@PAPAX@Z ; 371
?GetFindUriPrefix@nsGlobalHistory@@IAEXABUsearchQuery@@HAAVnsACString@@@Z ; 324
?GetSources@nsBookmarksService@@UAGIPAVnsIRDFResource@@PAVnsIRDFNode@@HPAPAVnsISimpleEnumerator@@@Z ; 291
?QueryInterface@InternetSearchDataSource@@UAGIABUnsID@@PAPAX@Z ; 262
?ParseDate@BookmarkParser@@KAIPAVnsIRDFResource@@AAVnsString@@PAPAVnsIRDFNode@@@Z ; 256
?AddRef@nsAutoCompleteResults@@UAGKXZ ; 249
?HasArcOut@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0PAH@Z ; 248
?FindData@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@PAPAVnsIRDFLiteral@@@Z ; 247
?GetTargets@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 237
?AddRef@InternetSearchDataSource@@UAGKXZ ; 234
?GetTargets@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 230
?GetTargets@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 230
?GetTargets@nsBookmarksService@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 230
?Release@InternetSearchDataSource@@UAGKXZ ; 228
?Release@nsAutoCompleteItem@@UAGKXZ ; 225
?ArcLabelsIn@nsBookmarksService@@UAGIPAVnsIRDFNode@@PAPAVnsISimpleEnumerator@@@Z ; 181
?ParseLiteral@BookmarkParser@@KAIPAVnsIRDFResource@@AAVnsString@@PAPAVnsIRDFNode@@@Z ; 167
?GetTarget@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 165
??1searchTerm@@QAE@XZ ; 162
??0searchTerm@@QAE@PBDI0I0I0I@Z ; 162
?GetNow@nsGlobalHistory@@IAE_JXZ ; 162
?getEOL@BookmarkParser@@IAEHPBDHH@Z ; 153
?isWellknownContainerURI@nsHTTPIndex@@IAEHPAVnsIRDFResource@@@Z ; 153
?GetDestination@nsHTTPIndex@@IAEPADPAVnsIRDFResource@@@Z ; 153
?ProcessLine@BookmarkParser@@QAEIPAVnsIRDFContainer@@PAVnsIRDFResource@@AAV?$nsCOMPtr@VnsIRDFResource@@@@ABVnsString@@AAV5@AAH5@Z ; 152
?DecodeBuffer@BookmarkParser@@QAEIAAVnsString@@PADI@Z ; 152
?AddRef@nsGlobalHistory@@UAGKXZ ; 132
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IAB_J@Z ; 131
?Release@nsGlobalHistory@@UAGKXZ ; 128
?HasArcOut@nsBookmarksService@@UAGIPAVnsIRDFResource@@0PAH@Z ; 124
?HasArcOut@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0PAH@Z ; 122
?HasArcOut@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0PAH@Z ; 122
?QueryInterface@nsAutoCompleteItem@@UAGIABUnsID@@PAPAX@Z ; 118
?OnUnassert@nsBookmarksService@@UAGIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@@Z ; 115
?ParseResource@BookmarkParser@@KAIPAVnsIRDFResource@@AAVnsString@@PAPAVnsIRDFNode@@@Z ; 114
?ParseBookmarkInfo@BookmarkParser@@IAEIPAUBookmarkField@1@HABVnsString@@ABV?$nsCOMPtr@VnsIRDFContainer@@@@PAVnsIRDFResource@@AAV?$nsCOMPtr@VnsIRDFResource@@@@@Z ; 114
?Unescape@RelatedLinksStreamListener@@QAEIAAVnsString@@@Z ; 114
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPA_J@Z ; 112
?FireTimer@nsBookmarksService@@KAXPAVnsITimer@@PAX@Z ; 110
?GetBookmarkToPing@nsBookmarksService@@IAEIPAPAVnsIRDFResource@@@Z ; 110
?QueryInterface@nsGlobalHistory@@UAGIABUnsID@@PAPAX@Z ; 105
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPBD@Z ; 100
?ParseHeaderEnd@BookmarkParser@@IAEIABVnsString@@@Z ; 96
?GetLastCharset@nsBookmarksService@@UAGIPBDPAPAG@Z ; 91
?SetPageTitle@nsGlobalHistory@@UAGIPBDPBG@Z ; 89
?GetItems@nsAutoCompleteResults@@UAGIPAPAVnsISupportsArray@@@Z ; 89
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IAAVnsAString@@@Z ; 87
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPBG@Z ; 87
?NotifyChange@nsGlobalHistory@@IAEIPAVnsIRDFResource@@0PAVnsIRDFNode@@1@Z ; 84
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IAAVnsACString@@@Z ; 82
?AddPage@nsGlobalHistory@@UAGIPBD@Z ; 81
?AddPageToDatabase@nsGlobalHistory@@IAEIPBD_J@Z ; 81
?SaveLastPageVisited@nsGlobalHistory@@IAEIPBD@Z ; 81
?do_GetService@@YA?BVnsGetServiceByCID@@ABUnsID@@PAI@Z ; 81
?NotifyFindAssertions@nsGlobalHistory@@IAEIPAVnsIRDFResource@@PAVnsIMdbRow@@@Z ; 81
?SetDirty@nsGlobalHistory@@IAEIXZ ; 81
?GetTarget@nsBookmarksService@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 78
?QueryInterface@nsAutoCompleteResults@@UAGIABUnsID@@PAPAX@Z ; 76
?Release@InternetSearchContext@@UAGKXZ ; 62
?AddRef@InternetSearchContext@@UAGKXZ ; 62
?GetValue@nsAutoCompleteItem@@UAGIPAPAG@Z ; 58
?updateAtom@InternetSearchDataSource@@IAEIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@PAH@Z ; 58
?SetURLToHiddenControl@nsUrlWidget@@UAGIPBDPAVnsIDOMWindowInternal@@@Z ; 50
?FindInternetSearchResults@InternetSearchDataSource@@UAGIPBDPAH@Z ; 50
?UpdateBookmarkLastVisitedDate@nsBookmarksService@@UAGIPBDPBG@Z ; 50
?AddNewPageToDatabase@nsGlobalHistory@@IAEIPBD_JPAPAVnsIMdbRow@@@Z ; 50
?do_GetIOService@@YA?BVnsGetServiceByCID@@PAI@Z ; 48
?NS_NewURI@@YAIPAPAVnsIURI@@PBDPAV1@PAVnsIIOService@@@Z ; 48
?ArcLabelsOut@nsBookmarksService@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 45
?QueryInterface@InternetSearchContext@@UAGIABUnsID@@PAPAX@Z ; 44
?ArcLabelsOut@nsHTTPIndex@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 43
??_GnsArrayEnumerator@@UAEPAXI@Z ; 43
?ArcLabelsOut@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 43
?ArcLabelsOut@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 43
?isSearchResultFiltered@InternetSearchDataSource@@IAEHABVnsString@@@Z ; 42
?ConvertEntities@InternetSearchDataSource@@IAEIAAVnsString@@HHH@Z ; 42
?OnDataAvailable@InternetSearchDataSource@@UAGIPAVnsIRequest@@PAVnsISupports@@PAVnsIInputStream@@II@Z ; 38
?GetUnicodeDecoder@InternetSearchContext@@UAGIPAPAVnsIUnicodeDecoder@@@Z ; 38
?AppendUnicodeBytes@InternetSearchContext@@UAGIPBGH@Z ; 37
?GetDefaultItemIndex@nsAutoCompleteResults@@UAGIPAH@Z ; 36
?AddRef@nsUrlbarHistory@@UAGKXZ ; 32
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IH@Z ; 31
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPAH@Z ; 31
?AddExistingPageToDatabase@nsGlobalHistory@@IAEIPAVnsIMdbRow@@_JPA_JPAH@Z ; 31
?WriteBookmarksContainer@nsBookmarksService@@IAEIPAVnsIRDFDataSource@@AAVnsOutputFileStream@@PAVnsIRDFResource@@HPAVnsISupportsArray@@@Z ; 30
?GetSearchEngineToPing@InternetSearchDataSource@@IAEIPAPAVnsIRDFResource@@AAVnsCString@@@Z ; 28
?FireTimer@InternetSearchDataSource@@KAXPAVnsITimer@@PAX@Z ; 28
?Flush@nsGlobalHistory@@UAGIXZ ; 26
?SetValue@nsAutoCompleteItem@@UAGIPBG@Z ; 26
?Commit@nsGlobalHistory@@IAEIW4eCommitType@1@@Z ; 26
?Sync@nsGlobalHistory@@IAEXXZ ; 25
?fireSyncTimer@nsGlobalHistory@@KAXPAVnsITimer@@PAX@Z ; 25
??1RegistryEntry@@QAE@XZ ; 24
??_EnsString@@UAEPAXI@Z ; 20
?SetDefaultItemIndex@nsAutoCompleteResults@@UAGIH@Z ; 17
?OnChange@nsBookmarksService@@UAGIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@2@Z ; 16
?Release@nsUrlbarHistory@@UAGKXZ ; 16
?Refresh@nsBookmarksService@@UAGIH@Z ; 16
?Parse@BookmarkParser@@QAEIPAVnsIRDFResource@@0@Z ; 15
??1nsAutoCompleteItem@@UAE@XZ ; 15
??_EnsAutoCompleteItem@@UAEPAXI@Z ; 15
??0nsAutoCompleteItem@@QAE@XZ ; 15
?currentSetting@RegistryEntry@@QBE?AVnsCString@@XZ ; 13
??BBoolRegistryEntry@@QAEPAXXZ ; 13
??0RegistryEntry@@QAE@PAUHKEY__@@PBD11@Z ; 13
?valueNameArg@RegistryEntry@@QBEPBDXZ ; 13
??0nsAutoCompleteResults@@QAE@XZ ; 12
??1nsAutoCompleteResults@@UAE@XZ ; 12
?AddRef@nsHTTPIndex@@UAGKXZ ; 12
?QueryInterface@nsUrlbarHistory@@UAGIABUnsID@@PAPAX@Z ; 12
??_EnsAutoCompleteResults@@UAEPAXI@Z ; 12
?GetTarget@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 12
??0ProtocolRegistryEntry@@QAE@PBD@Z ; 11
?Release@LocalSearchDataSource@@UAGKXZ ; 10
?Release@nsWindowsHooks@@UAGKXZ ; 10
?Release@nsUrlWidget@@UAGKXZ ; 10
?QueryInterface@nsUrlWidget@@UAGIABUnsID@@PAPAX@Z ; 10
?QueryInterface@nsWindowsHooks@@UAGIABUnsID@@PAPAX@Z ; 10
?CheckItemAvailability@nsUrlbarHistory@@MAGIPBGPAVnsIAutoCompleteResults@@PAH@Z ; 9
?AddObserver@InternetSearchDataSource@@UAGIPAVnsIRDFObserver@@@Z ; 8
?SetParam@nsAutoCompleteItem@@UAGIPAVnsISupports@@@Z ; 8
?Release@nsHTTPIndex@@UAGKXZ ; 8
?NS_GetSpecialDirectory@@YAIPBDPAPAVnsIFile@@@Z ; 8
?SaveEngineInfoIntoGraph@InternetSearchDataSource@@IAEIPAVnsIFile@@0PBG1H@Z ; 7
?GetContextType@InternetSearchContext@@UAGIPAI@Z ; 6
?MapEncoding@InternetSearchDataSource@@IAEIABVnsString@@AAV2@@Z ; 6
??0InternetSearchContext@@QAE@IPAVnsIRDFResource@@0PAVnsIUnicodeDecoder@@PBG@Z ; 6
??1InternetSearchContext@@UAE@XZ ; 6
?OnStopRequest@InternetSearchDataSource@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 6
?AddObserver@LocalSearchDataSource@@UAGIPAVnsIRDFObserver@@@Z ; 6
?AddObserver@nsBookmarksService@@UAGIPAVnsIRDFObserver@@@Z ; 6
?updateDataHintsInGraph@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@PBG@Z ; 6
??_EInternetSearchContext@@UAEPAXI@Z ; 6
?ReadFileContents@InternetSearchDataSource@@IAEIABVnsFileSpec@@AAVnsString@@@Z ; 6
?NS_OpenURI@@YAIPAPAVnsIChannel@@PAVnsIURI@@PAVnsIIOService@@PAVnsILoadGroup@@PAVnsIInterfaceRequestor@@I@Z ; 6
??1FileTypeRegistryEntry@@QAE@XZ ; 6
?NS_NewInternetSearchContext@@YAIIPAVnsIRDFResource@@0PAVnsIUnicodeDecoder@@PBGPAPAVnsIInternetSearchContext@@@Z ; 6
?OnStartLookup@nsUrlbarHistory@@UAGIPBGPAVnsIAutoCompleteResults@@PAVnsIAutoCompleteListener@@@Z ; 5
?VerifyAndCreateEntry@nsUrlbarHistory@@MAGIPBGPAGPAVnsIAutoCompleteResults@@@Z ; 5
?GetBufferConst@InternetSearchContext@@UAGIPAPBG@Z ; 5
?SearchCache@nsUrlbarHistory@@MAGIPBGPAVnsIAutoCompleteResults@@@Z ; 5
?OnStartRequest@InternetSearchDataSource@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 4
?Truncate@InternetSearchContext@@UAGIXZ ; 4
?GetEngine@InternetSearchContext@@UAGIPAPAVnsIRDFResource@@@Z ; 4
?AddObserver@nsHTTPIndex@@UAGIPAVnsIRDFObserver@@@Z ; 4
?OnAutoComplete@nsUrlbarHistory@@UAGIPBGPAVnsIAutoCompleteResults@@PAVnsIAutoCompleteListener@@@Z ; 3
?Release@nsTimeBomb@@UAGKXZ ; 3
?DoSearch@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@0ABVnsString@@1@Z ; 3
?QueryInterface@nsHTTPIndex@@UAGIABUnsID@@PAPAX@Z ; 3
?validateEngine@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@@Z ; 3
?QueryInterface@LocalSearchDataSource@@UAGIABUnsID@@PAPAX@Z ; 3
?ParseHTML@InternetSearchDataSource@@IAEIPAVnsIURI@@PAVnsIRDFResource@@1PBG@Z ; 3
?Stop@InternetSearchDataSource@@UAGIXZ ; 3
?FindShortcut@nsBookmarksService@@UAGIPBGPAPAD@Z ; 3
?GetBookmarksFile@nsBookmarksService@@IAEIPAVnsFileSpec@@@Z ; 3
?GetSource@nsBookmarksService@@UAGIPAVnsIRDFResource@@PAVnsIRDFNode@@HPAPAV2@@Z ; 3
?GetParent@InternetSearchContext@@UAGIPAPAVnsIRDFResource@@@Z ; 3
?GetNumInterpretSections@InternetSearchDataSource@@IAEIPBGAAI@Z ; 3
?GetSearchFolder@InternetSearchDataSource@@IAEIPAPAVnsIFile@@@Z ; 3
?RememberLastSearchText@InternetSearchDataSource@@UAGIPBG@Z ; 3
?ClearResults@InternetSearchDataSource@@UAGIH@Z ; 3
?webSearchFinalize@InternetSearchDataSource@@IAEIPAVnsIChannel@@PAVnsIInternetSearchContext@@@Z ; 3
?GetInputs@InternetSearchDataSource@@IAEIPBGAAVnsString@@ABV2@1@Z ; 3
?Flush@nsBookmarksService@@UAGIXZ ; 2
?CheckSettings@nsWindowsHooks@@UAGIPAVnsIDOMWindowInternal@@@Z ; 2
?saveContents@InternetSearchDataSource@@IAEIPAVnsIChannel@@PAVnsIInternetSearchContext@@I@Z ; 2
?RemoveObserver@InternetSearchDataSource@@UAGIPAVnsIRDFObserver@@@Z ; 2
?NS_NewLoadGroup@@YAIPAPAVnsILoadGroup@@PAVnsIStreamObserver@@@Z ; 2
?WriteBookmarks@nsBookmarksService@@IAEIPAVnsFileSpec@@PAVnsIRDFDataSource@@PAVnsIRDFResource@@@Z ; 2
?getLocaleString@nsBookmarksService@@IAEIPBDAAVnsString@@@Z ; 2
?GetBufferLength@InternetSearchContext@@UAGIPAH@Z ; 2
??1nsWindowsHooksSettings@@UAE@XZ ; 1
??1nsUrlbarHistory@@MAE@XZ ; 1
??1nsUrlWidget@@UAE@XZ ; 1
?Init@nsTimeBomb@@UAGIXZ ; 1
?CreateAnonymousResource@BookmarkParser@@KAIPAV?$nsCOMPtr@VnsIRDFResource@@@@@Z ; 1
?GetURI@nsBookmarksService@@UAGIPAPAD@Z ; 1
?validateEngineNow@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@@Z ; 1
?DeferredInit@InternetSearchDataSource@@QAGIXZ ; 1
??_EnsUrlbarHistory@@MAEPAXI@Z ; 1
??0nsGlobalHistory@@QAE@XZ ; 1
?GetURI@LocalSearchDataSource@@UAGIPAPAD@Z ; 1
??0InternetSearchDataSource@@QAE@XZ ; 1
?GetSettings@nsWindowsHooks@@MAGIPAPAVnsWindowsHooksSettings@@@Z ; 1
?Init@nsBookmarksService@@QAEIXZ ; 1
?Init@LocalSearchDataSource@@QAEIXZ ; 1
?GetSearchEngineList@InternetSearchDataSource@@IAEIPAVnsIFile@@H@Z ; 1
?Release@nsWindowsHooksSettings@@UAGKXZ ; 1
?CreateTokens@nsGlobalHistory@@IAEIXZ ; 1
??0nsUrlWidget@@QAE@XZ ; 1
?AppendBytes@InternetSearchContext@@UAGIPBDH@Z ; 1
?GetInt64ForPref@nsTimeBomb@@IAEIPBDPA_J@Z ; 1
?Init@nsGlobalHistory@@QAGIXZ ; 1
?Init@nsHTTPIndex@@QAEIXZ ; 1
?GetFirstLaunch@nsTimeBomb@@UAGIPA_J@Z ; 1
??0nsWindowsHooksSettings@@QAE@XZ ; 1
??0BookmarkParser@@QAE@XZ ; 1
??_EnsWindowsHooksSettings@@UAEPAXI@Z ; 1
?GetURI@nsHTTPIndex@@UAGIPAPAD@Z ; 1
??_GnsUrlWidget@@UAEPAXI@Z ; 1
??_EnsWindowsHooks@@UAEPAXI@Z ; 1
?CommonInit@nsHTTPIndex@@IAEIXZ ; 1
?GetURI@InternetSearchDataSource@@UAGIPAPAD@Z ; 1
??0nsUrlbarHistory@@QAE@XZ ; 1
??1BookmarkParser@@QAE@XZ ; 1
??1nsTimeBomb@@UAE@XZ ; 1
??0nsHTTPIndex@@QAE@XZ ; 1
?GetCategoryList@InternetSearchDataSource@@IAEIXZ ; 1
??_GnsTimeBomb@@UAEPAXI@Z ; 1
?GetCategoryDataSource@InternetSearchDataSource@@UAGIPAPAVnsIRDFDataSource@@@Z ; 1
?CheckHostnameEntries@nsGlobalHistory@@IAEIXZ ; 1
??0nsTimeBomb@@QAE@XZ ; 1
_NSGetModule ; 1
??0LocalSearchDataSource@@QAE@XZ ; 1
?Init@InternetSearchDataSource@@QAGIXZ ; 1
?ParseBookmarkSeparator@BookmarkParser@@IAEIABVnsString@@ABV?$nsCOMPtr@VnsIRDFContainer@@@@@Z ; 1
?setFolderHint@BookmarkParser@@IAEIPAVnsIRDFResource@@0@Z ; 1
?Init@BookmarkParser@@QAEIPAVnsFileSpec@@PAVnsIRDFDataSource@@ABVnsString@@@Z ; 1
??1nsWindowsHooks@@UAE@XZ ; 1
?GetEnabled@nsTimeBomb@@UAGIPAH@Z ; 1
?QueryInterface@nsTimeBomb@@UAGIABUnsID@@PAPAX@Z ; 1
?CheckWithUI@nsTimeBomb@@UAGIPAH@Z ; 1
?AddSearchEngine@InternetSearchDataSource@@UAGIPBD0PBG1@Z ; 1
?OpenExistingFile@nsGlobalHistory@@IAEIPAVnsIMdbFactory@@PBD@Z ; 1
??0nsWindowsHooks@@QAE@XZ ; 1
??0nsBookmarksService@@QAE@XZ ; 1
?ParseMetaTag@BookmarkParser@@IAEIABVnsString@@PAPAVnsIUnicodeDecoder@@@Z ; 1
?GetURI@nsGlobalHistory@@UAGIPAPAD@Z ; 1
?ReadBookmarks@nsBookmarksService@@UAGIXZ ; 1
?Init@nsUrlWidget@@QAEIXZ ; 1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff