Backed out 10 changesets (bug 914944, bug 871445) for mochitest failures on a CLOSED TREE.

Backed out changeset a840638b5b18 (bug 914944)
Backed out changeset f40c7d5790bd (bug 914944)
Backed out changeset e1b288e29663 (bug 871445)
Backed out changeset 6242ddf7b6c7 (bug 871445)
Backed out changeset 7679185a8cf3 (bug 871445)
Backed out changeset 639ec7a627f8 (bug 871445)
Backed out changeset 93b050a79db4 (bug 871445)
Backed out changeset ec3382ceef99 (bug 871445)
Backed out changeset 51c0d5230306 (bug 871445)
Backed out changeset 76c9069bdb56 (bug 871445)
This commit is contained in:
Ryan VanderMeulen 2013-09-11 11:45:51 -04:00
parent f675a4f5a7
commit 1f6d0efee0
47 changed files with 22 additions and 2884 deletions

View File

@ -18,4 +18,4 @@
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 785884 - Implement support for temporary storage (aka shared pool)
Bug 785884 - Implement support for temporary storage (aka shared pool)

View File

@ -747,9 +747,6 @@ pref("disk_space_watcher.enabled", true);
// Enable promise
pref("dom.promise.enabled", false);
// Enable dataStore
pref("dom.datastore.enabled", false);
// Allow ADB to run for this many hours before disabling
// (only applies when marionette is disabled)
// 0 disables the timer.

View File

@ -6,7 +6,6 @@
Cu.import('resource://gre/modules/ContactService.jsm');
Cu.import('resource://gre/modules/SettingsChangeNotifier.jsm');
Cu.import('resource://gre/modules/DataStoreChangeNotifier.jsm');
Cu.import('resource://gre/modules/AlarmService.jsm');
Cu.import('resource://gre/modules/ActivitiesService.jsm');
Cu.import('resource://gre/modules/PermissionPromptHelper.jsm');

View File

@ -747,10 +747,6 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/components/B2GAboutRedirector.js
@BINPATH@/components/FilePicker.js
@BINPATH@/components/DataStore.manifest
@BINPATH@/components/DataStoreService.js
@BINPATH@/components/dom_datastore.xpt
#ifdef MOZ_WEBSPEECH
@BINPATH@/components/dom_webspeechsynth.xpt
#endif

View File

@ -794,8 +794,3 @@ bin/libfreebl_32int64_3.so
@BINPATH@/metro/defaults
@BINPATH@/metro/modules
#endif
@BINPATH@/components/DataStore.manifest
@BINPATH@/components/DataStoreService.js
@BINPATH@/components/dom_datastore.xpt

View File

