зеркало из https://github.com/mozilla/gecko-dev.git
Bug 594583 - 'IndexedDB: Add some UI to clear IndexedDB databases'. r=sicking+gavin. a=beta6blocking.
This commit is contained in:
Родитель
9959033066
Коммит
c9978327b5
|
@ -89,11 +89,13 @@
|
|||
<command id="cmd_cookieDef" oncommand="onCheckboxClick('cookie');"/>
|
||||
<command id="cmd_installDef" oncommand="onCheckboxClick('install');"/>
|
||||
<command id="cmd_geoDef" oncommand="onCheckboxClick('geo');"/>
|
||||
<command id="cmd_indexedDBDef" oncommand="onCheckboxClick('indexedDB');"/>
|
||||
<command id="cmd_imageToggle" oncommand="onRadioClick('image');"/>
|
||||
<command id="cmd_popupToggle" oncommand="onRadioClick('popup');"/>
|
||||
<command id="cmd_cookieToggle" oncommand="onRadioClick('cookie');"/>
|
||||
<command id="cmd_installToggle" oncommand="onRadioClick('install');"/>
|
||||
<command id="cmd_geoToggle" oncommand="onRadioClick('geo');"/>
|
||||
<command id="cmd_indexedDBToggle" oncommand="onRadioClick('indexedDB');"/>
|
||||
</commandset>
|
||||
|
||||
<keyset>
|
||||
|
@ -375,6 +377,23 @@
|
|||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox class="permission">
|
||||
<label class="permissionLabel" id="permIndexedDBLabel"
|
||||
value="&permIndexedDB;" control="indexedDBRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permIndexedDBLabel">
|
||||
<checkbox id="indexedDBDef" command="cmd_indexedDBDef" label="&permAskAlways;"/>
|
||||
<spacer flex="1"/>
|
||||
<vbox pack="center">
|
||||
<label id="indexedDBStatus" control="indexedDBClear"/>
|
||||
</vbox>
|
||||
<button id="indexedDBClear" label="&permClearStorage;"
|
||||
accesskey="&permClearStorage.accesskey;" onclick="onIndexedDBClear();"/>
|
||||
<radiogroup id="indexedDBRadioGroup" orient="horizontal">
|
||||
<radio id="indexedDB#1" command="cmd_indexedDBToggle" label="&permAllow;"/>
|
||||
<radio id="indexedDB#2" command="cmd_indexedDBToggle" label="&permBlock;"/>
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
const ALLOW = nsIPermissionManager.ALLOW_ACTION; // 1
|
||||
const BLOCK = nsIPermissionManager.DENY_ACTION; // 2
|
||||
const SESSION = nsICookiePermission.ACCESS_SESSION;// 8
|
||||
|
||||
const nsIIndexedDatabaseManager =
|
||||
Components.interfaces.nsIIndexedDatabaseManager;
|
||||
|
||||
var gPermURI;
|
||||
var gPrefs;
|
||||
|
||||
|
@ -73,7 +77,11 @@ var gPermObj = {
|
|||
},
|
||||
geo: function getGeoDefaultPermissions()
|
||||
{
|
||||
return BLOCK;
|
||||
return BLOCK;
|
||||
},
|
||||
indexedDB: function getIndexedDBDefaultPermissions()
|
||||
{
|
||||
return BLOCK;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -137,6 +145,10 @@ function initRow(aPartId)
|
|||
perm = gPermObj[aPartId]();
|
||||
}
|
||||
setRadioState(aPartId, perm);
|
||||
|
||||
if (aPartId == "indexedDB") {
|
||||
initIndexedDBRow();
|
||||
}
|
||||
}
|
||||
|
||||
function onCheckboxClick(aPartId)
|
||||
|
@ -148,6 +160,9 @@ function onCheckboxClick(aPartId)
|
|||
var checkbox = document.getElementById(aPartId + "Def");
|
||||
if (checkbox.checked) {
|
||||
permissionManager.remove(gPermURI.host, aPartId);
|
||||
if (aPartId == "indexedDB") {
|
||||
permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
|
||||
}
|
||||
command.setAttribute("disabled", "true");
|
||||
var perm = gPermObj[aPartId]();
|
||||
setRadioState(aPartId, perm);
|
||||
|
@ -167,6 +182,9 @@ function onRadioClick(aPartId)
|
|||
var id = radioGroup.selectedItem.id;
|
||||
var permission = id.split('#')[1];
|
||||
permissionManager.add(gPermURI, aPartId, permission);
|
||||
if (aPartId == "indexedDB" && permission == BLOCK) {
|
||||
permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
|
||||
}
|
||||
}
|
||||
|
||||
function setRadioState(aPartId, aValue)
|
||||
|
@ -174,3 +192,41 @@ function setRadioState(aPartId, aValue)
|
|||
var radio = document.getElementById(aPartId + "#" + aValue);
|
||||
radio.radioGroup.selectedItem = radio;
|
||||
}
|
||||
|
||||
function initIndexedDBRow()
|
||||
{
|
||||
var status = document.getElementById("indexedDBStatus");
|
||||
var button = document.getElementById("indexedDBClear");
|
||||
|
||||
var usage = Components.classes["@mozilla.org/dom/indexeddb/manager;1"]
|
||||
.getService(nsIIndexedDatabaseManager)
|
||||
.getUsageForURI(gPermURI);
|
||||
if (usage) {
|
||||
if (!("DownloadUtils" in window)) {
|
||||
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
}
|
||||
status.value =
|
||||
gBundle.getFormattedString("indexedDBUsage",
|
||||
DownloadUtils.convertByteUnits(usage));
|
||||
status.removeAttribute("hidden");
|
||||
button.removeAttribute("hidden");
|
||||
}
|
||||
else {
|
||||
status.value = "";
|
||||
status.setAttribute("hidden", "true");
|
||||
button.setAttribute("hidden", "true");
|
||||
}
|
||||
}
|
||||
|
||||
function onIndexedDBClear()
|
||||
{
|
||||
Components.classes["@mozilla.org/dom/indexeddb/manager;1"]
|
||||
.getService(nsIIndexedDatabaseManager)
|
||||
.clearDatabasesForURI(gPermURI);
|
||||
|
||||
var permissionManager = Components.classes[PERMISSION_CONTRACTID]
|
||||
.getService(nsIPermissionManager);
|
||||
permissionManager.remove(gPermURI.host, "indexedDB");
|
||||
permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
|
||||
initIndexedDBRow();
|
||||
}
|
||||
|
|
|
@ -99,6 +99,10 @@
|
|||
<!ENTITY permInstall "Install Extensions or Themes">
|
||||
<!ENTITY permGeo "Share Location">
|
||||
|
||||
<!ENTITY permIndexedDB "Maintain Offline Storage">
|
||||
<!ENTITY permClearStorage "Clear Storage">
|
||||
<!ENTITY permClearStorage.accesskey "C">
|
||||
|
||||
<!ENTITY securityTab "Security">
|
||||
<!ENTITY securityTab.accesskey "S">
|
||||
<!ENTITY securityHeader "Security information for this page">
|
||||
|
|
|
@ -79,3 +79,10 @@ feedXML=XML
|
|||
securityNoOwner=This web site does not supply ownership information.
|
||||
securityOneVisit=Yes, once
|
||||
securityNVisits=Yes, %S times
|
||||
|
||||
# LOCALIZATION NOTE: The next string is for the disk usage of the
|
||||
# database
|
||||
# e.g. indexedDBUsage : "50.23 MB"
|
||||
# %1$S = size (in bytes or megabytes, ...)
|
||||
# %2$S = unit of measure (bytes, KB, MB, ...)
|
||||
indexedDBUsage=This web site is using %1$S %2$S
|
||||
|
|
|
@ -179,8 +179,6 @@ AsyncConnectionHelper::Run()
|
|||
}
|
||||
}
|
||||
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "GetOrCreateConnection failed!");
|
||||
|
||||
if (connection) {
|
||||
rv = connection->SetProgressHandler(kProgressHandlerGranularity, this,
|
||||
getter_AddRefs(mOldProgressHandler));
|
||||
|
@ -200,7 +198,11 @@ AsyncConnectionHelper::Run()
|
|||
}
|
||||
}
|
||||
else {
|
||||
mErrorCode = nsIIDBDatabaseException::UNKNOWN_ERR;
|
||||
// NS_ERROR_NOT_AVAILABLE is our special code for "database is invalidated"
|
||||
// and we should fail with RECOVERABLE_ERR.
|
||||
mErrorCode = rv == NS_ERROR_NOT_AVAILABLE ?
|
||||
nsIIDBDatabaseException::RECOVERABLE_ERR :
|
||||
nsIIDBDatabaseException::UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (!mStartTime.IsNull()) {
|
||||
|
@ -226,6 +228,12 @@ NS_IMETHODIMP
|
|||
AsyncConnectionHelper::OnProgress(mozIStorageConnection* aConnection,
|
||||
PRBool* _retval)
|
||||
{
|
||||
if (mDatabase && mDatabase->IsInvalidated()) {
|
||||
// Someone is trying to delete the database file. Exit lightningfast!
|
||||
*_retval = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TimeDuration elapsed = TimeStamp::Now() - mStartTime;
|
||||
if (elapsed >= mTimeoutDuration) {
|
||||
*_retval = PR_TRUE;
|
||||
|
|
|
@ -54,7 +54,9 @@
|
|||
#include "IDBObjectStore.h"
|
||||
#include "IDBTransaction.h"
|
||||
#include "IDBFactory.h"
|
||||
#include "IndexedDatabaseManager.h"
|
||||
#include "LazyIdleThread.h"
|
||||
#include "TransactionThreadPool.h"
|
||||
|
||||
USING_INDEXEDDB_NAMESPACE
|
||||
|
||||
|
@ -248,12 +250,23 @@ IDBDatabase::Create(nsIScriptContext* aScriptContext,
|
|||
|
||||
db->mConnection.swap(aConnection);
|
||||
|
||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetInstance();
|
||||
NS_ASSERTION(mgr, "This should never be null!");
|
||||
|
||||
if (!mgr->RegisterDatabase(db)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return db.forget();
|
||||
}
|
||||
|
||||
IDBDatabase::IDBDatabase()
|
||||
: mDatabaseId(0)
|
||||
: mDatabaseId(0),
|
||||
mInvalidated(0)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (!gDatabaseInstanceCount++) {
|
||||
NS_ASSERTION(!gPromptHelpersMutex, "Should be null!");
|
||||
gPromptHelpersMutex = new mozilla::Mutex("IDBDatabase gPromptHelpersMutex");
|
||||
|
@ -262,6 +275,12 @@ IDBDatabase::IDBDatabase()
|
|||
|
||||
IDBDatabase::~IDBDatabase()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetInstance();
|
||||
if (mgr) {
|
||||
mgr->UnregisterDatabase(this);
|
||||
}
|
||||
|
||||
if (mConnectionThread) {
|
||||
mConnectionThread->SetWeakIdleObserver(nsnull);
|
||||
}
|
||||
|
@ -300,6 +319,10 @@ IDBDatabase::GetOrCreateConnection(mozIStorageConnection** aResult)
|
|||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (mInvalidated) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!mConnection) {
|
||||
mConnection = IDBFactory::GetConnection(mFilePath);
|
||||
NS_ENSURE_TRUE(mConnection, NS_ERROR_FAILURE);
|
||||
|
@ -369,6 +392,30 @@ IDBDatabase::IsQuotaDisabled()
|
|||
return foundHelper->PromptAndReturnQuotaIsDisabled();
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::Invalidate()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
PR_AtomicSet(&mInvalidated, 1);
|
||||
CloseConnection();
|
||||
}
|
||||
|
||||
bool
|
||||
IDBDatabase::IsInvalidated()
|
||||
{
|
||||
return !!mInvalidated;
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::WaitForConnectionReleased()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
TransactionThreadPool* threadPool = TransactionThreadPool::Get();
|
||||
if (threadPool) {
|
||||
threadPool->WaitForAllTransactionsToComplete(this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBDatabase)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase,
|
||||
|
|
|
@ -119,6 +119,11 @@ public:
|
|||
return mASCIIOrigin;
|
||||
}
|
||||
|
||||
void Invalidate();
|
||||
bool IsInvalidated();
|
||||
|
||||
void WaitForConnectionReleased();
|
||||
|
||||
private:
|
||||
IDBDatabase();
|
||||
~IDBDatabase();
|
||||
|
@ -131,6 +136,7 @@ private:
|
|||
nsString mDescription;
|
||||
nsString mFilePath;
|
||||
nsCString mASCIIOrigin;
|
||||
PRInt32 mInvalidated;
|
||||
|
||||
nsRefPtr<LazyIdleThread> mConnectionThread;
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "DatabaseInfo.h"
|
||||
#include "IDBDatabase.h"
|
||||
#include "IDBKeyRange.h"
|
||||
#include "IndexedDatabaseManager.h"
|
||||
#include "LazyIdleThread.h"
|
||||
|
||||
#define PREF_INDEXEDDB_QUOTA "dom.indexedDB.warningQuota"
|
||||
|
@ -623,6 +624,29 @@ IDBFactory::GetIndexedDBQuota()
|
|||
return PRUint32(PR_MAX(gIndexedDBQuota, 0));
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
IDBFactory::GetDirectoryForOrigin(const nsACString& aASCIIOrigin,
|
||||
nsIFile** aDirectory)
|
||||
{
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(directory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = directory->Append(NS_LITERAL_STRING("indexedDB"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ConvertASCIItoUTF16 originSanitized(aASCIIOrigin);
|
||||
originSanitized.ReplaceChar(":/", '+');
|
||||
|
||||
rv = directory->Append(originSanitized);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
directory.forget(aDirectory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(IDBFactory)
|
||||
NS_IMPL_RELEASE(IDBFactory)
|
||||
|
||||
|
@ -703,7 +727,12 @@ IDBFactory::Open(const nsAString& aName,
|
|||
nsRefPtr<CheckPermissionsHelper> permissionHelper =
|
||||
new CheckPermissionsHelper(openHelper, thread, innerWindow, origin);
|
||||
|
||||
rv = NS_DispatchToCurrentThread(permissionHelper);
|
||||
nsRefPtr<IndexedDatabaseManager> mgr =
|
||||
already_AddRefed<IndexedDatabaseManager>(
|
||||
IndexedDatabaseManager::GetOrCreateInstance());
|
||||
NS_ENSURE_TRUE(mgr, NS_ERROR_FAILURE);
|
||||
|
||||
rv = mgr->WaitForClearAndDispatch(origin, permissionHelper);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
request.forget(_retval);
|
||||
|
|
|
@ -66,6 +66,10 @@ public:
|
|||
static PRUint32
|
||||
GetIndexedDBQuota();
|
||||
|
||||
static nsresult
|
||||
GetDirectoryForOrigin(const nsACString& aASCIIOrigin,
|
||||
nsIFile** aDirectory);
|
||||
|
||||
private:
|
||||
IDBFactory() { }
|
||||
~IDBFactory() { }
|
||||
|
|
|
@ -242,6 +242,10 @@ IDBTransaction::GetOrCreateConnection(mozIStorageConnection** aResult)
|
|||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (mDatabase->IsInvalidated()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!mConnection) {
|
||||
nsCOMPtr<mozIStorageConnection> connection =
|
||||
IDBFactory::GetConnection(mDatabase->FilePath());
|
||||
|
@ -765,7 +769,12 @@ CommitHelper::Run()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
IDBFactory::SetCurrentDatabase(mTransaction->Database());
|
||||
IDBDatabase* database = mTransaction->Database();
|
||||
if (database->IsInvalidated()) {
|
||||
mAborted = true;
|
||||
}
|
||||
|
||||
IDBFactory::SetCurrentDatabase(database);
|
||||
|
||||
if (mAborted) {
|
||||
NS_ASSERTION(mConnection, "This had better not be null!");
|
||||
|
|
|
@ -0,0 +1,420 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** 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 Indexed Database.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Turner <bent.mozilla@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "IndexedDatabaseManager.h"
|
||||
|
||||
#include "nsIFile.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
#include "IDBDatabase.h"
|
||||
#include "IDBFactory.h"
|
||||
|
||||
USING_INDEXEDDB_NAMESPACE
|
||||
using namespace mozilla::services;
|
||||
|
||||
namespace {
|
||||
|
||||
bool gShutdown = false;
|
||||
|
||||
// Holds a reference!
|
||||
IndexedDatabaseManager* gInstance = nsnull;
|
||||
|
||||
// Adds all databases in the hash to the given array.
|
||||
PLDHashOperator
|
||||
EnumerateToTArray(const nsACString& aKey,
|
||||
nsTArray<IDBDatabase*>* aValue,
|
||||
void* aUserArg)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!aKey.IsEmpty(), "Empty key!");
|
||||
NS_ASSERTION(aValue, "Null pointer!");
|
||||
NS_ASSERTION(aUserArg, "Null pointer!");
|
||||
|
||||
nsTArray<nsRefPtr<IDBDatabase> >* array =
|
||||
static_cast<nsTArray<nsRefPtr<IDBDatabase> >* >(aUserArg);
|
||||
|
||||
if (!array->AppendElements(*aValue)) {
|
||||
NS_WARNING("Out of memory!");
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
IndexedDatabaseManager::IndexedDatabaseManager()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!gInstance, "More than one instance!");
|
||||
}
|
||||
|
||||
IndexedDatabaseManager::~IndexedDatabaseManager()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(gInstance == this, "Different instances!");
|
||||
gInstance = nsnull;
|
||||
}
|
||||
|
||||
// Returns a raw pointer that carries an owning reference! Lame, but the
|
||||
// singleton factory macros force this.
|
||||
IndexedDatabaseManager*
|
||||
IndexedDatabaseManager::GetOrCreateInstance()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (gShutdown) {
|
||||
NS_ERROR("Calling GetOrCreateInstance() after shutdown!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!gInstance) {
|
||||
nsRefPtr<IndexedDatabaseManager> instance(new IndexedDatabaseManager());
|
||||
|
||||
if (!instance->mLiveDatabases.Init()) {
|
||||
NS_WARNING("Out of memory!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// We need to know when to release the singleton.
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
nsresult rv = obs->AddObserver(instance, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
instance.forget(&gInstance);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(gInstance);
|
||||
return gInstance;
|
||||
}
|
||||
|
||||
// Does not return an owning reference.
|
||||
IndexedDatabaseManager*
|
||||
IndexedDatabaseManager::GetInstance()
|
||||
{
|
||||
return gInstance;
|
||||
}
|
||||
|
||||
// Called when an IDBDatabase is constructed.
|
||||
bool
|
||||
IndexedDatabaseManager::RegisterDatabase(IDBDatabase* aDatabase)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aDatabase, "Null pointer!");
|
||||
|
||||
// Don't allow any new databases to be created after shutdown.
|
||||
if (gShutdown) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add this database to its origin array if it exists, create it otherwise.
|
||||
nsTArray<IDBDatabase*>* array;
|
||||
if (!mLiveDatabases.Get(aDatabase->Origin(), &array)) {
|
||||
nsAutoPtr<nsTArray<IDBDatabase*> > newArray(new nsTArray<IDBDatabase*>());
|
||||
if (!mLiveDatabases.Put(aDatabase->Origin(), newArray)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
return false;
|
||||
}
|
||||
array = newArray.forget();
|
||||
}
|
||||
if (!array->AppendElement(aDatabase)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called when an IDBDatabase is destroyed.
|
||||
void
|
||||
IndexedDatabaseManager::UnregisterDatabase(IDBDatabase* aDatabase)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aDatabase, "Null pointer!");
|
||||
|
||||
// Remove this database from its origin array, maybe remove the array if it
|
||||
// is then empty.
|
||||
nsTArray<IDBDatabase*>* array;
|
||||
if (mLiveDatabases.Get(aDatabase->Origin(), &array) &&
|
||||
array->RemoveElement(aDatabase)) {
|
||||
if (array->IsEmpty()) {
|
||||
mLiveDatabases.Remove(aDatabase->Origin());
|
||||
}
|
||||
return;
|
||||
}
|
||||
NS_ERROR("Didn't know anything about this database!");
|
||||
}
|
||||
|
||||
nsresult
|
||||
IndexedDatabaseManager::WaitForClearAndDispatch(const nsACString& aOrigin,
|
||||
nsIRunnable* aRunnable)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!aOrigin.IsEmpty(), "Empty origin!");
|
||||
NS_ASSERTION(aRunnable, "Null pointer!");
|
||||
|
||||
// See if we're currently clearing database files for this origin. If so then
|
||||
// queue the runnable for later dispatch after we're done clearing.
|
||||
PRUint32 count = mOriginClearData.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
OriginClearData& data = mOriginClearData[index];
|
||||
if (data.origin == aOrigin) {
|
||||
nsCOMPtr<nsIRunnable>* newPtr =
|
||||
data.delayedRunnables.AppendElement(aRunnable);
|
||||
NS_ENSURE_TRUE(newPtr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// We aren't currently clearing databases for this origin, so dispatch the
|
||||
// runnable immediately.
|
||||
return NS_DispatchToCurrentThread(aRunnable);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(IndexedDatabaseManager, nsIIndexedDatabaseManager,
|
||||
nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
IndexedDatabaseManager::GetUsageForURI(nsIURI* aURI,
|
||||
PRUint64* _retval)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
|
||||
// Figure out which origin we're dealing with.
|
||||
nsCString origin;
|
||||
nsresult rv = nsContentUtils::GetASCIIOrigin(aURI, origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Non-standard URIs can't create databases anyway, so return 0.
|
||||
if (origin.EqualsLiteral("null")) {
|
||||
*_retval = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the directory where we may be storing database files for this origin.
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
rv = IDBFactory::GetDirectoryForOrigin(origin, getter_AddRefs(directory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool exists;
|
||||
rv = directory->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint64 usage = 0;
|
||||
|
||||
// If the directory exists then enumerate all the files inside, adding up the
|
||||
// sizes to get the final usage statistic.
|
||||
if (exists) {
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (entries) {
|
||||
PRBool hasMore;
|
||||
while (NS_SUCCEEDED(entries->HasMoreElements(&hasMore)) && hasMore) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> file(do_QueryInterface(entry));
|
||||
NS_ASSERTION(file, "Don't know what this is!");
|
||||
|
||||
PRInt64 fileSize;
|
||||
rv = file->GetFileSize(&fileSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(fileSize > 0, "Negative size?!");
|
||||
|
||||
// Watch for overflow!
|
||||
if (NS_UNLIKELY((LL_MAXINT - usage) <= PRUint64(fileSize))) {
|
||||
NS_WARNING("Database sizes exceed max we can report!");
|
||||
usage = LL_MAXINT;
|
||||
}
|
||||
else {
|
||||
usage += fileSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*_retval = usage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IndexedDatabaseManager::ClearDatabasesForURI(nsIURI* aURI)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
|
||||
// Figure out which origin we're dealing with.
|
||||
nsCString origin;
|
||||
nsresult rv = nsContentUtils::GetASCIIOrigin(aURI, origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Non-standard URIs can't create databases anyway, so return immediately.
|
||||
if (origin.EqualsLiteral("null")) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we're already clearing out files for this origin then return
|
||||
// immediately.
|
||||
PRUint32 clearDataCount = mOriginClearData.Length();
|
||||
for (PRUint32 index = 0; index < clearDataCount; index++) {
|
||||
if (mOriginClearData[index].origin == origin) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// We need to grab references to any live databases here to prevent them from
|
||||
// dying while we invalidate them.
|
||||
nsTArray<nsRefPtr<IDBDatabase> > liveDatabases;
|
||||
|
||||
// Grab all live databases for this origin.
|
||||
nsTArray<IDBDatabase*>* array;
|
||||
if (mLiveDatabases.Get(origin, &array)) {
|
||||
if (!liveDatabases.AppendElements(*array)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// Make a new entry for this origin in mOriginClearData. Don't return early
|
||||
// while mOriginClearData has this origin in it!
|
||||
OriginClearData* data = mOriginClearData.AppendElement();
|
||||
NS_ENSURE_TRUE(data, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
data->origin = origin;
|
||||
|
||||
if (!liveDatabases.IsEmpty()) {
|
||||
PRUint32 count = liveDatabases.Length();
|
||||
|
||||
// Invalidate all the live databases first.
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
liveDatabases[index]->Invalidate();
|
||||
}
|
||||
|
||||
// Now wait for them to finish.
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
liveDatabases[index]->WaitForConnectionReleased();
|
||||
}
|
||||
}
|
||||
|
||||
// Now that all our databases have released their connections to their files
|
||||
// we can go ahead and delete the directory. Don't return early while
|
||||
// mOriginClearData has this origin in it!
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
rv = IDBFactory::GetDirectoryForOrigin(origin, getter_AddRefs(directory));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool exists;
|
||||
rv = directory->Exists(&exists);
|
||||
if (NS_SUCCEEDED(rv) && exists) {
|
||||
rv = directory->Remove(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove this origin's entry from mOriginClearData. Dispatch any runnables
|
||||
// that were queued along the way.
|
||||
clearDataCount = mOriginClearData.Length();
|
||||
for (PRUint32 clearDataIndex = 0; clearDataIndex < clearDataCount;
|
||||
clearDataIndex++) {
|
||||
OriginClearData& data = mOriginClearData[clearDataIndex];
|
||||
if (data.origin == origin) {
|
||||
nsTArray<nsCOMPtr<nsIRunnable> >& runnables = data.delayedRunnables;
|
||||
PRUint32 runnableCount = runnables.Length();
|
||||
for (PRUint32 runnableIndex = 0; runnableIndex < runnableCount;
|
||||
runnableIndex++) {
|
||||
NS_DispatchToCurrentThread(runnables[runnableIndex]);
|
||||
}
|
||||
mOriginClearData.RemoveElementAt(clearDataIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can finally return errors.
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IndexedDatabaseManager::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
// Setting this flag prevents the servic from being recreated and prevents
|
||||
// further databases from being created.
|
||||
gShutdown = true;
|
||||
|
||||
// Grab all live databases, for all origins. Need references to keep them
|
||||
// alive while we wait on them.
|
||||
nsAutoTArray<nsRefPtr<IDBDatabase>, 50> liveDatabases;
|
||||
mLiveDatabases.EnumerateRead(EnumerateToTArray, &liveDatabases);
|
||||
|
||||
// Wait for all live databases to finish.
|
||||
if (!liveDatabases.IsEmpty()) {
|
||||
PRUint32 count = liveDatabases.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
liveDatabases[index]->WaitForConnectionReleased();
|
||||
}
|
||||
}
|
||||
|
||||
mLiveDatabases.Clear();
|
||||
|
||||
// This may kill us.
|
||||
gInstance->Release();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Unknown topic!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** 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 Indexed Database.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Turner <bent.mozilla@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||
#define mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
|
||||
#include "nsIIndexedDatabaseManager.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
#define INDEXEDDB_MANAGER_CONTRACTID \
|
||||
"@mozilla.org/dom/indexeddb/manager;1"
|
||||
|
||||
class nsIRunnable;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class IDBDatabase;
|
||||
|
||||
class IndexedDatabaseManager : public nsIIndexedDatabaseManager,
|
||||
public nsIObserver
|
||||
{
|
||||
friend class IDBDatabase;
|
||||
|
||||
public:
|
||||
// Returns an owning reference!
|
||||
static IndexedDatabaseManager* GetOrCreateInstance();
|
||||
|
||||
// Returns a non-owning reference.
|
||||
static IndexedDatabaseManager* GetInstance();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINDEXEDDATABASEMANAGER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsresult WaitForClearAndDispatch(const nsACString& aOrigin,
|
||||
nsIRunnable* aRunnable);
|
||||
|
||||
private:
|
||||
IndexedDatabaseManager();
|
||||
~IndexedDatabaseManager();
|
||||
|
||||
bool RegisterDatabase(IDBDatabase* aDatabase);
|
||||
void UnregisterDatabase(IDBDatabase* aDatabase);
|
||||
|
||||
struct OriginClearData
|
||||
{
|
||||
nsCString origin;
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > delayedRunnables;
|
||||
};
|
||||
|
||||
// Maintains a list of live databases per origin.
|
||||
nsClassHashtable<nsCStringHashKey, nsTArray<IDBDatabase*> > mLiveDatabases;
|
||||
|
||||
// Maintains a list of origins that are currently being cleared.
|
||||
nsAutoTArray<OriginClearData, 1> mOriginClearData;
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
||||
#endif /* mozilla_dom_indexeddb_indexeddatabasemanager_h__ */
|
|
@ -65,6 +65,7 @@ CPPSRCS = \
|
|||
IDBRequest.cpp \
|
||||
IDBTransaction.cpp \
|
||||
IDBFactory.cpp \
|
||||
IndexedDatabaseManager.cpp \
|
||||
LazyIdleThread.cpp \
|
||||
TransactionThreadPool.cpp \
|
||||
$(NULL)
|
||||
|
@ -79,6 +80,7 @@ EXPORTS_mozilla/dom/indexedDB = \
|
|||
IDBRequest.h \
|
||||
IDBTransaction.h \
|
||||
IndexedDatabase.h \
|
||||
IndexedDatabaseManager.h \
|
||||
IDBFactory.h \
|
||||
LazyIdleThread.h \
|
||||
$(NULL)
|
||||
|
@ -108,6 +110,7 @@ XPIDLSRCS = \
|
|||
nsIIDBTransaction.idl \
|
||||
nsIIDBTransactionEvent.idl \
|
||||
nsIIDBFactory.idl \
|
||||
nsIIndexedDatabaseManager.idl \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
|
|
|
@ -143,6 +143,13 @@ TransactionThreadPool::GetOrCreate()
|
|||
return gInstance;
|
||||
}
|
||||
|
||||
// static
|
||||
TransactionThreadPool*
|
||||
TransactionThreadPool::Get()
|
||||
{
|
||||
return gInstance;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
TransactionThreadPool::Shutdown()
|
||||
|
@ -384,6 +391,10 @@ TransactionThreadPool::Dispatch(IDBTransaction* aTransaction,
|
|||
NS_ASSERTION(aTransaction, "Null pointer!");
|
||||
NS_ASSERTION(aRunnable, "Null pointer!");
|
||||
|
||||
if (aTransaction->mDatabase->IsInvalidated() && !aFinish) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool canRun;
|
||||
TransactionQueue* existingQueue;
|
||||
nsresult rv = TransactionCanRun(aTransaction, &canRun, &existingQueue);
|
||||
|
@ -472,6 +483,24 @@ TransactionThreadPool::Dispatch(IDBTransaction* aTransaction,
|
|||
return mThreadPool->Dispatch(transactionInfo->queue, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
TransactionThreadPool::WaitForAllTransactionsToComplete(IDBDatabase* aDatabase)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
const PRUint32 databaseId = aDatabase->Id();
|
||||
nsIThread* currentThread = NS_GetCurrentThread();
|
||||
|
||||
// As soon as all of the transactions for this database are complete its
|
||||
// entry in mTransactionsInProgress will be removed, so just loop while
|
||||
// checking.
|
||||
while (mTransactionsInProgress.Get(databaseId, nsnull)) {
|
||||
if (NS_FAILED(NS_ProcessNextEvent(currentThread, PR_TRUE))) {
|
||||
NS_WARNING("Failed to process next event?!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(TransactionThreadPool, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
|
||||
// returns a non-owning ref!
|
||||
static TransactionThreadPool* GetOrCreate();
|
||||
static TransactionThreadPool* Get();
|
||||
static void Shutdown();
|
||||
|
||||
nsresult Dispatch(IDBTransaction* aTransaction,
|
||||
|
@ -78,6 +79,8 @@ public:
|
|||
bool aFinish,
|
||||
nsIRunnable* aFinishRunnable);
|
||||
|
||||
void WaitForAllTransactionsToComplete(IDBDatabase* aDatabase);
|
||||
|
||||
protected:
|
||||
class TransactionQueue : public nsIRunnable
|
||||
{
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** 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 Indexed Database.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Turner <bent.mozilla@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
[scriptable, uuid(dba13d2e-ea4f-4011-9b66-a8b0e61a7f84)]
|
||||
interface nsIIndexedDatabaseManager : nsISupports
|
||||
{
|
||||
unsigned long long getUsageForURI(in nsIURI aURI);
|
||||
|
||||
void clearDatabasesForURI(in nsIURI aURI);
|
||||
};
|
|
@ -242,6 +242,10 @@
|
|||
#define NS_ICONTENTUTILS_CID \
|
||||
{ 0x762C4AE7, 0xB923, 0x422F, { 0xB9, 0x7E, 0xB9, 0xBF, 0xC1, 0xEF, 0x7B, 0xF0 } }
|
||||
|
||||
// {1A26A7B7-D06E-4F45-8B45-D7AD60F7A9AB}
|
||||
#define INDEXEDDB_MANAGER_CID \
|
||||
{ 0x1a26a7b7, 0xd06e, 0x4f45, { 0x8b, 0x45, 0xd7, 0xad, 0x60, 0xf7, 0xa9, 0xab } }
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
#define NS_HTMLAUDIOELEMENT_CID \
|
||||
{ /* 1d40026b-4c44-4f6f-b158-26bb5e9c65e9 */ \
|
||||
|
|
|
@ -133,6 +133,9 @@
|
|||
#include "nsDOMScriptObjectFactory.h"
|
||||
#include "nsDOMStorage.h"
|
||||
#include "nsJSON.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
|
||||
using mozilla::dom::indexedDB::IndexedDatabaseManager;
|
||||
|
||||
// Editor stuff
|
||||
#include "nsEditorCID.h"
|
||||
|
@ -321,6 +324,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
|
|||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager,
|
||||
nsDOMStorageManager::GetInstance)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChannelPolicy)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(IndexedDatabaseManager,
|
||||
IndexedDatabaseManager::GetOrCreateInstance)
|
||||
#if defined(XP_UNIX) || \
|
||||
defined(_WINDOWS) || \
|
||||
defined(machintosh) || \
|
||||
|
@ -853,6 +858,7 @@ NS_DEFINE_NAMED_CID(NS_DOMSTORAGE2_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_DOMSTORAGEMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_DOMJSON_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID);
|
||||
NS_DEFINE_NAMED_CID(INDEXEDDB_MANAGER_CID );
|
||||
#ifndef MOZILLA_PLAINTEXT_EDITOR_ONLY
|
||||
#ifdef ENABLE_EDITOR_API_LOG
|
||||
NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_CID);
|
||||
|
@ -1003,6 +1009,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
|||
{ &kNS_DOMSTORAGEMANAGER_CID, false, NULL, nsDOMStorageManagerConstructor },
|
||||
{ &kNS_DOMJSON_CID, false, NULL, NS_NewJSON },
|
||||
{ &kNS_TEXTEDITOR_CID, false, NULL, nsPlaintextEditorConstructor },
|
||||
{ &kINDEXEDDB_MANAGER_CID, false, NULL, IndexedDatabaseManagerConstructor },
|
||||
#ifndef MOZILLA_PLAINTEXT_EDITOR_ONLY
|
||||
#ifdef ENABLE_EDITOR_API_LOG
|
||||
{ &kNS_HTMLEDITOR_CID, false, NULL, nsHTMLEditorLogConstructor },
|
||||
|
@ -1147,6 +1154,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
|||
{ "@mozilla.org/dom/storagemanager;1", &kNS_DOMSTORAGEMANAGER_CID },
|
||||
{ "@mozilla.org/dom/json;1", &kNS_DOMJSON_CID },
|
||||
{ "@mozilla.org/editor/texteditor;1", &kNS_TEXTEDITOR_CID },
|
||||
{ INDEXEDDB_MANAGER_CONTRACTID, &kINDEXEDDB_MANAGER_CID },
|
||||
#ifndef MOZILLA_PLAINTEXT_EDITOR_ONLY
|
||||
#ifdef ENABLE_EDITOR_API_LOG
|
||||
{ "@mozilla.org/editor/htmleditor;1", &kNS_HTMLEDITOR_CID },
|
||||
|
|
Загрузка…
Ссылка в новой задаче