зеркало из https://github.com/mozilla/pjs.git
Add a mozstorage-based FormHistory implementation, with an importer that uses the MorkReader class. Stop building Mork if building Places. Bug 324170, r=brettw, bsmedberg.
This commit is contained in:
Родитель
abdac7eba1
Коммит
0ff9d4e39d
|
@ -160,7 +160,7 @@ Sanitizer.prototype = {
|
|||
{
|
||||
var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"]
|
||||
.getService(Components.interfaces.nsIFormHistory);
|
||||
return formHistory.rowCount != 0;
|
||||
return formHistory.hasEntries;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -137,6 +137,8 @@ MOZ_PROFILESHARING = @MOZ_PROFILESHARING@
|
|||
MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
|
||||
MOZ_PLACES = @MOZ_PLACES@
|
||||
MOZ_STORAGE = @MOZ_STORAGE@
|
||||
MOZ_MORK = @MOZ_MORK@
|
||||
MOZ_MORKREADER = @MOZ_MORKREADER@
|
||||
MOZ_NO_XPCOM_OBSOLETE = @MOZ_NO_XPCOM_OBSOLETE@
|
||||
MOZ_NO_FAST_LOAD = @MOZ_NO_FAST_LOAD@
|
||||
NS_PRINTING = @NS_PRINTING@
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
16
configure.in
16
configure.in
|
@ -4156,6 +4156,8 @@ MOZ_LIBART_CFLAGS=
|
|||
MOZ_LIBART_LIBS=
|
||||
MOZ_MAIL_NEWS=
|
||||
MOZ_MATHML=1
|
||||
MOZ_MORK=1
|
||||
MOZ_MORKREADER=
|
||||
MOZ_AUTH_EXTENSION=1
|
||||
MOZ_NO_ACTIVEX_SUPPORT=1
|
||||
MOZ_NO_XPCOM_OBSOLETE=
|
||||
|
@ -5476,6 +5478,8 @@ MOZ_ARG_ENABLE_BOOL(places,
|
|||
MOZ_PLACES= )
|
||||
if test -n "$MOZ_PLACES"; then
|
||||
AC_DEFINE(MOZ_PLACES)
|
||||
MOZ_MORK=
|
||||
MOZ_MORKREADER=1
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
|
@ -6937,6 +6941,18 @@ if test "$MOZ_V1_STRING_ABI"; then
|
|||
AC_DEFINE(MOZ_V1_STRING_ABI)
|
||||
fi
|
||||
|
||||
dnl Only build Mork if it's required
|
||||
AC_SUBST(MOZ_MORK)
|
||||
if test "$MOZ_MORK"; then
|
||||
AC_DEFINE(MOZ_MORK)
|
||||
fi
|
||||
|
||||
dnl Build the lightweight Mork reader if required
|
||||
AC_SUBST(MOZ_MORKREADER)
|
||||
if test "$MOZ_MORKREADER"; then
|
||||
AC_DEFINE(MOZ_MORKREADER)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
if test "$MOZ_DEBUG" || test "$NS_TRACE_MALLOC"; then
|
||||
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS=
|
||||
|
|
|
@ -42,9 +42,10 @@ VPATH = @srcdir@
|
|||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifdef MOZ_MORK
|
||||
DIRS = mdb mork
|
||||
|
||||
ifdef MOZ_PLACES
|
||||
endif
|
||||
ifdef MOZ_MORKREADER
|
||||
DIRS += morkreader
|
||||
endif
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ MODULE = morkreader
|
|||
LIBRARY_NAME = morkreader_s
|
||||
MOZILLA_INTERNAL_API = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
EXPORT_LIBRARY = 1
|
||||
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
|
|
|
@ -55,19 +55,26 @@ REQUIRES = xpcom \
|
|||
string \
|
||||
dom \
|
||||
layout \
|
||||
mork \
|
||||
unicharutil \
|
||||
toolkitcomps \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsAutoCompleteController.cpp \
|
||||
nsAutoCompleteMdbResult.cpp \
|
||||
nsAutoCompleteSimpleResult.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_MORK
|
||||
REQUIRES += mork
|
||||
CPPSRCS += nsAutoCompleteMdbResult.cpp
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_MORKREADER
|
||||
EXTRA_DSO_LDOPTS += $(DIST)/lib/$(LIB_PREFIX)morkreader_s.$(LIB_SUFFIX)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -40,11 +40,12 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAutoCompleteController.h"
|
||||
#ifdef MOZ_MORK
|
||||
#include "nsAutoCompleteMdbResult.h"
|
||||
#endif
|
||||
#include "nsAutoCompleteSimpleResult.h"
|
||||
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsIAutoCompleteResultTypes.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIAtomService.h"
|
||||
|
@ -1274,7 +1275,9 @@ nsAutoCompleteController::RowIndexToSearch(PRInt32 aRowIndex, PRInt32 *aSearchIn
|
|||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteController)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteSimpleResult)
|
||||
#ifdef MOZ_MORK
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteMdbResult)
|
||||
#endif
|
||||
|
||||
static const nsModuleComponentInfo components[] =
|
||||
{
|
||||
|
@ -1288,10 +1291,12 @@ static const nsModuleComponentInfo components[] =
|
|||
NS_AUTOCOMPLETESIMPLERESULT_CONTRACTID,
|
||||
nsAutoCompleteSimpleResultConstructor },
|
||||
|
||||
#ifdef MOZ_MORK
|
||||
{ "AutoComplete Mdb Result",
|
||||
NS_AUTOCOMPLETEMDBRESULT_CID,
|
||||
NS_AUTOCOMPLETEMDBRESULT_CONTRACTID,
|
||||
nsAutoCompleteMdbResultConstructor },
|
||||
#endif
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(tkAutoCompleteModule, components)
|
||||
|
|
|
@ -156,7 +156,12 @@ NS_IMETHODIMP
|
|||
nsAutoCompleteSimpleResult::RemoveValueAt(PRInt32 aRowIndex,
|
||||
PRBool aRemoveFromDb)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
NS_ENSURE_TRUE(aRowIndex >= 0 && aRowIndex < mValues.Count(),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
mValues.RemoveStringAt(aRowIndex);
|
||||
mComments.RemoveStringAt(aRowIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,6 @@ REQUIRES = \
|
|||
widget \
|
||||
layout \
|
||||
dom \
|
||||
mork \
|
||||
pref \
|
||||
rdf \
|
||||
intl \
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
#define NS_FORMHISTORY_CONTRACTID \
|
||||
"@mozilla.org/satchel/form-history;1"
|
||||
|
||||
#define NS_FORMHISTORYIMPORTER_CONTRACTID \
|
||||
"@mozilla.org/satchel/form-history-importer;1"
|
||||
|
||||
#define NS_FORMFILLCONTROLLER_CONTRACTID \
|
||||
"@mozilla.org/satchel/form-fill-controller;1"
|
||||
|
||||
|
@ -100,6 +103,10 @@
|
|||
#define NS_FORMHISTORY_CID \
|
||||
{ 0xa2059c0e, 0x5a58, 0x4c55, { 0xab, 0x7c, 0x26, 0xf0, 0x55, 0x75, 0x46, 0xef } }
|
||||
|
||||
// {db340cc2-7f50-4ea3-8427-f529daf6dc87}
|
||||
#define NS_FORMHISTORYIMPORTER_CID \
|
||||
{ 0xdb340cc2, 0x7f50, 0x4ea3, { 0x84, 0x27, 0xf5, 0x29, 0xda, 0xf6, 0xdc, 0x87 } }
|
||||
|
||||
// {59648a91-5a60-4122-8ff2-54b839c84aed}
|
||||
#define NS_GLOBALHISTORY_CID \
|
||||
{ 0x59648a91, 0x5a60, 0x4122, { 0x8f, 0xf2, 0x54, 0xb8, 0x39, 0xc8, 0x4a, 0xed} }
|
||||
|
|
|
@ -36,39 +36,36 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, uuid(fa5a871d-29f5-489e-aaa4-c266def52b79)]
|
||||
/**
|
||||
* The nsIFormHistory object is a service which holds a set of name/value
|
||||
* pairs. The names correspond to form field names, and the values correspond
|
||||
* to values the user has submitted. So, several values may exist for a single
|
||||
* name.
|
||||
*
|
||||
* Note: this interface provides no means to access stored values.
|
||||
* Stored values are used by the FormFillController to generate
|
||||
* autocomplete matches.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(a61f0a62-ae0a-4382-b474-d259442ca80c)]
|
||||
interface nsIFormHistory : nsISupports
|
||||
{
|
||||
/**
|
||||
* The total number of rows in the form history.
|
||||
* Returns true if the form history has any entries.
|
||||
*/
|
||||
readonly attribute unsigned long rowCount;
|
||||
readonly attribute boolean hasEntries;
|
||||
|
||||
/**
|
||||
* Gets the name and value at a position in the form history.
|
||||
*/
|
||||
void getEntryAt(in unsigned long index, out AString name, out AString value);
|
||||
|
||||
/**
|
||||
* Gets just the name at a position in the form history.
|
||||
*/
|
||||
void getNameAt(in unsigned long index, out AString name);
|
||||
|
||||
/**
|
||||
* Gets just the value at a position in the form history.
|
||||
*/
|
||||
void getValueAt(in unsigned long index, out AString value);
|
||||
|
||||
/**
|
||||
* Appends a name and value pair to the end of the form history.
|
||||
* Adds a name and value pair to the form history.
|
||||
*/
|
||||
void addEntry(in AString name, in AString value);
|
||||
|
||||
/**
|
||||
* Removes the entry at a position.
|
||||
* Removes a name and value pair from the form history.
|
||||
*/
|
||||
void removeEntryAt(in unsigned long index);
|
||||
void removeEntry(in AString name, in AString value);
|
||||
|
||||
/**
|
||||
* Removes all entries that are paired with a name.
|
||||
|
@ -90,3 +87,21 @@ interface nsIFormHistory : nsISupports
|
|||
*/
|
||||
boolean entryExists(in AString name, in AString value);
|
||||
};
|
||||
|
||||
/**
|
||||
* nsIFormHistoryImporter is an interface for importing a Mork formhistory.dat
|
||||
* file into the new form history storage.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(9e811188-6a5b-4d96-a92d-1bac66a41898)]
|
||||
interface nsIFormHistoryImporter : nsISupports
|
||||
{
|
||||
/**
|
||||
* Import the given Mork form history file.
|
||||
* @param file The Mork form history file to import
|
||||
* @param history A reference to the nsIFormHistory. This is
|
||||
* supplied since the importer is invoked during
|
||||
* form history initialization.
|
||||
*/
|
||||
void importFormHistory(in nsIFile file, in nsIFormHistory formHistory);
|
||||
};
|
||||
|
|
|
@ -64,7 +64,6 @@ REQUIRES = \
|
|||
content \
|
||||
view \
|
||||
locale \
|
||||
mork \
|
||||
unicharutil \
|
||||
intl \
|
||||
pref \
|
||||
|
@ -73,10 +72,25 @@ REQUIRES = \
|
|||
$(NULL)
|
||||
|
||||
CPPSRCS = nsFormFillController.cpp \
|
||||
nsFormHistory.cpp \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = -I$(srcdir)/../../passwordmgr/base
|
||||
ifdef MOZ_STORAGE
|
||||
REQUIRES += storage
|
||||
CPPSRCS += nsStorageFormHistory.cpp
|
||||
ifdef MOZ_MORKREADER
|
||||
REQUIRES += morkreader
|
||||
endif
|
||||
else # MOZ_STORAGE
|
||||
ifdef MOZ_MORK
|
||||
REQUIRES += mork
|
||||
CPPSRCS += nsFormHistory.cpp
|
||||
endif
|
||||
endif # MOZ_STORAGE
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../../passwordmgr/base \
|
||||
-I$(srcdir)/../../build \
|
||||
$(NULL)
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)passwordmgr_s.$(LIB_SUFFIX) \
|
||||
|
@ -91,3 +105,8 @@ EXTRA_DSO_LDOPTS += \
|
|||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_MORKREADER
|
||||
EXTRA_DSO_LDOPTS += $(DIST)/lib/$(LIB_PREFIX)morkreader_s.$(LIB_SUFFIX)
|
||||
endif
|
||||
|
||||
|
|
|
@ -39,8 +39,13 @@
|
|||
|
||||
#include "nsFormFillController.h"
|
||||
|
||||
#ifdef MOZ_STORAGE
|
||||
#include "nsStorageFormHistory.h"
|
||||
#include "nsIAutoCompleteSimpleResult.h"
|
||||
#elif defined(MOZ_MORK)
|
||||
#include "nsFormHistory.h"
|
||||
#include "nsIAutoCompleteResultTypes.h"
|
||||
#endif
|
||||
#include "nsString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
@ -489,17 +494,27 @@ nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAStrin
|
|||
nsIAutoCompleteResult *aPreviousResult, nsIAutoCompleteObserver *aListener)
|
||||
{
|
||||
nsCOMPtr<nsIAutoCompleteResult> result;
|
||||
nsCOMPtr<nsIAutoCompleteMdbResult> mdbResult = do_QueryInterface(aPreviousResult);
|
||||
|
||||
#ifdef MOZ_STORAGE
|
||||
// This assumes that FormHistory uses nsIAutoCompleteSimpleResult,
|
||||
// while PasswordManager does not.
|
||||
nsCOMPtr<nsIAutoCompleteSimpleResult> historyResult;
|
||||
#elif defined(MOZ_MORK)
|
||||
nsCOMPtr<nsIAutoCompleteMdbResult> historyResult;
|
||||
#else
|
||||
#error either mozstorage or mork must be compiled
|
||||
#endif
|
||||
historyResult = do_QueryInterface(aPreviousResult);
|
||||
|
||||
nsPasswordManager* passMgr = nsPasswordManager::GetInstance();
|
||||
if (!passMgr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Only hand off a previous result to the password manager if it's
|
||||
// a password manager result (i.e. not an nsIAutoCompleteMdbResult).
|
||||
// a password manager result (i.e. not an nsIAutoCompleteMdb/SimpleResult).
|
||||
|
||||
if (!passMgr->AutoCompleteSearch(aSearchString,
|
||||
mdbResult ? nsnull : aPreviousResult,
|
||||
historyResult ? nsnull : aPreviousResult,
|
||||
mFocusedInput,
|
||||
getter_AddRefs(result)))
|
||||
{
|
||||
|
@ -507,9 +522,8 @@ nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAStrin
|
|||
if (history) {
|
||||
history->AutoCompleteSearch(aSearchParam,
|
||||
aSearchString,
|
||||
mdbResult,
|
||||
historyResult,
|
||||
getter_AddRefs(result));
|
||||
NS_RELEASE(history);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(passMgr);
|
||||
|
@ -1106,15 +1120,17 @@ nsFormFillController::GetIndexOfDocShell(nsIDocShell *aDocShell)
|
|||
return -1;
|
||||
}
|
||||
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsFormHistory, nsFormHistory::GetInstance)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFormHistory, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormFillController)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsPasswordManager, nsPasswordManager::GetInstance)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSingleSignonPrompt)
|
||||
#if defined(MOZ_STORAGE) && defined(MOZ_MORKREADER)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormHistoryImporter)
|
||||
#endif
|
||||
|
||||
static void PR_CALLBACK nsFormHistoryModuleDtor(nsIModule* self)
|
||||
{
|
||||
nsPasswordManager::Shutdown();
|
||||
nsFormHistory::ReleaseInstance();
|
||||
}
|
||||
|
||||
static const nsModuleComponentInfo components[] =
|
||||
|
@ -1144,7 +1160,14 @@ static const nsModuleComponentInfo components[] =
|
|||
{ "HTML Form History AutoComplete",
|
||||
NS_FORMFILLCONTROLLER_CID,
|
||||
NS_FORMHISTORYAUTOCOMPLETE_CONTRACTID,
|
||||
nsFormFillControllerConstructor }
|
||||
nsFormFillControllerConstructor },
|
||||
|
||||
#if defined(MOZ_STORAGE) && defined(MOZ_MORKREADER)
|
||||
{ "Form History Importer",
|
||||
NS_FORMHISTORYIMPORTER_CID,
|
||||
NS_FORMHISTORYIMPORTER_CONTRACTID,
|
||||
nsFormHistoryImporterConstructor },
|
||||
#endif
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE_WITH_DTOR(satchel, components, nsFormHistoryModuleDtor)
|
||||
|
|
|
@ -56,7 +56,8 @@
|
|||
#include "nsIDocShell.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsFormHistory.h"
|
||||
|
||||
class nsFormHistory;
|
||||
|
||||
class nsFormFillController : public nsIFormFillController,
|
||||
public nsIAutoCompleteInput,
|
||||
|
|
|
@ -88,18 +88,21 @@ nsFormHistory::nsFormHistory() :
|
|||
mStore(nsnull),
|
||||
mTable(nsnull)
|
||||
{
|
||||
NS_ASSERTION(!gFormHistory, "nsFormHistory must be used as a service");
|
||||
gFormHistory = this;
|
||||
}
|
||||
|
||||
nsFormHistory::~nsFormHistory()
|
||||
{
|
||||
NS_ASSERTION(gFormHistory == this,
|
||||
"nsFormHistory must be used as a service");
|
||||
CloseDatabase();
|
||||
gFormHistory = nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormHistory::Init()
|
||||
{
|
||||
gFormHistory = this;
|
||||
|
||||
nsCOMPtr<nsIObserverService> service = do_GetService("@mozilla.org/observer-service;1");
|
||||
if (service)
|
||||
service->AddObserver(this, NS_FORMSUBMIT_SUBJECT, PR_TRUE);
|
||||
|
@ -109,35 +112,6 @@ nsFormHistory::Init()
|
|||
|
||||
nsFormHistory *nsFormHistory::gFormHistory = nsnull;
|
||||
|
||||
nsFormHistory *
|
||||
nsFormHistory::GetInstance()
|
||||
{
|
||||
if (!gFormHistory) {
|
||||
gFormHistory = new nsFormHistory();
|
||||
if (!gFormHistory)
|
||||
return nsnull;
|
||||
|
||||
NS_ADDREF(gFormHistory); // addref for the global
|
||||
|
||||
if (NS_FAILED(gFormHistory->Init())) {
|
||||
NS_RELEASE(gFormHistory);
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(gFormHistory); // addref for the getter
|
||||
|
||||
return gFormHistory;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsFormHistory::ReleaseInstance()
|
||||
{
|
||||
NS_IF_RELEASE(gFormHistory);
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsFormHistory::FormHistoryEnabled()
|
||||
{
|
||||
|
@ -164,60 +138,16 @@ nsFormHistory::FormHistoryEnabled()
|
|||
//// nsIFormHistory
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::GetRowCount(PRUint32 *aRowCount)
|
||||
nsFormHistory::GetHasEntries(PRBool *aHasEntries)
|
||||
{
|
||||
nsresult rv = OpenDatabase(); // lazily ensure that the database is open
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mdb_err err = mTable->GetCount(mEnv, aRowCount);
|
||||
PRUint32 rowCount;
|
||||
mdb_err err = mTable->GetCount(mEnv, &rowCount);
|
||||
NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::GetEntryAt(PRUint32 aIndex, nsAString &aName, nsAString &aValue)
|
||||
{
|
||||
nsresult rv = OpenDatabase(); // lazily ensure that the database is open
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMdbRow> row;
|
||||
mdb_err err = mTable->PosToRow(mEnv, aIndex, getter_AddRefs(row));
|
||||
NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
|
||||
|
||||
GetRowValue(row, kToken_NameColumn, aName);
|
||||
GetRowValue(row, kToken_ValueColumn, aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::GetNameAt(PRUint32 aIndex, nsAString &aName)
|
||||
{
|
||||
nsresult rv = OpenDatabase(); // lazily ensure that the database is open
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMdbRow> row;
|
||||
mdb_err err = mTable->PosToRow(mEnv, aIndex, getter_AddRefs(row));
|
||||
NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
|
||||
|
||||
GetRowValue(row, kToken_NameColumn, aName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::GetValueAt(PRUint32 aIndex, nsAString &aValue)
|
||||
{
|
||||
nsresult rv = OpenDatabase(); // lazily ensure that the database is open
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMdbRow> row;
|
||||
mdb_err err = mTable->PosToRow(mEnv, aIndex, getter_AddRefs(row));
|
||||
NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
|
||||
|
||||
GetRowValue(row, kToken_ValueColumn, aValue);
|
||||
|
||||
*aHasEntries = rowCount != 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -235,12 +165,6 @@ nsFormHistory::AddEntry(const nsAString &aName, const nsAString &aValue)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::RemoveEntryAt(PRUint32 index)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::EntryExists(const nsAString &aName, const nsAString &aValue, PRBool *_retval)
|
||||
{
|
||||
|
@ -253,6 +177,12 @@ nsFormHistory::NameExists(const nsAString &aName, PRBool *_retval)
|
|||
return EntriesExistInternal(&aName, nsnull, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::RemoveEntry(const nsAString &aName, const nsAString &aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::RemoveEntriesForName(const nsAString &aName)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include "nsIPrefBranch.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "mdb.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
|
||||
class nsFormHistory : public nsIFormHistory,
|
||||
public nsIObserver,
|
||||
|
@ -65,8 +67,13 @@ public:
|
|||
virtual ~nsFormHistory();
|
||||
nsresult Init();
|
||||
|
||||
static nsFormHistory *GetInstance();
|
||||
static void ReleaseInstance(void);
|
||||
static nsFormHistory *GetInstance()
|
||||
{
|
||||
if (!gFormHistory) {
|
||||
nsCOMPtr<nsIFormHistory> fh = do_GetService(NS_FORMHISTORY_CONTRACTID);
|
||||
}
|
||||
return gFormHistory;
|
||||
}
|
||||
|
||||
nsresult AutoCompleteSearch(const nsAString &aInputName, const nsAString &aInputValue,
|
||||
nsIAutoCompleteMdbResult *aPrevResult, nsIAutoCompleteResult **aNewResult);
|
||||
|
|
|
@ -0,0 +1,615 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client 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):
|
||||
* Joe Hewitt <hewitt@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 MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsStorageFormHistory.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "nsIAutoCompleteSimpleResult.h"
|
||||
|
||||
// nsFormHistoryResult is a specialized autocomplete result class that knows
|
||||
// how to remove entries from the form history table.
|
||||
class nsFormHistoryResult : public nsIAutoCompleteSimpleResult
|
||||
{
|
||||
public:
|
||||
nsFormHistoryResult(const nsAString &aFieldName)
|
||||
: mFieldName(aFieldName) {}
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// Forward everything except RemoveValueAt to the internal result
|
||||
NS_IMETHOD GetSearchString(nsAString &_result)
|
||||
{ return mResult->GetSearchString(_result); }
|
||||
NS_IMETHOD GetSearchResult(PRUint16 *_result)
|
||||
{ return mResult->GetSearchResult(_result); }
|
||||
NS_IMETHOD GetDefaultIndex(PRInt32 *_result)
|
||||
{ return mResult->GetDefaultIndex(_result); }
|
||||
NS_IMETHOD GetErrorDescription(nsAString &_result)
|
||||
{ return mResult->GetErrorDescription(_result); }
|
||||
NS_IMETHOD GetMatchCount(PRUint32 *_result)
|
||||
{ return mResult->GetMatchCount(_result); }
|
||||
NS_IMETHOD GetValueAt(PRInt32 aIndex, nsAString &_result)
|
||||
{ return mResult->GetValueAt(aIndex, _result); }
|
||||
NS_IMETHOD GetCommentAt(PRInt32 aIndex, nsAString &_result)
|
||||
{ return mResult->GetCommentAt(aIndex, _result); }
|
||||
NS_IMETHOD GetStyleAt(PRInt32 aIndex, nsAString &_result)
|
||||
{ return mResult->GetStyleAt(aIndex, _result); }
|
||||
NS_IMETHOD RemoveValueAt(PRInt32 aRowIndex, PRBool aRemoveFromDB);
|
||||
NS_FORWARD_NSIAUTOCOMPLETESIMPLERESULT(mResult->)
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIAutoCompleteSimpleResult> mResult;
|
||||
nsString mFieldName;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsFormHistoryResult,
|
||||
nsIAutoCompleteResult, nsIAutoCompleteSimpleResult)
|
||||
|
||||
nsresult
|
||||
nsFormHistoryResult::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
mResult = do_CreateInstance(NS_AUTOCOMPLETESIMPLERESULT_CONTRACTID, &rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistoryResult::RemoveValueAt(PRInt32 aRowIndex, PRBool aRemoveFromDB)
|
||||
{
|
||||
if (!aRemoveFromDB) {
|
||||
return mResult->RemoveValueAt(aRowIndex, aRemoveFromDB);
|
||||
}
|
||||
|
||||
nsAutoString value;
|
||||
nsresult rv = mResult->GetValueAt(aRowIndex, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mResult->RemoveValueAt(aRowIndex, aRemoveFromDB);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsFormHistory* fh = nsFormHistory::GetInstance();
|
||||
NS_ENSURE_TRUE(fh, NS_ERROR_OUT_OF_MEMORY);
|
||||
return fh->RemoveEntry(mFieldName, value);
|
||||
}
|
||||
|
||||
#define PREF_FORMFILL_BRANCH "browser.formfill."
|
||||
#define PREF_FORMFILL_ENABLE "enable"
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsFormHistory)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFormHistory)
|
||||
// Have to do this one by hand because it's an ambiguous conversion
|
||||
// to nsISupports.
|
||||
if (aIID.Equals(NS_GET_IID(nsFormHistory))) {
|
||||
NS_ADDREF_THIS();
|
||||
*aInstancePtr = this;
|
||||
return NS_OK;
|
||||
} else
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFormSubmitObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(nsFormHistory)
|
||||
NS_IMPL_RELEASE(nsFormHistory)
|
||||
|
||||
PRBool nsFormHistory::gFormHistoryEnabled = PR_FALSE;
|
||||
PRBool nsFormHistory::gPrefsInitialized = PR_FALSE;
|
||||
nsFormHistory* nsFormHistory::gFormHistory = nsnull;
|
||||
|
||||
nsFormHistory::nsFormHistory()
|
||||
{
|
||||
NS_ASSERTION(!gFormHistory, "nsFormHistory must be used as a service");
|
||||
gFormHistory = this;
|
||||
}
|
||||
|
||||
nsFormHistory::~nsFormHistory()
|
||||
{
|
||||
NS_ASSERTION(gFormHistory == this,
|
||||
"nsFormHistory must be used as a service");
|
||||
gFormHistory = nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormHistory::Init()
|
||||
{
|
||||
nsresult rv = OpenDatabase();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIObserverService> service = do_GetService("@mozilla.org/observer-service;1");
|
||||
if (service)
|
||||
service->AddObserver(this, NS_FORMSUBMIT_SUBJECT, PR_TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsFormHistory::FormHistoryEnabled()
|
||||
{
|
||||
if (!gPrefsInitialized) {
|
||||
nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
|
||||
prefService->GetBranch(PREF_FORMFILL_BRANCH,
|
||||
getter_AddRefs(gFormHistory->mPrefBranch));
|
||||
gFormHistory->mPrefBranch->GetBoolPref(PREF_FORMFILL_ENABLE,
|
||||
&gFormHistoryEnabled);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch2> branchInternal =
|
||||
do_QueryInterface(gFormHistory->mPrefBranch);
|
||||
branchInternal->AddObserver(PREF_FORMFILL_ENABLE, gFormHistory, PR_TRUE);
|
||||
|
||||
gPrefsInitialized = PR_TRUE;
|
||||
}
|
||||
|
||||
return gFormHistoryEnabled;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//// nsIFormHistory
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::GetHasEntries(PRBool *aHasEntries)
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBSelectEntries);
|
||||
|
||||
PRBool hasMore;
|
||||
*aHasEntries = mDBSelectEntries->ExecuteStep(&hasMore) && hasMore;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::AddEntry(const nsAString &aName, const nsAString &aValue)
|
||||
{
|
||||
if (!FormHistoryEnabled())
|
||||
return NS_OK;
|
||||
|
||||
mozStorageTransaction transaction(mDBConn, PR_FALSE);
|
||||
|
||||
PRBool exists;
|
||||
EntryExists(aName, aValue, &exists);
|
||||
if (!exists) {
|
||||
mozStorageStatementScoper scope(mDBInsertNameValue);
|
||||
nsresult rv = mDBInsertNameValue->BindStringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBInsertNameValue->BindStringParameter(1, aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBInsertNameValue->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return transaction.Commit();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::EntryExists(const nsAString &aName,
|
||||
const nsAString &aValue, PRBool *_retval)
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBFindEntry);
|
||||
|
||||
nsresult rv = mDBFindEntry->BindStringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBFindEntry->BindStringParameter(1, aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasMore;
|
||||
*_retval = NS_SUCCEEDED(mDBFindEntry->ExecuteStep(&hasMore)) && hasMore;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::NameExists(const nsAString &aName, PRBool *_retval)
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBFindEntryByName);
|
||||
|
||||
nsresult rv = mDBFindEntryByName->BindStringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasMore;
|
||||
*_retval = (NS_SUCCEEDED(mDBFindEntryByName->ExecuteStep(&hasMore)) &&
|
||||
hasMore);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::RemoveEntry(const nsAString &aName, const nsAString &aValue)
|
||||
{
|
||||
nsCOMPtr<mozIStorageStatement> dbDelete;
|
||||
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_formhistory WHERE fieldname=?1 AND value=?2"),
|
||||
getter_AddRefs(dbDelete));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = dbDelete->BindStringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = dbDelete->BindStringParameter(1, aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return dbDelete->Execute();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::RemoveEntriesForName(const nsAString &aName)
|
||||
{
|
||||
nsCOMPtr<mozIStorageStatement> dbDelete;
|
||||
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_formhistory WHERE fieldname=?1"),
|
||||
getter_AddRefs(dbDelete));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = dbDelete->BindStringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return dbDelete->Execute();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::RemoveAllEntries()
|
||||
{
|
||||
nsCOMPtr<mozIStorageStatement> dbDeleteAll;
|
||||
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_formhistory"),
|
||||
getter_AddRefs(dbDeleteAll));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return dbDeleteAll->Execute();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//// nsIObserver
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
|
||||
{
|
||||
if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||||
mPrefBranch->GetBoolPref(PREF_FORMFILL_ENABLE, &gFormHistoryEnabled);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//// nsIFormSubmitObserver
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistory::Notify(nsIContent* aFormNode, nsIDOMWindowInternal* aWindow, nsIURI* aActionURL, PRBool* aCancelSubmit)
|
||||
{
|
||||
if (!FormHistoryEnabled())
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> formElt = do_QueryInterface(aFormNode);
|
||||
NS_ENSURE_TRUE(formElt, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> elts;
|
||||
formElt->GetElements(getter_AddRefs(elts));
|
||||
|
||||
const char *textString = "text";
|
||||
|
||||
PRUint32 length;
|
||||
elts->GetLength(&length);
|
||||
for (PRUint32 i = 0; i < length; ++i) {
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
elts->Item(i, getter_AddRefs(node));
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> inputElt = do_QueryInterface(node);
|
||||
if (inputElt) {
|
||||
// Filter only inputs that are of type "text"
|
||||
nsAutoString type;
|
||||
inputElt->GetType(type);
|
||||
if (type.EqualsIgnoreCase(textString)) {
|
||||
// If this input has a name/id and value, add it to the database
|
||||
nsAutoString value;
|
||||
inputElt->GetValue(value);
|
||||
if (!value.IsEmpty()) {
|
||||
nsAutoString name;
|
||||
inputElt->GetName(name);
|
||||
if (name.IsEmpty())
|
||||
inputElt->GetId(name);
|
||||
|
||||
if (!name.IsEmpty())
|
||||
AddEntry(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult
|
||||
nsFormHistory::OpenDatabase()
|
||||
{
|
||||
// init DB service and obtain a connection
|
||||
nsresult rv;
|
||||
mStorageService = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mStorageService->OpenSpecialDatabase(MOZ_STORAGE_PROFILE_STORAGE_KEY,
|
||||
getter_AddRefs(mDBConn));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool exists;
|
||||
mDBConn->TableExists(NS_LITERAL_CSTRING("moz_formhistory"), &exists);
|
||||
if (!exists) {
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE TABLE moz_formhistory (id INTEGER PRIMARY KEY, fieldname LONGVARCHAR, value LONGVARCHAR)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE INDEX moz_formhistory_index ON moz_formhistory (fieldname)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM moz_formhistory"),
|
||||
getter_AddRefs(mDBSelectEntries));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM moz_formhistory WHERE fieldname=?1 AND value=?2"),
|
||||
getter_AddRefs(mDBFindEntry));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM moz_formhistory WHERE fieldname=?1"),
|
||||
getter_AddRefs(mDBFindEntryByName));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT value FROM moz_formhistory WHERE fieldname=?1"),
|
||||
getter_AddRefs(mDBGetMatchingField));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_formhistory (fieldname, value) VALUES (?1, ?2)"),
|
||||
getter_AddRefs(mDBInsertNameValue));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!exists) {
|
||||
// Locate the old formhistory.dat file and import it.
|
||||
nsCOMPtr<nsIFile> historyFile;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(historyFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
historyFile->Append(NS_LITERAL_STRING("formhistory.dat"));
|
||||
|
||||
nsCOMPtr<nsIFormHistoryImporter> importer = new nsFormHistoryImporter();
|
||||
NS_ENSURE_TRUE(importer, NS_ERROR_OUT_OF_MEMORY);
|
||||
importer->ImportFormHistory(historyFile, this);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormHistory::AutoCompleteSearch(const nsAString &aInputName,
|
||||
const nsAString &aInputValue,
|
||||
nsIAutoCompleteSimpleResult *aPrevResult,
|
||||
nsIAutoCompleteResult **aResult)
|
||||
{
|
||||
if (!FormHistoryEnabled())
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteSimpleResult> result;
|
||||
|
||||
if (aPrevResult) {
|
||||
result = aPrevResult;
|
||||
|
||||
PRUint32 matchCount;
|
||||
result->GetMatchCount(&matchCount);
|
||||
|
||||
for (PRInt32 i = matchCount - 1; i >= 0; --i) {
|
||||
nsAutoString match;
|
||||
result->GetValueAt(i, match);
|
||||
if (!StringBeginsWith(match, aInputValue,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
result->RemoveValueAt(i, PR_FALSE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsFormHistoryResult> fhResult =
|
||||
new nsFormHistoryResult(aInputName);
|
||||
NS_ENSURE_TRUE(fhResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsresult rv = fhResult->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_REINTERPRET_CAST(nsCOMPtr<nsIAutoCompleteSimpleResult>*, &fhResult)->swap(result);
|
||||
|
||||
result->SetSearchString(aInputValue);
|
||||
|
||||
// generates query string
|
||||
mozStorageStatementScoper scope(mDBGetMatchingField);
|
||||
rv = mDBGetMatchingField->BindStringParameter(0, aInputName);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
PRBool hasMore = PR_FALSE;
|
||||
PRUint32 count = 0;
|
||||
while (NS_SUCCEEDED(mDBGetMatchingField->ExecuteStep(&hasMore)) &&
|
||||
hasMore) {
|
||||
nsAutoString entryString;
|
||||
mDBGetMatchingField->GetString(0, entryString);
|
||||
// filters out irrelevant results
|
||||
if(StringBeginsWith(entryString, aInputValue,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
result->AppendMatch(entryString, EmptyString());
|
||||
++count;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
result->SetSearchResult(nsIAutoCompleteResult::RESULT_SUCCESS);
|
||||
result->SetDefaultIndex(0);
|
||||
} else {
|
||||
result->SetSearchResult(nsIAutoCompleteResult::RESULT_NOMATCH);
|
||||
result->SetDefaultIndex(-1);
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = result;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_MORKREADER
|
||||
|
||||
// Columns for form history rows
|
||||
enum {
|
||||
kNameColumn,
|
||||
kValueColumn,
|
||||
kColumnCount // keep me last
|
||||
};
|
||||
|
||||
static const char * const gColumnNames[] = {
|
||||
"Name", "Value"
|
||||
};
|
||||
|
||||
struct FormHistoryImportClosure
|
||||
{
|
||||
FormHistoryImportClosure(nsMorkReader *aReader, nsIFormHistory *aFormHistory)
|
||||
: reader(aReader), formHistory(aFormHistory) { }
|
||||
|
||||
// Back pointers to the reader and history we're operating on
|
||||
nsMorkReader *reader;
|
||||
nsIFormHistory *formHistory;
|
||||
|
||||
// Column ids of the columns that we care about
|
||||
nsCString columnIDs[kColumnCount];
|
||||
};
|
||||
|
||||
// Enumerator callback to build up the column list
|
||||
/* static */ PLDHashOperator PR_CALLBACK
|
||||
nsFormHistoryImporter::EnumerateColumnsCB(const nsACString &aColumnID,
|
||||
nsCString aName, void *aData)
|
||||
{
|
||||
FormHistoryImportClosure *data = NS_STATIC_CAST(FormHistoryImportClosure*,
|
||||
aData);
|
||||
for (PRUint32 i = 0; i < kColumnCount; ++i) {
|
||||
if (aName.Equals(gColumnNames[i])) {
|
||||
data->columnIDs[i].Assign(aColumnID);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// Enumerator callback to add an entry to the FormHistory
|
||||
/* static */ PLDHashOperator PR_CALLBACK
|
||||
nsFormHistoryImporter::AddToFormHistoryCB(const nsACString &aRowID,
|
||||
const nsMorkReader::StringMap *aMap,
|
||||
void *aData)
|
||||
{
|
||||
FormHistoryImportClosure *data = NS_STATIC_CAST(FormHistoryImportClosure*,
|
||||
aData);
|
||||
nsMorkReader *reader = data->reader;
|
||||
nsCString values[kColumnCount];
|
||||
const PRUnichar* valueStrings[kColumnCount];
|
||||
PRUint32 valueLengths[kColumnCount];
|
||||
nsCString *columnIDs = data->columnIDs;
|
||||
PRInt32 i;
|
||||
|
||||
// Values are in UTF16.
|
||||
|
||||
for (i = 0; i < kColumnCount; ++i) {
|
||||
aMap->Get(columnIDs[i], &values[i]);
|
||||
reader->NormalizeValue(values[i]);
|
||||
|
||||
PRUint32 length;
|
||||
const char *bytes;
|
||||
if (values[i].IsEmpty()) {
|
||||
bytes = "\0";
|
||||
length = 0;
|
||||
} else {
|
||||
length = values[i].Length() / 2;
|
||||
|
||||
// add an extra null byte onto the end, so that the buffer ends
|
||||
// with a complete unicode null character.
|
||||
values[i].Append('\0');
|
||||
|
||||
// XXX this should handle byte swapping, but there's no endianness marker
|
||||
bytes = values[i].get();
|
||||
}
|
||||
valueStrings[i] = NS_REINTERPRET_CAST(const PRUnichar*, bytes);
|
||||
valueLengths[i] = length;
|
||||
}
|
||||
|
||||
data->formHistory->AddEntry(nsDependentString(valueStrings[kNameColumn],
|
||||
valueLengths[kNameColumn]),
|
||||
nsDependentString(valueStrings[kValueColumn],
|
||||
valueLengths[kValueColumn]));
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsFormHistoryImporter, nsIFormHistoryImporter)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormHistoryImporter::ImportFormHistory(nsIFile *aFile,
|
||||
nsIFormHistory *aFormHistory)
|
||||
{
|
||||
nsMorkReader reader;
|
||||
nsresult rv = reader.Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = reader.Read(aFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Gather up the column ids so we don't need to find them on each row
|
||||
FormHistoryImportClosure data(&reader, aFormHistory);
|
||||
reader.EnumerateColumns(EnumerateColumnsCB, &data);
|
||||
|
||||
// Add the rows to form history
|
||||
nsCOMPtr<nsFormHistory> formHistory = do_QueryInterface(aFormHistory);
|
||||
NS_ENSURE_TRUE(formHistory, NS_ERROR_FAILURE);
|
||||
|
||||
mozIStorageConnection *conn = formHistory->GetStorageConnection();
|
||||
NS_ENSURE_TRUE(conn, NS_ERROR_NOT_INITIALIZED);
|
||||
mozStorageTransaction transaction(conn, PR_FALSE);
|
||||
|
||||
reader.EnumerateRows(AddToFormHistoryCB, &data);
|
||||
return transaction.Commit();
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,148 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client 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):
|
||||
* Joe Hewitt <hewitt@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 MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __nsFormHistory__
|
||||
#define __nsFormHistory__
|
||||
|
||||
#include "nsIFormHistory.h"
|
||||
#include "nsIFormSubmitObserver.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozIStorageConnection.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#ifdef MOZ_MORKREADER
|
||||
#include "nsMorkReader.h"
|
||||
#endif
|
||||
|
||||
class nsIAutoCompleteSimpleResult;
|
||||
class nsIAutoCompleteResult;
|
||||
|
||||
#define NS_FORMHISTORY_IID \
|
||||
{0xc4a47315, 0xaeb5, 0x4039, {0x9f, 0x34, 0x45, 0x11, 0xb3, 0xa7, 0x58, 0xdd}}
|
||||
|
||||
class nsFormHistory : public nsIFormHistory,
|
||||
public nsIObserver,
|
||||
public nsIFormSubmitObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
#ifdef MOZILLA_1_8_BRANCH
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_FORMHISTORY_IID)
|
||||
#else
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_FORMHISTORY_IID)
|
||||
#endif
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFORMHISTORY
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
// nsIFormSubmitObserver
|
||||
NS_IMETHOD Notify(nsIContent* formNode, nsIDOMWindowInternal* window, nsIURI* actionURL, PRBool* cancelSubmit);
|
||||
|
||||
nsFormHistory();
|
||||
nsresult Init();
|
||||
|
||||
static nsFormHistory* GetInstance()
|
||||
{
|
||||
if (!gFormHistory) {
|
||||
nsCOMPtr<nsIFormHistory> fh = do_GetService(NS_FORMHISTORY_CONTRACTID);
|
||||
}
|
||||
return gFormHistory;
|
||||
}
|
||||
|
||||
mozIStorageConnection* GetStorageConnection() { return mDBConn; }
|
||||
|
||||
nsresult AutoCompleteSearch(const nsAString &aInputName,
|
||||
const nsAString &aInputValue,
|
||||
nsIAutoCompleteSimpleResult *aPrevResult,
|
||||
nsIAutoCompleteResult **aNewResult);
|
||||
|
||||
private:
|
||||
~nsFormHistory();
|
||||
|
||||
protected:
|
||||
// Database I/O
|
||||
nsresult OpenDatabase();
|
||||
nsresult CloseDatabase();
|
||||
|
||||
static PRBool FormHistoryEnabled();
|
||||
static nsFormHistory *gFormHistory;
|
||||
static PRBool gFormHistoryEnabled;
|
||||
static PRBool gPrefsInitialized;
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> mPrefBranch;
|
||||
nsCOMPtr<mozIStorageService> mStorageService;
|
||||
nsCOMPtr<mozIStorageConnection> mDBConn;
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetMatchingField;
|
||||
nsCOMPtr<mozIStorageStatement> mDBFindEntry;
|
||||
nsCOMPtr<mozIStorageStatement> mDBFindEntryByName;
|
||||
nsCOMPtr<mozIStorageStatement> mDBSelectEntries;
|
||||
nsCOMPtr<mozIStorageStatement> mDBInsertNameValue;
|
||||
};
|
||||
|
||||
#ifdef MOZ_MORKREADER
|
||||
class nsFormHistoryImporter : public nsIFormHistoryImporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFORMHISTORYIMPORTER
|
||||
|
||||
private:
|
||||
// Enumerator callback to build up a list of columns
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
EnumerateColumnsCB(const nsACString &aColumnID,
|
||||
nsCString aName,
|
||||
void *aData);
|
||||
|
||||
// Enumerator callback to add a single row to the FormHistory.
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
AddToFormHistoryCB(const nsACString &aRowID,
|
||||
const nsMorkReader::StringMap *aMap,
|
||||
void *aData);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // __nsFormHistory__
|
Загрузка…
Ссылка в новой задаче