@ -60,10 +60,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
"@mozilla.org/datastore-service;1",
"nsIDataStoreService");
XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
return Cc["@mozilla.org/system-message-internal;1"]
.getService(Ci.nsISystemMessagesInternal);
@ -264,19 +260,6 @@ this.DOMApplicationRegistry = {
}
},
updateDataStoreForApp: function(aId) {
if (!this.webapps[aId]) {
return;
}
// Create or Update the DataStore for this app
this._readManifests([{ id: aId }], (function(aResult) {
this.updateDataStore(this.webapps[aId].localId,
this.webapps[aId].manifestURL,
aResult[0]);
}).bind(this));
},
updatePermissionsForApp: function updatePermissionsForApp(aId) {
if (!this.webapps[aId]) {
return;
@ -518,7 +501,6 @@ this.DOMApplicationRegistry = {
}
this.updateOfflineCacheForApp(id);
this.updatePermissionsForApp(id);
this.updateDataStoreForApp(id);
}
// Need to update the persisted list of apps since
// installPreinstalledApp() removes the ones failing to install.
@ -540,30 +522,6 @@ this.DOMApplicationRegistry = {
}).bind(this));
},
updateDataStore: function(aId, aManifestURL, aManifest) {
if ('datastores-owned' in aManifest) {
for (let name in aManifest['datastores-owned']) {
let readonly = "access" in aManifest['datastores-owned'][name]
? aManifest['datastores-owned'][name].access == 'readonly'
: false;
dataStoreService.installDataStore(aId, name, aManifestURL, readonly);
}
}
if ('datastores-access' in aManifest) {
for (let name in aManifest['datastores-access']) {
let readonly = ("readonly" in aManifest['datastores-access'][name]) &&
!aManifest['datastores-access'][name].readonly
? false : true;
// The first release is always in readonly mode.
dataStoreService.installAccessDataStore(aId, name, aManifestURL,
/* readonly */ true);
}
}
},
// |aEntryPoint| is either the entry_point name or the null in which case we
// use the root of the manifest.
_registerSystemMessagesForEntryPoint: function(aManifest, aApp, aEntryPoint) {
@ -1313,7 +1271,7 @@ this.DOMApplicationRegistry = {
manifestURL: app.manifestURL },
true);
}
this.updateDataStore(this.webapps[id].localId, app.manifestURL, aData);
this.broadcastMessage("Webapps:PackageEvent",
{ type: "applied",
manifestURL: app.manifestURL,
@ -1517,8 +1475,6 @@ this.DOMApplicationRegistry = {
}, true);
}
this.updateDataStore(this.webapps[id].localId, app.manifestURL, app.manifest);
app.name = manifest.name;
app.csp = manifest.csp || "";
app.updateTime = Date.now();
@ -2017,10 +1973,6 @@ this.DOMApplicationRegistry = {
manifestURL: appObject.manifestURL },
true);
}
this.updateDataStore(this.webapps[aId].localId, appObject.manifestURL,
aManifest);
debug("About to fire Webapps:PackageEvent 'installed'");
this.broadcastMessage("Webapps:PackageEvent",
{ type: "installed",
@ -2122,9 +2074,6 @@ this.DOMApplicationRegistry = {
this.uninstall(aData, aData.mm);
}).bind(this));
}
this.updateDataStore(this.webapps[id].localId, this.webapps[id].manifestURL,
jsonManifest);
}
["installState", "downloadAvailable",

View File

@ -112,17 +112,9 @@ IndexedDBHelper.prototype = {
newTxn: function newTxn(txn_type, store_name, callback, successCb, failureCb) {
this.ensureDB(function () {
if (DEBUG) debug("Starting new transaction" + txn_type);
let txn = this._db.transaction(Array.isArray(store_name) ? store_name : this.dbStoreNames, txn_type);
let txn = this._db.transaction(this.dbStoreNames, txn_type);
if (DEBUG) debug("Retrieving object store", this.dbName);
let stores;
if (Array.isArray(store_name)) {
stores = [];
for (let i = 0; i < store_name.length; ++i) {
stores.push(txn.objectStore(store_name[i]));
}
} else {
stores = txn.objectStore(store_name);
}
let store = txn.objectStore(store_name);
txn.oncomplete = function (event) {
if (DEBUG) debug("Transaction complete. Returning to callback.");
@ -145,7 +137,7 @@ IndexedDBHelper.prototype = {
}
}
};
callback(txn, stores);
callback(txn, store);
}.bind(this), failureCb);
},

View File

@ -25,7 +25,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "BatteryManager.h"
#include "mozilla/dom/PowerManager.h"
#include "PowerManager.h"
#include "nsIDOMWakeLock.h"
#include "nsIPowerManagerService.h"
#include "mozilla/dom/MobileMessageManager.h"
@ -70,13 +70,13 @@
#endif
#include "nsIDOMGlobalPropertyInitializer.h"
#include "nsIDataStoreService.h"
#include "nsJSUtils.h"
#include "nsScriptNameSpaceManager.h"
#include "mozilla/dom/NavigatorBinding.h"
#include "mozilla/dom/Promise.h"
using namespace mozilla::dom::power;
// This should not be in the namespace.
DOMCI_DATA(Navigator, mozilla::dom::Navigator)
@ -1100,29 +1100,7 @@ Navigator::GetBattery(ErrorResult& aRv)
return mBatteryManager;
}
already_AddRefed<Promise>
Navigator::GetDataStores(const nsAString& aName, ErrorResult& aRv)
{
if (!mWindow || !mWindow->GetDocShell()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsCOMPtr<nsIDataStoreService> service =
do_GetService("@mozilla.org/datastore-service;1");
if (!service) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsCOMPtr<nsISupports> promise;
aRv = service->GetDataStores(mWindow, aName, getter_AddRefs(promise));
nsRefPtr<Promise> p = static_cast<Promise*>(promise.get());
return p.forget();
}
PowerManager*
power::PowerManager*
Navigator::GetMozPower(ErrorResult& aRv)
{
if (!mPowerManager) {

View File

@ -55,8 +55,6 @@ class BatteryManager;
class FMRadio;
#endif
class Promise;
class DesktopNotificationCenter;
class MobileMessageManager;
class MozIdleObserver;
@ -99,7 +97,9 @@ class BluetoothManager;
class Voicemail;
#endif
namespace power {
class PowerManager;
} // namespace power
namespace time {
class TimeManager;
@ -181,8 +181,6 @@ public:
// The XPCOM GetDoNotTrack is ok
Geolocation* GetGeolocation(ErrorResult& aRv);
battery::BatteryManager* GetBattery(ErrorResult& aRv);
already_AddRefed<Promise> GetDataStores(const nsAString &aName,
ErrorResult& aRv);
void Vibrate(uint32_t aDuration, ErrorResult& aRv);
void Vibrate(const nsTArray<uint32_t>& aDuration, ErrorResult& aRv);
void GetAppCodeName(nsString& aAppCodeName, ErrorResult& aRv)
@ -201,7 +199,7 @@ public:
{
aRv = GetBuildID(aBuildID);
}
PowerManager* GetMozPower(ErrorResult& aRv);
power::PowerManager* GetMozPower(ErrorResult& aRv);
bool JavaEnabled(ErrorResult& aRv);
bool TaintEnabled()
{
@ -329,7 +327,7 @@ private:
#ifdef MOZ_B2G_FM
nsRefPtr<FMRadio> mFMRadio;
#endif
nsRefPtr<PowerManager> mPowerManager;
nsRefPtr<power::PowerManager> mPowerManager;
nsRefPtr<MobileMessageManager> mMobileMessageManager;
#ifdef MOZ_B2G_RIL
nsRefPtr<telephony::Telephony> mTelephony;

View File

@ -777,7 +777,7 @@ DOMInterfaces = {
},
'MozPowerManager': {
'nativeType': 'mozilla::dom::PowerManager',
'nativeType': 'mozilla::dom::power::PowerManager',
},
'MozStkCommandEvent' : {

View File

@ -1,598 +0,0 @@
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict'
this.EXPORTED_SYMBOLS = ["DataStore", "DataStoreAccess"];
function debug(s) {
// dump('DEBUG DataStore: ' + s + '\n');
}
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const REVISION_ADDED = "added";
const REVISION_UPDATED = "updated";
const REVISION_REMOVED = "removed";
const REVISION_VOID = "void";
// This value has to be tuned a bit. Currently it's just a guess
// and yet we don't know if it's too low or too high.
const MAX_REQUESTS = 25;
Cu.import("resource://gre/modules/DataStoreDB.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
/* Helper functions */
function createDOMError(aWindow, aEvent) {
return new aWindow.DOMError(aEvent.target.error.name);
}
function throwInvalidArg(aWindow) {
return aWindow.Promise.reject(
new aWindow.DOMError("SyntaxError", "Non-numeric or invalid id"));
}
function throwReadOnly(aWindow) {
return aWindow.Promise.reject(
new aWindow.DOMError("ReadOnlyError", "DataStore in readonly mode"));
}
function parseIds(aId) {
function parseId(aId) {
return (isNaN(aId) || aId <= 0) ? null : aId;
}
if (!Array.isArray(aId)) {
return parseId(aId);
}
for (let i = 0; i < aId.length; ++i) {
aId[i] = parseId(aId[i]);
if (aId[i] === null) {
return null;
}
}
return aId;
}
/* Exposed DataStore object */
function ExposedDataStore(aWindow, aDataStore, aReadOnly) {
debug("ExposedDataStore created");
this.init(aWindow, aDataStore, aReadOnly);
}
ExposedDataStore.prototype = {
classDescription: "DataStore XPCOM Component",
classID: Components.ID("{db5c9602-030f-4bff-a3de-881a8de370f2}"),
contractID: "@mozilla.org/dom/datastore;1",
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]),
callbacks: [],
init: function(aWindow, aDataStore, aReadOnly) {
debug("ExposedDataStore init");
this.window = aWindow;
this.dataStore = aDataStore;
this.isReadOnly = aReadOnly;
},
receiveMessage: function(aMessage) {
debug("receiveMessage");
if (aMessage.name != "DataStore:Changed:Return:OK") {
debug("Wrong message: " + aMessage.name);
return;
}
let self = this;
this.dataStore.retrieveRevisionId(
function() {
let event = new self.window.DataStoreChangeEvent('change', aMessage.data);
self.__DOM_IMPL__.dispatchEvent(event);
},
// Forcing the reading of the revisionId
true
);
},
// Public interface :
get name() {
return this.dataStore.name;
},
get owner() {
return this.dataStore.owner;
},
get readOnly() {
return this.isReadOnly;
},
get: function(aId) {
aId = parseIds(aId);
if (aId === null) {
return throwInvalidArg(this.window);
}
let self = this;
// Promise<Object>
return this.dataStore.newDBPromise(this.window, "readonly",
function(aResolver, aTxn, aStore, aRevisionStore) {
self.dataStore.getInternal(self.window, aStore,
Array.isArray(aId) ? aId : [ aId ],
function(aResults) {
aResolver.resolve(Array.isArray(aId) ? aResults : aResults[0]);
});
}
);
},
update: function(aId, aObj) {
aId = parseInt(aId);
if (isNaN(aId) || aId <= 0) {
return throwInvalidArg(this.window);
}
if (this.isReadOnly) {
return throwReadOnly(this.window);
}
let self = this;
// Promise<void>
return this.dataStore.newDBPromise(this.window, "readwrite",
function(aResolver, aTxn, aStore, aRevisionStore) {
self.dataStore.updateInternal(self.window, aResolver, aStore, aRevisionStore, aId, aObj);
}
);
},
add: function(aObj) {
if (this.isReadOnly) {
return throwReadOnly(this.window);
}
let self = this;
// Promise<int>
return this.dataStore.newDBPromise(this.window, "readwrite",
function(aResolver, aTxn, aStore, aRevisionStore) {
self.dataStore.addInternal(self.window, aResolver, aStore, aRevisionStore, aObj);
}
);
},
remove: function(aId) {
aId = parseInt(aId);
if (isNaN(aId) || aId <= 0) {
return throwInvalidArg(this.window);
}
if (this.isReadOnly) {
return throwReadOnly(this.window);
}
let self = this;
// Promise<void>
return this.dataStore.newDBPromise(this.window, "readwrite",
function(aResolver, aTxn, aStore, aRevisionStore) {
self.dataStore.removeInternal(aResolver, aStore, aRevisionStore, aId);
}
);
},
clear: function() {
if (this.isReadOnly) {
return throwReadOnly(this.window);
}
let self = this;
// Promise<void>
return this.dataStore.newDBPromise(this.window, "readwrite",
function(aResolver, aTxn, aStore, aRevisionStore) {
self.dataStore.clearInternal(self.window, aResolver, aStore, aRevisionStore);
}
);
},
get revisionId() {
return this.dataStore.revisionId;
},
getChanges: function(aRevisionId) {
debug("GetChanges: " + aRevisionId);
if (aRevisionId === null || aRevisionId === undefined) {
return this.window.Promise.reject(
new this.window.DOMError("SyntaxError", "Invalid revisionId"));
}
let self = this;
// Promise<DataStoreChanges>
return new this.window.Promise(function(aResolver) {
debug("GetChanges promise started");
self.dataStore.db.revisionTxn(
'readonly',
function(aTxn, aStore) {
debug("GetChanges transaction success");
let request = self.dataStore.db.getInternalRevisionId(
aRevisionId,
aStore,
function(aInternalRevisionId) {
if (aInternalRevisionId == undefined) {
aResolver.resolve(undefined);
return;
}
// This object is the return value of this promise.
// Initially we use maps, and then we convert them in array.
let changes = {
revisionId: '',
addedIds: {},
updatedIds: {},
removedIds: {}
};
let request = aStore.mozGetAll(self.window.IDBKeyRange.lowerBound(aInternalRevisionId, true));
request.onsuccess = function(aEvent) {
for (let i = 0; i < aEvent.target.result.length; ++i) {
let data = aEvent.target.result[i];
switch (data.operation) {
case REVISION_ADDED:
changes.addedIds[data.objectId] = true;
break;
case REVISION_UPDATED:
// We don't consider an update if this object has been added
// or if it has been already modified by a previous
// operation.
if (!(data.objectId in changes.addedIds) &&
!(data.objectId in changes.updatedIds)) {
changes.updatedIds[data.objectId] = true;
}
break;
case REVISION_REMOVED:
let id = data.objectId;
// If the object has been added in this range of revisions
// we can ignore it and remove it from the list.
if (id in changes.addedIds) {
delete changes.addedIds[id];
} else {
changes.removedIds[id] = true;
}
if (id in changes.updatedIds) {
delete changes.updatedIds[id];
}
break;
}
}
// The last revisionId.
if (aEvent.target.result.length) {
changes.revisionId = aEvent.target.result[aEvent.target.result.length - 1].revisionId;
}
// From maps to arrays.
changes.addedIds = Object.keys(changes.addedIds).map(function(aKey) { return parseInt(aKey, 10); });
changes.updatedIds = Object.keys(changes.updatedIds).map(function(aKey) { return parseInt(aKey, 10); });
changes.removedIds = Object.keys(changes.removedIds).map(function(aKey) { return parseInt(aKey, 10); });
let wrappedObject = ObjectWrapper.wrap(changes, self.window);
aResolver.resolve(wrappedObject);
};
}
);
},
function(aEvent) {
debug("GetChanges transaction failed");
aResolver.reject(createDOMError(self.window, aEvent));
}
);
});
},
getLength: function() {
let self = this;
// Promise<int>
return this.dataStore.newDBPromise(this.window, "readonly",
function(aResolver, aTxn, aStore, aRevisionStore) {
self.dataStore.getLengthInternal(aResolver, aStore);
}
);
},
set onchange(aCallback) {
debug("Set OnChange");
this.__DOM_IMPL__.setEventHandler("onchange", aCallback);
},
get onchange() {
debug("Get OnChange");
return this.__DOM_IMPL__.getEventHandler("onchange");
}
};
/* DataStore object */
function DataStore(aAppId, aName, aOwner, aReadOnly, aGlobalScope) {
this.appId = aAppId;
this.name = aName;
this.owner = aOwner;
this.readOnly = aReadOnly;
this.db = new DataStoreDB();
this.db.init(aOwner, aName, aGlobalScope);
}
DataStore.prototype = {
appId: null,
name: null,
owner: null,
readOnly: null,
revisionId: null,
newDBPromise: function(aWindow, aTxnType, aFunction) {
let db = this.db;
return new aWindow.Promise(function(aResolver) {
debug("DBPromise started");
db.txn(
aTxnType,
function(aTxn, aStore, aRevisionStore) {
debug("DBPromise success");
aFunction(aResolver, aTxn, aStore, aRevisionStore);
},
function(aEvent) {
debug("DBPromise error");
aResolver.reject(createDOMError(aWindow, aEvent));
}
);
});
},
getInternal: function(aWindow, aStore, aIds, aCallback) {
debug("GetInternal: " + aIds.toSource());
// Creation of the results array.
let results = new Array(aIds.length);
// We're going to create this amount of requests.
let pendingIds = aIds.length;
let indexPos = 0;
function getInternalSuccess(aEvent, aPos) {
debug("GetInternal success. Record: " + aEvent.target.result);
results[aPos] = aEvent.target.result;
if (!--pendingIds) {
aCallback(results);
return;
}
if (indexPos < aIds.length) {
// Just MAX_REQUESTS requests at the same time.
let count = 0;
while (indexPos < aIds.length && ++count < MAX_REQUESTS) {
getInternalRequest();
}
}
}
function getInternalRequest() {
let currentPos = indexPos++;
let request = aStore.get(aIds[currentPos]);
request.onsuccess = function(aEvent) {
getInternalSuccess(aEvent, currentPos);
}
}
getInternalRequest();
},
updateInternal: function(aWindow, aResolver, aStore, aRevisionStore, aId, aObj) {
debug("UpdateInternal " + aId);
let self = this;
let request = aStore.put(aObj, aId);
request.onsuccess = function(aEvent) {
debug("UpdateInternal success");
self.addRevision(aRevisionStore, aId, REVISION_UPDATED,
function() {
debug("UpdateInternal - revisionId increased");
// No wrap here because the result is always a int.
aResolver.resolve(aEvent.target.result);
}
);
};
},
addInternal: function(aWindow, aResolver, aStore, aRevisionStore, aObj) {
debug("AddInternal");
let self = this;
let request = aStore.put(aObj);
request.onsuccess = function(aEvent) {
debug("Request successful. Id: " + aEvent.target.result);
self.addRevision(aRevisionStore, aEvent.target.result, REVISION_ADDED,
function() {
debug("AddInternal - revisionId increased");
// No wrap here because the result is always a int.
aResolver.resolve(aEvent.target.result);
}
);
};
},
removeInternal: function(aResolver, aStore, aRevisionStore, aId) {
debug("RemoveInternal");
let self = this;
let request = aStore.get(aId);
request.onsuccess = function(aEvent) {
debug("RemoveInternal success. Record: " + aEvent.target.result);
if (aEvent.target.result === undefined) {
aResolver.resolve(false);
return;
}
let deleteRequest = aStore.delete(aId);
deleteRequest.onsuccess = function() {
debug("RemoveInternal success");
self.addRevision(aRevisionStore, aId, REVISION_REMOVED,
function() {
aResolver.resolve(true);
}
);
};
};
},
clearInternal: function(aWindow, aResolver, aStore, aRevisionStore) {
debug("ClearInternal");
let self = this;
let request = aStore.clear();
request.onsuccess = function() {
debug("ClearInternal success");
self.db.clearRevisions(aRevisionStore,
function() {
debug("Revisions cleared");
self.addRevision(aRevisionStore, 0, REVISION_VOID,
function() {
debug("ClearInternal - revisionId increased");
aResolver.resolve();
}
);
}
);
};
},
getLengthInternal: function(aResolver, aStore) {
debug("GetLengthInternal");
let request = aStore.count();
request.onsuccess = function(aEvent) {
debug("GetLengthInternal success: " + aEvent.target.result);
// No wrap here because the result is always a int.
aResolver.resolve(aEvent.target.result);
};
},
addRevision: function(aRevisionStore, aId, aType, aSuccessCb) {
let self = this;
this.db.addRevision(aRevisionStore, aId, aType,
function(aRevisionId) {
self.revisionId = aRevisionId;
self.sendNotification(aId, aType, aRevisionId);
aSuccessCb();
}
);
},
retrieveRevisionId: function(aSuccessCb, aForced) {
if (this.revisionId != null && !aForced) {
aSuccessCb();
return;
}
let self = this;
this.db.revisionTxn(
'readwrite',
function(aTxn, aRevisionStore) {
debug("RetrieveRevisionId transaction success");
let request = aRevisionStore.openCursor(null, 'prev');
request.onsuccess = function(aEvent) {
let cursor = aEvent.target.result;
if (!cursor) {
// If the revision doesn't exist, let's create the first one.
self.addRevision(aRevisionStore, 0, REVISION_VOID,
function(aRevisionId) {
self.revisionId = aRevisionId;
aSuccessCb();
}
);
return;
}
self.revisionId = cursor.value.revisionId;
aSuccessCb();
};
}
);
},
exposeObject: function(aWindow, aReadOnly) {
debug("Exposing Object");
let exposedObject = new ExposedDataStore(aWindow, this, aReadOnly);
let object = aWindow.DataStore._create(aWindow, exposedObject);
Services.obs.addObserver(function(aSubject, aTopic, aData) {
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == exposedObject.innerWindowID) {
cpmm.removeMessageListener("DataStore:Changed:Return:OK", exposedObject);
}
}, "inner-window-destroyed", false);
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
exposedObject.innerWindowID = util.currentInnerWindowID;
cpmm.addMessageListener("DataStore:Changed:Return:OK", exposedObject);
cpmm.sendAsyncMessage("DataStore:RegisterForMessages",
{ store: this.name, owner: this.owner });
return object;
},
delete: function() {
this.db.delete();
},
sendNotification: function(aId, aOperation, aRevisionId) {
debug("SendNotification");
if (aOperation != REVISION_VOID) {
cpmm.sendAsyncMessage("DataStore:Changed",
{ store: this.name, owner: this.owner,
message: { revisionId: aRevisionId, id: aId,
operation: aOperation } } );
}
}
};
/* DataStoreAccess */
function DataStoreAccess(aAppId, aName, aOrigin, aReadOnly) {
this.appId = aAppId;
this.name = aName;
this.origin = aOrigin;
this.readOnly = aReadOnly;
}
DataStoreAccess.prototype = {};

View File

@ -1,2 +0,0 @@
component {d193d0e2-c677-4a7b-bb0a-19155b470f2e} DataStoreService.js
contract @mozilla.org/datastore-service;1 {d193d0e2-c677-4a7b-bb0a-19155b470f2e}

View File

@ -1,110 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
this.EXPORTED_SYMBOLS = ["DataStoreChangeNotifier"];
function debug(s) {
//dump('DEBUG DataStoreChangeNotifier: ' + s + '\n');
}
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const kFromDataStoreChangeNotifier = "fromDataStoreChangeNotifier";
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageBroadcaster");
this.DataStoreChangeNotifier = {
children: [],
messages: [ "DataStore:Changed", "DataStore:RegisterForMessages",
"child-process-shutdown" ],
init: function() {
debug("init");
this.messages.forEach((function(msgName) {
ppmm.addMessageListener(msgName, this);
}).bind(this));
Services.obs.addObserver(this, 'xpcom-shutdown', false);
},
observe: function(aSubject, aTopic, aData) {
debug("observe");
switch (aTopic) {
case 'xpcom-shutdown':
this.messages.forEach((function(msgName) {
ppmm.removeMessageListener(msgName, this);
}).bind(this));
Services.obs.removeObserver(this, 'xpcom-shutdown');
ppmm = null;
break;
default:
debug("Wrong observer topic: " + aTopic);
break;
}
},
broadcastMessage: function broadcastMessage(aMsgName, aData) {
debug("Broadast");
this.children.forEach(function(obj) {
if (obj.store == aData.store && obj.owner == aData.owner) {
obj.mm.sendAsyncMessage(aMsgName, aData.message);
}
});
},
receiveMessage: function(aMessage) {
debug("receiveMessage");
switch (aMessage.name) {
case "DataStore:Changed":
this.broadcastMessage("DataStore:Changed:Return:OK", aMessage.data);
break;
case "DataStore:RegisterForMessages":
debug("Register!");
for (let i = 0; i < this.children.length; ++i) {
if (this.children[i].mm == aMessage.target &&
this.children[i].store == aMessage.data.store &&
this.children[i].owner == aMessage.data.owner) {
return;
}
}
this.children.push({ mm: aMessage.target,
store: aMessage.data.store,
owner: aMessage.data.owner });
break;
case "child-process-shutdown":
debug("Unregister");
for (let i = 0; i < this.children.length;) {
if (this.children[i].mm == aMessage.target) {
debug("Unregister index: " + i);
this.children.splice(i, 1);
} else {
++i;
}
}
break;
default:
debug("Wrong message: " + aMessage.name);
}
}
}
DataStoreChangeNotifier.init();

View File

@ -1,104 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
this.EXPORTED_SYMBOLS = ['DataStoreDB'];
function debug(s) {
// dump('DEBUG DataStoreDB: ' + s + '\n');
}
const DATASTOREDB_VERSION = 1;
const DATASTOREDB_OBJECTSTORE_NAME = 'DataStoreDB';
const DATASTOREDB_REVISION = 'revision';
const DATASTOREDB_REVISION_INDEX = 'revisionIndex';
Cu.import('resource://gre/modules/IndexedDBHelper.jsm');
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
this.DataStoreDB = function DataStoreDB() {}
DataStoreDB.prototype = {
__proto__: IndexedDBHelper.prototype,
upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
debug('updateSchema');
aDb.createObjectStore(DATASTOREDB_OBJECTSTORE_NAME, { autoIncrement: true });
let store = aDb.createObjectStore(DATASTOREDB_REVISION,
{ autoIncrement: true,
keyPath: 'internalRevisionId' });
store.createIndex(DATASTOREDB_REVISION_INDEX, 'revisionId', { unique: true });
},
init: function(aOrigin, aName, aGlobal) {
let dbName = aOrigin + '_' + aName;
this.initDBHelper(dbName, DATASTOREDB_VERSION,
[DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION], aGlobal);
},
txn: function(aType, aCallback, aErrorCb) {
debug('Transaction request');
this.newTxn(
aType,
aType == 'readonly'
? [ DATASTOREDB_OBJECTSTORE_NAME ] : [ DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION ],
function(aTxn, aStores) {
aType == 'readonly' ? aCallback(aTxn, aStores[0], null) : aCallback(aTxn, aStores[0], aStores[1]);
},
function() {},
aErrorCb
);
},
revisionTxn: function(aType, aCallback, aErrorCb) {
debug("Transaction request");
this.newTxn(
aType,
DATASTOREDB_REVISION,
aCallback,
function() {},
aErrorCb
);
},
addRevision: function(aStore, aId, aType, aSuccessCb) {
debug("AddRevision: " + aId + " - " + aType);
let revisionId = uuidgen.generateUUID().toString();
let request = aStore.put({ revisionId: revisionId, objectId: aId, operation: aType });
request.onsuccess = function() {
aSuccessCb(revisionId);
}
},
getInternalRevisionId: function(aRevisionId, aStore, aSuccessCb) {
debug('GetInternalRevisionId');
let request = aStore.index(DATASTOREDB_REVISION_INDEX).getKey(aRevisionId);
request.onsuccess = function(aEvent) {
aSuccessCb(aEvent.target.result);
}
},
clearRevisions: function(aStore, aSuccessCb) {
debug("ClearRevisions");
let request = aStore.clear();
request.onsuccess = function() {
aSuccessCb();
}
},
delete: function() {
debug('delete');
this.close();
this.dbGlobal.indexedDB.deleteDatabase(this.dbName);
debug('database deleted');
}
}

View File

@ -1,194 +0,0 @@
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict'
/* static functions */
function debug(s) {
// dump('DEBUG DataStoreService: ' + s + '\n');
}
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/DataStore.jsm');
const GLOBAL_SCOPE = this;
/* DataStoreService */
const DATASTORESERVICE_CID = Components.ID('{d193d0e2-c677-4a7b-bb0a-19155b470f2e}');
function DataStoreService() {
debug('DataStoreService Constructor');
let obs = Services.obs;
if (!obs) {
debug("DataStore Error: observer-service is null!");
return;
}
obs.addObserver(this, 'webapps-clear-data', false);
let idbManager = Cc["@mozilla.org/dom/indexeddb/manager;1"]
.getService(Ci.nsIIndexedDatabaseManager);
if (!idbManager) {
debug("DataStore Error: indexedDb Manager is null!");
}
idbManager.initWindowless(GLOBAL_SCOPE);
}
DataStoreService.prototype = {
// Hash of DataStores
stores: {},
accessStores: {},
installDataStore: function(aAppId, aName, aOwner, aReadOnly) {
debug('installDataStore - appId: ' + aAppId + ', aName: ' +
aName + ', aOwner:' + aOwner + ', aReadOnly: ' +
aReadOnly);
if (aName in this.stores && aAppId in this.stores[aName]) {
debug('This should not happen');
return;
}
let store = new DataStore(aAppId, aName, aOwner, aReadOnly, GLOBAL_SCOPE);
if (!(aName in this.stores)) {
this.stores[aName] = {};
}
this.stores[aName][aAppId] = store;
},
installAccessDataStore: function(aAppId, aName, aOwner, aReadOnly) {
debug('installDataStore - appId: ' + aAppId + ', aName: ' +
aName + ', aOwner:' + aOwner + ', aReadOnly: ' +
aReadOnly);
if (aName in this.accessStores && aAppId in this.accessStores[aName]) {
debug('This should not happen');
return;
}
let accessStore = new DataStoreAccess(aAppId, aName, aOwner, aReadOnly);
if (!(aName in this.accessStores)) {
this.accessStores[aName] = {};
}
this.accessStores[aName][aAppId] = accessStore;
},
getDataStores: function(aWindow, aName) {
debug('getDataStores - aName: ' + aName);
let appId = aWindow.document.nodePrincipal.appId;
let self = this;
return new aWindow.Promise(function(resolver) {
let matchingStores = [];
if (aName in self.stores) {
if (appId in self.stores[aName]) {
matchingStores.push({ store: self.stores[aName][appId],
readonly: false });
}
for (var i in self.stores[aName]) {
if (i == appId) {
continue;
}
let access = self.getDataStoreAccess(self.stores[aName][i], appId);
if (!access) {
continue;
}
let readOnly = self.stores[aName][i].readOnly || access.readOnly;
matchingStores.push({ store: self.stores[aName][i],
readonly: readOnly });
}
}
let callbackPending = matchingStores.length;
let results = [];
if (!callbackPending) {
resolver.resolve(results);
return;
}
for (let i = 0; i < matchingStores.length; ++i) {
let obj = matchingStores[i].store.exposeObject(aWindow,
matchingStores[i].readonly);
results.push(obj);
matchingStores[i].store.retrieveRevisionId(
function() {
--callbackPending;
if (!callbackPending) {
resolver.resolve(results);
}
},
// if the revision is already known, we don't need to retrieve it
// again.
false
);
}
});
},
getDataStoreAccess: function(aStore, aAppId) {
if (!(aStore.name in this.accessStores) ||
!(aAppId in this.accessStores[aStore.name])) {
return null;
}
return this.accessStores[aStore.name][aAppId];
},
observe: function observe(aSubject, aTopic, aData) {
debug('getDataStores - aTopic: ' + aTopic);
if (aTopic != 'webapps-clear-data') {
return;
}
let params =
aSubject.QueryInterface(Ci.mozIApplicationClearPrivateDataParams);
// DataStore is explosed to apps, not browser content.
if (params.browserOnly) {
return;
}
for (let key in this.stores) {
if (params.appId in this.stores[key]) {
this.stores[key][params.appId].delete();
delete this.stores[key][params.appId];
}
if (!this.stores[key].length) {
delete this.stores[key];
}
}
},
classID : DATASTORESERVICE_CID,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataStoreService,
Ci.nsIObserver]),
classInfo: XPCOMUtils.generateCI({
classID: DATASTORESERVICE_CID,
contractID: '@mozilla.org/datastore-service;1',
interfaces: [Ci.nsIDataStoreService, Ci.nsIObserver],
flags: Ci.nsIClassInfo.SINGLETON
})
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataStoreService]);

