mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 871445 - patch 10 - DataStore: indexedDB permissions, r=ehsan
This commit is contained in:
parent
462224589b
commit
376ecbb43f
@ -284,6 +284,7 @@ this.DOMApplicationRegistry = {
|
|||||||
// Create or Update the DataStore for this app
|
// Create or Update the DataStore for this app
|
||||||
this._readManifests([{ id: aId }], (function(aResult) {
|
this._readManifests([{ id: aId }], (function(aResult) {
|
||||||
this.updateDataStore(this.webapps[aId].localId,
|
this.updateDataStore(this.webapps[aId].localId,
|
||||||
|
this.webapps[aId].origin,
|
||||||
this.webapps[aId].manifestURL,
|
this.webapps[aId].manifestURL,
|
||||||
aResult[0].manifest);
|
aResult[0].manifest);
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
@ -530,12 +531,17 @@ this.DOMApplicationRegistry = {
|
|||||||
}
|
}
|
||||||
this.updateOfflineCacheForApp(id);
|
this.updateOfflineCacheForApp(id);
|
||||||
this.updatePermissionsForApp(id);
|
this.updatePermissionsForApp(id);
|
||||||
this.updateDataStoreForApp(id);
|
|
||||||
}
|
}
|
||||||
// Need to update the persisted list of apps since
|
// Need to update the persisted list of apps since
|
||||||
// installPreinstalledApp() removes the ones failing to install.
|
// installPreinstalledApp() removes the ones failing to install.
|
||||||
this._saveApps();
|
this._saveApps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataStores must be initialized at startup.
|
||||||
|
for (let id in this.webapps) {
|
||||||
|
this.updateDataStoreForApp(id);
|
||||||
|
}
|
||||||
|
|
||||||
this.registerAppsHandlers(runUpdate);
|
this.registerAppsHandlers(runUpdate);
|
||||||
}).bind(this);
|
}).bind(this);
|
||||||
|
|
||||||
@ -552,14 +558,15 @@ this.DOMApplicationRegistry = {
|
|||||||
}).bind(this));
|
}).bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
updateDataStore: function(aId, aManifestURL, aManifest) {
|
updateDataStore: function(aId, aOrigin, aManifestURL, aManifest) {
|
||||||
if ('datastores-owned' in aManifest) {
|
if ('datastores-owned' in aManifest) {
|
||||||
for (let name in aManifest['datastores-owned']) {
|
for (let name in aManifest['datastores-owned']) {
|
||||||
let readonly = "access" in aManifest['datastores-owned'][name]
|
let readonly = "access" in aManifest['datastores-owned'][name]
|
||||||
? aManifest['datastores-owned'][name].access == 'readonly'
|
? aManifest['datastores-owned'][name].access == 'readonly'
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
dataStoreService.installDataStore(aId, name, aManifestURL, readonly);
|
dataStoreService.installDataStore(aId, name, aOrigin, aManifestURL,
|
||||||
|
readonly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,9 +576,8 @@ this.DOMApplicationRegistry = {
|
|||||||
!aManifest['datastores-access'][name].readonly
|
!aManifest['datastores-access'][name].readonly
|
||||||
? false : true;
|
? false : true;
|
||||||
|
|
||||||
// The first release is always in readonly mode.
|
dataStoreService.installAccessDataStore(aId, name, aOrigin,
|
||||||
dataStoreService.installAccessDataStore(aId, name, aManifestURL,
|
aManifestURL, readonly);
|
||||||
/* readonly */ true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1434,7 +1440,8 @@ this.DOMApplicationRegistry = {
|
|||||||
manifestURL: app.manifestURL },
|
manifestURL: app.manifestURL },
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
this.updateDataStore(this.webapps[id].localId, app.manifestURL, aData);
|
this.updateDataStore(this.webapps[id].localId, app.origin,
|
||||||
|
app.manifestURL, aData);
|
||||||
this.broadcastMessage("Webapps:PackageEvent",
|
this.broadcastMessage("Webapps:PackageEvent",
|
||||||
{ type: "applied",
|
{ type: "applied",
|
||||||
manifestURL: app.manifestURL,
|
manifestURL: app.manifestURL,
|
||||||
@ -1640,7 +1647,8 @@ this.DOMApplicationRegistry = {
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDataStore(this.webapps[id].localId, app.manifestURL, app.manifest);
|
this.updateDataStore(this.webapps[id].localId, app.origin,
|
||||||
|
app.manifestURL, app.manifest);
|
||||||
|
|
||||||
app.name = manifest.name;
|
app.name = manifest.name;
|
||||||
app.csp = manifest.csp || "";
|
app.csp = manifest.csp || "";
|
||||||
@ -2142,8 +2150,8 @@ this.DOMApplicationRegistry = {
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDataStore(this.webapps[aId].localId, appObject.manifestURL,
|
this.updateDataStore(this.webapps[aId].localId, appObject.origin,
|
||||||
aManifest);
|
appObject.manifestURL, aManifest);
|
||||||
|
|
||||||
debug("About to fire Webapps:PackageEvent 'installed'");
|
debug("About to fire Webapps:PackageEvent 'installed'");
|
||||||
this.broadcastMessage("Webapps:PackageEvent",
|
this.broadcastMessage("Webapps:PackageEvent",
|
||||||
@ -2248,8 +2256,8 @@ this.DOMApplicationRegistry = {
|
|||||||
}).bind(this));
|
}).bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDataStore(this.webapps[id].localId, this.webapps[id].manifestURL,
|
this.updateDataStore(this.webapps[id].localId, this.webapps[id].origin,
|
||||||
jsonManifest);
|
this.webapps[id].manifestURL, jsonManifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
["installState", "downloadAvailable",
|
["installState", "downloadAvailable",
|
||||||
|
@ -103,7 +103,7 @@ this.DataStore.prototype = {
|
|||||||
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||||
if (wId == self._innerWindowID) {
|
if (wId == self._innerWindowID) {
|
||||||
cpmm.removeMessageListener("DataStore:Changed:Return:OK", self);
|
cpmm.removeMessageListener("DataStore:Changed:Return:OK", self);
|
||||||
self._db.delete();
|
self._db.close();
|
||||||
}
|
}
|
||||||
}, "inner-window-destroyed", false);
|
}, "inner-window-destroyed", false);
|
||||||
|
|
||||||
@ -278,26 +278,18 @@ this.DataStore.prototype = {
|
|||||||
retrieveRevisionId: function(aSuccessCb) {
|
retrieveRevisionId: function(aSuccessCb) {
|
||||||
let self = this;
|
let self = this;
|
||||||
this._db.revisionTxn(
|
this._db.revisionTxn(
|
||||||
'readwrite',
|
'readonly',
|
||||||
function(aTxn, aRevisionStore) {
|
function(aTxn, aRevisionStore) {
|
||||||
debug("RetrieveRevisionId transaction success");
|
debug("RetrieveRevisionId transaction success");
|
||||||
|
|
||||||
let request = aRevisionStore.openCursor(null, 'prev');
|
let request = aRevisionStore.openCursor(null, 'prev');
|
||||||
request.onsuccess = function(aEvent) {
|
request.onsuccess = function(aEvent) {
|
||||||
let cursor = aEvent.target.result;
|
let cursor = aEvent.target.result;
|
||||||
if (!cursor) {
|
if (cursor) {
|
||||||
// If the revision doesn't exist, let's create the first one.
|
self._revisionId = cursor.value.revisionId;
|
||||||
self.addRevision(aRevisionStore, 0, REVISION_VOID,
|
|
||||||
function(aRevisionId) {
|
|
||||||
self._revisionId = aRevisionId;
|
|
||||||
aSuccessCb();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self._revisionId = cursor.value.revisionId;
|
aSuccessCb(self._revisionId);
|
||||||
aSuccessCb();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -475,7 +467,7 @@ this.DataStore.prototype = {
|
|||||||
removedIds: {}
|
removedIds: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let request = aStore.mozGetAll(self._window.IDBKeyRange.lowerBound(aInternalRevisionId, true));
|
let request = aStore.mozGetAll(IDBKeyRange.lowerBound(aInternalRevisionId, true));
|
||||||
request.onsuccess = function(aEvent) {
|
request.onsuccess = function(aEvent) {
|
||||||
for (let i = 0; i < aEvent.target.result.length; ++i) {
|
for (let i = 0; i < aEvent.target.result.length; ++i) {
|
||||||
let data = aEvent.target.result[i];
|
let data = aEvent.target.result[i];
|
||||||
|
@ -12,6 +12,9 @@ function debug(s) {
|
|||||||
//dump('DEBUG DataStoreChangeNotifier: ' + s + '\n');
|
//dump('DEBUG DataStoreChangeNotifier: ' + s + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataStoreServiceInternal should not be converted into a lazy getter as it
|
||||||
|
// runs code during initialization.
|
||||||
|
Cu.import('resource://gre/modules/DataStoreServiceInternal.jsm');
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ DataStoreDB.prototype = {
|
|||||||
store.createIndex(DATASTOREDB_REVISION_INDEX, 'revisionId', { unique: true });
|
store.createIndex(DATASTOREDB_REVISION_INDEX, 'revisionId', { unique: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function(aOrigin, aName) {
|
init: function(aOwner, aName) {
|
||||||
let dbName = aOrigin + '_' + aName;
|
let dbName = aName + '|' + aOwner;
|
||||||
this.initDBHelper(dbName, DATASTOREDB_VERSION,
|
this.initDBHelper(dbName, DATASTOREDB_VERSION,
|
||||||
[DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION]);
|
[DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION]);
|
||||||
},
|
},
|
||||||
|
@ -17,6 +17,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|||||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||||
Cu.import('resource://gre/modules/Services.jsm');
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
Cu.import('resource://gre/modules/DataStore.jsm');
|
Cu.import('resource://gre/modules/DataStore.jsm');
|
||||||
|
Cu.import("resource://gre/modules/DataStoreDB.jsm");
|
||||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||||
@ -27,37 +28,54 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|||||||
"@mozilla.org/parentprocessmessagemanager;1",
|
"@mozilla.org/parentprocessmessagemanager;1",
|
||||||
"nsIMessageBroadcaster");
|
"nsIMessageBroadcaster");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "permissionManager",
|
||||||
|
"@mozilla.org/permissionmanager;1",
|
||||||
|
"nsIPermissionManager");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "secMan",
|
||||||
|
"@mozilla.org/scriptsecuritymanager;1",
|
||||||
|
"nsIScriptSecurityManager");
|
||||||
|
|
||||||
/* DataStoreService */
|
/* DataStoreService */
|
||||||
|
|
||||||
const DATASTORESERVICE_CID = Components.ID('{d193d0e2-c677-4a7b-bb0a-19155b470f2e}');
|
const DATASTORESERVICE_CID = Components.ID('{d193d0e2-c677-4a7b-bb0a-19155b470f2e}');
|
||||||
|
const REVISION_VOID = "void";
|
||||||
|
|
||||||
function DataStoreService() {
|
function DataStoreService() {
|
||||||
debug('DataStoreService Constructor');
|
debug('DataStoreService Constructor');
|
||||||
|
|
||||||
let obs = Services.obs;
|
this.inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||||
if (!obs) {
|
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||||
debug("DataStore Error: observer-service is null!");
|
|
||||||
return;
|
if (this.inParent) {
|
||||||
|
let obs = Services.obs;
|
||||||
|
if (!obs) {
|
||||||
|
debug("DataStore Error: observer-service is null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs.addObserver(this, 'webapps-clear-data', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs.addObserver(this, 'webapps-clear-data', false);
|
let self = this;
|
||||||
|
cpmm.addMessageListener("datastore-first-revision-created",
|
||||||
let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
function(aMsg) { self.receiveMessage(aMsg); });
|
||||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
|
||||||
if (inParent) {
|
|
||||||
ppmm.addMessageListener("DataStore:Get", this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStoreService.prototype = {
|
DataStoreService.prototype = {
|
||||||
|
inParent: false,
|
||||||
|
|
||||||
// Hash of DataStores
|
// Hash of DataStores
|
||||||
stores: {},
|
stores: {},
|
||||||
accessStores: {},
|
accessStores: {},
|
||||||
|
pendingRequests: {},
|
||||||
|
|
||||||
installDataStore: function(aAppId, aName, aOwner, aReadOnly) {
|
installDataStore: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
||||||
debug('installDataStore - appId: ' + aAppId + ', aName: ' +
|
debug('installDataStore - appId: ' + aAppId + ', aName: ' +
|
||||||
aName + ', aOwner:' + aOwner + ', aReadOnly: ' +
|
aName + ', aOrigin: ' + aOrigin + ', aOwner:' + aOwner +
|
||||||
aReadOnly);
|
', aReadOnly: ' + aReadOnly);
|
||||||
|
|
||||||
|
this.checkIfInParent();
|
||||||
|
|
||||||
if (aName in this.stores && aAppId in this.stores[aName]) {
|
if (aName in this.stores && aAppId in this.stores[aName]) {
|
||||||
debug('This should not happen');
|
debug('This should not happen');
|
||||||
@ -68,13 +86,21 @@ DataStoreService.prototype = {
|
|||||||
this.stores[aName] = {};
|
this.stores[aName] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.stores[aName][aAppId] = { owner: aOwner, readOnly: aReadOnly };
|
// A DataStore is enabled when it has a first valid revision.
|
||||||
|
this.stores[aName][aAppId] = { origin: aOrigin, owner: aOwner,
|
||||||
|
readOnly: aReadOnly, enabled: false };
|
||||||
|
|
||||||
|
this.addPermissions(aAppId, aName, aOrigin, aOwner, aReadOnly);
|
||||||
|
|
||||||
|
this.createFirstRevisionId(aAppId, aName, aOwner);
|
||||||
},
|
},
|
||||||
|
|
||||||
installAccessDataStore: function(aAppId, aName, aOwner, aReadOnly) {
|
installAccessDataStore: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
||||||
debug('installDataStore - appId: ' + aAppId + ', aName: ' +
|
debug('installAccessDataStore - appId: ' + aAppId + ', aName: ' +
|
||||||
aName + ', aOwner:' + aOwner + ', aReadOnly: ' +
|
aName + ', aOrigin: ' + aOrigin + ', aOwner:' + aOwner +
|
||||||
aReadOnly);
|
', aReadOnly: ' + aReadOnly);
|
||||||
|
|
||||||
|
this.checkIfInParent();
|
||||||
|
|
||||||
if (aName in this.accessStores && aAppId in this.accessStores[aName]) {
|
if (aName in this.accessStores && aAppId in this.accessStores[aName]) {
|
||||||
debug('This should not happen');
|
debug('This should not happen');
|
||||||
@ -85,56 +111,231 @@ DataStoreService.prototype = {
|
|||||||
this.accessStores[aName] = {};
|
this.accessStores[aName] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.accessStores[aName][aAppId] = { owner: aOwner, readOnly: aReadOnly };
|
this.accessStores[aName][aAppId] = { origin: aOrigin, owner: aOwner,
|
||||||
|
readOnly: aReadOnly };
|
||||||
|
this.addAccessPermissions(aAppId, aName, aOrigin, aOwner, aReadOnly);
|
||||||
|
},
|
||||||
|
|
||||||
|
checkIfInParent: function() {
|
||||||
|
if (!this.inParent) {
|
||||||
|
throw "DataStore can execute this operation just in the parent process";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createFirstRevisionId: function(aAppId, aName, aOwner) {
|
||||||
|
debug("createFirstRevisionId database: " + aName);
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
let db = new DataStoreDB();
|
||||||
|
db.init(aOwner, aName);
|
||||||
|
db.revisionTxn(
|
||||||
|
'readwrite',
|
||||||
|
function(aTxn, aRevisionStore) {
|
||||||
|
debug("createFirstRevisionId - 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.
|
||||||
|
db.addRevision(aRevisionStore, 0, REVISION_VOID, function() {
|
||||||
|
debug("First revision created.");
|
||||||
|
if (aName in self.stores && aAppId in self.stores[aName]) {
|
||||||
|
self.stores[aName][aAppId].enabled = true;
|
||||||
|
ppmm.broadcastAsyncMessage('datastore-first-revision-created',
|
||||||
|
{ name: aName, owner: aOwner });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
addPermissions: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
||||||
|
// When a new DataStore is installed, the permissions must be set for the
|
||||||
|
// owner app.
|
||||||
|
let permission = "indexedDB-chrome-" + aName + '|' + aOwner;
|
||||||
|
this.resetPermissions(aAppId, aOrigin, aOwner, permission, aReadOnly);
|
||||||
|
|
||||||
|
// For any app that wants to have access to this DataStore we add the
|
||||||
|
// permissions.
|
||||||
|
if (aName in this.accessStores) {
|
||||||
|
for (let appId in this.accessStores[aName]) {
|
||||||
|
// ReadOnly is decided by the owner first.
|
||||||
|
let readOnly = aReadOnly || this.accessStores[aName][appId].readOnly;
|
||||||
|
this.resetPermissions(appId, this.accessStores[aName][appId].origin,
|
||||||
|
this.accessStores[aName][appId].owner,
|
||||||
|
permission, readOnly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addAccessPermissions: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
||||||
|
// When an app wants to have access to a DataStore, the permissions must be
|
||||||
|
// set.
|
||||||
|
if (!(aName in this.stores)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let appId in this.stores[aName]) {
|
||||||
|
let permission = "indexedDB-chrome-" + aName + '|' + this.stores[aName][appId].owner;
|
||||||
|
// The ReadOnly is decied by the owenr first.
|
||||||
|
let readOnly = this.stores[aName][appId].readOnly || aReadOnly;
|
||||||
|
this.resetPermissions(aAppId, aOrigin, aOwner, permission, readOnly);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resetPermissions: function(aAppId, aOrigin, aOwner, aPermission, aReadOnly) {
|
||||||
|
debug("ResetPermissions - appId: " + aAppId + " - origin: " + aOrigin +
|
||||||
|
" - owner: " + aOwner + " - permissions: " + aPermission +
|
||||||
|
" - readOnly: " + aReadOnly);
|
||||||
|
|
||||||
|
let uri = Services.io.newURI(aOrigin, null, null);
|
||||||
|
let principal = secMan.getAppCodebasePrincipal(uri, aAppId, false);
|
||||||
|
|
||||||
|
let result = permissionManager.testExactPermissionFromPrincipal(principal,
|
||||||
|
aPermission + '-write');
|
||||||
|
|
||||||
|
if (aReadOnly && result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
|
debug("Write permission removed");
|
||||||
|
permissionManager.removeFromPrincipal(principal, aPermission + '-write');
|
||||||
|
} else if (!aReadOnly && result != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
|
debug("Write permission added");
|
||||||
|
permissionManager.addFromPrincipal(principal, aPermission + '-write',
|
||||||
|
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = permissionManager.testExactPermissionFromPrincipal(principal,
|
||||||
|
aPermission + '-read');
|
||||||
|
if (result != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
|
debug("Read permission added");
|
||||||
|
permissionManager.addFromPrincipal(principal, aPermission + '-read',
|
||||||
|
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = permissionManager.testExactPermissionFromPrincipal(principal, aPermission);
|
||||||
|
if (result != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
|
debug("Generic permission added");
|
||||||
|
permissionManager.addFromPrincipal(principal, aPermission,
|
||||||
|
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getDataStores: function(aWindow, aName) {
|
getDataStores: function(aWindow, aName) {
|
||||||
debug('getDataStores - aName: ' + aName);
|
debug('getDataStores - aName: ' + aName);
|
||||||
|
|
||||||
// This method can be called in the child so we need to send a request to
|
let self = this;
|
||||||
// the parent and create DataStore object here.
|
|
||||||
|
|
||||||
return new aWindow.Promise(function(resolve, reject) {
|
return new aWindow.Promise(function(resolve, reject) {
|
||||||
new DataStoreServiceChild(aWindow, aName, resolve);
|
// If this request comes from the main process, we have access to the
|
||||||
|
// window, so we can skip the ipc communication.
|
||||||
|
if (self.inParent) {
|
||||||
|
let stores = self.getDataStoresInfo(aName, aWindow.document.nodePrincipal.appId);
|
||||||
|
self.getDataStoreCreate(aWindow, resolve, stores);
|
||||||
|
} else {
|
||||||
|
// This method can be called in the child so we need to send a request
|
||||||
|
// to the parent and create DataStore object here.
|
||||||
|
new DataStoreServiceChild(aWindow, aName, function(aStores) {
|
||||||
|
debug("DataStoreServiceChild callback!");
|
||||||
|
self.getDataStoreCreate(aWindow, resolve, aStores);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
receiveMessage: function(aMessage) {
|
getDataStoresInfo: function(aName, aAppId) {
|
||||||
if (aMessage.name != 'DataStore:Get') {
|
debug('GetDataStoresInfo');
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let msg = aMessage.data;
|
|
||||||
|
|
||||||
// This is a security issue and it will be fixed by Bug 916091
|
|
||||||
let appId = msg.appId;
|
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
|
|
||||||
if (msg.name in this.stores) {
|
if (aName in this.stores) {
|
||||||
if (appId in this.stores[msg.name]) {
|
if (aAppId in this.stores[aName]) {
|
||||||
results.push({ store: this.stores[msg.name][appId],
|
results.push({ name: aName,
|
||||||
readOnly: false });
|
owner: this.stores[aName][aAppId].owner,
|
||||||
|
readOnly: false,
|
||||||
|
enabled: this.stores[aName][aAppId].enabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i in this.stores[msg.name]) {
|
for (var i in this.stores[aName]) {
|
||||||
if (i == appId) {
|
if (i == aAppId) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let access = this.getDataStoreAccess(msg.name, appId);
|
let access = this.getDataStoreAccess(aName, aAppId);
|
||||||
if (!access) {
|
if (!access) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let readOnly = this.stores[msg.name][i].readOnly || access.readOnly;
|
let readOnly = this.stores[aName][i].readOnly || access.readOnly;
|
||||||
results.push({ store: this.stores[msg.name][i],
|
results.push({ name: aName,
|
||||||
readOnly: readOnly });
|
owner: this.stores[aName][i].owner,
|
||||||
|
readOnly: readOnly,
|
||||||
|
enabled: this.stores[aName][i].enabled });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.stores = results;
|
return results;
|
||||||
aMessage.target.sendAsyncMessage("DataStore:Get:Return", msg);
|
},
|
||||||
|
|
||||||
|
getDataStoreCreate: function(aWindow, aResolve, aStores) {
|
||||||
|
debug("GetDataStoreCreate");
|
||||||
|
|
||||||
|
let results = [];
|
||||||
|
|
||||||
|
if (!aStores.length) {
|
||||||
|
aResolve(results);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pendingDataStores = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < aStores.length; ++i) {
|
||||||
|
if (!aStores[i].enabled) {
|
||||||
|
pendingDataStores.push(aStores[i].owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pendingDataStores.length) {
|
||||||
|
this.getDataStoreResolve(aWindow, aResolve, aStores);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(aStores[0].name in this.pendingRequests)) {
|
||||||
|
this.pendingRequests[aStores[0].name] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingRequests[aStores[0].name].push({ window: aWindow,
|
||||||
|
resolve: aResolve,
|
||||||
|
stores: aStores,
|
||||||
|
pendingDataStores: pendingDataStores });
|
||||||
|
},
|
||||||
|
|
||||||
|
getDataStoreResolve: function(aWindow, aResolve, aStores) {
|
||||||
|
debug("GetDataStoreResolve");
|
||||||
|
|
||||||
|
let callbackPending = aStores.length;
|
||||||
|
let results = [];
|
||||||
|
|
||||||
|
if (!callbackPending) {
|
||||||
|
aResolve(results);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < aStores.length; ++i) {
|
||||||
|
let obj = new DataStore(aWindow, aStores[i].name,
|
||||||
|
aStores[i].owner, aStores[i].readOnly);
|
||||||
|
let exposedObj = aWindow.DataStore._create(aWindow, obj);
|
||||||
|
results.push(exposedObj);
|
||||||
|
|
||||||
|
obj.retrieveRevisionId(
|
||||||
|
function() {
|
||||||
|
--callbackPending;
|
||||||
|
if (!callbackPending) {
|
||||||
|
aResolve(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getDataStoreAccess: function(aName, aAppId) {
|
getDataStoreAccess: function(aName, aAppId) {
|
||||||
@ -162,6 +363,7 @@ DataStoreService.prototype = {
|
|||||||
|
|
||||||
for (let key in this.stores) {
|
for (let key in this.stores) {
|
||||||
if (params.appId in this.stores[key]) {
|
if (params.appId in this.stores[key]) {
|
||||||
|
this.deleteDatabase(key, this.stores[key][params.appId].owner);
|
||||||
delete this.stores[key][params.appId];
|
delete this.stores[key][params.appId];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +373,43 @@ DataStoreService.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deleteDatabase: function(aName, aOwner) {
|
||||||
|
debug("delete database: " + aName);
|
||||||
|
|
||||||
|
let db = new DataStoreDB();
|
||||||
|
db.init(aOwner, aName);
|
||||||
|
db.delete();
|
||||||
|
},
|
||||||
|
|
||||||
|
receiveMessage: function(aMsg) {
|
||||||
|
debug("receiveMessage");
|
||||||
|
let data = aMsg.json;
|
||||||
|
|
||||||
|
if (!(data.name in this.pendingRequests)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.pendingRequests[data.name].length;) {
|
||||||
|
let pos = this.pendingRequests[data.name][i].pendingDataStores.indexOf(data.owner);
|
||||||
|
if (pos != -1) {
|
||||||
|
this.pendingRequests[data.name][i].pendingDataStores.splice(pos, 1);
|
||||||
|
if (!this.pendingRequests[data.name][i].pendingDataStores.length) {
|
||||||
|
this.getDataStoreResolve(this.pendingRequests[data.name][i].window,
|
||||||
|
this.pendingRequests[data.name][i].resolve,
|
||||||
|
this.pendingRequests[data.name][i].stores);
|
||||||
|
this.pendingRequests[data.name].splice(i, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.pendingRequests[data.name].length) {
|
||||||
|
delete this.pendingRequests[data.name];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
classID : DATASTORESERVICE_CID,
|
classID : DATASTORESERVICE_CID,
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataStoreService,
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataStoreService,
|
||||||
Ci.nsIObserver]),
|
Ci.nsIObserver]),
|
||||||
@ -184,18 +423,17 @@ DataStoreService.prototype = {
|
|||||||
|
|
||||||
/* DataStoreServiceChild */
|
/* DataStoreServiceChild */
|
||||||
|
|
||||||
function DataStoreServiceChild(aWindow, aName, aResolve) {
|
function DataStoreServiceChild(aWindow, aName, aCallback) {
|
||||||
debug("DataStoreServiceChild created");
|
debug("DataStoreServiceChild created");
|
||||||
this.init(aWindow, aName, aResolve);
|
this.init(aWindow, aName, aCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStoreServiceChild.prototype = {
|
DataStoreServiceChild.prototype = {
|
||||||
__proto__: DOMRequestIpcHelper.prototype,
|
__proto__: DOMRequestIpcHelper.prototype,
|
||||||
|
|
||||||
init: function(aWindow, aName, aResolve) {
|
init: function(aWindow, aName, aCallback) {
|
||||||
this._window = aWindow;
|
debug("DataStoreServiceChild init");
|
||||||
this._name = aName;
|
this._callback = aCallback;
|
||||||
this._resolve = aResolve;
|
|
||||||
|
|
||||||
this.initDOMRequestHelper(aWindow, [ "DataStore:Get:Return" ]);
|
this.initDOMRequestHelper(aWindow, [ "DataStore:Get:Return" ]);
|
||||||
|
|
||||||
@ -205,35 +443,12 @@ DataStoreServiceChild.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
receiveMessage: function(aMessage) {
|
receiveMessage: function(aMessage) {
|
||||||
|
debug("DataStoreServiceChild receiveMessage");
|
||||||
if (aMessage.name != 'DataStore:Get:Return') {
|
if (aMessage.name != 'DataStore:Get:Return') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let msg = aMessage.data;
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
let callbackPending = msg.stores.length;
|
this._callback(aMessage.data.stores);
|
||||||
let results = [];
|
|
||||||
|
|
||||||
if (!callbackPending) {
|
|
||||||
this._resolve(results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < msg.stores.length; ++i) {
|
|
||||||
let obj = new DataStore(this._window, this._name,
|
|
||||||
msg.stores[i].owner, msg.stores[i].readOnly);
|
|
||||||
let exposedObj = this._window.DataStore._create(this._window, obj);
|
|
||||||
results.push(exposedObj);
|
|
||||||
|
|
||||||
obj.retrieveRevisionId(
|
|
||||||
function() {
|
|
||||||
--callbackPending;
|
|
||||||
if (!callbackPending) {
|
|
||||||
self._resolve(results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
51
dom/datastore/DataStoreServiceInternal.jsm
Normal file
51
dom/datastore/DataStoreServiceInternal.jsm
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 = ["DataStoreServiceInternal"];
|
||||||
|
|
||||||
|
function debug(s) {
|
||||||
|
// dump('DEBUG DataStoreServiceInternal: ' + s + '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||||
|
"@mozilla.org/parentprocessmessagemanager;1",
|
||||||
|
"nsIMessageBroadcaster");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
|
||||||
|
"@mozilla.org/datastore-service;1",
|
||||||
|
"nsIDataStoreService");
|
||||||
|
|
||||||
|
this.DataStoreServiceInternal = {
|
||||||
|
init: function() {
|
||||||
|
debug("init");
|
||||||
|
|
||||||
|
let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||||
|
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||||
|
if (inParent) {
|
||||||
|
ppmm.addMessageListener("DataStore:Get", this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
receiveMessage: function(aMessage) {
|
||||||
|
debug("receiveMessage");
|
||||||
|
|
||||||
|
if (aMessage.name != 'DataStore:Get') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = aMessage.data;
|
||||||
|
|
||||||
|
// This is a security issue and it will be fixed by Bug 916091
|
||||||
|
msg.stores = dataStoreService.getDataStoresInfo(msg.name, msg.appId);
|
||||||
|
aMessage.target.sendAsyncMessage("DataStore:Get:Return", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataStoreServiceInternal.init();
|
@ -23,4 +23,5 @@ EXTRA_JS_MODULES += [
|
|||||||
'DataStore.jsm',
|
'DataStore.jsm',
|
||||||
'DataStoreChangeNotifier.jsm',
|
'DataStoreChangeNotifier.jsm',
|
||||||
'DataStoreDB.jsm',
|
'DataStoreDB.jsm',
|
||||||
|
'DataStoreServiceInternal.jsm',
|
||||||
]
|
]
|
||||||
|
@ -7,19 +7,29 @@
|
|||||||
|
|
||||||
interface nsIDOMWindow;
|
interface nsIDOMWindow;
|
||||||
|
|
||||||
[scriptable, uuid(d193d0e2-c677-4a7b-bb0a-19155b470f2e)]
|
[scriptable, uuid(bd02d09c-41ab-47b7-9319-57aa8e5059b0)]
|
||||||
interface nsIDataStoreService : nsISupports
|
interface nsIDataStoreService : nsISupports
|
||||||
{
|
{
|
||||||
void installDataStore(in unsigned long appId,
|
void installDataStore(in unsigned long appId,
|
||||||
in DOMString name,
|
in DOMString name,
|
||||||
|
in DOMString originURL,
|
||||||
in DOMString manifestURL,
|
in DOMString manifestURL,
|
||||||
in boolean readOnly);
|
in boolean readOnly);
|
||||||
|
|
||||||
void installAccessDataStore(in unsigned long appId,
|
void installAccessDataStore(in unsigned long appId,
|
||||||
in DOMString name,
|
in DOMString name,
|
||||||
|
in DOMString originURL,
|
||||||
in DOMString manifestURL,
|
in DOMString manifestURL,
|
||||||
in boolean readOnly);
|
in boolean readOnly);
|
||||||
|
|
||||||
nsISupports getDataStores(in nsIDOMWindow window,
|
nsISupports getDataStores(in nsIDOMWindow window,
|
||||||
in DOMString name);
|
in DOMString name);
|
||||||
|
|
||||||
|
// This is an array of objects composed by:
|
||||||
|
// - readOnly: boolean
|
||||||
|
// - name: DOMString
|
||||||
|
// - owner: DOMString
|
||||||
|
// - enabled: true/false - true if this dataStore is ready to be used.
|
||||||
|
jsval getDataStoresInfo(in DOMString name,
|
||||||
|
in unsigned long appId);
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
<div id="container"></div>
|
<div id="container"></div>
|
||||||
<script type="application/javascript;version=1.7">
|
<script type="application/javascript;version=1.7">
|
||||||
|
|
||||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
@ -23,7 +25,8 @@
|
|||||||
{ "type": "embed-apps", "allow": 1, "context": document },
|
{ "type": "embed-apps", "allow": 1, "context": document },
|
||||||
{ "type": "webapps-manage", "allow": 1, "context": document }],
|
{ "type": "webapps-manage", "allow": 1, "context": document }],
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true]]}, function() {
|
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||||
|
["dom.promise.enabled", true]]}, function() {
|
||||||
gGenerator.next(); });
|
gGenerator.next(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -46,6 +49,7 @@
|
|||||||
}, cbError);
|
}, cbError);
|
||||||
yield undefined;
|
yield undefined;
|
||||||
|
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
|
|
||||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
runTest();
|
runTest();
|
||||||
},
|
},
|
||||||
@ -117,7 +118,10 @@
|
|||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
runTest();
|
runTest();
|
||||||
</script>
|
</script>
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
runTest();
|
runTest();
|
||||||
},
|
},
|
||||||
@ -117,7 +118,10 @@
|
|||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
runTest();
|
runTest();
|
||||||
</script>
|
</script>
|
||||||
|
@ -129,6 +129,7 @@
|
|||||||
|
|
||||||
// Enabling mozBrowser
|
// Enabling mozBrowser
|
||||||
function() {
|
function() {
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
|
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -170,7 +171,10 @@
|
|||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
runTest();
|
runTest();
|
||||||
</script>
|
</script>
|
||||||
|
@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
runTest();
|
runTest();
|
||||||
},
|
},
|
||||||
@ -121,7 +122,10 @@
|
|||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
runTest();
|
runTest();
|
||||||
</script>
|
</script>
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
|
|
||||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||||
@ -94,11 +95,13 @@
|
|||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true]]}, function() {
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true]]}, runTest);
|
["dom.datastore.enabled", true]]}, runTest);
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
|
|
||||||
// Enabling mozBrowser
|
// Enabling mozBrowser
|
||||||
function() {
|
function() {
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
|
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -126,7 +127,10 @@
|
|||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
runTest();
|
runTest();
|
||||||
</script>
|
</script>
|
||||||
|
@ -35,5 +35,9 @@
|
|||||||
"description": "Mochitests"
|
"description": "Mochitests"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"datastores-access" : {
|
||||||
|
"foo" : { "readonly": false },
|
||||||
|
"bar" : { "readonly": false }
|
||||||
|
},
|
||||||
"default_locale": "en-US"
|
"default_locale": "en-US"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user