--- a/dom/base/Webapps.jsm
+++ b/dom/base/Webapps.jsm
@@ -1,13 +1,13 @@
/* 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/. */
-const Cu = Components.utils;
+const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
let EXPORTED_SYMBOLS = ["DOMApplicationRegistry", "DOMApplicationManifest"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
@@ -171,48 +171,51 @@ let DOMApplicationRegistry = {
// install an application again is considered as an update
if (id) {
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
try {
dir.remove(true);
} catch(e) {
}
- }
- else {
- let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
- id = uuidGenerator.generateUUID().toString();
+ } else {
+ id = this.makeAppId();
}
+ let appObject = this._cloneAppObject(app);
+ appObject.installTime = (new Date()).getTime();
+ let appNote = JSON.stringify(appObject);
+ appNote.id = id;
+
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
-
let manFile = dir.clone();
manFile.append("manifest.json");
this._writeFile(manFile, JSON.stringify(app.manifest));
+ this.webapps[id] = appObject;
- this.webapps[id] = this._cloneAppObject(app);
- delete this.webapps[id].manifest;
- this.webapps[id].installTime = (new Date()).getTime()
-
-
if (!aFromSync)
this._saveApps((function() {
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
- Services.obs.notifyObservers(this, "webapps-sync-install", id);
+ Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
}).bind(this));
},
_appId: function(aURI) {
for (let id in this.webapps) {
if (this.webapps[id].origin == aURI)
return id;
}
return null;
},
+ makeAppId: function() {
+ let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
+ return uuidGenerator.generateUUID().toString();
+ },
+
_saveApps: function(aCallback) {
this._writeFile(this.appsFile, JSON.stringify(this.webapps), function() {
if (aCallback)
aCallback();
});
},
/**
@@ -228,34 +231,38 @@ let DOMApplicationRegistry = {
let id = aData[index].id;
let file = FileUtils.getFile(DIRECTORY_NAME, ["webapps", id, "manifest.json"], true);
this._loadJSONAsync(file, (function(aJSON) {
aData[index].manifest = aJSON;
if (index == aData.length - 1)
aFinalCallback(aData);
else
this._readManifests(aData, aFinalCallback, index + 1);
- }).bind(this));
+ }).bind(this));
},
uninstall: function(aData) {
let found = false;
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.origin == aData.origin) {
found = true;
+ let appNote = JSON.stringify(this._cloneAppObject(app));
+ appNote.id = id;
+
delete this.webapps[id];
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
try {
dir.remove(true);
} catch (e) {
}
+
this._saveApps((function() {
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
- Services.obs.notifyObservers(this, "webapps-sync-uninstall", id);
+ Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
}).bind(this));
}
}
if (!found)
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:KO", aData);
},
getSelf: function(aData) {
@@ -294,17 +301,17 @@ let DOMApplicationRegistry = {
ppmm.sendAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
}).bind(this));
},
getAll: function(aData) {
aData.apps = [];
let tmp = [];
- for (id in this.webapps) {
+ for (let id in this.webapps) {
let app = this._cloneAppObject(this.webapps[id]);
aData.apps.push(app);
tmp.push({ id: id });
}
this._readManifests(tmp, (function(aResult) {
for (let i = 0; i < aResult.length; i++)
aData.apps[i].manifest = aResult[i].manifest;
@@ -322,28 +329,36 @@ let DOMApplicationRegistry = {
return;
}
this._readManifests([{ id: id }], function(aResult) {
aCallback(aResult[0].manifest);
});
},
- /** added to support the sync engine */
+ /** Added to support AITC and classic sync */
+ itemExists: function(aId) {
+ return !!this.webapps[aId];
+ },
getAppById: function(aId) {
if (!this.webapps[aId])
return null;
-
+
let app = this._cloneAppObject(this.webapps[aId]);
return app;
},
- itemExists: function(aId) {
- return !!this.webapps[aId];
+ getAllWithoutManifests: function(aCallback) {
+ let result = {};
+ for (let id in this.webapps) {
+ let app = this._cloneAppObject(this.webapps[id]);
+ result[id] = app;
+ }
+ aCallback(result);
},
updateApps: function(aRecords, aCallback) {
for (let i = 0; i < aRecords.length; i++) {
let record = aRecords[i];
if (record.deleted) {
if (!this.webapps[record.id])
continue;
@@ -351,33 +366,29 @@ let DOMApplicationRegistry = {
delete this.webapps[record.id];
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", record.id], true, true);
try {
dir.remove(true);
} catch (e) {
}
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
} else {
- if (!!this.webapps[record.id]) {
+ if (this.webapps[record.id]) {
this.webapps[record.id] = record.value;
delete this.webapps[record.id].manifest;
- }
- else {
+ } else {
let data = { app: record.value };
this.confirmInstall(data, true);
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", data);
}
}
}
this._saveApps(aCallback);
},
- /*
- * May be removed once sync API change
- */
getAllIDs: function() {
let apps = {};
for (let id in this.webapps) {
// only sync http and https apps
if (this.webapps[id].origin.indexOf("http") == 0)
apps[id] = true;
}
return apps;
@@ -389,87 +400,87 @@ let DOMApplicationRegistry = {
delete this.webapps[id];
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
try {
dir.remove(true);
} catch (e) {
}
}
this._saveApps(aCallback);
- }
+ }
};
/**
* Helper object to access manifest information with locale support
*/
DOMApplicationManifest = function(aManifest, aOrigin) {
this._origin = Services.io.newURI(aOrigin, null, null);
this._manifest = aManifest;
let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry)
.QueryInterface(Ci.nsIToolkitChromeRegistry);
let locale = chrome.getSelectedLocale("browser").toLowerCase();
this._localeRoot = this._manifest;
-
+
if (this._manifest.locales && this._manifest.locales[locale]) {
this._localeRoot = this._manifest.locales[locale];
}
else if (this._manifest.locales) {
// try with the language part of the locale ("en" for en-GB) only
let lang = locale.split('-')[0];
if (lang != locale && this._manifest.locales[lang])
this._localeRoot = this._manifest.locales[lang];
}
-}
+};
DOMApplicationManifest.prototype = {
_localeProp: function(aProp) {
if (this._localeRoot[aProp] != undefined)
return this._localeRoot[aProp];
return this._manifest[aProp];
},
get name() {
return this._localeProp("name");
},
-
+
get description() {
return this._localeProp("description");
},
-
+
get version() {
return this._localeProp("version");
},
-
+
get launch_path() {
return this._localeProp("launch_path");
},
-
+
get developer() {
return this._localeProp("developer");
},
-
+
get icons() {
return this._localeProp("icons");
},
-
+
iconURLForSize: function(aSize) {
let icons = this._localeProp("icons");
if (!icons)
return null;
let dist = 100000;
let icon = null;
for (let size in icons) {
let iSize = parseInt(size);
if (Math.abs(iSize - aSize) < dist) {
icon = this._origin.resolve(icons[size]);
dist = Math.abs(iSize - aSize);
}
}
return icon;
},
-
+
fullLaunchPath: function() {
let launchPath = this._localeProp("launch_path");
return this._origin.resolve(launchPath ? launchPath : "");
}
-}
+};
DOMApplicationRegistry.init();