View File

@ -1,26 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += ['tests']
XPIDL_SOURCES += [
'nsIDataStoreService.idl',
]
XPIDL_MODULE = 'dom_datastore'
MODULE = 'dom'
EXTRA_COMPONENTS += [
'DataStore.manifest',
'DataStoreService.js',
]
EXTRA_JS_MODULES += [
'DataStore.jsm',
'DataStoreChangeNotifier.jsm',
'DataStoreDB.jsm',
]

View File

@ -1,25 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIDOMWindow;
[scriptable, uuid(d193d0e2-c677-4a7b-bb0a-19155b470f2e)]
interface nsIDataStoreService : nsISupports
{
void installDataStore(in unsigned long appId,
in DOMString name,
in DOMString manifestURL,
in boolean readOnly);
void installAccessDataStore(in unsigned long appId,
in DOMString name,
in DOMString manifestURL,
in boolean readOnly);
nsISupports getDataStores(in nsIDOMWindow window,
in DOMString name);
};

View File

@ -1,33 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES = \
test_app_install.html \
file_app_install.html \
test_readonly.html \
file_readonly.html \
test_basic.html \
file_basic.html \
test_revision.html \
file_revision.html \
test_changes.html \
file_changes.html \
file_changes2.html \
file_app.sjs \
file_app.template.webapp \
file_app2.template.webapp \
test_arrays.html \
file_arrays.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -1,56 +0,0 @@
var gBasePath = "tests/dom/datastore/tests/";
function handleRequest(request, response) {
var query = getQuery(request);
var testToken = '';
if ('testToken' in query) {
testToken = query.testToken;
}
var template = 'file_app.template.webapp';
if ('template' in query) {
template = query.template;
}
var template = gBasePath + template;
response.setHeader("Content-Type", "application/x-web-app-manifest+json", false);
response.write(readTemplate(template).replace(/TESTTOKEN/g, testToken));
}
// Copy-pasted incantations. There ought to be a better way to synchronously read
// a file into a string, but I guess we're trying to discourage that.
function readTemplate(path) {
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("CurWorkD", Components.interfaces.nsILocalFile);
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
createInstance(Components.interfaces.nsIFileInputStream);
var cis = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Components.interfaces.nsIConverterInputStream);
var split = path.split("/");
for(var i = 0; i < split.length; ++i) {
file.append(split[i]);
}
fis.init(file, -1, -1, false);
cis.init(fis, "UTF-8", 0, 0);
var data = "";
let (str = {}) {
let read = 0;
do {
read = cis.readString(0xffffffff, str); // read as much as we can and put it in str.value
data += str.value;
} while (read != 0);
}
cis.close();
return data;
}
function getQuery(request) {
var query = {};
request.queryString.split('&').forEach(function (val) {
var [name, value] = val.split('=');
query[name] = unescape(value);
});
return query;
}

