diff --git a/accessible/atk/DocAccessibleWrap.cpp b/accessible/atk/DocAccessibleWrap.cpp index 0d05332bfd..d78d724b43 100644 --- a/accessible/atk/DocAccessibleWrap.cpp +++ b/accessible/atk/DocAccessibleWrap.cpp @@ -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) { } diff --git a/accessible/atk/DocAccessibleWrap.h b/accessible/atk/DocAccessibleWrap.h index 5eb4a5ed44..e5fc8e5e47 100644 --- a/accessible/atk/DocAccessibleWrap.h +++ b/accessible/atk/DocAccessibleWrap.h @@ -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; diff --git a/accessible/base/DocManager.cpp b/accessible/base/DocManager.cpp index 6c6bf13af4..e74d3fdd03 100644 --- a/accessible/base/DocManager.cpp +++ b/accessible/base/DocManager.cpp @@ -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 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) { diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index c7053a03bf..18e522fe1b 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -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)); } diff --git a/accessible/generic/DocAccessible.h b/accessible/generic/DocAccessible.h index afd34dab03..237bea0a49 100644 --- a/accessible/generic/DocAccessible.h +++ b/accessible/generic/DocAccessible.h @@ -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 {} diff --git a/accessible/generic/RootAccessible.cpp b/accessible/generic/RootAccessible.cpp index 6f16826ef7..f96ab5a98e 100644 --- a/accessible/generic/RootAccessible.cpp +++ b/accessible/generic/RootAccessible.cpp @@ -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; } diff --git a/accessible/generic/RootAccessible.h b/accessible/generic/RootAccessible.h index 8e015d5166..beb74cf4b6 100644 --- a/accessible/generic/RootAccessible.h +++ b/accessible/generic/RootAccessible.h @@ -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; diff --git a/accessible/mac/DocAccessibleWrap.h b/accessible/mac/DocAccessibleWrap.h index 0d9c2cc9ed..3e80a0d33c 100644 --- a/accessible/mac/DocAccessibleWrap.h +++ b/accessible/mac/DocAccessibleWrap.h @@ -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(); }; diff --git a/accessible/mac/DocAccessibleWrap.mm b/accessible/mac/DocAccessibleWrap.mm index 54eadf0923..8a513f485a 100644 --- a/accessible/mac/DocAccessibleWrap.mm +++ b/accessible/mac/DocAccessibleWrap.mm @@ -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) { } diff --git a/accessible/mac/RootAccessibleWrap.h b/accessible/mac/RootAccessibleWrap.h index 9415bed81d..aa53e06ac0 100644 --- a/accessible/mac/RootAccessibleWrap.h +++ b/accessible/mac/RootAccessibleWrap.h @@ -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 (); diff --git a/accessible/mac/RootAccessibleWrap.mm b/accessible/mac/RootAccessibleWrap.mm index ea6e1c7ffa..60674c99c2 100644 --- a/accessible/mac/RootAccessibleWrap.mm +++ b/accessible/mac/RootAccessibleWrap.mm @@ -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) { } diff --git a/accessible/windows/msaa/DocAccessibleWrap.cpp b/accessible/windows/msaa/DocAccessibleWrap.cpp index 16c0b2dfe8..d2215a9969 100644 --- a/accessible/windows/msaa/DocAccessibleWrap.cpp +++ b/accessible/windows/msaa/DocAccessibleWrap.cpp @@ -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) { } diff --git a/accessible/windows/msaa/DocAccessibleWrap.h b/accessible/windows/msaa/DocAccessibleWrap.h index 18e58b0ab3..8350782d7a 100644 --- a/accessible/windows/msaa/DocAccessibleWrap.h +++ b/accessible/windows/msaa/DocAccessibleWrap.h @@ -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 diff --git a/accessible/windows/msaa/RootAccessibleWrap.cpp b/accessible/windows/msaa/RootAccessibleWrap.cpp index 0c232dd472..3d0592f1de 100644 --- a/accessible/windows/msaa/RootAccessibleWrap.cpp +++ b/accessible/windows/msaa/RootAccessibleWrap.cpp @@ -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) { } diff --git a/accessible/windows/msaa/RootAccessibleWrap.h b/accessible/windows/msaa/RootAccessibleWrap.h index c616c26ca4..6aa6fefe38 100644 --- a/accessible/windows/msaa/RootAccessibleWrap.h +++ b/accessible/windows/msaa/RootAccessibleWrap.h @@ -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 diff --git a/b2g/chrome/content/settings.js b/b2g/chrome/content/settings.js index 770e983249..4148e0f314 100644 --- a/b2g/chrome/content/settings.js +++ b/b2g/chrome/content/settings.js @@ -351,8 +351,7 @@ setUpdateTrackingId(); }); } - syncPrefDefault(AppConstants.MOZ_B2GDROID ? 'app.update.url.android' - : 'app.update.url'); + syncPrefDefault('app.update.url'); syncPrefDefault('app.update.channel'); })(); diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index 7e357691a9..58dbdec2bc 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -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'); diff --git a/b2g/components/B2GComponents.manifest b/b2g/components/B2GComponents.manifest index f8ee912448..01b5661cf8 100644 --- a/b2g/components/B2GComponents.manifest +++ b/b2g/components/B2GComponents.manifest @@ -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 diff --git a/b2g/components/moz.build b/b2g/components/moz.build index 1e9c05d9f5..e454c70c33 100644 --- a/b2g/components/moz.build +++ b/b2g/components/moz.build @@ -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', diff --git a/b2g/gaia/Makefile.in b/b2g/gaia/Makefile.in index 99925c930a..0820b16a4b 100644 --- a/b2g/gaia/Makefile.in +++ b/b2g/gaia/Makefile.in @@ -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 -) diff --git a/b2g/gaia/moz.build b/b2g/gaia/moz.build index 362ce5671a..c0c0642490 100644 --- a/b2g/gaia/moz.build +++ b/b2g/gaia/moz.build @@ -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"' diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index f8bf91ab4d..211d98abe2 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -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 diff --git a/build/virtualenv_packages.txt b/build/virtualenv_packages.txt index 0861273c0f..122804e652 100644 --- a/build/virtualenv_packages.txt +++ b/build/virtualenv_packages.txt @@ -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 diff --git a/configure.in b/configure.in index ffd65649f0..e5138eb512 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/dom/apps/AndroidUtils.jsm b/dom/apps/AndroidUtils.jsm deleted file mode 100644 index 53fb4002cf..0000000000 --- a/dom/apps/AndroidUtils.jsm +++ /dev/null @@ -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); - } - }, -} diff --git a/dom/apps/Webapps.jsm b/dom/apps/Webapps.jsm index 6d134139ab..0f5adeed8e 100755 --- a/dom/apps/Webapps.jsm +++ b/dom/apps/Webapps.jsm @@ -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); diff --git a/dom/apps/moz.build b/dom/apps/moz.build index 866dc47222..8577cf5506 100644 --- a/dom/apps/moz.build +++ b/dom/apps/moz.build @@ -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', diff --git a/dom/base/ChildIterator.cpp b/dom/base/ChildIterator.cpp index 9557d1ed1a..a95631e639 100644 --- a/dom/base/ChildIterator.cpp +++ b/dom/base/ChildIterator.cpp @@ -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; } diff --git a/dom/base/ChildIterator.h b/dom/base/ChildIterator.h index d7c0c4c896..282ce5d63e 100644 --- a/dom/base/ChildIterator.h +++ b/dom/base/ChildIterator.h @@ -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 mAnonKids; + uint32_t mAnonKidsIdx; + uint32_t mFlags; IteratorPhase mPhase; #ifdef DEBUG diff --git a/dom/base/ScriptSettings.cpp b/dom/base/ScriptSettings.cpp index 96119210b4..d3a6a0a624 100644 --- a/dom/base/ScriptSettings.cpp +++ b/dom/base/ScriptSettings.cpp @@ -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 exn(aCx); + JS_GetPendingException(aCx, &exn); + + JS_ClearPendingException(aCx); + if (exn.isObject()) { + JS::Rooted exnObj(aCx, &exn.toObject()); + + nsAutoJSString stack, filename, name, message; + int32_t line; + + JS::Rooted 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 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) diff --git a/dom/base/ScriptSettings.h b/dom/base/ScriptSettings.h index 4bbb5adaec..7264347e7e 100644 --- a/dom/base/ScriptSettings.h +++ b/dom/base/ScriptSettings.h @@ -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 }; /** diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp index d8a47bc8d1..68e5d7f1d8 100644 --- a/dom/base/WebSocket.cpp +++ b/dom/base/WebSocket.cpp @@ -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 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 parentWindow = + innerWindow->GetScriptableParent(); + if (NS_WARN_IF(!parentWindow)) { + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return; + } + + nsCOMPtr 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 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 jsData(aCx); + JS::Rooted 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 arrayBuf(aCx); - nsresult rv = nsContentUtils::CreateArrayBuffer(aCx, aData, + JS::Rooted 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); diff --git a/dom/base/WebSocket.h b/dom/base/WebSocket.h index 2b75a3493f..ecbd15cf8b 100644 --- a/dom/base/WebSocket.h +++ b/dom/base/WebSocket.h @@ -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); diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 2d05643cdf..508080dee2 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -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 aRetval, mozilla::ErrorResult& aError); already_AddRefed GetOpener() override; diff --git a/dom/devicestorage/DeviceStorageStatics.cpp b/dom/devicestorage/DeviceStorageStatics.cpp index dbb9e8e65b..806162ffd0 100644 --- a/dom/devicestorage/DeviceStorageStatics.cpp +++ b/dom/devicestorage/DeviceStorageStatics.cpp @@ -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")); diff --git a/dom/identity/nsDOMIdentity.js b/dom/identity/nsDOMIdentity.js index 666fb9ab9b..e2a15d46fc 100644 --- a/dom/identity/nsDOMIdentity.js +++ b/dom/identity/nsDOMIdentity.js @@ -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); }, /** diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index 38fd07f5ae..3e40a4522f 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -727,25 +727,17 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal, } } - AutoJSAPI autoJS; RefPtr 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 scriptOwner(cx, - static_cast(mWindow.get())->FastGetGlobalJSObject()); + JS::Rooted scriptOwner(nsContentUtils::RootingCxForThread(), + nsGlobalWindow::Cast(mWindow.get())->FastGetGlobalJSObject()); MOZ_ASSERT(scriptOwner); request = IDBOpenDBRequest::CreateForWindow(this, mWindow, scriptOwner); } else { - autoJS.Init(mOwningObject.get()); - JS::Rooted scriptOwner(autoJS.cx(), mOwningObject); + JS::Rooted scriptOwner(nsContentUtils::RootingCxForThread(), + mOwningObject); request = IDBOpenDBRequest::CreateForJS(this, scriptOwner); if (!request) { diff --git a/dom/tests/browser/browser.ini b/dom/tests/browser/browser.ini index 9a67de3dff..363758ed7b 100644 --- a/dom/tests/browser/browser.ini +++ b/dom/tests/browser/browser.ini @@ -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" diff --git a/dom/tests/browser/browser_test_new_window_from_content.js b/dom/tests/browser/browser_test_new_window_from_content.js index 5e8a35a793..1ae7461b0c 100644 --- a/dom/tests/browser/browser_test_new_window_from_content.js +++ b/dom/tests/browser/browser_test_new_window_from_content.js @@ -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 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); }); diff --git a/dom/tests/browser/browser_test_toolbars_visibility.js b/dom/tests/browser/browser_test_toolbars_visibility.js new file mode 100644 index 0000000000..77c15e67bd --- /dev/null +++ b/dom/tests/browser/browser_test_toolbars_visibility.js @@ -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 () + * 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); +}); diff --git a/dom/tests/browser/test_new_window_from_content_child.html b/dom/tests/browser/test_new_window_from_content_child.html index 0594919b3a..5d2733ba18 100644 --- a/dom/tests/browser/test_new_window_from_content_child.html +++ b/dom/tests/browser/test_new_window_from_content_child.html @@ -5,19 +5,15 @@

Open a new window via window.open with default features.

-

Open a new window via window.open with non-default features.

-

Open a new window via target="_blank".

+

Open a new window via window.open with non-default features.

+

Open a new window via window.open with dialog=1.

+

Open a new window via target="_blank".

\ No newline at end of file + diff --git a/dom/tests/browser/test_new_window_from_content_child.js b/dom/tests/browser/test_new_window_from_content_child.js deleted file mode 100644 index cd3f3ea9aa..0000000000 --- a/dom/tests/browser/test_new_window_from_content_child.js +++ /dev/null @@ -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); \ No newline at end of file diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index 1f8575ada6..7df8c13ac2 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -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 diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 1401299ab7..56d9155044 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -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( diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp index 5c1a52ed9b..a3ab2996e2 100644 --- a/netwerk/protocol/websocket/WebSocketChannel.cpp +++ b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -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(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; } diff --git a/testing/config/marionette_requirements.txt b/testing/config/marionette_requirements.txt index 296c5d61b8..e596b596ef 100644 --- a/testing/config/marionette_requirements.txt +++ b/testing/config/marionette_requirements.txt @@ -1,6 +1,5 @@ -r mozbase_requirements.txt ../tools/wptserve -../marionette/transport ../marionette/driver ../marionette/marionette/runner/mixins/browsermob-proxy-py ../marionette diff --git a/testing/marionette/client/marionette/__init__.py b/testing/marionette/client/marionette/__init__.py index cda1e0d555..cf25ab2b96 100644 --- a/testing/marionette/client/marionette/__init__.py +++ b/testing/marionette/client/marionette/__init__.py @@ -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, diff --git a/testing/marionette/client/marionette/tests/unit/mn-restartless.xpi b/testing/marionette/client/marionette/tests/unit/mn-restartless-unsigned.xpi similarity index 100% rename from testing/marionette/client/marionette/tests/unit/mn-restartless.xpi rename to testing/marionette/client/marionette/tests/unit/mn-restartless-unsigned.xpi diff --git a/testing/marionette/client/marionette/tests/unit/test_addons.py b/testing/marionette/client/marionette/tests/unit/test_addons.py index f1ebe851f8..cf87c12bc5 100644 --- a/testing/marionette/client/marionette/tests/unit/test_addons.py +++ b/testing/marionette/client/marionette/tests/unit/test_addons.py @@ -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) diff --git a/testing/marionette/client/requirements.txt b/testing/marionette/client/requirements.txt index 67dce7b022..7058980bbc 100644 --- a/testing/marionette/client/requirements.txt +++ b/testing/marionette/client/requirements.txt @@ -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 diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py index f3a03679b9..e654f75e6a 100644 --- a/testing/marionette/driver/marionette_driver/__init__.py +++ b/testing/marionette/driver/marionette_driver/__init__.py @@ -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, diff --git a/testing/marionette/driver/marionette_driver/addons.py b/testing/marionette/driver/marionette_driver/addons.py index 480914ba6d..de0fbc0818 100644 --- a/testing/marionette/driver/marionette_driver/addons.py +++ b/testing/marionette/driver/marionette_driver/addons.py @@ -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: diff --git a/testing/marionette/driver/marionette_driver/marionette.py b/testing/marionette/driver/marionette_driver/marionette.py index f09f35b6b5..e9fed002cc 100644 --- a/testing/marionette/driver/marionette_driver/marionette.py +++ b/testing/marionette/driver/marionette_driver/marionette.py @@ -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. diff --git a/testing/marionette/transport/marionette_transport/transport.py b/testing/marionette/driver/marionette_driver/transport.py similarity index 100% rename from testing/marionette/transport/marionette_transport/transport.py rename to testing/marionette/driver/marionette_driver/transport.py diff --git a/testing/marionette/driver/requirements.txt b/testing/marionette/driver/requirements.txt index 44f895e786..a77e91f0e8 100644 --- a/testing/marionette/driver/requirements.txt +++ b/testing/marionette/driver/requirements.txt @@ -1,2 +1 @@ -marionette-transport == 1.0.0 mozrunner >= 6.9 diff --git a/testing/marionette/transport/marionette_transport/__init__.py b/testing/marionette/transport/marionette_transport/__init__.py deleted file mode 100644 index da9d39fb9c..0000000000 --- a/testing/marionette/transport/marionette_transport/__init__.py +++ /dev/null @@ -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 * diff --git a/testing/marionette/transport/setup.py b/testing/marionette/transport/setup.py deleted file mode 100644 index 1be3ff9d1e..0000000000 --- a/testing/marionette/transport/setup.py +++ /dev/null @@ -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=[], - ) diff --git a/testing/mozbase/docs/mozhttpd.rst b/testing/mozbase/docs/mozhttpd.rst index 8ad9284df7..f6ceddb370 100644 --- a/testing/mozbase/docs/mozhttpd.rst +++ b/testing/mozbase/docs/mozhttpd.rst @@ -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 ------------------------------------ diff --git a/testing/mozbase/mozcrash/setup.py b/testing/mozbase/mozcrash/setup.py index 01f254d162..587060e108 100644 --- a/testing/mozbase/mozcrash/setup.py +++ b/testing/mozbase/mozcrash/setup.py @@ -5,7 +5,7 @@ from setuptools import setup PACKAGE_NAME = 'mozcrash' -PACKAGE_VERSION = '0.14' +PACKAGE_VERSION = '0.15' # dependencies deps = ['mozfile >= 1.0', diff --git a/testing/mozbase/mozdevice/setup.py b/testing/mozbase/mozdevice/setup.py index 8f5e5dd6fb..9be7e0bf96 100644 --- a/testing/mozbase/mozdevice/setup.py +++ b/testing/mozbase/mozdevice/setup.py @@ -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', diff --git a/testing/mozbase/moznetwork/setup.py b/testing/mozbase/moznetwork/setup.py index 34eb91a963..88efd961e1 100644 --- a/testing/mozbase/moznetwork/setup.py +++ b/testing/mozbase/moznetwork/setup.py @@ -4,7 +4,7 @@ from setuptools import setup -PACKAGE_VERSION = '0.26' +PACKAGE_VERSION = '0.27' deps = ['mozinfo', 'mozlog >= 3.0', diff --git a/testing/mozbase/mozprofile/mozprofile/addons.py b/testing/mozbase/mozprofile/mozprofile/addons.py index f1c9d6b8fc..e21d70890c 100644 --- a/testing/mozbase/mozprofile/mozprofile/addons.py +++ b/testing/mozbase/mozprofile/mozprofile/addons.py @@ -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() diff --git a/testing/mozbase/mozprofile/setup.py b/testing/mozbase/mozprofile/setup.py index 742be785b1..dda07d962e 100644 --- a/testing/mozbase/mozprofile/setup.py +++ b/testing/mozbase/mozprofile/setup.py @@ -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: -*- diff --git a/testing/mozbase/mozrunner/setup.py b/testing/mozbase/mozrunner/setup.py index abda83f430..c7dc459121 100644 --- a/testing/mozbase/mozrunner/setup.py +++ b/testing/mozbase/mozrunner/setup.py @@ -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.)""" diff --git a/testing/mozbase/mozversion/setup.py b/testing/mozbase/mozversion/setup.py index 80ad0d2837..cc679661e6 100644 --- a/testing/mozbase/mozversion/setup.py +++ b/testing/mozbase/mozversion/setup.py @@ -4,7 +4,7 @@ from setuptools import setup -PACKAGE_VERSION = '1.2' +PACKAGE_VERSION = '1.3' dependencies = ['mozdevice >= 0.44', 'mozfile >= 1.0', diff --git a/testing/testsuite-targets.mk b/testing/testsuite-targets.mk index 0ae2ac993c..0fddcf1883 100644 --- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -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) \