mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 725408 - implement WebappRT launcher/shell; r=bsmedberg
This commit is contained in:
parent
dde7ad05f5
commit
253337cae3
@ -40,6 +40,12 @@ probes/Makefile
|
||||
extensions/Makefile
|
||||
"
|
||||
|
||||
if [ "$MOZ_WEBAPP_RUNTIME" ]; then
|
||||
add_makefiles "
|
||||
webapprt/Makefile
|
||||
"
|
||||
fi
|
||||
|
||||
if [ ! "$LIBXUL_SDK" ]; then
|
||||
if [ "$STLPORT_SOURCES" ]; then
|
||||
add_makefiles "
|
||||
|
@ -51,6 +51,10 @@ ifdef MOZ_SERVICES_SYNC
|
||||
tier_app_dirs += services
|
||||
endif
|
||||
|
||||
ifdef MOZ_WEBAPP_RUNTIME
|
||||
tier_app_dirs += webapprt
|
||||
endif
|
||||
|
||||
tier_app_dirs += browser
|
||||
# Never add other tier_app_dirs after browser. They won't get packaged
|
||||
# properly on mac.
|
||||
|
@ -24,8 +24,22 @@ category command-line-handler x-default @mozilla.org/browser/final-clh;1 applica
|
||||
category command-line-validator b-browser @mozilla.org/browser/clh;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
|
||||
# nsBrowserGlue.js
|
||||
|
||||
# WebappRT doesn't need these instructions, and they don't necessarily work
|
||||
# with it, but it does use a GRE directory that the GRE shares with Firefox,
|
||||
# so in order to prevent the instructions from being processed for WebappRT,
|
||||
# we need to restrict them to the applications that depend on them, i.e.:
|
||||
#
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
#
|
||||
# In theory we should do this for all these instructions, but in practice it is
|
||||
# sufficient to do it for the app-startup one, and the file is simpler that way.
|
||||
|
||||
component {eab9012e-5f74-4cbc-b2b5-a590235513cc} nsBrowserGlue.js
|
||||
contract @mozilla.org/browser/browserglue;1 {eab9012e-5f74-4cbc-b2b5-a590235513cc}
|
||||
category app-startup nsBrowserGlue service,@mozilla.org/browser/browserglue;1
|
||||
category app-startup nsBrowserGlue service,@mozilla.org/browser/browserglue;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
component {d8903bf6-68d5-4e97-bcd1-e4d3012f721a} nsBrowserGlue.js
|
||||
contract @mozilla.org/content-permission/prompt;1 {d8903bf6-68d5-4e97-bcd1-e4d3012f721a}
|
||||
|
@ -1,3 +1,16 @@
|
||||
# WebappRT doesn't need these instructions, and they don't necessarily work
|
||||
# with it, but it does use a GRE directory that the GRE shares with Firefox,
|
||||
# so in order to prevent the instructions from being processed for WebappRT,
|
||||
# we need to restrict them to the applications that depend on them, i.e.:
|
||||
#
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
#
|
||||
# In theory we should do this for all these instructions, but in practice it is
|
||||
# sufficient to do it for the app-startup one, and the file is simpler that way.
|
||||
|
||||
component {229fa115-9412-4d32-baf3-2fc407f76fb1} FeedConverter.js
|
||||
contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
|
||||
contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.video.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
|
||||
@ -13,4 +26,4 @@ contract @mozilla.org/browser/feeds/result-writer;1 {49bb6593-3aff-4eb3-a068-271
|
||||
category JavaScript-global-constructor BrowserFeedWriter @mozilla.org/browser/feeds/result-writer;1
|
||||
component {792a7e82-06a0-437c-af63-b2d12e808acc} WebContentConverter.js
|
||||
contract @mozilla.org/embeddor.implemented/web-content-handler-registrar;1 {792a7e82-06a0-437c-af63-b2d12e808acc}
|
||||
category app-startup WebContentConverter service,@mozilla.org/embeddor.implemented/web-content-handler-registrar;1
|
||||
category app-startup WebContentConverter service,@mozilla.org/embeddor.implemented/web-content-handler-registrar;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
|
@ -1,4 +1,17 @@
|
||||
# WebappRT doesn't need these instructions, and they don't necessarily work
|
||||
# with it, but it does use a GRE directory that the GRE shares with Firefox,
|
||||
# so in order to prevent the instructions from being processed for WebappRT,
|
||||
# we need to restrict them to the applications that depend on them, i.e.:
|
||||
#
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
#
|
||||
# In theory we should do this for all these instructions, but in practice it is
|
||||
# sufficient to do it for the app-startup one, and the file is simpler that way.
|
||||
|
||||
component {c31f4883-839b-45f6-82ad-a6a9bc5ad599} nsPrivateBrowsingService.js
|
||||
contract @mozilla.org/privatebrowsing;1 {c31f4883-839b-45f6-82ad-a6a9bc5ad599}
|
||||
category command-line-handler m-privatebrowsing @mozilla.org/privatebrowsing;1
|
||||
category app-startup nsPrivateBrowsingService service,@mozilla.org/privatebrowsing;1
|
||||
category app-startup nsPrivateBrowsingService service,@mozilla.org/privatebrowsing;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
|
@ -1,5 +1,18 @@
|
||||
# WebappRT doesn't need these instructions, and they don't necessarily work
|
||||
# with it, but it does use a GRE directory that the GRE shares with Firefox,
|
||||
# so in order to prevent the instructions from being processed for WebappRT,
|
||||
# we need to restrict them to the applications that depend on them, i.e.:
|
||||
#
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
#
|
||||
# In theory we should do this for all these instructions, but in practice it is
|
||||
# sufficient to do it for the app-startup one, and the file is simpler that way.
|
||||
|
||||
component {5280606b-2510-4fe0-97ef-9b5a22eafe6b} nsSessionStore.js
|
||||
contract @mozilla.org/browser/sessionstore;1 {5280606b-2510-4fe0-97ef-9b5a22eafe6b}
|
||||
component {ec7a6c20-e081-11da-8ad9-0800200c9a66} nsSessionStartup.js
|
||||
contract @mozilla.org/browser/sessionstartup;1 {ec7a6c20-e081-11da-8ad9-0800200c9a66}
|
||||
category app-startup nsSessionStartup service,@mozilla.org/browser/sessionstartup;1
|
||||
category app-startup nsSessionStartup service,@mozilla.org/browser/sessionstartup;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
|
@ -503,6 +503,9 @@
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
@BINPATH@/@PREF_DIR@/services-sync.js
|
||||
#endif
|
||||
#ifdef MOZ_WEBAPP_RUNTIME
|
||||
@BINPATH@/@PREF_DIR@/webapprt@mozilla.org/prefs.js
|
||||
#endif
|
||||
@BINPATH@/greprefs.js
|
||||
@BINPATH@/defaults/autoconfig/platform.js
|
||||
@BINPATH@/defaults/autoconfig/prefcalls.js
|
||||
@ -624,3 +627,14 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
||||
@BINPATH@/*.xqs
|
||||
@BINPATH@/components/*.xqs
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WEBAPP_RUNTIME
|
||||
; [Webapp Runtime]
|
||||
@BINPATH@/webapprt-stub@BIN_SUFFIX@
|
||||
@BINPATH@/chrome/webapprt@JAREXT@
|
||||
@BINPATH@/chrome/webapprt.manifest
|
||||
@BINPATH@/components/WebappRTComponents.manifest
|
||||
@BINPATH@/components/WebappRTDirectoryProvider.js
|
||||
@BINPATH@/components/WebappRTCommandLineHandler.js
|
||||
@BINPATH@/webapprt.ini
|
||||
#endif
|
||||
|
49
browser/locales/en-US/webapprt/webapp.dtd
Normal file
49
browser/locales/en-US/webapprt/webapp.dtd
Normal file
@ -0,0 +1,49 @@
|
||||
<!-- 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 quitApplicationCmdMac.key "Q">
|
||||
<!ENTITY hideThisAppCmdMac.key "H">
|
||||
<!ENTITY hideOtherAppsCmdMac.label "Hide Others">
|
||||
<!ENTITY hideOtherAppsCmdMac.key "H">
|
||||
<!ENTITY showAllAppsCmdMac.label "Show All">
|
||||
|
||||
<!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">
|
17
browser/locales/en-US/webapprt/webapp.properties
Normal file
17
browser/locales/en-US/webapprt/webapp.properties
Normal file
@ -0,0 +1,17 @@
|
||||
# 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
|
@ -110,3 +110,6 @@
|
||||
% locale testpilot @AB_CD@ %locale/feedback/
|
||||
locale/feedback/main.dtd (%feedback/main.dtd)
|
||||
locale/feedback/main.properties (%feedback/main.properties)
|
||||
% locale webapprt @AB_CD@ %locale/webapprt/
|
||||
locale/webapprt/webapp.dtd (%webapprt/webapp.dtd)
|
||||
locale/webapprt/webapp.properties (%webapprt/webapp.properties)
|
||||
|
@ -680,6 +680,8 @@ MOZ_THEME_FASTSTRIPE = @MOZ_THEME_FASTSTRIPE@
|
||||
|
||||
MOZ_SERVICES_SYNC = @MOZ_SERVICES_SYNC@
|
||||
|
||||
MOZ_WEBAPP_RUNTIME = @MOZ_WEBAPP_RUNTIME@
|
||||
|
||||
MOZ_OFFICIAL_BRANDING = @MOZ_OFFICIAL_BRANDING@
|
||||
|
||||
HAVE_CLOCK_MONOTONIC = @HAVE_CLOCK_MONOTONIC@
|
||||
|
41
configure.in
41
configure.in
@ -4497,6 +4497,7 @@ MOZ_BRANDING_DIRECTORY=
|
||||
MOZ_OFFICIAL_BRANDING=
|
||||
MOZ_FEEDS=1
|
||||
MOZ_FLEXBOX=
|
||||
MOZ_WEBAPP_RUNTIME=
|
||||
MOZ_JSDEBUGGER=1
|
||||
MOZ_AUTH_EXTENSION=1
|
||||
MOZ_OGG=1
|
||||
@ -4559,6 +4560,7 @@ MOZ_GRAPHITE=1
|
||||
case "${target}" in
|
||||
*darwin*)
|
||||
ACCESSIBILITY=
|
||||
MOZ_WEBAPP_RUNTIME=1
|
||||
;;
|
||||
*)
|
||||
ACCESSIBILITY=1
|
||||
@ -4569,6 +4571,7 @@ case "$target_os" in
|
||||
mingw*)
|
||||
NS_ENABLE_TSF=1
|
||||
AC_DEFINE(NS_ENABLE_TSF)
|
||||
MOZ_WEBAPP_RUNTIME=1
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -6274,6 +6277,44 @@ if test -n "$MOZ_TREE_FREETYPE"; then
|
||||
AC_SUBST(CAIRO_FT_CFLAGS)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Web App Runtime
|
||||
dnl ========================================================
|
||||
MOZ_ARG_DISABLE_BOOL(webapp-runtime,
|
||||
[ --disable-webapp-runtime Disable Web App Runtime],
|
||||
MOZ_WEBAPP_RUNTIME=,
|
||||
MOZ_WEBAPP_RUNTIME=1)
|
||||
if test -n "$MOZ_WEBAPP_RUNTIME" -a "$OS_ARCH" = "WINNT"; then
|
||||
# Disable Web App Runtime for Windows builds that use the new toolkit if the
|
||||
# required major version and minimum minor version of Unicode NSIS isn't in
|
||||
# the path.
|
||||
REQ_NSIS_MAJOR_VER=2
|
||||
MIN_NSIS_MINOR_VER=33
|
||||
MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensisu-2.46 makensisu makensis)
|
||||
if test -z "$MAKENSISU" -o "$MAKENSISU" = ":"; then
|
||||
AC_MSG_ERROR([To build the Web App Runtime you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the Web App Runtime reconfigure using --disable-webapp-runtime.])
|
||||
fi
|
||||
changequote(,)
|
||||
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
|
||||
changequote([,])
|
||||
if test ! "$MAKENSISU_VER" = ""; then
|
||||
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
|
||||
MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
|
||||
fi
|
||||
AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
|
||||
if test "$MAKENSISU_VER" = "" ||
|
||||
test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
|
||||
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([To build the Web App Runtime you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the Web App Runtime reconfigure using --disable-webapp-runtime.])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
AC_SUBST(MOZ_WEBAPP_RUNTIME)
|
||||
if test "$MOZ_WEBAPP_RUNTIME"; then
|
||||
AC_DEFINE(MOZ_WEBAPP_RUNTIME)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Installer
|
||||
dnl ========================================================
|
||||
|
@ -12,6 +12,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
const WEBAPP_RUNTIME = Services.appinfo.ID == "webapprt@mozilla.org";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
return NetUtil;
|
||||
@ -24,7 +26,10 @@ XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
const DIRECTORY_NAME = "webappsDir";
|
||||
#else
|
||||
const DIRECTORY_NAME = "ProfD";
|
||||
// If we're executing in the context of the webapp runtime, the data files
|
||||
// are in a different directory (currently the Firefox profile that installed
|
||||
// the webapp); otherwise, they're in the current profile.
|
||||
const DIRECTORY_NAME = WEBAPP_RUNTIME ? "WebappRegD" : "ProfD";
|
||||
#endif
|
||||
|
||||
let DOMApplicationRegistry = {
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIXULAppInfo.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
@ -84,6 +85,8 @@ namespace mozilla {
|
||||
#define INITIAL_PREF_FILES 10
|
||||
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
|
||||
|
||||
#define WEBAPPRT_APPID "webapprt@mozilla.org"
|
||||
|
||||
// Prototypes
|
||||
static nsresult openPrefFile(nsIFile* aFile);
|
||||
static nsresult pref_InitInitialObjects(void);
|
||||
@ -1015,6 +1018,14 @@ static nsresult pref_InitInitialObjects()
|
||||
// - $app/defaults/preferences/*.js
|
||||
// and in non omni.jar case:
|
||||
// - $app/defaults/preferences/*.js
|
||||
//
|
||||
// When we're running WebappRT (i.e. $app == WEBAPPRT_APPID), in omni.jar
|
||||
// case, we also load:
|
||||
// - jar:$gre/omni.jar!/defaults/pref/$WEBAPPRT_APPID/*.js
|
||||
// This allows WebappRT-specific prefs to override those of another app
|
||||
// with whom it shares an app dir (i.e. Firefox).
|
||||
// (A $WEBAPPRT_APPID dir is similarly hardcoded into the app pref dir list
|
||||
// in nsXREDirProvider for when we're running WebappRT in non omni.jar case.)
|
||||
|
||||
nsZipFind *findPtr;
|
||||
nsAutoPtr<nsZipFind> find;
|
||||
@ -1038,6 +1049,30 @@ static nsresult pref_InitInitialObjects()
|
||||
}
|
||||
|
||||
prefEntries.Sort();
|
||||
|
||||
// Load jar:$gre/omni.jar!/defaults/pref/$WEBAPPRT_APPID/*.js
|
||||
// if we're running WebappRT.
|
||||
nsCOMPtr<nsIXULAppInfo> appInfo =
|
||||
do_GetService("@mozilla.org/xre/app-info;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString appID;
|
||||
if (NS_SUCCEEDED(appInfo->GetID(appID)) && appID.Equals(WEBAPPRT_APPID)) {
|
||||
nsCAutoString prefsPath("defaults/pref/");
|
||||
prefsPath.Append(appID);
|
||||
prefsPath.AppendLiteral("/*.js$");
|
||||
rv = jarReader->FindInit(prefsPath.get(), &findPtr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Make sure the files get read last by putting them at the beginning
|
||||
// of the list of pref entries (which is processed backwards), so prefs
|
||||
// in these app-specific files override those in non-app-specific ones.
|
||||
find = findPtr;
|
||||
while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
|
||||
prefEntries.InsertElementAt(0, Substring(entryName, entryNameLen));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PRUint32 i = prefEntries.Length(); i--; ) {
|
||||
rv = pref_ReadPrefFromJar(jarReader, prefEntries[i].get());
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -1,7 +1,20 @@
|
||||
# WebappRT doesn't need these instructions, and they don't necessarily work
|
||||
# with it, but it does use a GRE directory that the GRE shares with Firefox,
|
||||
# so in order to prevent the instructions from being processed for WebappRT,
|
||||
# we need to restrict them to the applications that depend on them, i.e.:
|
||||
#
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
#
|
||||
# In theory we should do this for all these instructions, but in practice it is
|
||||
# sufficient to do it for the app-startup one, and the file is simpler that way.
|
||||
|
||||
# Weave.js
|
||||
component {74b89fb0-f200-4ae8-a3ec-dd164117f6de} Weave.js
|
||||
contract @mozilla.org/weave/service;1 {74b89fb0-f200-4ae8-a3ec-dd164117f6de}
|
||||
category app-startup WeaveService service,@mozilla.org/weave/service;1
|
||||
category app-startup WeaveService service,@mozilla.org/weave/service;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
component {d28f8a0b-95da-48f4-b712-caf37097be41} Weave.js
|
||||
contract @mozilla.org/network/protocol/about;1?what=sync-log {d28f8a0b-95da-48f4-b712-caf37097be41}
|
||||
# Register resource aliases
|
||||
|
@ -107,3 +107,12 @@ maintenanceservice_installer::
|
||||
$(NSINSTALL) -D $(DIST)/bin/
|
||||
cp $(CONFIG_DIR)/maintenanceservice_installer.exe $(DIST)/bin
|
||||
endif
|
||||
|
||||
ifdef MOZ_WEBAPP_RUNTIME
|
||||
webapp_uninstaller::
|
||||
$(INSTALL) $(addprefix $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/,$(TOOLKIT_NSIS_FILES)) $(CONFIG_DIR)
|
||||
$(INSTALL) $(addprefix $(MOZILLA_DIR)/other-licenses/nsis/Plugins/,$(CUSTOM_NSIS_PLUGINS)) $(CONFIG_DIR)
|
||||
cd $(CONFIG_DIR) && $(MAKENSISU) webapp-uninstaller.nsi
|
||||
$(NSINSTALL) -D $(DIST)/bin/
|
||||
cp $(CONFIG_DIR)/webapp-uninstaller.exe $(DIST)/bin
|
||||
endif
|
||||
|
@ -67,26 +67,65 @@ def lookup(path, l10ndirs):
|
||||
return join(d, path)
|
||||
return join(l10ndirs[-1], path)
|
||||
|
||||
def preprocess_locale_files(moz_dir, ab_cd, config_dir, l10ndirs):
|
||||
def preprocess_locale_files(config_dir, l10ndirs):
|
||||
"""
|
||||
Preprocesses the installer localized properties files into the format
|
||||
required by NSIS and creates a basic NSIS nlf file.
|
||||
|
||||
Parameters:
|
||||
config_dir - the path to the destination directory
|
||||
l10ndirs - list of paths to search for installer locale files
|
||||
"""
|
||||
|
||||
# Create the main NSIS language file
|
||||
fp = open_utf16le_file(join(config_dir, "overrideLocale.nsh"))
|
||||
locale_strings = get_locale_strings(lookup("override.properties",
|
||||
l10ndirs),
|
||||
"LangString ^",
|
||||
" 0 ",
|
||||
False)
|
||||
fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
|
||||
fp.close()
|
||||
|
||||
# Create the Modern User Interface language file
|
||||
fp = open_utf16le_file(join(config_dir, "baseLocale.nsh"))
|
||||
fp.write((u""";NSIS Modern User Interface - Language File
|
||||
;Compatible with Modern UI 1.68
|
||||
;Language: baseLocale (0)
|
||||
!insertmacro MOZ_MUI_LANGUAGEFILE_BEGIN \"baseLocale\"
|
||||
!define MUI_LANGNAME \"baseLocale\"
|
||||
""").encode("utf-16-le"))
|
||||
locale_strings = get_locale_strings(lookup("mui.properties", l10ndirs),
|
||||
"!define ", " ", True)
|
||||
fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
|
||||
fp.write(u"!insertmacro MOZ_MUI_LANGUAGEFILE_END\n".encode("utf-16-le"))
|
||||
fp.close()
|
||||
|
||||
# Create the custom language file for our custom strings
|
||||
fp = open_utf16le_file(join(config_dir, "customLocale.nsh"))
|
||||
locale_strings = get_locale_strings(lookup("custom.properties",
|
||||
l10ndirs),
|
||||
"LangString ",
|
||||
" 0 ",
|
||||
True)
|
||||
fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
|
||||
fp.close()
|
||||
|
||||
def create_nlf_file(moz_dir, ab_cd, config_dir):
|
||||
"""
|
||||
Create a basic NSIS nlf file.
|
||||
|
||||
Parameters:
|
||||
moz_dir - the path to top source directory for the toolkit source
|
||||
ab_cd - the locale code
|
||||
config_dir - the path to the destination directory
|
||||
l10ndirs - list of paths to search for installer locale files
|
||||
"""
|
||||
|
||||
# Set the language ID to 0 to make this locale the default locale. An
|
||||
# actual ID will need to be used to create a multi-language installer
|
||||
# (e.g. for CD distributions, etc.).
|
||||
lang_id = "0"
|
||||
rtl = "-"
|
||||
|
||||
# Check whether the locale is right to left from locales.nsi.
|
||||
fp = open(join(moz_dir, "toolkit/mozapps/installer/windows/nsis/locales.nsi"), "r")
|
||||
fp = open(join(moz_dir,
|
||||
"toolkit/mozapps/installer/windows/nsis/locales.nsi"),
|
||||
"r")
|
||||
for line in fp:
|
||||
line = line.strip()
|
||||
if line == "!define " + ab_cd + "_rtl":
|
||||
@ -103,7 +142,7 @@ def preprocess_locale_files(moz_dir, ab_cd, config_dir, l10ndirs):
|
||||
NLF v6
|
||||
# Start editing here
|
||||
# Language ID
|
||||
%s
|
||||
0
|
||||
# Font and size - dash (-) means default
|
||||
-
|
||||
-
|
||||
@ -111,37 +150,35 @@ NLF v6
|
||||
-
|
||||
# RTL - anything else than RTL means LTR
|
||||
%s
|
||||
""" % (lang_id, rtl)).encode("utf-16-le"))
|
||||
""" % rtl).encode("utf-16-le"))
|
||||
fp.close()
|
||||
|
||||
# Create the main NSIS language file
|
||||
fp = open_utf16le_file(join(config_dir, "overrideLocale.nsh"))
|
||||
locale_strings = get_locale_strings(lookup("override.properties", l10ndirs),
|
||||
"LangString ^", " " + lang_id + " ", False)
|
||||
fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
|
||||
fp.close()
|
||||
def preprocess_locale_file(config_dir,
|
||||
l10ndirs,
|
||||
properties_filename,
|
||||
output_filename):
|
||||
"""
|
||||
Preprocesses a single localized properties file into the format
|
||||
required by NSIS and creates a basic NSIS nlf file.
|
||||
|
||||
# Create the Modern User Interface language file
|
||||
fp = open_utf16le_file(join(config_dir, "baseLocale.nsh"))
|
||||
fp.write((u""";NSIS Modern User Interface - Language File
|
||||
;Compatible with Modern UI 1.68
|
||||
;Language: baseLocale (%s)
|
||||
!insertmacro MOZ_MUI_LANGUAGEFILE_BEGIN \"baseLocale\"
|
||||
!define MUI_LANGNAME \"baseLocale\"
|
||||
""" % (lang_id)).encode("utf-16-le"))
|
||||
locale_strings = get_locale_strings(lookup("mui.properties", l10ndirs),
|
||||
"!define ", " ", True)
|
||||
fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
|
||||
fp.write(u"!insertmacro MOZ_MUI_LANGUAGEFILE_END\n".encode("utf-16-le"))
|
||||
fp.close()
|
||||
Parameters:
|
||||
config_dir - the path to the destination directory
|
||||
l10ndirs - list of paths to search for installer locale files
|
||||
properties_filename - the name of the properties file to search for
|
||||
output_filename - the output filename to write
|
||||
"""
|
||||
|
||||
# Create the custom language file for our custom strings
|
||||
fp = open_utf16le_file(join(config_dir, "customLocale.nsh"))
|
||||
locale_strings = get_locale_strings(lookup("custom.properties", l10ndirs),
|
||||
"LangString ", " " + lang_id + " ", True)
|
||||
fp = open_utf16le_file(join(config_dir, output_filename))
|
||||
locale_strings = get_locale_strings(lookup(properties_filename,
|
||||
l10ndirs),
|
||||
"LangString ",
|
||||
" 0 ",
|
||||
True)
|
||||
fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
|
||||
fp.close()
|
||||
|
||||
|
||||
def convert_utf8_utf16le(in_file_path, out_file_path):
|
||||
"""
|
||||
Converts a UTF-8 file to a new UTF-16LE file
|
||||
@ -160,11 +197,13 @@ if __name__ == '__main__':
|
||||
usage = """usage: %prog command <args>
|
||||
|
||||
Commands:
|
||||
--convert-utf8-utf16le - preprocesses installer locale properties files and
|
||||
creates a basic NSIS nlf file
|
||||
--preprocess-locale - Preprocesses the installer localized properties files
|
||||
into the format required by NSIS and creates a basic
|
||||
NSIS nlf file.
|
||||
--convert-utf8-utf16le - Preprocesses installer locale properties files
|
||||
--preprocess-locale - Preprocesses the installer localized properties
|
||||
files into the format required by NSIS and
|
||||
creates a basic NSIS nlf file.
|
||||
--preprocess-single-file - Preprocesses a single properties file into the
|
||||
format required by NSIS
|
||||
--create-nlf-file - Creates a basic NSIS nlf file
|
||||
|
||||
preprocess-locale.py --preprocess-locale <src> <locale> <code> <dest>
|
||||
|
||||
@ -175,15 +214,61 @@ Arguments:
|
||||
<dest> \tthe path to the destination directory
|
||||
|
||||
|
||||
preprocess-locale.py --preprocess-single-file <src>
|
||||
<locale>
|
||||
<dest>
|
||||
<infile>
|
||||
<outfile>
|
||||
|
||||
Arguments:
|
||||
<src> \tthe path to top source directory for the toolkit source
|
||||
<locale> \tthe path to the installer's locale files
|
||||
<dest> \tthe path to the destination directory
|
||||
<infile> \tthe properties file to process
|
||||
<outfile>\tthe nsh file to write
|
||||
|
||||
|
||||
preprocess-locale.py --create-nlf-file <src>
|
||||
<code>
|
||||
<dest>
|
||||
|
||||
Arguments:
|
||||
<src> \tthe path to top source directory for the toolkit source
|
||||
<code> \tthe locale code
|
||||
<dest> \tthe path to the destination directory
|
||||
|
||||
|
||||
preprocess-locale.py --convert-utf8-utf16le <src> <dest>
|
||||
|
||||
Arguments:
|
||||
<src> \tthe path to the UTF-8 source file to convert
|
||||
<dest>\tthe path to the UTF-16LE destination file to create
|
||||
"""
|
||||
|
||||
preprocess_locale_args_help_string = """\
|
||||
Arguments to --preprocess-locale should be:
|
||||
<src> <locale> <code> <dest>
|
||||
or
|
||||
<src> <code> <dest> --l10n-dir <dir> [--l10n-dir <dir> ...]"""
|
||||
|
||||
preprocess_single_file_args_help_string = """\
|
||||
Arguments to --preprocess-single_file should be:
|
||||
<src> <locale> <code> <dest> <infile> <outfile>
|
||||
or
|
||||
<src> <locale> <code> <dest> <infile> <outfile>
|
||||
--l10n-dir <dir> [--l10n-dir <dir>...]"""
|
||||
|
||||
create_nlf_args_help_string = """\
|
||||
Arguments to --create-nlf-file should be:
|
||||
<src> <code> <dest>"""
|
||||
|
||||
p = OptionParser(usage=usage)
|
||||
p.add_option("--preprocess-locale", action="store_true", default=False,
|
||||
dest='preprocess')
|
||||
p.add_option("--preprocess-single-file", action="store_true", default=False,
|
||||
dest='preprocessSingle')
|
||||
p.add_option("--create-nlf-file", action="store_true", default=False,
|
||||
dest='createNlf')
|
||||
p.add_option("--l10n-dir", action="append", default=[],
|
||||
dest="l10n_dirs",
|
||||
help="Add directory to lookup for locale files")
|
||||
@ -192,25 +277,84 @@ Arguments:
|
||||
|
||||
options, args = p.parse_args()
|
||||
|
||||
if ((not (options.preprocess or options.convert)) or
|
||||
(options.preprocess and options.convert)):
|
||||
p.error("You need to specify either --preprocess-locale or --convert-utf-utf16le")
|
||||
foundOne = False
|
||||
if (options.preprocess):
|
||||
foundOne = True
|
||||
if (options.convert):
|
||||
if(foundOne):
|
||||
p.error("More than one command specified")
|
||||
else:
|
||||
foundOne = True
|
||||
if (options.preprocessSingle):
|
||||
if(foundOne):
|
||||
p.error("More than one command specified")
|
||||
else:
|
||||
foundOne = True
|
||||
if (options.createNlf):
|
||||
if(foundOne):
|
||||
p.error("More than one command specified")
|
||||
else:
|
||||
foundOne = True
|
||||
|
||||
if (not foundOne):
|
||||
p.error("No command specified")
|
||||
|
||||
if options.preprocess:
|
||||
if len(args) not in (3,4):
|
||||
p.error("--preprocess-locale needs all of <src> <locale> <code> <dest>")
|
||||
p.error(preprocess_locale_args_help_string)
|
||||
|
||||
# Parse args
|
||||
pargs = args[:]
|
||||
if len(args) == 4:
|
||||
l10n_dirs = [args[1]]
|
||||
moz_dir = pargs[0]
|
||||
if len(pargs) == 4:
|
||||
l10n_dirs = [pargs[1]]
|
||||
del pargs[1]
|
||||
else:
|
||||
if not options.l10n_dirs:
|
||||
p.error("--preprocess-locale needs either <locale> or --l10ndir")
|
||||
p.error(preprocess_locale_args_help_string)
|
||||
l10n_dirs = options.l10n_dirs
|
||||
ab_cd = pargs[1]
|
||||
config_dir = pargs[2]
|
||||
|
||||
pargs.append(l10n_dirs)
|
||||
preprocess_locale_files(*pargs)
|
||||
else:
|
||||
# Create the output files
|
||||
create_nlf_file(moz_dir, ab_cd, config_dir)
|
||||
preprocess_locale_files(config_dir, l10n_dirs)
|
||||
elif options.preprocessSingle:
|
||||
if len(args) not in (4,5):
|
||||
p.error(preprocess_single_file_args_help_string)
|
||||
|
||||
# Parse args
|
||||
pargs = args[:]
|
||||
moz_dir = pargs[0]
|
||||
if len(pargs) == 5:
|
||||
l10n_dirs = [pargs[1]]
|
||||
del pargs[1]
|
||||
else:
|
||||
if not options.l10n_dirs:
|
||||
p.error(preprocess_single_file_args_help_string)
|
||||
l10n_dirs = options.l10n_dirs
|
||||
config_dir = pargs[1]
|
||||
in_file = pargs[2]
|
||||
out_file = pargs[3]
|
||||
|
||||
# Create the output files
|
||||
preprocess_locale_file(config_dir,
|
||||
l10n_dirs,
|
||||
in_file,
|
||||
out_file)
|
||||
elif options.createNlf:
|
||||
if len(args) != 3:
|
||||
p.error(create_nlf_args_help_string)
|
||||
|
||||
# Parse args
|
||||
pargs = args[:]
|
||||
moz_dir = pargs[0]
|
||||
ab_cd = pargs[1]
|
||||
config_dir = pargs[2]
|
||||
|
||||
# Create the output files
|
||||
create_nlf_file(moz_dir, ab_cd, config_dir)
|
||||
elif options.convert:
|
||||
if len(args) != 2:
|
||||
p.error("--convert-utf8-utf16le needs both of <src> <dest>")
|
||||
convert_utf8_utf16le(*args)
|
||||
|
@ -99,6 +99,8 @@
|
||||
|
||||
#define PREF_OVERRIDE_DIRNAME "preferences"
|
||||
|
||||
#define WEBAPPRT_APPID "webapprt@mozilla.org"
|
||||
|
||||
static already_AddRefed<nsILocalFile>
|
||||
CloneAndAppend(nsIFile* aFile, const char* name)
|
||||
{
|
||||
@ -425,24 +427,26 @@ nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
|
||||
}
|
||||
|
||||
static void
|
||||
LoadAppDirIntoArray(nsIFile* aXULAppDir,
|
||||
const char *const *aAppendList,
|
||||
nsCOMArray<nsIFile>& aDirectories)
|
||||
LoadDirIntoArray(nsIFile* dir,
|
||||
const char *const *aAppendList,
|
||||
nsCOMArray<nsIFile>& aDirectories)
|
||||
{
|
||||
if (!aXULAppDir)
|
||||
if (!dir)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIFile> subdir;
|
||||
aXULAppDir->Clone(getter_AddRefs(subdir));
|
||||
dir->Clone(getter_AddRefs(subdir));
|
||||
if (!subdir)
|
||||
return;
|
||||
|
||||
for (; *aAppendList; ++aAppendList)
|
||||
subdir->AppendNative(nsDependentCString(*aAppendList));
|
||||
for (const char *const *a = aAppendList; *a; ++a) {
|
||||
subdir->AppendNative(nsDependentCString(*a));
|
||||
}
|
||||
|
||||
bool exists;
|
||||
if (NS_SUCCEEDED(subdir->Exists(&exists)) && exists)
|
||||
if (NS_SUCCEEDED(subdir->Exists(&exists)) && exists) {
|
||||
aDirectories.AppendObject(subdir);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -461,12 +465,10 @@ LoadDirsIntoArray(nsCOMArray<nsIFile>& aSourceDirs,
|
||||
nsCAutoString leaf;
|
||||
appended->GetNativeLeafName(leaf);
|
||||
if (!Substring(leaf, leaf.Length() - 4).Equals(NS_LITERAL_CSTRING(".xpi"))) {
|
||||
for (const char *const *a = aAppendList; *a; ++a)
|
||||
appended->AppendNative(nsDependentCString(*a));
|
||||
LoadDirIntoArray(appended,
|
||||
aAppendList,
|
||||
aDirectories);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(appended->Exists(&exists)) && exists)
|
||||
aDirectories.AppendObject(appended);
|
||||
}
|
||||
}
|
||||
|
||||
@ -642,10 +644,17 @@ nsXREDirProvider::GetFilesInternal(const char* aProperty,
|
||||
else if (!strcmp(aProperty, NS_APP_PREFS_DEFAULTS_DIR_LIST)) {
|
||||
nsCOMArray<nsIFile> directories;
|
||||
|
||||
LoadAppDirIntoArray(mXULAppDir, kAppendPrefDir, directories);
|
||||
LoadDirIntoArray(mXULAppDir, kAppendPrefDir, directories);
|
||||
LoadDirsIntoArray(mAppBundleDirectories,
|
||||
kAppendPrefDir, directories);
|
||||
|
||||
// Include the WebappRT-specific prefs dir if we're running WebappRT.
|
||||
if (gAppData && !strcmp(gAppData->ID, WEBAPPRT_APPID)) {
|
||||
const char *const kAppendAppIDPrefDir[] =
|
||||
{ "defaults", "pref", gAppData->ID, nsnull };
|
||||
LoadDirIntoArray(mXULAppDir, kAppendAppIDPrefDir, directories);
|
||||
}
|
||||
|
||||
rv = NS_NewArrayEnumerator(aResult, directories);
|
||||
}
|
||||
else if (!strcmp(aProperty, NS_EXT_PREFS_DEFAULTS_DIR_LIST)) {
|
||||
@ -672,9 +681,9 @@ nsXREDirProvider::GetFilesInternal(const char* aProperty,
|
||||
|
||||
static const char *const kAppendChromeDir[] = { "chrome", nsnull };
|
||||
nsCOMArray<nsIFile> directories;
|
||||
LoadAppDirIntoArray(mXULAppDir,
|
||||
kAppendChromeDir,
|
||||
directories);
|
||||
LoadDirIntoArray(mXULAppDir,
|
||||
kAppendChromeDir,
|
||||
directories);
|
||||
LoadDirsIntoArray(mAppBundleDirectories,
|
||||
kAppendChromeDir,
|
||||
directories);
|
||||
|
48
webapprt/Makefile.in
Normal file
48
webapprt/Makefile.in
Normal file
@ -0,0 +1,48 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
DIRS = $(NULL)
|
||||
|
||||
ifneq (,$(filter WINNT,$(OS_ARCH)))
|
||||
DIRS += win
|
||||
else
|
||||
ifeq ($(OS_ARCH),Darwin)
|
||||
DIRS += mac
|
||||
endif # mac
|
||||
endif # windows
|
||||
|
||||
EXTRA_PP_COMPONENTS = \
|
||||
WebappRTComponents.manifest \
|
||||
WebappRTCommandLineHandler.js \
|
||||
WebappRTDirectoryProvider.js \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
WebappRT.jsm \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs:: prefs.js
|
||||
$(NSINSTALL) -D $(DIST)/bin/defaults/pref/webapprt@mozilla.org
|
||||
$(INSTALL) $^ $(DIST)/bin/defaults/pref/webapprt@mozilla.org
|
||||
|
||||
GRE_MILESTONE := $(shell tail -n 1 $(topsrcdir)/config/milestone.txt 2>/dev/null || tail -1 $(topsrcdir)/config/milestone.txt)
|
||||
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
|
||||
DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
|
||||
|
||||
webapprt.ini: webapprt.ini.in $(DEPTH)/config/buildid $(topsrcdir)/config/milestone.txt
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
|
||||
|
||||
libs:: webapprt.ini
|
||||
$(INSTALL) webapprt.ini $(DIST)/bin
|
||||
|
||||
GARBAGE += webapprt.ini
|
55
webapprt/WebappRT.jsm
Normal file
55
webapprt/WebappRT.jsm
Normal file
@ -0,0 +1,55 @@
|
||||
/* 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 EXPORTED_SYMBOLS = ["WebappRT"];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "FileUtils", function() {
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
return FileUtils;
|
||||
});
|
||||
|
||||
let WebappRT = {
|
||||
get config() {
|
||||
let webappFile = FileUtils.getFile("AppRegD", ["webapp.json"]);
|
||||
let inputStream = Cc["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Ci.nsIFileInputStream);
|
||||
inputStream.init(webappFile, -1, 0, 0);
|
||||
let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
|
||||
let config = json.decodeFromStream(inputStream, webappFile.fileSize);
|
||||
|
||||
// Memoize the getter, freezing the `config` object in the meantime so
|
||||
// consumers don't inadvertently (or intentionally) change it, as the object
|
||||
// is meant to be a read-only representation of the webapp's configuration.
|
||||
config = deepFreeze(config);
|
||||
delete this.config;
|
||||
Object.defineProperty(this, "config", { get: function getConfig() config });
|
||||
return this.config;
|
||||
}
|
||||
};
|
||||
|
||||
function deepFreeze(o) {
|
||||
// First, freeze the object.
|
||||
Object.freeze(o);
|
||||
|
||||
// Then recursively call deepFreeze() to freeze its properties.
|
||||
for (let p in o) {
|
||||
// If the object is on the prototype, not an object, or is already frozen,
|
||||
// skip it. Note that this might leave an unfrozen reference somewhere in
|
||||
// the object if there is an already frozen object containing an unfrozen
|
||||
// object.
|
||||
if (!o.hasOwnProperty(p) || !(typeof o[p] == "object") ||
|
||||
Object.isFrozen(o[p]))
|
||||
continue;
|
||||
|
||||
deepFreeze(o[p]);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
31
webapprt/WebappRTCommandLineHandler.js
Normal file
31
webapprt/WebappRTCommandLineHandler.js
Normal file
@ -0,0 +1,31 @@
|
||||
/* 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) {
|
||||
Services.ww.openWindow(null,
|
||||
"chrome://webapprt/content/webapp.xul",
|
||||
"_blank",
|
||||
"chrome,dialog=no,all,resizable",
|
||||
null);
|
||||
},
|
||||
|
||||
helpInfo : "",
|
||||
};
|
||||
|
||||
let components = [CommandLineHandler];
|
||||
let NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
|
9
webapprt/WebappRTComponents.manifest
Normal file
9
webapprt/WebappRTComponents.manifest
Normal file
@ -0,0 +1,9 @@
|
||||
# WebappRTCommandLineHandler.js
|
||||
component {6d69c782-40a3-469b-8bfd-3ee366105a4a} WebappRTCommandLineHandler.js application=webapprt@mozilla.org
|
||||
contract @mozilla.org/webapprt/clh;1 {6d69c782-40a3-469b-8bfd-3ee366105a4a} application=webapprt@mozilla.org
|
||||
category command-line-handler x-default @mozilla.org/webapprt/clh;1 application=webapprt@mozilla.org
|
||||
|
||||
# WebappRTDirectoryProvider.js
|
||||
component {e1799fda-4b2f-4457-b671-e0641d95698d} WebappRTDirectoryProvider.js application=webapprt@mozilla.org
|
||||
contract @mozilla.org/webapprt/directory-provider;1 {e1799fda-4b2f-4457-b671-e0641d95698d} application=webapprt@mozilla.org
|
||||
category xpcom-directory-providers webapprt-directory-provider @mozilla.org/webapprt/directory-provider;1 application=webapprt@mozilla.org
|
34
webapprt/WebappRTDirectoryProvider.js
Normal file
34
webapprt/WebappRTDirectoryProvider.js
Normal file
@ -0,0 +1,34 @@
|
||||
/* 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";
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/WebappRT.jsm");
|
||||
|
||||
function DirectoryProvider() {}
|
||||
|
||||
DirectoryProvider.prototype = {
|
||||
classID: Components.ID("{e1799fda-4b2f-4457-b671-e0641d95698d}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider]),
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]);
|
77
webapprt/content/webapp.js
Normal file
77
webapprt/content/webapp.js
Normal file
@ -0,0 +1,77 @@
|
||||
/* 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/WebappRT.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function onLoad() {
|
||||
window.removeEventListener("load", onLoad, false);
|
||||
|
||||
let installRecord = WebappRT.config.app;
|
||||
let manifest = WebappRT.config.app.manifest;
|
||||
|
||||
// Set the title of the window to the name of the webapp.
|
||||
document.documentElement.setAttribute("title", manifest.name);
|
||||
|
||||
// Load the webapp's launch path.
|
||||
let url = Services.io.newURI(installRecord.origin, null, null);
|
||||
if (manifest.launch_path)
|
||||
url = Services.io.newURI(manifest.launch_path, null, url);
|
||||
document.getElementById("content").setAttribute("src", url.spec);
|
||||
}
|
||||
window.addEventListener("load", onLoad, false);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// On Mac, we dynamically create the label for the Quit menuitem, using
|
||||
// a string property to inject the name of the webapp into it.
|
||||
window.addEventListener("load", function onLoadUpdateMenuItems() {
|
||||
window.removeEventListener("load", onLoadUpdateMenuItems, false);
|
||||
let installRecord = WebappRT.config.app;
|
||||
let manifest = WebappRT.config.app.manifest;
|
||||
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);
|
||||
}, false);
|
||||
#endif
|
||||
|
||||
function updateEditUIVisibility() {
|
||||
#ifndef XP_MACOSX
|
||||
let editMenuPopupState = document.getElementById("menu_EditPopup").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";
|
||||
|
||||
// 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
|
||||
}
|
156
webapprt/content/webapp.xul
Normal file
156
webapprt/content/webapp.xul
Normal file
@ -0,0 +1,156 @@
|
||||
<?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"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
width="1024" height="768">
|
||||
|
||||
<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="©Cmd.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="&quitApplicationCmdMac.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="©Cmd.label;"
|
||||
key="key_copy"
|
||||
accesskey="©Cmd.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" id="content" flex="1"/>
|
||||
|
||||
</window>
|
4
webapprt/jar.mn
Normal file
4
webapprt/jar.mn
Normal file
@ -0,0 +1,4 @@
|
||||
webapprt.jar:
|
||||
% content webapprt %content/
|
||||
* content/webapp.js (content/webapp.js)
|
||||
* content/webapp.xul (content/webapp.xul)
|
@ -0,0 +1,10 @@
|
||||
# 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.
|
47
webapprt/mac/Makefile.in
Normal file
47
webapprt/mac/Makefile.in
Normal file
@ -0,0 +1,47 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
# 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
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
PROGRAM = webapprt-stub$(BIN_SUFFIX)
|
||||
|
||||
CMMSRCS = webapprt.mm
|
||||
|
||||
# Don't create a dependency on mozglue, which is impossible (difficult?)
|
||||
# to dynamically link into our executable, as we copy it to arbitrary locations.
|
||||
MOZ_GLUE_LDFLAGS =
|
||||
MOZ_GLUE_PROGRAM_LDFLAGS =
|
||||
|
||||
# mozglue uses mfbt's Assertions.cpp, which provides MOZ_ASSERT, which lots
|
||||
# of code in libxpcom uses, so we have to do the same.
|
||||
VPATH += $(topsrcdir)/mfbt
|
||||
CPPSRCS = Assertions.cpp
|
||||
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
|
||||
LOCAL_INCLUDES += -I$(DEPTH)/build
|
||||
|
||||
DEFINES += -DXPCOM_GLUE
|
||||
STL_FLAGS=
|
||||
|
||||
LIBS = \
|
||||
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
|
||||
DEFINES += -DGRE_BUILDID=$(GRE_BUILDID)
|
||||
|
||||
webapprt.$(OBJ_SUFFIX): $(DEPTH)/config/buildid
|
356
webapprt/mac/webapprt.mm
Normal file
356
webapprt/mac/webapprt.mm
Normal file
@ -0,0 +1,356 @@
|
||||
/* 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 "nsILocalFile.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
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_CONTENTS_PATH[] = "/Contents/MacOS/";
|
||||
|
||||
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 },
|
||||
{ nsnull, nsnull }
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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 = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
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 pathForAuxiliaryExecutable: @"webapprt"];
|
||||
if (!myWebRTPath) {
|
||||
@throw MakeException(@"Missing WebRT Files", @"Cannot locate binary for this application");
|
||||
}
|
||||
|
||||
//GET FIREFOX BUILD ID
|
||||
NSString *firefoxINIFilePath = [NSString stringWithFormat:@"%@%s%s", firefoxPath, APP_CONTENTS_PATH, FXAPPINI_NAME];
|
||||
nsINIParser ffparser;
|
||||
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_CONTENTS_PATH, WEBAPPRT_EXECUTABLE];
|
||||
NSLog(@"### 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 WebRT 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 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", @"Failed to update 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_CONTENTS_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 webapp 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_CONTENTS_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
|
||||
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");
|
||||
}
|
||||
|
||||
// Get the path to the runtime's INI file. This should be in the
|
||||
// same directory as the GRE.
|
||||
snprintf(rtINIPath, MAXPATHLEN, "%s%s%s", [firefoxPath UTF8String], APP_CONTENTS_PATH, WEBRTINI_NAME);
|
||||
NSLog(@"webapprt.ini path: %s", rtINIPath);
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%s", rtINIPath]]) {
|
||||
NSString* msg = [NSString stringWithFormat: @"This copy of Firefox (%@) cannot run web applications, because it is missing important files", firefoxVersion];
|
||||
@throw MakeException(@"Missing WebRT Files", msg);
|
||||
}
|
||||
|
||||
// Load the runtime's INI from its path.
|
||||
nsCOMPtr<nsILocalFile> 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.");
|
||||
}
|
||||
|
||||
if (!rtINI) {
|
||||
NSLog(@"Error: missing webapprt.ini");
|
||||
@throw MakeException(@"Error", @"Missing base INI file.");
|
||||
}
|
||||
|
||||
nsXREAppData *webShellAppData;
|
||||
if (NS_FAILED(XRE_CreateAppData(rtINI, &webShellAppData))) {
|
||||
NSLog(@"Couldn't read webapprt.ini: %s", rtINIPath);
|
||||
@throw MakeException(@"Error", @"Unable to parse base INI file.");
|
||||
}
|
||||
|
||||
char profile[MAXPATHLEN];
|
||||
if (NS_FAILED(parser.GetString("Webapp", "Profile", profile, MAXPATHLEN))) {
|
||||
NSLog(@"Unable to retrieve profile from web app INI file");
|
||||
@throw MakeException(@"Error", @"Unable to retrieve installation profile.");
|
||||
}
|
||||
NSLog(@"setting app profile: %s", profile);
|
||||
SetAllocatedString(webShellAppData->profile, profile);
|
||||
|
||||
nsCOMPtr<nsILocalFile> directory;
|
||||
if (NS_FAILED(XRE_GetFileFromPath(greDir, getter_AddRefs(directory)))) {
|
||||
NSLog(@"Unable to open app dir");
|
||||
@throw MakeException(@"Error", @"Unable to open application directory.");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILocalFile> xreDir;
|
||||
if (NS_FAILED(XRE_GetFileFromPath(greDir, getter_AddRefs(xreDir)))) {
|
||||
NSLog(@"Unable to open XRE dir");
|
||||
@throw MakeException(@"Error", @"Unable to open application 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);
|
||||
|
||||
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 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 manual override, use that. If they made an error, it will fail to launch
|
||||
if (alternateBinaryID != nil && ([alternateBinaryID length] > 0)) {
|
||||
binaryPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:alternateBinaryID];
|
||||
if (binaryPath == nil || [binaryPath length] == 0) {
|
||||
@throw MakeException(@"WebappRT Not Found",
|
||||
[NSString stringWithFormat:@"Failed to locate specified override runtime with signature '%@'", alternateBinaryID]);
|
||||
}
|
||||
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(@"Missing Runtime", @"Mozilla Apps require Firefox to be installed");
|
||||
|
||||
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);
|
||||
}
|
13
webapprt/prefs.js
Normal file
13
webapprt/prefs.js
Normal file
@ -0,0 +1,13 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pref("browser.chromeURL", "chrome://webapprt/content/webapp.xul");
|
||||
|
||||
// We set this to the value of DEFAULT_HIDDENWINDOW_URL in nsAppShellService.cpp
|
||||
// so our app is treated as not having an application-provided hidden window.
|
||||
// Ideally, we could just leave it out, but because we are being distributed
|
||||
// in a unified directory with Firefox, Firefox's preferences are being read
|
||||
// before ours, which means this preference is being set by Firefox, and we need
|
||||
// to set it here to override the Firefox-provided value.
|
||||
pref("browser.hiddenWindowChromeURL", "resource://gre-resources/hiddenWindow.html");
|
18
webapprt/webapprt.ini.in
Normal file
18
webapprt/webapprt.ini.in
Normal file
@ -0,0 +1,18 @@
|
||||
#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
|
||||
Name=Webapp Runtime
|
||||
Version=@GRE_MILESTONE@
|
||||
BuildID=@GRE_BUILDID@
|
||||
|
||||
[Gecko]
|
||||
MinVersion=@GRE_MILESTONE@
|
||||
MaxVersion=@GRE_MILESTONE@
|
125
webapprt/win/Makefile.in
Normal file
125
webapprt/win/Makefile.in
Normal file
@ -0,0 +1,125 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
# Build a binary bootstrapping with XRE_main
|
||||
PROGRAM = webapprt-stub$(BIN_SUFFIX)
|
||||
|
||||
CPPSRCS = webapprt.cpp
|
||||
|
||||
# Don't create a dependency on mozglue, which is impossible (difficult?)
|
||||
# to dynamically link into our executable, as we copy it to arbitrary locations.
|
||||
MOZ_GLUE_LDFLAGS =
|
||||
|
||||
# mozglue uses mfbt's Assertions.cpp, which provides MOZ_ASSERT, which lots
|
||||
# of code in libxpcom uses, so we have to do the same.
|
||||
VPATH += $(topsrcdir)/mfbt
|
||||
CPPSRCS += Assertions.cpp
|
||||
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
|
||||
LOCAL_INCLUDES += -I$(DEPTH)/build
|
||||
|
||||
DEFINES += -DXPCOM_GLUE
|
||||
STL_FLAGS=
|
||||
|
||||
LIBS = \
|
||||
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
|
||||
$(NULL)
|
||||
|
||||
ifndef MOZ_WINCONSOLE
|
||||
ifdef MOZ_DEBUG
|
||||
MOZ_WINCONSOLE = 1
|
||||
else
|
||||
MOZ_WINCONSOLE = 0
|
||||
endif
|
||||
endif
|
||||
|
||||
# Installer stuff
|
||||
include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
|
||||
|
||||
CONFIG_DIR = instgen
|
||||
SFX_MODULE = $(topsrcdir)/other-licenses/7zstub/firefox/7zSD.sfx
|
||||
APP_VERSION := $(shell cat $(topsrcdir)/browser/config/version.txt)
|
||||
DEFINES += -DAPP_VERSION=$(APP_VERSION)
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifdef _MSC_VER
|
||||
# Always enter a Windows program through wmain, whether or not we're
|
||||
# a console application.
|
||||
WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
|
||||
endif
|
||||
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,shell32)
|
||||
|
||||
RCINCLUDE = webapprt.rc
|
||||
ifndef GNU_CC
|
||||
RCFLAGS += -I$(srcdir)
|
||||
else
|
||||
RCFLAGS += --include-dir $(srcdir)
|
||||
endif
|
||||
ifdef DEBUG
|
||||
RCFLAGS += -DDEBUG
|
||||
endif
|
||||
|
||||
# Uninstaller
|
||||
ifdef LOCALE_MERGEDIR
|
||||
PPL_LOCALE_ARGS = \
|
||||
--l10n-dir=$(LOCALE_MERGEDIR)/webapprt/webapp-uninstaller \
|
||||
--l10n-dir=$(call EXPAND_LOCALE_SRCDIR,webapprt/locales)/webapp-uninstaller \
|
||||
--l10n-dir=$(topsrcdir)/webapprt/locales/en-US/webapp-uninstaller \
|
||||
$(NULL)
|
||||
else
|
||||
PPL_LOCALE_ARGS=$(call EXPAND_LOCALE_SRCDIR,webapprt/locales)/webapp-uninstaller
|
||||
endif
|
||||
|
||||
libs::
|
||||
$(RM) -r $(CONFIG_DIR)
|
||||
$(MKDIR) $(CONFIG_DIR)
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution \
|
||||
$(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/webapp-uninstaller.nsi.in > $(CONFIG_DIR)/webapp-uninstaller.nsi
|
||||
$(PYTHON) \
|
||||
$(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \
|
||||
--create-nlf-file $(topsrcdir) $(AB_CD) $(CONFIG_DIR)
|
||||
$(PYTHON) \
|
||||
$(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \
|
||||
--preprocess-single-file $(topsrcdir) $(PPL_LOCALE_ARGS) $(CONFIG_DIR) \
|
||||
webapp-uninstaller.properties webapp-uninstaller-locale.nsh
|
||||
$(MAKE) webapp_uninstaller
|
||||
|
||||
GARBAGE_DIRS += instgen
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
include $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/makensis.mk
|
||||
|
||||
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
|
||||
DEFINES += -DGRE_BUILDID=$(GRE_BUILDID)
|
||||
|
||||
webapprt.$(OBJ_SUFFIX): $(DEPTH)/config/buildid
|
||||
|
||||
# Control the default heap size.
|
||||
# This is the heap returned by GetProcessHeap().
|
||||
# As we use the CRT heap, the default size is too large and wastes VM.
|
||||
#
|
||||
# The default heap size is 1MB on Win32.
|
||||
# The heap will grow if need be.
|
||||
#
|
||||
# Set it to 256k. See bug 127069.
|
||||
#
|
||||
ifndef GNU_CC
|
||||
LDFLAGS += /HEAP:0x40000
|
||||
ifeq ($(OS_TEST),x86_64)
|
||||
# set stack to 2MB on x64 build. See bug 582910
|
||||
LDFLAGS += -STACK:2097152
|
||||
endif
|
||||
endif
|
163
webapprt/win/webapp-uninstaller.nsi.in
Normal file
163
webapprt/win/webapp-uninstaller.nsi.in
Normal file
@ -0,0 +1,163 @@
|
||||
# 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/.
|
||||
|
||||
# Required Plugins:
|
||||
# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in
|
||||
|
||||
; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs
|
||||
!verbose 3
|
||||
|
||||
; 7-Zip provides better compression than the lzma from NSIS so we add the files
|
||||
; uncompressed and let the application installer compress it.
|
||||
SetDatablockOptimize on
|
||||
SetCompress off
|
||||
CRCCheck on
|
||||
SilentInstall silent
|
||||
|
||||
RequestExecutionLevel user
|
||||
|
||||
!addplugindir ./
|
||||
|
||||
; prevents compiling of the reg write logging.
|
||||
!define NO_LOG
|
||||
|
||||
; Variables
|
||||
Var AppFilename
|
||||
Var AppName
|
||||
Var AppRTTempDir
|
||||
|
||||
; Variables/macros used by common.nsh
|
||||
Var TmpVal
|
||||
!define FileMainEXE "$AppFilename.exe"
|
||||
|
||||
; Other included files may depend upon these includes!
|
||||
; The following includes are provided by NSIS.
|
||||
!include "FileFunc.nsh"
|
||||
!insertmacro GetParameters
|
||||
!insertmacro un.RefreshShellIcons
|
||||
!include "LogicLib.nsh"
|
||||
!include "WinMessages.nsh"
|
||||
!include "WinVer.nsh"
|
||||
!include "WordFunc.nsh"
|
||||
|
||||
; File properties, version strings, etc
|
||||
!define CompanyName "Mozilla Corporation"
|
||||
!define UninstallerName "Mozilla Webapp Runtime App Uninstaller"
|
||||
!define UninstallerFilename "webapp-uninstaller.exe"
|
||||
!define AppVersion "@APP_VERSION@"
|
||||
VIProductVersion "1.0.0.0"
|
||||
VIAddVersionKey "ProductName" "${UninstallerName}"
|
||||
VIAddVersionKey "CompanyName" "${CompanyName}"
|
||||
VIAddVersionKey "LegalCopyright" "${CompanyName}"
|
||||
VIAddVersionKey "FileVersion" "${AppVersion}"
|
||||
VIAddVersionKey "ProductVersion" "${AppVersion}"
|
||||
VIAddVersionKey "FileDescription" "${UninstallerName}"
|
||||
VIAddVersionKey "OriginalFilename" "${UninstallerFilename}"
|
||||
|
||||
; Mozilla custom include
|
||||
!include "common.nsh"
|
||||
!insertmacro un.DeleteShortcuts
|
||||
!insertmacro un.RegCleanUninstall
|
||||
!insertmacro un.ParseUninstallLog
|
||||
|
||||
Name "Mozilla Web App Runtime App"
|
||||
OutFile "${UninstallerFilename}"
|
||||
ShowUnInstDetails nevershow
|
||||
|
||||
# Create a blank page so that the default pages (instfiles) don't appear
|
||||
UninstPage custom un.blankPage
|
||||
|
||||
################################################################################
|
||||
# Install Sections
|
||||
# The "installer" that is generated by this file will be run during the build
|
||||
# process to generate an uninstaller. We call `WriteUninstaller` during
|
||||
# `onInit` so this section is empty.
|
||||
Section ""
|
||||
SectionEnd
|
||||
|
||||
################################################################################
|
||||
# This is where uninstallation happens
|
||||
################################################################################
|
||||
Function un.blankPage
|
||||
MessageBox MB_OKCANCEL "$(UN_CONFIRM_UNINSTALL)" /SD IDOK IDCANCEL done
|
||||
|
||||
; Delete the app exe to prevent launching the app while we are uninstalling.
|
||||
ClearErrors
|
||||
${DeleteFile} "$INSTDIR\${FileMainEXE}"
|
||||
${If} ${Errors}
|
||||
; If the app is running, rename the EXE out of the way
|
||||
CreateDirectory "$AppRTTempDir"
|
||||
Rename "$INSTDIR\${FileMainEXE}" "$AppRTTempDir\${FileMainEXE}"
|
||||
ClearErrors
|
||||
${EndIf}
|
||||
|
||||
|
||||
SetShellVarContext current ; Set SHCTX to HKCU
|
||||
|
||||
; Remove our entry in the "Uninstall" key
|
||||
${un.RegCleanUninstall}
|
||||
|
||||
; Remove our shortcuts from start menu, desktop, and taskbar
|
||||
${un.DeleteShortcuts}
|
||||
|
||||
; Parse the uninstall log to remove all installed
|
||||
; files / directories this install is responsible for.
|
||||
${un.ParseUninstallLog}
|
||||
|
||||
; Remove the uninstall directory that we control
|
||||
RmDir /r "$INSTDIR\uninstall"
|
||||
|
||||
; Remove the installation directory if it is empty
|
||||
${RemoveDir} "$INSTDIR"
|
||||
|
||||
; Refresh shell icons to reflect the changes we've made
|
||||
${un.RefreshShellIcons}
|
||||
|
||||
done:
|
||||
FunctionEnd
|
||||
|
||||
################################################################################
|
||||
# Language
|
||||
|
||||
!verbose push
|
||||
!verbose 3
|
||||
!include "webapp-uninstaller-locale.nsh"
|
||||
!verbose pop
|
||||
|
||||
; Set this after the locale files to override it if it is in the locale. Using
|
||||
; " " for BrandingText will hide the "Nullsoft Install System..." branding.
|
||||
BrandingText " "
|
||||
|
||||
# Initialization Functions
|
||||
Function .onInit
|
||||
GetTempFileName $0
|
||||
Delete "$0"
|
||||
CreateDirectory "$0"
|
||||
SetOutPath "$0"
|
||||
|
||||
StrCpy $1 "$0\${UninstallerFilename}"
|
||||
WriteUninstaller "$1"
|
||||
|
||||
${GetParameters} $2
|
||||
StrCpy $2 "_?=$EXEDIR $2"
|
||||
Exec '"$1" $2'
|
||||
Quit
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
StrCpy $LANGUAGE 0
|
||||
|
||||
${un.GetParent} "$INSTDIR" $INSTDIR
|
||||
${un.GetLongPath} "$INSTDIR" $INSTDIR
|
||||
|
||||
ReadINIStr $AppFilename "$INSTDIR\webapp.ini" "WebappRT" "Executable"
|
||||
ReadINIStr $AppName "$INSTDIR\webapp.ini" "Webapp" "Name"
|
||||
|
||||
${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}"
|
||||
Abort
|
||||
${EndUnless}
|
||||
|
||||
StrCpy $AppRTTempDir "$TEMP\moz_webapprt"
|
||||
RmDir /r "$AppRTTempDir"
|
||||
FunctionEnd
|
513
webapprt/win/webapprt.cpp
Normal file
513
webapprt/win/webapprt.cpp
Normal file
@ -0,0 +1,513 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
// System headers (alphabetical)
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <share.h>
|
||||
#include <sys/stat.h>
|
||||
#include <windows.h>
|
||||
|
||||
// Mozilla headers (alphabetical)
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsINIParser.h"
|
||||
#include "nsWindowsWMain.cpp" // we want a wmain entry point
|
||||
#include "nsXPCOMGlue.h"
|
||||
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
XRE_GetFileFromPathType XRE_GetFileFromPath;
|
||||
XRE_CreateAppDataType XRE_CreateAppData;
|
||||
XRE_FreeAppDataType XRE_FreeAppData;
|
||||
XRE_mainType XRE_main;
|
||||
|
||||
namespace {
|
||||
const char kAPP_INI[] = "application.ini";
|
||||
const char kWEBAPP_INI[] = "webapp.ini";
|
||||
const char kWEBAPPRT_INI[] = "webapprt.ini";
|
||||
const char kAPP_ENV_PREFIX[] = "XUL_APP_FILE=";
|
||||
const char kAPP_RT[] = "webapprt-stub.exe";
|
||||
|
||||
const wchar_t kAPP_RT_BACKUP[] = L"webapprt.old";
|
||||
|
||||
wchar_t curExePath[MAXPATHLEN];
|
||||
wchar_t backupFilePath[MAXPATHLEN];
|
||||
wchar_t iconPath[MAXPATHLEN];
|
||||
char profile[MAXPATHLEN];
|
||||
int* pargc;
|
||||
char*** pargv;
|
||||
|
||||
// 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 = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
joinPath(char* const dest,
|
||||
char const* const dir,
|
||||
char const* const leaf,
|
||||
size_t bufferSize)
|
||||
{
|
||||
size_t dirLen = strlen(dir);
|
||||
size_t leafLen = strlen(leaf);
|
||||
bool needsSeparator = (dirLen != 0
|
||||
&& dir[dirLen-1] != '\\'
|
||||
&& leafLen != 0
|
||||
&& leaf[0] != '\\');
|
||||
|
||||
if (dirLen + (needsSeparator? 1 : 0) + leafLen >= bufferSize) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
strncpy(dest, dir, bufferSize);
|
||||
char* destEnd = dest + dirLen;
|
||||
if (needsSeparator) {
|
||||
*(destEnd++) = '\\';
|
||||
}
|
||||
|
||||
strncpy(destEnd, leaf, leafLen);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper class which calls NS_LogInit/NS_LogTerm in its scope.
|
||||
*/
|
||||
class ScopedLogging
|
||||
{
|
||||
public:
|
||||
ScopedLogging() { NS_LogInit(); }
|
||||
~ScopedLogging() { NS_LogTerm(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class for scope-guarding nsXREAppData.
|
||||
*/
|
||||
class ScopedXREAppData
|
||||
{
|
||||
public:
|
||||
ScopedXREAppData()
|
||||
: mAppData(NULL) { }
|
||||
|
||||
nsresult
|
||||
create(nsILocalFile* aINIFile)
|
||||
{
|
||||
return XRE_CreateAppData(aINIFile, &mAppData);
|
||||
}
|
||||
|
||||
~ScopedXREAppData()
|
||||
{
|
||||
if (NULL != mAppData) {
|
||||
XRE_FreeAppData(mAppData);
|
||||
}
|
||||
}
|
||||
|
||||
nsXREAppData* const
|
||||
operator->()
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
nsXREAppData
|
||||
operator*()
|
||||
{
|
||||
return *get();
|
||||
}
|
||||
|
||||
operator
|
||||
nsXREAppData*()
|
||||
{
|
||||
return get();
|
||||
}
|
||||
private:
|
||||
nsXREAppData* mAppData;
|
||||
nsXREAppData* const get() { return mAppData; }
|
||||
};
|
||||
|
||||
void
|
||||
Output(const wchar_t *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
wchar_t msg[1024];
|
||||
_vsnwprintf_s(msg, _countof(msg), _countof(msg), fmt, ap);
|
||||
|
||||
MessageBoxW(NULL, msg, L"WebappRT", MB_OK);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
Output(const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
char msg[1024];
|
||||
vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
|
||||
wchar_t wide_msg[1024];
|
||||
MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
msg,
|
||||
-1,
|
||||
wide_msg,
|
||||
_countof(wide_msg));
|
||||
Output(wide_msg);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
const nsDynamicFunctionLoad kXULFuncs[] = {
|
||||
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
|
||||
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
|
||||
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
|
||||
{ "XRE_main", (NSFuncPtr*) &XRE_main },
|
||||
{ nsnull, nsnull }
|
||||
};
|
||||
|
||||
bool
|
||||
AttemptCopyAndLaunch(wchar_t* src)
|
||||
{
|
||||
// Rename the old app executable
|
||||
if (FALSE == ::MoveFileExW(curExePath,
|
||||
backupFilePath,
|
||||
MOVEFILE_REPLACE_EXISTING)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy webapprt-stub.exe from the Firefox dir to the app's dir
|
||||
if (FALSE == ::CopyFileW(src,
|
||||
curExePath,
|
||||
TRUE)) {
|
||||
// Try to move the old file back to its original location
|
||||
::MoveFileW(backupFilePath,
|
||||
curExePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: We will soon embed the app's icon in the EXE here
|
||||
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
::ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
::ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
if (!CreateProcessW(curExePath, // Module name
|
||||
NULL, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
FALSE, // Set handle inheritance to FALSE
|
||||
0, // No creation flags
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&si,
|
||||
&pi)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close process and thread handles.
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AttemptCopyAndLaunch(char* srcUtf8)
|
||||
{
|
||||
wchar_t src[MAXPATHLEN];
|
||||
if (0 == MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
srcUtf8,
|
||||
-1,
|
||||
src,
|
||||
MAXPATHLEN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AttemptCopyAndLaunch(src);
|
||||
}
|
||||
|
||||
bool
|
||||
AttemptGRELoadAndLaunch(char* greDir)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
char xpcomDllPath[MAXPATHLEN];
|
||||
rv = joinPath(xpcomDllPath, greDir, XPCOM_DLL, MAXPATHLEN);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
rv = XPCOMGlueStartup(xpcomDllPath);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
|
||||
NS_ENSURE_SUCCESS(rv, 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's INI file. This should be in the
|
||||
// same directory as the GRE.
|
||||
char rtIniPath[MAXPATHLEN];
|
||||
rv = joinPath(rtIniPath, greDir, kWEBAPPRT_INI, MAXPATHLEN);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// Load the runtime's INI from its path.
|
||||
nsCOMPtr<nsILocalFile> rtINI;
|
||||
rv = XRE_GetFileFromPath(rtIniPath, getter_AddRefs(rtINI));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
if (!rtINI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedXREAppData webShellAppData;
|
||||
rv = webShellAppData.create(rtINI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SetAllocatedString(webShellAppData->profile, profile);
|
||||
|
||||
nsCOMPtr<nsILocalFile> directory;
|
||||
rv = XRE_GetFileFromPath(greDir,
|
||||
getter_AddRefs(directory));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsCOMPtr<nsILocalFile> xreDir;
|
||||
rv = XRE_GetFileFromPath(greDir,
|
||||
getter_AddRefs(xreDir));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
xreDir.forget(&webShellAppData->xreDirectory);
|
||||
NS_IF_RELEASE(webShellAppData->directory);
|
||||
directory.forget(&webShellAppData->directory);
|
||||
|
||||
// There is only XUL.
|
||||
XRE_main(*pargc, *pargv, webShellAppData);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AttemptLoadFromDir(char* firefoxDir)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Here we're going to open Firefox's application.ini
|
||||
char appIniPath[MAXPATHLEN];
|
||||
rv = joinPath(appIniPath, firefoxDir, kAPP_INI, MAXPATHLEN);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsINIParser parser;
|
||||
rv = parser.Init(appIniPath);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// Get buildid of FF we're trying to load
|
||||
char buildid[MAXPATHLEN]; // This isn't a path, so MAXPATHLEN doesn't
|
||||
// necessarily make sense, but it's a
|
||||
// convenient number to use.
|
||||
rv = parser.GetString("App",
|
||||
"BuildID",
|
||||
buildid,
|
||||
MAXPATHLEN);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
if (0 == strcmp(buildid, NS_STRINGIFY(GRE_BUILDID))) {
|
||||
return AttemptGRELoadAndLaunch(firefoxDir);
|
||||
}
|
||||
|
||||
char webAppRTExe[MAXPATHLEN];
|
||||
rv = joinPath(webAppRTExe, firefoxDir, kAPP_RT, MAXPATHLEN);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return AttemptCopyAndLaunch(webAppRTExe);
|
||||
}
|
||||
|
||||
bool
|
||||
GetFirefoxDirFromRegistry(char* firefoxDir)
|
||||
{
|
||||
HKEY key;
|
||||
wchar_t wideGreDir[MAXPATHLEN];
|
||||
|
||||
if (ERROR_SUCCESS !=
|
||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows"
|
||||
L"\\CurrentVersion\\App paths\\firefox.exe",
|
||||
0,
|
||||
KEY_READ,
|
||||
&key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD length = MAXPATHLEN * sizeof(wchar_t);
|
||||
// XXX: When Vista/XP64 become our minimum supported client, we can use
|
||||
// RegGetValue instead
|
||||
if (ERROR_SUCCESS != RegQueryValueExW(key,
|
||||
L"Path",
|
||||
NULL,
|
||||
NULL,
|
||||
reinterpret_cast<BYTE*>(wideGreDir),
|
||||
&length)) {
|
||||
RegCloseKey(key);
|
||||
return false;
|
||||
};
|
||||
RegCloseKey(key);
|
||||
|
||||
// According to this article, we need to write our own null terminator:
|
||||
// http://msdn.microsoft.com/en-us/library/ms724911%28v=vs.85%29.aspx
|
||||
length = length / sizeof(wchar_t);
|
||||
if (wideGreDir[length] != L'\0') {
|
||||
if (length >= MAXPATHLEN) {
|
||||
return false;
|
||||
}
|
||||
wideGreDir[length] = L'\0';
|
||||
}
|
||||
|
||||
if (0 == WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wideGreDir,
|
||||
-1,
|
||||
firefoxDir,
|
||||
MAXPATHLEN,
|
||||
NULL,
|
||||
NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// main
|
||||
//
|
||||
// Note: XPCOM cannot be used until AttemptGRELoad has returned successfully.
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pargc = &argc;
|
||||
pargv = &argv;
|
||||
nsresult rv;
|
||||
char buffer[MAXPATHLEN];
|
||||
wchar_t wbuffer[MAXPATHLEN];
|
||||
|
||||
// Set up curEXEPath
|
||||
if (!GetModuleFileNameW(0, wbuffer, MAXPATHLEN)) {
|
||||
Output("Couldn't calculate the application directory.");
|
||||
return 255;
|
||||
}
|
||||
wcsncpy(curExePath, wbuffer, MAXPATHLEN);
|
||||
|
||||
// Get the current directory into wbuffer
|
||||
wchar_t* lastSlash = wcsrchr(wbuffer, L'\\');
|
||||
if (!lastSlash) {
|
||||
Output("Application directory format not understood.");
|
||||
return 255;
|
||||
}
|
||||
*(++lastSlash) = L'\0';
|
||||
|
||||
// Set up backup file path
|
||||
if (wcslen(wbuffer) + _countof(kAPP_RT_BACKUP) >= MAXPATHLEN) {
|
||||
Output("Application directory path is too long (couldn't set up backup file path).");
|
||||
}
|
||||
wcsncpy(lastSlash, kAPP_RT_BACKUP, _countof(kAPP_RT_BACKUP));
|
||||
wcsncpy(backupFilePath, wbuffer, MAXPATHLEN);
|
||||
|
||||
*lastSlash = L'\0';
|
||||
|
||||
// Convert current directory to utf8 and stuff it in buffer
|
||||
if (0 == WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wbuffer,
|
||||
-1,
|
||||
buffer,
|
||||
MAXPATHLEN,
|
||||
NULL,
|
||||
NULL)) {
|
||||
Output("Application directory could not be processed.");
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Set up appIniPath with path to webapp.ini.
|
||||
// This should be in the same directory as the running executable.
|
||||
char appIniPath[MAXPATHLEN];
|
||||
if (NS_FAILED(joinPath(appIniPath, buffer, kWEBAPP_INI, MAXPATHLEN))) {
|
||||
Output("Path to webapp.ini could not be processed.");
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Open webapp.ini as an INI file (as opposed to using the
|
||||
// XRE webapp.ini-specific processing we do later)
|
||||
nsINIParser parser;
|
||||
if (NS_FAILED(parser.Init(appIniPath))) {
|
||||
Output("Could not open webapp.ini");
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Set up our environment to know where webapp.ini was loaded from.
|
||||
char appEnv[MAXPATHLEN + _countof(kAPP_ENV_PREFIX)];
|
||||
strcpy(appEnv, kAPP_ENV_PREFIX);
|
||||
strcpy(appEnv + _countof(kAPP_ENV_PREFIX) - 1, appIniPath);
|
||||
if (putenv(appEnv)) {
|
||||
Output("Couldn't set up app environment");
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Get profile dir from webapp.ini
|
||||
if (NS_FAILED(parser.GetString("Webapp",
|
||||
"Profile",
|
||||
profile,
|
||||
MAXPATHLEN))) {
|
||||
Output("Unable to retrieve profile from web app INI file");
|
||||
return 255;
|
||||
}
|
||||
|
||||
char firefoxDir[MAXPATHLEN];
|
||||
|
||||
// First attempt at loading Firefox binaries:
|
||||
// Get the location of Firefox from our webapp.ini
|
||||
|
||||
// XXX: This string better be UTF-8...
|
||||
rv = parser.GetString("WebappRT",
|
||||
"InstallDir",
|
||||
firefoxDir,
|
||||
MAXPATHLEN);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (AttemptLoadFromDir(firefoxDir)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Second attempt at loading Firefox binaries:
|
||||
// Get the location of Firefox from the registry
|
||||
rv = GetFirefoxDirFromRegistry(firefoxDir);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (AttemptLoadFromDir(firefoxDir)) {
|
||||
// XXX: Write gre dir location to webapp.ini
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// We've done all we know how to do to try to find and launch FF
|
||||
Output("This app requires that Firefox version 14 or above is installed."
|
||||
" Firefox 14+ has not been detected.");
|
||||
return 255;
|
||||
}
|
39
webapprt/win/webapprt.exe.manifest
Normal file
39
webapprt/win/webapprt.exe.manifest
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity
|
||||
version="1.0.0.0"
|
||||
processorArchitecture="*"
|
||||
name="Mozilla.WebAppRT"
|
||||
type="win32"
|
||||
/>
|
||||
<description>Mozilla Webapp Runtime</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<ms_asmv3:security>
|
||||
<ms_asmv3:requestedPrivileges>
|
||||
<ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</ms_asmv3:requestedPrivileges>
|
||||
</ms_asmv3:security>
|
||||
</ms_asmv3:trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
6
webapprt/win/webapprt.rc
Normal file
6
webapprt/win/webapprt.rc
Normal file
@ -0,0 +1,6 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
1 24 "webapprt.exe.manifest"
|
@ -40,6 +40,8 @@
|
||||
#ifndef mozilla_FileUtils_h
|
||||
#define mozilla_FileUtils_h
|
||||
|
||||
#include "nscore.h" // nsnull
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_OS2)
|
||||
# include <unistd.h>
|
||||
#elif defined(XP_WIN)
|
||||
|
@ -121,8 +121,22 @@ nsAppShellService::CreateHiddenWindow()
|
||||
PRUint32 chromeMask = 0;
|
||||
nsAdoptingCString prefVal =
|
||||
Preferences::GetCString("browser.hiddenWindowChromeURL");
|
||||
const char* hiddenWindowURL = prefVal.get() ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
|
||||
mApplicationProvidedHiddenWindow = prefVal.get() ? true : false;
|
||||
|
||||
// Set mApplicationProvidedHiddenWindow to true only if there is a hidden
|
||||
// window chrome URL in preferences AND it is set to a non-default value.
|
||||
// This enables an app that doesn't have a hidden window (like WebappRT)
|
||||
// to share an app directory with one that does (like Firefox), the former
|
||||
// taking advantage of this behavior to "unset" the latter's hidden window
|
||||
// pref by setting it to the default value.
|
||||
//
|
||||
// (Ideally, the former would be able to simply unset the latter's pref,
|
||||
// but there is no way to do that; even more ideally, the two apps would not
|
||||
// share an app directory, but in the case of WebappRT and Firefox that's
|
||||
// a longer-term fix.)
|
||||
//
|
||||
mApplicationProvidedHiddenWindow = prefVal.get() && strcmp(prefVal.get(), DEFAULT_HIDDENWINDOW_URL) ? true : false;
|
||||
|
||||
const char* hiddenWindowURL = mApplicationProvidedHiddenWindow ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
|
||||
#else
|
||||
static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL;
|
||||
PRUint32 chromeMask = nsIWebBrowserChrome::CHROME_ALL;
|
||||
|
Loading…
Reference in New Issue
Block a user