View File

@ -1,10 +0,0 @@
{
"name": "Really Rapid Release (hosted)",
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
"launch_path": "/tests/dom/datastore/tests/TESTTOKEN",
"icons": { "128": "default_icon" },
"datastores-owned" : {
"foo" : { "access": "readwrite", "description" : "This store is called foo" },
"bar" : { "access": "readonly", "description" : "This store is called bar" }
}
}

View File

@ -1,10 +0,0 @@
{
"name": "Really Rapid Release (hosted) - app 2",
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
"launch_path": "/tests/dom/datastore/tests/TESTTOKEN",
"icons": { "128": "default_icon" },
"datastores-access" : {
"foo" : { "readonly": false, "description" : "This store is called foo" },
"bar" : { "readonly": true, "description" : "This store is called bar" }
}
}

View File

@ -1,40 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - install/uninstall apps</title>
<body>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
navigator.getDataStores('bar').then(function(stores) {
is(stores.length, 1, "getDataStores('bar') returns 1 element");
is(stores[0].name, 'bar', 'The dataStore.name is bar');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore bar is in readonly');
finish();
}, cbError);
}, cbError);
</script>
</html>

View File

@ -1,108 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - add([array]) remove([array])</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gStore;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
var store = stores[0];
ok("get" in store, "store.get exists");
ok("update" in store, "store.update exists");
ok("add" in store, "store.add exists");
ok("remove" in store, "store.remove exists");
ok("clear" in store, "store.clear exists");
gStore = stores[0];
runTest();
}, cbError);
}
function testStoreAdd() {
var objects = [];
for (var i = 0; i < 300; ++i) {
objects.push(i);
}
function testStoreAddInternal() {
if (!objects.length) {
ok(true, "We inserted 300 items");
runTest();
return;
}
var obj = objects.shift();
gStore.add(obj).then(function() {
ok(true, "We inserted a new item!");
testStoreAddInternal();
}, cbError);
}
testStoreAddInternal();
}
function testStoreGet() {
var objects = [];
for (var i = 1; i <= 300; ++i) {
objects.push(i);
}
gStore.get(objects).then(function(data) {
is(data.length, objects.length, "Get - Data matches");
for (var i = 0; i < data.length; ++i) {
is(data[i], objects[i] - 1, "Get - Data matches: " + i + " " + data[i] + " == " + objects[i]);
}
runTest();
}, cbError);
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Add many items
function() { testStoreAdd() },
function() { testStoreGet() },
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</body>
</html>

View File

@ -1,149 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gStore;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
var store = stores[0];
ok("get" in store, "store.get exists");
ok("update" in store, "store.update exists");
ok("add" in store, "store.add exists");
ok("remove" in store, "store.remove exists");
ok("clear" in store, "store.clear exists");
gStore = stores[0];
runTest();
}, cbError);
}
function testStoreGet(id, value) {
gStore.get(id).then(function(what) {
ok(true, "store.get() retrieves data");
is(what, value, "store.get(" + id + ") returns " + value);
}, function() {
ok(false, "store.get(" + id + ") retrieves data");
}).then(runTest, cbError);
}
function testStoreAdd(value) {
return gStore.add(value).then(function(what) {
ok(true, "store.add() is called");
ok(what > 0, "store.add() returns something");
return what;
}, cbError);
}
function testStoreUpdate(id, value) {
return gStore.update(id, value).then(function() {
ok(true, "store.update() is called");
}, cbError);
}
function testStoreGetLength(number) {
return gStore.getLength().then(function(n) {
is(number, n, "store.getLength() returns the right number");
}, cbError);
}
function testStoreRemove(id) {
return gStore.remove(id).then(function() {
ok(true, "store.remove() is called");
}, cbError);
}
function testStoreClear() {
return gStore.clear().then(function() {
ok(true, "store.clear() is called");
}, cbError);
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Unknown ID
function() { testStoreGet(42, undefined); },
function() { testStoreGet(42, undefined); }, // twice
// Add + Get - number
function() { testStoreAdd(42).then(function(id) {
gId = id; runTest(); }, cbError); },
function() { testStoreGet(gId, 42); },
function() { testStoreGet(gId + "", 42); },
// Add + Get - boolean
function() { testStoreAdd(true).then(function(id) {
gId = id; runTest(); }, cbError); },
function() { testStoreGet(gId, true); },
// Add + Get - string
function() { testStoreAdd("hello world").then(function(id) {
gId = id; runTest(); }, cbError); },
function() { testStoreGet(gId, "hello world"); },
// Update + Get - string
function() { testStoreUpdate(gId, "hello world 2").then(function() {
runTest(); }, cbError); },
function() { testStoreGet(gId, "hello world 2"); },
// getLength
function() { testStoreGetLength(3).then(function() { runTest(); }, cbError); },
// Remove
function() { testStoreRemove(gId).then(function(what) {
runTest(); }, cbError); },
function() { testStoreGet(gId).catch(function() {
runTest(); }); },
// Remove - wrong ID
function() { testStoreRemove(gId).then(function(what) {
runTest(); }, cbError); },
// Clear
function() { testStoreClear().then(function(what) {
runTest(); }, cbError); },
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</body>
</html>

View File

@ -1,135 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
var gStore;
var gChangeId = null;
var gChangeOperation = null;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
gStore = stores[0];
runTest();
}, cbError);
}
function testStoreAdd(value, expectedId) {
gStore.add(value).then(function(id) {
is(id, expectedId, "store.add() is called");
}, cbError);
}
function testStoreUpdate(id, value) {
gStore.update(id, value).then(function(retId) {
is(id, retId, "store.update() is called with the right id");
}, cbError);
}
function testStoreRemove(id, expectedSuccess) {
gStore.remove(id).then(function(success) {
is(success, expectedSuccess, "store.remove() returns the right value");
}, cbError);
}
function eventListener(evt) {
ok(evt, "OnChangeListener is called with data");
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(evt.revisionId), true, "event.revisionId returns something");
is(evt.id, gChangeId, "OnChangeListener is called with the right ID: " + evt.id);
is(evt.operation, gChangeOperation, "OnChangeListener is called with the right operation:" + evt.operation + " " + gChangeOperation);
runTest();
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Add onchange = function
function() {
gStore.onchange = eventListener;
is(gStore.onchange, eventListener, "onChange is set");
runTest();
},
// Add
function() { gChangeId = 1; gChangeOperation = 'added';
testStoreAdd({ number: 42 }, 1); },
// Update
function() { gChangeId = 1; gChangeOperation = 'updated';
testStoreUpdate(1, { number: 43 }); },
// Remove
function() { gChangeId = 1; gChangeOperation = 'removed';
testStoreRemove(1, true); },
// Remove onchange function and replace it with addEventListener
function() {
gStore.onchange = null;
gStore.addEventListener('change', eventListener);
runTest();
},
// Add
function() { gChangeId = 2; gChangeOperation = 'added';
testStoreAdd({ number: 42 }, 2); },
// Update
function() { gChangeId = 2; gChangeOperation = 'updated';
testStoreUpdate(2, { number: 43 }); },
// Remove
function() { gChangeId = 2; gChangeOperation = 'removed';
testStoreRemove(2, true); },
// Remove event listener
function() {
gStore.removeEventListener('change', eventListener);
runTest();
},
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</pre>
</body>
</html>

