mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1243546 - Add mach command for external-media-tests - r=gps (8c74584251) - Bug 1239987 - Remove marionette-transport dependency from build environment; r=gps (b5e6166e61) - Bug 1250748 - Remove the 20s countdown timer from mach first run; r=chmanchester (8755a9b3e0) - Bug 1238996 - Release marionette-driver 1.2, marionette-transport 1.1, and marionette-client 2.1; r=automatedtester (746bc487a4) - Bug 1243739 - Bump versions of marionette-driver, marionette-client and marionette-transport. r=ato (c87d6e57f8) - Bug 1243739: Update marionette-driver dependecy for marionette-transport. r=ato (582a2f8d8e) - Bug 1239987 - Merge marionette-transport into marionette-driver; r=automatedtester (254ed0727c) - Bug 1239330 - Support AddonManager.installTemporaryAddon() in marionette_driver.addons, r=ato (1f132b1cb3) - Bug 1230622 - Docs: Suggest people use wptserve instead of mozhttpd. r=jgraham (8b1c669740) - Bug 1174497 - [mozprofile] bump version and release to pypi; r=wlach (0360927850) - Bug 1014760 - Version bump mozbase modules that depend on mozlog 3.0, r=me (d16b10a25f) - Bug 1189858 - [mozprofile] remove the manifest parser required dependency. r=ahal (b181c379ce) - Bug 1189858 - fix typos in pip extra dependency declaration (587697be0d) - Bug 1199115 - Release mozprofile 0.27. r=jgraham DONTBUILD (a1e1452486) - Bug 1233534 - [mozprofile] bump version to 0.28. r=ahal (6e17f001dd) - Bug 1256401 - Part 2: Remove references to b2gdroid. r=fabrice (1486bf8669) - Bug 1112920 - Assert against pending exceptions in AutoJSAPI::InitInternal. v1 r=luke,r=smaug (fa9b99c835) - Fix the asset for bug 1112920 to not touch uninitialized memory. Totally my fault, since I moved it above the mCx assignment, and now we have a CLOSED TREE. (f404994a66) - Logging patch for bug 1256008. r=khuey (dcb846a987) - Bug 1255817 part 1. Make AutoJSAPI always take ownership of error reporting. r=bholley (638b9ca3fe) - Bug 1257306. Simplify the implementation of AutoSafeJSContext (and therefore AutoJSContext, since AutoSafeJSContext will no longer be an AutoJSContext). r=bholley (58b655ad7a) - Bug 1245951 - "Unused method in WebSocket". r=smaug (b2f8937893) - Bug 1227136 - crash in mozilla::net::WebSocketChannel::StartWebsocketData, r=bagder, r=baku (5249e56b52) - Bug 1252751 - Improve the security model between webSocket and sandboxed iframe, r=smaug (9a6c0be275) - Bug 1250234. Make WebSocket::CreateAndDispatchMessageEvent properly report JS exceptions it might be producing. r=khuey (eaae502684) - Bug 1255840. Get rid of the AutoJSAPI usage in IDBFactory. r=khuey (d0a965d1aa) - Bug 1151112 - 'Sending message that cannot be cloned. Are you trying to send an XPCOM object?' seen when unlocking phone. r=ferjm (7ba4294750) - Bug 1253834 - add AllChildrenIterator::Get(), r=bz (5c1ab2f7f2) - Bug 1249443 - add AllChildrenIterator::GetPreviousChild, r=bz (812f61db28) - Bug 1249443 - add AllChildrenIterator::Phase, r=bz (9106ec6dbb) - Bug 1095236 - Simplify browser_test_new_window_from_content.js to use BrowserTestUtils. r=mrbkap (b8fcea4ad1) - Bug 1095236 - Test that windows opened from content with dialog=1 still open. r=mrbkap. (db67a80e2b) - Bug 1210482 - regression tests for 1194897 in which window.[location|menu|personal|status|tool]bar.visible broke for e10s, we're testing these behave appropiately both in content and chrome. r=mconley (a17099181c) - Bug 1251897 - DocAccessible constructor doesn't have to take root element as an argument, r=davidb (77ef52ac2a)
This commit is contained in:
@@ -14,9 +14,8 @@ using namespace mozilla::a11y;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DocAccessibleWrap::
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aRootContent, aPresShell), mActivated(false)
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aPresShell), mActivated(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace a11y {
|
||||
class DocAccessibleWrap : public DocAccessible
|
||||
{
|
||||
public:
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell);
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~DocAccessibleWrap();
|
||||
|
||||
bool mActivated;
|
||||
|
||||
@@ -471,17 +471,15 @@ DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
||||
|
||||
// We only create root accessibles for the true root, otherwise create a
|
||||
// doc accessible.
|
||||
nsIContent *rootElm = nsCoreUtils::GetRoleContent(aDocument);
|
||||
RefPtr<DocAccessible> docAcc = isRootDoc ?
|
||||
new RootAccessibleWrap(aDocument, rootElm, presShell) :
|
||||
new DocAccessibleWrap(aDocument, rootElm, presShell);
|
||||
new RootAccessibleWrap(aDocument, presShell) :
|
||||
new DocAccessibleWrap(aDocument, presShell);
|
||||
|
||||
// Cache the document accessible into document cache.
|
||||
mDocAccessibleCache.Put(aDocument, docAcc);
|
||||
|
||||
// Initialize the document accessible.
|
||||
docAcc->Init();
|
||||
docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument));
|
||||
|
||||
// Bind the document to the tree.
|
||||
if (isRootDoc) {
|
||||
|
||||
@@ -76,9 +76,8 @@ static const uint32_t kRelationAttrsLen = ArrayLength(kRelationAttrs);
|
||||
// Constructor/desctructor
|
||||
|
||||
DocAccessible::
|
||||
DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell) :
|
||||
HyperTextAccessibleWrap(aRootContent, this),
|
||||
DocAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
HyperTextAccessibleWrap(nullptr, this),
|
||||
// XXX aaronl should we use an algorithm for the initial cache size?
|
||||
mAccessibleCache(kDefaultCacheLength),
|
||||
mNodeToAccessibleMap(kDefaultCacheLength),
|
||||
@@ -1493,7 +1492,7 @@ DocAccessible::DoInitialUpdate()
|
||||
// miss the notification (since content tree change notifications are ignored
|
||||
// prior to initial update). Make sure the content element is valid.
|
||||
nsIContent* contentElm = nsCoreUtils::GetRoleContent(mDocumentNode);
|
||||
if (mContent != contentElm) {
|
||||
if (contentElm) {
|
||||
mContent = contentElm;
|
||||
SetRoleMapEntry(aria::GetRoleMap(mContent));
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ class DocAccessible : public HyperTextAccessibleWrap,
|
||||
|
||||
public:
|
||||
|
||||
DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell);
|
||||
DocAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
|
||||
// nsIScrollPositionListener
|
||||
virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) override {}
|
||||
|
||||
@@ -59,9 +59,8 @@ NS_IMPL_ISUPPORTS_INHERITED0(RootAccessible, DocAccessible)
|
||||
// Constructor/destructor
|
||||
|
||||
RootAccessible::
|
||||
RootAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell) :
|
||||
DocAccessibleWrap(aDocument, aRootContent, aPresShell)
|
||||
RootAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
DocAccessibleWrap(aDocument, aPresShell)
|
||||
{
|
||||
mType = eRootType;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ class RootAccessible : public DocAccessibleWrap,
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
public:
|
||||
RootAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell);
|
||||
RootAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
|
||||
|
||||
@@ -14,8 +14,7 @@ namespace a11y {
|
||||
class DocAccessibleWrap : public DocAccessible
|
||||
{
|
||||
public:
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell);
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~DocAccessibleWrap();
|
||||
|
||||
};
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
DocAccessibleWrap::
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aRootContent, aPresShell)
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ namespace a11y {
|
||||
class RootAccessibleWrap : public RootAccessible
|
||||
{
|
||||
public:
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell);
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~RootAccessibleWrap();
|
||||
|
||||
Class GetNativeType ();
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
RootAccessibleWrap::
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell) :
|
||||
RootAccessible(aDocument, aRootContent, aPresShell)
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
RootAccessible(aDocument, aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,8 @@ using namespace mozilla::a11y;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DocAccessibleWrap::
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aRootContent, aPresShell), mHWND(nullptr)
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aPresShell), mHWND(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@ namespace a11y {
|
||||
class DocAccessibleWrap : public DocAccessible
|
||||
{
|
||||
public:
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell);
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~DocAccessibleWrap();
|
||||
|
||||
DECL_IUNKNOWN_INHERITED
|
||||
|
||||
@@ -15,9 +15,8 @@ using namespace mozilla::a11y;
|
||||
// Constructor/desctructor
|
||||
|
||||
RootAccessibleWrap::
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell) :
|
||||
RootAccessible(aDocument, aRootContent, aPresShell)
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
RootAccessible(aDocument, aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ namespace a11y {
|
||||
class RootAccessibleWrap : public RootAccessible
|
||||
{
|
||||
public:
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIPresShell* aPresShell);
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~RootAccessibleWrap();
|
||||
|
||||
// RootAccessible
|
||||
|
||||
@@ -351,8 +351,7 @@ setUpdateTrackingId();
|
||||
});
|
||||
}
|
||||
|
||||
syncPrefDefault(AppConstants.MOZ_B2GDROID ? 'app.update.url.android'
|
||||
: 'app.update.url');
|
||||
syncPrefDefault('app.update.url');
|
||||
syncPrefDefault('app.update.channel');
|
||||
})();
|
||||
|
||||
|
||||
@@ -230,10 +230,6 @@ var shell = {
|
||||
},
|
||||
|
||||
bootstrap: function() {
|
||||
#ifdef MOZ_B2GDROID
|
||||
Cc["@mozilla.org/b2g/b2gdroid-setup;1"]
|
||||
.getService(Ci.nsIObserver).observe(window, "shell-startup", null);
|
||||
#endif
|
||||
|
||||
window.performance.mark('gecko-shell-bootstrap');
|
||||
|
||||
|
||||
@@ -16,15 +16,12 @@ contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49f
|
||||
category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59}
|
||||
#endif
|
||||
|
||||
# On b2gdroid we want to use the android implementation of the directory service.
|
||||
#ifndef MOZ_B2GDROID
|
||||
#ifdef MOZ_B2G
|
||||
# DirectoryProvider.js
|
||||
component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js
|
||||
contract @mozilla.org/b2g/directory-provider;1 {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}
|
||||
category xpcom-directory-providers b2g-directory-provider @mozilla.org/b2g/directory-provider;1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
# ActivitiesGlue.js
|
||||
component {3a54788b-48cc-4ab4-93d6-0d6a8ef74f8e} ActivitiesGlue.js
|
||||
@@ -94,7 +91,6 @@ contract @mozilla.org/fxaccounts/fxaccounts-ui-glue;1 {51875c14-91d7-4b8c-b65d-3
|
||||
component {710322af-e6ae-4b0c-b2c9-1474a87b077e} HelperAppDialog.js
|
||||
contract @mozilla.org/helperapplauncherdialog;1 {710322af-e6ae-4b0c-b2c9-1474a87b077e}
|
||||
|
||||
#ifndef MOZ_B2GDROID
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
component {c83c02c0-5d43-4e3e-987f-9173b313e880} SimulatorScreen.js
|
||||
contract @mozilla.org/simulator-screen;1 {c83c02c0-5d43-4e3e-987f-9173b313e880}
|
||||
@@ -108,7 +104,6 @@ component {385993fe-8710-4621-9fb1-00a09d8bec37} CommandLine.js
|
||||
contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds {385993fe-8710-4621-9fb1-00a09d8bec37}
|
||||
category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
# BootstrapCommandLine.js
|
||||
component {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} BootstrapCommandLine.js
|
||||
|
||||
@@ -43,7 +43,7 @@ EXTRA_PP_COMPONENTS += [
|
||||
'B2GComponents.manifest',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G'] and not CONFIG['MOZ_B2GDROID']:
|
||||
if CONFIG['MOZ_B2G']:
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'DirectoryProvider.js',
|
||||
'RecoveryService.js',
|
||||
|
||||
+2
-10
@@ -2,15 +2,7 @@
|
||||
# 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/.
|
||||
|
||||
# For b2gdroid, gaia ends up in the assets/gaia folder in the APK.
|
||||
GAIA_PATH := $(if MOZ_B2GDROID,gaia/assets/gaia,gaia/profile)
|
||||
|
||||
# For b2gdroid, we disable the screen timeout since this is managed by android.
|
||||
# We also limit the app set to the production ones.
|
||||
GAIA_OPTIONS := $(if MOZ_B2GDROID, \
|
||||
GAIA_DISTRIBUTION_DIR=distros/b2gdroid \
|
||||
NO_LOCK_SCREEN=1 \
|
||||
)
|
||||
GAIA_PATH := gaia/profile
|
||||
|
||||
GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
|
||||
|
||||
@@ -18,5 +10,5 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
+$(MAKE) -j1 -C $(GAIADIR) clean
|
||||
+$(GAIA_OPTIONS) $(MAKE) -j1 -C $(GAIADIR) profile
|
||||
+$(MAKE) -j1 -C $(GAIADIR) profile
|
||||
(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(ABS_DIST)/bin/$(GAIA_PATH) && tar -xf -)
|
||||
|
||||
+13
-15
@@ -4,19 +4,17 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if not CONFIG['MOZ_B2GDROID']:
|
||||
# b2gdroid does not build a runner executable, but it does build gaia; see Makefile.in.
|
||||
Program(CONFIG['MOZ_APP_NAME'])
|
||||
Program(CONFIG['MOZ_APP_NAME'])
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'run-b2g.cpp',
|
||||
]
|
||||
DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
|
||||
DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
|
||||
else:
|
||||
SOURCES += [
|
||||
'run-b2g.c',
|
||||
]
|
||||
DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
|
||||
DEFINES['GAIA_PATH'] = '"gaia/profile"'
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'run-b2g.cpp',
|
||||
]
|
||||
DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
|
||||
DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
|
||||
else:
|
||||
SOURCES += [
|
||||
'run-b2g.c',
|
||||
]
|
||||
DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
|
||||
DEFINES['GAIA_PATH'] = '"gaia/profile"'
|
||||
|
||||
+7
-11
@@ -20,6 +20,8 @@ If you would like to use a different directory, hit CTRL+c and set the
|
||||
MOZBUILD_STATE_PATH environment variable to the directory you would like to
|
||||
use and re-run mach. For this change to take effect forever, you'll likely
|
||||
want to export this environment variable from your shell's init scripts.
|
||||
|
||||
Press ENTER/RETURN to continue or CTRL+c to abort.
|
||||
'''.lstrip()
|
||||
|
||||
|
||||
@@ -41,6 +43,7 @@ SEARCH_PATHS = [
|
||||
'config',
|
||||
'dom/bindings',
|
||||
'dom/bindings/parser',
|
||||
'dom/media/test/external',
|
||||
'layout/tools/reftest',
|
||||
'other-licenses/ply',
|
||||
'testing',
|
||||
@@ -49,7 +52,6 @@ SEARCH_PATHS = [
|
||||
'testing/luciddream',
|
||||
'testing/marionette/client',
|
||||
'testing/marionette/client/marionette/runner/mixins/browsermob-proxy-py',
|
||||
'testing/marionette/transport',
|
||||
'testing/marionette/driver',
|
||||
'testing/mozbase/mozcrash',
|
||||
'testing/mozbase/mozdebug',
|
||||
@@ -83,6 +85,7 @@ SEARCH_PATHS = [
|
||||
MACH_MODULES = [
|
||||
'build/valgrind/mach_commands.py',
|
||||
'dom/bindings/mach_commands.py',
|
||||
'dom/media/test/external/mach_commands.py',
|
||||
'layout/tools/reftest/mach_commands.py',
|
||||
'python/mach_commands.py',
|
||||
'python/mach/mach/commands/commandinfo.py',
|
||||
@@ -188,26 +191,19 @@ def bootstrap(topsrcdir, mozilla_dir=None):
|
||||
if state_env_dir:
|
||||
if not os.path.exists(state_env_dir):
|
||||
print('Creating global state directory from environment variable: %s'
|
||||
% state_env_dir)
|
||||
% state_env_dir)
|
||||
os.makedirs(state_env_dir, mode=0o770)
|
||||
print('Please re-run mach.')
|
||||
sys.exit(1)
|
||||
state_dir = state_env_dir
|
||||
else:
|
||||
if not os.path.exists(state_user_dir):
|
||||
print(STATE_DIR_FIRST_RUN.format(userdir=state_user_dir))
|
||||
try:
|
||||
for i in range(20, -1, -1):
|
||||
time.sleep(1)
|
||||
sys.stdout.write('%d ' % i)
|
||||
sys.stdout.flush()
|
||||
sys.stdin.readline()
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(1)
|
||||
|
||||
print('\nCreating default state directory: %s' % state_user_dir)
|
||||
os.mkdir(state_user_dir)
|
||||
print('Please re-run mach.')
|
||||
sys.exit(1)
|
||||
os.makedirs(state_user_dir, mode=0o770)
|
||||
state_dir = state_user_dir
|
||||
|
||||
return state_dir
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
marionette_transport.pth:testing/marionette/transport
|
||||
marionette_driver.pth:testing/marionette/driver
|
||||
browsermobproxy.pth:testing/marionette/client/marionette/runner/mixins/browsermob-proxy-py
|
||||
wptserve.pth:testing/web-platform/tests/tools/wptserve
|
||||
|
||||
@@ -3974,10 +3974,6 @@ esac
|
||||
|
||||
BUILD_BACKENDS="$BUILD_BACKENDS FasterMake"
|
||||
|
||||
if test -n "$MOZ_B2GDROID"; then
|
||||
AC_DEFINE(MOZ_B2GDROID)
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_BUILD_APP)
|
||||
AC_SUBST(MOZ_PHOENIX)
|
||||
AC_SUBST(MOZ_XULRUNNER)
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const { interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["AndroidUtils"];
|
||||
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Messaging",
|
||||
"resource://gre/modules/Messaging.jsm");
|
||||
|
||||
let appsRegistry = null;
|
||||
|
||||
function debug() {
|
||||
//dump("-*- AndroidUtils " + Array.slice(arguments) + "\n");
|
||||
}
|
||||
|
||||
// Helper functions to manage Android native apps. We keep them in the
|
||||
// registry with a `kind` equals to "android-native" and we also store
|
||||
// the package name and class name in the registry.
|
||||
// Communication with the android side happens through json messages.
|
||||
|
||||
this.AndroidUtils = {
|
||||
init: function(aRegistry) {
|
||||
appsRegistry = aRegistry;
|
||||
Services.obs.addObserver(this, "Android:Apps:Installed", false);
|
||||
Services.obs.addObserver(this, "Android:Apps:Uninstalled", false);
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
Services.obs.removeObserver(this, "Android:Apps:Installed");
|
||||
Services.obs.removeObserver(this, "Android:Apps:Uninstalled");
|
||||
},
|
||||
|
||||
getOriginAndManifestURL: function(aPackageName) {
|
||||
let origin = "android://" + aPackageName.toLowerCase();
|
||||
let manifestURL = origin + "/manifest.webapp";
|
||||
return [origin, manifestURL];
|
||||
},
|
||||
|
||||
getPackageAndClassFromManifestURL: function(aManifestURL) {
|
||||
debug("getPackageAndClassFromManifestURL " + aManifestURL);
|
||||
let app = appsRegistry.getAppByManifestURL(aManifestURL);
|
||||
if (!app) {
|
||||
debug("No app for " + aManifestURL);
|
||||
return [];
|
||||
}
|
||||
return [app.android_packagename, app.android_classname];
|
||||
},
|
||||
|
||||
buildAndroidAppData: function(aApp) {
|
||||
// Use the package and class name to get a unique origin.
|
||||
// We put the version with the normal case as part of the manifest url.
|
||||
let [origin, manifestURL] =
|
||||
this.getOriginAndManifestURL(aApp.packagename);
|
||||
// TODO: Bug 1204557 to improve the icons support.
|
||||
let manifest = {
|
||||
name: aApp.name,
|
||||
icons: { "96": aApp.icon }
|
||||
}
|
||||
debug("Origin is " + origin);
|
||||
let appData = {
|
||||
app: {
|
||||
installOrigin: origin,
|
||||
origin: origin,
|
||||
manifest: manifest,
|
||||
manifestURL: manifestURL,
|
||||
manifestHash: AppsUtils.computeHash(JSON.stringify(manifest)),
|
||||
appStatus: Ci.nsIPrincipal.APP_STATUS_INSTALLED,
|
||||
removable: aApp.removable,
|
||||
android_packagename: aApp.packagename,
|
||||
android_classname: aApp.classname
|
||||
},
|
||||
isBrowser: false,
|
||||
isPackage: false
|
||||
};
|
||||
|
||||
return appData;
|
||||
},
|
||||
|
||||
installAndroidApps: function() {
|
||||
return Messaging.sendRequestForResult({ type: "Apps:GetList" }).then(
|
||||
aApps => {
|
||||
debug("Got " + aApps.apps.length + " android apps.");
|
||||
let promises = [];
|
||||
aApps.apps.forEach(app => {
|
||||
debug("App is " + app.name + " removable? " + app.removable);
|
||||
let p = new Promise((aResolveInstall, aRejectInstall) => {
|
||||
let appData = this.buildAndroidAppData(app);
|
||||
appsRegistry.confirmInstall(appData, null, aResolveInstall);
|
||||
});
|
||||
promises.push(p);
|
||||
});
|
||||
|
||||
// Wait for all apps to be installed.
|
||||
return Promise.all(promises);
|
||||
}
|
||||
).then(appsRegistry._saveApps.bind(appsRegistry));
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(aData);
|
||||
} catch(e) {
|
||||
debug(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTopic == "Android:Apps:Installed") {
|
||||
let appData = this.buildAndroidAppData(data);
|
||||
appsRegistry.confirmInstall(appData);
|
||||
} else if (aTopic == "Android:Apps:Uninstalled") {
|
||||
let [origin, manifestURL] =
|
||||
this.getOriginAndManifestURL(data.packagename);
|
||||
appsRegistry.uninstall(manifestURL);
|
||||
}
|
||||
},
|
||||
}
|
||||
+5
-14
@@ -260,11 +260,6 @@ this.DOMApplicationRegistry = {
|
||||
this.getFullAppByManifestURL.bind(this));
|
||||
|
||||
MessageBroadcaster.init(this.getAppByManifestURL);
|
||||
|
||||
if (AppConstants.MOZ_B2GDROID) {
|
||||
Cu.import("resource://gre/modules/AndroidUtils.jsm");
|
||||
AndroidUtils.init(this);
|
||||
}
|
||||
},
|
||||
|
||||
// loads the current registry, that could be empty on first run.
|
||||
@@ -530,7 +525,7 @@ this.DOMApplicationRegistry = {
|
||||
|
||||
// Installs a 3rd party app.
|
||||
installPreinstalledApp: function installPreinstalledApp(aId) {
|
||||
if (!AppConstants.MOZ_B2GDROID && AppConstants.platform !== "gonk") {
|
||||
if (AppConstants.platform !== "gonk") {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -799,14 +794,10 @@ this.DOMApplicationRegistry = {
|
||||
}
|
||||
}
|
||||
|
||||
if (AppConstants.MOZ_B2GDROID || AppConstants.MOZ_B2G) {
|
||||
if (AppConstants.MOZ_B2G) {
|
||||
yield this.installSystemApps();
|
||||
}
|
||||
|
||||
if (AppConstants.MOZ_B2GDROID) {
|
||||
yield AndroidUtils.installAndroidApps();
|
||||
}
|
||||
|
||||
// At first run, install preloaded apps and set up their permissions.
|
||||
for (let id in this.webapps) {
|
||||
let isPreinstalled = this.installPreinstalledApp(id);
|
||||
@@ -1319,7 +1310,7 @@ this.DOMApplicationRegistry = {
|
||||
this.registryReady.then( () => {
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install": {
|
||||
if (AppConstants.platform == "android" && !AppConstants.MOZ_B2GDROID) {
|
||||
if (AppConstants.platform == "android") {
|
||||
Services.obs.notifyObservers(mm, "webapps-runtime-install", JSON.stringify(msg));
|
||||
} else {
|
||||
this.doInstall(msg, mm);
|
||||
@@ -1330,7 +1321,7 @@ this.DOMApplicationRegistry = {
|
||||
this.getSelf(msg, mm);
|
||||
break;
|
||||
case "Webapps:Uninstall":
|
||||
if (AppConstants.platform == "android" && !AppConstants.MOZ_B2GDROID) {
|
||||
if (AppConstants.platform == "android") {
|
||||
Services.obs.notifyObservers(mm, "webapps-runtime-uninstall", JSON.stringify(msg));
|
||||
} else {
|
||||
this.doUninstall(msg, mm);
|
||||
@@ -1352,7 +1343,7 @@ this.DOMApplicationRegistry = {
|
||||
this.getNotInstalled(msg, mm);
|
||||
break;
|
||||
case "Webapps:InstallPackage": {
|
||||
if (AppConstants.platform == "android" && !AppConstants.MOZ_B2GDROID) {
|
||||
if (AppConstants.platform == "android") {
|
||||
Services.obs.notifyObservers(mm, "webapps-runtime-install-package", JSON.stringify(msg));
|
||||
} else {
|
||||
this.doInstallPackage(msg, mm);
|
||||
|
||||
@@ -45,11 +45,6 @@ EXTRA_JS_MODULES += [
|
||||
'UserCustomizations.jsm',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2GDROID']:
|
||||
EXTRA_JS_MODULES += [
|
||||
'AndroidUtils.jsm',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'AppsUtils.jsm',
|
||||
'ImportExport.jsm',
|
||||
|
||||
+121
-23
@@ -215,7 +215,7 @@ ExplicitChildIterator::Seek(nsIContent* aChildToFind)
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
ExplicitChildIterator::Get()
|
||||
ExplicitChildIterator::Get() const
|
||||
{
|
||||
MOZ_ASSERT(!mIsFirst);
|
||||
|
||||
@@ -311,27 +311,60 @@ ExplicitChildIterator::GetPreviousChild()
|
||||
return mChild;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
AllChildrenIterator::Get() const
|
||||
{
|
||||
switch (mPhase) {
|
||||
case eAtBeforeKid: {
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
MOZ_ASSERT(frame, "No frame at eAtBeforeKid phase");
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
MOZ_ASSERT(beforeFrame, "No content before frame at eAtBeforeKid phase");
|
||||
return beforeFrame->GetContent();
|
||||
}
|
||||
|
||||
case eAtExplicitKids:
|
||||
return ExplicitChildIterator::Get();
|
||||
|
||||
case eAtAnonKids:
|
||||
return mAnonKids[mAnonKidsIdx];
|
||||
|
||||
case eAtAfterKid: {
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
MOZ_ASSERT(frame, "No frame at eAtAfterKid phase");
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
MOZ_ASSERT(afterFrame, "No content before frame at eAtBeforeKid phase");
|
||||
return afterFrame->GetContent();
|
||||
}
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
||||
{
|
||||
if (mPhase == eNeedBeforeKid) {
|
||||
mPhase = eNeedExplicitKids;
|
||||
if (mPhase == eAtBegin || mPhase == eAtBeforeKid) {
|
||||
mPhase = eAtExplicitKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
if (beforeFrame->GetContent() == aChildToFind) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mPhase == eNeedExplicitKids) {
|
||||
if (mPhase == eAtExplicitKids) {
|
||||
if (ExplicitChildIterator::Seek(aChildToFind)) {
|
||||
return true;
|
||||
}
|
||||
mPhase = eNeedAnonKids;
|
||||
mPhase = eAtAnonKids;
|
||||
}
|
||||
|
||||
nsIContent* child = nullptr;
|
||||
@@ -345,59 +378,124 @@ AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
||||
nsIContent*
|
||||
AllChildrenIterator::GetNextChild()
|
||||
{
|
||||
if (mPhase == eNeedBeforeKid) {
|
||||
mPhase = eNeedExplicitKids;
|
||||
if (mPhase == eAtBegin) {
|
||||
mPhase = eAtExplicitKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mPhase == eNeedExplicitKids) {
|
||||
if (mPhase == eAtBeforeKid) {
|
||||
// Advance into our explicit kids.
|
||||
mPhase = eAtExplicitKids;
|
||||
}
|
||||
|
||||
if (mPhase == eAtExplicitKids) {
|
||||
nsIContent* kid = ExplicitChildIterator::GetNextChild();
|
||||
if (kid) {
|
||||
return kid;
|
||||
}
|
||||
|
||||
mPhase = eNeedAnonKids;
|
||||
mPhase = eAtAnonKids;
|
||||
}
|
||||
|
||||
if (mPhase == eNeedAnonKids) {
|
||||
if (mPhase == eAtAnonKids) {
|
||||
if (mAnonKids.IsEmpty()) {
|
||||
MOZ_ASSERT(mAnonKidsIdx == UINT32_MAX);
|
||||
nsIAnonymousContentCreator* ac =
|
||||
do_QueryFrame(mOriginalContent->GetPrimaryFrame());
|
||||
if (ac) {
|
||||
ac->AppendAnonymousContentTo(mAnonKids, mFlags);
|
||||
}
|
||||
mAnonKidsIdx = 0;
|
||||
}
|
||||
|
||||
if (!mAnonKids.IsEmpty()) {
|
||||
nsIContent* nextKid = mAnonKids[0];
|
||||
mAnonKids.RemoveElementAt(0);
|
||||
if (mAnonKids.IsEmpty()) {
|
||||
mPhase = eNeedAfterKid;
|
||||
else {
|
||||
if (mAnonKidsIdx == UINT32_MAX) {
|
||||
mAnonKidsIdx = 0;
|
||||
}
|
||||
else {
|
||||
mAnonKidsIdx++;
|
||||
}
|
||||
|
||||
return nextKid;
|
||||
}
|
||||
|
||||
mPhase = eNeedAfterKid;
|
||||
}
|
||||
if (mAnonKidsIdx < mAnonKids.Length()) {
|
||||
return mAnonKids[mAnonKidsIdx];
|
||||
}
|
||||
|
||||
if (mPhase == eNeedAfterKid) {
|
||||
mPhase = eDone;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
if (afterFrame) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPhase = eAtEnd;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
AllChildrenIterator::GetPreviousChild()
|
||||
{
|
||||
if (mPhase == eAtEnd) {
|
||||
MOZ_ASSERT(mAnonKidsIdx == mAnonKids.Length());
|
||||
mPhase = eAtAnonKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
if (afterFrame) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mPhase == eAtAfterKid) {
|
||||
mPhase = eAtAnonKids;
|
||||
}
|
||||
|
||||
if (mPhase == eAtAnonKids) {
|
||||
if (mAnonKids.IsEmpty()) {
|
||||
nsIAnonymousContentCreator* ac =
|
||||
do_QueryFrame(mOriginalContent->GetPrimaryFrame());
|
||||
if (ac) {
|
||||
ac->AppendAnonymousContentTo(mAnonKids, mFlags);
|
||||
mAnonKidsIdx = mAnonKids.Length();
|
||||
}
|
||||
}
|
||||
|
||||
// If 0 then it turns into UINT32_MAX, which indicates the iterator is
|
||||
// before the anonymous children.
|
||||
--mAnonKidsIdx;
|
||||
if (mAnonKidsIdx < mAnonKids.Length()) {
|
||||
return mAnonKids[mAnonKidsIdx];
|
||||
}
|
||||
mPhase = eAtExplicitKids;
|
||||
}
|
||||
|
||||
if (mPhase == eAtExplicitKids) {
|
||||
nsIContent* kid = ExplicitChildIterator::GetPreviousChild();
|
||||
if (kid) {
|
||||
return kid;
|
||||
}
|
||||
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPhase = eAtBegin;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
+37
-17
@@ -89,7 +89,7 @@ public:
|
||||
// Returns the current target of this iterator (which might be an explicit
|
||||
// child of the node, fallback content of an insertion point or
|
||||
// a node distributed to an insertion point.
|
||||
nsIContent* Get();
|
||||
nsIContent* Get() const;
|
||||
|
||||
// The inverse of GetNextChild. Properly steps in and out of insertion
|
||||
// points.
|
||||
@@ -170,26 +170,27 @@ protected:
|
||||
};
|
||||
|
||||
/**
|
||||
* AllChildrenIterator returns the children of a element including before /
|
||||
* after content and optionally XBL children. It assumes that no mutation of
|
||||
* the DOM or frame tree takes place during iteration, and will break horribly
|
||||
* if that is not true. The iterator can be initialized to start at the end by
|
||||
* providing false for aStartAtBeginning in order to start iterating in reverse
|
||||
* from the last child.
|
||||
* AllChildrenIterator traverses the children of an element including before /
|
||||
* after content and optionally XBL children. The iterator can be initialized
|
||||
* to start at the end by providing false for aStartAtBeginning in order to
|
||||
* start iterating in reverse from the last child.
|
||||
*
|
||||
* Note: it assumes that no mutation of the DOM or frame tree takes place during
|
||||
* iteration, and will break horribly if that is not true.
|
||||
*/
|
||||
class AllChildrenIterator : private FlattenedChildIterator
|
||||
{
|
||||
public:
|
||||
AllChildrenIterator(nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) :
|
||||
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||
mOriginalContent(aNode), mFlags(aFlags),
|
||||
mPhase(eNeedBeforeKid) {}
|
||||
mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
|
||||
|
||||
AllChildrenIterator(AllChildrenIterator&& aOther)
|
||||
: FlattenedChildIterator(Move(aOther)),
|
||||
mOriginalContent(aOther.mOriginalContent),
|
||||
mAnonKids(Move(aOther.mAnonKids)), mFlags(aOther.mFlags),
|
||||
mPhase(aOther.mPhase)
|
||||
mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
|
||||
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
|
||||
#ifdef DEBUG
|
||||
, mMutationGuard(aOther.mMutationGuard)
|
||||
#endif
|
||||
@@ -199,23 +200,42 @@ public:
|
||||
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
|
||||
#endif
|
||||
|
||||
// Returns the current target the iterator is at, or null if the iterator
|
||||
// doesn't point to any child node (either eAtBegin or eAtEnd phase).
|
||||
nsIContent* Get() const;
|
||||
|
||||
// Seeks the given node in children of a parent element, starting from
|
||||
// the current iterator's position, and sets the iterator at the given child
|
||||
// node if it was found.
|
||||
bool Seek(nsIContent* aChildToFind);
|
||||
|
||||
nsIContent* GetNextChild();
|
||||
nsIContent* GetPreviousChild();
|
||||
nsIContent* Parent() const { return mOriginalContent; }
|
||||
|
||||
private:
|
||||
enum IteratorPhase
|
||||
{
|
||||
eNeedBeforeKid,
|
||||
eNeedExplicitKids,
|
||||
eNeedAnonKids,
|
||||
eNeedAfterKid,
|
||||
eDone
|
||||
eAtBegin,
|
||||
eAtBeforeKid,
|
||||
eAtExplicitKids,
|
||||
eAtAnonKids,
|
||||
eAtAfterKid,
|
||||
eAtEnd
|
||||
};
|
||||
IteratorPhase Phase() const { return mPhase; }
|
||||
|
||||
private:
|
||||
nsIContent* mOriginalContent;
|
||||
|
||||
// mAnonKids is an array of native anonymous children, mAnonKidsIdx is index
|
||||
// in the array. If mAnonKidsIdx < mAnonKids.Length() and mPhase is
|
||||
// eAtAnonKids then the iterator points at a child at mAnonKidsIdx index. If
|
||||
// mAnonKidsIdx == mAnonKids.Length() then the iterator is somewhere after
|
||||
// the last native anon child. If mAnonKidsIdx == UINT32_MAX then the iterator
|
||||
// is somewhere before the first native anon child.
|
||||
nsTArray<nsIContent*> mAnonKids;
|
||||
uint32_t mAnonKidsIdx;
|
||||
|
||||
uint32_t mFlags;
|
||||
IteratorPhase mPhase;
|
||||
#ifdef DEBUG
|
||||
|
||||
+101
-39
@@ -303,7 +303,6 @@ FindJSContext(nsIGlobalObject* aGlobalObject)
|
||||
|
||||
AutoJSAPI::AutoJSAPI()
|
||||
: mCx(nullptr)
|
||||
, mOwnErrorReporting(false)
|
||||
, mOldAutoJSAPIOwnsErrorReporting(false)
|
||||
, mIsMainThread(false) // For lack of anything better
|
||||
{
|
||||
@@ -311,27 +310,39 @@ AutoJSAPI::AutoJSAPI()
|
||||
|
||||
AutoJSAPI::~AutoJSAPI()
|
||||
{
|
||||
if (mOwnErrorReporting) {
|
||||
ReportException();
|
||||
|
||||
// We need to do this _after_ processing the existing exception, because the
|
||||
// JS engine can throw while doing that, and uses this bit to determine what
|
||||
// to do in that case: squelch the exception if the bit is set, otherwise
|
||||
// call the error reporter. Calling WarningOnlyErrorReporter with a
|
||||
// non-warning will assert, so we need to make sure we do the former.
|
||||
JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(mOldAutoJSAPIOwnsErrorReporting);
|
||||
if (!mCx) {
|
||||
// No need to do anything here: we never managed to Init, so can't have an
|
||||
// exception on our (nonexistent) JSContext. We also don't need to restore
|
||||
// any state on it.
|
||||
return;
|
||||
}
|
||||
|
||||
ReportException();
|
||||
|
||||
// We need to do this _after_ processing the existing exception, because the
|
||||
// JS engine can throw while doing that, and uses this bit to determine what
|
||||
// to do in that case: squelch the exception if the bit is set, otherwise
|
||||
// call the error reporter. Calling WarningOnlyErrorReporter with a
|
||||
// non-warning will assert, so we need to make sure we do the former.
|
||||
JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(mOldAutoJSAPIOwnsErrorReporting);
|
||||
|
||||
if (mOldErrorReporter.isSome()) {
|
||||
JS_SetErrorReporter(JS_GetRuntime(cx()), mOldErrorReporter.value());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage,
|
||||
JSErrorReport* aRep);
|
||||
|
||||
void
|
||||
AutoJSAPI::InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
|
||||
#ifdef DEBUG
|
||||
bool haveException = JS_IsExceptionPending(aCx);
|
||||
#endif // DEBUG
|
||||
|
||||
mCx = aCx;
|
||||
mIsMainThread = aIsMainThread;
|
||||
@@ -350,16 +361,81 @@ AutoJSAPI::InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread)
|
||||
JSRuntime* rt = JS_GetRuntime(aCx);
|
||||
mOldErrorReporter.emplace(JS_GetErrorReporter(rt));
|
||||
|
||||
if (aIsMainThread) {
|
||||
JS_SetErrorReporter(rt, xpc::SystemErrorReporter);
|
||||
mOldAutoJSAPIOwnsErrorReporting = JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting();
|
||||
JS::ContextOptionsRef(aCx).setAutoJSAPIOwnsErrorReporting(true);
|
||||
JS_SetErrorReporter(rt, WarningOnlyErrorReporter);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (haveException) {
|
||||
JS::Rooted<JS::Value> exn(aCx);
|
||||
JS_GetPendingException(aCx, &exn);
|
||||
|
||||
JS_ClearPendingException(aCx);
|
||||
if (exn.isObject()) {
|
||||
JS::Rooted<JSObject*> exnObj(aCx, &exn.toObject());
|
||||
|
||||
nsAutoJSString stack, filename, name, message;
|
||||
int32_t line;
|
||||
|
||||
JS::Rooted<JS::Value> tmp(aCx);
|
||||
if (!JS_GetProperty(aCx, exnObj, "filename", &tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
if (tmp.isUndefined()) {
|
||||
if (!JS_GetProperty(aCx, exnObj, "fileName", &tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "stack", &tmp) ||
|
||||
!stack.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "name", &tmp) ||
|
||||
!name.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "message", &tmp) ||
|
||||
!message.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "lineNumber", &tmp) ||
|
||||
!JS::ToInt32(aCx, tmp, &line)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
line = 0;
|
||||
}
|
||||
|
||||
printf_stderr("PREEXISTING EXCEPTION OBJECT: '%s: %s'\n%s:%d\n%s\n",
|
||||
NS_ConvertUTF16toUTF8(name).get(),
|
||||
NS_ConvertUTF16toUTF8(message).get(),
|
||||
NS_ConvertUTF16toUTF8(filename).get(), line,
|
||||
NS_ConvertUTF16toUTF8(stack).get());
|
||||
} else {
|
||||
// It's a primitive... not much we can do other than stringify it.
|
||||
nsAutoJSString exnStr;
|
||||
if (!exnStr.init(aCx, exn)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
printf_stderr("PREEXISTING EXCEPTION PRIMITIVE: %s\n",
|
||||
NS_ConvertUTF16toUTF8(exnStr).get());
|
||||
}
|
||||
MOZ_ASSERT(false, "We had an exception; we should not have");
|
||||
}
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
|
||||
bool aIsMainThread,
|
||||
JSContext* aCx)
|
||||
: mOwnErrorReporting(false)
|
||||
, mOldAutoJSAPIOwnsErrorReporting(false)
|
||||
: mOldAutoJSAPIOwnsErrorReporting(false)
|
||||
, mIsMainThread(aIsMainThread)
|
||||
{
|
||||
MOZ_ASSERT(aGlobalObject);
|
||||
@@ -476,19 +552,11 @@ WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage, JSErrorReport* aR
|
||||
void
|
||||
AutoJSAPI::TakeOwnershipOfErrorReporting()
|
||||
{
|
||||
MOZ_ASSERT(!mOwnErrorReporting);
|
||||
mOwnErrorReporting = true;
|
||||
|
||||
JSRuntime *rt = JS_GetRuntime(cx());
|
||||
mOldAutoJSAPIOwnsErrorReporting = JS::ContextOptionsRef(cx()).autoJSAPIOwnsErrorReporting();
|
||||
JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(true);
|
||||
JS_SetErrorReporter(rt, WarningOnlyErrorReporter);
|
||||
}
|
||||
|
||||
void
|
||||
AutoJSAPI::ReportException()
|
||||
{
|
||||
MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
|
||||
if (!HasException()) {
|
||||
return;
|
||||
}
|
||||
@@ -757,18 +825,6 @@ danger::AutoCxPusher::IsStackTop() const
|
||||
|
||||
AutoJSContext::AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
|
||||
: mCx(nullptr)
|
||||
{
|
||||
Init(false MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT);
|
||||
}
|
||||
|
||||
AutoJSContext::AutoJSContext(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: mCx(nullptr)
|
||||
{
|
||||
Init(aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT);
|
||||
}
|
||||
|
||||
void
|
||||
AutoJSContext::Init(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
{
|
||||
JS::AutoSuppressGCAnalysis nogc;
|
||||
MOZ_ASSERT(!mCx, "mCx should not be initialized!");
|
||||
@@ -776,9 +832,7 @@ AutoJSContext::Init(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
nsXPConnect *xpc = nsXPConnect::XPConnect();
|
||||
if (!aSafe) {
|
||||
mCx = xpc->GetCurrentJSContext();
|
||||
}
|
||||
mCx = xpc->GetCurrentJSContext();
|
||||
|
||||
if (!mCx) {
|
||||
mJSAPI.Init();
|
||||
@@ -814,9 +868,17 @@ ThreadsafeAutoJSContext::operator JSContext*() const
|
||||
}
|
||||
|
||||
AutoSafeJSContext::AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
|
||||
: AutoJSContext(true MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
|
||||
, mAc(mCx, xpc::UnprivilegedJunkScope())
|
||||
: AutoJSAPI()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
DebugOnly<bool> ok = Init(xpc::UnprivilegedJunkScope());
|
||||
MOZ_ASSERT(ok,
|
||||
"This is quite odd. We should have crashed in the "
|
||||
"xpc::NativeGlobal() call if xpc::UnprivilegedJunkScope() "
|
||||
"returned null, and inited correctly otherwise!");
|
||||
}
|
||||
|
||||
ThreadsafeAutoSafeJSContext::ThreadsafeAutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
|
||||
|
||||
@@ -272,7 +272,7 @@ public:
|
||||
// process incremental, we allow consumers to opt-in to the new behavior
|
||||
// while keeping the old behavior as the default.
|
||||
void TakeOwnershipOfErrorReporting();
|
||||
bool OwnsErrorReporting() { return mOwnErrorReporting; }
|
||||
bool OwnsErrorReporting() { return true; }
|
||||
// If HasException, report it. Otherwise, a no-op. This must be
|
||||
// called only if OwnsErrorReporting().
|
||||
void ReportException();
|
||||
@@ -317,7 +317,6 @@ private:
|
||||
JSContext *mCx;
|
||||
|
||||
// Track state between the old and new error reporting modes.
|
||||
bool mOwnErrorReporting;
|
||||
bool mOldAutoJSAPIOwnsErrorReporting;
|
||||
// Whether we're mainthread or not; set when we're initialized.
|
||||
bool mIsMainThread;
|
||||
@@ -439,13 +438,6 @@ public:
|
||||
operator JSContext*() const;
|
||||
|
||||
protected:
|
||||
explicit AutoJSContext(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
// We need this Init() method because we can't use delegating constructor for
|
||||
// the moment. It is a C++11 feature and we do not require C++11 to be
|
||||
// supported to be able to compile Gecko.
|
||||
void Init(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
JSContext* mCx;
|
||||
dom::AutoJSAPI mJSAPI;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
@@ -473,11 +465,16 @@ private:
|
||||
*
|
||||
* Note - This is deprecated. Please use AutoJSAPI instead.
|
||||
*/
|
||||
class MOZ_RAII AutoSafeJSContext : public AutoJSContext {
|
||||
class MOZ_RAII AutoSafeJSContext : public dom::AutoJSAPI {
|
||||
public:
|
||||
explicit AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
|
||||
operator JSContext*() const
|
||||
{
|
||||
return cx();
|
||||
}
|
||||
|
||||
private:
|
||||
JSAutoCompartment mAc;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+88
-37
@@ -21,6 +21,7 @@
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
@@ -150,18 +151,11 @@ public:
|
||||
bool isBinary);
|
||||
|
||||
// ConnectionCloseEvents: 'error' event if needed, then 'close' event.
|
||||
// - These must not be dispatched while we are still within an incoming call
|
||||
// from JS (ex: close()). Set 'sync' to false in that case to dispatch in a
|
||||
// separate new event.
|
||||
nsresult ScheduleConnectionCloseEvents(nsISupports* aContext,
|
||||
nsresult aStatusCode,
|
||||
bool sync);
|
||||
// 2nd half of ScheduleConnectionCloseEvents, sometimes run in its own event.
|
||||
nsresult aStatusCode);
|
||||
// 2nd half of ScheduleConnectionCloseEvents, run in its own event.
|
||||
void DispatchConnectionCloseEvents();
|
||||
|
||||
// Dispatch a runnable to the right thread.
|
||||
nsresult DispatchRunnable(nsIRunnable* aRunnable);
|
||||
|
||||
nsresult UpdateURI();
|
||||
|
||||
void AddRefObject();
|
||||
@@ -520,14 +514,11 @@ WebSocketImpl::CloseConnection(uint16_t aReasonCode,
|
||||
|
||||
mWebSocket->SetReadyState(WebSocket::CLOSING);
|
||||
|
||||
// Can be called from Cancel() or Init() codepaths, so need to dispatch
|
||||
// onerror/onclose asynchronously
|
||||
ScheduleConnectionCloseEvents(
|
||||
nullptr,
|
||||
(aReasonCode == nsIWebSocketChannel::CLOSE_NORMAL ||
|
||||
aReasonCode == nsIWebSocketChannel::CLOSE_GOING_AWAY) ?
|
||||
NS_OK : NS_ERROR_FAILURE,
|
||||
false);
|
||||
NS_OK : NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -801,14 +792,12 @@ WebSocketImpl::OnStop(nsISupports* aContext, nsresult aStatusCode)
|
||||
MOZ_ASSERT(mWebSocket->ReadyState() != WebSocket::CLOSED,
|
||||
"Shouldn't already be CLOSED when OnStop called");
|
||||
|
||||
// called by network stack, not JS, so can dispatch JS events synchronously
|
||||
return ScheduleConnectionCloseEvents(aContext, aStatusCode, true);
|
||||
return ScheduleConnectionCloseEvents(aContext, aStatusCode);
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebSocketImpl::ScheduleConnectionCloseEvents(nsISupports* aContext,
|
||||
nsresult aStatusCode,
|
||||
bool sync)
|
||||
nsresult aStatusCode)
|
||||
{
|
||||
AssertIsOnTargetThread();
|
||||
|
||||
@@ -828,11 +817,7 @@ WebSocketImpl::ScheduleConnectionCloseEvents(nsISupports* aContext,
|
||||
|
||||
mOnCloseScheduled = true;
|
||||
|
||||
if (sync) {
|
||||
DispatchConnectionCloseEvents();
|
||||
} else {
|
||||
NS_DispatchToCurrentThread(new CallDispatchConnectionCloseEvents(this));
|
||||
}
|
||||
NS_DispatchToCurrentThread(new CallDispatchConnectionCloseEvents(this));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -1602,11 +1587,85 @@ WebSocketImpl::Init(JSContext* aCx,
|
||||
if (globalObject) {
|
||||
principal = globalObject->PrincipalOrNull();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> innerWindow;
|
||||
|
||||
while (true) {
|
||||
bool isNullPrincipal = true;
|
||||
if (principal) {
|
||||
nsresult rv = principal->GetIsNullPrincipal(&isNullPrincipal);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isNullPrincipal) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!innerWindow) {
|
||||
innerWindow = do_QueryInterface(globalObject);
|
||||
if (NS_WARN_IF(!innerWindow)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> parentWindow =
|
||||
innerWindow->GetScriptableParent();
|
||||
if (NS_WARN_IF(!parentWindow)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> currentInnerWindow =
|
||||
parentWindow->GetCurrentInnerWindow();
|
||||
if (NS_WARN_IF(!currentInnerWindow)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// We are at the top. Let's see if we have an opener window.
|
||||
if (innerWindow == currentInnerWindow) {
|
||||
ErrorResult error;
|
||||
parentWindow =
|
||||
nsGlobalWindow::Cast(innerWindow)->GetOpenerWindow(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
error.SuppressException();
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!parentWindow) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentInnerWindow = parentWindow->GetCurrentInnerWindow();
|
||||
if (NS_WARN_IF(!currentInnerWindow)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(currentInnerWindow != innerWindow);
|
||||
}
|
||||
|
||||
innerWindow = currentInnerWindow;
|
||||
|
||||
nsCOMPtr<nsIDocument> document = innerWindow->GetExtantDoc();
|
||||
if (NS_WARN_IF(!document)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
principal = document->NodePrincipal();
|
||||
}
|
||||
}
|
||||
|
||||
if (principal) {
|
||||
principal->GetURI(getter_AddRefs(originURI));
|
||||
}
|
||||
|
||||
if (originURI) {
|
||||
bool originIsHttps = false;
|
||||
aRv = originURI->SchemeIs("https", &originIsHttps);
|
||||
@@ -1832,16 +1891,8 @@ WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData,
|
||||
}
|
||||
}
|
||||
|
||||
return CreateAndDispatchMessageEvent(jsapi.cx(), aData, aIsBinary);
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
|
||||
const nsACString& aData,
|
||||
bool aIsBinary)
|
||||
{
|
||||
MOZ_ASSERT(mImpl);
|
||||
AssertIsOnTargetThread();
|
||||
jsapi.TakeOwnershipOfErrorReporting();
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1851,19 +1902,19 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
|
||||
uint16_t messageType = nsIWebSocketEventListener::TYPE_STRING;
|
||||
|
||||
// Create appropriate JS object for message
|
||||
JS::Rooted<JS::Value> jsData(aCx);
|
||||
JS::Rooted<JS::Value> jsData(cx);
|
||||
if (aIsBinary) {
|
||||
if (mBinaryType == dom::BinaryType::Blob) {
|
||||
messageType = nsIWebSocketEventListener::TYPE_BLOB;
|
||||
|
||||
nsresult rv = nsContentUtils::CreateBlobBuffer(aCx, GetOwner(), aData,
|
||||
nsresult rv = nsContentUtils::CreateBlobBuffer(cx, GetOwner(), aData,
|
||||
&jsData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (mBinaryType == dom::BinaryType::Arraybuffer) {
|
||||
messageType = nsIWebSocketEventListener::TYPE_ARRAYBUFFER;
|
||||
|
||||
JS::Rooted<JSObject*> arrayBuf(aCx);
|
||||
nsresult rv = nsContentUtils::CreateArrayBuffer(aCx, aData,
|
||||
JS::Rooted<JSObject*> arrayBuf(cx);
|
||||
nsresult rv = nsContentUtils::CreateArrayBuffer(cx, aData,
|
||||
arrayBuf.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
jsData.setObject(*arrayBuf);
|
||||
@@ -1875,7 +1926,7 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
|
||||
// JS string
|
||||
NS_ConvertUTF8toUTF16 utf16Data(aData);
|
||||
JSString* jsString;
|
||||
jsString = JS_NewUCStringCopyN(aCx, utf16Data.get(), utf16Data.Length());
|
||||
jsString = JS_NewUCStringCopyN(cx, utf16Data.get(), utf16Data.Length());
|
||||
NS_ENSURE_TRUE(jsString, NS_ERROR_FAILURE);
|
||||
|
||||
jsData.setString(jsString);
|
||||
|
||||
@@ -138,9 +138,6 @@ private: // constructor && distructor
|
||||
nsresult CreateAndDispatchSimpleEvent(const nsAString& aName);
|
||||
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
|
||||
bool aIsBinary);
|
||||
nsresult CreateAndDispatchMessageEvent(JSContext* aCx,
|
||||
const nsACString& aData,
|
||||
bool aIsBinary);
|
||||
nsresult CreateAndDispatchCloseEvent(bool aWasClean,
|
||||
uint16_t aCode,
|
||||
const nsAString& aReason);
|
||||
|
||||
@@ -853,10 +853,10 @@ public:
|
||||
protected:
|
||||
explicit nsGlobalWindow(nsGlobalWindow *aOuterWindow);
|
||||
nsPIDOMWindow* GetOpenerWindowOuter();
|
||||
nsPIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
|
||||
// Initializes the mWasOffline member variable
|
||||
void InitWasOffline();
|
||||
public:
|
||||
nsPIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
|
||||
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
|
||||
mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsPIDOMWindow> GetOpener() override;
|
||||
|
||||
@@ -198,13 +198,6 @@ DeviceStorageStatics::InitDirs()
|
||||
NS_NewLocalFile(path, /* aFollowLinks */ true,
|
||||
getter_AddRefs(mDirs[TYPE_SDCARD]));
|
||||
}
|
||||
#ifdef MOZ_B2GDROID
|
||||
if (NS_SUCCEEDED(mozilla::AndroidBridge::GetExternalPublicDirectory(
|
||||
NS_LITERAL_STRING(DEVICESTORAGE_APPS), path))) {
|
||||
NS_NewLocalFile(path, /* aFollowLinks */ true,
|
||||
getter_AddRefs(mDirs[TYPE_APPS]));
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined (XP_UNIX)
|
||||
dirService->Get(NS_UNIX_XDG_PICTURES_DIR,
|
||||
@@ -239,10 +232,8 @@ DeviceStorageStatics::InitDirs()
|
||||
}
|
||||
#endif // !MOZ_WIDGET_ANDROID
|
||||
|
||||
#ifndef MOZ_B2GDROID
|
||||
dirService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(mDirs[TYPE_APPS]));
|
||||
#endif
|
||||
|
||||
if (mDirs[TYPE_APPS]) {
|
||||
mDirs[TYPE_APPS]->AppendRelativeNativePath(NS_LITERAL_CSTRING("webapps"));
|
||||
|
||||
@@ -28,6 +28,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "checkRenamed",
|
||||
"resource://gre/modules/identity/IdentityUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "objectCopy",
|
||||
"resource://gre/modules/identity/IdentityUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "makeMessageObject",
|
||||
"resource://gre/modules/identity/IdentityUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
"@mozilla.org/uuid-generator;1",
|
||||
@@ -639,7 +641,7 @@ nsDOMIdentity.prototype = {
|
||||
|
||||
this._log("DOMIdentityMessage: " + JSON.stringify(message));
|
||||
|
||||
return message;
|
||||
return makeMessageObject(message);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -727,25 +727,17 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
}
|
||||
|
||||
AutoJSAPI autoJS;
|
||||
RefPtr<IDBOpenDBRequest> request;
|
||||
|
||||
if (mWindow) {
|
||||
AutoJSContext cx;
|
||||
if (NS_WARN_IF(!autoJS.Init(mWindow, cx))) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> scriptOwner(cx,
|
||||
static_cast<nsGlobalWindow*>(mWindow.get())->FastGetGlobalJSObject());
|
||||
JS::Rooted<JSObject*> scriptOwner(nsContentUtils::RootingCxForThread(),
|
||||
nsGlobalWindow::Cast(mWindow.get())->FastGetGlobalJSObject());
|
||||
MOZ_ASSERT(scriptOwner);
|
||||
|
||||
request = IDBOpenDBRequest::CreateForWindow(this, mWindow, scriptOwner);
|
||||
} else {
|
||||
autoJS.Init(mOwningObject.get());
|
||||
JS::Rooted<JSObject*> scriptOwner(autoJS.cx(), mOwningObject);
|
||||
JS::Rooted<JSObject*> scriptOwner(nsContentUtils::RootingCxForThread(),
|
||||
mOwningObject);
|
||||
|
||||
request = IDBOpenDBRequest::CreateForJS(this, scriptOwner);
|
||||
if (!request) {
|
||||
|
||||
@@ -9,6 +9,9 @@ support-files =
|
||||
worker_bug1004814.js
|
||||
geo_leak_test.html
|
||||
|
||||
[browser_test_toolbars_visibility.js]
|
||||
support-files =
|
||||
test_new_window_from_content_child.html
|
||||
[browser_bug1008941_dismissGeolocationHanger.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_test__content.js]
|
||||
@@ -28,7 +31,6 @@ skip-if= buildapp == 'mulet'
|
||||
skip-if = (toolkit == 'android' || buildapp == 'b2g' || buildapp == 'mulet')
|
||||
support-files =
|
||||
test_new_window_from_content_child.html
|
||||
test_new_window_from_content_child.js
|
||||
[browser_webapps_permissions.js]
|
||||
# TODO: Re-enable permissions tests on Mac, bug 795334
|
||||
skip-if = buildapp != "b2g"
|
||||
|
||||
@@ -35,10 +35,7 @@
|
||||
each preference.
|
||||
*/
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const kContentDoc = "http://www.example.com/browser/dom/tests/browser/test_new_window_from_content_child.html";
|
||||
@@ -91,117 +88,8 @@ registerCleanupFunction(function() {
|
||||
Services.prefs.setIntPref(kNewWindowPrefKey, originalNewWindowPref);
|
||||
Services.prefs.setIntPref(kNewWindowRestrictionPrefKey,
|
||||
originalNewWindowRestrictionPref);
|
||||
// If there are any content tabs leftover, make sure they're not going to
|
||||
// block exiting with onbeforeunload.
|
||||
for (let tab of gBrowser.tabs) {
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
if (browser.contentDocument.location == kContentDoc) {
|
||||
closeTab(tab);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* WindowOpenListener is a very simple nsIWindowMediatorListener that
|
||||
* listens for a new window opening to aExpectedURI. It has two Promises
|
||||
* attached to it - openPromise and closePromise. As you'd expect,
|
||||
* openPromise resolves when the window is opened, and closePromise
|
||||
* resolves if and when a window with the same URI closes. There is
|
||||
* no attempt to make sure that it's the same window opening and
|
||||
* closing - we just use the URI.
|
||||
*
|
||||
* @param aExpectedURI the URI to watch for in a new window.
|
||||
* @return nsIWindowMediatorListener
|
||||
*/
|
||||
function WindowOpenListener(aExpectedURI) {
|
||||
this._openDeferred = Promise.defer();
|
||||
this._closeDeferred = Promise.defer();
|
||||
this._expectedURI = aExpectedURI;
|
||||
}
|
||||
|
||||
WindowOpenListener.prototype = {
|
||||
get openPromise() {
|
||||
return this._openDeferred.promise;
|
||||
},
|
||||
|
||||
get closePromise() {
|
||||
return this._closeDeferred.promise;
|
||||
},
|
||||
|
||||
onOpenWindow: function(aXULWindow) {
|
||||
let domWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
let location = domWindow.document.location;
|
||||
if (location == this._expectedURI) {
|
||||
let deferred = this._openDeferred;
|
||||
domWindow.addEventListener("load", function onWindowLoad() {
|
||||
domWindow.removeEventListener("load", onWindowLoad);
|
||||
deferred.resolve(domWindow);
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onCloseWindow: function(aXULWindow) {
|
||||
this._closeDeferred.resolve();
|
||||
},
|
||||
onWindowTitleChange: function(aXULWindow, aNewTitle) {},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowMediatorListener])
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the testing tab, and injects our frame script which
|
||||
* allows us to send click events to links and other things.
|
||||
*
|
||||
* @return a Promise that resolves once the tab is loaded and ready.
|
||||
*/
|
||||
function loadAndSelectTestTab() {
|
||||
let tab = gBrowser.addTab(kContentDoc);
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
browser.messageManager.loadFrameScript(kContentScript, false);
|
||||
|
||||
let deferred = Promise.defer();
|
||||
browser.addEventListener("DOMContentLoaded", function onBrowserLoad(aEvent) {
|
||||
browser.removeEventListener("DOMContentLoaded", onBrowserLoad);
|
||||
deferred.resolve(tab);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the onbeforeunload event handler from the testing tab,
|
||||
* and then closes the tab.
|
||||
*
|
||||
* @param aTab the testing tab to close.
|
||||
* @param a Promise that resolves once the tab has been closed.
|
||||
*/
|
||||
function closeTab(aTab) {
|
||||
let deferred = Promise.defer();
|
||||
let browserMM = gBrowser.getBrowserForTab(aTab).messageManager;
|
||||
browserMM.sendAsyncMessage("TEST:allow-unload");
|
||||
browserMM.addMessageListener("TEST:allow-unload:done", function(aMessage) {
|
||||
gBrowser.removeTab(aTab);
|
||||
deferred.resolve();
|
||||
})
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a click event on some item into a tab.
|
||||
*
|
||||
* @param aTab the tab to send the click event to
|
||||
* @param aItemId the item within the tab content to click.
|
||||
*/
|
||||
function clickInTab(aTab, aItemId) {
|
||||
let browserMM = gBrowser.getBrowserForTab(aTab).messageManager;
|
||||
browserMM.sendAsyncMessage("TEST:click-item", {
|
||||
details: aItemId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* For some expectation when a link is clicked, creates and
|
||||
* returns a Promise that resolves when that expectation is
|
||||
@@ -213,62 +101,38 @@ function clickInTab(aTab, aItemId) {
|
||||
* occurred - for example, if a new window was opened, this function
|
||||
* closes it before resolving.
|
||||
*
|
||||
* @param aTab the tab with the test document
|
||||
* @param aBrowser the <xul:browser> with the test document
|
||||
* @param aExpectation one of kSameTab, kNewWin, or kNewTab.
|
||||
* @return a Promise that resolves when the expectation is fulfilled,
|
||||
* and cleaned up after.
|
||||
*/
|
||||
function prepareForResult(aTab, aExpectation) {
|
||||
let deferred = Promise.defer();
|
||||
let browser = gBrowser.getBrowserForTab(aTab);
|
||||
|
||||
function prepareForResult(aBrowser, aExpectation) {
|
||||
switch(aExpectation) {
|
||||
case kSameTab:
|
||||
// We expect about:blank to be loaded in the current tab. In order
|
||||
// to prevent us needing to reload the document and content script
|
||||
// after browsing away, we'll detect the attempt by using onbeforeunload,
|
||||
// and then cancel the unload. It's a hack, but it's also a pretty
|
||||
// cheap way of detecting when we're browsing away in the test tab.
|
||||
// The onbeforeunload event handler is set in the content script automatically.
|
||||
browser.addEventListener("DOMWillOpenModalDialog", function onModalDialog() {
|
||||
browser.removeEventListener("DOMWillOpenModalDialog", onModalDialog, true);
|
||||
executeSoon(() => {
|
||||
let stack = browser.parentNode;
|
||||
let dialogs = stack.getElementsByTagNameNS(kXULNS, "tabmodalprompt");
|
||||
dialogs[0].ui.button1.click()
|
||||
deferred.resolve();
|
||||
})
|
||||
}, true);
|
||||
return Task.spawn(function*() {
|
||||
yield BrowserTestUtils.browserLoaded(aBrowser);
|
||||
is(aBrowser.currentURI.spec, "about:robots", "Should be at about:robots");
|
||||
// Now put the browser back where it came from
|
||||
yield BrowserTestUtils.loadURI(aBrowser, kContentDoc);
|
||||
yield BrowserTestUtils.browserLoaded(aBrowser);
|
||||
});
|
||||
break;
|
||||
case kNewWin:
|
||||
let listener = new WindowOpenListener("about:blank");
|
||||
Services.wm.addListener(listener);
|
||||
|
||||
info("Waiting for a new about:blank window");
|
||||
listener.openPromise.then(function(aWindow) {
|
||||
info("Got the new about:blank window - closing it.");
|
||||
executeSoon(() => {
|
||||
aWindow.close();
|
||||
});
|
||||
listener.closePromise.then(() => {
|
||||
info("New about:blank window closed!");
|
||||
Services.wm.removeListener(listener);
|
||||
deferred.resolve();
|
||||
});
|
||||
return Task.spawn(function*() {
|
||||
let newWin = yield BrowserTestUtils.waitForNewWindow();
|
||||
let newBrowser = newWin.gBrowser.selectedBrowser;
|
||||
yield BrowserTestUtils.browserLoaded(newBrowser);
|
||||
is(newBrowser.currentURI.spec, "about:robots", "Should be at about:robots");
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
});
|
||||
break;
|
||||
case kNewTab:
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", function onTabOpen(aEvent) {
|
||||
let newTab = aEvent.target;
|
||||
let newBrowser = gBrowser.getBrowserForTab(newTab);
|
||||
if (newBrowser.contentDocument.location.href == "about:blank") {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen);
|
||||
executeSoon(() => {
|
||||
gBrowser.removeTab(newTab);
|
||||
deferred.resolve();
|
||||
})
|
||||
}
|
||||
})
|
||||
return Task.spawn(function*() {
|
||||
let newTab = yield BrowserTestUtils.waitForNewTab(gBrowser);
|
||||
is(newTab.linkedBrowser.currentURI.spec, "about:robots",
|
||||
"Should be at about:robots");
|
||||
yield BrowserTestUtils.removeTab(newTab);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
ok(false, "prepareForResult can't handle an expectation of " + aExpectation)
|
||||
@@ -283,14 +147,16 @@ function prepareForResult(aTab, aExpectation) {
|
||||
* perform as specified in the supplied aMatrix (kWinOpenDefault,
|
||||
* for example).
|
||||
*
|
||||
* @param aLinkId the id of the link within the testing page to test.
|
||||
* @param aLinkSelector a selector for the link within the testing page to click.
|
||||
* @param aMatrix a testing matrix for the
|
||||
* browser.link.open_newwindow and browser.link.open_newwindow.restriction
|
||||
* prefs to test against. See kWinOpenDefault for an example.
|
||||
*/
|
||||
function testLinkWithMatrix(aLinkId, aMatrix) {
|
||||
return Task.spawn(function* () {
|
||||
let tab = yield loadAndSelectTestTab();
|
||||
function testLinkWithMatrix(aLinkSelector, aMatrix) {
|
||||
return BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: kContentDoc,
|
||||
}, function*(browser) {
|
||||
// This nested for-loop is unravelling the matrix const
|
||||
// we set up, and gives us three things through each tick
|
||||
// of the inner loop:
|
||||
@@ -298,7 +164,6 @@ function testLinkWithMatrix(aLinkId, aMatrix) {
|
||||
// 2) newWindowRestPref: a browser.link.open_newwindow.restriction pref to try
|
||||
// 3) expectation: what we expect the click outcome on this link to be,
|
||||
// which will either be kSameTab, kNewWin or kNewTab.
|
||||
|
||||
for (let newWindowPref in aMatrix) {
|
||||
let expectations = aMatrix[newWindowPref];
|
||||
for (let i = 0; i < expectations.length; ++i) {
|
||||
@@ -307,28 +172,31 @@ function testLinkWithMatrix(aLinkId, aMatrix) {
|
||||
|
||||
Services.prefs.setIntPref("browser.link.open_newwindow", newWindowPref);
|
||||
Services.prefs.setIntPref("browser.link.open_newwindow.restriction", newWindowRestPref);
|
||||
info("Clicking on " + aLinkId);
|
||||
info("Clicking on " + aLinkSelector);
|
||||
info("Testing with browser.link.open_newwindow = " + newWindowPref + " and " +
|
||||
"browser.link.open_newwindow.restriction = " + newWindowRestPref);
|
||||
info("Expecting: " + expectation);
|
||||
let resultPromise = prepareForResult(tab, expectation);
|
||||
clickInTab(tab, aLinkId);
|
||||
let resultPromise = prepareForResult(browser, expectation);
|
||||
BrowserTestUtils.synthesizeMouseAtCenter(aLinkSelector, {}, browser);
|
||||
yield resultPromise;
|
||||
ok(true, "Got expectation: " + expectation);
|
||||
info("Got expectation: " + expectation);
|
||||
}
|
||||
}
|
||||
yield closeTab(tab);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* test_window_open_with_defaults() {
|
||||
yield testLinkWithMatrix("winOpenDefault", kWinOpenDefault);
|
||||
yield testLinkWithMatrix("#winOpenDefault", kWinOpenDefault);
|
||||
});
|
||||
|
||||
add_task(function* test_window_open_with_non_defaults() {
|
||||
yield testLinkWithMatrix("winOpenNonDefault", kWinOpenNonDefault);
|
||||
yield testLinkWithMatrix("#winOpenNonDefault", kWinOpenNonDefault);
|
||||
});
|
||||
|
||||
add_task(function* test_window_open_dialog() {
|
||||
yield testLinkWithMatrix("#winOpenDialog", kWinOpenNonDefault);
|
||||
});
|
||||
|
||||
add_task(function* test_target__blank() {
|
||||
yield testLinkWithMatrix("targetBlank", kTargetBlank);
|
||||
yield testLinkWithMatrix("#targetBlank", kTargetBlank);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
// Tests that toolbars have proper visibility when opening a new window
|
||||
// in either content or chrome context.
|
||||
|
||||
const CONTENT_PAGE = "http://www.example.com/browser/dom/tests/browser/test_new_window_from_content_child.html";
|
||||
|
||||
/**
|
||||
* This function retrieves the visibility state of the toolbars of a
|
||||
* window within the content context.
|
||||
*
|
||||
* @param aBrowser (<xul:browser>)
|
||||
* The browser to query for toolbar visibility states
|
||||
* @returns Promise
|
||||
* A promise that resolves when the toolbar state is retrieved
|
||||
* within the content context, which value is an object that holds
|
||||
* the visibility state of the toolbars
|
||||
*/
|
||||
function getToolbarsFromBrowserContent(aBrowser) {
|
||||
return ContentTask.spawn(aBrowser, {}, function*() {
|
||||
return {
|
||||
toolbar: content.toolbar.visible,
|
||||
menubar: content.menubar.visible,
|
||||
personalbar: content.personalbar.visible,
|
||||
statusbar: content.statusbar.visible,
|
||||
locationbar: content.locationbar.visible,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function retrieves the visibility state of the toolbars of a
|
||||
* window within the chrome context.
|
||||
*
|
||||
* @param win
|
||||
* the chrome privileged window
|
||||
* @returns object
|
||||
* an object that holds the visibility state of the toolbars
|
||||
*/
|
||||
function getToolbarsFromWindowChrome(win) {
|
||||
return {
|
||||
toolbar: win.toolbar.visible,
|
||||
menubar: win.menubar.visible,
|
||||
personalbar: win.personalbar.visible,
|
||||
statusbar: win.statusbar.visible,
|
||||
locationbar: win.locationbar.visible,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests toolbar visibility when opening a window with default parameters.
|
||||
*
|
||||
* @param toolbars
|
||||
* the visibility state of the toolbar elements
|
||||
*/
|
||||
function testDefaultToolbars(toolbars) {
|
||||
ok(toolbars.locationbar,
|
||||
"locationbar should be visible on default window.open()");
|
||||
ok(toolbars.menubar,
|
||||
"menubar be visible on default window.open()");
|
||||
ok(toolbars.personalbar,
|
||||
"personalbar should be visible on default window.open()");
|
||||
ok(toolbars.statusbar,
|
||||
"statusbar should be visible on default window.open()");
|
||||
ok(toolbars.toolbar,
|
||||
"toolbar should be visible on default window.open()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests toolbar visibility when opening a window with non default parameters
|
||||
* on the content context.
|
||||
*
|
||||
* Ensure that locationbar can't be hidden in the content context, see bug#337344.
|
||||
*
|
||||
* @param toolbars
|
||||
* the visibility state of the toolbar elements
|
||||
*/
|
||||
function testNonDefaultContentToolbars(toolbars) {
|
||||
// Locationbar should always be visible on content context
|
||||
ok(toolbars.locationbar,
|
||||
"locationbar should be visible even with location=no");
|
||||
ok(!toolbars.menubar,
|
||||
"menubar shouldn't be visible when menubar=no");
|
||||
ok(!toolbars.personalbar,
|
||||
"personalbar shouldn't be visible when personalbar=no");
|
||||
// statusbar will report visible=true even when it's hidden because of bug#55820
|
||||
todo(!toolbars.statusbar,
|
||||
"statusbar shouldn't be visible when status=no");
|
||||
ok(!toolbars.toolbar,
|
||||
"toolbar shouldn't be visible when toolbar=no");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests toolbar visibility when opening a window with non default parameters
|
||||
* on the chrome context.
|
||||
*
|
||||
* @param toolbars
|
||||
* the visibility state of the toolbar elements
|
||||
*/
|
||||
function testNonDefaultChromeToolbars(toolbars) {
|
||||
// None of the toolbars should be visible if hidden with chrome privileges
|
||||
ok(!toolbars.locationbar,
|
||||
"locationbar should be visible on default window.open()");
|
||||
ok(!toolbars.menubar,
|
||||
"menubar be visible on default window.open()");
|
||||
ok(!toolbars.personalbar,
|
||||
"personalbar should be visible on default window.open()");
|
||||
ok(!toolbars.statusbar,
|
||||
"statusbar should be visible on default window.open()");
|
||||
ok(!toolbars.toolbar,
|
||||
"toolbar should be visible on default window.open()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that toolbars of a window opened in the content context have the
|
||||
* correct visibility.
|
||||
*
|
||||
* A window opened with default parameters should have all toolbars visible.
|
||||
*
|
||||
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
|
||||
* menubar=no, status=no", should only have location visible.
|
||||
*/
|
||||
add_task(function*() {
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: CONTENT_PAGE,
|
||||
}, function*(browser) {
|
||||
// First, call the default window.open() which will open a new tab
|
||||
let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
|
||||
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenDefault", {}, browser);
|
||||
let tab = yield newTabPromise;
|
||||
|
||||
// Check that all toolbars are visible
|
||||
let toolbars = yield getToolbarsFromBrowserContent(gBrowser.selectedBrowser);
|
||||
testDefaultToolbars(toolbars);
|
||||
|
||||
// Cleanup
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
|
||||
// Now let's open a window with toolbars hidden
|
||||
let winPromise = BrowserTestUtils.waitForNewWindow();
|
||||
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenNonDefault", {}, browser);
|
||||
let popupWindow = yield winPromise;
|
||||
|
||||
let popupBrowser = popupWindow.gBrowser.selectedBrowser;
|
||||
yield BrowserTestUtils.browserLoaded(popupBrowser);
|
||||
|
||||
// Test toolbars visibility
|
||||
let popupToolbars = yield getToolbarsFromBrowserContent(popupBrowser);
|
||||
testNonDefaultContentToolbars(popupToolbars);
|
||||
|
||||
// Cleanup
|
||||
yield BrowserTestUtils.closeWindow(popupWindow);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Ensure that toolbars of a window opened in the chrome context have the
|
||||
* correct visibility.
|
||||
*
|
||||
* A window opened with default parameters should have all toolbars visible.
|
||||
*
|
||||
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
|
||||
* menubar=no, status=no", should not have any toolbar visible.
|
||||
*/
|
||||
add_task(function* () {
|
||||
// First open a default window from this chrome context
|
||||
let defaultWindowPromise = BrowserTestUtils.waitForNewWindow();
|
||||
window.open("about:robots", "_blank");
|
||||
let defaultWindow = yield defaultWindowPromise;
|
||||
|
||||
// Check that all toolbars are visible
|
||||
let toolbars = getToolbarsFromWindowChrome(defaultWindow);
|
||||
testDefaultToolbars(toolbars);
|
||||
|
||||
// Now lets open a window with toolbars hidden from this chrome context
|
||||
let features = "location=no, personalbar=no, toolbar=no, scrollbars=no, menubar=no, status=no";
|
||||
let popupWindowPromise = BrowserTestUtils.waitForNewWindow();
|
||||
window.open("about:robots", "_blank", features);
|
||||
let popupWindow = yield popupWindowPromise;
|
||||
|
||||
// Test none of the tooolbars are visible
|
||||
let hiddenToolbars = getToolbarsFromWindowChrome(popupWindow);
|
||||
testNonDefaultChromeToolbars(hiddenToolbars);
|
||||
|
||||
// Cleanup
|
||||
yield BrowserTestUtils.closeWindow(defaultWindow);
|
||||
yield BrowserTestUtils.closeWindow(popupWindow);
|
||||
});
|
||||
@@ -5,19 +5,15 @@
|
||||
</head>
|
||||
<body>
|
||||
<p><a id="winOpenDefault" href="#" onclick="return openWindow();">Open a new window via window.open with default features.</a></p>
|
||||
<p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p>
|
||||
<p><a id="targetBlank" href="about:blank" target="_blank">Open a new window via target="_blank".</a></p>
|
||||
<p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, location=no, personalbar=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p>
|
||||
<p><a id="winOpenDialog" href="#" onclick="return openWindow('dialog=yes');">Open a new window via window.open with dialog=1.</a></p>
|
||||
<p><a id="targetBlank" href="about:robots" target="_blank">Open a new window via target="_blank".</a></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
function openWindow(aFeatures="") {
|
||||
window.open("about:blank", "_blank", aFeatures);
|
||||
window.open("about:robots", "_blank", aFeatures);
|
||||
return false;
|
||||
}
|
||||
|
||||
window.onbeforeunload = function(aEvent) {
|
||||
return "We should not browse away from this document.";
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// A hacky mechanism for catching and detecting that we're attempting
|
||||
// to browse away is by setting the onbeforeunload event handler. We
|
||||
// detect this dialog opening in the parent test script, and dismiss
|
||||
// it.
|
||||
|
||||
function handleClickItem(aMessage) {
|
||||
let itemId = aMessage.data.details;
|
||||
content.console.log("Getting item with ID: " + itemId);
|
||||
let item = content.document.getElementById(itemId);
|
||||
item.click();
|
||||
}
|
||||
|
||||
function handleAllowUnload(aMessage) {
|
||||
content.onbeforeunload = null;
|
||||
sendSyncMessage("TEST:allow-unload:done");
|
||||
}
|
||||
|
||||
addMessageListener("TEST:click-item", handleClickItem);
|
||||
addMessageListener("TEST:allow-unload", handleAllowUnload);
|
||||
@@ -297,7 +297,7 @@ mozJSComponentLoader::ReallyInit()
|
||||
// results in getting the wrong value.
|
||||
// But we don't want that on Firefox Mulet as it break most Firefox JSMs...
|
||||
// Also disable on debug builds to break js components that rely on this.
|
||||
#if defined(MOZ_B2G) && !defined(MOZ_MULET) && !defined(MOZ_B2GDROID) && !defined(DEBUG)
|
||||
#if defined(MOZ_B2G) && !defined(MOZ_MULET) && !defined(DEBUG)
|
||||
mReuseLoaderGlobal = true;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1199,17 +1199,11 @@ InitSystemMetrics()
|
||||
sSystemMetrics->AppendElement(nsGkAtoms::swipe_animation_enabled);
|
||||
}
|
||||
|
||||
// On b2gdroid, make it so that we always have a physical home button from
|
||||
// gecko's point of view, event if it's just the Android home button remapped.
|
||||
#ifdef MOZ_B2GDROID
|
||||
sSystemMetrics->AppendElement(nsGkAtoms::physical_home_button);
|
||||
#else
|
||||
rv = LookAndFeel::GetInt(LookAndFeel::eIntID_PhysicalHomeButton,
|
||||
&metricResult);
|
||||
if (NS_SUCCEEDED(rv) && metricResult) {
|
||||
sSystemMetrics->AppendElement(nsGkAtoms::physical_home_button);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (NS_SUCCEEDED(
|
||||
|
||||
@@ -2854,18 +2854,15 @@ WebSocketChannel::StartWebsocketData()
|
||||
mDataStarted = 1;
|
||||
}
|
||||
|
||||
LOG(("WebSocketChannel::StartWebsocketData Notifying Listener %p\n",
|
||||
mListenerMT ? mListenerMT->mListener.get() : nullptr));
|
||||
|
||||
if (mListenerMT) {
|
||||
mListenerMT->mListener->OnStart(mListenerMT->mContext);
|
||||
}
|
||||
|
||||
rv = mSocketIn->AsyncWait(this, 0, 0, mSocketThread);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocketChannel::StartWebsocketData mSocketIn->AsyncWait() failed "
|
||||
"with error %0x%08x\n", rv));
|
||||
return rv;
|
||||
"with error 0x%08x", rv));
|
||||
return mSocketThread->Dispatch(
|
||||
NS_NewRunnableMethodWithArgs<nsresult>(this,
|
||||
&WebSocketChannel::AbortSession,
|
||||
rv),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
if (mPingInterval) {
|
||||
@@ -2873,10 +2870,19 @@ WebSocketChannel::StartWebsocketData()
|
||||
NS_NewRunnableMethod(this, &WebSocketChannel::StartPinging),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocketChannel::StartWebsocketData Could not start pinging, "
|
||||
"rv=0x%08x", rv));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(("WebSocketChannel::StartWebsocketData Notifying Listener %p",
|
||||
mListenerMT ? mListenerMT->mListener.get() : nullptr));
|
||||
|
||||
if (mListenerMT) {
|
||||
mListenerMT->mListener->OnStart(mListenerMT->mContext);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
-r mozbase_requirements.txt
|
||||
../tools/wptserve
|
||||
../marionette/transport
|
||||
../marionette/driver
|
||||
../marionette/marionette/runner/mixins/browsermob-proxy-py
|
||||
../marionette
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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/.
|
||||
|
||||
__version__ = '2.0.0'
|
||||
__version__ = '2.2.0'
|
||||
|
||||
from .marionette_test import (
|
||||
CommonTestCase,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from marionette import MarionetteTestCase
|
||||
from marionette_driver.addons import Addons, AddonInstallException
|
||||
@@ -14,7 +15,6 @@ class TestAddons(MarionetteTestCase):
|
||||
def setUp(self):
|
||||
MarionetteTestCase.setUp(self)
|
||||
self.addons = Addons(self.marionette)
|
||||
self.addon_path = os.path.join(here, 'mn-restartless.xpi')
|
||||
|
||||
|
||||
@property
|
||||
@@ -32,19 +32,27 @@ class TestAddons(MarionetteTestCase):
|
||||
|
||||
return addons
|
||||
|
||||
def test_install_and_remove_unsigned_addon(self):
|
||||
self.addons.signature_required = False
|
||||
def test_install_and_remove_temporary_unsigned_addon(self):
|
||||
addon_path = os.path.join(here, 'mn-restartless-unsigned.xpi')
|
||||
|
||||
addon_id = self.addons.install(self.addon_path)
|
||||
addon_id = self.addons.install(addon_path, temp=True)
|
||||
self.assertIn(addon_id, self.all_addon_ids)
|
||||
|
||||
self.addons.uninstall(addon_id)
|
||||
self.assertNotIn(addon_id, self.all_addon_ids)
|
||||
|
||||
self.addons.signature_required = True
|
||||
|
||||
def test_install_unsigned_addon_with_signature_required(self):
|
||||
self.signature_required = True
|
||||
def test_install_unsigned_addon(self):
|
||||
addon_path = os.path.join(here, 'mn-restartless-unsigned.xpi')
|
||||
|
||||
with self.assertRaises(AddonInstallException):
|
||||
self.addons.install(self.addon_path)
|
||||
self.addons.install(addon_path)
|
||||
|
||||
@unittest.skip("need to get the test extension signed")
|
||||
def test_install_and_remove_signed_addon(self):
|
||||
addon_path = os.path.join(here, 'mn-restartless-signed.xpi')
|
||||
|
||||
addon_id = self.addons.install(addon_path)
|
||||
self.assertIn(addon_id, self.all_addon_ids)
|
||||
|
||||
self.addons.uninstall(addon_id)
|
||||
self.assertNotIn(addon_id, self.all_addon_ids)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
marionette-driver >= 1.1.1
|
||||
marionette-driver >= 1.3.0
|
||||
browsermob-proxy >= 0.6.0
|
||||
manifestparser >= 1.1
|
||||
wptserve >= 1.3.0
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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/.
|
||||
|
||||
__version__ = '1.1.1'
|
||||
__version__ = '1.3.0'
|
||||
|
||||
from marionette_driver import (
|
||||
addons,
|
||||
|
||||
@@ -37,25 +37,8 @@ class Addons(object):
|
||||
|
||||
def __init__(self, marionette):
|
||||
self._mn = marionette
|
||||
self._signature_required = True
|
||||
|
||||
def on_restart():
|
||||
self.signature_required = self._signature_required
|
||||
self._mn.restart_handlers.append(on_restart)
|
||||
|
||||
@property
|
||||
def signature_required(self):
|
||||
"""
|
||||
Whether or not addons must be signed.
|
||||
"""
|
||||
return self._signature_required
|
||||
|
||||
@signature_required.setter
|
||||
def signature_required(self, val):
|
||||
self._mn.set_pref('xpinstall.signatures.required', val)
|
||||
self._signature_required = val
|
||||
|
||||
def install(self, path):
|
||||
def install(self, path, temp=False):
|
||||
"""Install an addon.
|
||||
|
||||
If the addon is restartless, it can be used right away. Otherwise
|
||||
@@ -63,6 +46,9 @@ class Addons(object):
|
||||
will be needed.
|
||||
|
||||
:param path: A file path to the extension to be installed.
|
||||
:param temp: Install a temporary addon. Temporary addons will
|
||||
automatically be uninstalled on shutdown and do not need
|
||||
to be signed, though they must be restartless.
|
||||
:returns: The addon ID string of the newly installed addon.
|
||||
:raises: :exc:`AddonInstallException`
|
||||
"""
|
||||
@@ -77,18 +63,29 @@ class Addons(object):
|
||||
|
||||
onInstallFailed: function(install) {
|
||||
marionetteScriptFinished([null, install.error]);
|
||||
},
|
||||
|
||||
onInstalled: function(addon) {
|
||||
marionetteScriptFinished([addon.id, 0]);
|
||||
}
|
||||
}
|
||||
|
||||
let file = new FileUtils.File(arguments[0]);
|
||||
AddonManager.getInstallForFile(file, function(aInstall) {
|
||||
if (aInstall.error != 0) {
|
||||
marionetteScriptFinished([null, aInstall.error]);
|
||||
}
|
||||
aInstall.addListener(listener);
|
||||
aInstall.install();
|
||||
});
|
||||
""", script_args=[path], debug_script=True)
|
||||
let temp = arguments[1];
|
||||
|
||||
if (!temp) {
|
||||
AddonManager.getInstallForFile(file, function(aInstall) {
|
||||
if (aInstall.error != 0) {
|
||||
marionetteScriptFinished([null, aInstall.error]);
|
||||
}
|
||||
aInstall.addListener(listener);
|
||||
aInstall.install();
|
||||
});
|
||||
} else {
|
||||
AddonManager.addAddonListener(listener);
|
||||
AddonManager.installTemporaryAddon(file);
|
||||
}
|
||||
""", script_args=[path, temp], debug_script=True)
|
||||
|
||||
if status:
|
||||
if status in ADDON_INSTALL_ERRORS:
|
||||
|
||||
@@ -15,12 +15,12 @@ from contextlib import contextmanager
|
||||
|
||||
from decorators import do_crash_check
|
||||
from keys import Keys
|
||||
import marionette_transport as transport
|
||||
|
||||
from mozrunner import B2GEmulatorRunner
|
||||
|
||||
import geckoinstance
|
||||
import errors
|
||||
import transport
|
||||
|
||||
WEBELEMENT_KEY = "ELEMENT"
|
||||
W3C_WEBELEMENT_KEY = "element-6066-11e4-a52e-4f735466cecf"
|
||||
@@ -563,7 +563,6 @@ class Marionette(object):
|
||||
self.device_serial = device_serial
|
||||
self.adb_host = adb_host
|
||||
self.adb_port = adb_port
|
||||
self.restart_handlers = []
|
||||
|
||||
startup_timeout = startup_timeout or self.DEFAULT_STARTUP_TIMEOUT
|
||||
|
||||
@@ -1111,11 +1110,6 @@ class Marionette(object):
|
||||
self.start_session(session_id=self.session_id)
|
||||
self._reset_timeouts()
|
||||
|
||||
# Give consumers who depended on the old session a
|
||||
# chance to re-initialize and/or restore state.
|
||||
for handler in self.restart_handlers:
|
||||
handler()
|
||||
|
||||
def absolute_url(self, relative_url):
|
||||
'''
|
||||
Returns an absolute url for files served from Marionette's www directory.
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
marionette-transport == 1.0.0
|
||||
mozrunner >= 6.9
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
__version__ = '1.0.0'
|
||||
|
||||
from transport import *
|
||||
@@ -1,53 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
import re
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
THIS_DIR = os.path.dirname(os.path.realpath(__name__))
|
||||
|
||||
|
||||
def read(*parts):
|
||||
with open(os.path.join(THIS_DIR, *parts)) as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def get_version():
|
||||
return re.findall("__version__ = '([\d\.]+)'",
|
||||
read('marionette_transport', '__init__.py'), re.M)[0]
|
||||
|
||||
|
||||
long_description = \
|
||||
"""Marionette_ is a Mozilla project to enable remote automation in Gecko-based
|
||||
projects, including desktop Firefox, mobile Firefox, and Firefox OS. It is
|
||||
inspired by `Selenium Webdriver`_.
|
||||
|
||||
This package defines the transport layer used by a Marionette client to
|
||||
communicate with the Marionette server embedded in Gecko. It has no entry
|
||||
points; rather it's designed to be used by a Marionette client implementation.
|
||||
|
||||
.. _Marionette: https://developer.mozilla.org/en/Marionette
|
||||
.. _`Selenium Webdriver`: http://www.seleniumhq.org/projects/webdriver/"""
|
||||
|
||||
|
||||
setup(name='marionette-transport',
|
||||
version=get_version(),
|
||||
description="Transport layer for Marionette client",
|
||||
long_description=long_description,
|
||||
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
keywords='mozilla',
|
||||
author='Mozilla Automation and Tools Team',
|
||||
author_email='tools@lists.mozilla.org',
|
||||
url='https://developer.mozilla.org/en-US/docs/Marionette',
|
||||
license='MPL',
|
||||
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
|
||||
package_data={},
|
||||
include_package_data=False,
|
||||
zip_safe=False,
|
||||
entry_points="""
|
||||
""",
|
||||
install_requires=[],
|
||||
)
|
||||
@@ -1,9 +1,13 @@
|
||||
|
||||
Serving up content to be consumed by the browser
|
||||
================================================
|
||||
|
||||
I know, right? ANOTHER Python HTTP server? In all seriousness, we
|
||||
weren't able to find anything out there that was fast enough, flexible
|
||||
enough, and easy-to-use enough for our needs. So we created our own.
|
||||
|
||||
.. warning:: The mozhttpd module is considered obsolete. For new code,
|
||||
please use wptserve_ which can do everything mozhttpd does
|
||||
and more.
|
||||
|
||||
.. _wptserve: https://pypi.python.org/pypi/wptserve
|
||||
|
||||
:mod:`mozhttpd` --- Simple webserver
|
||||
------------------------------------
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_NAME = 'mozcrash'
|
||||
PACKAGE_VERSION = '0.14'
|
||||
PACKAGE_VERSION = '0.15'
|
||||
|
||||
# dependencies
|
||||
deps = ['mozfile >= 1.0',
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_NAME = 'mozdevice'
|
||||
PACKAGE_VERSION = '0.45'
|
||||
PACKAGE_VERSION = '0.46'
|
||||
|
||||
deps = ['mozfile >= 1.0',
|
||||
'mozlog >= 3.0',
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_VERSION = '0.26'
|
||||
PACKAGE_VERSION = '0.27'
|
||||
|
||||
deps = ['mozinfo',
|
||||
'mozlog >= 3.0',
|
||||
|
||||
@@ -11,7 +11,6 @@ import zipfile
|
||||
from xml.dom import minidom
|
||||
|
||||
import mozfile
|
||||
from manifestparser import ManifestParser
|
||||
from mozlog.unstructured import getLogger
|
||||
|
||||
# Needed for the AMO's rest API - https://developer.mozilla.org/en/addons.mozilla.org_%28AMO%29_API_Developers%27_Guide/The_generic_AMO_API
|
||||
@@ -185,6 +184,14 @@ class AddonManager(object):
|
||||
Installs addons from a manifest
|
||||
:param filepath: path to the manifest of addons to install
|
||||
"""
|
||||
try:
|
||||
from manifestparser import ManifestParser
|
||||
except ImportError:
|
||||
module_logger.critical(
|
||||
"Installing addons from manifest requires the"
|
||||
" manifestparser package to be installed.")
|
||||
raise
|
||||
|
||||
manifest = ManifestParser()
|
||||
manifest.read(filepath)
|
||||
addons = manifest.get()
|
||||
|
||||
@@ -6,14 +6,12 @@ import sys
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_NAME = 'mozprofile'
|
||||
PACKAGE_VERSION = '0.23'
|
||||
PACKAGE_VERSION = '0.28'
|
||||
|
||||
# we only support python 2 right now
|
||||
assert sys.version_info[0] == 2
|
||||
|
||||
deps = ['manifestparser >= 0.6',
|
||||
'mozfile >= 1.0',
|
||||
'mozlog >= 3.0']
|
||||
deps = ['mozfile >= 1.0', 'mozlog >= 3.0']
|
||||
|
||||
setup(name=PACKAGE_NAME,
|
||||
version=PACKAGE_VERSION,
|
||||
@@ -36,6 +34,7 @@ setup(name=PACKAGE_NAME,
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
install_requires=deps,
|
||||
extras_require={'manifest': ['manifestparser >= 0.6']},
|
||||
tests_require=['mozhttpd'],
|
||||
entry_points="""
|
||||
# -*- Entry points: -*-
|
||||
|
||||
@@ -6,7 +6,7 @@ import sys
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
PACKAGE_NAME = 'mozrunner'
|
||||
PACKAGE_VERSION = '6.7'
|
||||
PACKAGE_VERSION = '6.8'
|
||||
|
||||
desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)"""
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_VERSION = '1.2'
|
||||
PACKAGE_VERSION = '1.3'
|
||||
|
||||
dependencies = ['mozdevice >= 0.44',
|
||||
'mozfile >= 1.0',
|
||||
|
||||
@@ -566,7 +566,6 @@ stage-marionette: make-stage-dir
|
||||
$(NSINSTALL) -D $(MARIONETTE_DIR)/transport
|
||||
$(NSINSTALL) -D $(MARIONETTE_DIR)/driver
|
||||
@(cd $(topsrcdir)/testing/marionette/client && tar --exclude marionette/tests $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/ && tar -xf -)
|
||||
@(cd $(topsrcdir)/testing/marionette/transport && tar $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/transport && tar -xf -)
|
||||
@(cd $(topsrcdir)/testing/marionette/driver && tar $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/driver && tar -xf -)
|
||||
$(PYTHON) $(topsrcdir)/testing/marionette/client/marionette/tests/print-manifest-dirs.py \
|
||||
$(topsrcdir) \
|
||||
|
||||
Reference in New Issue
Block a user