Exterminate WebAppRT - Part 1: Remove webapprt application directory

This commit is contained in:
NTD
2016-10-07 15:20:50 -04:00
committed by roytam1
parent 8635511628
commit be4baf49a9
143 changed files with 0 additions and 8122 deletions
-110
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/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
function CommandLineHandler() {}
CommandLineHandler.prototype = {
classID: Components.ID("{6d69c782-40a3-469b-8bfd-3ee366105a4a}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
handle: function handle(cmdLine) {
let args = Cc["@mozilla.org/hash-property-bag;1"].
createInstance(Ci.nsIWritablePropertyBag);
let inTestMode = this._handleTestMode(cmdLine, args);
let debugPort = this._handleDebugMode(cmdLine);
if (!isNaN(debugPort)) {
Cu.import("resource://webapprt/modules/RemoteDebugger.jsm");
RemoteDebugger.init(debugPort);
}
if (inTestMode) {
// Open the mochitest shim window, which configures the runtime for tests.
Services.ww.openWindow(null,
"chrome://webapprt/content/mochitest.xul",
"_blank",
"chrome,dialog=no",
args);
} else {
// We're opening the window here in order to show it as soon as possible.
let window = Services.ww.openWindow(null,
"chrome://webapprt/content/webapp.xul",
"_blank",
"chrome,dialog=no,resizable,scrollbars,centerscreen",
null);
// Load the module to start up the app
Cu.import("resource://webapprt/modules/Startup.jsm");
startup(window).then(null, function (aError) {
dump("Error: " + aError + "\n");
Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
});
}
},
/**
* Handle debug command line option.
*
* @param cmdLine A nsICommandLine object.
*
* @returns the port number if it's specified, the default port number if
* the debug option is specified, NaN if the debug option isn't
* specified or the port number isn't valid.
*/
_handleDebugMode: function(cmdLine) {
// -debug [port]
let idx = cmdLine.findFlag("debug", true);
if (idx < 0) {
return NaN;
}
let port;
let portIdx = idx + 1;
if (portIdx < cmdLine.length) {
port = parseInt(cmdLine.getArgument(portIdx));
if (port != NaN) {
return port;
}
}
return Services.prefs.getIntPref('devtools.debugger.remote-port');
},
_handleTestMode: function _handleTestMode(cmdLine, args) {
// -test-mode [url]
let idx = cmdLine.findFlag("test-mode", true);
if (idx < 0)
return false;
let url;
let urlIdx = idx + 1;
if (urlIdx < cmdLine.length) {
let potentialURL = cmdLine.getArgument(urlIdx);
if (potentialURL && potentialURL[0] != "-") {
try {
url = Services.io.newURI(potentialURL, null, null);
} catch (err) {
throw Components.Exception(
"-test-mode argument is not a valid URL: " + potentialURL,
Components.results.NS_ERROR_INVALID_ARG);
}
cmdLine.removeArguments(urlIdx, urlIdx);
args.setProperty("url", url.spec);
}
}
cmdLine.removeArguments(idx, idx);
return true;
},
helpInfo : "",
};
let components = [CommandLineHandler];
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
-118
View File
@@ -1,118 +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/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const UNKNOWN_FAIL = ["geolocation", "desktop-notification"];
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://webapprt/modules/WebappRT.jsm");
function ContentPermission() {}
ContentPermission.prototype = {
classID: Components.ID("{07ef5b2e-88fb-47bd-8cec-d3b0bef11ac4}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
_getChromeWindow: function(aWindow) {
return aWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow)
.QueryInterface(Ci.nsIDOMChromeWindow);
},
prompt: function(request) {
// Only allow exactly one permission request here.
let types = request.types.QueryInterface(Ci.nsIArray);
if (types.length != 1) {
request.cancel();
return;
}
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
// Reuse any remembered permission preferences
let result =
Services.perms.testExactPermissionFromPrincipal(request.principal,
perm.type);
// We used to use the name "geo" for the geolocation permission, now we're
// using "geolocation". We need to check both to support existing
// installations.
if ((result == Ci.nsIPermissionManager.UNKNOWN_ACTION ||
result == Ci.nsIPermissionManager.PROMPT_ACTION) &&
perm.type == "geolocation") {
let geoResult = Services.perms.testExactPermission(request.principal.URI,
"geo");
// We override the result only if the "geo" permission was allowed or
// denied.
if (geoResult == Ci.nsIPermissionManager.ALLOW_ACTION ||
geoResult == Ci.nsIPermissionManager.DENY_ACTION) {
result = geoResult;
}
}
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
request.allow();
return;
} else if (result == Ci.nsIPermissionManager.DENY_ACTION ||
(result == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
UNKNOWN_FAIL.indexOf(perm.type) >= 0)) {
request.cancel();
return;
}
// Display a prompt at the top level
let {name} = WebappRT.localeManifest;
let requestingWindow = request.window.top;
let chromeWin = this._getChromeWindow(requestingWindow);
let bundle = Services.strings.createBundle("chrome://webapprt/locale/webapp.properties");
// Construct a prompt with share/don't and remember checkbox
let remember = {value: false};
let choice = Services.prompt.confirmEx(
chromeWin,
bundle.formatStringFromName(perm.type + ".title", [name], 1),
bundle.GetStringFromName(perm.type + ".description"),
// Set both buttons to strings with the cancel button being default
Ci.nsIPromptService.BUTTON_POS_1_DEFAULT |
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_0 |
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_1,
bundle.GetStringFromName(perm.type + ".allow"),
bundle.GetStringFromName(perm.type + ".deny"),
null,
bundle.GetStringFromName(perm.type + ".remember"),
remember);
let action = Ci.nsIPermissionManager.ALLOW_ACTION;
if (choice != 0) {
action = Ci.nsIPermissionManager.DENY_ACTION;
}
if (remember.value) {
// Persist the choice if the user wants to remember
Services.perms.addFromPrincipal(request.principal, perm.type, action);
} else {
// Otherwise allow the permission for the current session
Services.perms.addFromPrincipal(request.principal, perm.type, action,
Ci.nsIPermissionManager.EXPIRE_SESSION);
}
// Trigger the selected choice
if (choice == 0) {
request.allow();
}
else {
request.cancel();
}
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermission]);
-56
View File
@@ -1,56 +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/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const WEBAPP_REGISTRY_DIR = "WebappRegD";
const NS_APP_CHROME_DIR_LIST = "AChromDL";
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://webapprt/modules/WebappRT.jsm");
Cu.import("resource://gre/modules/Services.jsm");
function DirectoryProvider() {}
DirectoryProvider.prototype = {
classID: Components.ID("{e1799fda-4b2f-4457-b671-e0641d95698d}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider,
Ci.nsIDirectoryServiceProvider2]),
getFile: function(prop, persistent) {
if (prop == WEBAPP_REGISTRY_DIR) {
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
dir.initWithPath(WebappRT.config.registryDir);
return dir;
}
// We return null to show failure instead of throwing an error,
// which works with the way the interface is called (per bug 529077).
return null;
},
getFiles: function(prop, persistent) {
if (prop == NS_APP_CHROME_DIR_LIST) {
return {
_done: false,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
hasMoreElements: function() {
return !this._done;
},
getNext: function() {
this._done = true;
return FileUtils.getDir("AppRegD", ["chrome"], false);
}
};
}
return null;
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]);
-35
View File
@@ -1,35 +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";
this.EXPORTED_SYMBOLS = ["DownloadView"];
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Downloads.jsm");
this.DownloadView = {
init: function() {
Downloads.getList(Downloads.ALL)
.then(list => list.addView(this))
.catch(Cu.reportError);
},
onDownloadAdded: function(aDownload) {
let dmWindow = Services.wm.getMostRecentWindow("Download:Manager");
if (dmWindow) {
dmWindow.focus();
} else {
Services.ww.openWindow(null,
"chrome://webapprt/content/downloads/downloads.xul",
"Download:Manager",
"chrome,dialog=no,resizable",
null);
}
},
};
DownloadView.init();
-22
View File
@@ -1,22 +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/.
# Include config.mk explicitly so we can override FINAL_TARGET.
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk
libs:: $(call mkdir_deps,$(FINAL_TARGET))
$(call py_action,buildlist,$(FINAL_TARGET)/chrome.manifest 'resource webapprt ./')
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
DEFINES += -DGRE_BUILDID=$(GRE_BUILDID)
webapprt.ini: application.ini.in $(DEPTH)/config/buildid $(topsrcdir)/config/milestone.txt
$(call py_action,preprocessor,$(DEFINES) $< -o $@)
libs:: webapprt.ini
$(INSTALL) webapprt.ini $(FINAL_TARGET)
GARBAGE += webapprt.ini
-148
View File
@@ -1,148 +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 { interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
function paymentSuccess(aRequestId) {
return function(aResult) {
closePaymentWindow(aRequestId, function() {
cpmm.sendAsyncMessage("Payment:Success", { requestId: aRequestId,
result: aResult });
});
};
}
function paymentFailed(aRequestId) {
return function(aErrorMsg) {
closePaymentWindow(aRequestId, function() {
cpmm.sendAsyncMessage("Payment:Failed", { requestId: aRequestId,
errorMsg: aErrorMsg });
});
};
}
let payments = {};
function closePaymentWindow(aId, aCallback) {
if (payments[aId]) {
payments[aId].handled = true;
payments[aId].win.close();
payments[aId] = null;
}
aCallback();
}
function PaymentUI() {}
PaymentUI.prototype = {
classID: Components.ID("{ede1124f-72e8-4a31-9567-3270d46f21fb}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue]),
confirmPaymentRequest: function(aRequestId, aRequests, aSuccessCb, aErrorCb) {
// If there's only one payment provider that will work, just move on
// without prompting the user.
if (aRequests.length == 1) {
aSuccessCb.onresult(aRequestId, aRequests[0].type);
return;
}
let items = [];
// Otherwise, let the user select a payment provider from a list.
for (let i = 0; i < aRequests.length; i++) {
let request = aRequests[i];
let requestText = request.providerName;
if (request.productPrice && Array.isArray(request.productPrice)) {
// We should guess the user currency and use that instead.
requestText += " (" + request.productPrice[0].amount + " " +
request.productPrice[0].currency + ")";
}
items.push(requestText);
}
let selected = {};
let bundle = Services.strings.
createBundle("chrome://webapprt/locale/webapp.properties");
let result = Services.prompt.
select(null, bundle.GetStringFromName("paymentDialog.title"),
bundle.GetStringFromName("paymentDialog.message"),
items.length, items, selected);
if (result) {
aSuccessCb.onresult(aRequestId,
aRequests[selected.value].type);
} else {
aErrorCb.onresult(aRequestId, "USER_CANCELLED");
}
},
showPaymentFlow: function(aRequestId, aPaymentFlowInfo, aErrorCb) {
let win = Services.ww.
openWindow(null,
"chrome://webapprt/content/webapp.xul",
"_blank",
"chrome,dialog=no,resizable,scrollbars,centerscreen",
null);
// Store a reference to the window so that we can close it when the payment
// succeeds or fails.
payments[aRequestId] = { win: win, handled: false };
// Inject paymentSuccess and paymentFailed methods into the document after
// its loaded.
win.addEventListener("DOMContentLoaded", function onDOMContentLoaded() {
win.removeEventListener("DOMContentLoaded", onDOMContentLoaded);
let browserElement = win.document.getElementById("content");
browserElement.
setAttribute("src", aPaymentFlowInfo.uri + aPaymentFlowInfo.jwt);
browserElement.addEventListener("DOMWindowCreated",
function onDOMWindowCreated() {
browserElement.removeEventListener("DOMWindowCreated",
onDOMWindowCreated);
win.document.getElementById("content").contentDocument.defaultView
.wrappedJSObject.mozPaymentProvider = {
__exposedProps__: {
paymentSuccess: 'r',
paymentFailed: 'r'
},
paymentSuccess: paymentSuccess(aRequestId),
paymentFailed: paymentFailed(aRequestId)
};
}, true);
});
let winObserver = function(aClosedWin, aTopic) {
if (aTopic == "domwindowclosed") {
// Fail the payment if the window is closed.
if (aClosedWin == win) {
Services.ww.unregisterNotification(winObserver);
if (payments[aRequestId] && !payments[aRequestId].handled) {
aErrorCb.onresult(aRequestId, "USER_CANCELLED");
}
}
}
}
Services.ww.registerNotification(winObserver);
},
cleanup: function() {
},
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentUI]);
-28
View File
@@ -1,28 +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";
this.EXPORTED_SYMBOLS = ["RemoteDebugger"];
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import('resource://gre/modules/devtools/dbg-server.jsm');
this.RemoteDebugger = {
init: function(port) {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors("webapprt:webapp");
DebuggerServer.addActors("chrome://webapprt/content/dbg-webapp-actors.js");
}
let listener = DebuggerServer.createListener();
listener.portOrPath = port;
listener.open();
}
}
-169
View File
@@ -1,169 +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/. */
/* This module is imported at the startup of an application. It takes care of
* permissions installation, application url loading, security settings. Put
* stuff here that you want to happen once on startup before the webapp is
* loaded. */
this.EXPORTED_SYMBOLS = ["startup"];
const Ci = Components.interfaces;
const Cu = Components.utils;
/* We load here modules that are needed to perform the application startup.
* We lazily load modules that aren't needed on every startup.
* We load modules that aren't used here but that need to perform some
* initialization steps later in the startup function. */
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://webapprt/modules/WebappRT.jsm");
// Lazily load these modules because we don't need them at every
// startup, but only during first run or runtime update.
XPCOMUtils.defineLazyModuleGetter(this, "PermissionsInstaller",
"resource://gre/modules/PermissionsInstaller.jsm");
const PROFILE_DIR = OS.Constants.Path.profileDir;
function isFirstRunOrUpdate() {
let savedBuildID = null;
try {
savedBuildID = Services.prefs.getCharPref("webapprt.buildID");
} catch (e) {}
let ourBuildID = Services.appinfo.platformBuildID;
if (ourBuildID != savedBuildID) {
Services.prefs.setCharPref("webapprt.buildID", ourBuildID);
return true;
}
return false;
}
function writeFile(aPath, aData) {
return Task.spawn(function() {
let data = new TextEncoder().encode(aData);
yield OS.File.writeAtomic(aPath, data, { tmpPath: aPath + ".tmp" });
});
}
function createBrandingFiles() {
return Task.spawn(function() {
let manifest = WebappRT.localeManifest;
let name = WebappRT.localeManifest.name;
let developer = " ";
if (WebappRT.localeManifest.developer) {
developer = WebappRT.localeManifest.developer.name;
}
let brandDTDContent = '<!ENTITY brandShortName "' + name + '">\n\
<!ENTITY brandFullName "' + name + '">\n\
<!ENTITY vendorShortName "' + developer + '">\n\
<!ENTITY trademarkInfo.part1 " ">';
yield writeFile(OS.Path.join(PROFILE_DIR, "brand.dtd"), brandDTDContent);
let brandPropertiesContent = 'brandShortName=' + name + '\n\
brandFullName=' + name + '\n\
vendorShortName=' + developer;
yield writeFile(OS.Path.join(PROFILE_DIR, "brand.properties"),
brandPropertiesContent);
});
}
// Observes all the events needed to actually launch an application.
// It waits for XUL window and webapps registry loading.
this.startup = function(window) {
return Task.spawn(function () {
// Observe XUL window loading.
// For tests, it could be already loaded.
let deferredWindowLoad = Promise.defer();
if (window.document && window.document.getElementById("content")) {
deferredWindowLoad.resolve();
} else {
window.addEventListener("DOMContentLoaded", function onLoad() {
window.removeEventListener("DOMContentLoaded", onLoad, false);
deferredWindowLoad.resolve();
});
}
let appUpdated = false;
let updatePending = yield WebappRT.isUpdatePending();
if (updatePending) {
appUpdated = yield WebappRT.applyUpdate();
}
yield WebappRT.configPromise;
let appData = WebappRT.config.app;
// Initialize DOMApplicationRegistry by importing Webapps.jsm.
Cu.import("resource://gre/modules/Webapps.jsm");
// Initialize window-independent handling of webapps- notifications.
Cu.import("resource://webapprt/modules/WebappManager.jsm");
// Wait for webapps registry loading.
yield DOMApplicationRegistry.registryStarted;
// Add the currently running app to the registry.
yield DOMApplicationRegistry.addInstalledApp(appData, appData.manifest,
appData.updateManifest);
let manifestURL = appData.manifestURL;
if (manifestURL) {
// On firstrun, set permissions to their default values.
// When the webapp runtime is updated, update the permissions.
if (isFirstRunOrUpdate(Services.prefs) || appUpdated) {
PermissionsInstaller.installPermissions(appData, true);
yield createBrandingFiles();
}
}
// Branding substitution
let aliasFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Ci.nsIFile);
aliasFile.initWithPath(PROFILE_DIR);
let aliasURI = Services.io.newFileURI(aliasFile);
Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler)
.setSubstitution("webappbranding", aliasURI);
// Wait for XUL window loading
yield deferredWindowLoad.promise;
// Load these modules here because they aren't needed right at startup,
// but they need to be loaded to perform some initialization steps.
Cu.import("resource://gre/modules/Payment.jsm");
Cu.import("resource://gre/modules/AlarmService.jsm");
Cu.import("resource://webapprt/modules/WebRTCHandler.jsm");
Cu.import("resource://webapprt/modules/DownloadView.jsm");
// Get the <browser> element in the webapp.xul window.
let appBrowser = window.document.getElementById("content");
// Set the principal to the correct appID and launch the application.
appBrowser.docShell.setIsApp(WebappRT.appID);
appBrowser.setAttribute("src", WebappRT.launchURI);
if (appData.manifest.fullscreen) {
appBrowser.addEventListener("load", function onLoad() {
appBrowser.removeEventListener("load", onLoad, true);
appBrowser.contentDocument.
documentElement.mozRequestFullScreen();
}, true);
}
WebappRT.startUpdateService();
});
}
-103
View File
@@ -1,103 +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";
this.EXPORTED_SYMBOLS = [];
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function handleRequest(aSubject, aTopic, aData) {
let { windowID, callID } = aSubject;
let constraints = aSubject.getConstraints();
let contentWindow = Services.wm.getOuterWindowWithId(windowID);
contentWindow.navigator.mozGetUserMediaDevices(
constraints,
function (devices) {
prompt(contentWindow, callID, constraints.audio,
constraints.video || constraints.picture,
devices);
},
function (error) {
denyRequest(callID, error);
});
}
function prompt(aWindow, aCallID, aAudioRequested, aVideoRequested, aDevices) {
let audioDevices = [];
let videoDevices = [];
for (let device of aDevices) {
device = device.QueryInterface(Ci.nsIMediaDevice);
switch (device.type) {
case "audio":
if (aAudioRequested) {
audioDevices.push(device);
}
break;
case "video":
if (aVideoRequested) {
videoDevices.push(device);
}
break;
}
}
if (audioDevices.length == 0 && videoDevices.length == 0) {
denyRequest(aCallID);
return;
}
let params = {
videoDevices: videoDevices,
audioDevices: audioDevices,
out: null
};
aWindow.openDialog("chrome://webapprt/content/getUserMediaDialog.xul", "",
"chrome, dialog, modal", params).focus();
if (!params.out) {
denyRequest(aCallID);
return;
}
let allowedDevices = Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsArray);
let videoIndex = params.out.video;
let audioIndex = params.out.audio;
if (videoIndex != -1) {
allowedDevices.AppendElement(videoDevices[videoIndex]);
}
if (audioIndex != -1) {
allowedDevices.AppendElement(audioDevices[audioIndex]);
}
if (allowedDevices.Count()) {
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow",
aCallID);
} else {
denyRequest(aCallID);
}
}
function denyRequest(aCallID, aError) {
let msg = null;
if (aError) {
msg = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
msg.data = aError;
}
Services.obs.notifyObservers(msg, "getUserMedia:response:deny", aCallID);
}
Services.obs.addObserver(handleRequest, "getUserMedia:request", false);
-142
View File
@@ -1,142 +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";
this.EXPORTED_SYMBOLS = ["WebappManager"];
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Webapps.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/NativeApp.jsm");
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://webapprt/modules/WebappRT.jsm");
this.WebappManager = {
observe: function(aSubject, aTopic, aData) {
let data = JSON.parse(aData);
data.mm = aSubject;
let chromeWin;
switch (aTopic) {
case "webapps-ask-install":
chromeWin = Services.wm.getOuterWindowWithId(data.oid);
if (chromeWin)
this.doInstall(data, chromeWin);
break;
case "webapps-ask-uninstall":
chromeWin = Services.wm.getOuterWindowWithId(data.windowId);
if (chromeWin) {
this.doUninstall(data, chromeWin);
}
break;
case "webapps-launch":
WebappOSUtils.launch(data);
break;
case "webapps-uninstall":
WebappOSUtils.uninstall(data).then(null, Cu.reportError);
break;
}
},
update: function(aApp, aManifest, aZipPath) {
let nativeApp = new NativeApp(aApp, aManifest,
WebappRT.config.app.categories,
WebappRT.config.registryDir);
nativeApp.prepareUpdate(aApp, aManifest, aZipPath);
},
doInstall: function(data, window) {
let jsonManifest = data.isPackage ? data.app.updateManifest : data.app.manifest;
let manifest =
new ManifestHelper(jsonManifest, data.app.origin, data.app.manifestURL);
let name = manifest.name;
let bundle = Services.strings.createBundle("chrome://webapprt/locale/webapp.properties");
let choice = Services.prompt.confirmEx(
window,
bundle.formatStringFromName("webapps.install.title", [name], 1),
bundle.formatStringFromName("webapps.install.description", [name], 1),
// Set both buttons to strings with the cancel button being default
Ci.nsIPromptService.BUTTON_POS_1_DEFAULT |
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_0 |
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_1,
bundle.GetStringFromName("webapps.install.install"),
bundle.GetStringFromName("webapps.install.dontinstall"),
null,
null,
{});
// Perform the install if the user allows it
if (choice == 0) {
let nativeApp = new NativeApp(data.app, jsonManifest,
data.app.categories,
WebappRT.config.registryDir);
let localDir;
try {
localDir = nativeApp.createProfile();
} catch (ex) {
DOMApplicationRegistry.denyInstall(data);
return;
}
DOMApplicationRegistry.confirmInstall(data, localDir,
Task.async(function*(aApp, aManifest, aZipPath) {
yield nativeApp.install(aApp, aManifest, aZipPath);
})
);
} else {
DOMApplicationRegistry.denyInstall(data);
}
},
doUninstall: function(aData, aWindow) {
let jsonManifest = aData.isPackage ? aData.app.updateManifest : aData.app.manifest;
let manifest = new ManifestHelper(jsonManifest, aData.app.origin,
aData.app.manifestURL);
let name = manifest.name;
let bundle = Services.strings.createBundle("chrome://webapprt/locale/webapp.properties");
let choice = Services.prompt.confirmEx(
aWindow,
bundle.formatStringFromName("webapps.uninstall.title", [name], 1),
bundle.formatStringFromName("webapps.uninstall.description", [name], 1),
// Set both buttons to strings with the cancel button being default
Ci.nsIPromptService.BUTTON_POS_1_DEFAULT |
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_0 |
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_1,
bundle.GetStringFromName("webapps.uninstall.uninstall"),
bundle.GetStringFromName("webapps.uninstall.dontuninstall"),
null,
null,
{});
// Perform the uninstall if the user allows it
if (choice == 0) {
DOMApplicationRegistry.confirmUninstall(aData).then((aApp) => {
WebappOSUtils.uninstall(aApp).then(null, Cu.reportError);
});
} else {
DOMApplicationRegistry.denyUninstall(aData);
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference])
};
Services.obs.addObserver(WebappManager, "webapps-ask-install", false);
Services.obs.addObserver(WebappManager, "webapps-ask-uninstall", false);
Services.obs.addObserver(WebappManager, "webapps-launch", false);
Services.obs.addObserver(WebappManager, "webapps-uninstall", false);
Services.obs.addObserver(WebappManager, "webapps-update", false);
DOMApplicationRegistry.registerUpdateHandler(WebappManager.update);
-143
View File
@@ -1,143 +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/. */
this.EXPORTED_SYMBOLS = ["WebappRT"];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, 'NativeApp',
'resource://gre/modules/NativeApp.jsm');
XPCOMUtils.defineLazyServiceGetter(this, "appsService",
"@mozilla.org/AppsService;1",
"nsIAppsService");
this.WebappRT = {
_configPromise: null,
get configPromise() {
if (!this._configPromise) {
this._configPromise = Task.spawn(function*() {
let webappJson = OS.Path.join(Services.dirsvc.get("AppRegD", Ci.nsIFile).path,
"webapp.json");
WebappRT.config = yield AppsUtils.loadJSONAsync(webappJson);
});
}
return this._configPromise;
},
get launchURI() {
return this.localeManifest.fullLaunchPath();
},
get localeManifest() {
return new ManifestHelper(this.config.app.manifest,
this.config.app.origin,
this.config.app.manifestURL);
},
get appID() {
let manifestURL = this.config.app.manifestURL;
if (!manifestURL) {
return Ci.nsIScriptSecurityManager.NO_APP_ID;
}
return appsService.getAppLocalIdByManifestURL(manifestURL);
},
isUpdatePending: Task.async(function*() {
let webappJson = OS.Path.join(Services.dirsvc.get("AppRegD", Ci.nsIFile).path,
"update", "webapp.json");
if (!(yield OS.File.exists(webappJson))) {
return false;
}
return true;
}),
applyUpdate: Task.async(function*() {
let webappJson = OS.Path.join(Services.dirsvc.get("AppRegD", Ci.nsIFile).path,
"update", "webapp.json");
let config = yield AppsUtils.loadJSONAsync(webappJson);
let nativeApp = new NativeApp(config.app, config.app.manifest,
config.app.categories,
config.registryDir);
try {
yield nativeApp.applyUpdate(config.app);
} catch (ex) {
return false;
}
// The update has been applied successfully, the new config file
// is the config file that was in the update directory.
this.config = config;
this._configPromise = Promise.resolve();
return true;
}),
startUpdateService: function() {
let manifestURL = this.config.app.manifestURL;
// We used to install apps without storing their manifest URL.
// Now we can't update them.
if (!manifestURL) {
return;
}
// Check for updates once a day.
let timerManager = Cc["@mozilla.org/updates/timer-manager;1"].
getService(Ci.nsIUpdateTimerManager);
timerManager.registerTimer("updateTimer", () => {
let window = Services.wm.getMostRecentWindow("webapprt:webapp");
window.navigator.mozApps.mgmt.getAll().onsuccess = function() {
let thisApp = null;
for (let app of this.result) {
if (app.manifestURL == manifestURL) {
thisApp = app;
break;
}
}
// This shouldn't happen if the app is installed.
if (!thisApp) {
Cu.reportError("Couldn't find the app in the webapps registry");
return;
}
thisApp.ondownloadavailable = () => {
// Download available, download it!
thisApp.download();
};
thisApp.ondownloadsuccess = () => {
// Update downloaded, apply it!
window.navigator.mozApps.mgmt.applyDownload(thisApp);
};
thisApp.ondownloadapplied = () => {
// Application updated, nothing to do.
};
thisApp.checkForUpdate();
}
}, Services.prefs.getIntPref("webapprt.app_update_interval"));
},
};
-28
View File
@@ -1,28 +0,0 @@
#if 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/.
#endif
#filter substitution
[App]
ID=webapprt@mozilla.org
Vendor=Mozilla
; Note: the Windows stub executable sets nsXREAppData::name to the webapp
; origin, overriding the value below, to make the app runner treat webapps
; as distinct products, per bug 747409.
Name=Webapp Runtime
Version=@GRE_MILESTONE@
BuildID=@GRE_BUILDID@
UAName=@MOZ_APP_BASENAME@
[Goanna]
MinVersion=@GRE_MILESTONE@
MaxVersion=@GRE_MILESTONE@
[Crash Reporter]
#if MOZILLA_OFFICIAL
Enabled=1
#endif
ServerURL=https://crash-reports.mozilla.com/submit?id=webapprt@mozilla.org&version=@GRE_MILESTONE@&buildid=@GRE_BUILDID@
-17
View File
@@ -1,17 +0,0 @@
# CommandLineHandler.js
component {6d69c782-40a3-469b-8bfd-3ee366105a4a} CommandLineHandler.js
contract @mozilla.org/webapprt/clh;1 {6d69c782-40a3-469b-8bfd-3ee366105a4a}
category command-line-handler x-default @mozilla.org/webapprt/clh;1
# ContentPermission.js
component {07ef5b2e-88fb-47bd-8cec-d3b0bef11ac4} ContentPermission.js
contract @mozilla.org/content-permission/prompt;1 {07ef5b2e-88fb-47bd-8cec-d3b0bef11ac4}
# DirectoryProvider.js
component {e1799fda-4b2f-4457-b671-e0641d95698d} DirectoryProvider.js
contract @mozilla.org/webapprt/directory-provider;1 {e1799fda-4b2f-4457-b671-e0641d95698d}
category xpcom-directory-providers webapprt-directory-provider @mozilla.org/webapprt/directory-provider;1
# PaymentUIGlue.js
component {ede1124f-72e8-4a31-9567-3270d46f21fb} PaymentUIGlue.js
contract @mozilla.org/payment/ui-glue;1 {ede1124f-72e8-4a31-9567-3270d46f21fb}
-130
View File
@@ -1,130 +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 { Promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const { BrowserTabActor, BrowserTabList, allAppShellDOMWindows,
sendShutdownEvent } = devtools.require("devtools/server/actors/webbrowser");
const { RootActor } = devtools.require("devtools/server/actors/root");
/**
* WebappRT-specific actors.
*/
/**
* Construct a root actor appropriate for use in a server running in the webapp
* runtime. The returned root actor:
* - respects the factories registered with DebuggerServer.addGlobalActor,
* - uses a WebappTabList to supply tab actors,
* - sends all webapprt:webapp window documents a Debugger:Shutdown event
* when it exits.
*
* * @param connection DebuggerServerConnection
* The conection to the client.
*/
function createRootActor(connection)
{
let parameters = {
tabList: new WebappTabList(connection),
globalActorFactories: DebuggerServer.globalActorFactories,
onShutdown: sendShutdownEvent
};
return new RootActor(connection, parameters);
}
/**
* A live list of BrowserTabActors representing the current webapp windows,
* to be provided to the root actor to answer 'listTabs' requests. In the
* webapp runtime, only a single tab per window is ever present.
*
* @param connection DebuggerServerConnection
* The connection in which this list's tab actors may participate.
*
* @see BrowserTabList for more a extensive description of how tab list objects
* work.
*/
function WebappTabList(connection)
{
BrowserTabList.call(this, connection);
}
WebappTabList.prototype = Object.create(BrowserTabList.prototype);
WebappTabList.prototype.constructor = WebappTabList;
WebappTabList.prototype.getList = function() {
let topXULWindow = Services.wm.getMostRecentWindow(this._windowType);
// As a sanity check, make sure all the actors presently in our map get
// picked up when we iterate over all windows.
let initialMapSize = this._actorByBrowser.size;
let foundCount = 0;
// To avoid mysterious behavior if windows are closed or opened mid-iteration,
// we update the map first, and then make a second pass over it to yield
// the actors. Thus, the sequence yielded is always a snapshot of the
// actors that were live when we began the iteration.
// Iterate over all webapprt:webapp XUL windows.
for (let win of allAppShellDOMWindows(this._windowType)) {
let browser = win.document.getElementById("content");
if (!browser) {
continue;
}
// Do we have an existing actor for this browser? If not, create one.
let actor = this._actorByBrowser.get(browser);
if (actor) {
foundCount++;
} else {
actor = new WebappTabActor(this._connection, browser);
this._actorByBrowser.set(browser, actor);
}
actor.selected = (win == topXULWindow);
}
if (this._testing && initialMapSize !== foundCount) {
throw Error("_actorByBrowser map contained actors for dead tabs");
}
this._mustNotify = true;
this._checkListening();
return Promise.resolve([actor for ([_, actor] of this._actorByBrowser)]);
};
/**
* Creates a tab actor for handling requests to the single tab, like
* attaching and detaching. WebappTabActor respects the actor factories
* registered with DebuggerServer.addTabActor.
*
* We override the title of the XUL window in content/webapp.js so here
* we need to override the title property to avoid confusion to the user.
* We won't return the title of the contained browser, but the title of
* the webapp window.
*
* @param connection DebuggerServerConnection
* The conection to the client.
* @param browser browser
* The browser instance that contains this tab.
*/
function WebappTabActor(connection, browser)
{
BrowserTabActor.call(this, connection, browser);
}
WebappTabActor.prototype.constructor = WebappTabActor;
WebappTabActor.prototype = Object.create(BrowserTabActor.prototype);
Object.defineProperty(WebappTabActor.prototype, "title", {
get: function() {
return this.browser.ownerDocument.defaultView.document.title;
},
enumerable: true,
configurable: false
});
-328
View File
@@ -1,328 +0,0 @@
<?xml version="1.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/. -->
<!DOCTYPE bindings [
<!ENTITY % downloadDTD SYSTEM "chrome://webapprt/locale/downloads/downloads.dtd" >
%downloadDTD;
]>
<bindings id="downloadBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="download-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://webapprt/skin/downloads/downloads.css"/>
</resources>
<implementation>
<property name="paused">
<getter>
<![CDATA[
return parseInt(this.getAttribute("state")) == Components.interfaces.nsIDownloadManager.DOWNLOAD_PAUSED;
]]>
</getter>
</property>
<property name="openable">
<getter>
<![CDATA[
return parseInt(this.getAttribute("state")) == Components.interfaces.nsIDownloadManager.DOWNLOAD_FINISHED;
]]>
</getter>
</property>
<property name="inProgress">
<getter>
<![CDATA[
var state = parseInt(this.getAttribute("state"));
const dl = Components.interfaces.nsIDownloadManager;
return state == dl.DOWNLOAD_NOTSTARTED ||
state == dl.DOWNLOAD_QUEUED ||
state == dl.DOWNLOAD_DOWNLOADING ||
state == dl.DOWNLOAD_PAUSED ||
state == dl.DOWNLOAD_SCANNING;
]]>
</getter>
</property>
<property name="removable">
<getter>
<![CDATA[
var state = parseInt(this.getAttribute("state"));
const dl = Components.interfaces.nsIDownloadManager;
return state == dl.DOWNLOAD_FINISHED ||
state == dl.DOWNLOAD_CANCELED ||
state == dl.DOWNLOAD_BLOCKED_PARENTAL ||
state == dl.DOWNLOAD_BLOCKED_POLICY ||
state == dl.DOWNLOAD_DIRTY ||
state == dl.DOWNLOAD_FAILED;
]]>
</getter>
</property>
<property name="buttons">
<getter>
<![CDATA[
var startEl = document.getAnonymousNodes(this);
if (!startEl.length) {
startEl = [this];
}
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
return startEl[0].getElementsByTagNameNS(XULNS, "button");
]]>
</getter>
</property>
</implementation>
</binding>
<binding id="download-starting" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon" validate="always"
xbl:inherits="src=image"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" class="name"/>
<xul:progressmeter mode="normal" value="0" flex="1"
anonid="progressmeter"/>
<xul:label value="&starting.label;" class="status"/>
<xul:spacer flex="1"/>
</xul:vbox>
<xul:vbox pack="center">
<xul:button class="cancel mini-button" tooltiptext="&cmd.cancel.label;"
cmd="cmd_cancel" ondblclick="event.stopPropagation();"
oncommand="gDownloadList.performCommand('cmd_cancel', this);"/>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-downloading" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1" class="downloadContentBox">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon" validate="always"
xbl:inherits="src=image"/>
</xul:vbox>
<xul:vbox flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="2" class="name"/>
<xul:hbox>
<xul:vbox flex="1">
<xul:progressmeter mode="normal" value="0" flex="1"
anonid="progressmeter"
xbl:inherits="value=progress,mode=progressmode"/>
</xul:vbox>
<xul:button class="pause mini-button" tooltiptext="&cmd.pause.label;"
cmd="cmd_pause" ondblclick="event.stopPropagation();"
oncommand="gDownloadList.performCommand('cmd_pause', this);"/>
<xul:button class="cancel mini-button" tooltiptext="&cmd.cancel.label;"
cmd="cmd_cancel" ondblclick="event.stopPropagation();"
oncommand="gDownloadList.performCommand('cmd_cancel', this);"/>
</xul:hbox>
<xul:label xbl:inherits="value=status,tooltiptext=statusTip" flex="1"
crop="right" class="status"/>
<xul:spacer flex="1"/>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-paused" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon" validate="always"
xbl:inherits="src=image"/>
</xul:vbox>
<xul:vbox flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="2" class="name"/>
<xul:hbox>
<xul:vbox flex="1">
<xul:progressmeter mode="normal" value="0" flex="1"
anonid="progressmeter"
xbl:inherits="value=progress,mode=progressmode"/>
</xul:vbox>
<xul:button class="resume mini-button" tooltiptext="&cmd.resume.label;"
cmd="cmd_resume" ondblclick="event.stopPropagation();"
oncommand="gDownloadList.performCommand('cmd_resume', this);"/>
<xul:button class="cancel mini-button" tooltiptext="&cmd.cancel.label;"
cmd="cmd_cancel" ondblclick="event.stopPropagation();"
oncommand="gDownloadList.performCommand('cmd_cancel', this);"/>
</xul:hbox>
<xul:label xbl:inherits="value=status,tooltiptext=statusTip" flex="1"
crop="right" class="status"/>
<xul:spacer flex="1"/>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-done" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon" validate="always"
xbl:inherits="src=image"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="1" class="name"/>
<xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
class="dateTime"/>
</xul:hbox>
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=status,tooltiptext=statusTip"
crop="end" flex="1" class="status"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-canceled" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon" validate="always"
xbl:inherits="src=image"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="1" class="name"/>
<xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
class="dateTime"/>
</xul:hbox>
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=status,tooltiptext=statusTip"
crop="end" flex="1" class="status"/>
<xul:button class="retry mini-button" tooltiptext="&cmd.retry.label;"
cmd="cmd_retry" ondblclick="event.stopPropagation();"
oncommand="gDownloadList.performCommand('cmd_retry', this);"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-failed" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon" validate="always"
xbl:inherits="src=image"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="1" class="name"/>
<xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
class="dateTime"/>
</xul:hbox>
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=status,tooltiptext=statusTip"
crop="end" flex="1" class="status"/>
<xul:button class="retry mini-button" tooltiptext="&cmd.retry.label;"
cmd="cmd_retry" ondblclick="event.stopPropagation();"
oncommand="gDownloadList.performCommand('cmd_retry', this);"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-blocked-parental" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon blockedIcon"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="1" class="name"/>
<xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
class="dateTime"/>
</xul:hbox>
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=status,tooltiptext=statusTip"
crop="end" flex="1" class="status"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-blocked-policy" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon blockedIcon"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="1" class="name"/>
<xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
class="dateTime"/>
</xul:hbox>
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=status,tooltiptext=statusTip"
crop="end" flex="1" class="status"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-scanning" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon" validate="always"
xbl:inherits="src=image"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="2" class="name"/>
<xul:hbox>
<xul:vbox flex="1">
<xul:progressmeter mode="undetermined" flex="1" />
</xul:vbox>
</xul:hbox>
<xul:label value="&scanning.label;" class="status"/>
<xul:spacer flex="1"/>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="download-dirty" extends="chrome://webapprt/content/downloads/download.xml#download-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="center">
<xul:image class="downloadTypeIcon blockedIcon"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=target"
crop="center" flex="1" class="name"/>
<xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
class="dateTime"/>
</xul:hbox>
<xul:hbox align="center" flex="1">
<xul:label xbl:inherits="value=status,tooltiptext=statusTip"
crop="end" flex="1" class="status"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
</bindings>
-50
View File
@@ -1,50 +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/. */
richlistitem[type="download"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-starting');
-moz-box-orient: vertical;
}
richlistitem[type="download"][state="0"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-downloading');
}
richlistitem[type="download"][state="1"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-done');
}
richlistitem[type="download"][state="2"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-failed');
}
richlistitem[type="download"][state="3"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-canceled');
}
richlistitem[type="download"][state="4"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-paused');
}
richlistitem[type="download"][state="6"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-blocked-parental');
}
richlistitem[type="download"][state="7"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-scanning');
}
richlistitem[type="download"][state="8"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-dirty');
}
richlistitem[type="download"][state="9"] {
-moz-binding: url('chrome://webapprt/content/downloads/download.xml#download-blocked-policy');
}
/* Only focus buttons in the selected item*/
richlistitem[type="download"]:not([selected="true"]) button {
-moz-user-focus: none;
}
File diff suppressed because it is too large Load Diff
-163
View File
@@ -1,163 +0,0 @@
<?xml version="1.0"?>
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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/.
#ifdef XP_UNIX
#ifndef XP_MACOSX
#define XP_GNOME 1
#endif
#endif
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://webapprt/content/downloads/downloads.css"?>
<?xml-stylesheet href="chrome://webapprt/skin/downloads/downloads.css"?>
<!DOCTYPE window [
<!ENTITY % downloadManagerDTD SYSTEM "chrome://webapprt/locale/downloads/downloads.dtd">
%downloadManagerDTD;
<!ENTITY % editMenuOverlayDTD SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
%editMenuOverlayDTD;
]>
<window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="downloadManager" windowtype="Download:Manager"
orient="vertical" title="&downloads.title;" statictitle="&downloads.title;"
width="&window.width2;" height="&window.height;" screenX="10" screenY="10"
persist="width height screenX screenY sizemode"
onload="Startup();" onunload="Shutdown();"
onclose="return closeWindow(false);">
<script type="application/javascript" src="chrome://webapprt/content/downloads/downloads.js"/>
<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<stringbundleset id="downloadSet">
<stringbundle id="brandStrings" src="chrome://branding/locale/brand.properties"/>
<stringbundle id="downloadStrings" src="chrome://mozapps/locale/downloads/downloads.properties"/>
</stringbundleset>
<!-- Use this commandset for command which do not depened on focus or selection -->
<commandset id="generalCommands">
<command id="cmd_findDownload" oncommand="gDownloadList.setSearchboxFocus();"/>
<command id="cmd_selectAllDownloads" oncommand="gDownloadList.selectAll();"/>
<command id="cmd_clearList" oncommand="gDownloadList.clearList();"/>
</commandset>
<keyset id="downloadKeys">
<key keycode="VK_RETURN" oncommand="gDownloadList.doDefaultForSelected();"/>
<key id="key_pauseResume" key=" " oncommand="gDownloadList.performCommand('cmd_pauseResume');"/>
<key id="key_removeFromList" keycode="VK_DELETE" oncommand="gDownloadList.performCommand('cmd_removeFromList');"/>
#ifdef XP_MACOSX
<key id="key_removeFromList2" keycode="VK_BACK" oncommand="gDownloadList.performCommand('cmd_removeFromList');"/>
#endif
<key id="key_close" key="&cmd.close.commandKey;" oncommand="closeWindow(true);" modifiers="accel"/>
#ifdef XP_GNOME
<key id="key_close2" key="&cmd.close2Unix.commandKey;" oncommand="closeWindow(true);" modifiers="accel,shift"/>
#else
<key id="key_close2" key="&cmd.close2.commandKey;" oncommand="closeWindow(true);" modifiers="accel"/>
#endif
<key keycode="VK_ESCAPE" oncommand="closeWindow(true);"/>
<key id="key_findDownload"
key="&cmd.find.commandKey;"
modifiers="accel"
command="cmd_findDownload"/>
<key id="key_findDownload2"
key="&cmd.search.commandKey;"
modifiers="accel"
command="cmd_findDownload"/>
<key id="key_selectAllDownloads"
key="&selectAllCmd.key;"
modifiers="accel"
command="cmd_selectAllDownloads"/>
<key id="pasteKey"
key="V"
modifiers="accel"
oncommand="gDownloadList.pasteHandler();"/>
</keyset>
<vbox id="contextMenuPalette" hidden="true">
<menuitem id="menuitem_pause"
label="&cmd.pause.label;" accesskey="&cmd.pause.accesskey;"
oncommand="gDownloadList.performCommand('cmd_pause');"
cmd="cmd_pause"/>
<menuitem id="menuitem_resume"
label="&cmd.resume.label;" accesskey="&cmd.resume.accesskey;"
oncommand="gDownloadList.performCommand('cmd_resume');"
cmd="cmd_resume"/>
<menuitem id="menuitem_cancel"
label="&cmd.cancel.label;" accesskey="&cmd.cancel.accesskey;"
oncommand="gDownloadList.performCommand('cmd_cancel');"
cmd="cmd_cancel"/>
<menuitem id="menuitem_open" default="true"
label="&cmd.open.label;" accesskey="&cmd.open.accesskey;"
oncommand="gDownloadList.performCommand('cmd_open');"
cmd="cmd_open"/>
<menuitem id="menuitem_show"
#ifdef XP_MACOSX
label="&cmd.showMac.label;"
accesskey="&cmd.showMac.accesskey;"
#else
label="&cmd.show.label;"
accesskey="&cmd.show.accesskey;"
#endif
oncommand="gDownloadList.performCommand('cmd_show');"
cmd="cmd_show"/>
<menuitem id="menuitem_retry" default="true"
label="&cmd.retry.label;" accesskey="&cmd.retry.accesskey;"
oncommand="gDownloadList.performCommand('cmd_retry');"
cmd="cmd_retry"/>
<menuitem id="menuitem_removeFromList"
label="&cmd.removeFromList.label;" accesskey="&cmd.removeFromList.accesskey;"
oncommand="gDownloadList.performCommand('cmd_removeFromList');"
cmd="cmd_removeFromList"/>
<menuseparator id="menuseparator"/>
<menuitem id="menuitem_openReferrer"
label="&cmd.goToDownloadPage.label;"
accesskey="&cmd.goToDownloadPage.accesskey;"
oncommand="gDownloadList.performCommand('cmd_openReferrer');"
cmd="cmd_openReferrer"/>
<menuitem id="menuitem_copyLocation"
label="&cmd.copyDownloadLink.label;"
accesskey="&cmd.copyDownloadLink.accesskey;"
oncommand="gDownloadList.performCommand('cmd_copyLocation');"
cmd="cmd_copyLocation"/>
<menuitem id="menuitem_selectAll"
label="&selectAllCmd.label;"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAllDownloads"/>
</vbox>
<menupopup id="downloadContextMenu" onpopupshowing="return gDownloadList.buildContextMenu(event);"/>
<richlistbox id="downloadView" seltype="multiple" flex="1"
context="downloadContextMenu"
ondblclick="gDownloadList.onDownloadDblClick(event);"
ondragstart="gDownloadList.onDragStart(event);"
ondragover="gDownloadList.onDragOver(event);"
ondrop="gDownloadList.onDrop(event)">
</richlistbox>
<windowdragbox id="search" align="center">
<button id="clearListButton" command="cmd_clearList"
label="&cmd.clearList.label;"
accesskey="&cmd.clearList.accesskey;"
tooltiptext="&cmd.clearList.tooltip;"/>
<spacer flex="1"/>
<textbox type="search" id="searchbox" class="compact"
aria-controls="downloadView"
oncommand="gDownloadList.buildList();" placeholder="&searchBox.label;"/>
</windowdragbox>
</window>
-38
View File
@@ -1,38 +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/. */
function onOK() {
window.arguments[0].out = {
video: document.getElementById("video").selectedItem.value,
audio: document.getElementById("audio").selectedItem.value
};
return true;
}
function onLoad() {
let videoDevices = window.arguments[0].videoDevices;
if (videoDevices.length) {
let videoMenu = document.getElementById("video");
for (let i = 0; i < videoDevices.length; i++) {
videoMenu.appendItem(videoDevices[i].name, i);
}
videoMenu.selectedIndex = 1;
} else {
document.getElementById("videoGroup").hidden = true;
}
let audioDevices = window.arguments[0].audioDevices;
if (audioDevices.length) {
let audioMenu = document.getElementById("audio");
for (let i = 0; i < audioDevices.length; i++) {
audioMenu.appendItem(audioDevices[i].name, i);
}
audioMenu.selectedIndex = 1;
} else {
document.getElementById("audioGroup").hidden = true;
}
window.sizeToContent();
}
-45
View File
@@ -1,45 +0,0 @@
<?xml version="1.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/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE dialog [
<!ENTITY % gum-askDTD SYSTEM "chrome://webapprt/locale/getUserMediaDialog.dtd">
%gum-askDTD;
]>
<dialog id="getUserMediaDialog" title="&getUserMediaDialog.title;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
buttons="accept,cancel"
buttonlabelaccept="&getUserMediaDialog.button.accept.label;"
buttonaccesskeyaccept="&getUserMediaDialog.button.accept.accesskey;"
onload="onLoad()"
ondialogaccept="return onOK()"
buttonlabelcancel="&getUserMediaDialog.button.cancel.label;"
buttonaccesskeycancel="&getUserMediaDialog.button.cancel.accesskey;">
<script type="application/javascript"
src="chrome://webapprt/content/getUserMediaDialog.js"/>
<groupbox id="videoGroup" flex="1">
<caption label="&getUserMediaDialog.video.label;"/>
<menulist id="video">
<menupopup>
<menuitem label="&getUserMediaDialog.video.noVideo;" value="-1"/>
</menupopup>
</menulist>
</groupbox>
<groupbox id="audioGroup" flex="1">
<caption label="&getUserMediaDialog.audio.label;"/>
<menulist id="audio">
<menupopup>
<menuitem label="&getUserMediaDialog.audio.noAudio;" value="-1"/>
</menupopup>
</menulist>
</groupbox>
</dialog>
-91
View File
@@ -1,91 +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/. */
/* Note: this script is loaded by both mochitest.js and head.js, so make sure
* the code you put here can be evaluated by both! */
Cu.import("resource://webapprt/modules/WebappRT.jsm");
Cu.import("resource://gre/modules/Task.jsm");
// When WebappsHandler opens an install confirmation dialog for apps we install,
// close it, which will be seen as the equivalent of cancelling the install.
// This doesn't prevent us from installing those apps, as we listen for the same
// notification as WebappsHandler and do the install ourselves. It just
// prevents the modal installation confirmation dialogs from hanging tests.
Services.ww.registerNotification({
observe: function(win, topic) {
if (topic == "domwindowopened") {
// Wait for load because the window is not yet sufficiently initialized.
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.location == "chrome://global/content/commonDialog.xul" &&
win.opener == window) {
win.close();
}
}, false);
}
}
});
/**
* Transmogrify the runtime session into one for the given webapp.
*
* @param {String} manifestURL
* The URL of the webapp's manifest, relative to the base URL.
* Note that the base URL points to the *chrome* WebappRT mochitests,
* so you must supply an absolute URL to manifests elsewhere.
* @param {Object} parameters
* The value to pass as the "parameters" argument to
* mozIDOMApplicationRegistry.install, e.g., { receipts: ... }.
* Use undefined to pass nothing.
* @param {Function} onBecome
* The callback to call once the transmogrification is complete.
*/
function becomeWebapp(manifestURL, parameters, onBecome) {
let observeInstall = Task.async(function*(subj, topic, data) {
Services.obs.removeObserver(observeInstall, "webapps-ask-install");
// Step 2: Configure the runtime session to represent the app.
// We load DOMApplicationRegistry into a local scope to avoid appearing
// to leak it.
let scope = {};
Cu.import("resource://gre/modules/Webapps.jsm", scope);
Cu.import("resource://webapprt/modules/Startup.jsm", scope);
yield scope.DOMApplicationRegistry.confirmInstall(JSON.parse(data));
let installRecord = JSON.parse(data);
installRecord.mm = subj;
installRecord.registryDir = Services.dirsvc.get("ProfD", Ci.nsIFile).path;
WebappRT.config = installRecord;
WebappRT._configPromise = new Promise((resolve) => resolve());
let win = Services.wm.getMostRecentWindow("webapprt:webapp");
if (!win) {
win = Services.ww.openWindow(null,
"chrome://webapprt/content/webapp.xul",
"_blank",
"chrome,dialog=no,resizable,scrollbars,centerscreen",
null);
}
// During chrome tests, we use the same window to load all the tests. We
// need to change the buildID so that the permissions for the currently
// tested application get installed.
Services.prefs.setCharPref("webapprt.buildID", WebappRT.config.app.manifestURL);
// During tests, the webapps registry is already loaded,
// but SystemMessageInternal expects to be notified when the registry
// start and then when it's ready, so we do that now.
Services.obs.notifyObservers(this, "webapps-registry-start", null);
Services.obs.notifyObservers(this, "webapps-registry-ready", null);
yield scope.startup(win);
onBecome();
});
Services.obs.addObserver(observeInstall, "webapps-ask-install", false);
// Step 1: Install the app at the URL specified by the manifest.
navigator.mozApps.install(manifestURL, parameters);
}
-35
View File
@@ -1,35 +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/. */
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Services.scriptloader
.loadSubScript("chrome://webapprt/content/mochitest-shared.js", this);
// In test mode, the runtime isn't configured until we tell it to become
// an app, which requires us to use DOMApplicationRegistry to install one.
// But DOMApplicationRegistry needs to know the location of its registry dir,
// so we need to configure the runtime with at least that information.
WebappRT.config = {
registryDir: Services.dirsvc.get("ProfD", Ci.nsIFile).path,
};
Cu.import("resource://gre/modules/Webapps.jsm");
becomeWebapp("http://mochi.test:8888/webapprtContent/webapprt/test/content/test.webapp",
undefined, function onBecome() {
if (window.arguments && window.arguments[0]) {
let testUrl = window.arguments[0].QueryInterface(Ci.nsIPropertyBag2).get("url");
if (testUrl) {
let win = Services.wm.getMostRecentWindow("webapprt:webapp");
win.document.getElementById("content").setAttribute("src", testUrl);
}
}
window.close();
});
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.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/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="browserTestHarness"
windowtype="webapprt:mochitest"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://webapprt/content/mochitest.js"/>
<description value="WebappRT Test Shim"/>
</window>
-238
View File
@@ -1,238 +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/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://webapprt/modules/WebappRT.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyGetter(this, "gAppBrowser",
function() document.getElementById("content"));
function isSameOrigin(url) {
let origin = Services.io.newURI(url, null, null).prePath;
return (origin == WebappRT.config.app.origin);
}
let progressListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
onLocationChange: function onLocationChange(progress, request, location,
flags) {
// Close tooltip (code adapted from /browser/base/content/browser.js)
let pageTooltip = document.getElementById("contentAreaTooltip");
let tooltipNode = pageTooltip.triggerNode;
if (tooltipNode) {
// Optimise for the common case
if (progress.isTopLevel) {
pageTooltip.hidePopup();
}
else {
for (let tooltipWindow = tooltipNode.ownerDocument.defaultView;
tooltipWindow != tooltipWindow.parent;
tooltipWindow = tooltipWindow.parent) {
if (tooltipWindow == progress.DOMWindow) {
pageTooltip.hidePopup();
break;
}
}
}
}
// Set the title of the window to the name of the webapp, adding the origin
// of the page being loaded if it's from a different origin than the app
// (per security bug 741955, which specifies that other-origin pages loaded
// in runtime windows must be identified in chrome).
let title = WebappRT.localeManifest.name;
if (!isSameOrigin(location.spec)) {
title = location.prePath + " - " + title;
}
document.documentElement.setAttribute("title", title);
},
onStateChange: function onStateChange(aProgress, aRequest, aFlags, aStatus) {
if (aRequest instanceof Ci.nsIChannel &&
aFlags & Ci.nsIWebProgressListener.STATE_START &&
aFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) {
}
}
};
function onOpenWindow(event) {
let name = event.detail.name;
if (name == "_blank") {
let uri = Services.io.newURI(event.detail.url, null, null);
// Direct the URL to the browser.
Cc["@mozilla.org/uriloader/external-protocol-service;1"].
getService(Ci.nsIExternalProtocolService).
getProtocolHandlerInfo(uri.scheme).
launchWithURI(uri);
} else {
let win = window.openDialog("chrome://webapprt/content/webapp.xul",
name,
"chrome,dialog=no,resizable," + event.detail.features);
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
#ifndef XP_WIN
#ifndef XP_MACOSX
if (isSameOrigin(event.detail.url)) {
// On non-Windows platforms, we open new windows in fullscreen mode
// if the opener window is in fullscreen mode, so we hide the menubar;
// but on Mac we don't need to hide the menubar.
if (document.mozFullScreenElement) {
win.document.getElementById("main-menubar").style.display = "none";
}
}
#endif
#endif
win.document.getElementById("content").docShell.setIsApp(WebappRT.appID);
win.document.getElementById("content").setAttribute("src", event.detail.url);
}, false);
}
}
function onLoad() {
window.removeEventListener("load", onLoad, false);
gAppBrowser.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION |
Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
updateMenuItems();
gAppBrowser.addEventListener("mozbrowseropenwindow", onOpenWindow);
}
window.addEventListener("load", onLoad, false);
function onUnload() {
gAppBrowser.removeProgressListener(progressListener);
gAppBrowser.removeEventListener("mozbrowseropenwindow", onOpenWindow);
}
window.addEventListener("unload", onUnload, false);
// Fullscreen handling.
#ifndef XP_MACOSX
document.addEventListener('mozfullscreenchange', function() {
if (document.mozFullScreenElement) {
document.getElementById("main-menubar").style.display = "none";
} else {
document.getElementById("main-menubar").style.display = "";
}
}, false);
#endif
// On Mac, we dynamically create the label for the Quit menuitem, using
// a string property to inject the name of the webapp into it.
let updateMenuItems = Task.async(function*() {
#ifdef XP_MACOSX
yield WebappRT.configPromise;
let manifest = WebappRT.localeManifest;
let bundle =
Services.strings.createBundle("chrome://webapprt/locale/webapp.properties");
let quitLabel = bundle.formatStringFromName("quitApplicationCmdMac.label",
[manifest.name], 1);
let hideLabel = bundle.formatStringFromName("hideApplicationCmdMac.label",
[manifest.name], 1);
document.getElementById("menu_FileQuitItem").setAttribute("label", quitLabel);
document.getElementById("menu_mac_hide_app").setAttribute("label", hideLabel);
#endif
});
#ifndef XP_MACOSX
let gEditUIVisible = true;
#endif
function updateEditUIVisibility() {
#ifndef XP_MACOSX
let editMenuPopupState = document.getElementById("menu_EditPopup").state;
let contextMenuPopupState = document.getElementById("contentAreaContextMenu").state;
// The UI is visible if the Edit menu is opening or open, if the context menu
// is open, or if the toolbar has been customized to include the Cut, Copy,
// or Paste toolbar buttons.
gEditUIVisible = editMenuPopupState == "showing" ||
editMenuPopupState == "open" ||
contextMenuPopupState == "showing" ||
contextMenuPopupState == "open";
// If UI is visible, update the edit commands' enabled state to reflect
// whether or not they are actually enabled for the current focus/selection.
if (gEditUIVisible) {
goUpdateGlobalEditMenuItems();
}
// Otherwise, enable all commands, so that keyboard shortcuts still work,
// then lazily determine their actual enabled state when the user presses
// a keyboard shortcut.
else {
goSetCommandEnabled("cmd_undo", true);
goSetCommandEnabled("cmd_redo", true);
goSetCommandEnabled("cmd_cut", true);
goSetCommandEnabled("cmd_copy", true);
goSetCommandEnabled("cmd_paste", true);
goSetCommandEnabled("cmd_selectAll", true);
goSetCommandEnabled("cmd_delete", true);
goSetCommandEnabled("cmd_switchTextDirection", true);
}
#endif
}
// Context menu handling code.
// At the moment there isn't any built-in menu, we only support HTML5 custom
// menus.
let gContextMenu = null;
XPCOMUtils.defineLazyGetter(this, "PageMenu", function() {
let tmp = {};
Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
return new tmp.PageMenu();
});
function showContextMenu(aEvent, aXULMenu) {
if (aEvent.target != aXULMenu) {
return true;
}
gContextMenu = new nsContextMenu(aXULMenu);
if (gContextMenu.shouldDisplay) {
updateEditUIVisibility();
}
return gContextMenu.shouldDisplay;
}
function hideContextMenu(aEvent, aXULMenu) {
if (aEvent.target != aXULMenu) {
return;
}
gContextMenu = null;
updateEditUIVisibility();
}
function nsContextMenu(aXULMenu) {
this.initMenu(aXULMenu);
}
nsContextMenu.prototype = {
initMenu: function(aXULMenu) {
this.hasPageMenu = PageMenu.maybeBuildAndAttachMenu(document.popupNode,
aXULMenu);
this.shouldDisplay = this.hasPageMenu;
},
};
-168
View File
@@ -1,168 +0,0 @@
<?xml version="1.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/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<!DOCTYPE window [
<!ENTITY % webappDTD SYSTEM "chrome://webapprt/locale/webapp.dtd">
%webappDTD;
]>
<window windowtype="webapprt:webapp"
id="default"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="1024" height="768"
fullscreenbutton="true"
persist="screenX screenY width height sizemode"
>
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript" src="chrome://webapprt/content/webapp.js"/>
<commandset id="mainCommandSet">
<command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
<commandset id="editMenuCommands"/>
</commandset>
<keyset id="mainKeyset">
<key id="key_undo"
key="&undoCmd.key;"
modifiers="accel"/>
<key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"/>
<key id="key_cut"
key="&cutCmd.key;"
modifiers="accel"/>
<key id="key_copy"
key="&copyCmd.key;"
modifiers="accel"/>
<key id="key_paste"
key="&pasteCmd.key;"
modifiers="accel"/>
<key id="key_delete" keycode="VK_DELETE" command="cmd_delete"/>
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
<key id="key_quitApplication"
key="&quitApplicationCmdUnix.key;"
command="cmd_quitApplication"
modifiers="accel"/>
<key id="key_hideThisAppCmdMac"
key="&hideThisAppCmdMac.key;"
modifiers="accel"/>
<key id="key_hideOtherAppsCmdMac"
key="&hideOtherAppsCmdMac.key;"
modifiers="accel,alt"/>
</keyset>
<menubar id="main-menubar">
#ifndef XP_MACOSX
<!-- On Mac, the Quit item gets moved to the Application menu by nsMenuBarX.
- And right now it's the only item in the File menu. So if we put it
- into that menu on Mac, the File menu shows up empty on that OS.
- To work around that problem, we put the item into the Edit menu on Mac
- (from which nsMenuBarX still moves it properly), and we don't create
- the File menu in the first place on that OS.
-
- But if you are adding a persistent item to the File menu on Mac,
- then that workaround is no longer necessary, and you can move the Quit
- item up here. -->
<menu id="file-menu" label="&fileMenu.label;"
accesskey="&fileMenu.accesskey;">
<menupopup id="menu_FilePopup">
<menuitem id="menu_FileQuitItem"
#ifdef XP_WIN
label="&quitApplicationCmdWin.label;"
accesskey="&quitApplicationCmdWin.accesskey;"
#else
label="&quitApplicationCmd.label;"
accesskey="&quitApplicationCmd.accesskey;"
#endif
#ifdef XP_UNIX
key="key_quitApplication"
#endif
command="cmd_quitApplication"/>
</menupopup>
</menu>
#endif
<menu id="edit-menu" label="&editMenu.label;"
accesskey="&editMenu.accesskey;">
<menupopup id="menu_EditPopup"
onpopupshowing="updateEditUIVisibility()"
onpopuphidden="updateEditUIVisibility()">
#ifdef XP_MACOSX
<!-- These items get moved to the Application menu by nsMenuBarX.
- They can live in any menu.
-
- See the comment on the File menu above for why the Quit item is
- here, and note that JavaScript code dynamically updates the labels
- of the Quit and Hide items, which include the name of the app. -->
<menuitem id="menu_FileQuitItem"
label="&quitApplicationCmd.label;"
key="key_quitApplication"
command="cmd_quitApplication"/>
<menuitem id="menu_mac_hide_app"
key="key_hideThisAppCmdMac"/>
<menuitem id="menu_mac_hide_others"
label="&hideOtherAppsCmdMac.label;"
key="key_hideOtherAppsCmdMac"/>
<menuitem id="menu_mac_show_all" label="&showAllAppsCmdMac.label;"/>
#endif
<menuitem id="menu_undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="cmd_undo"/>
<menuitem id="menu_redo"
label="&redoCmd.label;"
key="key_redo"
accesskey="&redoCmd.accesskey;"
command="cmd_redo"/>
<menuseparator/>
<menuitem id="menu_cut"
label="&cutCmd.label;"
key="key_cut"
accesskey="&cutCmd.accesskey;"
command="cmd_cut"/>
<menuitem id="menu_copy"
label="&copyCmd.label;"
key="key_copy"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="menu_paste"
label="&pasteCmd.label;"
key="key_paste"
accesskey="&pasteCmd.accesskey;"
command="cmd_paste"/>
<menuitem id="menu_delete"
label="&deleteCmd.label;"
key="key_delete"
accesskey="&deleteCmd.accesskey;"
command="cmd_delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
</menupopup>
</menu>
</menubar>
<browser type="content-primary" id="content" flex="1" context="contentAreaContextMenu" tooltip="contentAreaTooltip" />
<popupset>
<menupopup id="contentAreaContextMenu" pagemenu="start"
onpopupshowing="return showContextMenu(event, this)"
onpopuphiding="hideContextMenu(event, this)">
</menupopup>
<tooltip id="contentAreaTooltip" page="true" />
</popupset>
</window>
-1
View File
@@ -1 +0,0 @@
XPI_ROOT_APPID=webapprt@mozilla.org
-14
View File
@@ -1,14 +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/.
NSDISTMODE = copy
PROGRAMS_DEST = $(DIST)/bin
include $(topsrcdir)/config/rules.mk
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
DEFINES += -DGRE_BUILDID=$(GRE_BUILDID)
webapprt.$(OBJ_SUFFIX): $(DEPTH)/config/buildid
-28
View File
@@ -1,28 +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/.
# mozglue is statically linked into GoannaPrograms on gtk builds, so
# we can use GoannaProgram, contrary to other platforms.
GoannaProgram('webapprt-stub')
SOURCES += [
'webapprt.cpp',
]
FAIL_ON_WARNINGS = True
GENERATED_INCLUDES += ['/build']
LOCAL_INCLUDES += [
'/toolkit/xre',
'/xpcom/base',
'/xpcom/build',
]
DISABLE_STL_WRAPPING = True
CXXFLAGS += CONFIG['TK_CFLAGS']
OS_LIBS += CONFIG['TK_LIBS']
-408
View File
@@ -1,408 +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/. */
// GTK headers
#include <gtk/gtk.h>
// Linux headers
#include <fcntl.h>
#include <unistd.h>
#include <dlfcn.h>
// Mozilla headers
#include "nsIFile.h"
#include "nsINIParser.h"
#include "nsXPCOMGlue.h"
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
#include "nsXULAppAPI.h"
#include "BinaryPath.h"
const char kAPP_INI[] = "application.ini";
const char kWEBAPP_INI[] = "webapp.ini";
const char kWEBAPP_JSON[] = "webapp.json";
const char kWEBAPP_PACKAGE[] = "application.zip";
const char kWEBAPPRT_INI[] = "webapprt.ini";
const char kWEBAPPRT_PATH[] = "webapprt";
const char kAPP_ENV_VAR[] = "XUL_APP_FILE";
const char kAPP_RT[] = "webapprt-stub";
int* pargc;
char*** pargv;
char profile[MAXPATHLEN];
bool isProfileOverridden = false;
XRE_GetFileFromPathType XRE_GetFileFromPath;
XRE_CreateAppDataType XRE_CreateAppData;
XRE_FreeAppDataType XRE_FreeAppData;
XRE_mainType XRE_main;
const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
{ "XRE_main", (NSFuncPtr*) &XRE_main },
{ nullptr, nullptr }
};
class ScopedLogging
{
public:
ScopedLogging() { NS_LogInit(); }
~ScopedLogging() { NS_LogTerm(); }
};
// Copied from toolkit/xre/nsAppData.cpp.
void SetAllocatedString(const char *&str, const char *newvalue)
{
NS_Free(const_cast<char*>(str));
if (newvalue) {
str = NS_strdup(newvalue);
}
else {
str = nullptr;
}
}
// Function to open a dialog box displaying the message provided
void ErrorDialog(const char* message)
{
gtk_init(pargc, pargv);
GtkWidget* dialog = gtk_message_dialog_new(nullptr, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
gtk_window_set_title(GTK_WINDOW(dialog), "Error launching webapp");
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), false);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
// Function to get the parent dir of a file
void GetDirFromPath(char* parentDir, char* filePath)
{
char* base = strrchr(filePath, '/');
if (!base) {
strcpy(parentDir, ".");
}
else {
while (base > filePath && *base == '/')
base--;
int len = 1 + base - filePath;
strncpy(parentDir, filePath, len);
parentDir[len] = '\0';
}
}
bool CopyFile(const char* inputFile, const char* outputFile)
{
// Open input file
int inputFD = open(inputFile, O_RDONLY);
if (!inputFD)
return false;
// Open output file
int outputFD = creat(outputFile, S_IRWXU);
if (!outputFD)
return false;
// Copy file
char buf[BUFSIZ];
ssize_t bytesRead;
while ((bytesRead = read(inputFD, buf, BUFSIZ)) > 0) {
ssize_t bytesWritten = write(outputFD, buf, bytesRead);
if (bytesWritten < 0) {
bytesRead = -1;
break;
}
}
// Close file descriptors
close(inputFD);
close(outputFD);
return (bytesRead >= 0);
}
bool GRELoadAndLaunch(const char* firefoxDir, bool silentFail)
{
char xpcomDllPath[MAXPATHLEN];
snprintf(xpcomDllPath, MAXPATHLEN, "%s/%s", firefoxDir, XPCOM_DLL);
if (silentFail && access(xpcomDllPath, F_OK) != 0)
return false;
if (NS_FAILED(XPCOMGlueStartup(xpcomDllPath))) {
ErrorDialog("Couldn't load the XPCOM library");
return false;
}
if (NS_FAILED(XPCOMGlueLoadXULFunctions(kXULFuncs))) {
ErrorDialog("Couldn't load libxul");
return false;
}
// NOTE: The GRE has successfully loaded, so we can use XPCOM now
{ // Scope for any XPCOM stuff we create
ScopedLogging log;
// Get the path to the runtime
char rtPath[MAXPATHLEN];
snprintf(rtPath, MAXPATHLEN, "%s/%s", firefoxDir, kWEBAPPRT_PATH);
// Get the path to the runtime's INI file
char rtIniPath[MAXPATHLEN];
snprintf(rtIniPath, MAXPATHLEN, "%s/%s", rtPath, kWEBAPPRT_INI);
// Load the runtime's INI from its path
nsCOMPtr<nsIFile> rtINI;
if (NS_FAILED(XRE_GetFileFromPath(rtIniPath, getter_AddRefs(rtINI)))) {
ErrorDialog("Couldn't load the runtime INI");
return false;
}
bool exists;
nsresult rv = rtINI->Exists(&exists);
if (NS_FAILED(rv) || !exists) {
ErrorDialog("The runtime INI doesn't exist");
return false;
}
nsXREAppData *webShellAppData;
if (NS_FAILED(XRE_CreateAppData(rtINI, &webShellAppData))) {
ErrorDialog("Couldn't read WebappRT application.ini");
return false;
}
if (!isProfileOverridden) {
SetAllocatedString(webShellAppData->profile, profile);
// nsXREAppData::name is used for the class name part of the WM_CLASS
// property. Set it so that the DE can match our window to the correct
// launcher.
char programClass[MAXPATHLEN];
snprintf(programClass, MAXPATHLEN, "owa-%s", profile);
SetAllocatedString(webShellAppData->name, programClass);
}
nsCOMPtr<nsIFile> directory;
if (NS_FAILED(XRE_GetFileFromPath(rtPath, getter_AddRefs(directory)))) {
ErrorDialog("Couldn't open runtime directory");
return false;
}
nsCOMPtr<nsIFile> xreDir;
if (NS_FAILED(XRE_GetFileFromPath(firefoxDir, getter_AddRefs(xreDir)))) {
ErrorDialog("Couldn't open XRE directory");
return false;
}
xreDir.forget(&webShellAppData->xreDirectory);
NS_IF_RELEASE(webShellAppData->directory);
directory.forget(&webShellAppData->directory);
XRE_main(*pargc, *pargv, webShellAppData, 0);
XRE_FreeAppData(webShellAppData);
}
return true;
}
void CopyAndRelaunch(const char* firefoxDir, const char* curExePath)
{
char newExePath[MAXPATHLEN];
snprintf(newExePath, MAXPATHLEN, "%s/%s", firefoxDir, kAPP_RT);
if (unlink(curExePath) == -1) {
ErrorDialog("Couldn't remove the old webapprt-stub executable");
return;
}
if (!CopyFile(newExePath, curExePath)) {
ErrorDialog("Couldn't copy the new webapprt-stub executable");
return;
}
execv(curExePath, *pargv);
ErrorDialog("Couldn't execute the new webapprt-stub executable");
}
void RemoveApplication(nsINIParser& parser, const char* curExeDir, const char* profile) {
if (!isProfileOverridden) {
// Remove the desktop entry file.
char desktopEntryFilePath[MAXPATHLEN];
char* dataDir = getenv("XDG_DATA_HOME");
if (dataDir && *dataDir) {
snprintf(desktopEntryFilePath, MAXPATHLEN, "%s/applications/owa-%s.desktop", dataDir, profile);
} else {
char* home = getenv("HOME");
snprintf(desktopEntryFilePath, MAXPATHLEN, "%s/.local/share/applications/owa-%s.desktop", home, profile);
}
unlink(desktopEntryFilePath);
}
// Remove the files from the installation directory.
char webAppIniPath[MAXPATHLEN];
snprintf(webAppIniPath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_INI);
unlink(webAppIniPath);
char curExePath[MAXPATHLEN];
snprintf(curExePath, MAXPATHLEN, "%s/%s", curExeDir, kAPP_RT);
unlink(curExePath);
char webAppJsonPath[MAXPATHLEN];
snprintf(webAppJsonPath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_JSON);
unlink(webAppJsonPath);
char iconPath[MAXPATHLEN];
snprintf(iconPath, MAXPATHLEN, "%s/icon.png", curExeDir);
unlink(iconPath);
char packagePath[MAXPATHLEN];
snprintf(packagePath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_PACKAGE);
unlink(packagePath);
char appName[MAXPATHLEN];
if (NS_FAILED(parser.GetString("Webapp", "Name", appName, MAXPATHLEN))) {
strcpy(appName, profile);
}
char uninstallMsg[MAXPATHLEN];
if (NS_SUCCEEDED(parser.GetString("Webapp", "UninstallMsg", uninstallMsg, MAXPATHLEN))) {
/**
* The only difference between libnotify.so.4 and libnotify.so.1 for these symbols
* is that notify_notification_new takes three arguments in libnotify.so.4 and
* four in libnotify.so.1.
* Passing the fourth argument as nullptr is binary compatible.
*/
typedef void (*notify_init_t)(const char*);
typedef void* (*notify_notification_new_t)(const char*, const char*, const char*, const char*);
typedef void (*notify_notification_show_t)(void*, void**);
void *handle = dlopen("libnotify.so.4", RTLD_LAZY);
if (!handle) {
handle = dlopen("libnotify.so.1", RTLD_LAZY);
if (!handle)
return;
}
notify_init_t nn_init = (notify_init_t)(uintptr_t)dlsym(handle, "notify_init");
notify_notification_new_t nn_new = (notify_notification_new_t)(uintptr_t)dlsym(handle, "notify_notification_new");
notify_notification_show_t nn_show = (notify_notification_show_t)(uintptr_t)dlsym(handle, "notify_notification_show");
if (!nn_init || !nn_new || !nn_show) {
dlclose(handle);
return;
}
nn_init(appName);
void* n = nn_new(uninstallMsg, nullptr, "dialog-information", nullptr);
nn_show(n, nullptr);
dlclose(handle);
}
}
int main(int argc, char *argv[])
{
pargc = &argc;
pargv = &argv;
// Get current executable path
char curExePath[MAXPATHLEN];
if (NS_FAILED(mozilla::BinaryPath::Get(argv[0], curExePath))) {
ErrorDialog("Couldn't read current executable path");
return 255;
}
char curExeDir[MAXPATHLEN];
GetDirFromPath(curExeDir, curExePath);
bool removeApp = false;
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-profile") || !strcmp(argv[i], "--profile")) {
isProfileOverridden = true;
}
else if (!strcmp(argv[i], "-remove") || !strcmp(argv[i], "--remove")) {
removeApp = true;
}
}
char firefoxDir[MAXPATHLEN];
// Check if Firefox is in the same directory as the webapp runtime.
// This is the case for webapprt chrome and content tests.
if (GRELoadAndLaunch(curExeDir, true)) {
return 0;
}
// Set up webAppIniPath with path to webapp.ini
char webAppIniPath[MAXPATHLEN];
snprintf(webAppIniPath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_INI);
// Open webapp.ini as an INI file
nsINIParser parser;
if (NS_FAILED(parser.Init(webAppIniPath))) {
ErrorDialog("Couldn't open webapp.ini");
return 255;
}
// Set up our environment to know where webapp.ini was loaded from
if (setenv(kAPP_ENV_VAR, webAppIniPath, 1) == -1) {
ErrorDialog("Couldn't set up app environment");
return 255;
}
// Get profile dir from webapp.ini
if (NS_FAILED(parser.GetString("Webapp", "Profile", profile, MAXPATHLEN))) {
ErrorDialog("Couldn't retrieve profile from web app INI file");
return 255;
}
if (removeApp) {
RemoveApplication(parser, curExeDir, profile);
return 0;
}
// Get the location of Firefox from our webapp.ini
if (NS_FAILED(parser.GetString("WebappRT", "InstallDir", firefoxDir, MAXPATHLEN))) {
ErrorDialog("Couldn't find your Firefox install directory.");
return 255;
}
// Set up appIniPath with path to application.ini.
// This is in the Firefox installation directory.
char appIniPath[MAXPATHLEN];
snprintf(appIniPath, MAXPATHLEN, "%s/%s", firefoxDir, kAPP_INI);
if (NS_FAILED(parser.Init(appIniPath))) {
ErrorDialog("This app requires that Firefox version 16 or above is installed."
" Firefox 16+ has not been detected.");
return 255;
}
// Get buildid of Firefox we're trying to load (MAXPATHLEN only for convenience)
char buildid[MAXPATHLEN];
if (NS_FAILED(parser.GetString("App", "BuildID", buildid, MAXPATHLEN))) {
ErrorDialog("Couldn't read BuildID from Firefox application.ini");
return 255;
}
// If WebAppRT version == Firefox version, load XUL and execute the application
if (!strcmp(buildid, NS_STRINGIFY(GRE_BUILDID))) {
if (GRELoadAndLaunch(firefoxDir, false))
return 0;
}
// Else, copy WebAppRT from Firefox installation and re-execute the process
else
CopyAndRelaunch(firefoxDir, curExePath);
return 255;
}
-18
View File
@@ -1,18 +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/.
webapprt.jar:
% content webapprt %content/
* content/webapp.js (content/webapp.js)
* content/webapp.xul (content/webapp.xul)
content/getUserMediaDialog.xul (content/getUserMediaDialog.xul)
content/getUserMediaDialog.js (content/getUserMediaDialog.js)
content/mochitest-shared.js (content/mochitest-shared.js)
content/mochitest.js (content/mochitest.js)
content/mochitest.xul (content/mochitest.xul)
content/dbg-webapp-actors.js (content/dbg-webapp-actors.js)
* content/downloads/downloads.xul (content/downloads/downloads.xul)
content/downloads/downloads.js (content/downloads/downloads.js)
content/downloads/downloads.css (content/downloads/downloads.css)
content/downloads/download.xml (content/downloads/download.xml)
@@ -1,10 +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/.
# LOCALIZATION NOTE: This file must be saved as UTF8
# LOCALIZATION NOTE: $AppName will be replaced with the (already localized)
# name of the webapp being uninstalled.
^UninstallCaption=$AppName Uninstall
UN_CONFIRM_UNINSTALL=$AppName will be uninstalled from your computer.
@@ -1,52 +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/. -->
<!-- LOCALIZATION NOTE (window.width2, window.height): These values should be
close to the golden ratio (1.618:1) while making sure it's wide enough for long
file names and tall enough to hint that there are more downloads in the list -->
<!ENTITY window.width2 "485">
<!ENTITY window.height "300">
<!ENTITY starting.label "Starting…">
<!ENTITY scanning.label "Scanning for viruses…">
<!ENTITY downloads.title "Downloads">
<!ENTITY cmd.pause.label "Pause">
<!ENTITY cmd.pause.accesskey "P">
<!ENTITY cmd.resume.label "Resume">
<!ENTITY cmd.resume.accesskey "R">
<!ENTITY cmd.cancel.label "Cancel">
<!ENTITY cmd.cancel.accesskey "C">
<!ENTITY cmd.show.label "Open Containing Folder">
<!ENTITY cmd.show.accesskey "F">
<!ENTITY cmd.showMac.label "Show in Finder">
<!ENTITY cmd.showMac.accesskey "F">
<!ENTITY cmd.open.label "Open">
<!ENTITY cmd.open.accesskey "O">
<!ENTITY cmd.openWith.label "Open With…">
<!ENTITY cmd.openWith.accesskey "h">
<!ENTITY cmd.retry.label "Retry">
<!ENTITY cmd.retry.accesskey "R">
<!ENTITY cmd.goToDownloadPage.label "Go to Download Page">
<!ENTITY cmd.goToDownloadPage.accesskey "G">
<!ENTITY cmd.copyDownloadLink.label "Copy Download Link">
<!ENTITY cmd.copyDownloadLink.accesskey "L">
<!ENTITY cmd.removeFromList.label "Remove From List">
<!ENTITY cmd.removeFromList.accesskey "e">
<!ENTITY cmd.close.commandKey "w">
<!ENTITY cmd.close2.commandKey "j">
<!ENTITY cmd.close2Unix.commandKey "y">
<!ENTITY cmd.clearList.label "Clear List">
<!ENTITY cmd.clearList.tooltip "Removes completed, canceled, and failed downloads from the list">
<!ENTITY cmd.clearList.accesskey "C">
<!ENTITY cmd.find.commandKey "f">
<!ENTITY cmd.search.commandKey "k">
<!ENTITY closeWhenDone.label "Close when downloads complete">
<!ENTITY closeWhenDone.tooltip "Closes the Downloads window when all files are done downloading">
<!ENTITY showFolder.label "Show this Folder">
<!ENTITY searchBox.label "Search…">
@@ -1,17 +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/. -->
<!-- LOCALIZATION NOTE: These are localized strings for the getUserMedia dialog
- to ask permissions in the webapp runtime. -->
<!ENTITY getUserMediaDialog.title "Media Sharing">
<!ENTITY getUserMediaDialog.button.accept.label "Share">
<!ENTITY getUserMediaDialog.button.accept.accesskey "S">
<!ENTITY getUserMediaDialog.button.cancel.label "Cancel">
<!ENTITY getUserMediaDialog.button.cancel.accesskey "n">
<!ENTITY getUserMediaDialog.video.label "Select camera">
<!ENTITY getUserMediaDialog.video.noVideo "No video">
<!ENTITY getUserMediaDialog.audio.label "Select microphone">
<!ENTITY getUserMediaDialog.audio.noAudio "No audio">
@@ -1,36 +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/.
malformedURI=The URL is not valid and cannot be loaded.
fileNotFound=The file %S cannot be found. Please check the location and try again.
dnsNotFound=%S could not be found. Please check the name and try again.
unknownProtocolFound=One of the following %S is not a registered protocol or is not allowed in this context.
connectionFailure=The connection was refused when attempting to contact %S.
netInterrupt=The connection to %S has terminated unexpectedly. Some data may have been transferred.
netTimeout=The operation timed out when attempting to contact %S.
redirectLoop=A server is redirecting a request in a way that will never complete.
confirmRepostPrompt=To continue, the application must send information that will repeat an action (such as a search or order confirmation) that was performed earlier.
resendButton.label=Resend
unknownSocketType=The application doesn't know how to communicate with the server.
netReset=The connection to the server was reset while the application was loading.
notCached=The application requested a document which is no longer available.
netOffline=The application is currently in offline mode and can't access the network.
isprinting=The document cannot change while Printing or in Print Preview.
deniedPortAccess=The application tried to access a network port that it should not have access to. The application has canceled the request for your protection.
proxyResolveFailure=The application is configured to use a proxy server that can't be found.
proxyConnectFailure=The application is configured to use a proxy server that is refusing connections.
contentEncodingError=The application received a response from a server which used an invalid or unsupported form of compression.
unsafeContentType=The application cannot continue because it accessed a file type that may not be safe to open. Please contact the application authors to inform them of this problem.
externalProtocolTitle=External Protocol Request
externalProtocolPrompt=An external application must be launched to handle %1$S: links.\n\n\nRequested link:\n\n%2$S\n\nApplication: %3$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n
#LOCALIZATION NOTE (externalProtocolUnknown): The following string is shown if the application name can't be determined
externalProtocolUnknown=<Unknown>
externalProtocolChkMsg=Remember my choice for all links of this type.
externalProtocolLaunchBtn=Launch application
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
cspBlocked=This application tried to access a resource that has a content security policy that prevents it from being loaded in this way.
corruptedContentError=The application cannot continue loading because an error in the data transmission was detected.
remoteXUL=This application tried to use an unsupported technology that is no longer available.
sslv3Used=This application cannot guarantee the safety of your data on %S because it uses SSLv3, a broken security protocol.
@@ -1,154 +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/.
KillScriptTitle=Warning: Unresponsive script
KillScriptMessage=A script may be busy, or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete.
KillScriptWithDebugMessage=A script may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.
KillScriptLocation=Script: %S
StopScriptButton=Stop script
DebugScriptButton=Debug script
WaitForScriptButton=Continue
DontAskAgain=&Don't ask me again
JSURLLoadBlockedWarning=Attempt to load a javascript: URL from one host\nin a window displaying content from another host\nwas blocked by the security manager.
WindowCloseBlockedWarning=Scripts may not close windows that were not opened by script.
OnBeforeUnloadTitle=Are you sure?
OnBeforeUnloadMessage=This application is asking you to confirm that you want to leave - data you have entered may not be saved.
OnBeforeUnloadStayButton=Stay
OnBeforeUnloadLeaveButton=Leave
UnexpectedCanvasVariantStyle=canvas: an attempt to set strokeStyle or fillStyle to a value that is neither a string, a CanvasGradient, or a CanvasPattern was ignored.
EmptyGetElementByIdParam=Empty string passed to getElementById().
LowMemoryTitle=Warning: Low memory
LowMemoryMessage=An application script has been stopped due to a low memory condition.
SpeculationFailed=An unbalanced tree was written using document.write() causing data from the network to be reparsed. For more information https://developer.mozilla.org/en/Optimizing_Your_Pages_for_Speculative_Parsing
DocumentWriteIgnored=A call to document.write() from an asynchronously-loaded external script was ignored.
FormValidationTextTooLong=Please shorten this text to %S characters or less (you are currently using %S characters).
FormValidationValueMissing=Please fill out this field.
FormValidationCheckboxMissing=Please check this box if you want to proceed.
FormValidationRadioMissing=Please select one of these options.
FormValidationFileMissing=Please select a file.
FormValidationSelectMissing=Please select an item in the list.
FormValidationInvalidEmail=Please enter an email address.
FormValidationInvalidURL=Please enter a URL.
FormValidationPatternMismatch=Please match the requested format.
# LOCALIZATION NOTE (FormValidationPatternMismatchWithTitle): %S is the (possibly truncated) title attribute value.
FormValidationPatternMismatchWithTitle=Please match the requested format: %S.
# LOCALIZATION NOTE (FormValidationNumberRangeOverflow): %S is a number.
FormValidationNumberRangeOverflow=Please select a value that is no more than %S.
# LOCALIZATION NOTE (FormValidationDateRangeOverflow): %S is a date.
FormValidationDateRangeOverflow=Please select a value that is no earlier than %S.
# LOCALIZATION NOTE (FormValidationTimeRangeOverflow): %S is a time.
FormValidationTimeRangeOverflow=Please select a value that is no earlier than %S.
# LOCALIZATION NOTE (FormValidationNumberRangeUnderflow): %S is a number.
FormValidationNumberRangeUnderflow=Please select a value that is no less than %S.
# LOCALIZATION NOTE (FormValidationDateRangeUnderflow): %S is a date.
FormValidationDateRangeUnderflow=Please select a value that is no later than %S.
# LOCALIZATION NOTE (FormValidationTimeRangeUnderflow): %S is a time.
FormValidationTimeRangeUnderflow=Please select a value that is no later than %S.
# LOCALIZATION NOTE (FormValidationStepMismatch): both %S can be a number, a date or a time.
FormValidationStepMismatch=Please select a valid value. The two nearest valid values are %S and %S.
# LOCALIZATION NOTE (FormValidationStepMismatchOneValue): %S can be a number, a date or a time. This is called instead of FormValidationStepMismatch when the second value is the same as the first.
FormValidationStepMismatchOneValue=Please select a valid value. The nearest valid value is %S.
FormValidationBadInputNumber=Please enter a number.
GetAttributeNodeWarning=Use of getAttributeNode() is deprecated. Use getAttribute() instead.
SetAttributeNodeWarning=Use of setAttributeNode() is deprecated. Use setAttribute() instead.
GetAttributeNodeNSWarning=Use of getAttributeNodeNS() is deprecated. Use getAttributeNS() instead.
SetAttributeNodeNSWarning=Use of setAttributeNodeNS() is deprecated. Use setAttributeNS() instead.
RemoveAttributeNodeWarning=Use of removeAttributeNode() is deprecated. Use removeAttribute() instead.
CreateAttributeWarning=Use of document.createAttribute() is deprecated. Use element.setAttribute() instead.
CreateAttributeNSWarning=Use of document.createAttributeNS() is deprecated. Use element.setAttributeNS() instead.
OwnerElementWarning=Use of attributes' ownerElement attribute is deprecated.
NodeValueWarning=Use of attributes' nodeValue attribute is deprecated. Use value instead.
TextContentWarning=Use of attributes' textContent attribute is deprecated. Use value instead.
EnablePrivilegeWarning=Use of enablePrivilege is deprecated. Please use code that runs with the system principal (e.g. an extension) instead.
nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated. Please use JSON.parse instead.
nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated. Please use JSON.stringify instead.
nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead.
InputEncodingWarning=Use of inputEncoding is deprecated.
# LOCALIZATION NOTE: Do not translate "MozBeforePaint" and "mozRequestAnimationFrame"
MozBeforePaintWarning=MozBeforePaint events are no longer supported. mozRequestAnimationFrame must be passed a non-null callback argument.
FullScreenDeniedBlocked=Request for full-screen was denied because this domain has been blocked from full-screen by user.
FullScreenDeniedDisabled=Request for full-screen was denied because full-screen API is disabled by user preference.
FullScreenDeniedFocusedPlugin=Request for full-screen was denied because a windowed plugin is focused.
FullScreenDeniedHidden=Request for full-screen was denied because the document is no longer visible.
FullScreenDeniedIframeNotAllowed=Request for full-screen was denied because at least one of the document's containing iframes does not have an "allowfullscreen" attribute.
FullScreenDeniedNotInputDriven=Request for full-screen was denied because Element.mozRequestFullScreen() was not called from inside a short running user-generated event handler.
FullScreenDeniedNotInDocument=Request for full-screen was denied because requesting element is no longer in its document.
FullScreenDeniedMovedDocument=Request for full-screen was denied because requesting element has moved document.
FullScreenDeniedLostWindow=Request for full-screen was denied because we no longer have a window.
FullScreenDeniedSubDocFullScreen=Request for full-screen was denied because a subdocument of the document requesting full-screen is already full-screen.
FullScreenDeniedNotDescendant=Request for full-screen was denied because requesting element is not a descendant of the current full-screen element.
FullScreenDeniedNotFocusedTab=Request for full-screen was denied because requesting element is not in the currently focused tab.
FullScreenDeniedContentOnly=Request for full-screen was denied because requesting element is in the chrome document and the fullscreen API is configured for content only.
RemovedFullScreenElement=Exited full-screen because full-screen element was removed from document.
FocusedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was focused.
HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.
ResponseTypeSyncXHRWarning=Use of XMLHttpRequest's responseType attribute is no longer supported in the synchronous mode in window context.
WithCredentialsSyncXHRWarning=Use of XMLHttpRequest's withCredentials attribute is no longer supported in the synchronous mode in window context.
TimeoutSyncXHRWarning=Use of XMLHttpRequest's timeout attribute is not supported in the synchronous mode in window context.
JSONCharsetWarning=An attempt was made to declare a non-UTF-8 encoding for JSON retrieved using XMLHttpRequest. Only UTF-8 is supported for decoding JSON.
# LOCALIZATION NOTE: Do not translate AudioBufferSourceNode
MediaBufferSourceNodeResampleOutOfMemory=Insufficient memory to resample the AudioBufferSourceNode for playback.
# LOCALIZATION NOTE: Do not translate decodeAudioData.
MediaDecodeAudioDataUnknownContentType=The buffer passed to decodeAudioData contains an unknown content type.
# LOCALIZATION NOTE: Do not translate decodeAudioData.
MediaDecodeAudioDataUnknownError=An unknown error occured while processing decodeAudioData.
# LOCALIZATION NOTE: Do not translate decodeAudioData.
MediaDecodeAudioDataInvalidContent=The buffer passed to decodeAudioData contains invalid content which cannot be decoded successfully.
# LOCALIZATION NOTE: Do not translate decodeAudioData.
MediaDecodeAudioDataNoAudio=The buffer passed to decodeAudioData does not contain any audio.
MediaLoadExhaustedCandidates=All candidate resources failed to load. Media load paused.
MediaLoadSourceMissingSrc=<source> element has no "src" attribute. Media resource load failed.
# LOCALIZATION NOTE: %1$S is the Http error code the server returned (e.g. 404, 500, etc), %2$S is the URL of the media resource which failed to load.
MediaLoadHttpError=HTTP load failed with status %1$S. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %S is the URL of the media resource which failed to load.
MediaLoadInvalidURI=Invalid URI. Load of media resource %S failed.
# LOCALIZATION NOTE: %1$S is the media resource's format/codec type (basically equivalent to the file type, e.g. MP4,AVI,WMV,MOV etc), %2$S is the URL of the media resource which failed to load.
MediaLoadUnsupportedTypeAttribute=Specified "type" attribute of "%1$S" is not supported. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %1$S is the "media" attribute value of the <source> element. It is a media query. %2$S is the URL of the media resource which failed to load.
MediaLoadSourceMediaNotMatched=Specified "media" attribute of "%1$S" does not match the environment. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %1$S is the MIME type HTTP header being sent by the web server, %2$S is the URL of the media resource which failed to load.
MediaLoadUnsupportedMimeType=HTTP "Content-Type" of "%1$S" is not supported. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %S is the URL of the media resource which failed to load because of error in decoding.
MediaLoadDecodeError=Media resource %S could not be decoded.
# LOCALIZATION NOTE: Do not translate "DOMException", "code" and "name"
DOMExceptionCodeWarning=Use of DOMException's code attribute is deprecated. Use name instead.
# LOCALIZATION NOTE: Do not translate "__exposedProps__"
NoExposedPropsWarning=Exposing chrome JS objects to content without __exposedProps__ is insecure and deprecated. See https://developer.mozilla.org/en/XPConnect_wrappers for more information.
# LOCALIZATION NOTE: Do not translate "Mutation Event" and "MutationObserver"
MutationEventWarning=Use of Mutation Events is deprecated. Use MutationObserver instead.
# LOCALIZATION NOTE: Do not translate "Components"
ComponentsWarning=The Components object is deprecated. It will soon be removed.
PluginHangUITitle=Warning: Unresponsive plugin
PluginHangUIMessage=%S may be busy, or it may have stopped responding. You can stop the plugin now, or you can continue to see if the plugin will complete.
PluginHangUIWaitButton=Continue
PluginHangUIStopButton=Stop plugin
# LOCALIZATION NOTE: Do not translate "mozHidden", "mozVisibilityState", "hidden", or "visibilityState"
PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
# LOCALIZATION NOTE: Do not translate "NodeIterator" or "detach()".
NodeIteratorDetachWarning=Calling detach() on a NodeIterator no longer has an effect.
# LOCALIZATION NOTE: Do not translate "LenientThis" and "this"
LenientThisWarning=Ignoring get or set of property that has [LenientThis] because the "this" object is incorrect.
# LOCALIZATION NOTE: Do not translate "nsIDOMWindowUtils", "getWindowWithOuterId", or "nsIWindowMediator"
GetWindowWithOuterIdWarning=Use of nsIDOMWindowUtils.getOuterWindowWithId() is deprecated. Instead, use the nsIWindowMediator method of the same name.
# LOCALIZATION NOTE: Do not translate "getPreventDefault" or "defaultPrevented".
GetPreventDefaultWarning=Use of getPreventDefault() is deprecated. Use defaultPrevented instead.
# LOCALIZATION NOTE: Do not translate "getUserData", "setUserData", "WeakMap", or "element.dataset".
GetSetUserDataWarning=Use of getUserData() or setUserData() is deprecated. Use WeakMap or element.dataset instead.
# LOCALIZATION NOTE: Do not translate "mozGetAsFile" or "toBlob"
MozGetAsFileWarning=The non-standard mozGetAsFile method is deprecated and will soon be removed. Use the standard toBlob method instead.
# LOCALIZATION NOTE: Do not translate "captureEvents()" or "addEventListener()"
UseOfCaptureEventsWarning=Use of captureEvents() is deprecated. To upgrade your code, use the DOM 2 addEventListener() method. For more help http://developer.mozilla.org/en/docs/DOM:element.addEventListener
# LOCALIZATION NOTE: Do not translate "releaseEvents()" or "removeEventListener()"
UseOfReleaseEventsWarning=Use of releaseEvents() is deprecated. To upgrade your code, use the DOM 2 removeEventListener() method. For more help http://developer.mozilla.org/en/docs/DOM:element.removeEventListener
# LOCALIZATION NOTE: Do not translate "document.load()" or "XMLHttpRequest"
UseOfDOM3LoadMethodWarning=Use of document.load() is deprecated. To upgrade your code, use the DOM XMLHttpRequest object. For more help https://developer.mozilla.org/en/XMLHttpRequest
# LOCALIZATION NOTE: Do not translate "window.showModalDialog()" or "window.open()"
ShowModalDialogWarning=Use of window.showModalDialog() is deprecated. Use window.open() instead. For more help https://developer.mozilla.org/en-US/docs/Web/API/Window.open
# LOCALIZATION NOTE: Do not translate "window._content" or "window.content"
Window_ContentWarning=window._content is deprecated. Please use window.content instead.
# LOCALIZATION NOTE: Do not translate "XMLHttpRequest"
SyncXMLHttpRequestWarning=Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help http://xhr.spec.whatwg.org/
# LOCALIZATION NOTE: Do not translate "DataContainerEvent" or "CustomEvent"
DataContainerEventWarning=Use of DataContainerEvent is deprecated. Use CustomEvent instead.
@@ -1,51 +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/. -->
<!-- LOCALIZATION NOTE: These are localized strings for the webapp runtime,
- which loads a webapp in a separate process from Firefox. Webapps loaded
- in this way have very little application chrome, but the runtime does
- provide them with some default functionality, like the standard OS
- menus/menuitems. -->
<!ENTITY fileMenu.label "File">
<!ENTITY fileMenu.accesskey "F">
<!ENTITY quitApplicationCmdWin.label "Exit">
<!ENTITY quitApplicationCmdWin.accesskey "x">
<!ENTITY quitApplicationCmd.label "Quit">
<!ENTITY quitApplicationCmd.accesskey "Q">
<!-- On Mac, we create the Quit and Hide command labels dynamically,
- using properties in window.properties, in order to include the name
- of the webapp in the labels without creating a DTD file for it. -->
<!ENTITY hideThisAppCmdMac.key "H">
<!ENTITY hideOtherAppsCmdMac.label "Hide Others">
<!ENTITY hideOtherAppsCmdMac.key "H">
<!ENTITY showAllAppsCmdMac.label "Show All">
<!-- LOCALIZATION NOTE(quitApplicationCmdUnix.key): This keyboard shortcut is used by both Linux and OSX -->
<!ENTITY quitApplicationCmdUnix.key "Q">
<!ENTITY editMenu.label "Edit">
<!ENTITY editMenu.accesskey "E">
<!ENTITY undoCmd.label "Undo">
<!ENTITY undoCmd.key "Z">
<!ENTITY undoCmd.accesskey "U">
<!ENTITY redoCmd.label "Redo">
<!ENTITY redoCmd.key "Y">
<!ENTITY redoCmd.accesskey "R">
<!ENTITY cutCmd.label "Cut">
<!ENTITY cutCmd.key "X">
<!ENTITY cutCmd.accesskey "t">
<!ENTITY copyCmd.label "Copy">
<!ENTITY copyCmd.key "C">
<!ENTITY copyCmd.accesskey "C">
<!ENTITY pasteCmd.label "Paste">
<!ENTITY pasteCmd.key "V">
<!ENTITY pasteCmd.accesskey "P">
<!ENTITY deleteCmd.label "Delete">
<!ENTITY deleteCmd.key "D">
<!ENTITY deleteCmd.accesskey "D">
<!ENTITY selectAllCmd.label "Select All">
<!ENTITY selectAllCmd.key "A">
<!ENTITY selectAllCmd.accesskey "A">
@@ -1,53 +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/.
# LOCALIZATION NOTE: These are localized strings for the webapp runtime,
# which loads a webapp in a separate process from Firefox. Webapps loaded
# in this way have very little application chrome, but the runtime does
# provide them with some default functionality, like the standard OS
# menus/menuitems.
# LOCALIZATION NOTE (quitApplicationCmdMac.label): %S will be replaced with
# the name of the webapp.
quitApplicationCmdMac.label=Quit %S
# LOCALIZATION NOTE (hideApplicationCmdMac.label): %S will be replaced with
# the name of the webapp.
hideApplicationCmdMac.label=Hide %S
# LOCALIZATION NOTE (geolocation.title): %S will be replaced with the name of
# the webapp.
geolocation.title=%S - Share Location
geolocation.description=Do you want to share your location?
geolocation.allow=Share Location
geolocation.deny=Don't Share
geolocation.remember=Remember my choice
# LOCALIZATION NOTE (desktop-notification.title): %S will be replaced with the
# name of the webapp.
desktop-notification.title=%S - Show notifications
desktop-notification.description=Do you want to allow notifications?
desktop-notification.allow=Show
desktop-notification.deny=Don't show
desktop-notification.remember=Remember my choice
# LOCALIZATION NOTE (webapps.install.title): %S will be replaced with the name
# of the webapp being installed.
webapps.install.title=Install %S
# LOCALIZATION NOTE (webapps.install.description): %S will be replaced with the
# name of the webapp being installed.
webapps.install.description=Do you want to install %S?
webapps.install.install=Install App
webapps.install.dontinstall=Don't Install
# LOCALIZATION NOTE (webapps.uninstall.title): %S will be replaced with the name
# of the webapp being uninstalled.
webapps.uninstall.title=Uninstall %S
# LOCALIZATION NOTE (webapps.uninstall.description): %S will be replaced with the
# name of the webapp being uninstalled.
webapps.uninstall.description=Do you want to uninstall %S?
webapps.uninstall.uninstall=Uninstall App
webapps.uninstall.dontuninstall=Don't Uninstall
paymentDialog.title=Payment
paymentDialog.message=Which payment provider do you want to use?
-19
View File
@@ -1,19 +0,0 @@
#filter substitution
# 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/.
@AB_CD@.jar:
% locale webapprt @AB_CD@ %locale/webapprt/
locale/webapprt/webapp.dtd (%webapprt/webapp.dtd)
locale/webapprt/webapp.properties (%webapprt/webapp.properties)
locale/webapprt/getUserMediaDialog.dtd (%webapprt/getUserMediaDialog.dtd)
locale/webapprt/appstrings.properties (%webapprt/overrides/appstrings.properties)
locale/webapprt/dom.properties (%webapprt/overrides/dom.properties)
locale/webapprt/downloads/downloads.dtd (%webapprt/downloads/downloads.dtd)
% locale branding @AB_CD@ resource://webappbranding/
% override chrome://global/locale/appstrings.properties chrome://webapprt/locale/appstrings.properties
% override chrome://global/locale/dom/dom.properties chrome://webapprt/locale/dom.properties
-9
View File
@@ -1,9 +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/.
[general]
depth = ../..
[compare]
dirs = webapprt
-6
View File
@@ -1,6 +0,0 @@
# 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/.
JAR_MANIFESTS += ['jar.mn']
-16
View File
@@ -1,16 +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/.
# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
NSDISTMODE = copy
PROGRAMS_DEST = $(DIST)/bin
include $(topsrcdir)/config/rules.mk
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
DEFINES += -DGRE_BUILDID=$(GRE_BUILDID)
webapprt.$(OBJ_SUFFIX): $(DEPTH)/config/buildid
-31
View File
@@ -1,31 +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/.
# Can't use GoannaProgram, because we don't want to create a dependency on
# mozglue, which is impossible (difficult?) to dynamically link into our
# executable, as we copy it to arbitrary locations.
Program('webapprt-stub')
SOURCES += [
'webapprt.mm',
]
DEFINES['XPCOM_GLUE'] = True
GENERATED_INCLUDES += ['/build']
LOCAL_INCLUDES += [
'/toolkit/xre',
'/xpcom/base',
'/xpcom/build',
]
USE_LIBS += [
'xpcomglue',
]
DISABLE_STL_WRAPPING = True
FAIL_ON_WARNINGS = True
-400
View File
@@ -1,400 +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/. */
//PLAN:
// open my bundle, check for an override binary signature
// find the newest firefox. open its bundle, get the version number.
// if the firefox version is different than ours:
// delete our own binary,
// copy the newer webapprt binary from Firefox
// exec it, and quit
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <Cocoa/Cocoa.h>
#include <Foundation/Foundation.h>
#include "nsXPCOMGlue.h"
#include "nsINIParser.h"
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
#include "nsXULAppAPI.h"
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "nsStringGlue.h"
#include "mozilla/AppData.h"
using namespace mozilla;
const char WEBAPPRT_EXECUTABLE[] = "webapprt-stub";
const char FXAPPINI_NAME[] = "application.ini";
const char WEBAPPINI_NAME[] = "webapp.ini";
const char WEBRTINI_NAME[] = "webapprt.ini";
//need the correct relative path here
const char APP_MACOS_PATH[] = "/Contents/MacOS/";
const char APP_RESOURCES_PATH[] = "/Contents/Resources/";
//the path to the WebappRT subdir within the Firefox app contents dir
const char WEBAPPRT_PATH[] = "webapprt/";
void ExecNewBinary(NSString* launchPath);
NSString *PathToWebRT(NSString* alternateBinaryID);
NSException* MakeException(NSString* name, NSString* message);
void DisplayErrorAlert(NSString* title, NSString* message);
XRE_GetFileFromPathType XRE_GetFileFromPath;
XRE_CreateAppDataType XRE_CreateAppData;
XRE_FreeAppDataType XRE_FreeAppData;
XRE_mainType XRE_main;
const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
{ "XRE_main", (NSFuncPtr*) &XRE_main },
{ nullptr, nullptr }
};
nsresult
AttemptGRELoad(char *greDir)
{
nsresult rv;
char xpcomDLLPath[MAXPATHLEN];
snprintf(xpcomDLLPath, MAXPATHLEN, "%s%s", greDir, XPCOM_DLL);
rv = XPCOMGlueStartup(xpcomDLLPath);
if (NS_FAILED(rv)) {
return rv;
}
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
if (NS_FAILED(rv)) {
return rv;
}
return rv;
}
int
main(int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDictionary *args = [[NSUserDefaults standardUserDefaults]
volatileDomainForName:NSArgumentDomain];
NSString *firefoxPath = nil;
NSString *alternateBinaryID = nil;
//this is our version, to be compared with the version of the binary we are asked to use
NSString* myVersion = [NSString stringWithFormat:@"%s", NS_STRINGIFY(GRE_BUILDID)];
NSLog(@"MY WEBAPPRT BUILDID: %@", myVersion);
//I need to look in our bundle first, before deciding what firefox binary to use
NSBundle* myBundle = [NSBundle mainBundle];
NSString* myBundlePath = [myBundle bundlePath];
alternateBinaryID = [myBundle objectForInfoDictionaryKey:@"FirefoxBinary"];
NSLog(@"found override firefox binary: %@", alternateBinaryID);
@try {
//find a webapprt binary to launch with. throws an exception with error dialog if none found.
firefoxPath = PathToWebRT(alternateBinaryID);
NSLog(@"USING FIREFOX : %@", firefoxPath);
NSString* myWebRTPath = [myBundle pathForResource:@"webapprt"
ofType:nil];
if (!myWebRTPath) {
myWebRTPath = [myBundlePath stringByAppendingPathComponent:@"Contents"];
myWebRTPath = [myWebRTPath stringByAppendingPathComponent:@"MacOS"];
myWebRTPath = [myWebRTPath stringByAppendingPathComponent:@"webapprt"];
if ([[NSFileManager defaultManager] fileExistsAtPath:myWebRTPath] == NO) {
@throw MakeException(@"Missing Web Runtime Files",
@"Cannot locate binary for this App");
}
}
//GET FIREFOX BUILD ID
NSString *firefoxINIFilePath =
[NSString stringWithFormat:@"%@%s%s", firefoxPath, APP_RESOURCES_PATH,
FXAPPINI_NAME];
nsINIParser ffparser;
NSLog(@"Looking for firefox ini file here: %@", firefoxINIFilePath);
if (NS_FAILED(ffparser.Init([firefoxINIFilePath UTF8String]))) {
firefoxINIFilePath = [NSString stringWithFormat:@"%@%s%s", firefoxPath,
APP_MACOS_PATH,
FXAPPINI_NAME];
NSLog(@"Looking for firefox ini file here: %@", firefoxINIFilePath);
if (NS_FAILED(ffparser.Init([firefoxINIFilePath UTF8String]))) {
NSLog(@"Unable to locate Firefox application.ini");
@throw MakeException(@"Error",
@"Unable to parse environment files for application startup");
}
}
char ffVersChars[MAXPATHLEN];
if (NS_FAILED(ffparser.GetString("App", "BuildID", ffVersChars, MAXPATHLEN))) {
NSLog(@"Unable to retrieve Firefox BuildID");
@throw MakeException(@"Error", @"Unable to determine Firefox version.");
}
NSString* firefoxVersion = [NSString stringWithFormat:@"%s", ffVersChars];
NSLog(@"FIREFOX WEBAPPRT BUILDID: %@", firefoxVersion);
//GOT FIREFOX BUILD ID
//COMPARE MY BUILD ID AND FIREFOX BUILD ID
if ([myVersion compare: firefoxVersion] != NSOrderedSame) {
//we are going to assume that if they are different, we need to re-copy the webapprt, regardless of whether
// it is newer or older. If we don't find a webapprt, then the current Firefox must not be new enough to run webapps.
NSLog(@"### This Application has an old webrt. Updating it.");
NSLog(@"### My webapprt path: %@", myWebRTPath);
NSFileManager* fileClerk = [[NSFileManager alloc] init];
NSError *errorDesc = nil;
//we know the firefox path, so copy the new webapprt here
NSString *newWebRTPath =
[NSString stringWithFormat: @"%@%s%s", firefoxPath, APP_RESOURCES_PATH,
WEBAPPRT_EXECUTABLE];
NSLog(@"### Trying Firefox webapprt path: %@", newWebRTPath);
if (![fileClerk fileExistsAtPath:newWebRTPath]) {
newWebRTPath =
[NSString stringWithFormat: @"%@%s%s", firefoxPath, APP_MACOS_PATH,
WEBAPPRT_EXECUTABLE];
NSLog(@"### Trying Firefox webapprt path: %@", newWebRTPath);
if (![fileClerk fileExistsAtPath:newWebRTPath]) {
NSString* msg =
[NSString stringWithFormat:
@"This version of Firefox (%@) cannot run web applications, because it is not recent enough or damaged", firefoxVersion];
@throw MakeException(@"Missing Web Runtime Files", msg);
}
}
[fileClerk removeItemAtPath: myWebRTPath error: &errorDesc];
if (errorDesc != nil) {
NSLog(@"failed to unlink old binary file at path: %@ with error: %@", myWebRTPath, errorDesc);
@throw MakeException(@"Unable To Update", @"Failed preparation for Web Runtime update");
}
[fileClerk copyItemAtPath: newWebRTPath toPath: myWebRTPath error: &errorDesc];
[fileClerk release];
if (errorDesc != nil) {
NSLog(@"failed to copy new webrt file: %@", errorDesc);
@throw MakeException(@"Unable To Update Web Runtime", @"Failed to update Web Runtime");
} else {
NSLog(@"### Successfully updated webapprt, relaunching");
}
//execv the new binary, and ride off into the sunset
ExecNewBinary(myWebRTPath);
} else {
//we are ready to load XUL and such, and go go go
NSLog(@"This Application has the newest webrt. Launching!");
int result = 0;
char rtINIPath[MAXPATHLEN];
// Set up our environment to know where webapp.ini was loaded from.
char appEnv[MAXPATHLEN];
snprintf(appEnv, MAXPATHLEN, "%s%s%s", [myBundlePath UTF8String],
APP_MACOS_PATH, WEBAPPINI_NAME);
if (setenv("XUL_APP_FILE", appEnv, 1)) {
NSLog(@"Couldn't set XUL_APP_FILE to: %s", appEnv);
@throw MakeException(@"Error", @"Unable to set Web Runtime INI file.");
}
NSLog(@"Set XUL_APP_FILE to: %s", appEnv);
//CONSTRUCT GREDIR AND CALL XPCOMGLUE WITH IT
char greDir[MAXPATHLEN];
snprintf(greDir, MAXPATHLEN, "%s%s", [firefoxPath UTF8String],
APP_RESOURCES_PATH);
if (!NS_SUCCEEDED(AttemptGRELoad(greDir))) {
@throw MakeException(@"Error", @"Unable to load XUL files for application startup");
}
// NOTE: The GRE has successfully loaded, so we can use XPCOM now
NS_LogInit();
{ // Scope for any XPCOM stuff we create
// Get the path to the runtime directory.
char rtDir[MAXPATHLEN];
snprintf(rtDir, MAXPATHLEN, "%s%s%s", [firefoxPath UTF8String],
APP_RESOURCES_PATH,
WEBAPPRT_PATH);
// Get the path to the runtime's INI file. This is in the runtime
// directory.
snprintf(rtINIPath, MAXPATHLEN, "%s%s%s%s", [firefoxPath UTF8String],
APP_RESOURCES_PATH,
WEBAPPRT_PATH,
WEBRTINI_NAME);
NSLog(@"WebappRT application.ini path: %s", rtINIPath);
// Load the runtime's INI from its path.
nsCOMPtr<nsIFile> rtINI;
if (NS_FAILED(XRE_GetFileFromPath(rtINIPath, getter_AddRefs(rtINI)))) {
NSLog(@"Runtime INI path not recognized: '%s'\n", rtINIPath);
@throw MakeException(@"Error", @"Incorrect path to base INI file.");
}
bool exists;
nsresult rv = rtINI->Exists(&exists);
if (NS_FAILED(rv) || !exists) {
NSString* msg = [NSString stringWithFormat: @"This copy of Firefox (%@) cannot run Apps, because it is missing the Web Runtime's application.ini file", firefoxVersion];
@throw MakeException(@"Missing Web Runtime application.ini", msg);
}
nsXREAppData *webShellAppData;
if (NS_FAILED(XRE_CreateAppData(rtINI, &webShellAppData))) {
NSLog(@"Couldn't read WebappRT application.ini: %s", rtINIPath);
@throw MakeException(@"Error", @"Unable to parse base INI file.");
}
NSString *profile = [args objectForKey:@"profile"];
if (profile) {
NSLog(@"Profile specified with --profile: %@", profile);
}
else {
nsINIParser parser;
if (NS_FAILED(parser.Init(appEnv))) {
NSLog(@"%s was not found\n", appEnv);
@throw MakeException(@"Error", @"Unable to parse environment files for application startup");
}
char profile[MAXPATHLEN];
if (NS_FAILED(parser.GetString("Webapp", "Profile", profile, MAXPATHLEN))) {
NSLog(@"Unable to retrieve profile from App INI file");
@throw MakeException(@"Error", @"Unable to retrieve installation profile.");
}
NSLog(@"setting app profile: %s", profile);
SetAllocatedString(webShellAppData->profile, profile);
}
nsCOMPtr<nsIFile> directory;
if (NS_FAILED(XRE_GetFileFromPath(rtDir, getter_AddRefs(directory)))) {
NSLog(@"Unable to open app dir");
@throw MakeException(@"Error", @"Unable to open App directory.");
}
nsCOMPtr<nsIFile> xreDir;
if (NS_FAILED(XRE_GetFileFromPath(greDir, getter_AddRefs(xreDir)))) {
NSLog(@"Unable to open XRE dir");
@throw MakeException(@"Error", @"Unable to open App XRE directory.");
}
xreDir.forget(&webShellAppData->xreDirectory);
NS_IF_RELEASE(webShellAppData->directory);
directory.forget(&webShellAppData->directory);
// There is only XUL.
result = XRE_main(argc, argv, webShellAppData, 0);
XRE_FreeAppData(webShellAppData);
}
NS_LogTerm();
return result;
}
}
@catch (NSException *e) {
NSLog(@"got exception: %@", e);
DisplayErrorAlert([e name], [e reason]);
}
@finally {
[pool drain];
}
return 0;
} //end main
NSException*
MakeException(NSString* name, NSString* message)
{
NSException* myException = [NSException
exceptionWithName:name
reason:message
userInfo:nil];
return myException;
}
void
DisplayErrorAlert(NSString* title, NSString* message)
{
CFUserNotificationDisplayNotice(0, kCFUserNotificationNoteAlertLevel,
NULL, NULL, NULL,
(CFStringRef)title,
(CFStringRef)message,
CFSTR("Quit")
);
}
/* Find the currently installed Firefox, if any, and return
* an absolute path to it. may return nil */
NSString
*PathToWebRT(NSString* alternateBinaryID)
{
//default is firefox
NSString *binaryPath = nil;
// We're run from the Firefox bundle during WebappRT chrome and content tests.
NSString *myBundlePath = [[NSBundle mainBundle] bundlePath];
NSString *fxPath =
[NSString stringWithFormat:@"%@%sfirefox-bin", myBundlePath,
APP_MACOS_PATH];
if ([[NSFileManager defaultManager] fileExistsAtPath:fxPath]) {
return myBundlePath;
}
//we look for these flavors of Firefox, in this order
NSArray* launchBinarySearchList = [NSArray arrayWithObjects: @"org.mozilla.nightly",
@"org.mozilla.aurora",
@"org.mozilla.firefox", nil];
// If they provided a binary ID, use that.
if (alternateBinaryID != nil && ([alternateBinaryID length] > 0)) {
binaryPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:alternateBinaryID];
if (binaryPath && [binaryPath length] > 0) {
return binaryPath;
}
}
//No override found, loop through the various flavors of firefox we have
for (NSString* signature in launchBinarySearchList) {
NSLog(@"SEARCHING for webapprt, trying: %@", signature);
binaryPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:signature];
if (binaryPath && [binaryPath length] > 0) {
return binaryPath;
}
}
NSLog(@"unable to find a valid webrt path");
@throw MakeException(@"This App requires that Firefox version 16 or above is installed.", @"Firefox 16+ has not been detected.");
return nil;
}
void
ExecNewBinary(NSString* launchPath)
{
NSLog(@" launching webrt at path: %@\n", launchPath);
const char *const newargv[] = {[launchPath UTF8String], NULL};
NSLog(@"COMMAND LINE: '%@ %s'", launchPath, newargv[0]);
execv([launchPath UTF8String], (char **)newargv);
}
-60
View File
@@ -1,60 +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/.
if CONFIG['OS_ARCH'] == 'WINNT':
DIRS += ['win']
elif CONFIG['OS_ARCH'] == 'Darwin':
DIRS += ['mac']
elif CONFIG['MOZ_ENABLE_GTK']:
DIRS += ['gtk']
DIRS += [
'locales',
'themes',
]
EXTRA_COMPONENTS += [
'CommandLineHandler.js',
'components.manifest',
'ContentPermission.js',
'DirectoryProvider.js',
'PaymentUIGlue.js',
]
EXTRA_JS_MODULES += [
'DownloadView.jsm',
'RemoteDebugger.jsm',
'Startup.jsm',
'WebappManager.jsm',
'WebappRT.jsm',
'WebRTCHandler.jsm',
]
MOCHITEST_WEBAPPRT_CHROME_MANIFESTS += [
'test/chrome/downloads/webapprt.ini',
'test/chrome/webapprt.ini',
]
MOCHITEST_WEBAPPRT_CONTENT_MANIFESTS += ['test/content/webapprt.ini']
# Place webapprt resources in a separate app dir
DIST_SUBDIR = 'webapprt'
export('DIST_SUBDIR')
if CONFIG['MOZ_DEBUG']:
DEFINES['MOZ_DEBUG'] = 1
if CONFIG['MOZILLA_OFFICIAL']:
DEFINES['MOZILLA_OFFICIAL'] = True
DEFINES['GRE_MILESTONE'] = CONFIG['GRE_MILESTONE']
DEFINES['MOZ_APP_BASENAME'] = CONFIG['MOZ_APP_BASENAME']
JAR_MANIFESTS += ['jar.mn']
JS_PREFERENCE_FILES += [
'prefs.js',
]
-98
View File
@@ -1,98 +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/. */
// Check for updates once a day.
pref("webapprt.app_update_interval", 86400);
pref("browser.chromeURL", "chrome://webapprt/content/webapp.xul");
pref("browser.download.folderList", 1);
// Disable all add-on locations other than the profile (which can't be disabled this way)
pref("extensions.enabledScopes", 1);
// Auto-disable any add-ons that are "dropped in" to the profile
pref("extensions.autoDisableScopes", 1);
// Disable add-on installation via the web-exposed APIs
pref("xpinstall.enabled", false);
// Disable installation of distribution add-ons
pref("extensions.installDistroAddons", false);
// Disable the add-on compatibility dialog
pref("extensions.showMismatchUI", false);
// Set reportURL for crashes
pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
// Blocklist preferences
pref("extensions.blocklist.enabled", true);
pref("extensions.blocklist.interval", 86400);
// Controls what level the blocklist switches from warning about items to forcibly
// blocking them.
pref("extensions.blocklist.level", 2);
pref("extensions.blocklist.url", "https://blocklist.addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
pref("extensions.blocklist.itemURL", "https://blocklist.addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
pref("full-screen-api.enabled", true);
// IndexedDB
pref("dom.indexedDB.enabled", true);
// Offline cache prefs
pref("browser.offline-apps.notify", false);
pref("browser.cache.offline.enable", true);
pref("offline-apps.allow_by_default", true);
// TCPSocket
pref("dom.mozTCPSocket.enabled", true);
// Enable smooth scrolling
pref("general.smoothScroll", true);
// WebPayment
pref("dom.mozPay.enabled", true);
// System messages
pref("dom.sysmsg.enabled", true);
// Alarm API
pref("dom.mozAlarms.enabled", true);
// Disable slow script dialog for apps
pref("dom.max_script_run_time", 0);
pref("dom.max_chrome_script_run_time", 0);
// The request URL of the GeoLocation backend
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
#ifndef RELEASE_BUILD
// Enable mozPay default provider
pref("dom.payment.provider.0.name", "Firefox Marketplace");
pref("dom.payment.provider.0.description", "marketplace.firefox.com");
pref("dom.payment.provider.0.uri", "https://marketplace.firefox.com/mozpay/?req=");
pref("dom.payment.provider.0.type", "mozilla/payments/pay/v1");
pref("dom.payment.provider.0.requestMethod", "GET");
#endif
// Enable window resize and move
pref("dom.always_allow_move_resize_window", true);
// Disable all plugins. This has to be a non-empty string to disable plugins;
// otherwise, nsPluginHost::IsTypeWhitelisted assumes all plugins are enabled.
pref("plugin.allowed_types", " ");
pref("devtools.debugger.remote-enabled", true);
pref("devtools.debugger.force-local", true);
// The default for this pref reflects whether the build is capable of IPC.
// (Turning it on in a no-IPC build will have no effect.)
#ifdef XP_MACOSX
// i386 ipc preferences
pref("dom.ipc.plugins.enabled.i386", false);
pref("dom.ipc.plugins.enabled.i386.flash player.plugin", true);
// x86_64 ipc preferences
pref("dom.ipc.plugins.enabled.x86_64", true);
#else
pref("dom.ipc.plugins.enabled", true);
#endif
pref("places.database.growthIncrementKiB", 0);
-29
View File
@@ -1,29 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
navigator.mozSetMessageHandler("alarm", function (message) {
document.getElementById("msgFired").textContent = "Alarm fired.";
});
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
var request = navigator.mozAlarms.add(yesterday, "honorTimezone", {});
request.onsuccess = function(e) {
navigator.mozAlarms.remove(e.target.result);
document.getElementById("msgSet").textContent = "Success.";
};
request.onerror = function(e) {
document.getElementById("msgSet").textContent = "Failure.";
};
</script>
<p id="msgSet">Webapp waiting to set an alarm...</p>
<p id="msgFired">Webapp waiting for an alarm to fire...</p>
</body>
</html>
-11
View File
@@ -1,11 +0,0 @@
{
"name": "Alarm API Test Webapp",
"description": "A webapp for testing the alarm API.",
"launch_path": "/webapprtChrome/webapprt/test/chrome/alarm.html",
"permissions": {
"alarms": { "description": "Desc" }
},
"messages": [
{ "alarm": "/alarm.html" }
]
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-38
View File
@@ -1,38 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
let mutObserverAlarmSet = null;
let mutObserverAlarmFired = null;
let alarmSet = false;
loadWebapp("alarm.webapp", undefined, function onLoad() {
let principal = document.getElementById("content").contentDocument.defaultView.document.nodePrincipal;
let permValue = Services.perms.testExactPermissionFromPrincipal(principal, "alarms");
is(permValue, Ci.nsIPermissionManager.ALLOW_ACTION, "Alarm permission: allow.");
let msgSet = gAppBrowser.contentDocument.getElementById("msgSet");
mutObserverAlarmSet = new MutationObserver(function(mutations) {
is(msgSet.textContent, "Success.", "Alarm added.");
alarmSet = true;
});
mutObserverAlarmSet.observe(msgSet, { childList: true });
let msgFired = gAppBrowser.contentDocument.getElementById("msgFired");
mutObserverAlarmFired = new MutationObserver(function(mutations) {
is(msgFired.textContent, "Alarm fired.", "Alarm fired.");
ok(alarmSet, "Alarm set before firing.");
finish();
});
mutObserverAlarmFired.observe(msgFired, { childList: true });
});
registerCleanupFunction(function() {
mutObserverAlarmSet.disconnect();
mutObserverAlarmFired.disconnect();
});
}
-37
View File
@@ -1,37 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
let { RemoteDebugger } = Cu.import("resource://webapprt/modules/RemoteDebugger.jsm", {});
function test() {
waitForExplicitFinish();
loadWebapp("debugger.webapp", undefined, () => {
RemoteDebugger.init(Services.prefs.getIntPref('devtools.debugger.remote-port'));
let client = new DebuggerClient(DebuggerServer.connectPipe());
client.connect(() => {
client.listTabs((aResponse) => {
is(aResponse.tabs[0].title, "Debugger Test Webapp", "Title correct");
is(aResponse.tabs[0].url, "http://test/webapprtChrome/webapprt/test/chrome/debugger.html", "URL correct");
ok(aResponse.tabs[0].consoleActor, "consoleActor set");
ok(aResponse.tabs[0].gcliActor, "gcliActor set");
ok(aResponse.tabs[0].styleEditorActor, "styleEditorActor set");
ok(aResponse.tabs[0].inspectorActor, "inspectorActor set");
ok(aResponse.tabs[0].traceActor, "traceActor set");
ok(aResponse.chromeDebugger, "chromeDebugger set");
ok(aResponse.consoleActor, "consoleActor set");
ok(aResponse.profilerActor, "profilerActor set");
ok(aResponse.deviceActor, "deviceActor set");
client.close(() => {
finish();
});
});
});
});
registerCleanupFunction(function() {
DebuggerServer.destroy();
});
}
-125
View File
@@ -1,125 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
let { Downloads } = Cu.import("resource://gre/modules/Downloads.jsm", {});
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
function getFile(aFilename) {
// The download database may contain targets stored as file URLs or native
// paths. This can still be true for previously stored items, even if new
// items are stored using their file URL. See also bug 239948 comment 12.
if (aFilename.startsWith("file:")) {
// Assume the file URL we obtained from the downloads database or from the
// "spec" property of the target has the UTF-8 charset.
let fileUrl = NetUtil.newURI(aFilename).QueryInterface(Ci.nsIFileURL);
return fileUrl.file.clone();
}
// The downloads database contains a native path. Try to create a local
// file, though this may throw an exception if the path is invalid.
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(aFilename);
return file;
}
let fileDownloaded = false;
let download = new DummyDownload("download.test");
download.state = 1;
download.percentComplete = 100;
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.document.documentURI ==
"chrome://mozapps/content/downloads/unknownContentType.xul") {
ok(true, "Download dialog shown");
executeSoon(() => {
let button = win.document.documentElement.getButton("accept");
button.disabled = false;
win.document.documentElement.acceptDialog();
});
} else if (win.document.documentURI ==
"chrome://webapprt/content/downloads/downloads.xul") {
ok(true, "Download manager window shown");
ok(fileDownloaded, "File downloaded");
waitDownloadListPopulation(win).then(() => {
test_downloadList(win, [download]);
finish();
});
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
let MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
MockFilePicker.returnFiles = [download.file];
MockFilePicker.showCallback = function() {
ok(true, "File picker shown");
return MockFilePicker.returnOK;
}
let downloadListener = {
onDownloadAdded: function(aDownload) {
if (aDownload.succeeded) {
let downloadedFile = getFile(aDownload.target.path);
ok(downloadedFile.exists(), "Download completed");
is(downloadedFile.fileSize, 10, "Downloaded file has correct size");
fileDownloaded = true;
try {
downloadedFile.remove(true);
} catch (ex) {
}
}
},
onDownloadChanged: function(aDownload) {
if (aDownload.succeeded) {
let downloadedFile = getFile(aDownload.target.path);
ok(downloadedFile.exists(), "Download completed");
is(downloadedFile.fileSize, 10, "Downloaded file has correct size");
fileDownloaded = true;
try {
downloadedFile.remove(true);
} catch (ex) {
}
}
},
};
let downloadList;
registerCleanupFunction(function() {
Services.wm.getMostRecentWindow("Download:Manager").close();
Services.ww.unregisterNotification(winObserver);
MockFilePicker.cleanup();
if (downloadList) {
return downloadList.removeView(downloadListener);
}
});
function test() {
waitForExplicitFinish();
loadWebapp("download.webapp", undefined, function onLoad() {
Task.spawn(function*() {
downloadList = yield Downloads.getList(Downloads.ALL);
yield downloadList.addView(downloadListener);
gAppBrowser.contentDocument.getElementById("download").click();
}).catch(function(e) {
ok(false, "Error during test: " + e);
SimpleTest.finish();
});
});
}
@@ -1,47 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
let openedWindows = 0;
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
openedWindows++;
if (openedWindows == 2) {
ok(false, "Prompt shown.");
win.close();
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
let mutObserver = null;
loadWebapp("geolocation-prompt-noperm.webapp", undefined, function onLoad() {
let principal = document.getElementById("content").contentDocument.defaultView.document.nodePrincipal;
let permValue = Services.perms.testExactPermissionFromPrincipal(principal, "geolocation");
is(permValue, Ci.nsIPermissionManager.UNKNOWN_ACTION, "Geolocation permission: unknown.");
let msg = gAppBrowser.contentDocument.getElementById("msg");
mutObserver = new MutationObserver(function(mutations) {
if (msg.textContent == "Failure.") {
ok(true, "Permission not granted.");
} else {
ok(false, "Permission not granted.");
}
finish();
});
mutObserver.observe(msg, { childList: true });
});
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
mutObserver.disconnect();
});
}
@@ -1,51 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
let openedWindows = 0;
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
openedWindows++;
if (openedWindows == 2) {
ok(true, "Prompt shown.");
win.close();
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
let mutObserver = null;
loadWebapp("geolocation-prompt-perm.webapp", undefined, function onLoad() {
let principal = document.getElementById("content").contentDocument.defaultView.document.nodePrincipal;
let permValue = Services.perms.testExactPermissionFromPrincipal(principal, "geolocation");
is(permValue, Ci.nsIPermissionManager.PROMPT_ACTION, "Geolocation permission: prompt.");
let msg = gAppBrowser.contentDocument.getElementById("msg");
mutObserver = new MutationObserver(function(mutations) {
if (msg.textContent == "Failure.") {
ok(true, "Permission not granted.");
} else {
ok(false, "Permission not granted.");
}
if (openedWindows != 2) {
ok(false, "Prompt not shown.");
}
finish();
});
mutObserver.observe(msg, { childList: true });
});
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
mutObserver.disconnect();
});
}
@@ -1,43 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
Services.prefs.setBoolPref("media.navigator.permission.fake", true);
let getUserMediaDialogOpened = false;
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.document.documentURI == "chrome://webapprt/content/getUserMediaDialog.xul") {
getUserMediaDialogOpened = true;
win.close();
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
let mutObserver = null;
loadWebapp("getUserMedia.webapp", undefined, function onLoad() {
let msg = gAppBrowser.contentDocument.getElementById("msg");
mutObserver = new MutationObserver(function(mutations) {
is(msg.textContent, "PermissionDeniedError: The user did not grant permission for the operation.",
"getUserMedia permission denied.");
ok(getUserMediaDialogOpened, "Prompt shown.");
finish();
});
mutObserver.observe(msg, { childList: true });
});
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
mutObserver.disconnect();
Services.prefs.clearUserPref("media.navigator.permission.fake");
});
}
@@ -1,49 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
let { WebappOSUtils } = Cu.import("resource://gre/modules/WebappOSUtils.jsm", {});
let url = "http://test/webapprtChrome/webapprt/test/chrome/sample.webapp";
function test() {
waitForExplicitFinish();
loadWebapp("install-app.webapp", undefined, function onLoad() {
let dialogShown = false;
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.document.documentURI == "chrome://global/content/commonDialog.xul") {
dialogShown = true;
executeSoon(() => {
win.document.documentElement.acceptDialog();
});
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
});
let request = navigator.mozApps.install(url);
request.onsuccess = function() {
ok(dialogShown, "Install app dialog shown");
ok(request.result, "App installed");
navigator.mozApps.mgmt.uninstall(request.result).onsuccess = function() {
finish();
}
}
request.onerror = function() {
ok(false, "Not installed: " + request.error.name);
finish();
}
});
}
-103
View File
@@ -1,103 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
let { PaymentManager } = Cu.import("resource://gre/modules/Payment.jsm", {});
Cu.import("resource://webapprt/modules/WebappRT.jsm");
function test() {
waitForExplicitFinish();
let curTest = 0;
let tests = [];
tests.push({
providerUri: "https://example.com:443/webapprtChrome/webapprt/test/chrome/mozpay-success.html?req=",
message: "Success."
});
tests.push({
providerUri: "https://example.com:443/webapprtChrome/webapprt/test/chrome/mozpay-failure.html?req=",
message: "Chocolate rejected."
});
let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibW9j" +
"a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
"HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
"llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
"iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
"Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
"WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
"15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
"gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
"IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
PaymentManager.registeredProviders = {};
PaymentManager.registeredProviders["mock/payments/inapp/v1"] = {
name: "mockprovider",
description: "Mock Payment Provider",
uri: tests[curTest].providerUri,
requestMethod: "GET"
};
let providerWindow;
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.document.getElementById("content").getAttribute("src") ==
(tests[curTest].providerUri + jwt)) {
ok(true, "Payment provider window shown.");
providerWindow = win;
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
let mutObserver = null;
function onLoad() {
let msg = gAppBrowser.contentDocument.getElementById("msg");
mutObserver = new MutationObserver(function(mutations) {
is(msg.textContent, tests[curTest].message, "Got: " + tests[curTest].message);
if (!providerWindow) {
ok(false, "Payment provider window shown.");
} else {
providerWindow.close();
providerWindow = null;
}
runNextTest();
});
mutObserver.observe(msg, { childList: true });
}
loadWebapp("mozpay.webapp", undefined, onLoad);
function runNextTest() {
providerWindow = null;
if (mutObserver) {
mutObserver.disconnect();
}
curTest++;
if (curTest < tests.length) {
PaymentManager.registeredProviders["mock/payments/inapp/v1"].uri = tests[curTest].providerUri;
gAppBrowser.addEventListener("load", function onLoadH() {
gAppBrowser.removeEventListener("load", onLoadH, true);
onLoad();
}, true);
gAppBrowser.reload();
} else {
finish();
}
}
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
mutObserver.disconnect();
});
}
-37
View File
@@ -1,37 +0,0 @@
Cu.import("resource://webapprt/modules/WebappRT.jsm");
let { AllPossiblePermissions } =
Cu.import("resource://gre/modules/PermissionsInstaller.jsm", {});
let { AppsUtils } = Cu.import("resource://gre/modules/AppsUtils.jsm", {});
let { DOMApplicationRegistry } =
Cu.import("resource://gre/modules/Webapps.jsm", {});
function test() {
waitForExplicitFinish();
loadWebapp("noperm.webapp", undefined, function onLoad() {
let app = WebappRT.config.app;
// Check that the app is non privileged.
is(AppsUtils.getAppManifestStatus(app.manifest), Ci.nsIPrincipal.APP_STATUS_INSTALLED, "The app is not privileged");
// Check that the app principal has the correct appId.
let principal = document.getElementById("content").contentDocument.defaultView.document.nodePrincipal;
is(DOMApplicationRegistry.getAppLocalIdByManifestURL(app.manifestURL), principal.appId, "Principal app ID correct");
let alwaysAllowed = ["indexedDB"]
// Check if all the permissions of the app are unknown.
for (let permName of AllPossiblePermissions) {
// Get the value for the permission.
let permValue = Services.perms.testExactPermissionFromPrincipal(principal, permName);
if (alwaysAllowed.includes(permName)) {
is(permValue, Ci.nsIPermissionManager.ALLOW_ACTION, "Permission " + permName + " allowed.");
} else {
is(permValue, Ci.nsIPermissionManager.UNKNOWN_ACTION, "Permission " + permName + " unknown.");
}
}
finish();
});
}
-20
View File
@@ -1,20 +0,0 @@
// This is a sample WebappRT chrome test. It's just a browser-chrome mochitest.
Cu.import("resource://webapprt/modules/WebappRT.jsm");
function test() {
waitForExplicitFinish();
ok(true, "true is true!");
loadWebapp("sample.webapp", undefined, function onLoad() {
is(document.documentElement.getAttribute("title"),
WebappRT.config.app.manifest.name,
"Window title should be webapp name");
let msg = gAppBrowser.contentDocument.getElementById("msg");
var observer = new MutationObserver(function (mutations) {
ok(/^Webapp getSelf OK:/.test(msg.textContent),
"The webapp should have successfully installed and updated its msg");
finish();
});
observer.observe(msg, { childList: true });
});
}
-66
View File
@@ -1,66 +0,0 @@
Cu.import("resource://webapprt/modules/WebappRT.jsm");
let { AppsUtils } = Cu.import("resource://gre/modules/AppsUtils.jsm", {});
let { DOMApplicationRegistry } =
Cu.import("resource://gre/modules/Webapps.jsm", {});
let { PermissionsTable } =
Cu.import("resource://gre/modules/PermissionsTable.jsm", {});
function test() {
waitForExplicitFinish();
loadWebapp("webperm.webapp", undefined, function onLoad() {
let app = WebappRT.config.app;
// Check that the app is non privileged.
is(AppsUtils.getAppManifestStatus(app.manifest), Ci.nsIPrincipal.APP_STATUS_INSTALLED, "The app is not privileged");
// Check that the app principal has the correct appId.
let principal = document.getElementById("content").contentDocument.defaultView.document.nodePrincipal;
is(DOMApplicationRegistry.getAppLocalIdByManifestURL(app.manifestURL), principal.appId, "Principal app ID correct");
let perms = [
{
manifestName: "storage",
permName: "indexedDB",
},
{
manifestName: "geolocation",
permName: "geolocation",
},
{
manifestName: "camera",
permName: "camera",
},
{
manifestName: "alarms",
permName: "alarms",
},
{
manifestName: "tcp-socket",
permName: "tcp-socket",
},
{
manifestName: "network-events",
permName: "network-events",
},
{
manifestName: "webapps-manage",
permName: "webapps-manage",
},
{
manifestName: "desktop-notification",
permName: "desktop-notification",
},
];
for (let perm of perms) {
// Get the values for all the permission.
let permValue = Services.perms.testExactPermissionFromPrincipal(principal, perm.permName);
// Check if the app has the permission as specified in the PermissionsTable.jsm file.
is(permValue, PermissionsTable[perm.manifestName]["app"], "Permission " + perm.permName + " correctly set.");
}
finish();
});
}
@@ -1,75 +0,0 @@
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let HandlerService = {
classID: Components.ID("{b4ed9fab-fd39-435a-8e3e-edc3e689e72e}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory,
Ci.nsIExternalProtocolService]),
createInstance: function(aOuter, aIID) {
if (aOuter) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return this.QueryInterface(aIID);
},
init: function() {
Components.manager.nsIComponentRegistrar.registerFactory(this.classID,
"Test Protocol Handler Service",
"@mozilla.org/uriloader/external-protocol-service;1",
this);
},
getProtocolHandlerInfo: function(aProtocolScheme) {
let handlerInfoObj = {
launchWithURI: function(aURI) {
is(aURI.spec,
"http://test/webapprtChrome/webapprt/test/chrome/sample.html",
"The app tried to open the link in the default browser");
finish();
}
};
return handlerInfoObj;
}
};
HandlerService.init();
function test() {
waitForExplicitFinish();
let progressListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
onLocationChange: function(progress, request, location, flags) {
ok(false, "Location changed");
finish();
}
};
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.location == "chrome://webapprt/content/webapp.xul") {
ok(false, "New app window opened");
finish();
}
}, false);
}
}
loadWebapp("window-open-blank.webapp", undefined, function() {
gAppBrowser.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
});
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
gAppBrowser.removeProgressListener(progressListener);
});
}
@@ -1,55 +0,0 @@
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://webapprt/modules/WebappRT.jsm");
let { DOMApplicationRegistry } =
Cu.import("resource://gre/modules/Webapps.jsm", {});
function test() {
waitForExplicitFinish();
let appID = Ci.nsIScriptSecurityManager.NO_APP_ID;
let progressListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
onLocationChange: function(progress, request, location, flags) {
gAppBrowser.addEventListener("load", function onLoad() {
gAppBrowser.removeEventListener("load", onLoad, true);
is(DOMApplicationRegistry.getAppLocalIdByManifestURL(WebappRT.config.app.manifestURL),
appID,
"Principal app ID hasn't changed");
finish();
}, true);
}
};
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.location == "chrome://webapprt/content/webapp.xul") {
ok(false, "New app window opened");
finish();
}
}, false);
}
}
loadWebapp("window-open-self.webapp", undefined, function() {
appID = gAppBrowser.contentDocument.defaultView.document.nodePrincipal.appId;
is(DOMApplicationRegistry.getAppLocalIdByManifestURL(WebappRT.config.app.manifestURL),
appID,
"Principal app ID correct");
gAppBrowser.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
});
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
gAppBrowser.removeProgressListener(progressListener);
});
}
@@ -1,64 +0,0 @@
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://webapprt/modules/WebappRT.jsm");
let { DOMApplicationRegistry } =
Cu.import("resource://gre/modules/Webapps.jsm", {});
function test() {
waitForExplicitFinish();
let appID = Ci.nsIScriptSecurityManager.NO_APP_ID;
let progressListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
onLocationChange: function(progress, request, location, flags) {
ok(false, "Content redirected")
finish();
}
};
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.location == "chrome://webapprt/content/webapp.xul") {
let winAppBrowser = win.document.getElementById("content");
winAppBrowser.addEventListener("load", function onLoadBrowser() {
winAppBrowser.removeEventListener("load", onLoadBrowser, true);
is(winAppBrowser.getAttribute("src"),
"http://test/webapprtChrome/webapprt/test/chrome/sample.html",
"New window browser has correct src");
is(winAppBrowser.contentDocument.defaultView.document.nodePrincipal.appId,
appID,
"New window principal app ID correct");
win.close();
finish();
}, true);
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
loadWebapp("window-open.webapp", undefined, function() {
appID = gAppBrowser.contentDocument.defaultView.document.nodePrincipal.appId;
is(DOMApplicationRegistry.getAppLocalIdByManifestURL(WebappRT.config.app.manifestURL),
appID,
"Principal app ID correct");
gAppBrowser.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
});
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
gAppBrowser.removeProgressListener(progressListener);
});
}
@@ -1,53 +0,0 @@
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://webapprt/modules/WebappRT.jsm");
function test() {
waitForExplicitFinish();
loadWebapp("window-title.webapp", undefined, function onLoad() {
is(document.documentElement.getAttribute("title"),
WebappRT.config.app.manifest.name,
"initial window title should be webapp name");
// Tests are triples of [URL to load, expected window title, test message].
let tests = [
["http://example.com/webapprtChrome/webapprt/test/chrome/window-title.html",
"http://example.com" + " - " + WebappRT.config.app.manifest.name,
"window title should show origin of page at different origin"],
["http://test/webapprtChrome/webapprt/test/chrome/window-title.html",
WebappRT.config.app.manifest.name,
"after returning to app origin, window title should no longer show origin"],
];
let title, message;
let progressListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
onLocationChange: function onLocationChange(progress, request, location,
flags) {
// Do test in timeout to give runtime time to change title.
window.setTimeout(function() {
is(document.documentElement.getAttribute("title"), title, message);
testNext();
}, 0);
}
};
gAppBrowser.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
function testNext() {
if (!tests.length) {
gAppBrowser.removeProgressListener(progressListener);
gAppBrowser.stop();
finish();
return;
}
[gAppBrowser.contentDocument.location, title, message] = tests.shift();
}
testNext();
});
}
-9
View File
@@ -1,9 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>This is the test webapp.</p>
</body>
</html>
-1
View File
@@ -1 +0,0 @@
{"name": "Debugger Test Webapp", "description": "A debugger test app.", "launch_path": "/webapprtChrome/webapprt/test/chrome/debugger.html" }
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-11
View File
@@ -1,11 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Download Test App</title>
<meta charset="utf-8">
</head>
<body>
<h1>Download Test App</h1>
<a id="download" href="http://mochi.test:8888//webapprtChrome/webapprt/test/chrome/download.test">Download</a>
</body>
</html>
-1
View File
@@ -1 +0,0 @@
TEST FILE
-5
View File
@@ -1,5 +0,0 @@
{
"name": "Download Test App",
"description": "an app for testing downloads",
"launch_path": "/webapprtChrome/webapprt/test/chrome/download.html"
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
@@ -1,44 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
let list = MockDownloadsModule();
let downloadsInList = [
new DummyDownload("test1"),
new DummyDownload("test2"),
];
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.document.documentURI ==
"chrome://webapprt/content/downloads/downloads.xul") {
ok(true, "Download manager window shown");
waitDownloadListPopulation(win).then(() => {
test_downloadList(win, downloadsInList);
finish();
});
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
Services.wm.getMostRecentWindow("Download:Manager").close();
});
function test() {
waitForExplicitFinish();
loadWebapp("download.webapp", undefined, function onLoad() {
for each (let download in downloadsInList) {
list.addDownload(download);
}
});
}
@@ -1,45 +0,0 @@
Cu.import("resource://gre/modules/Services.jsm");
let list = MockDownloadsModule();
let download = new DummyDownload("test");
let removedDownload = new DummyDownload("removed");
let winObserver = function(win, topic) {
if (topic == "domwindowopened") {
win.addEventListener("load", function onLoadWindow() {
win.removeEventListener("load", onLoadWindow, false);
if (win.document.documentURI ==
"chrome://webapprt/content/downloads/downloads.xul") {
ok(true, "Download manager window shown");
waitDownloadListPopulation(win).then(() => {
test_downloadList(win, [download, removedDownload]);
list.removeDownload(removedDownload);
executeSoon(() => {
test_downloadList(win, [download]);
finish();
});
});
}
}, false);
}
}
Services.ww.registerNotification(winObserver);
registerCleanupFunction(function() {
Services.ww.unregisterNotification(winObserver);
Services.wm.getMostRecentWindow("Download:Manager").close();
});
function test() {
waitForExplicitFinish();
loadWebapp("download.webapp", undefined, function onLoad() {
list.addDownload(download);
list.addDownload(removedDownload);
});
}
@@ -1,6 +0,0 @@
[DEFAULT]
support-files =
../head.js
[browser_add_download.js]
[browser_remove_download.js]
@@ -1,22 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
window.onload = function() {
function failureCallback() {
document.getElementById("msg").textContent = "Failure.";
}
function successCallback() {
document.getElementById("msg").textContent = "Success.";
}
navigator.geolocation.getCurrentPosition(successCallback, failureCallback);
};
</script>
<p id="msg">Webapp waiting for geolocation...</p>
</body>
</html>
@@ -1,5 +0,0 @@
{
"name": "Geolocation Permission Test Webapp",
"description": "A webapp for testing geolocation prompt.",
"launch_path": "/webapprtChrome/webapprt/test/chrome/geolocation-prompt-noperm.html"
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
@@ -1,18 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
function failureCallback() {
document.getElementById("msg").textContent = "Failure.";
}
function successCallback() {
document.getElementById("msg").textContent = "Success.";
}
navigator.geolocation.getCurrentPosition(successCallback, failureCallback);
</script>
<p id="msg">Webapp waiting for geolocation...</p>
</body>
</html>
@@ -1,8 +0,0 @@
{
"name": "Geolocation Permission Test Webapp",
"description": "A webapp for testing geolocation prompt.",
"launch_path": "/webapprtChrome/webapprt/test/chrome/geolocation-prompt-perm.html",
"permissions": {
"geolocation": { "description": "Desc" }
}
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-21
View File
@@ -1,21 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>getUserMedia Test App</title>
<meta charset="utf-8">
</head>
<body>
<span id="msg"></span>
<script>
navigator.mozGetUserMedia({ video: true, audio: true, fake: true },
function(localMediaStream) {
document.getElementById("msg").textContent = window.URL.createObjectURL(localMediaStream);
},
function(err) {
document.getElementById("msg").textContent = err;
});
</script>
<h1>getUserMedia Test App</h1>
</body>
</html>
-5
View File
@@ -1,5 +0,0 @@
{
"name": "getUserMedia Test App",
"description": "an app for testing getUserMedia",
"launch_path": "/webapprtChrome/webapprt/test/chrome/getUserMedia.html"
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-234
View File
@@ -1,234 +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/. */
Cu.import("resource://gre/modules/Services.jsm");
// Some of the code we want to provide to chrome mochitests is in another file
// so we can share it with the mochitest shim window, thus we need to load it.
Services.scriptloader
.loadSubScript("chrome://webapprt/content/mochitest-shared.js", this);
const MANIFEST_URL_BASE = Services.io.newURI(
"http://test/webapprtChrome/webapprt/test/chrome/", null, null);
/**
* Load the webapp in the app browser.
*
* @param {String} manifestURL
* @see becomeWebapp
* @param {Object} parameters
* @see becomeWebapp
* @param {Function} onLoad
* The callback to call once the webapp is loaded.
*/
function loadWebapp(manifest, parameters, onLoad) {
let url = Services.io.newURI(manifest, null, MANIFEST_URL_BASE);
becomeWebapp(url.spec, parameters, function onBecome() {
function onLoadApp() {
gAppBrowser.removeEventListener("load", onLoadApp, true);
onLoad();
}
gAppBrowser.addEventListener("load", onLoadApp, true);
gAppBrowser.setAttribute("src", WebappRT.launchURI);
});
registerCleanupFunction(function() {
// We load DOMApplicationRegistry into a local scope to avoid appearing
// to leak it.
let { DOMApplicationRegistry } = Cu.import("resource://gre/modules/Webapps.jsm", {});
return new Promise(function(resolve, reject) {
DOMApplicationRegistry.uninstall(url.spec).then(() => {
// Load another page in the browser element, this is needed for tests
// that use the same app (that have the same URL).
gAppBrowser.setAttribute("src", "about:blank");
resolve();
}, reject);
});
});
}
// Utilities for the downloads tests
let MockDownloadList = function() {
};
MockDownloadList.prototype = {
downloads: new Set(),
views: new Set(),
addView: function(aView) {
this.views.add(aView);
for (let download of this.downloads) {
for (let view of this.views) {
view.onDownloadAdded(download);
}
}
},
removeView: function(aView) {
this.views.delete(aView);
},
addDownload: function(aDownload) {
this.downloads.add(aDownload);
for (let view of this.views) {
view.onDownloadAdded(aDownload);
}
},
changeDownload: function(aDownload) {
for (let view of this.views) {
if (view.onDownloadChanged) {
view.onDownloadChanged(aDownload);
}
}
},
removeDownload: function(aDownload) {
this.downloads.delete(aDownload);
for (let view of this.views) {
if (view.onDownloadRemoved) {
view.onDownloadRemoved(aDownload);
}
}
},
}
function MockDownloadsModule() {
let { DownloadView } = Cu.import("resource://webapprt/modules/DownloadView.jsm", {});
let list = new MockDownloadList();
let { Downloads } = Cu.import("resource://gre/modules/Downloads.jsm", {});
let oldDownloadsGetList = Downloads.getList;
Downloads.getList = function(aKind) {
return new Promise(function(resolve, reject) {
resolve(list);
});
};
registerCleanupFunction(function() {
list.removeView(DownloadView);
Downloads.getList = oldDownloadsGetList;
});
// Reinitialize DownloadView because it's already initialized
// when the webapprt test starts.
// We need to reinitialize it so that it gets associated to the
// MockDownloadList object that we've created.
DownloadView.init();
return list;
}
function DummyDownload(aFileName) {
this.file = Services.dirsvc.get("ProfD", Ci.nsIFile);
this.file.append(aFileName);
this.file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
this.startTime = Date.now();
this.source = {
url: "http://mochi.test:8888//webapprtChrome/webapprt/test/chrome/download.webapp",
isPrivate: false,
referrer: null,
};
this.target = {
path: this.file.path,
partFilePath: this.file.path + ".part",
}
};
DummyDownload.prototype = {
succeeded: false,
canceled: false,
stopped: false,
hasPartialData: false,
hasProgress: false,
progress: 0,
currentBytes: 0,
totalBytes: 0,
error: null,
// Attributes needed to test the download item in the richlistbox
state: 0,
percentComplete: -1,
};
function waitDownloadListPopulation(aWin) {
return new Promise(function(resolve, reject) {
let disconnected = false;
var observer = new MutationObserver(function(aMutations) {
for each (let mutation in aMutations) {
if (mutation.addedNodes) {
for each (let node in mutation.addedNodes) {
if (node.id == "downloadView") {
observer.disconnect();
disconnected = true;
// Wait for the resolution of the Downloads.getList promise.
executeSoon(() => {
resolve();
});
}
}
}
}
});
observer.observe(aWin.document, {
childList: true,
subtree: true,
attributes: false,
characterData: false
});
registerCleanupFunction(function() {
if (!disconnected) {
observer.disconnect();
}
});
});
}
function test_downloadList(aWin, aDownloadList) {
let richlistbox = aWin.document.getElementById("downloadView");
is(richlistbox.children.length, aDownloadList.length,
"There is the correct number of richlistitems");
for (let i = 0; i < richlistbox.children.length; i++) {
let elm = richlistbox.children[i];
let name = elm.getAttribute("target");
let download = null;
for (let d = 0; d < aDownloadList.length; d++) {
if (aDownloadList[d].file.leafName == name) {
download = aDownloadList[d];
aDownloadList.splice(d, 1);
}
}
if (!download) {
ok(false, "Download item unexpected");
} else {
ok(true, "Download item expected");
is(elm.getAttribute("state"), download.state, "Download state correct");
is(elm.getAttribute("progress"), download.percentComplete,
"Download progress correct");
}
}
is(aDownloadList.length, 0,
"All the downloads expected to be in the list were in the list");
}
-10
View File
@@ -1,10 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Install Test App</title>
<meta charset="utf-8">
</head>
<body>
<h1>Install Test App</h1>
</body>
</html>
-5
View File
@@ -1,5 +0,0 @@
{
"name": "Install Test App",
"description": "an app for testing installing apps",
"launch_path": "/webapprtChrome/webapprt/test/chrome/install-app.html"
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-12
View File
@@ -1,12 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
mozPaymentProvider.paymentFailed('Chocolate rejected.');
</script>
<p id="msg">Webapp waiting to pay...</p>
</body>
</html>
-12
View File
@@ -1,12 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
mozPaymentProvider.paymentSuccess();
</script>
<p id="msg">Webapp waiting to pay...</p>
</body>
</html>
-45
View File
@@ -1,45 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
// Payload
// {
// "aud": "mockpayprovider.phpfogapp.com",
// "iss": "Enter you app key here!",
// "request": {
// "name": "Piece of Cake",
// "price": "10.50",
// "priceTier": 1,
// "productdata": "transaction_id=86",
// "currencyCode": "USD",
// "description": "Virtual chocolate cake to fill your virtual tummy"
// },
// "exp": 1352232792,
// "iat": 1352229192,
// "typ": "mock/payments/inapp/v1"
// }
var jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibW9j" +
"a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
"HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
"llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
"iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
"Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
"WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
"15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
"gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
"IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
var request = navigator.mozPay(jwt);
request.onsuccess = function onsuccess() {
document.getElementById("msg").textContent = "Success.";
};
request.onerror = function onerror() {
document.getElementById("msg").textContent = request.error.name;
};
</script>
<p id="msg">Webapp waiting to be paid...</p>
</body>
</html>
-5
View File
@@ -1,5 +0,0 @@
{
"name": "mozPay Test Webapp",
"description": "A webapp that wants to be paid (and shall be paid).",
"launch_path": "/webapprtChrome/webapprt/test/chrome/mozpay.html"
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-9
View File
@@ -1,9 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>This is the test webapp.</p>
</body>
</html>
-5
View File
@@ -1,5 +0,0 @@
{
"name": "No Permissions Test Webapp",
"description": "A webapp for testing permission installation.",
"launch_path": "/webapprtChrome/webapprt/test/chrome/noperm.html"
}
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-30
View File
@@ -1,30 +0,0 @@
<!DOCTYPE HTML>
<!--
This is the webapp. It doesn't need to do anything in particular, just
whatever you want to test from your browser_ test file.
-->
<html>
<head>
<meta charset="utf-8">
<script>
function onLoad() {
var msg = document.getElementById("msg");
var self = navigator.mozApps.getSelf();
self.onsuccess = function () {
msg.textContent = "Webapp getSelf OK: " + self.result;
};
self.onerror = function () {
msg.textContent = "Webapp getSelf failed: " + self.error.name;
};
}
</script>
</head>
<body onload="onLoad();" onunload="">
<p>This is the test webapp.</p>
<p id="msg">Webapp waiting for page load...</p>
</body>
</html>
-1
View File
@@ -1 +0,0 @@
{"name": "Sample Test Webapp", "description": "A webapp that demonstrates how to make a WebappRT test.", "launch_path": "/webapprtChrome/webapprt/test/chrome/sample.html" }
@@ -1 +0,0 @@
Content-Type: application/x-web-app-manifest+json
-67
View File
@@ -1,67 +0,0 @@
[DEFAULT]
support-files =
head.js
sample.webapp
sample.webapp^headers^
sample.html
window-title.webapp
window-title.webapp^headers^
window-title.html
webperm.webapp
webperm.webapp^headers^
webperm.html
noperm.webapp
noperm.webapp^headers^
noperm.html
geolocation-prompt-perm.webapp
geolocation-prompt-perm.webapp^headers^
geolocation-prompt-noperm.webapp
geolocation-prompt-noperm.webapp^headers^
geolocation-prompt-perm.html
geolocation-prompt-noperm.html
debugger.webapp
debugger.webapp^headers^
debugger.html
mozpay.webapp
mozpay.webapp^headers^
mozpay.html
mozpay-success.html
mozpay-failure.html
getUserMedia.webapp
getUserMedia.webapp^headers^
getUserMedia.html
window-open-self.webapp
window-open-self.webapp^headers^
window-open-self.html
window-open.webapp
window-open.webapp^headers^
window-open.html
window-open-blank.webapp
window-open-blank.webapp^headers^
window-open-blank.html
alarm.html
alarm.webapp
alarm.webapp^headers^
download.html
download.webapp
download.webapp^headers^
download.test
install-app.html
install-app.webapp
install-app.webapp^headers^
[browser_alarm.js]
[browser_debugger.js]
[browser_download.js]
[browser_geolocation-prompt-noperm.js]
[browser_geolocation-prompt-perm.js]
[browser_getUserMedia.js]
[browser_install-app.js]
[browser_mozpay.js]
[browser_noperm.js]
[browser_sample.js]
[browser_webperm.js]
[browser_window-open-blank.js]
[browser_window-open-self.js]
[browser_window-open.js]
[browser_window-title.js]
-9
View File
@@ -1,9 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>This is the test webapp.</p>
</body>
</html>
-15
View File
@@ -1,15 +0,0 @@
{
"name": "Hosted Permissions Test Webapp",
"description": "A webapp for testing permission installation.",
"launch_path": "/webapprtChrome/webapprt/test/chrome/webperm.html",
"permissions": {
"storage": { "description": "I need to store 1 million dollars in your bank account" },
"geolocation": { "description": "Desc" },
"camera": { "description": "Desc" },
"alarms": { "description": "Desc" },
"tcp-socket": { "description": "Desc" },
"network-events": { "description": "Desc" },
"webapps-manage": { "description": "Desc" },
"desktop-notification": { "description": "Desc" }
}
}

Some files were not shown because too many files have changed in this diff Show More