View File

@ -1,46 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function eventListener(obj) {
ok(obj, "OnChangeListener is called with data");
finish();
}
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
stores[0].onchange = eventListener;
alert('READY');
});
</script>
</pre>
</body>
</html>

View File

@ -1,72 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
dump((a === b ? 'OK' : 'KO') + ' ' + msg + "\n")
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function runTest() {
navigator.getDataStores('bar').then(function(stores) {
is(stores.length, 1, "getDataStores('bar') returns 1 element");
is(stores[0].name, 'bar', 'The dataStore.name is bar');
is(stores[0].readOnly, true, 'The dataStore bar is eadonly');
var store = stores[0];
ok("get" in store, "store.get exists");
ok("update" in store, "store.update exists");
ok("add" in store, "store.add exists");
ok("remove" in store, "store.remove exists");
ok("clear" in store, "store.clear exists");
var f = store.clear();
f = f.then(cbError, function() {
ok(true, "store.clear() fails because the db is readonly");
return store.remove(123);
});
f = f.then(cbError, function() {
ok(true, "store.remove() fails because the db is readonly");
return store.add(123, true);
});
f = f.then(cbError, function() {
ok(true, "store.add() fails because the db is readonly");
return store.update(123, {});
})
f = f.then(cbError, function() {
ok(true, "store.update() fails because the db is readonly");
})
f.then(function() {
// All done.
ok(true, "All done");
finish();
});
}, cbError);
}
runTest();
</script>
</body>
</html>

View File

@ -1,196 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
var gStore;
var gPreviousRevisionId = '';
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function isnot(a, b, msg) {
alert((a !== b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
gStore = stores[0];
runTest();
}, cbError);
}
function testStoreAdd(value, expectedId) {
return gStore.add(value).then(function(id) {
is(id, expectedId, "store.add() is called");
runTest();
}, cbError);
}
function testStoreUpdate(id, value) {
return gStore.update(id, value).then(function(retId) {
is(id, retId, "store.update() is called with the right id");
runTest();
}, cbError);
}
function testStoreRemove(id, expectedSuccess) {
return gStore.remove(id).then(function(success) {
is(success, expectedSuccess, "store.remove() returns the right value");
runTest();
}, cbError);
}
function testStoreRevisionId() {
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(gStore.revisionId), true, "store.revisionId returns something");
runTest();
}
function testStoreWrongRevisions(id) {
return gStore.getChanges(id).then(
function(what) {
is(what, undefined, "Wrong revisionId == undefined object");
runTest();
}, cbError);
}
function testStoreRevisions(id, changes) {
return gStore.getChanges(id).then(function(what) {
is(JSON.stringify(changes.addedIds),
JSON.stringify(what.addedIds), "store.revisions - addedIds: " +
JSON.stringify(what.addedIds) + " | " + JSON.stringify(changes.addedIds));
is(JSON.stringify(changes.updatedIds),
JSON.stringify(what.updatedIds), "store.revisions - updatedIds: " +
JSON.stringify(what.updatedIds) + " | " + JSON.stringify(changes.updatedIds));
is(JSON.stringify(changes.removedIds),
JSON.stringify(what.removedIds), "store.revisions - removedIds: " +
JSON.stringify(what.removedIds) + " | " + JSON.stringify(changes.removedIds));
runTest();
}, cbError);
}
function testStoreRevisionIdChanged() {
isnot(gStore.revisionId, gPreviousRevisionId, "Revision changed");
gPreviousRevisionId = gStore.revisionId;
runTest();
}
function testStoreRevisionIdNotChanged() {
is(gStore.revisionId, gPreviousRevisionId, "Revision changed");
runTest();
}
var revisions = [];
var tests = [
// Test for GetDataStore
testGetDataStores,
// The first revision is not empty
testStoreRevisionIdChanged,
// wrong revision ID
function() { testStoreWrongRevisions('foobar'); },
// Add
function() { testStoreAdd({ number: 42 }, 1); },
function() { revisions.push(gStore.revisionId); testStoreRevisionId(); },
testStoreRevisionIdChanged,
function() { testStoreRevisions(revisions[0], { addedIds: [], updatedIds: [], removedIds: [] }); },
// Add
function() { testStoreAdd({ number: 42 }, 2); },
function() { revisions.push(gStore.revisionId); runTest(); },
testStoreRevisionIdChanged,
function() { testStoreRevisions(revisions[0], { addedIds: [2], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[1], { addedIds: [], updatedIds: [], removedIds: [] }); },
// Add
function() { testStoreAdd({ number: 42 }, 3); },
function() { revisions.push(gStore.revisionId); runTest(); },
testStoreRevisionIdChanged,
function() { testStoreRevisions(revisions[0], { addedIds: [2,3], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[1], { addedIds: [3], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[2], { addedIds: [], updatedIds: [], removedIds: [] }); },
// Update
function() { testStoreUpdate(3, { number: 43 }); },
function() { revisions.push(gStore.revisionId); runTest(); },
testStoreRevisionIdChanged,
function() { testStoreRevisions(revisions[0], { addedIds: [2,3], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[1], { addedIds: [3], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[2], { addedIds: [], updatedIds: [3], removedIds: [] }); },
function() { testStoreRevisions(revisions[3], { addedIds: [], updatedIds: [], removedIds: [] }); },
// Update
function() { testStoreUpdate(3, { number: 42 }); },
function() { revisions.push(gStore.revisionId); runTest(); },
testStoreRevisionIdChanged,
function() { testStoreRevisions(revisions[0], { addedIds: [2,3], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[1], { addedIds: [3], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[2], { addedIds: [], updatedIds: [3], removedIds: [] }); },
function() { testStoreRevisions(revisions[3], { addedIds: [], updatedIds: [3], removedIds: [] }); },
function() { testStoreRevisions(revisions[4], { addedIds: [], updatedIds: [], removedIds: [] }); },
// Remove
function() { testStoreRemove(3, true); },
function() { revisions.push(gStore.revisionId); runTest(); },
testStoreRevisionIdChanged,
function() { testStoreRevisions(revisions[0], { addedIds: [2], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[1], { addedIds: [], updatedIds: [], removedIds: [] }); },
function() { testStoreRevisions(revisions[2], { addedIds: [], updatedIds: [], removedIds: [3] }); },
function() { testStoreRevisions(revisions[3], { addedIds: [], updatedIds: [], removedIds: [3] }); },
function() { testStoreRevisions(revisions[4], { addedIds: [], updatedIds: [], removedIds: [3] }); },
function() { testStoreRevisions(revisions[5], { addedIds: [], updatedIds: [], removedIds: [] }); },
function() { testStoreRemove(3, false); },
testStoreRevisionIdNotChanged,
// Remove
function() { testStoreRemove(42, false); },
testStoreRevisionIdNotChanged,
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</pre>
</body>
</html>

View File

@ -1,5 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

View File

@ -1,103 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - install/uninstall apps</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
SimpleTest.waitForExplicitFinish();
var gBaseURL = 'http://test/tests/dom/datastore/tests/';
var gHostedManifestURL = gBaseURL + 'file_app.sjs?testToken=file_app_install.html';
var gGenerator = runTest();
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }],
function() { gGenerator.next() });
function continueTest() {
try { gGenerator.next(); }
catch(e) { dump("Got exception: " + e + "\n"); }
}
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function runTest() {
ok("getDataStores" in navigator, "getDataStores exists");
is(typeof navigator.getDataStores, "function", "getDataStores exists and it's a function");
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 0, "getDataStores('foo') returns 0 elements");
continueTest();
}, cbError);
yield undefined;
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
SpecialPowers.autoConfirmAppInstall(continueTest);
yield undefined;
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = continueTest;
yield undefined;
var app = request.result;
isnot(app, null, "App is non-null");
is(app.manifest.description, "Updated even faster than Firefox, just to annoy slashdotters.",
"Manifest is HTML-sanitized");
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', app.manifestURL);
ifr.setAttribute('src', app.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
// Uninstall the app.
request = navigator.mozApps.mgmt.uninstall(app);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
ok(true, "All done");
finish();
}
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
function finish() {
SpecialPowers.clearUserPref("dom.mozBrowserFramesEnabled");
SimpleTest.finish();
}
</script>
</body>
</html>

View File

@ -1,121 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - add([array]) remove([array])</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_arrays.html';
var gApp;
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
runTest();
}
}
function uninstallApp() {
// Uninstall the app.
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
runTest();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var tests = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], runTest);
},
// Preferences
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true]]}, runTest);
},
function() {
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
runTest();
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(runTest);
},
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
function finish() {
SimpleTest.finish();
}
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</body>
</html>

View File

@ -1,121 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_basic.html';
var gApp;
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
runTest();
}
}
function uninstallApp() {
// Uninstall the app.
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
runTest();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var tests = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], runTest);
},
// Preferences
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true]]}, runTest);
},
function() {
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
runTest();
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(runTest);
},
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
function finish() {
SimpleTest.finish();
}
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</body>
</html>

View File

@ -1,177 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_changes.html';
var gHostedManifestURL2 = 'http://example.com/tests/dom/datastore/tests/file_app.sjs?testToken=file_changes2.html&template=file_app2.template.webapp';
var gApps = [];
var gApp2Events = 0;
var gStore;
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function installApp(aApp) {
var request = navigator.mozApps.install(aApp);
request.onerror = cbError;
request.onsuccess = function() {
gApps.push(request.result);
runTest();
}
}
function uninstallApps() {
if (!gApps.length) {
ok(true, "All done!");
runTest();
return;
}
var app = gApps.pop();
var request = navigator.mozApps.mgmt.uninstall(app);
request.onerror = cbError;
request.onsuccess = uninstallApps;
}
function setupApp2() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApps[1].manifestURL);
ifr.setAttribute('src', gApps[1].manifest.launch_path);
var domParent = document.getElementById('content');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/READY/.exec(message)) {
ok(true, "App2 ready");
runTest();
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
gApp2Events++;
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
function testApp1() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApps[0].manifestURL);
ifr.setAttribute('src', gApps[0].manifest.launch_path);
var domParent = document.getElementById('content');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
function checkApp2() {
ok(gApp2Events, "App2 received events");
runTest();
}
var tests = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], runTest);
},
// Preferences
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true]]}, runTest);
},
// Enabling mozBrowser
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(runTest);
},
// Installing the app1
function() { installApp(gHostedManifestURL); },
// Installing the app2
function() { installApp(gHostedManifestURL2); },
// Setup app2 for receving events
setupApp2,
// Run tests in app
testApp1,
// Check app2
checkApp2,
// Uninstall the apps
uninstallApps,
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
function finish() {
SimpleTest.finish();
}
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

View File

@ -1,102 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_readonly.html';
var gHostedManifestURL2 = 'http://example.com/tests/dom/datastore/tests/file_app.sjs?testToken=file_readonly.html&template=file_app2.template.webapp';
var gGenerator = runTest();
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }],
function() { gGenerator.next() });
function continueTest() {
try { gGenerator.next(); }
catch(e) {}
}
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function runTest() {
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
SpecialPowers.autoConfirmAppInstall(continueTest);
yield undefined;
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = continueTest;
yield undefined;
var app = request.result;
request = navigator.mozApps.install(gHostedManifestURL2);
request.onerror = cbError;
request.onsuccess = continueTest;
yield undefined;
var app2 = request.result;
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', app2.manifestURL);
ifr.setAttribute('src', app2.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
// Uninstall the app.
request = navigator.mozApps.mgmt.uninstall(app);
request.onerror = cbError;
request.onsuccess = function() {
// Uninstall app2
request = navigator.mozApps.mgmt.uninstall(app2);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
finish();
}
}
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
function finish() {
SpecialPowers.clearUserPref("dom.mozBrowserFramesEnabled");
SimpleTest.finish();
}
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true]]}, runTest);
</script>
</body>
</html>

View File

@ -1,132 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
var gBaseURL = 'http://test/tests/dom/datastore/tests/';
var gHostedManifestURL = gBaseURL + 'file_app.sjs?testToken=file_revision.html';
var gApp;
var gStore;
var gPreviousRevisionId = '';
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
runTest();
}
}
function uninstallApp() {
// Uninstall the app.
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
ok(true, "All done");
runTest();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('content');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var revisions = [];
var tests = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], runTest);
},
// Preferences
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true]]}, runTest);
},
// Enabling mozBrowser
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(runTest);
},
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
function finish() {
SimpleTest.finish();
}
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

View File

@ -46,7 +46,6 @@ PARALLEL_DIRS += [
'contacts',
'phonenumberutils',
'alarm',
'datastore',
'devicestorage',
'encoding',
'file',

View File

@ -3,9 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/PowerManager.h"
#include "mozilla/Hal.h"
#include "PowerManager.h"
#include "WakeLock.h"
#include "nsDOMClassInfoID.h"
#include "nsIDOMWakeLockListener.h"
@ -20,6 +19,7 @@
namespace mozilla {
namespace dom {
namespace power {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PowerManager)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -205,5 +205,6 @@ PowerManager::CreateInstance(nsPIDOMWindow* aWindow)
return powerManager.forget();
}
} // power
} // dom
} // mozilla

View File

@ -19,6 +19,7 @@ namespace mozilla {
class ErrorResult;
namespace dom {
namespace power {
class PowerManager MOZ_FINAL : public nsIDOMMozWakeLockListener
, public nsWrapperCache
@ -65,6 +66,7 @@ private:
nsTArray<nsCOMPtr<nsIDOMMozWakeLockListener> > mListeners;
};
} // namespace power
} // namespace dom
} // namespace mozilla

View File

@ -14,7 +14,7 @@
#include "nsIDOMWindow.h"
#include "nsIDOMEvent.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/PowerManager.h"
#include "PowerManager.h"
DOMCI_DATA(MozWakeLock, mozilla::dom::power::WakeLock)

View File

@ -15,11 +15,8 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'dom_power'
EXPORTS.mozilla.dom += [
'PowerManager.h',
]
EXPORTS.mozilla.dom.power += [
'PowerManager.h',
'PowerManagerService.h',
'Types.h',
]

View File

@ -1,54 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Pref="dom.datastore.enabled",
JSImplementation="@mozilla.org/dom/datastore;1"]
interface DataStore : EventTarget {
// Returns the label of the DataSource.
readonly attribute DOMString name;
// Returns the origin of the DataSource (e.g., 'facebook.com').
// This value is the manifest URL of the owner app.
readonly attribute DOMString owner;
// is readOnly a F(current_app, datastore) function? yes
readonly attribute boolean readOnly;
// Promise<any>
Promise get(unsigned long id);
// Promise<any>
Promise get(sequence<unsigned long> id);
// Promise<void>
Promise update(unsigned long id, any obj);
// Promise<unsigned long>
Promise add(any obj);
// Promise<boolean>
Promise remove(unsigned long id);
// Promise<void>
Promise clear();
readonly attribute DOMString revisionId;
attribute EventHandler onchange;
// Promise<DataStoreChanges>
Promise getChanges(DOMString revisionId);
// Promise<unsigned long>
Promise getLength();
};
dictionary DataStoreChanges {
DOMString revisionId;
sequence<unsigned long> addedIds;
sequence<unsigned long> updatedIds;
sequence<unsigned long> removedIds;
};

View File

@ -1,19 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
dictionary DataStoreChangeEventInit : EventInit {
DOMString revisionId = "";
unsigned long id = 0;
DOMString operation = "";
};
[Pref="dom.datastore.enabled",
Constructor(DOMString type, optional DataStoreChangeEventInit eventInitDict)]
interface DataStoreChangeEvent : Event {
readonly attribute DOMString revisionId;
readonly attribute unsigned long id;
readonly attribute DOMString operation;
};

View File

@ -108,14 +108,6 @@ interface NavigatorBattery {
};
Navigator implements NavigatorBattery;
// https://wiki.mozilla.org/WebAPI/DataStore
[NoInterfaceObject]
interface NavigatorDataStore {
[Throws, Creator, Pref="dom.datastore.enabled"]
Promise getDataStores(DOMString name);
};
Navigator implements NavigatorDataStore;
// http://www.w3.org/TR/vibration/#vibration-interface
partial interface Navigator {
// We don't support sequences in unions yet

View File

@ -62,7 +62,6 @@ WEBIDL_FILES = [
'CSSValue.webidl',
'CSSValueList.webidl',
'DataContainerEvent.webidl',
'DataStore.webidl',
'DelayNode.webidl',
'DesktopNotification.webidl',
'DeviceMotionEvent.webidl',
@ -543,5 +542,4 @@ if CONFIG['MOZ_B2G']:
GENERATED_EVENTS_WEBIDL_FILES = [
'BlobEvent.webidl',
'DataStoreChangeEvent.webidl',
]

View File

@ -584,7 +584,3 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/components/MarionetteComponents.manifest
@BINPATH@/components/marionettecomponent.js
#endif
@BINPATH@/components/DataStore.manifest
@BINPATH@/components/DataStoreService.js
@BINPATH@/components/dom_datastore.xpt

View File

@ -4401,6 +4401,3 @@ pref("dom.forms.inputmode", false);
#else
pref("dom.forms.inputmode", true);
#endif
// DataStore is disabled by default
pref("dom.datastore.enabled", false);

View File

@ -47,7 +47,7 @@
#include "InputDispatcher.h"
#include "Trace.h"
#include "mozilla/dom/PowerManager.h"
#include "PowerManager.h"
#include <stddef.h>
#include <unistd.h>